1 /* sun3x_esp.c: EnhancedScsiProcessor Sun3x SCSI driver code.
3 * (C) 1999 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
5 * Based on David S. Miller's esp driver
8 #include <linux/kernel.h>
9 #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>
16 #include <linux/interrupt.h>
22 #include <asm/sun3x.h>
26 extern struct NCR_ESP
*espchain
;
28 static void dma_barrier(struct NCR_ESP
*esp
);
29 static int dma_bytes_sent(struct NCR_ESP
*esp
, int fifo_count
);
30 static int dma_can_transfer(struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
);
31 static void dma_drain(struct NCR_ESP
*esp
);
32 static void dma_invalidate(struct NCR_ESP
*esp
);
33 static void dma_dump_state(struct NCR_ESP
*esp
);
34 static void dma_init_read(struct NCR_ESP
*esp
, __u32 vaddress
, int length
);
35 static void dma_init_write(struct NCR_ESP
*esp
, __u32 vaddress
, int length
);
36 static void dma_ints_off(struct NCR_ESP
*esp
);
37 static void dma_ints_on(struct NCR_ESP
*esp
);
38 static int dma_irq_p(struct NCR_ESP
*esp
);
39 static void dma_poll(struct NCR_ESP
*esp
, unsigned char *vaddr
);
40 static int dma_ports_p(struct NCR_ESP
*esp
);
41 static void dma_reset(struct NCR_ESP
*esp
);
42 static void dma_setup(struct NCR_ESP
*esp
, __u32 addr
, int count
, int write
);
43 static void dma_mmu_get_scsi_one (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
);
44 static void dma_mmu_get_scsi_sgl (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
);
45 static void dma_mmu_release_scsi_one (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
);
46 static void dma_mmu_release_scsi_sgl (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
);
47 static void dma_advance_sg (Scsi_Cmnd
*sp
);
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
55 /* Detecting ESP chips on the machine. This is the simple and easy
58 int sun3x_esp_detect(Scsi_Host_Template
*tpnt
)
61 struct ConfigDev
*esp_dev
;
64 esp
= esp_allocate(tpnt
, (void *) esp_dev
);
66 /* Do command transfer with DMA */
69 /* Required functions */
70 esp
->dma_bytes_sent
= &dma_bytes_sent
;
71 esp
->dma_can_transfer
= &dma_can_transfer
;
72 esp
->dma_dump_state
= &dma_dump_state
;
73 esp
->dma_init_read
= &dma_init_read
;
74 esp
->dma_init_write
= &dma_init_write
;
75 esp
->dma_ints_off
= &dma_ints_off
;
76 esp
->dma_ints_on
= &dma_ints_on
;
77 esp
->dma_irq_p
= &dma_irq_p
;
78 esp
->dma_ports_p
= &dma_ports_p
;
79 esp
->dma_setup
= &dma_setup
;
81 /* Optional functions */
82 esp
->dma_barrier
= &dma_barrier
;
83 esp
->dma_invalidate
= &dma_invalidate
;
84 esp
->dma_drain
= &dma_drain
;
85 esp
->dma_irq_entry
= 0;
86 esp
->dma_irq_exit
= 0;
89 esp
->dma_poll
= &dma_poll
;
90 esp
->dma_reset
= &dma_reset
;
92 /* virtual DMA functions */
93 esp
->dma_mmu_get_scsi_one
= &dma_mmu_get_scsi_one
;
94 esp
->dma_mmu_get_scsi_sgl
= &dma_mmu_get_scsi_sgl
;
95 esp
->dma_mmu_release_scsi_one
= &dma_mmu_release_scsi_one
;
96 esp
->dma_mmu_release_scsi_sgl
= &dma_mmu_release_scsi_sgl
;
97 esp
->dma_advance_sg
= &dma_advance_sg
;
100 esp
->cfreq
= 20000000;
101 esp
->eregs
= (struct ESP_regs
*)(SUN3X_ESP_BASE
);
102 esp
->dregs
= (void *)SUN3X_ESP_DMA
;
105 esp
->esp_command
= (volatile unsigned char *)cmd_buffer
;
106 esp
->esp_command_dvma
= dvma_map((unsigned long)cmd_buffer
,
107 sizeof (cmd_buffer
));
109 esp
->esp_command
= (volatile unsigned char *)dvma_malloc(DVMA_PAGE_SIZE
);
110 esp
->esp_command_dvma
= dvma_vtob((unsigned long)esp
->esp_command
);
114 if (request_irq(esp
->irq
, esp_intr
, SA_INTERRUPT
,
115 "SUN3X SCSI", esp
->ehost
)) {
125 /* for reasons beyond my knowledge (and which should likely be fixed)
126 sync mode doesn't work on a 3/80 at 5mhz. but it does at 4. */
127 esp
->sync_defp
= 0x3f;
129 printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps
,
131 esps_running
= esps_in_use
;
135 static void dma_do_drain(struct NCR_ESP
*esp
)
137 struct sparc_dma_registers
*dregs
=
138 (struct sparc_dma_registers
*) esp
->dregs
;
142 while((dregs
->cond_reg
& DMA_PEND_READ
) && (--count
> 0))
146 printk("%s:%d timeout CSR %08lx\n", __FILE__
, __LINE__
, dregs
->cond_reg
);
149 dregs
->cond_reg
|= DMA_FIFO_STDRAIN
;
153 while((dregs
->cond_reg
& DMA_FIFO_ISDRAIN
) && (--count
> 0))
157 printk("%s:%d timeout CSR %08lx\n", __FILE__
, __LINE__
, dregs
->cond_reg
);
162 static void dma_barrier(struct NCR_ESP
*esp
)
164 struct sparc_dma_registers
*dregs
=
165 (struct sparc_dma_registers
*) esp
->dregs
;
168 while((dregs
->cond_reg
& DMA_PEND_READ
) && (--count
> 0))
172 printk("%s:%d timeout CSR %08lx\n", __FILE__
, __LINE__
, dregs
->cond_reg
);
175 dregs
->cond_reg
&= ~(DMA_ENABLE
);
178 /* This uses various DMA csr fields and the fifo flags count value to
179 * determine how many bytes were successfully sent/received by the ESP.
181 static int dma_bytes_sent(struct NCR_ESP
*esp
, int fifo_count
)
183 struct sparc_dma_registers
*dregs
=
184 (struct sparc_dma_registers
*) esp
->dregs
;
186 int rval
= dregs
->st_addr
- esp
->esp_command_dvma
;
188 return rval
- fifo_count
;
191 static int dma_can_transfer(struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
)
193 return sp
->SCp
.this_residual
;
196 static void dma_drain(struct NCR_ESP
*esp
)
198 struct sparc_dma_registers
*dregs
=
199 (struct sparc_dma_registers
*) esp
->dregs
;
202 if(dregs
->cond_reg
& DMA_FIFO_ISDRAIN
) {
203 dregs
->cond_reg
|= DMA_FIFO_STDRAIN
;
204 while((dregs
->cond_reg
& DMA_FIFO_ISDRAIN
) && (--count
> 0))
207 printk("%s:%d timeout CSR %08lx\n", __FILE__
, __LINE__
, dregs
->cond_reg
);
213 static void dma_invalidate(struct NCR_ESP
*esp
)
215 struct sparc_dma_registers
*dregs
=
216 (struct sparc_dma_registers
*) esp
->dregs
;
221 while(((tmp
= dregs
->cond_reg
) & DMA_PEND_READ
) && (--count
> 0))
225 printk("%s:%d timeout CSR %08lx\n", __FILE__
, __LINE__
, dregs
->cond_reg
);
228 dregs
->cond_reg
= tmp
| DMA_FIFO_INV
;
229 dregs
->cond_reg
&= ~DMA_FIFO_INV
;
233 static void dma_dump_state(struct NCR_ESP
*esp
)
235 struct sparc_dma_registers
*dregs
=
236 (struct sparc_dma_registers
*) esp
->dregs
;
238 ESPLOG(("esp%d: dma -- cond_reg<%08lx> addr<%08lx>\n",
239 esp
->esp_id
, dregs
->cond_reg
, dregs
->st_addr
));
242 static void dma_init_read(struct NCR_ESP
*esp
, __u32 vaddress
, int length
)
244 struct sparc_dma_registers
*dregs
=
245 (struct sparc_dma_registers
*) esp
->dregs
;
247 dregs
->st_addr
= vaddress
;
248 dregs
->cond_reg
|= (DMA_ST_WRITE
| DMA_ENABLE
);
251 static void dma_init_write(struct NCR_ESP
*esp
, __u32 vaddress
, int length
)
253 struct sparc_dma_registers
*dregs
=
254 (struct sparc_dma_registers
*) esp
->dregs
;
256 /* Set up the DMA counters */
258 dregs
->st_addr
= vaddress
;
259 dregs
->cond_reg
= ((dregs
->cond_reg
& ~(DMA_ST_WRITE
)) | DMA_ENABLE
);
262 static void dma_ints_off(struct NCR_ESP
*esp
)
264 DMA_INTSOFF((struct sparc_dma_registers
*) esp
->dregs
);
267 static void dma_ints_on(struct NCR_ESP
*esp
)
269 DMA_INTSON((struct sparc_dma_registers
*) esp
->dregs
);
272 static int dma_irq_p(struct NCR_ESP
*esp
)
274 return DMA_IRQ_P((struct sparc_dma_registers
*) esp
->dregs
);
277 static void dma_poll(struct NCR_ESP
*esp
, unsigned char *vaddr
)
282 /* Wait till the first bits settle. */
283 while((*(volatile unsigned char *)vaddr
== 0xff) && (--count
> 0))
287 // printk("%s:%d timeout expire (data %02x)\n", __FILE__, __LINE__,
288 // esp_read(esp->eregs->esp_fdata));
290 vaddr
[0] = esp_read(esp
->eregs
->esp_fdata
);
291 vaddr
[1] = esp_read(esp
->eregs
->esp_fdata
);
296 static int dma_ports_p(struct NCR_ESP
*esp
)
298 return (((struct sparc_dma_registers
*) esp
->dregs
)->cond_reg
302 /* Resetting various pieces of the ESP scsi driver chipset/buses. */
303 static void dma_reset(struct NCR_ESP
*esp
)
305 struct sparc_dma_registers
*dregs
=
306 (struct sparc_dma_registers
*)esp
->dregs
;
308 /* Punt the DVMA into a known state. */
309 dregs
->cond_reg
|= DMA_RST_SCSI
;
310 dregs
->cond_reg
&= ~(DMA_RST_SCSI
);
314 static void dma_setup(struct NCR_ESP
*esp
, __u32 addr
, int count
, int write
)
316 struct sparc_dma_registers
*dregs
=
317 (struct sparc_dma_registers
*) esp
->dregs
;
318 unsigned long nreg
= dregs
->cond_reg
;
320 // printk("dma_setup %c addr %08x cnt %08x\n",
321 // write ? 'W' : 'R', addr, count);
326 nreg
|= DMA_ST_WRITE
;
328 nreg
&= ~(DMA_ST_WRITE
);
332 dregs
->cond_reg
= nreg
;
333 dregs
->st_addr
= addr
;
336 static void dma_mmu_get_scsi_one (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
)
338 sp
->SCp
.have_data_in
= dvma_map((unsigned long)sp
->SCp
.buffer
,
339 sp
->SCp
.this_residual
);
340 sp
->SCp
.ptr
= (char *)((unsigned long)sp
->SCp
.have_data_in
);
343 static void dma_mmu_get_scsi_sgl (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
)
345 int sz
= sp
->SCp
.buffers_residual
;
346 struct scatterlist
*sg
= sp
->SCp
.buffer
;
349 sg
[sz
].dvma_address
= dvma_map((unsigned long)page_address(sg
[sz
].page
) +
350 sg
[sz
].offset
, sg
[sz
].length
);
353 sp
->SCp
.ptr
=(char *)((unsigned long)sp
->SCp
.buffer
->dvma_address
);
356 static void dma_mmu_release_scsi_one (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
)
358 dvma_unmap((char *)sp
->SCp
.have_data_in
);
361 static void dma_mmu_release_scsi_sgl (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
)
363 int sz
= sp
->use_sg
- 1;
364 struct scatterlist
*sg
= (struct scatterlist
*)sp
->buffer
;
367 dvma_unmap((char *)sg
[sz
].dvma_address
);
372 static void dma_advance_sg (Scsi_Cmnd
*sp
)
374 sp
->SCp
.ptr
= (char *)((unsigned long)sp
->SCp
.buffer
->dvma_address
);
378 static int esp_slave_alloc(Scsi_Device
*SDptr
)
380 struct esp_device
*esp_dev
=
381 kmalloc(sizeof(struct esp_device
), GFP_ATOMIC
);
385 memset(esp_dev
, 0, sizeof(struct esp_device
));
386 SDptr
->hostdata
= esp_dev
;
390 static void esp_slave_destroy(Scsi_Device
*SDptr
)
392 struct NCR_ESP
*esp
= (struct NCR_ESP
*) SDptr
->host
->hostdata
;
394 esp
->targets_present
&= ~(1 << SDptr
->id
);
395 kfree(SDptr
->hostdata
);
396 SDptr
->hostdata
= NULL
;
400 static int sun3x_esp_release(struct Scsi_Host
*instance
)
402 /* this code does not support being compiled as a module */
407 static Scsi_Host_Template driver_template
= {
409 .proc_info
= &esp_proc_info
,
410 .name
= "Sun ESP 100/100a/200",
411 .detect
= sun3x_esp_detect
,
412 .release
= sun3x_esp_release
,
413 .slave_alloc
= esp_slave_alloc
,
414 .slave_destroy
= esp_slave_destroy
,
416 .queuecommand
= esp_queue
,
417 .eh_abort_handler
= esp_abort
,
418 .eh_bus_reset_handler
= esp_reset
,
421 .sg_tablesize
= SG_ALL
,
423 .use_clustering
= DISABLE_CLUSTERING
,
427 #include "scsi_module.c"
429 MODULE_LICENSE("GPL");