Annotation of Examples/DriverKit/SCSITape/stblocksize.tproj/stblocksize.c, revision 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.