This code cleans up some bugs that were introduced by earlier
patches, and fixes up the code which assumed that partitions started
on cylinder boundaries. Also, some other initialization bugs were
(hopefully) squashed.
AUTHOR: Bruce Evans and Andrew Chernov
386BSD-Patchkit: patch00072
*
* PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
* -------------------- ----- ----------------------
*
* PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
* -------------------- ----- ----------------------
- * CURRENT PATCH LEVEL: 3 00038
+ * CURRENT PATCH LEVEL: 4 00072
* -------------------- ----- ----------------------
*
* 17 Sep 92 Frank Maclachlan Fixed I/O error reporting on raw device
* -------------------- ----- ----------------------
*
* 17 Sep 92 Frank Maclachlan Fixed I/O error reporting on raw device
* boot problem.
* 19 Aug 92 Frank Maclachlan Fixed bug when first sector of a
* multisector read is in bad144 table.
* boot problem.
* 19 Aug 92 Frank Maclachlan Fixed bug when first sector of a
* multisector read is in bad144 table.
+ * 17 Jan 93 B. Evans & A.Chernov Fixed bugs from previous patches,
+ * driver initialization, and cylinder
+ * boundary conditions.
*/
/* TODO:peel out buffer at low ipl, speed improvement */
*/
/* TODO:peel out buffer at low ipl, speed improvement */
wdc = du->dk_port = dvp->id_iobase;
/* check if we have registers that work */
wdc = du->dk_port = dvp->id_iobase;
/* check if we have registers that work */
- outb(wdc+wd_error, 0x5a) ; /* error register not writable */
- outb(wdc+wd_cyl_lo, 0xa5) ; /* but all of cyllo are implemented */
- if(inb(wdc+wd_error) == 0x5a || inb(wdc+wd_cyl_lo) != 0xa5)
+ outb(wdc+wd_cyl_lo, 0xa5) ; /* wd_cyl_lo is read/write */
+ if(inb(wdc+wd_cyl_lo) != 0xa5)
goto nodevice;
/* reset the device */
goto nodevice;
/* reset the device */
du->dk_unit = unit;
}
else {
du->dk_unit = unit;
}
else {
- free(du, M_TEMP);
- wddrives[unit] = 0;
+ /* old ST506 controller */
+ printf(" %d:<wdgetctlr failed, assuming OK>",
+ unit);
lp = &du->dk_dd;
secpertrk = lp->d_nsectors;
secpercyl = lp->d_secpercyl;
lp = &du->dk_dd;
secpertrk = lp->d_nsectors;
secpercyl = lp->d_secpercyl;
+ if ((du->dk_flags & DKFL_BSDLABEL) != 0 && wdpart(bp->b_dev) != WDRAW)
+ blknum += lp->d_partitions[wdpart(bp->b_dev)].p_offset;
cylin = blknum / secpercyl;
head = (blknum % secpercyl) / secpertrk;
sector = blknum % secpertrk;
cylin = blknum / secpercyl;
head = (blknum % secpercyl) / secpertrk;
sector = blknum % secpertrk;
- if ((du->dk_flags & DKFL_BSDLABEL) != 0 && wdpart(bp->b_dev) != WDRAW)
- cylin += lp->d_partitions[wdpart(bp->b_dev)].p_offset
- / secpercyl;
/*
* See if the current block is in the bad block list.
/*
* See if the current block is in the bad block list.
outb(wdc+wd_sdh, WDSD_IBM | (unit << 4));
wdtab.b_active = 1;
outb(wdc+wd_sdh, WDSD_IBM | (unit << 4));
wdtab.b_active = 1;
+
+ /* wait for drive and controller to become ready */
+ for (i = 1000000; (inb(wdc+wd_status) & (WDCS_READY|WDCS_BUSY))
+ != WDCS_READY && i-- != 0; )
+ ;
outb(wdc+wd_command, WDCC_RESTORE | WD_STEP);
du->dk_state++;
splx(s);
outb(wdc+wd_command, WDCC_RESTORE | WD_STEP);
du->dk_state++;
splx(s);
stat, WDCS_BITS, inb(wdc+wd_error),
WDERR_BITS);
}
stat, WDCS_BITS, inb(wdc+wd_error),
WDERR_BITS);
}
- if (++wdtab.b_errcnt < RETRIES)
+ if (++wdtab.b_errcnt < RETRIES) {
+ du->dk_state = WANTOPEN;
bp->b_error = ENXIO; /* XXX needs translation */
goto badopen;
}
bp->b_error = ENXIO; /* XXX needs translation */
goto badopen;
}