summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authormlelstv <mlelstv@NetBSD.org>2017-11-01 19:34:45 +0000
committermlelstv <mlelstv@NetBSD.org>2017-11-01 19:34:45 +0000
commit0fdf1a3e4df1887fb802c1fa381d03032a2dd47c (patch)
treee3c86c6abd7420d80d5772fc7c6c55badb85fddc /sys/dev
parentfc1be4b374dc731df5864a657efb5e2c57b85a3b (diff)
refactor wd and ataraid drivers to use common disk subroutines.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ata/ata_raid_adaptec.c21
-rw-r--r--sys/dev/ata/ata_raid_intel.c21
-rw-r--r--sys/dev/ata/ata_raid_jmicron.c23
-rw-r--r--sys/dev/ata/ata_raid_nvidia.c19
-rw-r--r--sys/dev/ata/ata_raid_promise.c21
-rw-r--r--sys/dev/ata/ata_raid_via.c23
-rw-r--r--sys/dev/ata/wd.c955
-rw-r--r--sys/dev/ata/wdvar.h12
-rw-r--r--sys/dev/files.dev4
9 files changed, 405 insertions, 694 deletions
diff --git a/sys/dev/ata/ata_raid_adaptec.c b/sys/dev/ata/ata_raid_adaptec.c
index e2969cbec3b..387515879f3 100644
--- a/sys/dev/ata/ata_raid_adaptec.c
+++ b/sys/dev/ata/ata_raid_adaptec.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_raid_adaptec.c,v 1.9 2008/09/15 11:44:50 tron Exp $ */
+/* $NetBSD: ata_raid_adaptec.c,v 1.10 2017/11/01 19:34:46 mlelstv Exp $ */
/*-
* Copyright (c) 2000,2001,2002 Søren Schmidt <sos@FreeBSD.org>
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_raid_adaptec.c,v 1.9 2008/09/15 11:44:50 tron Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_raid_adaptec.c,v 1.10 2017/11/01 19:34:46 mlelstv Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@@ -67,6 +67,7 @@ __KERNEL_RCSID(0, "$NetBSD: ata_raid_adaptec.c,v 1.9 2008/09/15 11:44:50 tron Ex
int
ata_raid_read_config_adaptec(struct wd_softc *sc)
{
+ struct dk_softc *dksc = &sc->sc_dksc;
struct adaptec_raid_conf *info;
struct atabus_softc *atabus;
struct vnode *vp;
@@ -78,10 +79,10 @@ ata_raid_read_config_adaptec(struct wd_softc *sc)
info = malloc(sizeof(*info), M_DEVBUF, M_WAITOK);
- bmajor = devsw_name2blk(device_xname(sc->sc_dev), NULL, 0);
+ bmajor = devsw_name2blk(dksc->sc_xname, NULL, 0);
/* Get a vnode for the raw partition of this disk. */
- dev = MAKEDISKDEV(bmajor, device_unit(sc->sc_dev), RAW_PART);
+ dev = MAKEDISKDEV(bmajor, device_unit(dksc->sc_dev), RAW_PART);
error = bdevvp(dev, &vp);
if (error)
goto out;
@@ -97,7 +98,7 @@ ata_raid_read_config_adaptec(struct wd_softc *sc)
VOP_CLOSE(vp, FREAD, NOCRED);
vput(vp);
if (error) {
- aprint_error_dev(sc->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"error %d reading Adaptec config block\n", error);
goto out;
}
@@ -110,7 +111,7 @@ ata_raid_read_config_adaptec(struct wd_softc *sc)
/* Check the signature. */
if (info->magic_0 != ADP_MAGIC_0 || info->magic_3 != ADP_MAGIC_3) {
DPRINTF(("%s: Adaptec signature check failed\n",
- device_xname(sc->sc_dev)));
+ dksc->sc_xname));
error = ESRCH;
goto out;
}
@@ -145,7 +146,7 @@ ata_raid_read_config_adaptec(struct wd_softc *sc)
break;
default:
- aprint_error_dev(sc->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"unknown Adaptec RAID type 0x%02x\n",
info->configs[0].type);
error = EINVAL;
@@ -169,10 +170,10 @@ ata_raid_read_config_adaptec(struct wd_softc *sc)
aai->aai_interleave = aai->aai_capacity;
}
- atabus = device_private(device_parent(sc->sc_dev));
+ atabus = device_private(device_parent(dksc->sc_dev));
drive = atabus->sc_chan->ch_channel;
if (drive >= aai->aai_ndisks) {
- aprint_error_dev(sc->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"drive number %d doesn't make sense within %d-disk "
"array\n", drive, aai->aai_ndisks);
error = EINVAL;
@@ -180,7 +181,7 @@ ata_raid_read_config_adaptec(struct wd_softc *sc)
}
adi = &aai->aai_disks[drive];
- adi->adi_dev = sc->sc_dev;
+ adi->adi_dev = dksc->sc_dev;
adi->adi_status = ADI_S_ONLINE | ADI_S_ASSIGNED;
adi->adi_sectors = aai->aai_capacity;
adi->adi_compsize = be32toh(info->configs[drive+1].sectors);
diff --git a/sys/dev/ata/ata_raid_intel.c b/sys/dev/ata/ata_raid_intel.c
index 60f91faf6b0..f8c0c6549da 100644
--- a/sys/dev/ata/ata_raid_intel.c
+++ b/sys/dev/ata/ata_raid_intel.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_raid_intel.c,v 1.7 2014/03/25 16:19:13 christos Exp $ */
+/* $NetBSD: ata_raid_intel.c,v 1.8 2017/11/01 19:34:46 mlelstv Exp $ */
/*-
* Copyright (c) 2000-2008 Søren Schmidt <sos@FreeBSD.org>
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_raid_intel.c,v 1.7 2014/03/25 16:19:13 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_raid_intel.c,v 1.8 2017/11/01 19:34:46 mlelstv Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@@ -136,6 +136,7 @@ ata_raid_intel_print_info(struct intel_raid_conf *info)
int
ata_raid_read_config_intel(struct wd_softc *sc)
{
+ struct dk_softc *dksc = &sc->sc_dksc;
struct intel_raid_conf *info;
struct intel_raid_mapping *map;
struct ataraid_array_info *aai;
@@ -149,10 +150,10 @@ ata_raid_read_config_intel(struct wd_softc *sc)
info = malloc(1536, M_DEVBUF, M_WAITOK|M_ZERO);
- bmajor = devsw_name2blk(device_xname(sc->sc_dev), NULL, 0);
+ bmajor = devsw_name2blk(dksc->sc_xname, NULL, 0);
/* Get a vnode for the raw partition of this disk. */
- dev = MAKEDISKDEV(bmajor, device_unit(sc->sc_dev), RAW_PART);
+ dev = MAKEDISKDEV(bmajor, device_unit(dksc->sc_dev), RAW_PART);
error = bdevvp(dev, &vp);
if (error)
goto out;
@@ -169,7 +170,7 @@ ata_raid_read_config_intel(struct wd_softc *sc)
vput(vp);
if (error) {
DPRINTF(("%s: error %d reading Intel MatrixRAID config block\n",
- device_xname(sc->sc_dev), error));
+ dksc->sc_xname, error));
goto out;
}
@@ -181,7 +182,7 @@ ata_raid_read_config_intel(struct wd_softc *sc)
/* Check if this is a Intel RAID struct */
if (strncmp(info->intel_id, INTEL_MAGIC, strlen(INTEL_MAGIC))) {
DPRINTF(("%s: Intel MatrixRAID signature check failed\n",
- device_xname(sc->sc_dev)));
+ dksc->sc_xname));
error = ESRCH;
goto out;
}
@@ -194,7 +195,7 @@ ata_raid_read_config_intel(struct wd_softc *sc)
checksum -= info->checksum;
if (checksum != info->checksum) {
DPRINTF(("%s: Intel MatrixRAID checksum failed 0x%x != 0x%x\n",
- device_xname(sc->sc_dev), checksum, info->checksum));
+ dksc->sc_xname, checksum, info->checksum));
error = ESRCH;
goto out;
}
@@ -208,7 +209,7 @@ ata_raid_read_config_intel(struct wd_softc *sc)
volumeid = find_volume_id(info);
if (volumeid < 0) {
- aprint_error_dev(sc->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"too many RAID arrays\n");
error = ENOMEM;
goto out;
@@ -235,7 +236,7 @@ findvol:
break;
default:
DPRINTF(("%s: unknown Intel MatrixRAID type 0x%02x\n",
- device_xname(sc->sc_dev), map->type));
+ dksc->sc_xname, map->type));
error = EINVAL;
goto out;
}
@@ -280,7 +281,7 @@ findvol:
adi->adi_status &= ~ADI_S_ONLINE;
if (adi->adi_status) {
- adi->adi_dev = sc->sc_dev;
+ adi->adi_dev = dksc->sc_dev;
adi->adi_sectors = info->disk[diskidx].sectors;
adi->adi_compsize = adi->adi_sectors - aai->aai_reserved;
diff --git a/sys/dev/ata/ata_raid_jmicron.c b/sys/dev/ata/ata_raid_jmicron.c
index 4f0b6b55583..cda3be7b2b3 100644
--- a/sys/dev/ata/ata_raid_jmicron.c
+++ b/sys/dev/ata/ata_raid_jmicron.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_raid_jmicron.c,v 1.5 2014/03/25 16:19:13 christos Exp $ */
+/* $NetBSD: ata_raid_jmicron.c,v 1.6 2017/11/01 19:34:46 mlelstv Exp $ */
/*-
* Copyright (c) 2000-2008 Søren Schmidt <sos@FreeBSD.org>
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_raid_jmicron.c,v 1.5 2014/03/25 16:19:13 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_raid_jmicron.c,v 1.6 2017/11/01 19:34:46 mlelstv Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@@ -118,6 +118,7 @@ ata_raid_jmicron_print_info(struct jmicron_raid_conf *info)
int
ata_raid_read_config_jmicron(struct wd_softc *sc)
{
+ struct dk_softc *dksc = &sc->sc_dksc;
struct atabus_softc *atabus;
struct jmicron_raid_conf *info;
struct vnode *vp;
@@ -131,10 +132,10 @@ ata_raid_read_config_jmicron(struct wd_softc *sc)
info = malloc(sizeof(*info), M_DEVBUF, M_WAITOK|M_ZERO);
- bmajor = devsw_name2blk(device_xname(sc->sc_dev), NULL, 0);
+ bmajor = devsw_name2blk(dksc->sc_xname, NULL, 0);
/* Get a vnode for the raw partition of this disk. */
- dev = MAKEDISKDEV(bmajor, device_unit(sc->sc_dev), RAW_PART);
+ dev = MAKEDISKDEV(bmajor, device_unit(dksc->sc_dev), RAW_PART);
error = bdevvp(dev, &vp);
if (error)
goto out;
@@ -151,14 +152,14 @@ ata_raid_read_config_jmicron(struct wd_softc *sc)
vput(vp);
if (error) {
DPRINTF(("%s: error %d reading JMicron config block\n",
- device_xname(sc->sc_dev), error));
+ dksc->sc_xname, error));
goto out;
}
/* Check for JMicron signature. */
if (strncmp(info->signature, JMICRON_MAGIC, 2)) {
DPRINTF(("%s: JMicron RAID signature check failed\n",
- device_xname(sc->sc_dev)));
+ dksc->sc_xname));
error = ESRCH;
goto out;
}
@@ -169,7 +170,7 @@ ata_raid_read_config_jmicron(struct wd_softc *sc)
checksum += *ptr++;
if (checksum) {
DPRINTF(("%s: JMicron checksum failed\n",
- device_xname(sc->sc_dev)));
+ dksc->sc_xname));
error = ESRCH;
goto out;
}
@@ -223,7 +224,7 @@ ata_raid_read_config_jmicron(struct wd_softc *sc)
break;
default:
DPRINTF(("%s: unknown JMicron RAID type 0x%02x\n",
- device_xname(sc->sc_dev), info->type));
+ dksc->sc_xname, info->type));
error = EINVAL;
goto out;
}
@@ -243,11 +244,11 @@ ata_raid_read_config_jmicron(struct wd_softc *sc)
if (info->name)
strlcpy(aai->aai_name, info->name, sizeof(aai->aai_name));
- atabus = device_private(device_parent(sc->sc_dev));
+ atabus = device_private(device_parent(dksc->sc_dev));
drive = atabus->sc_chan->ch_channel;
if (drive >= aai->aai_ndisks) {
DPRINTF(("%s: drive number %d doesn't make sense within "
- "%d-disk array\n", device_xname(sc->sc_dev),
+ "%d-disk array\n", dksc->sc_xname,
drive, aai->aai_ndisks));
error = EINVAL;
goto out;
@@ -255,7 +256,7 @@ ata_raid_read_config_jmicron(struct wd_softc *sc)
if (info->disks[drive] == info->disk_id) {
adi = &aai->aai_disks[drive];
- adi->adi_dev = sc->sc_dev;
+ adi->adi_dev = dksc->sc_dev;
adi->adi_status = ADI_S_ONLINE | ADI_S_ASSIGNED;
adi->adi_sectors = aai->aai_capacity;
adi->adi_compsize = disk_size - aai->aai_reserved;
diff --git a/sys/dev/ata/ata_raid_nvidia.c b/sys/dev/ata/ata_raid_nvidia.c
index 7e811d5a29c..81935c061e1 100644
--- a/sys/dev/ata/ata_raid_nvidia.c
+++ b/sys/dev/ata/ata_raid_nvidia.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_raid_nvidia.c,v 1.2 2014/03/25 16:19:13 christos Exp $ */
+/* $NetBSD: ata_raid_nvidia.c,v 1.3 2017/11/01 19:34:46 mlelstv Exp $ */
/*-
* Copyright (c) 2000 - 2008 Søren Schmidt <sos@FreeBSD.org>
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_raid_nvidia.c,v 1.2 2014/03/25 16:19:13 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_raid_nvidia.c,v 1.3 2017/11/01 19:34:46 mlelstv Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@@ -122,6 +122,7 @@ ata_raid_nvidia_print_info(struct nvidia_raid_conf *info)
int
ata_raid_read_config_nvidia(struct wd_softc *sc)
{
+ struct dk_softc *dksc = &sc->sc_dksc;
struct nvidia_raid_conf *info;
struct vnode *vp;
int bmajor, error, count;
@@ -137,10 +138,10 @@ ata_raid_read_config_nvidia(struct wd_softc *sc)
info = malloc(sizeof(*info), M_DEVBUF, M_WAITOK);
- bmajor = devsw_name2blk(device_xname(sc->sc_dev), NULL, 0);
+ bmajor = devsw_name2blk(dksc->sc_xname, NULL, 0);
/* Get a vnode for the raw partition of this disk. */
- dev = MAKEDISKDEV(bmajor, device_unit(sc->sc_dev), RAW_PART);
+ dev = MAKEDISKDEV(bmajor, device_unit(dksc->sc_dev), RAW_PART);
error = bdevvp(dev, &vp);
if (error)
goto out;
@@ -156,7 +157,7 @@ ata_raid_read_config_nvidia(struct wd_softc *sc)
VOP_CLOSE(vp, FREAD, NOCRED);
vput(vp);
if (error) {
- aprint_error_dev(sc->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"error %d reading nVidia MediaShield config block\n", error);
goto out;
}
@@ -168,7 +169,7 @@ ata_raid_read_config_nvidia(struct wd_softc *sc)
/* Check the signature. */
if (strncmp(info->nvidia_id, NV_MAGIC, strlen(NV_MAGIC)) != 0) {
DPRINTF(("%s: nVidia signature check failed\n",
- device_xname(sc->sc_dev)));
+ dksc->sc_xname));
error = ESRCH;
goto out;
}
@@ -179,7 +180,7 @@ ata_raid_read_config_nvidia(struct wd_softc *sc)
cksum += *ckptr++;
if (cksum) {
DPRINTF(("%s: nVidia checksum failed (0x%02x)\n",
- device_xname(sc->sc_dev), cksum));
+ dksc->sc_xname, cksum));
error = ESRCH;
goto out;
}
@@ -229,7 +230,7 @@ ata_raid_read_config_nvidia(struct wd_softc *sc)
break;
default:
- aprint_error_dev(sc->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"unknown nVidia type 0x%02x\n", info->type);
error = EINVAL;
goto out;
@@ -248,7 +249,7 @@ ata_raid_read_config_nvidia(struct wd_softc *sc)
aai->aai_reserved = 2;
adi = &aai->aai_disks[info->disk_number];
- adi->adi_dev = sc->sc_dev;
+ adi->adi_dev = dksc->sc_dev;
adi->adi_status = ADI_S_ONLINE | ADI_S_ASSIGNED;
adi->adi_sectors = aai->aai_capacity;
adi->adi_compsize = aai->aai_capacity / info->array_width;
diff --git a/sys/dev/ata/ata_raid_promise.c b/sys/dev/ata/ata_raid_promise.c
index a996bc6a0a7..f4c32816008 100644
--- a/sys/dev/ata/ata_raid_promise.c
+++ b/sys/dev/ata/ata_raid_promise.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_raid_promise.c,v 1.11 2008/03/18 20:46:36 cube Exp $ */
+/* $NetBSD: ata_raid_promise.c,v 1.12 2017/11/01 19:34:46 mlelstv Exp $ */
/*-
* Copyright (c) 2000,2001,2002 Søren Schmidt <sos@FreeBSD.org>
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_raid_promise.c,v 1.11 2008/03/18 20:46:36 cube Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_raid_promise.c,v 1.12 2017/11/01 19:34:46 mlelstv Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@@ -67,6 +67,7 @@ __KERNEL_RCSID(0, "$NetBSD: ata_raid_promise.c,v 1.11 2008/03/18 20:46:36 cube E
int
ata_raid_read_config_promise(struct wd_softc *sc)
{
+ struct dk_softc *dksc = &sc->sc_dksc;
struct promise_raid_conf *info;
struct vnode *vp;
int bmajor, error, count;
@@ -78,10 +79,10 @@ ata_raid_read_config_promise(struct wd_softc *sc)
info = malloc(sizeof(*info), M_DEVBUF, M_WAITOK);
- bmajor = devsw_name2blk(device_xname(sc->sc_dev), NULL, 0);
+ bmajor = devsw_name2blk(dksc->sc_xname, NULL, 0);
/* Get a vnode for the raw partition of this disk. */
- dev = MAKEDISKDEV(bmajor, device_unit(sc->sc_dev), RAW_PART);
+ dev = MAKEDISKDEV(bmajor, device_unit(dksc->sc_dev), RAW_PART);
error = bdevvp(dev, &vp);
if (error)
goto out;
@@ -97,7 +98,7 @@ ata_raid_read_config_promise(struct wd_softc *sc)
VOP_CLOSE(vp, FREAD, NOCRED);
vput(vp);
if (error) {
- aprint_error_dev(sc->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"error %d reading Promise config block\n", error);
goto out;
}
@@ -105,7 +106,7 @@ ata_raid_read_config_promise(struct wd_softc *sc)
/* Check the signature. */
if (strncmp(info->promise_id, PR_MAGIC, sizeof(PR_MAGIC)) != 0) {
DPRINTF(("%s: Promise signature check failed\n",
- device_xname(sc->sc_dev)));
+ dksc->sc_xname));
error = ESRCH;
goto out;
}
@@ -116,14 +117,14 @@ ata_raid_read_config_promise(struct wd_softc *sc)
cksum += *ckptr++;
if (cksum != *ckptr) {
DPRINTF(("%s: Promise checksum failed\n",
- device_xname(sc->sc_dev)));
+ dksc->sc_xname));
error = ESRCH;
goto out;
}
if (info->raid.integrity != PR_I_VALID) {
DPRINTF(("%s: Promise config block marked invalid\n",
- device_xname(sc->sc_dev)));
+ dksc->sc_xname));
error = ESRCH;
goto out;
}
@@ -164,7 +165,7 @@ ata_raid_read_config_promise(struct wd_softc *sc)
break;
default:
- aprint_error_dev(sc->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"unknown Promise RAID type 0x%02x\n",
info->raid.type);
error = EINVAL;
@@ -199,7 +200,7 @@ ata_raid_read_config_promise(struct wd_softc *sc)
}
adi = &aai->aai_disks[info->raid.disk_number];
if (adi->adi_status) {
- adi->adi_dev = sc->sc_dev;
+ adi->adi_dev = dksc->sc_dev;
adi->adi_sectors = info->raid.disk_sectors;
adi->adi_compsize = sc->sc_capacity - aai->aai_reserved;
}
diff --git a/sys/dev/ata/ata_raid_via.c b/sys/dev/ata/ata_raid_via.c
index c0fe8c9fddf..d8bec59dc0f 100644
--- a/sys/dev/ata/ata_raid_via.c
+++ b/sys/dev/ata/ata_raid_via.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_raid_via.c,v 1.7 2014/03/25 16:19:13 christos Exp $ */
+/* $NetBSD: ata_raid_via.c,v 1.8 2017/11/01 19:34:46 mlelstv Exp $ */
/*-
* Copyright (c) 2000,2001,2002 Søren Schmidt <sos@FreeBSD.org>
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_raid_via.c,v 1.7 2014/03/25 16:19:13 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_raid_via.c,v 1.8 2017/11/01 19:34:46 mlelstv Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@@ -114,6 +114,7 @@ ata_raid_via_print_info(struct via_raid_conf *info)
int
ata_raid_read_config_via(struct wd_softc *sc)
{
+ struct dk_softc *dksc = &sc->sc_dksc;
struct via_raid_conf *info;
struct atabus_softc *atabus;
struct vnode *vp;
@@ -127,10 +128,10 @@ ata_raid_read_config_via(struct wd_softc *sc)
info = malloc(sizeof(*info), M_DEVBUF, M_WAITOK);
- bmajor = devsw_name2blk(device_xname(sc->sc_dev), NULL, 0);
+ bmajor = devsw_name2blk(dksc->sc_xname, NULL, 0);
/* Get a vnode for the raw partition of this disk. */
- dev = MAKEDISKDEV(bmajor, device_unit(sc->sc_dev), RAW_PART);
+ dev = MAKEDISKDEV(bmajor, device_unit(dksc->sc_dev), RAW_PART);
error = bdevvp(dev, &vp);
if (error)
goto out;
@@ -146,7 +147,7 @@ ata_raid_read_config_via(struct wd_softc *sc)
VOP_CLOSE(vp, FREAD, NOCRED);
vput(vp);
if (error) {
- aprint_error_dev(sc->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"error %d reading VIA V-RAID config block\n", error);
goto out;
}
@@ -159,7 +160,7 @@ ata_raid_read_config_via(struct wd_softc *sc)
/* Check the signature. */
if (info->magic != VIA_MAGIC) {
DPRINTF(("%s: VIA V-RAID signature check failed\n",
- device_xname(sc->sc_dev)));
+ dksc->sc_xname));
error = ESRCH;
goto out;
}
@@ -175,7 +176,7 @@ ata_raid_read_config_via(struct wd_softc *sc)
checksum += byte3;
if (checksum != info->checksum && checksum_alt != info->checksum) {
DPRINTF(("%s: VIA V-RAID checksum failed 0x%02x != "
- "0x%02x or 0x%02x\n", device_xname(sc->sc_dev),
+ "0x%02x or 0x%02x\n", dksc->sc_xname,
info->checksum, checksum, checksum_alt));
error = ESRCH;
goto out;
@@ -215,7 +216,7 @@ ata_raid_read_config_via(struct wd_softc *sc)
break;
default:
- aprint_error_dev(sc->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"unknown VIA V-RAID type 0x%02x\n", info->type);
error = EINVAL;
goto out;
@@ -238,10 +239,10 @@ ata_raid_read_config_via(struct wd_softc *sc)
if (aai->aai_interleave == 0)
aai->aai_interleave = aai->aai_capacity;
- atabus = device_private(device_parent(sc->sc_dev));
+ atabus = device_private(device_parent(dksc->sc_dev));
drive = atabus->sc_chan->ch_channel;
if (drive >= aai->aai_ndisks) {
- aprint_error_dev(sc->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"drive number %d doesn't make sense within %d-disk "
"array\n", drive, aai->aai_ndisks);
error = EINVAL;
@@ -249,7 +250,7 @@ ata_raid_read_config_via(struct wd_softc *sc)
}
adi = &aai->aai_disks[drive];
- adi->adi_dev = sc->sc_dev;
+ adi->adi_dev = dksc->sc_dev;
adi->adi_status = ADI_S_ONLINE | ADI_S_ASSIGNED;
adi->adi_sectors = aai->aai_capacity;
adi->adi_compsize = info->disk_sectors;
diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c
index 390b67831ca..5a47cfc5c29 100644
--- a/sys/dev/ata/wd.c
+++ b/sys/dev/ata/wd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: wd.c,v 1.433 2017/10/19 20:45:07 jdolecek Exp $ */
+/* $NetBSD: wd.c,v 1.434 2017/11/01 19:34:46 mlelstv Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
@@ -54,7 +54,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.433 2017/10/19 20:45:07 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.434 2017/11/01 19:34:46 mlelstv Exp $");
#include "opt_ata.h"
#include "opt_wd.h"
@@ -107,7 +107,10 @@ __KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.433 2017/10/19 20:45:07 jdolecek Exp $");
#define DEBUG_DETACH 0x20
#define DEBUG_XFERS 0x40
#ifdef ATADEBUG
-int wdcdebug_wd_mask = 0x0;
+#ifndef ATADEBUG_WD_MASK
+#define ATADEBUG_WD_MASK 0x0
+#endif
+int wdcdebug_wd_mask = ATADEBUG_WD_MASK;
#define ATADEBUG_PRINT(args, level) \
if (wdcdebug_wd_mask & (level)) \
printf args
@@ -115,15 +118,15 @@ int wdcdebug_wd_mask = 0x0;
#define ATADEBUG_PRINT(args, level)
#endif
-int wdprobe(device_t, cfdata_t, void *);
-void wdattach(device_t, device_t, void *);
-int wddetach(device_t, int);
-int wdprint(void *, char *);
-void wdperror(const struct wd_softc *, struct ata_xfer *);
+static int wdprobe(device_t, cfdata_t, void *);
+static void wdattach(device_t, device_t, void *);
+static int wddetach(device_t, int);
+static void wdperror(const struct wd_softc *, struct ata_xfer *);
static void wdminphys(struct buf *);
-static int wdlastclose(device_t);
+static int wd_firstopen(device_t, dev_t, int, int);
+static int wd_lastclose(device_t);
static bool wd_suspend(device_t, const pmf_qual_t *);
static int wd_standby(struct wd_softc *, int);
@@ -132,14 +135,14 @@ CFATTACH_DECL3_NEW(wd, sizeof(struct wd_softc),
extern struct cfdriver wd_cd;
-dev_type_open(wdopen);
-dev_type_close(wdclose);
-dev_type_read(wdread);
-dev_type_write(wdwrite);
-dev_type_ioctl(wdioctl);
-dev_type_strategy(wdstrategy);
-dev_type_dump(wddump);
-dev_type_size(wdsize);
+static dev_type_open(wdopen);
+static dev_type_close(wdclose);
+static dev_type_read(wdread);
+static dev_type_write(wdwrite);
+static dev_type_ioctl(wdioctl);
+static dev_type_strategy(wdstrategy);
+static dev_type_dump(wddump);
+static dev_type_size(wdsize);
static dev_type_discard(wddiscard);
const struct bdevsw wd_bdevsw = {
@@ -185,32 +188,41 @@ struct wd_ioctl {
struct wd_softc *wi_softc;
};
-struct wd_ioctl *wi_find(struct buf *);
-void wi_free(struct wd_ioctl *);
-struct wd_ioctl *wi_get(struct wd_softc *);
-void wdioctlstrategy(struct buf *);
-
-void wdgetdefaultlabel(struct wd_softc *, struct disklabel *);
-void wdgetdisklabel(struct wd_softc *);
-void wdstart(device_t);
-void wdstart1(struct wd_softc *, struct buf *, struct ata_xfer *);
-static void wdbiorestart(void *);
-void wddone(device_t, struct ata_xfer *);
-static void wd_params_to_properties(struct wd_softc *);
-int wd_get_params(struct wd_softc *, uint8_t, struct ataparams *);
-int wd_flushcache(struct wd_softc *, int, bool);
-int wd_trim(struct wd_softc *, int, daddr_t, long);
-bool wd_shutdown(device_t, int);
-
-int wd_getcache(struct wd_softc *, int *);
-int wd_setcache(struct wd_softc *, int);
+static struct wd_ioctl *wi_find(struct buf *);
+static void wi_free(struct wd_ioctl *);
+static struct wd_ioctl *wi_get(struct wd_softc *);
+static void wdioctlstrategy(struct buf *);
+
+static void wdstart(device_t);
+static int wd_diskstart(device_t, struct buf *);
+static int wd_dumpblocks(device_t, void *, daddr_t, int);
+static void wd_iosize(device_t, int *);
+static int wd_discard(device_t, off_t, off_t);
+static void wdbiorestart(void *);
+static void wddone(device_t, struct ata_xfer *);
+static int wd_get_params(struct wd_softc *, uint8_t, struct ataparams *);
+static void wd_set_geometry(struct wd_softc *);
+static int wd_flushcache(struct wd_softc *, int, bool);
+static int wd_trim(struct wd_softc *, daddr_t, long);
+static bool wd_shutdown(device_t, int);
+
+static int wd_getcache(struct wd_softc *, int *);
+static int wd_setcache(struct wd_softc *, int);
static void wd_sysctl_attach(struct wd_softc *);
static void wd_sysctl_detach(struct wd_softc *);
struct dkdriver wddkdriver = {
+ .d_open = wdopen,
+ .d_close = wdclose,
.d_strategy = wdstrategy,
- .d_minphys = wdminphys
+ .d_minphys = wdminphys,
+ .d_diskstart = wd_diskstart,
+ .d_dumpblocks = wd_dumpblocks,
+ .d_iosize = wd_iosize,
+ .d_firstopen = wd_firstopen,
+ .d_lastclose = wd_lastclose,
+ .d_discard = wd_discard
};
#ifdef HAS_BAD144_HANDLING
@@ -273,7 +285,7 @@ wd_lookup_quirks(const char *name)
return (NULL);
}
-int
+static int
wdprobe(device_t parent, cfdata_t match, void *aux)
{
struct ata_device *adev = aux;
@@ -289,20 +301,21 @@ wdprobe(device_t parent, cfdata_t match, void *aux)
return 1;
}
-void
+static void
wdattach(device_t parent, device_t self, void *aux)
{
struct wd_softc *wd = device_private(self);
+ struct dk_softc *dksc = &wd->sc_dksc;
struct ata_device *adev= aux;
int i, blank;
char tbuf[41], pbuf[9], c, *p, *q;
const struct wd_quirk *wdq;
+ int dtype = DKTYPE_UNKNOWN;
- wd->sc_dev = self;
+ dksc->sc_dev = self;
ATADEBUG_PRINT(("wdattach\n"), DEBUG_FUNCS | DEBUG_PROBE);
mutex_init(&wd->sc_lock, MUTEX_DEFAULT, IPL_BIO);
- bufq_alloc(&wd->sc_q, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK);
#ifdef WD_SOFTBADSECT
SLIST_INIT(&wd->sc_bslist);
#endif
@@ -312,7 +325,7 @@ wdattach(device_t parent, device_t self, void *aux)
wd->drvp->drv_openings = 1;
wd->drvp->drv_start = wdstart;
wd->drvp->drv_done = wddone;
- wd->drvp->drv_softc = wd->sc_dev; /* done in atabusconfig_thread()
+ wd->drvp->drv_softc = dksc->sc_dev; /* done in atabusconfig_thread()
but too late */
aprint_naive("\n");
@@ -430,20 +443,30 @@ wdattach(device_t parent, device_t self, void *aux)
"might not actually work\n", wd->sc_blksize);
}
+ if (strcmp(wd->sc_params.atap_model, "ST506") == 0)
+ dtype = DKTYPE_ST506;
+ else
+ dtype = DKTYPE_ESDI;
+
out:
/*
* Initialize and attach the disk structure.
*/
- /* we fill in dk_info later */
- disk_init(&wd->sc_dk, device_xname(wd->sc_dev), &wddkdriver);
- disk_attach(&wd->sc_dk);
- wd->drvp->lp = wd->sc_dk.dk_label;
- wd_params_to_properties(wd);
- rnd_attach_source(&wd->rnd_source, device_xname(wd->sc_dev),
- RND_TYPE_DISK, RND_FLAG_DEFAULT);
+ dk_init(dksc, self, dtype);
+ disk_init(&dksc->sc_dkdev, dksc->sc_xname, &wddkdriver);
+
+ /* Attach dk and disk subsystems */
+ dk_attach(dksc);
+ disk_attach(&dksc->sc_dkdev);
+ wd_set_geometry(wd);
+
+ bufq_alloc(&dksc->sc_bufq, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK);
+
+ /* reference to label structure, used by ata code */
+ wd->drvp->lp = dksc->sc_dkdev.dk_label;
/* Discover wedges on this disk. */
- dkwedge_discover(&wd->sc_dk);
+ dkwedge_discover(&dksc->sc_dkdev);
if (!pmf_device_register1(self, wd_suspend, NULL, wd_shutdown))
aprint_error_dev(self, "couldn't establish power handler\n");
@@ -467,13 +490,14 @@ wd_suspend(device_t dv, const pmf_qual_t *qual)
return true;
}
-int
+static int
wddetach(device_t self, int flags)
{
- struct wd_softc *sc = device_private(self);
+ struct wd_softc *wd = device_private(self);
+ struct dk_softc *dksc = &wd->sc_dksc;
int bmaj, cmaj, i, mn, rc;
- if ((rc = disk_begindetach(&sc->sc_dk, wdlastclose, self, flags)) != 0)
+ if ((rc = disk_begindetach(&dksc->sc_dkdev, wd_lastclose, self, flags)) != 0)
return rc;
/* locate the major number */
@@ -487,25 +511,26 @@ wddetach(device_t self, int flags)
vdevgone(cmaj, mn, mn, VCHR);
}
- /* Delete all of our wedges. */
- dkwedge_delall(&sc->sc_dk);
-
- mutex_enter(&sc->sc_lock);
+ dk_drain(dksc);
- /* Kill off any queued buffers. */
- bufq_drain(sc->sc_q);
+ /* Kill off any pending commands. */
+ mutex_enter(&wd->sc_lock);
+ wd->atabus->ata_killpending(wd->drvp);
+ mutex_exit(&wd->sc_lock);
- sc->atabus->ata_killpending(sc->drvp);
- mutex_exit(&sc->sc_lock);
+ bufq_free(dksc->sc_bufq);
if (flags & DETACH_POWEROFF)
- wd_standby(sc, AT_POLL);
+ wd_standby(wd, AT_POLL);
+
+ /* Delete all of our wedges. */
+ dkwedge_delall(&dksc->sc_dkdev);
- bufq_free(sc->sc_q);
+ /* Detach from the disk list. */
+ disk_detach(&dksc->sc_dkdev);
+ disk_destroy(&dksc->sc_dkdev);
- /* Detach disk. */
- disk_detach(&sc->sc_dk);
- disk_destroy(&sc->sc_dk);
+ dk_detach(dksc);
#ifdef WD_SOFTBADSECT
/* Clean out the bad sector list */
@@ -519,15 +544,12 @@ wddetach(device_t self, int flags)
pmf_device_deregister(self);
- wd_sysctl_detach(sc);
+ wd_sysctl_detach(wd);
- /* Unhook the entropy source. */
- rnd_detach_source(&sc->rnd_source);
+ mutex_destroy(&wd->sc_lock);
- mutex_destroy(&sc->sc_lock);
-
- sc->drvp->drive_type = ATA_DRIVET_NONE; /* no drive any more here */
- sc->drvp->drive_flags = 0;
+ wd->drvp->drive_type = ATA_DRIVET_NONE; /* no drive any more here */
+ wd->drvp->drive_flags = 0;
return (0);
}
@@ -536,65 +558,22 @@ wddetach(device_t self, int flags)
* Read/write routine for a buffer. Validates the arguments and schedules the
* transfer. Does not wait for the transfer to complete.
*/
-void
+static void
wdstrategy(struct buf *bp)
{
struct wd_softc *wd =
device_lookup_private(&wd_cd, WDUNIT(bp->b_dev));
- struct disklabel *lp = wd->sc_dk.dk_label;
- daddr_t blkno;
+ struct dk_softc *dksc = &wd->sc_dksc;
- ATADEBUG_PRINT(("wdstrategy (%s)\n", device_xname(wd->sc_dev)),
+ ATADEBUG_PRINT(("wdstrategy (%s)\n", dksc->sc_xname),
DEBUG_XFERS);
- /* Valid request? */
- if (bp->b_blkno < 0 ||
- (bp->b_bcount % lp->d_secsize) != 0 ||
- (bp->b_bcount / lp->d_secsize) >= (1 << NBBY)) {
- bp->b_error = EINVAL;
- goto done;
- }
-
/* If device invalidated (e.g. media change, door open,
* device detachment), then error.
*/
if ((wd->sc_flags & WDF_LOADED) == 0 ||
- !device_is_enabled(wd->sc_dev)) {
- bp->b_error = EIO;
- goto done;
- }
-
- /* If it's a null transfer, return immediately. */
- if (bp->b_bcount == 0)
- goto done;
-
- /*
- * Do bounds checking, adjust transfer. if error, process.
- * If end of partition, just return.
- */
- if (WDPART(bp->b_dev) == RAW_PART) {
- if (bounds_check_with_mediasize(bp, DEV_BSIZE,
- wd->sc_capacity512) <= 0)
- goto done;
- } else {
- if (bounds_check_with_label(&wd->sc_dk, bp,
- (wd->sc_flags & (WDF_WLABEL|WDF_LABELLING)) != 0) <= 0)
- goto done;
- }
-
- /*
- * Now convert the block number to absolute and put it in
- * terms of the device's logical block size.
- */
- if (lp->d_secsize >= DEV_BSIZE)
- blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE);
- else
- blkno = bp->b_blkno * (DEV_BSIZE / lp->d_secsize);
-
- if (WDPART(bp->b_dev) != RAW_PART)
- blkno += lp->d_partitions[WDPART(bp->b_dev)].p_offset;
-
- bp->b_rawblkno = blkno;
+ !device_is_enabled(dksc->sc_dev))
+ goto err;
#ifdef WD_SOFTBADSECT
/*
@@ -612,86 +591,40 @@ wdstrategy(struct buf *bp)
SLIST_FOREACH(dbs, &wd->sc_bslist, dbs_next)
if ((dbs->dbs_min <= blkno && blkno <= dbs->dbs_max) ||
(dbs->dbs_min <= maxblk && maxblk <= dbs->dbs_max)){
- bp->b_error = EIO;
mutex_exit(&wd->sc_lock);
- goto done;
+ goto err;
}
mutex_exit(&wd->sc_lock);
}
#endif
- /* Queue transfer on drive, activate drive and controller if idle. */
- mutex_enter(&wd->sc_lock);
- disk_wait(&wd->sc_dk);
- bufq_put(wd->sc_q, bp);
- mutex_exit(&wd->sc_lock);
-
- /* Try to queue on the current drive only */
- wdstart(wd->sc_dev);
+ dk_strategy(dksc, bp);
return;
-done:
- /* Toss transfer; we're done early. */
+
+err:
+ bp->b_error = EIO;
bp->b_resid = bp->b_bcount;
biodone(bp);
}
-/*
- * Queue a drive for I/O.
- */
-void
-wdstart(device_t self)
+static int
+wd_diskstart(device_t dev, struct buf *bp)
{
- struct wd_softc *wd = device_private(self);
- struct buf *bp;
+ struct wd_softc *wd = device_private(dev);
+ struct dk_softc *dksc = &wd->sc_dksc;
struct ata_xfer *xfer;
- ATADEBUG_PRINT(("wdstart %s\n", device_xname(wd->sc_dev)),
- DEBUG_XFERS);
-
- if (!device_is_active(wd->sc_dev))
- return;
-
mutex_enter(&wd->sc_lock);
- /*
- * Do not queue any transfers until flush is finished, so that
- * once flush is pending, it will get handled as soon as xfer
- * is available.
- */
- if (ISSET(wd->sc_flags, WDF_FLUSH_PEND)) {
- ATADEBUG_PRINT(("wdstart %s flush pend\n",
- device_xname(wd->sc_dev)), DEBUG_XFERS);
- goto out;
- }
-
- while (bufq_peek(wd->sc_q) != NULL) {
- /* First try to get xfer. Limit to drive openings iff NCQ. */
- xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, 0,
- WD_USE_NCQ(wd) ? WD_MAX_OPENINGS(wd) : 0);
- if (xfer == NULL) {
- ATADEBUG_PRINT(("wdstart %s no xfer\n",
- device_xname(wd->sc_dev)), DEBUG_XFERS);
- break;
- }
-
- /* There is got to be a buf for us */
- bp = bufq_get(wd->sc_q);
- KASSERT(bp != NULL);
-
- xfer->c_retries = 0;
- wdstart1(wd, bp, xfer);
+ xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, 0,
+ WD_USE_NCQ(wd) ? WD_MAX_OPENINGS(wd) : 0);
+ if (xfer == NULL) {
+ ATADEBUG_PRINT(("wdstart %s no xfer\n",
+ dksc->sc_xname), DEBUG_XFERS);
+ mutex_exit(&wd->sc_lock);
+ return EAGAIN;
}
-out:
- mutex_exit(&wd->sc_lock);
-}
-
-void
-wdstart1(struct wd_softc *wd, struct buf *bp, struct ata_xfer *xfer)
-{
- /* must be locked on entry */
- KASSERT(mutex_owned(&wd->sc_lock));
-
KASSERT(bp == xfer->c_bio.bp || xfer->c_bio.bp == NULL);
KASSERT((xfer->c_flags & (C_WAITACT|C_FREE)) == 0);
@@ -716,7 +649,7 @@ wdstart1(struct wd_softc *wd, struct buf *bp, struct ata_xfer *xfer)
*/
if (BUF_ISREAD(bp) && xfer->c_retries == 0 && wd->drv_chaos_freq > 0 &&
(++wd->drv_chaos_cnt % wd->drv_chaos_freq) == 0) {
- aprint_normal_dev(wd->sc_dev, "%s: chaos xfer %d\n",
+ aprint_normal_dev(dksc->sc_dev, "%s: chaos xfer %d\n",
__func__, xfer->c_slot);
xfer->c_bio.blkno = 7777777 + wd->sc_capacity;
xfer->c_flags |= C_CHAOS;
@@ -735,11 +668,16 @@ wdstart1(struct wd_softc *wd, struct buf *bp, struct ata_xfer *xfer)
xfer->c_bio.flags = ATA_SINGLE;
else
xfer->c_bio.flags = 0;
+
+ /*
+ * request LBA48 transfers when supported by the controller
+ * and needed by transfer offset or size.
+ */
if (wd->sc_flags & WDF_LBA48 &&
(((xfer->c_bio.blkno +
- xfer->c_bio.bcount / wd->sc_dk.dk_label->d_secsize) >
+ xfer->c_bio.bcount / dksc->sc_dkdev.dk_geom.dg_secsize) >
wd->sc_capacity28) ||
- ((xfer->c_bio.bcount / wd->sc_dk.dk_label->d_secsize) > 128)))
+ ((xfer->c_bio.bcount / dksc->sc_dkdev.dk_geom.dg_secsize) > 128)))
xfer->c_bio.flags |= ATA_LBA48;
/*
@@ -774,9 +712,6 @@ wdstart1(struct wd_softc *wd, struct buf *bp, struct ata_xfer *xfer)
xfer->c_bio.flags |= ATA_FUA;
}
- /* Instrumentation. */
- if (xfer->c_retries == 0)
- disk_busy(&wd->sc_dk);
switch (wd->atabus->ata_bio(wd->drvp, xfer)) {
case ATACMD_TRY_AGAIN:
panic("wdstart1: try again");
@@ -787,17 +722,51 @@ wdstart1(struct wd_softc *wd, struct buf *bp, struct ata_xfer *xfer)
default:
panic("wdstart1: bad return code from ata_bio()");
}
+
+ mutex_exit(&wd->sc_lock);
+
+ return 0;
}
-void
+/*
+ * Queue a drive for I/O.
+ */
+static void
+wdstart(device_t self)
+{
+ struct wd_softc *wd = device_private(self);
+ struct dk_softc *dksc = &wd->sc_dksc;
+
+ ATADEBUG_PRINT(("wdstart %s\n", dksc->sc_xname),
+ DEBUG_XFERS);
+
+ if (!device_is_active(dksc->sc_dev))
+ return;
+
+ /*
+ * Do not queue any transfers until flush is finished, so that
+ * once flush is pending, it will get handled as soon as xfer
+ * is available.
+ */
+ if (ISSET(wd->sc_flags, WDF_FLUSH_PEND)) {
+ ATADEBUG_PRINT(("wdstart %s flush pend\n",
+ dksc->sc_xname), DEBUG_XFERS);
+ return;
+ }
+
+ dk_start(dksc, NULL);
+}
+
+static void
wddone(device_t self, struct ata_xfer *xfer)
{
struct wd_softc *wd = device_private(self);
+ struct dk_softc *dksc = &wd->sc_dksc;
const char *errmsg;
int do_perror = 0;
struct buf *bp;
- ATADEBUG_PRINT(("wddone %s\n", device_xname(wd->sc_dev)),
+ ATADEBUG_PRINT(("wddone %s\n", dksc->sc_xname),
DEBUG_XFERS);
if (__predict_false(wddoingadump)) {
@@ -842,7 +811,7 @@ retry2:
mutex_enter(&wd->sc_lock);
diskerr(bp, "wd", errmsg, LOG_PRINTF,
- xfer->c_bio.blkdone, wd->sc_dk.dk_label);
+ xfer->c_bio.blkdone, dksc->sc_dkdev.dk_label);
if (xfer->c_retries < WDIORETRIES)
printf(", slot %d, retry %d", xfer->c_slot,
xfer->c_retries + 1);
@@ -856,7 +825,7 @@ retry2:
/* Rerun ASAP if just requeued */
callout_reset(&xfer->c_retry_callout,
(xfer->c_bio.error == REQUEUE) ? 1 : RECOVERYTIME,
- wdbiorestart, xfer);
+ wdbiorestart, wd);
mutex_exit(&wd->sc_lock);
return;
@@ -878,7 +847,7 @@ retry2:
dbs = malloc(sizeof *dbs, M_TEMP, M_NOWAIT);
if (dbs == NULL) {
- aprint_error_dev(wd->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"failed to add bad block to list\n");
goto out;
}
@@ -899,7 +868,7 @@ out:
break;
case NOERROR:
noerror: if ((xfer->c_bio.flags & ATA_CORR) || xfer->c_retries > 0)
- aprint_error_dev(wd->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"soft error (corrected) slot %d\n", xfer->c_slot);
#ifdef WD_CHAOS_MONKEY
KASSERT((xfer->c_flags & C_CHAOS) == 0);
@@ -917,27 +886,23 @@ noerror: if ((xfer->c_bio.flags & ATA_CORR) || xfer->c_retries > 0)
*/
bp->b_resid = bp->b_bcount;
}
- disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid),
- (bp->b_flags & B_READ));
- rnd_add_uint32(&wd->rnd_source, bp->b_blkno);
+
ata_free_xfer(wd->drvp->chnl_softc, xfer);
- biodone(bp);
- ata_channel_start(wd->drvp->chnl_softc, wd->drvp->drive);
+
+ dk_done(dksc, bp);
+ dk_start(dksc, NULL);
}
static void
wdbiorestart(void *v)
{
- struct ata_xfer *xfer = v;
- struct buf *bp = xfer->c_bio.bp;
- struct wd_softc *wd = device_lookup_private(&wd_cd, WDUNIT(bp->b_dev));
+ struct wd_softc *wd = v;
+ struct dk_softc *dksc = &wd->sc_dksc;
- ATADEBUG_PRINT(("wdrestart %s\n", device_xname(wd->sc_dev)),
+ ATADEBUG_PRINT(("wdrestart %s\n", dksc->sc_xname),
DEBUG_XFERS);
- mutex_enter(&wd->sc_lock);
- wdstart1(wd, bp, xfer);
- mutex_exit(&wd->sc_lock);
+ dk_start(dksc, NULL);
}
static void
@@ -945,7 +910,7 @@ wdminphys(struct buf *bp)
{
const struct wd_softc * const wd =
device_lookup_private(&wd_cd, WDUNIT(bp->b_dev));
- uint32_t maxsectors;
+ int maxsectors;
/*
* The limit is actually 65536 for LBA48 and 256 for non-LBA48,
@@ -963,7 +928,22 @@ wdminphys(struct buf *bp)
minphys(bp);
}
-int
+static void
+wd_iosize(device_t dev, int *count)
+{
+ struct buf B;
+ int bmaj;
+
+ bmaj = bdevsw_lookup_major(&wd_bdevsw);
+ B.b_dev = MAKEWDDEV(bmaj,device_unit(dev),RAW_PART);
+ B.b_bcount = *count;
+
+ wdminphys(&B);
+
+ *count = B.b_bcount;
+}
+
+static int
wdread(dev_t dev, struct uio *uio, int flags)
{
@@ -971,7 +951,7 @@ wdread(dev_t dev, struct uio *uio, int flags)
return (physio(wdstrategy, NULL, dev, B_READ, wdminphys, uio));
}
-int
+static int
wdwrite(dev_t dev, struct uio *uio, int flags)
{
@@ -979,97 +959,74 @@ wdwrite(dev_t dev, struct uio *uio, int flags)
return (physio(wdstrategy, NULL, dev, B_WRITE, wdminphys, uio));
}
-int
+static int
wdopen(dev_t dev, int flag, int fmt, struct lwp *l)
{
struct wd_softc *wd;
- int part, error;
+ struct dk_softc *dksc;
+ int unit, part, error;
ATADEBUG_PRINT(("wdopen\n"), DEBUG_FUNCS);
- wd = device_lookup_private(&wd_cd, WDUNIT(dev));
+ unit = WDUNIT(dev);
+ wd = device_lookup_private(&wd_cd, unit);
if (wd == NULL)
return (ENXIO);
+ dksc = &wd->sc_dksc;
- if (! device_is_active(wd->sc_dev))
- return (ENODEV);
-
- if (wd->sc_capacity == 0)
+ if (! device_is_active(dksc->sc_dev))
return (ENODEV);
part = WDPART(dev);
- mutex_enter(&wd->sc_dk.dk_openlock);
+ if (wd->sc_capacity == 0)
+ return (ENODEV);
/*
- * If there are wedges, and this is not RAW_PART, then we
- * need to fail.
+ * If any partition is open, but the disk has been invalidated,
+ * disallow further opens.
*/
- if (wd->sc_dk.dk_nwedges != 0 && part != RAW_PART) {
- error = EBUSY;
- goto bad1;
+ if ((wd->sc_flags & WDF_LOADED) == 0) {
+ if (part != RAW_PART || fmt != S_IFCHR)
+ return EIO;
}
- /*
- * If this is the first open of this device, add a reference
- * to the adapter.
- */
- if (wd->sc_dk.dk_openmask == 0 &&
- (error = wd->atabus->ata_addref(wd->drvp)) != 0)
- goto bad1;
+ error = dk_open(dksc, dev, flag, fmt, l);
- if (wd->sc_dk.dk_openmask != 0) {
- /*
- * If any partition is open, but the disk has been invalidated,
- * disallow further opens.
- */
- if ((wd->sc_flags & WDF_LOADED) == 0) {
- error = EIO;
- goto bad2;
- }
- } else {
- if ((wd->sc_flags & WDF_LOADED) == 0) {
-
- /* Load the physical device parameters. */
- if (wd_get_params(wd, AT_WAIT, &wd->sc_params) != 0) {
- aprint_error_dev(wd->sc_dev,
- "IDENTIFY failed\n");
- error = EIO;
- goto bad2;
- }
- wd->sc_flags |= WDF_LOADED;
- /* Load the partition info if not already loaded. */
- wdgetdisklabel(wd);
- }
- }
+ return error;
+}
- /* Check that the partition exists. */
- if (part != RAW_PART &&
- (part >= wd->sc_dk.dk_label->d_npartitions ||
- wd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
- error = ENXIO;
- goto bad2;
- }
+/*
+ * Serialized by caller
+ */
+static int
+wd_firstopen(device_t self, dev_t dev, int flag, int fmt)
+{
+ struct wd_softc *wd = device_private(self);
+ struct dk_softc *dksc = &wd->sc_dksc;
+ int error;
- /* Insure only one open at a time. */
- switch (fmt) {
- case S_IFCHR:
- wd->sc_dk.dk_copenmask |= (1 << part);
- break;
- case S_IFBLK:
- wd->sc_dk.dk_bopenmask |= (1 << part);
- break;
+ error = wd->atabus->ata_addref(wd->drvp);
+ if (error)
+ return error;
+
+ if ((wd->sc_flags & WDF_LOADED) == 0) {
+ int param_error;
+
+ /* Load the physical device parameters. */
+ param_error = wd_get_params(wd, AT_WAIT, &wd->sc_params);
+ if (param_error != 0) {
+ aprint_error_dev(dksc->sc_dev, "IDENTIFY failed\n");
+ error = EIO;
+ goto bad;
+ }
+ wd_set_geometry(wd);
+ wd->sc_flags |= WDF_LOADED;
}
- wd->sc_dk.dk_openmask =
- wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
- mutex_exit(&wd->sc_dk.dk_openlock);
return 0;
- bad2:
- if (wd->sc_dk.dk_openmask == 0)
- wd->atabus->ata_delref(wd->drvp);
- bad1:
- mutex_exit(&wd->sc_dk.dk_openlock);
+bad:
+ wd->atabus->ata_delref(wd->drvp);
return error;
}
@@ -1077,143 +1034,29 @@ wdopen(dev_t dev, int flag, int fmt, struct lwp *l)
* Caller must hold wd->sc_dk.dk_openlock.
*/
static int
-wdlastclose(device_t self)
+wd_lastclose(device_t self)
{
struct wd_softc *wd = device_private(self);
wd_flushcache(wd, AT_WAIT, false);
- if (! (wd->sc_flags & WDF_KLABEL))
- wd->sc_flags &= ~WDF_LOADED;
-
wd->atabus->ata_delref(wd->drvp);
return 0;
}
-int
+static int
wdclose(dev_t dev, int flag, int fmt, struct lwp *l)
{
- struct wd_softc *wd =
- device_lookup_private(&wd_cd, WDUNIT(dev));
- int part = WDPART(dev);
-
- ATADEBUG_PRINT(("wdclose\n"), DEBUG_FUNCS);
-
- mutex_enter(&wd->sc_dk.dk_openlock);
-
- switch (fmt) {
- case S_IFCHR:
- wd->sc_dk.dk_copenmask &= ~(1 << part);
- break;
- case S_IFBLK:
- wd->sc_dk.dk_bopenmask &= ~(1 << part);
- break;
- }
- wd->sc_dk.dk_openmask =
- wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
-
- if (wd->sc_dk.dk_openmask == 0)
- wdlastclose(wd->sc_dev);
-
- mutex_exit(&wd->sc_dk.dk_openlock);
- return 0;
-}
-
-void
-wdgetdefaultlabel(struct wd_softc *wd, struct disklabel *lp)
-{
-
- ATADEBUG_PRINT(("wdgetdefaultlabel\n"), DEBUG_FUNCS);
- memset(lp, 0, sizeof(struct disklabel));
-
- lp->d_secsize = wd->sc_blksize;
- lp->d_ntracks = wd->sc_params.atap_heads;
- lp->d_nsectors = wd->sc_params.atap_sectors;
- lp->d_ncylinders = (wd->sc_flags & WDF_LBA) ? wd->sc_capacity /
- (wd->sc_params.atap_heads * wd->sc_params.atap_sectors) :
- wd->sc_params.atap_cylinders;
- lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
-
- if (strcmp(wd->sc_params.atap_model, "ST506") == 0)
- lp->d_type = DKTYPE_ST506;
- else
- lp->d_type = DKTYPE_ESDI;
-
- strncpy(lp->d_typename, wd->sc_params.atap_model, 16);
- strncpy(lp->d_packname, "fictitious", 16);
- if (wd->sc_capacity > UINT32_MAX)
- lp->d_secperunit = UINT32_MAX;
- else
- lp->d_secperunit = wd->sc_capacity;
- lp->d_rpm = 3600;
- lp->d_interleave = 1;
- lp->d_flags = 0;
-
- lp->d_partitions[RAW_PART].p_offset = 0;
- lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
- lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
- lp->d_npartitions = RAW_PART + 1;
-
- lp->d_magic = DISKMAGIC;
- lp->d_magic2 = DISKMAGIC;
- lp->d_checksum = dkcksum(lp);
-}
-
-/*
- * Fabricate a default disk label, and try to read the correct one.
- */
-void
-wdgetdisklabel(struct wd_softc *wd)
-{
- struct disklabel *lp = wd->sc_dk.dk_label;
- const char *errstring;
-
- ATADEBUG_PRINT(("wdgetdisklabel\n"), DEBUG_FUNCS);
-
- memset(wd->sc_dk.dk_cpulabel, 0, sizeof(struct cpu_disklabel));
-
- wdgetdefaultlabel(wd, lp);
-
- wd->drvp->badsect[0] = -1;
+ struct wd_softc *wd;
+ struct dk_softc *dksc;
+ int unit;
- if (wd->drvp->state > RESET) {
- mutex_enter(&wd->sc_lock);
- wd->drvp->drive_flags |= ATA_DRIVE_RESET;
- mutex_exit(&wd->sc_lock);
- }
- errstring = readdisklabel(MAKEWDDEV(0, device_unit(wd->sc_dev),
- RAW_PART), wdstrategy, lp,
- wd->sc_dk.dk_cpulabel);
- if (errstring) {
- /*
- * This probably happened because the drive's default
- * geometry doesn't match the DOS geometry. We
- * assume the DOS geometry is now in the label and try
- * again. XXX This is a kluge.
- */
- if (wd->drvp->state > RESET) {
- mutex_enter(&wd->sc_lock);
- wd->drvp->drive_flags |= ATA_DRIVE_RESET;
- mutex_exit(&wd->sc_lock);
- }
- errstring = readdisklabel(MAKEWDDEV(0, device_unit(wd->sc_dev),
- RAW_PART), wdstrategy, lp, wd->sc_dk.dk_cpulabel);
- }
- if (errstring) {
- aprint_error_dev(wd->sc_dev, "%s\n", errstring);
- return;
- }
+ unit = WDUNIT(dev);
+ wd = device_lookup_private(&wd_cd, unit);
+ dksc = &wd->sc_dksc;
- if (wd->drvp->state > RESET) {
- mutex_enter(&wd->sc_lock);
- wd->drvp->drive_flags |= ATA_DRIVE_RESET;
- mutex_exit(&wd->sc_lock);
- }
-#ifdef HAS_BAD144_HANDLING
- if ((lp->d_flags & D_BADSECT) != 0)
- bad144intern(wd);
-#endif
+ return dk_close(dksc, dev, flag, fmt, l);
}
void
@@ -1232,7 +1075,8 @@ wdperror(const struct wd_softc *wd, struct ata_xfer *xfer)
int i;
const char *sep = "";
- const char *devname = device_xname(wd->sc_dev);
+ const struct dk_softc *dksc = &wd->sc_dksc;
+ const char *devname = dksc->sc_xname;
struct ata_drive_datas *drvp = wd->drvp;
int errno = xfer->c_bio.r_error;
@@ -1256,32 +1100,24 @@ wdperror(const struct wd_softc *wd, struct ata_xfer *xfer)
}
int
-wdioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l)
+wdioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
{
struct wd_softc *wd =
device_lookup_private(&wd_cd, WDUNIT(dev));
- int error;
-#ifdef __HAVE_OLD_DISKLABEL
- struct disklabel *newlabel = NULL;
-#endif
+ struct dk_softc *dksc = &wd->sc_dksc;
ATADEBUG_PRINT(("wdioctl\n"), DEBUG_FUNCS);
if ((wd->sc_flags & WDF_LOADED) == 0)
return EIO;
- error = disk_ioctl(&wd->sc_dk, dev, xfer, addr, flag, l);
- if (error != EPASSTHROUGH)
- return error;
-
- error = 0;
- switch (xfer) {
+ switch (cmd) {
#ifdef HAS_BAD144_HANDLING
case DIOCSBAD:
if ((flag & FWRITE) == 0)
return EBADF;
- wd->sc_dk.dk_cpulabel->bad = *(struct dkbad *)addr;
- wd->sc_dk.dk_label->d_flags |= D_BADSECT;
+ dksc->sc_dkdev.dk_cpulabel->bad = *(struct dkbad *)addr;
+ dksc->sc_dkdev.dk_label->d_flags |= D_BADSECT;
bad144intern(wd);
return 0;
#endif
@@ -1341,94 +1177,6 @@ wdioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l)
return 0;
#endif
- case DIOCWDINFO:
- case DIOCSDINFO:
-#ifdef __HAVE_OLD_DISKLABEL
- case ODIOCWDINFO:
- case ODIOCSDINFO:
-#endif
- {
- struct disklabel *lp;
-
- if ((flag & FWRITE) == 0)
- return EBADF;
-
-#ifdef __HAVE_OLD_DISKLABEL
- if (xfer == ODIOCSDINFO || xfer == ODIOCWDINFO) {
- newlabel = malloc(sizeof *newlabel, M_TEMP,
- M_WAITOK | M_ZERO);
- if (newlabel == NULL)
- return EIO;
- memcpy(newlabel, addr, sizeof (struct olddisklabel));
- lp = newlabel;
- } else
-#endif
- lp = (struct disklabel *)addr;
-
- mutex_enter(&wd->sc_dk.dk_openlock);
- wd->sc_flags |= WDF_LABELLING;
-
- error = setdisklabel(wd->sc_dk.dk_label,
- lp, /*wd->sc_dk.dk_openmask : */0,
- wd->sc_dk.dk_cpulabel);
- if (error == 0) {
- if (wd->drvp->state > RESET) {
- mutex_enter(&wd->sc_lock);
- wd->drvp->drive_flags |= ATA_DRIVE_RESET;
- mutex_exit(&wd->sc_lock);
- }
- if (xfer == DIOCWDINFO
-#ifdef __HAVE_OLD_DISKLABEL
- || xfer == ODIOCWDINFO
-#endif
- )
- error = writedisklabel(WDLABELDEV(dev),
- wdstrategy, wd->sc_dk.dk_label,
- wd->sc_dk.dk_cpulabel);
- }
-
- wd->sc_flags &= ~WDF_LABELLING;
- mutex_exit(&wd->sc_dk.dk_openlock);
-#ifdef __HAVE_OLD_DISKLABEL
- if (newlabel != NULL)
- free(newlabel, M_TEMP);
-#endif
- return error;
- }
-
- case DIOCKLABEL:
- if (*(int *)addr)
- wd->sc_flags |= WDF_KLABEL;
- else
- wd->sc_flags &= ~WDF_KLABEL;
- return 0;
-
- case DIOCWLABEL:
- if ((flag & FWRITE) == 0)
- return EBADF;
- if (*(int *)addr)
- wd->sc_flags |= WDF_WLABEL;
- else
- wd->sc_flags &= ~WDF_WLABEL;
- return 0;
-
- case DIOCGDEFLABEL:
- wdgetdefaultlabel(wd, (struct disklabel *)addr);
- return 0;
-#ifdef __HAVE_OLD_DISKLABEL
- case ODIOCGDEFLABEL:
- newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK);
- if (newlabel == NULL)
- return EIO;
- wdgetdefaultlabel(wd, newlabel);
- if (newlabel->d_npartitions <= OLDMAXPARTITIONS)
- memcpy(addr, &newlabel, sizeof (struct olddisklabel));
- else
- error = ENOTTY;
- free(newlabel, M_TEMP);
- return error;
-#endif
-
#ifdef notyet
case DIOCWFORMAT:
if ((flag & FWRITE) == 0)
@@ -1437,6 +1185,7 @@ wdioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l)
register struct format_op *fop;
struct iovec aiov;
struct uio auio;
+ int error1;
fop = (struct format_op *)addr;
aiov.iov_base = fop->df_buf;
@@ -1447,12 +1196,12 @@ wdioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l)
auio.uio_offset =
fop->df_startblk * wd->sc_dk.dk_label->d_secsize;
auio.uio_vmspace = l->l_proc->p_vmspace;
- error = physio(wdformat, NULL, dev, B_WRITE, wdminphys,
+ error1 = physio(wdformat, NULL, dev, B_WRITE, wdminphys,
&auio);
fop->df_count -= auio.uio_resid;
fop->df_reg[0] = wdc->sc_status;
fop->df_reg[1] = wdc->sc_error;
- return error;
+ return error1;
}
#endif
case DIOCGCACHE:
@@ -1524,49 +1273,8 @@ wdioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l)
return(error1);
}
- case DIOCGSTRATEGY:
- {
- struct disk_strategy *dks = (void *)addr;
-
- mutex_enter(&wd->sc_lock);
- strlcpy(dks->dks_name, bufq_getstrategyname(wd->sc_q),
- sizeof(dks->dks_name));
- mutex_exit(&wd->sc_lock);
- dks->dks_paramlen = 0;
-
- return 0;
- }
-
- case DIOCSSTRATEGY:
- {
- struct disk_strategy *dks = (void *)addr;
- struct bufq_state *new;
- struct bufq_state *old;
-
- if ((flag & FWRITE) == 0) {
- return EBADF;
- }
- if (dks->dks_param != NULL) {
- return EINVAL;
- }
- dks->dks_name[sizeof(dks->dks_name) - 1] = 0; /* ensure term */
- error = bufq_alloc(&new, dks->dks_name,
- BUFQ_EXACT|BUFQ_SORT_RAWBLOCK);
- if (error) {
- return error;
- }
- mutex_enter(&wd->sc_lock);
- old = wd->sc_q;
- bufq_move(new, old);
- wd->sc_q = new;
- mutex_exit(&wd->sc_lock);
- bufq_free(old);
-
- return 0;
- }
-
default:
- return ENOTTY;
+ return dk_ioctl(dksc, dev, cmd, addr, flag, l);
}
#ifdef DIAGNOSTIC
@@ -1575,9 +1283,9 @@ wdioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l)
}
static int
-wddiscard(dev_t dev, off_t pos, off_t len)
+wd_discard(device_t dev, off_t pos, off_t len)
{
- struct wd_softc *wd = device_lookup_private(&wd_cd, WDUNIT(dev));
+ struct wd_softc *wd = device_private(dev);
daddr_t bno;
long size, done;
long maxatonce, amount;
@@ -1606,7 +1314,7 @@ wddiscard(dev_t dev, off_t pos, off_t len)
if (amount > maxatonce) {
amount = maxatonce;
}
- result = wd_trim(wd, WDPART(dev), bno + done, amount);
+ result = wd_trim(wd, bno + done, amount);
if (result) {
return result;
}
@@ -1615,6 +1323,20 @@ wddiscard(dev_t dev, off_t pos, off_t len)
return 0;
}
+static int
+wddiscard(dev_t dev, off_t pos, off_t len)
+{
+ struct wd_softc *wd;
+ struct dk_softc *dksc;
+ int unit;
+
+ unit = WDUNIT(dev);
+ wd = device_lookup_private(&wd_cd, unit);
+ dksc = &wd->sc_dksc;
+
+ return dk_discard(dksc, dev, pos, len);
+}
+
#ifdef B_FORMAT
int
wdformat(struct buf *bp)
@@ -1629,66 +1351,55 @@ int
wdsize(dev_t dev)
{
struct wd_softc *wd;
- int part, omask;
- int size;
+ struct dk_softc *dksc;
+ int unit;
ATADEBUG_PRINT(("wdsize\n"), DEBUG_FUNCS);
- wd = device_lookup_private(&wd_cd, WDUNIT(dev));
+ unit = WDUNIT(dev);
+ wd = device_lookup_private(&wd_cd, unit);
if (wd == NULL)
return (-1);
+ dksc = &wd->sc_dksc;
- part = WDPART(dev);
- omask = wd->sc_dk.dk_openmask & (1 << part);
-
- if (omask == 0 && wdopen(dev, 0, S_IFBLK, NULL) != 0)
- return (-1);
- if (wd->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
- size = -1;
- else
- size = wd->sc_dk.dk_label->d_partitions[part].p_size *
- (wd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
- if (omask == 0 && wdclose(dev, 0, S_IFBLK, NULL) != 0)
+ if (!device_is_active(dksc->sc_dev))
return (-1);
- return (size);
+
+ return dk_size(dksc, dev);
}
/*
* Dump core after a system crash.
*/
-int
+static int
wddump(dev_t dev, daddr_t blkno, void *va, size_t size)
{
- struct wd_softc *wd; /* disk unit to do the I/O */
- struct disklabel *lp; /* disk's disklabel */
- int part, err;
- int nblks; /* total number of sectors left to write */
- struct ata_xfer *xfer;
+ struct wd_softc *wd;
+ struct dk_softc *dksc;
+ int unit;
/* Check if recursive dump; if so, punt. */
if (wddoingadump)
return EFAULT;
wddoingadump = 1;
- wd = device_lookup_private(&wd_cd, WDUNIT(dev));
+ unit = WDUNIT(dev);
+ wd = device_lookup_private(&wd_cd, unit);
if (wd == NULL)
return (ENXIO);
+ dksc = &wd->sc_dksc;
- part = WDPART(dev);
-
- /* Convert to disk sectors. Request must be a multiple of size. */
- lp = wd->sc_dk.dk_label;
- if ((size % lp->d_secsize) != 0)
- return EFAULT;
- nblks = size / lp->d_secsize;
- blkno = blkno / (lp->d_secsize / DEV_BSIZE);
-
- /* Check transfer bounds against partition size. */
- if ((blkno < 0) || ((blkno + nblks) > lp->d_partitions[part].p_size))
- return EINVAL;
+ return dk_dump(dksc, dev, blkno, va, size);
+}
- /* Offset block number to start of partition. */
- blkno += lp->d_partitions[part].p_offset;
+static int
+wd_dumpblocks(device_t dev, void *va, daddr_t blkno, int nblk)
+{
+ struct wd_softc *wd = device_private(dev);
+ struct dk_softc *dksc = &wd->sc_dksc;
+ struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
+ struct ata_xfer *xfer;
+ int err;
/* Recalibrate, if first dump transfer. */
if (wddumprecalibrated == 0) {
@@ -1707,11 +1418,11 @@ wddump(dev_t dev, daddr_t blkno, void *va, size_t size)
xfer->c_bio.blkno = blkno;
xfer->c_bio.flags = ATA_POLL;
if (wd->sc_flags & WDF_LBA48 &&
- (xfer->c_bio.blkno + nblks) > wd->sc_capacity28)
+ (xfer->c_bio.blkno + nblk) > wd->sc_capacity28)
xfer->c_bio.flags |= ATA_LBA48;
if (wd->sc_flags & WDF_LBA)
xfer->c_bio.flags |= ATA_LBA;
- xfer->c_bio.bcount = nblks * lp->d_secsize;
+ xfer->c_bio.bcount = nblk * dg->dg_secsize;
xfer->c_bio.databuf = va;
#ifndef WD_DUMP_NOT_TRUSTED
switch (err = wd->atabus->ata_bio(wd->drvp, xfer)) {
@@ -1773,8 +1484,9 @@ wddump(dev_t dev, daddr_t blkno, void *va, size_t size)
void
bad144intern(struct wd_softc *wd)
{
- struct dkbad *bt = &wd->sc_dk.dk_cpulabel->bad;
- struct disklabel *lp = wd->sc_dk.dk_label;
+ struct dk_softc *dksc = &wd->sc_dksc;
+ struct dkbad *bt = &dksc->sc_dkdev.dk_cpulabel->bad;
+ struct disklabel *lp = dksc->sc_dkdev.dk_label;
int i = 0;
ATADEBUG_PRINT(("bad144intern\n"), DEBUG_XFERS);
@@ -1793,9 +1505,10 @@ bad144intern(struct wd_softc *wd)
#endif
static void
-wd_params_to_properties(struct wd_softc *wd)
+wd_set_geometry(struct wd_softc *wd)
{
- struct disk_geom *dg = &wd->sc_dk.dk_geom;
+ struct dk_softc *dksc = &wd->sc_dksc;
+ struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
memset(dg, 0, sizeof(*dg));
@@ -1806,11 +1519,7 @@ wd_params_to_properties(struct wd_softc *wd)
if ((wd->sc_flags & WDF_LBA) == 0)
dg->dg_ncylinders = wd->sc_params.atap_cylinders;
- /* XXX Should have a case for ATA here, too. */
- const char *cp = strcmp(wd->sc_params.atap_model, "ST506") ?
- "ST506" : "ESDI";
-
- disk_set_info(wd->sc_dev, &wd->sc_dk, cp);
+ disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL);
}
int
@@ -1874,6 +1583,7 @@ const char at_errbits[] = "\20\10ERROR\11TIMEOU\12DF";
int
wd_setcache(struct wd_softc *wd, int bits)
{
+ struct dk_softc *dksc = &wd->sc_dksc;
struct ataparams params;
struct ata_xfer *xfer;
int error;
@@ -1904,7 +1614,7 @@ wd_setcache(struct wd_softc *wd, int bits)
else
xfer->c_ata_c.r_features = WDSF_WRITE_CACHE_DS;
if (wd->atabus->ata_exec_command(wd->drvp, xfer) != ATACMD_COMPLETE) {
- aprint_error_dev(wd->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"wd_setcache command not complete\n");
error = EIO;
goto out;
@@ -1913,7 +1623,7 @@ wd_setcache(struct wd_softc *wd, int bits)
if (xfer->c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
char sbuf[sizeof(at_errbits) + 64];
snprintb(sbuf, sizeof(sbuf), at_errbits, xfer->c_ata_c.flags);
- aprint_error_dev(wd->sc_dev, "wd_setcache: status=%s\n", sbuf);
+ aprint_error_dev(dksc->sc_dev, "wd_setcache: status=%s\n", sbuf);
error = EIO;
goto out;
}
@@ -1929,6 +1639,7 @@ out:
static int
wd_standby(struct wd_softc *wd, int flags)
{
+ struct dk_softc *dksc = &wd->sc_dksc;
struct ata_xfer *xfer;
int error;
@@ -1942,7 +1653,7 @@ wd_standby(struct wd_softc *wd, int flags)
xfer->c_ata_c.flags = flags;
xfer->c_ata_c.timeout = 30000; /* 30s timeout */
if (wd->atabus->ata_exec_command(wd->drvp, xfer) != ATACMD_COMPLETE) {
- aprint_error_dev(wd->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"standby immediate command didn't complete\n");
error = EIO;
goto out;
@@ -1957,7 +1668,7 @@ wd_standby(struct wd_softc *wd, int flags)
if (xfer->c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
char sbuf[sizeof(at_errbits) + 64];
snprintb(sbuf, sizeof(sbuf), at_errbits, xfer->c_ata_c.flags);
- aprint_error_dev(wd->sc_dev, "wd_standby: status=%s\n", sbuf);
+ aprint_error_dev(dksc->sc_dev, "wd_standby: status=%s\n", sbuf);
error = EIO;
goto out;
}
@@ -1972,6 +1683,7 @@ out:
int
wd_flushcache(struct wd_softc *wd, int flags, bool start)
{
+ struct dk_softc *dksc = &wd->sc_dksc;
struct ata_xfer *xfer;
int error;
@@ -2010,7 +1722,7 @@ wd_flushcache(struct wd_softc *wd, int flags, bool start)
xfer->c_ata_c.flags = flags | AT_READREG;
xfer->c_ata_c.timeout = 300000; /* 5m timeout */
if (wd->atabus->ata_exec_command(wd->drvp, xfer) != ATACMD_COMPLETE) {
- aprint_error_dev(wd->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"flush cache command didn't complete\n");
error = EIO;
goto out_xfer;
@@ -2025,7 +1737,7 @@ wd_flushcache(struct wd_softc *wd, int flags, bool start)
if (xfer->c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
char sbuf[sizeof(at_errbits) + 64];
snprintb(sbuf, sizeof(sbuf), at_errbits, xfer->c_ata_c.flags);
- aprint_error_dev(wd->sc_dev, "wd_flushcache: status=%s\n",
+ aprint_error_dev(dksc->sc_dev, "wd_flushcache: status=%s\n",
sbuf);
error = EIO;
goto out_xfer;
@@ -2043,16 +1755,14 @@ out:
return error;
}
-int
-wd_trim(struct wd_softc *wd, int part, daddr_t bno, long size)
+static int
+wd_trim(struct wd_softc *wd, daddr_t bno, long size)
{
+ struct dk_softc *dksc = &wd->sc_dksc;
struct ata_xfer *xfer;
int error;
unsigned char *req;
- if (part != RAW_PART)
- bno += wd->sc_dk.dk_label->d_partitions[part].p_offset;;
-
xfer = ata_get_xfer(wd->drvp->chnl_softc);
if (xfer == NULL)
return EINTR;
@@ -2077,7 +1787,7 @@ wd_trim(struct wd_softc *wd, int part, daddr_t bno, long size)
xfer->c_ata_c.bcount = 512;
xfer->c_ata_c.flags |= AT_WRITE | AT_WAIT;
if (wd->atabus->ata_exec_command(wd->drvp, xfer) != ATACMD_COMPLETE) {
- aprint_error_dev(wd->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"trim command didn't complete\n");
kmem_free(req, 512);
error = EIO;
@@ -2094,7 +1804,7 @@ wd_trim(struct wd_softc *wd, int part, daddr_t bno, long size)
if (xfer->c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
char sbuf[sizeof(at_errbits) + 64];
snprintb(sbuf, sizeof(sbuf), at_errbits, xfer->c_ata_c.flags);
- aprint_error_dev(wd->sc_dev, "wd_trim: status=%s\n",
+ aprint_error_dev(dksc->sc_dev, "wd_trim: status=%s\n",
sbuf);
error = EIO;
goto out;
@@ -2326,18 +2036,19 @@ out2:
static void
wd_sysctl_attach(struct wd_softc *wd)
{
+ struct dk_softc *dksc = &wd->sc_dksc;
const struct sysctlnode *node;
int error;
/* sysctl set-up */
if (sysctl_createv(&wd->nodelog, 0, NULL, &node,
- 0, CTLTYPE_NODE, device_xname(wd->sc_dev),
+ 0, CTLTYPE_NODE, dksc->sc_xname,
SYSCTL_DESCR("wd driver settings"),
NULL, 0, NULL, 0,
CTL_HW, CTL_CREATE, CTL_EOL) != 0) {
- aprint_error_dev(wd->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"could not create %s.%s sysctl node\n",
- "hw", device_xname(wd->sc_dev));
+ "hw", dksc->sc_xname);
return;
}
@@ -2348,9 +2059,9 @@ wd_sysctl_attach(struct wd_softc *wd)
NULL, 0, &wd->drv_max_tags, 0,
CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
!= 0) {
- aprint_error_dev(wd->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"could not create %s.%s.max_tags sysctl - error %d\n",
- "hw", device_xname(wd->sc_dev), error);
+ "hw", dksc->sc_xname, error);
return;
}
@@ -2361,9 +2072,9 @@ wd_sysctl_attach(struct wd_softc *wd)
NULL, 0, &wd->drv_ncq, 0,
CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
!= 0) {
- aprint_error_dev(wd->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"could not create %s.%s.use_ncq sysctl - error %d\n",
- "hw", device_xname(wd->sc_dev), error);
+ "hw", dksc->sc_xname, error);
return;
}
@@ -2374,9 +2085,9 @@ wd_sysctl_attach(struct wd_softc *wd)
NULL, 0, &wd->drv_ncq_prio, 0,
CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
!= 0) {
- aprint_error_dev(wd->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"could not create %s.%s.use_ncq_prio sysctl - error %d\n",
- "hw", device_xname(wd->sc_dev), error);
+ "hw", dksc->sc_xname, error);
return;
}
@@ -2388,9 +2099,9 @@ wd_sysctl_attach(struct wd_softc *wd)
NULL, 0, &wd->drv_chaos_freq, 0,
CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
!= 0) {
- aprint_error_dev(wd->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"could not create %s.%s.chaos_freq sysctl - error %d\n",
- "hw", device_xname(wd->sc_dev), error);
+ "hw", dksc->sc_xname, error);
return;
}
@@ -2401,9 +2112,9 @@ wd_sysctl_attach(struct wd_softc *wd)
NULL, 0, &wd->drv_chaos_cnt, 0,
CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
!= 0) {
- aprint_error_dev(wd->sc_dev,
+ aprint_error_dev(dksc->sc_dev,
"could not create %s.%s.chaos_cnt sysctl - error %d\n",
- "hw", device_xname(wd->sc_dev), error);
+ "hw", dksc->sc_xname, error);
return;
}
#endif
diff --git a/sys/dev/ata/wdvar.h b/sys/dev/ata/wdvar.h
index 0062794368c..1a410d86fb6 100644
--- a/sys/dev/ata/wdvar.h
+++ b/sys/dev/ata/wdvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: wdvar.h,v 1.44 2017/10/07 16:05:32 jdolecek Exp $ */
+/* $NetBSD: wdvar.h,v 1.45 2017/11/01 19:34:46 mlelstv Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -31,14 +31,12 @@
#include "opt_wd.h"
#endif
-#include <sys/rndsource.h>
+#include <dev/dkvar.h>
#include <sys/sysctl.h>
struct wd_softc {
/* General disk infos */
- device_t sc_dev;
- struct disk sc_dk;
- struct bufq_state *sc_q;
+ struct dk_softc sc_dksc;
kmutex_t sc_lock;
int sc_quirks; /* any quirks drive might have */
@@ -47,8 +45,6 @@ struct wd_softc {
const struct ata_bustype *atabus;
struct ataparams sc_params;/* drive characteristics found */
int sc_flags;
-#define WDF_WLABEL 0x004 /* label is writable */
-#define WDF_LABELLING 0x008 /* writing label */
/*
* XXX Nothing resets this yet, but disk change sensing will when ATA-4 is
* more fully implemented.
@@ -56,7 +52,6 @@ struct wd_softc {
#define WDF_LOADED 0x010 /* parameters loaded */
#define WDF_WAIT 0x020 /* waiting for resources */
#define WDF_LBA 0x040 /* using LBA mode */
-#define WDF_KLABEL 0x080 /* retain label after 'full' close */
#define WDF_LBA48 0x100 /* using 48-bit LBA mode */
#define WDF_FLUSH_PEND 0x200 /* cache flush waits for free xfer */
uint64_t sc_capacity; /* full capacity of the device */
@@ -68,7 +63,6 @@ struct wd_softc {
SLIST_HEAD(, disk_badsectors) sc_bslist;
u_int sc_bscount;
#endif
- krndsource_t rnd_source;
/* Sysctl nodes specific for the disk */
struct sysctllog *nodelog;
diff --git a/sys/dev/files.dev b/sys/dev/files.dev
index d900e2aa2f0..f187877d893 100644
--- a/sys/dev/files.dev
+++ b/sys/dev/files.dev
@@ -1,4 +1,4 @@
-# $NetBSD: files.dev,v 1.3 2017/02/26 11:56:49 rin Exp $
+# $NetBSD: files.dev,v 1.4 2017/11/01 19:34:45 mlelstv Exp $
file dev/bio.c bio needs-flag
file dev/ccd.c ccd
@@ -6,7 +6,7 @@ file dev/cgd.c cgd
file dev/cgd_crypto.c cgd
file dev/clock_subr.c kern # XXX
file dev/clockctl.c clockctl
-file dev/dksubr.c cgd | xbd | ccd | raid | dm | ld | sd | cd
+file dev/dksubr.c cgd | xbd | ccd | raid | dm | ld | sd | cd | wd
file dev/dkwedge/dk.c kern # XXX
file dev/dkwedge/dkwedge_apple.c dkwedge_method_apple
file dev/dkwedge/dkwedge_bsdlabel.c dkwedge_method_bsdlabel