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