diff options
author | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-12-06 14:49:40 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@centraldogma> | 2011-12-06 14:49:40 +0100 |
commit | 077537baeb0be8a41253327e2dfd8ea8fb63d7cd (patch) | |
tree | 1ac8b9171df864538763264bc18af2c84d7a2353 | |
parent | 2720d097377419111f17adfa66f2966f238fb5fd (diff) |
fix cdrom media change
-rw-r--r-- | sys/src/9/pc/sdiahci.c | 25 | ||||
-rw-r--r-- | sys/src/9/pc/sdide.c | 19 | ||||
-rw-r--r-- | sys/src/9/port/sdscsi.c | 69 |
3 files changed, 66 insertions, 47 deletions
diff --git a/sys/src/9/pc/sdiahci.c b/sys/src/9/pc/sdiahci.c index 3bc9667da..c06b6a0dd 100644 --- a/sys/src/9/pc/sdiahci.c +++ b/sys/src/9/pc/sdiahci.c @@ -1473,24 +1473,22 @@ iaonline(SDunit *unit) c = unit->dev->ctlr; d = c->drive[unit->subno]; - r = 0; - - if(d->portm.feat & Datapi && d->drivechange){ - r = scsionline(unit); - if(r > 0) - d->drivechange = 0; - return r; - } - ilock(d); + if(d->portm.feat & Datapi){ + d->drivechange = 0; + iunlock(d); + return scsionline(unit); + } + r = 0; if(d->drivechange){ - r = 2; d->drivechange = 0; - /* devsd resets this after online is called; why? */ - unit->sectors = d->sectors; - unit->secsize = d->secsize; + r = 2; }else if(d->state == Dready) r = 1; + if(r){ + unit->sectors = d->sectors; + unit->secsize = d->secsize; + } iunlock(d); return r; } @@ -1707,7 +1705,6 @@ iariopkt(SDreq *r, Drive *d) case SDretry: continue; } -// print("%.2ux :: %.2ux :: %.4ux\n", r->cmd[0], r->status, d->port->task); r->rlen = d->portm.list->len; return SDok; } diff --git a/sys/src/9/pc/sdide.c b/sys/src/9/pc/sdide.c index e2c264597..ca489525c 100644 --- a/sys/src/9/pc/sdide.c +++ b/sys/src/9/pc/sdide.c @@ -1188,7 +1188,7 @@ atapktio0(Drive *drive, SDreq *r) cmdport = ctlr->cmdport; ctlport = ctlr->ctlport; - as = ataready(cmdport, ctlport, drive->dev, Bsy|Drq, Drdy, 107*1000); + as = ataready(cmdport, ctlport, drive->dev, Bsy|Drq, 0, 107*1000); /* used to test as&Chk as failure too, but some CD readers use that for media change */ if(as < 0) return SDnostatus; @@ -1242,12 +1242,12 @@ atapktio0(Drive *drive, SDreq *r) iunlock(ctlr); if(drive->status & Chk){ + rv = SDcheck; if(drive->pktdma){ print("atapktio: disabling dma\n"); drive->dmactl = 0; rv = SDretry; - } else - rv = SDcheck; + } } return rv; } @@ -1545,7 +1545,7 @@ atagenatastart(Drive* d, SDreq *r) ctlr = d->ctlr; cmdport = ctlr->cmdport; ctlport = ctlr->ctlport; - if(ataready(cmdport, ctlport, d->dev, Bsy|Drq, d->pkt? 0: Drdy, 101*1000) < 0) + if(ataready(cmdport, ctlport, d->dev, Bsy|Drq, d->pkt ? 0 : Drdy, 101*1000) < 0) return -1; ilock(ctlr); @@ -1902,7 +1902,6 @@ atainterrupt(Ureg*, void* arg) print("Inil%2.2uX+", ctlr->command); return; } - if(status & Err) drive->error = inb(cmdport+Error); else switch(drive->command){ @@ -1999,8 +1998,8 @@ badccru(Pcidev *p) switch(p->did<<16 | p->did){ case 0x439c<<16 | 0x1002: case 0x438c<<16 | 0x1002: -print("hi, anothy\n"); -print("%T: allowing bad ccru %.2ux for suspected ide controller\n", p->tbdf, p->ccru); + print("%T: allowing bad ccru %.2ux for suspected ide controller\n", + p->tbdf, p->ccru); return 1; default: return 0; @@ -2411,9 +2410,8 @@ ataonline(SDunit *unit) if((drive->flags & Online) == 0){ drive->flags |= Online; atadrive(unit, drive, ctlr->cmdport, ctlr->ctlport, drive->dev); + ret = 2; } - unit->sectors = drive->sectors; - unit->secsize = drive->secsize; if(drive->feat & Datapi){ ulong dma; @@ -2421,6 +2419,9 @@ ataonline(SDunit *unit) drive->dmactl = 0; ret = scsionline(unit); drive->dmactl = dma; + } else { + unit->sectors = drive->sectors; + unit->secsize = drive->secsize; } return ret; } diff --git a/sys/src/9/port/sdscsi.c b/sys/src/9/port/sdscsi.c index e4e3b20cb..dd4188ec7 100644 --- a/sys/src/9/port/sdscsi.c +++ b/sys/src/9/port/sdscsi.c @@ -214,7 +214,6 @@ capreply(SDreq *r, ulong *secsize) ulong ss; uvlong s; - *secsize = 0; u = r->data; if(r->clen == 16){ s = (uvlong)belong(u)<<32 | belong(u + 4); @@ -223,24 +222,8 @@ capreply(SDreq *r, ulong *secsize) s = belong(u); ss = belong(u + 4); } - /* - * Some ATAPI CD readers lie about the block size. - * Since we don't read audio via this interface - * it's okay to always fudge this. - */ - if(ss == 2352) - ss = 2048; - /* - * Devices with removable media may return 0 sectors - * when they have empty media (e.g. sata dvd writers); - * if so, keep the count zero. - * - * Read-capacity returns the LBA of the last sector, - * therefore the number of sectors must be incremented. - */ - if(s != 0) - s++; - *secsize = ss; + if(secsize) + *secsize = ss; return s; } @@ -249,6 +232,8 @@ scsionline(SDunit* unit) { SDreq *r; uchar *p; + ulong ss; + uvlong s; int ok, retries; void (*cap)(SDreq*); @@ -276,20 +261,51 @@ scsionline(SDunit* unit) memset(r->cmd, 0, sizeof r->cmd); cap(r); - r->status = ~0; switch(scsirio(r)){ default: + /* + * ATAPI returns error and no sense information + * on media change / no media present. + * count as retries. + */ + if(retries < 4) + continue; break; case 0: - unit->sectors = capreply(r, &unit->secsize); - if(unit->sectors == 0xffffffff && cap == cap10){ + s = capreply(r, &ss); + if(s == 0xffffffff && cap == cap10){ cap = cap16; continue; } - ok = 1; + if(s == 0xffffffffffffffffLL) + s = 0; + + /* + * Some ATAPI CD readers lie about the block size. + * Since we don't read audio via this interface + * it's okay to always fudge this. + */ + if(ss == 2352) + ss = 2048; + + /* + * Devices with removable media may return 0 sectors + * when they have empty media (e.g. sata dvd writers); + * if so, keep the count zero. + * + * Read-capacity returns the LBA of the last sector, + * therefore the number of sectors must be incremented. + */ + if(s != 0) + s++; + + ok = (unit->sectors != s) ? 2 : 1; + unit->sectors = s; + unit->secsize = ss; break; case 1: - ok = 1; + ok = (unit->sectors != 0) ? 2 : 1; + unit->sectors = 0; break; case 2: continue; @@ -299,6 +315,11 @@ scsionline(SDunit* unit) free(p); free(r); + /* + print("scsionline: %s: ok=%d retries=%d sectors=%llud secsize=%lud\n", + unit->name, ok, retries, unit->sectors, unit->secsize); + */ + if(ok) return ok+retries; else |