File:  [NeXTSTEP 3.3 examples] / Examples / DriverKit / SCSITape / stblocksize.tproj / stblocksize.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:49:02 2018 UTC (8 years, 1 month ago) by root
Branches: NeXT, MAIN
CVS tags: NeXTSTEP33, HEAD
Sample Programs from NeXSTEP 3.3

/* Copyright (c) 1993 NeXT Computer, Inc.  All rights reserved.
 *
 * stblocksize.c
 *
 * Read and set the native block size for a SCSI tape device.
 *
 * HISTORY
 * 18-Oct-93	Phillip Dibner at NeXT
 *	Created.
 */ 

#include <errno.h>
#include <sys/types.h>
#include <sys/file.h>
#include <bsd/dev/scsireg.h>
#include "stblocksize.h" /* XXX merge this file with scsireg.h */
#include <bsd/libc.h>
#include <bsd/sys/fcntl.h>
#include <ctype.h>
#include <objc/objc.h>

int	fd;
int	read_block_limits(), do_ioc();
void	usage();

int
main(int argc, char **argv)
{
    int		i, j, len;
    int		maxblocksize, minblocksize, blocksize;
    BOOL	verbose = NO, manualsize = NO;
    int		last = argc - 1;

    /*
     * Check argument count
     */
    if (argc < 2 || argc > 5) {
	usage();
	return -1;
    }

    for (i = 1; i < argc-1; i++) {

	/*
	 * See if we have been asked to print the device's blocksize...
	 */
	if (strcmp (argv [i], "-v") == 0) {
	    verbose = YES;
	}

	/*
	 * ... or if we are setting the blocksize from the command line.
	 */
	else if ((strcmp (argv[i], "-s")) == 0) {
	    manualsize = YES;

	    /*
	     * Check that next argument is a number, and convert it.
	     */
	    i++;
	    len = strlen (argv [i]);
	    for (j=0; j<len; j++) {
		if (!isdigit(argv[i][j])) {
		    usage();
		    return -1;
		}
	    }
	    blocksize = atoi (argv[i]);   
	}

	else {
	    usage();
	    return -1;
	}
    }

    /*
     * Open the tape device, which should be the last argument
     */
    if ((fd = open(argv[last], O_RDWR, 777)) < 0) {
	printf ("Cannot open %s\n", argv[last]);
	return -1;
    }

    /*
     * Read block size.
     *
     * We don't read it if we're setting it manually.   This may allow us to
     * use a device that implements the READ_BLOCK_LIMITS command improperly.
     */
    if (!manualsize) {
	if (read_block_limits(&maxblocksize, &minblocksize)) {
	    printf ("Error reading block size parameters for %s\n",
		argv[last]);
	    return -1;
	}

	/*
	 * Equal max and min blocksize mean the device requires transfers
	 * with a fixed block size.
	 */
	if (maxblocksize == minblocksize) {
	    blocksize = minblocksize;
	}
	else {
	    blocksize = 0;
	}
    }

    if (verbose) {
	if (!manualsize)
	    printf ("Tape device %s block limits: min = %d, max = %d\n",
		argv[last], minblocksize, maxblocksize);
	printf ("Setting %s blocksize to %d.\n", argv[last], blocksize); 
    }

    /*
     * Set the block size that the device will use for data transfers.
     */
    if (ioctl(fd, MTIOCFIXBLK, &blocksize))
    {
	printf ("Cannot set block size 0x%x for %s\n",
	    blocksize, argv[last]);
	return -1; 
    }
    close (fd);
    return 0;
} /* main() */

int
read_block_limits (int *maxp, int *minp)
{
    struct scsi_req sr;
    struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;
    struct read_blk_sz_reply rbsr;

    bzero ((char *) cdbp, sizeof (union cdb));
    cdbp->c6_opcode = C6OP_RDBLKLIMS;

    /*
     * NB: The lun is set by the driver, since we don't know what
     * it is from the user level.
     */

    sr.sr_dma_dir = SR_DMA_RD;
    sr.sr_addr = (caddr_t) &rbsr;
    sr.sr_dma_max = sizeof (struct read_blk_sz_reply);
    sr.sr_ioto = 10;
    if (do_ioc(&sr)) {
	return -1;
    }
    else { 

#if	__BIG_ENDIAN__ 
	*maxp = rbsr.rsbr_max_bll;
	*minp = rbsr.rsbr_min_bll;
#elif	__LITTLE_ENDIAN__
	*maxp = (rbsr.rbsr_max_bll2 << 16) + (rbsr.rbsr_max_bll1 << 8) +
	    rbsr.rbsr_max_bll0;
	*minp = (rbsr.rbsr_min_bll1 << 8) + (rbsr.rbsr_min_bll0);
#else
#error	byte order? 
#endif

    }
    return 0;
} /* read_block_limits() */

int
do_ioc(srp)
struct scsi_req *srp;
{
	
    if (ioctl(fd,MTIOCSRQ,srp) < 0) {
	printf("..Error executing ioctl\n");
	printf("errno = %d\n",errno);
	perror("ioctl (MTIOCSRQ)");
	return 1;
    }
    if(srp->sr_io_status) {
	printf("sr_io_status = 0x%X\n",srp->sr_io_status);
	if(srp->sr_io_status == SR_IOST_CHKSV) {
	    printf("   sense key = %02XH   sense code = %02XH\n",
		srp->sr_esense.er_sensekey,
		srp->sr_esense.er_addsensecode);
	}
	printf("SCSI status = %02XH\n", srp->sr_scsi_status);
	return 1;
    }
    return 0;
} /* do_ioc() */


void
usage()
{
	printf ("Usage: stblocksize [-v] [-s <blocksize>] "
		"<dev-full-pathname>\n");
	return;
}

unix.superglobalmegacorp.com

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