Annotation of Examples/UNIX/SCSI_CD/scsi_commands.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.