Annotation of Examples/UNIX/SCSI/sg_example.c, revision 1.1.1.1

1.1       root        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:        

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.