home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.0 / NeXTSTEP3.0.iso / NextDeveloper / Examples / UNIX / SCSI_CD / scsi_commands.c < prev    next >
Text File  |  1992-07-24  |  7KB  |  319 lines

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