|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.