static long loopbio(SDunit *u, int, int write, void *a, long count, uvlong lba) { uchar *data; int n; long (*rio)(Chan*, void*, long, vlong); Ctlr *c; c = u->dev->ctlr; data = a; if(write) rio = devtab[c->c->type]->write; else rio = devtab[c->c->type]->read; if(waserror()){ if(strcmp(up->errstr, Echange) == 0 || strstr(up->errstr, "device is down") != nil) u->sectors = 0; nexterror(); } n = rio(c->c, data, c->sectsize * count, c->sectsize * lba); poperror(); return n; }
static long aoebio(SDunit *u, int, int write, void *a, long count, uvlong lba) { uchar *data; int n; long (*rio)(Chan*, void*, long, vlong); Ctlr *c; c = u->dev->ctlr; // if(c->feat & Datapi) // return scsibio(u, lun, write, a, count, lba); data = a; if(write) rio = devtab[c->c->type]->write; else rio = devtab[c->c->type]->read; if(waserror()) { if(strcmp(up->errstr, Echange) == 0 || strcmp(up->errstr, Enotup) == 0) u->sectors = 0; nexterror(); } n = rio(c->c, data, Aoesectsz * count, Aoesectsz * lba); poperror(); return n; }
static int aoerio(SDreq *r) { int i, count; uvlong lba; char *name; uchar *cmd; long (*rio)(Chan*, void*, long, vlong); Ctlr *c; SDunit *unit; unit = r->unit; c = unit->dev->ctlr; // if(c->feat & Datapi) // return aoeriopkt(r, d); cmd = r->cmd; name = unit->name; if(r->cmd[0] == 0x35 || r->cmd[0] == 0x91){ // qlock(c); // i = flushcache(); // qunlock(c); // if(i == 0) // return sdsetsense(r, SDok, 0, 0, 0); return sdsetsense(r, SDcheck, 3, 0xc, 2); } if((i = sdfakescsi(r, c->ident, sizeof c->ident)) != SDnostatus){ r->status = i; return i; } switch(*cmd){ case 0x88: case 0x28: rio = devtab[c->c->type]->read; break; case 0x8a: case 0x2a: rio = devtab[c->c->type]->write; break; default: print("%s: bad cmd %#.2ux\n", name, cmd[0]); r->status = SDcheck; return SDcheck; } if(r->data == nil) return SDok; if(r->clen == 16){ if(cmd[2] || cmd[3]) return sdsetsense(r, SDcheck, 3, 0xc, 2); lba = (uvlong)cmd[4]<<40 | (uvlong)cmd[5]<<32; lba |= cmd[6]<<24 | cmd[7]<<16 | cmd[8]<<8 | cmd[9]; count = cmd[10]<<24 | cmd[11]<<16 | cmd[12]<<8 | cmd[13]; }else{ lba = cmd[2]<<24 | cmd[3]<<16 | cmd[4]<<8 | cmd[5]; count = cmd[7]<<8 | cmd[8]; } count *= Aoesectsz; if(r->dlen < count) count = r->dlen & ~0x1ff; if(waserror()){ if(strcmp(up->errstr, Echange) == 0 || strcmp(up->errstr, Eaoedown) == 0) unit->sectors = 0; nexterror(); } r->rlen = rio(c->c, r->data, count, Aoesectsz * lba); poperror(); r->status = SDok; return SDok; }