Annotation of Examples/UNIX/SCSI_CD/scsi_commands.c, revision 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.