Import 2.3.18pre1
[davej-history.git] / drivers / scsi / mca_53c9x.c
blob6639a3a0a4c16f5ec5c1a8a640758e69f72ee6bd
1 /* mca_53c9x.c: Driver for the SCSI adapter found on NCR 35xx
2 * (and maybe some other) Microchannel machines
4 * Code taken mostly from Cyberstorm SCSI drivers
5 * Copyright (C) 1996 Jesper Skov (jskov@cygnus.co.uk)
7 * Hacked to work with the NCR MCA stuff by Tymm Twillman (tymm@computer.org)
9 * The CyberStorm SCSI driver (and this driver) is based on David S. Miller's
10 * ESP driver * for the Sparc computers.
12 * Special thanks to Ken Stewart at Symbios (LSI) for helping with info on
13 * the 86C01. I was on the brink of going ga-ga...
15 * Also thanks to Jesper Skov for helping me with info on how the Amiga
16 * does things...
20 * This is currently only set up to use one 53c9x card at a time; it could be
21 * changed fairly easily to detect/use more than one, but I'm not too sure how
22 * many cards that use the 53c9x on MCA systems there are (if, in fact, there
23 * are cards that use them, other than the one built into some NCR systems)...
24 * If anyone requests this, I'll throw it in, otherwise it's not worth the
25 * effort.
29 * Info on the 86C01 MCA interface chip at the bottom, if you care enough to
30 * look.
33 #include <linux/kernel.h>
34 #include <linux/delay.h>
35 #include <linux/types.h>
36 #include <linux/string.h>
37 #include <linux/malloc.h>
38 #include <linux/blk.h>
39 #include <linux/proc_fs.h>
40 #include <linux/stat.h>
42 #include "scsi.h"
43 #include "hosts.h"
44 #include "NCR53C9x.h"
45 #include "mca_53c9x.h"
47 #include <asm/dma.h>
48 #include <linux/mca.h>
49 #include <asm/irq.h>
50 #include <asm/mca_dma.h>
52 #include <asm/pgtable.h>
54 static int dma_bytes_sent(struct NCR_ESP *, int);
55 static int dma_can_transfer(struct NCR_ESP *, Scsi_Cmnd *);
56 static void dma_dump_state(struct NCR_ESP *);
57 static void dma_init_read(struct NCR_ESP *, __u32, int);
58 static void dma_init_write(struct NCR_ESP *, __u32, int);
59 static void dma_ints_off(struct NCR_ESP *);
60 static void dma_ints_on(struct NCR_ESP *);
61 static int dma_irq_p(struct NCR_ESP *);
62 static int dma_ports_p(struct NCR_ESP *);
63 static void dma_setup(struct NCR_ESP *, __u32, int, int);
64 static void dma_led_on(struct NCR_ESP *);
65 static void dma_led_off(struct NCR_ESP *);
67 /* This is where all commands are put before they are trasfered to the
68 * 53c9x via PIO.
71 volatile unsigned char cmd_buffer[16];
74 * We keep the structure that is used to access the registers on the 53c9x
75 * here.
78 static struct ESP_regs eregs;
80 /***************************************************************** Detection */
81 int mca_esp_detect(Scsi_Host_Template *tpnt)
83 struct NCR_ESP *esp;
84 static int io_port_by_pos[] = MCA_53C9X_IO_PORTS;
85 int mca_53c9x_ids[] = MCA_53C9X_IDS;
86 int *id_to_check = mca_53c9x_ids;
87 int slot;
88 int pos[3];
89 unsigned int tmp_io_addr;
90 unsigned char tmp_byte;
93 if (!MCA_bus)
94 return 0;
96 while (*id_to_check) {
97 if ((slot = mca_find_adapter(*id_to_check, 0)) !=
98 MCA_NOTFOUND)
100 esp = esp_allocate(tpnt, (void *) NULL);
102 pos[0] = mca_read_stored_pos(slot, 2);
103 pos[1] = mca_read_stored_pos(slot, 3);
104 pos[2] = mca_read_stored_pos(slot, 4);
106 esp->eregs = &eregs;
109 * IO port base is given in the first (non-ID) pos
110 * register, like so:
112 * Bits 3 2 1 IO base
113 * ----------------------------
114 * 0 0 0 <disabled>
115 * 0 0 1 0x0240
116 * 0 1 0 0x0340
117 * 0 1 1 0x0400
118 * 1 0 0 0x0420
119 * 1 0 1 0x3240
120 * 1 1 0 0x8240
121 * 1 1 1 0xA240
124 tmp_io_addr =
125 io_port_by_pos[(pos[0] & 0x0E) >> 1];
127 esp->eregs->io_addr = tmp_io_addr + 0x10;
129 if (esp->eregs->io_addr == 0x0000) {
130 printk("Adapter is disabled.\n");
131 break;
135 * IRQ is specified in bits 4 and 5:
137 * Bits 4 5 IRQ
138 * -----------------------
139 * 0 0 3
140 * 0 1 5
141 * 1 0 7
142 * 1 1 9
145 esp->irq = ((pos[0] & 0x30) >> 3) + 3;
148 * DMA channel is in the low 3 bits of the second
149 * POS register
152 esp->dma = pos[1] & 7;
153 esp->slot = slot;
155 if (request_irq(esp->irq, esp_intr, 0,
156 "NCR 53c9x SCSI", esp_intr))
158 printk("Unable to request IRQ %d.\n", esp->irq);
159 esp_deallocate(esp);
160 scsi_unregister(esp->ehost);
161 return 0;
164 if (request_dma(esp->dma, "NCR 53c9x SCSI")) {
165 printk("Unable to request DMA channel %d.\n",
166 esp->dma);
167 free_irq(esp->irq, esp_intr);
168 esp_deallocate(esp);
169 scsi_unregister(esp->ehost);
170 return 0;
173 request_region(tmp_io_addr, 32, "NCR 53c9x SCSI");
176 * 86C01 handles DMA, IO mode, from address
177 * (base + 0x0a)
180 mca_disable_dma(esp->dma);
181 mca_set_dma_io(esp->dma, tmp_io_addr + 0x0a);
182 mca_enable_dma(esp->dma);
184 /* Tell the 86C01 to give us interrupts */
186 tmp_byte = inb(tmp_io_addr + 0x02) | 0x40;
187 outb(tmp_byte, tmp_io_addr + 0x02);
190 * Scsi ID -- general purpose register, hi
191 * 2 bits; add 4 to this number to get the
192 * ID
195 esp->scsi_id = ((pos[2] & 0xC0) >> 6) + 4;
197 /* Do command transfer with programmed I/O */
199 esp->do_pio_cmds = 1;
201 /* Required functions */
203 esp->dma_bytes_sent = &dma_bytes_sent;
204 esp->dma_can_transfer = &dma_can_transfer;
205 esp->dma_dump_state = &dma_dump_state;
206 esp->dma_init_read = &dma_init_read;
207 esp->dma_init_write = &dma_init_write;
208 esp->dma_ints_off = &dma_ints_off;
209 esp->dma_ints_on = &dma_ints_on;
210 esp->dma_irq_p = &dma_irq_p;
211 esp->dma_ports_p = &dma_ports_p;
212 esp->dma_setup = &dma_setup;
214 /* Optional functions */
216 esp->dma_barrier = 0;
217 esp->dma_drain = 0;
218 esp->dma_invalidate = 0;
219 esp->dma_irq_entry = 0;
220 esp->dma_irq_exit = 0;
221 esp->dma_led_on = dma_led_on;
222 esp->dma_led_off = dma_led_off;
223 esp->dma_poll = 0;
224 esp->dma_reset = 0;
226 /* Set the command buffer */
228 esp->esp_command = (volatile unsigned char*)
229 cmd_buffer;
230 esp->esp_command_dvma = virt_to_bus(cmd_buffer);
232 /* SCSI chip speed */
234 esp->cfreq = 25000000;
236 /* Differential SCSI? I think not. */
238 esp->diff = 0;
240 esp_initialize(esp);
242 printk(" Adapter found in slot %2d: io port 0x%x "
243 "irq %d dma channel %d\n", slot + 1, tmp_io_addr,
244 esp->irq, esp->dma);
246 mca_set_adapter_name(slot, "NCR 53C9X SCSI Adapter");
247 mca_mark_as_used(slot);
249 break;
252 id_to_check++;
255 return esps_in_use;
259 /******************************************************************* Release */
261 int mca_esp_release(struct Scsi_Host *host)
263 struct NCR_ESP *esp = (struct NCR_ESP *)host->hostdata;
264 unsigned char tmp_byte;
266 esp_deallocate(esp);
268 * Tell the 86C01 to stop sending interrupts
271 tmp_byte = inb(esp->eregs->io_addr - 0x0E);
272 tmp_byte &= ~0x40;
273 outb(tmp_byte, esp->eregs->io_addr - 0x0E);
275 free_irq(esp->irq, esp_intr);
276 free_dma(esp->dma);
278 mca_mark_as_unused(esp->slot);
280 return 0;
283 /************************************************************* DMA Functions */
284 static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
286 /* Ask the 53c9x. It knows. */
288 return fifo_count;
291 static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp)
294 * The MCA dma channels can only do up to 128K bytes at a time.
295 * (16 bit mode)
298 unsigned long sz = sp->SCp.this_residual;
299 if(sz > 0x20000)
300 sz = 0x20000;
301 return sz;
304 static void dma_dump_state(struct NCR_ESP *esp)
307 * Doesn't quite match up to the other drivers, but we do what we
308 * can.
311 ESPLOG(("esp%d: dma channel <%d>\n", esp->esp_id, esp->dma));
312 ESPLOG(("bytes left to dma: %d\n", mca_get_dma_residue(esp->dma)));
315 static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length)
317 unsigned long flags;
320 save_flags(flags);
321 cli();
323 mca_disable_dma(esp->dma);
324 mca_set_dma_mode(esp->dma, MCA_DMA_MODE_XFER | MCA_DMA_MODE_16 |
325 MCA_DMA_MODE_IO);
326 mca_set_dma_addr(esp->dma, addr);
327 mca_set_dma_count(esp->dma, length / 2); /* !!! */
328 mca_enable_dma(esp->dma);
330 restore_flags(flags);
333 static void dma_init_write(struct NCR_ESP *esp, __u32 addr, int length)
335 unsigned long flags;
338 save_flags(flags);
339 cli();
341 mca_disable_dma(esp->dma);
342 mca_set_dma_mode(esp->dma, MCA_DMA_MODE_XFER | MCA_DMA_MODE_WRITE |
343 MCA_DMA_MODE_16 | MCA_DMA_MODE_IO);
344 mca_set_dma_addr(esp->dma, addr);
345 mca_set_dma_count(esp->dma, length / 2); /* !!! */
346 mca_enable_dma(esp->dma);
348 restore_flags(flags);
351 static void dma_ints_off(struct NCR_ESP *esp)
354 * Tell the 'C01 to shut up. All interrupts are routed through it.
357 outb(inb(esp->eregs->io_addr - 0x0E) & ~0x40,
358 esp->eregs->io_addr - 0x0E);
361 static void dma_ints_on(struct NCR_ESP *esp)
364 * Ok. You can speak again.
367 outb(inb(esp->eregs->io_addr - 0x0E) | 0x40,
368 esp->eregs->io_addr - 0x0E);
371 static int dma_irq_p(struct NCR_ESP *esp)
374 * DaveM says that this should return a "yes" if there is an interrupt
375 * or a DMA error occurred. I copied the Amiga driver's semantics,
376 * though, because it seems to work and we can't really tell if
377 * a DMA error happened. This gives the "yes" if the scsi chip
378 * is sending an interrupt and no DMA activity is taking place
381 return (!(inb(esp->eregs->io_addr - 0x04) & 1) &&
382 !(inb(esp->eregs->io_addr - 0x04) & 2) );
385 static int dma_ports_p(struct NCR_ESP *esp)
388 * Check to see if interrupts are enabled on the 'C01 (in case abort
389 * is entered multiple times, so we only do the abort once)
392 return (inb(esp->eregs->io_addr - 0x0E) & 0x40) ? 1:0;
395 static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
397 if(write){
398 dma_init_write(esp, addr, count);
399 } else {
400 dma_init_read(esp, addr, count);
405 * These will not play nicely with other disk controllers that try to use the
406 * disk active LED... but what can you do? Don't answer that.
408 * Stolen shamelessly from ibmmca.c -- IBM Microchannel SCSI adapter driver
412 static void dma_led_on(struct NCR_ESP *esp)
414 outb(inb(PS2_SYS_CTR) | 0xc0, PS2_SYS_CTR);
417 static void dma_led_off(struct NCR_ESP *esp)
419 outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR);
422 #ifdef MODULE
423 Scsi_Host_Template driver_template = MCA_53C9X;
424 #include "scsi_module.c"
425 #endif
428 * OK, here's the goods I promised. The NCR 86C01 is an MCA interface chip
429 * that handles enabling/diabling IRQ, dma interfacing, IO port selection
430 * and other fun stuff. It takes up 16 addresses, and the chip it is
431 * connnected to gets the following 16. Registers are as follows:
433 * Offsets 0-1 : Card ID
435 * Offset 2 : Mode enable register --
436 * Bit 7 : Data Word width (1 = 16, 0 = 8)
437 * Bit 6 : IRQ enable (1 = enabled)
438 * Bits 5,4 : IRQ select
439 * 0 0 : IRQ 3
440 * 0 1 : IRQ 5
441 * 1 0 : IRQ 7
442 * 1 1 : IRQ 9
443 * Bits 3-1 : Base Address
444 * 0 0 0 : <disabled>
445 * 0 0 1 : 0x0240
446 * 0 1 0 : 0x0340
447 * 0 1 1 : 0x0400
448 * 1 0 0 : 0x0420
449 * 1 0 1 : 0x3240
450 * 1 1 0 : 0x8240
451 * 1 1 1 : 0xA240
452 * Bit 0 : Card enable (1 = enabled)
454 * Offset 3 : DMA control register --
455 * Bit 7 : DMA enable (1 = enabled)
456 * Bits 6,5 : Preemt Count Select (transfers to complete after
457 * 'C01 has been preempted on MCA bus)
458 * 0 0 : 0
459 * 0 1 : 1
460 * 1 0 : 3
461 * 1 1 : 7
462 * (all these wacky numbers; I'm sure there's a reason somewhere)
463 * Bit 4 : Fairness enable (1 = fair bus priority)
464 * Bits 3-0 : Arbitration level (0-15 consecutive)
466 * Offset 4 : General purpose register
467 * Bits 7-3 : User definable (here, 7,6 are SCSI ID)
468 * Bits 2-0 : reserved
470 * Offset 10 : DMA decode register (used for IO based DMA; also can do
471 * PIO through this port)
473 * Offset 12 : Status
474 * Bits 7-2 : reserved
475 * Bit 1 : DMA pending (1 = pending)
476 * Bit 0 : IRQ pending (0 = pending)
478 * Exciting, huh?