home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer) / NeXT_Developer-3.3.iso / NextDeveloper / Examples / DriverKit / SCSITape / stblocksize.tproj / stblocksize.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-11  |  4.1 KB  |  201 lines

  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. }
  201.