2 * linux/drivers/block/icside.c
4 * Copyright (c) 1996,1997 Russell King.
7 * 08-Jun-1996 RMK Created
8 * 12-Sep-1997 RMK Added interrupt enable/disable
9 * 17-Apr-1999 RMK Added support for V6 EASI
10 * 22-May-1999 RMK Added support for V6 DMA
13 #include <linux/config.h>
14 #include <linux/string.h>
15 #include <linux/module.h>
16 #include <linux/ioport.h>
17 #include <linux/malloc.h>
18 #include <linux/blkdev.h>
19 #include <linux/errno.h>
20 #include <linux/hdreg.h>
21 #include <linux/ide.h>
24 #include <asm/ecard.h>
28 * Maximum number of interfaces per card
32 #define ICS_IDENT_OFFSET 0x8a0
34 #define ICS_ARCIN_V5_INTRSTAT 0x000
35 #define ICS_ARCIN_V5_INTROFFSET 0x001
36 #define ICS_ARCIN_V5_IDEOFFSET 0xa00
37 #define ICS_ARCIN_V5_IDEALTOFFSET 0xae0
38 #define ICS_ARCIN_V5_IDESTEPPING 4
40 #define ICS_ARCIN_V6_IDEOFFSET_1 0x800
41 #define ICS_ARCIN_V6_INTROFFSET_1 0x880
42 #define ICS_ARCIN_V6_INTRSTAT_1 0x8a4
43 #define ICS_ARCIN_V6_IDEALTOFFSET_1 0x8e0
44 #define ICS_ARCIN_V6_IDEOFFSET_2 0xc00
45 #define ICS_ARCIN_V6_INTROFFSET_2 0xc80
46 #define ICS_ARCIN_V6_INTRSTAT_2 0xca4
47 #define ICS_ARCIN_V6_IDEALTOFFSET_2 0xce0
48 #define ICS_ARCIN_V6_IDESTEPPING 4
51 unsigned int dataoffset
;
52 unsigned int ctrloffset
;
53 unsigned int stepping
;
56 static struct cardinfo icside_cardinfo_v5
= {
57 ICS_ARCIN_V5_IDEOFFSET
,
58 ICS_ARCIN_V5_IDEALTOFFSET
,
59 ICS_ARCIN_V5_IDESTEPPING
62 static struct cardinfo icside_cardinfo_v6_1
= {
63 ICS_ARCIN_V6_IDEOFFSET_1
,
64 ICS_ARCIN_V6_IDEALTOFFSET_1
,
65 ICS_ARCIN_V6_IDESTEPPING
68 static struct cardinfo icside_cardinfo_v6_2
= {
69 ICS_ARCIN_V6_IDEOFFSET_2
,
70 ICS_ARCIN_V6_IDEALTOFFSET_2
,
71 ICS_ARCIN_V6_IDESTEPPING
74 static const card_ids icside_cids
[] = {
75 { MANU_ICS
, PROD_ICS_IDE
},
76 { MANU_ICS2
, PROD_ICS2_IDE
},
86 /* ---------------- Version 5 PCB Support Functions --------------------- */
87 /* Prototype: icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
88 * Purpose : enable interrupts from card
90 static void icside_irqenable_arcin_v5 (struct expansion_card
*ec
, int irqnr
)
92 unsigned int memc_port
= (unsigned int)ec
->irq_data
;
93 outb (0, memc_port
+ ICS_ARCIN_V5_INTROFFSET
);
96 /* Prototype: icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
97 * Purpose : disable interrupts from card
99 static void icside_irqdisable_arcin_v5 (struct expansion_card
*ec
, int irqnr
)
101 unsigned int memc_port
= (unsigned int)ec
->irq_data
;
102 inb (memc_port
+ ICS_ARCIN_V5_INTROFFSET
);
105 static const expansioncard_ops_t icside_ops_arcin_v5
= {
106 icside_irqenable_arcin_v5
,
107 icside_irqdisable_arcin_v5
,
115 /* ---------------- Version 6 PCB Support Functions --------------------- */
116 /* Prototype: icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
117 * Purpose : enable interrupts from card
119 static void icside_irqenable_arcin_v6 (struct expansion_card
*ec
, int irqnr
)
121 unsigned int ide_base_port
= (unsigned int)ec
->irq_data
;
123 outb (0, ide_base_port
+ ICS_ARCIN_V6_INTROFFSET_1
);
124 outb (0, ide_base_port
+ ICS_ARCIN_V6_INTROFFSET_2
);
127 /* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
128 * Purpose : disable interrupts from card
130 static void icside_irqdisable_arcin_v6 (struct expansion_card
*ec
, int irqnr
)
132 unsigned int ide_base_port
= (unsigned int)ec
->irq_data
;
134 inb (ide_base_port
+ ICS_ARCIN_V6_INTROFFSET_1
);
135 inb (ide_base_port
+ ICS_ARCIN_V6_INTROFFSET_2
);
138 /* Prototype: icside_irqprobe(struct expansion_card *ec)
139 * Purpose : detect an active interrupt from card
141 static int icside_irqpending_arcin_v6(struct expansion_card
*ec
)
143 unsigned int ide_base_port
= (unsigned int)ec
->irq_data
;
145 return inb(ide_base_port
+ ICS_ARCIN_V6_INTRSTAT_1
) & 1 ||
146 inb(ide_base_port
+ ICS_ARCIN_V6_INTRSTAT_2
) & 1;
149 static const expansioncard_ops_t icside_ops_arcin_v6
= {
150 icside_irqenable_arcin_v6
,
151 icside_irqdisable_arcin_v6
,
152 icside_irqpending_arcin_v6
,
158 /* Prototype: icside_identifyif (struct expansion_card *ec)
159 * Purpose : identify IDE interface type
160 * Notes : checks the description string
162 static iftype_t
icside_identifyif (struct expansion_card
*ec
)
168 iftype
= ics_if_unknown
;
170 addr
= ecard_address (ec
, ECARD_IOC
, ECARD_FAST
) + ICS_IDENT_OFFSET
;
173 id
|= (inb (addr
+ 1) & 1) << 1;
174 id
|= (inb (addr
+ 2) & 1) << 2;
175 id
|= (inb (addr
+ 3) & 1) << 3;
179 printk("icside: A3IN unsupported\n");
183 printk("icside: A3USER unsupported\n");
186 case 3: /* ARCIN V6 */
187 printk(KERN_DEBUG
"icside: detected ARCIN V6 in slot %d\n", ec
->slot_no
);
188 iftype
= ics_if_arcin_v6
;
191 case 15:/* ARCIN V5 (no id) */
192 printk(KERN_DEBUG
"icside: detected ARCIN V5 in slot %d\n", ec
->slot_no
);
193 iftype
= ics_if_arcin_v5
;
196 default:/* we don't know - complain very loudly */
197 printk("icside: ***********************************\n");
198 printk("icside: *** UNKNOWN ICS INTERFACE id=%d ***\n", id
);
199 printk("icside: ***********************************\n");
200 printk("icside: please report this to linux@arm.linux.org.uk\n");
201 printk("icside: defaulting to ARCIN V5\n");
202 iftype
= ics_if_arcin_v5
;
209 #ifdef CONFIG_BLK_DEV_IDEDMA_ICS
213 * Similar to the BM-DMA, but we use the RiscPCs IOMD
214 * DMA controllers. There is only one DMA controller
215 * per card, which means that only one drive can be
216 * accessed at one time. NOTE! We do not inforce that
217 * here, but we rely on the main IDE driver spotting
218 * that both interfaces use the same IRQ, which should
221 * We are limited by the drives IOR/IOW pulse time.
222 * The closest that we can get to the requirements is
223 * a type C cycle for both mode 1 and mode 2. However,
224 * this does give a burst of 8MB/s.
226 * This has been tested with a couple of Conner
227 * Peripherals 1080MB CFS1081A drives, one on each
228 * interface, which deliver about 2MB/s each. I
229 * believe that this is limited by the lack of
230 * on-board drive cache.
232 #define TABLE_SIZE 2048
235 icside_build_dmatable(ide_drive_t
*drive
, int reading
)
237 struct request
*rq
= HWGROUP(drive
)->rq
;
238 struct buffer_head
*bh
= rq
->bh
;
239 unsigned long addr
, size
;
240 unsigned char *virt_addr
;
241 unsigned int count
= 0;
242 dmasg_t
*sg
= (dmasg_t
*)HWIF(drive
)->dmatable
;
246 /* paging requests have (rq->bh == NULL) */
247 virt_addr
= rq
->buffer
;
248 addr
= virt_to_bus (virt_addr
);
249 size
= rq
->nr_sectors
<< 9;
251 /* group sequential buffers into one large buffer */
252 virt_addr
= bh
->b_data
;
253 addr
= virt_to_bus (virt_addr
);
255 while ((bh
= bh
->b_reqnext
) != NULL
) {
256 if ((addr
+ size
) != virt_to_bus (bh
->b_data
))
263 printk("%s: misaligned DMA buffer\n", drive
->name
);
269 dma_cache_inv((unsigned int)virt_addr
, size
);
271 dma_cache_wback((unsigned int)virt_addr
, size
);
274 sg
[count
].address
= addr
;
275 sg
[count
].length
= size
;
276 if (++count
>= (TABLE_SIZE
/ sizeof(dmasg_t
))) {
277 printk("%s: DMA table too small\n", drive
->name
);
280 } while (bh
!= NULL
);
283 printk("%s: empty DMA table?\n", drive
->name
);
289 icside_config_drive(ide_drive_t
*drive
, int mode
)
294 speed
= XFER_MW_DMA_2
;
295 drive
->drive_data
= 250;
297 speed
= XFER_MW_DMA_1
;
298 drive
->drive_data
= 250;
301 err
= ide_config_drive_speed(drive
, (byte
) speed
);
304 drive
->id
->dma_mword
&= 0x00ff;
305 drive
->id
->dma_mword
|= 256 << mode
;
307 drive
->drive_data
= 0;
313 icside_dma_check(ide_drive_t
*drive
)
315 struct hd_driveid
*id
= drive
->id
;
316 ide_hwif_t
*hwif
= HWIF(drive
);
317 int autodma
= hwif
->autodma
;
319 if (id
&& (id
->capability
& 1) && autodma
) {
322 /* Consult the list of known "bad" drives */
323 if (ide_dmaproc(ide_dma_bad_drive
, drive
))
324 return hwif
->dmaproc(ide_dma_off
, drive
);
326 /* Enable DMA on any drive that has
327 * UltraDMA (mode 0/1/2) enabled
329 if (id
->field_valid
& 4 && id
->dma_ultra
& 7)
332 /* Enable DMA on any drive that has mode1
333 * or mode2 multiword DMA enabled
335 if (id
->field_valid
& 2 && id
->dma_mword
& 6)
336 dma_mode
= id
->dma_mword
& 4 ? 2 : 1;
338 /* Consult the list of known "good" drives */
339 if (ide_dmaproc(ide_dma_good_drive
, drive
))
342 if (dma_mode
&& icside_config_drive(drive
, dma_mode
) == 0)
343 return hwif
->dmaproc(ide_dma_on
, drive
);
345 return hwif
->dmaproc(ide_dma_off_quietly
, drive
);
349 icside_dmaproc(ide_dma_action_t func
, ide_drive_t
*drive
)
351 ide_hwif_t
*hwif
= HWIF(drive
);
352 int count
, reading
= 0;
356 return icside_dma_check(drive
);
361 count
= icside_build_dmatable(drive
, reading
);
364 disable_dma(hwif
->hw
.dma
);
366 /* Route the DMA signals to
367 * to the correct interface.
369 outb(hwif
->select_data
, hwif
->config_data
);
371 /* Select the correct timing
374 set_dma_speed(hwif
->hw
.dma
, drive
->drive_data
);
376 set_dma_sg(hwif
->hw
.dma
, (dmasg_t
*)hwif
->dmatable
, count
);
377 set_dma_mode(hwif
->hw
.dma
, reading
? DMA_MODE_READ
380 drive
->waiting_for_dma
= 1;
381 if (drive
->media
!= ide_disk
)
384 drive
->timeout
= WAIT_CMD
;
385 ide_set_handler(drive
, &ide_dma_intr
);
386 OUT_BYTE(reading
? WIN_READDMA
: WIN_WRITEDMA
,
390 enable_dma(hwif
->hw
.dma
);
394 drive
->waiting_for_dma
= 0;
395 disable_dma(hwif
->hw
.dma
);
396 return get_dma_residue(hwif
->hw
.dma
) != 0;
398 case ide_dma_test_irq
:
399 return inb((unsigned long)hwif
->hw
.priv
) & 1;
402 return ide_dmaproc(func
, drive
);
407 icside_alloc_dmatable(void)
409 static unsigned long dmatable
;
410 static unsigned int leftover
;
413 if (leftover
< TABLE_SIZE
) {
414 #if PAGE_SIZE == TABLE_SIZE * 2
415 dmatable
= __get_free_pages(GFP_KERNEL
, 1);
416 leftover
= PAGE_SIZE
;
418 dmatable
= kmalloc(TABLE_SIZE
, GFP_KERNEL
);
419 leftover
= TABLE_SIZE
;
425 dmatable
+= TABLE_SIZE
;
426 leftover
-= TABLE_SIZE
;
433 icside_setup_dma(ide_hwif_t
*hwif
, int autodma
)
435 unsigned long table
= icside_alloc_dmatable();
437 printk(" %s: SG-DMA", hwif
->name
);
440 printk(" -- ERROR, unable to allocate DMA table\n");
442 hwif
->dmatable
= (void *)table
;
443 hwif
->dmaproc
= icside_dmaproc
;
444 hwif
->autodma
= autodma
;
446 printk(" capable%s\n", autodma
?
447 ", auto-enable" : "");
450 return hwif
->dmatable
!= NULL
;
455 icside_find_hwif(unsigned long dataport
)
460 for (index
= 0; index
< MAX_HWIFS
; ++index
) {
461 hwif
= &ide_hwifs
[index
];
462 if (hwif
->hw
.io_ports
[IDE_DATA_OFFSET
] == (ide_ioreg_t
)dataport
)
466 for (index
= 0; index
< MAX_HWIFS
; ++index
) {
467 hwif
= &ide_hwifs
[index
];
468 if (!hwif
->hw
.io_ports
[IDE_DATA_OFFSET
])
478 icside_setup(unsigned long base
, struct cardinfo
*info
, int irq
)
480 unsigned long port
= base
+ info
->dataoffset
;
483 hwif
= icside_find_hwif(base
);
487 memset(&hwif
->hw
, 0, sizeof(hw_regs_t
));
489 for (i
= IDE_DATA_OFFSET
; i
<= IDE_STATUS_OFFSET
; i
++) {
490 hwif
->hw
.io_ports
[i
] = (ide_ioreg_t
)port
;
491 port
+= 1 << info
->stepping
;
493 hwif
->hw
.io_ports
[IDE_CONTROL_OFFSET
] = base
+ info
->ctrloffset
;
495 hwif
->hw
.dma
= NO_DMA
;
497 hwif
->chipset
= ide_acorn
;
503 static int icside_register_v5(struct expansion_card
*ec
, int autodma
)
505 unsigned long slot_port
;
508 slot_port
= ecard_address(ec
, ECARD_MEMC
, 0);
510 ec
->irqaddr
= (unsigned char *)ioaddr(slot_port
+ ICS_ARCIN_V5_INTRSTAT
);
512 ec
->irq_data
= (void *)slot_port
;
513 ec
->ops
= (expansioncard_ops_t
*)&icside_ops_arcin_v5
;
516 * Be on the safe side - disable interrupts
518 inb(slot_port
+ ICS_ARCIN_V5_INTROFFSET
);
520 hwif
= icside_setup(slot_port
, &icside_cardinfo_v5
, ec
->irq
);
522 return hwif
? 0 : -1;
525 static int icside_register_v6(struct expansion_card
*ec
, int autodma
)
527 unsigned long slot_port
, port
;
528 ide_hwif_t
*hwif
, *mate
;
531 slot_port
= ecard_address(ec
, ECARD_IOC
, ECARD_FAST
);
532 port
= ecard_address(ec
, ECARD_EASI
, ECARD_FAST
);
539 outb(sel
, slot_port
);
541 ec
->irq_data
= (void *)port
;
542 ec
->ops
= (expansioncard_ops_t
*)&icside_ops_arcin_v6
;
545 * Be on the safe side - disable interrupts
547 inb(port
+ ICS_ARCIN_V6_INTROFFSET_1
);
548 inb(port
+ ICS_ARCIN_V6_INTROFFSET_2
);
550 hwif
= icside_setup(port
, &icside_cardinfo_v6_1
, ec
->irq
);
551 mate
= icside_setup(port
, &icside_cardinfo_v6_2
, ec
->irq
);
553 #ifdef CONFIG_BLK_DEV_IDEDMA_ICS
554 if (ec
->dma
!= NO_DMA
) {
555 if (request_dma(ec
->dma
, hwif
->name
))
559 hwif
->config_data
= slot_port
;
560 hwif
->select_data
= sel
;
561 hwif
->hw
.dma
= ec
->dma
;
562 hwif
->hw
.priv
= (void *)
563 (port
+ ICS_ARCIN_V6_INTRSTAT_1
);
565 icside_setup_dma(hwif
, autodma
);
568 mate
->config_data
= slot_port
;
569 mate
->select_data
= sel
| 1;
570 mate
->hw
.dma
= ec
->dma
;
571 mate
->hw
.priv
= (void *)
572 (port
+ ICS_ARCIN_V6_INTRSTAT_2
);
574 icside_setup_dma(mate
, autodma
);
580 return hwif
|| mate
? 0 : -1;
583 int icside_init(void)
587 #ifdef CONFIG_IDEDMA_ICS_AUTO
594 struct expansion_card
*ec
;
597 ec
= ecard_find(0, icside_cids
);
603 switch (icside_identifyif(ec
)) {
604 case ics_if_arcin_v5
:
605 result
= icside_register_v5(ec
, autodma
);
608 case ics_if_arcin_v6
:
609 result
= icside_register_v6(ec
, autodma
);