aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/Kconfig11
-rw-r--r--drivers/scsi/Makefile1
-rw-r--r--drivers/scsi/mca_53c9x.c520
3 files changed, 0 insertions, 532 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index fa86f340cbb3..21675ae83901 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1263,17 +1263,6 @@ config SCSI_NCR53C8XX_NO_DISCONNECT
1263 not allow targets to disconnect is not reasonable if there is more 1263 not allow targets to disconnect is not reasonable if there is more
1264 than 1 device on a SCSI bus. The normal answer therefore is N. 1264 than 1 device on a SCSI bus. The normal answer therefore is N.
1265 1265
1266config SCSI_MCA_53C9X
1267 tristate "NCR MCA 53C9x SCSI support"
1268 depends on MCA_LEGACY && SCSI && BROKEN_ON_SMP
1269 help
1270 Some MicroChannel machines, notably the NCR 35xx line, use a SCSI
1271 controller based on the NCR 53C94. This driver will allow use of
1272 the controller on the 3550, and very possibly others.
1273
1274 To compile this driver as a module, choose M here: the
1275 module will be called mca_53c9x.
1276
1277config SCSI_PAS16 1266config SCSI_PAS16
1278 tristate "PAS16 SCSI support" 1267 tristate "PAS16 SCSI support"
1279 depends on ISA && SCSI 1268 depends on ISA && SCSI
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 999327dbbede..9c9fa7f5c98a 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -95,7 +95,6 @@ obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/
95obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o 95obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o
96obj-$(CONFIG_SCSI_EATA_PIO) += eata_pio.o 96obj-$(CONFIG_SCSI_EATA_PIO) += eata_pio.o
97obj-$(CONFIG_SCSI_7000FASST) += wd7000.o 97obj-$(CONFIG_SCSI_7000FASST) += wd7000.o
98obj-$(CONFIG_SCSI_MCA_53C9X) += NCR53C9x.o mca_53c9x.o
99obj-$(CONFIG_SCSI_IBMMCA) += ibmmca.o 98obj-$(CONFIG_SCSI_IBMMCA) += ibmmca.o
100obj-$(CONFIG_SCSI_EATA) += eata.o 99obj-$(CONFIG_SCSI_EATA) += eata.o
101obj-$(CONFIG_SCSI_DC395x) += dc395x.o 100obj-$(CONFIG_SCSI_DC395x) += dc395x.o
diff --git a/drivers/scsi/mca_53c9x.c b/drivers/scsi/mca_53c9x.c
deleted file mode 100644
index d693d0f21395..000000000000
--- a/drivers/scsi/mca_53c9x.c
+++ /dev/null
@@ -1,520 +0,0 @@
1/* mca_53c9x.c: Driver for the SCSI adapter found on NCR 35xx
2 * (and maybe some other) Microchannel machines
3 *
4 * Code taken mostly from Cyberstorm SCSI drivers
5 * Copyright (C) 1996 Jesper Skov (jskov@cygnus.co.uk)
6 *
7 * Hacked to work with the NCR MCA stuff by Tymm Twillman (tymm@computer.org)
8 *
9 * The CyberStorm SCSI driver (and this driver) is based on David S. Miller's
10 * ESP driver * for the Sparc computers.
11 *
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...
14 *
15 * Also thanks to Jesper Skov for helping me with info on how the Amiga
16 * does things...
17 */
18
19/*
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.
26 */
27
28/*
29 * Info on the 86C01 MCA interface chip at the bottom, if you care enough to
30 * look.
31 */
32
33#include <linux/delay.h>
34#include <linux/interrupt.h>
35#include <linux/kernel.h>
36#include <linux/mca.h>
37#include <linux/types.h>
38#include <linux/string.h>
39#include <linux/slab.h>
40#include <linux/blkdev.h>
41#include <linux/proc_fs.h>
42#include <linux/stat.h>
43#include <linux/mca-legacy.h>
44
45#include "scsi.h"
46#include <scsi/scsi_host.h>
47#include "NCR53C9x.h"
48
49#include <asm/dma.h>
50#include <asm/irq.h>
51#include <asm/mca_dma.h>
52#include <asm/pgtable.h>
53
54/*
55 * From ibmmca.c (IBM scsi controller card driver) -- used for turning PS2 disk
56 * activity LED on and off
57 */
58
59#define PS2_SYS_CTR 0x92
60
61/* Ports the ncr's 53c94 can be put at; indexed by pos register value */
62
63#define MCA_53C9X_IO_PORTS { \
64 0x0000, 0x0240, 0x0340, 0x0400, \
65 0x0420, 0x3240, 0x8240, 0xA240, \
66 }
67
68/*
69 * Supposedly there were some cards put together with the 'c9x and 86c01. If
70 * they have different ID's from the ones on the 3500 series machines,
71 * you can add them here and hopefully things will work out.
72 */
73
74#define MCA_53C9X_IDS { \
75 0x7F4C, \
76 0x0000, \
77 }
78
79static int dma_bytes_sent(struct NCR_ESP *, int);
80static int dma_can_transfer(struct NCR_ESP *, Scsi_Cmnd *);
81static void dma_dump_state(struct NCR_ESP *);
82static void dma_init_read(struct NCR_ESP *, __u32, int);
83static void dma_init_write(struct NCR_ESP *, __u32, int);
84static void dma_ints_off(struct NCR_ESP *);
85static void dma_ints_on(struct NCR_ESP *);
86static int dma_irq_p(struct NCR_ESP *);
87static int dma_ports_p(struct NCR_ESP *);
88static void dma_setup(struct NCR_ESP *, __u32, int, int);
89static void dma_led_on(struct NCR_ESP *);
90static void dma_led_off(struct NCR_ESP *);
91
92/* This is where all commands are put before they are trasfered to the
93 * 53c9x via PIO.
94 */
95
96static volatile unsigned char cmd_buffer[16];
97
98/*
99 * We keep the structure that is used to access the registers on the 53c9x
100 * here.
101 */
102
103static struct ESP_regs eregs;
104
105/***************************************************************** Detection */
106static int mca_esp_detect(struct scsi_host_template *tpnt)
107{
108 struct NCR_ESP *esp;
109 static int io_port_by_pos[] = MCA_53C9X_IO_PORTS;
110 int mca_53c9x_ids[] = MCA_53C9X_IDS;
111 int *id_to_check = mca_53c9x_ids;
112 int slot;
113 int pos[3];
114 unsigned int tmp_io_addr;
115 unsigned char tmp_byte;
116
117
118 if (!MCA_bus)
119 return 0;
120
121 while (*id_to_check) {
122 if ((slot = mca_find_adapter(*id_to_check, 0)) !=
123 MCA_NOTFOUND)
124 {
125 esp = esp_allocate(tpnt, NULL, 0);
126
127 pos[0] = mca_read_stored_pos(slot, 2);
128 pos[1] = mca_read_stored_pos(slot, 3);
129 pos[2] = mca_read_stored_pos(slot, 4);
130
131 esp->eregs = &eregs;
132
133 /*
134 * IO port base is given in the first (non-ID) pos
135 * register, like so:
136 *
137 * Bits 3 2 1 IO base
138 * ----------------------------
139 * 0 0 0 <disabled>
140 * 0 0 1 0x0240
141 * 0 1 0 0x0340
142 * 0 1 1 0x0400
143 * 1 0 0 0x0420
144 * 1 0 1 0x3240
145 * 1 1 0 0x8240
146 * 1 1 1 0xA240
147 */
148
149 tmp_io_addr =
150 io_port_by_pos[(pos[0] & 0x0E) >> 1];
151
152 esp->eregs->io_addr = tmp_io_addr + 0x10;
153
154 if (esp->eregs->io_addr == 0x0000) {
155 printk("Adapter is disabled.\n");
156 break;
157 }
158
159 /*
160 * IRQ is specified in bits 4 and 5:
161 *
162 * Bits 4 5 IRQ
163 * -----------------------
164 * 0 0 3
165 * 0 1 5
166 * 1 0 7
167 * 1 1 9
168 */
169
170 esp->irq = ((pos[0] & 0x30) >> 3) + 3;
171
172 /*
173 * DMA channel is in the low 3 bits of the second
174 * POS register
175 */
176
177 esp->dma = pos[1] & 7;
178 esp->slot = slot;
179
180 if (request_irq(esp->irq, esp_intr, 0,
181 "NCR 53c9x SCSI", esp->ehost))
182 {
183 printk("Unable to request IRQ %d.\n", esp->irq);
184 esp_deallocate(esp);
185 scsi_unregister(esp->ehost);
186 return 0;
187 }
188
189 if (request_dma(esp->dma, "NCR 53c9x SCSI")) {
190 printk("Unable to request DMA channel %d.\n",
191 esp->dma);
192 free_irq(esp->irq, esp_intr);
193 esp_deallocate(esp);
194 scsi_unregister(esp->ehost);
195 return 0;
196 }
197
198 request_region(tmp_io_addr, 32, "NCR 53c9x SCSI");
199
200 /*
201 * 86C01 handles DMA, IO mode, from address
202 * (base + 0x0a)
203 */
204
205 mca_disable_dma(esp->dma);
206 mca_set_dma_io(esp->dma, tmp_io_addr + 0x0a);
207 mca_enable_dma(esp->dma);
208
209 /* Tell the 86C01 to give us interrupts */
210
211 tmp_byte = inb(tmp_io_addr + 0x02) | 0x40;
212 outb(tmp_byte, tmp_io_addr + 0x02);
213
214 /*
215 * Scsi ID -- general purpose register, hi
216 * 2 bits; add 4 to this number to get the
217 * ID
218 */
219
220 esp->scsi_id = ((pos[2] & 0xC0) >> 6) + 4;
221
222 /* Do command transfer with programmed I/O */
223
224 esp->do_pio_cmds = 1;
225
226 /* Required functions */
227
228 esp->dma_bytes_sent = &dma_bytes_sent;
229 esp->dma_can_transfer = &dma_can_transfer;
230 esp->dma_dump_state = &dma_dump_state;
231 esp->dma_init_read = &dma_init_read;
232 esp->dma_init_write = &dma_init_write;
233 esp->dma_ints_off = &dma_ints_off;
234 esp->dma_ints_on = &dma_ints_on;
235 esp->dma_irq_p = &dma_irq_p;
236 esp->dma_ports_p = &dma_ports_p;
237 esp->dma_setup = &dma_setup;
238
239 /* Optional functions */
240
241 esp->dma_barrier = NULL;
242 esp->dma_drain = NULL;
243 esp->dma_invalidate = NULL;
244 esp->dma_irq_entry = NULL;
245 esp->dma_irq_exit = NULL;
246 esp->dma_led_on = dma_led_on;
247 esp->dma_led_off = dma_led_off;
248 esp->dma_poll = NULL;
249 esp->dma_reset = NULL;
250
251 /* Set the command buffer */
252
253 esp->esp_command = (volatile unsigned char*)
254 cmd_buffer;
255 esp->esp_command_dvma = isa_virt_to_bus(cmd_buffer);
256
257 /* SCSI chip speed */
258
259 esp->cfreq = 25000000;
260
261 /* Differential SCSI? I think not. */
262
263 esp->diff = 0;
264
265 esp_initialize(esp);
266
267 printk(" Adapter found in slot %2d: io port 0x%x "
268 "irq %d dma channel %d\n", slot + 1, tmp_io_addr,
269 esp->irq, esp->dma);
270
271 mca_set_adapter_name(slot, "NCR 53C9X SCSI Adapter");
272 mca_mark_as_used(slot);
273
274 break;
275 }
276
277 id_to_check++;
278 }
279
280 return esps_in_use;
281}
282
283
284/******************************************************************* Release */
285
286static int mca_esp_release(struct Scsi_Host *host)
287{
288 struct NCR_ESP *esp = (struct NCR_ESP *)host->hostdata;
289 unsigned char tmp_byte;
290
291 esp_deallocate(esp);
292 /*
293 * Tell the 86C01 to stop sending interrupts
294 */
295
296 tmp_byte = inb(esp->eregs->io_addr - 0x0E);
297 tmp_byte &= ~0x40;
298 outb(tmp_byte, esp->eregs->io_addr - 0x0E);
299
300 free_irq(esp->irq, esp_intr);
301 free_dma(esp->dma);
302
303 mca_mark_as_unused(esp->slot);
304
305 return 0;
306}
307
308/************************************************************* DMA Functions */
309static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
310{
311 /* Ask the 53c9x. It knows. */
312
313 return fifo_count;
314}
315
316static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp)
317{
318 /*
319 * The MCA dma channels can only do up to 128K bytes at a time.
320 * (16 bit mode)
321 */
322
323 unsigned long sz = sp->SCp.this_residual;
324 if(sz > 0x20000)
325 sz = 0x20000;
326 return sz;
327}
328
329static void dma_dump_state(struct NCR_ESP *esp)
330{
331 /*
332 * Doesn't quite match up to the other drivers, but we do what we
333 * can.
334 */
335
336 ESPLOG(("esp%d: dma channel <%d>\n", esp->esp_id, esp->dma));
337 ESPLOG(("bytes left to dma: %d\n", mca_get_dma_residue(esp->dma)));
338}
339
340static void dma_init_read(struct NCR_ESP *esp, __u32 addr, int length)
341{
342 unsigned long flags;
343
344
345 save_flags(flags);
346 cli();
347
348 mca_disable_dma(esp->dma);
349 mca_set_dma_mode(esp->dma, MCA_DMA_MODE_XFER | MCA_DMA_MODE_16 |
350 MCA_DMA_MODE_IO);
351 mca_set_dma_addr(esp->dma, addr);
352 mca_set_dma_count(esp->dma, length / 2); /* !!! */
353 mca_enable_dma(esp->dma);
354
355 restore_flags(flags);
356}
357
358static void dma_init_write(struct NCR_ESP *esp, __u32 addr, int length)
359{
360 unsigned long flags;
361
362
363 save_flags(flags);
364 cli();
365
366 mca_disable_dma(esp->dma);
367 mca_set_dma_mode(esp->dma, MCA_DMA_MODE_XFER | MCA_DMA_MODE_WRITE |
368 MCA_DMA_MODE_16 | MCA_DMA_MODE_IO);
369 mca_set_dma_addr(esp->dma, addr);
370 mca_set_dma_count(esp->dma, length / 2); /* !!! */
371 mca_enable_dma(esp->dma);
372
373 restore_flags(flags);
374}
375
376static void dma_ints_off(struct NCR_ESP *esp)
377{
378 /*
379 * Tell the 'C01 to shut up. All interrupts are routed through it.
380 */
381
382 outb(inb(esp->eregs->io_addr - 0x0E) & ~0x40,
383 esp->eregs->io_addr - 0x0E);
384}
385
386static void dma_ints_on(struct NCR_ESP *esp)
387{
388 /*
389 * Ok. You can speak again.
390 */
391
392 outb(inb(esp->eregs->io_addr - 0x0E) | 0x40,
393 esp->eregs->io_addr - 0x0E);
394}
395
396static int dma_irq_p(struct NCR_ESP *esp)
397{
398 /*
399 * DaveM says that this should return a "yes" if there is an interrupt
400 * or a DMA error occurred. I copied the Amiga driver's semantics,
401 * though, because it seems to work and we can't really tell if
402 * a DMA error happened. This gives the "yes" if the scsi chip
403 * is sending an interrupt and no DMA activity is taking place
404 */
405
406 return (!(inb(esp->eregs->io_addr - 0x04) & 1) &&
407 !(inb(esp->eregs->io_addr - 0x04) & 2) );
408}
409
410static int dma_ports_p(struct NCR_ESP *esp)
411{
412 /*
413 * Check to see if interrupts are enabled on the 'C01 (in case abort
414 * is entered multiple times, so we only do the abort once)
415 */
416
417 return (inb(esp->eregs->io_addr - 0x0E) & 0x40) ? 1:0;
418}
419
420static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write)
421{
422 if(write){
423 dma_init_write(esp, addr, count);
424 } else {
425 dma_init_read(esp, addr, count);
426 }
427}
428
429/*
430 * These will not play nicely with other disk controllers that try to use the
431 * disk active LED... but what can you do? Don't answer that.
432 *
433 * Stolen shamelessly from ibmmca.c -- IBM Microchannel SCSI adapter driver
434 *
435 */
436
437static void dma_led_on(struct NCR_ESP *esp)
438{
439 outb(inb(PS2_SYS_CTR) | 0xc0, PS2_SYS_CTR);
440}
441
442static void dma_led_off(struct NCR_ESP *esp)
443{
444 outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR);
445}
446
447static struct scsi_host_template driver_template = {
448 .proc_name = "mca_53c9x",
449 .name = "NCR 53c9x SCSI",
450 .detect = mca_esp_detect,
451 .slave_alloc = esp_slave_alloc,
452 .slave_destroy = esp_slave_destroy,
453 .release = mca_esp_release,
454 .queuecommand = esp_queue,
455 .eh_abort_handler = esp_abort,
456 .eh_bus_reset_handler = esp_reset,
457 .can_queue = 7,
458 .sg_tablesize = SG_ALL,
459 .cmd_per_lun = 1,
460 .unchecked_isa_dma = 1,
461 .use_clustering = DISABLE_CLUSTERING
462};
463
464
465#include "scsi_module.c"
466
467/*
468 * OK, here's the goods I promised. The NCR 86C01 is an MCA interface chip
469 * that handles enabling/diabling IRQ, dma interfacing, IO port selection
470 * and other fun stuff. It takes up 16 addresses, and the chip it is
471 * connnected to gets the following 16. Registers are as follows:
472 *
473 * Offsets 0-1 : Card ID
474 *
475 * Offset 2 : Mode enable register --
476 * Bit 7 : Data Word width (1 = 16, 0 = 8)
477 * Bit 6 : IRQ enable (1 = enabled)
478 * Bits 5,4 : IRQ select
479 * 0 0 : IRQ 3
480 * 0 1 : IRQ 5
481 * 1 0 : IRQ 7
482 * 1 1 : IRQ 9
483 * Bits 3-1 : Base Address
484 * 0 0 0 : <disabled>
485 * 0 0 1 : 0x0240
486 * 0 1 0 : 0x0340
487 * 0 1 1 : 0x0400
488 * 1 0 0 : 0x0420
489 * 1 0 1 : 0x3240
490 * 1 1 0 : 0x8240
491 * 1 1 1 : 0xA240
492 * Bit 0 : Card enable (1 = enabled)
493 *
494 * Offset 3 : DMA control register --
495 * Bit 7 : DMA enable (1 = enabled)
496 * Bits 6,5 : Preemt Count Select (transfers to complete after
497 * 'C01 has been preempted on MCA bus)
498 * 0 0 : 0
499 * 0 1 : 1
500 * 1 0 : 3
501 * 1 1 : 7
502 * (all these wacky numbers; I'm sure there's a reason somewhere)
503 * Bit 4 : Fairness enable (1 = fair bus priority)
504 * Bits 3-0 : Arbitration level (0-15 consecutive)
505 *
506 * Offset 4 : General purpose register
507 * Bits 7-3 : User definable (here, 7,6 are SCSI ID)
508 * Bits 2-0 : reserved
509 *
510 * Offset 10 : DMA decode register (used for IO based DMA; also can do
511 * PIO through this port)
512 *
513 * Offset 12 : Status
514 * Bits 7-2 : reserved
515 * Bit 1 : DMA pending (1 = pending)
516 * Bit 0 : IRQ pending (0 = pending)
517 *
518 * Exciting, huh?
519 *
520 */