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