|
|
1.1 root 1: /*
2: * NCR53c406.c
3: * Low-level SCSI driver for NCR53c406a chip.
4: * Copyright (C) 1994, 1995, 1996 Normunds Saumanis ([email protected])
5: *
6: * LILO command line usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]]
7: * Specify IRQ = 0 for non-interrupt driven mode.
8: * FASTPIO = 1 for fast pio mode, 0 for slow mode.
9: *
10: * This program is free software; you can redistribute it and/or modify it
11: * under the terms of the GNU General Public License as published by the
12: * Free Software Foundation; either version 2, or (at your option) any
13: * later version.
14: *
15: * This program is distributed in the hope that it will be useful, but
16: * WITHOUT ANY WARRANTY; without even the implied warranty of
17: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18: * General Public License for more details.
19: *
20: */
21:
22: #define NCR53C406A_DEBUG 0
23: #define VERBOSE_NCR53C406A_DEBUG 0
24:
25: /* Set this to 1 for PIO mode (recommended) or to 0 for DMA mode */
26: #define USE_PIO 1
27:
28: #define USE_BIOS 0
29: /* #define BIOS_ADDR 0xD8000 */ /* define this if autoprobe fails */
30: /* #define PORT_BASE 0x330 */ /* define this if autoprobe fails */
31: /* #define IRQ_LEV 0 */ /* define this if autoprobe fails */
32: #define DMA_CHAN 5 /* this is ignored if DMA is disabled */
33:
34: /* Set this to 0 if you encounter kernel lockups while transferring
35: * data in PIO mode */
36: #define USE_FAST_PIO 1
37:
38: /* ============= End of user configurable parameters ============= */
39:
40: #include <linux/module.h>
41:
42: #include <linux/errno.h>
43: #include <linux/ioport.h>
44: #include <linux/sched.h>
45: #include <linux/interrupt.h>
46: #include <linux/proc_fs.h>
47: #include <linux/stat.h>
48: #include <asm/io.h>
49: #include <asm/dma.h>
50: #include <asm/bitops.h>
51: #include <asm/irq.h>
52:
53: #include <linux/blk.h>
54: #include "scsi.h"
55: #include "hosts.h"
56: #include "sd.h"
57:
58: #include "NCR53c406a.h"
59:
60: /* ============================================================= */
61:
62: #define WATCHDOG 5000000
63:
64: #define SYNC_MODE 0 /* Synchronous transfer mode */
65:
66: #if DEBUG
67: #undef NCR53C406A_DEBUG
68: #define NCR53C406A_DEBUG 1
69: #endif
70:
71: #if USE_PIO
72: #define USE_DMA 0
73: #else
74: #define USE_DMA 1
75: #endif
76:
77: /* Default configuration */
78: #define C1_IMG 0x07 /* ID=7 */
79: #define C2_IMG 0x48 /* FE SCSI2 */
80: #if USE_DMA
81: #define C3_IMG 0x21 /* CDB TE */
82: #else
83: #define C3_IMG 0x20 /* CDB */
84: #endif
85: #define C4_IMG 0x04 /* ANE */
86: #define C5_IMG 0xb6 /* AA PI SIE POL */
87:
88: #define REG0 (outb(C4_IMG, CONFIG4))
89: #define REG1 (outb(C5_IMG, CONFIG5))
90:
91: #if NCR53C406A_DEBUG
92: #define DEB(x) x
93: #else
94: #define DEB(x)
95: #endif
96:
97: #if VERBOSE_NCR53C406A_DEBUG
98: #define VDEB(x) x
99: #else
100: #define VDEB(x)
101: #endif
102:
103: #define LOAD_DMA_COUNT(count) \
104: outb(count & 0xff, TC_LSB); \
105: outb((count >> 8) & 0xff, TC_MSB); \
106: outb((count >> 16) & 0xff, TC_HIGH);
107:
108: /* Chip commands */
109: #define DMA_OP 0x80
110:
111: #define SCSI_NOP 0x00
112: #define FLUSH_FIFO 0x01
113: #define CHIP_RESET 0x02
114: #define SCSI_RESET 0x03
115: #define RESELECT 0x40
116: #define SELECT_NO_ATN 0x41
117: #define SELECT_ATN 0x42
118: #define SELECT_ATN_STOP 0x43
119: #define ENABLE_SEL 0x44
120: #define DISABLE_SEL 0x45
121: #define SELECT_ATN3 0x46
122: #define RESELECT3 0x47
123: #define TRANSFER_INFO 0x10
124: #define INIT_CMD_COMPLETE 0x11
125: #define MSG_ACCEPT 0x12
126: #define TRANSFER_PAD 0x18
127: #define SET_ATN 0x1a
128: #define RESET_ATN 0x1b
129: #define SEND_MSG 0x20
130: #define SEND_STATUS 0x21
131: #define SEND_DATA 0x22
132: #define DISCONN_SEQ 0x23
133: #define TERMINATE_SEQ 0x24
134: #define TARG_CMD_COMPLETE 0x25
135: #define DISCONN 0x27
136: #define RECV_MSG 0x28
137: #define RECV_CMD 0x29
138: #define RECV_DATA 0x2a
139: #define RECV_CMD_SEQ 0x2b
140: #define TARGET_ABORT_DMA 0x04
141:
142: /*----------------------------------------------------------------*/
143: /* the following will set the monitor border color (useful to find
144: where something crashed or gets stuck at */
145: /* 1 = blue
146: 2 = green
147: 3 = cyan
148: 4 = red
149: 5 = magenta
150: 6 = yellow
151: 7 = white
152: */
153:
154: #if NCR53C406A_DEBUG
155: #define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);}
156: #else
157: #define rtrc(i) {}
158: #endif
159: /*----------------------------------------------------------------*/
160:
161: enum Phase {
162: idle,
163: data_out,
164: data_in,
165: command_ph,
166: status_ph,
167: message_out,
168: message_in
169: };
170:
171: /* Static function prototypes */
172: static void NCR53c406a_intr(int, void *, struct pt_regs *);
173: static void internal_done(Scsi_Cmnd *);
174: static void wait_intr(void);
175: static void chip_init(void);
176: static void calc_port_addr(void);
177: #ifndef IRQ_LEV
178: static int irq_probe(void);
179: #endif
180:
181: /* ================================================================= */
182:
183: #if USE_BIOS
184: static void *bios_base = (void *)0;
185: #endif
186:
187: #if PORT_BASE
188: static int port_base = PORT_BASE;
189: #else
190: static int port_base = 0;
191: #endif
192:
193: #if IRQ_LEV
194: static int irq_level = IRQ_LEV;
195: #else
196: static int irq_level = -1; /* 0 is 'no irq', so use -1 for 'uninitialized'*/
197: #endif
198:
199: #if USE_DMA
200: static int dma_chan = 0;
201: #endif
202:
203: #if USE_PIO
204: static int fast_pio = USE_FAST_PIO;
205: #endif
206:
207: static Scsi_Cmnd *current_SC = NULL;
208: static volatile int internal_done_flag = 0;
209: static volatile int internal_done_errcode = 0;
210: static char info_msg[256];
211:
212: struct proc_dir_entry proc_scsi_NCR53c406a = {
213: PROC_SCSI_NCR53C406A, 7, "NCR53c406a",
214: S_IFDIR | S_IRUGO | S_IXUGO, 2
215: };
216: /* ================================================================= */
217:
218: /* possible BIOS locations */
219: #if USE_BIOS
220: static void *addresses[] = {
221: (void *)0xd8000,
222: (void *)0xc8000
223: };
224: #define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
225: #endif USE_BIOS
226:
227: /* possible i/o port addresses */
228: static unsigned short ports[] = { 0x230, 0x330 };
229: #define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
230:
231: /* possible interrupt channels */
232: static unsigned short intrs[] = { 10, 11, 12, 15 };
233: #define INTR_COUNT (sizeof( intrs ) / sizeof( unsigned short ))
234:
235: /* signatures for NCR 53c406a based controllers */
236: #if USE_BIOS
237: struct signature {
238: char *signature;
239: int sig_offset;
240: int sig_length;
241: } signatures[] = {
242: /* 1 2 3 4 5 6 */
243: /* 123456789012345678901234567890123456789012345678901234567890 */
244: { "Copyright (C) Acculogic, Inc.\r\n2.8M Diskette Extension Bios ver 4.04.03 03/01/1993", 61, 82 },
245: };
246: #define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
247: #endif USE_BIOS
248:
249: /* ============================================================ */
250:
251: /* Control Register Set 0 */
252: static int TC_LSB; /* transfer counter lsb */
253: static int TC_MSB; /* transfer counter msb */
254: static int SCSI_FIFO; /* scsi fifo register */
255: static int CMD_REG; /* command register */
256: static int STAT_REG; /* status register */
257: static int DEST_ID; /* selection/reselection bus id */
258: static int INT_REG; /* interrupt status register */
259: static int SRTIMOUT; /* select/reselect timeout reg */
260: static int SEQ_REG; /* sequence step register */
261: static int SYNCPRD; /* synchronous transfer period */
262: static int FIFO_FLAGS; /* indicates # of bytes in fifo */
263: static int SYNCOFF; /* synchronous offset register */
264: static int CONFIG1; /* configuration register */
265: static int CLKCONV; /* clock conversion reg */
266: /*static int TESTREG;*/ /* test mode register */
267: static int CONFIG2; /* Configuration 2 Register */
268: static int CONFIG3; /* Configuration 3 Register */
269: static int CONFIG4; /* Configuration 4 Register */
270: static int TC_HIGH; /* Transfer Counter High */
271: /*static int FIFO_BOTTOM;*/ /* Reserve FIFO byte register */
272:
273: /* Control Register Set 1 */
274: /*static int JUMPER_SENSE;*/ /* Jumper sense port reg (r/w) */
275: /*static int SRAM_PTR;*/ /* SRAM address pointer reg (r/w) */
276: /*static int SRAM_DATA;*/ /* SRAM data register (r/w) */
277: static int PIO_FIFO; /* PIO FIFO registers (r/w) */
278: /*static int PIO_FIFO1;*/ /* */
279: /*static int PIO_FIFO2;*/ /* */
280: /*static int PIO_FIFO3;*/ /* */
281: static int PIO_STATUS; /* PIO status (r/w) */
282: /*static int ATA_CMD;*/ /* ATA command/status reg (r/w) */
283: /*static int ATA_ERR;*/ /* ATA features/error register (r/w)*/
284: static int PIO_FLAG; /* PIO flag interrupt enable (r/w) */
285: static int CONFIG5; /* Configuration 5 register (r/w) */
286: /*static int SIGNATURE;*/ /* Signature Register (r) */
287: /*static int CONFIG6;*/ /* Configuration 6 register (r) */
288:
289: /* ============================================================== */
290:
291: #if USE_DMA
292: static __inline__ int
293: NCR53c406a_dma_setup (unsigned char *ptr,
294: unsigned int count,
295: unsigned char mode) {
296: unsigned limit;
297: unsigned long flags = 0;
298:
299: VDEB(printk("dma: before count=%d ", count));
300: if (dma_chan <=3) {
301: if (count > 65536)
302: count = 65536;
303: limit = 65536 - (((unsigned) ptr) & 0xFFFF);
304: } else {
305: if (count > (65536<<1))
306: count = (65536<<1);
307: limit = (65536<<1) - (((unsigned) ptr) & 0x1FFFF);
308: }
309:
310: if (count > limit) count = limit;
311:
312: VDEB(printk("after count=%d\n", count));
313: if ((count & 1) || (((unsigned) ptr) & 1))
314: panic ("NCR53c406a: attempted unaligned DMA transfer\n");
315:
316: save_flags(flags);
317: cli();
318: disable_dma(dma_chan);
319: clear_dma_ff(dma_chan);
320: set_dma_addr(dma_chan, (long) ptr);
321: set_dma_count(dma_chan, count);
322: set_dma_mode(dma_chan, mode);
323: enable_dma(dma_chan);
324: restore_flags(flags);
325:
326: return count;
327: }
328:
329: static __inline__ int
330: NCR53c406a_dma_write(unsigned char *src, unsigned int count) {
331: return NCR53c406a_dma_setup (src, count, DMA_MODE_WRITE);
332: }
333:
334: static __inline__ int
335: NCR53c406a_dma_read(unsigned char *src, unsigned int count) {
336: return NCR53c406a_dma_setup (src, count, DMA_MODE_READ);
337: }
338:
339: static __inline__ int
340: NCR53c406a_dma_residual (void) {
341: register int tmp;
342: unsigned long flags = 0;
343: save_flags(flags);
344: cli();
345: clear_dma_ff(dma_chan);
346: tmp = get_dma_residue(dma_chan);
347: restore_flags(flags);
348:
349: return tmp;
350: }
351: #endif USE_DMA
352:
353: #if USE_PIO
354: static __inline__ int NCR53c406a_pio_read(unsigned char *request,
355: unsigned int reqlen)
356: {
357: int i;
358: int len; /* current scsi fifo size */
359: unsigned long flags = 0;
360:
361: REG1;
362: while (reqlen) {
363: i = inb(PIO_STATUS);
364: /* VDEB(printk("pio_status=%x\n", i)); */
365: if (i & 0x80)
366: return 0;
367:
368: switch( i & 0x1e ) {
369: default:
370: case 0x10:
371: len=0; break;
372: case 0x0:
373: len=1; break;
374: case 0x8:
375: len=42; break;
376: case 0xc:
377: len=84; break;
378: case 0xe:
379: len=128; break;
380: }
381:
382: if ((i & 0x40) && len == 0) { /* fifo empty and interrupt occurred */
383: return 0;
384: }
385:
386: if (len) {
387: if( len > reqlen )
388: len = reqlen;
389:
390: save_flags(flags);
391: cli();
392: if( fast_pio && len > 3 ) {
393: insl(PIO_FIFO,request,len>>2);
394: request += len & 0xfc;
395: reqlen -= len & 0xfc;
396: }
397: else {
398: while(len--) {
399: *request++ = inb(PIO_FIFO);
400: reqlen--;
401: }
402: }
403: restore_flags(flags);
404: }
405: }
406: return 0;
407: }
408:
409: static __inline__ int NCR53c406a_pio_write(unsigned char *request,
410: unsigned int reqlen)
411: {
412: int i = 0;
413: int len; /* current scsi fifo size */
414: unsigned long flags = 0;
415:
416: REG1;
417: while (reqlen && !(i&0x40)) {
418: i = inb(PIO_STATUS);
419: /* VDEB(printk("pio_status=%x\n", i)); */
420: if (i & 0x80) /* error */
421: return 0;
422:
423: switch( i & 0x1e ) {
424: case 0x10:
425: len=128; break;
426: case 0x0:
427: len=84; break;
428: case 0x8:
429: len=42; break;
430: case 0xc:
431: len=1; break;
432: default:
433: case 0xe:
434: len=0; break;
435: }
436:
437: if (len) {
438: if( len > reqlen )
439: len = reqlen;
440:
441: save_flags(flags);
442: cli();
443: if( fast_pio && len > 3 ) {
444: outsl(PIO_FIFO,request,len>>2);
445: request += len & 0xfc;
446: reqlen -= len & 0xfc;
447: }
448: else {
449: while(len--) {
450: outb(*request++, PIO_FIFO);
451: reqlen--;
452: }
453: }
454: restore_flags(flags);
455: }
456: }
457: return 0;
458: }
459: #endif USE_PIO
460:
461: int
462: NCR53c406a_detect(Scsi_Host_Template * tpnt){
463: struct Scsi_Host *shpnt;
464: #ifndef PORT_BASE
465: int i;
466: #endif
467:
468: #if USE_BIOS
469: int ii, jj;
470: bios_base = 0;
471: /* look for a valid signature */
472: for( ii=0; ii < ADDRESS_COUNT && !bios_base; ii++)
473: for( jj=0; (jj < SIGNATURE_COUNT) && !bios_base; jj++)
474: if(!memcmp((void *) addresses[ii]+signatures[jj].sig_offset,
475: (void *) signatures[jj].signature,
476: (int) signatures[jj].sig_length))
477: bios_base=addresses[ii];
478:
479: if(!bios_base){
480: printk("NCR53c406a: BIOS signature not found\n");
481: return 0;
482: }
483:
484: DEB(printk("NCR53c406a BIOS found at %X\n", (unsigned int) bios_base););
485: #endif USE_BIOS
486:
487: #ifdef PORT_BASE
488: if (check_region(port_base, 0x10)) /* ports already snatched */
489: port_base = 0;
490:
491: #else /* autodetect */
492: if (port_base) { /* LILO override */
493: if (check_region(port_base, 0x10))
494: port_base = 0;
495: }
496: else {
497: for(i=0; i<PORT_COUNT && !port_base; i++){
498: if(check_region(ports[i], 0x10)){
499: DEB(printk("NCR53c406a: port %x in use\n", ports[i]));
500: }
501: else {
502: VDEB(printk("NCR53c406a: port %x available\n", ports[i]));
503: outb(C5_IMG, ports[i] + 0x0d); /* reg set 1 */
504: if( (inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7
505: && (inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7
506: && (inb(ports[i] + 0x0e) & 0xf8) == 0x58 ) {
507: VDEB(printk("NCR53c406a: Sig register valid\n"));
508: VDEB(printk("port_base=%x\n", port_base));
509: port_base = ports[i];
510: }
511: }
512: }
513: }
514: #endif PORT_BASE
515:
516: if(!port_base){ /* no ports found */
517: printk("NCR53c406a: no available ports found\n");
518: return 0;
519: }
520:
521: DEB(printk("NCR53c406a detected\n"));
522:
523: calc_port_addr();
524: chip_init();
525:
526: #ifndef IRQ_LEV
527: if (irq_level < 0) { /* LILO override if >= 0*/
528: irq_level=irq_probe();
529: if (irq_level < 0) { /* Trouble */
530: printk("NCR53c406a: IRQ problem, irq_level=%d, giving up\n", irq_level);
531: return 0;
532: }
533: }
534: #endif
535:
536: DEB(printk("NCR53c406a: using port_base %x\n", port_base));
537: request_region(port_base, 0x10, "NCR53c406a");
538:
539: if(irq_level > 0) {
540: if(request_irq(irq_level, NCR53c406a_intr, 0, "NCR53c406a", NULL)){
541: printk("NCR53c406a: unable to allocate IRQ %d\n", irq_level);
542: return 0;
543: }
544: tpnt->can_queue = 1;
545: DEB(printk("NCR53c406a: allocated IRQ %d\n", irq_level));
546: }
547: else if (irq_level == 0) {
548: tpnt->can_queue = 0;
549: DEB(printk("NCR53c406a: No interrupts detected\n"));
550: #if USE_DMA
551: printk("NCR53c406a: No interrupts found and DMA mode defined. Giving up.\n");
552: return 0;
553: #endif USE_DMA
554: }
555: else {
556: DEB(printk("NCR53c406a: Shouldn't get here!\n"));
557: return 0;
558: }
559:
560: #if USE_DMA
561: dma_chan = DMA_CHAN;
562: if(request_dma(dma_chan, "NCR53c406a") != 0){
563: printk("NCR53c406a: unable to allocate DMA channel %d\n", dma_chan);
564: return 0;
565: }
566:
567: DEB(printk("Allocated DMA channel %d\n", dma_chan));
568: #endif USE_DMA
569:
570: tpnt->present = 1;
571: tpnt->proc_dir = &proc_scsi_NCR53c406a;
572:
573: shpnt = scsi_register(tpnt, 0);
574: shpnt->irq = irq_level;
575: shpnt->io_port = port_base;
576: shpnt->n_io_port = 0x10;
577: #if USE_DMA
578: shpnt->dma = dma_chan;
579: #endif
580:
581: #if USE_DMA
582: sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, DMA channel %d.",
583: port_base, irq_level, dma_chan);
584: #else
585: sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, %s PIO mode.",
586: port_base, irq_level, fast_pio ? "fast" : "slow");
587: #endif
588:
589: return (tpnt->present);
590: }
591:
592: /* called from init/main.c */
593: void NCR53c406a_setup(char *str, int *ints)
594: {
595: static size_t setup_idx = 0;
596: size_t i;
597:
598: DEB(printk("NCR53c406a: Setup called\n"););
599:
600: if (setup_idx >= PORT_COUNT - 1) {
601: printk("NCR53c406a: Setup called too many times. Bad LILO params?\n");
602: return;
603: }
604: if (ints[0] < 1 || ints[0] > 3) {
605: printk("NCR53c406a: Malformed command line\n");
606: printk("NCR53c406a: Usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]]\n");
607: return;
608: }
609: for (i = 0; i < PORT_COUNT && !port_base; i++)
610: if (ports[i] == ints[1]) {
611: port_base = ints[1];
612: DEB(printk("NCR53c406a: Specified port_base 0x%X\n", port_base);)
613: }
614: if (!port_base) {
615: printk("NCR53c406a: Invalid PORTBASE 0x%X specified\n", ints[1]);
616: return;
617: }
618:
619: if (ints[0] > 1) {
620: if (ints[2] == 0) {
621: irq_level = 0;
622: DEB(printk("NCR53c406a: Specified irq %d\n", irq_level);)
623: }
624: else
625: for (i = 0; i < INTR_COUNT && irq_level < 0; i++)
626: if (intrs[i] == ints[2]) {
627: irq_level = ints[2];
628: DEB(printk("NCR53c406a: Specified irq %d\n", port_base);)
629: }
630: if (irq_level < 0)
631: printk("NCR53c406a: Invalid IRQ %d specified\n", ints[2]);
632: }
633:
634: if (ints[0] > 2)
635: fast_pio = ints[3];
636:
637: DEB(printk("NCR53c406a: port_base=0x%X, irq=%d, fast_pio=%d\n",
638: port_base, irq_level, fast_pio);)
639: }
640:
641: const char*
642: NCR53c406a_info(struct Scsi_Host *SChost){
643: DEB(printk("NCR53c406a_info called\n"));
644: return (info_msg);
645: }
646:
647: static void internal_done(Scsi_Cmnd *SCpnt) {
648: internal_done_errcode = SCpnt->result;
649: ++internal_done_flag;
650: }
651:
652:
653: static void wait_intr() {
654: int i = jiffies + WATCHDOG;
655:
656: while(i>jiffies && !(inb(STAT_REG)&0xe0)) /* wait for a pseudo-interrupt */
657: barrier();
658:
659: if (i <= jiffies) { /* Timed out */
660: rtrc(0);
661: current_SC->result = DID_TIME_OUT << 16;
662: current_SC->SCp.phase = idle;
663: current_SC->scsi_done(current_SC);
664: return;
665: }
666:
667: NCR53c406a_intr(0, NULL, NULL);
668: }
669:
670: int NCR53c406a_command(Scsi_Cmnd *SCpnt){
671: DEB(printk("NCR53c406a_command called\n"));
672: NCR53c406a_queue(SCpnt, internal_done);
673: if(irq_level)
674: while (!internal_done_flag);
675: else /* interrupts not supported */
676: while (!internal_done_flag)
677: wait_intr();
678:
679: internal_done_flag = 0;
680: return internal_done_errcode;
681: }
682:
683:
684: int
685: NCR53c406a_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)){
686: int i;
687: unsigned long flags = 0;
688:
689: VDEB(printk("NCR53c406a_queue called\n"));
690: DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n",
691: SCpnt->cmnd[0],
692: SCpnt->cmd_len,
693: SCpnt->target,
694: SCpnt->lun,
695: SCpnt->request_bufflen));
696:
697: #if 0
698: VDEB(for(i=0; i<SCpnt->cmd_len; i++)
699: printk("cmd[%d]=%02x ", i, SCpnt->cmnd[i]));
700: VDEB(printk("\n"));
701: #endif
702:
703: current_SC = SCpnt;
704: current_SC->scsi_done = done;
705: current_SC->SCp.phase = command_ph;
706: current_SC->SCp.Status = 0;
707: current_SC->SCp.Message = 0;
708:
709: save_flags(flags);
710: cli();
711: REG0;
712: outb(SCpnt->target, DEST_ID); /* set destination */
713: outb(FLUSH_FIFO, CMD_REG); /* reset the fifos */
714:
715: for(i=0; i<SCpnt->cmd_len; i++){
716: outb(SCpnt->cmnd[i], SCSI_FIFO);
717: }
718: outb(SELECT_NO_ATN, CMD_REG);
719: restore_flags(flags);
720:
721: rtrc(1);
722: return 0;
723: }
724:
725: int
726: NCR53c406a_abort(Scsi_Cmnd *SCpnt){
727: DEB(printk("NCR53c406a_abort called\n"));
728: return SCSI_ABORT_SNOOZE; /* Don't know how to abort */
729: }
730:
731: int
732: NCR53c406a_reset(Scsi_Cmnd *SCpnt, unsigned int flags){
733: DEB(printk("NCR53c406a_reset called\n"));
734: outb(C4_IMG, CONFIG4); /* Select reg set 0 */
735: outb(CHIP_RESET, CMD_REG);
736: outb(SCSI_NOP, CMD_REG); /* required after reset */
737: outb(SCSI_RESET, CMD_REG);
738: chip_init();
739:
740: rtrc(2);
741: if (irq_level)
742: return SCSI_RESET_PENDING; /* should get an interrupt */
743: else
744: return SCSI_RESET_WAKEUP; /* won't get any interrupts */
745: }
746:
747: int
748: NCR53c406a_biosparm(Scsi_Disk *disk, kdev_t dev, int* info_array){
749: int size;
750:
751: DEB(printk("NCR53c406a_biosparm called\n"));
752:
753: size = disk->capacity;
754: info_array[0] = 64; /* heads */
755: info_array[1] = 32; /* sectors */
756: info_array[2] = size>>11; /* cylinders */
757: if (info_array[2] > 1024) { /* big disk */
758: info_array[0] = 255;
759: info_array[1] = 63;
760: info_array[2] = size / (255*63);
761: }
762: return 0;
763: }
764:
765: static void
766: NCR53c406a_intr(int unused, void *dev_id, struct pt_regs *regs){
767: DEB(unsigned char fifo_size;)
768: DEB(unsigned char seq_reg;)
769: unsigned char status, int_reg;
770: unsigned long flags = 0;
771: #if USE_PIO
772: unsigned char pio_status;
773: struct scatterlist *sglist;
774: unsigned int sgcount;
775: #endif
776:
777: VDEB(printk("NCR53c406a_intr called\n"));
778:
779: save_flags(flags);
780: cli();
781: #if USE_PIO
782: REG1;
783: pio_status = inb(PIO_STATUS);
784: #endif
785: REG0;
786: status = inb(STAT_REG);
787: DEB(seq_reg = inb(SEQ_REG));
788: int_reg = inb(INT_REG);
789: DEB(fifo_size = inb(FIFO_FLAGS) & 0x1f);
790: restore_flags(flags);
791:
792: #if NCR53C406A_DEBUG
793: printk("status=%02x, seq_reg=%02x, int_reg=%02x, fifo_size=%02x",
794: status, seq_reg, int_reg, fifo_size);
795: #if (USE_DMA)
796: printk("\n");
797: #else
798: printk(", pio=%02x\n", pio_status);
799: #endif USE_DMA
800: #endif NCR53C406A_DEBUG
801:
802: if(int_reg & 0x80){ /* SCSI reset intr */
803: rtrc(3);
804: DEB(printk("NCR53c406a: reset intr received\n"));
805: current_SC->SCp.phase = idle;
806: current_SC->result = DID_RESET << 16;
807: current_SC->scsi_done(current_SC);
808: return;
809: }
810:
811: #if USE_PIO
812: if(pio_status & 0x80) {
813: printk("NCR53C406A: Warning: PIO error!\n");
814: current_SC->SCp.phase = idle;
815: current_SC->result = DID_ERROR << 16;
816: current_SC->scsi_done(current_SC);
817: return;
818: }
819: #endif USE_PIO
820:
821: if(status & 0x20) { /* Parity error */
822: printk("NCR53c406a: Warning: parity error!\n");
823: current_SC->SCp.phase = idle;
824: current_SC->result = DID_PARITY << 16;
825: current_SC->scsi_done(current_SC);
826: return;
827: }
828:
829: if(status & 0x40) { /* Gross error */
830: printk("NCR53c406a: Warning: gross error!\n");
831: current_SC->SCp.phase = idle;
832: current_SC->result = DID_ERROR << 16;
833: current_SC->scsi_done(current_SC);
834: return;
835: }
836:
837: if(int_reg & 0x20){ /* Disconnect */
838: DEB(printk("NCR53c406a: disconnect intr received\n"));
839: if(current_SC->SCp.phase != message_in){ /* Unexpected disconnect */
840: current_SC->result = DID_NO_CONNECT << 16;
841: }
842: else{ /* Command complete, return status and message */
843: current_SC->result = (current_SC->SCp.Status & 0xff)
844: | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16);
845: }
846:
847: rtrc(0);
848: current_SC->SCp.phase = idle;
849: current_SC->scsi_done( current_SC );
850: return;
851: }
852:
853: switch(status & 0x07){ /* scsi phase */
854: case 0x00: /* DATA-OUT */
855: if(int_reg & 0x10){ /* Target requesting info transfer */
856: rtrc(5);
857: current_SC->SCp.phase = data_out;
858: VDEB(printk("NCR53c406a: Data-Out phase\n"));
859: outb(FLUSH_FIFO, CMD_REG);
860: LOAD_DMA_COUNT(current_SC->request_bufflen); /* Max transfer size */
861: #if USE_DMA /* No s/g support for DMA */
862: NCR53c406a_dma_write(current_SC->request_buffer,
863: current_SC->request_bufflen);
864: #endif USE_DMA
865: outb(TRANSFER_INFO | DMA_OP, CMD_REG);
866: #if USE_PIO
867: if (!current_SC->use_sg) /* Don't use scatter-gather */
868: NCR53c406a_pio_write(current_SC->request_buffer,
869: current_SC->request_bufflen);
870: else { /* use scatter-gather */
871: sgcount = current_SC->use_sg;
872: sglist = current_SC->request_buffer;
873: while( sgcount-- ) {
874: NCR53c406a_pio_write(sglist->address, sglist->length);
875: sglist++;
876: }
877: }
878: REG0;
879: #endif USE_PIO
880: }
881: break;
882:
883: case 0x01: /* DATA-IN */
884: if(int_reg & 0x10){ /* Target requesting info transfer */
885: rtrc(6);
886: current_SC->SCp.phase = data_in;
887: VDEB(printk("NCR53c406a: Data-In phase\n"));
888: outb(FLUSH_FIFO, CMD_REG);
889: LOAD_DMA_COUNT(current_SC->request_bufflen); /* Max transfer size */
890: #if USE_DMA /* No s/g support for DMA */
891: NCR53c406a_dma_read(current_SC->request_buffer,
892: current_SC->request_bufflen);
893: #endif USE_DMA
894: outb(TRANSFER_INFO | DMA_OP, CMD_REG);
895: #if USE_PIO
896: if (!current_SC->use_sg) /* Don't use scatter-gather */
897: NCR53c406a_pio_read(current_SC->request_buffer,
898: current_SC->request_bufflen);
899: else { /* Use scatter-gather */
900: sgcount = current_SC->use_sg;
901: sglist = current_SC->request_buffer;
902: while( sgcount-- ) {
903: NCR53c406a_pio_read(sglist->address, sglist->length);
904: sglist++;
905: }
906: }
907: REG0;
908: #endif USE_PIO
909: }
910: break;
911:
912: case 0x02: /* COMMAND */
913: current_SC->SCp.phase = command_ph;
914: printk("NCR53c406a: Warning: Unknown interrupt occurred in command phase!\n");
915: break;
916:
917: case 0x03: /* STATUS */
918: rtrc(7);
919: current_SC->SCp.phase = status_ph;
920: VDEB(printk("NCR53c406a: Status phase\n"));
921: outb(FLUSH_FIFO, CMD_REG);
922: outb(INIT_CMD_COMPLETE, CMD_REG);
923: break;
924:
925: case 0x04: /* Reserved */
926: case 0x05: /* Reserved */
927: printk("NCR53c406a: WARNING: Reserved phase!!!\n");
928: break;
929:
930: case 0x06: /* MESSAGE-OUT */
931: DEB(printk("NCR53c406a: Message-Out phase\n"));
932: current_SC->SCp.phase = message_out;
933: outb(SET_ATN, CMD_REG); /* Reject the message */
934: outb(MSG_ACCEPT, CMD_REG);
935: break;
936:
937: case 0x07: /* MESSAGE-IN */
938: rtrc(4);
939: VDEB(printk("NCR53c406a: Message-In phase\n"));
940: current_SC->SCp.phase = message_in;
941:
942: current_SC->SCp.Status = inb(SCSI_FIFO);
943: current_SC->SCp.Message = inb(SCSI_FIFO);
944:
945: VDEB(printk("SCSI FIFO size=%d\n", inb(FIFO_FLAGS) & 0x1f));
946: DEB(printk("Status = %02x Message = %02x\n",
947: current_SC->SCp.Status, current_SC->SCp.Message));
948:
949: if(current_SC->SCp.Message == SAVE_POINTERS ||
950: current_SC->SCp.Message == DISCONNECT) {
951: outb(SET_ATN, CMD_REG); /* Reject message */
952: DEB(printk("Discarding SAVE_POINTERS message\n"));
953: }
954: outb(MSG_ACCEPT, CMD_REG);
955: break;
956: }
957: }
958:
959: #ifndef IRQ_LEV
960: static int irq_probe()
961: {
962: int irqs, irq;
963: int i;
964:
965: inb(INT_REG); /* clear the interrupt register */
966: sti();
967: irqs = probe_irq_on();
968:
969: /* Invalid command will cause an interrupt */
970: REG0;
971: outb(0xff, CMD_REG);
972:
973: /* Wait for the interrupt to occur */
974: i = jiffies + WATCHDOG;
975: while(i > jiffies && !(inb(STAT_REG) & 0x80))
976: barrier();
977: if (i <= jiffies) { /* Timed out, must be hardware trouble */
978: probe_irq_off(irqs);
979: return -1;
980: }
981:
982: irq = probe_irq_off(irqs);
983:
984: /* Kick the chip */
985: outb(CHIP_RESET, CMD_REG);
986: outb(SCSI_NOP, CMD_REG);
987: chip_init();
988:
989: return irq;
990: }
991: #endif IRQ_LEV
992:
993: static void chip_init()
994: {
995: REG1;
996: #if USE_DMA
997: outb(0x00, PIO_STATUS);
998: #else /* USE_PIO */
999: outb(0x01, PIO_STATUS);
1000: #endif
1001: outb(0x00, PIO_FLAG);
1002:
1003: outb(C4_IMG, CONFIG4); /* REG0; */
1004: outb(C3_IMG, CONFIG3);
1005: outb(C2_IMG, CONFIG2);
1006: outb(C1_IMG, CONFIG1);
1007:
1008: outb(0x05, CLKCONV); /* clock conversion factor */
1009: outb(0x9C, SRTIMOUT); /* Selection timeout */
1010: outb(0x05, SYNCPRD); /* Synchronous transfer period */
1011: outb(SYNC_MODE, SYNCOFF); /* synchronous mode */
1012: }
1013:
1014: void calc_port_addr()
1015: {
1016: /* Control Register Set 0 */
1017: TC_LSB = (port_base+0x00);
1018: TC_MSB = (port_base+0x01);
1019: SCSI_FIFO = (port_base+0x02);
1020: CMD_REG = (port_base+0x03);
1021: STAT_REG = (port_base+0x04);
1022: DEST_ID = (port_base+0x04);
1023: INT_REG = (port_base+0x05);
1024: SRTIMOUT = (port_base+0x05);
1025: SEQ_REG = (port_base+0x06);
1026: SYNCPRD = (port_base+0x06);
1027: FIFO_FLAGS = (port_base+0x07);
1028: SYNCOFF = (port_base+0x07);
1029: CONFIG1 = (port_base+0x08);
1030: CLKCONV = (port_base+0x09);
1031: /* TESTREG = (port_base+0x0A); */
1032: CONFIG2 = (port_base+0x0B);
1033: CONFIG3 = (port_base+0x0C);
1034: CONFIG4 = (port_base+0x0D);
1035: TC_HIGH = (port_base+0x0E);
1036: /* FIFO_BOTTOM = (port_base+0x0F); */
1037:
1038: /* Control Register Set 1 */
1039: /* JUMPER_SENSE = (port_base+0x00);*/
1040: /* SRAM_PTR = (port_base+0x01);*/
1041: /* SRAM_DATA = (port_base+0x02);*/
1042: PIO_FIFO = (port_base+0x04);
1043: /* PIO_FIFO1 = (port_base+0x05);*/
1044: /* PIO_FIFO2 = (port_base+0x06);*/
1045: /* PIO_FIFO3 = (port_base+0x07);*/
1046: PIO_STATUS = (port_base+0x08);
1047: /* ATA_CMD = (port_base+0x09);*/
1048: /* ATA_ERR = (port_base+0x0A);*/
1049: PIO_FLAG = (port_base+0x0B);
1050: CONFIG5 = (port_base+0x0D);
1051: /* SIGNATURE = (port_base+0x0E);*/
1052: /* CONFIG6 = (port_base+0x0F);*/
1053: }
1054:
1055: #ifdef MODULE
1056: /* Eventually this will go into an include file, but this will be later */
1057: Scsi_Host_Template driver_template = NCR53c406a;
1058:
1059: #include "scsi_module.c"
1060: #endif
1061:
1062: /*
1063: * Overrides for Emacs so that we get a uniform tabbing style.
1064: * Emacs will notice this stuff at the end of the file and automatically
1065: * adjust the settings for this buffer only. This must remain at the end
1066: * of the file.
1067: * ---------------------------------------------------------------------------
1068: * Local variables:
1069: * c-indent-level: 4
1070: * c-brace-imaginary-offset: 0
1071: * c-brace-offset: -4
1072: * c-argdecl-indent: 4
1073: * c-label-offset: -4
1074: * c-continued-statement-offset: 4
1075: * c-continued-brace-offset: 0
1076: * indent-tabs-mode: nil
1077: * tab-width: 8
1078: * End:
1079: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.