aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/legacy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/legacy')
-rw-r--r--drivers/ide/legacy/Makefile1
-rw-r--r--drivers/ide/legacy/ali14xx.c32
-rw-r--r--drivers/ide/legacy/buddha.c18
-rw-r--r--drivers/ide/legacy/dtc2278.c27
-rw-r--r--drivers/ide/legacy/falconide.c40
-rw-r--r--drivers/ide/legacy/gayle.c22
-rw-r--r--drivers/ide/legacy/hd.c78
-rw-r--r--drivers/ide/legacy/ht6560b.c54
-rw-r--r--drivers/ide/legacy/ide-4drives.c72
-rw-r--r--drivers/ide/legacy/ide-cs.c84
-rw-r--r--drivers/ide/legacy/ide_platform.c16
-rw-r--r--drivers/ide/legacy/macide.c8
-rw-r--r--drivers/ide/legacy/q40ide.c74
-rw-r--r--drivers/ide/legacy/qd65xx.c223
-rw-r--r--drivers/ide/legacy/qd65xx.h1
-rw-r--r--drivers/ide/legacy/umc8672.c80
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
6obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o 6obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o
7obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o 7obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o
8obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o 8obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o
9obj-$(CONFIG_BLK_DEV_4DRIVES) += ide-4drives.o
9 10
10obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o 11obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o
11obj-$(CONFIG_BLK_DEV_FALCON_IDE) += falconide.o 12obj-$(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
54static const int ports[ALI_NUM_PORTS] __initdata = 56static 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 */
89static inline u8 inReg (u8 reg) 91static 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 */
98static void outReg (u8 data, u8 reg) 100static 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 */
146static int __init findPort (void) 148static 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 */
178static int __init initRegisters (void) { 180static 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
197static const struct ide_port_ops ali14xx_port_ops = {
198 .set_pio_mode = ali14xx_set_pio_mode,
199};
200
194static const struct ide_port_info ali14xx_port_info = { 201static 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
200static int __init ali14xx_probe(void) 209static 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
221int probe_ali14xx = 0; 223static int probe_ali14xx;
222 224
223module_param_named(probe, probe_ali14xx, bool, 0); 225module_param_named(probe, probe_ali14xx, bool, 0);
224MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets"); 226MODULE_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
91static const struct ide_port_ops dtc2278_port_ops = {
92 .set_pio_mode = dtc2278_set_pio_mode,
93};
94
89static const struct ide_port_info dtc2278_port_info __initdata = { 95static 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
101static int __init dtc2278_probe(void) 108static 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
138int probe_dtc2278 = 0; 133static int probe_dtc2278;
139 134
140module_param_named(probe, probe_dtc2278, bool, 0); 135module_param_named(probe, probe_dtc2278, bool, 0);
141MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets"); 136MODULE_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 @@
43int falconide_intr_lock; 44int falconide_intr_lock;
44EXPORT_SYMBOL(falconide_intr_lock); 45EXPORT_SYMBOL(falconide_intr_lock);
45 46
47static 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
58static 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
46static void __init falconide_setup_ports(hw_regs_t *hw) 69static 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)
65int ide_doubler = 0; /* support IDE doublers? */ 65int ide_doubler = 0; /* support IDE doublers? */
66module_param_named(doubler, ide_doubler, bool, 0);
67MODULE_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 */
124struct hd_i_struct { 124struct 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
132static struct hd_i_struct hd_info[] = { HD_TYPE }; 132static struct hd_i_struct hd_info[] = { HD_TYPE };
133static int NR_HD = ARRAY_SIZE(hd_info); 133static 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
196static void dump_status (const char *msg, unsigned int stat) 196static 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
295static void hd_out(struct hd_i_struct *disk, 294static 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
327static void hd_request (void); 326static 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
357static void reset_hd(void) 356static 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;
454ok_to_read: 453ok_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
658static void do_hd_request (struct request_queue * q) 659static 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;
792out: 793out:
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;
797Enomem: 798Enomem:
@@ -800,7 +801,8 @@ Enomem:
800 goto out; 801 goto out;
801} 802}
802 803
803static int __init parse_hd_setup (char *line) { 804static 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 */
128static void ht6560b_selectproc (ide_drive_t *drive) 129static 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
324int probe_ht6560b = 0; 326static int probe_ht6560b;
325 327
326module_param_named(probe, probe_ht6560b, bool, 0); 328module_param_named(probe, probe_ht6560b, bool, 0);
327MODULE_PARM_DESC(probe, "probe for HT6560B chipset"); 329MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
328 330
331static 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
329static const struct ide_port_info ht6560b_port_info __initdata = { 337static 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
338static int __init ht6560b_init(void) 347static 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
373release_region: 365release_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
9static int probe_4drives;
10
11module_param_named(probe, probe_4drives, bool, 0);
12MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port");
13
14static 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
68module_init(ide_4drives_init);
69
70MODULE_AUTHOR("Bartlomiej Zolnierkiewicz");
71MODULE_DESCRIPTION("generic IDE chipset with 4 drives/port support");
72MODULE_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
75static const char ide_major[] = {
76 IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR,
77 IDE4_MAJOR, IDE5_MAJOR
78};
79
80typedef struct ide_info_t { 77typedef 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
87static void ide_release(struct pcmcia_device *); 84static void ide_release(struct pcmcia_device *);
@@ -136,45 +133,71 @@ static int ide_probe(struct pcmcia_device *link)
136 133
137static void ide_detach(struct pcmcia_device *link) 134static 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
146static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) 149static const struct ide_port_ops idecs_port_ops = {
150 .quirkproc = ide_undecoded_slave,
151};
152
153static 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
197out_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:
354void ide_release(struct pcmcia_device *link) 379void 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)
130static struct platform_driver platform_ide_driver = { 130static 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
148MODULE_DESCRIPTION("Platform IDE driver"); 149MODULE_DESCRIPTION("Platform IDE driver");
149MODULE_LICENSE("GPL"); 150MODULE_LICENSE("GPL");
151MODULE_ALIAS("platform:pata_platform");
150 152
151module_init(platform_ide_init); 153module_init(platform_ide_init);
152module_exit(platform_ide_exit); 154module_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
50static 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
56static int q40ide_default_irq(unsigned long base) 39static 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 */
71void q40_ide_setup_ports ( hw_regs_t *hw, 54static 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
75static 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
86static 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 @@
88static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */ 86static 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
96static void qd_select (ide_drive_t *drive) 94static 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
113static u8 qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery_time) 111static 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
134static u8 qd6580_compute_timing (int active_time, int recovery_time) 133static 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
176static 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
190static void qd_set_timing (ide_drive_t *drive, u8 timing) 178static 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
226static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio) 207static 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
308static 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
314static void __init qd6500_port_init_devs(ide_hwif_t *hwif) 284static 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)
322static void __init qd6580_port_init_devs(ide_hwif_t *hwif) 293static 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
309static 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
315static 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
337static const struct ide_port_info qd65xx_port_info __initdata = { 321static 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
352static int __init qd_probe(int base) 336static 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
460int probe_qd65xx = 0; 401static int probe_qd65xx;
461 402
462module_param_named(probe, probe_qd65xx, bool, 0); 403module_param_named(probe, probe_qd65xx, bool, 0);
463MODULE_PARM_DESC(probe, "probe for QD65xx chipsets"); 404MODULE_PARM_DESC(probe, "probe for QD65xx chipsets");
464 405
465static int __init qd65xx_init(void) 406static 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
62static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3}; 64static u8 current_speeds[4] = {UMC_DRIVE0, UMC_DRIVE1, UMC_DRIVE2, UMC_DRIVE3};
63static const u8 pio_to_umc [5] = {0,3,7,10,11}; /* rough guesses */ 65static 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 */
66static const u8 speedtab [3][12] = { 68static 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
71static void out_umc (char port,char wert) 74static 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
77static inline u8 in_umc (char port) 80static 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
83static void umc_set_speeds (u8 speeds[]) 86static 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
106static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio) 108static 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
125static const struct ide_port_ops umc8672_port_ops = {
126 .set_pio_mode = umc_set_pio_mode,
127};
128
123static const struct ide_port_info umc8672_port_info __initdata = { 129static 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
129static int __init umc8672_probe(void) 137static 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
159int probe_umc8672 = 0; 161static int probe_umc8672;
160 162
161module_param_named(probe, probe_umc8672, bool, 0); 163module_param_named(probe, probe_umc8672, bool, 0);
162MODULE_PARM_DESC(probe, "probe for UMC8672 chipset"); 164MODULE_PARM_DESC(probe, "probe for UMC8672 chipset");