aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-29 17:03:42 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-29 17:03:42 -0400
commit6e98ee75c3ab99db48ecc0615c2246dc193111a9 (patch)
treeafdad9dc968ebef3787e7dc16a41290a525f18f5 /drivers/scsi
parent486b4ce13221aa6cd0cbc9fff6993f444d8a52b5 (diff)
parent7db35f31cbb8ca1dbaba03d74b7db79ace084358 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6: [SPARC64]: Fill holes in hypervisor APIs and fix KTSB registry. [SPARC64]: Fix two bugs wrt. kernel 4MB TSB. [SPARC]: Mark as emulating cmpxchg, add appropriate depends for DRM. [SPARC]: Emulate cmpxchg like parisc [SPARC64]: Fix _PAGE_EXEC_4U check in sun4u I-TLB miss handler. [SPARC]: Linux always started with 9600 8N1 [SPARC64]: arch/sparc64/time.c doesn't compile on Ultra 1 (no PCI) [SPARC64]: Eliminate NR_CPUS limitations. [SPARC64]: Use machine description and OBP properly for cpu probing. [SPARC64]: Negotiate hypervisor API for PCI services. [SPARC64]: Report proper system soft state to the hypervisor. [SPARC64]: Fix typo in sun4v_hvapi_register error handling. [SCSI] ESP: Kill SCSI_ESP_CORE and link directly just like jazz_esp [SCSI] jazz_esp: Converted to use esp_core. [SPARC64]: PCI device scan is way too verbose by default. [SERIAL] sunzilog: section mismatch fix [SPARC32]: Removes mismatch section warnigs in sparc time.c file [SPARC64]: Don't be picky about virtual-dma values on sun4v. [SPARC64]: Kill unused DIE_PAGE_FAULT enum value. [SCSI] pluto: Use wait_for_completion_timeout.
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/Kconfig14
-rw-r--r--drivers/scsi/Makefile5
-rw-r--r--drivers/scsi/jazz_esp.c429
-rw-r--r--drivers/scsi/pluto.c18
4 files changed, 189 insertions, 277 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index d28c14e23c32..572034ceb143 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1753,23 +1753,9 @@ config SUN3X_ESP
1753 The ESP was an on-board SCSI controller used on Sun 3/80 1753 The ESP was an on-board SCSI controller used on Sun 3/80
1754 machines. Say Y here to compile in support for it. 1754 machines. Say Y here to compile in support for it.
1755 1755
1756config SCSI_ESP_CORE
1757 tristate "ESP Scsi Driver Core"
1758 depends on SCSI
1759 select SCSI_SPI_ATTRS
1760 help
1761 This is a core driver for NCR53c9x based scsi chipsets,
1762 also known as "ESP" for Emulex Scsi Processor or
1763 Enhanced Scsi Processor. This driver does not exist by
1764 itself, there are front-end drivers which, when enabled,
1765 select and enable this driver. One example is SCSI_SUNESP.
1766 These front-end drivers provide probing, DMA, and register
1767 access support for the core driver.
1768
1769config SCSI_SUNESP 1756config SCSI_SUNESP
1770 tristate "Sparc ESP Scsi Driver" 1757 tristate "Sparc ESP Scsi Driver"
1771 depends on SBUS && SCSI 1758 depends on SBUS && SCSI
1772 select SCSI_ESP_CORE
1773 help 1759 help
1774 This is the driver for the Sun ESP SCSI host adapter. The ESP 1760 This is the driver for the Sun ESP SCSI host adapter. The ESP
1775 chipset is present in most SPARC SBUS-based computers. 1761 chipset is present in most SPARC SBUS-based computers.
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 51e884fa10b0..b1b632791580 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -106,8 +106,7 @@ obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o
106obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/ 106obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
107obj-$(CONFIG_MEGARAID_SAS) += megaraid/ 107obj-$(CONFIG_MEGARAID_SAS) += megaraid/
108obj-$(CONFIG_SCSI_ACARD) += atp870u.o 108obj-$(CONFIG_SCSI_ACARD) += atp870u.o
109obj-$(CONFIG_SCSI_ESP_CORE) += esp_scsi.o 109obj-$(CONFIG_SCSI_SUNESP) += esp_scsi.o sun_esp.o
110obj-$(CONFIG_SCSI_SUNESP) += sun_esp.o
111obj-$(CONFIG_SCSI_GDTH) += gdth.o 110obj-$(CONFIG_SCSI_GDTH) += gdth.o
112obj-$(CONFIG_SCSI_INITIO) += initio.o 111obj-$(CONFIG_SCSI_INITIO) += initio.o
113obj-$(CONFIG_SCSI_INIA100) += a100u2w.o 112obj-$(CONFIG_SCSI_INIA100) += a100u2w.o
@@ -121,7 +120,7 @@ obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o
121obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o 120obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o
122obj-$(CONFIG_SCSI_PPA) += ppa.o 121obj-$(CONFIG_SCSI_PPA) += ppa.o
123obj-$(CONFIG_SCSI_IMM) += imm.o 122obj-$(CONFIG_SCSI_IMM) += imm.o
124obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o 123obj-$(CONFIG_JAZZ_ESP) += esp_scsi.o jazz_esp.o
125obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o 124obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o
126obj-$(CONFIG_SCSI_FCAL) += fcal.o 125obj-$(CONFIG_SCSI_FCAL) += fcal.o
127obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o 126obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o
diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c
index 19dd4b962e18..81e497d9eae0 100644
--- a/drivers/scsi/jazz_esp.c
+++ b/drivers/scsi/jazz_esp.c
@@ -1,307 +1,244 @@
1/* 1/* jazz_esp.c: ESP front-end for MIPS JAZZ systems.
2 * jazz_esp.c: Driver for SCSI chip on Mips Magnum Boards (JAZZ architecture)
3 * 2 *
4 * Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de) 3 * Copyright (C) 2007 Thomas Bogendörfer (tsbogend@alpha.frankende)
5 *
6 * jazz_esp is based on David S. Miller's ESP driver and cyber_esp
7 */ 4 */
8 5
9#include <linux/init.h>
10#include <linux/kernel.h> 6#include <linux/kernel.h>
11#include <linux/delay.h>
12#include <linux/types.h> 7#include <linux/types.h>
13#include <linux/string.h> 8#include <linux/module.h>
14#include <linux/slab.h> 9#include <linux/init.h>
15#include <linux/blkdev.h> 10#include <linux/interrupt.h>
16#include <linux/proc_fs.h> 11#include <linux/platform_device.h>
17#include <linux/stat.h> 12#include <linux/dma-mapping.h>
18
19#include "scsi.h"
20#include <scsi/scsi_host.h>
21#include "NCR53C9x.h"
22 13
23#include <asm/irq.h> 14#include <asm/irq.h>
15#include <asm/io.h>
16#include <asm/dma.h>
17
24#include <asm/jazz.h> 18#include <asm/jazz.h>
25#include <asm/jazzdma.h> 19#include <asm/jazzdma.h>
26#include <asm/dma.h>
27 20
28#include <asm/pgtable.h> 21#include <scsi/scsi_host.h>
29
30static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
31static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp);
32static void dma_dump_state(struct NCR_ESP *esp);
33static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
34static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
35static void dma_ints_off(struct NCR_ESP *esp);
36static void dma_ints_on(struct NCR_ESP *esp);
37static int dma_irq_p(struct NCR_ESP *esp);
38static int dma_ports_p(struct NCR_ESP *esp);
39static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
40static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp);
41static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp);
42static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp);
43static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp);
44static void dma_advance_sg (struct scsi_cmnd *sp);
45static void dma_led_off(struct NCR_ESP *);
46static void dma_led_on(struct NCR_ESP *);
47
48
49static volatile unsigned char cmd_buffer[16];
50 /* This is where all commands are put
51 * before they are trasfered to the ESP chip
52 * via PIO.
53 */
54
55static int jazz_esp_release(struct Scsi_Host *shost)
56{
57 if (shost->irq)
58 free_irq(shost->irq, NULL);
59 if (shost->dma_channel != 0xff)
60 free_dma(shost->dma_channel);
61 if (shost->io_port && shost->n_io_port)
62 release_region(shost->io_port, shost->n_io_port);
63 scsi_unregister(shost);
64 return 0;
65}
66 22
67/***************************************************************** Detection */ 23#include "esp_scsi.h"
68static int jazz_esp_detect(struct scsi_host_template *tpnt)
69{
70 struct NCR_ESP *esp;
71 struct ConfigDev *esp_dev;
72
73 /*
74 * first assumption it is there:-)
75 */
76 if (1) {
77 esp_dev = NULL;
78 esp = esp_allocate(tpnt, esp_dev, 0);
79
80 /* Do command transfer with programmed I/O */
81 esp->do_pio_cmds = 1;
82
83 /* Required functions */
84 esp->dma_bytes_sent = &dma_bytes_sent;
85 esp->dma_can_transfer = &dma_can_transfer;
86 esp->dma_dump_state = &dma_dump_state;
87 esp->dma_init_read = &dma_init_read;
88 esp->dma_init_write = &dma_init_write;
89 esp->dma_ints_off = &dma_ints_off;
90 esp->dma_ints_on = &dma_ints_on;
91 esp->dma_irq_p = &dma_irq_p;
92 esp->dma_ports_p = &dma_ports_p;
93 esp->dma_setup = &dma_setup;
94
95 /* Optional functions */
96 esp->dma_barrier = NULL;
97 esp->dma_drain = NULL;
98 esp->dma_invalidate = NULL;
99 esp->dma_irq_entry = NULL;
100 esp->dma_irq_exit = NULL;
101 esp->dma_poll = NULL;
102 esp->dma_reset = NULL;
103 esp->dma_led_off = &dma_led_off;
104 esp->dma_led_on = &dma_led_on;
105
106 /* virtual DMA functions */
107 esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one;
108 esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl;
109 esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one;
110 esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl;
111 esp->dma_advance_sg = &dma_advance_sg;
112
113
114 /* SCSI chip speed */
115 esp->cfreq = 40000000;
116 24
117 /* 25#define DRV_MODULE_NAME "jazz_esp"
118 * we don't give the address of DMA channel, but the number 26#define PFX DRV_MODULE_NAME ": "
119 * of DMA channel, so we can use the jazz DMA functions 27#define DRV_VERSION "1.000"
120 * 28#define DRV_MODULE_RELDATE "May 19, 2007"
121 */
122 esp->dregs = (void *) JAZZ_SCSI_DMA;
123
124 /* ESP register base */
125 esp->eregs = (struct ESP_regs *)(JAZZ_SCSI_BASE);
126
127 /* Set the command buffer */
128 esp->esp_command = (volatile unsigned char *)cmd_buffer;
129
130 /* get virtual dma address for command buffer */
131 esp->esp_command_dvma = vdma_alloc(CPHYSADDR(cmd_buffer), sizeof (cmd_buffer));
132
133 esp->irq = JAZZ_SCSI_IRQ;
134 request_irq(JAZZ_SCSI_IRQ, esp_intr, IRQF_DISABLED, "JAZZ SCSI",
135 esp->ehost);
136
137 /*
138 * FIXME, look if the scsi id is available from NVRAM
139 */
140 esp->scsi_id = 7;
141
142 /* Check for differential SCSI-bus */
143 /* What is this stuff? */
144 esp->diff = 0;
145
146 esp_initialize(esp);
147
148 printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use);
149 esps_running = esps_in_use;
150 return esps_in_use;
151 }
152 return 0;
153}
154 29
155/************************************************************* DMA Functions */ 30static void jazz_esp_write8(struct esp *esp, u8 val, unsigned long reg)
156static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
157{ 31{
158 return fifo_count; 32 *(volatile u8 *)(esp->regs + reg) = val;
159} 33}
160 34
161static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp) 35static u8 jazz_esp_read8(struct esp *esp, unsigned long reg)
162{ 36{
163 /* 37 return *(volatile u8 *)(esp->regs + reg);
164 * maximum DMA size is 1MB
165 */
166 unsigned long sz = sp->SCp.this_residual;
167 if(sz > 0x100000)
168 sz = 0x100000;
169 return sz;
170} 38}
171 39
172static void dma_dump_state(struct NCR_ESP *esp) 40static dma_addr_t jazz_esp_map_single(struct esp *esp, void *buf,
41 size_t sz, int dir)
173{ 42{
174 43 return dma_map_single(esp->dev, buf, sz, dir);
175 ESPLOG(("esp%d: dma -- enable <%08x> residue <%08x\n",
176 esp->esp_id, vdma_get_enable((int)esp->dregs), vdma_get_residue((int)esp->dregs)));
177} 44}
178 45
179static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length) 46static int jazz_esp_map_sg(struct esp *esp, struct scatterlist *sg,
47 int num_sg, int dir)
180{ 48{
181 dma_cache_wback_inv ((unsigned long)phys_to_virt(vdma_log2phys(vaddress)), length); 49 return dma_map_sg(esp->dev, sg, num_sg, dir);
182 vdma_disable ((int)esp->dregs);
183 vdma_set_mode ((int)esp->dregs, DMA_MODE_READ);
184 vdma_set_addr ((int)esp->dregs, vaddress);
185 vdma_set_count ((int)esp->dregs, length);
186 vdma_enable ((int)esp->dregs);
187} 50}
188 51
189static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length) 52static void jazz_esp_unmap_single(struct esp *esp, dma_addr_t addr,
53 size_t sz, int dir)
190{ 54{
191 dma_cache_wback_inv ((unsigned long)phys_to_virt(vdma_log2phys(vaddress)), length); 55 dma_unmap_single(esp->dev, addr, sz, dir);
192 vdma_disable ((int)esp->dregs);
193 vdma_set_mode ((int)esp->dregs, DMA_MODE_WRITE);
194 vdma_set_addr ((int)esp->dregs, vaddress);
195 vdma_set_count ((int)esp->dregs, length);
196 vdma_enable ((int)esp->dregs);
197} 56}
198 57
199static void dma_ints_off(struct NCR_ESP *esp) 58static void jazz_esp_unmap_sg(struct esp *esp, struct scatterlist *sg,
59 int num_sg, int dir)
200{ 60{
201 disable_irq(esp->irq); 61 dma_unmap_sg(esp->dev, sg, num_sg, dir);
202} 62}
203 63
204static void dma_ints_on(struct NCR_ESP *esp) 64static int jazz_esp_irq_pending(struct esp *esp)
205{ 65{
206 enable_irq(esp->irq); 66 if (jazz_esp_read8(esp, ESP_STATUS) & ESP_STAT_INTR)
67 return 1;
68 return 0;
207} 69}
208 70
209static int dma_irq_p(struct NCR_ESP *esp) 71static void jazz_esp_reset_dma(struct esp *esp)
210{ 72{
211 return (esp_read(esp->eregs->esp_status) & ESP_STAT_INTR); 73 vdma_disable ((int)esp->dma_regs);
212} 74}
213 75
214static int dma_ports_p(struct NCR_ESP *esp) 76static void jazz_esp_dma_drain(struct esp *esp)
215{ 77{
216 int enable = vdma_get_enable((int)esp->dregs); 78 /* nothing to do */
217
218 return (enable & R4030_CHNL_ENABLE);
219} 79}
220 80
221static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) 81static void jazz_esp_dma_invalidate(struct esp *esp)
222{ 82{
223 /* 83 vdma_disable ((int)esp->dma_regs);
224 * On the Sparc, DMA_ST_WRITE means "move data from device to memory"
225 * so when (write) is true, it actually means READ!
226 */
227 if(write){
228 dma_init_read(esp, addr, count);
229 } else {
230 dma_init_write(esp, addr, count);
231 }
232} 84}
233 85
234static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp) 86static void jazz_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count,
87 u32 dma_count, int write, u8 cmd)
235{ 88{
236 sp->SCp.have_data_in = vdma_alloc(CPHYSADDR(sp->SCp.buffer), sp->SCp.this_residual); 89 BUG_ON(!(cmd & ESP_CMD_DMA));
237 sp->SCp.ptr = (char *)((unsigned long)sp->SCp.have_data_in); 90
91 jazz_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
92 jazz_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
93 vdma_disable ((int)esp->dma_regs);
94 if (write)
95 vdma_set_mode ((int)esp->dma_regs, DMA_MODE_READ);
96 else
97 vdma_set_mode ((int)esp->dma_regs, DMA_MODE_WRITE);
98
99 vdma_set_addr ((int)esp->dma_regs, addr);
100 vdma_set_count ((int)esp->dma_regs, dma_count);
101 vdma_enable ((int)esp->dma_regs);
102
103 scsi_esp_cmd(esp, cmd);
238} 104}
239 105
240static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp) 106static int jazz_esp_dma_error(struct esp *esp)
241{
242 int sz = sp->SCp.buffers_residual;
243 struct scatterlist *sg = (struct scatterlist *) sp->SCp.buffer;
244
245 while (sz >= 0) {
246 sg[sz].dma_address = vdma_alloc(CPHYSADDR(page_address(sg[sz].page) + sg[sz].offset), sg[sz].length);
247 sz--;
248 }
249 sp->SCp.ptr=(char *)(sp->SCp.buffer->dma_address);
250}
251
252static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp)
253{ 107{
254 vdma_free(sp->SCp.have_data_in); 108 u32 enable = vdma_get_enable((int)esp->dma_regs);
109
110 if (enable & (R4030_MEM_INTR|R4030_ADDR_INTR))
111 return 1;
112
113 return 0;
255} 114}
256 115
257static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp) 116static const struct esp_driver_ops jazz_esp_ops = {
117 .esp_write8 = jazz_esp_write8,
118 .esp_read8 = jazz_esp_read8,
119 .map_single = jazz_esp_map_single,
120 .map_sg = jazz_esp_map_sg,
121 .unmap_single = jazz_esp_unmap_single,
122 .unmap_sg = jazz_esp_unmap_sg,
123 .irq_pending = jazz_esp_irq_pending,
124 .reset_dma = jazz_esp_reset_dma,
125 .dma_drain = jazz_esp_dma_drain,
126 .dma_invalidate = jazz_esp_dma_invalidate,
127 .send_dma_cmd = jazz_esp_send_dma_cmd,
128 .dma_error = jazz_esp_dma_error,
129};
130
131static int __devinit esp_jazz_probe(struct platform_device *dev)
258{ 132{
259 int sz = sp->use_sg - 1; 133 struct scsi_host_template *tpnt = &scsi_esp_template;
260 struct scatterlist *sg = (struct scatterlist *)sp->request_buffer; 134 struct Scsi_Host *host;
261 135 struct esp *esp;
262 while(sz >= 0) { 136 struct resource *res;
263 vdma_free(sg[sz].dma_address); 137 int err;
264 sz--; 138
265 } 139 host = scsi_host_alloc(tpnt, sizeof(struct esp));
140
141 err = -ENOMEM;
142 if (!host)
143 goto fail;
144
145 host->max_id = 8;
146 esp = host_to_esp(host);
147
148 esp->host = host;
149 esp->dev = dev;
150 esp->ops = &jazz_esp_ops;
151
152 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
153 if (!res)
154 goto fail_unlink;
155
156 esp->regs = (void __iomem *)res->start;
157 if (!esp->regs)
158 goto fail_unlink;
159
160 res = platform_get_resource(dev, IORESOURCE_MEM, 1);
161 if (!res)
162 goto fail_unlink;
163
164 esp->dma_regs = (void __iomem *)res->start;
165
166 esp->command_block = dma_alloc_coherent(esp->dev, 16,
167 &esp->command_block_dma,
168 GFP_KERNEL);
169 if (!esp->command_block)
170 goto fail_unmap_regs;
171
172 host->irq = platform_get_irq(dev, 0);
173 err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp);
174 if (err < 0)
175 goto fail_unmap_command_block;
176
177 esp->scsi_id = 7;
178 esp->host->this_id = esp->scsi_id;
179 esp->scsi_id_mask = (1 << esp->scsi_id);
180 esp->cfreq = 40000000;
181
182 dev_set_drvdata(&dev->dev, esp);
183
184 err = scsi_esp_register(esp, &dev->dev);
185 if (err)
186 goto fail_free_irq;
187
188 return 0;
189
190fail_free_irq:
191 free_irq(host->irq, esp);
192fail_unmap_command_block:
193 dma_free_coherent(esp->dev, 16,
194 esp->command_block,
195 esp->command_block_dma);
196fail_unmap_regs:
197fail_unlink:
198 scsi_host_put(host);
199fail:
200 return err;
266} 201}
267 202
268static void dma_advance_sg (struct scsi_cmnd *sp) 203static int __devexit esp_jazz_remove(struct platform_device *dev)
269{ 204{
270 sp->SCp.ptr = (char *)(sp->SCp.buffer->dma_address); 205 struct esp *esp = dev_get_drvdata(&dev->dev);
206 unsigned int irq = esp->host->irq;
207
208 scsi_esp_unregister(esp);
209
210 free_irq(irq, esp);
211 dma_free_coherent(esp->dev, 16,
212 esp->command_block,
213 esp->command_block_dma);
214
215 scsi_host_put(esp->host);
216
217 return 0;
271} 218}
272 219
273#define JAZZ_HDC_LED 0xe000d100 /* FIXME, find correct address */ 220static struct platform_driver esp_jazz_driver = {
221 .probe = esp_jazz_probe,
222 .remove = __devexit_p(esp_jazz_remove),
223 .driver = {
224 .name = "jazz_esp",
225 },
226};
274 227
275static void dma_led_off(struct NCR_ESP *esp) 228static int __init jazz_esp_init(void)
276{ 229{
277#if 0 230 return platform_driver_register(&esp_jazz_driver);
278 *(unsigned char *)JAZZ_HDC_LED = 0;
279#endif
280} 231}
281 232
282static void dma_led_on(struct NCR_ESP *esp) 233static void __exit jazz_esp_exit(void)
283{ 234{
284#if 0 235 platform_driver_unregister(&esp_jazz_driver);
285 *(unsigned char *)JAZZ_HDC_LED = 1;
286#endif
287} 236}
288 237
289static struct scsi_host_template driver_template = { 238MODULE_DESCRIPTION("JAZZ ESP SCSI driver");
290 .proc_name = "jazz_esp", 239MODULE_AUTHOR("Thomas Bogendoerfer (tsbogend@alpha.franken.de)");
291 .proc_info = esp_proc_info, 240MODULE_LICENSE("GPL");
292 .name = "ESP 100/100a/200", 241MODULE_VERSION(DRV_VERSION);
293 .detect = jazz_esp_detect, 242
294 .slave_alloc = esp_slave_alloc, 243module_init(jazz_esp_init);
295 .slave_destroy = esp_slave_destroy, 244module_exit(jazz_esp_exit);
296 .release = jazz_esp_release,
297 .info = esp_info,
298 .queuecommand = esp_queue,
299 .eh_abort_handler = esp_abort,
300 .eh_bus_reset_handler = esp_reset,
301 .can_queue = 7,
302 .this_id = 7,
303 .sg_tablesize = SG_ALL,
304 .cmd_per_lun = 1,
305 .use_clustering = DISABLE_CLUSTERING,
306};
307#include "scsi_module.c"
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c
index 3b2e1a53e6e2..d953d43fe2e6 100644
--- a/drivers/scsi/pluto.c
+++ b/drivers/scsi/pluto.c
@@ -4,6 +4,7 @@
4 * 4 *
5 */ 5 */
6 6
7#include <linux/completion.h>
7#include <linux/kernel.h> 8#include <linux/kernel.h>
8#include <linux/delay.h> 9#include <linux/delay.h>
9#include <linux/types.h> 10#include <linux/types.h>
@@ -50,16 +51,10 @@ static struct ctrl_inquiry {
50} *fcs __initdata; 51} *fcs __initdata;
51static int fcscount __initdata = 0; 52static int fcscount __initdata = 0;
52static atomic_t fcss __initdata = ATOMIC_INIT(0); 53static atomic_t fcss __initdata = ATOMIC_INIT(0);
53DECLARE_MUTEX_LOCKED(fc_sem); 54static DECLARE_COMPLETION(fc_detect_complete);
54 55
55static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd); 56static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd);
56 57
57static void __init pluto_detect_timeout(unsigned long data)
58{
59 PLND(("Timeout\n"))
60 up(&fc_sem);
61}
62
63static void __init pluto_detect_done(Scsi_Cmnd *SCpnt) 58static void __init pluto_detect_done(Scsi_Cmnd *SCpnt)
64{ 59{
65 /* Do nothing */ 60 /* Do nothing */
@@ -69,7 +64,7 @@ static void __init pluto_detect_scsi_done(Scsi_Cmnd *SCpnt)
69{ 64{
70 PLND(("Detect done %08lx\n", (long)SCpnt)) 65 PLND(("Detect done %08lx\n", (long)SCpnt))
71 if (atomic_dec_and_test (&fcss)) 66 if (atomic_dec_and_test (&fcss))
72 up(&fc_sem); 67 complete(&fc_detect_complete);
73} 68}
74 69
75int pluto_slave_configure(struct scsi_device *device) 70int pluto_slave_configure(struct scsi_device *device)
@@ -96,7 +91,6 @@ int __init pluto_detect(struct scsi_host_template *tpnt)
96 int i, retry, nplutos; 91 int i, retry, nplutos;
97 fc_channel *fc; 92 fc_channel *fc;
98 struct scsi_device dev; 93 struct scsi_device dev;
99 DEFINE_TIMER(fc_timer, pluto_detect_timeout, 0, 0);
100 94
101 tpnt->proc_name = "pluto"; 95 tpnt->proc_name = "pluto";
102 fcscount = 0; 96 fcscount = 0;
@@ -187,15 +181,11 @@ int __init pluto_detect(struct scsi_host_template *tpnt)
187 } 181 }
188 } 182 }
189 183
190 fc_timer.expires = jiffies + 10 * HZ; 184 wait_for_completion_timeout(&fc_detect_complete, 10 * HZ);
191 add_timer(&fc_timer);
192
193 down(&fc_sem);
194 PLND(("Woken up\n")) 185 PLND(("Woken up\n"))
195 if (!atomic_read(&fcss)) 186 if (!atomic_read(&fcss))
196 break; /* All fc channels have answered us */ 187 break; /* All fc channels have answered us */
197 } 188 }
198 del_timer_sync(&fc_timer);
199 189
200 PLND(("Finished search\n")) 190 PLND(("Finished search\n"))
201 for (i = 0, nplutos = 0; i < fcscount; i++) { 191 for (i = 0, nplutos = 0; i < fcscount; i++) {