diff options
author | dg <dg@FreeBSD.org> | 1995-10-14 15:41:10 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1995-10-14 15:41:10 +0000 |
commit | 8d3425ea6285435601f20980b43c3143b05bc8d7 (patch) | |
tree | 70f4d924760a26cfd35ea6eb6ac64af1e30cefa4 /sys/i386/isa/wd.c | |
parent | a308e5f9a1ba49753fdbe0e60fd5ee377a5096df (diff) | |
download | FreeBSD-src-8d3425ea6285435601f20980b43c3143b05bc8d7.zip FreeBSD-src-8d3425ea6285435601f20980b43c3143b05bc8d7.tar.gz |
Latest fixes from Serge:
I tried to solve the problem of IDE probing compatibility in this version.
When compiled without an ATAPI option, the wd driver is
fully backward compatible with 2.0.5. With ATAPI option,
the wdprobe becomes strictly weaker. That is, if wdprobe works
without ATAPI option, it will always work with it too.
Another problem was with the CD-ROM drive attached as a slave
in the IDE bus, where there is no master. All IDE CD-ROM
drives are shipped in slave configuration, and most users
just plug them in, never thinking about jumpers.
It works fine with ms-dos and ms-windows, and this
version of the driver supports it as well.
The eject op can now load disks. Just repeat it twice,
and the disk will be ejected and then loaded back.
The disc cannot be ejected if it is mounted.
Submitted by: Serge Vakulenko, <vak@cronyx.ru>
Diffstat (limited to 'sys/i386/isa/wd.c')
-rw-r--r-- | sys/i386/isa/wd.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/sys/i386/isa/wd.c b/sys/i386/isa/wd.c index 115f275..d3c8ec3 100644 --- a/sys/i386/isa/wd.c +++ b/sys/i386/isa/wd.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)wd.c 7.2 (Berkeley) 5/9/91 - * $Id: wd.c,v 1.85 1995/09/30 00:11:19 jkh Exp $ + * $Id: wd.c,v 1.86 1995/09/30 15:19:44 davidg Exp $ */ /* TODO: @@ -301,11 +301,34 @@ wdprobe(struct isa_device *dvp) /* check if we have registers that work */ outb(du->dk_port + wd_sdh, WDSD_IBM); /* set unit 0 */ outb(du->dk_port + wd_cyl_lo, 0xa5); /* wd_cyl_lo is read/write */ - if (inb(du->dk_port + wd_cyl_lo) == 0xff) /* XXX too weak */ - goto nodevice; + if (inb(du->dk_port + wd_cyl_lo) == 0xff) { /* XXX too weak */ +#ifdef ATAPI + /* There is no master, try the ATAPI slave. */ + outb(du->dk_port + wd_sdh, WDSD_IBM | 0x10); + outb(du->dk_port + wd_cyl_lo, 0xa5); + if (inb(du->dk_port + wd_cyl_lo) == 0xff) +#endif + goto nodevice; + } - if (wdreset(du) != 0 && (DELAY(RECOVERYTIME), wdreset(du)) != 0) + if (wdreset(du) == 0) + goto reset_ok; +#ifdef ATAPI + /* test for ATAPI signature */ + outb(du->dk_port + wd_sdh, WDSD_IBM); /* master */ + if (inb(du->dk_port + wd_cyl_lo) == 0x14 && + inb(du->dk_port + wd_cyl_hi) == 0xeb) + goto reset_ok; + du->dk_unit = 1; + outb(du->dk_port + wd_sdh, WDSD_IBM | 0x10); /* slave */ + if (inb(du->dk_port + wd_cyl_lo) == 0x14 && + inb(du->dk_port + wd_cyl_hi) == 0xeb) + goto reset_ok; +#endif + DELAY(RECOVERYTIME); + if (wdreset(du) != 0) goto nodevice; +reset_ok: /* execute a controller only command */ if (wdcommand(du, 0, 0, 0, 0, WDCC_DIAGNOSE) != 0 @@ -657,7 +680,7 @@ loop: bp = wdtab[ctrlr].b_actf; if (bp == NULL) { #ifdef ATAPI - if (atapi_start (ctrlr)) + if (atapi_start && atapi_start (ctrlr)) /* mark controller active in ATAPI mode */ wdtab[ctrlr].b_active = 3; #endif @@ -891,7 +914,7 @@ wdintr(int unit) #ifdef ATAPI if (wdtab[unit].b_active == 3) { /* process an ATAPI interrupt */ - if (atapi_intr (unit)) + if (atapi_intr && atapi_intr (unit)) /* ATAPI op continues */ return; /* controller is free, start new op */ @@ -1916,13 +1939,6 @@ wdreset(struct disk *du) du->dk_error = inb(wdc + wd_error); if (du->dk_error != 0x01) err = 1; /* the drive is incompatible */ - if (err) { - /* no IDE drive, test for ATAPI signature */ - int lo = inb(wdc + wd_cyl_lo); - int hi = inb(wdc + wd_cyl_hi); - if (lo == 0x14 && hi == 0xeb) - err = 0; /* ATAPI drive detected */ - } #else if (wdwait(du, WDCS_READY | WDCS_SEEKCMPLT, TIMEOUT) != 0 || (du->dk_error = inb(wdc + wd_error)) != 0x01) @@ -2042,6 +2058,18 @@ wdwait(struct disk *du, u_char bits_wanted, int timeout) min_retries[du->dk_ctrlr] = timeout; #endif du->dk_status = status = inb(wdc + wd_status); +#ifdef ATAPI + /* + * Atapi drives have a very interesting feature, when attached + * as a slave on the IDE bus, and there is no master. + * They release the bus after getting the command. + * We should reselect the drive here to get the status. + */ + if (status == 0xff) { + outb(wdc + wd_sdh, WDSD_IBM | du->dk_unit << 4); + du->dk_status = status = inb(wdc + wd_status); + } +#endif if (!(status & WDCS_BUSY)) { if (status & WDCS_ERR) { du->dk_error = inb(wdc + wd_error); |