second crack at syncing up sdscsi Reference: /n/atom/patch/applied/sdscsiredux Date: Thu Mar 27 06:13:48 CET 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/nix/port/sdscsi.c Thu Mar 27 06:13:44 2014 +++ /sys/src/nix/port/sdscsi.c Thu Mar 27 06:13:44 2014 @@ -113,6 +113,67 @@ return 0; } +static int +scsirio(SDreq* r) +{ + /* + * Perform an I/O request, returning + * -1 failure + * 0 ok + * 1 no medium present + * 2 retry + * The contents of r may be altered so the + * caller should re-initialise if necesary. + */ + r->status = ~0; + switch(r->unit->dev->ifc->rio(r)){ + default: + break; + case SDcheck: + if(!(r->flags & SDvalidsense)) + break; + switch(r->sense[2] & 0x0F){ + case 0x00: /* no sense */ + case 0x01: /* recovered error */ + return 2; + case 0x06: /* check condition */ + /* + * 0x28 - not ready to ready transition, + * medium may have changed. + * 0x29 - power on or some type of reset. + */ + if(r->sense[12] == 0x28 && r->sense[13] == 0) + return 2; + if(r->sense[12] == 0x29) + return 2; + break; + case 0x02: /* not ready */ + /* + * If no medium present, bail out. + * If unit is becoming ready, rather than not + * not ready, wait a little then poke it again. + */ + if(r->sense[12] == 0x3A) + break; + if(r->sense[12] != 0x04 || r->sense[13] != 0x01) + break; + + while(waserror()) + ; + tsleep(&up->sleep, return0, 0, 500); + poperror(); + scsitest(r); + return 2; + default: + break; + } + break; + case SDok: + return 0; + } + return -1; +} + static void cap10(SDreq *r) { @@ -181,67 +242,6 @@ return s; } -static int -scsirio(SDreq* r) -{ - /* - * Perform an I/O request, returning - * -1 failure - * 0 ok - * 1 no medium present - * 2 retry - * The contents of r may be altered so the - * caller should re-initialise if necesary. - */ - r->status = ~0; - switch(r->unit->dev->ifc->rio(r)){ - default: - break; - case SDcheck: - if(!(r->flags & SDvalidsense)) - break; - switch(r->sense[2] & 0x0F){ - case 0x00: /* no sense */ - case 0x01: /* recovered error */ - return 2; - case 0x06: /* check condition */ - /* - * 0x28 - not ready to ready transition, - * medium may have changed. - * 0x29 - power on or some type of reset. - */ - if(r->sense[12] == 0x28 && r->sense[13] == 0) - return 2; - if(r->sense[12] == 0x29) - return 2; - break; - case 0x02: /* not ready */ - /* - * If no medium present, bail out. - * If unit is becoming ready, rather than not - * not ready, wait a little then poke it again. - */ - if(r->sense[12] == 0x3A) - break; - if(r->sense[12] != 0x04 || r->sense[13] != 0x01) - break; - - while(waserror()) - ; - tsleep(&up->sleep, return0, 0, 500); - poperror(); - scsitest(r); - return 2; - default: - break; - } - break; - case SDok: - return 0; - } - return -1; -} - int scsionline(SDunit* unit) { @@ -354,7 +354,7 @@ } static void -scsifmt10(SDreq *r, int write, int lun, long nb, vlong bno) +scsifmt10(SDreq *r, int write, int lun, ulong nb, uvlong bno) { uchar *c; @@ -377,7 +377,7 @@ } static void -scsifmt16(SDreq *r, int write, int lun, long nb, vlong bno) +scsifmt16(SDreq *r, int write, int lun, ulong nb, uvlong bno) { uchar *c; @@ -417,7 +417,7 @@ r->lun = lun; again: r->write = write; - if(bno >= (1ULL<<32)) + if(bno > 0xffffffff) scsifmt16(r, write, lun, nb, bno); else scsifmt10(r, write, lun, nb, bno); @@ -431,8 +431,19 @@ rlen = -1; break; case 0: - rlen = r->rlen; - break; + /* + * scsi allows commands to return successfully + * but return sense data, indicating that the + * operation didn't proceed as expected. + * (confusing, no). this allows the raw commands + * to successfully return errors. but any sense + * data bio sees must be an error. bomb out. + */ + if(r->status == SDok && r->rlen > 0 + && ((r->flags & SDvalidsense) == 0 || r->sense[2] == 0)){ + rlen = r->rlen; + break; + } case 2: rlen = -1; if(!(r->flags & SDvalidsense)) @@ -465,6 +476,10 @@ goto again; break; } + snprint(up->genbuf, sizeof up->genbuf, "%s %.2ux%.2ux%.2ux %lld", + Eio, r->sense[2], r->sense[12], r->sense[13], bno); + free(r); + error(up->genbuf); break; } free(r);