|
|
1.1 root 1: /*
2: * @(#)st.c 1.1 86/02/03 Copyright (c) 1985 by Sun Microsystems, Inc.
3: */
4:
5: #include <sys/types.h>
6: #include <sys/inode.h>
7: #include <sun/dklabel.h>
8: #include <sun/dkio.h>
9: #include <sys/buf.h>
10: #include <sundev/screg.h>
11: #include <sundev/sireg.h>
12: #include <sundev/scsi.h>
13: #include <sundev/streg.h>
14: #include <machine/idprom.h>
15: #include "saio.h"
16: #include "param.h"
17:
18: /*
19: * Driver for Sysgen SC4000 and EMULEX MT-02 SCSI tape controllers.
20: * Supports qic11 format only.
21: */
22: extern int scdoit();
23: #ifdef SUN3
24: extern int sidoit();
25: #endif
26:
27: #define min(a,b) ((a)<(b)? (a): (b))
28:
29: #define NSD 1
30: unsigned long staddrs[NSD] = { 0x0, };
31:
32: extern int xxprobe(), xxboot();
33: int stopen(), stclose(), ststrategy();
34:
35:
36: struct stparam {
37: int st_target;
38: int st_unit;
39: int st_eof;
40: int st_lastcmd;
41: int st_ctype;
42: #ifdef SUN3
43: int st_ha_type;
44: #endif
45: struct saioreq subsip[1]; /* sip for host adapter */
46: };
47:
48: /*
49: * DMA-able buffers
50: */
51: #ifdef SUN2
52: /* virtual addresses are precious on Sun-2 */
53: #define MAXSTBSIZE (20*1024)
54: #endif
55: #ifdef SUN3
56: #define MAXSTBSIZE (127*512)
57: #endif
58: struct stdma {
59: char sbuffer[SENSE_LENGTH];
60: char databuffer[MAXSTBSIZE];
61: };
62:
63: #define STSBUF (((struct stdma *)sip->si_dmaaddr)->sbuffer)
64: #define STBUF (((struct stdma *)sip->si_dmaaddr)->databuffer)
65:
66: #define ISAEMULEX(stp) (stp->st_ctype == ST_TYPE_EMULEX ? 1 : 0)
67:
68: /*
69: * What resources we need to run
70: */
71: struct devinfo stinfo = {
72: 0, /* No device to map in */
73: sizeof (struct stdma),
74: sizeof (struct stparam),
75: NSD, /* Dummy devices */
76: staddrs, /* Dummy devices */
77: MAP_MAINMEM,
78: MAXSTBSIZE, /* transfer size */
79: };
80:
81: struct boottab stdriver = {
82: "st", xxprobe, xxboot,
83: stopen, stclose, ststrategy,
84: "st: SCSI tape", &stinfo
85: };
86:
87: #define TAPE_TARGET 4 /* default SCSI target # for tape */
88:
89: #define SENSE_BITS \
90: "\020\17NoCart\16NoDrive\15WriteProt\14EndMedium\13HardErr\12WrongBlock\
91: \11FileMark\7InvCmd\6NoData\5Flaking\4BOT\0034\0022\1GotReset"
92:
93: #define SENSELOC 4 /* sysgen returns sense at this offset */
94:
95: #define ROUNDUP(x) ((x + DEV_BSIZE - 1) & ~(DEV_BSIZE - 1))
96:
97: #ifdef SUN3
98: /*
99: * Determine type of host adaptor interface, si or sc.
100: * Returns 1 if si host adaptor and 0 if sc host adaptor.
101: */
102: st_probe(sip)
103: struct saioreq *sip;
104: {
105: if (siprobe(sip)) {
106: return (1);
107: } else {
108: return (0);
109: }
110: }
111: #endif
112:
113: /*
114: * Open the SCSI Tape controller
115: */
116: int
117: stopen(sip)
118: register struct saioreq *sip;
119: {
120: register struct stparam *stp;
121: register int r;
122: register int skip;
123: register int i;
124: struct scsi_cdb cdb;
125: struct scsi_scb scb;
126:
127: stp = (struct stparam *) sip->si_devdata;
128: bzero( (char *)stp, (sizeof (struct stparam)));
129:
130: *stp->subsip = *sip; /* initialize subsip */
131:
132: #ifdef SUN3
133: {
134: extern struct boottab scdriver;
135: extern struct boottab sidriver;
136:
137: /* FIXME, find out which scsi interface to use */
138: if (st_probe(sip)) {
139: stp->st_ha_type = 1;
140:
141: /* FIXME, must vector thru table */
142: stp->subsip->si_boottab = &sidriver;
143: } else {
144: stp->st_ha_type = 0;
145:
146: /* FIXME, must vector thru table */
147: stp->subsip->si_boottab = &scdriver;
148: }
149: }
150: #endif
151: #ifdef SUN2
152: {
153: extern struct boottab scdriver;
154:
155: stp->subsip->si_boottab = &scdriver;
156: }
157: #endif
158:
159: stp->subsip->si_unit = sip->si_unit >> 3; /* Target number */
160: if (stp->subsip->si_unit == 0) {
161: stp->subsip->si_unit = TAPE_TARGET;
162: }
163:
164: r = devopen(stp->subsip);
165: if (r < 0) return r;
166:
167: /* Logical unit number */
168: stp->st_unit = sip->si_unit & 0x07;
169:
170: /*
171: * Must wait for tape controller to become ready.
172: * This takes about 10 seconds for the Emulex.
173: */
174: /*
175: * Test for the controller being ready. First test will fail if
176: * the SCSI bus is permanently busy or if a previous op was
177: * interrupted in mid-transfer. Second one should work.
178: */
179: for (i = 0; i < 2; i++) {
180: bzero((char *) &cdb, sizeof cdb);
181: cdb.cmd = SC_TEST_UNIT_READY;
182: cdb.count = 0;
183: stp->subsip->si_cc = 0;
184: stp->subsip->si_ma = 0;
185: #ifdef SUN3
186: if (stp->st_ha_type)
187: r = sidoit(&cdb, &scb, stp->subsip);
188: else
189: #endif
190: r = scdoit(&cdb, &scb, stp->subsip);
191: }
192:
193: /*
194: * To figure out what type of tape controller is out there we send
195: * a REQUEST_SENSE command and see how much sense data comes back.
196: */
197: stp->st_ctype = ST_TYPE_EMULEX;
198: cdb.cmd = SC_REQUEST_SENSE;
199: stp->subsip->si_cc = cdb.count = ST_EMULEX_SENSE_LEN;
200: stp->subsip->si_ma = STSBUF;
201: #ifdef SUN3
202: if (stp->st_ha_type)
203: r = sidoit(&cdb, &scb, stp->subsip);
204: else
205: #endif
206: r = scdoit(&cdb, &scb, stp->subsip);
207: if (r != ST_EMULEX_SENSE_LEN) {
208: stp->st_ctype = ST_TYPE_SYSGEN;
209: cdb.cmd = SC_REQUEST_SENSE;
210: stp->subsip->si_cc = cdb.count = ST_SYSGEN_SENSE_LEN;
211: stp->subsip->si_ma = STSBUF;
212: #ifdef SUN3
213: if (stp->st_ha_type)
214: r = sidoit(&cdb, &scb, stp->subsip);
215: else
216: #endif
217: r = scdoit(&cdb, &scb, stp->subsip);
218: if (r == -1) {
219: printf("stopen: cannot get sense, %d\n", r);
220: return (-1);
221: }
222: }
223:
224: /*
225: * Default format mode for emulex is qic24.
226: * Needs to be qic11.
227: */
228: if (ISAEMULEX(stp)) {
229: sip->si_cc = EM_MS_PL_LEN;
230: if (stcmd(SC_QIC11, sip, 1) == 0) {
231: printf("stopen: mode select command fail");
232: return (-1);
233: }
234: }
235:
236: /*
237: * Rewind a few times until it works. First one will fail if
238: * the SCSI bus is permanently busy if a previous op was interrupted
239: * in mid-transfer. Second one will fail with POR status, after
240: * the scsi bus is reset from the busy. Third one should work.
241: */
242: sip->si_cc = 0;
243: if (stcmd(SC_REWIND, sip, 0) == 0 &&
244: stcmd(SC_REWIND, sip, 0) == 0 &&
245: stcmd(SC_REWIND, sip, 1) == 0) {
246: return (-1);
247: }
248: skip = sip->si_boff;
249: while (skip--) {
250: sip->si_cc = 0;
251: if (stcmd(SC_SPACE_FILE, sip, 1) == 0) {
252: return (-1);
253: }
254: }
255: stp->st_eof = 0;
256: stp->st_lastcmd = 0;
257: return (0);
258: }
259:
260: /*
261: * Close the tape drive.
262: */
263: stclose(sip)
264: register struct saioreq *sip;
265: {
266: register struct stparam *stp;
267:
268: stp = (struct stparam *) sip->si_devdata;
269: if (stp->st_lastcmd == SC_WRITE) {
270: (void) stcmd(SC_WRITE_FILE_MARK, sip, 0);
271: }
272: (void) stcmd(SC_REWIND, sip, 0);
273: }
274:
275:
276: /*
277: * Perform a read or write of the SCSI tape.
278: */
279: int
280: ststrategy(sip, rw)
281: register struct saioreq *sip;
282: int rw;
283: {
284: register struct stparam *stp;
285:
286: stp = (struct stparam *) sip->si_devdata;
287: if (stp->st_eof) {
288: stp->st_eof = 0;
289: return (0);
290: }
291: return (stcmd(rw == WRITE ? SC_WRITE : SC_READ, sip, 1));
292: }
293:
294: /*
295: * Execute a scsi tape command
296: */
297: int
298: stcmd(cmd, sip, errprint)
299: int cmd;
300: register struct saioreq *sip;
301: int errprint;
302: {
303: register struct st_emulex_mspl *mode;
304: register int r, i, c;
305: register char *buf;
306: register struct stparam *stp;
307: struct scsi_cdb cdb, scdb;
308: struct scsi_scb scb, sscb;
309: int count;
310: int qic;
311: int sense_length;
312: char *cp;
313: struct st_emulex_sense *ems;
314: struct st_sysgen_sense *scs;
315:
316: count = sip->si_cc;
317: stp = (struct stparam *)sip->si_devdata;
318: buf = sip->si_ma;
319:
320: if (cmd == SC_WRITE && buf != STBUF) {
321: bcopy(buf, STBUF, (unsigned)count);
322: }
323:
324: /* set up cdb */
325: bzero((char *) &cdb, sizeof cdb);
326: cdb.cmd = cmd;
327: cdb.lun = stp->st_unit;
328: c = ROUNDUP(count) / DEV_BSIZE;
329: cdb.high_count = c >> 16;
330: cdb.mid_count = (c >> 8) & 0xFF;
331: cdb.low_count = c & 0xFF;
332: stp->subsip->si_ma = STBUF;
333: stp->subsip->si_cc = ROUNDUP(count);
334:
335: /* some fields in the cdb are command specific */
336: switch (cmd) {
337:
338: case SC_QIC11:
339: stp->subsip->si_ma = 0;
340: stp->subsip->si_cc = 0;
341: if (ISAEMULEX(stp)) {
342: qic = ST_EMULEX_QIC11;
343: cdb.cmd = SC_MODE_SELECT;
344: goto MODE;
345: } else {
346: cdb.cmd = SC_QIC02;
347: cdb.high_count = ST_SYSGEN_QIC11;
348: break;
349: }
350: /* NOTREACHED */
351:
352: case SC_QIC24:
353: stp->subsip->si_ma = 0;
354: stp->subsip->si_cc = 0;
355: if (ISAEMULEX(stp)) {
356: qic = ST_EMULEX_QIC24;
357: cdb.cmd = SC_MODE_SELECT;
358: goto MODE;
359: } else {
360: cdb.cmd = SC_QIC02;
361: cdb.high_count = ST_SYSGEN_QIC24;
362: break;
363: }
364: /* NOTREACHED */
365: MODE:
366: case SC_MODE_SELECT:
367: mode = (struct st_emulex_mspl *)STSBUF;
368: bzero(mode, sizeof(*mode));
369: mode->hdr.bufm = 1;
370: mode->bd.density = qic;
371: mode->hdr.bd_len = EM_MS_BD_LEN;
372: stp->subsip->si_ma = (char *)mode;
373: stp->subsip->si_cc = cdb.count = EM_MS_PL_LEN;
374: break;
375:
376: case SC_SPACE_FILE:
377: cdb.cmd = SC_SPACE; /* the real SCSI cmd */
378: cdb.t_code = 1; /* space file, not rec */
379: cdb.low_count = 1; /* space 1 file, not 0 */
380: stp->subsip->si_ma = 0;
381: stp->subsip->si_cc = 0;
382: break;
383:
384: case SC_WRITE_FILE_MARK:
385: cdb.count = 1;
386: /* fall through... */
387:
388: case SC_TEST_UNIT_READY:
389: case SC_REWIND:
390: case SC_LOAD:
391: stp->subsip->si_ma = 0;
392: stp->subsip->si_cc = 0;
393: break;
394:
395: case SC_READ:
396: case SC_WRITE:
397: if (ISAEMULEX(stp)) {
398: cdb.t_code = 1;
399: }
400: break;
401:
402: default:
403: if (errprint)
404: printf("st: unknown command\n");
405: return (0);
406: }
407:
408: /* execute the command */
409: #ifdef SUN3
410: if (stp->st_ha_type)
411: r = sidoit(&cdb, &scb, stp->subsip);
412: else
413: #endif
414: r = scdoit(&cdb, &scb, stp->subsip);
415:
416: /* allow for tape blocking */
417: if (r > count)
418: r = count;
419: /* error */
420: if (r == -1)
421: return (0);
422:
423: if (cmd == SC_READ) {
424: if (min(count, r))
425: bcopy(STBUF, buf, (unsigned)(min(count, r)));
426: }
427:
428: /* we may need to get sense data */
429: if (scb.chk) {
430: bzero((char *) &scdb, sizeof scdb);
431: scdb.cmd = SC_REQUEST_SENSE;
432: scdb.lun = stp->st_unit;
433: if (ISAEMULEX(stp)) {
434: sense_length = stp->subsip->si_cc =
435: scdb.count = ST_EMULEX_SENSE_LEN;
436: } else {
437: sense_length = stp->subsip->si_cc =
438: scdb.count = ST_SYSGEN_SENSE_LEN;
439: }
440: stp->subsip->si_ma = STSBUF;
441: #ifdef SUN3
442: if (stp->st_ha_type)
443: i = sidoit(&scdb, &sscb, stp->subsip );
444: else
445: #endif
446: i = scdoit(&scdb, &sscb, stp->subsip );
447: if (i != sense_length) {
448: if (errprint) {
449: printf("st: sense error\n");
450: }
451: stp->st_eof = 1;
452: return (0);
453: }
454: if (ISAEMULEX(stp)) {
455: ems = (struct st_emulex_sense *)STSBUF;
456: if ((ems->ext_sense.fil_mk == 0) && errprint) {
457: printf("st: error:\n");
458: printf("\tsense key is %x",
459: ems->ext_sense.key);
460: printf("\terror is %x\n",
461: ems->error);
462: }
463: stp->st_eof = 1;
464: return (r);
465: } else {
466: scs = (struct st_sysgen_sense *)STSBUF;
467: if ((scs->qic_sense.file_mark == 0) && errprint) {
468: #ifdef STBOOT
469: printf("st: error %x\n",
470: *(unsigned short *)&STSBUF[SENSELOC]);
471: #else STBOOT
472: printf("st: error %b\n",
473: *(unsigned short *)&STSBUF[SENSELOC],
474: SENSE_BITS);
475: #endif STBOOT
476: }
477: stp->st_eof = 1;
478: return (r);
479: }
480: }
481: if (r >= count) {
482: return (count ? count : 1);
483: } else {
484: if (errprint) {
485: printf("st: short transfer\n");
486: }
487: return (r);
488: }
489: }
490:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.