Annotation of Examples/DriverKit/SCSITape/stblocksize.tproj/stblocksize.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1993 NeXT Computer, Inc.  All rights reserved.
                      2:  *
                      3:  * stblocksize.c
                      4:  *
                      5:  * Read and set the native block size for a SCSI tape device.
                      6:  *
                      7:  * HISTORY
                      8:  * 18-Oct-93   Phillip Dibner at NeXT
                      9:  *     Created.
                     10:  */ 
                     11: 
                     12: #include <errno.h>
                     13: #include <sys/types.h>
                     14: #include <sys/file.h>
                     15: #include <bsd/dev/scsireg.h>
                     16: #include "stblocksize.h" /* XXX merge this file with scsireg.h */
                     17: #include <bsd/libc.h>
                     18: #include <bsd/sys/fcntl.h>
                     19: #include <ctype.h>
                     20: #include <objc/objc.h>
                     21: 
                     22: int    fd;
                     23: int    read_block_limits(), do_ioc();
                     24: void   usage();
                     25: 
                     26: int
                     27: main(int argc, char **argv)
                     28: {
                     29:     int                i, j, len;
                     30:     int                maxblocksize, minblocksize, blocksize;
                     31:     BOOL       verbose = NO, manualsize = NO;
                     32:     int                last = argc - 1;
                     33: 
                     34:     /*
                     35:      * Check argument count
                     36:      */
                     37:     if (argc < 2 || argc > 5) {
                     38:        usage();
                     39:        return -1;
                     40:     }
                     41: 
                     42:     for (i = 1; i < argc-1; i++) {
                     43: 
                     44:        /*
                     45:         * See if we have been asked to print the device's blocksize...
                     46:         */
                     47:        if (strcmp (argv [i], "-v") == 0) {
                     48:            verbose = YES;
                     49:        }
                     50: 
                     51:        /*
                     52:         * ... or if we are setting the blocksize from the command line.
                     53:         */
                     54:        else if ((strcmp (argv[i], "-s")) == 0) {
                     55:            manualsize = YES;
                     56: 
                     57:            /*
                     58:             * Check that next argument is a number, and convert it.
                     59:             */
                     60:            i++;
                     61:            len = strlen (argv [i]);
                     62:            for (j=0; j<len; j++) {
                     63:                if (!isdigit(argv[i][j])) {
                     64:                    usage();
                     65:                    return -1;
                     66:                }
                     67:            }
                     68:            blocksize = atoi (argv[i]);   
                     69:        }
                     70: 
                     71:        else {
                     72:            usage();
                     73:            return -1;
                     74:        }
                     75:     }
                     76: 
                     77:     /*
                     78:      * Open the tape device, which should be the last argument
                     79:      */
                     80:     if ((fd = open(argv[last], O_RDWR, 777)) < 0) {
                     81:        printf ("Cannot open %s\n", argv[last]);
                     82:        return -1;
                     83:     }
                     84: 
                     85:     /*
                     86:      * Read block size.
                     87:      *
                     88:      * We don't read it if we're setting it manually.   This may allow us to
                     89:      * use a device that implements the READ_BLOCK_LIMITS command improperly.
                     90:      */
                     91:     if (!manualsize) {
                     92:        if (read_block_limits(&maxblocksize, &minblocksize)) {
                     93:            printf ("Error reading block size parameters for %s\n",
                     94:                argv[last]);
                     95:            return -1;
                     96:        }
                     97: 
                     98:        /*
                     99:         * Equal max and min blocksize mean the device requires transfers
                    100:         * with a fixed block size.
                    101:         */
                    102:        if (maxblocksize == minblocksize) {
                    103:            blocksize = minblocksize;
                    104:        }
                    105:        else {
                    106:            blocksize = 0;
                    107:        }
                    108:     }
                    109: 
                    110:     if (verbose) {
                    111:        if (!manualsize)
                    112:            printf ("Tape device %s block limits: min = %d, max = %d\n",
                    113:                argv[last], minblocksize, maxblocksize);
                    114:        printf ("Setting %s blocksize to %d.\n", argv[last], blocksize); 
                    115:     }
                    116: 
                    117:     /*
                    118:      * Set the block size that the device will use for data transfers.
                    119:      */
                    120:     if (ioctl(fd, MTIOCFIXBLK, &blocksize))
                    121:     {
                    122:        printf ("Cannot set block size 0x%x for %s\n",
                    123:            blocksize, argv[last]);
                    124:        return -1; 
                    125:     }
                    126:     close (fd);
                    127:     return 0;
                    128: } /* main() */
                    129: 
                    130: int
                    131: read_block_limits (int *maxp, int *minp)
                    132: {
                    133:     struct scsi_req sr;
                    134:     struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;
                    135:     struct read_blk_sz_reply rbsr;
                    136: 
                    137:     bzero ((char *) cdbp, sizeof (union cdb));
                    138:     cdbp->c6_opcode = C6OP_RDBLKLIMS;
                    139: 
                    140:     /*
                    141:      * NB: The lun is set by the driver, since we don't know what
                    142:      * it is from the user level.
                    143:      */
                    144: 
                    145:     sr.sr_dma_dir = SR_DMA_RD;
                    146:     sr.sr_addr = (caddr_t) &rbsr;
                    147:     sr.sr_dma_max = sizeof (struct read_blk_sz_reply);
                    148:     sr.sr_ioto = 10;
                    149:     if (do_ioc(&sr)) {
                    150:        return -1;
                    151:     }
                    152:     else { 
                    153: 
                    154: #if    __BIG_ENDIAN__ 
                    155:        *maxp = rbsr.rsbr_max_bll;
                    156:        *minp = rbsr.rsbr_min_bll;
                    157: #elif  __LITTLE_ENDIAN__
                    158:        *maxp = (rbsr.rbsr_max_bll2 << 16) + (rbsr.rbsr_max_bll1 << 8) +
                    159:            rbsr.rbsr_max_bll0;
                    160:        *minp = (rbsr.rbsr_min_bll1 << 8) + (rbsr.rbsr_min_bll0);
                    161: #else
                    162: #error byte order? 
                    163: #endif
                    164: 
                    165:     }
                    166:     return 0;
                    167: } /* read_block_limits() */
                    168: 
                    169: int
                    170: do_ioc(srp)
                    171: struct scsi_req *srp;
                    172: {
                    173:        
                    174:     if (ioctl(fd,MTIOCSRQ,srp) < 0) {
                    175:        printf("..Error executing ioctl\n");
                    176:        printf("errno = %d\n",errno);
                    177:        perror("ioctl (MTIOCSRQ)");
                    178:        return 1;
                    179:     }
                    180:     if(srp->sr_io_status) {
                    181:        printf("sr_io_status = 0x%X\n",srp->sr_io_status);
                    182:        if(srp->sr_io_status == SR_IOST_CHKSV) {
                    183:            printf("   sense key = %02XH   sense code = %02XH\n",
                    184:                srp->sr_esense.er_sensekey,
                    185:                srp->sr_esense.er_addsensecode);
                    186:        }
                    187:        printf("SCSI status = %02XH\n", srp->sr_scsi_status);
                    188:        return 1;
                    189:     }
                    190:     return 0;
                    191: } /* do_ioc() */
                    192: 
                    193: 
                    194: void
                    195: usage()
                    196: {
                    197:        printf ("Usage: stblocksize [-v] [-s <blocksize>] "
                    198:                "<dev-full-pathname>\n");
                    199:        return;
                    200: }

unix.superglobalmegacorp.com

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