diff options
Diffstat (limited to 'drivers/ide/pci/siimage.c')
-rw-r--r-- | drivers/ide/pci/siimage.c | 161 |
1 files changed, 94 insertions, 67 deletions
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index 5965a35d94ae..b8ad9ad6cf0d 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c | |||
@@ -44,6 +44,8 @@ | |||
44 | #include <linux/init.h> | 44 | #include <linux/init.h> |
45 | #include <linux/io.h> | 45 | #include <linux/io.h> |
46 | 46 | ||
47 | #define DRV_NAME "siimage" | ||
48 | |||
47 | /** | 49 | /** |
48 | * pdev_is_sata - check if device is SATA | 50 | * pdev_is_sata - check if device is SATA |
49 | * @pdev: PCI device to check | 51 | * @pdev: PCI device to check |
@@ -127,9 +129,10 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r) | |||
127 | 129 | ||
128 | static u8 sil_ioread8(struct pci_dev *dev, unsigned long addr) | 130 | static u8 sil_ioread8(struct pci_dev *dev, unsigned long addr) |
129 | { | 131 | { |
132 | struct ide_host *host = pci_get_drvdata(dev); | ||
130 | u8 tmp = 0; | 133 | u8 tmp = 0; |
131 | 134 | ||
132 | if (pci_get_drvdata(dev)) | 135 | if (host->host_priv) |
133 | tmp = readb((void __iomem *)addr); | 136 | tmp = readb((void __iomem *)addr); |
134 | else | 137 | else |
135 | pci_read_config_byte(dev, addr, &tmp); | 138 | pci_read_config_byte(dev, addr, &tmp); |
@@ -139,9 +142,10 @@ static u8 sil_ioread8(struct pci_dev *dev, unsigned long addr) | |||
139 | 142 | ||
140 | static u16 sil_ioread16(struct pci_dev *dev, unsigned long addr) | 143 | static u16 sil_ioread16(struct pci_dev *dev, unsigned long addr) |
141 | { | 144 | { |
145 | struct ide_host *host = pci_get_drvdata(dev); | ||
142 | u16 tmp = 0; | 146 | u16 tmp = 0; |
143 | 147 | ||
144 | if (pci_get_drvdata(dev)) | 148 | if (host->host_priv) |
145 | tmp = readw((void __iomem *)addr); | 149 | tmp = readw((void __iomem *)addr); |
146 | else | 150 | else |
147 | pci_read_config_word(dev, addr, &tmp); | 151 | pci_read_config_word(dev, addr, &tmp); |
@@ -151,7 +155,9 @@ static u16 sil_ioread16(struct pci_dev *dev, unsigned long addr) | |||
151 | 155 | ||
152 | static void sil_iowrite8(struct pci_dev *dev, u8 val, unsigned long addr) | 156 | static void sil_iowrite8(struct pci_dev *dev, u8 val, unsigned long addr) |
153 | { | 157 | { |
154 | if (pci_get_drvdata(dev)) | 158 | struct ide_host *host = pci_get_drvdata(dev); |
159 | |||
160 | if (host->host_priv) | ||
155 | writeb(val, (void __iomem *)addr); | 161 | writeb(val, (void __iomem *)addr); |
156 | else | 162 | else |
157 | pci_write_config_byte(dev, addr, val); | 163 | pci_write_config_byte(dev, addr, val); |
@@ -159,7 +165,9 @@ static void sil_iowrite8(struct pci_dev *dev, u8 val, unsigned long addr) | |||
159 | 165 | ||
160 | static void sil_iowrite16(struct pci_dev *dev, u16 val, unsigned long addr) | 166 | static void sil_iowrite16(struct pci_dev *dev, u16 val, unsigned long addr) |
161 | { | 167 | { |
162 | if (pci_get_drvdata(dev)) | 168 | struct ide_host *host = pci_get_drvdata(dev); |
169 | |||
170 | if (host->host_priv) | ||
163 | writew(val, (void __iomem *)addr); | 171 | writew(val, (void __iomem *)addr); |
164 | else | 172 | else |
165 | pci_write_config_word(dev, addr, val); | 173 | pci_write_config_word(dev, addr, val); |
@@ -167,7 +175,9 @@ static void sil_iowrite16(struct pci_dev *dev, u16 val, unsigned long addr) | |||
167 | 175 | ||
168 | static void sil_iowrite32(struct pci_dev *dev, u32 val, unsigned long addr) | 176 | static void sil_iowrite32(struct pci_dev *dev, u32 val, unsigned long addr) |
169 | { | 177 | { |
170 | if (pci_get_drvdata(dev)) | 178 | struct ide_host *host = pci_get_drvdata(dev); |
179 | |||
180 | if (host->host_priv) | ||
171 | writel(val, (void __iomem *)addr); | 181 | writel(val, (void __iomem *)addr); |
172 | else | 182 | else |
173 | pci_write_config_dword(dev, addr, val); | 183 | pci_write_config_dword(dev, addr, val); |
@@ -445,66 +455,24 @@ static void sil_sata_pre_reset(ide_drive_t *drive) | |||
445 | } | 455 | } |
446 | 456 | ||
447 | /** | 457 | /** |
448 | * setup_mmio_siimage - switch controller into MMIO mode | ||
449 | * @dev: PCI device we are configuring | ||
450 | * @name: device name | ||
451 | * | ||
452 | * Attempt to put the device into MMIO mode. There are some slight | ||
453 | * complications here with certain systems where the MMIO BAR isn't | ||
454 | * mapped, so we have to be sure that we can fall back to I/O. | ||
455 | */ | ||
456 | |||
457 | static unsigned int setup_mmio_siimage(struct pci_dev *dev, const char *name) | ||
458 | { | ||
459 | resource_size_t bar5 = pci_resource_start(dev, 5); | ||
460 | unsigned long barsize = pci_resource_len(dev, 5); | ||
461 | void __iomem *ioaddr; | ||
462 | |||
463 | /* | ||
464 | * Drop back to PIO if we can't map the MMIO. Some systems | ||
465 | * seem to get terminally confused in the PCI spaces. | ||
466 | */ | ||
467 | if (!request_mem_region(bar5, barsize, name)) { | ||
468 | printk(KERN_WARNING "siimage: IDE controller MMIO ports not " | ||
469 | "available.\n"); | ||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | ioaddr = ioremap(bar5, barsize); | ||
474 | if (ioaddr == NULL) { | ||
475 | release_mem_region(bar5, barsize); | ||
476 | return 0; | ||
477 | } | ||
478 | |||
479 | pci_set_master(dev); | ||
480 | pci_set_drvdata(dev, (void *) ioaddr); | ||
481 | |||
482 | return 1; | ||
483 | } | ||
484 | |||
485 | /** | ||
486 | * init_chipset_siimage - set up an SI device | 458 | * init_chipset_siimage - set up an SI device |
487 | * @dev: PCI device | 459 | * @dev: PCI device |
488 | * @name: device name | ||
489 | * | 460 | * |
490 | * Perform the initial PCI set up for this device. Attempt to switch | 461 | * Perform the initial PCI set up for this device. Attempt to switch |
491 | * to 133 MHz clocking if the system isn't already set up to do it. | 462 | * to 133 MHz clocking if the system isn't already set up to do it. |
492 | */ | 463 | */ |
493 | 464 | ||
494 | static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, | 465 | static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev) |
495 | const char *name) | ||
496 | { | 466 | { |
467 | struct ide_host *host = pci_get_drvdata(dev); | ||
468 | void __iomem *ioaddr = host->host_priv; | ||
497 | unsigned long base, scsc_addr; | 469 | unsigned long base, scsc_addr; |
498 | void __iomem *ioaddr = NULL; | 470 | u8 rev = dev->revision, tmp; |
499 | u8 rev = dev->revision, tmp, BA5_EN; | ||
500 | 471 | ||
501 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, rev ? 1 : 255); | 472 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, rev ? 1 : 255); |
502 | 473 | ||
503 | pci_read_config_byte(dev, 0x8A, &BA5_EN); | 474 | if (ioaddr) |
504 | 475 | pci_set_master(dev); | |
505 | if ((BA5_EN & 0x01) || pci_resource_start(dev, 5)) | ||
506 | if (setup_mmio_siimage(dev, name)) | ||
507 | ioaddr = pci_get_drvdata(dev); | ||
508 | 476 | ||
509 | base = (unsigned long)ioaddr; | 477 | base = (unsigned long)ioaddr; |
510 | 478 | ||
@@ -571,7 +539,8 @@ static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, | |||
571 | { "== 100", "== 133", "== 2X PCI", "DISABLED!" }; | 539 | { "== 100", "== 133", "== 2X PCI", "DISABLED!" }; |
572 | 540 | ||
573 | tmp >>= 4; | 541 | tmp >>= 4; |
574 | printk(KERN_INFO "%s: BASE CLOCK %s\n", name, clk_str[tmp & 3]); | 542 | printk(KERN_INFO DRV_NAME " %s: BASE CLOCK %s\n", |
543 | pci_name(dev), clk_str[tmp & 3]); | ||
575 | } | 544 | } |
576 | 545 | ||
577 | return 0; | 546 | return 0; |
@@ -592,7 +561,8 @@ static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, | |||
592 | static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) | 561 | static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) |
593 | { | 562 | { |
594 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 563 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
595 | void *addr = pci_get_drvdata(dev); | 564 | struct ide_host *host = pci_get_drvdata(dev); |
565 | void *addr = host->host_priv; | ||
596 | u8 ch = hwif->channel; | 566 | u8 ch = hwif->channel; |
597 | struct ide_io_ports *io_ports = &hwif->io_ports; | 567 | struct ide_io_ports *io_ports = &hwif->io_ports; |
598 | unsigned long base; | 568 | unsigned long base; |
@@ -691,16 +661,15 @@ static void __devinit sil_quirkproc(ide_drive_t *drive) | |||
691 | static void __devinit init_iops_siimage(ide_hwif_t *hwif) | 661 | static void __devinit init_iops_siimage(ide_hwif_t *hwif) |
692 | { | 662 | { |
693 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 663 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
664 | struct ide_host *host = pci_get_drvdata(dev); | ||
694 | 665 | ||
695 | hwif->hwif_data = NULL; | 666 | hwif->hwif_data = NULL; |
696 | 667 | ||
697 | /* Pessimal until we finish probing */ | 668 | /* Pessimal until we finish probing */ |
698 | hwif->rqsize = 15; | 669 | hwif->rqsize = 15; |
699 | 670 | ||
700 | if (pci_get_drvdata(dev) == NULL) | 671 | if (host->host_priv) |
701 | return; | 672 | init_mmio_iops_siimage(hwif); |
702 | |||
703 | init_mmio_iops_siimage(hwif); | ||
704 | } | 673 | } |
705 | 674 | ||
706 | /** | 675 | /** |
@@ -748,9 +717,9 @@ static const struct ide_dma_ops sil_dma_ops = { | |||
748 | .dma_lost_irq = ide_dma_lost_irq, | 717 | .dma_lost_irq = ide_dma_lost_irq, |
749 | }; | 718 | }; |
750 | 719 | ||
751 | #define DECLARE_SII_DEV(name_str, p_ops) \ | 720 | #define DECLARE_SII_DEV(p_ops) \ |
752 | { \ | 721 | { \ |
753 | .name = name_str, \ | 722 | .name = DRV_NAME, \ |
754 | .init_chipset = init_chipset_siimage, \ | 723 | .init_chipset = init_chipset_siimage, \ |
755 | .init_iops = init_iops_siimage, \ | 724 | .init_iops = init_iops_siimage, \ |
756 | .port_ops = p_ops, \ | 725 | .port_ops = p_ops, \ |
@@ -761,9 +730,8 @@ static const struct ide_dma_ops sil_dma_ops = { | |||
761 | } | 730 | } |
762 | 731 | ||
763 | static const struct ide_port_info siimage_chipsets[] __devinitdata = { | 732 | static const struct ide_port_info siimage_chipsets[] __devinitdata = { |
764 | /* 0 */ DECLARE_SII_DEV("SiI680", &sil_pata_port_ops), | 733 | /* 0: SiI680 */ DECLARE_SII_DEV(&sil_pata_port_ops), |
765 | /* 1 */ DECLARE_SII_DEV("SiI3112 Serial ATA", &sil_sata_port_ops), | 734 | /* 1: SiI3112 */ DECLARE_SII_DEV(&sil_sata_port_ops) |
766 | /* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA", &sil_sata_port_ops) | ||
767 | }; | 735 | }; |
768 | 736 | ||
769 | /** | 737 | /** |
@@ -778,8 +746,13 @@ static const struct ide_port_info siimage_chipsets[] __devinitdata = { | |||
778 | static int __devinit siimage_init_one(struct pci_dev *dev, | 746 | static int __devinit siimage_init_one(struct pci_dev *dev, |
779 | const struct pci_device_id *id) | 747 | const struct pci_device_id *id) |
780 | { | 748 | { |
749 | void __iomem *ioaddr = NULL; | ||
750 | resource_size_t bar5 = pci_resource_start(dev, 5); | ||
751 | unsigned long barsize = pci_resource_len(dev, 5); | ||
752 | int rc; | ||
781 | struct ide_port_info d; | 753 | struct ide_port_info d; |
782 | u8 idx = id->driver_data; | 754 | u8 idx = id->driver_data; |
755 | u8 BA5_EN; | ||
783 | 756 | ||
784 | d = siimage_chipsets[idx]; | 757 | d = siimage_chipsets[idx]; |
785 | 758 | ||
@@ -787,7 +760,7 @@ static int __devinit siimage_init_one(struct pci_dev *dev, | |||
787 | static int first = 1; | 760 | static int first = 1; |
788 | 761 | ||
789 | if (first) { | 762 | if (first) { |
790 | printk(KERN_INFO "siimage: For full SATA support you " | 763 | printk(KERN_INFO DRV_NAME ": For full SATA support you " |
791 | "should use the libata sata_sil module.\n"); | 764 | "should use the libata sata_sil module.\n"); |
792 | first = 0; | 765 | first = 0; |
793 | } | 766 | } |
@@ -795,14 +768,61 @@ static int __devinit siimage_init_one(struct pci_dev *dev, | |||
795 | d.host_flags |= IDE_HFLAG_NO_ATAPI_DMA; | 768 | d.host_flags |= IDE_HFLAG_NO_ATAPI_DMA; |
796 | } | 769 | } |
797 | 770 | ||
798 | return ide_setup_pci_device(dev, &d); | 771 | rc = pci_enable_device(dev); |
772 | if (rc) | ||
773 | return rc; | ||
774 | |||
775 | pci_read_config_byte(dev, 0x8A, &BA5_EN); | ||
776 | if ((BA5_EN & 0x01) || bar5) { | ||
777 | /* | ||
778 | * Drop back to PIO if we can't map the MMIO. Some systems | ||
779 | * seem to get terminally confused in the PCI spaces. | ||
780 | */ | ||
781 | if (!request_mem_region(bar5, barsize, d.name)) { | ||
782 | printk(KERN_WARNING DRV_NAME " %s: MMIO ports not " | ||
783 | "available\n", pci_name(dev)); | ||
784 | } else { | ||
785 | ioaddr = ioremap(bar5, barsize); | ||
786 | if (ioaddr == NULL) | ||
787 | release_mem_region(bar5, barsize); | ||
788 | } | ||
789 | } | ||
790 | |||
791 | rc = ide_pci_init_one(dev, &d, ioaddr); | ||
792 | if (rc) { | ||
793 | if (ioaddr) { | ||
794 | iounmap(ioaddr); | ||
795 | release_mem_region(bar5, barsize); | ||
796 | } | ||
797 | pci_disable_device(dev); | ||
798 | } | ||
799 | |||
800 | return rc; | ||
801 | } | ||
802 | |||
803 | static void __devexit siimage_remove(struct pci_dev *dev) | ||
804 | { | ||
805 | struct ide_host *host = pci_get_drvdata(dev); | ||
806 | void __iomem *ioaddr = host->host_priv; | ||
807 | |||
808 | ide_pci_remove(dev); | ||
809 | |||
810 | if (ioaddr) { | ||
811 | resource_size_t bar5 = pci_resource_start(dev, 5); | ||
812 | unsigned long barsize = pci_resource_len(dev, 5); | ||
813 | |||
814 | iounmap(ioaddr); | ||
815 | release_mem_region(bar5, barsize); | ||
816 | } | ||
817 | |||
818 | pci_disable_device(dev); | ||
799 | } | 819 | } |
800 | 820 | ||
801 | static const struct pci_device_id siimage_pci_tbl[] = { | 821 | static const struct pci_device_id siimage_pci_tbl[] = { |
802 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), 0 }, | 822 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), 0 }, |
803 | #ifdef CONFIG_BLK_DEV_IDE_SATA | 823 | #ifdef CONFIG_BLK_DEV_IDE_SATA |
804 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_3112), 1 }, | 824 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_3112), 1 }, |
805 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_1210SA), 2 }, | 825 | { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_1210SA), 1 }, |
806 | #endif | 826 | #endif |
807 | { 0, }, | 827 | { 0, }, |
808 | }; | 828 | }; |
@@ -812,6 +832,7 @@ static struct pci_driver driver = { | |||
812 | .name = "SiI_IDE", | 832 | .name = "SiI_IDE", |
813 | .id_table = siimage_pci_tbl, | 833 | .id_table = siimage_pci_tbl, |
814 | .probe = siimage_init_one, | 834 | .probe = siimage_init_one, |
835 | .remove = siimage_remove, | ||
815 | }; | 836 | }; |
816 | 837 | ||
817 | static int __init siimage_ide_init(void) | 838 | static int __init siimage_ide_init(void) |
@@ -819,7 +840,13 @@ static int __init siimage_ide_init(void) | |||
819 | return ide_pci_register_driver(&driver); | 840 | return ide_pci_register_driver(&driver); |
820 | } | 841 | } |
821 | 842 | ||
843 | static void __exit siimage_ide_exit(void) | ||
844 | { | ||
845 | pci_unregister_driver(&driver); | ||
846 | } | ||
847 | |||
822 | module_init(siimage_ide_init); | 848 | module_init(siimage_ide_init); |
849 | module_exit(siimage_ide_exit); | ||
823 | 850 | ||
824 | MODULE_AUTHOR("Andre Hedrick, Alan Cox"); | 851 | MODULE_AUTHOR("Andre Hedrick, Alan Cox"); |
825 | MODULE_DESCRIPTION("PCI driver module for SiI IDE"); | 852 | MODULE_DESCRIPTION("PCI driver module for SiI IDE"); |