2 /* #define PSEUDO_DMA */
5 * EcoSCSI Generic NCR5380 driver
7 * Copyright 1995, Russell King
11 * For more information, please consult
14 * SCSI Protocol Controller
17 * NCR Microelectronics
18 * 1635 Aeroplaza Drive
19 * Colorado Springs, CO 80916
24 #include <linux/module.h>
25 #include <linux/signal.h>
26 #include <linux/sched.h>
27 #include <linux/ioport.h>
28 #include <linux/delay.h>
29 #include <linux/init.h>
30 #include <linux/blkdev.h>
33 #include <asm/system.h>
36 #include <scsi/scsi_host.h>
38 #define NCR5380_implementation_fields int port, ctrl
39 #define NCR5380_local_declare() struct Scsi_Host *_instance
40 #define NCR5380_setup(instance) _instance = instance
42 #define NCR5380_read(reg) ecoscsi_read(_instance, reg)
43 #define NCR5380_write(reg, value) ecoscsi_write(_instance, reg, value)
45 #define NCR5380_intr ecoscsi_intr
46 #define NCR5380_queue_command ecoscsi_queue_command
47 #define NCR5380_proc_info ecoscsi_proc_info
49 #include "../NCR5380.h"
51 #define ECOSCSI_PUBLIC_RELEASE 1
53 static char ecoscsi_read(struct Scsi_Host
*instance
, int reg
)
55 int iobase
= instance
->io_port
;
56 outb(reg
| 8, iobase
);
57 return inb(iobase
+ 1);
60 static void ecoscsi_write(struct Scsi_Host
*instance
, int reg
, int value
)
62 int iobase
= instance
->io_port
;
63 outb(reg
| 8, iobase
);
64 outb(value
, iobase
+ 1);
68 * Function : ecoscsi_setup(char *str, int *ints)
70 * Purpose : LILO command line initialization of the overrides array,
72 * Inputs : str - unused, ints - array of integer parameters with ints[0]
73 * equal to the number of ints.
77 void ecoscsi_setup(char *str
, int *ints
)
81 const char * ecoscsi_info (struct Scsi_Host
*spnt
)
87 #define STAT(p) inw(p + 144)
89 static inline int NCR5380_pwrite(struct Scsi_Host
*host
, unsigned char *addr
,
92 int iobase
= host
->io_port
;
93 printk("writing %p len %d\n",addr
, len
);
99 while(((status
= STAT(iobase
)) & 0x100)==0);
103 static inline int NCR5380_pread(struct Scsi_Host
*host
, unsigned char *addr
,
106 int iobase
= host
->io_port
;
107 int iobase2
= host
->io_port
+ 0x100;
108 unsigned char *start
= addr
;
110 printk("reading %p len %d\n",addr
, len
);
111 outb(inb(iobase
+ 128), iobase
+ 135);
114 int status
,b
,i
, timeout
;
115 timeout
= 0x07FFFFFF;
116 while(((status
= STAT(iobase
)) & 0x100)==0)
119 if(status
& 0x200 || !timeout
)
121 printk("status = %p\n",status
);
122 outb(0, iobase
+ 135);
130 b
= inw(iobase
+ 136);
138 b
= inw(iobase
+ 136);
146 outb(0, iobase
+ 135);
147 printk("first bytes = %02X %02X %02X %20X %02X %02X %02X\n",*start
, start
[1], start
[2], start
[3], start
[4], start
[5], start
[6]);
153 #define BOARD_NORMAL 0
154 #define BOARD_NCR53C400 1
156 #include "../NCR5380.c"
158 static struct scsi_host_template ecoscsi_template
= {
159 .module
= THIS_MODULE
,
160 .name
= "Serial Port EcoSCSI NCR5380",
161 .proc_name
= "ecoscsi",
162 .info
= ecoscsi_info
,
163 .queuecommand
= ecoscsi_queue_command
,
164 .eh_abort_handler
= NCR5380_abort
,
165 .eh_bus_reset_handler
= NCR5380_bus_reset
,
168 .sg_tablesize
= SG_ALL
,
170 .use_clustering
= DISABLE_CLUSTERING
173 static struct Scsi_Host
*host
;
175 static int __init
ecoscsi_init(void)
178 host
= scsi_host_alloc(tpnt
, sizeof(struct NCR5380_hostdata
));
182 host
->io_port
= 0x80ce8000;
183 host
->n_io_port
= 144;
184 host
->irq
= IRQ_NONE
;
186 if (!(request_region(host
->io_port
, host
->n_io_port
, "ecoscsi")) )
187 goto unregister_scsi
;
189 ecoscsi_write(host
, MODE_REG
, 0x20); /* Is it really SCSI? */
190 if (ecoscsi_read(host
, MODE_REG
) != 0x20) /* Write to a reg. */
193 ecoscsi_write(host
, MODE_REG
, 0x00 ); /* it back. */
194 if (ecoscsi_read(host
, MODE_REG
) != 0x00)
197 NCR5380_init(host
, 0);
199 printk("scsi%d: at port 0x%08lx irqs disabled", host
->host_no
, host
->io_port
);
200 printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
201 host
->can_queue
, host
->cmd_per_lun
, ECOSCSI_PUBLIC_RELEASE
);
202 printk("\nscsi%d:", host
->host_no
);
203 NCR5380_print_options(host
);
206 scsi_add_host(host
, NULL
); /* XXX handle failure */
207 scsi_scan_host(host
);
211 release_region(host
->io_port
, host
->n_io_port
);
217 static void __exit
ecoscsi_exit(void)
219 scsi_remove_host(host
);
221 if (shpnt
->irq
!= IRQ_NONE
)
222 free_irq(shpnt
->irq
, NULL
);
225 release_region(shpnt
->io_port
, shpnt
->n_io_port
);
231 module_init(ecoscsi_init
);
232 module_exit(ecoscsi_exit
);
234 MODULE_AUTHOR("Russell King");
235 MODULE_DESCRIPTION("Econet-SCSI driver for Acorn machines");
236 MODULE_LICENSE("GPL");