From 23c90a71403861ded3d26bf888e9eb1529b83e50 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 26 May 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-05-26 --- pc/sdata.c | 57 +++++++++++++++++++++++++++++++++++------------- port/devbridge.c | 2 +- port/devsd.c | 52 +++++++++++++++++++------------------------ port/sd.h | 3 +-- 4 files changed, 66 insertions(+), 48 deletions(-) diff --git a/pc/sdata.c b/pc/sdata.c index 405148dcc3dda1590242745c26892d3e96d4e1a6..48cbcf7fd187311227222a3b1e8b3e699e2e0e3c 100644 --- a/pc/sdata.c +++ b/pc/sdata.c @@ -91,6 +91,7 @@ enum { /* Command */ Cidpkt = 0xA1, /* Identify Packet Device */ Crsm = 0xC4, /* Read Multiple */ Cwsm = 0xC5, /* Write Multiple */ + Csm = 0xC6, /* Set Multiple */ Crdq = 0xC7, /* Read DMA queued */ Crd = 0xC8, /* Read DMA */ Cwd = 0xCA, /* Write DMA */ @@ -225,11 +226,12 @@ typedef struct Drive { int s; /* sector */ int sectors; /* total */ int secsize; /* sector size */ + + int dma; /* DMA R/W possible */ + int block; /* R/W multiple size */ int pior; /* PIO read command */ int piow; /* PIO write command */ - int dma; /* DMA R/W possible */ - int pkt; /* PACKET device, length of pktcmd */ uchar sense[18]; uchar inquiry[48]; @@ -244,6 +246,7 @@ typedef struct Drive { int status; int error; + int pkt; /* PACKET device, length of pktcmd */ uchar pktcmd[16]; int pktdma; } Drive; @@ -411,6 +414,40 @@ atacsfenabled(Drive* drive, vlong csf) return 0; } +static int +atasetrwmode(Drive* drive, int cmdport, int ctlport, int dev) +{ + int as, block; + + drive->block = drive->secsize; + drive->pior = Crs; + drive->piow = Cws; + if((block = drive->info[Imaxrwm] & 0xFF) == 0) + return 0; + + /* + * Prior to ATA-4 there was no way to determine the + * current block count (now in Irwm). + * Sometimes drives come up with the current count set + * to 0, so always set a suitable value. + */ + if(ataready(cmdport, ctlport, dev, Bsy|Drq, Drdy, 100*1000) < 0) + return 0; + outb(cmdport+Sector, block); + outb(cmdport+Command, Csf); + microdelay(1); + as = ataready(cmdport, ctlport, dev, Bsy, Drdy|Df|Err, 1000); + if(as < 0 || (as & (Df|Err))) + return -1; + + drive->info[Irwm] = 0x100|block; + drive->block = block*drive->secsize; + drive->pior = Crsm; + drive->piow = Cwsm; + + return block; +} + static Drive* ataidentify(int cmdport, int ctlport, int dev) { @@ -471,6 +508,8 @@ retry: *p++ = *sp>>8; *p++ = *sp++; } + + drive->secsize = 512; if((drive->info[Iconfig] & 0xC000) == 0x8000){ if(drive->info[Iconfig] & 0x01) drive->pkt = 16; @@ -495,20 +534,8 @@ retry: } else drive->sectors = drive->c*drive->h*drive->s; + atasetrwmode(drive, cmdport, ctlport, dev); } - drive->secsize = 512; - - if((drive->info[Imaxrwm] & 0xFF) && (drive->info[Irwm] & 0x0100)){ - drive->block = drive->info[Imaxrwm] & 0x00FF; - drive->pior = Crsm; - drive->piow = Cwsm; - } - else{ - drive->block = 1; - drive->pior = Crs; - drive->piow = Cws; - } - drive->block *= drive->secsize; /* * Check if any DMA mode enabled. diff --git a/port/devbridge.c b/port/devbridge.c index 66f9a3e2242f06364cf38035e787411cc9290d4f..71164e87b91bb3a85fe845ddaa5fe00fab2b5d5b 100644 --- a/port/devbridge.c +++ b/port/devbridge.c @@ -30,7 +30,7 @@ enum MaxQ, Maxbridge= 4, - Maxport= 32, // power of 2 + Maxport= 64, // power of 2 CacheHash= 257, // prime CacheLook= 5, // how many cache entries to examine CacheSize= (CacheHash+CacheLook-1), diff --git a/port/devsd.c b/port/devsd.c index 0b48502c4c8109ad3c8c00651fecab153d0678fb..12a189503b49de889e3c32a1a358d9454c373c83 100644 --- a/port/devsd.c +++ b/port/devsd.c @@ -328,7 +328,7 @@ sd2gen(Chan* c, int i, Dir* dp) return 1; case Qraw: q = (Qid){QID(UNIT(c->qid), PART(c->qid), Qraw), c->qid.vers}; - devdir(c, q, "raw", 0, eve, 0600, dp); + devdir(c, q, "raw", 0, eve, CHEXCL|0600, dp); return 1; case Qpart: unit = sdunit[UNIT(c->qid)]; @@ -492,6 +492,12 @@ sdopen(Chan* c, int omode) switch(TYPE(c->qid)){ default: break; + case Qraw: + unit = sdunit[UNIT(c->qid)]; + if(!canlock(&unit->rawinuse)) + error(Einuse); + unit->state = Rawcmd; + break; case Qpart: unit = sdunit[UNIT(c->qid)]; qlock(&unit->ctl); @@ -528,11 +534,7 @@ sdclose(Chan* c) break; case Qraw: unit = sdunit[UNIT(c->qid)]; - if(canqlock(&unit->raw) || unit->pid == up->pid){ - unit->pid = 0; - unit->state = Rawcmd; - qunlock(&unit->raw); - } + unlock(&unit->rawinuse); break; case Qpart: unit = sdunit[UNIT(c->qid)]; @@ -744,23 +746,15 @@ sdread(Chan *c, void *a, long n, vlong off) return l; case Qraw: unit = sdunit[UNIT(c->qid)]; - if(canqlock(&unit->raw)){ - qunlock(&unit->raw); - error(Ebadusefd); - } - if(unit->pid != up->pid) - error(Eperm); if(unit->state == Rawdata){ unit->state = Rawstatus; return sdrio(unit->req, a, n); } else if(unit->state == Rawstatus){ status = unit->req->status; - unit->pid = 0; unit->state = Rawcmd; free(unit->req); unit->req = nil; - qunlock(&unit->raw); return readnum(0, a, n, status, NUMSIZE); } break; @@ -819,21 +813,15 @@ sdwrite(Chan *c, void *a, long n, vlong off) poperror(); free(cb); break; + case Qraw: unit = sdunit[UNIT(c->qid)]; - if(canqlock(&unit->raw)){ - if(unit->state != Rawcmd){ - qunlock(&unit->raw); - error(Ebadusefd); - } - if(n < 6 || n > sizeof(req->cmd)){ - qunlock(&unit->raw); + switch(unit->state){ + case Rawcmd: + if(n < 6 || n > sizeof(req->cmd)) error(Ebadarg); - } - if((req = malloc(sizeof(SDreq))) == nil){ - qunlock(&unit->raw); + if((req = malloc(sizeof(SDreq))) == nil) error(Enomem); - } req->unit = unit; memmove(req->cmd, a, n); req->clen = n; @@ -841,12 +829,16 @@ sdwrite(Chan *c, void *a, long n, vlong off) req->status = ~0; unit->req = req; - unit->pid = up->pid; unit->state = Rawdata; - } - else{ - if(unit->pid != up->pid) - error(Eperm); + break; + + case Rawstatus: + unit->state = Rawcmd; + free(unit->req); + unit->req = nil; + error(Ebadusefd); + + case Rawdata: if(unit->state != Rawdata) error(Ebadusefd); unit->state = Rawstatus; diff --git a/port/sd.h b/port/sd.h index 8d4c68b4eb5cfdd435b1c9c6af309b5f6f17017e..4d0b4a98fd31fda55c8a773c70ff485866aa8f1c 100644 --- a/port/sd.h +++ b/port/sd.h @@ -32,9 +32,8 @@ typedef struct SDunit { int nopen; /* of partitions on this unit */ int changed; - QLock raw; + Lock rawinuse; int state; - ulong pid; SDreq* req; } SDunit;