int scsiready(Scsi *s) { return _scsiready(s, 1); }
int scsi(Scsi *s, uchar *cmd, int ccount, void *v, int dcount, int io) { uchar req[6], sense[255], *data; int tries, code, key, n; char *p; data = v; SET(key); SET(code); qlock(&s->lk); for(tries=0; tries<2; tries++) { n = _scsicmd(s, cmd, ccount, data, dcount, io, 0); if(n >= 0) { qunlock(&s->lk); return n; } /* * request sense */ memset(req, 0, sizeof(req)); req[0] = 0x03; req[4] = sizeof(sense); memset(sense, 0xFF, sizeof(sense)); if((n=_scsicmd(s, req, sizeof(req), sense, sizeof(sense), Sread, 0)) < 14) if(scsiverbose) fprint(2, "reqsense scsicmd %d: %r\n", n); if(_scsiready(s, 0) < 0) if(scsiverbose) fprint(2, "unit not ready\n"); key = sense[2]; code = sense[12]; if(code == 0x17 || code == 0x18) { /* recovered errors */ qunlock(&s->lk); return dcount; } if(code == 0x28 && cmd[0] == 0x43) { /* get info and media changed */ s->nchange++; s->changetime = time(0); continue; } } /* drive not ready, or medium not present */ if(cmd[0] == 0x43 && key == 2 && (code == 0x3a || code == 0x04)) { s->changetime = 0; qunlock(&s->lk); return -1; } qunlock(&s->lk); if(cmd[0] == 0x43 && key == 5 && code == 0x24) /* blank media */ return -1; p = scsierror(code, sense[13]); werrstr("cmd #%.2ux: %s", cmd[0], p); if(scsiverbose) fprint(2, "scsi cmd #%.2ux: %.2ux %.2ux %.2ux: %s\n", cmd[0], key, code, sense[13], p); /* if(key == 0) */ /* return dcount; */ return -1; }
int scsi(Scsi *s, uchar *cmd, int ccount, void *v, int dcount, int io) { uchar req[6], sense[255], *data; int tries, code, key, n; char *p; data = v; SET(key, code); qlock(s); for(tries=0; tries<2; tries++) { n = _scsicmd(s, cmd, ccount, data, dcount, io, 0); if(n >= 0) { qunlock(s); return n; } /* * request sense */ memset(req, 0, sizeof(req)); req[0] = Reqsense; req[4] = sizeof(sense); memset(sense, 0xFF, sizeof(sense)); if((n=_scsicmd(s, req, sizeof(req), sense, sizeof(sense), Sread, 0)) < 14) if(scsiverbose) fprint(2, "reqsense scsicmd %d: %r\n", n); if(_scsiready(s, 0) < 0) if(scsiverbose) fprint(2, "unit not ready\n"); key = sense[2] & 0xf; code = sense[12]; /* asc */ if(code == Recovnoecc || code == Recovecc) { /* recovered errors */ qunlock(s); return dcount; } /* retry various odd cases */ if(code == Newmedium && cmd[0] == Readtoc) { /* read toc and media changed */ s->nchange++; s->changetime = time(0); } else if((cmd[0] == Write10 || cmd[0] == Writever10) && key == Sensenotrdy && code == Lunnotrdy && sense[13] == 0x08) { /* long write in progress, per mmc-6 */ tries = 0; sleep(1); } } /* drive not ready, or medium not present */ if(cmd[0] == Readtoc && key == Sensenotrdy && (code == Nomedium || code == Lunnotrdy)) { s->changetime = 0; qunlock(s); return -1; } qunlock(s); if(cmd[0] == Readtoc && key == Sensebadreq && code == Badcdb) return -1; /* blank media */ p = scsierror(code, sense[13]); werrstr("cmd #%.2ux: %s", cmd[0], p); if(scsiverbose) fprint(2, "scsi cmd #%.2ux: %.2ux %.2ux %.2ux: %s\n", cmd[0], key, code, sense[13], p); // if(key == Sensenone) // return dcount; return -1; }