aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sun3x_esp.c
diff options
context:
space:
mode:
authorThomas Bogendoerfer <tsbogend@alpha.franken.de>2008-01-31 18:13:34 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-02-07 19:02:33 -0500
commit0bb67f181834044db6e9b15c7d5cc3cce0489bfd (patch)
tree028d0c510e8f219c660c4369e32bb6bc8d556ab1 /drivers/scsi/sun3x_esp.c
parentf8d9d654fcc7dd87f5d0b222e233eaab15d650c4 (diff)
[SCSI] sun3x_esp: convert to esp_scsi
Converted sun3x_esp driver to use esp_scsi.c Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/sun3x_esp.c')
-rw-r--r--drivers/scsi/sun3x_esp.c546
1 files changed, 235 insertions, 311 deletions
diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c
index 1bc41907a038..06152c7fa689 100644
--- a/drivers/scsi/sun3x_esp.c
+++ b/drivers/scsi/sun3x_esp.c
@@ -1,392 +1,316 @@
1/* sun3x_esp.c: EnhancedScsiProcessor Sun3x SCSI driver code. 1/* sun3x_esp.c: ESP front-end for Sun3x systems.
2 * 2 *
3 * (C) 1999 Thomas Bogendoerfer (tsbogend@alpha.franken.de) 3 * Copyright (C) 2007,2008 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
4 *
5 * Based on David S. Miller's esp driver
6 */ 4 */
7 5
8#include <linux/kernel.h> 6#include <linux/kernel.h>
9#include <linux/types.h> 7#include <linux/types.h>
10#include <linux/string.h>
11#include <linux/slab.h>
12#include <linux/blkdev.h>
13#include <linux/proc_fs.h>
14#include <linux/stat.h>
15#include <linux/delay.h> 8#include <linux/delay.h>
9#include <linux/module.h>
10#include <linux/init.h>
11#include <linux/platform_device.h>
12#include <linux/dma-mapping.h>
16#include <linux/interrupt.h> 13#include <linux/interrupt.h>
17 14
18#include "scsi.h"
19#include <scsi/scsi_host.h>
20#include "NCR53C9x.h"
21
22#include <asm/sun3x.h> 15#include <asm/sun3x.h>
16#include <asm/io.h>
17#include <asm/dma.h>
23#include <asm/dvma.h> 18#include <asm/dvma.h>
24#include <asm/irq.h>
25
26static void dma_barrier(struct NCR_ESP *esp);
27static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count);
28static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp);
29static void dma_drain(struct NCR_ESP *esp);
30static void dma_invalidate(struct NCR_ESP *esp);
31static void dma_dump_state(struct NCR_ESP *esp);
32static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length);
33static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length);
34static void dma_ints_off(struct NCR_ESP *esp);
35static void dma_ints_on(struct NCR_ESP *esp);
36static int dma_irq_p(struct NCR_ESP *esp);
37static void dma_poll(struct NCR_ESP *esp, unsigned char *vaddr);
38static int dma_ports_p(struct NCR_ESP *esp);
39static void dma_reset(struct NCR_ESP *esp);
40static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write);
41static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp);
42static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp);
43static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp);
44static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp);
45static void dma_advance_sg (Scsi_Cmnd *sp);
46
47/* Detecting ESP chips on the machine. This is the simple and easy
48 * version.
49 */
50int sun3x_esp_detect(struct scsi_host_template *tpnt)
51{
52 struct NCR_ESP *esp;
53 struct ConfigDev *esp_dev;
54
55 esp_dev = 0;
56 esp = esp_allocate(tpnt, esp_dev, 0);
57
58 /* Do command transfer with DMA */
59 esp->do_pio_cmds = 0;
60
61 /* Required functions */
62 esp->dma_bytes_sent = &dma_bytes_sent;
63 esp->dma_can_transfer = &dma_can_transfer;
64 esp->dma_dump_state = &dma_dump_state;
65 esp->dma_init_read = &dma_init_read;
66 esp->dma_init_write = &dma_init_write;
67 esp->dma_ints_off = &dma_ints_off;
68 esp->dma_ints_on = &dma_ints_on;
69 esp->dma_irq_p = &dma_irq_p;
70 esp->dma_ports_p = &dma_ports_p;
71 esp->dma_setup = &dma_setup;
72
73 /* Optional functions */
74 esp->dma_barrier = &dma_barrier;
75 esp->dma_invalidate = &dma_invalidate;
76 esp->dma_drain = &dma_drain;
77 esp->dma_irq_entry = 0;
78 esp->dma_irq_exit = 0;
79 esp->dma_led_on = 0;
80 esp->dma_led_off = 0;
81 esp->dma_poll = &dma_poll;
82 esp->dma_reset = &dma_reset;
83
84 /* virtual DMA functions */
85 esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one;
86 esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl;
87 esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one;
88 esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl;
89 esp->dma_advance_sg = &dma_advance_sg;
90
91 /* SCSI chip speed */
92 esp->cfreq = 20000000;
93 esp->eregs = (struct ESP_regs *)(SUN3X_ESP_BASE);
94 esp->dregs = (void *)SUN3X_ESP_DMA;
95 19
96 esp->esp_command = (volatile unsigned char *)dvma_malloc(DVMA_PAGE_SIZE); 20/* DMA controller reg offsets */
97 esp->esp_command_dvma = dvma_vtob((unsigned long)esp->esp_command); 21#define DMA_CSR 0x00UL /* rw DMA control/status register 0x00 */
98 22#define DMA_ADDR 0x04UL /* rw DMA transfer address register 0x04 */
99 esp->irq = 2; 23#define DMA_COUNT 0x08UL /* rw DMA transfer count register 0x08 */
100 if (request_irq(esp->irq, esp_intr, IRQF_DISABLED, 24#define DMA_TEST 0x0cUL /* rw DMA test/debug register 0x0c */
101 "SUN3X SCSI", esp->ehost)) {
102 esp_deallocate(esp);
103 return 0;
104 }
105 25
106 esp->scsi_id = 7; 26#include <scsi/scsi_host.h>
107 esp->diff = 0;
108 27
109 esp_initialize(esp); 28#include "esp_scsi.h"
110 29
111 /* for reasons beyond my knowledge (and which should likely be fixed) 30#define DRV_MODULE_NAME "sun3x_esp"
112 sync mode doesn't work on a 3/80 at 5mhz. but it does at 4. */ 31#define PFX DRV_MODULE_NAME ": "
113 esp->sync_defp = 0x3f; 32#define DRV_VERSION "1.000"
33#define DRV_MODULE_RELDATE "Nov 1, 2007"
114 34
115 printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps, 35/*
116 esps_in_use); 36 * m68k always assumes readl/writel operate on little endian
117 esps_running = esps_in_use; 37 * mmio space; this is wrong at least for Sun3x, so we
118 return esps_in_use; 38 * need to workaround this until a proper way is found
39 */
40#if 0
41#define dma_read32(REG) \
42 readl(esp->dma_regs + (REG))
43#define dma_write32(VAL, REG) \
44 writel((VAL), esp->dma_regs + (REG))
45#else
46#define dma_read32(REG) \
47 *(volatile u32 *)(esp->dma_regs + (REG))
48#define dma_write32(VAL, REG) \
49 do { *(volatile u32 *)(esp->dma_regs + (REG)) = (VAL); } while (0)
50#endif
51
52static void sun3x_esp_write8(struct esp *esp, u8 val, unsigned long reg)
53{
54 writeb(val, esp->regs + (reg * 4UL));
119} 55}
120 56
121static void dma_do_drain(struct NCR_ESP *esp) 57static u8 sun3x_esp_read8(struct esp *esp, unsigned long reg)
122{ 58{
123 struct sparc_dma_registers *dregs = 59 return readb(esp->regs + (reg * 4UL));
124 (struct sparc_dma_registers *) esp->dregs;
125
126 int count = 500000;
127
128 while((dregs->cond_reg & DMA_PEND_READ) && (--count > 0))
129 udelay(1);
130
131 if(!count) {
132 printk("%s:%d timeout CSR %08lx\n", __FILE__, __LINE__, dregs->cond_reg);
133 }
134
135 dregs->cond_reg |= DMA_FIFO_STDRAIN;
136
137 count = 500000;
138
139 while((dregs->cond_reg & DMA_FIFO_ISDRAIN) && (--count > 0))
140 udelay(1);
141
142 if(!count) {
143 printk("%s:%d timeout CSR %08lx\n", __FILE__, __LINE__, dregs->cond_reg);
144 }
145
146} 60}
147 61
148static void dma_barrier(struct NCR_ESP *esp) 62static dma_addr_t sun3x_esp_map_single(struct esp *esp, void *buf,
63 size_t sz, int dir)
149{ 64{
150 struct sparc_dma_registers *dregs = 65 return dma_map_single(esp->dev, buf, sz, dir);
151 (struct sparc_dma_registers *) esp->dregs;
152 int count = 500000;
153
154 while((dregs->cond_reg & DMA_PEND_READ) && (--count > 0))
155 udelay(1);
156
157 if(!count) {
158 printk("%s:%d timeout CSR %08lx\n", __FILE__, __LINE__, dregs->cond_reg);
159 }
160
161 dregs->cond_reg &= ~(DMA_ENABLE);
162} 66}
163 67
164/* This uses various DMA csr fields and the fifo flags count value to 68static int sun3x_esp_map_sg(struct esp *esp, struct scatterlist *sg,
165 * determine how many bytes were successfully sent/received by the ESP. 69 int num_sg, int dir)
166 */
167static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
168{ 70{
169 struct sparc_dma_registers *dregs = 71 return dma_map_sg(esp->dev, sg, num_sg, dir);
170 (struct sparc_dma_registers *) esp->dregs;
171
172 int rval = dregs->st_addr - esp->esp_command_dvma;
173
174 return rval - fifo_count;
175} 72}
176 73
177static int dma_can_transfer(struct NCR_ESP *esp, Scsi_Cmnd *sp) 74static void sun3x_esp_unmap_single(struct esp *esp, dma_addr_t addr,
75 size_t sz, int dir)
178{ 76{
179 return sp->SCp.this_residual; 77 dma_unmap_single(esp->dev, addr, sz, dir);
180} 78}
181 79
182static void dma_drain(struct NCR_ESP *esp) 80static void sun3x_esp_unmap_sg(struct esp *esp, struct scatterlist *sg,
81 int num_sg, int dir)
183{ 82{
184 struct sparc_dma_registers *dregs = 83 dma_unmap_sg(esp->dev, sg, num_sg, dir);
185 (struct sparc_dma_registers *) esp->dregs;
186 int count = 500000;
187
188 if(dregs->cond_reg & DMA_FIFO_ISDRAIN) {
189 dregs->cond_reg |= DMA_FIFO_STDRAIN;
190 while((dregs->cond_reg & DMA_FIFO_ISDRAIN) && (--count > 0))
191 udelay(1);
192 if(!count) {
193 printk("%s:%d timeout CSR %08lx\n", __FILE__, __LINE__, dregs->cond_reg);
194 }
195
196 }
197} 84}
198 85
199static void dma_invalidate(struct NCR_ESP *esp) 86static int sun3x_esp_irq_pending(struct esp *esp)
200{ 87{
201 struct sparc_dma_registers *dregs = 88 if (dma_read32(DMA_CSR) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))
202 (struct sparc_dma_registers *) esp->dregs; 89 return 1;
203 90 return 0;
204 __u32 tmp; 91}
205 int count = 500000;
206
207 while(((tmp = dregs->cond_reg) & DMA_PEND_READ) && (--count > 0))
208 udelay(1);
209 92
210 if(!count) { 93static void sun3x_esp_reset_dma(struct esp *esp)
211 printk("%s:%d timeout CSR %08lx\n", __FILE__, __LINE__, dregs->cond_reg); 94{
212 } 95 u32 val;
213 96
214 dregs->cond_reg = tmp | DMA_FIFO_INV; 97 val = dma_read32(DMA_CSR);
215 dregs->cond_reg &= ~DMA_FIFO_INV; 98 dma_write32(val | DMA_RST_SCSI, DMA_CSR);
99 dma_write32(val & ~DMA_RST_SCSI, DMA_CSR);
216 100
101 /* Enable interrupts. */
102 val = dma_read32(DMA_CSR);
103 dma_write32(val | DMA_INT_ENAB, DMA_CSR);
217} 104}
218 105
219static void dma_dump_state(struct NCR_ESP *esp) 106static void sun3x_esp_dma_drain(struct esp *esp)
220{ 107{
221 struct sparc_dma_registers *dregs = 108 u32 csr;
222 (struct sparc_dma_registers *) esp->dregs; 109 int lim;
223 110
224 ESPLOG(("esp%d: dma -- cond_reg<%08lx> addr<%08lx>\n", 111 csr = dma_read32(DMA_CSR);
225 esp->esp_id, dregs->cond_reg, dregs->st_addr)); 112 if (!(csr & DMA_FIFO_ISDRAIN))
226} 113 return;
227 114
228static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length) 115 dma_write32(csr | DMA_FIFO_STDRAIN, DMA_CSR);
229{
230 struct sparc_dma_registers *dregs =
231 (struct sparc_dma_registers *) esp->dregs;
232 116
233 dregs->st_addr = vaddress; 117 lim = 1000;
234 dregs->cond_reg |= (DMA_ST_WRITE | DMA_ENABLE); 118 while (dma_read32(DMA_CSR) & DMA_FIFO_ISDRAIN) {
119 if (--lim == 0) {
120 printk(KERN_ALERT PFX "esp%d: DMA will not drain!\n",
121 esp->host->unique_id);
122 break;
123 }
124 udelay(1);
125 }
235} 126}
236 127
237static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length) 128static void sun3x_esp_dma_invalidate(struct esp *esp)
238{ 129{
239 struct sparc_dma_registers *dregs = 130 u32 val;
240 (struct sparc_dma_registers *) esp->dregs; 131 int lim;
241 132
242 /* Set up the DMA counters */ 133 lim = 1000;
134 while ((val = dma_read32(DMA_CSR)) & DMA_PEND_READ) {
135 if (--lim == 0) {
136 printk(KERN_ALERT PFX "esp%d: DMA will not "
137 "invalidate!\n", esp->host->unique_id);
138 break;
139 }
140 udelay(1);
141 }
243 142
244 dregs->st_addr = vaddress; 143 val &= ~(DMA_ENABLE | DMA_ST_WRITE | DMA_BCNT_ENAB);
245 dregs->cond_reg = ((dregs->cond_reg & ~(DMA_ST_WRITE)) | DMA_ENABLE); 144 val |= DMA_FIFO_INV;
145 dma_write32(val, DMA_CSR);
146 val &= ~DMA_FIFO_INV;
147 dma_write32(val, DMA_CSR);
246} 148}
247 149
248static void dma_ints_off(struct NCR_ESP *esp) 150static void sun3x_esp_send_dma_cmd(struct esp *esp, u32 addr, u32 esp_count,
151 u32 dma_count, int write, u8 cmd)
249{ 152{
250 DMA_INTSOFF((struct sparc_dma_registers *) esp->dregs); 153 u32 csr;
154
155 BUG_ON(!(cmd & ESP_CMD_DMA));
156
157 sun3x_esp_write8(esp, (esp_count >> 0) & 0xff, ESP_TCLOW);
158 sun3x_esp_write8(esp, (esp_count >> 8) & 0xff, ESP_TCMED);
159 csr = dma_read32(DMA_CSR);
160 csr |= DMA_ENABLE;
161 if (write)
162 csr |= DMA_ST_WRITE;
163 else
164 csr &= ~DMA_ST_WRITE;
165 dma_write32(csr, DMA_CSR);
166 dma_write32(addr, DMA_ADDR);
167
168 scsi_esp_cmd(esp, cmd);
251} 169}
252 170
253static void dma_ints_on(struct NCR_ESP *esp) 171static int sun3x_esp_dma_error(struct esp *esp)
254{ 172{
255 DMA_INTSON((struct sparc_dma_registers *) esp->dregs); 173 u32 csr = dma_read32(DMA_CSR);
256}
257 174
258static int dma_irq_p(struct NCR_ESP *esp) 175 if (csr & DMA_HNDL_ERROR)
259{ 176 return 1;
260 return DMA_IRQ_P((struct sparc_dma_registers *) esp->dregs); 177
178 return 0;
261} 179}
262 180
263static void dma_poll(struct NCR_ESP *esp, unsigned char *vaddr) 181static const struct esp_driver_ops sun3x_esp_ops = {
182 .esp_write8 = sun3x_esp_write8,
183 .esp_read8 = sun3x_esp_read8,
184 .map_single = sun3x_esp_map_single,
185 .map_sg = sun3x_esp_map_sg,
186 .unmap_single = sun3x_esp_unmap_single,
187 .unmap_sg = sun3x_esp_unmap_sg,
188 .irq_pending = sun3x_esp_irq_pending,
189 .reset_dma = sun3x_esp_reset_dma,
190 .dma_drain = sun3x_esp_dma_drain,
191 .dma_invalidate = sun3x_esp_dma_invalidate,
192 .send_dma_cmd = sun3x_esp_send_dma_cmd,
193 .dma_error = sun3x_esp_dma_error,
194};
195
196static int __devinit esp_sun3x_probe(struct platform_device *dev)
264{ 197{
265 int count = 50; 198 struct scsi_host_template *tpnt = &scsi_esp_template;
266 dma_do_drain(esp); 199 struct Scsi_Host *host;
200 struct esp *esp;
201 struct resource *res;
202 int err = -ENOMEM;
267 203
268 /* Wait till the first bits settle. */ 204 host = scsi_host_alloc(tpnt, sizeof(struct esp));
269 while((*(volatile unsigned char *)vaddr == 0xff) && (--count > 0)) 205 if (!host)
270 udelay(1); 206 goto fail;
271 207
272 if(!count) { 208 host->max_id = 8;
273// printk("%s:%d timeout expire (data %02x)\n", __FILE__, __LINE__, 209 esp = shost_priv(host);
274// esp_read(esp->eregs->esp_fdata));
275 //mach_halt();
276 vaddr[0] = esp_read(esp->eregs->esp_fdata);
277 vaddr[1] = esp_read(esp->eregs->esp_fdata);
278 }
279 210
280} 211 esp->host = host;
212 esp->dev = dev;
213 esp->ops = &sun3x_esp_ops;
281 214
282static int dma_ports_p(struct NCR_ESP *esp) 215 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
283{ 216 if (!res && !res->start)
284 return (((struct sparc_dma_registers *) esp->dregs)->cond_reg 217 goto fail_unlink;
285 & DMA_INT_ENAB);
286}
287 218
288/* Resetting various pieces of the ESP scsi driver chipset/buses. */ 219 esp->regs = ioremap_nocache(res->start, 0x20);
289static void dma_reset(struct NCR_ESP *esp) 220 if (!esp->regs)
290{ 221 goto fail_unmap_regs;
291 struct sparc_dma_registers *dregs =
292 (struct sparc_dma_registers *)esp->dregs;
293 222
294 /* Punt the DVMA into a known state. */ 223 res = platform_get_resource(dev, IORESOURCE_MEM, 1);
295 dregs->cond_reg |= DMA_RST_SCSI; 224 if (!res && !res->start)
296 dregs->cond_reg &= ~(DMA_RST_SCSI); 225 goto fail_unmap_regs;
297 DMA_INTSON(dregs);
298}
299 226
300static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) 227 esp->dma_regs = ioremap_nocache(res->start, 0x10);
301{
302 struct sparc_dma_registers *dregs =
303 (struct sparc_dma_registers *) esp->dregs;
304 unsigned long nreg = dregs->cond_reg;
305 228
306// printk("dma_setup %c addr %08x cnt %08x\n", 229 esp->command_block = dma_alloc_coherent(esp->dev, 16,
307// write ? 'W' : 'R', addr, count); 230 &esp->command_block_dma,
231 GFP_KERNEL);
232 if (!esp->command_block)
233 goto fail_unmap_regs_dma;
308 234
309 dma_do_drain(esp); 235 host->irq = platform_get_irq(dev, 0);
236 err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED,
237 "SUN3X ESP", esp);
238 if (err < 0)
239 goto fail_unmap_command_block;
310 240
311 if(write) 241 esp->scsi_id = 7;
312 nreg |= DMA_ST_WRITE; 242 esp->host->this_id = esp->scsi_id;
313 else { 243 esp->scsi_id_mask = (1 << esp->scsi_id);
314 nreg &= ~(DMA_ST_WRITE); 244 esp->cfreq = 20000000;
315 }
316
317 nreg |= DMA_ENABLE;
318 dregs->cond_reg = nreg;
319 dregs->st_addr = addr;
320}
321 245
322static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp) 246 dev_set_drvdata(&dev->dev, esp);
323{ 247
324 sp->SCp.have_data_in = dvma_map((unsigned long)sp->SCp.buffer, 248 err = scsi_esp_register(esp, &dev->dev);
325 sp->SCp.this_residual); 249 if (err)
326 sp->SCp.ptr = (char *)((unsigned long)sp->SCp.have_data_in); 250 goto fail_free_irq;
251
252 return 0;
253
254fail_free_irq:
255 free_irq(host->irq, esp);
256fail_unmap_command_block:
257 dma_free_coherent(esp->dev, 16,
258 esp->command_block,
259 esp->command_block_dma);
260fail_unmap_regs_dma:
261 iounmap(esp->dma_regs);
262fail_unmap_regs:
263 iounmap(esp->regs);
264fail_unlink:
265 scsi_host_put(host);
266fail:
267 return err;
327} 268}
328 269
329static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp) 270static int __devexit esp_sun3x_remove(struct platform_device *dev)
330{ 271{
331 int sz = sp->SCp.buffers_residual; 272 struct esp *esp = dev_get_drvdata(&dev->dev);
332 struct scatterlist *sg = sp->SCp.buffer; 273 unsigned int irq = esp->host->irq;
333 274 u32 val;
334 while (sz >= 0) {
335 sg[sz].dma_address = dvma_map((unsigned long)sg_virt(&sg[sz]),
336 sg[sz].length);
337 sz--;
338 }
339 sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dma_address);
340}
341 275
342static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp) 276 scsi_esp_unregister(esp);
343{
344 dvma_unmap((char *)sp->SCp.have_data_in);
345}
346 277
347static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp) 278 /* Disable interrupts. */
348{ 279 val = dma_read32(DMA_CSR);
349 int sz = sp->use_sg - 1; 280 dma_write32(val & ~DMA_INT_ENAB, DMA_CSR);
350 struct scatterlist *sg = (struct scatterlist *)sp->request_buffer;
351
352 while(sz >= 0) {
353 dvma_unmap((char *)sg[sz].dma_address);
354 sz--;
355 }
356}
357 281
358static void dma_advance_sg (Scsi_Cmnd *sp) 282 free_irq(irq, esp);
359{ 283 dma_free_coherent(esp->dev, 16,
360 sp->SCp.ptr = (char *)((unsigned long)sp->SCp.buffer->dma_address); 284 esp->command_block,
361} 285 esp->command_block_dma);
362 286
363static int sun3x_esp_release(struct Scsi_Host *instance) 287 scsi_host_put(esp->host);
364{
365 /* this code does not support being compiled as a module */
366 return 1;
367 288
289 return 0;
368} 290}
369 291
370static struct scsi_host_template driver_template = { 292static struct platform_driver esp_sun3x_driver = {
371 .proc_name = "sun3x_esp", 293 .probe = esp_sun3x_probe,
372 .proc_info = &esp_proc_info, 294 .remove = __devexit_p(esp_sun3x_remove),
373 .name = "Sun ESP 100/100a/200", 295 .driver = {
374 .detect = sun3x_esp_detect, 296 .name = "sun3x_esp",
375 .release = sun3x_esp_release, 297 },
376 .slave_alloc = esp_slave_alloc,
377 .slave_destroy = esp_slave_destroy,
378 .info = esp_info,
379 .queuecommand = esp_queue,
380 .eh_abort_handler = esp_abort,
381 .eh_bus_reset_handler = esp_reset,
382 .can_queue = 7,
383 .this_id = 7,
384 .sg_tablesize = SG_ALL,
385 .cmd_per_lun = 1,
386 .use_clustering = DISABLE_CLUSTERING,
387}; 298};
388 299
300static int __init sun3x_esp_init(void)
301{
302 return platform_driver_register(&esp_sun3x_driver);
303}
389 304
390#include "scsi_module.c" 305static void __exit sun3x_esp_exit(void)
306{
307 platform_driver_unregister(&esp_sun3x_driver);
308}
391 309
310MODULE_DESCRIPTION("Sun3x ESP SCSI driver");
311MODULE_AUTHOR("Thomas Bogendoerfer (tsbogend@alpha.franken.de)");
392MODULE_LICENSE("GPL"); 312MODULE_LICENSE("GPL");
313MODULE_VERSION(DRV_VERSION);
314
315module_init(sun3x_esp_init);
316module_exit(sun3x_esp_exit);