ide: ->cable_detect method cannot be marked __devinit
[pandora-kernel.git] / drivers / ide / pci / siimage.c
index 5965a35..445ce6f 100644 (file)
@@ -44,6 +44,8 @@
 #include <linux/init.h>
 #include <linux/io.h>
 
+#define DRV_NAME "siimage"
+
 /**
  *     pdev_is_sata            -       check if device is SATA
  *     @pdev:  PCI device to check
@@ -127,9 +129,10 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
 
 static u8 sil_ioread8(struct pci_dev *dev, unsigned long addr)
 {
+       struct ide_host *host = pci_get_drvdata(dev);
        u8 tmp = 0;
 
-       if (pci_get_drvdata(dev))
+       if (host->host_priv)
                tmp = readb((void __iomem *)addr);
        else
                pci_read_config_byte(dev, addr, &tmp);
@@ -139,9 +142,10 @@ static u8 sil_ioread8(struct pci_dev *dev, unsigned long addr)
 
 static u16 sil_ioread16(struct pci_dev *dev, unsigned long addr)
 {
+       struct ide_host *host = pci_get_drvdata(dev);
        u16 tmp = 0;
 
-       if (pci_get_drvdata(dev))
+       if (host->host_priv)
                tmp = readw((void __iomem *)addr);
        else
                pci_read_config_word(dev, addr, &tmp);
@@ -151,7 +155,9 @@ static u16 sil_ioread16(struct pci_dev *dev, unsigned long addr)
 
 static void sil_iowrite8(struct pci_dev *dev, u8 val, unsigned long addr)
 {
-       if (pci_get_drvdata(dev))
+       struct ide_host *host = pci_get_drvdata(dev);
+
+       if (host->host_priv)
                writeb(val, (void __iomem *)addr);
        else
                pci_write_config_byte(dev, addr, val);
@@ -159,7 +165,9 @@ static void sil_iowrite8(struct pci_dev *dev, u8 val, unsigned long addr)
 
 static void sil_iowrite16(struct pci_dev *dev, u16 val, unsigned long addr)
 {
-       if (pci_get_drvdata(dev))
+       struct ide_host *host = pci_get_drvdata(dev);
+
+       if (host->host_priv)
                writew(val, (void __iomem *)addr);
        else
                pci_write_config_word(dev, addr, val);
@@ -167,7 +175,9 @@ static void sil_iowrite16(struct pci_dev *dev, u16 val, unsigned long addr)
 
 static void sil_iowrite32(struct pci_dev *dev, u32 val, unsigned long addr)
 {
-       if (pci_get_drvdata(dev))
+       struct ide_host *host = pci_get_drvdata(dev);
+
+       if (host->host_priv)
                writel(val, (void __iomem *)addr);
        else
                pci_write_config_dword(dev, addr, val);
@@ -444,67 +454,25 @@ static void sil_sata_pre_reset(ide_drive_t *drive)
        }
 }
 
-/**
- *     setup_mmio_siimage      -       switch controller into MMIO mode
- *     @dev: PCI device we are configuring
- *     @name: device name
- *
- *     Attempt to put the device into MMIO mode. There are some slight
- *     complications here with certain systems where the MMIO BAR isn't
- *     mapped, so we have to be sure that we can fall back to I/O.
- */
-
-static unsigned int setup_mmio_siimage(struct pci_dev *dev, const char *name)
-{
-       resource_size_t bar5    = pci_resource_start(dev, 5);
-       unsigned long barsize   = pci_resource_len(dev, 5);
-       void __iomem *ioaddr;
-
-       /*
-        *      Drop back to PIO if we can't map the MMIO. Some systems
-        *      seem to get terminally confused in the PCI spaces.
-        */
-       if (!request_mem_region(bar5, barsize, name)) {
-               printk(KERN_WARNING "siimage: IDE controller MMIO ports not "
-                                   "available.\n");
-               return 0;
-       }
-
-       ioaddr = ioremap(bar5, barsize);
-       if (ioaddr == NULL) {
-               release_mem_region(bar5, barsize);
-               return 0;
-       }
-
-       pci_set_master(dev);
-       pci_set_drvdata(dev, (void *) ioaddr);
-
-       return 1;
-}
-
 /**
  *     init_chipset_siimage    -       set up an SI device
  *     @dev: PCI device
- *     @name: device name
  *
  *     Perform the initial PCI set up for this device. Attempt to switch
  *     to 133 MHz clocking if the system isn't already set up to do it.
  */
 
-static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev,
-                                                  const char *name)
+static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev)
 {
+       struct ide_host *host = pci_get_drvdata(dev);
+       void __iomem *ioaddr = host->host_priv;
        unsigned long base, scsc_addr;
-       void __iomem *ioaddr = NULL;
-       u8 rev = dev->revision, tmp, BA5_EN;
+       u8 rev = dev->revision, tmp;
 
        pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, rev ? 1 : 255);
 
-       pci_read_config_byte(dev, 0x8A, &BA5_EN);
-
-       if ((BA5_EN & 0x01) || pci_resource_start(dev, 5))
-               if (setup_mmio_siimage(dev, name))
-                       ioaddr = pci_get_drvdata(dev);
+       if (ioaddr)
+               pci_set_master(dev);
 
        base = (unsigned long)ioaddr;
 
@@ -571,7 +539,8 @@ static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev,
                        { "== 100", "== 133", "== 2X PCI", "DISABLED!" };
 
                tmp >>= 4;
-               printk(KERN_INFO "%s: BASE CLOCK %s\n", name, clk_str[tmp & 3]);
+               printk(KERN_INFO DRV_NAME " %s: BASE CLOCK %s\n",
+                       pci_name(dev), clk_str[tmp & 3]);
        }
 
        return 0;
@@ -592,7 +561,8 @@ static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev,
 static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
 {
        struct pci_dev *dev     = to_pci_dev(hwif->dev);
-       void *addr              = pci_get_drvdata(dev);
+       struct ide_host *host   = pci_get_drvdata(dev);
+       void *addr              = host->host_priv;
        u8 ch                   = hwif->channel;
        struct ide_io_ports *io_ports = &hwif->io_ports;
        unsigned long base;
@@ -669,7 +639,7 @@ static int is_dev_seagate_sata(ide_drive_t *drive)
  *     that can occur before we know what drives are present.
  */
 
-static void __devinit sil_quirkproc(ide_drive_t *drive)
+static void sil_quirkproc(ide_drive_t *drive)
 {
        ide_hwif_t *hwif = drive->hwif;
 
@@ -691,16 +661,15 @@ static void __devinit sil_quirkproc(ide_drive_t *drive)
 static void __devinit init_iops_siimage(ide_hwif_t *hwif)
 {
        struct pci_dev *dev = to_pci_dev(hwif->dev);
+       struct ide_host *host = pci_get_drvdata(dev);
 
        hwif->hwif_data = NULL;
 
        /* Pessimal until we finish probing */
        hwif->rqsize = 15;
 
-       if (pci_get_drvdata(dev) == NULL)
-               return;
-
-       init_mmio_iops_siimage(hwif);
+       if (host->host_priv)
+               init_mmio_iops_siimage(hwif);
 }
 
 /**
@@ -710,7 +679,7 @@ static void __devinit init_iops_siimage(ide_hwif_t *hwif)
  *     Check for the presence of an ATA66 capable cable on the interface.
  */
 
-static u8 __devinit sil_cable_detect(ide_hwif_t *hwif)
+static u8 sil_cable_detect(ide_hwif_t *hwif)
 {
        struct pci_dev *dev     = to_pci_dev(hwif->dev);
        unsigned long addr      = siimage_selreg(hwif, 0);
@@ -748,9 +717,9 @@ static const struct ide_dma_ops sil_dma_ops = {
        .dma_lost_irq           = ide_dma_lost_irq,
 };
 
-#define DECLARE_SII_DEV(name_str, p_ops)               \
+#define DECLARE_SII_DEV(p_ops)                         \
        {                                               \
-               .name           = name_str,             \
+               .name           = DRV_NAME,             \
                .init_chipset   = init_chipset_siimage, \
                .init_iops      = init_iops_siimage,    \
                .port_ops       = p_ops,                \
@@ -761,9 +730,8 @@ static const struct ide_dma_ops sil_dma_ops = {
        }
 
 static const struct ide_port_info siimage_chipsets[] __devinitdata = {
-       /* 0 */ DECLARE_SII_DEV("SiI680",               &sil_pata_port_ops),
-       /* 1 */ DECLARE_SII_DEV("SiI3112 Serial ATA",   &sil_sata_port_ops),
-       /* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA",   &sil_sata_port_ops)
+       /* 0: SiI680 */  DECLARE_SII_DEV(&sil_pata_port_ops),
+       /* 1: SiI3112 */ DECLARE_SII_DEV(&sil_sata_port_ops)
 };
 
 /**
@@ -778,8 +746,13 @@ static const struct ide_port_info siimage_chipsets[] __devinitdata = {
 static int __devinit siimage_init_one(struct pci_dev *dev,
                                      const struct pci_device_id *id)
 {
+       void __iomem *ioaddr = NULL;
+       resource_size_t bar5 = pci_resource_start(dev, 5);
+       unsigned long barsize = pci_resource_len(dev, 5);
+       int rc;
        struct ide_port_info d;
        u8 idx = id->driver_data;
+       u8 BA5_EN;
 
        d = siimage_chipsets[idx];
 
@@ -787,7 +760,7 @@ static int __devinit siimage_init_one(struct pci_dev *dev,
                static int first = 1;
 
                if (first) {
-                       printk(KERN_INFO "siimage: For full SATA support you "
+                       printk(KERN_INFO DRV_NAME ": For full SATA support you "
                                "should use the libata sata_sil module.\n");
                        first = 0;
                }
@@ -795,14 +768,61 @@ static int __devinit siimage_init_one(struct pci_dev *dev,
                d.host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
        }
 
-       return ide_setup_pci_device(dev, &d);
+       rc = pci_enable_device(dev);
+       if (rc)
+               return rc;
+
+       pci_read_config_byte(dev, 0x8A, &BA5_EN);
+       if ((BA5_EN & 0x01) || bar5) {
+               /*
+               * Drop back to PIO if we can't map the MMIO. Some systems
+               * seem to get terminally confused in the PCI spaces.
+               */
+               if (!request_mem_region(bar5, barsize, d.name)) {
+                       printk(KERN_WARNING DRV_NAME " %s: MMIO ports not "
+                               "available\n", pci_name(dev));
+               } else {
+                       ioaddr = ioremap(bar5, barsize);
+                       if (ioaddr == NULL)
+                               release_mem_region(bar5, barsize);
+               }
+       }
+
+       rc = ide_pci_init_one(dev, &d, ioaddr);
+       if (rc) {
+               if (ioaddr) {
+                       iounmap(ioaddr);
+                       release_mem_region(bar5, barsize);
+               }
+               pci_disable_device(dev);
+       }
+
+       return rc;
+}
+
+static void __devexit siimage_remove(struct pci_dev *dev)
+{
+       struct ide_host *host = pci_get_drvdata(dev);
+       void __iomem *ioaddr = host->host_priv;
+
+       ide_pci_remove(dev);
+
+       if (ioaddr) {
+               resource_size_t bar5 = pci_resource_start(dev, 5);
+               unsigned long barsize = pci_resource_len(dev, 5);
+
+               iounmap(ioaddr);
+               release_mem_region(bar5, barsize);
+       }
+
+       pci_disable_device(dev);
 }
 
 static const struct pci_device_id siimage_pci_tbl[] = {
        { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680),    0 },
 #ifdef CONFIG_BLK_DEV_IDE_SATA
        { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_3112),   1 },
-       { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_1210SA), 2 },
+       { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_1210SA), 1 },
 #endif
        { 0, },
 };
@@ -812,6 +832,7 @@ static struct pci_driver driver = {
        .name           = "SiI_IDE",
        .id_table       = siimage_pci_tbl,
        .probe          = siimage_init_one,
+       .remove         = siimage_remove,
 };
 
 static int __init siimage_ide_init(void)
@@ -819,7 +840,13 @@ static int __init siimage_ide_init(void)
        return ide_pci_register_driver(&driver);
 }
 
+static void __exit siimage_ide_exit(void)
+{
+       pci_unregister_driver(&driver);
+}
+
 module_init(siimage_ide_init);
+module_exit(siimage_ide_exit);
 
 MODULE_AUTHOR("Andre Hedrick, Alan Cox");
 MODULE_DESCRIPTION("PCI driver module for SiI IDE");