1 /*
2 * linux/drivers/ide/icside.c
3 *
4 * Copyright (c) 1996,1997 Russell King.
5 *
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
11 */
12
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>
22 #include <linux/pci.h>
23 #include <linux/init.h>
24
25 #include <asm/dma.h>
26 #include <asm/ecard.h>
27 #include <asm/io.h>
28
29 extern char *ide_xfer_verbose (byte xfer_rate);
30
31 /*
32 * Maximum number of interfaces per card
33 */
34 #define MAX_IFS 2
35
36 #define ICS_IDENT_OFFSET 0x8a0
37
38 #define ICS_ARCIN_V5_INTRSTAT 0x000
39 #define ICS_ARCIN_V5_INTROFFSET 0x001
40 #define ICS_ARCIN_V5_IDEOFFSET 0xa00
41 #define ICS_ARCIN_V5_IDEALTOFFSET 0xae0
42 #define ICS_ARCIN_V5_IDESTEPPING 4
43
44 #define ICS_ARCIN_V6_IDEOFFSET_1 0x800
45 #define ICS_ARCIN_V6_INTROFFSET_1 0x880
46 #define ICS_ARCIN_V6_INTRSTAT_1 0x8a4
47 #define ICS_ARCIN_V6_IDEALTOFFSET_1 0x8e0
48 #define ICS_ARCIN_V6_IDEOFFSET_2 0xc00
49 #define ICS_ARCIN_V6_INTROFFSET_2 0xc80
50 #define ICS_ARCIN_V6_INTRSTAT_2 0xca4
51 #define ICS_ARCIN_V6_IDEALTOFFSET_2 0xce0
52 #define ICS_ARCIN_V6_IDESTEPPING 4
53
54 struct cardinfo {
55 unsigned int dataoffset;
56 unsigned int ctrloffset;
57 unsigned int stepping;
58 };
59
60 static struct cardinfo icside_cardinfo_v5 = {
61 ICS_ARCIN_V5_IDEOFFSET,
62 ICS_ARCIN_V5_IDEALTOFFSET,
63 ICS_ARCIN_V5_IDESTEPPING
64 };
65
66 static struct cardinfo icside_cardinfo_v6_1 = {
67 ICS_ARCIN_V6_IDEOFFSET_1,
68 ICS_ARCIN_V6_IDEALTOFFSET_1,
69 ICS_ARCIN_V6_IDESTEPPING
70 };
71
72 static struct cardinfo icside_cardinfo_v6_2 = {
73 ICS_ARCIN_V6_IDEOFFSET_2,
74 ICS_ARCIN_V6_IDEALTOFFSET_2,
75 ICS_ARCIN_V6_IDESTEPPING
76 };
77
78 static const card_ids icside_cids[] = {
79 { MANU_ICS, PROD_ICS_IDE },
80 { MANU_ICS2, PROD_ICS2_IDE },
81 { 0xffff, 0xffff }
82 };
83
84 typedef enum {
85 ics_if_unknown,
86 ics_if_arcin_v5,
87 ics_if_arcin_v6
88 } iftype_t;
89
90 /* ---------------- Version 5 PCB Support Functions --------------------- */
91 /* Prototype: icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
92 * Purpose : enable interrupts from card
93 */
94 static void icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
95 {
96 unsigned int memc_port = (unsigned int)ec->irq_data;
97 outb (0, memc_port + ICS_ARCIN_V5_INTROFFSET);
98 }
99
100 /* Prototype: icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
101 * Purpose : disable interrupts from card
102 */
103 static void icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
104 {
105 unsigned int memc_port = (unsigned int)ec->irq_data;
106 inb (memc_port + ICS_ARCIN_V5_INTROFFSET);
107 }
108
109 static const expansioncard_ops_t icside_ops_arcin_v5 = {
110 icside_irqenable_arcin_v5,
111 icside_irqdisable_arcin_v5,
112 NULL,
113 NULL,
114 NULL,
115 NULL
116 };
117
118
119 /* ---------------- Version 6 PCB Support Functions --------------------- */
120 /* Prototype: icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
121 * Purpose : enable interrupts from card
122 */
123 static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
124 {
125 unsigned int ide_base_port = (unsigned int)ec->irq_data;
126
127 outb (0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_1);
128 outb (0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_2);
129 }
130
131 /* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
132 * Purpose : disable interrupts from card
133 */
134 static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
135 {
136 unsigned int ide_base_port = (unsigned int)ec->irq_data;
137
138 inb (ide_base_port + ICS_ARCIN_V6_INTROFFSET_1);
139 inb (ide_base_port + ICS_ARCIN_V6_INTROFFSET_2);
140 }
141
142 /* Prototype: icside_irqprobe(struct expansion_card *ec)
143 * Purpose : detect an active interrupt from card
144 */
145 static int icside_irqpending_arcin_v6(struct expansion_card *ec)
146 {
147 unsigned int ide_base_port = (unsigned int)ec->irq_data;
148
149 return inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||
150 inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;
151 }
152
153 static const expansioncard_ops_t icside_ops_arcin_v6 = {
154 icside_irqenable_arcin_v6,
155 icside_irqdisable_arcin_v6,
156 icside_irqpending_arcin_v6,
157 NULL,
158 NULL,
159 NULL
160 };
161
162 /* Prototype: icside_identifyif (struct expansion_card *ec)
163 * Purpose : identify IDE interface type
164 * Notes : checks the description string
165 */
166 static iftype_t __init icside_identifyif (struct expansion_card *ec)
167 {
168 unsigned int addr;
169 iftype_t iftype;
170 int id = 0;
171
172 iftype = ics_if_unknown;
173
174 addr = ecard_address (ec, ECARD_IOC, ECARD_FAST) + ICS_IDENT_OFFSET;
175
176 id = inb (addr) & 1;
177 id |= (inb (addr + 1) & 1) << 1;
178 id |= (inb (addr + 2) & 1) << 2;
179 id |= (inb (addr + 3) & 1) << 3;
180
181 switch (id) {
182 case 0: /* A3IN */
183 printk("icside: A3IN unsupported\n");
184 break;
185
186 case 1: /* A3USER */
187 printk("icside: A3USER unsupported\n");
188 break;
189
190 case 3: /* ARCIN V6 */
191 printk(KERN_DEBUG "icside: detected ARCIN V6 in slot %d\n", ec->slot_no);
192 iftype = ics_if_arcin_v6;
193 break;
194
195 case 15:/* ARCIN V5 (no id) */
196 printk(KERN_DEBUG "icside: detected ARCIN V5 in slot %d\n", ec->slot_no);
197 iftype = ics_if_arcin_v5;
198 break;
199
200 default:/* we don't know - complain very loudly */
201 printk("icside: ***********************************\n");
202 printk("icside: *** UNKNOWN ICS INTERFACE id=%d ***\n", id);
203 printk("icside: ***********************************\n");
204 printk("icside: please report this to linux@arm.linux.org.uk\n");
205 printk("icside: defaulting to ARCIN V5\n");
206 iftype = ics_if_arcin_v5;
207 break;
208 }
209
210 return iftype;
211 }
212
213 #ifdef CONFIG_BLK_DEV_IDEDMA_ICS
214 /*
215 * SG-DMA support.
216 *
217 * Similar to the BM-DMA, but we use the RiscPCs IOMD DMA controllers.
218 * There is only one DMA controller per card, which means that only
219 * one drive can be accessed at one time. NOTE! We do not enforce that
220 * here, but we rely on the main IDE driver spotting that both
221 * interfaces use the same IRQ, which should guarantee this.
222 */
223 #define NR_ENTRIES 256
224 #define TABLE_SIZE (NR_ENTRIES * 8)
225
226 static int ide_build_sglist(ide_hwif_t *hwif, struct request *rq)
227 {
228 struct buffer_head *bh;
229 struct scatterlist *sg = hwif->sg_table;
230 int nents = 0;
231
232 if (rq->cmd == READ)
233 hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
234 else
235 hwif->sg_dma_direction = PCI_DMA_TODEVICE;
236 bh = rq->bh;
237 do {
238 unsigned char *virt_addr = bh->b_data;
239 unsigned int size = bh->b_size;
240
241 while ((bh = bh->b_reqnext) != NULL) {
242 if ((virt_addr + size) != (unsigned char *)bh->b_data)
243 break;
244 size += bh->b_size;
245 }
246 memset(&sg[nents], 0, sizeof(*sg));
247 sg[nents].address = virt_addr;
248 sg[nents].length = size;
249 nents++;
250 } while (bh != NULL);
251
252 return pci_map_sg(NULL, sg, nents, hwif->sg_dma_direction);
253 }
254
255 static int
256 icside_build_dmatable(ide_drive_t *drive, int reading)
257 {
258 return HWIF(drive)->sg_nents = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq);
259 }
260
261 /* Teardown mappings after DMA has completed. */
262 static void icside_destroy_dmatable(ide_drive_t *drive)
263 {
264 struct scatterlist *sg = HWIF(drive)->sg_table;
265 int nents = HWIF(drive)->sg_nents;
266
267 pci_unmap_sg(NULL, sg, nents, HWIF(drive)->sg_dma_direction);
268 }
269
270 static int
271 icside_config_if(ide_drive_t *drive, int xfer_mode)
272 {
273 int func = ide_dma_off;
274
275 switch (xfer_mode) {
276 case XFER_MW_DMA_2:
277 /*
278 * The cycle time is limited to 250ns by the r/w
279 * pulse width (90ns), however we should still
280 * have a maximum burst transfer rate of 8MB/s.
281 */
282 drive->drive_data = 250;
283 break;
284
285 case XFER_MW_DMA_1:
286 drive->drive_data = 250;
287 break;
288
289 case XFER_MW_DMA_0:
290 drive->drive_data = 480;
291 break;
292
293 default:
294 drive->drive_data = 0;
295 break;
296 }
297
298 if (!drive->init_speed)
299 drive->init_speed = (byte) xfer_mode;
300
301 if (drive->drive_data &&
302 ide_config_drive_speed(drive, (byte) xfer_mode) == 0)
303 func = ide_dma_on;
304 else
305 drive->drive_data = 480;
306
307 printk("%s: %s selected (peak %dMB/s)\n", drive->name,
308 ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data);
309
310 drive->current_speed = (byte) xfer_mode;
311
312 return func;
313 }
314
315 static int
316 icside_set_speed(ide_drive_t *drive, byte speed)
317 {
318 return icside_config_if(drive, speed);
319 }
320
321 static int
322 icside_dma_check(ide_drive_t *drive)
323 {
324 struct hd_driveid *id = drive->id;
325 ide_hwif_t *hwif = HWIF(drive);
326 int autodma = hwif->autodma;
327 int xfer_mode = XFER_PIO_2;
328 int func = ide_dma_off_quietly;
329
330 if (!id || !(id->capability & 1) || !autodma)
331 goto out;
332
333 /*
334 * Consult the list of known "bad" drives
335 */
336 if (ide_dmaproc(ide_dma_bad_drive, drive)) {
337 func = ide_dma_off;
338 goto out;
339 }
340
341 /*
342 * Enable DMA on any drive that has multiword DMA
343 */
344 if (id->field_valid & 2) {
345 if (id->dma_mword & 4) {
346 xfer_mode = XFER_MW_DMA_2;
347 func = ide_dma_on;
348 } else if (id->dma_mword & 2) {
349 xfer_mode = XFER_MW_DMA_1;
350 func = ide_dma_on;
351 } else if (id->dma_mword & 1) {
352 xfer_mode = XFER_MW_DMA_0;
353 func = ide_dma_on;
354 }
355 goto out;
356 }
357
358 /*
359 * Consult the list of known "good" drives
360 */
361 if (ide_dmaproc(ide_dma_good_drive, drive)) {
362 if (id->eide_dma_time > 150)
363 goto out;
364 xfer_mode = XFER_MW_DMA_1;
365 func = ide_dma_on;
366 }
367
368 out:
369 func = icside_config_if(drive, xfer_mode);
370
371 return hwif->dmaproc(func, drive);
372 }
373
374 static int
375 icside_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
376 {
377 ide_hwif_t *hwif = HWIF(drive);
378 int count, reading = 0;
379
380 switch (func) {
381 case ide_dma_check:
382 return icside_dma_check(drive);
383
384 case ide_dma_read:
385 reading = 1;
386 case ide_dma_write:
387 count = icside_build_dmatable(drive, reading);
388 if (!count)
389 return 1;
390 disable_dma(hwif->hw.dma);
391
392 /* Route the DMA signals to
393 * to the correct interface.
394 */
395 outb(hwif->select_data, hwif->config_data);
396
397 /* Select the correct timing
398 * for this drive
399 */
400 set_dma_speed(hwif->hw.dma, drive->drive_data);
401
402 set_dma_sg(hwif->hw.dma, HWIF(drive)->sg_table, count);
403 set_dma_mode(hwif->hw.dma, reading ? DMA_MODE_READ
404 : DMA_MODE_WRITE);
405
406 drive->waiting_for_dma = 1;
407 if (drive->media != ide_disk)
408 return 0;
409
410 ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
411 OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA,
412 IDE_COMMAND_REG);
413
414 case ide_dma_begin:
415 enable_dma(hwif->hw.dma);
416 return 0;
417
418 case ide_dma_end:
419 drive->waiting_for_dma = 0;
420 disable_dma(hwif->hw.dma);
421 icside_destroy_dmatable(drive);
422 return get_dma_residue(hwif->hw.dma) != 0;
423
424 case ide_dma_test_irq:
425 return inb((unsigned long)hwif->hw.priv) & 1;
426
427 default:
428 return ide_dmaproc(func, drive);
429 }
430 }
431
432 static int
433 icside_setup_dma(ide_hwif_t *hwif, int autodma)
434 {
435 printk(" %s: SG-DMA", hwif->name);
436
437 hwif->sg_table = kmalloc(sizeof(struct scatterlist) * NR_ENTRIES,
438 GFP_KERNEL);
439 if (!hwif->sg_table)
440 goto failed;
441
442 hwif->dmatable_cpu = NULL;
443 hwif->dmatable_dma = 0;
444 hwif->speedproc = icside_set_speed;
445 hwif->dmaproc = icside_dmaproc;
446 hwif->autodma = autodma;
447
448 printk(" capable%s\n", autodma ?
449 ", auto-enable" : "");
450
451 return 1;
452
453 failed:
454 printk(" -- ERROR, unable to allocate DMA table\n");
455 return 0;
456 }
457 #endif
458
459 static ide_hwif_t *
460 icside_find_hwif(unsigned long dataport)
461 {
462 ide_hwif_t *hwif;
463 int index;
464
465 for (index = 0; index < MAX_HWIFS; ++index) {
466 hwif = &ide_hwifs[index];
467 if (hwif->hw.io_ports[IDE_DATA_OFFSET] == (ide_ioreg_t)dataport)
468 goto found;
469 }
470
471 for (index = 0; index < MAX_HWIFS; ++index) {
472 hwif = &ide_hwifs[index];
473 if (!hwif->hw.io_ports[IDE_DATA_OFFSET])
474 goto found;
475 }
476
477 return NULL;
478 found:
479 return hwif;
480 }
481
482 static ide_hwif_t *
483 icside_setup(unsigned long base, struct cardinfo *info, int irq)
484 {
485 unsigned long port = base + info->dataoffset;
486 ide_hwif_t *hwif;
487
488 hwif = icside_find_hwif(base);
489 if (hwif) {
490 int i;
491
492 memset(&hwif->hw, 0, sizeof(hw_regs_t));
493
494 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
495 hwif->hw.io_ports[i] = (ide_ioreg_t)port;
496 port += 1 << info->stepping;
497 }
498 hwif->hw.io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset;
499 hwif->hw.irq = irq;
500 hwif->hw.dma = NO_DMA;
501 hwif->noprobe = 0;
502 hwif->chipset = ide_acorn;
503 }
504
505 return hwif;
506 }
507
508 static int __init icside_register_v5(struct expansion_card *ec, int autodma)
509 {
510 unsigned long slot_port;
511 ide_hwif_t *hwif;
512
513 slot_port = ecard_address(ec, ECARD_MEMC, 0);
514
515 ec->irqaddr = (unsigned char *)ioaddr(slot_port + ICS_ARCIN_V5_INTRSTAT);
516 ec->irqmask = 1;
517 ec->irq_data = (void *)slot_port;
518 ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v5;
519
520 /*
521 * Be on the safe side - disable interrupts
522 */
523 inb(slot_port + ICS_ARCIN_V5_INTROFFSET);
524
525 hwif = icside_setup(slot_port, &icside_cardinfo_v5, ec->irq);
526
527 return hwif ? 0 : -1;
528 }
529
530 static int __init icside_register_v6(struct expansion_card *ec, int autodma)
531 {
532 unsigned long slot_port, port;
533 ide_hwif_t *hwif, *mate;
534 int sel = 0;
535
536 slot_port = ecard_address(ec, ECARD_IOC, ECARD_FAST);
537 port = ecard_address(ec, ECARD_EASI, ECARD_FAST);
538
539 if (port == 0)
540 port = slot_port;
541 else
542 sel = 1 << 5;
543
544 outb(sel, slot_port);
545
546 ec->irq_data = (void *)port;
547 ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v6;
548
549 /*
550 * Be on the safe side - disable interrupts
551 */
552 inb(port + ICS_ARCIN_V6_INTROFFSET_1);
553 inb(port + ICS_ARCIN_V6_INTROFFSET_2);
554
555 hwif = icside_setup(port, &icside_cardinfo_v6_1, ec->irq);
556 mate = icside_setup(port, &icside_cardinfo_v6_2, ec->irq);
557
558 #ifdef CONFIG_BLK_DEV_IDEDMA_ICS
559 if (ec->dma != NO_DMA) {
560 if (request_dma(ec->dma, hwif->name))
561 goto no_dma;
562
563 if (hwif) {
564 hwif->config_data = slot_port;
565 hwif->select_data = sel;
566 hwif->hw.dma = ec->dma;
567 hwif->hw.priv = (void *)
568 (port + ICS_ARCIN_V6_INTRSTAT_1);
569 hwif->channel = 0;
570 icside_setup_dma(hwif, autodma);
571 }
572 if (mate) {
573 mate->config_data = slot_port;
574 mate->select_data = sel | 1;
575 mate->hw.dma = ec->dma;
576 mate->hw.priv = (void *)
577 (port + ICS_ARCIN_V6_INTRSTAT_2);
578 mate->channel = 1;
579 icside_setup_dma(mate, autodma);
580 }
581 }
582 #endif
583
584 no_dma:
585 return hwif || mate ? 0 : -1;
586 }
587
588 int __init icside_init(void)
589 {
590 int autodma = 0;
591
592 #ifdef CONFIG_IDEDMA_ICS_AUTO
593 autodma = 1;
594 #endif
595
596 ecard_startfind ();
597
598 do {
599 struct expansion_card *ec;
600 int result;
601
602 ec = ecard_find(0, icside_cids);
603 if (ec == NULL)
604 break;
605
606 ecard_claim(ec);
607
608 switch (icside_identifyif(ec)) {
609 case ics_if_arcin_v5:
610 result = icside_register_v5(ec, autodma);
611 break;
612
613 case ics_if_arcin_v6:
614 result = icside_register_v6(ec, autodma);
615 break;
616
617 default:
618 result = -1;
619 break;
620 }
621
622 if (result)
623 ecard_release(ec);
624 } while (1);
625
626 return 0;
627 }
628
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.