From df1d6ba99da637f21cc38d2690ad599c1a803a86 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Thu, 19 Apr 2012 23:56:10 +0200 Subject: [PATCH] sdide: do drive presence check in atadrive, probe slave drive before master. --- sys/src/9/pc/sdide.c | 48 +++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/sys/src/9/pc/sdide.c b/sys/src/9/pc/sdide.c index 1ab4fe8e5..007d6b89f 100644 --- a/sys/src/9/pc/sdide.c +++ b/sys/src/9/pc/sdide.c @@ -549,7 +549,7 @@ atadmamode(SDunit *unit, Drive* drive) static int ataidentify(Ctlr*, int cmdport, int ctlport, int dev, int pkt, void* info) { - int as, command, drdy, rlo, rhi; + int as, command, drdy; if(pkt){ command = Cidpkt; @@ -561,51 +561,32 @@ ataidentify(Ctlr*, int cmdport, int ctlport, int dev, int pkt, void* info) } dev &= ~Lba; as = ataready(cmdport, ctlport, dev, Bsy|Drq, drdy, 103*1000); - if(as < 0){ - /* try to detect floating bus */ - outb(cmdport+Cyllo, 0xAA); - outb(cmdport+Cylhi, 0x55); - outb(cmdport+Sector, 0xFF); - rlo = inb(cmdport+Cyllo); - rhi = inb(cmdport+Cylhi); - if(rlo != 0xAA && (rlo == 0xFF || rhi != 0x55)) - return as; - - /* theres a device, try waiting some more */ - as = ataready(cmdport, ctlport, dev, Bsy|Drq, drdy, 6*1000*1000); - if(as < 0) - return as; - } + if(as < 0) + return -1; outb(cmdport+Command, command); microdelay(1); as = ataready(cmdport, ctlport, 0, Bsy, Drq|Err, 400*1000); - if(as < 0) - return -1; - if(as & Err) + if(as < 0 || (as & Err)) return as; - memset(info, 0, 512); inss(cmdport+Data, info, 256); - - ataready(cmdport, ctlport, dev, Bsy|Drq, drdy, 3*1000); inb(cmdport+Status); - return 0; } static Drive* atadrive(SDunit *unit, Drive *drive, int cmdport, int ctlport, int dev) { - int as, pkt; + int as, pkt, rlo, rhi; uchar buf[512], oserial[21]; uvlong osectors; Ctlr *ctlr; if(DEBUG & DbgIDENTIFY) print("identify: port %ux dev %.2ux\n", cmdport, dev & ~Lba); + atadebug(0, 0, "identify: port 0x%uX dev 0x%2.2uX\n", cmdport, dev); - pkt = 1; if(drive != nil){ osectors = drive->sectors; memmove(oserial, drive->serial, sizeof drive->serial); @@ -614,7 +595,20 @@ atadrive(SDunit *unit, Drive *drive, int cmdport, int ctlport, int dev) osectors = 0; memset(oserial, 0, sizeof drive->serial); ctlr = nil; + + /* detect if theres a drive present */ + outb(cmdport+Dh, dev & ~Lba); + microdelay(1); + outb(cmdport+Cyllo, 0xAA); + outb(cmdport+Cylhi, 0x55); + outb(cmdport+Sector, 0xFF); + rlo = inb(cmdport+Cyllo); + rhi = inb(cmdport+Cylhi); + if(rlo != 0xAA && (rlo == 0xFF || rhi != 0x55)) + return nil; } + + pkt = 1; retry: as = ataidentify(ctlr, cmdport, ctlport, dev, pkt, buf); if(as < 0) @@ -724,10 +718,10 @@ ataprobe(int cmdport, int ctlport, int irq, int map) goto release; } - if((map & 1) && (ctlr->drive[0] = atadrive(0, 0, cmdport, ctlport, Dev0))) - ctlr->drive[0]->ctlr = ctlr; if((map & 2) && (ctlr->drive[1] = atadrive(0, 0, cmdport, ctlport, Dev1))) ctlr->drive[1]->ctlr = ctlr; + if((map & 1) && (ctlr->drive[0] = atadrive(0, 0, cmdport, ctlport, Dev0))) + ctlr->drive[0]->ctlr = ctlr; if(ctlr->drive[0] == nil && ctlr->drive[1] == nil){ free(ctlr->drive[0]);