static int wormdevopen(ScsiReq *rp) { int32_t status; uint8_t list[MaxDirData]; if (SRstart(rp, 1) == -1 || (status = SRmodesense10(rp, Allmodepages, list, sizeof list)) == -1) return -1; /* nbytes = list[0]<<8 | list[1]; */ /* # of bytes of block descriptors of 8 bytes each; not even 1? */ if((list[6]<<8 | list[7]) < 8) rp->lbsize = 2048; else /* last 3 bytes of block 0 descriptor */ rp->lbsize = GETBE24(list+13); if(debug) fprint(2, "disk: wormdevopen: 10-byte logical block size %lud\n", rp->lbsize); return status; }
static long cmdmodesense10(ScsiReq *rp, int argc, char *argv[]) { uchar *list, *lp, page; long blen, i, n, nbytes, status; char *p; nbytes = MaxDirData; switch(argc){ default: rp->status = Status_BADARG; return -1; case 2: if((nbytes = strtoul(argv[1], &p, 0)) == 0 && p == argv[1]){ rp->status = Status_BADARG; return -1; } /*FALLTHROUGH*/ case 1: if((page = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){ rp->status = Status_BADARG; return -1; } break; case 0: page = Allmodepages; break; } list = malloc(nbytes); if(list == 0){ rp->status = STnomem; return -1; } if((status = SRmodesense10(rp, page, list, nbytes)) == -1) return -1; lp = list; nbytes = ((list[0]<<8)|list[1]); Bprint(&bout, " Header\n "); for(i = 0; i < 8; i++){ /* header */ Bprint(&bout, " %2.2uX", *lp); lp++; } Bputc(&bout, '\n'); blen = (list[6]<<8)|list[7]; if(blen){ /* block descriptors */ for(n = 0; n < blen/8; n++){ Bprint(&bout, " Block %ld\n ", n); for(i = 0; i < 8; i++) Bprint(&bout, " %2.2uX", lp[i]); Bprint(&bout, " (density %2.2uX", lp[0]); Bprint(&bout, " blocks %d", (lp[1]<<16)|(lp[2]<<8)|lp[3]); Bprint(&bout, " length %d)", (lp[5]<<16)|(lp[6]<<8)|lp[7]); lp += 8; nbytes -= 8; Bputc(&bout, '\n'); } } /* * Special for ATA drives, page 0 is the drive info in 16-bit * chunks, little-endian, 256 in total. No decoding for now. */ if(page == 0){ for(n = 0; n < nbytes; n += 2){ if(n && ((n & 0x1F) == 0)) Bprint(&bout, "\n"); Bprint(&bout, " %4.4uX", (*(lp+1)<<8)|*lp); lp += 2; } Bputc(&bout, '\n'); } else while(nbytes > 0){ /* pages */ i = *(lp+1); nbytes -= i+2; Bprint(&bout, " Page %2.2uX %d\n ", *lp & 0x3F, lp[1]); lp += 2; for(n = 0; n < i; n++){ if(n && ((n & 0x0F) == 0)) Bprint(&bout, "\n "); Bprint(&bout, " %2.2uX", *lp); lp++; } if(n && (n & 0x0F)) Bputc(&bout, '\n'); } free(list); return status; }