2 * Copyright (c) 1990 The Regents of the University of California.
5 * This code is derived from software contributed to Berkeley by
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * from: @(#)wd.c 7.2 (Berkeley) 5/9/91
37 * $FreeBSD: src/sys/i386/isa/wd.c,v 1.219.2.2 2000/08/04 22:31:07 peter Exp $
38 * $DragonFly: src/sys/dev/disk/wd/Attic/wd.c,v 1.2 2003/06/17 04:28:37 dillon Exp $
42 * o Bump error count after timeout.
43 * o Satisfy ATA timing in all cases.
44 * o Finish merging berry/sos timeout code (bump error count...).
45 * o Don't use polling except for initialization. Need to
46 * reorganize the state machine. Then "extra" interrupts
47 * shouldn't happen (except maybe one for initialization).
48 * o Support extended DOS partitions.
49 * o Support swapping to DOS partitions.
50 * o Handle clustering, disklabelling, DOS
51 * partitions and swapping driver-independently.
52 * Swapping will need new
53 * driver entries for polled reinit and polled write).
65 #include "opt_hw_wdog.h"
66 #include "opt_ide_delay.h"
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/kernel.h>
73 #include <sys/disklabel.h>
74 #include <sys/diskslice.h>
76 #include <sys/devicestat.h>
77 #include <sys/malloc.h>
79 #include <machine/bootinfo.h>
80 #include <machine/clock.h>
81 #include <machine/md_var.h>
82 #include <i386/isa/isa.h>
83 #include <i386/isa/isa_device.h>
84 #include <i386/isa/wdreg.h>
85 #include <sys/syslog.h>
89 #include <i386/isa/atapi.h>
91 extern void wdstart(int ctrlr);
94 #define TIMEOUT IDE_DELAY
98 #define RETRIES 5 /* number of retries before giving up */
99 #define RECOVERYTIME 500000 /* usec for controller to recover after err */
100 #define MAXTRANSFER 255 /* max size of transfer in sectors */
101 /* correct max is 256 but some controllers */
102 /* can't handle that in all cases */
103 #define WDOPT_32BIT 0x8000
104 #define WDOPT_SLEEPHACK 0x4000
105 #define WDOPT_DMA 0x2000
106 #define WDOPT_LBA 0x1000
107 #define WDOPT_FORCEHD(x) (((x)&0x0f00)>>8)
108 #define WDOPT_MULTIMASK 0x00ff
111 * Drive states. Used to initialize drive.
114 #define CLOSED 0 /* disk is closed. */
115 #define WANTOPEN 1 /* open requested, not started */
116 #define RECAL 2 /* doing restore */
117 #define OPEN 3 /* done with open */
122 * Disk geometry. A small part of struct disklabel.
123 * XXX disklabel.5 contains an old clone of disklabel.h.
126 u_long d_secsize; /* # of bytes per sector */
127 u_long d_nsectors; /* # of data sectors per track */
128 u_long d_ntracks; /* # of tracks per cylinder */
129 u_long d_ncylinders; /* # of data cylinders per unit */
130 u_long d_secpercyl; /* # of data sectors per cylinder */
131 u_long d_secperunit; /* # of data sectors per unit */
132 u_long d_precompcyl; /* XXX always 0 */
136 * The structure of a disk drive.
139 u_int dk_bc; /* byte count left */
140 short dk_skip; /* blocks already transferred */
141 int dk_ctrlr; /* physical controller number */
142 int dk_ctrlr_cmd640;/* controller number for CMD640 quirk */
143 u_int32_t dk_unit; /* physical unit number */
144 u_int32_t dk_lunit; /* logical unit number */
145 u_int32_t dk_interface; /* interface (two ctrlrs per interface) */
146 char dk_state; /* control state */
147 u_char dk_status; /* copy of status reg. */
148 u_char dk_error; /* copy of error reg. */
149 u_char dk_timeout; /* countdown to next timeout */
150 u_int32_t dk_port; /* i/o port base */
151 u_int32_t dk_altport; /* altstatus port base */
152 u_long cfg_flags; /* configured characteristics */
153 short dk_flags; /* drive characteristics found */
154 #define DKFL_SINGLE 0x00004 /* sector at a time mode */
155 #define DKFL_ERROR 0x00008 /* processing a disk error */
156 #define DKFL_LABELLING 0x00080 /* readdisklabel() in progress */
157 #define DKFL_32BIT 0x00100 /* use 32-bit i/o mode */
158 #define DKFL_MULTI 0x00200 /* use multi-i/o mode */
159 #define DKFL_USEDMA 0x00800 /* use DMA for data transfers */
160 #define DKFL_DMA 0x01000 /* using DMA on this transfer-- DKFL_SINGLE
163 #define DKFL_LBA 0x02000 /* use LBA for data transfers */
164 struct wdparams dk_params; /* ESDI/IDE drive/controller parameters */
165 unsigned int dk_multi; /* multi transfers */
166 int dk_currentiosize; /* current io size */
167 struct diskgeom dk_dd; /* device configuration data */
168 struct diskslices *dk_slices; /* virtual drives */
169 void *dk_dmacookie; /* handle for DMA services */
171 struct devstat dk_stats; /* devstat entry */
174 #define WD_COUNT_RETRIES
175 static int wdtest = 0;
177 static struct disk *wddrives[NWD]; /* table of units */
178 static struct buf_queue_head drive_queue[NWD]; /* head of queue per drive */
183 static struct buf wdtab[NWDC];
186 struct buf_queue_head controller_queue;
191 struct wddma wddma[NWDC];
194 static struct buf rwdbuf[NWD]; /* buffers for raw IO */
197 static int wdprobe(struct isa_device *dvp);
198 static int wdattach(struct isa_device *dvp);
199 static void wdustart(struct disk *du);
200 static int wdcontrol(struct buf *bp);
201 static int wdcommand(struct disk *du, u_int cylinder, u_int head,
202 u_int sector, u_int count, u_int command);
203 static int wdsetctlr(struct disk *du);
205 static int wdwsetctlr(struct disk *du);
207 static int wdsetmode(int mode, void *wdinfo);
208 static int wdgetctlr(struct disk *du);
209 static void wderror(struct buf *bp, struct disk *du, char *mesg);
210 static void wdflushirq(struct disk *du, int old_ipl);
211 static int wdreset(struct disk *du);
212 static void wdsleep(int ctrlr, char *wmesg);
213 static timeout_t wdtimeout;
214 static int wdunwedge(struct disk *du);
215 static int wdwait(struct disk *du, u_char bits_wanted, int timeout);
217 struct isa_driver wdcdriver = {
218 wdprobe, wdattach, "wdc",
223 static d_open_t wdopen;
224 static d_close_t wdclose;
225 static d_strategy_t wdstrategy;
226 static d_ioctl_t wdioctl;
227 static d_dump_t wddump;
228 static d_psize_t wdsize;
234 static struct cdevsw wd_cdevsw = {
238 /* write */ physwrite,
242 /* strategy */ wdstrategy,
244 /* maj */ CDEV_MAJOR,
248 /* bmaj */ BDEV_MAJOR
252 static int atapictrlr;
253 static int eide_quirks;
257 * Here we use the pci-subsystem to find out, whether there is
258 * a cmd640b-chip attached on this pci-bus. This public routine
259 * will be called by ide_pci.c
265 eide_quirks = quirks;
269 * Probe for controller.
272 wdprobe(struct isa_device *dvp)
274 int unit = dvp->id_unit;
281 du = malloc(sizeof *du, M_TEMP, M_NOWAIT);
284 bzero(du, sizeof *du);
285 du->dk_ctrlr = dvp->id_unit;
286 interface = du->dk_ctrlr / 2;
287 du->dk_interface = interface;
288 du->dk_port = dvp->id_iobase;
289 if (wddma[interface].wdd_candma != NULL) {
291 wddma[interface].wdd_candma(dvp->id_iobase, du->dk_ctrlr,
294 wddma[interface].wdd_altiobase(du->dk_dmacookie);
296 if (du->dk_altport == 0)
297 du->dk_altport = du->dk_port + wd_ctlr;
299 /* check if we have registers that work */
300 outb(du->dk_port + wd_sdh, WDSD_IBM); /* set unit 0 */
301 outb(du->dk_port + wd_cyl_lo, 0xa5); /* wd_cyl_lo is read/write */
302 if (inb(du->dk_port + wd_cyl_lo) == 0xff) { /* XXX too weak */
303 /* There is no master, try the ATAPI slave. */
305 outb(du->dk_port + wd_sdh, WDSD_IBM | 0x10);
306 outb(du->dk_port + wd_cyl_lo, 0xa5);
307 if (inb(du->dk_port + wd_cyl_lo) == 0xff)
311 if (wdreset(du) == 0)
313 /* test for ATAPI signature */
314 outb(du->dk_port + wd_sdh, WDSD_IBM); /* master */
315 if (inb(du->dk_port + wd_cyl_lo) == 0x14 &&
316 inb(du->dk_port + wd_cyl_hi) == 0xeb)
319 outb(du->dk_port + wd_sdh, WDSD_IBM | 0x10); /* slave */
320 if (inb(du->dk_port + wd_cyl_lo) == 0x14 &&
321 inb(du->dk_port + wd_cyl_hi) == 0xeb)
324 if (wdreset(du) != 0) {
329 /* execute a controller only command */
330 if (wdcommand(du, 0, 0, 0, 0, WDCC_DIAGNOSE) != 0
331 || wdwait(du, 0, TIMEOUT) < 0) {
336 * drive(s) did not time out during diagnostic :
337 * Get error status and check that both drives are OK.
338 * Table 9-2 of ATA specs suggests that we must check for
341 * Strangely, some controllers will return a status of
342 * 0x81 (drive 0 OK, drive 1 failure), and then when
343 * the DRV bit is set, return status of 0x01 (OK) for
344 * drive 2. (This seems to contradict the ATA spec.)
346 du->dk_error = inb(du->dk_port + wd_error);
347 if(du->dk_error != 0x01 && du->dk_error != 0) {
348 if(du->dk_error & 0x80) { /* drive 1 failure */
350 /* first set the DRV bit */
352 sdh = inb(du->dk_port+ wd_sdh);
354 outb(du->dk_port+ wd_sdh, sdh);
356 /* Wait, to make sure drv 1 has completed diags */
357 if ( wdwait(du, 0, TIMEOUT) < 0)
360 /* Get status for drive 1 */
361 du->dk_error = inb(du->dk_port + wd_error);
362 /* printf("Error (drv 1) : %x\n", du->dk_error); */
364 * Sometimes (apparently mostly with ATAPI
365 * drives involved) 0x81 really means 0x81
366 * (drive 0 OK, drive 1 failed).
368 if(du->dk_error != 0x01 && du->dk_error != 0x81)
370 } else /* drive 0 fail */
384 * Attach each drive if possible.
387 wdattach(struct isa_device *dvp)
389 int unit, lunit, flags, i;
392 static char buf[] = "wdcXXX";
395 dvp->id_intr = wdintr;
397 if (dvp->id_unit >= NWDC)
401 cdevsw_add(&wd_cdevsw);
405 if (eide_quirks & Q_CMD640B) {
406 if (dvp->id_unit == PRIMARY) {
407 printf("wdc0: CMD640B workaround enabled\n");
408 bufq_init(&wdtab[PRIMARY].controller_queue);
411 bufq_init(&wdtab[dvp->id_unit].controller_queue);
413 sprintf(buf, "wdc%d", dvp->id_unit);
414 for (i = resource_query_string(-1, "at", buf);
416 i = resource_query_string(i, "at", buf)) {
417 if (strcmp(resource_query_name(i), "wd"))
418 /* Avoid a bit of foot shooting. */
421 lunit = resource_query_unit(i);
425 if (resource_int_value("wd", lunit, "drive", &unit) != 0)
427 if (resource_int_value("wd", lunit, "flags", &flags) != 0)
430 du = malloc(sizeof *du, M_TEMP, M_NOWAIT);
433 if (wddrives[lunit] != NULL)
434 panic("drive attached twice");
435 wddrives[lunit] = du;
436 bufq_init(&drive_queue[lunit]);
437 bzero(du, sizeof *du);
438 du->dk_ctrlr = dvp->id_unit;
439 if (eide_quirks & Q_CMD640B) {
440 du->dk_ctrlr_cmd640 = PRIMARY;
442 du->dk_ctrlr_cmd640 = du->dk_ctrlr;
445 du->dk_lunit = lunit;
446 du->dk_port = dvp->id_iobase;
448 du->dk_altport = du->dk_port + wd_ctlr;
450 * Use the individual device flags or the controller
453 du->cfg_flags = flags |
454 ((dvp->id_flags) >> (16 * unit));
456 if (wdgetctlr(du) == 0) {
458 * Print out description of drive.
459 * wdp_model may not be null terminated.
461 printf("wdc%d: unit %d (wd%d): <%.*s>",
462 dvp->id_unit, unit, lunit,
463 (int)sizeof(du->dk_params.wdp_model),
464 du->dk_params.wdp_model);
465 if (du->dk_flags & DKFL_LBA)
467 if (du->dk_flags & DKFL_USEDMA)
469 if (du->dk_flags & DKFL_32BIT)
471 if (du->dk_multi > 1)
472 printf(", multi-block-%d", du->dk_multi);
473 if (du->cfg_flags & WDOPT_SLEEPHACK)
474 printf(", sleep-hack");
476 if (du->dk_params.wdp_heads == 0)
477 printf("wd%d: size unknown, using %s values\n",
478 lunit, du->dk_dd.d_secperunit > 17
480 printf( "wd%d: %luMB (%lu sectors), "
481 "%lu cyls, %lu heads, %lu S/T, %lu B/S\n",
483 du->dk_dd.d_secperunit
484 / ((1024L * 1024L) / du->dk_dd.d_secsize),
485 du->dk_dd.d_secperunit,
486 du->dk_dd.d_ncylinders,
488 du->dk_dd.d_nsectors,
489 du->dk_dd.d_secsize);
493 printf( "wd%d: ATA INQUIRE valid = %04x, "
494 "dmamword = %04x, apio = %04x, "
499 wp->wdp_eidepiomodes,
504 * Start timeout routine for this drive.
505 * XXX timeout should be per controller.
510 dkmakeminor(lunit, WHOLE_DISK_SLICE, RAW_PART),
511 UID_ROOT, GID_OPERATOR, 0640, "rwd%d", lunit);
514 * Export the drive to the devstat interface.
516 devstat_add_entry(&du->dk_stats, "wd",
517 lunit, du->dk_dd.d_secsize,
518 DEVSTAT_NO_ORDERED_TAGS,
519 DEVSTAT_TYPE_DIRECT |
521 DEVSTAT_PRIORITY_DISK);
525 wddrives[lunit] = NULL;
529 * Probe all free IDE units, searching for ATAPI drives.
531 for (unit=0; unit<2; ++unit) {
532 for (lunit=0; lunit<NWD; ++lunit)
533 if (wddrives[lunit] &&
534 wddrives[lunit]->dk_ctrlr == dvp->id_unit &&
535 wddrives[lunit]->dk_unit == unit)
537 if (atapi_attach (dvp->id_unit, unit, dvp->id_iobase))
538 atapictrlr = dvp->id_unit;
542 * Discard any interrupts generated by wdgetctlr(). wdflushirq()
543 * doesn't work now because the ambient ipl is too high.
545 if (eide_quirks & Q_CMD640B) {
546 wdtab[PRIMARY].b_active = 2;
548 wdtab[dvp->id_unit].b_active = 2;
554 /* Read/write routine for a buffer. Finds the proper unit, range checks
555 * arguments, and schedules the transfer. Does not wait for the transfer
556 * to complete. Multi-page transfers are supported. All I/O requests must
557 * be a multiple of a sector in length.
560 wdstrategy(register struct buf *bp)
563 int lunit = dkunit(bp->b_dev);
566 /* valid unit, controller, and request? */
567 if (lunit >= NWD || bp->b_blkno < 0 || (du = wddrives[lunit]) == NULL
568 || bp->b_bcount % DEV_BSIZE != 0) {
570 bp->b_error = EINVAL;
571 bp->b_flags |= B_ERROR;
576 * Do bounds checking, adjust transfer, and set b_pblkno.
578 if (dscheck(bp, du->dk_slices) <= 0)
581 /* queue transfer on drive, activate drive and controller if idle */
584 /* Pick up changes made by readdisklabel(). */
585 if (du->dk_flags & DKFL_LABELLING && du->dk_state > RECAL) {
586 wdsleep(du->dk_ctrlr, "wdlab");
587 du->dk_state = WANTOPEN;
590 bufqdisksort(&drive_queue[lunit], bp);
592 if (wdutab[lunit].b_active == 0)
593 wdustart(du); /* start drive */
595 if (wdtab[du->dk_ctrlr_cmd640].b_active == 0)
596 wdstart(du->dk_ctrlr); /* start controller */
598 /* Tell devstat that we have started a transaction on this drive */
599 devstat_start_transaction(&du->dk_stats);
605 /* toss transfer, we're done early */
610 * Routine to queue a command to the controller. The unit's
611 * request is linked into the active list for the controller.
612 * If the controller is idle, the transfer is started.
615 wdustart(register struct disk *du)
617 register struct buf *bp;
618 int ctrlr = du->dk_ctrlr_cmd640;
620 /* unit already active? */
621 if (wdutab[du->dk_lunit].b_active)
625 bp = bufq_first(&drive_queue[du->dk_lunit]);
626 if (bp == NULL) { /* yes, an assign */
630 * store away which device we came from.
634 bufq_remove(&drive_queue[du->dk_lunit], bp);
636 /* link onto controller queue */
637 bufq_insert_tail(&wdtab[ctrlr].controller_queue, bp);
639 /* mark the drive unit as busy */
640 wdutab[du->dk_lunit].b_active = 1;
645 * Controller startup routine. This does the calculation, and starts
646 * a single-sector read or write operation. Called to start a transfer,
647 * or from the interrupt routine to continue a multi-sector transfer.
649 * 1. The transfer length must be an exact multiple of the sector size.
655 register struct disk *du;
656 register struct buf *bp;
657 struct diskgeom *lp; /* XXX sic */
659 long secpertrk, secpercyl;
664 if (eide_quirks & Q_CMD640B) {
666 ctrlr_atapi = atapictrlr;
671 if (wdtab[ctrlr].b_active == 2)
672 wdtab[ctrlr].b_active = 0;
673 if (wdtab[ctrlr].b_active)
675 /* is there a drive for the controller to do a transfer with? */
676 bp = bufq_first(&wdtab[ctrlr].controller_queue);
678 if (atapi_strt && atapi_strt (ctrlr_atapi))
679 /* mark controller active in ATAPI mode */
680 wdtab[ctrlr].b_active = 3;
684 /* obtain controller and drive information */
685 lunit = dkunit(bp->b_dev);
686 du = wddrives[lunit];
688 /* if not really a transfer, do control operations specially */
689 if (du->dk_state < OPEN) {
690 if (du->dk_state != WANTOPEN)
691 printf("wd%d: wdstart: weird dk_state %d\n",
692 du->dk_lunit, du->dk_state);
693 if (wdcontrol(bp) != 0)
694 printf("wd%d: wdstart: wdcontrol returned nonzero, state = %d\n",
695 du->dk_lunit, du->dk_state);
699 /* calculate transfer details */
700 blknum = bp->b_pblkno + du->dk_skip;
702 if (du->dk_skip == 0)
703 printf("wd%d: wdstart: %s %d@%d; map ", lunit,
704 (bp->b_flags & B_READ) ? "read" : "write",
705 bp->b_bcount, blknum);
707 printf(" %d)%x", du->dk_skip, inb(du->dk_altport));
711 secpertrk = lp->d_nsectors;
712 secpercyl = lp->d_secpercyl;
714 if (du->dk_skip == 0)
715 du->dk_bc = bp->b_bcount;
717 wdtab[ctrlr].b_active = 1; /* mark controller active */
719 /* if starting a multisector transfer, or doing single transfers */
720 if (du->dk_skip == 0 || (du->dk_flags & DKFL_SINGLE)) {
723 long cylin, head, sector;
725 if (du->dk_flags & DKFL_LBA) {
726 sector = (blknum >> 0) & 0xff;
727 cylin = (blknum >> 8) & 0xffff;
728 head = ((blknum >> 24) & 0xf) | WDSD_LBA;
730 cylin = blknum / secpercyl;
731 head = (blknum % secpercyl) / secpertrk;
732 sector = blknum % secpertrk;
735 * XXX this looks like an attempt to skip bad sectors
738 if (wdtab[ctrlr].b_errcnt && (bp->b_flags & B_READ) == 0)
739 du->dk_bc += DEV_BSIZE;
741 count1 = howmany( du->dk_bc, DEV_BSIZE);
743 du->dk_flags &= ~DKFL_MULTI;
745 if (du->dk_flags & DKFL_SINGLE) {
746 command = (bp->b_flags & B_READ)
747 ? WDCC_READ : WDCC_WRITE;
749 du->dk_currentiosize = 1;
751 if((du->dk_flags & DKFL_USEDMA) &&
752 wddma[du->dk_interface].wdd_dmaverify(du->dk_dmacookie,
753 (void *)((int)bp->b_data +
754 du->dk_skip * DEV_BSIZE),
756 bp->b_flags & B_READ)) {
757 du->dk_flags |= DKFL_DMA;
758 if( bp->b_flags & B_READ)
759 command = WDCC_READ_DMA;
761 command = WDCC_WRITE_DMA;
762 du->dk_currentiosize = count1;
763 } else if( (count1 > 1) && (du->dk_multi > 1)) {
764 du->dk_flags |= DKFL_MULTI;
765 if( bp->b_flags & B_READ) {
766 command = WDCC_READ_MULTI;
768 command = WDCC_WRITE_MULTI;
770 du->dk_currentiosize = du->dk_multi;
771 if( du->dk_currentiosize > count1)
772 du->dk_currentiosize = count1;
774 if( bp->b_flags & B_READ) {
777 command = WDCC_WRITE;
779 du->dk_currentiosize = 1;
784 * XXX this loop may never terminate. The code to handle
785 * counting down of retries and eventually failing the i/o
786 * is in wdintr() and we can't get there from here.
791 printf("dummy wdunwedge\n");
796 if ((du->dk_flags & (DKFL_DMA|DKFL_SINGLE)) == DKFL_DMA) {
797 wddma[du->dk_interface].wdd_dmaprep(du->dk_dmacookie,
798 (void *)((int)bp->b_data +
799 du->dk_skip * DEV_BSIZE),
801 bp->b_flags & B_READ);
803 while (wdcommand(du, cylin, head, sector, count1, command)
806 "wdstart: timeout waiting to give command");
810 printf("cylin %ld head %ld sector %ld addr %x sts %x\n",
812 (int)bp->b_data + du->dk_skip * DEV_BSIZE,
813 inb(du->dk_altport));
818 * Schedule wdtimeout() to wake up after a few seconds. Retrying
819 * unmarked bad blocks can take 3 seconds! Then it is not good that
822 * On the first try, we give it 10 seconds, for drives that may need
825 * XXX wdtimeout() doesn't increment the error count so we may loop
826 * forever. More seriously, the loop isn't forever but causes a
829 * TODO fix b_resid bug elsewhere (fd.c....). Fix short but positive
830 * counts being discarded after there is an error (in physio I
831 * think). Discarding them would be OK if the (special) file offset
834 if (wdtab[ctrlr].b_errcnt == 0)
835 du->dk_timeout = 1 + 10;
837 du->dk_timeout = 1 + 3;
839 /* if this is a DMA op, start DMA and go away until it's done. */
840 if ((du->dk_flags & (DKFL_DMA|DKFL_SINGLE)) == DKFL_DMA) {
841 wddma[du->dk_interface].wdd_dmastart(du->dk_dmacookie);
845 /* If this is a read operation, just go away until it's done. */
846 if (bp->b_flags & B_READ)
849 /* Ready to send data? */
850 if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ, TIMEOUT) < 0) {
851 wderror(bp, du, "wdstart: timeout waiting for DRQ");
853 * XXX what do we do now? If we've just issued the command,
854 * then we can treat this failure the same as a command
855 * failure. But if we are continuing a multi-sector write,
856 * the command was issued ages ago, so we can't simply
859 * XXX we waste a lot of time unnecessarily translating block
860 * numbers to cylin/head/sector for continued i/o's.
865 if( du->dk_flags & DKFL_MULTI) {
866 count = howmany(du->dk_bc, DEV_BSIZE);
867 if( count > du->dk_multi)
868 count = du->dk_multi;
869 if( du->dk_currentiosize > count)
870 du->dk_currentiosize = count;
873 if (du->dk_flags & DKFL_32BIT)
874 outsl(du->dk_port + wd_data,
875 (void *)((int)bp->b_data + du->dk_skip * DEV_BSIZE),
876 (count * DEV_BSIZE) / sizeof(long));
878 outsw(du->dk_port + wd_data,
879 (void *)((int)bp->b_data + du->dk_skip * DEV_BSIZE),
880 (count * DEV_BSIZE) / sizeof(short));
881 du->dk_bc -= DEV_BSIZE * count;
884 /* Interrupt routine for the controller. Acknowledge the interrupt, check for
885 * errors on the current operation, mark it done if necessary, and start
886 * the next request. Also check for a partially done transfer, and
887 * continue with the next chunk if so.
891 wdintr(void *unitnum)
893 register struct disk *du;
894 register struct buf *bp;
895 int dmastat = 0; /* Shut up GCC */
896 int unit = (int)unitnum;
900 if (eide_quirks & Q_CMD640B) {
902 ctrlr_atapi = atapictrlr;
907 if (wdtab[unit].b_active == 2)
908 return; /* intr in wdflushirq() */
909 if (!wdtab[unit].b_active) {
912 * These happen mostly because the power-mgt part of the
913 * bios shuts us down, and we just manage to see the
914 * interrupt from the "SLEEP" command.
916 printf("wdc%d: extra interrupt\n", unit);
920 if (wdtab[unit].b_active == 3) {
921 /* process an ATAPI interrupt */
922 if (atapi_intr && atapi_intr (ctrlr_atapi))
923 /* ATAPI op continues */
925 /* controller is free, start new op */
926 wdtab[unit].b_active = 0;
930 bp = bufq_first(&wdtab[unit].controller_queue);
931 du = wddrives[dkunit(bp->b_dev)];
934 if ((du->dk_flags & (DKFL_DMA|DKFL_SINGLE)) == DKFL_DMA) {
935 /* XXX SMP boxes sometimes generate an early intr. Why? */
936 if ((wddma[du->dk_interface].wdd_dmastatus(du->dk_dmacookie) &
937 WDDS_INTERRUPT) == 0)
939 dmastat = wddma[du->dk_interface].wdd_dmadone(du->dk_dmacookie);
944 /* check drive status/failure */
945 if (wdwait(du, 0, TIMEOUT) < 0) {
946 wderror(bp, du, "wdintr: timeout waiting for status");
947 du->dk_status |= WDCS_ERR; /* XXX */
950 /* is it not a transfer, but a control operation? */
951 if (du->dk_state < OPEN) {
952 wdtab[unit].b_active = 0;
953 switch (wdcontrol(bp)) {
964 /* have we an error? */
965 if ((du->dk_status & (WDCS_ERR | WDCS_ECCCOR))
966 || (((du->dk_flags & (DKFL_DMA|DKFL_SINGLE)) == DKFL_DMA)
967 && dmastat != WDDS_INTERRUPT)) {
969 unsigned int errstat;
972 * XXX bogus inb() here
974 errstat = inb(du->dk_port + wd_error);
976 if(((du->dk_flags & (DKFL_DMA|DKFL_SINGLE)) == DKFL_DMA) &&
977 (errstat & WDERR_ABORT)) {
978 wderror(bp, du, "reverting to PIO mode");
979 du->dk_flags &= ~DKFL_USEDMA;
980 } else if((du->dk_flags & DKFL_MULTI) &&
981 (errstat & WDERR_ABORT)) {
982 wderror(bp, du, "reverting to non-multi sector mode");
986 if (!(du->dk_status & (WDCS_ERR | WDCS_ECCCOR)) &&
987 (((du->dk_flags & (DKFL_DMA|DKFL_SINGLE)) == DKFL_DMA) &&
988 (dmastat != WDDS_INTERRUPT)))
989 printf("wd%d: DMA failure, DMA status %b\n",
990 du->dk_lunit, dmastat, WDDS_BITS);
992 wderror(bp, du, "wdintr");
994 if ((du->dk_flags & DKFL_SINGLE) == 0) {
995 du->dk_flags |= DKFL_ERROR;
999 if (du->dk_status & WDCS_ERR) {
1000 if (++wdtab[unit].b_errcnt < RETRIES) {
1001 wdtab[unit].b_active = 0;
1003 wderror(bp, du, "hard error");
1005 bp->b_flags |= B_ERROR; /* flag the error */
1007 } else if (du->dk_status & WDCS_ECCCOR)
1008 wderror(bp, du, "soft ecc");
1012 * If this was a successful read operation, fetch the data.
1014 if (((bp->b_flags & (B_READ | B_ERROR)) == B_READ)
1015 && !((du->dk_flags & (DKFL_DMA|DKFL_SINGLE)) == DKFL_DMA)
1016 && wdtab[unit].b_active) {
1017 u_int chk, dummy, multisize;
1018 multisize = chk = du->dk_currentiosize * DEV_BSIZE;
1019 if( du->dk_bc < chk) {
1021 if( ((chk + DEV_BSIZE - 1) / DEV_BSIZE) < du->dk_currentiosize) {
1022 du->dk_currentiosize = (chk + DEV_BSIZE - 1) / DEV_BSIZE;
1023 multisize = du->dk_currentiosize * DEV_BSIZE;
1027 /* ready to receive data? */
1028 if ((du->dk_status & (WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ))
1029 != (WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ))
1030 wderror(bp, du, "wdintr: read intr arrived early");
1031 if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ, TIMEOUT) != 0) {
1032 wderror(bp, du, "wdintr: read error detected late");
1037 if( du->dk_flags & DKFL_32BIT)
1038 insl(du->dk_port + wd_data,
1039 (void *)((int)bp->b_data + du->dk_skip * DEV_BSIZE),
1040 chk / sizeof(long));
1042 insw(du->dk_port + wd_data,
1043 (void *)((int)bp->b_data + du->dk_skip * DEV_BSIZE),
1044 chk / sizeof(short));
1047 /* XXX for obsolete fractional sector reads. */
1048 while (chk < multisize) {
1049 insw(du->dk_port + wd_data, &dummy, 1);
1050 chk += sizeof(short);
1055 /* final cleanup on DMA */
1056 if (((bp->b_flags & B_ERROR) == 0)
1057 && ((du->dk_flags & (DKFL_DMA|DKFL_SINGLE)) == DKFL_DMA)
1058 && wdtab[unit].b_active) {
1061 iosize = du->dk_currentiosize * DEV_BSIZE;
1063 du->dk_bc -= iosize;
1068 if (wdtab[unit].b_active) {
1069 if ((bp->b_flags & B_ERROR) == 0) {
1070 du->dk_skip += du->dk_currentiosize;/* add to successful sectors */
1071 if (wdtab[unit].b_errcnt)
1072 wderror(bp, du, "soft error");
1073 wdtab[unit].b_errcnt = 0;
1075 /* see if more to transfer */
1076 if (du->dk_bc > 0 && (du->dk_flags & DKFL_ERROR) == 0) {
1077 if( (du->dk_flags & DKFL_SINGLE) ||
1078 ((bp->b_flags & B_READ) == 0)) {
1079 wdtab[unit].b_active = 0;
1082 du->dk_timeout = 1 + 3;
1084 return; /* next chunk is started */
1085 } else if ((du->dk_flags & (DKFL_SINGLE | DKFL_ERROR))
1088 du->dk_flags &= ~DKFL_ERROR;
1089 du->dk_flags |= DKFL_SINGLE;
1090 wdtab[unit].b_active = 0;
1092 return; /* redo xfer sector by sector */
1097 /* done with this transfer, with or without error */
1098 du->dk_flags &= ~(DKFL_SINGLE|DKFL_DMA);
1099 bufq_remove( &wdtab[unit].controller_queue, bp);
1100 wdtab[unit].b_errcnt = 0;
1101 bp->b_resid = bp->b_bcount - du->dk_skip * DEV_BSIZE;
1102 wdutab[du->dk_lunit].b_active = 0;
1104 devstat_end_transaction_buf(&du->dk_stats, bp);
1108 /* controller idle */
1109 wdtab[unit].b_active = 0;
1111 /* anything more on drive queue? */
1113 /* anything more for controller to do? */
1118 * Initialize a drive.
1121 wdopen(dev_t dev, int flags, int fmt, struct proc *p)
1123 register unsigned int lunit;
1124 register struct disk *du;
1127 lunit = dkunit(dev);
1128 if (lunit >= NWD || dktype(dev) != 0)
1130 du = wddrives[lunit];
1134 dev->si_iosize_max = 248 * 512;
1135 /* Finish flushing IRQs left over from wdattach(). */
1136 if (wdtab[du->dk_ctrlr_cmd640].b_active == 2)
1137 wdtab[du->dk_ctrlr_cmd640].b_active = 0;
1139 /* spin waiting for anybody else reading the disk label */
1140 while (du->dk_flags & DKFL_LABELLING)
1141 tsleep((caddr_t)&du->dk_flags, PZERO - 1, "wdopen", 1);
1143 wdsleep(du->dk_ctrlr, "wdopn1");
1144 du->dk_flags |= DKFL_LABELLING;
1145 du->dk_state = WANTOPEN;
1147 struct disklabel label;
1149 bzero(&label, sizeof label);
1150 label.d_secsize = du->dk_dd.d_secsize;
1151 label.d_nsectors = du->dk_dd.d_nsectors;
1152 label.d_ntracks = du->dk_dd.d_ntracks;
1153 label.d_ncylinders = du->dk_dd.d_ncylinders;
1154 label.d_secpercyl = du->dk_dd.d_secpercyl;
1155 label.d_secperunit = du->dk_dd.d_secperunit;
1156 error = dsopen(dev, fmt, 0, &du->dk_slices, &label);
1158 du->dk_flags &= ~DKFL_LABELLING;
1159 wdsleep(du->dk_ctrlr, "wdopn2");
1162 if ((du->dk_flags & DKFL_BSDLABEL) == 0) {
1164 * wdtab[ctrlr].b_active != 0 implies XXX applicable now ??
1165 * drive_queue[lunit].b_act == NULL (?) XXX applicable now ??
1166 * so the following guards most things (until the next i/o).
1167 * It doesn't guard against a new i/o starting and being
1168 * affected by the label being changed. Sigh.
1170 wdsleep(du->dk_ctrlr, "wdopn1");
1172 du->dk_flags |= DKFL_LABELLING;
1173 du->dk_state = WANTOPEN;
1175 error = dsinit(dkmodpart(dev, RAW_PART),
1176 &du->dk_dd, &du->dk_slices);
1178 du->dk_flags &= ~DKFL_LABELLING;
1181 /* XXX check value returned by wdwsetctlr(). */
1183 if (dkslice(dev) == WHOLE_DISK_SLICE) {
1184 dsopen(dev, fmt, du->dk_slices);
1189 * Read label using RAW_PART partition.
1191 * If the drive has an MBR, then the current geometry (from
1192 * wdgetctlr()) is used to read it; then the BIOS/DOS
1193 * geometry is inferred and used to read the label off the
1194 * 'c' partition. Otherwise the label is read using the
1195 * current geometry. The label gives the final geometry.
1196 * If bad sector handling is enabled, then this geometry
1197 * is used to read the bad sector table. The geometry
1198 * changes occur inside readdisklabel() and are propagated
1199 * to the driver by resetting the state machine.
1201 * XXX can now handle changes directly since dsinit() doesn't
1204 msg = correct_readdisklabel(dkmodpart(dev, RAW_PART),
1206 /* XXX check value returned by wdwsetctlr(). */
1208 du->dk_flags &= ~DKFL_LABELLING;
1210 log(LOG_WARNING, "wd%d: cannot find label (%s)\n",
1212 if (part != RAW_PART)
1213 return (EINVAL); /* XXX needs translation */
1215 * Soon return. This is how slices without labels
1216 * are allowed. They only work on the raw partition.
1219 unsigned long newsize, offset, size;
1222 * Force RAW_PART partition to be the whole disk.
1224 offset = du->dk_dd.d_partitions[RAW_PART].p_offset;
1227 "wd%d: changing offset of '%c' partition from %lu to 0\n",
1228 du->dk_lunit, 'a' + RAW_PART, offset);
1229 du->dk_dd.d_partitions[RAW_PART].p_offset = 0;
1231 size = du->dk_dd.d_partitions[RAW_PART].p_size;
1232 newsize = du->dk_dd.d_secperunit; /* XXX */
1233 if (size != newsize) {
1235 "wd%d: changing size of '%c' partition from %lu to %lu\n",
1236 du->dk_lunit, 'a' + RAW_PART, size,
1238 du->dk_dd.d_partitions[RAW_PART].p_size
1244 /* Pick up changes made by readdisklabel(). */
1245 wdsleep(du->dk_ctrlr, "wdopn2");
1246 du->dk_state = WANTOPEN;
1250 * Warn if a partion is opened that overlaps another partition which
1251 * is open unless one is the "raw" partition (whole disk).
1253 if ((du->dk_openpart & mask) == 0 && part != RAW_PART) {
1256 pp = &du->dk_dd.d_partitions[part];
1257 start = pp->p_offset;
1258 end = pp->p_offset + pp->p_size;
1259 for (pp = du->dk_dd.d_partitions;
1260 pp < &du->dk_dd.d_partitions[du->dk_dd.d_npartitions];
1262 if (pp->p_offset + pp->p_size <= start ||
1263 pp->p_offset >= end)
1265 if (pp - du->dk_dd.d_partitions == RAW_PART)
1268 & (1 << (pp - du->dk_dd.d_partitions)))
1270 "wd%d%c: overlaps open partition (%c)\n",
1272 pp - du->dk_dd.d_partitions + 'a');
1275 if (part >= du->dk_dd.d_npartitions && part != RAW_PART)
1278 dsopen(dev, fmt, du->dk_slices);
1285 * Implement operations other than read/write.
1286 * Called from wdstart or wdintr during opens.
1287 * Uses finite-state-machine to track progress of operation in progress.
1288 * Returns 0 if operation still in progress, 1 if completed, 2 if error.
1291 wdcontrol(register struct buf *bp)
1293 register struct disk *du;
1296 du = wddrives[dkunit(bp->b_dev)];
1297 ctrlr = du->dk_ctrlr_cmd640;
1299 switch (du->dk_state) {
1302 wdtab[ctrlr].b_active = 1;
1303 if (wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) != 0) {
1304 wderror(bp, du, "wdcontrol: wdcommand failed");
1307 du->dk_state = RECAL;
1310 if (du->dk_status & WDCS_ERR || wdsetctlr(du) != 0) {
1311 wderror(bp, du, "wdcontrol: recal failed");
1313 if (du->dk_status & WDCS_ERR)
1315 du->dk_state = WANTOPEN;
1316 if (++wdtab[ctrlr].b_errcnt < RETRIES)
1318 bp->b_error = ENXIO; /* XXX needs translation */
1319 bp->b_flags |= B_ERROR;
1322 wdtab[ctrlr].b_errcnt = 0;
1323 du->dk_state = OPEN;
1325 * The rest of the initialization can be done by normal
1335 * Wait uninterruptibly until controller is not busy, then send it a command.
1336 * The wait usually terminates immediately because we waited for the previous
1337 * command to terminate.
1340 wdcommand(struct disk *du, u_int cylinder, u_int head, u_int sector,
1341 u_int count, u_int command)
1346 if (du->cfg_flags & WDOPT_SLEEPHACK) {
1347 /* OK, so the APM bios has put the disk into SLEEP mode,
1348 * how can we tell ? Uhm, we can't. There is no
1349 * standardized way of finding out, and the only way to
1350 * wake it up is to reset it. Bummer.
1352 * All the many and varied versions of the IDE/ATA standard
1353 * explicitly tells us not to look at these registers if
1354 * the disk is in SLEEP mode. Well, too bad really, we
1355 * have to find out if it's in sleep mode before we can
1356 * avoid reading the registers.
1358 * I have reason to belive that most disks will return
1359 * either 0xff or 0x00 in all but the status register
1360 * when in SLEEP mode, but I have yet to see one return
1361 * 0x00, so we don't check for that yet.
1363 * The check for WDCS_BUSY is for the case where the
1364 * bios spins up the disk for us, but doesn't initialize
1367 if(inb(wdc + wd_precomp) + inb(wdc + wd_cyl_lo) +
1368 inb(wdc + wd_cyl_hi) + inb(wdc + wd_sdh) +
1369 inb(wdc + wd_sector) + inb(wdc + wd_seccnt) == 6 * 0xff) {
1371 printf("wd(%d,%d): disk aSLEEP\n",
1372 du->dk_ctrlr, du->dk_unit);
1374 } else if(inb(wdc + wd_status) == WDCS_BUSY) {
1376 printf("wd(%d,%d): disk is BUSY\n",
1377 du->dk_ctrlr, du->dk_unit);
1382 if (wdwait(du, 0, TIMEOUT) < 0)
1384 if( command == WDCC_FEATURES) {
1385 outb(wdc + wd_sdh, WDSD_IBM | (du->dk_unit << 4) | head);
1386 outb(wdc + wd_features, count);
1387 if ( count == WDFEA_SETXFER )
1388 outb(wdc + wd_seccnt, sector);
1390 outb(wdc + wd_precomp, du->dk_dd.d_precompcyl / 4);
1391 outb(wdc + wd_cyl_lo, cylinder);
1392 outb(wdc + wd_cyl_hi, cylinder >> 8);
1393 outb(wdc + wd_sdh, WDSD_IBM | (du->dk_unit << 4) | head);
1394 if (head & WDSD_LBA)
1395 outb(wdc + wd_sector, sector);
1397 outb(wdc + wd_sector, sector + 1);
1398 outb(wdc + wd_seccnt, count);
1400 if (wdwait(du, (command == WDCC_DIAGNOSE || command == WDCC_IDC)
1401 ? 0 : WDCS_READY, TIMEOUT) < 0)
1403 outb(wdc + wd_command, command);
1408 wdsetmulti(struct disk *du)
1411 * The config option flags low 8 bits define the maximum multi-block
1412 * transfer size. If the user wants the maximum that the drive
1413 * is capable of, just set the low bits of the config option to
1416 if ((du->cfg_flags & WDOPT_MULTIMASK) != 0 && (du->dk_multi > 1)) {
1417 int configval = du->cfg_flags & WDOPT_MULTIMASK;
1418 du->dk_multi = min(du->dk_multi, configval);
1419 if (wdcommand(du, 0, 0, 0, du->dk_multi, WDCC_SET_MULTI)) {
1422 if (wdwait(du, WDCS_READY, TIMEOUT) < 0) {
1432 * issue IDC to drive to tell it just what geometry it is to be.
1435 wdsetctlr(struct disk *du)
1439 printf("wd(%d,%d): wdsetctlr: C %lu H %lu S %lu\n",
1440 du->dk_ctrlr, du->dk_unit,
1441 du->dk_dd.d_ncylinders, du->dk_dd.d_ntracks,
1442 du->dk_dd.d_nsectors);
1444 if (!(du->dk_flags & DKFL_LBA)) {
1445 if (du->dk_dd.d_ntracks == 0 || du->dk_dd.d_ntracks > 16) {
1446 struct wdparams *wp;
1448 printf("wd%d: can't handle %lu heads from partition table ",
1449 du->dk_lunit, du->dk_dd.d_ntracks);
1450 /* obtain parameters */
1451 wp = &du->dk_params;
1452 if (wp->wdp_heads > 0 && wp->wdp_heads <= 16) {
1453 printf("(controller value %u restored)\n",
1455 du->dk_dd.d_ntracks = wp->wdp_heads;
1458 printf("(truncating to 16)\n");
1459 du->dk_dd.d_ntracks = 16;
1463 if (du->dk_dd.d_nsectors == 0 || du->dk_dd.d_nsectors > 255) {
1464 printf("wd%d: cannot handle %lu sectors (max 255)\n",
1465 du->dk_lunit, du->dk_dd.d_nsectors);
1469 wdtab[du->dk_ctrlr_cmd640].b_errcnt += RETRIES;
1472 if (wdcommand(du, du->dk_dd.d_ncylinders, du->dk_dd.d_ntracks - 1, 0,
1473 du->dk_dd.d_nsectors, WDCC_IDC) != 0
1474 || wdwait(du, WDCS_READY, TIMEOUT) < 0) {
1475 wderror((struct buf *)NULL, du, "wdsetctlr failed");
1483 /* set read caching and write caching */
1484 wdcommand(du, 0, 0, 0, WDFEA_RCACHE, WDCC_FEATURES);
1485 wdwait(du, WDCS_READY, TIMEOUT);
1487 wdcommand(du, 0, 0, 0, WDFEA_WCACHE, WDCC_FEATURES);
1488 wdwait(du, WDCS_READY, TIMEOUT);
1496 * Wait until driver is inactive, then set up controller.
1499 wdwsetctlr(struct disk *du)
1504 wdsleep(du->dk_ctrlr, "wdwset");
1506 stat = wdsetctlr(du);
1514 * gross little callback function for wdddma interface. returns 1 for
1515 * success, 0 for failure.
1518 wdsetmode(int mode, void *wdinfo)
1525 printf("wd%d: wdsetmode() setting transfer mode to %02x\n",
1526 du->dk_lunit, mode);
1527 i = wdcommand(du, 0, 0, mode, WDFEA_SETXFER,
1528 WDCC_FEATURES) == 0 &&
1529 wdwait(du, WDCS_READY, TIMEOUT) == 0;
1534 * issue READP to drive to ask it what it is.
1537 wdgetctlr(struct disk *du)
1540 char tb[DEV_BSIZE], tb2[DEV_BSIZE];
1541 struct wdparams *wp = NULL;
1542 u_long flags = du->cfg_flags;
1544 if (wdcommand(du, 0, 0, 0, 0, WDCC_READP) != 0
1545 || wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ, TIMEOUT) != 0) {
1548 * if we failed on the second try, assume non-32bit
1550 if( du->dk_flags & DKFL_32BIT)
1553 /* XXX need to check error status after final transfer. */
1555 * Old drives don't support WDCC_READP. Try a seek to 0.
1556 * Some IDE controllers return trash if there is no drive
1557 * attached, so first test that the drive can be selected.
1558 * This also avoids long waits for nonexistent drives.
1560 if (wdwait(du, 0, TIMEOUT) < 0)
1562 outb(du->dk_port + wd_sdh, WDSD_IBM | (du->dk_unit << 4));
1563 DELAY(5000); /* usually unnecessary; drive select is fast */
1565 * Do this twice: may get a false WDCS_READY the first time.
1567 inb(du->dk_port + wd_status);
1568 if ((inb(du->dk_port + wd_status) & (WDCS_BUSY | WDCS_READY))
1570 || wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) != 0
1571 || wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) != 0)
1574 if (du->dk_unit == bootinfo.bi_n_bios_used) {
1575 du->dk_dd.d_secsize = DEV_BSIZE;
1576 du->dk_dd.d_nsectors =
1577 bootinfo.bi_bios_geom[du->dk_unit] & 0xff;
1578 du->dk_dd.d_ntracks =
1579 ((bootinfo.bi_bios_geom[du->dk_unit] >> 8) & 0xff)
1582 du->dk_dd.d_ncylinders =
1583 (bootinfo.bi_bios_geom[du->dk_unit] >> 16) + 2;
1584 du->dk_dd.d_secpercyl =
1585 du->dk_dd.d_ntracks * du->dk_dd.d_nsectors;
1586 du->dk_dd.d_secperunit =
1587 du->dk_dd.d_secpercyl * du->dk_dd.d_ncylinders;
1589 du->dk_dd.d_partitions[WDRAW].p_size =
1590 du->dk_dd.d_secperunit;
1591 du->dk_dd.d_type = DTYPE_ST506;
1592 du->dk_dd.d_subtype |= DSTYPE_GEOMETRY;
1593 strncpy(du->dk_dd.d_typename, "Bios geometry",
1594 sizeof du->dk_dd.d_typename);
1595 strncpy(du->dk_params.wdp_model, "ST506",
1596 sizeof du->dk_params.wdp_model);
1598 bootinfo.bi_n_bios_used ++;
1602 * Fake minimal drive geometry for reading the MBR.
1603 * readdisklabel() may enlarge it to read the label.
1605 du->dk_dd.d_secsize = DEV_BSIZE;
1606 du->dk_dd.d_nsectors = 17;
1607 du->dk_dd.d_ntracks = 1;
1608 du->dk_dd.d_ncylinders = 1;
1609 du->dk_dd.d_secpercyl = 17;
1610 du->dk_dd.d_secperunit = 17;
1614 * Fake maximal drive size for writing the label.
1616 du->dk_dd.d_partitions[RAW_PART].p_size = 64 * 16 * 1024;
1619 * Fake some more of the label for printing by disklabel(1)
1620 * in case there is no real label.
1622 du->dk_dd.d_type = DTYPE_ST506;
1623 du->dk_dd.d_subtype |= DSTYPE_GEOMETRY;
1624 strncpy(du->dk_dd.d_typename, "Fake geometry",
1625 sizeof du->dk_dd.d_typename);
1628 /* Fake the model name for printing by wdattach(). */
1629 strncpy(du->dk_params.wdp_model, "unknown",
1630 sizeof du->dk_params.wdp_model);
1635 /* obtain parameters */
1636 wp = &du->dk_params;
1637 if (du->dk_flags & DKFL_32BIT)
1638 insl(du->dk_port + wd_data, tb, sizeof(tb) / sizeof(long));
1640 insw(du->dk_port + wd_data, tb, sizeof(tb) / sizeof(short));
1642 /* try 32-bit data path (VLB IDE controller) */
1643 if (flags & WDOPT_32BIT) {
1644 if (! (du->dk_flags & DKFL_32BIT)) {
1645 bcopy(tb, tb2, sizeof(struct wdparams));
1646 du->dk_flags |= DKFL_32BIT;
1650 /* check that we really have 32-bit controller */
1651 if (bcmp (tb, tb2, sizeof(struct wdparams)) != 0) {
1653 /* test failed, use 16-bit i/o mode */
1654 bcopy(tb2, tb, sizeof(struct wdparams));
1655 du->dk_flags &= ~DKFL_32BIT;
1659 bcopy(tb, wp, sizeof(struct wdparams));
1661 /* shuffle string byte order */
1662 for (i = 0; (unsigned)i < sizeof(wp->wdp_model); i += 2) {
1665 p = (u_short *) (wp->wdp_model + i);
1669 * Clean up the wdp_model by converting nulls to spaces, and
1670 * then removing the trailing spaces.
1672 for (i = 0; (unsigned)i < sizeof(wp->wdp_model); i++) {
1673 if (wp->wdp_model[i] == '\0') {
1674 wp->wdp_model[i] = ' ';
1677 for (i = sizeof(wp->wdp_model) - 1;
1678 (i >= 0 && wp->wdp_model[i] == ' '); i--) {
1679 wp->wdp_model[i] = '\0';
1683 * find out the drives maximum multi-block transfer capability
1685 du->dk_multi = wp->wdp_nsecperint & 0xff;
1689 * check drive's DMA capability
1691 if (wddma[du->dk_interface].wdd_candma) {
1692 du->dk_dmacookie = wddma[du->dk_interface].wdd_candma(
1693 du->dk_port, du->dk_ctrlr, du->dk_unit);
1694 /* does user want this? */
1695 if ((du->cfg_flags & WDOPT_DMA) &&
1696 /* have we got a DMA controller? */
1698 /* can said drive do DMA? */
1699 wddma[du->dk_interface].wdd_dmainit(du->dk_dmacookie, wp, wdsetmode, du)) {
1700 du->dk_flags |= DKFL_USEDMA;
1703 du->dk_dmacookie = NULL;
1708 "\nwd(%d,%d): wdgetctlr: gc %x cyl %d trk %d sec %d type %d sz %d model %s\n",
1709 du->dk_ctrlr, du->dk_unit, wp->wdp_config, wp->wdp_cylinders,
1710 wp->wdp_heads, wp->wdp_sectors, wp->wdp_buffertype,
1711 wp->wdp_buffersize, wp->wdp_model);
1714 /* update disklabel given drive information */
1715 du->dk_dd.d_secsize = DEV_BSIZE;
1716 if ((du->cfg_flags & WDOPT_LBA) && wp->wdp_lbasize) {
1717 du->dk_dd.d_nsectors = 63;
1718 if (wp->wdp_lbasize < 16*63*1024) { /* <=528.4 MB */
1719 du->dk_dd.d_ntracks = 16;
1721 else if (wp->wdp_lbasize < 32*63*1024) { /* <=1.057 GB */
1722 du->dk_dd.d_ntracks = 32;
1724 else if (wp->wdp_lbasize < 64*63*1024) { /* <=2.114 GB */
1725 du->dk_dd.d_ntracks = 64;
1727 else if (wp->wdp_lbasize < 128*63*1024) { /* <=4.228 GB */
1728 du->dk_dd.d_ntracks = 128;
1730 else if (wp->wdp_lbasize < 255*63*1024) { /* <=8.422 GB */
1731 du->dk_dd.d_ntracks = 255;
1733 else { /* >8.422 GB */
1734 du->dk_dd.d_ntracks = 255; /* XXX */
1736 du->dk_dd.d_secpercyl= du->dk_dd.d_ntracks*du->dk_dd.d_nsectors;
1737 du->dk_dd.d_ncylinders = wp->wdp_lbasize/du->dk_dd.d_secpercyl;
1738 du->dk_dd.d_secperunit = wp->wdp_lbasize;
1739 du->dk_flags |= DKFL_LBA;
1742 du->dk_dd.d_ncylinders = wp->wdp_cylinders; /* +- 1 */
1743 du->dk_dd.d_ntracks = wp->wdp_heads;
1744 du->dk_dd.d_nsectors = wp->wdp_sectors;
1745 du->dk_dd.d_secpercyl =
1746 du->dk_dd.d_ntracks * du->dk_dd.d_nsectors;
1747 du->dk_dd.d_secperunit =
1748 du->dk_dd.d_secpercyl * du->dk_dd.d_ncylinders;
1749 if (wp->wdp_cylinders == 16383 &&
1750 du->dk_dd.d_secperunit < wp->wdp_lbasize) {
1751 du->dk_dd.d_secperunit = wp->wdp_lbasize;
1752 du->dk_dd.d_ncylinders =
1753 du->dk_dd.d_secperunit / du->dk_dd.d_secpercyl;
1756 if (WDOPT_FORCEHD(du->cfg_flags)) {
1757 du->dk_dd.d_ntracks = WDOPT_FORCEHD(du->cfg_flags);
1758 du->dk_dd.d_secpercyl =
1759 du->dk_dd.d_ntracks * du->dk_dd.d_nsectors;
1760 du->dk_dd.d_ncylinders =
1761 du->dk_dd.d_secperunit / du->dk_dd.d_secpercyl;
1763 if (du->dk_dd.d_ncylinders > 0x10000 && !(du->cfg_flags & WDOPT_LBA)) {
1764 du->dk_dd.d_ncylinders = 0x10000;
1765 du->dk_dd.d_secperunit = du->dk_dd.d_secpercyl *
1766 du->dk_dd.d_ncylinders;
1768 "wd%d: cannot handle %d total sectors; truncating to %lu\n",
1769 du->dk_lunit, wp->wdp_lbasize, du->dk_dd.d_secperunit);
1772 du->dk_dd.d_partitions[RAW_PART].p_size = du->dk_dd.d_secperunit;
1774 bcopy("ESDI/IDE", du->dk_dd.d_typename, 9);
1775 bcopy(wp->wdp_model + 20, du->dk_dd.d_packname, 14 - 1);
1777 du->dk_dd.d_type = DTYPE_ESDI;
1778 du->dk_dd.d_subtype |= DSTYPE_GEOMETRY;
1785 wdclose(dev_t dev, int flags, int fmt, struct proc *p)
1787 dsclose(dev, fmt, wddrives[dkunit(dev)]->dk_slices);
1792 wdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
1794 int lunit = dkunit(dev);
1795 register struct disk *du;
1798 du = wddrives[lunit];
1799 wdsleep(du->dk_ctrlr, "wdioct");
1800 error = dsioctl(dev, cmd, addr, flags, &du->dk_slices);
1801 if (error != ENOIOCTL)
1812 lunit = dkunit(dev);
1813 if (lunit >= NWD || dktype(dev) != 0)
1815 du = wddrives[lunit];
1818 return (dssize(dev, &du->dk_slices));
1824 register struct disk *du;
1825 struct disklabel *lp;
1826 long num; /* number of sectors to write */
1828 long blkoff, blknum;
1829 long blkcnt, blknext;
1832 static int wddoingadump = 0;
1833 long cylin, head, sector;
1834 long secpertrk, secpercyl;
1837 /* Toss any characters present prior to dump. */
1838 while (cncheckc() != -1)
1841 /* Check for acceptable device. */
1842 /* XXX should reset to maybe allow du->dk_state < OPEN. */
1843 lunit = dkunit(dev); /* eventually support floppies? */
1845 if (lunit >= NWD || (du = wddrives[lunit]) == NULL
1846 || du->dk_state < OPEN
1847 || (lp = dsgetlabel(dev, du->dk_slices)) == NULL)
1850 /* Size of memory to dump, in disk sectors. */
1851 num = (u_long)Maxmem * PAGE_SIZE / du->dk_dd.d_secsize;
1854 secpertrk = du->dk_dd.d_nsectors;
1855 secpercyl = du->dk_dd.d_secpercyl;
1856 nblocks = lp->d_partitions[part].p_size;
1857 blkoff = lp->d_partitions[part].p_offset;
1859 ds_offset = du->dk_slices->dss_slices[dkslice(dev)].ds_offset;
1860 blkoff += ds_offset;
1863 printf("part %d, nblocks %lu, dumplo %ld num %ld\n",
1864 part, nblocks, dumplo, num);
1867 /* Check transfer bounds against partition size. */
1868 if (dumplo < 0 || dumplo + num > nblocks)
1871 /* Check if we are being called recursively. */
1876 /* Mark controller active for if we panic during the dump. */
1877 wdtab[du->dk_ctrlr].b_active = 1;
1881 /* Recalibrate the drive. */
1882 DELAY(5); /* ATA spec XXX NOT */
1883 if (wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) != 0
1884 || wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) != 0
1885 || wdsetctlr(du) != 0) {
1886 wderror((struct buf *)NULL, du, "wddump: recalibrate failed");
1890 du->dk_flags |= DKFL_SINGLE;
1892 blknum = dumplo + blkoff;
1895 if (blkcnt > MAXTRANSFER)
1896 blkcnt = MAXTRANSFER;
1897 if ((du->dk_flags & DKFL_LBA) == 0) {
1898 /* XXX keep transfer within current cylinder. */
1899 if ((blknum + blkcnt - 1) / secpercyl !=
1901 blkcnt = secpercyl - (blknum % secpercyl);
1903 blknext = blknum + blkcnt;
1905 /* Compute disk address. */
1906 if (du->dk_flags & DKFL_LBA) {
1907 sector = (blknum >> 0) & 0xff;
1908 cylin = (blknum >> 8) & 0xffff;
1909 head = ((blknum >> 24) & 0xf) | WDSD_LBA;
1911 cylin = blknum / secpercyl;
1912 head = (blknum % secpercyl) / secpertrk;
1913 sector = blknum % secpertrk;
1917 /* Let's just talk about this first... */
1918 printf("cylin %ld head %ld sector %ld addr %p count %ld\n",
1919 cylin, head, sector, addr, blkcnt);
1924 if (wdcommand(du, cylin, head, sector, blkcnt, WDCC_WRITE)
1926 wderror((struct buf *)NULL, du,
1927 "wddump: timeout waiting to to give command");
1930 while (blkcnt != 0) {
1931 if (is_physical_memory((vm_offset_t)addr))
1932 pmap_kenter((vm_offset_t)CADDR1,
1933 trunc_page((vm_offset_t)addr));
1935 pmap_kenter((vm_offset_t)CADDR1,
1938 /* Ready to send data? */
1939 DELAY(5); /* ATA spec */
1940 if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ, TIMEOUT)
1942 wderror((struct buf *)NULL, du,
1943 "wddump: timeout waiting for DRQ");
1946 if (du->dk_flags & DKFL_32BIT)
1947 outsl(du->dk_port + wd_data,
1948 CADDR1 + ((int)addr & PAGE_MASK),
1949 DEV_BSIZE / sizeof(long));
1951 outsw(du->dk_port + wd_data,
1952 CADDR1 + ((int)addr & PAGE_MASK),
1953 DEV_BSIZE / sizeof(short));
1956 * If we are dumping core, it may take a while.
1957 * So reassure the user and hold off any watchdogs.
1959 if ((unsigned)addr % (1024 * 1024) == 0) {
1963 #endif /* HW_WDOG */
1964 printf("%ld ", num / (1024 * 1024 / DEV_BSIZE));
1970 /* Wait for completion. */
1971 DELAY(5); /* ATA spec XXX NOT */
1972 if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) < 0) {
1973 wderror((struct buf *)NULL, du,
1974 "wddump: timeout waiting for status");
1978 /* Check final status. */
1980 & (WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ | WDCS_ERR))
1981 != (WDCS_READY | WDCS_SEEKCMPLT)) {
1982 wderror((struct buf *)NULL, du,
1983 "wddump: extra DRQ, or error");
1987 /* Update block count. */
1990 /* Operator aborting dump? */
1991 if (cncheckc() != -1)
1998 wderror(struct buf *bp, struct disk *du, char *mesg)
2001 printf("wd%d: %s", du->dk_lunit, mesg);
2003 diskerr(bp, mesg, LOG_PRINTF, du->dk_skip,
2004 dsgetlabel(bp->b_dev, du->dk_slices));
2005 printf(" (status %b error %b)\n",
2006 du->dk_status, WDCS_BITS, du->dk_error, WDERR_BITS);
2010 * Discard any interrupts that were latched by the interrupt system while
2011 * we were doing polled i/o.
2014 wdflushirq(struct disk *du, int old_ipl)
2016 wdtab[du->dk_ctrlr_cmd640].b_active = 2;
2019 wdtab[du->dk_ctrlr_cmd640].b_active = 0;
2023 * Reset the controller.
2026 wdreset(struct disk *du)
2030 if ((du->dk_flags & (DKFL_DMA|DKFL_SINGLE)) == DKFL_DMA)
2031 wddma[du->dk_interface].wdd_dmadone(du->dk_dmacookie);
2032 (void)wdwait(du, 0, TIMEOUT);
2033 outb(du->dk_altport, WDCTL_IDS | WDCTL_RST);
2035 outb(du->dk_altport, WDCTL_IDS);
2036 outb(du->dk_port + wd_sdh, WDSD_IBM | (du->dk_unit << 4));
2037 if (wdwait(du, 0, TIMEOUT) != 0)
2038 err = 1; /* no IDE drive found */
2039 du->dk_error = inb(du->dk_port + wd_error);
2040 if (du->dk_error != 0x01)
2041 err = 1; /* the drive is incompatible */
2042 outb(du->dk_altport, WDCTL_4BIT);
2047 * Sleep until driver is inactive.
2048 * This is used only for avoiding rare race conditions, so it is unimportant
2049 * that the sleep may be far too short or too long.
2052 wdsleep(int ctrlr, char *wmesg)
2055 if (eide_quirks & Q_CMD640B)
2057 while (wdtab[ctrlr].b_active)
2058 tsleep((caddr_t)&wdtab[ctrlr].b_active, PZERO - 1, wmesg, 1);
2063 wdtimeout(void *cdu)
2067 static int timeouts;
2069 du = (struct disk *)cdu;
2071 if (du->dk_timeout != 0 && --du->dk_timeout == 0) {
2072 if(timeouts++ <= 5) {
2075 msg = (timeouts > 5) ?
2076 "Last time I say: interrupt timeout. Probably a portable PC." :
2077 "interrupt timeout";
2078 wderror((struct buf *)NULL, du, msg);
2079 if (du->dk_dmacookie)
2080 printf("wd%d: wdtimeout() DMA status %b\n",
2082 wddma[du->dk_interface].wdd_dmastatus(du->dk_dmacookie),
2088 du->dk_flags |= DKFL_SINGLE;
2089 wdstart(du->dk_ctrlr);
2091 timeout(wdtimeout, cdu, hz);
2096 * Reset the controller after it has become wedged. This is different from
2097 * wdreset() so that wdreset() can be used in the probe and so that this
2098 * can restore the geometry .
2101 wdunwedge(struct disk *du)
2106 /* Schedule other drives for recalibration. */
2107 for (lunit = 0; lunit < NWD; lunit++)
2108 if ((du1 = wddrives[lunit]) != NULL && du1 != du
2109 && du1->dk_ctrlr == du->dk_ctrlr
2110 && du1->dk_state > WANTOPEN)
2111 du1->dk_state = WANTOPEN;
2113 DELAY(RECOVERYTIME);
2114 if (wdreset(du) == 0) {
2116 * XXX - recalibrate current drive now because some callers
2117 * aren't prepared to have its state change.
2119 if (wdcommand(du, 0, 0, 0, 0, WDCC_RESTORE | WD_STEP) == 0
2120 && wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) == 0
2121 && wdsetctlr(du) == 0)
2124 wderror((struct buf *)NULL, du, "wdunwedge failed");
2129 * Wait uninterruptibly until controller is not busy and either certain
2130 * status bits are set or an error has occurred.
2131 * The wait is usually short unless it is for the controller to process
2132 * an entire critical command.
2133 * Return 1 for (possibly stale) controller errors, -1 for timeout errors,
2134 * or 0 for no errors.
2135 * Return controller status in du->dk_status and, if there was a controller
2136 * error, return the error code in du->dk_error.
2138 #ifdef WD_COUNT_RETRIES
2139 static int min_retries[NWDC];
2143 wdwait(struct disk *du, u_char bits_wanted, int timeout)
2148 #define POLLING 1000
2154 * This delay is really too long, but does not impact the performance
2155 * as much when using the multi-sector option. Shorter delays have
2156 * caused I/O errors on some drives and system configs. This should
2157 * probably be fixed if we develop a better short term delay mechanism.
2162 #ifdef WD_COUNT_RETRIES
2163 if (min_retries[du->dk_ctrlr] > timeout
2164 || min_retries[du->dk_ctrlr] == 0)
2165 min_retries[du->dk_ctrlr] = timeout;
2167 du->dk_status = status = inb(wdc + wd_status);
2169 * Atapi drives have a very interesting feature, when attached
2170 * as a slave on the IDE bus, and there is no master.
2171 * They release the bus after getting the command.
2172 * We should reselect the drive here to get the status.
2174 if (status == 0xff) {
2175 outb(wdc + wd_sdh, WDSD_IBM | du->dk_unit << 4);
2176 du->dk_status = status = inb(wdc + wd_status);
2178 if (!(status & WDCS_BUSY)) {
2179 if (status & WDCS_ERR) {
2180 du->dk_error = inb(wdc + wd_error);
2182 * We once returned here. This is wrong
2183 * because the error bit is apparently only
2184 * valid after the controller has interrupted
2185 * (e.g., the error bit is stale when we wait
2186 * for DRQ for writes). So we can't depend
2187 * on the error bit at all when polling for
2188 * command completion.
2191 if ((status & bits_wanted) == bits_wanted) {
2192 return (status & WDCS_ERR);
2195 if (timeout < TIMEOUT)
2197 * Switch to a polling rate of about 1 KHz so that
2198 * the timeout is almost machine-independent. The
2199 * controller is taking a long time to respond, so
2200 * an extra msec won't matter.
2205 } while (--timeout != 0);
2209 #endif /* NWDC > 0 */