diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-29 17:03:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-29 17:03:42 -0400 |
commit | 6e98ee75c3ab99db48ecc0615c2246dc193111a9 (patch) | |
tree | afdad9dc968ebef3787e7dc16a41290a525f18f5 /drivers/scsi | |
parent | 486b4ce13221aa6cd0cbc9fff6993f444d8a52b5 (diff) | |
parent | 7db35f31cbb8ca1dbaba03d74b7db79ace084358 (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/Kconfig | 14 | ||||
-rw-r--r-- | drivers/scsi/Makefile | 5 | ||||
-rw-r--r-- | drivers/scsi/jazz_esp.c | 429 | ||||
-rw-r--r-- | drivers/scsi/pluto.c | 18 |
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 | ||
1756 | config 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 | |||
1769 | config SCSI_SUNESP | 1756 | config 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 | |||
106 | obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/ | 106 | obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/ |
107 | obj-$(CONFIG_MEGARAID_SAS) += megaraid/ | 107 | obj-$(CONFIG_MEGARAID_SAS) += megaraid/ |
108 | obj-$(CONFIG_SCSI_ACARD) += atp870u.o | 108 | obj-$(CONFIG_SCSI_ACARD) += atp870u.o |
109 | obj-$(CONFIG_SCSI_ESP_CORE) += esp_scsi.o | 109 | obj-$(CONFIG_SCSI_SUNESP) += esp_scsi.o sun_esp.o |
110 | obj-$(CONFIG_SCSI_SUNESP) += sun_esp.o | ||
111 | obj-$(CONFIG_SCSI_GDTH) += gdth.o | 110 | obj-$(CONFIG_SCSI_GDTH) += gdth.o |
112 | obj-$(CONFIG_SCSI_INITIO) += initio.o | 111 | obj-$(CONFIG_SCSI_INITIO) += initio.o |
113 | obj-$(CONFIG_SCSI_INIA100) += a100u2w.o | 112 | obj-$(CONFIG_SCSI_INIA100) += a100u2w.o |
@@ -121,7 +120,7 @@ obj-$(CONFIG_BLK_DEV_3W_XXXX_RAID) += 3w-xxxx.o | |||
121 | obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o | 120 | obj-$(CONFIG_SCSI_3W_9XXX) += 3w-9xxx.o |
122 | obj-$(CONFIG_SCSI_PPA) += ppa.o | 121 | obj-$(CONFIG_SCSI_PPA) += ppa.o |
123 | obj-$(CONFIG_SCSI_IMM) += imm.o | 122 | obj-$(CONFIG_SCSI_IMM) += imm.o |
124 | obj-$(CONFIG_JAZZ_ESP) += NCR53C9x.o jazz_esp.o | 123 | obj-$(CONFIG_JAZZ_ESP) += esp_scsi.o jazz_esp.o |
125 | obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o | 124 | obj-$(CONFIG_SUN3X_ESP) += NCR53C9x.o sun3x_esp.o |
126 | obj-$(CONFIG_SCSI_FCAL) += fcal.o | 125 | obj-$(CONFIG_SCSI_FCAL) += fcal.o |
127 | obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o | 126 | obj-$(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 | |||
30 | static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count); | ||
31 | static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp); | ||
32 | static void dma_dump_state(struct NCR_ESP *esp); | ||
33 | static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length); | ||
34 | static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length); | ||
35 | static void dma_ints_off(struct NCR_ESP *esp); | ||
36 | static void dma_ints_on(struct NCR_ESP *esp); | ||
37 | static int dma_irq_p(struct NCR_ESP *esp); | ||
38 | static int dma_ports_p(struct NCR_ESP *esp); | ||
39 | static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write); | ||
40 | static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp); | ||
41 | static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp); | ||
42 | static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp); | ||
43 | static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp); | ||
44 | static void dma_advance_sg (struct scsi_cmnd *sp); | ||
45 | static void dma_led_off(struct NCR_ESP *); | ||
46 | static void dma_led_on(struct NCR_ESP *); | ||
47 | |||
48 | |||
49 | static 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 | |||
55 | static 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" |
68 | static 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 */ | 30 | static void jazz_esp_write8(struct esp *esp, u8 val, unsigned long reg) |
156 | static 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 | ||
161 | static int dma_can_transfer(struct NCR_ESP *esp, struct scsi_cmnd *sp) | 35 | static 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 | ||
172 | static void dma_dump_state(struct NCR_ESP *esp) | 40 | static 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 | ||
179 | static void dma_init_read(struct NCR_ESP *esp, __u32 vaddress, int length) | 46 | static 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 | ||
189 | static void dma_init_write(struct NCR_ESP *esp, __u32 vaddress, int length) | 52 | static 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 | ||
199 | static void dma_ints_off(struct NCR_ESP *esp) | 58 | static 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 | ||
204 | static void dma_ints_on(struct NCR_ESP *esp) | 64 | static 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 | ||
209 | static int dma_irq_p(struct NCR_ESP *esp) | 71 | static 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 | ||
214 | static int dma_ports_p(struct NCR_ESP *esp) | 76 | static 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 | ||
221 | static void dma_setup(struct NCR_ESP *esp, __u32 addr, int count, int write) | 81 | static 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 | ||
234 | static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp) | 86 | static 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 | ||
240 | static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp) | 106 | static 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 | |||
252 | static 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 | ||
257 | static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp) | 116 | static 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 | |||
131 | static 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 | |||
190 | fail_free_irq: | ||
191 | free_irq(host->irq, esp); | ||
192 | fail_unmap_command_block: | ||
193 | dma_free_coherent(esp->dev, 16, | ||
194 | esp->command_block, | ||
195 | esp->command_block_dma); | ||
196 | fail_unmap_regs: | ||
197 | fail_unlink: | ||
198 | scsi_host_put(host); | ||
199 | fail: | ||
200 | return err; | ||
266 | } | 201 | } |
267 | 202 | ||
268 | static void dma_advance_sg (struct scsi_cmnd *sp) | 203 | static 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 */ | 220 | static 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 | ||
275 | static void dma_led_off(struct NCR_ESP *esp) | 228 | static 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 | ||
282 | static void dma_led_on(struct NCR_ESP *esp) | 233 | static 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 | ||
289 | static struct scsi_host_template driver_template = { | 238 | MODULE_DESCRIPTION("JAZZ ESP SCSI driver"); |
290 | .proc_name = "jazz_esp", | 239 | MODULE_AUTHOR("Thomas Bogendoerfer (tsbogend@alpha.franken.de)"); |
291 | .proc_info = esp_proc_info, | 240 | MODULE_LICENSE("GPL"); |
292 | .name = "ESP 100/100a/200", | 241 | MODULE_VERSION(DRV_VERSION); |
293 | .detect = jazz_esp_detect, | 242 | |
294 | .slave_alloc = esp_slave_alloc, | 243 | module_init(jazz_esp_init); |
295 | .slave_destroy = esp_slave_destroy, | 244 | module_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; |
51 | static int fcscount __initdata = 0; | 52 | static int fcscount __initdata = 0; |
52 | static atomic_t fcss __initdata = ATOMIC_INIT(0); | 53 | static atomic_t fcss __initdata = ATOMIC_INIT(0); |
53 | DECLARE_MUTEX_LOCKED(fc_sem); | 54 | static DECLARE_COMPLETION(fc_detect_complete); |
54 | 55 | ||
55 | static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd); | 56 | static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd); |
56 | 57 | ||
57 | static void __init pluto_detect_timeout(unsigned long data) | ||
58 | { | ||
59 | PLND(("Timeout\n")) | ||
60 | up(&fc_sem); | ||
61 | } | ||
62 | |||
63 | static void __init pluto_detect_done(Scsi_Cmnd *SCpnt) | 58 | static 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 | ||
75 | int pluto_slave_configure(struct scsi_device *device) | 70 | int 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++) { |