Import 2.3.9pre5
[davej-history.git] / drivers / block / gayle.c
blob920f2ee0adba3927904d78bf0c4cb0492037a568
1 /*
2 * linux/drivers/block/gayle.c -- Amiga Gayle IDE Driver
4 * Created 9 Jul 1997 by Geert Uytterhoeven
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive for
8 * more details.
9 */
11 #include <linux/config.h>
12 #include <linux/types.h>
13 #include <linux/mm.h>
14 #include <linux/interrupt.h>
15 #include <linux/blkdev.h>
16 #include <linux/hdreg.h>
17 #include <linux/ide.h>
19 #include <asm/amigahw.h>
20 #include <asm/amigaints.h>
24 * Bases of the IDE interfaces
27 #define GAYLE_BASE_4000 0xdd2020 /* A4000/A4000T */
28 #define GAYLE_BASE_1200 0xda0000 /* A1200/A600 */
31 * Offsets from one of the above bases
34 #define GAYLE_DATA 0x00
35 #define GAYLE_ERROR 0x06 /* see err-bits */
36 #define GAYLE_NSECTOR 0x0a /* nr of sectors to read/write */
37 #define GAYLE_SECTOR 0x0e /* starting sector */
38 #define GAYLE_LCYL 0x12 /* starting cylinder */
39 #define GAYLE_HCYL 0x16 /* high byte of starting cyl */
40 #define GAYLE_SELECT 0x1a /* 101dhhhh , d=drive, hhhh=head */
41 #define GAYLE_STATUS 0x1e /* see status-bits */
42 #define GAYLE_CONTROL 0x101a
44 static int gayle_offsets[IDE_NR_PORTS] = {
45 GAYLE_DATA, GAYLE_ERROR, GAYLE_NSECTOR, GAYLE_SECTOR, GAYLE_LCYL,
46 GAYLE_HCYL, GAYLE_SELECT, GAYLE_STATUS, -1, -1
51 * These are at different offsets from the base
54 #define GAYLE_IRQ_4000 0xdd3020 /* MSB = 1, Harddisk is source of */
55 #define GAYLE_IRQ_1200 0xda9000 /* interrupt */
59 * Offset of the secondary port for IDE doublers
60 * Note that GAYLE_CONTROL is NOT available then!
63 #define GAYLE_NEXT_PORT 0x1000
65 #ifndef CONFIG_BLK_DEV_IDEDOUBLER
66 #define GAYLE_NUM_HWIFS 1
67 #define GAYLE_NUM_PROBE_HWIFS GAYLE_NUM_HWIFS
68 #define GAYLE_HAS_CONTROL_REG 1
69 #else /* CONFIG_BLK_DEV_IDEDOUBLER */
70 #define GAYLE_NUM_HWIFS 2
71 #define GAYLE_NUM_PROBE_HWIFS (ide_doubler ? GAYLE_NUM_HWIFS : \
72 GAYLE_NUM_HWIFS-1)
73 #define GAYLE_HAS_CONTROL_REG (!ide_doubler)
74 int ide_doubler = 0; /* support IDE doublers? */
75 #endif /* CONFIG_BLK_DEV_IDEDOUBLER */
79 * Check and acknowledge the interrupt status
82 static int gayle_ack_intr_a4000(ide_hwif_t *hwif)
84 unsigned char ch;
86 ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
87 if (!(ch & 0x80))
88 return 0;
89 return 1;
92 static int gayle_ack_intr_a1200(ide_hwif_t *hwif)
94 unsigned char ch;
96 ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
97 if (!(ch & 0x80))
98 return 0;
99 (void)inb(hwif->io_ports[IDE_STATUS_OFFSET]);
100 outb(0x7c | (ch & 0x03), hwif->io_ports[IDE_IRQ_OFFSET]);
101 return 1;
105 * Probe for a Gayle IDE interface (and optionally for an IDE doubler)
108 void gayle_init(void)
110 int a4000, i;
112 if (!MACH_IS_AMIGA)
113 return;
115 if (!(a4000 = AMIGAHW_PRESENT(A4000_IDE)) && !AMIGAHW_PRESENT(A1200_IDE))
116 return;
118 for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) {
119 ide_ioreg_t base, ctrlport, irqport;
120 ide_ack_intr_t *ack_intr;
121 hw_regs_t hw;
122 int index;
124 if (a4000) {
125 base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_4000);
126 irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_4000);
127 ack_intr = gayle_ack_intr_a4000;
128 } else {
129 base = (ide_ioreg_t)ZTWO_VADDR(GAYLE_BASE_1200);
130 irqport = (ide_ioreg_t)ZTWO_VADDR(GAYLE_IRQ_1200);
131 ack_intr = gayle_ack_intr_a1200;
134 if (GAYLE_HAS_CONTROL_REG)
135 ctrlport = base + GAYLE_CONTROL;
136 else
137 ctrlport = 0;
139 base += i*GAYLE_NEXT_PORT;
141 ide_setup_ports(&hw, base, gayle_offsets,
142 ctrlport, irqport, ack_intr, IRQ_AMIGA_PORTS);
144 index = ide_register_hw(&hw, NULL);
145 if (index != -1) {
146 switch (i) {
147 case 0:
148 printk("ide%d: Gayle IDE interface (A%d style)\n", index,
149 a4000 ? 4000 : 1200);
150 break;
151 #ifdef CONFIG_BLK_DEV_IDEDOUBLER
152 case 1:
153 printk("ide%d: IDE doubler\n", index);
154 break;
155 #endif /* CONFIG_BLK_DEV_IDEDOUBLER */
158 #if 1 /* TESTING */
159 if (i == 1) {
160 volatile u_short *addr = (u_short *)base;
161 u_short data;
162 printk("+++ Probing for IDE doubler... ");
163 *addr = 0xffff;
164 data = *addr;
165 printk("probe returned 0x%02x (PLEASE REPORT THIS!!)\n", data);
167 #endif /* TESTING */