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/ioport.h>
27 #include <linux/delay.h>
28 #include <linux/init.h>
29 #include <linux/blkdev.h>
32 #include <asm/system.h>
35 #include <scsi/scsi_host.h>
37 #define NCR5380_implementation_fields int port, ctrl
38 #define NCR5380_local_declare() struct Scsi_Host *_instance
39 #define NCR5380_setup(instance) _instance = instance
41 #define NCR5380_read(reg) ecoscsi_read(_instance, reg)
42 #define NCR5380_write(reg, value) ecoscsi_write(_instance, reg, value)
44 #define NCR5380_intr ecoscsi_intr
45 #define NCR5380_queue_command ecoscsi_queue_command
46 #define NCR5380_proc_info ecoscsi_proc_info
48 #include "../NCR5380.h"
50 #define ECOSCSI_PUBLIC_RELEASE 1
52 static char ecoscsi_read(struct Scsi_Host
*instance
, int reg
)
54 int iobase
= instance
->io_port
;
55 outb(reg
| 8, iobase
);
56 return inb(iobase
+ 1);
59 static void ecoscsi_write(struct Scsi_Host
*instance
, int reg
, int value
)
61 int iobase
= instance
->io_port
;
62 outb(reg
| 8, iobase
);
63 outb(value
, iobase
+ 1);
67 * Function : ecoscsi_setup(char *str, int *ints)
69 * Purpose : LILO command line initialization of the overrides array,
71 * Inputs : str - unused, ints - array of integer parameters with ints[0]
72 * equal to the number of ints.
76 void ecoscsi_setup(char *str
, int *ints
)
80 const char * ecoscsi_info (struct Scsi_Host
*spnt
)
86 #define STAT(p) inw(p + 144)
88 static inline int NCR5380_pwrite(struct Scsi_Host
*host
, unsigned char *addr
,
91 int iobase
= host
->io_port
;
92 printk("writing %p len %d\n",addr
, len
);
98 while(((status
= STAT(iobase
)) & 0x100)==0);
102 static inline int NCR5380_pread(struct Scsi_Host
*host
, unsigned char *addr
,
105 int iobase
= host
->io_port
;
106 int iobase2
= host
->io_port
+ 0x100;
107 unsigned char *start
= addr
;
109 printk("reading %p len %d\n",addr
, len
);
110 outb(inb(iobase
+ 128), iobase
+ 135);
113 int status
,b
,i
, timeout
;
114 timeout
= 0x07FFFFFF;
115 while(((status
= STAT(iobase
)) & 0x100)==0)
118 if(status
& 0x200 || !timeout
)
120 printk("status = %p\n",status
);
121 outb(0, iobase
+ 135);
129 b
= inw(iobase
+ 136);
137 b
= inw(iobase
+ 136);
145 outb(0, iobase
+ 135);
146 printk("first bytes = %02X %02X %02X %20X %02X %02X %02X\n",*start
, start
[1], start
[2], start
[3], start
[4], start
[5], start
[6]);
152 #define BOARD_NORMAL 0
153 #define BOARD_NCR53C400 1
155 #include "../NCR5380.c"
157 static struct scsi_host_template ecoscsi_template
= {
158 .module
= THIS_MODULE
,
159 .name
= "Serial Port EcoSCSI NCR5380",
160 .proc_name
= "ecoscsi",
161 .info
= ecoscsi_info
,
162 .queuecommand
= ecoscsi_queue_command
,
163 .eh_abort_handler
= NCR5380_abort
,
164 .eh_bus_reset_handler
= NCR5380_bus_reset
,
167 .sg_tablesize
= SG_ALL
,
169 .use_clustering
= DISABLE_CLUSTERING
172 static struct Scsi_Host
*host
;
174 static int __init
ecoscsi_init(void)
177 host
= scsi_host_alloc(tpnt
, sizeof(struct NCR5380_hostdata
));
181 host
->io_port
= 0x80ce8000;
182 host
->n_io_port
= 144;
183 host
->irq
= IRQ_NONE
;
185 if (!(request_region(host
->io_port
, host
->n_io_port
, "ecoscsi")) )
186 goto unregister_scsi
;
188 ecoscsi_write(host
, MODE_REG
, 0x20); /* Is it really SCSI? */
189 if (ecoscsi_read(host
, MODE_REG
) != 0x20) /* Write to a reg. */
192 ecoscsi_write(host
, MODE_REG
, 0x00 ); /* it back. */
193 if (ecoscsi_read(host
, MODE_REG
) != 0x00)
196 NCR5380_init(host
, 0);
198 printk("scsi%d: at port 0x%08lx irqs disabled", host
->host_no
, host
->io_port
);
199 printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
200 host
->can_queue
, host
->cmd_per_lun
, ECOSCSI_PUBLIC_RELEASE
);
201 printk("\nscsi%d:", host
->host_no
);
202 NCR5380_print_options(host
);
205 scsi_add_host(host
, NULL
); /* XXX handle failure */
206 scsi_scan_host(host
);
210 release_region(host
->io_port
, host
->n_io_port
);
216 static void __exit
ecoscsi_exit(void)
218 scsi_remove_host(host
);
220 if (shpnt
->irq
!= IRQ_NONE
)
221 free_irq(shpnt
->irq
, NULL
);
224 release_region(shpnt
->io_port
, shpnt
->n_io_port
);
230 module_init(ecoscsi_init
);
231 module_exit(ecoscsi_exit
);
233 MODULE_AUTHOR("Russell King");
234 MODULE_DESCRIPTION("Econet-SCSI driver for Acorn machines");
235 MODULE_LICENSE("GPL");