diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/Kconfig | 11 | ||||
-rw-r--r-- | drivers/scsi/Makefile | 1 | ||||
-rw-r--r-- | drivers/scsi/dec_esp.c | 687 |
3 files changed, 0 insertions, 699 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 21675ae83901..9680f82b3ecf 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -350,17 +350,6 @@ config SGIWD93_SCSI | |||
350 | If you have a Western Digital WD93 SCSI controller on | 350 | If you have a Western Digital WD93 SCSI controller on |
351 | an SGI MIPS system, say Y. Otherwise, say N. | 351 | an SGI MIPS system, say Y. Otherwise, say N. |
352 | 352 | ||
353 | config SCSI_DECNCR | ||
354 | tristate "DEC NCR53C94 Scsi Driver" | ||
355 | depends on MACH_DECSTATION && SCSI && TC | ||
356 | help | ||
357 | Say Y here to support the NCR53C94 SCSI controller chips on IOASIC | ||
358 | based TURBOchannel DECstations and TURBOchannel PMAZ-A cards. | ||
359 | |||
360 | config SCSI_DECSII | ||
361 | tristate "DEC SII Scsi Driver" | ||
362 | depends on MACH_DECSTATION && SCSI && 32BIT | ||
363 | |||
364 | config BLK_DEV_3W_XXXX_RAID | 353 | config BLK_DEV_3W_XXXX_RAID |
365 | tristate "3ware 5/6/7/8xxx ATA-RAID support" | 354 | tristate "3ware 5/6/7/8xxx ATA-RAID support" |
366 | depends on PCI && SCSI | 355 | depends on PCI && SCSI |
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 9c9fa7f5c98a..576cfc68d469 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile | |||
@@ -111,7 +111,6 @@ obj-$(CONFIG_SCSI_QLOGICPTI) += qlogicpti.o | |||
111 | obj-$(CONFIG_BLK_DEV_IDESCSI) += ide-scsi.o | 111 | obj-$(CONFIG_BLK_DEV_IDESCSI) += ide-scsi.o |
112 | obj-$(CONFIG_SCSI_MESH) += mesh.o | 112 | obj-$(CONFIG_SCSI_MESH) += mesh.o |
113 | obj-$(CONFIG_SCSI_MAC53C94) += mac53c94.o | 113 | obj-$(CONFIG_SCSI_MAC53C94) += mac53c94.o |
114 | obj-$(CONFIG_SCSI_DECNCR) += NCR53C9x.o dec_esp.o | ||
115 | obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o | 114 | obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o |
116 | obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o | 115 | obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o |
117 | obj-$(CONFIG_SCSI_PPA) += ppa.o | 116 | obj-$(CONFIG_SCSI_PPA) += ppa.o |
diff --git a/drivers/scsi/dec_esp.c b/drivers/scsi/dec_esp.c deleted file mode 100644 index d42ad663ffee..000000000000 --- a/drivers/scsi/dec_esp.c +++ /dev/null | |||
@@ -1,687 +0,0 @@ | |||
1 | /* | ||
2 | * dec_esp.c: Driver for SCSI chips on IOASIC based TURBOchannel DECstations | ||
3 | * and TURBOchannel PMAZ-A cards | ||
4 | * | ||
5 | * TURBOchannel changes by Harald Koerfgen | ||
6 | * PMAZ-A support by David Airlie | ||
7 | * | ||
8 | * based on jazz_esp.c: | ||
9 | * Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de) | ||
10 | * | ||
11 | * jazz_esp is based on David S. Miller's ESP driver and cyber_esp | ||
12 | * | ||
13 | * 20000819 - Small PMAZ-AA fixes by Florian Lohoff <flo@rfc822.org> | ||
14 | * Be warned the PMAZ-AA works currently as a single card. | ||
15 | * Dont try to put multiple cards in one machine - They are | ||
16 | * both detected but it may crash under high load garbling your | ||
17 | * data. | ||
18 | * 20001005 - Initialization fixes for 2.4.0-test9 | ||
19 | * Florian Lohoff <flo@rfc822.org> | ||
20 | * | ||
21 | * Copyright (C) 2002, 2003, 2005, 2006 Maciej W. Rozycki | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/types.h> | ||
27 | #include <linux/string.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/blkdev.h> | ||
30 | #include <linux/proc_fs.h> | ||
31 | #include <linux/spinlock.h> | ||
32 | #include <linux/stat.h> | ||
33 | #include <linux/tc.h> | ||
34 | |||
35 | #include <asm/dma.h> | ||
36 | #include <asm/irq.h> | ||
37 | #include <asm/pgtable.h> | ||
38 | #include <asm/system.h> | ||
39 | |||
40 | #include <asm/dec/interrupts.h> | ||
41 | #include <asm/dec/ioasic.h> | ||
42 | #include <asm/dec/ioasic_addrs.h> | ||
43 | #include <asm/dec/ioasic_ints.h> | ||
44 | #include <asm/dec/machtype.h> | ||
45 | #include <asm/dec/system.h> | ||
46 | |||
47 | #define DEC_SCSI_SREG 0 | ||
48 | #define DEC_SCSI_DMAREG 0x40000 | ||
49 | #define DEC_SCSI_SRAM 0x80000 | ||
50 | #define DEC_SCSI_DIAG 0xC0000 | ||
51 | |||
52 | #include "scsi.h" | ||
53 | #include <scsi/scsi_host.h> | ||
54 | #include "NCR53C9x.h" | ||
55 | |||
56 | static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count); | ||
57 | static void dma_drain(struct NCR_ESP *esp); | ||
58 | static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp); | ||
59 | static void dma_dump_state(struct NCR_ESP *esp); | ||
60 | static void dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length); | ||
61 | static void dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length); | ||
62 | static void dma_ints_off(struct NCR_ESP *esp); | ||
63 | static void dma_ints_on(struct NCR_ESP *esp); | ||
64 | static int dma_irq_p(struct NCR_ESP *esp); | ||
65 | static int dma_ports_p(struct NCR_ESP *esp); | ||
66 | static void dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write); | ||
67 | static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, struct scsi_cmnd * sp); | ||
68 | static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, struct scsi_cmnd * sp); | ||
69 | static void dma_advance_sg(struct scsi_cmnd * sp); | ||
70 | |||
71 | static void pmaz_dma_drain(struct NCR_ESP *esp); | ||
72 | static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length); | ||
73 | static void pmaz_dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length); | ||
74 | static void pmaz_dma_ints_off(struct NCR_ESP *esp); | ||
75 | static void pmaz_dma_ints_on(struct NCR_ESP *esp); | ||
76 | static void pmaz_dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write); | ||
77 | static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, struct scsi_cmnd * sp); | ||
78 | |||
79 | #define TC_ESP_RAM_SIZE 0x20000 | ||
80 | #define ESP_TGT_DMA_SIZE ((TC_ESP_RAM_SIZE/7) & ~(sizeof(int)-1)) | ||
81 | #define ESP_NCMD 7 | ||
82 | |||
83 | #define TC_ESP_DMAR_MASK 0x1ffff | ||
84 | #define TC_ESP_DMAR_WRITE 0x80000000 | ||
85 | #define TC_ESP_DMA_ADDR(x) ((unsigned)(x) & TC_ESP_DMAR_MASK) | ||
86 | |||
87 | u32 esp_virt_buffer; | ||
88 | int scsi_current_length; | ||
89 | |||
90 | volatile unsigned char cmd_buffer[16]; | ||
91 | volatile unsigned char pmaz_cmd_buffer[16]; | ||
92 | /* This is where all commands are put | ||
93 | * before they are trasfered to the ESP chip | ||
94 | * via PIO. | ||
95 | */ | ||
96 | |||
97 | static irqreturn_t scsi_dma_merr_int(int, void *); | ||
98 | static irqreturn_t scsi_dma_err_int(int, void *); | ||
99 | static irqreturn_t scsi_dma_int(int, void *); | ||
100 | |||
101 | static struct scsi_host_template dec_esp_template = { | ||
102 | .module = THIS_MODULE, | ||
103 | .name = "NCR53C94", | ||
104 | .info = esp_info, | ||
105 | .queuecommand = esp_queue, | ||
106 | .eh_abort_handler = esp_abort, | ||
107 | .eh_bus_reset_handler = esp_reset, | ||
108 | .slave_alloc = esp_slave_alloc, | ||
109 | .slave_destroy = esp_slave_destroy, | ||
110 | .proc_info = esp_proc_info, | ||
111 | .proc_name = "dec_esp", | ||
112 | .can_queue = 7, | ||
113 | .sg_tablesize = SG_ALL, | ||
114 | .cmd_per_lun = 1, | ||
115 | .use_clustering = DISABLE_CLUSTERING, | ||
116 | }; | ||
117 | |||
118 | static struct NCR_ESP *dec_esp_platform; | ||
119 | |||
120 | /***************************************************************** Detection */ | ||
121 | static int dec_esp_platform_probe(void) | ||
122 | { | ||
123 | struct NCR_ESP *esp; | ||
124 | int err = 0; | ||
125 | |||
126 | if (IOASIC) { | ||
127 | esp = esp_allocate(&dec_esp_template, NULL, 1); | ||
128 | |||
129 | /* Do command transfer with programmed I/O */ | ||
130 | esp->do_pio_cmds = 1; | ||
131 | |||
132 | /* Required functions */ | ||
133 | esp->dma_bytes_sent = &dma_bytes_sent; | ||
134 | esp->dma_can_transfer = &dma_can_transfer; | ||
135 | esp->dma_dump_state = &dma_dump_state; | ||
136 | esp->dma_init_read = &dma_init_read; | ||
137 | esp->dma_init_write = &dma_init_write; | ||
138 | esp->dma_ints_off = &dma_ints_off; | ||
139 | esp->dma_ints_on = &dma_ints_on; | ||
140 | esp->dma_irq_p = &dma_irq_p; | ||
141 | esp->dma_ports_p = &dma_ports_p; | ||
142 | esp->dma_setup = &dma_setup; | ||
143 | |||
144 | /* Optional functions */ | ||
145 | esp->dma_barrier = 0; | ||
146 | esp->dma_drain = &dma_drain; | ||
147 | esp->dma_invalidate = 0; | ||
148 | esp->dma_irq_entry = 0; | ||
149 | esp->dma_irq_exit = 0; | ||
150 | esp->dma_poll = 0; | ||
151 | esp->dma_reset = 0; | ||
152 | esp->dma_led_off = 0; | ||
153 | esp->dma_led_on = 0; | ||
154 | |||
155 | /* virtual DMA functions */ | ||
156 | esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one; | ||
157 | esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl; | ||
158 | esp->dma_mmu_release_scsi_one = 0; | ||
159 | esp->dma_mmu_release_scsi_sgl = 0; | ||
160 | esp->dma_advance_sg = &dma_advance_sg; | ||
161 | |||
162 | |||
163 | /* SCSI chip speed */ | ||
164 | esp->cfreq = 25000000; | ||
165 | |||
166 | esp->dregs = 0; | ||
167 | |||
168 | /* ESP register base */ | ||
169 | esp->eregs = (void *)CKSEG1ADDR(dec_kn_slot_base + | ||
170 | IOASIC_SCSI); | ||
171 | |||
172 | /* Set the command buffer */ | ||
173 | esp->esp_command = (volatile unsigned char *) cmd_buffer; | ||
174 | |||
175 | /* get virtual dma address for command buffer */ | ||
176 | esp->esp_command_dvma = virt_to_phys(cmd_buffer); | ||
177 | |||
178 | esp->irq = dec_interrupt[DEC_IRQ_ASC]; | ||
179 | |||
180 | esp->scsi_id = 7; | ||
181 | |||
182 | /* Check for differential SCSI-bus */ | ||
183 | esp->diff = 0; | ||
184 | |||
185 | err = request_irq(esp->irq, esp_intr, IRQF_DISABLED, | ||
186 | "ncr53c94", esp->ehost); | ||
187 | if (err) | ||
188 | goto err_alloc; | ||
189 | err = request_irq(dec_interrupt[DEC_IRQ_ASC_MERR], | ||
190 | scsi_dma_merr_int, IRQF_DISABLED, | ||
191 | "ncr53c94 error", esp->ehost); | ||
192 | if (err) | ||
193 | goto err_irq; | ||
194 | err = request_irq(dec_interrupt[DEC_IRQ_ASC_ERR], | ||
195 | scsi_dma_err_int, IRQF_DISABLED, | ||
196 | "ncr53c94 overrun", esp->ehost); | ||
197 | if (err) | ||
198 | goto err_irq_merr; | ||
199 | err = request_irq(dec_interrupt[DEC_IRQ_ASC_DMA], scsi_dma_int, | ||
200 | IRQF_DISABLED, "ncr53c94 dma", esp->ehost); | ||
201 | if (err) | ||
202 | goto err_irq_err; | ||
203 | |||
204 | esp_initialize(esp); | ||
205 | |||
206 | err = scsi_add_host(esp->ehost, NULL); | ||
207 | if (err) { | ||
208 | printk(KERN_ERR "ESP: Unable to register adapter\n"); | ||
209 | goto err_irq_dma; | ||
210 | } | ||
211 | |||
212 | scsi_scan_host(esp->ehost); | ||
213 | |||
214 | dec_esp_platform = esp; | ||
215 | } | ||
216 | |||
217 | return 0; | ||
218 | |||
219 | err_irq_dma: | ||
220 | free_irq(dec_interrupt[DEC_IRQ_ASC_DMA], esp->ehost); | ||
221 | err_irq_err: | ||
222 | free_irq(dec_interrupt[DEC_IRQ_ASC_ERR], esp->ehost); | ||
223 | err_irq_merr: | ||
224 | free_irq(dec_interrupt[DEC_IRQ_ASC_MERR], esp->ehost); | ||
225 | err_irq: | ||
226 | free_irq(esp->irq, esp->ehost); | ||
227 | err_alloc: | ||
228 | esp_deallocate(esp); | ||
229 | scsi_host_put(esp->ehost); | ||
230 | return err; | ||
231 | } | ||
232 | |||
233 | static int __init dec_esp_probe(struct device *dev) | ||
234 | { | ||
235 | struct NCR_ESP *esp; | ||
236 | resource_size_t start, len; | ||
237 | int err; | ||
238 | |||
239 | esp = esp_allocate(&dec_esp_template, NULL, 1); | ||
240 | |||
241 | dev_set_drvdata(dev, esp); | ||
242 | |||
243 | start = to_tc_dev(dev)->resource.start; | ||
244 | len = to_tc_dev(dev)->resource.end - start + 1; | ||
245 | |||
246 | if (!request_mem_region(start, len, dev->bus_id)) { | ||
247 | printk(KERN_ERR "%s: Unable to reserve MMIO resource\n", | ||
248 | dev->bus_id); | ||
249 | err = -EBUSY; | ||
250 | goto err_alloc; | ||
251 | } | ||
252 | |||
253 | /* Store base addr into esp struct. */ | ||
254 | esp->slot = start; | ||
255 | |||
256 | esp->dregs = 0; | ||
257 | esp->eregs = (void *)CKSEG1ADDR(start + DEC_SCSI_SREG); | ||
258 | esp->do_pio_cmds = 1; | ||
259 | |||
260 | /* Set the command buffer. */ | ||
261 | esp->esp_command = (volatile unsigned char *)pmaz_cmd_buffer; | ||
262 | |||
263 | /* Get virtual dma address for command buffer. */ | ||
264 | esp->esp_command_dvma = virt_to_phys(pmaz_cmd_buffer); | ||
265 | |||
266 | esp->cfreq = tc_get_speed(to_tc_dev(dev)->bus); | ||
267 | |||
268 | esp->irq = to_tc_dev(dev)->interrupt; | ||
269 | |||
270 | /* Required functions. */ | ||
271 | esp->dma_bytes_sent = &dma_bytes_sent; | ||
272 | esp->dma_can_transfer = &dma_can_transfer; | ||
273 | esp->dma_dump_state = &dma_dump_state; | ||
274 | esp->dma_init_read = &pmaz_dma_init_read; | ||
275 | esp->dma_init_write = &pmaz_dma_init_write; | ||
276 | esp->dma_ints_off = &pmaz_dma_ints_off; | ||
277 | esp->dma_ints_on = &pmaz_dma_ints_on; | ||
278 | esp->dma_irq_p = &dma_irq_p; | ||
279 | esp->dma_ports_p = &dma_ports_p; | ||
280 | esp->dma_setup = &pmaz_dma_setup; | ||
281 | |||
282 | /* Optional functions. */ | ||
283 | esp->dma_barrier = 0; | ||
284 | esp->dma_drain = &pmaz_dma_drain; | ||
285 | esp->dma_invalidate = 0; | ||
286 | esp->dma_irq_entry = 0; | ||
287 | esp->dma_irq_exit = 0; | ||
288 | esp->dma_poll = 0; | ||
289 | esp->dma_reset = 0; | ||
290 | esp->dma_led_off = 0; | ||
291 | esp->dma_led_on = 0; | ||
292 | |||
293 | esp->dma_mmu_get_scsi_one = pmaz_dma_mmu_get_scsi_one; | ||
294 | esp->dma_mmu_get_scsi_sgl = 0; | ||
295 | esp->dma_mmu_release_scsi_one = 0; | ||
296 | esp->dma_mmu_release_scsi_sgl = 0; | ||
297 | esp->dma_advance_sg = 0; | ||
298 | |||
299 | err = request_irq(esp->irq, esp_intr, IRQF_DISABLED, "PMAZ_AA", | ||
300 | esp->ehost); | ||
301 | if (err) { | ||
302 | printk(KERN_ERR "%s: Unable to get IRQ %d\n", | ||
303 | dev->bus_id, esp->irq); | ||
304 | goto err_resource; | ||
305 | } | ||
306 | |||
307 | esp->scsi_id = 7; | ||
308 | esp->diff = 0; | ||
309 | esp_initialize(esp); | ||
310 | |||
311 | err = scsi_add_host(esp->ehost, dev); | ||
312 | if (err) { | ||
313 | printk(KERN_ERR "%s: Unable to register adapter\n", | ||
314 | dev->bus_id); | ||
315 | goto err_irq; | ||
316 | } | ||
317 | |||
318 | scsi_scan_host(esp->ehost); | ||
319 | |||
320 | return 0; | ||
321 | |||
322 | err_irq: | ||
323 | free_irq(esp->irq, esp->ehost); | ||
324 | |||
325 | err_resource: | ||
326 | release_mem_region(start, len); | ||
327 | |||
328 | err_alloc: | ||
329 | esp_deallocate(esp); | ||
330 | scsi_host_put(esp->ehost); | ||
331 | return err; | ||
332 | } | ||
333 | |||
334 | static void __exit dec_esp_platform_remove(void) | ||
335 | { | ||
336 | struct NCR_ESP *esp = dec_esp_platform; | ||
337 | |||
338 | free_irq(esp->irq, esp->ehost); | ||
339 | esp_deallocate(esp); | ||
340 | scsi_host_put(esp->ehost); | ||
341 | dec_esp_platform = NULL; | ||
342 | } | ||
343 | |||
344 | static void __exit dec_esp_remove(struct device *dev) | ||
345 | { | ||
346 | struct NCR_ESP *esp = dev_get_drvdata(dev); | ||
347 | |||
348 | free_irq(esp->irq, esp->ehost); | ||
349 | esp_deallocate(esp); | ||
350 | scsi_host_put(esp->ehost); | ||
351 | } | ||
352 | |||
353 | |||
354 | /************************************************************* DMA Functions */ | ||
355 | static irqreturn_t scsi_dma_merr_int(int irq, void *dev_id) | ||
356 | { | ||
357 | printk("Got unexpected SCSI DMA Interrupt! < "); | ||
358 | printk("SCSI_DMA_MEMRDERR "); | ||
359 | printk(">\n"); | ||
360 | |||
361 | return IRQ_HANDLED; | ||
362 | } | ||
363 | |||
364 | static irqreturn_t scsi_dma_err_int(int irq, void *dev_id) | ||
365 | { | ||
366 | /* empty */ | ||
367 | |||
368 | return IRQ_HANDLED; | ||
369 | } | ||
370 | |||
371 | static irqreturn_t scsi_dma_int(int irq, void *dev_id) | ||
372 | { | ||
373 | u32 scsi_next_ptr; | ||
374 | |||
375 | scsi_next_ptr = ioasic_read(IO_REG_SCSI_DMA_P); | ||
376 | |||
377 | /* next page */ | ||
378 | scsi_next_ptr = (((scsi_next_ptr >> 3) + PAGE_SIZE) & PAGE_MASK) << 3; | ||
379 | ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr); | ||
380 | fast_iob(); | ||
381 | |||
382 | return IRQ_HANDLED; | ||
383 | } | ||
384 | |||
385 | static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count) | ||
386 | { | ||
387 | return fifo_count; | ||
388 | } | ||
389 | |||
390 | static void dma_drain(struct NCR_ESP *esp) | ||
391 | { | ||
392 | u32 nw, data0, data1, scsi_data_ptr; | ||
393 | u16 *p; | ||
394 | |||
395 | nw = ioasic_read(IO_REG_SCSI_SCR); | ||
396 | |||
397 | /* | ||
398 | * Is there something in the dma buffers left? | ||
399 | */ | ||
400 | if (nw) { | ||
401 | scsi_data_ptr = ioasic_read(IO_REG_SCSI_DMA_P) >> 3; | ||
402 | p = phys_to_virt(scsi_data_ptr); | ||
403 | switch (nw) { | ||
404 | case 1: | ||
405 | data0 = ioasic_read(IO_REG_SCSI_SDR0); | ||
406 | p[0] = data0 & 0xffff; | ||
407 | break; | ||
408 | case 2: | ||
409 | data0 = ioasic_read(IO_REG_SCSI_SDR0); | ||
410 | p[0] = data0 & 0xffff; | ||
411 | p[1] = (data0 >> 16) & 0xffff; | ||
412 | break; | ||
413 | case 3: | ||
414 | data0 = ioasic_read(IO_REG_SCSI_SDR0); | ||
415 | data1 = ioasic_read(IO_REG_SCSI_SDR1); | ||
416 | p[0] = data0 & 0xffff; | ||
417 | p[1] = (data0 >> 16) & 0xffff; | ||
418 | p[2] = data1 & 0xffff; | ||
419 | break; | ||
420 | default: | ||
421 | printk("Strange: %d words in dma buffer left\n", nw); | ||
422 | break; | ||
423 | } | ||
424 | } | ||
425 | } | ||
426 | |||
427 | static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd * sp) | ||
428 | { | ||
429 | return sp->SCp.this_residual; | ||
430 | } | ||
431 | |||
432 | static void dma_dump_state(struct NCR_ESP *esp) | ||
433 | { | ||
434 | } | ||
435 | |||
436 | static void dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length) | ||
437 | { | ||
438 | u32 scsi_next_ptr, ioasic_ssr; | ||
439 | unsigned long flags; | ||
440 | |||
441 | if (vaddress & 3) | ||
442 | panic("dec_esp.c: unable to handle partial word transfers, yet..."); | ||
443 | |||
444 | dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress), length); | ||
445 | |||
446 | spin_lock_irqsave(&ioasic_ssr_lock, flags); | ||
447 | |||
448 | fast_mb(); | ||
449 | ioasic_ssr = ioasic_read(IO_REG_SSR); | ||
450 | |||
451 | ioasic_ssr &= ~IO_SSR_SCSI_DMA_EN; | ||
452 | ioasic_write(IO_REG_SSR, ioasic_ssr); | ||
453 | |||
454 | fast_wmb(); | ||
455 | ioasic_write(IO_REG_SCSI_SCR, 0); | ||
456 | ioasic_write(IO_REG_SCSI_DMA_P, vaddress << 3); | ||
457 | |||
458 | /* prepare for next page */ | ||
459 | scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3; | ||
460 | ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr); | ||
461 | |||
462 | ioasic_ssr |= (IO_SSR_SCSI_DMA_DIR | IO_SSR_SCSI_DMA_EN); | ||
463 | fast_wmb(); | ||
464 | ioasic_write(IO_REG_SSR, ioasic_ssr); | ||
465 | |||
466 | fast_iob(); | ||
467 | spin_unlock_irqrestore(&ioasic_ssr_lock, flags); | ||
468 | } | ||
469 | |||
470 | static void dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length) | ||
471 | { | ||
472 | u32 scsi_next_ptr, ioasic_ssr; | ||
473 | unsigned long flags; | ||
474 | |||
475 | if (vaddress & 3) | ||
476 | panic("dec_esp.c: unable to handle partial word transfers, yet..."); | ||
477 | |||
478 | dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress), length); | ||
479 | |||
480 | spin_lock_irqsave(&ioasic_ssr_lock, flags); | ||
481 | |||
482 | fast_mb(); | ||
483 | ioasic_ssr = ioasic_read(IO_REG_SSR); | ||
484 | |||
485 | ioasic_ssr &= ~(IO_SSR_SCSI_DMA_DIR | IO_SSR_SCSI_DMA_EN); | ||
486 | ioasic_write(IO_REG_SSR, ioasic_ssr); | ||
487 | |||
488 | fast_wmb(); | ||
489 | ioasic_write(IO_REG_SCSI_SCR, 0); | ||
490 | ioasic_write(IO_REG_SCSI_DMA_P, vaddress << 3); | ||
491 | |||
492 | /* prepare for next page */ | ||
493 | scsi_next_ptr = ((vaddress + PAGE_SIZE) & PAGE_MASK) << 3; | ||
494 | ioasic_write(IO_REG_SCSI_DMA_BP, scsi_next_ptr); | ||
495 | |||
496 | ioasic_ssr |= IO_SSR_SCSI_DMA_EN; | ||
497 | fast_wmb(); | ||
498 | ioasic_write(IO_REG_SSR, ioasic_ssr); | ||
499 | |||
500 | fast_iob(); | ||
501 | spin_unlock_irqrestore(&ioasic_ssr_lock, flags); | ||
502 | } | ||
503 | |||
504 | static void dma_ints_off(struct NCR_ESP *esp) | ||
505 | { | ||
506 | disable_irq(dec_interrupt[DEC_IRQ_ASC_DMA]); | ||
507 | } | ||
508 | |||
509 | static void dma_ints_on(struct NCR_ESP *esp) | ||
510 | { | ||
511 | enable_irq(dec_interrupt[DEC_IRQ_ASC_DMA]); | ||
512 | } | ||
513 | |||
514 | static int dma_irq_p(struct NCR_ESP *esp) | ||
515 | { | ||
516 | return (esp->eregs->esp_status & ESP_STAT_INTR); | ||
517 | } | ||
518 | |||
519 | static int dma_ports_p(struct NCR_ESP *esp) | ||
520 | { | ||
521 | /* | ||
522 | * FIXME: what's this good for? | ||
523 | */ | ||
524 | return 1; | ||
525 | } | ||
526 | |||
527 | static void dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write) | ||
528 | { | ||
529 | /* | ||
530 | * DMA_ST_WRITE means "move data from device to memory" | ||
531 | * so when (write) is true, it actually means READ! | ||
532 | */ | ||
533 | if (write) | ||
534 | dma_init_read(esp, addr, count); | ||
535 | else | ||
536 | dma_init_write(esp, addr, count); | ||
537 | } | ||
538 | |||
539 | static void dma_mmu_get_scsi_one(struct NCR_ESP *esp, struct scsi_cmnd * sp) | ||
540 | { | ||
541 | sp->SCp.ptr = (char *)virt_to_phys(sp->request_buffer); | ||
542 | } | ||
543 | |||
544 | static void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, struct scsi_cmnd * sp) | ||
545 | { | ||
546 | int sz = sp->SCp.buffers_residual; | ||
547 | struct scatterlist *sg = sp->SCp.buffer; | ||
548 | |||
549 | while (sz >= 0) { | ||
550 | sg[sz].dma_address = page_to_phys(sg[sz].page) + sg[sz].offset; | ||
551 | sz--; | ||
552 | } | ||
553 | sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address); | ||
554 | } | ||
555 | |||
556 | static void dma_advance_sg(struct scsi_cmnd * sp) | ||
557 | { | ||
558 | sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address); | ||
559 | } | ||
560 | |||
561 | static void pmaz_dma_drain(struct NCR_ESP *esp) | ||
562 | { | ||
563 | memcpy(phys_to_virt(esp_virt_buffer), | ||
564 | (void *)CKSEG1ADDR(esp->slot + DEC_SCSI_SRAM + | ||
565 | ESP_TGT_DMA_SIZE), | ||
566 | scsi_current_length); | ||
567 | } | ||
568 | |||
569 | static void pmaz_dma_init_read(struct NCR_ESP *esp, u32 vaddress, int length) | ||
570 | { | ||
571 | volatile u32 *dmareg = | ||
572 | (volatile u32 *)CKSEG1ADDR(esp->slot + DEC_SCSI_DMAREG); | ||
573 | |||
574 | if (length > ESP_TGT_DMA_SIZE) | ||
575 | length = ESP_TGT_DMA_SIZE; | ||
576 | |||
577 | *dmareg = TC_ESP_DMA_ADDR(ESP_TGT_DMA_SIZE); | ||
578 | |||
579 | iob(); | ||
580 | |||
581 | esp_virt_buffer = vaddress; | ||
582 | scsi_current_length = length; | ||
583 | } | ||
584 | |||
585 | static void pmaz_dma_init_write(struct NCR_ESP *esp, u32 vaddress, int length) | ||
586 | { | ||
587 | volatile u32 *dmareg = | ||
588 | (volatile u32 *)CKSEG1ADDR(esp->slot + DEC_SCSI_DMAREG); | ||
589 | |||
590 | memcpy((void *)CKSEG1ADDR(esp->slot + DEC_SCSI_SRAM + | ||
591 | ESP_TGT_DMA_SIZE), | ||
592 | phys_to_virt(vaddress), length); | ||
593 | |||
594 | wmb(); | ||
595 | *dmareg = TC_ESP_DMAR_WRITE | TC_ESP_DMA_ADDR(ESP_TGT_DMA_SIZE); | ||
596 | |||
597 | iob(); | ||
598 | } | ||
599 | |||
600 | static void pmaz_dma_ints_off(struct NCR_ESP *esp) | ||
601 | { | ||
602 | } | ||
603 | |||
604 | static void pmaz_dma_ints_on(struct NCR_ESP *esp) | ||
605 | { | ||
606 | } | ||
607 | |||
608 | static void pmaz_dma_setup(struct NCR_ESP *esp, u32 addr, int count, int write) | ||
609 | { | ||
610 | /* | ||
611 | * DMA_ST_WRITE means "move data from device to memory" | ||
612 | * so when (write) is true, it actually means READ! | ||
613 | */ | ||
614 | if (write) | ||
615 | pmaz_dma_init_read(esp, addr, count); | ||
616 | else | ||
617 | pmaz_dma_init_write(esp, addr, count); | ||
618 | } | ||
619 | |||
620 | static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP *esp, struct scsi_cmnd * sp) | ||
621 | { | ||
622 | sp->SCp.ptr = (char *)virt_to_phys(sp->request_buffer); | ||
623 | } | ||
624 | |||
625 | |||
626 | #ifdef CONFIG_TC | ||
627 | static int __init dec_esp_tc_probe(struct device *dev); | ||
628 | static int __exit dec_esp_tc_remove(struct device *dev); | ||
629 | |||
630 | static const struct tc_device_id dec_esp_tc_table[] = { | ||
631 | { "DEC ", "PMAZ-AA " }, | ||
632 | { } | ||
633 | }; | ||
634 | MODULE_DEVICE_TABLE(tc, dec_esp_tc_table); | ||
635 | |||
636 | static struct tc_driver dec_esp_tc_driver = { | ||
637 | .id_table = dec_esp_tc_table, | ||
638 | .driver = { | ||
639 | .name = "dec_esp", | ||
640 | .bus = &tc_bus_type, | ||
641 | .probe = dec_esp_tc_probe, | ||
642 | .remove = __exit_p(dec_esp_tc_remove), | ||
643 | }, | ||
644 | }; | ||
645 | |||
646 | static int __init dec_esp_tc_probe(struct device *dev) | ||
647 | { | ||
648 | int status = dec_esp_probe(dev); | ||
649 | if (!status) | ||
650 | get_device(dev); | ||
651 | return status; | ||
652 | } | ||
653 | |||
654 | static int __exit dec_esp_tc_remove(struct device *dev) | ||
655 | { | ||
656 | put_device(dev); | ||
657 | dec_esp_remove(dev); | ||
658 | return 0; | ||
659 | } | ||
660 | #endif | ||
661 | |||
662 | static int __init dec_esp_init(void) | ||
663 | { | ||
664 | int status; | ||
665 | |||
666 | status = tc_register_driver(&dec_esp_tc_driver); | ||
667 | if (!status) | ||
668 | dec_esp_platform_probe(); | ||
669 | |||
670 | if (nesps) { | ||
671 | pr_info("ESP: Total of %d ESP hosts found, " | ||
672 | "%d actually in use.\n", nesps, esps_in_use); | ||
673 | esps_running = esps_in_use; | ||
674 | } | ||
675 | |||
676 | return status; | ||
677 | } | ||
678 | |||
679 | static void __exit dec_esp_exit(void) | ||
680 | { | ||
681 | dec_esp_platform_remove(); | ||
682 | tc_unregister_driver(&dec_esp_tc_driver); | ||
683 | } | ||
684 | |||
685 | |||
686 | module_init(dec_esp_init); | ||
687 | module_exit(dec_esp_exit); | ||