|
|
1.1 root 1: /* (-lgl
2: * COHERENT Driver Kit Version 1.1.0
3: * Copyright (c) 1982, 1990 by Mark Williams Company.
4: * All rights reserved. May not be copied without permission.
5: -lgl) */
6: /*
7: * This is a driver for the
8: * Archive SC-400 Series Tape Controller.
9: */
10: #include <sys/coherent.h>
11: #include <sys/buf.h>
12: #include <sys/con.h>
13: #include <sys/const.h>
14: #include <sys/devices.h>
15: #include <sys/inode.h>
16: #include <sys/mtioctl.h>
17: #include <sys/sched.h>
18: #include <sys/seg.h>
19: #include <sys/stat.h>
20: #include <errno.h>
21:
22: /*
23: * Fixed parameters.
24: */
25: #define NCMDS 8 /* Max # chained commands */
26:
27: /*
28: * Configurable parameters
29: */
30: int STIRQ = 3; /* IRQ Level 3 */
31: int STPORT = 0x200; /* I/O Port */
32: int STDMA = 1; /* DMA Channel */
33:
34: #define BIT(n) (1 << (n))
35:
36: /*
37: * Forward referenced functions.
38: */
39: void stcache();
40: void stflush();
41: void stinvoke();
42: void ststart();
43: void stintr();
44: void strecov();
45: void stnext();
46: void stdiag();
47: void stspin();
48:
49: /*
50: * Driver configuration.
51: */
52: int stload();
53: int stuload();
54: int stopen();
55: int stclose();
56: int stread();
57: int stwrite();
58: int stioctl();
59: void stwatch();
60: int nulldev();
61: int nonedev();
62:
63: CON stcon = {
64: DFCHR, /* Flags */
65: ST_MAJOR, /* Major index */
66: stopen, /* Open */
67: stclose, /* Close */
68: nonedev, /* Block */
69: stread, /* Read */
70: stwrite, /* Write */
71: stioctl, /* Ioctl */
72: nulldev, /* Powerfail */
73: stwatch, /* Timeout */
74: stload, /* Load */
75: stuload /* Unload */
76: };
77:
78: /*
79: * I/O Port Addresses
80: */
81: #define DATA_REG (STPORT+0) /* Data register */
82: #define CTRL_REG (STPORT+1) /* Control/Status register */
83: #define DMAGO_REG (STPORT+2) /* DMA Go register */
84: #define DMARST_REG (STPORT+3) /* DMA reset register */
85:
86: /*
87: * Control Register
88: */
89: #define CR_RSTSAC BIT(7) /* 1 -> reset control micro */
90: #define CR_REQ BIT(6) /* 1 -> request to LSI chip */
91: #define CR_IEN BIT(5) /* 1 -> enables interrupts */
92: #define CR_DNIEN BIT(4) /* 1 -> enable DONE interrupts */
93:
94: /*
95: * Status Register
96: */
97: #define SR_IRQF BIT(7) /* 1 -> Interrupt Request Flag */
98: #define SR_NRDY BIT(6) /* 0 -> Ready */
99: #define SR_NEXC BIT(5) /* 0 -> Exception */
100: #define SR_DONE BIT(4) /* 1 -> DMA Done */
101: #define SR_TO_PC BIT(3) /* 1 -> Direction is to PC */
102:
103: /*
104: * Controller Commands.
105: */
106: #define CC_SELECT 0x01 /* Select Drive 0 */
107: #define CC_LOCK 0x11 /* Select Drive 0 and Lock */
108: #define CC_BOT 0x21 /* Rewind to beginning of tape */
109: #define CC_ERASE 0x22 /* Completely erase cartridge */
110: #define CC_TENSION 0x24 /* Wind tape to BOT, EOT, BOT */
111: #define CC_AUTO 0x25 /* Select auto-initialization */
112: #define CC_QIC11 0x26 /* Select QIC-11 media format */
113: #define CC_QIC24 0x27 /* Select QIC-24 media format */
114: #define CC_WRITE 0x40 /* Write to tape */
115: #define CC_WFM 0x60 /* Write file mark */
116: #define CC_READ 0x80 /* Read from tape */
117: #define CC_RFM 0xA0 /* Skip past next file mark */
118: #define CC_SENSE 0xC0 /* Read controller status */
119:
120: /*
121: * Sense Status Bytes 0 and 1.
122: */
123: #define SS0_FIL BIT(0) /* File Mark Detected */
124: #define SS0_BNL BIT(1) /* Bad Block Not located */
125: #define SS0_UDA BIT(2) /* Unrecoverable data error */
126: #define SS0_EOM BIT(3) /* End of media */
127: #define SS0_WRP BIT(4) /* Write Protected Cartridge */
128: #define SS0_USL BIT(5) /* Unselected Drive */
129: #define SS0_CNI BIT(6) /* Cartridge Not In Place */
130: #define SS0_ERR (SS0_BNL+SS0_UDA+SS0_USL+SS0_CNI)
131:
132: #define SS1_POR BIT(0) /* Power on Reset Occurred */
133: #define SS1_BOM BIT(3) /* Beginning of media */
134: #define SS1_MBD BIT(4) /* Marginal Block Detected */
135: #define SS1_NDT BIT(5) /* No Data Detected */
136: #define SS1_ILL BIT(6) /* Illegal Command */
137: #define SS1_ERR (SS1_NDT+SS1_ILL)
138:
139: /*
140: * Device States.
141: */
142: #define SDEAD 0 /* controller not found */
143: #define SIDLE 1 /* controller idle */
144: #define SCMD 2 /* initiating command */
145: #define SRUN 3 /* performing command */
146: #define SRDWR 4 /* starting read/write */
147: #define SBLOCK 5 /* performing read/write */
148: #define SBLEND 6 /* concluding block i/o */
149: #define SSENSE 7 /* reading status bytes */
150: #define SSDONE 8 /* concluding status sense */
151:
152: /*
153: * Driver State Information.
154: */
155: struct st_s {
156: int st_state;
157: int st_mode; /* IPR or IPW */
158: int st_iocmd; /* CC_READ or CC_WRITE */
159: int st_cmd; /* last command executed */
160: int st_cmds[NCMDS]; /* list of chained commands */
161: int st_ncmds; /* num of chained commands */
162: int st_iswr;
163: int st_wasio;
164: int st_iseof;
165: int st_error;
166: paddr_t st_paddr;
167: fsize_t st_resid;
168: fsize_t st_size;
169: saddr_t st_sel;
170: SEG * st_seg;
171: char st_status[6];
172: int st_nstat;
173: int st_rdys; /* number of ready watchdogs */
174: int st_nlost; /* number of lost interrupts */
175: } st;
176:
177: /**
178: *
179: * void
180: * stload() -- initialize tape device
181: *
182: * Action: Reset tape controller and drive.
183: * Seize tape interrupt vector.
184: *
185: * Note: If the tape controller is present and operational,
186: * a interrupt will occur and set st.st_state to SIDLE.
187: */
188: static
189: stload()
190: {
191: /*
192: * Paranoia - Turn off DMA.
193: * Should already be turned off.
194: */
195: dmaoff( STDMA );
196:
197: /*
198: * Reset tape controller and drive
199: */
200: outb( CTRL_REG, CR_RSTSAC );
201:
202: /*
203: * Wait at least 25 microseconds
204: */
205: stspin( 25 );
206:
207: /*
208: * Terminate reset condition
209: */
210: outb( CTRL_REG, CR_IEN );
211:
212: /*
213: * Seize tape interrupt vector.
214: */
215: setivec( STIRQ, &stintr );
216: }
217:
218: /**
219: *
220: * stuload( dev ) -- Unload tape device.
221: * dev_t dev;
222: */
223: stuload( dev )
224: dev_t dev;
225: {
226: /*
227: * Turn off DMA.
228: */
229: dmaoff( STDMA );
230:
231: /*
232: * Release tape interrupt vector.
233: */
234: clrivec( STIRQ );
235:
236: /*
237: * Disable tape interrupts.
238: */
239: outb( CTRL_REG, 0 );
240: }
241:
242: /**
243: *
244: * stopen( dev, mode ) -- open tape device
245: * dev_t dev;
246: * int mode;
247: *
248: * Input: dev = tape device to be opened.
249: * mode = desired access mode.
250: *
251: * Action: Refuse access if tape drive does not exist or is in use.
252: * Refuse simultaneous read and write access.
253: * Refuse access if cartridge is not inserted in tape drive.
254: * Refuse write access to a write protected cartridge.
255: * Allocate tape cache.
256: * Initialize device state.
257: * Lock tape cartridge.
258: */
259: static
260: stopen( dev, mode )
261: register dev_t dev;
262: register int mode;
263: {
264: int s;
265:
266: /*
267: * Refuse access if no tape drive.
268: */
269: if ( st.st_state == SDEAD ) {
270: u.u_error = ENXIO;
271: return;
272: }
273:
274: /*
275: * Refuse access if tape drive is already open.
276: */
277: if ( st.st_mode != 0 ) {
278: u.u_error = EDBUSY;
279: return;
280: }
281:
282: /*
283: * Access must be read-only or write-only.
284: */
285: if ( (mode != IPR) && (mode != IPW) ) {
286: u.u_error = EINVAL;
287: return;
288: }
289:
290: /*
291: * Wait for tape drive to become idle.
292: */
293: if ( stwait() < 0 ) {
294: u.u_error = EINTR;
295: return;
296: }
297:
298: /*
299: * Initialize tape interface.
300: */
301: s = sphi();
302: outb( DMARST_REG, 0 );
303: outb( CTRL_REG, CR_IEN );
304: spl( s );
305:
306: /*
307: * Obtain tape status.
308: */
309: stinvoke( CC_SENSE );
310:
311: /*
312: * Wait for tape status.
313: */
314: if ( stwait() < 0 ) {
315: u.u_error = EINTR;
316: return;
317: }
318:
319: /*
320: * Refuse access if no cartridge.
321: */
322: if ( st.st_status[0] & (SS0_CNI|SS0_USL) ) {
323: u.u_error = EDATTN;
324: return;
325: }
326:
327: /*
328: * Refuse write access to a write protected cartridge.
329: */
330: if ( (mode == IPW) && (st.st_status[0] & SS0_WRP) ) {
331: u.u_error = EROFS;
332: return;
333: }
334:
335: /*
336: * Calculate desired cache size in Kbytes.
337: */
338: st.st_size = minor(dev) & ~0x80;
339: if ( st.st_size == 0 )
340: st.st_size = 256;
341:
342: /*
343: * Allocate cache
344: */
345: for ( st.st_size *= 1024; st.st_size != 0; st.st_size -= 1024 )
346: if ( st.st_seg = salloc( st.st_size, SFSYST|SFNSWP|SFNCLR ) )
347: break;
348:
349: /*
350: * Refuse access if couldn't allocate cache.
351: */
352: if ( st.st_seg == 0 ) {
353: u.u_error = ENOMEM;
354: return;
355: };
356:
357: /*
358: * Initialize device state.
359: */
360: st.st_sel = FP_SEL(st.st_seg->s_faddr);
361: st.st_iswr = (mode == IPW);
362: st.st_paddr = st.st_seg->s_paddr;
363: st.st_resid = (mode == IPW) ? st.st_size : 0 ;
364: st.st_iocmd = (mode == IPW) ? CC_WRITE : CC_READ ;
365: st.st_mode = mode;
366: st.st_iseof = 0;
367: st.st_wasio = 0;
368: st.st_error = 0;
369: st.st_rdys = 0;
370: st.st_nlost = 0;
371:
372: /*
373: * Lock cartridge if at beginning of media.
374: */
375: if ( st.st_status[1] & SS1_BOM )
376: stinvoke( CC_LOCK );
377: }
378:
379: /**
380: *
381: * stclose( dev, mode ) -- close tape device
382: * dev_t dev;
383: * int mode;
384: *
385: * Input: dev = tape device to be closed.
386: * mode = access mode.
387: *
388: * Action: If access mode was for writing, flush the tape cache.
389: * If data was written to tape, write a file mark.
390: * If data was read from tape on the non rewinding device,
391: * read until end of file or an error is encountered.
392: * Rewind the tape if the rewinding device is open.
393: * Unlock the tape cartridge.
394: * Clear tape state and release tape cache memory.
395: */
396: static
397: stclose( dev, mode )
398: register dev_t dev;
399: {
400: /*
401: * Check if tape was opened for writing.
402: */
403: if ( st.st_iswr ) {
404:
405: /*
406: * Flush the tape cache.
407: */
408: stflush();
409:
410: /*
411: * Write a file mark if data was written to tape.
412: */
413: if ( st.st_wasio )
414: stinvoke( CC_WFM );
415: }
416:
417: /*
418: * Check if non-rewinding device was opened for reading.
419: */
420: else if ( st.st_wasio && (dev & 0x80 ) ) {
421:
422: /*
423: * Read file mark if not just past one.
424: */
425: if ( (st.st_status[0] & SS0_FIL) == 0 )
426: stinvoke( CC_RFM );
427: }
428:
429: /*
430: * Rewinding device.
431: */
432: if ( (dev & 0x80) == 0 ) {
433:
434: /*
435: * Wait for controller to idle.
436: */
437: while ( stwait() < 0 )
438: ;
439:
440: /*
441: * Initiate rewind.
442: */
443: stinvoke( CC_BOT );
444:
445: /*
446: * Unlock the drive [turn off the light].
447: */
448: stinvoke( CC_SELECT );
449: }
450:
451: /*
452: * Clear tape state, releasing tape cache.
453: */
454: sfree( st.st_seg );
455: st.st_seg = 0;
456: st.st_mode = 0;
457: }
458:
459: /**
460: *
461: * stread( dev, iop ) -- tape device read
462: * dev_t dev;
463: * IO * iop;
464: *
465: * Input: dev = tape device to be read from.
466: * iop = pointer to IO structure.
467: *
468: * Action: Transfer data from tape cache to user memory,
469: * filling the cache as required by initiating reads from tape.
470: */
471:
472: static
473: stread( dev, iop )
474: dev_t dev;
475: register IO * iop;
476: {
477: register int n;
478: register int ioc;
479:
480: ioc = iop->io_ioc;
481:
482: while ( iop->io_ioc > 0 ) {
483:
484: /*
485: * Check for empty cache.
486: */
487: while ( st.st_resid == 0 ) {
488:
489: /*
490: * Special handling if end of file was encountered.
491: */
492: if ( st.st_iseof ) {
493:
494: /*
495: * Clear EOF if no data was transferred yet.
496: */
497: if ( ioc == iop->io_ioc )
498: st.st_iseof = 0;
499:
500: return;
501: }
502:
503: /*
504: * Abort on I/O error.
505: */
506: if ( u.u_error = st.st_error ) {
507: stdiag();
508: return;
509: }
510:
511: /*
512: * Fill the cache from tape.
513: */
514: stcache();
515: }
516:
517: /*
518: * Determine max data transferable in one chunk.
519: */
520: n = iop->io_ioc;
521: if ( n > st.st_resid )
522: n = st.st_resid;
523:
524: /*
525: * Transfer some data from cache to user memory.
526: */
527: if ( pucopy( st.st_paddr, iop->io_base, n ) != n )
528: return;
529:
530: /*
531: * Update addresses and counts.
532: */
533: iop->io_base += n;
534: iop->io_ioc -= n;
535: st.st_resid -= n;
536: st.st_paddr += n;
537: }
538: }
539:
540: /**
541: *
542: * stwrite( dev, iop ) -- write to tape device
543: * dev_t dev;
544: * IO * iop;
545: *
546: * Input: dev = tape device to be written to.
547: * iop = pointer to IO structure.
548: *
549: * Action: Transfer data from user memory to tape cache,
550: * flushing the cache as required by initiating writes to tape.
551: */
552:
553: static
554: stwrite( dev, iop )
555: dev_t dev;
556: register IO *iop;
557: {
558: register int n;
559:
560: while ( iop->io_ioc > 0 ) {
561:
562: /*
563: * Determine max data transferable in one chunk.
564: */
565: n = iop->io_ioc;
566: if ( n > st.st_resid )
567: n = st.st_resid;
568:
569: /*
570: * Transfer some data from user memory to cache.
571: */
572: if ( upcopy( iop->io_base, st.st_paddr, n ) != n )
573: break;
574:
575: /*
576: * Update addresses and counts.
577: */
578: iop->io_base += n;
579: iop->io_ioc -= n;
580: st.st_paddr += n;
581: st.st_resid -= n;
582:
583: /*
584: * Flush the cache to tape if full.
585: */
586: if ( st.st_resid == 0 )
587: stflush();
588:
589: /*
590: * Abort on I/O error.
591: */
592: if ( u.u_error = st.st_error ) {
593: stdiag();
594: return;
595: }
596: }
597: }
598:
599: /**
600: *
601: * stioctl( dev, cmd, arg ) -- service tape I/O control requests
602: * int dev;
603: * int cmd;
604: * int arg;
605: *
606: * Input: dev = tape device to be serviced
607: * cmd = ioctl command
608: * arg = argument to ioctl command
609: *
610: * Action: Service tape I/O control request.
611: */
612:
613: static
614: stioctl( dev, cmd, arg )
615: {
616: if ( st.st_iswr )
617: stflush();
618:
619: st.st_error = EINVAL;
620:
621: switch ( cmd ) {
622:
623: case MTERASE:
624: stinvoke( CC_ERASE );
625: break;
626:
627: case MTTENSE:
628: stinvoke( CC_TENSION );
629: break;
630:
631: case MTREWIND:
632: if ( st.st_iswr && st.st_wasio ) {
633: stinvoke( CC_WFM );
634: st.st_wasio = 0;
635: }
636: stinvoke( CC_BOT );
637: break;
638:
639: case MTWEOF:
640: if ( st.st_iswr ) {
641: stinvoke( CC_WFM );
642: st.st_wasio = 0;
643: }
644: break;
645:
646: case MTFSKIP:
647: if ( ! st.st_iswr ) {
648: if ( ! st.st_iseof )
649: stinvoke( CC_RFM );
650: st.st_iseof = 0;
651: st.st_resid = 0;
652: }
653: break;
654: }
655:
656: /*
657: * Record tape error code.
658: */
659: u.u_error = st.st_error;
660: }
661:
662: /**
663: *
664: * void
665: * stcache() -- read from tape into cache
666: *
667: * Action: Read as much data as possible into the tape cache.
668: * Set st.st_paddr to the cache address.
669: * Set st.st_resid to the number of data bytes in the cache.
670: */
671: static void
672: stcache()
673: {
674: /*
675: * Try to fill cache from tape.
676: */
677: st.st_paddr = st.st_seg->s_paddr;
678: st.st_resid = st.st_size;
679: ststart();
680:
681: /*
682: * Update cache information.
683: */
684: st.st_paddr = st.st_seg->s_paddr;
685: st.st_resid = st.st_size - st.st_resid;
686:
687: /*
688: * Clear the cache on I/O error.
689: */
690: if ( st.st_error )
691: st.st_resid = 0;
692: }
693:
694: /**
695: *
696: * void
697: * stflush() -- flush cache to tape
698: *
699: * Action: Ensure tape cache is block aligned.
700: * Write cache to the tape.
701: * Set st.st_paddr to the cache address.
702: * Set st.st_resid to the number of cache bytes available.
703: */
704: static void
705: stflush()
706: {
707: static char zc;
708:
709: /*
710: * Check for empty cache.
711: */
712: if ( st.st_resid == st.st_size )
713: return;
714:
715: /*
716: * Block align the cache.
717: */
718: while ( st.st_resid % BSIZE ) {
719: kpcopy( &zc, st.st_paddr, 1 );
720: st.st_paddr++;
721: st.st_resid--;
722: }
723:
724: /*
725: * Flush the cache to tape.
726: */
727: st.st_paddr = st.st_seg->s_paddr;
728: st.st_resid = st.st_size - st.st_resid;
729: ststart();
730:
731: /*
732: * Update cache information.
733: */
734: st.st_paddr = st.st_seg->s_paddr;
735: st.st_resid = st.st_size;
736: }
737:
738: /**
739: *
740: * void
741: * stinvoke() -- start tape control operation
742: *
743: * Action: Initiate tape control operation.
744: */
745: static void
746: stinvoke( cmd )
747: int cmd;
748: {
749: register int s;
750:
751: /*
752: * Disable interrupts.
753: */
754: s = sphi();
755:
756: /*
757: * Wait for controller to become idle.
758: */
759: while ( st.st_state != SIDLE ) {
760:
761: /*
762: * Create chained command if possible.
763: */
764: if ( st.st_ncmds < NCMDS ) {
765: st.st_cmds[ st.st_ncmds++ ] = cmd;
766: spl( s );
767: return;
768: }
769:
770: sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
771: }
772:
773: /*
774: * Setup for tape operation.
775: */
776: drvl[ST_MAJOR].d_time = 1;
777: st.st_state = SCMD;
778: st.st_error = 0;
779: st.st_rdys = 0;
780: stspin( 100 );
781:
782: /*
783: * Request tape operation.
784: * Do NOT wait for results.
785: */
786: outb( DATA_REG, st.st_cmd = cmd );
787: outb( CTRL_REG, CR_IEN+CR_REQ );
788:
789: /*
790: * Enable interrupts.
791: */
792: spl( s );
793: }
794:
795: /**
796: *
797: * void
798: * ststart() -- start tape read/write operation
799: *
800: * Action: Initiate tape read/write operation.
801: * Wait for tape operation to complete.
802: */
803: static void
804: ststart()
805: {
806: register int s;
807:
808: /*
809: * Disable interrupts.
810: */
811: s = sphi();
812:
813: /*
814: * Wait for controller to become idle.
815: */
816: while ( st.st_state != SIDLE )
817: sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
818:
819: /*
820: * Setup for tape read/write.
821: */
822: drvl[ST_MAJOR].d_time = 1;
823: st.st_state = SRDWR;
824: st.st_error = 0;
825: st.st_rdys = 0;
826: stspin( 100 );
827:
828: /*
829: * Tape read/write was last command executed.
830: */
831: if ( st.st_cmd == st.st_iocmd ) {
832: /*
833: * Resume tape i/o operation.
834: * Simulate RDY interrupt.
835: */
836: stintr();
837: }
838: else {
839: /*
840: * Request tape operation.
841: */
842: outb( DATA_REG, st.st_cmd = st.st_iocmd );
843: outb( CTRL_REG, CR_IEN+CR_REQ );
844: }
845:
846: /*
847: * Wait for tape operation to complete.
848: */
849: while ( st.st_state != SIDLE )
850: sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
851:
852: /*
853: * Enable interrupts.
854: */
855: spl( s );
856: }
857:
858: /**
859: *
860: * void
861: * stintr() -- tape interrupt handler
862: *
863: * Action: Service tape interrupts.
864: * Perform transitions to new tape states.
865: * Wake sleeping processes if appropriate.
866: */
867: static void
868: stintr()
869: {
870: register int csr;
871: register int s;
872:
873: s = sphi();
874: csr = inb( CTRL_REG );
875:
876: /*
877: * Initiate exception recovery.
878: */
879: if ( (csr & SR_NEXC) == 0 ) {
880: strecov();
881: spl( s );
882: return;
883: }
884:
885: /*
886: * Clear ready watchdog count.
887: */
888: st.st_rdys = 0;
889:
890: /*
891: * Process normal operations.
892: */
893: switch ( st.st_state ) {
894:
895: case SCMD:
896: /*
897: * Command has been acknowledged.
898: * Wait for command completion.
899: */
900: outb( CTRL_REG, CR_IEN );
901: st.st_state = (st.st_cmd == CC_SENSE) ? SSENSE : SRUN;
902: st.st_nstat = 0;
903: break;
904:
905: case SRUN:
906: /*
907: * Command has completed.
908: * Chain a sense status command if no other chained commands.
909: */
910: if ( st.st_ncmds == 0 )
911: st.st_cmds[ st.st_ncmds++ ] = CC_SENSE;
912:
913: /*
914: * Initiate next chained command.
915: */
916: stnext();
917: break;
918:
919: case SRDWR:
920: /*
921: * Read/Write command had been acknowledged.
922: * Clear tape request, enable done interrupt.
923: */
924: outb( CTRL_REG, CR_IEN+CR_DNIEN );
925:
926: /*
927: * Define direct memory access parameters.
928: */
929: dmaon( STDMA, st.st_paddr, BSIZE, st.st_iswr );
930:
931: /*
932: * If tape read command, wait for interface to switch direction
933: */
934: if ( st.st_iocmd == CC_READ )
935: while ( (inb(CTRL_REG) & SR_TO_PC) != SR_TO_PC )
936: ;
937:
938: /*
939: * Enable DMA transfer on tape interface and at DMA controller chip.
940: */
941: st.st_state = SBLOCK;
942: outb( DMAGO_REG, 0 );
943: dmago( STDMA );
944: break;
945:
946: case SBLOCK:
947: /*
948: * Perform Block I/O.
949: * Ignore RDY interrupt, wait for [DMA] DONE interrupt.
950: */
951: if ( (csr & SR_DONE) == 0 )
952: break;
953:
954: /*
955: * Turn off DMA.
956: */
957: dmaoff( STDMA );
958:
959: /*
960: * If more data remains to be transferred, reenable DMA.
961: * NOTE: do -= BEFORE if() to avoid potential compiler bug.
962: */
963: st.st_resid -= BSIZE;
964: if ( st.st_resid > 0 ) {
965: st.st_paddr += BSIZE;
966: dmaon( STDMA, st.st_paddr, BSIZE, st.st_iswr );
967: outb( DMAGO_REG, 0 );
968: dmago( STDMA );
969: break;
970: }
971:
972: /*
973: * Disable done interrupt.
974: * Wait for I/O completion.
975: */
976: outb( CTRL_REG, CR_IEN );
977: st.st_state = SBLEND;
978: break;
979:
980: case SBLEND:
981: /*
982: * Completion of Block I/O.
983: * Clear the file mark and beginning of media indicators.
984: * Record the fact that data has been transferred.
985: */
986: st.st_status[0] &= ~SS0_FIL;
987: st.st_status[1] &= ~SS1_BOM;
988: st.st_wasio = 1;
989: stnext();
990: break;
991:
992: case SSENSE:
993: /*
994: * Sense Status Byte.
995: * Wait for availability.
996: */
997: do {
998: csr = inb(CTRL_REG) & (SR_NRDY|SR_TO_PC);
999: } while ( csr != SR_TO_PC );
1000:
1001: /*
1002: * Save status byte.
1003: */
1004: st.st_status[st.st_nstat] = inb(DATA_REG);
1005:
1006: /*
1007: * Acknowledge reception.
1008: * CR_REQ must be present for at least 20 microseconds.
1009: */
1010: outb( CTRL_REG, CR_IEN+CR_REQ );
1011: stspin( 20 );
1012: outb( CTRL_REG, CR_IEN );
1013:
1014: /*
1015: * Change state to status completion if all bytes saved.
1016: */
1017: if ( ++(st.st_nstat) == 6 )
1018: st.st_state = SSDONE;
1019: break;
1020:
1021: case SSDONE:
1022: /*
1023: * Completion of Sense Status Command.
1024: * Check for file mark.
1025: */
1026: if ( st.st_status[0] & SS0_FIL ) {
1027: outb( DMARST_REG, 0 );
1028: st.st_iseof = 1;
1029: }
1030:
1031: /*
1032: * Check for I/O error.
1033: */
1034: else if ( (st.st_status[0] & SS0_ERR) ||
1035: (st.st_status[1] & SS1_ERR) ) {
1036: st.st_error = EIO;
1037: }
1038:
1039: /*
1040: * Check for write protected cartridge.
1041: */
1042: else if ( (st.st_iocmd == CC_WRITE) &&
1043: (st.st_status[0] & SS0_WRP) ) {
1044: st.st_error = EROFS;
1045: }
1046:
1047: stnext();
1048: break;
1049: }
1050:
1051: spl( s );
1052: }
1053:
1054: /**
1055: *
1056: * void
1057: * strecov() -- initiate recovery from exception conditions
1058: *
1059: * Action: Invoked when the tape controller asserts EXCEPTION.
1060: * A sense status command is initiated to clear the exception.
1061: */
1062: static void
1063: strecov()
1064: {
1065: /*
1066: * Ensure tape interface is idle.
1067: */
1068: outb( CTRL_REG, CR_IEN );
1069: stspin( 100 );
1070:
1071: /*
1072: * Turn off DMA on read/write exception.
1073: */
1074: if ( st.st_cmd == st.st_iocmd )
1075: dmaoff( STDMA );
1076:
1077: /*
1078: * Initiate sense status command.
1079: */
1080: outb( DATA_REG, st.st_cmd = CC_SENSE );
1081: outb( CTRL_REG, CR_IEN+CR_REQ );
1082: drvl[ST_MAJOR].d_time = 1;
1083: st.st_state = SCMD;
1084: st.st_error = 0;
1085: st.st_rdys = 0;
1086: }
1087:
1088: /**
1089: *
1090: * static void
1091: * stnext() -- initiate next chained command.
1092: */
1093: static void
1094: stnext()
1095: {
1096: /*
1097: * Ensure tape interface is idle.
1098: */
1099: outb( CTRL_REG, CR_IEN );
1100: drvl[ST_MAJOR].d_time = 0;
1101: st.st_state = SIDLE;
1102: stspin( 100 );
1103:
1104: /*
1105: * Initiate a chained command.
1106: */
1107: if ( st.st_ncmds ) {
1108: outb( DATA_REG, st.st_cmd = st.st_cmds[ --st.st_ncmds ] );
1109: outb( CTRL_REG, CR_IEN+CR_REQ );
1110: drvl[ST_MAJOR].d_time = 1;
1111: st.st_state = SCMD;
1112: st.st_error = 0;
1113: st.st_rdys = 0;
1114: return;
1115: }
1116:
1117: /*
1118: * Wake waiting processes.
1119: */
1120: wakeup( &st );
1121: }
1122:
1123: /**
1124: *
1125: * void
1126: * stwatch() -- periodic [1 sec] watchdog
1127: *
1128: * Action: If an exception condition exists, initate recovery actions.
1129: * If ready condition exists for 1-2 seconds, simulate interrupt.
1130: *
1131: * Notes: If an exception condition occurs after a ready interrupt has
1132: * been serviced, but before the ready condition is cleared,
1133: * the exception interrupt will not occur, and is simulated here.
1134: */
1135: static void
1136: stwatch()
1137: {
1138: register int csr;
1139: register int s;
1140:
1141: /*
1142: * Disable interrupts, preventing critical race with stintr().
1143: */
1144: s = sphi();
1145: csr = inb(CTRL_REG);
1146:
1147: /*
1148: * Initiate recovery from exception conditions.
1149: */
1150: if ( (csr & SR_NEXC) == 0 )
1151: strecov();
1152:
1153: /*
1154: * Reset ready watchdog if not ready.
1155: */
1156: else if ( csr & SR_NRDY )
1157: st.st_rdys = 0;
1158:
1159: /*
1160: * Simulate lost ready interrupts after 2 seconds.
1161: */
1162: else if ( ++st.st_rdys >= 2 )
1163: stintr();
1164:
1165: /*
1166: * Enable interrupts.
1167: */
1168: spl( s );
1169: }
1170:
1171: /**
1172: *
1173: * void
1174: * stdiag() - Report tape status.
1175: *
1176: * Action: Identify and report the highest priority tape error.
1177: * There will normally only be one valid error present.
1178: * The USL error can invalidate most remaining flags.
1179: * The CNI error can invalidate cartridge related flags.
1180: *
1181: * Notes: Never called from interrupt level, but always from background.
1182: */
1183: static void
1184: stdiag()
1185: {
1186: if ( st.st_status[0] & SS0_USL )
1187: printf( "st: Unselected Drive\n" );
1188:
1189: else if ( st.st_status[0] & SS0_CNI )
1190: printf( "st: Cartridge missing\n" );
1191:
1192: else if ( st.st_status[1] & SS1_NDT )
1193: printf( "st: No data detected\n" );
1194:
1195: else if ( st.st_status[0] & SS0_BNL )
1196: printf( "st: Bad block not located\n" );
1197:
1198: else if ( st.st_status[0] & SS0_UDA )
1199: printf( "st: Unrecoverable data error\n" );
1200:
1201: else if ( st.st_status[1] & SS1_ILL )
1202: printf( "st: Illegal command\n" );
1203:
1204: else
1205: printf( "st: %x\n", (st.st_status[1] << 8) + st.st_status[0] );
1206: }
1207:
1208: /**
1209: *
1210: * int
1211: * stwait() -- wait for tape controller to idle.
1212: *
1213: * Return: 0 = tape controller idle.
1214: * -1 = signal received.
1215: */
1216: static int
1217: stwait()
1218: {
1219: int s;
1220:
1221: s = sphi();
1222: while ( st.st_state != SIDLE ) {
1223:
1224: sleep( &st, CVTTOUT, IVTTOUT, SVTTOUT );
1225:
1226: if ( SELF->p_ssig ) {
1227: spl( s );
1228: return -1;
1229: }
1230: }
1231: spl( s );
1232:
1233: return 0;
1234: }
1235:
1236: /**
1237: *
1238: * void
1239: * stspin( usec ) -- delay execution
1240: * int usec;
1241: *
1242: * Input: usec = number of micro-seconds to delay.
1243: *
1244: * Action: Wait at least 'usec' micro-seconds.
1245: *
1246: * Notes: Provides minimum delay required at times by tape controller.
1247: * Should function properly up to at least 16 Mhz system clock.
1248: */
1249:
1250: static void
1251: stspin( usec )
1252: register int usec;
1253: {
1254: while ( --usec >= 0 )
1255: ;
1256: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.