2 * dec_esp.c: Driver for SCSI chips on IOASIC based TURBOchannel DECstations
3 * and TURBOchannel PMAZ-A cards
5 * TURBOchannel changes by Harald Koerfgen
6 * PMAZ-A support by David Airlie
9 * Copyright (C) 1997 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
11 * jazz_esp is based on David S. Miller's ESP driver and cyber_esp
13 * 20000819 - Small PMAZ-AA fixes by Florian Lohoff <flo@rfc822.org>
14 * Be warned the PMAZ-AA works currently as a single card.
15 * Dont try to put multiple cards in one machine - They are
16 * both detected but it may crash under high load garbling your
18 * 20001005 - Initialization fixes for 2.4.0-test9
19 * Florian Lohoff <flo@rfc822.org>
21 * Copyright (C) 2002, 2003 Maciej W. Rozycki
24 #include <linux/kernel.h>
25 #include <linux/delay.h>
26 #include <linux/types.h>
27 #include <linux/string.h>
28 #include <linux/slab.h>
29 #include <linux/blkdev.h>
30 #include <linux/proc_fs.h>
31 #include <linux/spinlock.h>
32 #include <linux/stat.h>
36 #include <asm/pgtable.h>
37 #include <asm/system.h>
39 #include <asm/dec/interrupts.h>
40 #include <asm/dec/ioasic.h>
41 #include <asm/dec/ioasic_addrs.h>
42 #include <asm/dec/ioasic_ints.h>
43 #include <asm/dec/machtype.h>
44 #include <asm/dec/tc.h>
46 #define DEC_SCSI_SREG 0
47 #define DEC_SCSI_DMAREG 0x40000
48 #define DEC_SCSI_SRAM 0x80000
49 #define DEC_SCSI_DIAG 0xC0000
52 #include <scsi/scsi_host.h>
55 static int dma_bytes_sent(struct NCR_ESP
*esp
, int fifo_count
);
56 static void dma_drain(struct NCR_ESP
*esp
);
57 static int dma_can_transfer(struct NCR_ESP
*esp
, struct scsi_cmnd
*sp
);
58 static void dma_dump_state(struct NCR_ESP
*esp
);
59 static void dma_init_read(struct NCR_ESP
*esp
, u32 vaddress
, int length
);
60 static void dma_init_write(struct NCR_ESP
*esp
, u32 vaddress
, int length
);
61 static void dma_ints_off(struct NCR_ESP
*esp
);
62 static void dma_ints_on(struct NCR_ESP
*esp
);
63 static int dma_irq_p(struct NCR_ESP
*esp
);
64 static int dma_ports_p(struct NCR_ESP
*esp
);
65 static void dma_setup(struct NCR_ESP
*esp
, u32 addr
, int count
, int write
);
66 static void dma_mmu_get_scsi_one(struct NCR_ESP
*esp
, struct scsi_cmnd
* sp
);
67 static void dma_mmu_get_scsi_sgl(struct NCR_ESP
*esp
, struct scsi_cmnd
* sp
);
68 static void dma_advance_sg(struct scsi_cmnd
* sp
);
70 static void pmaz_dma_drain(struct NCR_ESP
*esp
);
71 static void pmaz_dma_init_read(struct NCR_ESP
*esp
, u32 vaddress
, int length
);
72 static void pmaz_dma_init_write(struct NCR_ESP
*esp
, u32 vaddress
, int length
);
73 static void pmaz_dma_ints_off(struct NCR_ESP
*esp
);
74 static void pmaz_dma_ints_on(struct NCR_ESP
*esp
);
75 static void pmaz_dma_setup(struct NCR_ESP
*esp
, u32 addr
, int count
, int write
);
76 static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP
*esp
, struct scsi_cmnd
* sp
);
78 #define TC_ESP_RAM_SIZE 0x20000
79 #define ESP_TGT_DMA_SIZE ((TC_ESP_RAM_SIZE/7) & ~(sizeof(int)-1))
82 #define TC_ESP_DMAR_MASK 0x1ffff
83 #define TC_ESP_DMAR_WRITE 0x80000000
84 #define TC_ESP_DMA_ADDR(x) ((unsigned)(x) & TC_ESP_DMAR_MASK)
87 int scsi_current_length
;
89 volatile unsigned char cmd_buffer
[16];
90 volatile unsigned char pmaz_cmd_buffer
[16];
91 /* This is where all commands are put
92 * before they are trasfered to the ESP chip
96 static irqreturn_t
scsi_dma_merr_int(int, void *, struct pt_regs
*);
97 static irqreturn_t
scsi_dma_err_int(int, void *, struct pt_regs
*);
98 static irqreturn_t
scsi_dma_int(int, void *, struct pt_regs
*);
100 static int dec_esp_detect(struct scsi_host_template
* tpnt
);
102 static int dec_esp_release(struct Scsi_Host
*shost
)
105 free_irq(shost
->irq
, NULL
);
106 if (shost
->io_port
&& shost
->n_io_port
)
107 release_region(shost
->io_port
, shost
->n_io_port
);
108 scsi_unregister(shost
);
112 static struct scsi_host_template driver_template
= {
113 .proc_name
= "dec_esp",
114 .proc_info
= esp_proc_info
,
116 .detect
= dec_esp_detect
,
117 .slave_alloc
= esp_slave_alloc
,
118 .slave_destroy
= esp_slave_destroy
,
119 .release
= dec_esp_release
,
121 .queuecommand
= esp_queue
,
122 .eh_abort_handler
= esp_abort
,
123 .eh_bus_reset_handler
= esp_reset
,
126 .sg_tablesize
= SG_ALL
,
128 .use_clustering
= DISABLE_CLUSTERING
,
132 #include "scsi_module.c"
134 /***************************************************************** Detection */
135 static int dec_esp_detect(Scsi_Host_Template
* tpnt
)
138 struct ConfigDev
*esp_dev
;
140 unsigned long mem_start
;
144 esp
= esp_allocate(tpnt
, (void *) esp_dev
);
146 /* Do command transfer with programmed I/O */
147 esp
->do_pio_cmds
= 1;
149 /* Required functions */
150 esp
->dma_bytes_sent
= &dma_bytes_sent
;
151 esp
->dma_can_transfer
= &dma_can_transfer
;
152 esp
->dma_dump_state
= &dma_dump_state
;
153 esp
->dma_init_read
= &dma_init_read
;
154 esp
->dma_init_write
= &dma_init_write
;
155 esp
->dma_ints_off
= &dma_ints_off
;
156 esp
->dma_ints_on
= &dma_ints_on
;
157 esp
->dma_irq_p
= &dma_irq_p
;
158 esp
->dma_ports_p
= &dma_ports_p
;
159 esp
->dma_setup
= &dma_setup
;
161 /* Optional functions */
162 esp
->dma_barrier
= 0;
163 esp
->dma_drain
= &dma_drain
;
164 esp
->dma_invalidate
= 0;
165 esp
->dma_irq_entry
= 0;
166 esp
->dma_irq_exit
= 0;
169 esp
->dma_led_off
= 0;
172 /* virtual DMA functions */
173 esp
->dma_mmu_get_scsi_one
= &dma_mmu_get_scsi_one
;
174 esp
->dma_mmu_get_scsi_sgl
= &dma_mmu_get_scsi_sgl
;
175 esp
->dma_mmu_release_scsi_one
= 0;
176 esp
->dma_mmu_release_scsi_sgl
= 0;
177 esp
->dma_advance_sg
= &dma_advance_sg
;
180 /* SCSI chip speed */
181 esp
->cfreq
= 25000000;
185 /* ESP register base */
186 esp
->eregs
= (struct ESP_regs
*) (system_base
+ IOASIC_SCSI
);
188 /* Set the command buffer */
189 esp
->esp_command
= (volatile unsigned char *) cmd_buffer
;
191 /* get virtual dma address for command buffer */
192 esp
->esp_command_dvma
= virt_to_phys(cmd_buffer
);
194 esp
->irq
= dec_interrupt
[DEC_IRQ_ASC
];
198 /* Check for differential SCSI-bus */
203 if (request_irq(esp
->irq
, esp_intr
, SA_INTERRUPT
,
204 "ncr53c94", esp
->ehost
))
206 if (request_irq(dec_interrupt
[DEC_IRQ_ASC_MERR
],
207 scsi_dma_merr_int
, SA_INTERRUPT
,
208 "ncr53c94 error", esp
->ehost
))
210 if (request_irq(dec_interrupt
[DEC_IRQ_ASC_ERR
],
211 scsi_dma_err_int
, SA_INTERRUPT
,
212 "ncr53c94 overrun", esp
->ehost
))
213 goto err_free_irq_merr
;
214 if (request_irq(dec_interrupt
[DEC_IRQ_ASC_DMA
],
215 scsi_dma_int
, SA_INTERRUPT
,
216 "ncr53c94 dma", esp
->ehost
))
217 goto err_free_irq_err
;
222 while ((slot
= search_tc_card("PMAZ-AA")) >= 0) {
226 esp
= esp_allocate(tpnt
, (void *) esp_dev
);
228 mem_start
= get_tc_base_addr(slot
);
230 /* Store base addr into esp struct */
231 esp
->slot
= PHYSADDR(mem_start
);
234 esp
->eregs
= (struct ESP_regs
*) (mem_start
+ DEC_SCSI_SREG
);
235 esp
->do_pio_cmds
= 1;
237 /* Set the command buffer */
238 esp
->esp_command
= (volatile unsigned char *) pmaz_cmd_buffer
;
240 /* get virtual dma address for command buffer */
241 esp
->esp_command_dvma
= virt_to_phys(pmaz_cmd_buffer
);
243 esp
->cfreq
= get_tc_speed();
245 esp
->irq
= get_tc_irq_nr(slot
);
247 /* Required functions */
248 esp
->dma_bytes_sent
= &dma_bytes_sent
;
249 esp
->dma_can_transfer
= &dma_can_transfer
;
250 esp
->dma_dump_state
= &dma_dump_state
;
251 esp
->dma_init_read
= &pmaz_dma_init_read
;
252 esp
->dma_init_write
= &pmaz_dma_init_write
;
253 esp
->dma_ints_off
= &pmaz_dma_ints_off
;
254 esp
->dma_ints_on
= &pmaz_dma_ints_on
;
255 esp
->dma_irq_p
= &dma_irq_p
;
256 esp
->dma_ports_p
= &dma_ports_p
;
257 esp
->dma_setup
= &pmaz_dma_setup
;
259 /* Optional functions */
260 esp
->dma_barrier
= 0;
261 esp
->dma_drain
= &pmaz_dma_drain
;
262 esp
->dma_invalidate
= 0;
263 esp
->dma_irq_entry
= 0;
264 esp
->dma_irq_exit
= 0;
267 esp
->dma_led_off
= 0;
270 esp
->dma_mmu_get_scsi_one
= pmaz_dma_mmu_get_scsi_one
;
271 esp
->dma_mmu_get_scsi_sgl
= 0;
272 esp
->dma_mmu_release_scsi_one
= 0;
273 esp
->dma_mmu_release_scsi_sgl
= 0;
274 esp
->dma_advance_sg
= 0;
276 if (request_irq(esp
->irq
, esp_intr
, SA_INTERRUPT
,
277 "PMAZ_AA", esp
->ehost
)) {
279 release_tc_card(slot
);
289 printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps
, esps_in_use
);
290 esps_running
= esps_in_use
;
296 free_irq(dec_interrupt
[DEC_IRQ_ASC_ERR
], scsi_dma_err_int
);
298 free_irq(dec_interrupt
[DEC_IRQ_ASC_MERR
], scsi_dma_merr_int
);
300 free_irq(esp
->irq
, esp_intr
);
306 /************************************************************* DMA Functions */
307 static irqreturn_t
scsi_dma_merr_int(int irq
, void *dev_id
, struct pt_regs
*regs
)
309 printk("Got unexpected SCSI DMA Interrupt! < ");
310 printk("SCSI_DMA_MEMRDERR ");
316 static irqreturn_t
scsi_dma_err_int(int irq
, void *dev_id
, struct pt_regs
*regs
)
323 static irqreturn_t
scsi_dma_int(int irq
, void *dev_id
, struct pt_regs
*regs
)
327 scsi_next_ptr
= ioasic_read(IO_REG_SCSI_DMA_P
);
330 scsi_next_ptr
= (((scsi_next_ptr
>> 3) + PAGE_SIZE
) & PAGE_MASK
) << 3;
331 ioasic_write(IO_REG_SCSI_DMA_BP
, scsi_next_ptr
);
337 static int dma_bytes_sent(struct NCR_ESP
*esp
, int fifo_count
)
342 static void dma_drain(struct NCR_ESP
*esp
)
344 u32 nw
, data0
, data1
, scsi_data_ptr
;
347 nw
= ioasic_read(IO_REG_SCSI_SCR
);
350 * Is there something in the dma buffers left?
353 scsi_data_ptr
= ioasic_read(IO_REG_SCSI_DMA_P
) >> 3;
354 p
= phys_to_virt(scsi_data_ptr
);
357 data0
= ioasic_read(IO_REG_SCSI_SDR0
);
358 p
[0] = data0
& 0xffff;
361 data0
= ioasic_read(IO_REG_SCSI_SDR0
);
362 p
[0] = data0
& 0xffff;
363 p
[1] = (data0
>> 16) & 0xffff;
366 data0
= ioasic_read(IO_REG_SCSI_SDR0
);
367 data1
= ioasic_read(IO_REG_SCSI_SDR1
);
368 p
[0] = data0
& 0xffff;
369 p
[1] = (data0
>> 16) & 0xffff;
370 p
[2] = data1
& 0xffff;
373 printk("Strange: %d words in dma buffer left\n", nw
);
379 static int dma_can_transfer(struct NCR_ESP
*esp
, struct scsi_cmnd
* sp
)
381 return sp
->SCp
.this_residual
;
384 static void dma_dump_state(struct NCR_ESP
*esp
)
388 static void dma_init_read(struct NCR_ESP
*esp
, u32 vaddress
, int length
)
390 u32 scsi_next_ptr
, ioasic_ssr
;
394 panic("dec_esp.c: unable to handle partial word transfers, yet...");
396 dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress
), length
);
398 spin_lock_irqsave(&ioasic_ssr_lock
, flags
);
401 ioasic_ssr
= ioasic_read(IO_REG_SSR
);
403 ioasic_ssr
&= ~IO_SSR_SCSI_DMA_EN
;
404 ioasic_write(IO_REG_SSR
, ioasic_ssr
);
407 ioasic_write(IO_REG_SCSI_SCR
, 0);
408 ioasic_write(IO_REG_SCSI_DMA_P
, vaddress
<< 3);
410 /* prepare for next page */
411 scsi_next_ptr
= ((vaddress
+ PAGE_SIZE
) & PAGE_MASK
) << 3;
412 ioasic_write(IO_REG_SCSI_DMA_BP
, scsi_next_ptr
);
414 ioasic_ssr
|= (IO_SSR_SCSI_DMA_DIR
| IO_SSR_SCSI_DMA_EN
);
416 ioasic_write(IO_REG_SSR
, ioasic_ssr
);
419 spin_unlock_irqrestore(&ioasic_ssr_lock
, flags
);
422 static void dma_init_write(struct NCR_ESP
*esp
, u32 vaddress
, int length
)
424 u32 scsi_next_ptr
, ioasic_ssr
;
428 panic("dec_esp.c: unable to handle partial word transfers, yet...");
430 dma_cache_wback_inv((unsigned long) phys_to_virt(vaddress
), length
);
432 spin_lock_irqsave(&ioasic_ssr_lock
, flags
);
435 ioasic_ssr
= ioasic_read(IO_REG_SSR
);
437 ioasic_ssr
&= ~(IO_SSR_SCSI_DMA_DIR
| IO_SSR_SCSI_DMA_EN
);
438 ioasic_write(IO_REG_SSR
, ioasic_ssr
);
441 ioasic_write(IO_REG_SCSI_SCR
, 0);
442 ioasic_write(IO_REG_SCSI_DMA_P
, vaddress
<< 3);
444 /* prepare for next page */
445 scsi_next_ptr
= ((vaddress
+ PAGE_SIZE
) & PAGE_MASK
) << 3;
446 ioasic_write(IO_REG_SCSI_DMA_BP
, scsi_next_ptr
);
448 ioasic_ssr
|= IO_SSR_SCSI_DMA_EN
;
450 ioasic_write(IO_REG_SSR
, ioasic_ssr
);
453 spin_unlock_irqrestore(&ioasic_ssr_lock
, flags
);
456 static void dma_ints_off(struct NCR_ESP
*esp
)
458 disable_irq(dec_interrupt
[DEC_IRQ_ASC_DMA
]);
461 static void dma_ints_on(struct NCR_ESP
*esp
)
463 enable_irq(dec_interrupt
[DEC_IRQ_ASC_DMA
]);
466 static int dma_irq_p(struct NCR_ESP
*esp
)
468 return (esp
->eregs
->esp_status
& ESP_STAT_INTR
);
471 static int dma_ports_p(struct NCR_ESP
*esp
)
474 * FIXME: what's this good for?
479 static void dma_setup(struct NCR_ESP
*esp
, u32 addr
, int count
, int write
)
482 * DMA_ST_WRITE means "move data from device to memory"
483 * so when (write) is true, it actually means READ!
486 dma_init_read(esp
, addr
, count
);
488 dma_init_write(esp
, addr
, count
);
491 static void dma_mmu_get_scsi_one(struct NCR_ESP
*esp
, struct scsi_cmnd
* sp
)
493 sp
->SCp
.ptr
= (char *)virt_to_phys(sp
->request_buffer
);
496 static void dma_mmu_get_scsi_sgl(struct NCR_ESP
*esp
, struct scsi_cmnd
* sp
)
498 int sz
= sp
->SCp
.buffers_residual
;
499 struct scatterlist
*sg
= sp
->SCp
.buffer
;
502 sg
[sz
].dma_address
= page_to_phys(sg
[sz
].page
) + sg
[sz
].offset
;
505 sp
->SCp
.ptr
= (char *)(sp
->SCp
.buffer
->dma_address
);
508 static void dma_advance_sg(struct scsi_cmnd
* sp
)
510 sp
->SCp
.ptr
= (char *)(sp
->SCp
.buffer
->dma_address
);
513 static void pmaz_dma_drain(struct NCR_ESP
*esp
)
515 memcpy(phys_to_virt(esp_virt_buffer
),
516 (void *)KSEG1ADDR(esp
->slot
+ DEC_SCSI_SRAM
+ ESP_TGT_DMA_SIZE
),
517 scsi_current_length
);
520 static void pmaz_dma_init_read(struct NCR_ESP
*esp
, u32 vaddress
, int length
)
522 volatile u32
*dmareg
=
523 (volatile u32
*)KSEG1ADDR(esp
->slot
+ DEC_SCSI_DMAREG
);
525 if (length
> ESP_TGT_DMA_SIZE
)
526 length
= ESP_TGT_DMA_SIZE
;
528 *dmareg
= TC_ESP_DMA_ADDR(ESP_TGT_DMA_SIZE
);
532 esp_virt_buffer
= vaddress
;
533 scsi_current_length
= length
;
536 static void pmaz_dma_init_write(struct NCR_ESP
*esp
, u32 vaddress
, int length
)
538 volatile u32
*dmareg
=
539 (volatile u32
*)KSEG1ADDR(esp
->slot
+ DEC_SCSI_DMAREG
);
541 memcpy((void *)KSEG1ADDR(esp
->slot
+ DEC_SCSI_SRAM
+ ESP_TGT_DMA_SIZE
),
542 phys_to_virt(vaddress
), length
);
545 *dmareg
= TC_ESP_DMAR_WRITE
| TC_ESP_DMA_ADDR(ESP_TGT_DMA_SIZE
);
550 static void pmaz_dma_ints_off(struct NCR_ESP
*esp
)
554 static void pmaz_dma_ints_on(struct NCR_ESP
*esp
)
558 static void pmaz_dma_setup(struct NCR_ESP
*esp
, u32 addr
, int count
, int write
)
561 * DMA_ST_WRITE means "move data from device to memory"
562 * so when (write) is true, it actually means READ!
565 pmaz_dma_init_read(esp
, addr
, count
);
567 pmaz_dma_init_write(esp
, addr
, count
);
570 static void pmaz_dma_mmu_get_scsi_one(struct NCR_ESP
*esp
, struct scsi_cmnd
* sp
)
572 sp
->SCp
.ptr
= (char *)virt_to_phys(sp
->request_buffer
);