From 277a84a906788060bc527f729cc3aaa3dea1800d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 28 Dec 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-12-28 --- pc/sdata.c | 110 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 39 deletions(-) diff --git a/pc/sdata.c b/pc/sdata.c index a2f3b34d42d7508544801ec7dc4b75ac9f94bed9..b862325d25b38b599690369553e69af2d7267872 100644 --- a/pc/sdata.c +++ b/pc/sdata.c @@ -97,6 +97,7 @@ enum { /* Command */ Crd = 0xC8, /* Read DMA */ Cwd = 0xCA, /* Write DMA */ Cwdq = 0xCC, /* Write DMA queued */ + Cstandby = 0xE2, /* Standby */ Cid = 0xEC, /* Identify Device */ Csf = 0xEF, /* Set Features */ }; @@ -167,12 +168,8 @@ enum { /* offsets into the identify info. */ Iqdepth = 75, /* max. queue depth */ Imajor = 80, /* major version number */ Iminor = 81, /* minor version number */ - Icmdset0 = 82, /* command sets supported */ - Icmdset1 = 83, /* command sets supported */ - Icmdset2 = 84, /* command sets supported extension */ - Icmdset3 = 85, /* command sets enabled */ - Icmdset4 = 86, /* command sets enabled */ - Icmdset5 = 87, /* command sets enabled extension */ + Icsfs = 82, /* command set/feature supported */ + Icsfe = 85, /* command set/feature enabled */ Iudma = 88, /* ultra DMA mode */ Ierase = 89, /* time for security erase */ Ieerase = 90, /* time for enhanced security erase */ @@ -395,15 +392,21 @@ ataready(int cmdport, int ctlport, int dev, int reset, int ready, int micro) } static int -atacsfenabled(Drive* drive, vlong csf) +atacsf(Drive* drive, vlong csf, int supported) { + ushort *info; int cmdset, i, x; + if(supported) + info = &drive->info[Icsfs]; + else + info = &drive->info[Icsfe]; + for(i = 0; i < 3; i++){ x = (csf>>(16*i)) & 0xFFFF; if(x == 0) continue; - cmdset = drive->info[Icmdset3+i]; + cmdset = info[i]; if(cmdset == 0 || cmdset == 0xFFFF) return 0; return cmdset & x; @@ -413,21 +416,9 @@ atacsfenabled(Drive* drive, vlong csf) } static int -atasf(int cmdport, int ctlport, int dev, uchar* command) +atadone(void* arg) { - int as, i; - - if(ataready(cmdport, ctlport, dev, Bsy|Drq, Drdy, 108*1000) < 0) - return -1; - - for(i = Features; i < Dh; i++) - outb(cmdport+i, command[i]); - outb(cmdport+Command, Csf); - microdelay(100); - as = ataready(cmdport, ctlport, 0, Bsy, Drdy|Df|Err, 109*1000); - if(as < 0 || (as & (Df|Err))) - return -1; - return 0; + return ((Ctlr*)arg)->done; } static int @@ -527,7 +518,7 @@ ataidentify(int cmdport, int ctlport, int dev, int pkt, void* info) for(i = 0; i < 256; i++){ if(i && (i%16) == 0) print("\n"); - print("%4.4uX ", *sp); + print(" %4.4uX", *sp); sp++; } print("\n"); @@ -796,6 +787,39 @@ atasetsense(Drive* drive, int status, int key, int asc, int ascq) return status; } +static int +atastandby(Drive* drive, int period) +{ + Ctlr* ctlr; + int cmdport, done; + + ctlr = drive->ctlr; + drive->command = Cstandby; + qlock(ctlr); + + cmdport = ctlr->cmdport; + ilock(ctlr); + outb(cmdport+Count, period); + outb(cmdport+Dh, drive->dev); + ctlr->done = 0; + ctlr->curdrive = drive; + ctlr->command = Cstandby; /* debugging */ + outb(cmdport+Command, Cstandby); + iunlock(ctlr); + + while(waserror()) + ; + tsleep(ctlr, atadone, ctlr, 30*1000); + poperror(); + + done = ctlr->done; + qunlock(ctlr); + + if(!done || (drive->status & Err)) + return atasetsense(drive, SDcheck, 4, 8, drive->error); + return SDok; +} + static int atamodesense(Drive* drive, uchar* cmd) { @@ -865,7 +889,7 @@ ataabort(Drive* drive, int dolock) */ if(dolock) ilock(drive->ctlr); - if(atacsfenabled(drive, 0x0000000000004000LL)) + if(atacsf(drive, 0x0000000000004000LL, 0)) atanop(drive, 0); else{ atasrst(drive->ctlr->ctlport); @@ -982,12 +1006,6 @@ atadmainterrupt(Drive* drive, int count) ctlr->done = 1; } -static int -atapktiodone(void* arg) -{ - return ((Ctlr*)arg)->done; -} - static void atapktinterrupt(Drive* drive) { @@ -1092,9 +1110,9 @@ atapktio(Drive* drive, uchar* cmd, int clen) while(waserror()) ; if(!drive->pktdma) - sleep(ctlr, atapktiodone, ctlr); + sleep(ctlr, atadone, ctlr); else for(timeo = 0; !ctlr->done; timeo++){ - tsleep(ctlr, atapktiodone, ctlr, 1000); + tsleep(ctlr, atadone, ctlr, 1000); if(ctlr->done) break; ilock(ctlr); @@ -1121,12 +1139,6 @@ atapktio(Drive* drive, uchar* cmd, int clen) return r; } -static int -atageniodone(void* arg) -{ - return ((Ctlr*)arg)->done; -} - static int atageniostart(Drive* drive, int lba) { @@ -1325,7 +1337,7 @@ atagenio(Drive* drive, uchar* cmd, int) while(waserror()) ; - tsleep(ctlr, atageniodone, ctlr, 10*1000); + tsleep(ctlr, atadone, ctlr, 30*1000); poperror(); if(!ctlr->done){ /* @@ -1336,6 +1348,7 @@ atagenio(Drive* drive, uchar* cmd, int) */ atadumpstate(drive, cmd, lba, count); ataabort(drive, 1); + qunlock(ctlr); return atagenioretry(drive); } @@ -1540,6 +1553,10 @@ atainterrupt(Ureg*, void* arg) case Cwd: atadmainterrupt(drive, drive->count*drive->secsize); break; + + case Cstandby: + ctlr->done = 1; + break; } iunlock(ctlr); @@ -1776,6 +1793,7 @@ atarctl(SDunit* unit, char* p, int l) static int atawctl(SDunit* unit, Cmdbuf* cb) { + int period; Ctlr *ctlr; Drive *drive; @@ -1815,6 +1833,20 @@ atawctl(SDunit* unit, Cmdbuf* cb) else error(Ebadctl); } + else if(strcmp(cb->f[0], "standby") == 0){ + switch(cb->nf){ + default: + error(Ebadctl); + case 2: + period = strtol(cb->f[1], 0, 0); + if(period && (period < 30 || period > 240*5)) + error(Ebadctl); + period /= 5; + break; + } + if(atastandby(drive, period) != SDok) + error(Ebadctl); + } else error(Ebadctl); qunlock(drive);