diff options
author | Alan Cox <alan@redhat.com> | 2009-01-05 09:13:22 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2009-01-08 16:09:11 -0500 |
commit | 1b2c357c301b76118973763e886d9f70a7f50f7e (patch) | |
tree | 0ca772edd989be84a87e9e04e1f4f926d12f9b4b /drivers/ata/pata_ali.c | |
parent | 978ff6db23279422046c1b3f89fe2045c234dc91 (diff) |
pata_ali: force initialise a few bits
We can't assume some of the setup here on non x86 boxes.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata/pata_ali.c')
-rw-r--r-- | drivers/ata/pata_ali.c | 71 |
1 files changed, 38 insertions, 33 deletions
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 73c466e452ca..d2ea2db61e52 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c | |||
@@ -19,7 +19,9 @@ | |||
19 | * | 19 | * |
20 | * TODO/CHECK | 20 | * TODO/CHECK |
21 | * Cannot have ATAPI on both master & slave for rev < c2 (???) but | 21 | * Cannot have ATAPI on both master & slave for rev < c2 (???) but |
22 | * otherwise should do atapi DMA. | 22 | * otherwise should do atapi DMA (For now for old we do PIO only for |
23 | * ATAPI) | ||
24 | * Review Sunblade workaround. | ||
23 | */ | 25 | */ |
24 | 26 | ||
25 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
@@ -33,12 +35,14 @@ | |||
33 | #include <linux/dmi.h> | 35 | #include <linux/dmi.h> |
34 | 36 | ||
35 | #define DRV_NAME "pata_ali" | 37 | #define DRV_NAME "pata_ali" |
36 | #define DRV_VERSION "0.7.5" | 38 | #define DRV_VERSION "0.7.7" |
37 | 39 | ||
38 | static int ali_atapi_dma = 0; | 40 | static int ali_atapi_dma = 0; |
39 | module_param_named(atapi_dma, ali_atapi_dma, int, 0644); | 41 | module_param_named(atapi_dma, ali_atapi_dma, int, 0644); |
40 | MODULE_PARM_DESC(atapi_dma, "Enable ATAPI DMA (0=disable, 1=enable)"); | 42 | MODULE_PARM_DESC(atapi_dma, "Enable ATAPI DMA (0=disable, 1=enable)"); |
41 | 43 | ||
44 | static struct pci_dev *isa_bridge; | ||
45 | |||
42 | /* | 46 | /* |
43 | * Cable special cases | 47 | * Cable special cases |
44 | */ | 48 | */ |
@@ -401,52 +405,49 @@ static struct ata_port_operations ali_c5_port_ops = { | |||
401 | static void ali_init_chipset(struct pci_dev *pdev) | 405 | static void ali_init_chipset(struct pci_dev *pdev) |
402 | { | 406 | { |
403 | u8 tmp; | 407 | u8 tmp; |
404 | struct pci_dev *north, *isa_bridge; | 408 | struct pci_dev *north; |
405 | 409 | ||
406 | /* | 410 | /* |
407 | * The chipset revision selects the driver operations and | 411 | * The chipset revision selects the driver operations and |
408 | * mode data. | 412 | * mode data. |
409 | */ | 413 | */ |
410 | 414 | ||
411 | if (pdev->revision >= 0x20 && pdev->revision < 0xC2) { | 415 | if (pdev->revision <= 0x20) { |
412 | /* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */ | 416 | pci_read_config_byte(pdev, 0x53, &tmp); |
413 | pci_read_config_byte(pdev, 0x4B, &tmp); | 417 | tmp |= 0x03; |
414 | /* Clear CD-ROM DMA write bit */ | 418 | pci_write_config_byte(pdev, 0x53, tmp); |
415 | tmp &= 0x7F; | 419 | } else { |
416 | pci_write_config_byte(pdev, 0x4B, tmp); | 420 | pci_read_config_byte(pdev, 0x4a, &tmp); |
417 | } else if (pdev->revision >= 0xC2) { | 421 | pci_write_config_byte(pdev, 0x4a, tmp | 0x20); |
418 | /* Enable cable detection logic */ | ||
419 | pci_read_config_byte(pdev, 0x4B, &tmp); | 422 | pci_read_config_byte(pdev, 0x4B, &tmp); |
420 | pci_write_config_byte(pdev, 0x4B, tmp | 0x08); | 423 | if (pdev->revision < 0xC2) |
421 | } | 424 | /* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */ |
422 | north = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); | 425 | /* Clear CD-ROM DMA write bit */ |
423 | isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); | 426 | tmp &= 0x7F; |
424 | 427 | /* Cable and UDMA */ | |
425 | if (north && north->vendor == PCI_VENDOR_ID_AL && isa_bridge) { | 428 | pci_write_config_byte(pdev, 0x4B, tmp | 0x09); |
426 | /* Configure the ALi bridge logic. For non ALi rely on BIOS. | ||
427 | Set the south bridge enable bit */ | ||
428 | pci_read_config_byte(isa_bridge, 0x79, &tmp); | ||
429 | if (pdev->revision == 0xC2) | ||
430 | pci_write_config_byte(isa_bridge, 0x79, tmp | 0x04); | ||
431 | else if (pdev->revision > 0xC2 && pdev->revision < 0xC5) | ||
432 | pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02); | ||
433 | } | ||
434 | if (pdev->revision >= 0x20) { | ||
435 | /* | 429 | /* |
436 | * CD_ROM DMA on (0x53 bit 0). Enable this even if we want | 430 | * CD_ROM DMA on (0x53 bit 0). Enable this even if we want |
437 | * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control | 431 | * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control |
438 | * via 0x54/55. | 432 | * via 0x54/55. |
439 | */ | 433 | */ |
440 | pci_read_config_byte(pdev, 0x53, &tmp); | 434 | pci_read_config_byte(pdev, 0x53, &tmp); |
441 | if (pdev->revision <= 0x20) | ||
442 | tmp &= ~0x02; | ||
443 | if (pdev->revision >= 0xc7) | 435 | if (pdev->revision >= 0xc7) |
444 | tmp |= 0x03; | 436 | tmp |= 0x03; |
445 | else | 437 | else |
446 | tmp |= 0x01; /* CD_ROM enable for DMA */ | 438 | tmp |= 0x01; /* CD_ROM enable for DMA */ |
447 | pci_write_config_byte(pdev, 0x53, tmp); | 439 | pci_write_config_byte(pdev, 0x53, tmp); |
448 | } | 440 | } |
449 | pci_dev_put(isa_bridge); | 441 | north = pci_get_bus_and_slot(0, PCI_DEVFN(0,0)); |
442 | if (north && north->vendor == PCI_VENDOR_ID_AL && isa_bridge) { | ||
443 | /* Configure the ALi bridge logic. For non ALi rely on BIOS. | ||
444 | Set the south bridge enable bit */ | ||
445 | pci_read_config_byte(isa_bridge, 0x79, &tmp); | ||
446 | if (pdev->revision == 0xC2) | ||
447 | pci_write_config_byte(isa_bridge, 0x79, tmp | 0x04); | ||
448 | else if (pdev->revision > 0xC2 && pdev->revision < 0xC5) | ||
449 | pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02); | ||
450 | } | ||
450 | pci_dev_put(north); | 451 | pci_dev_put(north); |
451 | ata_pci_bmdma_clear_simplex(pdev); | 452 | ata_pci_bmdma_clear_simplex(pdev); |
452 | } | 453 | } |
@@ -516,7 +517,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
516 | 517 | ||
517 | const struct ata_port_info *ppi[] = { NULL, NULL }; | 518 | const struct ata_port_info *ppi[] = { NULL, NULL }; |
518 | u8 tmp; | 519 | u8 tmp; |
519 | struct pci_dev *isa_bridge; | ||
520 | int rc; | 520 | int rc; |
521 | 521 | ||
522 | rc = pcim_enable_device(pdev); | 522 | rc = pcim_enable_device(pdev); |
@@ -543,14 +543,12 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
543 | 543 | ||
544 | ali_init_chipset(pdev); | 544 | ali_init_chipset(pdev); |
545 | 545 | ||
546 | isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); | ||
547 | if (isa_bridge && pdev->revision >= 0x20 && pdev->revision < 0xC2) { | 546 | if (isa_bridge && pdev->revision >= 0x20 && pdev->revision < 0xC2) { |
548 | /* Are we paired with a UDMA capable chip */ | 547 | /* Are we paired with a UDMA capable chip */ |
549 | pci_read_config_byte(isa_bridge, 0x5E, &tmp); | 548 | pci_read_config_byte(isa_bridge, 0x5E, &tmp); |
550 | if ((tmp & 0x1E) == 0x12) | 549 | if ((tmp & 0x1E) == 0x12) |
551 | ppi[0] = &info_20_udma; | 550 | ppi[0] = &info_20_udma; |
552 | } | 551 | } |
553 | pci_dev_put(isa_bridge); | ||
554 | 552 | ||
555 | return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL); | 553 | return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL); |
556 | } | 554 | } |
@@ -590,13 +588,20 @@ static struct pci_driver ali_pci_driver = { | |||
590 | 588 | ||
591 | static int __init ali_init(void) | 589 | static int __init ali_init(void) |
592 | { | 590 | { |
593 | return pci_register_driver(&ali_pci_driver); | 591 | int ret; |
592 | isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); | ||
593 | |||
594 | ret = pci_register_driver(&ali_pci_driver); | ||
595 | if (ret < 0) | ||
596 | pci_dev_put(isa_bridge); | ||
597 | return ret; | ||
594 | } | 598 | } |
595 | 599 | ||
596 | 600 | ||
597 | static void __exit ali_exit(void) | 601 | static void __exit ali_exit(void) |
598 | { | 602 | { |
599 | pci_unregister_driver(&ali_pci_driver); | 603 | pci_unregister_driver(&ali_pci_driver); |
604 | pci_dev_put(isa_bridge); | ||
600 | } | 605 | } |
601 | 606 | ||
602 | 607 | ||