home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.0 / NeXTSTEP3.0.iso / NextDeveloper / Examples / UNIX / SCSI / sg_example.c < prev   
Encoding:
Text File  |  1992-07-24  |  3.8 KB  |  189 lines

  1. /*
  2.  * Generic SCSI driver example.
  3.  *
  4.  * History
  5.  * -------
  6.  * 10-Apr-89    Doug Mitchell
  7.  *    Write after read to avoid trashing system disk.
  8.  * 20-Mar-89    Doug Mitchell at NeXT
  9.  *    Created.
  10.  *
  11.  *    Procedure:
  12.  *        open sg0;
  13.  *        set (target,lun) to (1,0);
  14.  *        execute Request Sense command;
  15.  *        Read 4 blocks;
  16.  *        Write 4 blocks;
  17.  *
  18.  *    You may freely copy, distribute and reuse the code in this example.
  19.  *    NeXT disclaims any warranty of any kind, expressed or implied, as to
  20.  *    its fitness for any particular use.
  21.  */
  22.  */
  23.  
  24. #include <fcntl.h>
  25. #include <stdio.h>
  26. #include <sys/types.h>
  27. #include <nextdev/scsireg.h>
  28.  
  29.  
  30. #define IO_SIZE        4            /* in blocks */
  31. #define BLOCK_SIZE    0x400            /* in bytes */
  32. #define BUF_SIZE    (IO_SIZE*BLOCK_SIZE)
  33. #define SENSE_SIZE    0x40            /* sense buffer size */
  34.  
  35. char rwbuf[BUF_SIZE];                /* read/write buffer */
  36. char sbuf[SENSE_SIZE];                 /* sense buffer */
  37.  
  38. int fd;                        /* file descriptor */
  39. int target=1;
  40. int lun=0;
  41. int lba=0;                    /* start block for rd/wr */
  42. char *dev_name="/dev/sg0";
  43.  
  44. main() {
  45.  
  46.     struct scsi_adr sa;
  47.     int rtn;
  48.     int i;
  49.     
  50.     /* open /dev/sg0 */
  51.     
  52.     if ((fd = open (dev_name, O_RDWR)) < 0) {
  53.         printf("\nCould not open %s - fd = %XH\n",dev_name,fd);
  54.         printf("errno = %d\n",errno);
  55.         perror("open");
  56.         exit(1);
  57.     }
  58.     
  59.     /* set (target,lun) */
  60.     
  61.     sa.sa_target = target;
  62.     sa.sa_lun = lun;
  63.     if (ioctl(fd,SGIOCSTL,&sa) < 0) {
  64.         printf("Error setting target %d lun %d\n",target,lun);
  65.         printf("errno = %d\n",errno);
  66.         perror("ioctl(SGIOCSTL)");
  67.         exit(1);
  68.     }
  69.  
  70.     if(gs_request_sense())            /* clear unit attention */
  71.         exit(1);
  72.     for(i=0; i<BUF_SIZE; i++)        /* init buffer */
  73.         rwbuf[i] = 0;
  74.     if(gs_read(lba,IO_SIZE,rwbuf))        /* read data */
  75.         exit(1);
  76.     if(gs_write(lba,IO_SIZE,rwbuf))        /* write the same data */
  77.         exit(1);
  78.     
  79.     /* close /dev/sg0 */
  80.     
  81.     if ((rtn = close(fd)) < 0) {
  82.         printf("\nCould not close %s - fd = %XH\n",dev_name,fd);
  83.         printf("\nerrno = %d\n",errno);
  84.         perror("close");
  85.         exit(1);
  86.     }
  87.     else
  88.         exit(0);
  89.  
  90. } /* main() */
  91.  
  92.  
  93. /*    
  94.  *    standard I/O routines
  95.  */
  96.  
  97. gs_requUsense() {
  98.  
  99.     struct scsi_req sr;    
  100.     struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;
  101.     
  102.     cdb_clr(cdbp);
  103.     cdbp->c6_opcode = C6OP_REQSENSE;
  104.     cdbp->c6_lun    = lun;
  105.     cdbp->c6_len    = SENSE_SIZE;
  106.     sr.sr_dma_dir    = SR_DMA_RD;
  107.     sr.sr_addr    = sbuf;
  108.     sr.sr_dma_max    = SENSE_SIZE;
  109.     sr.sr_ioto    = 10;
  110.     return(do_ioc(&sr));
  111.  
  112.  
  113. } /* gs_request_seense() */
  114.  
  115. gs_read(int lba, int block_count, u_char *bp) {
  116.  
  117.     /* read block_count blocks starting at lba. Data goes to *bp. */
  118.     
  119.     struct scsi_req sr;    
  120.     struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;
  121.     
  122.     cdb_clr(cdbp);
  123.     cdbp->c6_opcode = C6OP_READ;
  124.     cdbp->c6_lun    = 0;
  125.     cdbp->c6_lba    = lba;
  126.     cdbp->c6_len    = block_count;
  127.     sr.sr_dma_dir    = SR_DMA_RD;
  128.     sr.sr_addr    = (char *)bp;
  129.     sr.sr_dma_max    = block_count * BLOCK_SIZE;
  130.     sr.sr_ioto    = 10;
  131.     return(do_ioc(&sr));
  132.  
  133. } /* gs_read() */
  134.  
  135. gs_write(int lba, int block_count, u_char *bp) {
  136.  
  137.     /* write block_count blocks starting at lba. Data comes from *bp. */
  138.  
  139.     struct scsi_req sr;    
  140.     struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;
  141.     
  142.     cdb_clr(cdbp);
  143.     cdbp->c6_opcode = C6OP_WRITE;
  144.     cdbp->c6_lun    = 0;
  145.     cdbp->c6_lba    = lba;
  146.     cdbp->c6_len    = block_count;
  147.     sr.sr_dma_dir    = SR_DMA_WR;
  148.     sr.sr_addr    = (char *)bp;
  149.     sr.sr_dma_max    = block_count * BLOCK_SIZE;
  150.     sr.sr_ioto    = 10;
  151.     return(do_ioc(&sr));
  152.  
  153. } /* gs_write() */
  154.  
  155. cdb_clr(cdbp)
  156. union cdb *cdbp;
  157. {
  158.     int i;
  159.     char *p;
  160.     
  161.     p = (char *)cdbp;
  162.     for(i=0; i<sizeof(union cdb); i++)
  163.         *p++ = 0;
  164. }
  165.  
  166. do_ioc(sr)
  167. struct scsi_req *sr;
  168. {
  169.     
  170.     if (ioctl(fd,SGIOCREQ,sr) < 0) {
  171.         printf("..Error executing ioctl\n");
  172.         printf("errno = %d\n",errno);
  173.         perror("ioctl(SGIOCREQ)");
  174.         return(1);
  175.     }
  176.     if(sr->sr_io_status) {
  177.         printf("sr_io_status = 0x%X\n",sr->sr_io_status);
  178.         if(sr->sr_io_status == SR_IOST_CHKSV) {
  179.             printf("   sense key = %02XH   sense code = %02XH\n",
  180.                 sr->sr_esense.er_sensekey,
  181.                 sr->sr_esense.er_addsensecode);
  182.         }
  183.         printf("SCSI status = %02XH\n",sr->sr_scsi_status);
  184.         return(1);
  185.     }
  186.     return(0);
  187. } /* do_ioc() */
  188.     
  189.