home *** CD-ROM | disk | FTP | other *** search
- /*
- * scsi_commands.c: scsi command functions
- *
- * History
- * -------
- * Tue Sep 3 15:00:13 PDT 1991 James C. Lee at NeXT
- * Created (copied a lot of data structures & functions calls from
- * perftest.c by Mike DeMoney)
- */
-
- #import "scsi_commands.h"
- #import <sys/time.h>
- #import <nextdev/disk.h>
- #import <nextdev/scsireg.h>
- #import <stdio.h>
- #import <libc.h>
- #import <stdlib.h>
-
-
- void fatal(const char *msg, ...)
- {
- va_list ap;
-
- va_start(ap, msg);
- /* fprintf(stderr, "%s: ", progname);*/
- vfprintf(stderr, msg, ap);
- fprintf(stderr, "\n");
- va_end(ap);
-
- exit(1);
- }
-
- inline int is_pow2(int i)
- {
- return (i & (i - 1)) == 0;
- }
-
- int do_inquiry(int fd, struct inquiry_reply *irp, struct esense_reply *erp)
- {
- struct scsi_req sr;
- struct cdb_6 *c6p;
- int err;
-
- bzero((char *)&sr, sizeof(sr));
-
- c6p = (struct cdb_6 *)&sr.sr_cdb;
- c6p->c6_opcode = C6OP_INQUIRY;
- c6p->c6_len = sizeof(*irp);
-
- sr.sr_addr = (char *)irp;
- sr.sr_dma_max = sizeof(*irp);
- sr.sr_ioto = 5;
- sr.sr_dma_dir = SR_DMA_RD;
-
- err = ioctl(fd, SDIOCSRQ, &sr);
- *erp = sr.sr_esense;
- return err | sr.sr_io_status;
- }
-
- int do_testunitready(int fd, struct timeval *tvp, struct esen$ eply *erp)
- {
- struct scsi_req sr;
- struct cdb_6 *c6p;
- int err;
-
- bzero((char *)&sr, sizeof(sr));
-
- c6p = (struct cdb_6 *)&sr.sr_cdb;
- c6p->c6_opcode = C6OP_TESTRDY;
-
- sr.sr_addr = NULL;
- sr.sr_dma_max = 0;
- sr.sr_ioto = 5;
- sr.sr_dma_dir = SR_DMA_RD;
-
- err = ioctl(fd, SDIOCSRQ, &sr);
-
- *tvp = sr.sr_exec_time;
-
- *erp = sr.sr_esense;
- return err | sr.sr_io_status;
- }
-
- int do_modesense(int fd, struct mode_sense_reply *msrp, int page,
- struct esense_reply *erp)
- {
- struct scsi_req sr;
- struct mode_sense_cmd *mscp;
- int err;
-
- bzero((char *)&sr, sizeof(sr));
-
- mscp = (struct mode_sense_cmd *)&sr.sr_cdb;
- mscp->msc_opcode = C6OP_MODESENSE;
- mscp->msc_pcf = 0; /* report current values */
- mscp->msc_page = page;
- mscp->msc_len = sizeof(*msrp);
-
- sr.sr_addr = (char *)msrp;
- sr.sr_dma_max = sizeof(*msrp);
- /*
- * Extend timeout so Quantum drive works with test.
- */
- sr.sr_ioto = 50;
- sr.sr_dma_dir = SR_DMA_RD;
-
- err = ioctl(fd, SDIOCSRQ, &sr);
-
- printf("sr.sr_io_status: %d\n", sr.sr_io_status);
- *erp = sr.sr_esense;
- return err | sr.sr_io_status;
- }
-
- int do_readcapacity(int fd, struct capacity_reply *crp,
- struct esense_reply *erp)
- {
- struct scsi_req sr;
- struct cdb_10 *c10p;
- int err;
-
- bzero((char *)&sr, sizeof(sr.sr_cdb));
-
- c10p = (struct cdb_10 *)&sr.sr_cdb;
- c10p->c10_opcode = C10OP_READCAPACITY;
-
- sr.sr_addr = (char *)crp;
- sr.sr_dma_max = sizeof(*crp);
- sr.sr_ioto = 5;
- sr.sr_dma_dir = SR_DMA_RD;
-
- err = ioctl(fd, SDIOCSRQ, &sr);
- *erp = sr.sr_esense;
- return err | sr.sr_io_status;
- }
-
- int do_seek(int fd, int lba, struct timeval *tvp, struct esense_reply *erp)
- {
- struct scsi_req sr;
- struct cdb_6 *c6p;
- int err;
-
- bzero((char *)&sr, sizeof(sr));
-
- c6p = (struct cdb_6 *)&sr.sr_cdb;
- c6p->c6_opcode = C6OP_SEEK;
- c6p->c6_lba = lba;
-
- sr.sr_addr = 0;
- sr.sr_dma_max = 0; /* don't really do I/O to memory */
- sr.sr_ioto = 5;
- sr.sr_dma_dir = SR_DMA_RD;
-
- err = ioctl(fd, SDIOCSRQ, &sr);
-
- *tvp = sr.sr_exec_time;
-
- *erp = sr.sr_esense;
- return err | sr.sr_io_status;
- }
-
- int do_read(int fd, int lba, int nblks, struct timeval *tvp,
- struct esense_reply *erp)
- {
- struct scsi_req sr;
- struct cdb_6 *c6p;
- int err;
-
- if (nblks > 256)
- fatal("Too many blocks for read: %d", nblks);
- if (nblks == 256)
- nblks = 0;
-
- bzero((char *)&sr, sizeof(sr));
-
- c6p = (struct cdb_6 *)&sr.sr_cdb;
- c6p->c6_opcode = C6OP_READ;
- c6p->c6_lba = lba$ 6p->c6_len = nblks;
-
- sr.sr_addr = NULL;
- sr.sr_dma_max = 0; /* don't really do I/O to memory */
- sr.sr_ioto = 5;
- sr.sr_dma_dir = SR_DMA_RD;
-
- err = ioctl(fd, SDIOCSRQ, &sr);
-
- *tvp = sr.sr_exec_time;
-
- if (sr.sr_dma_xfr != 0)
- fatal("scsi driver did transfer: %d", sr.sr_dma_xfr);
-
- *erp = sr.sr_esense;
- return err | sr.sr_io_status;
- }
-
- int do_write(int fd, int lba, int nblks, struct timeval *tvp,
- struct esense_reply *erp)
- {
- struct scsi_req sr;
- struct cdb_6 *c6p;
- int err;
-
- if (nblks > 256)
- fatal("Too many blocks for read: %d", nblks);
- if (nblks == 256)
- nblks = 0;
-
- bzero((char *)&sr, sizeof(sr));
-
- c6p = (struct cdb_6 *)&sr.sr_cdb;
- c6p->c6_opcode = C6OP_WRITE;
- c6p->c6_lba = lba;
- c6p->c6_len = nblks;
-
- sr.sr_addr = NULL;
- sr.sr_dma_max = 0; /* don't really do I/O to memory */
- sr.sr_ioto = 5;
- sr.sr_dma_dir = SR_DMA_WR;
-
- err = ioctl(fd, SDIOCSRQ, &sr);
-
- *tvp = sr.sr_exec_time;
-
- if (sr.sr_dma_xfr != 0)
- fatal("scsi driver did transfer: %d", sr.sr_dma_xfr);
-
- *erp = sr.sr_esense;
- return err | sr.sr_io_status;
- }
-
- int do_readbuffer(int fd, int alloc_len, int *avail_len, struct timeval *tvp,
- struct esense_reply *erp)
- {
- struct scsi_req sr;
- struct cdb_10 *c10p;
- int err;
-
- bzero((char *)&sr, sizeof(sr));
-
- c10p = (struct cdb_10 *)&sr.sr_cdb;
- c10p->c10_opcode = 0x3C;
- c10p->c10_len = alloc_len;
-
- sr.sr_addr = (char *)avail_len;
- sr.sr_dma_max = alloc_len > 4 ? 0 : alloc_len;
- sr.sr_ioto = 5;
- sr.sr_dma_dir = SR_DMA_RD;
-
- err = ioctl(fd, SDIOCSRQ, &sr);
-
- *tvp = sr.sr_exec_time;
-
- *erp = sr.sr_esense;
- return err | sr.sr_io_status;
- }
-
- int do_writebuffer(int fd, int alloc_len, struct timeval *tvp,
- struct esense_reply *erp)
- {
- struct scsi_req sr;
- struct cdb_10 *c10p;
- int err;
-
- bzero((char *)&sr, sizeof(sr));
-
- c10p = (struct cdb_10 *)&sr.sr_cdb;
- c10p->c10_opcode = 0x3B;
- c10p->c10_len = alloc_len;
-
- sr.sr_addr = NULL;
- sr.sr_dma_max = 0;
- sr.sr_ioto = 5;
- sr.sr_dma_dir = SR_DMA_WR;
-
- err = ioctl(fd, SDIOCSRQ, &sr);
-
- *tvp = sr.sr_exec_time;
-
- *erp = sr.sr_esense;
- return err | sr.sr_io_status;
- }
-
-
- void sprint_er(char *string, struct esense_reply *erp)
- {
- sprintf(string, " Valid : %d\n", erp->er_ibvalid);
- sprintf(string, "%s ErCode : 0x%x\n", string,
- erp->er_class<<4+erp->er_code);
- sprintf(string, "%s Segment : %d\n", string, erp->er_segment);
- sprintf(str$ "%s ILI : %d\n", string, erp->er_badlen);
- sprintf(string, "%s SenseKey : 0x%x\n", string, erp->er_sensekey);
- sprintf(string, "%s Info : 0x%x%x\n", string,
- erp->er_infomsb, erp->er_info);
- sprintf(string, "%s AddSenseLength : %d\n", string, erp->er_addsenselen);
- sprintf(string, "%s CmdInfo : %d\n", string, erp->er_rsvd8);
- sprintf(string, "%s AddSenseCode : 0x%x\n", string,
- erp->er_addsensecode);
- sprintf(string, "%s AddSenseCodeQual: 0x%x\n", string, erp->er_qualifier);
-
- return;
- }
-
- void fprint_er(int fd, struct esense_reply *erp)
- {
- fprintf(fd, " Valid : %d\n", erp->er_ibvalid);
- fprintf(fd, " ErCode : 0x%x\n",
- erp->er_class<<4+erp->er_code);
- fprintf(fd, " Segment : %d\n", erp->er_segment);
- fprintf(fd, " ILI : %d\n", erp->er_badlen);
- fprintf(fd, " SenseKey : 0x%x\n", erp->er_sensekey);
- fprintf(fd, " Info : 0x%x%x\n", erp->er_infomsb,
- erp->er_info);
- fprintf(fd, " AddSenseLength : %d\n", erp->er_addsenselen);
- fprintf(fd, " CmdInfo : %d\n", erp->er_rsvd8);
- fprintf(fd, " AddSenseCode : 0x%x\n", erp->er_addsensecode);
- fprintf(fd, " AddSenseCodeQual: 0x%x\n", erp->er_qualifier);
-
- return;
- }
-