diff options
Diffstat (limited to 'drivers/ide/pci/via82cxxx.c')
| -rw-r--r-- | drivers/ide/pci/via82cxxx.c | 139 |
1 files changed, 77 insertions, 62 deletions
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 09dc4803ef9..454d2bf62dc 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c | |||
| @@ -35,6 +35,8 @@ | |||
| 35 | #include <asm/processor.h> | 35 | #include <asm/processor.h> |
| 36 | #endif | 36 | #endif |
| 37 | 37 | ||
| 38 | #define DRV_NAME "via82cxxx" | ||
| 39 | |||
| 38 | #define VIA_IDE_ENABLE 0x40 | 40 | #define VIA_IDE_ENABLE 0x40 |
| 39 | #define VIA_IDE_CONFIG 0x41 | 41 | #define VIA_IDE_CONFIG 0x41 |
| 40 | #define VIA_FIFO_CONFIG 0x43 | 42 | #define VIA_FIFO_CONFIG 0x43 |
| @@ -113,7 +115,8 @@ struct via82cxxx_dev | |||
| 113 | static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing) | 115 | static void via_set_speed(ide_hwif_t *hwif, u8 dn, struct ide_timing *timing) |
| 114 | { | 116 | { |
| 115 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 117 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
| 116 | struct via82cxxx_dev *vdev = pci_get_drvdata(dev); | 118 | struct ide_host *host = pci_get_drvdata(dev); |
| 119 | struct via82cxxx_dev *vdev = host->host_priv; | ||
| 117 | u8 t; | 120 | u8 t; |
| 118 | 121 | ||
| 119 | if (~vdev->via_config->flags & VIA_BAD_AST) { | 122 | if (~vdev->via_config->flags & VIA_BAD_AST) { |
| @@ -153,7 +156,8 @@ static void via_set_drive(ide_drive_t *drive, const u8 speed) | |||
| 153 | ide_hwif_t *hwif = drive->hwif; | 156 | ide_hwif_t *hwif = drive->hwif; |
| 154 | ide_drive_t *peer = hwif->drives + (~drive->dn & 1); | 157 | ide_drive_t *peer = hwif->drives + (~drive->dn & 1); |
| 155 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 158 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
| 156 | struct via82cxxx_dev *vdev = pci_get_drvdata(dev); | 159 | struct ide_host *host = pci_get_drvdata(dev); |
| 160 | struct via82cxxx_dev *vdev = host->host_priv; | ||
| 157 | struct ide_timing t, p; | 161 | struct ide_timing t, p; |
| 158 | unsigned int T, UT; | 162 | unsigned int T, UT; |
| 159 | 163 | ||
| @@ -258,37 +262,19 @@ static void __devinit via_cable_detect(struct via82cxxx_dev *vdev, u32 u) | |||
| 258 | /** | 262 | /** |
| 259 | * init_chipset_via82cxxx - initialization handler | 263 | * init_chipset_via82cxxx - initialization handler |
| 260 | * @dev: PCI device | 264 | * @dev: PCI device |
| 261 | * @name: Name of interface | ||
| 262 | * | 265 | * |
| 263 | * The initialization callback. Here we determine the IDE chip type | 266 | * The initialization callback. Here we determine the IDE chip type |
| 264 | * and initialize its drive independent registers. | 267 | * and initialize its drive independent registers. |
| 265 | */ | 268 | */ |
| 266 | 269 | ||
| 267 | static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name) | 270 | static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev) |
| 268 | { | 271 | { |
| 269 | struct pci_dev *isa = NULL; | 272 | struct ide_host *host = pci_get_drvdata(dev); |
| 270 | struct via82cxxx_dev *vdev; | 273 | struct via82cxxx_dev *vdev = host->host_priv; |
| 271 | struct via_isa_bridge *via_config; | 274 | struct via_isa_bridge *via_config = vdev->via_config; |
| 272 | u8 t, v; | 275 | u8 t, v; |
| 273 | u32 u; | 276 | u32 u; |
| 274 | 277 | ||
| 275 | vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); | ||
| 276 | if (!vdev) { | ||
| 277 | printk(KERN_ERR "VP_IDE: out of memory :(\n"); | ||
| 278 | return -ENOMEM; | ||
| 279 | } | ||
| 280 | pci_set_drvdata(dev, vdev); | ||
| 281 | |||
| 282 | /* | ||
| 283 | * Find the ISA bridge to see how good the IDE is. | ||
| 284 | */ | ||
| 285 | vdev->via_config = via_config = via_config_find(&isa); | ||
| 286 | |||
| 287 | /* We checked this earlier so if it fails here deeep badness | ||
| 288 | is involved */ | ||
| 289 | |||
| 290 | BUG_ON(!via_config->id); | ||
| 291 | |||
| 292 | /* | 278 | /* |
| 293 | * Detect cable and configure Clk66 | 279 | * Detect cable and configure Clk66 |
| 294 | */ | 280 | */ |
| @@ -334,39 +320,6 @@ static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const | |||
| 334 | 320 | ||
| 335 | pci_write_config_byte(dev, VIA_FIFO_CONFIG, t); | 321 | pci_write_config_byte(dev, VIA_FIFO_CONFIG, t); |
| 336 | 322 | ||
| 337 | /* | ||
| 338 | * Determine system bus clock. | ||
| 339 | */ | ||
| 340 | |||
| 341 | via_clock = (ide_pci_clk ? ide_pci_clk : 33) * 1000; | ||
| 342 | |||
| 343 | switch (via_clock) { | ||
| 344 | case 33000: via_clock = 33333; break; | ||
| 345 | case 37000: via_clock = 37500; break; | ||
| 346 | case 41000: via_clock = 41666; break; | ||
| 347 | } | ||
| 348 | |||
| 349 | if (via_clock < 20000 || via_clock > 50000) { | ||
| 350 | printk(KERN_WARNING "VP_IDE: User given PCI clock speed " | ||
| 351 | "impossible (%d), using 33 MHz instead.\n", via_clock); | ||
| 352 | printk(KERN_WARNING "VP_IDE: Use ide0=ata66 if you want " | ||
| 353 | "to assume 80-wire cable.\n"); | ||
| 354 | via_clock = 33333; | ||
| 355 | } | ||
| 356 | |||
| 357 | /* | ||
| 358 | * Print the boot message. | ||
| 359 | */ | ||
| 360 | |||
| 361 | printk(KERN_INFO "VP_IDE: VIA %s (rev %02x) IDE %sDMA%s " | ||
| 362 | "controller on pci%s\n", | ||
| 363 | via_config->name, isa->revision, | ||
| 364 | via_config->udma_mask ? "U" : "MW", | ||
| 365 | via_dma[via_config->udma_mask ? | ||
| 366 | (fls(via_config->udma_mask) - 1) : 0], | ||
| 367 | pci_name(dev)); | ||
| 368 | |||
| 369 | pci_dev_put(isa); | ||
| 370 | return 0; | 323 | return 0; |
| 371 | } | 324 | } |
| 372 | 325 | ||
| @@ -402,7 +355,8 @@ static int via_cable_override(struct pci_dev *pdev) | |||
| 402 | static u8 __devinit via82cxxx_cable_detect(ide_hwif_t *hwif) | 355 | static u8 __devinit via82cxxx_cable_detect(ide_hwif_t *hwif) |
| 403 | { | 356 | { |
| 404 | struct pci_dev *pdev = to_pci_dev(hwif->dev); | 357 | struct pci_dev *pdev = to_pci_dev(hwif->dev); |
| 405 | struct via82cxxx_dev *vdev = pci_get_drvdata(pdev); | 358 | struct ide_host *host = pci_get_drvdata(pdev); |
| 359 | struct via82cxxx_dev *vdev = host->host_priv; | ||
| 406 | 360 | ||
| 407 | if (via_cable_override(pdev)) | 361 | if (via_cable_override(pdev)) |
| 408 | return ATA_CBL_PATA40_SHORT; | 362 | return ATA_CBL_PATA40_SHORT; |
| @@ -420,7 +374,7 @@ static const struct ide_port_ops via_port_ops = { | |||
| 420 | }; | 374 | }; |
| 421 | 375 | ||
| 422 | static const struct ide_port_info via82cxxx_chipset __devinitdata = { | 376 | static const struct ide_port_info via82cxxx_chipset __devinitdata = { |
| 423 | .name = "VP_IDE", | 377 | .name = DRV_NAME, |
| 424 | .init_chipset = init_chipset_via82cxxx, | 378 | .init_chipset = init_chipset_via82cxxx, |
| 425 | .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } }, | 379 | .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } }, |
| 426 | .port_ops = &via_port_ops, | 380 | .port_ops = &via_port_ops, |
| @@ -436,6 +390,8 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i | |||
| 436 | { | 390 | { |
| 437 | struct pci_dev *isa = NULL; | 391 | struct pci_dev *isa = NULL; |
| 438 | struct via_isa_bridge *via_config; | 392 | struct via_isa_bridge *via_config; |
| 393 | struct via82cxxx_dev *vdev; | ||
| 394 | int rc; | ||
| 439 | u8 idx = id->driver_data; | 395 | u8 idx = id->driver_data; |
| 440 | struct ide_port_info d; | 396 | struct ide_port_info d; |
| 441 | 397 | ||
| @@ -445,12 +401,42 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i | |||
| 445 | * Find the ISA bridge and check we know what it is. | 401 | * Find the ISA bridge and check we know what it is. |
| 446 | */ | 402 | */ |
| 447 | via_config = via_config_find(&isa); | 403 | via_config = via_config_find(&isa); |
| 448 | pci_dev_put(isa); | ||
| 449 | if (!via_config->id) { | 404 | if (!via_config->id) { |
| 450 | printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n"); | 405 | printk(KERN_WARNING DRV_NAME " %s: unknown chipset, skipping\n", |
| 406 | pci_name(dev)); | ||
| 451 | return -ENODEV; | 407 | return -ENODEV; |
| 452 | } | 408 | } |
| 453 | 409 | ||
| 410 | /* | ||
| 411 | * Print the boot message. | ||
| 412 | */ | ||
| 413 | printk(KERN_INFO DRV_NAME " %s: VIA %s (rev %02x) IDE %sDMA%s\n", | ||
| 414 | pci_name(dev), via_config->name, isa->revision, | ||
| 415 | via_config->udma_mask ? "U" : "MW", | ||
| 416 | via_dma[via_config->udma_mask ? | ||
| 417 | (fls(via_config->udma_mask) - 1) : 0]); | ||
| 418 | |||
| 419 | pci_dev_put(isa); | ||
| 420 | |||
| 421 | /* | ||
| 422 | * Determine system bus clock. | ||
| 423 | */ | ||
| 424 | via_clock = (ide_pci_clk ? ide_pci_clk : 33) * 1000; | ||
| 425 | |||
| 426 | switch (via_clock) { | ||
| 427 | case 33000: via_clock = 33333; break; | ||
| 428 | case 37000: via_clock = 37500; break; | ||
| 429 | case 41000: via_clock = 41666; break; | ||
| 430 | } | ||
| 431 | |||
| 432 | if (via_clock < 20000 || via_clock > 50000) { | ||
| 433 | printk(KERN_WARNING DRV_NAME ": User given PCI clock speed " | ||
| 434 | "impossible (%d), using 33 MHz instead.\n", via_clock); | ||
| 435 | printk(KERN_WARNING DRV_NAME ": Use ide0=ata66 if you want " | ||
| 436 | "to assume 80-wire cable.\n"); | ||
| 437 | via_clock = 33333; | ||
| 438 | } | ||
| 439 | |||
| 454 | if (idx == 0) | 440 | if (idx == 0) |
| 455 | d.host_flags |= IDE_HFLAG_NO_AUTODMA; | 441 | d.host_flags |= IDE_HFLAG_NO_AUTODMA; |
| 456 | else | 442 | else |
| @@ -466,7 +452,29 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i | |||
| 466 | 452 | ||
| 467 | d.udma_mask = via_config->udma_mask; | 453 | d.udma_mask = via_config->udma_mask; |
| 468 | 454 | ||
| 469 | return ide_setup_pci_device(dev, &d); | 455 | vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); |
| 456 | if (!vdev) { | ||
| 457 | printk(KERN_ERR DRV_NAME " %s: out of memory :(\n", | ||
| 458 | pci_name(dev)); | ||
| 459 | return -ENOMEM; | ||
| 460 | } | ||
| 461 | |||
| 462 | vdev->via_config = via_config; | ||
| 463 | |||
| 464 | rc = ide_pci_init_one(dev, &d, vdev); | ||
| 465 | if (rc) | ||
| 466 | kfree(vdev); | ||
| 467 | |||
| 468 | return rc; | ||
| 469 | } | ||
| 470 | |||
| 471 | static void __devexit via_remove(struct pci_dev *dev) | ||
| 472 | { | ||
| 473 | struct ide_host *host = pci_get_drvdata(dev); | ||
| 474 | struct via82cxxx_dev *vdev = host->host_priv; | ||
| 475 | |||
| 476 | ide_pci_remove(dev); | ||
| 477 | kfree(vdev); | ||
| 470 | } | 478 | } |
| 471 | 479 | ||
| 472 | static const struct pci_device_id via_pci_tbl[] = { | 480 | static const struct pci_device_id via_pci_tbl[] = { |
| @@ -483,6 +491,7 @@ static struct pci_driver driver = { | |||
| 483 | .name = "VIA_IDE", | 491 | .name = "VIA_IDE", |
| 484 | .id_table = via_pci_tbl, | 492 | .id_table = via_pci_tbl, |
| 485 | .probe = via_init_one, | 493 | .probe = via_init_one, |
| 494 | .remove = via_remove, | ||
| 486 | }; | 495 | }; |
| 487 | 496 | ||
| 488 | static int __init via_ide_init(void) | 497 | static int __init via_ide_init(void) |
| @@ -490,7 +499,13 @@ static int __init via_ide_init(void) | |||
| 490 | return ide_pci_register_driver(&driver); | 499 | return ide_pci_register_driver(&driver); |
| 491 | } | 500 | } |
| 492 | 501 | ||
| 502 | static void __exit via_ide_exit(void) | ||
| 503 | { | ||
| 504 | pci_unregister_driver(&driver); | ||
| 505 | } | ||
| 506 | |||
| 493 | module_init(via_ide_init); | 507 | module_init(via_ide_init); |
| 508 | module_exit(via_ide_exit); | ||
| 494 | 509 | ||
| 495 | MODULE_AUTHOR("Vojtech Pavlik, Michel Aubry, Jeff Garzik, Andre Hedrick"); | 510 | MODULE_AUTHOR("Vojtech Pavlik, Michel Aubry, Jeff Garzik, Andre Hedrick"); |
| 496 | MODULE_DESCRIPTION("PCI driver module for VIA IDE"); | 511 | MODULE_DESCRIPTION("PCI driver module for VIA IDE"); |
