GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / scsi / dtc.c
blob7ddfdc6c138b9855ebc60ee4f5cb6847b3f94d79
2 #define AUTOSENSE
3 #define PSEUDO_DMA
4 #define DONT_USE_INTR
5 #define UNSAFE /* Leave interrupts enabled during pseudo-dma I/O */
6 #define xNDEBUG (NDEBUG_INTR+NDEBUG_RESELECTION+\
7 NDEBUG_SELECTION+NDEBUG_ARBITRATION)
8 #define DMA_WORKS_RIGHT
12 * DTC 3180/3280 driver, by
13 * Ray Van Tassle rayvt@comm.mot.com
15 * taken from ...
16 * Trantor T128/T128F/T228 driver by...
18 * Drew Eckhardt
19 * Visionary Computing
20 * (Unix and Linux consulting and custom programming)
21 * drew@colorado.edu
22 * +1 (303) 440-4894
24 * DISTRIBUTION RELEASE 1.
26 * For more information, please consult
28 * NCR 5380 Family
29 * SCSI Protocol Controller
30 * Databook
34 * Options :
35 * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
36 * for commands that return with a CHECK CONDITION status.
38 * PSEUDO_DMA - enables PSEUDO-DMA hardware, should give a 3-4X performance
39 * increase compared to polled I/O.
41 * PARITY - enable parity checking. Not supported.
43 * UNSAFE - leave interrupts enabled during pseudo-DMA transfers.
44 * You probably want this.
46 * The card is detected and initialized in one of several ways :
47 * 1. Autoprobe (default) - since the board is memory mapped,
48 * a BIOS signature is scanned for to locate the registers.
49 * An interrupt is triggered to autoprobe for the interrupt
50 * line.
52 * 2. With command line overrides - dtc=address,irq may be
53 * used on the LILO command line to override the defaults.
57 /*----------------------------------------------------------------*/
58 /* the following will set the monitor border color (useful to find
59 where something crashed or gets stuck at */
60 /* 1 = blue
61 2 = green
62 3 = cyan
63 4 = red
64 5 = magenta
65 6 = yellow
66 7 = white
68 #define rtrc(i) {}
71 #include <asm/system.h>
72 #include <linux/module.h>
73 #include <linux/signal.h>
74 #include <linux/blkdev.h>
75 #include <linux/delay.h>
76 #include <linux/stat.h>
77 #include <linux/string.h>
78 #include <linux/init.h>
79 #include <linux/interrupt.h>
80 #include <linux/io.h>
81 #include "scsi.h"
82 #include <scsi/scsi_host.h>
83 #include "dtc.h"
84 #define AUTOPROBE_IRQ
85 #include "NCR5380.h"
88 #define DTC_PUBLIC_RELEASE 2
91 * The DTC3180 & 3280 boards are memory mapped.
97 /* Offset from DTC_5380_OFFSET */
98 #define DTC_CONTROL_REG 0x100 /* rw */
99 #define D_CR_ACCESS 0x80 /* ro set=can access 3280 registers */
100 #define CSR_DIR_READ 0x40 /* rw direction, 1 = read 0 = write */
102 #define CSR_RESET 0x80 /* wo Resets 53c400 */
103 #define CSR_5380_REG 0x80 /* ro 5380 registers can be accessed */
104 #define CSR_TRANS_DIR 0x40 /* rw Data transfer direction */
105 #define CSR_SCSI_BUFF_INTR 0x20 /* rw Enable int on transfer ready */
106 #define CSR_5380_INTR 0x10 /* rw Enable 5380 interrupts */
107 #define CSR_SHARED_INTR 0x08 /* rw Interrupt sharing */
108 #define CSR_HOST_BUF_NOT_RDY 0x04 /* ro Host buffer not ready */
109 #define CSR_SCSI_BUF_RDY 0x02 /* ro SCSI buffer ready */
110 #define CSR_GATED_5380_IRQ 0x01 /* ro Last block xferred */
111 #define CSR_INT_BASE (CSR_SCSI_BUFF_INTR | CSR_5380_INTR)
114 #define DTC_BLK_CNT 0x101 /* rw
115 * # of 128-byte blocks to transfer */
118 #define D_CR_ACCESS 0x80 /* ro set=can access 3280 registers */
120 #define DTC_SWITCH_REG 0x3982 /* ro - DIP switches */
121 #define DTC_RESUME_XFER 0x3982 /* wo - resume data xfer
122 * after disconnect/reconnect*/
124 #define DTC_5380_OFFSET 0x3880 /* 8 registers here, see NCR5380.h */
126 /*!!!! for dtc, it's a 128 byte buffer at 3900 !!! */
127 #define DTC_DATA_BUF 0x3900 /* rw 128 bytes long */
129 static struct override {
130 unsigned int address;
131 int irq;
132 } overrides
133 #ifdef OVERRIDE
134 [] __initdata = OVERRIDE;
135 #else
136 [4] __initdata = {
137 { 0, IRQ_AUTO }, { 0, IRQ_AUTO }, { 0, IRQ_AUTO }, { 0, IRQ_AUTO }
139 #endif
141 #define NO_OVERRIDES ARRAY_SIZE(overrides)
143 static struct base {
144 unsigned long address;
145 int noauto;
146 } bases[] __initdata = {
147 { 0xcc000, 0 },
148 { 0xc8000, 0 },
149 { 0xdc000, 0 },
150 { 0xd8000, 0 }
153 #define NO_BASES ARRAY_SIZE(bases)
155 static const struct signature {
156 const char *string;
157 int offset;
158 } signatures[] = {
159 {"DATA TECHNOLOGY CORPORATION BIOS", 0x25},
162 #define NO_SIGNATURES ARRAY_SIZE(signatures)
164 #ifndef MODULE
166 * Function : dtc_setup(char *str, int *ints)
168 * Purpose : LILO command line initialization of the overrides array,
170 * Inputs : str - unused, ints - array of integer parameters with ints[0]
171 * equal to the number of ints.
175 static void __init dtc_setup(char *str, int *ints)
177 static int commandline_current = 0;
178 int i;
179 if (ints[0] != 2)
180 printk("dtc_setup: usage dtc=address,irq\n");
181 else if (commandline_current < NO_OVERRIDES) {
182 overrides[commandline_current].address = ints[1];
183 overrides[commandline_current].irq = ints[2];
184 for (i = 0; i < NO_BASES; ++i)
185 if (bases[i].address == ints[1]) {
186 bases[i].noauto = 1;
187 break;
189 ++commandline_current;
192 #endif
195 * Function : int dtc_detect(struct scsi_host_template * tpnt)
197 * Purpose : detects and initializes DTC 3180/3280 controllers
198 * that were autoprobed, overridden on the LILO command line,
199 * or specified at compile time.
201 * Inputs : tpnt - template for this SCSI adapter.
203 * Returns : 1 if a host adapter was found, 0 if not.
207 static int __init dtc_detect(struct scsi_host_template * tpnt)
209 static int current_override = 0, current_base = 0;
210 struct Scsi_Host *instance;
211 unsigned int addr;
212 void __iomem *base;
213 int sig, count;
215 tpnt->proc_name = "dtc3x80";
216 tpnt->proc_info = &dtc_proc_info;
218 for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
219 addr = 0;
220 base = NULL;
222 if (overrides[current_override].address) {
223 addr = overrides[current_override].address;
224 base = ioremap(addr, 0x2000);
225 if (!base)
226 addr = 0;
227 } else
228 for (; !addr && (current_base < NO_BASES); ++current_base) {
229 #if (DTCDEBUG & DTCDEBUG_INIT)
230 printk(KERN_DEBUG "scsi-dtc : probing address %08x\n", bases[current_base].address);
231 #endif
232 if (bases[current_base].noauto)
233 continue;
234 base = ioremap(bases[current_base].address, 0x2000);
235 if (!base)
236 continue;
237 for (sig = 0; sig < NO_SIGNATURES; ++sig) {
238 if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) {
239 addr = bases[current_base].address;
240 #if (DTCDEBUG & DTCDEBUG_INIT)
241 printk(KERN_DEBUG "scsi-dtc : detected board.\n");
242 #endif
243 goto found;
246 iounmap(base);
249 #if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
250 printk(KERN_DEBUG "scsi-dtc : base = %08x\n", addr);
251 #endif
253 if (!addr)
254 break;
256 found:
257 instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
258 if (instance == NULL)
259 break;
261 instance->base = addr;
262 ((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
264 NCR5380_init(instance, 0);
266 NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR); /* Enable int's */
267 if (overrides[current_override].irq != IRQ_AUTO)
268 instance->irq = overrides[current_override].irq;
269 else
270 instance->irq = NCR5380_probe_irq(instance, DTC_IRQS);
272 #ifndef DONT_USE_INTR
273 /* With interrupts enabled, it will sometimes hang when doing heavy
274 * reads. So better not enable them until I finger it out. */
275 if (instance->irq != SCSI_IRQ_NONE)
276 if (request_irq(instance->irq, dtc_intr, IRQF_DISABLED,
277 "dtc", instance)) {
278 printk(KERN_ERR "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
279 instance->irq = SCSI_IRQ_NONE;
282 if (instance->irq == SCSI_IRQ_NONE) {
283 printk(KERN_WARNING "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
284 printk(KERN_WARNING "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
286 #else
287 if (instance->irq != SCSI_IRQ_NONE)
288 printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
289 instance->irq = SCSI_IRQ_NONE;
290 #endif
291 #if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
292 printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
293 #endif
295 printk(KERN_INFO "scsi%d : at 0x%05X", instance->host_no, (int) instance->base);
296 if (instance->irq == SCSI_IRQ_NONE)
297 printk(" interrupts disabled");
298 else
299 printk(" irq %d", instance->irq);
300 printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", CAN_QUEUE, CMD_PER_LUN, DTC_PUBLIC_RELEASE);
301 NCR5380_print_options(instance);
302 printk("\n");
304 ++current_override;
305 ++count;
307 return count;
311 * Function : int dtc_biosparam(Disk * disk, struct block_device *dev, int *ip)
313 * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for
314 * the specified device / size.
316 * Inputs : size = size of device in sectors (512 bytes), dev = block device
317 * major / minor, ip[] = {heads, sectors, cylinders}
319 * Returns : always 0 (success), initializes ip
324 static int dtc_biosparam(struct scsi_device *sdev, struct block_device *dev,
325 sector_t capacity, int *ip)
327 int size = capacity;
329 ip[0] = 64;
330 ip[1] = 32;
331 ip[2] = size >> 11;
332 return 0;
336 /****************************************************************
337 * Function : int NCR5380_pread (struct Scsi_Host *instance,
338 * unsigned char *dst, int len)
340 * Purpose : Fast 5380 pseudo-dma read function, reads len bytes to
341 * dst
343 * Inputs : dst = destination, len = length in bytes
345 * Returns : 0 on success, non zero on a failure such as a watchdog
346 * timeout.
349 static int dtc_maxi = 0;
350 static int dtc_wmaxi = 0;
352 static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
354 unsigned char *d = dst;
355 int i; /* For counting time spent in the poll-loop */
356 NCR5380_local_declare();
357 NCR5380_setup(instance);
359 i = 0;
360 NCR5380_read(RESET_PARITY_INTERRUPT_REG);
361 NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
362 if (instance->irq == SCSI_IRQ_NONE)
363 NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ);
364 else
365 NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ | CSR_INT_BASE);
366 NCR5380_write(DTC_BLK_CNT, len >> 7); /* Block count */
367 rtrc(1);
368 while (len > 0) {
369 rtrc(2);
370 while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
371 ++i;
372 rtrc(3);
373 memcpy_fromio(d, base + DTC_DATA_BUF, 128);
374 d += 128;
375 len -= 128;
376 rtrc(7);
377 /*** with int's on, it sometimes hangs after here.
378 * Looks like something makes HBNR go away. */
380 rtrc(4);
381 while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
382 ++i;
383 NCR5380_write(MODE_REG, 0); /* Clear the operating mode */
384 rtrc(0);
385 NCR5380_read(RESET_PARITY_INTERRUPT_REG);
386 if (i > dtc_maxi)
387 dtc_maxi = i;
388 return (0);
391 /****************************************************************
392 * Function : int NCR5380_pwrite (struct Scsi_Host *instance,
393 * unsigned char *src, int len)
395 * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from
396 * src
398 * Inputs : src = source, len = length in bytes
400 * Returns : 0 on success, non zero on a failure such as a watchdog
401 * timeout.
404 static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
406 int i;
407 NCR5380_local_declare();
408 NCR5380_setup(instance);
410 NCR5380_read(RESET_PARITY_INTERRUPT_REG);
411 NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
412 /* set direction (write) */
413 if (instance->irq == SCSI_IRQ_NONE)
414 NCR5380_write(DTC_CONTROL_REG, 0);
415 else
416 NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR);
417 NCR5380_write(DTC_BLK_CNT, len >> 7); /* Block count */
418 for (i = 0; len > 0; ++i) {
419 rtrc(5);
420 /* Poll until the host buffer can accept data. */
421 while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
422 ++i;
423 rtrc(3);
424 memcpy_toio(base + DTC_DATA_BUF, src, 128);
425 src += 128;
426 len -= 128;
428 rtrc(4);
429 while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
430 ++i;
431 rtrc(6);
432 /* Wait until the last byte has been sent to the disk */
433 while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
434 ++i;
435 rtrc(7);
436 NCR5380_write(MODE_REG, 0); /* Clear the operating mode */
437 rtrc(0);
438 if (i > dtc_wmaxi)
439 dtc_wmaxi = i;
440 return (0);
443 MODULE_LICENSE("GPL");
445 #include "NCR5380.c"
447 static int dtc_release(struct Scsi_Host *shost)
449 NCR5380_local_declare();
450 NCR5380_setup(shost);
451 if (shost->irq)
452 free_irq(shost->irq, shost);
453 NCR5380_exit(shost);
454 if (shost->io_port && shost->n_io_port)
455 release_region(shost->io_port, shost->n_io_port);
456 scsi_unregister(shost);
457 iounmap(base);
458 return 0;
461 static struct scsi_host_template driver_template = {
462 .name = "DTC 3180/3280 ",
463 .detect = dtc_detect,
464 .release = dtc_release,
465 .queuecommand = dtc_queue_command,
466 .eh_abort_handler = dtc_abort,
467 .eh_bus_reset_handler = dtc_bus_reset,
468 .bios_param = dtc_biosparam,
469 .can_queue = CAN_QUEUE,
470 .this_id = 7,
471 .sg_tablesize = SG_ALL,
472 .cmd_per_lun = CMD_PER_LUN,
473 .use_clustering = DISABLE_CLUSTERING,
475 #include "scsi_module.c"