home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer) / NeXT_Developer-3.3.iso / NextDeveloper / Examples / UNIX / SCSI / sg_example.c < prev   
Encoding:
C/C++ Source or Header  |  1995-02-10  |  4.3 KB  |  209 lines

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