|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.