22 #define NCR53C406A_DEBUG 0
23 #define VERBOSE_NCR53C406A_DEBUG 0
36 #define USE_FAST_PIO 1
40 #include <linux/module.h>
42 #include <linux/errno.h>
46 #include <linux/stat.h>
48 #include <linux/bitops.h>
60 #define WATCHDOG 5000000
65 #undef NCR53C406A_DEBUG
66 #define NCR53C406A_DEBUG 1
86 #define REG0 (outb(C4_IMG, CONFIG4))
87 #define REG1 (outb(C5_IMG, CONFIG5))
95 #if VERBOSE_NCR53C406A_DEBUG
101 #define LOAD_DMA_COUNT(count) \
102 outb(count & 0xff, TC_LSB); \
103 outb((count >> 8) & 0xff, TC_MSB); \
104 outb((count >> 16) & 0xff, TC_HIGH);
109 #define SCSI_NOP 0x00
110 #define FLUSH_FIFO 0x01
111 #define CHIP_RESET 0x02
112 #define SCSI_RESET 0x03
113 #define RESELECT 0x40
114 #define SELECT_NO_ATN 0x41
115 #define SELECT_ATN 0x42
116 #define SELECT_ATN_STOP 0x43
117 #define ENABLE_SEL 0x44
118 #define DISABLE_SEL 0x45
119 #define SELECT_ATN3 0x46
120 #define RESELECT3 0x47
121 #define TRANSFER_INFO 0x10
122 #define INIT_CMD_COMPLETE 0x11
123 #define MSG_ACCEPT 0x12
124 #define TRANSFER_PAD 0x18
126 #define RESET_ATN 0x1b
127 #define SEND_MSG 0x20
128 #define SEND_STATUS 0x21
129 #define SEND_DATA 0x22
130 #define DISCONN_SEQ 0x23
131 #define TERMINATE_SEQ 0x24
132 #define TARG_CMD_COMPLETE 0x25
134 #define RECV_MSG 0x28
135 #define RECV_CMD 0x29
136 #define RECV_DATA 0x2a
137 #define RECV_CMD_SEQ 0x2b
138 #define TARGET_ABORT_DMA 0x04
153 #define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);}
170 static void NCR53c406a_intr(
void *);
171 static irqreturn_t do_NCR53c406a_intr(
int,
void *);
172 static void chip_init(
void);
173 static void calc_port_addr(
void);
175 static int irq_probe(
void);
181 static void *bios_base;
187 static int port_base;
191 static int irq_level = IRQ_LEV;
193 static int irq_level = -1;
205 static char info_msg[256];
211 static void *addresses[] = {
215 #define ADDRESS_COUNT ARRAY_SIZE(addresses)
219 static unsigned short ports[] = { 0x230, 0x330, 0x280, 0x290, 0x330, 0x340, 0x300, 0x310, 0x348, 0x350 };
220 #define PORT_COUNT ARRAY_SIZE(ports)
224 static unsigned short intrs[] = { 10, 11, 12, 15 };
225 #define INTR_COUNT ARRAY_SIZE(intrs)
238 "Copyright (C) Acculogic, Inc.\r\n2.8M Diskette Extension Bios ver 4.04.03 03/01/1993", 61, 82},};
240 #define SIGNATURE_COUNT ARRAY_SIZE(signatures)
289 unsigned long flags = 0;
295 limit = 65536 - (((unsigned) ptr) & 0xFFFF);
297 if (count > (65536 << 1))
298 count = (65536 << 1);
299 limit = (65536 << 1) - (((
unsigned)
ptr) & 0x1FFFF);
306 if ((count & 1) || (((
unsigned) ptr) & 1))
307 panic(
"NCR53c406a: attempted unaligned DMA transfer\n");
321 static __inline__ int NCR53c406a_dma_write(
unsigned char *
src,
unsigned int count)
326 static __inline__ int NCR53c406a_dma_read(
unsigned char *
src,
unsigned int count)
331 static __inline__ int NCR53c406a_dma_residual(
void)
346 static __inline__ int NCR53c406a_pio_read(
unsigned char *
request,
unsigned int reqlen)
377 if ((i & 0x40) && len == 0) {
385 if (fast_pio && len > 3) {
386 insl(PIO_FIFO, request, len >> 2);
387 request += len & 0xfc;
388 reqlen -= len & 0xfc;
391 *request++ =
inb(PIO_FIFO);
400 static __inline__ int NCR53c406a_pio_write(
unsigned char *request,
unsigned int reqlen)
406 while (reqlen && !(i & 0x40)) {
435 if (fast_pio && len > 3) {
436 outsl(PIO_FIFO, request, len >> 2);
437 request += len & 0xfc;
438 reqlen -= len & 0xfc;
441 outb(*request++, PIO_FIFO);
465 if (!
memcmp((
void *) addresses[ii] + signatures[jj].sig_offset, (
void *) signatures[jj].
signature, (
int) signatures[jj].sig_length))
466 bios_base = addresses[ii];
469 printk(
"NCR53c406a: BIOS signature not found\n");
473 DEB(
printk(
"NCR53c406a BIOS found at 0x%x\n", (
unsigned int) bios_base);
486 for (i = 0; i <
PORT_COUNT && !port_base; i++) {
488 DEB(
printk(
"NCR53c406a: port 0x%x in use\n", ports[i]));
490 VDEB(
printk(
"NCR53c406a: port 0x%x available\n", ports[i]));
492 if ((
inb(ports[i] + 0x0e) ^
inb(ports[i] + 0x0e)) == 7 && (
inb(ports[i] + 0x0e) ^
inb(ports[i] + 0x0e)) == 7 && (
inb(ports[i] + 0x0e) & 0xf8) == 0x58) {
493 port_base = ports[
i];
494 VDEB(
printk(
"NCR53c406a: Sig register valid\n"));
505 printk(
"NCR53c406a: no available ports found\n");
516 irq_level = irq_probe();
518 printk(
"NCR53c406a: IRQ problem, irq_level=%d, giving up\n", irq_level);
524 DEB(
printk(
"NCR53c406a: using port_base 0x%x\n", port_base));
531 printk(
"NCR53c406a: Unable to register host, giving up.\n");
536 if (
request_irq(irq_level, do_NCR53c406a_intr, 0,
"NCR53c406a", shpnt)) {
537 printk(
"NCR53c406a: unable to allocate IRQ %d\n", irq_level);
541 DEB(
printk(
"NCR53c406a: allocated IRQ %d\n", irq_level));
542 }
else if (irq_level == 0) {
544 DEB(
printk(
"NCR53c406a: No interrupts detected\n"));
545 printk(
"NCR53c406a driver no longer supports polling interface\n");
549 printk(
"NCR53c406a: No interrupts found and DMA mode defined. Giving up.\n");
553 DEB(
printk(
"NCR53c406a: Shouldn't get here!\n"));
560 printk(
"NCR53c406a: unable to allocate DMA channel %d\n",
dma_chan);
567 shpnt->
irq = irq_level;
575 sprintf(info_msg,
"NCR53c406a at 0x%x, IRQ %d, DMA channel %d.", port_base, irq_level,
dma_chan);
577 sprintf(info_msg,
"NCR53c406a at 0x%x, IRQ %d, %s PIO mode.", port_base, irq_level, fast_pio ?
"fast" :
"slow");
611 static int __init NCR53c406a_setup(
char *
str)
613 static size_t setup_idx = 0;
617 DEB(
printk(
"NCR53c406a: Setup called\n");
621 printk(
"NCR53c406a: Setup called too many times. Bad LILO params?\n");
625 if (ints[0] < 1 || ints[0] > 3) {
626 printk(
"NCR53c406a: Malformed command line\n");
627 printk(
"NCR53c406a: Usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]]\n");
630 for (i = 0; i <
PORT_COUNT && !port_base; i++)
631 if (ports[i] == ints[1]) {
633 DEB(
printk(
"NCR53c406a: Specified port_base 0x%x\n", port_base);
637 printk(
"NCR53c406a: Invalid PORTBASE 0x%x specified\n", ints[1]);
644 DEB(
printk(
"NCR53c406a: Specified irq %d\n", irq_level);
647 for (i = 0; i <
INTR_COUNT && irq_level < 0; i++)
648 if (intrs[i] == ints[2]) {
650 DEB(
printk(
"NCR53c406a: Specified irq %d\n", port_base);
654 printk("NCR53c406a: Invalid
IRQ %
d specified\
n", ints[2]);
660 DEB(
printk("NCR53c406a: port_base=0
x%
x,
irq=%
d, fast_pio=%d\n", port_base, irq_level, fast_pio);)
664 __setup("ncr53c406a=", NCR53c406a_setup);
668 static const char *NCR53c406a_info(
struct Scsi_Host *SChost)
675 static void wait_intr(
void)
692 NCR53c406a_intr(
NULL);
701 DEB(
printk(
"cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n", SCpnt->
cmnd[0], SCpnt->
cmd_len, SCpnt->target, SCpnt->lun, scsi_bufflen(SCpnt)));
712 current_SC->
SCp.Status = 0;
713 current_SC->
SCp.Message = 0;
720 for (i = 0; i < SCpnt->
cmd_len; i++) {
731 static
int NCR53c406a_host_reset(
Scsi_Cmnd * SCpnt)
733 DEB(
printk(
"NCR53c406a_reset called\n"));
735 spin_lock_irq(SCpnt->device->host->host_lock);
745 spin_unlock_irq(SCpnt->device->host->host_lock);
750 static int NCR53c406a_biosparm(
struct scsi_device *disk,
756 DEB(
printk(
"NCR53c406a_biosparm called\n"));
761 info_array[2] = size >> 11;
762 if (info_array[2] > 1024) {
765 info_array[2] = size / (255 * 63);
776 NCR53c406a_intr(dev_id);
777 spin_unlock_irqrestore(dev->
host_lock, flags);
781 static void NCR53c406a_intr(
void *
dev_id)
785 DEB(
unsigned char seq_reg;
787 unsigned char status, int_reg;
789 unsigned char pio_status;
798 pio_status =
inb(PIO_STATUS);
801 status =
inb(STAT_REG);
802 DEB(seq_reg =
inb(SEQ_REG));
803 int_reg =
inb(INT_REG);
807 printk(
"status=%02x, seq_reg=%02x, int_reg=%02x, fifo_size=%02x", status, seq_reg, int_reg,
fifo_size);
811 printk(
", pio=%02x\n", pio_status);
815 if (int_reg & 0x80) {
817 DEB(
printk(
"NCR53c406a: reset intr received\n"));
824 if (pio_status & 0x80) {
825 printk(
"NCR53C406A: Warning: PIO error!\n");
834 printk(
"NCR53c406a: Warning: parity error!\n");
842 printk(
"NCR53c406a: Warning: gross error!\n");
849 if (int_reg & 0x20) {
850 DEB(
printk(
"NCR53c406a: disconnect intr received\n"));
854 current_SC->
result = (current_SC->
SCp.Status & 0xff)
855 | ((current_SC->
SCp.Message & 0xff) << 8) | (
DID_OK << 16);
864 switch (status & 0x07) {
866 if (int_reg & 0x10) {
873 NCR53c406a_dma_write(scsi_sglist(current_SC),
874 scsdi_bufflen(current_SC));
880 NCR53c406a_pio_write(sg_virt(sg), sg->
length);
888 if (int_reg & 0x10) {
895 NCR53c406a_dma_read(scsi_sglist(current_SC),
896 scsdi_bufflen(current_SC));
901 NCR53c406a_pio_read(sg_virt(sg), sg->
length);
910 printk(
"NCR53c406a: Warning: Unknown interrupt occurred in command phase!\n");
923 printk(
"NCR53c406a: WARNING: Reserved phase!!!\n");
927 DEB(
printk(
"NCR53c406a: Message-Out phase\n"));
935 VDEB(
printk(
"NCR53c406a: Message-In phase\n"));
938 current_SC->
SCp.Status =
inb(SCSI_FIFO);
939 current_SC->
SCp.Message =
inb(SCSI_FIFO);
942 DEB(
printk(
"Status = %02x Message = %02x\n", current_SC->
SCp.Status, current_SC->
SCp.Message));
946 DEB(
printk(
"Discarding SAVE_POINTERS message\n"));
954 static int irq_probe(
void)
986 static void chip_init(
void)
990 outb(0x00, PIO_STATUS);
992 outb(0x01, PIO_STATUS);
994 outb(0x00, PIO_FLAG);
1001 outb(0x05, CLKCONV);
1002 outb(0x9C, SRTIMOUT);
1003 outb(0x05, SYNCPRD);
1007 static void __init calc_port_addr(
void)
1010 TC_LSB = (port_base + 0x00);
1011 TC_MSB = (port_base + 0x01);
1012 SCSI_FIFO = (port_base + 0x02);
1013 CMD_REG = (port_base + 0x03);
1014 STAT_REG = (port_base + 0x04);
1015 DEST_ID = (port_base + 0x04);
1016 INT_REG = (port_base + 0x05);
1017 SRTIMOUT = (port_base + 0x05);
1018 SEQ_REG = (port_base + 0x06);
1019 SYNCPRD = (port_base + 0x06);
1020 FIFO_FLAGS = (port_base + 0x07);
1021 SYNCOFF = (port_base + 0x07);
1022 CONFIG1 = (port_base + 0x08);
1023 CLKCONV = (port_base + 0x09);
1025 CONFIG2 = (port_base + 0x0B);
1026 CONFIG3 = (port_base + 0x0C);
1027 CONFIG4 = (port_base + 0x0D);
1028 TC_HIGH = (port_base + 0x0E);
1035 PIO_FIFO = (port_base + 0x04);
1039 PIO_STATUS = (port_base + 0x08);
1042 PIO_FLAG = (port_base + 0x0B);
1043 CONFIG5 = (port_base + 0x0D);
1056 .proc_name =
"NCR53c406a" ,
1057 .name =
"NCR53c406a" ,
1058 .detect = NCR53c406a_detect ,
1059 .release = NCR53c406a_release,
1060 .info = NCR53c406a_info ,
1061 .queuecommand = NCR53c406a_queue ,
1062 .eh_host_reset_handler = NCR53c406a_host_reset ,
1063 .bios_param = NCR53c406a_biosparm ,
1066 .sg_tablesize = 32 ,
1068 .unchecked_isa_dma = 1 ,