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/delay.h>
10 #include <linux/types.h>
11 #include <linux/string.h>
12 #include <linux/malloc.h>
13 #include <linux/blk.h>
14 #include <linux/proc_fs.h>
15 #include <linux/stat.h>
21 #include "sun3x_esp.h"
22 #include <asm/sun3x.h>
25 extern struct NCR_ESP
*espchain
;
27 static void dma_barrier(struct NCR_ESP
*esp
);
28 static int dma_bytes_sent(struct NCR_ESP
*esp
, int fifo_count
);
29 static int dma_can_transfer(struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
);
30 static void dma_drain(struct NCR_ESP
*esp
);
31 static void dma_dump_state(struct NCR_ESP
*esp
);
32 static void dma_init_read(struct NCR_ESP
*esp
, __u32 vaddress
, int length
);
33 static void dma_init_write(struct NCR_ESP
*esp
, __u32 vaddress
, int length
);
34 static void dma_ints_off(struct NCR_ESP
*esp
);
35 static void dma_ints_on(struct NCR_ESP
*esp
);
36 static int dma_irq_p(struct NCR_ESP
*esp
);
37 static void dma_poll(struct NCR_ESP
*esp
, unsigned char *vaddr
);
38 static int dma_ports_p(struct NCR_ESP
*esp
);
39 static void dma_reset(struct NCR_ESP
*esp
);
40 static void dma_setup(struct NCR_ESP
*esp
, __u32 addr
, int count
, int write
);
41 static void dma_mmu_get_scsi_one (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
);
42 static void dma_mmu_get_scsi_sgl (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
);
43 static void dma_mmu_release_scsi_one (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
);
44 static void dma_mmu_release_scsi_sgl (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
);
45 static void dma_advance_sg (Scsi_Cmnd
*sp
);
47 volatile unsigned char cmd_buffer
[16];
48 /* This is where all commands are put
49 * before they are trasfered to the ESP chip
53 /* Detecting ESP chips on the machine. This is the simple and easy
56 int sun3x_esp_detect(Scsi_Host_Template
*tpnt
)
59 struct ConfigDev
*esp_dev
;
62 esp
= esp_allocate(tpnt
, (void *) esp_dev
);
64 /* Do command transfer with DMA */
67 /* Required functions */
68 esp
->dma_bytes_sent
= &dma_bytes_sent
;
69 esp
->dma_can_transfer
= &dma_can_transfer
;
70 esp
->dma_dump_state
= &dma_dump_state
;
71 esp
->dma_init_read
= &dma_init_read
;
72 esp
->dma_init_write
= &dma_init_write
;
73 esp
->dma_ints_off
= &dma_ints_off
;
74 esp
->dma_ints_on
= &dma_ints_on
;
75 esp
->dma_irq_p
= &dma_irq_p
;
76 esp
->dma_ports_p
= &dma_ports_p
;
77 esp
->dma_setup
= &dma_setup
;
79 /* Optional functions */
80 esp
->dma_barrier
= &dma_barrier
;
81 esp
->dma_drain
= &dma_drain
;
82 esp
->dma_irq_entry
= &dma_ints_off
;
83 esp
->dma_irq_exit
= &dma_ints_on
;
86 esp
->dma_poll
= &dma_poll
;
87 esp
->dma_reset
= &dma_reset
;
89 /* virtual DMA functions */
90 esp
->dma_mmu_get_scsi_one
= &dma_mmu_get_scsi_one
;
91 esp
->dma_mmu_get_scsi_sgl
= &dma_mmu_get_scsi_sgl
;
92 esp
->dma_mmu_release_scsi_one
= &dma_mmu_release_scsi_one
;
93 esp
->dma_mmu_release_scsi_sgl
= &dma_mmu_release_scsi_sgl
;
94 esp
->dma_advance_sg
= &dma_advance_sg
;
97 esp
->cfreq
= 20000000;
98 esp
->eregs
= (struct ESP_regs
*)(SUN3X_ESP_BASE
);
99 esp
->dregs
= (void *)SUN3X_ESP_DMA
;
101 esp
->esp_command
= (volatile unsigned char *)cmd_buffer
;
102 esp
->esp_command_dvma
= dvma_alloc(virt_to_phys(cmd_buffer
),
103 sizeof (cmd_buffer
));
106 request_irq(esp
->irq
, esp_intr
, SA_INTERRUPT
, "SUN3X SCSI", NULL
);
113 printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps
,
115 esps_running
= esps_in_use
;
119 static void dma_barrier(struct NCR_ESP
*esp
)
121 struct sparc_dma_registers
*dregs
=
122 (struct sparc_dma_registers
*) esp
->dregs
;
124 while(dregs
->cond_reg
& DMA_PEND_READ
)
126 dregs
->cond_reg
&= ~(DMA_ENABLE
);
129 /* This uses various DMA csr fields and the fifo flags count value to
130 * determine how many bytes were successfully sent/received by the ESP.
132 static int dma_bytes_sent(struct NCR_ESP
*esp
, int fifo_count
)
134 struct sparc_dma_registers
*dregs
=
135 (struct sparc_dma_registers
*) esp
->dregs
;
137 int rval
= dregs
->st_addr
- esp
->esp_command_dvma
;
139 return rval
- fifo_count
;
142 static int dma_can_transfer(struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
)
146 base
= ((__u32
)sp
->SCp
.ptr
);
147 base
&= (0x1000000 - 1);
148 end
= (base
+ sp
->SCp
.this_residual
);
155 static void dma_drain(struct NCR_ESP
*esp
)
157 struct sparc_dma_registers
*dregs
=
158 (struct sparc_dma_registers
*) esp
->dregs
;
160 if(dregs
->cond_reg
& DMA_FIFO_ISDRAIN
) {
161 dregs
->cond_reg
|= DMA_FIFO_STDRAIN
;
162 while(dregs
->cond_reg
& DMA_FIFO_ISDRAIN
)
167 static void dma_dump_state(struct NCR_ESP
*esp
)
169 struct sparc_dma_registers
*dregs
=
170 (struct sparc_dma_registers
*) esp
->dregs
;
172 ESPLOG(("esp%d: dma -- cond_reg<%08lx> addr<%p>\n",
173 esp
->esp_id
, dregs
->cond_reg
, dregs
->st_addr
));
176 static void dma_init_read(struct NCR_ESP
*esp
, __u32 vaddress
, int length
)
178 struct sparc_dma_registers
*dregs
=
179 (struct sparc_dma_registers
*) esp
->dregs
;
181 dregs
->cond_reg
|= (DMA_ST_WRITE
| DMA_ENABLE
);
182 dregs
->st_addr
= vaddress
;
185 static void dma_init_write(struct NCR_ESP
*esp
, __u32 vaddress
, int length
)
187 struct sparc_dma_registers
*dregs
=
188 (struct sparc_dma_registers
*) esp
->dregs
;
190 /* Set up the DMA counters */
191 dregs
->cond_reg
= ((dregs
->cond_reg
& ~(DMA_ST_WRITE
)) | DMA_ENABLE
);
192 dregs
->st_addr
= vaddress
;
195 static void dma_ints_off(struct NCR_ESP
*esp
)
197 DMA_INTSOFF((struct sparc_dma_registers
*) esp
->dregs
);
200 static void dma_ints_on(struct NCR_ESP
*esp
)
202 DMA_INTSON((struct sparc_dma_registers
*) esp
->dregs
);
205 static int dma_irq_p(struct NCR_ESP
*esp
)
207 return DMA_IRQ_P((struct sparc_dma_registers
*) esp
->dregs
);
210 static void dma_poll(struct NCR_ESP
*esp
, unsigned char *vaddr
)
214 /* Wait till the first bits settle. */
215 while(vaddr
[0] == 0xff)
219 static int dma_ports_p(struct NCR_ESP
*esp
)
221 return (((struct sparc_dma_registers
*) esp
->dregs
)->cond_reg
225 /* Resetting various pieces of the ESP scsi driver chipset/buses. */
226 static void dma_reset(struct NCR_ESP
*esp
)
228 struct sparc_dma_registers
*dregs
=
229 (struct sparc_dma_registers
*)esp
->dregs
;
231 /* Punt the DVMA into a known state. */
232 dregs
->cond_reg
|= DMA_RST_SCSI
;
233 dregs
->cond_reg
&= ~(DMA_RST_SCSI
);
237 static void dma_setup(struct NCR_ESP
*esp
, __u32 addr
, int count
, int write
)
239 struct sparc_dma_registers
*dregs
=
240 (struct sparc_dma_registers
*) esp
->dregs
;
241 unsigned long nreg
= dregs
->cond_reg
;
244 nreg
|= DMA_ST_WRITE
;
246 nreg
&= ~(DMA_ST_WRITE
);
248 dregs
->cond_reg
= nreg
;
249 dregs
->st_addr
= addr
;
252 static void dma_mmu_get_scsi_one (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
)
254 sp
->SCp
.have_data_in
= dvma_alloc(virt_to_phys(sp
->SCp
.buffer
),
255 sp
->SCp
.this_residual
);
256 sp
->SCp
.ptr
= (char *)((unsigned long)sp
->SCp
.have_data_in
);
259 static void dma_mmu_get_scsi_sgl (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
)
261 int sz
= sp
->SCp
.buffers_residual
;
262 struct mmu_sglist
*sg
= (struct mmu_sglist
*) sp
->SCp
.buffer
;
265 sg
[sz
].dvma_addr
= dvma_alloc(virt_to_phys(sg
[sz
].addr
), sg
[sz
].len
);
268 sp
->SCp
.ptr
=(char *)((unsigned long)sp
->SCp
.buffer
->dvma_address
);
271 static void dma_mmu_release_scsi_one (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
)
273 dvma_free(sp
->SCp
.have_data_in
, sp
->request_bufflen
);
276 static void dma_mmu_release_scsi_sgl (struct NCR_ESP
*esp
, Scsi_Cmnd
*sp
)
278 int sz
= sp
->use_sg
- 1;
279 struct mmu_sglist
*sg
= (struct mmu_sglist
*)sp
->buffer
;
282 dvma_free(sg
[sz
].dvma_addr
,sg
[sz
].len
);
287 static void dma_advance_sg (Scsi_Cmnd
*sp
)
289 sp
->SCp
.ptr
= (char *)((unsigned long)sp
->SCp
.buffer
->dvma_address
);