home *** CD-ROM | disk | FTP | other *** search
- /*
- * Generic SCSI driver example.
- *
- * History
- * -------
- * 10-Apr-89 Doug Mitchell
- * Write after read to avoid trashing system disk.
- * 20-Mar-89 Doug Mitchell at NeXT
- * Created.
- *
- * Procedure:
- * open sg0;
- * set (target,lun) to (1,0);
- * execute Request Sense command;
- * Read 4 blocks;
- * Write 4 blocks;
- *
- * You may freely copy, distribute and reuse the code in this example.
- * NeXT disclaims any warranty of any kind, expressed or implied, as to
- * its fitness for any particular use.
- */
- */
-
- #include <fcntl.h>
- #include <stdio.h>
- #include <sys/types.h>
- #include <nextdev/scsireg.h>
-
-
- #define IO_SIZE 4 /* in blocks */
- #define BLOCK_SIZE 0x400 /* in bytes */
- #define BUF_SIZE (IO_SIZE*BLOCK_SIZE)
- #define SENSE_SIZE 0x40 /* sense buffer size */
-
- char rwbuf[BUF_SIZE]; /* read/write buffer */
- char sbuf[SENSE_SIZE]; /* sense buffer */
-
- int fd; /* file descriptor */
- int target=1;
- int lun=0;
- int lba=0; /* start block for rd/wr */
- char *dev_name="/dev/sg0";
-
- main() {
-
- struct scsi_adr sa;
- int rtn;
- int i;
-
- /* open /dev/sg0 */
-
- if ((fd = open (dev_name, O_RDWR)) < 0) {
- printf("\nCould not open %s - fd = %XH\n",dev_name,fd);
- printf("errno = %d\n",errno);
- perror("open");
- exit(1);
- }
-
- /* set (target,lun) */
-
- sa.sa_target = target;
- sa.sa_lun = lun;
- if (ioctl(fd,SGIOCSTL,&sa) < 0) {
- printf("Error setting target %d lun %d\n",target,lun);
- printf("errno = %d\n",errno);
- perror("ioctl(SGIOCSTL)");
- exit(1);
- }
-
- if(gs_request_sense()) /* clear unit attention */
- exit(1);
- for(i=0; i<BUF_SIZE; i++) /* init buffer */
- rwbuf[i] = 0;
- if(gs_read(lba,IO_SIZE,rwbuf)) /* read data */
- exit(1);
- if(gs_write(lba,IO_SIZE,rwbuf)) /* write the same data */
- exit(1);
-
- /* close /dev/sg0 */
-
- if ((rtn = close(fd)) < 0) {
- printf("\nCould not close %s - fd = %XH\n",dev_name,fd);
- printf("\nerrno = %d\n",errno);
- perror("close");
- exit(1);
- }
- else
- exit(0);
-
- } /* main() */
-
-
- /*
- * standard I/O routines
- */
-
- gs_requUsense() {
-
- struct scsi_req sr;
- struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;
-
- cdb_clr(cdbp);
- cdbp->c6_opcode = C6OP_REQSENSE;
- cdbp->c6_lun = lun;
- cdbp->c6_len = SENSE_SIZE;
- sr.sr_dma_dir = SR_DMA_RD;
- sr.sr_addr = sbuf;
- sr.sr_dma_max = SENSE_SIZE;
- sr.sr_ioto = 10;
- return(do_ioc(&sr));
-
-
- } /* gs_request_seense() */
-
- gs_read(int lba, int block_count, u_char *bp) {
-
- /* read block_count blocks starting at lba. Data goes to *bp. */
-
- struct scsi_req sr;
- struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;
-
- cdb_clr(cdbp);
- cdbp->c6_opcode = C6OP_READ;
- cdbp->c6_lun = 0;
- cdbp->c6_lba = lba;
- cdbp->c6_len = block_count;
- sr.sr_dma_dir = SR_DMA_RD;
- sr.sr_addr = (char *)bp;
- sr.sr_dma_max = block_count * BLOCK_SIZE;
- sr.sr_ioto = 10;
- return(do_ioc(&sr));
-
- } /* gs_read() */
-
- gs_write(int lba, int block_count, u_char *bp) {
-
- /* write block_count blocks starting at lba. Data comes from *bp. */
-
- struct scsi_req sr;
- struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;
-
- cdb_clr(cdbp);
- cdbp->c6_opcode = C6OP_WRITE;
- cdbp->c6_lun = 0;
- cdbp->c6_lba = lba;
- cdbp->c6_len = block_count;
- sr.sr_dma_dir = SR_DMA_WR;
- sr.sr_addr = (char *)bp;
- sr.sr_dma_max = block_count * BLOCK_SIZE;
- sr.sr_ioto = 10;
- return(do_ioc(&sr));
-
- } /* gs_write() */
-
- cdb_clr(cdbp)
- union cdb *cdbp;
- {
- int i;
- char *p;
-
- p = (char *)cdbp;
- for(i=0; i<sizeof(union cdb); i++)
- *p++ = 0;
- }
-
- do_ioc(sr)
- struct scsi_req *sr;
- {
-
- if (ioctl(fd,SGIOCREQ,sr) < 0) {
- printf("..Error executing ioctl\n");
- printf("errno = %d\n",errno);
- perror("ioctl(SGIOCREQ)");
- return(1);
- }
- if(sr->sr_io_status) {
- printf("sr_io_status = 0x%X\n",sr->sr_io_status);
- if(sr->sr_io_status == SR_IOST_CHKSV) {
- printf(" sense key = %02XH sense code = %02XH\n",
- sr->sr_esense.er_sensekey,
- sr->sr_esense.er_addsensecode);
- }
- printf("SCSI status = %02XH\n",sr->sr_scsi_status);
- return(1);
- }
- return(0);
- } /* do_ioc() */
-
-