Annotation of Examples/UNIX/SCSI/sg_example.c, revision 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.