diff options
Diffstat (limited to 'drivers/ide/pci/aec62xx.c')
-rw-r--r-- | drivers/ide/pci/aec62xx.c | 76 |
1 files changed, 48 insertions, 28 deletions
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index fbc43e121e6b..e0c8fe7d9fea 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c | |||
@@ -13,6 +13,8 @@ | |||
13 | 13 | ||
14 | #include <asm/io.h> | 14 | #include <asm/io.h> |
15 | 15 | ||
16 | #define DRV_NAME "aec62xx" | ||
17 | |||
16 | struct chipset_bus_clock_list_entry { | 18 | struct chipset_bus_clock_list_entry { |
17 | u8 xfer_speed; | 19 | u8 xfer_speed; |
18 | u8 chipset_settings; | 20 | u8 chipset_settings; |
@@ -59,10 +61,6 @@ static const struct chipset_bus_clock_list_entry aec6xxx_34_base [] = { | |||
59 | { 0, 0x00, 0x00 } | 61 | { 0, 0x00, 0x00 } |
60 | }; | 62 | }; |
61 | 63 | ||
62 | #define BUSCLOCK(D) \ | ||
63 | ((struct chipset_bus_clock_list_entry *) pci_get_drvdata((D))) | ||
64 | |||
65 | |||
66 | /* | 64 | /* |
67 | * TO DO: active tuning and correction of cards without a bios. | 65 | * TO DO: active tuning and correction of cards without a bios. |
68 | */ | 66 | */ |
@@ -88,6 +86,8 @@ static void aec6210_set_mode(ide_drive_t *drive, const u8 speed) | |||
88 | { | 86 | { |
89 | ide_hwif_t *hwif = HWIF(drive); | 87 | ide_hwif_t *hwif = HWIF(drive); |
90 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 88 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
89 | struct ide_host *host = pci_get_drvdata(dev); | ||
90 | struct chipset_bus_clock_list_entry *bus_clock = host->host_priv; | ||
91 | u16 d_conf = 0; | 91 | u16 d_conf = 0; |
92 | u8 ultra = 0, ultra_conf = 0; | 92 | u8 ultra = 0, ultra_conf = 0; |
93 | u8 tmp0 = 0, tmp1 = 0, tmp2 = 0; | 93 | u8 tmp0 = 0, tmp1 = 0, tmp2 = 0; |
@@ -96,7 +96,7 @@ static void aec6210_set_mode(ide_drive_t *drive, const u8 speed) | |||
96 | local_irq_save(flags); | 96 | local_irq_save(flags); |
97 | /* 0x40|(2*drive->dn): Active, 0x41|(2*drive->dn): Recovery */ | 97 | /* 0x40|(2*drive->dn): Active, 0x41|(2*drive->dn): Recovery */ |
98 | pci_read_config_word(dev, 0x40|(2*drive->dn), &d_conf); | 98 | pci_read_config_word(dev, 0x40|(2*drive->dn), &d_conf); |
99 | tmp0 = pci_bus_clock_list(speed, BUSCLOCK(dev)); | 99 | tmp0 = pci_bus_clock_list(speed, bus_clock); |
100 | d_conf = ((tmp0 & 0xf0) << 4) | (tmp0 & 0xf); | 100 | d_conf = ((tmp0 & 0xf0) << 4) | (tmp0 & 0xf); |
101 | pci_write_config_word(dev, 0x40|(2*drive->dn), d_conf); | 101 | pci_write_config_word(dev, 0x40|(2*drive->dn), d_conf); |
102 | 102 | ||
@@ -104,7 +104,7 @@ static void aec6210_set_mode(ide_drive_t *drive, const u8 speed) | |||
104 | tmp2 = 0x00; | 104 | tmp2 = 0x00; |
105 | pci_read_config_byte(dev, 0x54, &ultra); | 105 | pci_read_config_byte(dev, 0x54, &ultra); |
106 | tmp1 = ((0x00 << (2*drive->dn)) | (ultra & ~(3 << (2*drive->dn)))); | 106 | tmp1 = ((0x00 << (2*drive->dn)) | (ultra & ~(3 << (2*drive->dn)))); |
107 | ultra_conf = pci_bus_clock_list_ultra(speed, BUSCLOCK(dev)); | 107 | ultra_conf = pci_bus_clock_list_ultra(speed, bus_clock); |
108 | tmp2 = ((ultra_conf << (2*drive->dn)) | (tmp1 & ~(3 << (2*drive->dn)))); | 108 | tmp2 = ((ultra_conf << (2*drive->dn)) | (tmp1 & ~(3 << (2*drive->dn)))); |
109 | pci_write_config_byte(dev, 0x54, tmp2); | 109 | pci_write_config_byte(dev, 0x54, tmp2); |
110 | local_irq_restore(flags); | 110 | local_irq_restore(flags); |
@@ -114,6 +114,8 @@ static void aec6260_set_mode(ide_drive_t *drive, const u8 speed) | |||
114 | { | 114 | { |
115 | ide_hwif_t *hwif = HWIF(drive); | 115 | ide_hwif_t *hwif = HWIF(drive); |
116 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 116 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
117 | struct ide_host *host = pci_get_drvdata(dev); | ||
118 | struct chipset_bus_clock_list_entry *bus_clock = host->host_priv; | ||
117 | u8 unit = (drive->select.b.unit & 0x01); | 119 | u8 unit = (drive->select.b.unit & 0x01); |
118 | u8 tmp1 = 0, tmp2 = 0; | 120 | u8 tmp1 = 0, tmp2 = 0; |
119 | u8 ultra = 0, drive_conf = 0, ultra_conf = 0; | 121 | u8 ultra = 0, drive_conf = 0, ultra_conf = 0; |
@@ -122,12 +124,12 @@ static void aec6260_set_mode(ide_drive_t *drive, const u8 speed) | |||
122 | local_irq_save(flags); | 124 | local_irq_save(flags); |
123 | /* high 4-bits: Active, low 4-bits: Recovery */ | 125 | /* high 4-bits: Active, low 4-bits: Recovery */ |
124 | pci_read_config_byte(dev, 0x40|drive->dn, &drive_conf); | 126 | pci_read_config_byte(dev, 0x40|drive->dn, &drive_conf); |
125 | drive_conf = pci_bus_clock_list(speed, BUSCLOCK(dev)); | 127 | drive_conf = pci_bus_clock_list(speed, bus_clock); |
126 | pci_write_config_byte(dev, 0x40|drive->dn, drive_conf); | 128 | pci_write_config_byte(dev, 0x40|drive->dn, drive_conf); |
127 | 129 | ||
128 | pci_read_config_byte(dev, (0x44|hwif->channel), &ultra); | 130 | pci_read_config_byte(dev, (0x44|hwif->channel), &ultra); |
129 | tmp1 = ((0x00 << (4*unit)) | (ultra & ~(7 << (4*unit)))); | 131 | tmp1 = ((0x00 << (4*unit)) | (ultra & ~(7 << (4*unit)))); |
130 | ultra_conf = pci_bus_clock_list_ultra(speed, BUSCLOCK(dev)); | 132 | ultra_conf = pci_bus_clock_list_ultra(speed, bus_clock); |
131 | tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit)))); | 133 | tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit)))); |
132 | pci_write_config_byte(dev, (0x44|hwif->channel), tmp2); | 134 | pci_write_config_byte(dev, (0x44|hwif->channel), tmp2); |
133 | local_irq_restore(flags); | 135 | local_irq_restore(flags); |
@@ -138,15 +140,8 @@ static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
138 | drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0); | 140 | drive->hwif->port_ops->set_dma_mode(drive, pio + XFER_PIO_0); |
139 | } | 141 | } |
140 | 142 | ||
141 | static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name) | 143 | static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev) |
142 | { | 144 | { |
143 | int bus_speed = ide_pci_clk ? ide_pci_clk : 33; | ||
144 | |||
145 | if (bus_speed <= 33) | ||
146 | pci_set_drvdata(dev, (void *) aec6xxx_33_base); | ||
147 | else | ||
148 | pci_set_drvdata(dev, (void *) aec6xxx_34_base); | ||
149 | |||
150 | /* These are necessary to get AEC6280 Macintosh cards to work */ | 145 | /* These are necessary to get AEC6280 Macintosh cards to work */ |
151 | if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) || | 146 | if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) || |
152 | (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R)) { | 147 | (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R)) { |
@@ -187,8 +182,8 @@ static const struct ide_port_ops atp86x_port_ops = { | |||
187 | }; | 182 | }; |
188 | 183 | ||
189 | static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { | 184 | static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { |
190 | { /* 0 */ | 185 | { /* 0: AEC6210 */ |
191 | .name = "AEC6210", | 186 | .name = DRV_NAME, |
192 | .init_chipset = init_chipset_aec62xx, | 187 | .init_chipset = init_chipset_aec62xx, |
193 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, | 188 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, |
194 | .port_ops = &atp850_port_ops, | 189 | .port_ops = &atp850_port_ops, |
@@ -199,8 +194,9 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { | |||
199 | .pio_mask = ATA_PIO4, | 194 | .pio_mask = ATA_PIO4, |
200 | .mwdma_mask = ATA_MWDMA2, | 195 | .mwdma_mask = ATA_MWDMA2, |
201 | .udma_mask = ATA_UDMA2, | 196 | .udma_mask = ATA_UDMA2, |
202 | },{ /* 1 */ | 197 | }, |
203 | .name = "AEC6260", | 198 | { /* 1: AEC6260 */ |
199 | .name = DRV_NAME, | ||
204 | .init_chipset = init_chipset_aec62xx, | 200 | .init_chipset = init_chipset_aec62xx, |
205 | .port_ops = &atp86x_port_ops, | 201 | .port_ops = &atp86x_port_ops, |
206 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_NO_AUTODMA | | 202 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_NO_AUTODMA | |
@@ -208,8 +204,9 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { | |||
208 | .pio_mask = ATA_PIO4, | 204 | .pio_mask = ATA_PIO4, |
209 | .mwdma_mask = ATA_MWDMA2, | 205 | .mwdma_mask = ATA_MWDMA2, |
210 | .udma_mask = ATA_UDMA4, | 206 | .udma_mask = ATA_UDMA4, |
211 | },{ /* 2 */ | 207 | }, |
212 | .name = "AEC6260R", | 208 | { /* 2: AEC6260R */ |
209 | .name = DRV_NAME, | ||
213 | .init_chipset = init_chipset_aec62xx, | 210 | .init_chipset = init_chipset_aec62xx, |
214 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, | 211 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, |
215 | .port_ops = &atp86x_port_ops, | 212 | .port_ops = &atp86x_port_ops, |
@@ -218,8 +215,9 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { | |||
218 | .pio_mask = ATA_PIO4, | 215 | .pio_mask = ATA_PIO4, |
219 | .mwdma_mask = ATA_MWDMA2, | 216 | .mwdma_mask = ATA_MWDMA2, |
220 | .udma_mask = ATA_UDMA4, | 217 | .udma_mask = ATA_UDMA4, |
221 | },{ /* 3 */ | 218 | }, |
222 | .name = "AEC6280", | 219 | { /* 3: AEC6280 */ |
220 | .name = DRV_NAME, | ||
223 | .init_chipset = init_chipset_aec62xx, | 221 | .init_chipset = init_chipset_aec62xx, |
224 | .port_ops = &atp86x_port_ops, | 222 | .port_ops = &atp86x_port_ops, |
225 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | | 223 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | |
@@ -227,8 +225,9 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { | |||
227 | .pio_mask = ATA_PIO4, | 225 | .pio_mask = ATA_PIO4, |
228 | .mwdma_mask = ATA_MWDMA2, | 226 | .mwdma_mask = ATA_MWDMA2, |
229 | .udma_mask = ATA_UDMA5, | 227 | .udma_mask = ATA_UDMA5, |
230 | },{ /* 4 */ | 228 | }, |
231 | .name = "AEC6280R", | 229 | { /* 4: AEC6280R */ |
230 | .name = DRV_NAME, | ||
232 | .init_chipset = init_chipset_aec62xx, | 231 | .init_chipset = init_chipset_aec62xx, |
233 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, | 232 | .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, |
234 | .port_ops = &atp86x_port_ops, | 233 | .port_ops = &atp86x_port_ops, |
@@ -254,10 +253,17 @@ static const struct ide_port_info aec62xx_chipsets[] __devinitdata = { | |||
254 | 253 | ||
255 | static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) | 254 | static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) |
256 | { | 255 | { |
256 | const struct chipset_bus_clock_list_entry *bus_clock; | ||
257 | struct ide_port_info d; | 257 | struct ide_port_info d; |
258 | u8 idx = id->driver_data; | 258 | u8 idx = id->driver_data; |
259 | int bus_speed = ide_pci_clk ? ide_pci_clk : 33; | ||
259 | int err; | 260 | int err; |
260 | 261 | ||
262 | if (bus_speed <= 33) | ||
263 | bus_clock = aec6xxx_33_base; | ||
264 | else | ||
265 | bus_clock = aec6xxx_34_base; | ||
266 | |||
261 | err = pci_enable_device(dev); | 267 | err = pci_enable_device(dev); |
262 | if (err) | 268 | if (err) |
263 | return err; | 269 | return err; |
@@ -268,18 +274,25 @@ static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_devi | |||
268 | unsigned long dma_base = pci_resource_start(dev, 4); | 274 | unsigned long dma_base = pci_resource_start(dev, 4); |
269 | 275 | ||
270 | if (inb(dma_base + 2) & 0x10) { | 276 | if (inb(dma_base + 2) & 0x10) { |
271 | d.name = (idx == 4) ? "AEC6880R" : "AEC6880"; | 277 | printk(KERN_INFO DRV_NAME " %s: AEC6880%s card detected" |
278 | "\n", pci_name(dev), (idx == 4) ? "R" : ""); | ||
272 | d.udma_mask = ATA_UDMA6; | 279 | d.udma_mask = ATA_UDMA6; |
273 | } | 280 | } |
274 | } | 281 | } |
275 | 282 | ||
276 | err = ide_setup_pci_device(dev, &d); | 283 | err = ide_pci_init_one(dev, &d, (void *)bus_clock); |
277 | if (err) | 284 | if (err) |
278 | pci_disable_device(dev); | 285 | pci_disable_device(dev); |
279 | 286 | ||
280 | return err; | 287 | return err; |
281 | } | 288 | } |
282 | 289 | ||
290 | static void __devexit aec62xx_remove(struct pci_dev *dev) | ||
291 | { | ||
292 | ide_pci_remove(dev); | ||
293 | pci_disable_device(dev); | ||
294 | } | ||
295 | |||
283 | static const struct pci_device_id aec62xx_pci_tbl[] = { | 296 | static const struct pci_device_id aec62xx_pci_tbl[] = { |
284 | { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF), 0 }, | 297 | { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF), 0 }, |
285 | { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP860), 1 }, | 298 | { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP860), 1 }, |
@@ -294,6 +307,7 @@ static struct pci_driver driver = { | |||
294 | .name = "AEC62xx_IDE", | 307 | .name = "AEC62xx_IDE", |
295 | .id_table = aec62xx_pci_tbl, | 308 | .id_table = aec62xx_pci_tbl, |
296 | .probe = aec62xx_init_one, | 309 | .probe = aec62xx_init_one, |
310 | .remove = aec62xx_remove, | ||
297 | }; | 311 | }; |
298 | 312 | ||
299 | static int __init aec62xx_ide_init(void) | 313 | static int __init aec62xx_ide_init(void) |
@@ -301,7 +315,13 @@ static int __init aec62xx_ide_init(void) | |||
301 | return ide_pci_register_driver(&driver); | 315 | return ide_pci_register_driver(&driver); |
302 | } | 316 | } |
303 | 317 | ||
318 | static void __exit aec62xx_ide_exit(void) | ||
319 | { | ||
320 | pci_unregister_driver(&driver); | ||
321 | } | ||
322 | |||
304 | module_init(aec62xx_ide_init); | 323 | module_init(aec62xx_ide_init); |
324 | module_exit(aec62xx_ide_exit); | ||
305 | 325 | ||
306 | MODULE_AUTHOR("Andre Hedrick"); | 326 | MODULE_AUTHOR("Andre Hedrick"); |
307 | MODULE_DESCRIPTION("PCI driver module for ARTOP AEC62xx IDE"); | 327 | MODULE_DESCRIPTION("PCI driver module for ARTOP AEC62xx IDE"); |