Sat Jul 30 04:42:04 2011 UTC ()
Add some additional consistency checking paranoia with KASSERT.


(jakllsch)
diff -r1.386 -r1.387 src/sys/dev/ata/wd.c

cvs diff -r1.386 -r1.387 src/sys/dev/ata/wd.c (switch to unified diff)

--- src/sys/dev/ata/wd.c 2011/02/10 05:07:46 1.386
+++ src/sys/dev/ata/wd.c 2011/07/30 04:42:03 1.387
@@ -1,1830 +1,1833 @@ @@ -1,1830 +1,1833 @@
1/* $NetBSD: wd.c,v 1.386 2011/02/10 05:07:46 enami Exp $ */ 1/* $NetBSD: wd.c,v 1.387 2011/07/30 04:42:03 jakllsch Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. 4 * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27/*- 27/*-
28 * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc. 28 * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc.
29 * All rights reserved. 29 * All rights reserved.
30 * 30 *
31 * This code is derived from software contributed to The NetBSD Foundation 31 * This code is derived from software contributed to The NetBSD Foundation
32 * by Charles M. Hannum and by Onno van der Linden. 32 * by Charles M. Hannum and by Onno van der Linden.
33 * 33 *
34 * Redistribution and use in source and binary forms, with or without 34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions 35 * modification, are permitted provided that the following conditions
36 * are met: 36 * are met:
37 * 1. Redistributions of source code must retain the above copyright 37 * 1. Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer. 38 * notice, this list of conditions and the following disclaimer.
39 * 2. Redistributions in binary form must reproduce the above copyright 39 * 2. Redistributions in binary form must reproduce the above copyright
40 * notice, this list of conditions and the following disclaimer in the 40 * notice, this list of conditions and the following disclaimer in the
41 * documentation and/or other materials provided with the distribution. 41 * documentation and/or other materials provided with the distribution.
42 * 42 *
43 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 43 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
44 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 44 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
45 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 45 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
46 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 46 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
47 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 47 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
48 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 48 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
49 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 49 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
50 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 50 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
51 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 51 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
52 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 52 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
53 * POSSIBILITY OF SUCH DAMAGE. 53 * POSSIBILITY OF SUCH DAMAGE.
54 */ 54 */
55 55
56#include <sys/cdefs.h> 56#include <sys/cdefs.h>
57__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.386 2011/02/10 05:07:46 enami Exp $"); 57__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.387 2011/07/30 04:42:03 jakllsch Exp $");
58 58
59#include "opt_ata.h" 59#include "opt_ata.h"
60 60
61#include "rnd.h" 61#include "rnd.h"
62 62
63#include <sys/param.h> 63#include <sys/param.h>
64#include <sys/systm.h> 64#include <sys/systm.h>
65#include <sys/kernel.h> 65#include <sys/kernel.h>
66#include <sys/conf.h> 66#include <sys/conf.h>
67#include <sys/file.h> 67#include <sys/file.h>
68#include <sys/stat.h> 68#include <sys/stat.h>
69#include <sys/ioctl.h> 69#include <sys/ioctl.h>
70#include <sys/buf.h> 70#include <sys/buf.h>
71#include <sys/bufq.h> 71#include <sys/bufq.h>
72#include <sys/uio.h> 72#include <sys/uio.h>
73#include <sys/malloc.h> 73#include <sys/malloc.h>
74#include <sys/device.h> 74#include <sys/device.h>
75#include <sys/disklabel.h> 75#include <sys/disklabel.h>
76#include <sys/disk.h> 76#include <sys/disk.h>
77#include <sys/syslog.h> 77#include <sys/syslog.h>
78#include <sys/proc.h> 78#include <sys/proc.h>
79#include <sys/reboot.h> 79#include <sys/reboot.h>
80#include <sys/vnode.h> 80#include <sys/vnode.h>
81#if NRND > 0 81#if NRND > 0
82#include <sys/rnd.h> 82#include <sys/rnd.h>
83#endif 83#endif
84 84
85#include <sys/intr.h> 85#include <sys/intr.h>
86#include <sys/bus.h> 86#include <sys/bus.h>
87 87
88#include <dev/ata/atareg.h> 88#include <dev/ata/atareg.h>
89#include <dev/ata/atavar.h> 89#include <dev/ata/atavar.h>
90#include <dev/ata/wdvar.h> 90#include <dev/ata/wdvar.h>
91#include <dev/ic/wdcreg.h> 91#include <dev/ic/wdcreg.h>
92#include <sys/ataio.h> 92#include <sys/ataio.h>
93#include "locators.h" 93#include "locators.h"
94 94
95#include <prop/proplib.h> 95#include <prop/proplib.h>
96 96
97#define WDIORETRIES_SINGLE 4 /* number of retries before single-sector */ 97#define WDIORETRIES_SINGLE 4 /* number of retries before single-sector */
98#define WDIORETRIES 5 /* number of retries before giving up */ 98#define WDIORETRIES 5 /* number of retries before giving up */
99#define RECOVERYTIME hz/2 /* time to wait before retrying a cmd */ 99#define RECOVERYTIME hz/2 /* time to wait before retrying a cmd */
100 100
101#define WDUNIT(dev) DISKUNIT(dev) 101#define WDUNIT(dev) DISKUNIT(dev)
102#define WDPART(dev) DISKPART(dev) 102#define WDPART(dev) DISKPART(dev)
103#define WDMINOR(unit, part) DISKMINOR(unit, part) 103#define WDMINOR(unit, part) DISKMINOR(unit, part)
104#define MAKEWDDEV(maj, unit, part) MAKEDISKDEV(maj, unit, part) 104#define MAKEWDDEV(maj, unit, part) MAKEDISKDEV(maj, unit, part)
105 105
106#define WDLABELDEV(dev) (MAKEWDDEV(major(dev), WDUNIT(dev), RAW_PART)) 106#define WDLABELDEV(dev) (MAKEWDDEV(major(dev), WDUNIT(dev), RAW_PART))
107 107
108#define DEBUG_INTR 0x01 108#define DEBUG_INTR 0x01
109#define DEBUG_XFERS 0x02 109#define DEBUG_XFERS 0x02
110#define DEBUG_STATUS 0x04 110#define DEBUG_STATUS 0x04
111#define DEBUG_FUNCS 0x08 111#define DEBUG_FUNCS 0x08
112#define DEBUG_PROBE 0x10 112#define DEBUG_PROBE 0x10
113#ifdef ATADEBUG 113#ifdef ATADEBUG
114int wdcdebug_wd_mask = 0x0; 114int wdcdebug_wd_mask = 0x0;
115#define ATADEBUG_PRINT(args, level) \ 115#define ATADEBUG_PRINT(args, level) \
116 if (wdcdebug_wd_mask & (level)) \ 116 if (wdcdebug_wd_mask & (level)) \
117 printf args 117 printf args
118#else 118#else
119#define ATADEBUG_PRINT(args, level) 119#define ATADEBUG_PRINT(args, level)
120#endif 120#endif
121 121
122int wdprobe(device_t, cfdata_t, void *); 122int wdprobe(device_t, cfdata_t, void *);
123void wdattach(device_t, device_t, void *); 123void wdattach(device_t, device_t, void *);
124int wddetach(device_t, int); 124int wddetach(device_t, int);
125int wdprint(void *, char *); 125int wdprint(void *, char *);
126void wdperror(const struct wd_softc *); 126void wdperror(const struct wd_softc *);
127 127
128static int wdlastclose(device_t); 128static int wdlastclose(device_t);
129static bool wd_suspend(device_t, const pmf_qual_t *); 129static bool wd_suspend(device_t, const pmf_qual_t *);
130static int wd_standby(struct wd_softc *, int); 130static int wd_standby(struct wd_softc *, int);
131 131
132CFATTACH_DECL3_NEW(wd, sizeof(struct wd_softc), 132CFATTACH_DECL3_NEW(wd, sizeof(struct wd_softc),
133 wdprobe, wdattach, wddetach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN); 133 wdprobe, wdattach, wddetach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
134 134
135extern struct cfdriver wd_cd; 135extern struct cfdriver wd_cd;
136 136
137dev_type_open(wdopen); 137dev_type_open(wdopen);
138dev_type_close(wdclose); 138dev_type_close(wdclose);
139dev_type_read(wdread); 139dev_type_read(wdread);
140dev_type_write(wdwrite); 140dev_type_write(wdwrite);
141dev_type_ioctl(wdioctl); 141dev_type_ioctl(wdioctl);
142dev_type_strategy(wdstrategy); 142dev_type_strategy(wdstrategy);
143dev_type_dump(wddump); 143dev_type_dump(wddump);
144dev_type_size(wdsize); 144dev_type_size(wdsize);
145 145
146const struct bdevsw wd_bdevsw = { 146const struct bdevsw wd_bdevsw = {
147 wdopen, wdclose, wdstrategy, wdioctl, wddump, wdsize, D_DISK 147 wdopen, wdclose, wdstrategy, wdioctl, wddump, wdsize, D_DISK
148}; 148};
149 149
150const struct cdevsw wd_cdevsw = { 150const struct cdevsw wd_cdevsw = {
151 wdopen, wdclose, wdread, wdwrite, wdioctl, 151 wdopen, wdclose, wdread, wdwrite, wdioctl,
152 nostop, notty, nopoll, nommap, nokqfilter, D_DISK 152 nostop, notty, nopoll, nommap, nokqfilter, D_DISK
153}; 153};
154 154
155/* 155/*
156 * Glue necessary to hook WDCIOCCOMMAND into physio 156 * Glue necessary to hook WDCIOCCOMMAND into physio
157 */ 157 */
158 158
159struct wd_ioctl { 159struct wd_ioctl {
160 LIST_ENTRY(wd_ioctl) wi_list; 160 LIST_ENTRY(wd_ioctl) wi_list;
161 struct buf wi_bp; 161 struct buf wi_bp;
162 struct uio wi_uio; 162 struct uio wi_uio;
163 struct iovec wi_iov; 163 struct iovec wi_iov;
164 atareq_t wi_atareq; 164 atareq_t wi_atareq;
165 struct wd_softc *wi_softc; 165 struct wd_softc *wi_softc;
166}; 166};
167 167
168LIST_HEAD(, wd_ioctl) wi_head; 168LIST_HEAD(, wd_ioctl) wi_head;
169 169
170struct wd_ioctl *wi_find(struct buf *); 170struct wd_ioctl *wi_find(struct buf *);
171void wi_free(struct wd_ioctl *); 171void wi_free(struct wd_ioctl *);
172struct wd_ioctl *wi_get(void); 172struct wd_ioctl *wi_get(void);
173void wdioctlstrategy(struct buf *); 173void wdioctlstrategy(struct buf *);
174 174
175void wdgetdefaultlabel(struct wd_softc *, struct disklabel *); 175void wdgetdefaultlabel(struct wd_softc *, struct disklabel *);
176void wdgetdisklabel(struct wd_softc *); 176void wdgetdisklabel(struct wd_softc *);
177void wdstart(void *); 177void wdstart(void *);
178void wdstart1(struct wd_softc*, struct buf *); 178void wdstart1(struct wd_softc*, struct buf *);
179void wdrestart(void *); 179void wdrestart(void *);
180void wddone(void *); 180void wddone(void *);
181int wd_get_params(struct wd_softc *, u_int8_t, struct ataparams *); 181int wd_get_params(struct wd_softc *, u_int8_t, struct ataparams *);
182int wd_flushcache(struct wd_softc *, int); 182int wd_flushcache(struct wd_softc *, int);
183bool wd_shutdown(device_t, int); 183bool wd_shutdown(device_t, int);
184 184
185int wd_getcache(struct wd_softc *, int *); 185int wd_getcache(struct wd_softc *, int *);
186int wd_setcache(struct wd_softc *, int); 186int wd_setcache(struct wd_softc *, int);
187 187
188struct dkdriver wddkdriver = { wdstrategy, minphys }; 188struct dkdriver wddkdriver = { wdstrategy, minphys };
189 189
190#ifdef HAS_BAD144_HANDLING 190#ifdef HAS_BAD144_HANDLING
191static void bad144intern(struct wd_softc *); 191static void bad144intern(struct wd_softc *);
192#endif 192#endif
193 193
194#define WD_QUIRK_SPLIT_MOD15_WRITE 0x0001 /* must split certain writes */ 194#define WD_QUIRK_SPLIT_MOD15_WRITE 0x0001 /* must split certain writes */
195 195
196#define WD_QUIRK_FMT "\20\1SPLIT_MOD15_WRITE\2FORCE_LBA48" 196#define WD_QUIRK_FMT "\20\1SPLIT_MOD15_WRITE\2FORCE_LBA48"
197 197
198/* 198/*
199 * Quirk table for IDE drives. Put more-specific matches first, since 199 * Quirk table for IDE drives. Put more-specific matches first, since
200 * a simple globbing routine is used for matching. 200 * a simple globbing routine is used for matching.
201 */ 201 */
202static const struct wd_quirk { 202static const struct wd_quirk {
203 const char *wdq_match; /* inquiry pattern to match */ 203 const char *wdq_match; /* inquiry pattern to match */
204 int wdq_quirks; /* drive quirks */ 204 int wdq_quirks; /* drive quirks */
205} wd_quirk_table[] = { 205} wd_quirk_table[] = {
206 /* 206 /*
207 * Some Seagate S-ATA drives have a PHY which can get confused 207 * Some Seagate S-ATA drives have a PHY which can get confused
208 * with the way data is packetized by some S-ATA controllers. 208 * with the way data is packetized by some S-ATA controllers.
209 * 209 *
210 * The work-around is to split in two any write transfer whose 210 * The work-around is to split in two any write transfer whose
211 * sector count % 15 == 1 (assuming 512 byte sectors). 211 * sector count % 15 == 1 (assuming 512 byte sectors).
212 * 212 *
213 * XXX This is an incomplete list. There are at least a couple 213 * XXX This is an incomplete list. There are at least a couple
214 * XXX more model numbers. If you have trouble with such transfers 214 * XXX more model numbers. If you have trouble with such transfers
215 * XXX (8K is the most common) on Seagate S-ATA drives, please 215 * XXX (8K is the most common) on Seagate S-ATA drives, please
216 * XXX notify thorpej@NetBSD.org. 216 * XXX notify thorpej@NetBSD.org.
217 */ 217 */
218 { "ST3120023AS", 218 { "ST3120023AS",
219 WD_QUIRK_SPLIT_MOD15_WRITE }, 219 WD_QUIRK_SPLIT_MOD15_WRITE },
220 { "ST380023AS", 220 { "ST380023AS",
221 WD_QUIRK_SPLIT_MOD15_WRITE }, 221 WD_QUIRK_SPLIT_MOD15_WRITE },
222 { NULL, 222 { NULL,
223 0 } 223 0 }
224}; 224};
225 225
226static const struct wd_quirk * 226static const struct wd_quirk *
227wd_lookup_quirks(const char *name) 227wd_lookup_quirks(const char *name)
228{ 228{
229 const struct wd_quirk *wdq; 229 const struct wd_quirk *wdq;
230 const char *estr; 230 const char *estr;
231 231
232 for (wdq = wd_quirk_table; wdq->wdq_match != NULL; wdq++) { 232 for (wdq = wd_quirk_table; wdq->wdq_match != NULL; wdq++) {
233 /* 233 /*
234 * We only want exact matches (which include matches 234 * We only want exact matches (which include matches
235 * against globbing characters). 235 * against globbing characters).
236 */ 236 */
237 if (pmatch(name, wdq->wdq_match, &estr) == 2) 237 if (pmatch(name, wdq->wdq_match, &estr) == 2)
238 return (wdq); 238 return (wdq);
239 } 239 }
240 return (NULL); 240 return (NULL);
241} 241}
242 242
243int 243int
244wdprobe(device_t parent, cfdata_t match, void *aux) 244wdprobe(device_t parent, cfdata_t match, void *aux)
245{ 245{
246 struct ata_device *adev = aux; 246 struct ata_device *adev = aux;
247 247
248 if (adev == NULL) 248 if (adev == NULL)
249 return 0; 249 return 0;
250 if (adev->adev_bustype->bustype_type != SCSIPI_BUSTYPE_ATA) 250 if (adev->adev_bustype->bustype_type != SCSIPI_BUSTYPE_ATA)
251 return 0; 251 return 0;
252 252
253 if (match->cf_loc[ATA_HLCF_DRIVE] != ATA_HLCF_DRIVE_DEFAULT && 253 if (match->cf_loc[ATA_HLCF_DRIVE] != ATA_HLCF_DRIVE_DEFAULT &&
254 match->cf_loc[ATA_HLCF_DRIVE] != adev->adev_drv_data->drive) 254 match->cf_loc[ATA_HLCF_DRIVE] != adev->adev_drv_data->drive)
255 return 0; 255 return 0;
256 return 1; 256 return 1;
257} 257}
258 258
259void 259void
260wdattach(device_t parent, device_t self, void *aux) 260wdattach(device_t parent, device_t self, void *aux)
261{ 261{
262 struct wd_softc *wd = device_private(self); 262 struct wd_softc *wd = device_private(self);
263 struct ata_device *adev= aux; 263 struct ata_device *adev= aux;
264 int i, blank; 264 int i, blank;
265 char tbuf[41], pbuf[9], c, *p, *q; 265 char tbuf[41], pbuf[9], c, *p, *q;
266 const struct wd_quirk *wdq; 266 const struct wd_quirk *wdq;
267 267
268 wd->sc_dev = self; 268 wd->sc_dev = self;
269 269
270 ATADEBUG_PRINT(("wdattach\n"), DEBUG_FUNCS | DEBUG_PROBE); 270 ATADEBUG_PRINT(("wdattach\n"), DEBUG_FUNCS | DEBUG_PROBE);
271 callout_init(&wd->sc_restart_ch, 0); 271 callout_init(&wd->sc_restart_ch, 0);
272 bufq_alloc(&wd->sc_q, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK); 272 bufq_alloc(&wd->sc_q, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK);
273#ifdef WD_SOFTBADSECT 273#ifdef WD_SOFTBADSECT
274 SLIST_INIT(&wd->sc_bslist); 274 SLIST_INIT(&wd->sc_bslist);
275#endif 275#endif
276 wd->atabus = adev->adev_bustype; 276 wd->atabus = adev->adev_bustype;
277 wd->openings = adev->adev_openings; 277 wd->openings = adev->adev_openings;
278 wd->drvp = adev->adev_drv_data; 278 wd->drvp = adev->adev_drv_data;
279 279
280 wd->drvp->drv_done = wddone; 280 wd->drvp->drv_done = wddone;
281 wd->drvp->drv_softc = wd->sc_dev; 281 wd->drvp->drv_softc = wd->sc_dev;
282 282
283 aprint_naive("\n"); 283 aprint_naive("\n");
284 aprint_normal("\n"); 284 aprint_normal("\n");
285 285
286 /* read our drive info */ 286 /* read our drive info */
287 if (wd_get_params(wd, AT_WAIT, &wd->sc_params) != 0) { 287 if (wd_get_params(wd, AT_WAIT, &wd->sc_params) != 0) {
288 aprint_error_dev(self, "IDENTIFY failed\n"); 288 aprint_error_dev(self, "IDENTIFY failed\n");
289 return; 289 return;
290 } 290 }
291 291
292 for (blank = 0, p = wd->sc_params.atap_model, q = tbuf, i = 0; 292 for (blank = 0, p = wd->sc_params.atap_model, q = tbuf, i = 0;
293 i < sizeof(wd->sc_params.atap_model); i++) { 293 i < sizeof(wd->sc_params.atap_model); i++) {
294 c = *p++; 294 c = *p++;
295 if (c == '\0') 295 if (c == '\0')
296 break; 296 break;
297 if (c != ' ') { 297 if (c != ' ') {
298 if (blank) { 298 if (blank) {
299 *q++ = ' '; 299 *q++ = ' ';
300 blank = 0; 300 blank = 0;
301 } 301 }
302 *q++ = c; 302 *q++ = c;
303 } else 303 } else
304 blank = 1; 304 blank = 1;
305 } 305 }
306 *q++ = '\0'; 306 *q++ = '\0';
307 307
308 aprint_normal_dev(self, "<%s>\n", tbuf); 308 aprint_normal_dev(self, "<%s>\n", tbuf);
309 309
310 wdq = wd_lookup_quirks(tbuf); 310 wdq = wd_lookup_quirks(tbuf);
311 if (wdq != NULL) 311 if (wdq != NULL)
312 wd->sc_quirks = wdq->wdq_quirks; 312 wd->sc_quirks = wdq->wdq_quirks;
313 313
314 if (wd->sc_quirks != 0) { 314 if (wd->sc_quirks != 0) {
315 char sbuf[sizeof(WD_QUIRK_FMT) + 64]; 315 char sbuf[sizeof(WD_QUIRK_FMT) + 64];
316 snprintb(sbuf, sizeof(sbuf), WD_QUIRK_FMT, wd->sc_quirks); 316 snprintb(sbuf, sizeof(sbuf), WD_QUIRK_FMT, wd->sc_quirks);
317 aprint_normal_dev(self, "quirks %s\n", sbuf); 317 aprint_normal_dev(self, "quirks %s\n", sbuf);
318 } 318 }
319 319
320 if ((wd->sc_params.atap_multi & 0xff) > 1) { 320 if ((wd->sc_params.atap_multi & 0xff) > 1) {
321 wd->sc_multi = wd->sc_params.atap_multi & 0xff; 321 wd->sc_multi = wd->sc_params.atap_multi & 0xff;
322 } else { 322 } else {
323 wd->sc_multi = 1; 323 wd->sc_multi = 1;
324 } 324 }
325 325
326 aprint_verbose_dev(self, "drive supports %d-sector PIO transfers,", 326 aprint_verbose_dev(self, "drive supports %d-sector PIO transfers,",
327 wd->sc_multi); 327 wd->sc_multi);
328 328
329 /* 48-bit LBA addressing */ 329 /* 48-bit LBA addressing */
330 if ((wd->sc_params.atap_cmd2_en & ATA_CMD2_LBA48) != 0) 330 if ((wd->sc_params.atap_cmd2_en & ATA_CMD2_LBA48) != 0)
331 wd->sc_flags |= WDF_LBA48; 331 wd->sc_flags |= WDF_LBA48;
332 332
333 /* Prior to ATA-4, LBA was optional. */ 333 /* Prior to ATA-4, LBA was optional. */
334 if ((wd->sc_params.atap_capabilities1 & WDC_CAP_LBA) != 0) 334 if ((wd->sc_params.atap_capabilities1 & WDC_CAP_LBA) != 0)
335 wd->sc_flags |= WDF_LBA; 335 wd->sc_flags |= WDF_LBA;
336#if 0 336#if 0
337 /* ATA-4 requires LBA. */ 337 /* ATA-4 requires LBA. */
338 if (wd->sc_params.atap_ataversion != 0xffff && 338 if (wd->sc_params.atap_ataversion != 0xffff &&
339 wd->sc_params.atap_ataversion >= WDC_VER_ATA4) 339 wd->sc_params.atap_ataversion >= WDC_VER_ATA4)
340 wd->sc_flags |= WDF_LBA; 340 wd->sc_flags |= WDF_LBA;
341#endif 341#endif
342 342
343 if ((wd->sc_flags & WDF_LBA48) != 0) { 343 if ((wd->sc_flags & WDF_LBA48) != 0) {
344 aprint_verbose(" LBA48 addressing\n"); 344 aprint_verbose(" LBA48 addressing\n");
345 wd->sc_capacity = 345 wd->sc_capacity =
346 ((u_int64_t) wd->sc_params.atap_max_lba[3] << 48) | 346 ((u_int64_t) wd->sc_params.atap_max_lba[3] << 48) |
347 ((u_int64_t) wd->sc_params.atap_max_lba[2] << 32) | 347 ((u_int64_t) wd->sc_params.atap_max_lba[2] << 32) |
348 ((u_int64_t) wd->sc_params.atap_max_lba[1] << 16) | 348 ((u_int64_t) wd->sc_params.atap_max_lba[1] << 16) |
349 ((u_int64_t) wd->sc_params.atap_max_lba[0] << 0); 349 ((u_int64_t) wd->sc_params.atap_max_lba[0] << 0);
350 wd->sc_capacity28 = 350 wd->sc_capacity28 =
351 (wd->sc_params.atap_capacity[1] << 16) | 351 (wd->sc_params.atap_capacity[1] << 16) |
352 wd->sc_params.atap_capacity[0]; 352 wd->sc_params.atap_capacity[0];
353 } else if ((wd->sc_flags & WDF_LBA) != 0) { 353 } else if ((wd->sc_flags & WDF_LBA) != 0) {
354 aprint_verbose(" LBA addressing\n"); 354 aprint_verbose(" LBA addressing\n");
355 wd->sc_capacity28 = wd->sc_capacity = 355 wd->sc_capacity28 = wd->sc_capacity =
356 (wd->sc_params.atap_capacity[1] << 16) | 356 (wd->sc_params.atap_capacity[1] << 16) |
357 wd->sc_params.atap_capacity[0]; 357 wd->sc_params.atap_capacity[0];
358 } else { 358 } else {
359 aprint_verbose(" chs addressing\n"); 359 aprint_verbose(" chs addressing\n");
360 wd->sc_capacity28 = wd->sc_capacity = 360 wd->sc_capacity28 = wd->sc_capacity =
361 wd->sc_params.atap_cylinders * 361 wd->sc_params.atap_cylinders *
362 wd->sc_params.atap_heads * 362 wd->sc_params.atap_heads *
363 wd->sc_params.atap_sectors; 363 wd->sc_params.atap_sectors;
364 } 364 }
365 format_bytes(pbuf, sizeof(pbuf), wd->sc_capacity * DEV_BSIZE); 365 format_bytes(pbuf, sizeof(pbuf), wd->sc_capacity * DEV_BSIZE);
366 aprint_normal_dev(self, "%s, %d cyl, %d head, %d sec, " 366 aprint_normal_dev(self, "%s, %d cyl, %d head, %d sec, "
367 "%d bytes/sect x %llu sectors\n", 367 "%d bytes/sect x %llu sectors\n",
368 pbuf, 368 pbuf,
369 (wd->sc_flags & WDF_LBA) ? (int)(wd->sc_capacity / 369 (wd->sc_flags & WDF_LBA) ? (int)(wd->sc_capacity /
370 (wd->sc_params.atap_heads * wd->sc_params.atap_sectors)) : 370 (wd->sc_params.atap_heads * wd->sc_params.atap_sectors)) :
371 wd->sc_params.atap_cylinders, 371 wd->sc_params.atap_cylinders,
372 wd->sc_params.atap_heads, wd->sc_params.atap_sectors, 372 wd->sc_params.atap_heads, wd->sc_params.atap_sectors,
373 DEV_BSIZE, (unsigned long long)wd->sc_capacity); 373 DEV_BSIZE, (unsigned long long)wd->sc_capacity);
374 374
375 ATADEBUG_PRINT(("%s: atap_dmatiming_mimi=%d, atap_dmatiming_recom=%d\n", 375 ATADEBUG_PRINT(("%s: atap_dmatiming_mimi=%d, atap_dmatiming_recom=%d\n",
376 device_xname(self), wd->sc_params.atap_dmatiming_mimi, 376 device_xname(self), wd->sc_params.atap_dmatiming_mimi,
377 wd->sc_params.atap_dmatiming_recom), DEBUG_PROBE); 377 wd->sc_params.atap_dmatiming_recom), DEBUG_PROBE);
378 /* 378 /*
379 * Initialize and attach the disk structure. 379 * Initialize and attach the disk structure.
380 */ 380 */
381 /* we fill in dk_info later */ 381 /* we fill in dk_info later */
382 disk_init(&wd->sc_dk, device_xname(wd->sc_dev), &wddkdriver); 382 disk_init(&wd->sc_dk, device_xname(wd->sc_dev), &wddkdriver);
383 disk_attach(&wd->sc_dk); 383 disk_attach(&wd->sc_dk);
384 wd->sc_wdc_bio.lp = wd->sc_dk.dk_label; 384 wd->sc_wdc_bio.lp = wd->sc_dk.dk_label;
385#if NRND > 0 385#if NRND > 0
386 rnd_attach_source(&wd->rnd_source, device_xname(wd->sc_dev), 386 rnd_attach_source(&wd->rnd_source, device_xname(wd->sc_dev),
387 RND_TYPE_DISK, 0); 387 RND_TYPE_DISK, 0);
388#endif 388#endif
389 389
390 /* Discover wedges on this disk. */ 390 /* Discover wedges on this disk. */
391 dkwedge_discover(&wd->sc_dk); 391 dkwedge_discover(&wd->sc_dk);
392 392
393 if (!pmf_device_register1(self, wd_suspend, NULL, wd_shutdown)) 393 if (!pmf_device_register1(self, wd_suspend, NULL, wd_shutdown))
394 aprint_error_dev(self, "couldn't establish power handler\n"); 394 aprint_error_dev(self, "couldn't establish power handler\n");
395} 395}
396 396
397static bool 397static bool
398wd_suspend(device_t dv, const pmf_qual_t *qual) 398wd_suspend(device_t dv, const pmf_qual_t *qual)
399{ 399{
400 struct wd_softc *sc = device_private(dv); 400 struct wd_softc *sc = device_private(dv);
401 401
402 wd_flushcache(sc, AT_WAIT); 402 wd_flushcache(sc, AT_WAIT);
403 wd_standby(sc, AT_WAIT); 403 wd_standby(sc, AT_WAIT);
404 return true; 404 return true;
405} 405}
406 406
407int 407int
408wddetach(device_t self, int flags) 408wddetach(device_t self, int flags)
409{ 409{
410 struct wd_softc *sc = device_private(self); 410 struct wd_softc *sc = device_private(self);
411 int bmaj, cmaj, i, mn, rc, s; 411 int bmaj, cmaj, i, mn, rc, s;
412 412
413 if ((rc = disk_begindetach(&sc->sc_dk, wdlastclose, self, flags)) != 0) 413 if ((rc = disk_begindetach(&sc->sc_dk, wdlastclose, self, flags)) != 0)
414 return rc; 414 return rc;
415 415
416 /* locate the major number */ 416 /* locate the major number */
417 bmaj = bdevsw_lookup_major(&wd_bdevsw); 417 bmaj = bdevsw_lookup_major(&wd_bdevsw);
418 cmaj = cdevsw_lookup_major(&wd_cdevsw); 418 cmaj = cdevsw_lookup_major(&wd_cdevsw);
419 419
420 /* Nuke the vnodes for any open instances. */ 420 /* Nuke the vnodes for any open instances. */
421 for (i = 0; i < MAXPARTITIONS; i++) { 421 for (i = 0; i < MAXPARTITIONS; i++) {
422 mn = WDMINOR(device_unit(self), i); 422 mn = WDMINOR(device_unit(self), i);
423 vdevgone(bmaj, mn, mn, VBLK); 423 vdevgone(bmaj, mn, mn, VBLK);
424 vdevgone(cmaj, mn, mn, VCHR); 424 vdevgone(cmaj, mn, mn, VCHR);
425 } 425 }
426 426
427 /* Delete all of our wedges. */ 427 /* Delete all of our wedges. */
428 dkwedge_delall(&sc->sc_dk); 428 dkwedge_delall(&sc->sc_dk);
429 429
430 s = splbio(); 430 s = splbio();
431 431
432 /* Kill off any queued buffers. */ 432 /* Kill off any queued buffers. */
433 bufq_drain(sc->sc_q); 433 bufq_drain(sc->sc_q);
434 434
435 bufq_free(sc->sc_q); 435 bufq_free(sc->sc_q);
436 sc->atabus->ata_killpending(sc->drvp); 436 sc->atabus->ata_killpending(sc->drvp);
437 437
438 splx(s); 438 splx(s);
439 439
440 /* Detach disk. */ 440 /* Detach disk. */
441 disk_detach(&sc->sc_dk); 441 disk_detach(&sc->sc_dk);
442 disk_destroy(&sc->sc_dk); 442 disk_destroy(&sc->sc_dk);
443 443
444#ifdef WD_SOFTBADSECT 444#ifdef WD_SOFTBADSECT
445 /* Clean out the bad sector list */ 445 /* Clean out the bad sector list */
446 while (!SLIST_EMPTY(&sc->sc_bslist)) { 446 while (!SLIST_EMPTY(&sc->sc_bslist)) {
447 void *head = SLIST_FIRST(&sc->sc_bslist); 447 void *head = SLIST_FIRST(&sc->sc_bslist);
448 SLIST_REMOVE_HEAD(&sc->sc_bslist, dbs_next); 448 SLIST_REMOVE_HEAD(&sc->sc_bslist, dbs_next);
449 free(head, M_TEMP); 449 free(head, M_TEMP);
450 } 450 }
451 sc->sc_bscount = 0; 451 sc->sc_bscount = 0;
452#endif 452#endif
453 453
454 pmf_device_deregister(self); 454 pmf_device_deregister(self);
455 455
456#if NRND > 0 456#if NRND > 0
457 /* Unhook the entropy source. */ 457 /* Unhook the entropy source. */
458 rnd_detach_source(&sc->rnd_source); 458 rnd_detach_source(&sc->rnd_source);
459#endif 459#endif
460 460
461 callout_destroy(&sc->sc_restart_ch); 461 callout_destroy(&sc->sc_restart_ch);
462 462
463 sc->drvp->drive_flags = 0; /* no drive any more here */ 463 sc->drvp->drive_flags = 0; /* no drive any more here */
464 464
465 return (0); 465 return (0);
466} 466}
467 467
468/* 468/*
469 * Read/write routine for a buffer. Validates the arguments and schedules the 469 * Read/write routine for a buffer. Validates the arguments and schedules the
470 * transfer. Does not wait for the transfer to complete. 470 * transfer. Does not wait for the transfer to complete.
471 */ 471 */
472void 472void
473wdstrategy(struct buf *bp) 473wdstrategy(struct buf *bp)
474{ 474{
475 struct wd_softc *wd = 475 struct wd_softc *wd =
476 device_lookup_private(&wd_cd, WDUNIT(bp->b_dev)); 476 device_lookup_private(&wd_cd, WDUNIT(bp->b_dev));
477 struct disklabel *lp = wd->sc_dk.dk_label; 477 struct disklabel *lp = wd->sc_dk.dk_label;
478 daddr_t blkno; 478 daddr_t blkno;
479 int s; 479 int s;
480 480
481 ATADEBUG_PRINT(("wdstrategy (%s)\n", device_xname(wd->sc_dev)), 481 ATADEBUG_PRINT(("wdstrategy (%s)\n", device_xname(wd->sc_dev)),
482 DEBUG_XFERS); 482 DEBUG_XFERS);
483 483
484 /* Valid request? */ 484 /* Valid request? */
485 if (bp->b_blkno < 0 || 485 if (bp->b_blkno < 0 ||
486 (bp->b_bcount % lp->d_secsize) != 0 || 486 (bp->b_bcount % lp->d_secsize) != 0 ||
487 (bp->b_bcount / lp->d_secsize) >= (1 << NBBY)) { 487 (bp->b_bcount / lp->d_secsize) >= (1 << NBBY)) {
488 bp->b_error = EINVAL; 488 bp->b_error = EINVAL;
489 goto done; 489 goto done;
490 } 490 }
491 491
492 /* If device invalidated (e.g. media change, door open, 492 /* If device invalidated (e.g. media change, door open,
493 * device detachment), then error. 493 * device detachment), then error.
494 */ 494 */
495 if ((wd->sc_flags & WDF_LOADED) == 0 || 495 if ((wd->sc_flags & WDF_LOADED) == 0 ||
496 !device_is_enabled(wd->sc_dev)) { 496 !device_is_enabled(wd->sc_dev)) {
497 bp->b_error = EIO; 497 bp->b_error = EIO;
498 goto done; 498 goto done;
499 } 499 }
500 500
501 /* If it's a null transfer, return immediately. */ 501 /* If it's a null transfer, return immediately. */
502 if (bp->b_bcount == 0) 502 if (bp->b_bcount == 0)
503 goto done; 503 goto done;
504 504
505 /* 505 /*
506 * Do bounds checking, adjust transfer. if error, process. 506 * Do bounds checking, adjust transfer. if error, process.
507 * If end of partition, just return. 507 * If end of partition, just return.
508 */ 508 */
509 if (WDPART(bp->b_dev) == RAW_PART) { 509 if (WDPART(bp->b_dev) == RAW_PART) {
510 if (bounds_check_with_mediasize(bp, DEV_BSIZE, 510 if (bounds_check_with_mediasize(bp, DEV_BSIZE,
511 wd->sc_capacity) <= 0) 511 wd->sc_capacity) <= 0)
512 goto done; 512 goto done;
513 } else { 513 } else {
514 if (bounds_check_with_label(&wd->sc_dk, bp, 514 if (bounds_check_with_label(&wd->sc_dk, bp,
515 (wd->sc_flags & (WDF_WLABEL|WDF_LABELLING)) != 0) <= 0) 515 (wd->sc_flags & (WDF_WLABEL|WDF_LABELLING)) != 0) <= 0)
516 goto done; 516 goto done;
517 } 517 }
518 518
519 /* 519 /*
520 * Now convert the block number to absolute and put it in 520 * Now convert the block number to absolute and put it in
521 * terms of the device's logical block size. 521 * terms of the device's logical block size.
522 */ 522 */
523 if (lp->d_secsize >= DEV_BSIZE) 523 if (lp->d_secsize >= DEV_BSIZE)
524 blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE); 524 blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE);
525 else 525 else
526 blkno = bp->b_blkno * (DEV_BSIZE / lp->d_secsize); 526 blkno = bp->b_blkno * (DEV_BSIZE / lp->d_secsize);
527 527
528 if (WDPART(bp->b_dev) != RAW_PART) 528 if (WDPART(bp->b_dev) != RAW_PART)
529 blkno += lp->d_partitions[WDPART(bp->b_dev)].p_offset; 529 blkno += lp->d_partitions[WDPART(bp->b_dev)].p_offset;
530 530
531 bp->b_rawblkno = blkno; 531 bp->b_rawblkno = blkno;
532 532
533#ifdef WD_SOFTBADSECT 533#ifdef WD_SOFTBADSECT
534 /* 534 /*
535 * If the transfer about to be attempted contains only a block that 535 * If the transfer about to be attempted contains only a block that
536 * is known to be bad then return an error for the transfer without 536 * is known to be bad then return an error for the transfer without
537 * even attempting to start a transfer up under the premis that we 537 * even attempting to start a transfer up under the premis that we
538 * will just end up doing more retries for a transfer that will end 538 * will just end up doing more retries for a transfer that will end
539 * up failing again. 539 * up failing again.
540 * XXX:SMP - mutex required to protect with DIOCBSFLUSH 540 * XXX:SMP - mutex required to protect with DIOCBSFLUSH
541 */ 541 */
542 if (__predict_false(!SLIST_EMPTY(&wd->sc_bslist))) { 542 if (__predict_false(!SLIST_EMPTY(&wd->sc_bslist))) {
543 struct disk_badsectors *dbs; 543 struct disk_badsectors *dbs;
544 daddr_t maxblk = blkno + (bp->b_bcount >> DEV_BSHIFT) - 1; 544 daddr_t maxblk = blkno + (bp->b_bcount >> DEV_BSHIFT) - 1;
545 545
546 SLIST_FOREACH(dbs, &wd->sc_bslist, dbs_next) 546 SLIST_FOREACH(dbs, &wd->sc_bslist, dbs_next)
547 if ((dbs->dbs_min <= blkno && blkno <= dbs->dbs_max) || 547 if ((dbs->dbs_min <= blkno && blkno <= dbs->dbs_max) ||
548 (dbs->dbs_min <= maxblk && maxblk <= dbs->dbs_max)){ 548 (dbs->dbs_min <= maxblk && maxblk <= dbs->dbs_max)){
549 bp->b_error = EIO; 549 bp->b_error = EIO;
550 goto done; 550 goto done;
551 } 551 }
552 } 552 }
553#endif 553#endif
554 554
555 /* Queue transfer on drive, activate drive and controller if idle. */ 555 /* Queue transfer on drive, activate drive and controller if idle. */
556 s = splbio(); 556 s = splbio();
557 bufq_put(wd->sc_q, bp); 557 bufq_put(wd->sc_q, bp);
558 wdstart(wd); 558 wdstart(wd);
559 splx(s); 559 splx(s);
560 return; 560 return;
561done: 561done:
562 /* Toss transfer; we're done early. */ 562 /* Toss transfer; we're done early. */
563 bp->b_resid = bp->b_bcount; 563 bp->b_resid = bp->b_bcount;
564 biodone(bp); 564 biodone(bp);
565} 565}
566 566
567/* 567/*
568 * Queue a drive for I/O. 568 * Queue a drive for I/O.
569 */ 569 */
570void 570void
571wdstart(void *arg) 571wdstart(void *arg)
572{ 572{
573 struct wd_softc *wd = arg; 573 struct wd_softc *wd = arg;
574 struct buf *bp = NULL; 574 struct buf *bp = NULL;
575 575
576 ATADEBUG_PRINT(("wdstart %s\n", device_xname(wd->sc_dev)), 576 ATADEBUG_PRINT(("wdstart %s\n", device_xname(wd->sc_dev)),
577 DEBUG_XFERS); 577 DEBUG_XFERS);
578 578
579 if (!device_is_active(wd->sc_dev)) 579 if (!device_is_active(wd->sc_dev))
580 return; 580 return;
581 581
582 while (wd->openings > 0) { 582 while (wd->openings > 0) {
583 583
584 /* Is there a buf for us ? */ 584 /* Is there a buf for us ? */
585 if ((bp = bufq_get(wd->sc_q)) == NULL) 585 if ((bp = bufq_get(wd->sc_q)) == NULL)
586 return; 586 return;
587 587
588 /* 588 /*
589 * Make the command. First lock the device 589 * Make the command. First lock the device
590 */ 590 */
591 wd->openings--; 591 wd->openings--;
592 592
593 wd->retries = 0; 593 wd->retries = 0;
594 wdstart1(wd, bp); 594 wdstart1(wd, bp);
595 } 595 }
596} 596}
597 597
598static void 598static void
599wd_split_mod15_write(struct buf *bp) 599wd_split_mod15_write(struct buf *bp)
600{ 600{
601 struct buf *obp = bp->b_private; 601 struct buf *obp = bp->b_private;
602 struct wd_softc *sc = 602 struct wd_softc *sc =
603 device_lookup_private(&wd_cd, DISKUNIT(obp->b_dev)); 603 device_lookup_private(&wd_cd, DISKUNIT(obp->b_dev));
604 int s; 604 int s;
605 605
606 if (__predict_false(bp->b_error != 0)) { 606 if (__predict_false(bp->b_error != 0)) {
607 /* 607 /*
608 * Propagate the error. If this was the first half of 608 * Propagate the error. If this was the first half of
609 * the original transfer, make sure to account for that 609 * the original transfer, make sure to account for that
610 * in the residual. 610 * in the residual.
611 */ 611 */
612 if (bp->b_data == obp->b_data) 612 if (bp->b_data == obp->b_data)
613 bp->b_resid += bp->b_bcount; 613 bp->b_resid += bp->b_bcount;
614 goto done; 614 goto done;
615 } 615 }
616 616
617 /* 617 /*
618 * If this was the second half of the transfer, we're all done! 618 * If this was the second half of the transfer, we're all done!
619 */ 619 */
620 if (bp->b_data != obp->b_data) 620 if (bp->b_data != obp->b_data)
621 goto done; 621 goto done;
622 622
623 /* 623 /*
624 * Advance the pointer to the second half and issue that command 624 * Advance the pointer to the second half and issue that command
625 * using the same opening. 625 * using the same opening.
626 */ 626 */
627 bp->b_flags = obp->b_flags; 627 bp->b_flags = obp->b_flags;
628 bp->b_oflags = obp->b_oflags; 628 bp->b_oflags = obp->b_oflags;
629 bp->b_cflags = obp->b_cflags; 629 bp->b_cflags = obp->b_cflags;
630 bp->b_data = (char *)bp->b_data + bp->b_bcount; 630 bp->b_data = (char *)bp->b_data + bp->b_bcount;
631 bp->b_blkno += (bp->b_bcount / 512); 631 bp->b_blkno += (bp->b_bcount / 512);
632 bp->b_rawblkno += (bp->b_bcount / 512); 632 bp->b_rawblkno += (bp->b_bcount / 512);
633 s = splbio(); 633 s = splbio();
634 wdstart1(sc, bp); 634 wdstart1(sc, bp);
635 splx(s); 635 splx(s);
636 return; 636 return;
637 637
638 done: 638 done:
639 obp->b_error = bp->b_error; 639 obp->b_error = bp->b_error;
640 obp->b_resid = bp->b_resid; 640 obp->b_resid = bp->b_resid;
641 s = splbio(); 641 s = splbio();
642 putiobuf(bp); 642 putiobuf(bp);
643 biodone(obp); 643 biodone(obp);
644 sc->openings++; 644 sc->openings++;
645 splx(s); 645 splx(s);
646 /* wddone() will call wdstart() */ 646 /* wddone() will call wdstart() */
647} 647}
648 648
649void 649void
650wdstart1(struct wd_softc *wd, struct buf *bp) 650wdstart1(struct wd_softc *wd, struct buf *bp)
651{ 651{
652 652
653 /* 653 /*
654 * Deal with the "split mod15 write" quirk. We just divide the 654 * Deal with the "split mod15 write" quirk. We just divide the
655 * transfer in two, doing the first half and then then second half 655 * transfer in two, doing the first half and then then second half
656 * with the same command opening. 656 * with the same command opening.
657 * 657 *
658 * Note we MUST do this here, because we can't let insertion 658 * Note we MUST do this here, because we can't let insertion
659 * into the bufq cause the transfers to be re-merged. 659 * into the bufq cause the transfers to be re-merged.
660 */ 660 */
661 if (__predict_false((wd->sc_quirks & WD_QUIRK_SPLIT_MOD15_WRITE) != 0 && 661 if (__predict_false((wd->sc_quirks & WD_QUIRK_SPLIT_MOD15_WRITE) != 0 &&
662 (bp->b_flags & B_READ) == 0 && 662 (bp->b_flags & B_READ) == 0 &&
663 bp->b_bcount > 512 && 663 bp->b_bcount > 512 &&
664 ((bp->b_bcount / 512) % 15) == 1)) { 664 ((bp->b_bcount / 512) % 15) == 1)) {
665 struct buf *nbp; 665 struct buf *nbp;
666 666
667 /* already at splbio */ 667 /* already at splbio */
668 nbp = getiobuf(NULL, false); 668 nbp = getiobuf(NULL, false);
669 if (__predict_false(nbp == NULL)) { 669 if (__predict_false(nbp == NULL)) {
670 /* No memory -- fail the iop. */ 670 /* No memory -- fail the iop. */
671 bp->b_error = ENOMEM; 671 bp->b_error = ENOMEM;
672 bp->b_resid = bp->b_bcount; 672 bp->b_resid = bp->b_bcount;
673 biodone(bp); 673 biodone(bp);
674 wd->openings++; 674 wd->openings++;
675 return; 675 return;
676 } 676 }
677 677
678 nbp->b_error = 0; 678 nbp->b_error = 0;
679 nbp->b_proc = bp->b_proc; 679 nbp->b_proc = bp->b_proc;
680 nbp->b_dev = bp->b_dev; 680 nbp->b_dev = bp->b_dev;
681 681
682 nbp->b_bcount = bp->b_bcount / 2; 682 nbp->b_bcount = bp->b_bcount / 2;
683 nbp->b_bufsize = bp->b_bcount / 2; 683 nbp->b_bufsize = bp->b_bcount / 2;
684 nbp->b_data = bp->b_data; 684 nbp->b_data = bp->b_data;
685 685
686 nbp->b_blkno = bp->b_blkno; 686 nbp->b_blkno = bp->b_blkno;
687 nbp->b_rawblkno = bp->b_rawblkno; 687 nbp->b_rawblkno = bp->b_rawblkno;
688 688
689 nbp->b_flags = bp->b_flags; 689 nbp->b_flags = bp->b_flags;
690 nbp->b_oflags = bp->b_oflags; 690 nbp->b_oflags = bp->b_oflags;
691 nbp->b_cflags = bp->b_cflags; 691 nbp->b_cflags = bp->b_cflags;
692 nbp->b_iodone = wd_split_mod15_write; 692 nbp->b_iodone = wd_split_mod15_write;
693 693
694 /* Put ptr to orig buf in b_private and use new buf */ 694 /* Put ptr to orig buf in b_private and use new buf */
695 nbp->b_private = bp; 695 nbp->b_private = bp;
696 696
697 BIO_COPYPRIO(nbp, bp); 697 BIO_COPYPRIO(nbp, bp);
698 698
699 bp = nbp; 699 bp = nbp;
700 } 700 }
701 701
702 wd->sc_wdc_bio.blkno = bp->b_rawblkno; 702 wd->sc_wdc_bio.blkno = bp->b_rawblkno;
703 wd->sc_wdc_bio.bcount = bp->b_bcount; 703 wd->sc_wdc_bio.bcount = bp->b_bcount;
704 wd->sc_wdc_bio.databuf = bp->b_data; 704 wd->sc_wdc_bio.databuf = bp->b_data;
705 wd->sc_wdc_bio.blkdone =0; 705 wd->sc_wdc_bio.blkdone =0;
 706 KASSERT(bp == wd->sc_bp || wd->sc_bp == NULL);
706 wd->sc_bp = bp; 707 wd->sc_bp = bp;
707 /* 708 /*
708 * If we're retrying, retry in single-sector mode. This will give us 709 * If we're retrying, retry in single-sector mode. This will give us
709 * the sector number of the problem, and will eventually allow the 710 * the sector number of the problem, and will eventually allow the
710 * transfer to succeed. 711 * transfer to succeed.
711 */ 712 */
712 if (wd->retries >= WDIORETRIES_SINGLE) 713 if (wd->retries >= WDIORETRIES_SINGLE)
713 wd->sc_wdc_bio.flags = ATA_SINGLE; 714 wd->sc_wdc_bio.flags = ATA_SINGLE;
714 else 715 else
715 wd->sc_wdc_bio.flags = 0; 716 wd->sc_wdc_bio.flags = 0;
716 if (wd->sc_flags & WDF_LBA48 && 717 if (wd->sc_flags & WDF_LBA48 &&
717 (wd->sc_wdc_bio.blkno + 718 (wd->sc_wdc_bio.blkno +
718 wd->sc_wdc_bio.bcount / wd->sc_dk.dk_label->d_secsize) > 719 wd->sc_wdc_bio.bcount / wd->sc_dk.dk_label->d_secsize) >
719 wd->sc_capacity28) 720 wd->sc_capacity28)
720 wd->sc_wdc_bio.flags |= ATA_LBA48; 721 wd->sc_wdc_bio.flags |= ATA_LBA48;
721 if (wd->sc_flags & WDF_LBA) 722 if (wd->sc_flags & WDF_LBA)
722 wd->sc_wdc_bio.flags |= ATA_LBA; 723 wd->sc_wdc_bio.flags |= ATA_LBA;
723 if (bp->b_flags & B_READ) 724 if (bp->b_flags & B_READ)
724 wd->sc_wdc_bio.flags |= ATA_READ; 725 wd->sc_wdc_bio.flags |= ATA_READ;
725 /* Instrumentation. */ 726 /* Instrumentation. */
726 disk_busy(&wd->sc_dk); 727 disk_busy(&wd->sc_dk);
727 switch (wd->atabus->ata_bio(wd->drvp, &wd->sc_wdc_bio)) { 728 switch (wd->atabus->ata_bio(wd->drvp, &wd->sc_wdc_bio)) {
728 case ATACMD_TRY_AGAIN: 729 case ATACMD_TRY_AGAIN:
729 callout_reset(&wd->sc_restart_ch, hz, wdrestart, wd); 730 callout_reset(&wd->sc_restart_ch, hz, wdrestart, wd);
730 break; 731 break;
731 case ATACMD_QUEUED: 732 case ATACMD_QUEUED:
732 case ATACMD_COMPLETE: 733 case ATACMD_COMPLETE:
733 break; 734 break;
734 default: 735 default:
735 panic("wdstart1: bad return code from ata_bio()"); 736 panic("wdstart1: bad return code from ata_bio()");
736 } 737 }
737} 738}
738 739
739void 740void
740wddone(void *v) 741wddone(void *v)
741{ 742{
742 struct wd_softc *wd = device_private(v); 743 struct wd_softc *wd = device_private(v);
743 struct buf *bp = wd->sc_bp; 744 struct buf *bp = wd->sc_bp;
744 const char *errmsg; 745 const char *errmsg;
745 int do_perror = 0; 746 int do_perror = 0;
746 747
747 ATADEBUG_PRINT(("wddone %s\n", device_xname(wd->sc_dev)), 748 ATADEBUG_PRINT(("wddone %s\n", device_xname(wd->sc_dev)),
748 DEBUG_XFERS); 749 DEBUG_XFERS);
749 if (bp == NULL) 750 if (bp == NULL)
750 return; 751 return;
751 bp->b_resid = wd->sc_wdc_bio.bcount; 752 bp->b_resid = wd->sc_wdc_bio.bcount;
752 switch (wd->sc_wdc_bio.error) { 753 switch (wd->sc_wdc_bio.error) {
753 case ERR_DMA: 754 case ERR_DMA:
754 errmsg = "DMA error"; 755 errmsg = "DMA error";
755 goto retry; 756 goto retry;
756 case ERR_DF: 757 case ERR_DF:
757 errmsg = "device fault"; 758 errmsg = "device fault";
758 goto retry; 759 goto retry;
759 case TIMEOUT: 760 case TIMEOUT:
760 errmsg = "device timeout"; 761 errmsg = "device timeout";
761 goto retry; 762 goto retry;
762 case ERR_RESET: 763 case ERR_RESET:
763 errmsg = "channel reset"; 764 errmsg = "channel reset";
764 goto retry2; 765 goto retry2;
765 case ERROR: 766 case ERROR:
766 /* Don't care about media change bits */ 767 /* Don't care about media change bits */
767 if (wd->sc_wdc_bio.r_error != 0 && 768 if (wd->sc_wdc_bio.r_error != 0 &&
768 (wd->sc_wdc_bio.r_error & ~(WDCE_MC | WDCE_MCR)) == 0) 769 (wd->sc_wdc_bio.r_error & ~(WDCE_MC | WDCE_MCR)) == 0)
769 goto noerror; 770 goto noerror;
770 errmsg = "error"; 771 errmsg = "error";
771 do_perror = 1; 772 do_perror = 1;
772retry: /* Just reset and retry. Can we do more ? */ 773retry: /* Just reset and retry. Can we do more ? */
773 (*wd->atabus->ata_reset_drive)(wd->drvp, AT_RST_NOCMD); 774 (*wd->atabus->ata_reset_drive)(wd->drvp, AT_RST_NOCMD);
774retry2: 775retry2:
775 diskerr(bp, "wd", errmsg, LOG_PRINTF, 776 diskerr(bp, "wd", errmsg, LOG_PRINTF,
776 wd->sc_wdc_bio.blkdone, wd->sc_dk.dk_label); 777 wd->sc_wdc_bio.blkdone, wd->sc_dk.dk_label);
777 if (wd->retries < WDIORETRIES) 778 if (wd->retries < WDIORETRIES)
778 printf(", retrying"); 779 printf(", retrying");
779 printf("\n"); 780 printf("\n");
780 if (do_perror) 781 if (do_perror)
781 wdperror(wd); 782 wdperror(wd);
782 if (wd->retries < WDIORETRIES) { 783 if (wd->retries < WDIORETRIES) {
783 wd->retries++; 784 wd->retries++;
784 callout_reset(&wd->sc_restart_ch, RECOVERYTIME, 785 callout_reset(&wd->sc_restart_ch, RECOVERYTIME,
785 wdrestart, wd); 786 wdrestart, wd);
786 return; 787 return;
787 } 788 }
788 789
789#ifdef WD_SOFTBADSECT 790#ifdef WD_SOFTBADSECT
790 /* 791 /*
791 * Not all errors indicate a failed block but those that do, 792 * Not all errors indicate a failed block but those that do,
792 * put the block on the bad-block list for the device. Only 793 * put the block on the bad-block list for the device. Only
793 * do this for reads because the drive should do it for writes, 794 * do this for reads because the drive should do it for writes,
794 * itself, according to Manuel. 795 * itself, according to Manuel.
795 */ 796 */
796 if ((bp->b_flags & B_READ) && 797 if ((bp->b_flags & B_READ) &&
797 ((wd->drvp->ata_vers >= 4 && wd->sc_wdc_bio.r_error & 64) || 798 ((wd->drvp->ata_vers >= 4 && wd->sc_wdc_bio.r_error & 64) ||
798 (wd->drvp->ata_vers < 4 && wd->sc_wdc_bio.r_error & 192))) { 799 (wd->drvp->ata_vers < 4 && wd->sc_wdc_bio.r_error & 192))) {
799 struct disk_badsectors *dbs; 800 struct disk_badsectors *dbs;
800 801
801 dbs = malloc(sizeof *dbs, M_TEMP, M_WAITOK); 802 dbs = malloc(sizeof *dbs, M_TEMP, M_WAITOK);
802 dbs->dbs_min = bp->b_rawblkno; 803 dbs->dbs_min = bp->b_rawblkno;
803 dbs->dbs_max = dbs->dbs_min + (bp->b_bcount >> DEV_BSHIFT) - 1; 804 dbs->dbs_max = dbs->dbs_min + (bp->b_bcount >> DEV_BSHIFT) - 1;
804 microtime(&dbs->dbs_failedat); 805 microtime(&dbs->dbs_failedat);
805 SLIST_INSERT_HEAD(&wd->sc_bslist, dbs, dbs_next); 806 SLIST_INSERT_HEAD(&wd->sc_bslist, dbs, dbs_next);
806 wd->sc_bscount++; 807 wd->sc_bscount++;
807 } 808 }
808#endif 809#endif
809 bp->b_error = EIO; 810 bp->b_error = EIO;
810 break; 811 break;
811 case NOERROR: 812 case NOERROR:
812noerror: if ((wd->sc_wdc_bio.flags & ATA_CORR) || wd->retries > 0) 813noerror: if ((wd->sc_wdc_bio.flags & ATA_CORR) || wd->retries > 0)
813 aprint_error_dev(wd->sc_dev, 814 aprint_error_dev(wd->sc_dev,
814 "soft error (corrected)\n"); 815 "soft error (corrected)\n");
815 break; 816 break;
816 case ERR_NODEV: 817 case ERR_NODEV:
817 bp->b_error = EIO; 818 bp->b_error = EIO;
818 break; 819 break;
819 } 820 }
820 disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid), 821 disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid),
821 (bp->b_flags & B_READ)); 822 (bp->b_flags & B_READ));
822#if NRND > 0 823#if NRND > 0
823 rnd_add_uint32(&wd->rnd_source, bp->b_blkno); 824 rnd_add_uint32(&wd->rnd_source, bp->b_blkno);
824#endif 825#endif
825 /* XXX Yuck, but we don't want to increment openings in this case */ 826 /* XXX Yuck, but we don't want to increment openings in this case */
826 if (__predict_false(bp->b_iodone == wd_split_mod15_write)) 827 if (__predict_false(bp->b_iodone == wd_split_mod15_write))
827 biodone(bp); 828 biodone(bp);
828 else { 829 else {
829 biodone(bp); 830 biodone(bp);
830 wd->openings++; 831 wd->openings++;
831 } 832 }
 833 KASSERT(wd->sc_bp != NULL);
 834 wd->sc_bp = NULL;
832 wdstart(wd); 835 wdstart(wd);
833} 836}
834 837
835void 838void
836wdrestart(void *v) 839wdrestart(void *v)
837{ 840{
838 struct wd_softc *wd = v; 841 struct wd_softc *wd = v;
839 struct buf *bp = wd->sc_bp; 842 struct buf *bp = wd->sc_bp;
840 int s; 843 int s;
841 844
842 ATADEBUG_PRINT(("wdrestart %s\n", device_xname(wd->sc_dev)), 845 ATADEBUG_PRINT(("wdrestart %s\n", device_xname(wd->sc_dev)),
843 DEBUG_XFERS); 846 DEBUG_XFERS);
844 s = splbio(); 847 s = splbio();
845 wdstart1(v, bp); 848 wdstart1(v, bp);
846 splx(s); 849 splx(s);
847} 850}
848 851
849int 852int
850wdread(dev_t dev, struct uio *uio, int flags) 853wdread(dev_t dev, struct uio *uio, int flags)
851{ 854{
852 855
853 ATADEBUG_PRINT(("wdread\n"), DEBUG_XFERS); 856 ATADEBUG_PRINT(("wdread\n"), DEBUG_XFERS);
854 return (physio(wdstrategy, NULL, dev, B_READ, minphys, uio)); 857 return (physio(wdstrategy, NULL, dev, B_READ, minphys, uio));
855} 858}
856 859
857int 860int
858wdwrite(dev_t dev, struct uio *uio, int flags) 861wdwrite(dev_t dev, struct uio *uio, int flags)
859{ 862{
860 863
861 ATADEBUG_PRINT(("wdwrite\n"), DEBUG_XFERS); 864 ATADEBUG_PRINT(("wdwrite\n"), DEBUG_XFERS);
862 return (physio(wdstrategy, NULL, dev, B_WRITE, minphys, uio)); 865 return (physio(wdstrategy, NULL, dev, B_WRITE, minphys, uio));
863} 866}
864 867
865int 868int
866wdopen(dev_t dev, int flag, int fmt, struct lwp *l) 869wdopen(dev_t dev, int flag, int fmt, struct lwp *l)
867{ 870{
868 struct wd_softc *wd; 871 struct wd_softc *wd;
869 int part, error; 872 int part, error;
870 873
871 ATADEBUG_PRINT(("wdopen\n"), DEBUG_FUNCS); 874 ATADEBUG_PRINT(("wdopen\n"), DEBUG_FUNCS);
872 wd = device_lookup_private(&wd_cd, WDUNIT(dev)); 875 wd = device_lookup_private(&wd_cd, WDUNIT(dev));
873 if (wd == NULL) 876 if (wd == NULL)
874 return (ENXIO); 877 return (ENXIO);
875 878
876 if (! device_is_active(wd->sc_dev)) 879 if (! device_is_active(wd->sc_dev))
877 return (ENODEV); 880 return (ENODEV);
878 881
879 part = WDPART(dev); 882 part = WDPART(dev);
880 883
881 mutex_enter(&wd->sc_dk.dk_openlock); 884 mutex_enter(&wd->sc_dk.dk_openlock);
882 885
883 /* 886 /*
884 * If there are wedges, and this is not RAW_PART, then we 887 * If there are wedges, and this is not RAW_PART, then we
885 * need to fail. 888 * need to fail.
886 */ 889 */
887 if (wd->sc_dk.dk_nwedges != 0 && part != RAW_PART) { 890 if (wd->sc_dk.dk_nwedges != 0 && part != RAW_PART) {
888 error = EBUSY; 891 error = EBUSY;
889 goto bad1; 892 goto bad1;
890 } 893 }
891 894
892 /* 895 /*
893 * If this is the first open of this device, add a reference 896 * If this is the first open of this device, add a reference
894 * to the adapter. 897 * to the adapter.
895 */ 898 */
896 if (wd->sc_dk.dk_openmask == 0 && 899 if (wd->sc_dk.dk_openmask == 0 &&
897 (error = wd->atabus->ata_addref(wd->drvp)) != 0) 900 (error = wd->atabus->ata_addref(wd->drvp)) != 0)
898 goto bad1; 901 goto bad1;
899 902
900 if (wd->sc_dk.dk_openmask != 0) { 903 if (wd->sc_dk.dk_openmask != 0) {
901 /* 904 /*
902 * If any partition is open, but the disk has been invalidated, 905 * If any partition is open, but the disk has been invalidated,
903 * disallow further opens. 906 * disallow further opens.
904 */ 907 */
905 if ((wd->sc_flags & WDF_LOADED) == 0) { 908 if ((wd->sc_flags & WDF_LOADED) == 0) {
906 error = EIO; 909 error = EIO;
907 goto bad2; 910 goto bad2;
908 } 911 }
909 } else { 912 } else {
910 if ((wd->sc_flags & WDF_LOADED) == 0) { 913 if ((wd->sc_flags & WDF_LOADED) == 0) {
911 wd->sc_flags |= WDF_LOADED; 914 wd->sc_flags |= WDF_LOADED;
912 915
913 /* Load the physical device parameters. */ 916 /* Load the physical device parameters. */
914 wd_get_params(wd, AT_WAIT, &wd->sc_params); 917 wd_get_params(wd, AT_WAIT, &wd->sc_params);
915 918
916 /* Load the partition info if not already loaded. */ 919 /* Load the partition info if not already loaded. */
917 wdgetdisklabel(wd); 920 wdgetdisklabel(wd);
918 } 921 }
919 } 922 }
920 923
921 /* Check that the partition exists. */ 924 /* Check that the partition exists. */
922 if (part != RAW_PART && 925 if (part != RAW_PART &&
923 (part >= wd->sc_dk.dk_label->d_npartitions || 926 (part >= wd->sc_dk.dk_label->d_npartitions ||
924 wd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) { 927 wd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
925 error = ENXIO; 928 error = ENXIO;
926 goto bad2; 929 goto bad2;
927 } 930 }
928 931
929 /* Insure only one open at a time. */ 932 /* Insure only one open at a time. */
930 switch (fmt) { 933 switch (fmt) {
931 case S_IFCHR: 934 case S_IFCHR:
932 wd->sc_dk.dk_copenmask |= (1 << part); 935 wd->sc_dk.dk_copenmask |= (1 << part);
933 break; 936 break;
934 case S_IFBLK: 937 case S_IFBLK:
935 wd->sc_dk.dk_bopenmask |= (1 << part); 938 wd->sc_dk.dk_bopenmask |= (1 << part);
936 break; 939 break;
937 } 940 }
938 wd->sc_dk.dk_openmask = 941 wd->sc_dk.dk_openmask =
939 wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask; 942 wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
940 943
941 mutex_exit(&wd->sc_dk.dk_openlock); 944 mutex_exit(&wd->sc_dk.dk_openlock);
942 return 0; 945 return 0;
943 946
944 bad2: 947 bad2:
945 if (wd->sc_dk.dk_openmask == 0) 948 if (wd->sc_dk.dk_openmask == 0)
946 wd->atabus->ata_delref(wd->drvp); 949 wd->atabus->ata_delref(wd->drvp);
947 bad1: 950 bad1:
948 mutex_exit(&wd->sc_dk.dk_openlock); 951 mutex_exit(&wd->sc_dk.dk_openlock);
949 return error; 952 return error;
950} 953}
951 954
952/*  955/*
953 * Caller must hold wd->sc_dk.dk_openlock. 956 * Caller must hold wd->sc_dk.dk_openlock.
954 */ 957 */
955static int 958static int
956wdlastclose(device_t self) 959wdlastclose(device_t self)
957{ 960{
958 struct wd_softc *wd = device_private(self); 961 struct wd_softc *wd = device_private(self);
959 962
960 wd_flushcache(wd, AT_WAIT); 963 wd_flushcache(wd, AT_WAIT);
961 964
962 if (! (wd->sc_flags & WDF_KLABEL)) 965 if (! (wd->sc_flags & WDF_KLABEL))
963 wd->sc_flags &= ~WDF_LOADED; 966 wd->sc_flags &= ~WDF_LOADED;
964 967
965 wd->atabus->ata_delref(wd->drvp); 968 wd->atabus->ata_delref(wd->drvp);
966 969
967 return 0; 970 return 0;
968} 971}
969 972
970int 973int
971wdclose(dev_t dev, int flag, int fmt, struct lwp *l) 974wdclose(dev_t dev, int flag, int fmt, struct lwp *l)
972{ 975{
973 struct wd_softc *wd = 976 struct wd_softc *wd =
974 device_lookup_private(&wd_cd, WDUNIT(dev)); 977 device_lookup_private(&wd_cd, WDUNIT(dev));
975 int part = WDPART(dev); 978 int part = WDPART(dev);
976 979
977 ATADEBUG_PRINT(("wdclose\n"), DEBUG_FUNCS); 980 ATADEBUG_PRINT(("wdclose\n"), DEBUG_FUNCS);
978 981
979 mutex_enter(&wd->sc_dk.dk_openlock); 982 mutex_enter(&wd->sc_dk.dk_openlock);
980 983
981 switch (fmt) { 984 switch (fmt) {
982 case S_IFCHR: 985 case S_IFCHR:
983 wd->sc_dk.dk_copenmask &= ~(1 << part); 986 wd->sc_dk.dk_copenmask &= ~(1 << part);
984 break; 987 break;
985 case S_IFBLK: 988 case S_IFBLK:
986 wd->sc_dk.dk_bopenmask &= ~(1 << part); 989 wd->sc_dk.dk_bopenmask &= ~(1 << part);
987 break; 990 break;
988 } 991 }
989 wd->sc_dk.dk_openmask = 992 wd->sc_dk.dk_openmask =
990 wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask; 993 wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
991 994
992 if (wd->sc_dk.dk_openmask == 0) 995 if (wd->sc_dk.dk_openmask == 0)
993 wdlastclose(wd->sc_dev); 996 wdlastclose(wd->sc_dev);
994 997
995 mutex_exit(&wd->sc_dk.dk_openlock); 998 mutex_exit(&wd->sc_dk.dk_openlock);
996 return 0; 999 return 0;
997} 1000}
998 1001
999void 1002void
1000wdgetdefaultlabel(struct wd_softc *wd, struct disklabel *lp) 1003wdgetdefaultlabel(struct wd_softc *wd, struct disklabel *lp)
1001{ 1004{
1002 1005
1003 ATADEBUG_PRINT(("wdgetdefaultlabel\n"), DEBUG_FUNCS); 1006 ATADEBUG_PRINT(("wdgetdefaultlabel\n"), DEBUG_FUNCS);
1004 memset(lp, 0, sizeof(struct disklabel)); 1007 memset(lp, 0, sizeof(struct disklabel));
1005 1008
1006 lp->d_secsize = DEV_BSIZE; 1009 lp->d_secsize = DEV_BSIZE;
1007 lp->d_ntracks = wd->sc_params.atap_heads; 1010 lp->d_ntracks = wd->sc_params.atap_heads;
1008 lp->d_nsectors = wd->sc_params.atap_sectors; 1011 lp->d_nsectors = wd->sc_params.atap_sectors;
1009 lp->d_ncylinders = (wd->sc_flags & WDF_LBA) ? wd->sc_capacity / 1012 lp->d_ncylinders = (wd->sc_flags & WDF_LBA) ? wd->sc_capacity /
1010 (wd->sc_params.atap_heads * wd->sc_params.atap_sectors) : 1013 (wd->sc_params.atap_heads * wd->sc_params.atap_sectors) :
1011 wd->sc_params.atap_cylinders; 1014 wd->sc_params.atap_cylinders;
1012 lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors; 1015 lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
1013 1016
1014 if (strcmp(wd->sc_params.atap_model, "ST506") == 0) 1017 if (strcmp(wd->sc_params.atap_model, "ST506") == 0)
1015 lp->d_type = DTYPE_ST506; 1018 lp->d_type = DTYPE_ST506;
1016 else 1019 else
1017 lp->d_type = DTYPE_ESDI; 1020 lp->d_type = DTYPE_ESDI;
1018 1021
1019 strncpy(lp->d_typename, wd->sc_params.atap_model, 16); 1022 strncpy(lp->d_typename, wd->sc_params.atap_model, 16);
1020 strncpy(lp->d_packname, "fictitious", 16); 1023 strncpy(lp->d_packname, "fictitious", 16);
1021 if (wd->sc_capacity > UINT32_MAX) 1024 if (wd->sc_capacity > UINT32_MAX)
1022 lp->d_secperunit = UINT32_MAX; 1025 lp->d_secperunit = UINT32_MAX;
1023 else 1026 else
1024 lp->d_secperunit = wd->sc_capacity; 1027 lp->d_secperunit = wd->sc_capacity;
1025 lp->d_rpm = 3600; 1028 lp->d_rpm = 3600;
1026 lp->d_interleave = 1; 1029 lp->d_interleave = 1;
1027 lp->d_flags = 0; 1030 lp->d_flags = 0;
1028 1031
1029 lp->d_partitions[RAW_PART].p_offset = 0; 1032 lp->d_partitions[RAW_PART].p_offset = 0;
1030 lp->d_partitions[RAW_PART].p_size = 1033 lp->d_partitions[RAW_PART].p_size =
1031 lp->d_secperunit * (lp->d_secsize / DEV_BSIZE); 1034 lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
1032 lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED; 1035 lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
1033 lp->d_npartitions = RAW_PART + 1; 1036 lp->d_npartitions = RAW_PART + 1;
1034 1037
1035 lp->d_magic = DISKMAGIC; 1038 lp->d_magic = DISKMAGIC;
1036 lp->d_magic2 = DISKMAGIC; 1039 lp->d_magic2 = DISKMAGIC;
1037 lp->d_checksum = dkcksum(lp); 1040 lp->d_checksum = dkcksum(lp);
1038} 1041}
1039 1042
1040/* 1043/*
1041 * Fabricate a default disk label, and try to read the correct one. 1044 * Fabricate a default disk label, and try to read the correct one.
1042 */ 1045 */
1043void 1046void
1044wdgetdisklabel(struct wd_softc *wd) 1047wdgetdisklabel(struct wd_softc *wd)
1045{ 1048{
1046 struct disklabel *lp = wd->sc_dk.dk_label; 1049 struct disklabel *lp = wd->sc_dk.dk_label;
1047 const char *errstring; 1050 const char *errstring;
1048 int s; 1051 int s;
1049 1052
1050 ATADEBUG_PRINT(("wdgetdisklabel\n"), DEBUG_FUNCS); 1053 ATADEBUG_PRINT(("wdgetdisklabel\n"), DEBUG_FUNCS);
1051 1054
1052 memset(wd->sc_dk.dk_cpulabel, 0, sizeof(struct cpu_disklabel)); 1055 memset(wd->sc_dk.dk_cpulabel, 0, sizeof(struct cpu_disklabel));
1053 1056
1054 wdgetdefaultlabel(wd, lp); 1057 wdgetdefaultlabel(wd, lp);
1055 1058
1056 wd->sc_badsect[0] = -1; 1059 wd->sc_badsect[0] = -1;
1057 1060
1058 if (wd->drvp->state > RESET) { 1061 if (wd->drvp->state > RESET) {
1059 s = splbio(); 1062 s = splbio();
1060 wd->drvp->drive_flags |= DRIVE_RESET; 1063 wd->drvp->drive_flags |= DRIVE_RESET;
1061 splx(s); 1064 splx(s);
1062 } 1065 }
1063 errstring = readdisklabel(MAKEWDDEV(0, device_unit(wd->sc_dev), 1066 errstring = readdisklabel(MAKEWDDEV(0, device_unit(wd->sc_dev),
1064 RAW_PART), wdstrategy, lp, 1067 RAW_PART), wdstrategy, lp,
1065 wd->sc_dk.dk_cpulabel); 1068 wd->sc_dk.dk_cpulabel);
1066 if (errstring) { 1069 if (errstring) {
1067 /* 1070 /*
1068 * This probably happened because the drive's default 1071 * This probably happened because the drive's default
1069 * geometry doesn't match the DOS geometry. We 1072 * geometry doesn't match the DOS geometry. We
1070 * assume the DOS geometry is now in the label and try 1073 * assume the DOS geometry is now in the label and try
1071 * again. XXX This is a kluge. 1074 * again. XXX This is a kluge.
1072 */ 1075 */
1073 if (wd->drvp->state > RESET) { 1076 if (wd->drvp->state > RESET) {
1074 s = splbio(); 1077 s = splbio();
1075 wd->drvp->drive_flags |= DRIVE_RESET; 1078 wd->drvp->drive_flags |= DRIVE_RESET;
1076 splx(s); 1079 splx(s);
1077 } 1080 }
1078 errstring = readdisklabel(MAKEWDDEV(0, device_unit(wd->sc_dev), 1081 errstring = readdisklabel(MAKEWDDEV(0, device_unit(wd->sc_dev),
1079 RAW_PART), wdstrategy, lp, wd->sc_dk.dk_cpulabel); 1082 RAW_PART), wdstrategy, lp, wd->sc_dk.dk_cpulabel);
1080 } 1083 }
1081 if (errstring) { 1084 if (errstring) {
1082 aprint_error_dev(wd->sc_dev, "%s\n", errstring); 1085 aprint_error_dev(wd->sc_dev, "%s\n", errstring);
1083 return; 1086 return;
1084 } 1087 }
1085 1088
1086 if (wd->drvp->state > RESET) { 1089 if (wd->drvp->state > RESET) {
1087 s = splbio(); 1090 s = splbio();
1088 wd->drvp->drive_flags |= DRIVE_RESET; 1091 wd->drvp->drive_flags |= DRIVE_RESET;
1089 splx(s); 1092 splx(s);
1090 } 1093 }
1091#ifdef HAS_BAD144_HANDLING 1094#ifdef HAS_BAD144_HANDLING
1092 if ((lp->d_flags & D_BADSECT) != 0) 1095 if ((lp->d_flags & D_BADSECT) != 0)
1093 bad144intern(wd); 1096 bad144intern(wd);
1094#endif 1097#endif
1095} 1098}
1096 1099
1097void 1100void
1098wdperror(const struct wd_softc *wd) 1101wdperror(const struct wd_softc *wd)
1099{ 1102{
1100 static const char *const errstr0_3[] = {"address mark not found", 1103 static const char *const errstr0_3[] = {"address mark not found",
1101 "track 0 not found", "aborted command", "media change requested", 1104 "track 0 not found", "aborted command", "media change requested",
1102 "id not found", "media changed", "uncorrectable data error", 1105 "id not found", "media changed", "uncorrectable data error",
1103 "bad block detected"}; 1106 "bad block detected"};
1104 static const char *const errstr4_5[] = { 1107 static const char *const errstr4_5[] = {
1105 "obsolete (address mark not found)", 1108 "obsolete (address mark not found)",
1106 "no media/write protected", "aborted command", 1109 "no media/write protected", "aborted command",
1107 "media change requested", "id not found", "media changed", 1110 "media change requested", "id not found", "media changed",
1108 "uncorrectable data error", "interface CRC error"}; 1111 "uncorrectable data error", "interface CRC error"};
1109 const char *const *errstr; 1112 const char *const *errstr;
1110 int i; 1113 int i;
1111 const char *sep = ""; 1114 const char *sep = "";
1112 1115
1113 const char *devname = device_xname(wd->sc_dev); 1116 const char *devname = device_xname(wd->sc_dev);
1114 struct ata_drive_datas *drvp = wd->drvp; 1117 struct ata_drive_datas *drvp = wd->drvp;
1115 int errno = wd->sc_wdc_bio.r_error; 1118 int errno = wd->sc_wdc_bio.r_error;
1116 1119
1117 if (drvp->ata_vers >= 4) 1120 if (drvp->ata_vers >= 4)
1118 errstr = errstr4_5; 1121 errstr = errstr4_5;
1119 else 1122 else
1120 errstr = errstr0_3; 1123 errstr = errstr0_3;
1121 1124
1122 printf("%s: (", devname); 1125 printf("%s: (", devname);
1123 1126
1124 if (errno == 0) 1127 if (errno == 0)
1125 printf("error not notified"); 1128 printf("error not notified");
1126 1129
1127 for (i = 0; i < 8; i++) { 1130 for (i = 0; i < 8; i++) {
1128 if (errno & (1 << i)) { 1131 if (errno & (1 << i)) {
1129 printf("%s%s", sep, errstr[i]); 1132 printf("%s%s", sep, errstr[i]);
1130 sep = ", "; 1133 sep = ", ";
1131 } 1134 }
1132 } 1135 }
1133 printf(")\n"); 1136 printf(")\n");
1134} 1137}
1135 1138
1136int 1139int
1137wdioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l) 1140wdioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l)
1138{ 1141{
1139 struct wd_softc *wd = 1142 struct wd_softc *wd =
1140 device_lookup_private(&wd_cd, WDUNIT(dev)); 1143 device_lookup_private(&wd_cd, WDUNIT(dev));
1141 int error = 0, s; 1144 int error = 0, s;
1142#ifdef __HAVE_OLD_DISKLABEL 1145#ifdef __HAVE_OLD_DISKLABEL
1143 struct disklabel *newlabel = NULL; 1146 struct disklabel *newlabel = NULL;
1144#endif 1147#endif
1145 1148
1146 ATADEBUG_PRINT(("wdioctl\n"), DEBUG_FUNCS); 1149 ATADEBUG_PRINT(("wdioctl\n"), DEBUG_FUNCS);
1147 1150
1148 if ((wd->sc_flags & WDF_LOADED) == 0) 1151 if ((wd->sc_flags & WDF_LOADED) == 0)
1149 return EIO; 1152 return EIO;
1150 1153
1151 error = disk_ioctl(&wd->sc_dk, xfer, addr, flag, l); 1154 error = disk_ioctl(&wd->sc_dk, xfer, addr, flag, l);
1152 if (error != EPASSTHROUGH) 1155 if (error != EPASSTHROUGH)
1153 return (error); 1156 return (error);
1154 1157
1155 switch (xfer) { 1158 switch (xfer) {
1156#ifdef HAS_BAD144_HANDLING 1159#ifdef HAS_BAD144_HANDLING
1157 case DIOCSBAD: 1160 case DIOCSBAD:
1158 if ((flag & FWRITE) == 0) 1161 if ((flag & FWRITE) == 0)
1159 return EBADF; 1162 return EBADF;
1160 wd->sc_dk.dk_cpulabel->bad = *(struct dkbad *)addr; 1163 wd->sc_dk.dk_cpulabel->bad = *(struct dkbad *)addr;
1161 wd->sc_dk.dk_label->d_flags |= D_BADSECT; 1164 wd->sc_dk.dk_label->d_flags |= D_BADSECT;
1162 bad144intern(wd); 1165 bad144intern(wd);
1163 return 0; 1166 return 0;
1164#endif 1167#endif
1165#ifdef WD_SOFTBADSECT 1168#ifdef WD_SOFTBADSECT
1166 case DIOCBSLIST : 1169 case DIOCBSLIST :
1167 { 1170 {
1168 u_int32_t count, missing, skip; 1171 u_int32_t count, missing, skip;
1169 struct disk_badsecinfo dbsi; 1172 struct disk_badsecinfo dbsi;
1170 struct disk_badsectors *dbs; 1173 struct disk_badsectors *dbs;
1171 size_t available; 1174 size_t available;
1172 uint8_t *laddr; 1175 uint8_t *laddr;
1173 1176
1174 dbsi = *(struct disk_badsecinfo *)addr; 1177 dbsi = *(struct disk_badsecinfo *)addr;
1175 missing = wd->sc_bscount; 1178 missing = wd->sc_bscount;
1176 count = 0; 1179 count = 0;
1177 available = dbsi.dbsi_bufsize; 1180 available = dbsi.dbsi_bufsize;
1178 skip = dbsi.dbsi_skip; 1181 skip = dbsi.dbsi_skip;
1179 laddr = (uint8_t *)dbsi.dbsi_buffer; 1182 laddr = (uint8_t *)dbsi.dbsi_buffer;
1180 1183
1181 /* 1184 /*
1182 * We start this loop with the expectation that all of the 1185 * We start this loop with the expectation that all of the
1183 * entries will be missed and decrement this counter each 1186 * entries will be missed and decrement this counter each
1184 * time we either skip over one (already copied out) or 1187 * time we either skip over one (already copied out) or
1185 * we actually copy it back to user space. The structs 1188 * we actually copy it back to user space. The structs
1186 * holding the bad sector information are copied directly 1189 * holding the bad sector information are copied directly
1187 * back to user space whilst the summary is returned via 1190 * back to user space whilst the summary is returned via
1188 * the struct passed in via the ioctl. 1191 * the struct passed in via the ioctl.
1189 */ 1192 */
1190 SLIST_FOREACH(dbs, &wd->sc_bslist, dbs_next) { 1193 SLIST_FOREACH(dbs, &wd->sc_bslist, dbs_next) {
1191 if (skip > 0) { 1194 if (skip > 0) {
1192 missing--; 1195 missing--;
1193 skip--; 1196 skip--;
1194 continue; 1197 continue;
1195 } 1198 }
1196 if (available < sizeof(*dbs)) 1199 if (available < sizeof(*dbs))
1197 break; 1200 break;
1198 available -= sizeof(*dbs); 1201 available -= sizeof(*dbs);
1199 copyout(dbs, laddr, sizeof(*dbs)); 1202 copyout(dbs, laddr, sizeof(*dbs));
1200 laddr += sizeof(*dbs); 1203 laddr += sizeof(*dbs);
1201 missing--; 1204 missing--;
1202 count++; 1205 count++;
1203 } 1206 }
1204 dbsi.dbsi_left = missing; 1207 dbsi.dbsi_left = missing;
1205 dbsi.dbsi_copied = count; 1208 dbsi.dbsi_copied = count;
1206 *(struct disk_badsecinfo *)addr = dbsi; 1209 *(struct disk_badsecinfo *)addr = dbsi;
1207 return 0; 1210 return 0;
1208 } 1211 }
1209 1212
1210 case DIOCBSFLUSH : 1213 case DIOCBSFLUSH :
1211 /* Clean out the bad sector list */ 1214 /* Clean out the bad sector list */
1212 while (!SLIST_EMPTY(&wd->sc_bslist)) { 1215 while (!SLIST_EMPTY(&wd->sc_bslist)) {
1213 void *head = SLIST_FIRST(&wd->sc_bslist); 1216 void *head = SLIST_FIRST(&wd->sc_bslist);
1214 SLIST_REMOVE_HEAD(&wd->sc_bslist, dbs_next); 1217 SLIST_REMOVE_HEAD(&wd->sc_bslist, dbs_next);
1215 free(head, M_TEMP); 1218 free(head, M_TEMP);
1216 } 1219 }
1217 wd->sc_bscount = 0; 1220 wd->sc_bscount = 0;
1218 return 0; 1221 return 0;
1219#endif 1222#endif
1220 case DIOCGDINFO: 1223 case DIOCGDINFO:
1221 *(struct disklabel *)addr = *(wd->sc_dk.dk_label); 1224 *(struct disklabel *)addr = *(wd->sc_dk.dk_label);
1222 return 0; 1225 return 0;
1223#ifdef __HAVE_OLD_DISKLABEL 1226#ifdef __HAVE_OLD_DISKLABEL
1224 case ODIOCGDINFO: 1227 case ODIOCGDINFO:
1225 newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK); 1228 newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK);
1226 if (newlabel == NULL) 1229 if (newlabel == NULL)
1227 return EIO; 1230 return EIO;
1228 *newlabel = *(wd->sc_dk.dk_label); 1231 *newlabel = *(wd->sc_dk.dk_label);
1229 if (newlabel->d_npartitions <= OLDMAXPARTITIONS) 1232 if (newlabel->d_npartitions <= OLDMAXPARTITIONS)
1230 memcpy(addr, newlabel, sizeof (struct olddisklabel)); 1233 memcpy(addr, newlabel, sizeof (struct olddisklabel));
1231 else 1234 else
1232 error = ENOTTY; 1235 error = ENOTTY;
1233 free(newlabel, M_TEMP); 1236 free(newlabel, M_TEMP);
1234 return error; 1237 return error;
1235#endif 1238#endif
1236 1239
1237 case DIOCGPART: 1240 case DIOCGPART:
1238 ((struct partinfo *)addr)->disklab = wd->sc_dk.dk_label; 1241 ((struct partinfo *)addr)->disklab = wd->sc_dk.dk_label;
1239 ((struct partinfo *)addr)->part = 1242 ((struct partinfo *)addr)->part =
1240 &wd->sc_dk.dk_label->d_partitions[WDPART(dev)]; 1243 &wd->sc_dk.dk_label->d_partitions[WDPART(dev)];
1241 return 0; 1244 return 0;
1242 1245
1243 case DIOCWDINFO: 1246 case DIOCWDINFO:
1244 case DIOCSDINFO: 1247 case DIOCSDINFO:
1245#ifdef __HAVE_OLD_DISKLABEL 1248#ifdef __HAVE_OLD_DISKLABEL
1246 case ODIOCWDINFO: 1249 case ODIOCWDINFO:
1247 case ODIOCSDINFO: 1250 case ODIOCSDINFO:
1248#endif 1251#endif
1249 { 1252 {
1250 struct disklabel *lp; 1253 struct disklabel *lp;
1251 1254
1252 if ((flag & FWRITE) == 0) 1255 if ((flag & FWRITE) == 0)
1253 return EBADF; 1256 return EBADF;
1254 1257
1255#ifdef __HAVE_OLD_DISKLABEL 1258#ifdef __HAVE_OLD_DISKLABEL
1256 if (xfer == ODIOCSDINFO || xfer == ODIOCWDINFO) { 1259 if (xfer == ODIOCSDINFO || xfer == ODIOCWDINFO) {
1257 newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK); 1260 newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK);
1258 if (newlabel == NULL) 1261 if (newlabel == NULL)
1259 return EIO; 1262 return EIO;
1260 memset(newlabel, 0, sizeof newlabel); 1263 memset(newlabel, 0, sizeof newlabel);
1261 memcpy(newlabel, addr, sizeof (struct olddisklabel)); 1264 memcpy(newlabel, addr, sizeof (struct olddisklabel));
1262 lp = newlabel; 1265 lp = newlabel;
1263 } else 1266 } else
1264#endif 1267#endif
1265 lp = (struct disklabel *)addr; 1268 lp = (struct disklabel *)addr;
1266 1269
1267 mutex_enter(&wd->sc_dk.dk_openlock); 1270 mutex_enter(&wd->sc_dk.dk_openlock);
1268 wd->sc_flags |= WDF_LABELLING; 1271 wd->sc_flags |= WDF_LABELLING;
1269 1272
1270 error = setdisklabel(wd->sc_dk.dk_label, 1273 error = setdisklabel(wd->sc_dk.dk_label,
1271 lp, /*wd->sc_dk.dk_openmask : */0, 1274 lp, /*wd->sc_dk.dk_openmask : */0,
1272 wd->sc_dk.dk_cpulabel); 1275 wd->sc_dk.dk_cpulabel);
1273 if (error == 0) { 1276 if (error == 0) {
1274 if (wd->drvp->state > RESET) { 1277 if (wd->drvp->state > RESET) {
1275 s = splbio(); 1278 s = splbio();
1276 wd->drvp->drive_flags |= DRIVE_RESET; 1279 wd->drvp->drive_flags |= DRIVE_RESET;
1277 splx(s); 1280 splx(s);
1278 } 1281 }
1279 if (xfer == DIOCWDINFO 1282 if (xfer == DIOCWDINFO
1280#ifdef __HAVE_OLD_DISKLABEL 1283#ifdef __HAVE_OLD_DISKLABEL
1281 || xfer == ODIOCWDINFO 1284 || xfer == ODIOCWDINFO
1282#endif 1285#endif
1283 ) 1286 )
1284 error = writedisklabel(WDLABELDEV(dev), 1287 error = writedisklabel(WDLABELDEV(dev),
1285 wdstrategy, wd->sc_dk.dk_label, 1288 wdstrategy, wd->sc_dk.dk_label,
1286 wd->sc_dk.dk_cpulabel); 1289 wd->sc_dk.dk_cpulabel);
1287 } 1290 }
1288 1291
1289 wd->sc_flags &= ~WDF_LABELLING; 1292 wd->sc_flags &= ~WDF_LABELLING;
1290 mutex_exit(&wd->sc_dk.dk_openlock); 1293 mutex_exit(&wd->sc_dk.dk_openlock);
1291#ifdef __HAVE_OLD_DISKLABEL 1294#ifdef __HAVE_OLD_DISKLABEL
1292 if (newlabel != NULL) 1295 if (newlabel != NULL)
1293 free(newlabel, M_TEMP); 1296 free(newlabel, M_TEMP);
1294#endif 1297#endif
1295 return error; 1298 return error;
1296 } 1299 }
1297 1300
1298 case DIOCKLABEL: 1301 case DIOCKLABEL:
1299 if (*(int *)addr) 1302 if (*(int *)addr)
1300 wd->sc_flags |= WDF_KLABEL; 1303 wd->sc_flags |= WDF_KLABEL;
1301 else 1304 else
1302 wd->sc_flags &= ~WDF_KLABEL; 1305 wd->sc_flags &= ~WDF_KLABEL;
1303 return 0; 1306 return 0;
1304 1307
1305 case DIOCWLABEL: 1308 case DIOCWLABEL:
1306 if ((flag & FWRITE) == 0) 1309 if ((flag & FWRITE) == 0)
1307 return EBADF; 1310 return EBADF;
1308 if (*(int *)addr) 1311 if (*(int *)addr)
1309 wd->sc_flags |= WDF_WLABEL; 1312 wd->sc_flags |= WDF_WLABEL;
1310 else 1313 else
1311 wd->sc_flags &= ~WDF_WLABEL; 1314 wd->sc_flags &= ~WDF_WLABEL;
1312 return 0; 1315 return 0;
1313 1316
1314 case DIOCGDEFLABEL: 1317 case DIOCGDEFLABEL:
1315 wdgetdefaultlabel(wd, (struct disklabel *)addr); 1318 wdgetdefaultlabel(wd, (struct disklabel *)addr);
1316 return 0; 1319 return 0;
1317#ifdef __HAVE_OLD_DISKLABEL 1320#ifdef __HAVE_OLD_DISKLABEL
1318 case ODIOCGDEFLABEL: 1321 case ODIOCGDEFLABEL:
1319 newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK); 1322 newlabel = malloc(sizeof *newlabel, M_TEMP, M_WAITOK);
1320 if (newlabel == NULL) 1323 if (newlabel == NULL)
1321 return EIO; 1324 return EIO;
1322 wdgetdefaultlabel(wd, newlabel); 1325 wdgetdefaultlabel(wd, newlabel);
1323 if (newlabel->d_npartitions <= OLDMAXPARTITIONS) 1326 if (newlabel->d_npartitions <= OLDMAXPARTITIONS)
1324 memcpy(addr, &newlabel, sizeof (struct olddisklabel)); 1327 memcpy(addr, &newlabel, sizeof (struct olddisklabel));
1325 else 1328 else
1326 error = ENOTTY; 1329 error = ENOTTY;
1327 free(newlabel, M_TEMP); 1330 free(newlabel, M_TEMP);
1328 return error; 1331 return error;
1329#endif 1332#endif
1330 1333
1331#ifdef notyet 1334#ifdef notyet
1332 case DIOCWFORMAT: 1335 case DIOCWFORMAT:
1333 if ((flag & FWRITE) == 0) 1336 if ((flag & FWRITE) == 0)
1334 return EBADF; 1337 return EBADF;
1335 { 1338 {
1336 register struct format_op *fop; 1339 register struct format_op *fop;
1337 struct iovec aiov; 1340 struct iovec aiov;
1338 struct uio auio; 1341 struct uio auio;
1339 1342
1340 fop = (struct format_op *)addr; 1343 fop = (struct format_op *)addr;
1341 aiov.iov_base = fop->df_buf; 1344 aiov.iov_base = fop->df_buf;
1342 aiov.iov_len = fop->df_count; 1345 aiov.iov_len = fop->df_count;
1343 auio.uio_iov = &aiov; 1346 auio.uio_iov = &aiov;
1344 auio.uio_iovcnt = 1; 1347 auio.uio_iovcnt = 1;
1345 auio.uio_resid = fop->df_count; 1348 auio.uio_resid = fop->df_count;
1346 auio.uio_offset = 1349 auio.uio_offset =
1347 fop->df_startblk * wd->sc_dk.dk_label->d_secsize; 1350 fop->df_startblk * wd->sc_dk.dk_label->d_secsize;
1348 auio.uio_vmspace = l->l_proc->p_vmspace; 1351 auio.uio_vmspace = l->l_proc->p_vmspace;
1349 error = physio(wdformat, NULL, dev, B_WRITE, minphys, 1352 error = physio(wdformat, NULL, dev, B_WRITE, minphys,
1350 &auio); 1353 &auio);
1351 fop->df_count -= auio.uio_resid; 1354 fop->df_count -= auio.uio_resid;
1352 fop->df_reg[0] = wdc->sc_status; 1355 fop->df_reg[0] = wdc->sc_status;
1353 fop->df_reg[1] = wdc->sc_error; 1356 fop->df_reg[1] = wdc->sc_error;
1354 return error; 1357 return error;
1355 } 1358 }
1356#endif 1359#endif
1357 case DIOCGCACHE: 1360 case DIOCGCACHE:
1358 return wd_getcache(wd, (int *)addr); 1361 return wd_getcache(wd, (int *)addr);
1359 1362
1360 case DIOCSCACHE: 1363 case DIOCSCACHE:
1361 return wd_setcache(wd, *(int *)addr); 1364 return wd_setcache(wd, *(int *)addr);
1362 1365
1363 case DIOCCACHESYNC: 1366 case DIOCCACHESYNC:
1364 return wd_flushcache(wd, AT_WAIT); 1367 return wd_flushcache(wd, AT_WAIT);
1365 1368
1366 case ATAIOCCOMMAND: 1369 case ATAIOCCOMMAND:
1367 /* 1370 /*
1368 * Make sure this command is (relatively) safe first 1371 * Make sure this command is (relatively) safe first
1369 */ 1372 */
1370 if ((((atareq_t *) addr)->flags & ATACMD_READ) == 0 && 1373 if ((((atareq_t *) addr)->flags & ATACMD_READ) == 0 &&
1371 (flag & FWRITE) == 0) 1374 (flag & FWRITE) == 0)
1372 return (EBADF); 1375 return (EBADF);
1373 { 1376 {
1374 struct wd_ioctl *wi; 1377 struct wd_ioctl *wi;
1375 atareq_t *atareq = (atareq_t *) addr; 1378 atareq_t *atareq = (atareq_t *) addr;
1376 int error1; 1379 int error1;
1377 1380
1378 wi = wi_get(); 1381 wi = wi_get();
1379 wi->wi_softc = wd; 1382 wi->wi_softc = wd;
1380 wi->wi_atareq = *atareq; 1383 wi->wi_atareq = *atareq;
1381 1384
1382 if (atareq->datalen && atareq->flags & 1385 if (atareq->datalen && atareq->flags &
1383 (ATACMD_READ | ATACMD_WRITE)) { 1386 (ATACMD_READ | ATACMD_WRITE)) {
1384 void *tbuf; 1387 void *tbuf;
1385 if (atareq->datalen < DEV_BSIZE 1388 if (atareq->datalen < DEV_BSIZE
1386 && atareq->command == WDCC_IDENTIFY) { 1389 && atareq->command == WDCC_IDENTIFY) {
1387 tbuf = malloc(DEV_BSIZE, M_TEMP, M_WAITOK); 1390 tbuf = malloc(DEV_BSIZE, M_TEMP, M_WAITOK);
1388 wi->wi_iov.iov_base = tbuf; 1391 wi->wi_iov.iov_base = tbuf;
1389 wi->wi_iov.iov_len = DEV_BSIZE; 1392 wi->wi_iov.iov_len = DEV_BSIZE;
1390 UIO_SETUP_SYSSPACE(&wi->wi_uio); 1393 UIO_SETUP_SYSSPACE(&wi->wi_uio);
1391 } else { 1394 } else {
1392 tbuf = NULL; 1395 tbuf = NULL;
1393 wi->wi_iov.iov_base = atareq->databuf; 1396 wi->wi_iov.iov_base = atareq->databuf;
1394 wi->wi_iov.iov_len = atareq->datalen; 1397 wi->wi_iov.iov_len = atareq->datalen;
1395 wi->wi_uio.uio_vmspace = l->l_proc->p_vmspace; 1398 wi->wi_uio.uio_vmspace = l->l_proc->p_vmspace;
1396 } 1399 }
1397 wi->wi_uio.uio_iov = &wi->wi_iov; 1400 wi->wi_uio.uio_iov = &wi->wi_iov;
1398 wi->wi_uio.uio_iovcnt = 1; 1401 wi->wi_uio.uio_iovcnt = 1;
1399 wi->wi_uio.uio_resid = atareq->datalen; 1402 wi->wi_uio.uio_resid = atareq->datalen;
1400 wi->wi_uio.uio_offset = 0; 1403 wi->wi_uio.uio_offset = 0;
1401 wi->wi_uio.uio_rw = 1404 wi->wi_uio.uio_rw =
1402 (atareq->flags & ATACMD_READ) ? B_READ : B_WRITE; 1405 (atareq->flags & ATACMD_READ) ? B_READ : B_WRITE;
1403 error1 = physio(wdioctlstrategy, &wi->wi_bp, dev, 1406 error1 = physio(wdioctlstrategy, &wi->wi_bp, dev,
1404 (atareq->flags & ATACMD_READ) ? B_READ : B_WRITE, 1407 (atareq->flags & ATACMD_READ) ? B_READ : B_WRITE,
1405 minphys, &wi->wi_uio); 1408 minphys, &wi->wi_uio);
1406 if (tbuf != NULL && error1 == 0) { 1409 if (tbuf != NULL && error1 == 0) {
1407 error1 = copyout(tbuf, atareq->databuf, 1410 error1 = copyout(tbuf, atareq->databuf,
1408 atareq->datalen); 1411 atareq->datalen);
1409 free(tbuf, M_TEMP); 1412 free(tbuf, M_TEMP);
1410 } 1413 }
1411 } else { 1414 } else {
1412 /* No need to call physio if we don't have any 1415 /* No need to call physio if we don't have any
1413 user data */ 1416 user data */
1414 wi->wi_bp.b_flags = 0; 1417 wi->wi_bp.b_flags = 0;
1415 wi->wi_bp.b_data = 0; 1418 wi->wi_bp.b_data = 0;
1416 wi->wi_bp.b_bcount = 0; 1419 wi->wi_bp.b_bcount = 0;
1417 wi->wi_bp.b_dev = 0; 1420 wi->wi_bp.b_dev = 0;
1418 wi->wi_bp.b_proc = l->l_proc; 1421 wi->wi_bp.b_proc = l->l_proc;
1419 wdioctlstrategy(&wi->wi_bp); 1422 wdioctlstrategy(&wi->wi_bp);
1420 error1 = wi->wi_bp.b_error; 1423 error1 = wi->wi_bp.b_error;
1421 } 1424 }
1422 *atareq = wi->wi_atareq; 1425 *atareq = wi->wi_atareq;
1423 wi_free(wi); 1426 wi_free(wi);
1424 return(error1); 1427 return(error1);
1425 } 1428 }
1426 1429
1427 case DIOCAWEDGE: 1430 case DIOCAWEDGE:
1428 { 1431 {
1429 struct dkwedge_info *dkw = (void *) addr; 1432 struct dkwedge_info *dkw = (void *) addr;
1430 1433
1431 if ((flag & FWRITE) == 0) 1434 if ((flag & FWRITE) == 0)
1432 return (EBADF); 1435 return (EBADF);
1433 1436
1434 /* If the ioctl happens here, the parent is us. */ 1437 /* If the ioctl happens here, the parent is us. */
1435 strcpy(dkw->dkw_parent, device_xname(wd->sc_dev)); 1438 strcpy(dkw->dkw_parent, device_xname(wd->sc_dev));
1436 return (dkwedge_add(dkw)); 1439 return (dkwedge_add(dkw));
1437 } 1440 }
1438 1441
1439 case DIOCDWEDGE: 1442 case DIOCDWEDGE:
1440 { 1443 {
1441 struct dkwedge_info *dkw = (void *) addr; 1444 struct dkwedge_info *dkw = (void *) addr;
1442 1445
1443 if ((flag & FWRITE) == 0) 1446 if ((flag & FWRITE) == 0)
1444 return (EBADF); 1447 return (EBADF);
1445 1448
1446 /* If the ioctl happens here, the parent is us. */ 1449 /* If the ioctl happens here, the parent is us. */
1447 strcpy(dkw->dkw_parent, device_xname(wd->sc_dev)); 1450 strcpy(dkw->dkw_parent, device_xname(wd->sc_dev));
1448 return (dkwedge_del(dkw)); 1451 return (dkwedge_del(dkw));
1449 } 1452 }
1450 1453
1451 case DIOCLWEDGES: 1454 case DIOCLWEDGES:
1452 { 1455 {
1453 struct dkwedge_list *dkwl = (void *) addr; 1456 struct dkwedge_list *dkwl = (void *) addr;
1454 1457
1455 return (dkwedge_list(&wd->sc_dk, dkwl, l)); 1458 return (dkwedge_list(&wd->sc_dk, dkwl, l));
1456 } 1459 }
1457 1460
1458 case DIOCGSTRATEGY: 1461 case DIOCGSTRATEGY:
1459 { 1462 {
1460 struct disk_strategy *dks = (void *)addr; 1463 struct disk_strategy *dks = (void *)addr;
1461 1464
1462 s = splbio(); 1465 s = splbio();
1463 strlcpy(dks->dks_name, bufq_getstrategyname(wd->sc_q), 1466 strlcpy(dks->dks_name, bufq_getstrategyname(wd->sc_q),
1464 sizeof(dks->dks_name)); 1467 sizeof(dks->dks_name));
1465 splx(s); 1468 splx(s);
1466 dks->dks_paramlen = 0; 1469 dks->dks_paramlen = 0;
1467 1470
1468 return 0; 1471 return 0;
1469 } 1472 }
1470  1473
1471 case DIOCSSTRATEGY: 1474 case DIOCSSTRATEGY:
1472 { 1475 {
1473 struct disk_strategy *dks = (void *)addr; 1476 struct disk_strategy *dks = (void *)addr;
1474 struct bufq_state *new; 1477 struct bufq_state *new;
1475 struct bufq_state *old; 1478 struct bufq_state *old;
1476 1479
1477 if ((flag & FWRITE) == 0) { 1480 if ((flag & FWRITE) == 0) {
1478 return EBADF; 1481 return EBADF;
1479 } 1482 }
1480 if (dks->dks_param != NULL) { 1483 if (dks->dks_param != NULL) {
1481 return EINVAL; 1484 return EINVAL;
1482 } 1485 }
1483 dks->dks_name[sizeof(dks->dks_name) - 1] = 0; /* ensure term */ 1486 dks->dks_name[sizeof(dks->dks_name) - 1] = 0; /* ensure term */
1484 error = bufq_alloc(&new, dks->dks_name, 1487 error = bufq_alloc(&new, dks->dks_name,
1485 BUFQ_EXACT|BUFQ_SORT_RAWBLOCK); 1488 BUFQ_EXACT|BUFQ_SORT_RAWBLOCK);
1486 if (error) { 1489 if (error) {
1487 return error; 1490 return error;
1488 } 1491 }
1489 s = splbio(); 1492 s = splbio();
1490 old = wd->sc_q; 1493 old = wd->sc_q;
1491 bufq_move(new, old); 1494 bufq_move(new, old);
1492 wd->sc_q = new; 1495 wd->sc_q = new;
1493 splx(s); 1496 splx(s);
1494 bufq_free(old); 1497 bufq_free(old);
1495 1498
1496 return 0; 1499 return 0;
1497 } 1500 }
1498 1501
1499 default: 1502 default:
1500 return ENOTTY; 1503 return ENOTTY;
1501 } 1504 }
1502 1505
1503#ifdef DIAGNOSTIC 1506#ifdef DIAGNOSTIC
1504 panic("wdioctl: impossible"); 1507 panic("wdioctl: impossible");
1505#endif 1508#endif
1506} 1509}
1507 1510
1508#ifdef B_FORMAT 1511#ifdef B_FORMAT
1509int 1512int
1510wdformat(struct buf *bp) 1513wdformat(struct buf *bp)
1511{ 1514{
1512 1515
1513 bp->b_flags |= B_FORMAT; 1516 bp->b_flags |= B_FORMAT;
1514 return wdstrategy(bp); 1517 return wdstrategy(bp);
1515} 1518}
1516#endif 1519#endif
1517 1520
1518int 1521int
1519wdsize(dev_t dev) 1522wdsize(dev_t dev)
1520{ 1523{
1521 struct wd_softc *wd; 1524 struct wd_softc *wd;
1522 int part, omask; 1525 int part, omask;
1523 int size; 1526 int size;
1524 1527
1525 ATADEBUG_PRINT(("wdsize\n"), DEBUG_FUNCS); 1528 ATADEBUG_PRINT(("wdsize\n"), DEBUG_FUNCS);
1526 1529
1527 wd = device_lookup_private(&wd_cd, WDUNIT(dev)); 1530 wd = device_lookup_private(&wd_cd, WDUNIT(dev));
1528 if (wd == NULL) 1531 if (wd == NULL)
1529 return (-1); 1532 return (-1);
1530 1533
1531 part = WDPART(dev); 1534 part = WDPART(dev);
1532 omask = wd->sc_dk.dk_openmask & (1 << part); 1535 omask = wd->sc_dk.dk_openmask & (1 << part);
1533 1536
1534 if (omask == 0 && wdopen(dev, 0, S_IFBLK, NULL) != 0) 1537 if (omask == 0 && wdopen(dev, 0, S_IFBLK, NULL) != 0)
1535 return (-1); 1538 return (-1);
1536 if (wd->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP) 1539 if (wd->sc_dk.dk_label->d_partitions[part].p_fstype != FS_SWAP)
1537 size = -1; 1540 size = -1;
1538 else 1541 else
1539 size = wd->sc_dk.dk_label->d_partitions[part].p_size * 1542 size = wd->sc_dk.dk_label->d_partitions[part].p_size *
1540 (wd->sc_dk.dk_label->d_secsize / DEV_BSIZE); 1543 (wd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
1541 if (omask == 0 && wdclose(dev, 0, S_IFBLK, NULL) != 0) 1544 if (omask == 0 && wdclose(dev, 0, S_IFBLK, NULL) != 0)
1542 return (-1); 1545 return (-1);
1543 return (size); 1546 return (size);
1544} 1547}
1545 1548
1546/* #define WD_DUMP_NOT_TRUSTED if you just want to watch */ 1549/* #define WD_DUMP_NOT_TRUSTED if you just want to watch */
1547static int wddoingadump = 0; 1550static int wddoingadump = 0;
1548static int wddumprecalibrated = 0; 1551static int wddumprecalibrated = 0;
1549 1552
1550/* 1553/*
1551 * Dump core after a system crash. 1554 * Dump core after a system crash.
1552 */ 1555 */
1553int 1556int
1554wddump(dev_t dev, daddr_t blkno, void *va, size_t size) 1557wddump(dev_t dev, daddr_t blkno, void *va, size_t size)
1555{ 1558{
1556 struct wd_softc *wd; /* disk unit to do the I/O */ 1559 struct wd_softc *wd; /* disk unit to do the I/O */
1557 struct disklabel *lp; /* disk's disklabel */ 1560 struct disklabel *lp; /* disk's disklabel */
1558 int part, err; 1561 int part, err;
1559 int nblks; /* total number of sectors left to write */ 1562 int nblks; /* total number of sectors left to write */
1560 1563
1561 /* Check if recursive dump; if so, punt. */ 1564 /* Check if recursive dump; if so, punt. */
1562 if (wddoingadump) 1565 if (wddoingadump)
1563 return EFAULT; 1566 return EFAULT;
1564 wddoingadump = 1; 1567 wddoingadump = 1;
1565 1568
1566 wd = device_lookup_private(&wd_cd, WDUNIT(dev)); 1569 wd = device_lookup_private(&wd_cd, WDUNIT(dev));
1567 if (wd == NULL) 1570 if (wd == NULL)
1568 return (ENXIO); 1571 return (ENXIO);
1569 1572
1570 part = WDPART(dev); 1573 part = WDPART(dev);
1571 1574
1572 /* Convert to disk sectors. Request must be a multiple of size. */ 1575 /* Convert to disk sectors. Request must be a multiple of size. */
1573 lp = wd->sc_dk.dk_label; 1576 lp = wd->sc_dk.dk_label;
1574 if ((size % lp->d_secsize) != 0) 1577 if ((size % lp->d_secsize) != 0)
1575 return EFAULT; 1578 return EFAULT;
1576 nblks = size / lp->d_secsize; 1579 nblks = size / lp->d_secsize;
1577 blkno = blkno / (lp->d_secsize / DEV_BSIZE); 1580 blkno = blkno / (lp->d_secsize / DEV_BSIZE);
1578 1581
1579 /* Check transfer bounds against partition size. */ 1582 /* Check transfer bounds against partition size. */
1580 if ((blkno < 0) || ((blkno + nblks) > lp->d_partitions[part].p_size)) 1583 if ((blkno < 0) || ((blkno + nblks) > lp->d_partitions[part].p_size))
1581 return EINVAL; 1584 return EINVAL;
1582 1585
1583 /* Offset block number to start of partition. */ 1586 /* Offset block number to start of partition. */
1584 blkno += lp->d_partitions[part].p_offset; 1587 blkno += lp->d_partitions[part].p_offset;
1585 1588
1586 /* Recalibrate, if first dump transfer. */ 1589 /* Recalibrate, if first dump transfer. */
1587 if (wddumprecalibrated == 0) { 1590 if (wddumprecalibrated == 0) {
1588 wddumprecalibrated = 1; 1591 wddumprecalibrated = 1;
1589 (*wd->atabus->ata_reset_drive)(wd->drvp, 1592 (*wd->atabus->ata_reset_drive)(wd->drvp,
1590 AT_POLL | AT_RST_EMERG); 1593 AT_POLL | AT_RST_EMERG);
1591 wd->drvp->state = RESET; 1594 wd->drvp->state = RESET;
1592 } 1595 }
1593 1596
1594 wd->sc_bp = NULL; 1597 wd->sc_bp = NULL;
1595 wd->sc_wdc_bio.blkno = blkno; 1598 wd->sc_wdc_bio.blkno = blkno;
1596 wd->sc_wdc_bio.flags = ATA_POLL; 1599 wd->sc_wdc_bio.flags = ATA_POLL;
1597 if (wd->sc_flags & WDF_LBA48 && 1600 if (wd->sc_flags & WDF_LBA48 &&
1598 (wd->sc_wdc_bio.blkno + nblks) > wd->sc_capacity28) 1601 (wd->sc_wdc_bio.blkno + nblks) > wd->sc_capacity28)
1599 wd->sc_wdc_bio.flags |= ATA_LBA48; 1602 wd->sc_wdc_bio.flags |= ATA_LBA48;
1600 if (wd->sc_flags & WDF_LBA) 1603 if (wd->sc_flags & WDF_LBA)
1601 wd->sc_wdc_bio.flags |= ATA_LBA; 1604 wd->sc_wdc_bio.flags |= ATA_LBA;
1602 wd->sc_wdc_bio.bcount = nblks * lp->d_secsize; 1605 wd->sc_wdc_bio.bcount = nblks * lp->d_secsize;
1603 wd->sc_wdc_bio.databuf = va; 1606 wd->sc_wdc_bio.databuf = va;
1604#ifndef WD_DUMP_NOT_TRUSTED 1607#ifndef WD_DUMP_NOT_TRUSTED
1605 switch (err = wd->atabus->ata_bio(wd->drvp, &wd->sc_wdc_bio)) { 1608 switch (err = wd->atabus->ata_bio(wd->drvp, &wd->sc_wdc_bio)) {
1606 case ATACMD_TRY_AGAIN: 1609 case ATACMD_TRY_AGAIN:
1607 panic("wddump: try again"); 1610 panic("wddump: try again");
1608 break; 1611 break;
1609 case ATACMD_QUEUED: 1612 case ATACMD_QUEUED:
1610 panic("wddump: polled command has been queued"); 1613 panic("wddump: polled command has been queued");
1611 break; 1614 break;
1612 case ATACMD_COMPLETE: 1615 case ATACMD_COMPLETE:
1613 break; 1616 break;
1614 default: 1617 default:
1615 panic("wddump: unknown atacmd code %d", err); 1618 panic("wddump: unknown atacmd code %d", err);
1616 } 1619 }
1617 switch(err = wd->sc_wdc_bio.error) { 1620 switch(err = wd->sc_wdc_bio.error) {
1618 case TIMEOUT: 1621 case TIMEOUT:
1619 printf("wddump: device timed out"); 1622 printf("wddump: device timed out");
1620 err = EIO; 1623 err = EIO;
1621 break; 1624 break;
1622 case ERR_DF: 1625 case ERR_DF:
1623 printf("wddump: drive fault"); 1626 printf("wddump: drive fault");
1624 err = EIO; 1627 err = EIO;
1625 break; 1628 break;
1626 case ERR_DMA: 1629 case ERR_DMA:
1627 printf("wddump: DMA error"); 1630 printf("wddump: DMA error");
1628 err = EIO; 1631 err = EIO;
1629 break; 1632 break;
1630 case ERROR: 1633 case ERROR:
1631 printf("wddump: "); 1634 printf("wddump: ");
1632 wdperror(wd); 1635 wdperror(wd);
1633 err = EIO; 1636 err = EIO;
1634 break; 1637 break;
1635 case NOERROR: 1638 case NOERROR:
1636 err = 0; 1639 err = 0;
1637 break; 1640 break;
1638 default: 1641 default:
1639 panic("wddump: unknown error type %d", err);  1642 panic("wddump: unknown error type %d", err);
1640 } 1643 }
1641 if (err != 0) { 1644 if (err != 0) {
1642 printf("\n"); 1645 printf("\n");
1643 return err; 1646 return err;
1644 } 1647 }
1645#else /* WD_DUMP_NOT_TRUSTED */ 1648#else /* WD_DUMP_NOT_TRUSTED */
1646 /* Let's just talk about this first... */ 1649 /* Let's just talk about this first... */
1647 printf("wd%d: dump addr 0x%x, cylin %d, head %d, sector %d\n", 1650 printf("wd%d: dump addr 0x%x, cylin %d, head %d, sector %d\n",
1648 unit, va, cylin, head, sector); 1651 unit, va, cylin, head, sector);
1649 delay(500 * 1000); /* half a second */ 1652 delay(500 * 1000); /* half a second */
1650#endif 1653#endif
1651 1654
1652 wddoingadump = 0; 1655 wddoingadump = 0;
1653 return 0; 1656 return 0;
1654} 1657}
1655 1658
1656#ifdef HAS_BAD144_HANDLING 1659#ifdef HAS_BAD144_HANDLING
1657/* 1660/*
1658 * Internalize the bad sector table. 1661 * Internalize the bad sector table.
1659 */ 1662 */
1660void 1663void
1661bad144intern(struct wd_softc *wd) 1664bad144intern(struct wd_softc *wd)
1662{ 1665{
1663 struct dkbad *bt = &wd->sc_dk.dk_cpulabel->bad; 1666 struct dkbad *bt = &wd->sc_dk.dk_cpulabel->bad;
1664 struct disklabel *lp = wd->sc_dk.dk_label; 1667 struct disklabel *lp = wd->sc_dk.dk_label;
1665 int i = 0; 1668 int i = 0;
1666 1669
1667 ATADEBUG_PRINT(("bad144intern\n"), DEBUG_XFERS); 1670 ATADEBUG_PRINT(("bad144intern\n"), DEBUG_XFERS);
1668 1671
1669 for (; i < NBT_BAD; i++) { 1672 for (; i < NBT_BAD; i++) {
1670 if (bt->bt_bad[i].bt_cyl == 0xffff) 1673 if (bt->bt_bad[i].bt_cyl == 0xffff)
1671 break; 1674 break;
1672 wd->sc_badsect[i] = 1675 wd->sc_badsect[i] =
1673 bt->bt_bad[i].bt_cyl * lp->d_secpercyl + 1676 bt->bt_bad[i].bt_cyl * lp->d_secpercyl +
1674 (bt->bt_bad[i].bt_trksec >> 8) * lp->d_nsectors + 1677 (bt->bt_bad[i].bt_trksec >> 8) * lp->d_nsectors +
1675 (bt->bt_bad[i].bt_trksec & 0xff); 1678 (bt->bt_bad[i].bt_trksec & 0xff);
1676 } 1679 }
1677 for (; i < NBT_BAD+1; i++) 1680 for (; i < NBT_BAD+1; i++)
1678 wd->sc_badsect[i] = -1; 1681 wd->sc_badsect[i] = -1;
1679} 1682}
1680#endif 1683#endif
1681 1684
1682static void 1685static void
1683wd_params_to_properties(struct wd_softc *wd, struct ataparams *params) 1686wd_params_to_properties(struct wd_softc *wd, struct ataparams *params)
1684{ 1687{
1685 prop_dictionary_t disk_info, odisk_info, geom; 1688 prop_dictionary_t disk_info, odisk_info, geom;
1686 const char *cp; 1689 const char *cp;
1687 1690
1688 disk_info = prop_dictionary_create(); 1691 disk_info = prop_dictionary_create();
1689 1692
1690 if (strcmp(wd->sc_params.atap_model, "ST506") == 0) 1693 if (strcmp(wd->sc_params.atap_model, "ST506") == 0)
1691 cp = "ST506"; 1694 cp = "ST506";
1692 else { 1695 else {
1693 /* XXX Should have a case for ATA here, too. */ 1696 /* XXX Should have a case for ATA here, too. */
1694 cp = "ESDI"; 1697 cp = "ESDI";
1695 } 1698 }
1696 prop_dictionary_set_cstring_nocopy(disk_info, "type", cp); 1699 prop_dictionary_set_cstring_nocopy(disk_info, "type", cp);
1697 1700
1698 geom = prop_dictionary_create(); 1701 geom = prop_dictionary_create();
1699 1702
1700 prop_dictionary_set_uint64(geom, "sectors-per-unit", wd->sc_capacity); 1703 prop_dictionary_set_uint64(geom, "sectors-per-unit", wd->sc_capacity);
1701 1704
1702 prop_dictionary_set_uint32(geom, "sector-size", 1705 prop_dictionary_set_uint32(geom, "sector-size",
1703 DEV_BSIZE /* XXX 512? */); 1706 DEV_BSIZE /* XXX 512? */);
1704 1707
1705 prop_dictionary_set_uint16(geom, "sectors-per-track", 1708 prop_dictionary_set_uint16(geom, "sectors-per-track",
1706 wd->sc_params.atap_sectors); 1709 wd->sc_params.atap_sectors);
1707 1710
1708 prop_dictionary_set_uint16(geom, "tracks-per-cylinder", 1711 prop_dictionary_set_uint16(geom, "tracks-per-cylinder",
1709 wd->sc_params.atap_heads); 1712 wd->sc_params.atap_heads);
1710 1713
1711 if (wd->sc_flags & WDF_LBA) 1714 if (wd->sc_flags & WDF_LBA)
1712 prop_dictionary_set_uint64(geom, "cylinders-per-unit", 1715 prop_dictionary_set_uint64(geom, "cylinders-per-unit",
1713 wd->sc_capacity / 1716 wd->sc_capacity /
1714 (wd->sc_params.atap_heads * 1717 (wd->sc_params.atap_heads *
1715 wd->sc_params.atap_sectors)); 1718 wd->sc_params.atap_sectors));
1716 else 1719 else
1717 prop_dictionary_set_uint16(geom, "cylinders-per-unit", 1720 prop_dictionary_set_uint16(geom, "cylinders-per-unit",
1718 wd->sc_params.atap_cylinders); 1721 wd->sc_params.atap_cylinders);
1719 1722
1720 prop_dictionary_set(disk_info, "geometry", geom); 1723 prop_dictionary_set(disk_info, "geometry", geom);
1721 prop_object_release(geom); 1724 prop_object_release(geom);
1722 1725
1723 prop_dictionary_set(device_properties(wd->sc_dev), 1726 prop_dictionary_set(device_properties(wd->sc_dev),
1724 "disk-info", disk_info); 1727 "disk-info", disk_info);
1725 1728
1726 /* 1729 /*
1727 * Don't release disk_info here; we keep a reference to it. 1730 * Don't release disk_info here; we keep a reference to it.
1728 * disk_detach() will release it when we go away. 1731 * disk_detach() will release it when we go away.
1729 */ 1732 */
1730 1733
1731 odisk_info = wd->sc_dk.dk_info; 1734 odisk_info = wd->sc_dk.dk_info;
1732 wd->sc_dk.dk_info = disk_info; 1735 wd->sc_dk.dk_info = disk_info;
1733 if (odisk_info) 1736 if (odisk_info)
1734 prop_object_release(odisk_info); 1737 prop_object_release(odisk_info);
1735} 1738}
1736 1739
1737int 1740int
1738wd_get_params(struct wd_softc *wd, u_int8_t flags, struct ataparams *params) 1741wd_get_params(struct wd_softc *wd, u_int8_t flags, struct ataparams *params)
1739{ 1742{
1740 1743
1741 switch (wd->atabus->ata_get_params(wd->drvp, flags, params)) { 1744 switch (wd->atabus->ata_get_params(wd->drvp, flags, params)) {
1742 case CMD_AGAIN: 1745 case CMD_AGAIN:
1743 return 1; 1746 return 1;
1744 case CMD_ERR: 1747 case CMD_ERR:
1745 /* 1748 /*
1746 * We `know' there's a drive here; just assume it's old. 1749 * We `know' there's a drive here; just assume it's old.
1747 * This geometry is only used to read the MBR and print a 1750 * This geometry is only used to read the MBR and print a
1748 * (false) attach message. 1751 * (false) attach message.
1749 */ 1752 */
1750 strncpy(params->atap_model, "ST506", 1753 strncpy(params->atap_model, "ST506",
1751 sizeof params->atap_model); 1754 sizeof params->atap_model);
1752 params->atap_config = ATA_CFG_FIXED; 1755 params->atap_config = ATA_CFG_FIXED;
1753 params->atap_cylinders = 1024; 1756 params->atap_cylinders = 1024;
1754 params->atap_heads = 8; 1757 params->atap_heads = 8;
1755 params->atap_sectors = 17; 1758 params->atap_sectors = 17;
1756 params->atap_multi = 1; 1759 params->atap_multi = 1;
1757 params->atap_capabilities1 = params->atap_capabilities2 = 0; 1760 params->atap_capabilities1 = params->atap_capabilities2 = 0;
1758 wd->drvp->ata_vers = -1; /* Mark it as pre-ATA */ 1761 wd->drvp->ata_vers = -1; /* Mark it as pre-ATA */
1759 /* FALLTHROUGH */ 1762 /* FALLTHROUGH */
1760 case CMD_OK: 1763 case CMD_OK:
1761 wd_params_to_properties(wd, params); 1764 wd_params_to_properties(wd, params);
1762 return 0; 1765 return 0;
1763 default: 1766 default:
1764 panic("wd_get_params: bad return code from ata_get_params"); 1767 panic("wd_get_params: bad return code from ata_get_params");
1765 /* NOTREACHED */ 1768 /* NOTREACHED */
1766 } 1769 }
1767} 1770}
1768 1771
1769int 1772int
1770wd_getcache(struct wd_softc *wd, int *bitsp) 1773wd_getcache(struct wd_softc *wd, int *bitsp)
1771{ 1774{
1772 struct ataparams params; 1775 struct ataparams params;
1773 1776
1774 if (wd_get_params(wd, AT_WAIT, &params) != 0) 1777 if (wd_get_params(wd, AT_WAIT, &params) != 0)
1775 return EIO; 1778 return EIO;
1776 if (params.atap_cmd_set1 == 0x0000 || 1779 if (params.atap_cmd_set1 == 0x0000 ||
1777 params.atap_cmd_set1 == 0xffff || 1780 params.atap_cmd_set1 == 0xffff ||
1778 (params.atap_cmd_set1 & WDC_CMD1_CACHE) == 0) { 1781 (params.atap_cmd_set1 & WDC_CMD1_CACHE) == 0) {
1779 *bitsp = 0; 1782 *bitsp = 0;
1780 return 0; 1783 return 0;
1781 } 1784 }
1782 *bitsp = DKCACHE_WCHANGE | DKCACHE_READ; 1785 *bitsp = DKCACHE_WCHANGE | DKCACHE_READ;
1783 if (params.atap_cmd1_en & WDC_CMD1_CACHE) 1786 if (params.atap_cmd1_en & WDC_CMD1_CACHE)
1784 *bitsp |= DKCACHE_WRITE; 1787 *bitsp |= DKCACHE_WRITE;
1785 1788
1786 return 0; 1789 return 0;
1787} 1790}
1788 1791
1789const char at_errbits[] = "\20\10ERROR\11TIMEOU\12DF"; 1792const char at_errbits[] = "\20\10ERROR\11TIMEOU\12DF";
1790 1793
1791int 1794int
1792wd_setcache(struct wd_softc *wd, int bits) 1795wd_setcache(struct wd_softc *wd, int bits)
1793{ 1796{
1794 struct ataparams params; 1797 struct ataparams params;
1795 struct ata_command ata_c; 1798 struct ata_command ata_c;
1796 1799
1797 if (wd_get_params(wd, AT_WAIT, &params) != 0) 1800 if (wd_get_params(wd, AT_WAIT, &params) != 0)
1798 return EIO; 1801 return EIO;
1799 1802
1800 if (params.atap_cmd_set1 == 0x0000 || 1803 if (params.atap_cmd_set1 == 0x0000 ||
1801 params.atap_cmd_set1 == 0xffff || 1804 params.atap_cmd_set1 == 0xffff ||
1802 (params.atap_cmd_set1 & WDC_CMD1_CACHE) == 0) 1805 (params.atap_cmd_set1 & WDC_CMD1_CACHE) == 0)
1803 return EOPNOTSUPP; 1806 return EOPNOTSUPP;
1804 1807
1805 if ((bits & DKCACHE_READ) == 0 || 1808 if ((bits & DKCACHE_READ) == 0 ||
1806 (bits & DKCACHE_SAVE) != 0) 1809 (bits & DKCACHE_SAVE) != 0)
1807 return EOPNOTSUPP; 1810 return EOPNOTSUPP;
1808 1811
1809 memset(&ata_c, 0, sizeof(struct ata_command)); 1812 memset(&ata_c, 0, sizeof(struct ata_command));
1810 ata_c.r_command = SET_FEATURES; 1813 ata_c.r_command = SET_FEATURES;
1811 ata_c.r_st_bmask = 0; 1814 ata_c.r_st_bmask = 0;
1812 ata_c.r_st_pmask = 0; 1815 ata_c.r_st_pmask = 0;
1813 ata_c.timeout = 30000; /* 30s timeout */ 1816 ata_c.timeout = 30000; /* 30s timeout */
1814 ata_c.flags = AT_WAIT; 1817 ata_c.flags = AT_WAIT;
1815 if (bits & DKCACHE_WRITE) 1818 if (bits & DKCACHE_WRITE)
1816 ata_c.r_features = WDSF_WRITE_CACHE_EN; 1819 ata_c.r_features = WDSF_WRITE_CACHE_EN;
1817 else 1820 else
1818 ata_c.r_features = WDSF_WRITE_CACHE_DS; 1821 ata_c.r_features = WDSF_WRITE_CACHE_DS;
1819 if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) { 1822 if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
1820 aprint_error_dev(wd->sc_dev, 1823 aprint_error_dev(wd->sc_dev,
1821 "wd_setcache command not complete\n"); 1824 "wd_setcache command not complete\n");
1822 return EIO; 1825 return EIO;
1823 } 1826 }
1824 if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) { 1827 if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
1825 char sbuf[sizeof(at_errbits) + 64]; 1828 char sbuf[sizeof(at_errbits) + 64];
1826 snprintb(sbuf, sizeof(sbuf), at_errbits, ata_c.flags); 1829 snprintb(sbuf, sizeof(sbuf), at_errbits, ata_c.flags);
1827 aprint_error_dev(wd->sc_dev, "wd_setcache: status=%s\n", sbuf); 1830 aprint_error_dev(wd->sc_dev, "wd_setcache: status=%s\n", sbuf);
1828 return EIO; 1831 return EIO;
1829 } 1832 }
1830 return 0; 1833 return 0;