Import 2.3.9pre5
[davej-history.git] / drivers / block / icside.c
blob299bce7a69dd825eeb72e25f59c4fd630bbd24b0
1 /*
2 * linux/drivers/block/icside.c
4 * Copyright (c) 1996,1997 Russell King.
6 * Changelog:
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/string.h>
14 #include <linux/module.h>
15 #include <linux/ioport.h>
16 #include <linux/malloc.h>
17 #include <linux/blkdev.h>
18 #include <linux/errno.h>
19 #include <linux/hdreg.h>
20 #include <linux/ide.h>
22 #include <asm/dma.h>
23 #include <asm/ecard.h>
24 #include <asm/io.h>
27 * Maximum number of interfaces per card
29 #define MAX_IFS 2
31 #define ICS_IDENT_OFFSET 0x8a0
33 #define ICS_ARCIN_V5_INTRSTAT 0x000
34 #define ICS_ARCIN_V5_INTROFFSET 0x001
35 #define ICS_ARCIN_V5_IDEOFFSET 0xa00
36 #define ICS_ARCIN_V5_IDEALTOFFSET 0xae0
37 #define ICS_ARCIN_V5_IDESTEPPING 4
39 #define ICS_ARCIN_V6_IDEOFFSET_1 0x800
40 #define ICS_ARCIN_V6_INTROFFSET_1 0x880
41 #define ICS_ARCIN_V6_INTRSTAT_1 0x8a4
42 #define ICS_ARCIN_V6_IDEALTOFFSET_1 0x8e0
43 #define ICS_ARCIN_V6_IDEOFFSET_2 0xc00
44 #define ICS_ARCIN_V6_INTROFFSET_2 0xc80
45 #define ICS_ARCIN_V6_INTRSTAT_2 0xca4
46 #define ICS_ARCIN_V6_IDEALTOFFSET_2 0xce0
47 #define ICS_ARCIN_V6_IDESTEPPING 4
49 struct cardinfo {
50 unsigned int dataoffset;
51 unsigned int ctrloffset;
52 unsigned int stepping;
55 static struct cardinfo icside_cardinfo_v5 = {
56 ICS_ARCIN_V5_IDEOFFSET,
57 ICS_ARCIN_V5_IDEALTOFFSET,
58 ICS_ARCIN_V5_IDESTEPPING
61 static struct cardinfo icside_cardinfo_v6_1 = {
62 ICS_ARCIN_V6_IDEOFFSET_1,
63 ICS_ARCIN_V6_IDEALTOFFSET_1,
64 ICS_ARCIN_V6_IDESTEPPING
67 static struct cardinfo icside_cardinfo_v6_2 = {
68 ICS_ARCIN_V6_IDEOFFSET_2,
69 ICS_ARCIN_V6_IDEALTOFFSET_2,
70 ICS_ARCIN_V6_IDESTEPPING
73 static const card_ids icside_cids[] = {
74 { MANU_ICS, PROD_ICS_IDE },
75 { MANU_ICS2, PROD_ICS2_IDE },
76 { 0xffff, 0xffff }
79 typedef enum {
80 ics_if_unknown,
81 ics_if_arcin_v5,
82 ics_if_arcin_v6
83 } iftype_t;
85 /* ---------------- Version 5 PCB Support Functions --------------------- */
86 /* Prototype: icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
87 * Purpose : enable interrupts from card
89 static void icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
91 unsigned int memc_port = (unsigned int)ec->irq_data;
92 outb (0, memc_port + ICS_ARCIN_V5_INTROFFSET);
95 /* Prototype: icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
96 * Purpose : disable interrupts from card
98 static void icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
100 unsigned int memc_port = (unsigned int)ec->irq_data;
101 inb (memc_port + ICS_ARCIN_V5_INTROFFSET);
104 static const expansioncard_ops_t icside_ops_arcin_v5 = {
105 icside_irqenable_arcin_v5,
106 icside_irqdisable_arcin_v5,
107 NULL,
108 NULL,
109 NULL,
110 NULL
114 /* ---------------- Version 6 PCB Support Functions --------------------- */
115 /* Prototype: icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
116 * Purpose : enable interrupts from card
118 static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
120 unsigned int ide_base_port = (unsigned int)ec->irq_data;
122 outb (0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_1);
123 outb (0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_2);
126 /* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
127 * Purpose : disable interrupts from card
129 static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
131 unsigned int ide_base_port = (unsigned int)ec->irq_data;
133 inb (ide_base_port + ICS_ARCIN_V6_INTROFFSET_1);
134 inb (ide_base_port + ICS_ARCIN_V6_INTROFFSET_2);
137 /* Prototype: icside_irqprobe(struct expansion_card *ec)
138 * Purpose : detect an active interrupt from card
140 static int icside_irqpending_arcin_v6(struct expansion_card *ec)
142 unsigned int ide_base_port = (unsigned int)ec->irq_data;
144 return inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||
145 inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;
148 static const expansioncard_ops_t icside_ops_arcin_v6 = {
149 icside_irqenable_arcin_v6,
150 icside_irqdisable_arcin_v6,
151 icside_irqpending_arcin_v6,
152 NULL,
153 NULL,
154 NULL
157 /* Prototype: icside_identifyif (struct expansion_card *ec)
158 * Purpose : identify IDE interface type
159 * Notes : checks the description string
161 static iftype_t icside_identifyif (struct expansion_card *ec)
163 unsigned int addr;
164 iftype_t iftype;
165 int id = 0;
167 iftype = ics_if_unknown;
169 addr = ecard_address (ec, ECARD_IOC, ECARD_FAST) + ICS_IDENT_OFFSET;
171 id = inb (addr) & 1;
172 id |= (inb (addr + 1) & 1) << 1;
173 id |= (inb (addr + 2) & 1) << 2;
174 id |= (inb (addr + 3) & 1) << 3;
176 switch (id) {
177 case 0: /* A3IN */
178 printk("icside: A3IN unsupported\n");
179 break;
181 case 1: /* A3USER */
182 printk("icside: A3USER unsupported\n");
183 break;
185 case 3: /* ARCIN V6 */
186 printk(KERN_DEBUG "icside: detected ARCIN V6 in slot %d\n", ec->slot_no);
187 iftype = ics_if_arcin_v6;
188 break;
190 case 15:/* ARCIN V5 (no id) */
191 printk(KERN_DEBUG "icside: detected ARCIN V5 in slot %d\n", ec->slot_no);
192 iftype = ics_if_arcin_v5;
193 break;
195 default:/* we don't know - complain very loudly */
196 printk("icside: ***********************************\n");
197 printk("icside: *** UNKNOWN ICS INTERFACE id=%d ***\n", id);
198 printk("icside: ***********************************\n");
199 printk("icside: please report this to linux@arm.linux.org.uk\n");
200 printk("icside: defaulting to ARCIN V5\n");
201 iftype = ics_if_arcin_v5;
202 break;
205 return iftype;
208 #ifdef CONFIG_BLK_DEV_IDEDMA_ICS
210 * SG-DMA support.
212 * Similar to the BM-DMA, but we use the RiscPCs IOMD
213 * DMA controllers. There is only one DMA controller
214 * per card, which means that only one drive can be
215 * accessed at one time. NOTE! We do not inforce that
216 * here, but we rely on the main IDE driver spotting
217 * that both interfaces use the same IRQ, which should
218 * guarantee this.
220 * We are limited by the drives IOR/IOW pulse time.
221 * The closest that we can get to the requirements is
222 * a type C cycle for both mode 1 and mode 2. However,
223 * this does give a burst of 8MB/s.
225 * This has been tested with a couple of Conner
226 * Peripherals 1080MB CFS1081A drives, one on each
227 * interface, which deliver about 2MB/s each. I
228 * believe that this is limited by the lack of
229 * on-board drive cache.
231 #define TABLE_SIZE 2048
233 static int
234 icside_build_dmatable(ide_drive_t *drive, int reading)
236 struct request *rq = HWGROUP(drive)->rq;
237 struct buffer_head *bh = rq->bh;
238 unsigned long addr, size;
239 unsigned char *virt_addr;
240 unsigned int count = 0;
241 dmasg_t *sg = (dmasg_t *)HWIF(drive)->dmatable;
243 do {
244 if (bh == NULL) {
245 /* paging requests have (rq->bh == NULL) */
246 virt_addr = rq->buffer;
247 addr = virt_to_bus (virt_addr);
248 size = rq->nr_sectors << 9;
249 } else {
250 /* group sequential buffers into one large buffer */
251 virt_addr = bh->b_data;
252 addr = virt_to_bus (virt_addr);
253 size = bh->b_size;
254 while ((bh = bh->b_reqnext) != NULL) {
255 if ((addr + size) != virt_to_bus (bh->b_data))
256 break;
257 size += bh->b_size;
261 if (addr & 3) {
262 printk("%s: misaligned DMA buffer\n", drive->name);
263 return 0;
266 if (size) {
267 if (reading)
268 dma_cache_inv((unsigned int)virt_addr, size);
269 else
270 dma_cache_wback((unsigned int)virt_addr, size);
273 sg[count].address = addr;
274 sg[count].length = size;
275 if (++count >= (TABLE_SIZE / sizeof(dmasg_t))) {
276 printk("%s: DMA table too small\n", drive->name);
277 return 0;
279 } while (bh != NULL);
281 if (!count)
282 printk("%s: empty DMA table?\n", drive->name);
284 return count;
287 static int
288 icside_config_drive(ide_drive_t *drive, int mode)
290 ide_hwif_t *hwif = HWIF(drive);
291 int speed, err;
293 if (mode == 2) {
294 speed = XFER_MW_DMA_2;
295 drive->drive_data = 250;
296 } else {
297 speed = XFER_MW_DMA_1;
298 drive->drive_data = 250;
302 * Don't use ide_wait_cmd here - it will
303 * attempt to set_geometry and recalibrate,
304 * but for some reason these don't work at
305 * this point (lost interrupt).
307 SELECT_DRIVE(hwif, drive);
308 OUT_BYTE(drive->ctl | 2, IDE_CONTROL_REG);
309 OUT_BYTE(speed, IDE_NSECTOR_REG);
310 OUT_BYTE(SETFEATURES_XFER, IDE_FEATURE_REG);
311 OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
313 err = ide_wait_stat(drive, DRIVE_READY,
314 BUSY_STAT|DRQ_STAT|ERR_STAT, WAIT_CMD);
316 if (err == 0) {
317 drive->id->dma_mword &= 0x00ff;
318 drive->id->dma_mword |= 256 << mode;
319 } else
320 drive->drive_data = 0;
322 return err;
325 static int
326 icside_dma_check(ide_drive_t *drive)
328 struct hd_driveid *id = drive->id;
329 ide_hwif_t *hwif = HWIF(drive);
330 int autodma = hwif->autodma;
332 if (id && (id->capability & 1) && autodma) {
333 int dma_mode = 0;
335 /* Consult the list of known "bad" drives */
336 if (ide_dmaproc(ide_dma_bad_drive, drive))
337 return hwif->dmaproc(ide_dma_off, drive);
339 /* Enable DMA on any drive that has
340 * UltraDMA (mode 0/1/2) enabled
342 if (id->field_valid & 4 && id->dma_ultra & 7)
343 dma_mode = 2;
345 /* Enable DMA on any drive that has mode1
346 * or mode2 multiword DMA enabled
348 if (id->field_valid & 2 && id->dma_mword & 6)
349 dma_mode = id->dma_mword & 4 ? 2 : 1;
351 /* Consult the list of known "good" drives */
352 if (ide_dmaproc(ide_dma_good_drive, drive))
353 dma_mode = 1;
355 if (dma_mode && icside_config_drive(drive, dma_mode) == 0)
356 return hwif->dmaproc(ide_dma_on, drive);
358 return hwif->dmaproc(ide_dma_off_quietly, drive);
361 static int
362 icside_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
364 ide_hwif_t *hwif = HWIF(drive);
365 int count, reading = 0;
367 switch (func) {
368 case ide_dma_check:
369 return icside_dma_check(drive);
371 case ide_dma_read:
372 reading = 1;
373 case ide_dma_write:
374 count = icside_build_dmatable(drive, reading);
375 if (!count)
376 return 1;
377 disable_dma(hwif->hw.dma);
379 /* Route the DMA signals to
380 * to the correct interface.
382 outb(hwif->select_data, hwif->config_data);
384 /* Select the correct timing
385 * for this drive
387 set_dma_speed(hwif->hw.dma, drive->drive_data);
389 set_dma_sg(hwif->hw.dma, (dmasg_t *)hwif->dmatable, count);
390 set_dma_mode(hwif->hw.dma, reading ? DMA_MODE_READ
391 : DMA_MODE_WRITE);
393 drive->waiting_for_dma = 1;
394 if (drive->media != ide_disk)
395 return 0;
397 ide_set_handler(drive, &ide_dma_intr, WAIT_CMD);
398 OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA,
399 IDE_COMMAND_REG);
401 case ide_dma_begin:
402 enable_dma(hwif->hw.dma);
403 return 0;
405 case ide_dma_end:
406 drive->waiting_for_dma = 0;
407 disable_dma(hwif->hw.dma);
408 return get_dma_residue(hwif->hw.dma) != 0;
410 case ide_dma_test_irq:
411 return inb((unsigned long)hwif->hw.priv) & 1;
413 default:
414 return ide_dmaproc(func, drive);
418 static unsigned long
419 icside_alloc_dmatable(void)
421 static unsigned long dmatable;
422 static unsigned int leftover;
423 unsigned long table;
425 if (leftover < TABLE_SIZE) {
426 #if PAGE_SIZE == TABLE_SIZE * 2
427 dmatable = __get_free_pages(GFP_KERNEL, 1);
428 leftover = PAGE_SIZE;
429 #else
430 dmatable = kmalloc(TABLE_SIZE, GFP_KERNEL);
431 leftover = TABLE_SIZE;
432 #endif
435 table = dmatable;
436 if (table) {
437 dmatable += TABLE_SIZE;
438 leftover -= TABLE_SIZE;
441 return table;
444 static int
445 icside_setup_dma(ide_hwif_t *hwif, int autodma)
447 unsigned long table = icside_alloc_dmatable();
449 printk(" %s: SG-DMA", hwif->name);
451 if (!table)
452 printk(" -- ERROR, unable to allocate DMA table\n");
453 else {
454 hwif->dmatable = (void *)table;
455 hwif->dmaproc = icside_dmaproc;
456 hwif->autodma = autodma;
458 printk(" capable%s\n", autodma ?
459 ", auto-enable" : "");
462 return hwif->dmatable != NULL;
464 #endif
466 static ide_hwif_t *
467 icside_find_hwif(unsigned long dataport)
469 ide_hwif_t *hwif;
470 int index;
472 for (index = 0; index < MAX_HWIFS; ++index) {
473 hwif = &ide_hwifs[index];
474 if (hwif->hw.io_ports[IDE_DATA_OFFSET] == (ide_ioreg_t)dataport)
475 goto found;
478 for (index = 0; index < MAX_HWIFS; ++index) {
479 hwif = &ide_hwifs[index];
480 if (!hwif->hw.io_ports[IDE_DATA_OFFSET])
481 goto found;
484 return NULL;
485 found:
486 return hwif;
489 static ide_hwif_t *
490 icside_setup(unsigned long base, struct cardinfo *info, int irq)
492 unsigned long port = base + info->dataoffset;
493 ide_hwif_t *hwif;
495 hwif = icside_find_hwif(base);
496 if (hwif) {
497 int i;
499 memset(&hwif->hw, 0, sizeof(hw_regs_t));
501 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
502 hwif->hw.io_ports[i] = (ide_ioreg_t)port;
503 port += 1 << info->stepping;
505 hwif->hw.io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset;
506 hwif->hw.irq = irq;
507 hwif->hw.dma = NO_DMA;
508 hwif->noprobe = 0;
509 hwif->chipset = ide_acorn;
512 return hwif;
515 static int icside_register_v5(struct expansion_card *ec, int autodma)
517 unsigned long slot_port;
518 ide_hwif_t *hwif;
520 slot_port = ecard_address(ec, ECARD_MEMC, 0);
522 ec->irqaddr = (unsigned char *)ioaddr(slot_port + ICS_ARCIN_V5_INTRSTAT);
523 ec->irqmask = 1;
524 ec->irq_data = (void *)slot_port;
525 ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v5;
528 * Be on the safe side - disable interrupts
530 inb(slot_port + ICS_ARCIN_V5_INTROFFSET);
532 hwif = icside_setup(slot_port, &icside_cardinfo_v5, ec->irq);
534 return hwif ? 0 : -1;
537 static int icside_register_v6(struct expansion_card *ec, int autodma)
539 unsigned long slot_port, port;
540 ide_hwif_t *hwif, *mate;
541 int sel = 0;
543 slot_port = ecard_address(ec, ECARD_IOC, ECARD_FAST);
544 port = ecard_address(ec, ECARD_EASI, ECARD_FAST);
546 if (port == 0)
547 port = slot_port;
548 else
549 sel = 1 << 5;
551 outb(sel, slot_port);
553 ec->irq_data = (void *)port;
554 ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v6;
557 * Be on the safe side - disable interrupts
559 inb(port + ICS_ARCIN_V6_INTROFFSET_1);
560 inb(port + ICS_ARCIN_V6_INTROFFSET_2);
562 hwif = icside_setup(port, &icside_cardinfo_v6_1, ec->irq);
563 mate = icside_setup(port, &icside_cardinfo_v6_2, ec->irq);
565 #ifdef CONFIG_BLK_DEV_IDEDMA_ICS
566 if (ec->dma != NO_DMA) {
567 if (request_dma(ec->dma, hwif->name))
568 goto no_dma;
570 if (hwif) {
571 hwif->config_data = slot_port;
572 hwif->select_data = sel;
573 hwif->hw.dma = ec->dma;
574 hwif->hw.priv = (void *)
575 (port + ICS_ARCIN_V6_INTRSTAT_1);
576 hwif->channel = 0;
577 icside_setup_dma(hwif, autodma);
579 if (mate) {
580 mate->config_data = slot_port;
581 mate->select_data = sel | 1;
582 mate->hw.dma = ec->dma;
583 mate->hw.priv = (void *)
584 (port + ICS_ARCIN_V6_INTRSTAT_2);
585 mate->channel = 1;
586 icside_setup_dma(mate, autodma);
589 #endif
591 no_dma:
592 return hwif || mate ? 0 : -1;
595 int icside_init(void)
597 int autodma = 0;
599 #ifdef CONFIG_IDEDMA_ICS_AUTO
600 autodma = 1;
601 #endif
603 ecard_startfind ();
605 do {
606 struct expansion_card *ec;
607 int result;
609 ec = ecard_find(0, icside_cids);
610 if (ec == NULL)
611 break;
613 ecard_claim(ec);
615 switch (icside_identifyif(ec)) {
616 case ics_if_arcin_v5:
617 result = icside_register_v5(ec, autodma);
618 break;
620 case ics_if_arcin_v6:
621 result = icside_register_v6(ec, autodma);
622 break;
624 default:
625 result = -1;
626 break;
629 if (result)
630 ecard_release(ec);
631 } while (1);
633 return 0;