4 #define UNSAFE /* Leave interrupts enabled during pseudo-dma I/O */
5 #define xNDEBUG (NDEBUG_INTR+NDEBUG_RESELECTION+\
6 NDEBUG_SELECTION+NDEBUG_ARBITRATION)
7 #define DMA_WORKS_RIGHT
10 * DTC 3180/3280 driver, by
11 * Ray Van Tassle rayvt@comm.mot.com
14 * Trantor T128/T128F/T228 driver by...
18 * (Unix and Linux consulting and custom programming)
22 * DISTRIBUTION RELEASE 1.
24 * For more information, please consult
27 * SCSI Protocol Controller
33 * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
34 * for commands that return with a CHECK CONDITION status.
36 * PSEUDO_DMA - enables PSEUDO-DMA hardware, should give a 3-4X performance
37 * increase compared to polled I/O.
39 * PARITY - enable parity checking. Not supported.
41 * UNSAFE - leave interrupts enabled during pseudo-DMA transfers.
42 * You probably want this.
44 * The card is detected and initialized in one of several ways :
45 * 1. Autoprobe (default) - since the board is memory mapped,
46 * a BIOS signature is scanned for to locate the registers.
47 * An interrupt is triggered to autoprobe for the interrupt
50 * 2. With command line overrides - dtc=address,irq may be
51 * used on the LILO command line to override the defaults.
55 /*----------------------------------------------------------------*/
56 /* the following will set the monitor border color (useful to find
57 where something crashed or gets stuck at */
68 #define rtrc(i) {inb(0x3da); outb(0x31, 0x3c0); outb((i), 0x3c0);}
74 #include <asm/system.h>
75 #include <linux/module.h>
76 #include <linux/signal.h>
77 #include <linux/sched.h>
78 #include <linux/blk.h>
85 #include "constants.h"
87 #include <linux/stat.h>
88 #include <linux/string.h>
89 #include <linux/init.h>
92 #define DTC_PUBLIC_RELEASE 2
94 /*#define DTCDEBUG 0x1*/
95 #define DTCDEBUG_INIT 0x1
96 #define DTCDEBUG_TRANSFER 0x2
99 * The DTC3180 & 3280 boards are memory mapped.
105 /* Offset from DTC_5380_OFFSET */
106 #define DTC_CONTROL_REG 0x100 /* rw */
107 #define D_CR_ACCESS 0x80 /* ro set=can access 3280 registers */
108 #define CSR_DIR_READ 0x40 /* rw direction, 1 = read 0 = write */
110 #define CSR_RESET 0x80 /* wo Resets 53c400 */
111 #define CSR_5380_REG 0x80 /* ro 5380 registers can be accessed */
112 #define CSR_TRANS_DIR 0x40 /* rw Data transfer direction */
113 #define CSR_SCSI_BUFF_INTR 0x20 /* rw Enable int on transfer ready */
114 #define CSR_5380_INTR 0x10 /* rw Enable 5380 interrupts */
115 #define CSR_SHARED_INTR 0x08 /* rw Interrupt sharing */
116 #define CSR_HOST_BUF_NOT_RDY 0x04 /* ro Host buffer not ready */
117 #define CSR_SCSI_BUF_RDY 0x02 /* ro SCSI buffer ready */
118 #define CSR_GATED_5380_IRQ 0x01 /* ro Last block xferred */
119 #define CSR_INT_BASE (CSR_SCSI_BUFF_INTR | CSR_5380_INTR)
122 #define DTC_BLK_CNT 0x101 /* rw
123 * # of 128-byte blocks to transfer */
126 #define D_CR_ACCESS 0x80 /* ro set=can access 3280 registers */
128 #define DTC_SWITCH_REG 0x3982 /* ro - DIP switches */
129 #define DTC_RESUME_XFER 0x3982 /* wo - resume data xfer
130 * after disconnect/reconnect */
132 #define DTC_5380_OFFSET 0x3880 /* 8 registers here, see NCR5380.h */
134 /*!!!! for dtc, it's a 128 byte buffer at 3900 !!! */
135 #define DTC_DATA_BUF 0x3900 /* rw 128 bytes long */
137 static struct override {
138 unsigned int address;
142 [] __initdata = OVERRIDE;
152 #define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
155 unsigned long address;
157 } bases[] __initdata = {
164 #define NO_BASES (sizeof (bases) / sizeof (struct base))
166 static const struct signature {
170 {"DATA TECHNOLOGY CORPORATION BIOS", 0x25},
173 #define NO_SIGNATURES (sizeof (signatures) / sizeof (struct signature))
176 * dtc_setup - option setup for dtc3x80
178 * LILO command line initialization of the overrides array,
181 static int __init dtc_setup(char *str)
183 static int commandline_current = 0;
187 get_options(str, sizeof(ints) / sizeof(int), ints);
190 printk(KERN_ERR "dtc_setup: usage dtc=address,irq\n");
191 else if (commandline_current < NO_OVERRIDES) {
192 overrides[commandline_current].address = ints[1];
193 overrides[commandline_current].irq = ints[2];
194 for (i = 0; i < NO_BASES; ++i)
195 if (bases[i].address == ints[1]) {
199 ++commandline_current;
204 __setup("dtc=", dtc_setup);
207 * dtc_detect - detect DTC 3x80 controllers
208 * @tpnt: controller template
210 * Detects and initializes DTC 3180/3280 controllers
211 * that were autoprobed, overridden on the LILO command line,
212 * or specified at compile time.
215 int __init dtc_detect(Scsi_Host_Template * tpnt)
217 static int current_override = 0, current_base = 0;
218 struct Scsi_Host *instance;
222 tpnt->proc_name = "dtc3x80";
223 tpnt->proc_info = &dtc_proc_info;
225 for (count = 0; current_override < NO_OVERRIDES; ++current_override)
229 if (overrides[current_override].address)
230 base = overrides[current_override].address;
233 for (; !base && (current_base < NO_BASES); ++current_base) {
234 for (sig = 0; sig < NO_SIGNATURES; ++sig)
236 if (!bases[current_base].noauto && isa_check_signature(bases[current_base].address + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) {
237 base = bases[current_base].address;
247 instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
248 if (instance == NULL)
251 instance->base = base;
253 NCR5380_init(instance, 0);
255 NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR); /* Enable int's */
256 if (overrides[current_override].irq != IRQ_AUTO)
257 instance->irq = overrides[current_override].irq;
259 instance->irq = NCR5380_probe_irq(instance, DTC_IRQS);
261 #ifndef DONT_USE_INTR
262 /* With interrupts enabled, it will sometimes hang when doing heavy
263 * reads. So better not enable them until I figure it out. */
264 if (instance->irq != IRQ_NONE)
265 if (request_irq(instance->irq, do_dtc_intr, SA_INTERRUPT, "dtc"))
267 printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
268 instance->irq = IRQ_NONE;
271 if (instance->irq == IRQ_NONE) {
272 printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
273 printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
276 if (instance->irq != IRQ_NONE)
277 printk(KERN_INFO "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
278 instance->irq = IRQ_NONE;
280 printk(KERN_INFO "scsi%d : at 0x%05X", instance->host_no, (int) instance->base);
281 if (instance->irq == IRQ_NONE)
282 printk(" interrupts disabled");
284 printk(" irq %d", instance->irq);
285 printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", CAN_QUEUE, CMD_PER_LUN, DTC_PUBLIC_RELEASE);
286 NCR5380_print_options(instance);
296 * dtc_biosparam - compute disk geometry
297 * @disk: disk to generate for
298 * @dev: major/minor of device
299 * @ip: returned geometry
301 * Generates a BIOS / DOS compatible H-C-S mapping for
302 * the specified device / size.
305 int dtc_biosparam(Disk * disk, kdev_t dev, int *ip)
307 int size = disk->capacity;
316 static int dtc_maxi = 0;
317 static int dtc_wmaxi = 0;
320 * NCR5380_pread - fast pseudo DMA read
321 * @instance: controller
322 * @dst: destination buffer
323 * @len: expected/max size
325 * Fast 5380 pseudo-dma read function, reads len bytes from the controller
326 * mmio area into dst.
329 static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
331 unsigned char *d = dst;
332 int i; /* For counting time spent in the poll-loop */
333 NCR5380_local_declare();
334 NCR5380_setup(instance);
337 NCR5380_read(RESET_PARITY_INTERRUPT_REG);
338 NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
339 if (instance->irq == IRQ_NONE)
340 NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ);
342 NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ | CSR_INT_BASE);
343 NCR5380_write(DTC_BLK_CNT, len >> 7); /* Block count */
347 while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
350 isa_memcpy_fromio(d, base + DTC_DATA_BUF, 128);
354 /*** with int's on, it sometimes hangs after here.
355 * Looks like something makes HBNR go away. */
358 while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
360 NCR5380_write(MODE_REG, 0); /* Clear the operating mode */
362 NCR5380_read(RESET_PARITY_INTERRUPT_REG);
369 * NCR5380_pwrite - fast pseudo DMA write
370 * @instance: controller
371 * @dst: destination buffer
372 * @len: expected/max size
374 * Fast 5380 pseudo-dma write function, writes len bytes to the
375 * controller mmio area from src.
378 static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
381 NCR5380_local_declare();
382 NCR5380_setup(instance);
384 NCR5380_read(RESET_PARITY_INTERRUPT_REG);
385 NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
386 /* set direction (write) */
387 if (instance->irq == IRQ_NONE)
388 NCR5380_write(DTC_CONTROL_REG, 0);
390 NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR);
391 NCR5380_write(DTC_BLK_CNT, len >> 7); /* Block count */
392 for (i = 0; len > 0; ++i) {
394 /* Poll until the host buffer can accept data. */
395 while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
398 isa_memcpy_toio(base + DTC_DATA_BUF, src, 128);
403 while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
406 /* Wait until the last byte has been sent to the disk */
407 while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
410 /* Check for parity error here. fixme. */
411 NCR5380_write(MODE_REG, 0); /* Clear the operating mode */
418 MODULE_LICENSE("GPL");
422 /* Eventually this will go into an include file, but this will be later */
423 static Scsi_Host_Template driver_template = DTC3x80;
424 #include "scsi_module.c"