|
|
1.1 ! root 1: /* ! 2: * scsi_commands.c: scsi command functions ! 3: * ! 4: * History ! 5: * ------- ! 6: * 02-Feb-93 Erik Kay at NeXT ! 7: * i386 support ! 8: * Tue Sep 3 15:00:13 PDT 1991 James C. Lee at NeXT ! 9: * Created (copied a lot of data structures & functions calls from ! 10: * perftest.c by Mike DeMoney) ! 11: */ ! 12: ! 13: #import "scsi_commands.h" ! 14: #import <sys/time.h> ! 15: #import <bsd/dev/disk.h> ! 16: #import <bsd/dev/scsireg.h> ! 17: #import <stdio.h> ! 18: #import <libc.h> ! 19: #import <stdlib.h> ! 20: ! 21: ! 22: void fatal(const char *msg, ...) ! 23: { ! 24: va_list ap; ! 25: ! 26: va_start(ap, msg); ! 27: /* fprintf(stderr, "%s: ", progname);*/ ! 28: vfprintf(stderr, msg, ap); ! 29: fprintf(stderr, "\n"); ! 30: va_end(ap); ! 31: ! 32: exit(1); ! 33: } ! 34: ! 35: inline int is_pow2(int i) ! 36: { ! 37: return (i & (i - 1)) == 0; ! 38: } ! 39: ! 40: int do_inquiry(int fd, struct inquiry_reply *irp, struct esense_reply *erp) ! 41: { ! 42: struct scsi_req sr; ! 43: struct cdb_6 *c6p; ! 44: int err; ! 45: ! 46: bzero((char *)&sr, sizeof(sr)); ! 47: ! 48: c6p = (struct cdb_6 *)&sr.sr_cdb; ! 49: c6p->c6_opcode = C6OP_INQUIRY; ! 50: c6p->c6_len = sizeof(*irp); ! 51: ! 52: sr.sr_addr = (char *)irp; ! 53: sr.sr_dma_max = sizeof(*irp); ! 54: sr.sr_ioto = 5; ! 55: sr.sr_dma_dir = SR_DMA_RD; ! 56: ! 57: err = ioctl(fd, SDIOCSRQ, &sr); ! 58: *erp = sr.sr_esense; ! 59: return err | sr.sr_io_status; ! 60: } ! 61: ! 62: int do_testunitready(int fd, struct timeval *tvp, struct esense_reply *erp) ! 63: { ! 64: struct scsi_req sr; ! 65: struct cdb_6 *c6p; ! 66: int err; ! 67: ! 68: bzero((char *)&sr, sizeof(sr)); ! 69: ! 70: c6p = (struct cdb_6 *)&sr.sr_cdb; ! 71: c6p->c6_opcode = C6OP_TESTRDY; ! 72: ! 73: sr.sr_addr = NULL; ! 74: sr.sr_dma_max = 0; ! 75: sr.sr_ioto = 5; ! 76: sr.sr_dma_dir = SR_DMA_RD; ! 77: ! 78: err = ioctl(fd, SDIOCSRQ, &sr); ! 79: ! 80: *tvp = sr.sr_exec_time; ! 81: ! 82: *erp = sr.sr_esense; ! 83: return err | sr.sr_io_status; ! 84: } ! 85: ! 86: int do_modesense(int fd, struct mode_sense_reply *msrp, int page, ! 87: struct esense_reply *erp) ! 88: { ! 89: struct scsi_req sr; ! 90: struct mode_sense_cmd *mscp; ! 91: int err; ! 92: ! 93: bzero((char *)&sr, sizeof(sr)); ! 94: ! 95: mscp = (struct mode_sense_cmd *)&sr.sr_cdb; ! 96: mscp->msc_opcode = C6OP_MODESENSE; ! 97: mscp->msc_pcf = 0; /* report current values */ ! 98: mscp->msc_page = page; ! 99: mscp->msc_len = sizeof(*msrp); ! 100: ! 101: sr.sr_addr = (char *)msrp; ! 102: sr.sr_dma_max = sizeof(*msrp); ! 103: /* ! 104: * Extend timeout so Quantum drive works with test. ! 105: */ ! 106: sr.sr_ioto = 50; ! 107: sr.sr_dma_dir = SR_DMA_RD; ! 108: ! 109: err = ioctl(fd, SDIOCSRQ, &sr); ! 110: ! 111: printf("sr.sr_io_status: %d\n", sr.sr_io_status); ! 112: *erp = sr.sr_esense; ! 113: return err | sr.sr_io_status; ! 114: } ! 115: ! 116: int do_readcapacity(int fd, struct capacity_reply *crp, ! 117: struct esense_reply *erp) ! 118: { ! 119: struct scsi_req sr; ! 120: struct cdb_10 *c10p; ! 121: int err; ! 122: ! 123: bzero((char *)&sr, sizeof(sr.sr_cdb)); ! 124: ! 125: c10p = (struct cdb_10 *)&sr.sr_cdb; ! 126: c10p->c10_opcode = C10OP_READCAPACITY; ! 127: ! 128: sr.sr_addr = (char *)crp; ! 129: sr.sr_dma_max = sizeof(*crp); ! 130: sr.sr_ioto = 5; ! 131: sr.sr_dma_dir = SR_DMA_RD; ! 132: ! 133: err = ioctl(fd, SDIOCSRQ, &sr); ! 134: *erp = sr.sr_esense; ! 135: return err | sr.sr_io_status; ! 136: } ! 137: ! 138: int do_seek(int fd, int lba, struct timeval *tvp, struct esense_reply *erp) ! 139: { ! 140: struct scsi_req sr; ! 141: struct cdb_6 *c6p; ! 142: int err; ! 143: ! 144: bzero((char *)&sr, sizeof(sr)); ! 145: ! 146: c6p = (struct cdb_6 *)&sr.sr_cdb; ! 147: c6p->c6_opcode = C6OP_SEEK; ! 148: #ifdef i386 ! 149: if (lba > 0) { ! 150: c6p->c6_lba0 = lba & 0xFF; ! 151: c6p->c6_lba1 = (lba >> 8) & 0xFF; ! 152: c6p->c6_lba2 = (lba >> 16) & 0xFF; ! 153: } else ! 154: c6p->c6_lba0 = c6p->c6_lba1 = c6p->c6_lba2 = 0; ! 155: #else ! 156: c6p->c6_lba = lba; ! 157: #endif ! 158: ! 159: sr.sr_addr = 0; ! 160: sr.sr_dma_max = 0; /* don't really do I/O to memory */ ! 161: sr.sr_ioto = 5; ! 162: sr.sr_dma_dir = SR_DMA_RD; ! 163: ! 164: err = ioctl(fd, SDIOCSRQ, &sr); ! 165: ! 166: *tvp = sr.sr_exec_time; ! 167: ! 168: *erp = sr.sr_esense; ! 169: return err | sr.sr_io_status; ! 170: } ! 171: ! 172: int do_read(int fd, int lba, int nblks, struct timeval *tvp, ! 173: struct esense_reply *erp) ! 174: { ! 175: struct scsi_req sr; ! 176: struct cdb_6 *c6p; ! 177: int err; ! 178: ! 179: if (nblks > 256) ! 180: fatal("Too many blocks for read: %d", nblks); ! 181: if (nblks == 256) ! 182: nblks = 0; ! 183: ! 184: bzero((char *)&sr, sizeof(sr)); ! 185: ! 186: c6p = (struct cdb_6 *)&sr.sr_cdb; ! 187: c6p->c6_opcode = C6OP_READ; ! 188: #ifdef i386 ! 189: if (lba > 0) { ! 190: c6p->c6_lba0 = lba & 0xFF; ! 191: c6p->c6_lba1 = (lba >> 8) & 0xFF; ! 192: c6p->c6_lba2 = (lba >> 16) & 0xFF; ! 193: } else ! 194: c6p->c6_lba0 = c6p->c6_lba1 = c6p->c6_lba2 = 0; ! 195: #else ! 196: c6p->c6_lba = lba; ! 197: #endif ! 198: c6p->c6_len = nblks; ! 199: ! 200: sr.sr_addr = NULL; ! 201: sr.sr_dma_max = 0; /* don't really do I/O to memory */ ! 202: sr.sr_ioto = 5; ! 203: sr.sr_dma_dir = SR_DMA_RD; ! 204: ! 205: err = ioctl(fd, SDIOCSRQ, &sr); ! 206: ! 207: *tvp = sr.sr_exec_time; ! 208: ! 209: if (sr.sr_dma_xfr != 0) ! 210: fatal("scsi driver did transfer: %d", sr.sr_dma_xfr); ! 211: ! 212: *erp = sr.sr_esense; ! 213: return err | sr.sr_io_status; ! 214: } ! 215: ! 216: int do_write(int fd, int lba, int nblks, struct timeval *tvp, ! 217: struct esense_reply *erp) ! 218: { ! 219: struct scsi_req sr; ! 220: struct cdb_6 *c6p; ! 221: int err; ! 222: ! 223: if (nblks > 256) ! 224: fatal("Too many blocks for read: %d", nblks); ! 225: if (nblks == 256) ! 226: nblks = 0; ! 227: ! 228: bzero((char *)&sr, sizeof(sr)); ! 229: ! 230: c6p = (struct cdb_6 *)&sr.sr_cdb; ! 231: c6p->c6_opcode = C6OP_WRITE; ! 232: #ifdef i386 ! 233: if (lba > 0) { ! 234: c6p->c6_lba0 = lba & 0xFF; ! 235: c6p->c6_lba1 = (lba >> 8) & 0xFF; ! 236: c6p->c6_lba2 = (lba >> 16) & 0xFF; ! 237: } else ! 238: c6p->c6_lba0 = c6p->c6_lba1 = c6p->c6_lba2 = 0; ! 239: #else ! 240: c6p->c6_lba = lba; ! 241: #endif ! 242: c6p->c6_len = nblks; ! 243: ! 244: sr.sr_addr = NULL; ! 245: sr.sr_dma_max = 0; /* don't really do I/O to memory */ ! 246: sr.sr_ioto = 5; ! 247: sr.sr_dma_dir = SR_DMA_WR; ! 248: ! 249: err = ioctl(fd, SDIOCSRQ, &sr); ! 250: ! 251: *tvp = sr.sr_exec_time; ! 252: ! 253: if (sr.sr_dma_xfr != 0) ! 254: fatal("scsi driver did transfer: %d", sr.sr_dma_xfr); ! 255: ! 256: *erp = sr.sr_esense; ! 257: return err | sr.sr_io_status; ! 258: } ! 259: ! 260: #if 0 ! 261: int do_readbuffer(int fd, int alloc_len, int *avail_len, struct timeval *tvp, ! 262: struct esense_reply *erp) ! 263: { ! 264: struct scsi_req sr; ! 265: struct cdb_10 *c10p; ! 266: int err; ! 267: ! 268: bzero((char *)&sr, sizeof(sr)); ! 269: ! 270: c10p = (struct cdb_10 *)&sr.sr_cdb; ! 271: c10p->c10_opcode = 0x3C; ! 272: c10p->c10_len = alloc_len; ! 273: ! 274: sr.sr_addr = (char *)avail_len; ! 275: sr.sr_dma_max = alloc_len > 4 ? 0 : alloc_len; ! 276: sr.sr_ioto = 5; ! 277: sr.sr_dma_dir = SR_DMA_RD; ! 278: ! 279: err = ioctl(fd, SDIOCSRQ, &sr); ! 280: ! 281: *tvp = sr.sr_exec_time; ! 282: ! 283: *erp = sr.sr_esense; ! 284: return err | sr.sr_io_status; ! 285: } ! 286: ! 287: int do_writebuffer(int fd, int alloc_len, struct timeval *tvp, ! 288: struct esense_reply *erp) ! 289: { ! 290: struct scsi_req sr; ! 291: struct cdb_10 *c10p; ! 292: int err; ! 293: ! 294: bzero((char *)&sr, sizeof(sr)); ! 295: ! 296: c10p = (struct cdb_10 *)&sr.sr_cdb; ! 297: c10p->c10_opcode = 0x3B; ! 298: c10p->c10_len = alloc_len; ! 299: ! 300: sr.sr_addr = NULL; ! 301: sr.sr_dma_max = 0; ! 302: sr.sr_ioto = 5; ! 303: sr.sr_dma_dir = SR_DMA_WR; ! 304: ! 305: err = ioctl(fd, SDIOCSRQ, &sr); ! 306: ! 307: *tvp = sr.sr_exec_time; ! 308: ! 309: *erp = sr.sr_esense; ! 310: return err | sr.sr_io_status; ! 311: } ! 312: #endif ! 313: ! 314: ! 315: void sprint_er(char *string, struct esense_reply *erp) ! 316: { ! 317: #ifdef i386 ! 318: unsigned int errinfo; ! 319: #endif ! 320: sprintf(string, " Valid : %d\n", erp->er_ibvalid); ! 321: sprintf(string, "%s ErCode : 0x%x\n", string, ! 322: erp->er_class << (4+erp->er_code)); ! 323: sprintf(string, "%s Segment : %d\n", string, erp->er_segment); ! 324: sprintf(string, "%s ILI : %d\n", string, erp->er_badlen); ! 325: sprintf(string, "%s SenseKey : 0x%x\n", string, erp->er_sensekey); ! 326: #ifdef i386 ! 327: errinfo = erp->er_info2 << 16 + erp->er_info1 << 8 + erp->er_info0; ! 328: sprintf(string, "%s Info : 0x%x%x\n", string, ! 329: erp->er_info3, errinfo); ! 330: #else ! 331: sprintf(string, "%s Info : 0x%x%x\n", string, ! 332: erp->er_infomsb, erp->er_info); ! 333: #endif ! 334: sprintf(string, "%s AddSenseLength : %d\n", string, erp->er_addsenselen); ! 335: sprintf(string, "%s CmdInfo : %d\n", string, erp->er_rsvd8); ! 336: sprintf(string, "%s AddSenseCode : 0x%x\n", string, ! 337: erp->er_addsensecode); ! 338: sprintf(string, "%s AddSenseCodeQual: 0x%x\n", string, erp->er_qualifier); ! 339: ! 340: return; ! 341: } ! 342: ! 343: #if 0 ! 344: void fprint_er(int fd, struct esense_reply *erp) ! 345: { ! 346: fprintf(fd, " Valid : %d\n", erp->er_ibvalid); ! 347: fprintf(fd, " ErCode : 0x%x\n", ! 348: erp->er_class<<4+erp->er_code); ! 349: fprintf(fd, " Segment : %d\n", erp->er_segment); ! 350: fprintf(fd, " ILI : %d\n", erp->er_badlen); ! 351: fprintf(fd, " SenseKey : 0x%x\n", erp->er_sensekey); ! 352: fprintf(fd, " Info : 0x%x%x\n", erp->er_infomsb, ! 353: erp->er_info); ! 354: fprintf(fd, " AddSenseLength : %d\n", erp->er_addsenselen); ! 355: fprintf(fd, " CmdInfo : %d\n", erp->er_rsvd8); ! 356: fprintf(fd, " AddSenseCode : 0x%x\n", erp->er_addsensecode); ! 357: fprintf(fd, " AddSenseCodeQual: 0x%x\n", erp->er_qualifier); ! 358: ! 359: return; ! 360: } ! 361: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.