diff options
Diffstat (limited to 'drivers/ide/legacy')
-rw-r--r-- | drivers/ide/legacy/Makefile | 1 | ||||
-rw-r--r-- | drivers/ide/legacy/ali14xx.c | 32 | ||||
-rw-r--r-- | drivers/ide/legacy/buddha.c | 18 | ||||
-rw-r--r-- | drivers/ide/legacy/dtc2278.c | 27 | ||||
-rw-r--r-- | drivers/ide/legacy/falconide.c | 40 | ||||
-rw-r--r-- | drivers/ide/legacy/gayle.c | 22 | ||||
-rw-r--r-- | drivers/ide/legacy/hd.c | 78 | ||||
-rw-r--r-- | drivers/ide/legacy/ht6560b.c | 54 | ||||
-rw-r--r-- | drivers/ide/legacy/ide-4drives.c | 72 | ||||
-rw-r--r-- | drivers/ide/legacy/ide-cs.c | 84 | ||||
-rw-r--r-- | drivers/ide/legacy/ide_platform.c | 16 | ||||
-rw-r--r-- | drivers/ide/legacy/macide.c | 8 | ||||
-rw-r--r-- | drivers/ide/legacy/q40ide.c | 74 | ||||
-rw-r--r-- | drivers/ide/legacy/qd65xx.c | 223 | ||||
-rw-r--r-- | drivers/ide/legacy/qd65xx.h | 1 | ||||
-rw-r--r-- | drivers/ide/legacy/umc8672.c | 80 |
16 files changed, 450 insertions, 380 deletions
diff --git a/drivers/ide/legacy/Makefile b/drivers/ide/legacy/Makefile index 7043ec7d1e05..6939329f89e8 100644 --- a/drivers/ide/legacy/Makefile +++ b/drivers/ide/legacy/Makefile | |||
@@ -6,6 +6,7 @@ obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o | |||
6 | obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o | 6 | obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o |
7 | obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o | 7 | obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o |
8 | obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o | 8 | obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o |
9 | obj-$(CONFIG_BLK_DEV_4DRIVES) += ide-4drives.o | ||
9 | 10 | ||
10 | obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o | 11 | obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o |
11 | obj-$(CONFIG_BLK_DEV_FALCON_IDE) += falconide.o | 12 | obj-$(CONFIG_BLK_DEV_FALCON_IDE) += falconide.o |
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c index d4d1a6bea599..90c65cf97448 100644 --- a/drivers/ide/legacy/ali14xx.c +++ b/drivers/ide/legacy/ali14xx.c | |||
@@ -49,6 +49,8 @@ | |||
49 | 49 | ||
50 | #include <asm/io.h> | 50 | #include <asm/io.h> |
51 | 51 | ||
52 | #define DRV_NAME "ali14xx" | ||
53 | |||
52 | /* port addresses for auto-detection */ | 54 | /* port addresses for auto-detection */ |
53 | #define ALI_NUM_PORTS 4 | 55 | #define ALI_NUM_PORTS 4 |
54 | static const int ports[ALI_NUM_PORTS] __initdata = | 56 | static const int ports[ALI_NUM_PORTS] __initdata = |
@@ -86,7 +88,7 @@ static u8 regOff; /* output to base port to close registers */ | |||
86 | /* | 88 | /* |
87 | * Read a controller register. | 89 | * Read a controller register. |
88 | */ | 90 | */ |
89 | static inline u8 inReg (u8 reg) | 91 | static inline u8 inReg(u8 reg) |
90 | { | 92 | { |
91 | outb_p(reg, regPort); | 93 | outb_p(reg, regPort); |
92 | return inb(dataPort); | 94 | return inb(dataPort); |
@@ -95,7 +97,7 @@ static inline u8 inReg (u8 reg) | |||
95 | /* | 97 | /* |
96 | * Write a controller register. | 98 | * Write a controller register. |
97 | */ | 99 | */ |
98 | static void outReg (u8 data, u8 reg) | 100 | static void outReg(u8 data, u8 reg) |
99 | { | 101 | { |
100 | outb_p(reg, regPort); | 102 | outb_p(reg, regPort); |
101 | outb_p(data, dataPort); | 103 | outb_p(data, dataPort); |
@@ -114,7 +116,7 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
114 | int time1, time2; | 116 | int time1, time2; |
115 | u8 param1, param2, param3, param4; | 117 | u8 param1, param2, param3, param4; |
116 | unsigned long flags; | 118 | unsigned long flags; |
117 | int bus_speed = system_bus_clock(); | 119 | int bus_speed = ide_vlb_clk ? ide_vlb_clk : system_bus_clock(); |
118 | 120 | ||
119 | /* calculate timing, according to PIO mode */ | 121 | /* calculate timing, according to PIO mode */ |
120 | time1 = ide_pio_cycle_time(drive, pio); | 122 | time1 = ide_pio_cycle_time(drive, pio); |
@@ -143,7 +145,7 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
143 | /* | 145 | /* |
144 | * Auto-detect the IDE controller port. | 146 | * Auto-detect the IDE controller port. |
145 | */ | 147 | */ |
146 | static int __init findPort (void) | 148 | static int __init findPort(void) |
147 | { | 149 | { |
148 | int i; | 150 | int i; |
149 | u8 t; | 151 | u8 t; |
@@ -175,7 +177,8 @@ static int __init findPort (void) | |||
175 | /* | 177 | /* |
176 | * Initialize controller registers with default values. | 178 | * Initialize controller registers with default values. |
177 | */ | 179 | */ |
178 | static int __init initRegisters (void) { | 180 | static int __init initRegisters(void) |
181 | { | ||
179 | const RegInitializer *p; | 182 | const RegInitializer *p; |
180 | u8 t; | 183 | u8 t; |
181 | unsigned long flags; | 184 | unsigned long flags; |
@@ -191,16 +194,20 @@ static int __init initRegisters (void) { | |||
191 | return t; | 194 | return t; |
192 | } | 195 | } |
193 | 196 | ||
197 | static const struct ide_port_ops ali14xx_port_ops = { | ||
198 | .set_pio_mode = ali14xx_set_pio_mode, | ||
199 | }; | ||
200 | |||
194 | static const struct ide_port_info ali14xx_port_info = { | 201 | static const struct ide_port_info ali14xx_port_info = { |
202 | .name = DRV_NAME, | ||
195 | .chipset = ide_ali14xx, | 203 | .chipset = ide_ali14xx, |
196 | .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_NO_AUTOTUNE, | 204 | .port_ops = &ali14xx_port_ops, |
205 | .host_flags = IDE_HFLAG_NO_DMA, | ||
197 | .pio_mask = ATA_PIO4, | 206 | .pio_mask = ATA_PIO4, |
198 | }; | 207 | }; |
199 | 208 | ||
200 | static int __init ali14xx_probe(void) | 209 | static int __init ali14xx_probe(void) |
201 | { | 210 | { |
202 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; | ||
203 | |||
204 | printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n", | 211 | printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n", |
205 | basePort, regOn); | 212 | basePort, regOn); |
206 | 213 | ||
@@ -210,15 +217,10 @@ static int __init ali14xx_probe(void) | |||
210 | return 1; | 217 | return 1; |
211 | } | 218 | } |
212 | 219 | ||
213 | ide_hwifs[0].set_pio_mode = &ali14xx_set_pio_mode; | 220 | return ide_legacy_device_add(&ali14xx_port_info, 0); |
214 | ide_hwifs[1].set_pio_mode = &ali14xx_set_pio_mode; | ||
215 | |||
216 | ide_device_add(idx, &ali14xx_port_info); | ||
217 | |||
218 | return 0; | ||
219 | } | 221 | } |
220 | 222 | ||
221 | int probe_ali14xx = 0; | 223 | static int probe_ali14xx; |
222 | 224 | ||
223 | module_param_named(probe, probe_ali14xx, bool, 0); | 225 | module_param_named(probe, probe_ali14xx, bool, 0); |
224 | MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets"); | 226 | MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets"); |
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c index fdd3791e465f..5c730e4dd735 100644 --- a/drivers/ide/legacy/buddha.c +++ b/drivers/ide/legacy/buddha.c | |||
@@ -102,7 +102,7 @@ static int buddha_ack_intr(ide_hwif_t *hwif) | |||
102 | { | 102 | { |
103 | unsigned char ch; | 103 | unsigned char ch; |
104 | 104 | ||
105 | ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]); | 105 | ch = z_readb(hwif->io_ports.irq_addr); |
106 | if (!(ch & 0x80)) | 106 | if (!(ch & 0x80)) |
107 | return 0; | 107 | return 0; |
108 | return 1; | 108 | return 1; |
@@ -112,9 +112,9 @@ static int xsurf_ack_intr(ide_hwif_t *hwif) | |||
112 | { | 112 | { |
113 | unsigned char ch; | 113 | unsigned char ch; |
114 | 114 | ||
115 | ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]); | 115 | ch = z_readb(hwif->io_ports.irq_addr); |
116 | /* X-Surf needs a 0 written to IRQ register to ensure ISA bit A11 stays at 0 */ | 116 | /* X-Surf needs a 0 written to IRQ register to ensure ISA bit A11 stays at 0 */ |
117 | z_writeb(0, hwif->io_ports[IDE_IRQ_OFFSET]); | 117 | z_writeb(0, hwif->io_ports.irq_addr); |
118 | if (!(ch & 0x80)) | 118 | if (!(ch & 0x80)) |
119 | return 0; | 119 | return 0; |
120 | return 1; | 120 | return 1; |
@@ -128,13 +128,13 @@ static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base, | |||
128 | 128 | ||
129 | memset(hw, 0, sizeof(*hw)); | 129 | memset(hw, 0, sizeof(*hw)); |
130 | 130 | ||
131 | hw->io_ports[IDE_DATA_OFFSET] = base; | 131 | hw->io_ports.data_addr = base; |
132 | 132 | ||
133 | for (i = 1; i < 8; i++) | 133 | for (i = 1; i < 8; i++) |
134 | hw->io_ports[i] = base + 2 + i * 4; | 134 | hw->io_ports_array[i] = base + 2 + i * 4; |
135 | 135 | ||
136 | hw->io_ports[IDE_CONTROL_OFFSET] = ctl; | 136 | hw->io_ports.ctl_addr = ctl; |
137 | hw->io_ports[IDE_IRQ_OFFSET] = irq_port; | 137 | hw->io_ports.irq_addr = irq_port; |
138 | 138 | ||
139 | hw->irq = IRQ_AMIGA_PORTS; | 139 | hw->irq = IRQ_AMIGA_PORTS; |
140 | hw->ack_intr = ack_intr; | 140 | hw->ack_intr = ack_intr; |
@@ -221,15 +221,13 @@ fail_base2: | |||
221 | 221 | ||
222 | buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr); | 222 | buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr); |
223 | 223 | ||
224 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 224 | hwif = ide_find_port(); |
225 | if (hwif) { | 225 | if (hwif) { |
226 | u8 index = hwif->index; | 226 | u8 index = hwif->index; |
227 | 227 | ||
228 | ide_init_port_data(hwif, index); | 228 | ide_init_port_data(hwif, index); |
229 | ide_init_port_hw(hwif, &hw); | 229 | ide_init_port_hw(hwif, &hw); |
230 | 230 | ||
231 | hwif->mmio = 1; | ||
232 | |||
233 | idx[i] = index; | 231 | idx[i] = index; |
234 | } | 232 | } |
235 | } | 233 | } |
diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c index 73396f70f2b7..af791a02a120 100644 --- a/drivers/ide/legacy/dtc2278.c +++ b/drivers/ide/legacy/dtc2278.c | |||
@@ -16,6 +16,8 @@ | |||
16 | 16 | ||
17 | #include <asm/io.h> | 17 | #include <asm/io.h> |
18 | 18 | ||
19 | #define DRV_NAME "dtc2278" | ||
20 | |||
19 | /* | 21 | /* |
20 | * Changing this #undef to #define may solve start up problems in some systems. | 22 | * Changing this #undef to #define may solve start up problems in some systems. |
21 | */ | 23 | */ |
@@ -86,29 +88,26 @@ static void dtc2278_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
86 | } | 88 | } |
87 | } | 89 | } |
88 | 90 | ||
91 | static const struct ide_port_ops dtc2278_port_ops = { | ||
92 | .set_pio_mode = dtc2278_set_pio_mode, | ||
93 | }; | ||
94 | |||
89 | static const struct ide_port_info dtc2278_port_info __initdata = { | 95 | static const struct ide_port_info dtc2278_port_info __initdata = { |
96 | .name = DRV_NAME, | ||
90 | .chipset = ide_dtc2278, | 97 | .chipset = ide_dtc2278, |
98 | .port_ops = &dtc2278_port_ops, | ||
91 | .host_flags = IDE_HFLAG_SERIALIZE | | 99 | .host_flags = IDE_HFLAG_SERIALIZE | |
92 | IDE_HFLAG_NO_UNMASK_IRQS | | 100 | IDE_HFLAG_NO_UNMASK_IRQS | |
93 | IDE_HFLAG_IO_32BIT | | 101 | IDE_HFLAG_IO_32BIT | |
94 | /* disallow ->io_32bit changes */ | 102 | /* disallow ->io_32bit changes */ |
95 | IDE_HFLAG_NO_IO_32BIT | | 103 | IDE_HFLAG_NO_IO_32BIT | |
96 | IDE_HFLAG_NO_DMA | | 104 | IDE_HFLAG_NO_DMA, |
97 | IDE_HFLAG_NO_AUTOTUNE, | ||
98 | .pio_mask = ATA_PIO4, | 105 | .pio_mask = ATA_PIO4, |
99 | }; | 106 | }; |
100 | 107 | ||
101 | static int __init dtc2278_probe(void) | 108 | static int __init dtc2278_probe(void) |
102 | { | 109 | { |
103 | unsigned long flags; | 110 | unsigned long flags; |
104 | ide_hwif_t *hwif, *mate; | ||
105 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; | ||
106 | |||
107 | hwif = &ide_hwifs[0]; | ||
108 | mate = &ide_hwifs[1]; | ||
109 | |||
110 | if (hwif->chipset != ide_unknown || mate->chipset != ide_unknown) | ||
111 | return 1; | ||
112 | 111 | ||
113 | local_irq_save(flags); | 112 | local_irq_save(flags); |
114 | /* | 113 | /* |
@@ -128,14 +127,10 @@ static int __init dtc2278_probe(void) | |||
128 | #endif | 127 | #endif |
129 | local_irq_restore(flags); | 128 | local_irq_restore(flags); |
130 | 129 | ||
131 | hwif->set_pio_mode = &dtc2278_set_pio_mode; | 130 | return ide_legacy_device_add(&dtc2278_port_info, 0); |
132 | |||
133 | ide_device_add(idx, &dtc2278_port_info); | ||
134 | |||
135 | return 0; | ||
136 | } | 131 | } |
137 | 132 | ||
138 | int probe_dtc2278 = 0; | 133 | static int probe_dtc2278; |
139 | 134 | ||
140 | module_param_named(probe, probe_dtc2278, bool, 0); | 135 | module_param_named(probe, probe_dtc2278, bool, 0); |
141 | MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets"); | 136 | MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets"); |
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index e950afa5939c..83555ca513b5 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/atariints.h> | 22 | #include <asm/atariints.h> |
23 | #include <asm/atari_stdma.h> | 23 | #include <asm/atari_stdma.h> |
24 | 24 | ||
25 | #define DRV_NAME "falconide" | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * Base of the IDE interface | 28 | * Base of the IDE interface |
@@ -43,18 +44,40 @@ | |||
43 | int falconide_intr_lock; | 44 | int falconide_intr_lock; |
44 | EXPORT_SYMBOL(falconide_intr_lock); | 45 | EXPORT_SYMBOL(falconide_intr_lock); |
45 | 46 | ||
47 | static void falconide_input_data(ide_drive_t *drive, struct request *rq, | ||
48 | void *buf, unsigned int len) | ||
49 | { | ||
50 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | ||
51 | |||
52 | if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) | ||
53 | return insw(data_addr, buf, (len + 1) / 2); | ||
54 | |||
55 | insw_swapw(data_addr, buf, (len + 1) / 2); | ||
56 | } | ||
57 | |||
58 | static void falconide_output_data(ide_drive_t *drive, struct request *rq, | ||
59 | void *buf, unsigned int len) | ||
60 | { | ||
61 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | ||
62 | |||
63 | if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) | ||
64 | return outsw(data_adr, buf, (len + 1) / 2); | ||
65 | |||
66 | outsw_swapw(data_addr, buf, (len + 1) / 2); | ||
67 | } | ||
68 | |||
46 | static void __init falconide_setup_ports(hw_regs_t *hw) | 69 | static void __init falconide_setup_ports(hw_regs_t *hw) |
47 | { | 70 | { |
48 | int i; | 71 | int i; |
49 | 72 | ||
50 | memset(hw, 0, sizeof(*hw)); | 73 | memset(hw, 0, sizeof(*hw)); |
51 | 74 | ||
52 | hw->io_ports[IDE_DATA_OFFSET] = ATA_HD_BASE; | 75 | hw->io_ports.data_addr = ATA_HD_BASE; |
53 | 76 | ||
54 | for (i = 1; i < 8; i++) | 77 | for (i = 1; i < 8; i++) |
55 | hw->io_ports[i] = ATA_HD_BASE + 1 + i * 4; | 78 | hw->io_ports_array[i] = ATA_HD_BASE + 1 + i * 4; |
56 | 79 | ||
57 | hw->io_ports[IDE_CONTROL_OFFSET] = ATA_HD_BASE + ATA_HD_CONTROL; | 80 | hw->io_ports.ctl_addr = ATA_HD_BASE + ATA_HD_CONTROL; |
58 | 81 | ||
59 | hw->irq = IRQ_MFP_IDE; | 82 | hw->irq = IRQ_MFP_IDE; |
60 | hw->ack_intr = NULL; | 83 | hw->ack_intr = NULL; |
@@ -74,9 +97,14 @@ static int __init falconide_init(void) | |||
74 | 97 | ||
75 | printk(KERN_INFO "ide: Falcon IDE controller\n"); | 98 | printk(KERN_INFO "ide: Falcon IDE controller\n"); |
76 | 99 | ||
100 | if (!request_mem_region(ATA_HD_BASE, 0x40, DRV_NAME)) { | ||
101 | printk(KERN_ERR "%s: resources busy\n", DRV_NAME); | ||
102 | return -EBUSY; | ||
103 | } | ||
104 | |||
77 | falconide_setup_ports(&hw); | 105 | falconide_setup_ports(&hw); |
78 | 106 | ||
79 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 107 | hwif = ide_find_port(); |
80 | if (hwif) { | 108 | if (hwif) { |
81 | u8 index = hwif->index; | 109 | u8 index = hwif->index; |
82 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | 110 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; |
@@ -84,6 +112,10 @@ static int __init falconide_init(void) | |||
84 | ide_init_port_data(hwif, index); | 112 | ide_init_port_data(hwif, index); |
85 | ide_init_port_hw(hwif, &hw); | 113 | ide_init_port_hw(hwif, &hw); |
86 | 114 | ||
115 | /* Atari has a byte-swapped IDE interface */ | ||
116 | hwif->input_data = falconide_input_data; | ||
117 | hwif->output_data = falconide_output_data; | ||
118 | |||
87 | ide_get_lock(NULL, NULL); | 119 | ide_get_lock(NULL, NULL); |
88 | ide_device_add(idx, NULL); | 120 | ide_device_add(idx, NULL); |
89 | ide_release_lock(); | 121 | ide_release_lock(); |
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c index e3b4638cc883..a9c2593a898c 100644 --- a/drivers/ide/legacy/gayle.c +++ b/drivers/ide/legacy/gayle.c | |||
@@ -63,6 +63,8 @@ | |||
63 | #define GAYLE_HAS_CONTROL_REG (!ide_doubler) | 63 | #define GAYLE_HAS_CONTROL_REG (!ide_doubler) |
64 | #define GAYLE_IDEREG_SIZE (ide_doubler ? 0x1000 : 0x2000) | 64 | #define GAYLE_IDEREG_SIZE (ide_doubler ? 0x1000 : 0x2000) |
65 | int ide_doubler = 0; /* support IDE doublers? */ | 65 | int ide_doubler = 0; /* support IDE doublers? */ |
66 | module_param_named(doubler, ide_doubler, bool, 0); | ||
67 | MODULE_PARM_DESC(doubler, "enable support for IDE doublers"); | ||
66 | #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ | 68 | #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ |
67 | 69 | ||
68 | 70 | ||
@@ -74,7 +76,7 @@ static int gayle_ack_intr_a4000(ide_hwif_t *hwif) | |||
74 | { | 76 | { |
75 | unsigned char ch; | 77 | unsigned char ch; |
76 | 78 | ||
77 | ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]); | 79 | ch = z_readb(hwif->io_ports.irq_addr); |
78 | if (!(ch & GAYLE_IRQ_IDE)) | 80 | if (!(ch & GAYLE_IRQ_IDE)) |
79 | return 0; | 81 | return 0; |
80 | return 1; | 82 | return 1; |
@@ -84,11 +86,11 @@ static int gayle_ack_intr_a1200(ide_hwif_t *hwif) | |||
84 | { | 86 | { |
85 | unsigned char ch; | 87 | unsigned char ch; |
86 | 88 | ||
87 | ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]); | 89 | ch = z_readb(hwif->io_ports.irq_addr); |
88 | if (!(ch & GAYLE_IRQ_IDE)) | 90 | if (!(ch & GAYLE_IRQ_IDE)) |
89 | return 0; | 91 | return 0; |
90 | (void)z_readb(hwif->io_ports[IDE_STATUS_OFFSET]); | 92 | (void)z_readb(hwif->io_ports.status_addr); |
91 | z_writeb(0x7c, hwif->io_ports[IDE_IRQ_OFFSET]); | 93 | z_writeb(0x7c, hwif->io_ports.irq_addr); |
92 | return 1; | 94 | return 1; |
93 | } | 95 | } |
94 | 96 | ||
@@ -100,13 +102,13 @@ static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base, | |||
100 | 102 | ||
101 | memset(hw, 0, sizeof(*hw)); | 103 | memset(hw, 0, sizeof(*hw)); |
102 | 104 | ||
103 | hw->io_ports[IDE_DATA_OFFSET] = base; | 105 | hw->io_ports.data_addr = base; |
104 | 106 | ||
105 | for (i = 1; i < 8; i++) | 107 | for (i = 1; i < 8; i++) |
106 | hw->io_ports[i] = base + 2 + i * 4; | 108 | hw->io_ports_array[i] = base + 2 + i * 4; |
107 | 109 | ||
108 | hw->io_ports[IDE_CONTROL_OFFSET] = ctl; | 110 | hw->io_ports.ctl_addr = ctl; |
109 | hw->io_ports[IDE_IRQ_OFFSET] = irq_port; | 111 | hw->io_ports.irq_addr = irq_port; |
110 | 112 | ||
111 | hw->irq = IRQ_AMIGA_PORTS; | 113 | hw->irq = IRQ_AMIGA_PORTS; |
112 | hw->ack_intr = ack_intr; | 114 | hw->ack_intr = ack_intr; |
@@ -175,15 +177,13 @@ found: | |||
175 | 177 | ||
176 | gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr); | 178 | gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr); |
177 | 179 | ||
178 | hwif = ide_find_port(base); | 180 | hwif = ide_find_port(); |
179 | if (hwif) { | 181 | if (hwif) { |
180 | u8 index = hwif->index; | 182 | u8 index = hwif->index; |
181 | 183 | ||
182 | ide_init_port_data(hwif, index); | 184 | ide_init_port_data(hwif, index); |
183 | ide_init_port_hw(hwif, &hw); | 185 | ide_init_port_hw(hwif, &hw); |
184 | 186 | ||
185 | hwif->mmio = 1; | ||
186 | |||
187 | idx[i] = index; | 187 | idx[i] = index; |
188 | } else | 188 | } else |
189 | release_mem_region(res_start, res_n); | 189 | release_mem_region(res_start, res_n); |
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c index 0b0d86731927..abdedf56643e 100644 --- a/drivers/ide/legacy/hd.c +++ b/drivers/ide/legacy/hd.c | |||
@@ -122,12 +122,12 @@ static int hd_error; | |||
122 | * This struct defines the HD's and their types. | 122 | * This struct defines the HD's and their types. |
123 | */ | 123 | */ |
124 | struct hd_i_struct { | 124 | struct hd_i_struct { |
125 | unsigned int head,sect,cyl,wpcom,lzone,ctl; | 125 | unsigned int head, sect, cyl, wpcom, lzone, ctl; |
126 | int unit; | 126 | int unit; |
127 | int recalibrate; | 127 | int recalibrate; |
128 | int special_op; | 128 | int special_op; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | #ifdef HD_TYPE | 131 | #ifdef HD_TYPE |
132 | static struct hd_i_struct hd_info[] = { HD_TYPE }; | 132 | static struct hd_i_struct hd_info[] = { HD_TYPE }; |
133 | static int NR_HD = ARRAY_SIZE(hd_info); | 133 | static int NR_HD = ARRAY_SIZE(hd_info); |
@@ -168,7 +168,7 @@ unsigned long read_timer(void) | |||
168 | 168 | ||
169 | spin_lock_irqsave(&i8253_lock, flags); | 169 | spin_lock_irqsave(&i8253_lock, flags); |
170 | t = jiffies * 11932; | 170 | t = jiffies * 11932; |
171 | outb_p(0, 0x43); | 171 | outb_p(0, 0x43); |
172 | i = inb_p(0x40); | 172 | i = inb_p(0x40); |
173 | i |= inb(0x40) << 8; | 173 | i |= inb(0x40) << 8; |
174 | spin_unlock_irqrestore(&i8253_lock, flags); | 174 | spin_unlock_irqrestore(&i8253_lock, flags); |
@@ -183,7 +183,7 @@ static void __init hd_setup(char *str, int *ints) | |||
183 | if (ints[0] != 3) | 183 | if (ints[0] != 3) |
184 | return; | 184 | return; |
185 | if (hd_info[0].head != 0) | 185 | if (hd_info[0].head != 0) |
186 | hdind=1; | 186 | hdind = 1; |
187 | hd_info[hdind].head = ints[2]; | 187 | hd_info[hdind].head = ints[2]; |
188 | hd_info[hdind].sect = ints[3]; | 188 | hd_info[hdind].sect = ints[3]; |
189 | hd_info[hdind].cyl = ints[1]; | 189 | hd_info[hdind].cyl = ints[1]; |
@@ -193,7 +193,7 @@ static void __init hd_setup(char *str, int *ints) | |||
193 | NR_HD = hdind+1; | 193 | NR_HD = hdind+1; |
194 | } | 194 | } |
195 | 195 | ||
196 | static void dump_status (const char *msg, unsigned int stat) | 196 | static void dump_status(const char *msg, unsigned int stat) |
197 | { | 197 | { |
198 | char *name = "hd?"; | 198 | char *name = "hd?"; |
199 | if (CURRENT) | 199 | if (CURRENT) |
@@ -291,7 +291,6 @@ static int controller_ready(unsigned int drive, unsigned int head) | |||
291 | return 0; | 291 | return 0; |
292 | } | 292 | } |
293 | 293 | ||
294 | |||
295 | static void hd_out(struct hd_i_struct *disk, | 294 | static void hd_out(struct hd_i_struct *disk, |
296 | unsigned int nsect, | 295 | unsigned int nsect, |
297 | unsigned int sect, | 296 | unsigned int sect, |
@@ -313,15 +312,15 @@ static void hd_out(struct hd_i_struct *disk, | |||
313 | return; | 312 | return; |
314 | } | 313 | } |
315 | SET_HANDLER(intr_addr); | 314 | SET_HANDLER(intr_addr); |
316 | outb_p(disk->ctl,HD_CMD); | 315 | outb_p(disk->ctl, HD_CMD); |
317 | port=HD_DATA; | 316 | port = HD_DATA; |
318 | outb_p(disk->wpcom>>2,++port); | 317 | outb_p(disk->wpcom >> 2, ++port); |
319 | outb_p(nsect,++port); | 318 | outb_p(nsect, ++port); |
320 | outb_p(sect,++port); | 319 | outb_p(sect, ++port); |
321 | outb_p(cyl,++port); | 320 | outb_p(cyl, ++port); |
322 | outb_p(cyl>>8,++port); | 321 | outb_p(cyl >> 8, ++port); |
323 | outb_p(0xA0|(disk->unit<<4)|head,++port); | 322 | outb_p(0xA0 | (disk->unit << 4) | head, ++port); |
324 | outb_p(cmd,++port); | 323 | outb_p(cmd, ++port); |
325 | } | 324 | } |
326 | 325 | ||
327 | static void hd_request (void); | 326 | static void hd_request (void); |
@@ -344,14 +343,14 @@ static void reset_controller(void) | |||
344 | { | 343 | { |
345 | int i; | 344 | int i; |
346 | 345 | ||
347 | outb_p(4,HD_CMD); | 346 | outb_p(4, HD_CMD); |
348 | for(i = 0; i < 1000; i++) barrier(); | 347 | for (i = 0; i < 1000; i++) barrier(); |
349 | outb_p(hd_info[0].ctl & 0x0f,HD_CMD); | 348 | outb_p(hd_info[0].ctl & 0x0f, HD_CMD); |
350 | for(i = 0; i < 1000; i++) barrier(); | 349 | for (i = 0; i < 1000; i++) barrier(); |
351 | if (drive_busy()) | 350 | if (drive_busy()) |
352 | printk("hd: controller still busy\n"); | 351 | printk("hd: controller still busy\n"); |
353 | else if ((hd_error = inb(HD_ERROR)) != 1) | 352 | else if ((hd_error = inb(HD_ERROR)) != 1) |
354 | printk("hd: controller reset failed: %02x\n",hd_error); | 353 | printk("hd: controller reset failed: %02x\n", hd_error); |
355 | } | 354 | } |
356 | 355 | ||
357 | static void reset_hd(void) | 356 | static void reset_hd(void) |
@@ -371,8 +370,8 @@ repeat: | |||
371 | if (++i < NR_HD) { | 370 | if (++i < NR_HD) { |
372 | struct hd_i_struct *disk = &hd_info[i]; | 371 | struct hd_i_struct *disk = &hd_info[i]; |
373 | disk->special_op = disk->recalibrate = 1; | 372 | disk->special_op = disk->recalibrate = 1; |
374 | hd_out(disk,disk->sect,disk->sect,disk->head-1, | 373 | hd_out(disk, disk->sect, disk->sect, disk->head-1, |
375 | disk->cyl,WIN_SPECIFY,&reset_hd); | 374 | disk->cyl, WIN_SPECIFY, &reset_hd); |
376 | if (reset) | 375 | if (reset) |
377 | goto repeat; | 376 | goto repeat; |
378 | } else | 377 | } else |
@@ -393,7 +392,7 @@ static void unexpected_hd_interrupt(void) | |||
393 | unsigned int stat = inb_p(HD_STATUS); | 392 | unsigned int stat = inb_p(HD_STATUS); |
394 | 393 | ||
395 | if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) { | 394 | if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) { |
396 | dump_status ("unexpected interrupt", stat); | 395 | dump_status("unexpected interrupt", stat); |
397 | SET_TIMER; | 396 | SET_TIMER; |
398 | } | 397 | } |
399 | } | 398 | } |
@@ -453,7 +452,7 @@ static void read_intr(void) | |||
453 | return; | 452 | return; |
454 | ok_to_read: | 453 | ok_to_read: |
455 | req = CURRENT; | 454 | req = CURRENT; |
456 | insw(HD_DATA,req->buffer,256); | 455 | insw(HD_DATA, req->buffer, 256); |
457 | req->sector++; | 456 | req->sector++; |
458 | req->buffer += 512; | 457 | req->buffer += 512; |
459 | req->errors = 0; | 458 | req->errors = 0; |
@@ -507,7 +506,7 @@ ok_to_write: | |||
507 | end_request(req, 1); | 506 | end_request(req, 1); |
508 | if (i > 0) { | 507 | if (i > 0) { |
509 | SET_HANDLER(&write_intr); | 508 | SET_HANDLER(&write_intr); |
510 | outsw(HD_DATA,req->buffer,256); | 509 | outsw(HD_DATA, req->buffer, 256); |
511 | local_irq_enable(); | 510 | local_irq_enable(); |
512 | } else { | 511 | } else { |
513 | #if (HD_DELAY > 0) | 512 | #if (HD_DELAY > 0) |
@@ -560,11 +559,11 @@ static int do_special_op(struct hd_i_struct *disk, struct request *req) | |||
560 | { | 559 | { |
561 | if (disk->recalibrate) { | 560 | if (disk->recalibrate) { |
562 | disk->recalibrate = 0; | 561 | disk->recalibrate = 0; |
563 | hd_out(disk,disk->sect,0,0,0,WIN_RESTORE,&recal_intr); | 562 | hd_out(disk, disk->sect, 0, 0, 0, WIN_RESTORE, &recal_intr); |
564 | return reset; | 563 | return reset; |
565 | } | 564 | } |
566 | if (disk->head > 16) { | 565 | if (disk->head > 16) { |
567 | printk ("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name); | 566 | printk("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name); |
568 | end_request(req, 0); | 567 | end_request(req, 0); |
569 | } | 568 | } |
570 | disk->special_op = 0; | 569 | disk->special_op = 0; |
@@ -633,19 +632,21 @@ repeat: | |||
633 | if (blk_fs_request(req)) { | 632 | if (blk_fs_request(req)) { |
634 | switch (rq_data_dir(req)) { | 633 | switch (rq_data_dir(req)) { |
635 | case READ: | 634 | case READ: |
636 | hd_out(disk,nsect,sec,head,cyl,WIN_READ,&read_intr); | 635 | hd_out(disk, nsect, sec, head, cyl, WIN_READ, |
636 | &read_intr); | ||
637 | if (reset) | 637 | if (reset) |
638 | goto repeat; | 638 | goto repeat; |
639 | break; | 639 | break; |
640 | case WRITE: | 640 | case WRITE: |
641 | hd_out(disk,nsect,sec,head,cyl,WIN_WRITE,&write_intr); | 641 | hd_out(disk, nsect, sec, head, cyl, WIN_WRITE, |
642 | &write_intr); | ||
642 | if (reset) | 643 | if (reset) |
643 | goto repeat; | 644 | goto repeat; |
644 | if (wait_DRQ()) { | 645 | if (wait_DRQ()) { |
645 | bad_rw_intr(); | 646 | bad_rw_intr(); |
646 | goto repeat; | 647 | goto repeat; |
647 | } | 648 | } |
648 | outsw(HD_DATA,req->buffer,256); | 649 | outsw(HD_DATA, req->buffer, 256); |
649 | break; | 650 | break; |
650 | default: | 651 | default: |
651 | printk("unknown hd-command\n"); | 652 | printk("unknown hd-command\n"); |
@@ -655,7 +656,7 @@ repeat: | |||
655 | } | 656 | } |
656 | } | 657 | } |
657 | 658 | ||
658 | static void do_hd_request (struct request_queue * q) | 659 | static void do_hd_request(struct request_queue *q) |
659 | { | 660 | { |
660 | disable_irq(HD_IRQ); | 661 | disable_irq(HD_IRQ); |
661 | hd_request(); | 662 | hd_request(); |
@@ -708,12 +709,12 @@ static int __init hd_init(void) | |||
708 | { | 709 | { |
709 | int drive; | 710 | int drive; |
710 | 711 | ||
711 | if (register_blkdev(MAJOR_NR,"hd")) | 712 | if (register_blkdev(MAJOR_NR, "hd")) |
712 | return -1; | 713 | return -1; |
713 | 714 | ||
714 | hd_queue = blk_init_queue(do_hd_request, &hd_lock); | 715 | hd_queue = blk_init_queue(do_hd_request, &hd_lock); |
715 | if (!hd_queue) { | 716 | if (!hd_queue) { |
716 | unregister_blkdev(MAJOR_NR,"hd"); | 717 | unregister_blkdev(MAJOR_NR, "hd"); |
717 | return -ENOMEM; | 718 | return -ENOMEM; |
718 | } | 719 | } |
719 | 720 | ||
@@ -742,7 +743,7 @@ static int __init hd_init(void) | |||
742 | goto out; | 743 | goto out; |
743 | } | 744 | } |
744 | 745 | ||
745 | for (drive=0 ; drive < NR_HD ; drive++) { | 746 | for (drive = 0 ; drive < NR_HD ; drive++) { |
746 | struct gendisk *disk = alloc_disk(64); | 747 | struct gendisk *disk = alloc_disk(64); |
747 | struct hd_i_struct *p = &hd_info[drive]; | 748 | struct hd_i_struct *p = &hd_info[drive]; |
748 | if (!disk) | 749 | if (!disk) |
@@ -756,7 +757,7 @@ static int __init hd_init(void) | |||
756 | disk->queue = hd_queue; | 757 | disk->queue = hd_queue; |
757 | p->unit = drive; | 758 | p->unit = drive; |
758 | hd_gendisk[drive] = disk; | 759 | hd_gendisk[drive] = disk; |
759 | printk ("%s: %luMB, CHS=%d/%d/%d\n", | 760 | printk("%s: %luMB, CHS=%d/%d/%d\n", |
760 | disk->disk_name, (unsigned long)get_capacity(disk)/2048, | 761 | disk->disk_name, (unsigned long)get_capacity(disk)/2048, |
761 | p->cyl, p->head, p->sect); | 762 | p->cyl, p->head, p->sect); |
762 | } | 763 | } |
@@ -776,7 +777,7 @@ static int __init hd_init(void) | |||
776 | } | 777 | } |
777 | 778 | ||
778 | /* Let them fly */ | 779 | /* Let them fly */ |
779 | for(drive=0; drive < NR_HD; drive++) | 780 | for (drive = 0; drive < NR_HD; drive++) |
780 | add_disk(hd_gendisk[drive]); | 781 | add_disk(hd_gendisk[drive]); |
781 | 782 | ||
782 | return 0; | 783 | return 0; |
@@ -791,7 +792,7 @@ out1: | |||
791 | NR_HD = 0; | 792 | NR_HD = 0; |
792 | out: | 793 | out: |
793 | del_timer(&device_timer); | 794 | del_timer(&device_timer); |
794 | unregister_blkdev(MAJOR_NR,"hd"); | 795 | unregister_blkdev(MAJOR_NR, "hd"); |
795 | blk_cleanup_queue(hd_queue); | 796 | blk_cleanup_queue(hd_queue); |
796 | return -1; | 797 | return -1; |
797 | Enomem: | 798 | Enomem: |
@@ -800,7 +801,8 @@ Enomem: | |||
800 | goto out; | 801 | goto out; |
801 | } | 802 | } |
802 | 803 | ||
803 | static int __init parse_hd_setup (char *line) { | 804 | static int __init parse_hd_setup(char *line) |
805 | { | ||
804 | int ints[6]; | 806 | int ints[6]; |
805 | 807 | ||
806 | (void) get_options(line, ARRAY_SIZE(ints), ints); | 808 | (void) get_options(line, ARRAY_SIZE(ints), ints); |
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c index 78ca68e60f97..4fe516df9f74 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/legacy/ht6560b.c | |||
@@ -35,6 +35,7 @@ | |||
35 | * Try: http://www.maf.iki.fi/~maf/ht6560b/ | 35 | * Try: http://www.maf.iki.fi/~maf/ht6560b/ |
36 | */ | 36 | */ |
37 | 37 | ||
38 | #define DRV_NAME "ht6560b" | ||
38 | #define HT6560B_VERSION "v0.08" | 39 | #define HT6560B_VERSION "v0.08" |
39 | 40 | ||
40 | #include <linux/module.h> | 41 | #include <linux/module.h> |
@@ -82,7 +83,7 @@ | |||
82 | * out how they setup those cycle time interfacing values, as they at Holtek | 83 | * out how they setup those cycle time interfacing values, as they at Holtek |
83 | * call them. IDESETUP.COM that is supplied with the drivers figures out | 84 | * call them. IDESETUP.COM that is supplied with the drivers figures out |
84 | * optimal values and fetches those values to drivers. I found out that | 85 | * optimal values and fetches those values to drivers. I found out that |
85 | * they use IDE_SELECT_REG to fetch timings to the ide board right after | 86 | * they use Select register to fetch timings to the ide board right after |
86 | * interface switching. After that it was quite easy to add code to | 87 | * interface switching. After that it was quite easy to add code to |
87 | * ht6560b.c. | 88 | * ht6560b.c. |
88 | * | 89 | * |
@@ -127,6 +128,7 @@ | |||
127 | */ | 128 | */ |
128 | static void ht6560b_selectproc (ide_drive_t *drive) | 129 | static void ht6560b_selectproc (ide_drive_t *drive) |
129 | { | 130 | { |
131 | ide_hwif_t *hwif = drive->hwif; | ||
130 | unsigned long flags; | 132 | unsigned long flags; |
131 | static u8 current_select = 0; | 133 | static u8 current_select = 0; |
132 | static u8 current_timing = 0; | 134 | static u8 current_timing = 0; |
@@ -155,8 +157,8 @@ static void ht6560b_selectproc (ide_drive_t *drive) | |||
155 | /* | 157 | /* |
156 | * Set timing for this drive: | 158 | * Set timing for this drive: |
157 | */ | 159 | */ |
158 | outb(timing, IDE_SELECT_REG); | 160 | outb(timing, hwif->io_ports.device_addr); |
159 | (void)inb(IDE_STATUS_REG); | 161 | (void)inb(hwif->io_ports.status_addr); |
160 | #ifdef DEBUG | 162 | #ifdef DEBUG |
161 | printk("ht6560b: %s: select=%#x timing=%#x\n", | 163 | printk("ht6560b: %s: select=%#x timing=%#x\n", |
162 | drive->name, select, timing); | 164 | drive->name, select, timing); |
@@ -193,9 +195,9 @@ static int __init try_to_init_ht6560b(void) | |||
193 | * Ht6560b autodetected | 195 | * Ht6560b autodetected |
194 | */ | 196 | */ |
195 | outb(HT_CONFIG_DEFAULT, HT_CONFIG_PORT); | 197 | outb(HT_CONFIG_DEFAULT, HT_CONFIG_PORT); |
196 | outb(HT_TIMING_DEFAULT, 0x1f6); /* IDE_SELECT_REG */ | 198 | outb(HT_TIMING_DEFAULT, 0x1f6); /* Select register */ |
197 | (void) inb(0x1f7); /* IDE_STATUS_REG */ | 199 | (void)inb(0x1f7); /* Status register */ |
198 | 200 | ||
199 | printk("ht6560b " HT6560B_VERSION | 201 | printk("ht6560b " HT6560B_VERSION |
200 | ": chipset detected and initialized" | 202 | ": chipset detected and initialized" |
201 | #ifdef DEBUG | 203 | #ifdef DEBUG |
@@ -210,8 +212,8 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio) | |||
210 | { | 212 | { |
211 | int active_time, recovery_time; | 213 | int active_time, recovery_time; |
212 | int active_cycles, recovery_cycles; | 214 | int active_cycles, recovery_cycles; |
213 | int bus_speed = system_bus_clock(); | 215 | int bus_speed = ide_vlb_clk ? ide_vlb_clk : system_bus_clock(); |
214 | 216 | ||
215 | if (pio) { | 217 | if (pio) { |
216 | unsigned int cycle_time; | 218 | unsigned int cycle_time; |
217 | 219 | ||
@@ -321,54 +323,44 @@ static void __init ht6560b_port_init_devs(ide_hwif_t *hwif) | |||
321 | hwif->drives[1].drive_data = t; | 323 | hwif->drives[1].drive_data = t; |
322 | } | 324 | } |
323 | 325 | ||
324 | int probe_ht6560b = 0; | 326 | static int probe_ht6560b; |
325 | 327 | ||
326 | module_param_named(probe, probe_ht6560b, bool, 0); | 328 | module_param_named(probe, probe_ht6560b, bool, 0); |
327 | MODULE_PARM_DESC(probe, "probe for HT6560B chipset"); | 329 | MODULE_PARM_DESC(probe, "probe for HT6560B chipset"); |
328 | 330 | ||
331 | static const struct ide_port_ops ht6560b_port_ops = { | ||
332 | .port_init_devs = ht6560b_port_init_devs, | ||
333 | .set_pio_mode = ht6560b_set_pio_mode, | ||
334 | .selectproc = ht6560b_selectproc, | ||
335 | }; | ||
336 | |||
329 | static const struct ide_port_info ht6560b_port_info __initdata = { | 337 | static const struct ide_port_info ht6560b_port_info __initdata = { |
338 | .name = DRV_NAME, | ||
330 | .chipset = ide_ht6560b, | 339 | .chipset = ide_ht6560b, |
340 | .port_ops = &ht6560b_port_ops, | ||
331 | .host_flags = IDE_HFLAG_SERIALIZE | /* is this needed? */ | 341 | .host_flags = IDE_HFLAG_SERIALIZE | /* is this needed? */ |
332 | IDE_HFLAG_NO_DMA | | 342 | IDE_HFLAG_NO_DMA | |
333 | IDE_HFLAG_NO_AUTOTUNE | | ||
334 | IDE_HFLAG_ABUSE_PREFETCH, | 343 | IDE_HFLAG_ABUSE_PREFETCH, |
335 | .pio_mask = ATA_PIO4, | 344 | .pio_mask = ATA_PIO4, |
336 | }; | 345 | }; |
337 | 346 | ||
338 | static int __init ht6560b_init(void) | 347 | static int __init ht6560b_init(void) |
339 | { | 348 | { |
340 | ide_hwif_t *hwif, *mate; | ||
341 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; | ||
342 | |||
343 | if (probe_ht6560b == 0) | 349 | if (probe_ht6560b == 0) |
344 | return -ENODEV; | 350 | return -ENODEV; |
345 | 351 | ||
346 | hwif = &ide_hwifs[0]; | 352 | if (!request_region(HT_CONFIG_PORT, 1, DRV_NAME)) { |
347 | mate = &ide_hwifs[1]; | ||
348 | |||
349 | if (!request_region(HT_CONFIG_PORT, 1, hwif->name)) { | ||
350 | printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n", | 353 | printk(KERN_NOTICE "%s: HT_CONFIG_PORT not found\n", |
351 | __FUNCTION__); | 354 | __func__); |
352 | return -ENODEV; | 355 | return -ENODEV; |
353 | } | 356 | } |
354 | 357 | ||
355 | if (!try_to_init_ht6560b()) { | 358 | if (!try_to_init_ht6560b()) { |
356 | printk(KERN_NOTICE "%s: HBA not found\n", __FUNCTION__); | 359 | printk(KERN_NOTICE "%s: HBA not found\n", __func__); |
357 | goto release_region; | 360 | goto release_region; |
358 | } | 361 | } |
359 | 362 | ||
360 | hwif->selectproc = &ht6560b_selectproc; | 363 | return ide_legacy_device_add(&ht6560b_port_info, 0); |
361 | hwif->set_pio_mode = &ht6560b_set_pio_mode; | ||
362 | |||
363 | mate->selectproc = &ht6560b_selectproc; | ||
364 | mate->set_pio_mode = &ht6560b_set_pio_mode; | ||
365 | |||
366 | hwif->port_init_devs = ht6560b_port_init_devs; | ||
367 | mate->port_init_devs = ht6560b_port_init_devs; | ||
368 | |||
369 | ide_device_add(idx, &ht6560b_port_info); | ||
370 | |||
371 | return 0; | ||
372 | 364 | ||
373 | release_region: | 365 | release_region: |
374 | release_region(HT_CONFIG_PORT, 1); | 366 | release_region(HT_CONFIG_PORT, 1); |
diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c new file mode 100644 index 000000000000..ecae916a3385 --- /dev/null +++ b/drivers/ide/legacy/ide-4drives.c | |||
@@ -0,0 +1,72 @@ | |||
1 | |||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/init.h> | ||
4 | #include <linux/module.h> | ||
5 | #include <linux/ide.h> | ||
6 | |||
7 | #define DRV_NAME "ide-4drives" | ||
8 | |||
9 | static int probe_4drives; | ||
10 | |||
11 | module_param_named(probe, probe_4drives, bool, 0); | ||
12 | MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port"); | ||
13 | |||
14 | static int __init ide_4drives_init(void) | ||
15 | { | ||
16 | ide_hwif_t *hwif, *mate; | ||
17 | unsigned long base = 0x1f0, ctl = 0x3f6; | ||
18 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | ||
19 | hw_regs_t hw; | ||
20 | |||
21 | if (probe_4drives == 0) | ||
22 | return -ENODEV; | ||
23 | |||
24 | if (!request_region(base, 8, DRV_NAME)) { | ||
25 | printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", | ||
26 | DRV_NAME, base, base + 7); | ||
27 | return -EBUSY; | ||
28 | } | ||
29 | |||
30 | if (!request_region(ctl, 1, DRV_NAME)) { | ||
31 | printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", | ||
32 | DRV_NAME, ctl); | ||
33 | release_region(base, 8); | ||
34 | return -EBUSY; | ||
35 | } | ||
36 | |||
37 | memset(&hw, 0, sizeof(hw)); | ||
38 | |||
39 | ide_std_init_ports(&hw, base, ctl); | ||
40 | hw.irq = 14; | ||
41 | hw.chipset = ide_4drives; | ||
42 | |||
43 | hwif = ide_find_port(); | ||
44 | if (hwif) { | ||
45 | ide_init_port_hw(hwif, &hw); | ||
46 | idx[0] = hwif->index; | ||
47 | } | ||
48 | |||
49 | mate = ide_find_port(); | ||
50 | if (mate) { | ||
51 | ide_init_port_hw(mate, &hw); | ||
52 | mate->drives[0].select.all ^= 0x20; | ||
53 | mate->drives[1].select.all ^= 0x20; | ||
54 | idx[1] = mate->index; | ||
55 | |||
56 | if (hwif) { | ||
57 | hwif->mate = mate; | ||
58 | mate->mate = hwif; | ||
59 | hwif->serialized = mate->serialized = 1; | ||
60 | } | ||
61 | } | ||
62 | |||
63 | ide_device_add(idx, NULL); | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | module_init(ide_4drives_init); | ||
69 | |||
70 | MODULE_AUTHOR("Bartlomiej Zolnierkiewicz"); | ||
71 | MODULE_DESCRIPTION("generic IDE chipset with 4 drives/port support"); | ||
72 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index 15ccf6944ae2..aa2ea3deac85 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -51,6 +51,8 @@ | |||
51 | #include <pcmcia/cisreg.h> | 51 | #include <pcmcia/cisreg.h> |
52 | #include <pcmcia/ciscode.h> | 52 | #include <pcmcia/ciscode.h> |
53 | 53 | ||
54 | #define DRV_NAME "ide-cs" | ||
55 | |||
54 | /*====================================================================*/ | 56 | /*====================================================================*/ |
55 | 57 | ||
56 | /* Module parameters */ | 58 | /* Module parameters */ |
@@ -72,16 +74,11 @@ static char *version = | |||
72 | 74 | ||
73 | /*====================================================================*/ | 75 | /*====================================================================*/ |
74 | 76 | ||
75 | static const char ide_major[] = { | ||
76 | IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, | ||
77 | IDE4_MAJOR, IDE5_MAJOR | ||
78 | }; | ||
79 | |||
80 | typedef struct ide_info_t { | 77 | typedef struct ide_info_t { |
81 | struct pcmcia_device *p_dev; | 78 | struct pcmcia_device *p_dev; |
79 | ide_hwif_t *hwif; | ||
82 | int ndev; | 80 | int ndev; |
83 | dev_node_t node; | 81 | dev_node_t node; |
84 | int hd; | ||
85 | } ide_info_t; | 82 | } ide_info_t; |
86 | 83 | ||
87 | static void ide_release(struct pcmcia_device *); | 84 | static void ide_release(struct pcmcia_device *); |
@@ -136,45 +133,71 @@ static int ide_probe(struct pcmcia_device *link) | |||
136 | 133 | ||
137 | static void ide_detach(struct pcmcia_device *link) | 134 | static void ide_detach(struct pcmcia_device *link) |
138 | { | 135 | { |
136 | ide_info_t *info = link->priv; | ||
137 | ide_hwif_t *hwif = info->hwif; | ||
138 | |||
139 | DEBUG(0, "ide_detach(0x%p)\n", link); | 139 | DEBUG(0, "ide_detach(0x%p)\n", link); |
140 | 140 | ||
141 | ide_release(link); | 141 | ide_release(link); |
142 | 142 | ||
143 | kfree(link->priv); | 143 | release_region(hwif->io_ports.ctl_addr, 1); |
144 | release_region(hwif->io_ports.data_addr, 8); | ||
145 | |||
146 | kfree(info); | ||
144 | } /* ide_detach */ | 147 | } /* ide_detach */ |
145 | 148 | ||
146 | static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) | 149 | static const struct ide_port_ops idecs_port_ops = { |
150 | .quirkproc = ide_undecoded_slave, | ||
151 | }; | ||
152 | |||
153 | static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl, | ||
154 | unsigned long irq, struct pcmcia_device *handle) | ||
147 | { | 155 | { |
148 | ide_hwif_t *hwif; | 156 | ide_hwif_t *hwif; |
149 | hw_regs_t hw; | 157 | hw_regs_t hw; |
150 | int i; | 158 | int i; |
151 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 159 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
152 | 160 | ||
161 | if (!request_region(io, 8, DRV_NAME)) { | ||
162 | printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", | ||
163 | DRV_NAME, io, io + 7); | ||
164 | return NULL; | ||
165 | } | ||
166 | |||
167 | if (!request_region(ctl, 1, DRV_NAME)) { | ||
168 | printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", | ||
169 | DRV_NAME, ctl); | ||
170 | release_region(io, 8); | ||
171 | return NULL; | ||
172 | } | ||
173 | |||
153 | memset(&hw, 0, sizeof(hw)); | 174 | memset(&hw, 0, sizeof(hw)); |
154 | ide_std_init_ports(&hw, io, ctl); | 175 | ide_std_init_ports(&hw, io, ctl); |
155 | hw.irq = irq; | 176 | hw.irq = irq; |
156 | hw.chipset = ide_pci; | 177 | hw.chipset = ide_pci; |
157 | hw.dev = &handle->dev; | 178 | hw.dev = &handle->dev; |
158 | 179 | ||
159 | hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 180 | hwif = ide_find_port(); |
160 | if (hwif == NULL) | 181 | if (hwif == NULL) |
161 | return -1; | 182 | goto out_release; |
162 | 183 | ||
163 | i = hwif->index; | 184 | i = hwif->index; |
164 | 185 | ||
165 | if (hwif->present) | 186 | ide_init_port_data(hwif, i); |
166 | ide_unregister(i, 0, 0); | ||
167 | else if (!hwif->hold) | ||
168 | ide_init_port_data(hwif, i); | ||
169 | |||
170 | ide_init_port_hw(hwif, &hw); | 187 | ide_init_port_hw(hwif, &hw); |
171 | hwif->quirkproc = &ide_undecoded_slave; | 188 | hwif->port_ops = &idecs_port_ops; |
172 | 189 | ||
173 | idx[0] = i; | 190 | idx[0] = i; |
174 | 191 | ||
175 | ide_device_add(idx, NULL); | 192 | ide_device_add(idx, NULL); |
176 | 193 | ||
177 | return hwif->present ? i : -1; | 194 | if (hwif->present) |
195 | return hwif; | ||
196 | |||
197 | out_release: | ||
198 | release_region(ctl, 1); | ||
199 | release_region(io, 8); | ||
200 | return NULL; | ||
178 | } | 201 | } |
179 | 202 | ||
180 | /*====================================================================== | 203 | /*====================================================================== |
@@ -199,8 +222,9 @@ static int ide_config(struct pcmcia_device *link) | |||
199 | cistpl_cftable_entry_t dflt; | 222 | cistpl_cftable_entry_t dflt; |
200 | } *stk = NULL; | 223 | } *stk = NULL; |
201 | cistpl_cftable_entry_t *cfg; | 224 | cistpl_cftable_entry_t *cfg; |
202 | int i, pass, last_ret = 0, last_fn = 0, hd, is_kme = 0; | 225 | int i, pass, last_ret = 0, last_fn = 0, is_kme = 0; |
203 | unsigned long io_base, ctl_base; | 226 | unsigned long io_base, ctl_base; |
227 | ide_hwif_t *hwif; | ||
204 | 228 | ||
205 | DEBUG(0, "ide_config(0x%p)\n", link); | 229 | DEBUG(0, "ide_config(0x%p)\n", link); |
206 | 230 | ||
@@ -296,14 +320,15 @@ static int ide_config(struct pcmcia_device *link) | |||
296 | outb(0x81, ctl_base+1); | 320 | outb(0x81, ctl_base+1); |
297 | 321 | ||
298 | /* retry registration in case device is still spinning up */ | 322 | /* retry registration in case device is still spinning up */ |
299 | for (hd = -1, i = 0; i < 10; i++) { | 323 | for (i = 0; i < 10; i++) { |
300 | hd = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link); | 324 | hwif = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link); |
301 | if (hd >= 0) break; | 325 | if (hwif) |
326 | break; | ||
302 | if (link->io.NumPorts1 == 0x20) { | 327 | if (link->io.NumPorts1 == 0x20) { |
303 | outb(0x02, ctl_base + 0x10); | 328 | outb(0x02, ctl_base + 0x10); |
304 | hd = idecs_register(io_base + 0x10, ctl_base + 0x10, | 329 | hwif = idecs_register(io_base + 0x10, ctl_base + 0x10, |
305 | link->irq.AssignedIRQ, link); | 330 | link->irq.AssignedIRQ, link); |
306 | if (hd >= 0) { | 331 | if (hwif) { |
307 | io_base += 0x10; | 332 | io_base += 0x10; |
308 | ctl_base += 0x10; | 333 | ctl_base += 0x10; |
309 | break; | 334 | break; |
@@ -312,7 +337,7 @@ static int ide_config(struct pcmcia_device *link) | |||
312 | msleep(100); | 337 | msleep(100); |
313 | } | 338 | } |
314 | 339 | ||
315 | if (hd < 0) { | 340 | if (hwif == NULL) { |
316 | printk(KERN_NOTICE "ide-cs: ide_register() at 0x%3lx & 0x%3lx" | 341 | printk(KERN_NOTICE "ide-cs: ide_register() at 0x%3lx & 0x%3lx" |
317 | ", irq %u failed\n", io_base, ctl_base, | 342 | ", irq %u failed\n", io_base, ctl_base, |
318 | link->irq.AssignedIRQ); | 343 | link->irq.AssignedIRQ); |
@@ -320,10 +345,10 @@ static int ide_config(struct pcmcia_device *link) | |||
320 | } | 345 | } |
321 | 346 | ||
322 | info->ndev = 1; | 347 | info->ndev = 1; |
323 | sprintf(info->node.dev_name, "hd%c", 'a' + (hd * 2)); | 348 | sprintf(info->node.dev_name, "hd%c", 'a' + hwif->index * 2); |
324 | info->node.major = ide_major[hd]; | 349 | info->node.major = hwif->major; |
325 | info->node.minor = 0; | 350 | info->node.minor = 0; |
326 | info->hd = hd; | 351 | info->hwif = hwif; |
327 | link->dev_node = &info->node; | 352 | link->dev_node = &info->node; |
328 | printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n", | 353 | printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n", |
329 | info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10); | 354 | info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10); |
@@ -354,13 +379,14 @@ failed: | |||
354 | void ide_release(struct pcmcia_device *link) | 379 | void ide_release(struct pcmcia_device *link) |
355 | { | 380 | { |
356 | ide_info_t *info = link->priv; | 381 | ide_info_t *info = link->priv; |
382 | ide_hwif_t *hwif = info->hwif; | ||
357 | 383 | ||
358 | DEBUG(0, "ide_release(0x%p)\n", link); | 384 | DEBUG(0, "ide_release(0x%p)\n", link); |
359 | 385 | ||
360 | if (info->ndev) { | 386 | if (info->ndev) { |
361 | /* FIXME: if this fails we need to queue the cleanup somehow | 387 | /* FIXME: if this fails we need to queue the cleanup somehow |
362 | -- need to investigate the required PCMCIA magic */ | 388 | -- need to investigate the required PCMCIA magic */ |
363 | ide_unregister(info->hd, 0, 0); | 389 | ide_unregister(hwif); |
364 | } | 390 | } |
365 | info->ndev = 0; | 391 | info->ndev = 0; |
366 | 392 | ||
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c index 688fcae17488..d3bc3f24e05d 100644 --- a/drivers/ide/legacy/ide_platform.c +++ b/drivers/ide/legacy/ide_platform.c | |||
@@ -30,14 +30,14 @@ static void __devinit plat_ide_setup_ports(hw_regs_t *hw, | |||
30 | unsigned long port = (unsigned long)base; | 30 | unsigned long port = (unsigned long)base; |
31 | int i; | 31 | int i; |
32 | 32 | ||
33 | hw->io_ports[IDE_DATA_OFFSET] = port; | 33 | hw->io_ports.data_addr = port; |
34 | 34 | ||
35 | port += (1 << pdata->ioport_shift); | 35 | port += (1 << pdata->ioport_shift); |
36 | for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET; | 36 | for (i = 1; i <= 7; |
37 | i++, port += (1 << pdata->ioport_shift)) | 37 | i++, port += (1 << pdata->ioport_shift)) |
38 | hw->io_ports[i] = port; | 38 | hw->io_ports_array[i] = port; |
39 | 39 | ||
40 | hw->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl; | 40 | hw->io_ports.ctl_addr = (unsigned long)ctrl; |
41 | 41 | ||
42 | hw->irq = irq; | 42 | hw->irq = irq; |
43 | 43 | ||
@@ -89,7 +89,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) | |||
89 | res_alt->start, res_alt->end - res_alt->start + 1); | 89 | res_alt->start, res_alt->end - res_alt->start + 1); |
90 | } | 90 | } |
91 | 91 | ||
92 | hwif = ide_find_port((unsigned long)base); | 92 | hwif = ide_find_port(); |
93 | if (!hwif) { | 93 | if (!hwif) { |
94 | ret = -ENODEV; | 94 | ret = -ENODEV; |
95 | goto out; | 95 | goto out; |
@@ -102,7 +102,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) | |||
102 | ide_init_port_hw(hwif, &hw); | 102 | ide_init_port_hw(hwif, &hw); |
103 | 103 | ||
104 | if (mmio) { | 104 | if (mmio) { |
105 | hwif->mmio = 1; | 105 | hwif->host_flags = IDE_HFLAG_MMIO; |
106 | default_hwif_mmiops(hwif); | 106 | default_hwif_mmiops(hwif); |
107 | } | 107 | } |
108 | 108 | ||
@@ -122,7 +122,7 @@ static int __devexit plat_ide_remove(struct platform_device *pdev) | |||
122 | { | 122 | { |
123 | ide_hwif_t *hwif = pdev->dev.driver_data; | 123 | ide_hwif_t *hwif = pdev->dev.driver_data; |
124 | 124 | ||
125 | ide_unregister(hwif->index, 0, 0); | 125 | ide_unregister(hwif); |
126 | 126 | ||
127 | return 0; | 127 | return 0; |
128 | } | 128 | } |
@@ -130,6 +130,7 @@ static int __devexit plat_ide_remove(struct platform_device *pdev) | |||
130 | static struct platform_driver platform_ide_driver = { | 130 | static struct platform_driver platform_ide_driver = { |
131 | .driver = { | 131 | .driver = { |
132 | .name = "pata_platform", | 132 | .name = "pata_platform", |
133 | .owner = THIS_MODULE, | ||
133 | }, | 134 | }, |
134 | .probe = plat_ide_probe, | 135 | .probe = plat_ide_probe, |
135 | .remove = __devexit_p(plat_ide_remove), | 136 | .remove = __devexit_p(plat_ide_remove), |
@@ -147,6 +148,7 @@ static void __exit platform_ide_exit(void) | |||
147 | 148 | ||
148 | MODULE_DESCRIPTION("Platform IDE driver"); | 149 | MODULE_DESCRIPTION("Platform IDE driver"); |
149 | MODULE_LICENSE("GPL"); | 150 | MODULE_LICENSE("GPL"); |
151 | MODULE_ALIAS("platform:pata_platform"); | ||
150 | 152 | ||
151 | module_init(platform_ide_init); | 153 | module_init(platform_ide_init); |
152 | module_exit(platform_ide_exit); | 154 | module_exit(platform_ide_exit); |
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index eaf5dbe58bc2..1f527bbf8d96 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c | |||
@@ -72,9 +72,9 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base, | |||
72 | memset(hw, 0, sizeof(*hw)); | 72 | memset(hw, 0, sizeof(*hw)); |
73 | 73 | ||
74 | for (i = 0; i < 8; i++) | 74 | for (i = 0; i < 8; i++) |
75 | hw->io_ports[i] = base + i * 4; | 75 | hw->io_ports_array[i] = base + i * 4; |
76 | 76 | ||
77 | hw->io_ports[IDE_CONTROL_OFFSET] = base + IDE_CONTROL; | 77 | hw->io_ports.ctl_addr = base + IDE_CONTROL; |
78 | 78 | ||
79 | hw->irq = irq; | 79 | hw->irq = irq; |
80 | hw->ack_intr = ack_intr; | 80 | hw->ack_intr = ack_intr; |
@@ -120,7 +120,7 @@ static int __init macide_init(void) | |||
120 | 120 | ||
121 | macide_setup_ports(&hw, base, irq, ack_intr); | 121 | macide_setup_ports(&hw, base, irq, ack_intr); |
122 | 122 | ||
123 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 123 | hwif = ide_find_port(); |
124 | if (hwif) { | 124 | if (hwif) { |
125 | u8 index = hwif->index; | 125 | u8 index = hwif->index; |
126 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; | 126 | u8 idx[4] = { index, 0xff, 0xff, 0xff }; |
@@ -128,8 +128,6 @@ static int __init macide_init(void) | |||
128 | ide_init_port_data(hwif, index); | 128 | ide_init_port_data(hwif, index); |
129 | ide_init_port_hw(hwif, &hw); | 129 | ide_init_port_hw(hwif, &hw); |
130 | 130 | ||
131 | hwif->mmio = 1; | ||
132 | |||
133 | ide_device_add(idx, NULL); | 131 | ide_device_add(idx, NULL); |
134 | } | 132 | } |
135 | 133 | ||
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c index 2da28759686e..6f535d00e638 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/legacy/q40ide.c | |||
@@ -36,23 +36,6 @@ static const unsigned long pcide_bases[Q40IDE_NUM_HWIFS] = { | |||
36 | PCIDE_BASE6 */ | 36 | PCIDE_BASE6 */ |
37 | }; | 37 | }; |
38 | 38 | ||
39 | |||
40 | /* | ||
41 | * Offsets from one of the above bases | ||
42 | */ | ||
43 | |||
44 | /* used to do addr translation here but it is easier to do in setup ports */ | ||
45 | /*#define IDE_OFF_B(x) ((unsigned long)Q40_ISA_IO_B((IDE_##x##_OFFSET)))*/ | ||
46 | |||
47 | #define IDE_OFF_B(x) ((unsigned long)((IDE_##x##_OFFSET))) | ||
48 | #define IDE_OFF_W(x) ((unsigned long)((IDE_##x##_OFFSET))) | ||
49 | |||
50 | static const int pcide_offsets[IDE_NR_PORTS] = { | ||
51 | IDE_OFF_W(DATA), IDE_OFF_B(ERROR), IDE_OFF_B(NSECTOR), IDE_OFF_B(SECTOR), | ||
52 | IDE_OFF_B(LCYL), IDE_OFF_B(HCYL), 6 /*IDE_OFF_B(CURRENT)*/, IDE_OFF_B(STATUS), | ||
53 | 518/*IDE_OFF(CMD)*/ | ||
54 | }; | ||
55 | |||
56 | static int q40ide_default_irq(unsigned long base) | 39 | static int q40ide_default_irq(unsigned long base) |
57 | { | 40 | { |
58 | switch (base) { | 41 | switch (base) { |
@@ -68,29 +51,48 @@ static int q40ide_default_irq(unsigned long base) | |||
68 | /* | 51 | /* |
69 | * Addresses are pretranslated for Q40 ISA access. | 52 | * Addresses are pretranslated for Q40 ISA access. |
70 | */ | 53 | */ |
71 | void q40_ide_setup_ports ( hw_regs_t *hw, | 54 | static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base, |
72 | unsigned long base, int *offsets, | ||
73 | unsigned long ctrl, unsigned long intr, | ||
74 | ide_ack_intr_t *ack_intr, | 55 | ide_ack_intr_t *ack_intr, |
75 | int irq) | 56 | int irq) |
76 | { | 57 | { |
77 | int i; | ||
78 | |||
79 | memset(hw, 0, sizeof(hw_regs_t)); | 58 | memset(hw, 0, sizeof(hw_regs_t)); |
80 | for (i = 0; i < IDE_NR_PORTS; i++) { | 59 | /* BIG FAT WARNING: |
81 | /* BIG FAT WARNING: | 60 | assumption: only DATA port is ever used in 16 bit mode */ |
82 | assumption: only DATA port is ever used in 16 bit mode */ | 61 | hw->io_ports.data_addr = Q40_ISA_IO_W(base); |
83 | if ( i==0 ) | 62 | hw->io_ports.error_addr = Q40_ISA_IO_B(base + 1); |
84 | hw->io_ports[i] = Q40_ISA_IO_W(base + offsets[i]); | 63 | hw->io_ports.nsect_addr = Q40_ISA_IO_B(base + 2); |
85 | else | 64 | hw->io_ports.lbal_addr = Q40_ISA_IO_B(base + 3); |
86 | hw->io_ports[i] = Q40_ISA_IO_B(base + offsets[i]); | 65 | hw->io_ports.lbam_addr = Q40_ISA_IO_B(base + 4); |
87 | } | 66 | hw->io_ports.lbah_addr = Q40_ISA_IO_B(base + 5); |
67 | hw->io_ports.device_addr = Q40_ISA_IO_B(base + 6); | ||
68 | hw->io_ports.status_addr = Q40_ISA_IO_B(base + 7); | ||
69 | hw->io_ports.ctl_addr = Q40_ISA_IO_B(base + 0x206); | ||
88 | 70 | ||
89 | hw->irq = irq; | 71 | hw->irq = irq; |
90 | hw->ack_intr = ack_intr; | 72 | hw->ack_intr = ack_intr; |
91 | } | 73 | } |
92 | 74 | ||
75 | static void q40ide_input_data(ide_drive_t *drive, struct request *rq, | ||
76 | void *buf, unsigned int len) | ||
77 | { | ||
78 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | ||
79 | |||
80 | if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) | ||
81 | return insw(data_addr, buf, (len + 1) / 2); | ||
93 | 82 | ||
83 | insw_swapw(data_addr, buf, (len + 1) / 2); | ||
84 | } | ||
85 | |||
86 | static void q40ide_output_data(ide_drive_t *drive, struct request *rq, | ||
87 | void *buf, unsigned int len) | ||
88 | { | ||
89 | unsigned long data_addr = drive->hwif->io_ports.data_addr; | ||
90 | |||
91 | if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS) | ||
92 | return outsw(data_addr, buf, (len + 1) / 2); | ||
93 | |||
94 | outsw_swapw(data_addr, buf, (len + 1) / 2); | ||
95 | } | ||
94 | 96 | ||
95 | /* | 97 | /* |
96 | * the static array is needed to have the name reported in /proc/ioports, | 98 | * the static array is needed to have the name reported in /proc/ioports, |
@@ -131,17 +133,19 @@ static int __init q40ide_init(void) | |||
131 | release_region(pcide_bases[i], 8); | 133 | release_region(pcide_bases[i], 8); |
132 | continue; | 134 | continue; |
133 | } | 135 | } |
134 | q40_ide_setup_ports(&hw,(unsigned long) pcide_bases[i], (int *)pcide_offsets, | 136 | q40_ide_setup_ports(&hw, pcide_bases[i], |
135 | pcide_bases[i]+0x206, | 137 | NULL, |
136 | 0, NULL, | ||
137 | // m68kide_iops, | 138 | // m68kide_iops, |
138 | q40ide_default_irq(pcide_bases[i])); | 139 | q40ide_default_irq(pcide_bases[i])); |
139 | 140 | ||
140 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 141 | hwif = ide_find_port(); |
141 | if (hwif) { | 142 | if (hwif) { |
142 | ide_init_port_data(hwif, hwif->index); | 143 | ide_init_port_data(hwif, hwif->index); |
143 | ide_init_port_hw(hwif, &hw); | 144 | ide_init_port_hw(hwif, &hw); |
144 | hwif->mmio = 1; | 145 | |
146 | /* Q40 has a byte-swapped IDE interface */ | ||
147 | hwif->input_data = q40ide_input_data; | ||
148 | hwif->output_data = q40ide_output_data; | ||
145 | 149 | ||
146 | idx[i] = hwif->index; | 150 | idx[i] = hwif->index; |
147 | } | 151 | } |
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index 2f4f47ad602f..6424af154325 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c | |||
@@ -11,11 +11,7 @@ | |||
11 | * | 11 | * |
12 | * QDI QD6500/QD6580 EIDE controller fast support | 12 | * QDI QD6500/QD6580 EIDE controller fast support |
13 | * | 13 | * |
14 | * Please set local bus speed using kernel parameter idebus | ||
15 | * for example, "idebus=33" stands for 33Mhz VLbus | ||
16 | * To activate controller support, use "ide0=qd65xx" | 14 | * To activate controller support, use "ide0=qd65xx" |
17 | * To enable tuning, use "hda=autotune hdb=autotune" | ||
18 | * To enable 2nd channel tuning (qd6580 only), use "hdc=autotune hdd=autotune" | ||
19 | */ | 15 | */ |
20 | 16 | ||
21 | /* | 17 | /* |
@@ -37,6 +33,8 @@ | |||
37 | #include <asm/system.h> | 33 | #include <asm/system.h> |
38 | #include <asm/io.h> | 34 | #include <asm/io.h> |
39 | 35 | ||
36 | #define DRV_NAME "qd65xx" | ||
37 | |||
40 | #include "qd65xx.h" | 38 | #include "qd65xx.h" |
41 | 39 | ||
42 | /* | 40 | /* |
@@ -88,12 +86,12 @@ | |||
88 | static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */ | 86 | static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */ |
89 | 87 | ||
90 | /* | 88 | /* |
91 | * qd_select: | 89 | * qd65xx_select: |
92 | * | 90 | * |
93 | * This routine is invoked from ide.c to prepare for access to a given drive. | 91 | * This routine is invoked to prepare for access to a given drive. |
94 | */ | 92 | */ |
95 | 93 | ||
96 | static void qd_select (ide_drive_t *drive) | 94 | static void qd65xx_select(ide_drive_t *drive) |
97 | { | 95 | { |
98 | u8 index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) | | 96 | u8 index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) | |
99 | (QD_TIMREG(drive) & 0x02); | 97 | (QD_TIMREG(drive) & 0x02); |
@@ -112,17 +110,18 @@ static void qd_select (ide_drive_t *drive) | |||
112 | 110 | ||
113 | static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery_time) | 111 | static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery_time) |
114 | { | 112 | { |
115 | u8 active_cycle,recovery_cycle; | 113 | int clk = ide_vlb_clk ? ide_vlb_clk : system_bus_clock(); |
114 | u8 act_cyc, rec_cyc; | ||
116 | 115 | ||
117 | if (system_bus_clock()<=33) { | 116 | if (clk <= 33) { |
118 | active_cycle = 9 - IDE_IN(active_time * system_bus_clock() / 1000 + 1, 2, 9); | 117 | act_cyc = 9 - IDE_IN(active_time * clk / 1000 + 1, 2, 9); |
119 | recovery_cycle = 15 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 0, 15); | 118 | rec_cyc = 15 - IDE_IN(recovery_time * clk / 1000 + 1, 0, 15); |
120 | } else { | 119 | } else { |
121 | active_cycle = 8 - IDE_IN(active_time * system_bus_clock() / 1000 + 1, 1, 8); | 120 | act_cyc = 8 - IDE_IN(active_time * clk / 1000 + 1, 1, 8); |
122 | recovery_cycle = 18 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 3, 18); | 121 | rec_cyc = 18 - IDE_IN(recovery_time * clk / 1000 + 1, 3, 18); |
123 | } | 122 | } |
124 | 123 | ||
125 | return((recovery_cycle<<4) | 0x08 | active_cycle); | 124 | return (rec_cyc << 4) | 0x08 | act_cyc; |
126 | } | 125 | } |
127 | 126 | ||
128 | /* | 127 | /* |
@@ -133,10 +132,13 @@ static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery | |||
133 | 132 | ||
134 | static u8 qd6580_compute_timing (int active_time, int recovery_time) | 133 | static u8 qd6580_compute_timing (int active_time, int recovery_time) |
135 | { | 134 | { |
136 | u8 active_cycle = 17 - IDE_IN(active_time * system_bus_clock() / 1000 + 1, 2, 17); | 135 | int clk = ide_vlb_clk ? ide_vlb_clk : system_bus_clock(); |
137 | u8 recovery_cycle = 15 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 2, 15); | 136 | u8 act_cyc, rec_cyc; |
137 | |||
138 | act_cyc = 17 - IDE_IN(active_time * clk / 1000 + 1, 2, 17); | ||
139 | rec_cyc = 15 - IDE_IN(recovery_time * clk / 1000 + 1, 2, 15); | ||
138 | 140 | ||
139 | return((recovery_cycle<<4) | active_cycle); | 141 | return (rec_cyc << 4) | act_cyc; |
140 | } | 142 | } |
141 | 143 | ||
142 | /* | 144 | /* |
@@ -168,36 +170,15 @@ static int qd_find_disk_type (ide_drive_t *drive, | |||
168 | } | 170 | } |
169 | 171 | ||
170 | /* | 172 | /* |
171 | * qd_timing_ok: | ||
172 | * | ||
173 | * check whether timings don't conflict | ||
174 | */ | ||
175 | |||
176 | static int qd_timing_ok (ide_drive_t drives[]) | ||
177 | { | ||
178 | return (IDE_IMPLY(drives[0].present && drives[1].present, | ||
179 | IDE_IMPLY(QD_TIMREG(drives) == QD_TIMREG(drives+1), | ||
180 | QD_TIMING(drives) == QD_TIMING(drives+1)))); | ||
181 | /* if same timing register, must be same timing */ | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * qd_set_timing: | 173 | * qd_set_timing: |
186 | * | 174 | * |
187 | * records the timing, and enables selectproc as needed | 175 | * records the timing |
188 | */ | 176 | */ |
189 | 177 | ||
190 | static void qd_set_timing (ide_drive_t *drive, u8 timing) | 178 | static void qd_set_timing (ide_drive_t *drive, u8 timing) |
191 | { | 179 | { |
192 | ide_hwif_t *hwif = HWIF(drive); | ||
193 | |||
194 | drive->drive_data &= 0xff00; | 180 | drive->drive_data &= 0xff00; |
195 | drive->drive_data |= timing; | 181 | drive->drive_data |= timing; |
196 | if (qd_timing_ok(hwif->drives)) { | ||
197 | qd_select(drive); /* selects once */ | ||
198 | hwif->selectproc = NULL; | ||
199 | } else | ||
200 | hwif->selectproc = &qd_select; | ||
201 | 182 | ||
202 | printk(KERN_DEBUG "%s: %#x\n", drive->name, timing); | 183 | printk(KERN_DEBUG "%s: %#x\n", drive->name, timing); |
203 | } | 184 | } |
@@ -225,10 +206,11 @@ static void qd6500_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
225 | 206 | ||
226 | static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) | 207 | static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) |
227 | { | 208 | { |
228 | int base = HWIF(drive)->select_data; | 209 | ide_hwif_t *hwif = drive->hwif; |
229 | unsigned int cycle_time; | 210 | unsigned int cycle_time; |
230 | int active_time = 175; | 211 | int active_time = 175; |
231 | int recovery_time = 415; /* worst case values from the dos driver */ | 212 | int recovery_time = 415; /* worst case values from the dos driver */ |
213 | u8 base = (hwif->config_data & 0xff00) >> 8; | ||
232 | 214 | ||
233 | if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)) { | 215 | if (drive->id && !qd_find_disk_type(drive, &active_time, &recovery_time)) { |
234 | cycle_time = ide_pio_cycle_time(drive, pio); | 216 | cycle_time = ide_pio_cycle_time(drive, pio); |
@@ -299,21 +281,10 @@ static int __init qd_testreg(int port) | |||
299 | return (readreg != QD_TESTVAL); | 281 | return (readreg != QD_TESTVAL); |
300 | } | 282 | } |
301 | 283 | ||
302 | /* | ||
303 | * qd_setup: | ||
304 | * | ||
305 | * called to setup an ata channel : adjusts attributes & links for tuning | ||
306 | */ | ||
307 | |||
308 | static void __init qd_setup(ide_hwif_t *hwif, int base, int config) | ||
309 | { | ||
310 | hwif->select_data = base; | ||
311 | hwif->config_data = config; | ||
312 | } | ||
313 | |||
314 | static void __init qd6500_port_init_devs(ide_hwif_t *hwif) | 284 | static void __init qd6500_port_init_devs(ide_hwif_t *hwif) |
315 | { | 285 | { |
316 | u8 base = hwif->select_data, config = QD_CONFIG(hwif); | 286 | u8 base = (hwif->config_data & 0xff00) >> 8; |
287 | u8 config = QD_CONFIG(hwif); | ||
317 | 288 | ||
318 | hwif->drives[0].drive_data = QD6500_DEF_DATA; | 289 | hwif->drives[0].drive_data = QD6500_DEF_DATA; |
319 | hwif->drives[1].drive_data = QD6500_DEF_DATA; | 290 | hwif->drives[1].drive_data = QD6500_DEF_DATA; |
@@ -322,9 +293,10 @@ static void __init qd6500_port_init_devs(ide_hwif_t *hwif) | |||
322 | static void __init qd6580_port_init_devs(ide_hwif_t *hwif) | 293 | static void __init qd6580_port_init_devs(ide_hwif_t *hwif) |
323 | { | 294 | { |
324 | u16 t1, t2; | 295 | u16 t1, t2; |
325 | u8 base = hwif->select_data, config = QD_CONFIG(hwif); | 296 | u8 base = (hwif->config_data & 0xff00) >> 8; |
297 | u8 config = QD_CONFIG(hwif); | ||
326 | 298 | ||
327 | if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) { | 299 | if (hwif->host_flags & IDE_HFLAG_SINGLE) { |
328 | t1 = QD6580_DEF_DATA; | 300 | t1 = QD6580_DEF_DATA; |
329 | t2 = QD6580_DEF_DATA2; | 301 | t2 = QD6580_DEF_DATA2; |
330 | } else | 302 | } else |
@@ -334,11 +306,23 @@ static void __init qd6580_port_init_devs(ide_hwif_t *hwif) | |||
334 | hwif->drives[1].drive_data = t2; | 306 | hwif->drives[1].drive_data = t2; |
335 | } | 307 | } |
336 | 308 | ||
309 | static const struct ide_port_ops qd6500_port_ops = { | ||
310 | .port_init_devs = qd6500_port_init_devs, | ||
311 | .set_pio_mode = qd6500_set_pio_mode, | ||
312 | .selectproc = qd65xx_select, | ||
313 | }; | ||
314 | |||
315 | static const struct ide_port_ops qd6580_port_ops = { | ||
316 | .port_init_devs = qd6580_port_init_devs, | ||
317 | .set_pio_mode = qd6580_set_pio_mode, | ||
318 | .selectproc = qd65xx_select, | ||
319 | }; | ||
320 | |||
337 | static const struct ide_port_info qd65xx_port_info __initdata = { | 321 | static const struct ide_port_info qd65xx_port_info __initdata = { |
322 | .name = DRV_NAME, | ||
338 | .chipset = ide_qd65xx, | 323 | .chipset = ide_qd65xx, |
339 | .host_flags = IDE_HFLAG_IO_32BIT | | 324 | .host_flags = IDE_HFLAG_IO_32BIT | |
340 | IDE_HFLAG_NO_DMA | | 325 | IDE_HFLAG_NO_DMA, |
341 | IDE_HFLAG_NO_AUTOTUNE, | ||
342 | .pio_mask = ATA_PIO4, | 326 | .pio_mask = ATA_PIO4, |
343 | }; | 327 | }; |
344 | 328 | ||
@@ -351,55 +335,41 @@ static const struct ide_port_info qd65xx_port_info __initdata = { | |||
351 | 335 | ||
352 | static int __init qd_probe(int base) | 336 | static int __init qd_probe(int base) |
353 | { | 337 | { |
354 | ide_hwif_t *hwif; | 338 | int rc; |
355 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 339 | u8 config, unit, control; |
356 | u8 config; | 340 | struct ide_port_info d = qd65xx_port_info; |
357 | u8 unit; | ||
358 | 341 | ||
359 | config = inb(QD_CONFIG_PORT); | 342 | config = inb(QD_CONFIG_PORT); |
360 | 343 | ||
361 | if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) ) | 344 | if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) ) |
362 | return 1; | 345 | return -ENODEV; |
363 | 346 | ||
364 | unit = ! (config & QD_CONFIG_IDE_BASEPORT); | 347 | unit = ! (config & QD_CONFIG_IDE_BASEPORT); |
365 | 348 | ||
366 | if ((config & 0xf0) == QD_CONFIG_QD6500) { | 349 | if (unit) |
350 | d.host_flags |= IDE_HFLAG_QD_2ND_PORT; | ||
367 | 351 | ||
368 | if (qd_testreg(base)) return 1; /* bad register */ | 352 | switch (config & 0xf0) { |
353 | case QD_CONFIG_QD6500: | ||
354 | if (qd_testreg(base)) | ||
355 | return -ENODEV; /* bad register */ | ||
369 | 356 | ||
370 | /* qd6500 found */ | ||
371 | |||
372 | hwif = &ide_hwifs[unit]; | ||
373 | printk(KERN_NOTICE "%s: qd6500 at %#x\n", hwif->name, base); | ||
374 | printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n", | ||
375 | config, QD_ID3); | ||
376 | |||
377 | if (config & QD_CONFIG_DISABLED) { | 357 | if (config & QD_CONFIG_DISABLED) { |
378 | printk(KERN_WARNING "qd6500 is disabled !\n"); | 358 | printk(KERN_WARNING "qd6500 is disabled !\n"); |
379 | return 1; | 359 | return -ENODEV; |
380 | } | 360 | } |
381 | 361 | ||
382 | qd_setup(hwif, base, config); | 362 | printk(KERN_NOTICE "qd6500 at %#x\n", base); |
383 | 363 | printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n", | |
384 | hwif->port_init_devs = qd6500_port_init_devs; | 364 | config, QD_ID3); |
385 | hwif->set_pio_mode = &qd6500_set_pio_mode; | ||
386 | |||
387 | idx[unit] = unit; | ||
388 | |||
389 | ide_device_add(idx, &qd65xx_port_info); | ||
390 | |||
391 | return 1; | ||
392 | } | ||
393 | |||
394 | if (((config & 0xf0) == QD_CONFIG_QD6580_A) || | ||
395 | ((config & 0xf0) == QD_CONFIG_QD6580_B)) { | ||
396 | |||
397 | u8 control; | ||
398 | |||
399 | if (qd_testreg(base) || qd_testreg(base+0x02)) return 1; | ||
400 | /* bad registers */ | ||
401 | 365 | ||
402 | /* qd6580 found */ | 366 | d.port_ops = &qd6500_port_ops; |
367 | d.host_flags |= IDE_HFLAG_SINGLE; | ||
368 | break; | ||
369 | case QD_CONFIG_QD6580_A: | ||
370 | case QD_CONFIG_QD6580_B: | ||
371 | if (qd_testreg(base) || qd_testreg(base + 0x02)) | ||
372 | return -ENODEV; /* bad registers */ | ||
403 | 373 | ||
404 | control = inb(QD_CONTROL_PORT); | 374 | control = inb(QD_CONTROL_PORT); |
405 | 375 | ||
@@ -409,69 +379,44 @@ static int __init qd_probe(int base) | |||
409 | 379 | ||
410 | outb(QD_DEF_CONTR, QD_CONTROL_PORT); | 380 | outb(QD_DEF_CONTR, QD_CONTROL_PORT); |
411 | 381 | ||
412 | if (control & QD_CONTR_SEC_DISABLED) { | 382 | d.port_ops = &qd6580_port_ops; |
413 | /* secondary disabled */ | 383 | if (control & QD_CONTR_SEC_DISABLED) |
414 | 384 | d.host_flags |= IDE_HFLAG_SINGLE; | |
415 | hwif = &ide_hwifs[unit]; | ||
416 | printk(KERN_INFO "%s: qd6580: single IDE board\n", | ||
417 | hwif->name); | ||
418 | |||
419 | qd_setup(hwif, base, config | (control << 8)); | ||
420 | |||
421 | hwif->port_init_devs = qd6580_port_init_devs; | ||
422 | hwif->set_pio_mode = &qd6580_set_pio_mode; | ||
423 | |||
424 | idx[unit] = unit; | ||
425 | 385 | ||
426 | ide_device_add(idx, &qd65xx_port_info); | 386 | printk(KERN_INFO "qd6580: %s IDE board\n", |
427 | 387 | (control & QD_CONTR_SEC_DISABLED) ? "single" : "dual"); | |
428 | return 1; | 388 | break; |
429 | } else { | 389 | default: |
430 | ide_hwif_t *mate; | 390 | return -ENODEV; |
431 | 391 | } | |
432 | hwif = &ide_hwifs[0]; | ||
433 | mate = &ide_hwifs[1]; | ||
434 | /* secondary enabled */ | ||
435 | printk(KERN_INFO "%s&%s: qd6580: dual IDE board\n", | ||
436 | hwif->name, mate->name); | ||
437 | |||
438 | qd_setup(hwif, base, config | (control << 8)); | ||
439 | |||
440 | hwif->port_init_devs = qd6580_port_init_devs; | ||
441 | hwif->set_pio_mode = &qd6580_set_pio_mode; | ||
442 | |||
443 | qd_setup(mate, base, config | (control << 8)); | ||
444 | |||
445 | mate->port_init_devs = qd6580_port_init_devs; | ||
446 | mate->set_pio_mode = &qd6580_set_pio_mode; | ||
447 | 392 | ||
448 | idx[0] = 0; | 393 | rc = ide_legacy_device_add(&d, (base << 8) | config); |
449 | idx[1] = 1; | ||
450 | 394 | ||
451 | ide_device_add(idx, &qd65xx_port_info); | 395 | if (d.host_flags & IDE_HFLAG_SINGLE) |
396 | return (rc == 0) ? 1 : rc; | ||
452 | 397 | ||
453 | return 0; /* no other qd65xx possible */ | 398 | return rc; |
454 | } | ||
455 | } | ||
456 | /* no qd65xx found */ | ||
457 | return 1; | ||
458 | } | 399 | } |
459 | 400 | ||
460 | int probe_qd65xx = 0; | 401 | static int probe_qd65xx; |
461 | 402 | ||
462 | module_param_named(probe, probe_qd65xx, bool, 0); | 403 | module_param_named(probe, probe_qd65xx, bool, 0); |
463 | MODULE_PARM_DESC(probe, "probe for QD65xx chipsets"); | 404 | MODULE_PARM_DESC(probe, "probe for QD65xx chipsets"); |
464 | 405 | ||
465 | static int __init qd65xx_init(void) | 406 | static int __init qd65xx_init(void) |
466 | { | 407 | { |
408 | int rc1, rc2 = -ENODEV; | ||
409 | |||
467 | if (probe_qd65xx == 0) | 410 | if (probe_qd65xx == 0) |
468 | return -ENODEV; | 411 | return -ENODEV; |
469 | 412 | ||
470 | if (qd_probe(0x30)) | 413 | rc1 = qd_probe(0x30); |
471 | qd_probe(0xb0); | 414 | if (rc1) |
472 | if (ide_hwifs[0].chipset != ide_qd65xx && | 415 | rc2 = qd_probe(0xb0); |
473 | ide_hwifs[1].chipset != ide_qd65xx) | 416 | |
417 | if (rc1 < 0 && rc2 < 0) | ||
474 | return -ENODEV; | 418 | return -ENODEV; |
419 | |||
475 | return 0; | 420 | return 0; |
476 | } | 421 | } |
477 | 422 | ||
diff --git a/drivers/ide/legacy/qd65xx.h b/drivers/ide/legacy/qd65xx.h index 28dd50a15d55..c83dea85e621 100644 --- a/drivers/ide/legacy/qd65xx.h +++ b/drivers/ide/legacy/qd65xx.h | |||
@@ -30,7 +30,6 @@ | |||
30 | #define QD_ID3 ((config & QD_CONFIG_ID3)!=0) | 30 | #define QD_ID3 ((config & QD_CONFIG_ID3)!=0) |
31 | 31 | ||
32 | #define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff) | 32 | #define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff) |
33 | #define QD_CONTROL(hwif) (((hwif)->config_data & 0xff00) >> 8) | ||
34 | 33 | ||
35 | #define QD_TIMING(drive) (byte)(((drive)->drive_data) & 0x00ff) | 34 | #define QD_TIMING(drive) (byte)(((drive)->drive_data) & 0x00ff) |
36 | #define QD_TIMREG(drive) (byte)((((drive)->drive_data) & 0xff00) >> 8) | 35 | #define QD_TIMREG(drive) (byte)((((drive)->drive_data) & 0xff00) >> 8) |
diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c index 5696ba026005..b54a14a57755 100644 --- a/drivers/ide/legacy/umc8672.c +++ b/drivers/ide/legacy/umc8672.c | |||
@@ -19,7 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * VLB Controller Support from | 22 | * VLB Controller Support from |
23 | * Wolfram Podien | 23 | * Wolfram Podien |
24 | * Rohoefe 3 | 24 | * Rohoefe 3 |
25 | * D28832 Achim | 25 | * D28832 Achim |
@@ -32,7 +32,7 @@ | |||
32 | * #define UMC_DRIVE0 11 | 32 | * #define UMC_DRIVE0 11 |
33 | * in the beginning of the driver, which sets the speed of drive 0 to 11 (there | 33 | * in the beginning of the driver, which sets the speed of drive 0 to 11 (there |
34 | * are some lines present). 0 - 11 are allowed speed values. These values are | 34 | * are some lines present). 0 - 11 are allowed speed values. These values are |
35 | * the results from the DOS speed test program supplied from UMC. 11 is the | 35 | * the results from the DOS speed test program supplied from UMC. 11 is the |
36 | * highest speed (about PIO mode 3) | 36 | * highest speed (about PIO mode 3) |
37 | */ | 37 | */ |
38 | #define REALLY_SLOW_IO /* some systems can safely undef this */ | 38 | #define REALLY_SLOW_IO /* some systems can safely undef this */ |
@@ -51,6 +51,8 @@ | |||
51 | 51 | ||
52 | #include <asm/io.h> | 52 | #include <asm/io.h> |
53 | 53 | ||
54 | #define DRV_NAME "umc8672" | ||
55 | |||
54 | /* | 56 | /* |
55 | * Default speeds. These can be changed with "auto-tune" and/or hdparm. | 57 | * Default speeds. These can be changed with "auto-tune" and/or hdparm. |
56 | */ | 58 | */ |
@@ -60,103 +62,103 @@ | |||
60 | #define UMC_DRIVE3 1 /* In case of crash reduce speed */ | 62 | #define UMC_DRIVE3 1 /* In case of crash reduce speed */ |
61 | 63 | ||
62 | static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3}; | 64 | static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3}; |
63 | static const u8 pio_to_umc [5] = {0,3,7,10,11}; /* rough guesses */ | 65 | static const u8 pio_to_umc [5] = {0, 3, 7, 10, 11}; /* rough guesses */ |
64 | 66 | ||
65 | /* 0 1 2 3 4 5 6 7 8 9 10 11 */ | 67 | /* 0 1 2 3 4 5 6 7 8 9 10 11 */ |
66 | static const u8 speedtab [3][12] = { | 68 | static const u8 speedtab [3][12] = { |
67 | {0xf, 0xb, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }, | 69 | {0x0f, 0x0b, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1}, |
68 | {0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }, | 70 | {0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x1}, |
69 | {0xff,0xcb,0xc0,0x58,0x36,0x33,0x23,0x22,0x21,0x11,0x10,0x0}}; | 71 | {0xff, 0xcb, 0xc0, 0x58, 0x36, 0x33, 0x23, 0x22, 0x21, 0x11, 0x10, 0x0} |
72 | }; | ||
70 | 73 | ||
71 | static void out_umc (char port,char wert) | 74 | static void out_umc(char port, char wert) |
72 | { | 75 | { |
73 | outb_p(port,0x108); | 76 | outb_p(port, 0x108); |
74 | outb_p(wert,0x109); | 77 | outb_p(wert, 0x109); |
75 | } | 78 | } |
76 | 79 | ||
77 | static inline u8 in_umc (char port) | 80 | static inline u8 in_umc(char port) |
78 | { | 81 | { |
79 | outb_p(port,0x108); | 82 | outb_p(port, 0x108); |
80 | return inb_p(0x109); | 83 | return inb_p(0x109); |
81 | } | 84 | } |
82 | 85 | ||
83 | static void umc_set_speeds (u8 speeds[]) | 86 | static void umc_set_speeds(u8 speeds[]) |
84 | { | 87 | { |
85 | int i, tmp; | 88 | int i, tmp; |
86 | 89 | ||
87 | outb_p(0x5A,0x108); /* enable umc */ | 90 | outb_p(0x5A, 0x108); /* enable umc */ |
88 | 91 | ||
89 | out_umc (0xd7,(speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4))); | 92 | out_umc(0xd7, (speedtab[0][speeds[2]] | (speedtab[0][speeds[3]]<<4))); |
90 | out_umc (0xd6,(speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4))); | 93 | out_umc(0xd6, (speedtab[0][speeds[0]] | (speedtab[0][speeds[1]]<<4))); |
91 | tmp = 0; | 94 | tmp = 0; |
92 | for (i = 3; i >= 0; i--) { | 95 | for (i = 3; i >= 0; i--) |
93 | tmp = (tmp << 2) | speedtab[1][speeds[i]]; | 96 | tmp = (tmp << 2) | speedtab[1][speeds[i]]; |
97 | out_umc(0xdc, tmp); | ||
98 | for (i = 0; i < 4; i++) { | ||
99 | out_umc(0xd0 + i, speedtab[2][speeds[i]]); | ||
100 | out_umc(0xd8 + i, speedtab[2][speeds[i]]); | ||
94 | } | 101 | } |
95 | out_umc (0xdc,tmp); | 102 | outb_p(0xa5, 0x108); /* disable umc */ |
96 | for (i = 0;i < 4; i++) { | ||
97 | out_umc (0xd0+i,speedtab[2][speeds[i]]); | ||
98 | out_umc (0xd8+i,speedtab[2][speeds[i]]); | ||
99 | } | ||
100 | outb_p(0xa5,0x108); /* disable umc */ | ||
101 | 103 | ||
102 | printk ("umc8672: drive speeds [0 to 11]: %d %d %d %d\n", | 104 | printk("umc8672: drive speeds [0 to 11]: %d %d %d %d\n", |
103 | speeds[0], speeds[1], speeds[2], speeds[3]); | 105 | speeds[0], speeds[1], speeds[2], speeds[3]); |
104 | } | 106 | } |
105 | 107 | ||
106 | static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio) | 108 | static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio) |
107 | { | 109 | { |
110 | ide_hwif_t *hwif = drive->hwif; | ||
108 | unsigned long flags; | 111 | unsigned long flags; |
109 | ide_hwgroup_t *hwgroup = ide_hwifs[HWIF(drive)->index^1].hwgroup; | ||
110 | 112 | ||
111 | printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", | 113 | printk("%s: setting umc8672 to PIO mode%d (speed %d)\n", |
112 | drive->name, pio, pio_to_umc[pio]); | 114 | drive->name, pio, pio_to_umc[pio]); |
113 | spin_lock_irqsave(&ide_lock, flags); | 115 | spin_lock_irqsave(&ide_lock, flags); |
114 | if (hwgroup && hwgroup->handler != NULL) { | 116 | if (hwif->mate && hwif->mate->hwgroup->handler) { |
115 | printk(KERN_ERR "umc8672: other interface is busy: exiting tune_umc()\n"); | 117 | printk(KERN_ERR "umc8672: other interface is busy: exiting tune_umc()\n"); |
116 | } else { | 118 | } else { |
117 | current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio]; | 119 | current_speeds[drive->name[2] - 'a'] = pio_to_umc[pio]; |
118 | umc_set_speeds (current_speeds); | 120 | umc_set_speeds(current_speeds); |
119 | } | 121 | } |
120 | spin_unlock_irqrestore(&ide_lock, flags); | 122 | spin_unlock_irqrestore(&ide_lock, flags); |
121 | } | 123 | } |
122 | 124 | ||
125 | static const struct ide_port_ops umc8672_port_ops = { | ||
126 | .set_pio_mode = umc_set_pio_mode, | ||
127 | }; | ||
128 | |||
123 | static const struct ide_port_info umc8672_port_info __initdata = { | 129 | static const struct ide_port_info umc8672_port_info __initdata = { |
130 | .name = DRV_NAME, | ||
124 | .chipset = ide_umc8672, | 131 | .chipset = ide_umc8672, |
125 | .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_NO_AUTOTUNE, | 132 | .port_ops = &umc8672_port_ops, |
133 | .host_flags = IDE_HFLAG_NO_DMA, | ||
126 | .pio_mask = ATA_PIO4, | 134 | .pio_mask = ATA_PIO4, |
127 | }; | 135 | }; |
128 | 136 | ||
129 | static int __init umc8672_probe(void) | 137 | static int __init umc8672_probe(void) |
130 | { | 138 | { |
131 | unsigned long flags; | 139 | unsigned long flags; |
132 | static u8 idx[4] = { 0, 1, 0xff, 0xff }; | ||
133 | 140 | ||
134 | if (!request_region(0x108, 2, "umc8672")) { | 141 | if (!request_region(0x108, 2, "umc8672")) { |
135 | printk(KERN_ERR "umc8672: ports 0x108-0x109 already in use.\n"); | 142 | printk(KERN_ERR "umc8672: ports 0x108-0x109 already in use.\n"); |
136 | return 1; | 143 | return 1; |
137 | } | 144 | } |
138 | local_irq_save(flags); | 145 | local_irq_save(flags); |
139 | outb_p(0x5A,0x108); /* enable umc */ | 146 | outb_p(0x5A, 0x108); /* enable umc */ |
140 | if (in_umc (0xd5) != 0xa0) { | 147 | if (in_umc (0xd5) != 0xa0) { |
141 | local_irq_restore(flags); | 148 | local_irq_restore(flags); |
142 | printk(KERN_ERR "umc8672: not found\n"); | 149 | printk(KERN_ERR "umc8672: not found\n"); |
143 | release_region(0x108, 2); | 150 | release_region(0x108, 2); |
144 | return 1; | 151 | return 1; |
145 | } | 152 | } |
146 | outb_p(0xa5,0x108); /* disable umc */ | 153 | outb_p(0xa5, 0x108); /* disable umc */ |
147 | 154 | ||
148 | umc_set_speeds (current_speeds); | 155 | umc_set_speeds(current_speeds); |
149 | local_irq_restore(flags); | 156 | local_irq_restore(flags); |
150 | 157 | ||
151 | ide_hwifs[0].set_pio_mode = &umc_set_pio_mode; | 158 | return ide_legacy_device_add(&umc8672_port_info, 0); |
152 | ide_hwifs[1].set_pio_mode = &umc_set_pio_mode; | ||
153 | |||
154 | ide_device_add(idx, &umc8672_port_info); | ||
155 | |||
156 | return 0; | ||
157 | } | 159 | } |
158 | 160 | ||
159 | int probe_umc8672 = 0; | 161 | static int probe_umc8672; |
160 | 162 | ||
161 | module_param_named(probe, probe_umc8672, bool, 0); | 163 | module_param_named(probe, probe_umc8672, bool, 0); |
162 | MODULE_PARM_DESC(probe, "probe for UMC8672 chipset"); | 164 | MODULE_PARM_DESC(probe, "probe for UMC8672 chipset"); |