static int seqdevopen(ScsiReq *rp) { uint8_t mode[16], limits[6]; if(SRrblimits(rp, limits) == -1) return -1; if(limits[1] == 0 && limits[2] == limits[4] && limits[3] == limits[5]){ rp->flags |= Fbfixed; rp->lbsize = limits[4]<<8 | limits[5]; if(debug) fprint(2, "disk: seqdevopen: 10-byte logical block size %lud\n", rp->lbsize); return 0; } /* * On some older hardware the optional 10-byte * modeselect command isn't implemented. */ if (force6bytecmds) rp->flags |= Fmode6; if(!(rp->flags & Fmode6)){ /* try 10-byte command first */ memset(mode, 0, sizeof mode); mode[3] = 0x10; /* device-specific param. */ mode[7] = 8; /* block descriptor length */ /* * exabytes can't handle this, and * modeselect(10) is optional. */ if(SRmodeselect10(rp, mode, sizeof mode) != -1){ rp->lbsize = 1; return 0; /* success */ } /* can't do 10-byte commands, back off to 6-byte ones */ rp->flags |= Fmode6; } /* 6-byte command */ memset(mode, 0, sizeof mode); mode[2] = 0x10; /* device-specific param. */ mode[3] = 8; /* block descriptor length */ /* * bsd sez exabytes need this bit (NBE: no busy enable) in * vendor-specific page (0), but so far we haven't needed it. mode[12] |= 8; */ if(SRmodeselect6(rp, mode, 4+8) == -1) return -1; rp->lbsize = 1; return 0; }
static long cmdmodeselect10(ScsiReq *rp, int argc, char *argv[]) { uchar list[MaxDirData]; long nbytes, ul; char *p; memset(list, 0, sizeof list); for(nbytes = 0; argc; argc--, argv++, nbytes++){ if((ul = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){ rp->status = Status_BADARG; return -1; } list[nbytes] = ul; } if(!(rp->flags & Finqok) && SRinquiry(rp) == -1) Bprint(&bout, "warning: couldn't determine whether SCSI-1/SCSI-2 mode"); return SRmodeselect10(rp, list, nbytes); }