Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Sun, 29 Apr 2007 17:48:21 +0000 (10:48 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Sun, 29 Apr 2007 17:48:21 +0000 (10:48 -0700)
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev: (86 commits)
  SPIN_LOCK_UNLOCKED cleanup in drivers/ata/pata_winbond.c
  drivers/ata/pata_cmd640.c: fix build with CONFIG_PM=n
  pata_hpt37x: Further small fixes
  pata_hpt3x2n: Add HPT371N support and other bits
  ata: printk warning fixes
  libata: separate ATA_EHI_DID_RESET into DID_SOFTRESET and DID_HARDRESET
  ahci: consolidate common port flags
  ata_timing: ensure t->cycle is always correct
  libata: add missing call to ->cable_detect() in new EH path
  pata_amd: remove contamination added during cable_detect conversion
  libata: Handle drives that require a spin-up command before first access
  libata: HPA support
  libata: kill probe_ent and related helpers
  libata: convert the remaining PATA drivers to new init model
  libata: convert the remaining SATA drivers to new init model
  libata: convert ata_pci_init_native_mode() users to new init model
  libata: convert drivers with combined SATA/PATA ports to new init model
  libata: add init helpers including ata_pci_prepare_native_host()
  libata: convert native PCI host handling to new init model
  libata: convert legacy PCI host handling to new init model
  ...

80 files changed:
arch/i386/defconfig
arch/parisc/configs/c3000_defconfig
arch/x86_64/defconfig
drivers/ata/Kconfig
drivers/ata/Makefile
drivers/ata/ahci.c
drivers/ata/ata_generic.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/libata-sff.c
drivers/ata/libata.h
drivers/ata/pata_ali.c
drivers/ata/pata_amd.c
drivers/ata/pata_artop.c
drivers/ata/pata_atiixp.c
drivers/ata/pata_cmd640.c [new file with mode: 0644]
drivers/ata/pata_cmd64x.c
drivers/ata/pata_cs5520.c
drivers/ata/pata_cs5530.c
drivers/ata/pata_cs5535.c
drivers/ata/pata_cypress.c
drivers/ata/pata_efar.c
drivers/ata/pata_hpt366.c
drivers/ata/pata_hpt37x.c
drivers/ata/pata_hpt3x2n.c
drivers/ata/pata_hpt3x3.c
drivers/ata/pata_isapnp.c
drivers/ata/pata_it8213.c
drivers/ata/pata_it821x.c
drivers/ata/pata_ixp4xx_cf.c
drivers/ata/pata_legacy.c
drivers/ata/pata_marvell.c
drivers/ata/pata_mpc52xx.c
drivers/ata/pata_mpiix.c
drivers/ata/pata_netcell.c
drivers/ata/pata_ns87410.c
drivers/ata/pata_oldpiix.c
drivers/ata/pata_opti.c
drivers/ata/pata_optidma.c
drivers/ata/pata_pcmcia.c
drivers/ata/pata_pdc2027x.c
drivers/ata/pata_pdc202xx_old.c
drivers/ata/pata_platform.c
drivers/ata/pata_qdi.c
drivers/ata/pata_radisys.c
drivers/ata/pata_rz1000.c
drivers/ata/pata_sc1200.c
drivers/ata/pata_scc.c
drivers/ata/pata_serverworks.c
drivers/ata/pata_sil680.c
drivers/ata/pata_sis.c
drivers/ata/pata_sl82c105.c
drivers/ata/pata_triflex.c
drivers/ata/pata_via.c
drivers/ata/pata_winbond.c
drivers/ata/pdc_adma.c
drivers/ata/sata_inic162x.c
drivers/ata/sata_mv.c
drivers/ata/sata_nv.c
drivers/ata/sata_promise.c
drivers/ata/sata_qstor.c
drivers/ata/sata_sil.c
drivers/ata/sata_sil24.c
drivers/ata/sata_sis.c
drivers/ata/sata_svw.c
drivers/ata/sata_sx4.c
drivers/ata/sata_uli.c
drivers/ata/sata_via.c
drivers/ata/sata_vsc.c
drivers/pci/quirks.c
drivers/scsi/ipr.c
include/linux/ata.h
include/linux/ioport.h
include/linux/libata.h
include/linux/pci.h
include/linux/pci_ids.h
kernel/resource.c
lib/devres.c

index f4efd66e1ee502a401c720085d8f81fcfe6c803e..c96911c37aea28b7141c7ee26d43b49e4982f902 100644 (file)
@@ -692,7 +692,6 @@ CONFIG_SATA_SIL=y
 CONFIG_SATA_VIA=y
 # CONFIG_SATA_VITESSE is not set
 # CONFIG_SATA_INIC162X is not set
-CONFIG_SATA_INTEL_COMBINED=y
 CONFIG_SATA_ACPI=y
 # CONFIG_PATA_ALI is not set
 # CONFIG_PATA_AMD is not set
index 782906b644ddd46253f231bfd692153f4ef973e0..eb2f9a3d515c4ec6925b30eb034888a67688541b 100644 (file)
@@ -435,7 +435,6 @@ CONFIG_SCSI_SATA_SIL=m
 # CONFIG_SCSI_SATA_ULI is not set
 CONFIG_SCSI_SATA_VIA=m
 # CONFIG_SCSI_SATA_VITESSE is not set
-CONFIG_SCSI_SATA_INTEL_COMBINED=y
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_IPS is not set
index 7a1e251e333ddfc505dcc3e68cfa10acb19a46dd..b26378815b9145ead9183f55113395d7271bfee0 100644 (file)
@@ -631,7 +631,6 @@ CONFIG_SATA_SIL=y
 CONFIG_SATA_VIA=y
 # CONFIG_SATA_VITESSE is not set
 # CONFIG_SATA_INIC162X is not set
-CONFIG_SATA_INTEL_COMBINED=y
 CONFIG_SATA_ACPI=y
 # CONFIG_PATA_ALI is not set
 # CONFIG_PATA_AMD is not set
index 7bdbe5a914d0ce78f34d10325ce0e9eba31fb126..365c306c7cf81e2fcfd75d4be9c3fb1e2c39e303 100644 (file)
@@ -156,11 +156,6 @@ config SATA_INIC162X
        help
          This option enables support for Initio 162x Serial ATA.
 
-config SATA_INTEL_COMBINED
-       bool
-       depends on IDE=y && !BLK_DEV_IDE_SATA && (SATA_AHCI || ATA_PIIX)
-       default y
-
 config SATA_ACPI
        bool
        depends on ACPI && PCI
@@ -184,7 +179,7 @@ config PATA_ALI
          If unsure, say N.
 
 config PATA_AMD
-       tristate "AMD/NVidia PATA support (Experimental)"
+       tristate "AMD/NVidia PATA support"
        depends on PCI
        help
          This option enables support for the AMD and NVidia PATA
@@ -209,6 +204,16 @@ config PATA_ATIIXP
 
          If unsure, say N.
 
+config PATA_CMD640_PCI
+       tristate "CMD640 PCI PATA support (Very Experimental)"
+       depends on PCI && EXPERIMENTAL
+       help
+         This option enables support for the CMD640 PCI IDE
+         interface chip. Only the primary channel is currently
+         supported.
+
+         If unsure, say N.
+
 config PATA_CMD64X
        tristate "CMD64x PATA support (Very Experimental)"
        depends on PCI&& EXPERIMENTAL
@@ -273,7 +278,7 @@ config ATA_GENERIC
          If unsure, say N.
 
 config PATA_HPT366
-       tristate "HPT 366/368 PATA support (Very Experimental)"
+       tristate "HPT 366/368 PATA support (Experimental)"
        depends on PCI && EXPERIMENTAL
        help
          This option enables support for the HPT 366 and 368
@@ -282,7 +287,7 @@ config PATA_HPT366
          If unsure, say N.
 
 config PATA_HPT37X
-       tristate "HPT 370/370A/371/372/374/302 PATA support (Very Experimental)"
+       tristate "HPT 370/370A/371/372/374/302 PATA support (Experimental)"
        depends on PCI && EXPERIMENTAL
        help
          This option enables support for the majority of the later HPT
@@ -309,7 +314,7 @@ config PATA_HPT3X3
          If unsure, say N.
 
 config PATA_ISAPNP
-       tristate "ISA Plug and Play PATA support (Very Experimental)"
+       tristate "ISA Plug and Play PATA support (Experimental)"
        depends on EXPERIMENTAL && ISAPNP
        help
          This option enables support for ISA plug & play ATA
@@ -318,8 +323,8 @@ config PATA_ISAPNP
          If unsure, say N.
 
 config PATA_IT821X
-       tristate "IT8211/2 PATA support (Experimental)"
-       depends on PCI && EXPERIMENTAL
+       tristate "IT8211/2 PATA support"
+       depends on PCI
        help
          This option enables support for the ITE 8211 and 8212
          PATA controllers via the new ATA layer, including RAID
@@ -390,10 +395,10 @@ config PATA_MPIIX
          If unsure, say N.
 
 config PATA_OLDPIIX
-       tristate "Intel PATA old PIIX support (Experimental)"
-       depends on PCI && EXPERIMENTAL
+       tristate "Intel PATA old PIIX support"
+       depends on PCI
        help
-         This option enables support for old(?) PIIX PATA support.
+         This option enables support for early PIIX PATA support.
 
          If unsure, say N.
 
@@ -444,7 +449,7 @@ config PATA_PCMCIA
          If unsure, say N.
 
 config PATA_PDC_OLD
-       tristate "Older Promise PATA controller support (Very Experimental)"
+       tristate "Older Promise PATA controller support (Experimental)"
        depends on PCI && EXPERIMENTAL
        help
          This option enables support for the Promise 20246, 20262, 20263,
@@ -459,7 +464,7 @@ config PATA_QDI
          Support for QDI 6500 and 6580 PATA controllers on VESA local bus.
 
 config PATA_RADISYS
-       tristate "RADISYS 82600 PATA support (Very experimental)"
+       tristate "RADISYS 82600 PATA support (Very Experimental)"
        depends on PCI && EXPERIMENTAL
        help
          This option enables support for the RADISYS 82600
@@ -477,7 +482,7 @@ config PATA_RZ1000
          If unsure, say N.
 
 config PATA_SC1200
-       tristate "SC1200 PATA support (Raving Lunatic)"
+       tristate "SC1200 PATA support (Very Experimental)"
        depends on PCI && EXPERIMENTAL
        help
          This option enables support for the NatSemi/AMD SC1200 SoC
@@ -486,8 +491,8 @@ config PATA_SC1200
          If unsure, say N.
 
 config PATA_SERVERWORKS
-       tristate "SERVERWORKS OSB4/CSB5/CSB6/HT1000 PATA support (Experimental)"
-       depends on PCI && EXPERIMENTAL
+       tristate "SERVERWORKS OSB4/CSB5/CSB6/HT1000 PATA support"
+       depends on PCI
        help
          This option enables support for the Serverworks OSB4/CSB5/CSB6 and
          HT1000 PATA controllers, via the new ATA layer.
index 13d7397e0008080fe84dc020f69e7f10a5e2b870..b7055e302650dc4d6dea4e81d6346dc2457208b1 100644 (file)
@@ -22,6 +22,7 @@ obj-$(CONFIG_PATA_ALI)                += pata_ali.o
 obj-$(CONFIG_PATA_AMD)         += pata_amd.o
 obj-$(CONFIG_PATA_ARTOP)       += pata_artop.o
 obj-$(CONFIG_PATA_ATIIXP)      += pata_atiixp.o
+obj-$(CONFIG_PATA_CMD640_PCI)  += pata_cmd640.o
 obj-$(CONFIG_PATA_CMD64X)      += pata_cmd64x.o
 obj-$(CONFIG_PATA_CS5520)      += pata_cs5520.o
 obj-$(CONFIG_PATA_CS5530)      += pata_cs5530.o
index fd27227771b48a8038ec867c62f9804fc34aa9af..34c5534ed64c22c65779b418a57793739b98f16f 100644 (file)
@@ -170,6 +170,10 @@ enum {
        AHCI_FLAG_IGN_IRQ_IF_ERR        = (1 << 25), /* ignore IRQ_IF_ERR */
        AHCI_FLAG_HONOR_PI              = (1 << 26), /* honor PORTS_IMPL */
        AHCI_FLAG_IGN_SERR_INTERNAL     = (1 << 27), /* ignore SERR_INTERNAL */
+
+       AHCI_FLAG_COMMON                = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                         ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
+                                         ATA_FLAG_SKIP_D2H_BSY,
 };
 
 struct ahci_cmd_hdr {
@@ -188,8 +192,10 @@ struct ahci_sg {
 };
 
 struct ahci_host_priv {
-       u32                     cap;    /* cache of HOST_CAP register */
-       u32                     port_map; /* cache of HOST_PORTS_IMPL reg */
+       u32                     cap;            /* cap to use */
+       u32                     port_map;       /* port map to use */
+       u32                     saved_cap;      /* saved initial cap */
+       u32                     saved_port_map; /* saved initial port_map */
 };
 
 struct ahci_port_priv {
@@ -209,7 +215,6 @@ static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
 static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
-static irqreturn_t ahci_interrupt (int irq, void *dev_instance);
 static void ahci_irq_clear(struct ata_port *ap);
 static int ahci_port_start(struct ata_port *ap);
 static void ahci_port_stop(struct ata_port *ap);
@@ -263,7 +268,6 @@ static const struct ata_port_operations ahci_ops = {
        .qc_prep                = ahci_qc_prep,
        .qc_issue               = ahci_qc_issue,
 
-       .irq_handler            = ahci_interrupt,
        .irq_clear              = ahci_irq_clear,
        .irq_on                 = ata_dummy_irq_on,
        .irq_ack                = ata_dummy_irq_ack,
@@ -298,7 +302,6 @@ static const struct ata_port_operations ahci_vt8251_ops = {
        .qc_prep                = ahci_qc_prep,
        .qc_issue               = ahci_qc_issue,
 
-       .irq_handler            = ahci_interrupt,
        .irq_clear              = ahci_irq_clear,
        .irq_on                 = ata_dummy_irq_on,
        .irq_ack                = ata_dummy_irq_ack,
@@ -324,58 +327,41 @@ static const struct ata_port_operations ahci_vt8251_ops = {
 static const struct ata_port_info ahci_port_info[] = {
        /* board_ahci */
        {
-               .sht            = &ahci_sht,
-               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-                                 ATA_FLAG_SKIP_D2H_BSY,
+               .flags          = AHCI_FLAG_COMMON,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &ahci_ops,
        },
        /* board_ahci_pi */
        {
-               .sht            = &ahci_sht,
-               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-                                 ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI,
+               .flags          = AHCI_FLAG_COMMON | AHCI_FLAG_HONOR_PI,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &ahci_ops,
        },
        /* board_ahci_vt8251 */
        {
-               .sht            = &ahci_sht,
-               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-                                 ATA_FLAG_SKIP_D2H_BSY |
-                                 ATA_FLAG_HRST_TO_RESUME | AHCI_FLAG_NO_NCQ,
+               .flags          = AHCI_FLAG_COMMON | ATA_FLAG_HRST_TO_RESUME |
+                                 AHCI_FLAG_NO_NCQ,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &ahci_vt8251_ops,
        },
        /* board_ahci_ign_iferr */
        {
-               .sht            = &ahci_sht,
-               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-                                 ATA_FLAG_SKIP_D2H_BSY |
-                                 AHCI_FLAG_IGN_IRQ_IF_ERR,
+               .flags          = AHCI_FLAG_COMMON | AHCI_FLAG_IGN_IRQ_IF_ERR,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &ahci_ops,
        },
        /* board_ahci_sb600 */
        {
-               .sht            = &ahci_sht,
-               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                                 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-                                 ATA_FLAG_SKIP_D2H_BSY |
+               .flags          = AHCI_FLAG_COMMON |
                                  AHCI_FLAG_IGN_SERR_INTERNAL,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &ahci_ops,
        },
-
 };
 
 static const struct pci_device_id ahci_pci_tbl[] = {
@@ -413,11 +399,11 @@ static const struct pci_device_id ahci_pci_tbl[] = {
          PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr },
 
        /* ATI */
-       { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 non-raid */
-       { PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */
+       { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */
 
        /* VIA */
        { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */
+       { PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 */
 
        /* NVIDIA */
        { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci },            /* MCP65 */
@@ -471,10 +457,100 @@ static inline int ahci_nr_ports(u32 cap)
        return (cap & 0x1f) + 1;
 }
 
-static inline void __iomem *ahci_port_base(void __iomem *base,
-                                          unsigned int port)
+static inline void __iomem *ahci_port_base(struct ata_port *ap)
+{
+       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
+
+       return mmio + 0x100 + (ap->port_no * 0x80);
+}
+
+/**
+ *     ahci_save_initial_config - Save and fixup initial config values
+ *     @pdev: target PCI device
+ *     @pi: associated ATA port info
+ *     @hpriv: host private area to store config values
+ *
+ *     Some registers containing configuration info might be setup by
+ *     BIOS and might be cleared on reset.  This function saves the
+ *     initial values of those registers into @hpriv such that they
+ *     can be restored after controller reset.
+ *
+ *     If inconsistent, config values are fixed up by this function.
+ *
+ *     LOCKING:
+ *     None.
+ */
+static void ahci_save_initial_config(struct pci_dev *pdev,
+                                    const struct ata_port_info *pi,
+                                    struct ahci_host_priv *hpriv)
 {
-       return base + 0x100 + (port * 0x80);
+       void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
+       u32 cap, port_map;
+       int i;
+
+       /* Values prefixed with saved_ are written back to host after
+        * reset.  Values without are used for driver operation.
+        */
+       hpriv->saved_cap = cap = readl(mmio + HOST_CAP);
+       hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL);
+
+       /* fixup zero port_map */
+       if (!port_map) {
+               port_map = (1 << ahci_nr_ports(hpriv->cap)) - 1;
+               dev_printk(KERN_WARNING, &pdev->dev,
+                          "PORTS_IMPL is zero, forcing 0x%x\n", port_map);
+
+               /* write the fixed up value to the PI register */
+               hpriv->saved_port_map = port_map;
+       }
+
+       /* cross check port_map and cap.n_ports */
+       if (pi->flags & AHCI_FLAG_HONOR_PI) {
+               u32 tmp_port_map = port_map;
+               int n_ports = ahci_nr_ports(cap);
+
+               for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) {
+                       if (tmp_port_map & (1 << i)) {
+                               n_ports--;
+                               tmp_port_map &= ~(1 << i);
+                       }
+               }
+
+               /* Whine if inconsistent.  No need to update cap.
+                * port_map is used to determine number of ports.
+                */
+               if (n_ports || tmp_port_map)
+                       dev_printk(KERN_WARNING, &pdev->dev,
+                                  "nr_ports (%u) and implemented port map "
+                                  "(0x%x) don't match\n",
+                                  ahci_nr_ports(cap), port_map);
+       } else {
+               /* fabricate port_map from cap.nr_ports */
+               port_map = (1 << ahci_nr_ports(cap)) - 1;
+       }
+
+       /* record values to use during operation */
+       hpriv->cap = cap;
+       hpriv->port_map = port_map;
+}
+
+/**
+ *     ahci_restore_initial_config - Restore initial config
+ *     @host: target ATA host
+ *
+ *     Restore initial config stored by ahci_save_initial_config().
+ *
+ *     LOCKING:
+ *     None.
+ */
+static void ahci_restore_initial_config(struct ata_host *host)
+{
+       struct ahci_host_priv *hpriv = host->private_data;
+       void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
+
+       writel(hpriv->saved_cap, mmio + HOST_CAP);
+       writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL);
+       (void) readl(mmio + HOST_PORTS_IMPL);   /* flush */
 }
 
 static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in)
@@ -511,8 +587,9 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in,
        writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
 }
 
-static void ahci_start_engine(void __iomem *port_mmio)
+static void ahci_start_engine(struct ata_port *ap)
 {
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 tmp;
 
        /* start DMA */
@@ -522,8 +599,9 @@ static void ahci_start_engine(void __iomem *port_mmio)
        readl(port_mmio + PORT_CMD); /* flush */
 }
 
-static int ahci_stop_engine(void __iomem *port_mmio)
+static int ahci_stop_engine(struct ata_port *ap)
 {
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 tmp;
 
        tmp = readl(port_mmio + PORT_CMD);
@@ -545,19 +623,23 @@ static int ahci_stop_engine(void __iomem *port_mmio)
        return 0;
 }
 
-static void ahci_start_fis_rx(void __iomem *port_mmio, u32 cap,
-                             dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
+static void ahci_start_fis_rx(struct ata_port *ap)
 {
+       void __iomem *port_mmio = ahci_port_base(ap);
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+       struct ahci_port_priv *pp = ap->private_data;
        u32 tmp;
 
        /* set FIS registers */
-       if (cap & HOST_CAP_64)
-               writel((cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI);
-       writel(cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
+       if (hpriv->cap & HOST_CAP_64)
+               writel((pp->cmd_slot_dma >> 16) >> 16,
+                      port_mmio + PORT_LST_ADDR_HI);
+       writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
 
-       if (cap & HOST_CAP_64)
-               writel((rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI);
-       writel(rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
+       if (hpriv->cap & HOST_CAP_64)
+               writel((pp->rx_fis_dma >> 16) >> 16,
+                      port_mmio + PORT_FIS_ADDR_HI);
+       writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
 
        /* enable FIS reception */
        tmp = readl(port_mmio + PORT_CMD);
@@ -568,8 +650,9 @@ static void ahci_start_fis_rx(void __iomem *port_mmio, u32 cap,
        readl(port_mmio + PORT_CMD);
 }
 
-static int ahci_stop_fis_rx(void __iomem *port_mmio)
+static int ahci_stop_fis_rx(struct ata_port *ap)
 {
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 tmp;
 
        /* disable FIS reception */
@@ -586,14 +669,16 @@ static int ahci_stop_fis_rx(void __iomem *port_mmio)
        return 0;
 }
 
-static void ahci_power_up(void __iomem *port_mmio, u32 cap)
+static void ahci_power_up(struct ata_port *ap)
 {
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 cmd;
 
        cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK;
 
        /* spin up device */
-       if (cap & HOST_CAP_SSS) {
+       if (hpriv->cap & HOST_CAP_SSS) {
                cmd |= PORT_CMD_SPIN_UP;
                writel(cmd, port_mmio + PORT_CMD);
        }
@@ -603,11 +688,13 @@ static void ahci_power_up(void __iomem *port_mmio, u32 cap)
 }
 
 #ifdef CONFIG_PM
-static void ahci_power_down(void __iomem *port_mmio, u32 cap)
+static void ahci_power_down(struct ata_port *ap)
 {
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 cmd, scontrol;
 
-       if (!(cap & HOST_CAP_SSS))
+       if (!(hpriv->cap & HOST_CAP_SSS))
                return;
 
        /* put device into listen mode, first set PxSCTL.DET to 0 */
@@ -622,29 +709,28 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap)
 }
 #endif
 
-static void ahci_init_port(void __iomem *port_mmio, u32 cap,
-                          dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
+static void ahci_init_port(struct ata_port *ap)
 {
        /* enable FIS reception */
-       ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma);
+       ahci_start_fis_rx(ap);
 
        /* enable DMA */
-       ahci_start_engine(port_mmio);
+       ahci_start_engine(ap);
 }
 
-static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg)
+static int ahci_deinit_port(struct ata_port *ap, const char **emsg)
 {
        int rc;
 
        /* disable DMA */
-       rc = ahci_stop_engine(port_mmio);
+       rc = ahci_stop_engine(ap);
        if (rc) {
                *emsg = "failed to stop engine";
                return rc;
        }
 
        /* disable FIS reception */
-       rc = ahci_stop_fis_rx(port_mmio);
+       rc = ahci_stop_fis_rx(ap);
        if (rc) {
                *emsg = "failed stop FIS RX";
                return rc;
@@ -653,12 +739,11 @@ static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg)
        return 0;
 }
 
-static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
+static int ahci_reset_controller(struct ata_host *host)
 {
-       u32 cap_save, impl_save, tmp;
-
-       cap_save = readl(mmio + HOST_CAP);
-       impl_save = readl(mmio + HOST_PORTS_IMPL);
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
+       u32 tmp;
 
        /* global controller reset */
        tmp = readl(mmio + HOST_CTL);
@@ -674,7 +759,7 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
 
        tmp = readl(mmio + HOST_CTL);
        if (tmp & HOST_RESET) {
-               dev_printk(KERN_ERR, &pdev->dev,
+               dev_printk(KERN_ERR, host->dev,
                           "controller reset failed (0x%x)\n", tmp);
                return -EIO;
        }
@@ -683,18 +768,8 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
        writel(HOST_AHCI_EN, mmio + HOST_CTL);
        (void) readl(mmio + HOST_CTL);  /* flush */
 
-       /* These write-once registers are normally cleared on reset.
-        * Restore BIOS values... which we HOPE were present before
-        * reset.
-        */
-       if (!impl_save) {
-               impl_save = (1 << ahci_nr_ports(cap_save)) - 1;
-               dev_printk(KERN_WARNING, &pdev->dev,
-                          "PORTS_IMPL is zero, forcing 0x%x\n", impl_save);
-       }
-       writel(cap_save, mmio + HOST_CAP);
-       writel(impl_save, mmio + HOST_PORTS_IMPL);
-       (void) readl(mmio + HOST_PORTS_IMPL);   /* flush */
+       /* some registers might be cleared on reset.  restore initial values */
+       ahci_restore_initial_config(host);
 
        if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
                u16 tmp16;
@@ -708,23 +783,23 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
        return 0;
 }
 
-static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
-                                int n_ports, unsigned int port_flags,
-                                struct ahci_host_priv *hpriv)
+static void ahci_init_controller(struct ata_host *host)
 {
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
        int i, rc;
        u32 tmp;
 
-       for (i = 0; i < n_ports; i++) {
-               void __iomem *port_mmio = ahci_port_base(mmio, i);
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+               void __iomem *port_mmio = ahci_port_base(ap);
                const char *emsg = NULL;
 
-               if ((port_flags & AHCI_FLAG_HONOR_PI) &&
-                   !(hpriv->port_map & (1 << i)))
+               if (ata_port_is_dummy(ap))
                        continue;
 
                /* make sure port is not active */
-               rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
+               rc = ahci_deinit_port(ap, &emsg);
                if (rc)
                        dev_printk(KERN_WARNING, &pdev->dev,
                                   "%s (%d)\n", emsg, rc);
@@ -752,7 +827,7 @@ static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
 
 static unsigned int ahci_dev_classify(struct ata_port *ap)
 {
-       void __iomem *port_mmio = ap->ioaddr.cmd_addr;
+       void __iomem *port_mmio = ahci_port_base(ap);
        struct ata_taskfile tf;
        u32 tmp;
 
@@ -802,8 +877,7 @@ static int ahci_clo(struct ata_port *ap)
 static int ahci_softreset(struct ata_port *ap, unsigned int *class)
 {
        struct ahci_port_priv *pp = ap->private_data;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+       void __iomem *port_mmio = ahci_port_base(ap);
        const u32 cmd_fis_len = 5; /* five dwords */
        const char *reason = NULL;
        struct ata_taskfile tf;
@@ -820,7 +894,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
        }
 
        /* prepare for SRST (AHCI-1.1 10.4.1) */
-       rc = ahci_stop_engine(port_mmio);
+       rc = ahci_stop_engine(ap);
        if (rc) {
                reason = "failed to stop engine";
                goto fail_restart;
@@ -840,7 +914,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
        }
 
        /* restart engine */
-       ahci_start_engine(port_mmio);
+       ahci_start_engine(ap);
 
        ata_tf_init(ap->device, &tf);
        fis = pp->cmd_tbl;
@@ -899,7 +973,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
        return 0;
 
  fail_restart:
-       ahci_start_engine(port_mmio);
+       ahci_start_engine(ap);
  fail:
        ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason);
        return rc;
@@ -910,13 +984,11 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
        struct ahci_port_priv *pp = ap->private_data;
        u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
        struct ata_taskfile tf;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
        int rc;
 
        DPRINTK("ENTER\n");
 
-       ahci_stop_engine(port_mmio);
+       ahci_stop_engine(ap);
 
        /* clear D2H reception area to properly wait for D2H FIS */
        ata_tf_init(ap->device, &tf);
@@ -925,7 +997,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
 
        rc = sata_std_hardreset(ap, class);
 
-       ahci_start_engine(port_mmio);
+       ahci_start_engine(ap);
 
        if (rc == 0 && ata_port_online(ap))
                *class = ahci_dev_classify(ap);
@@ -938,20 +1010,18 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
 
 static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
 {
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
        int rc;
 
        DPRINTK("ENTER\n");
 
-       ahci_stop_engine(port_mmio);
+       ahci_stop_engine(ap);
 
        rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context));
 
        /* vt8251 needs SError cleared for the port to operate */
        ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR));
 
-       ahci_start_engine(port_mmio);
+       ahci_start_engine(ap);
 
        DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
 
@@ -963,7 +1033,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
 
 static void ahci_postreset(struct ata_port *ap, unsigned int *class)
 {
-       void __iomem *port_mmio = ap->ioaddr.cmd_addr;
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 new_tmp, tmp;
 
        ata_std_postreset(ap, class);
@@ -1131,8 +1201,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
 
 static void ahci_host_intr(struct ata_port *ap)
 {
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+       void __iomem *port_mmio = ap->ioaddr.cmd_addr;
        struct ata_eh_info *ehi = &ap->eh_info;
        struct ahci_port_priv *pp = ap->private_data;
        u32 status, qc_active;
@@ -1283,7 +1352,7 @@ static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
 static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
-       void __iomem *port_mmio = ap->ioaddr.cmd_addr;
+       void __iomem *port_mmio = ahci_port_base(ap);
 
        if (qc->tf.protocol == ATA_PROT_NCQ)
                writel(1 << qc->tag, port_mmio + PORT_SCR_ACT);
@@ -1295,8 +1364,7 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
 
 static void ahci_freeze(struct ata_port *ap)
 {
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+       void __iomem *port_mmio = ahci_port_base(ap);
 
        /* turn IRQ off */
        writel(0, port_mmio + PORT_IRQ_MASK);
@@ -1305,7 +1373,7 @@ static void ahci_freeze(struct ata_port *ap)
 static void ahci_thaw(struct ata_port *ap)
 {
        void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
+       void __iomem *port_mmio = ahci_port_base(ap);
        u32 tmp;
 
        /* clear IRQ */
@@ -1319,13 +1387,10 @@ static void ahci_thaw(struct ata_port *ap)
 
 static void ahci_error_handler(struct ata_port *ap)
 {
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
-
        if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
                /* restart engine */
-               ahci_stop_engine(port_mmio);
-               ahci_start_engine(port_mmio);
+               ahci_stop_engine(ap);
+               ahci_start_engine(ap);
        }
 
        /* perform recovery */
@@ -1335,13 +1400,10 @@ static void ahci_error_handler(struct ata_port *ap)
 
 static void ahci_vt8251_error_handler(struct ata_port *ap)
 {
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
-
        if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
                /* restart engine */
-               ahci_stop_engine(port_mmio);
-               ahci_start_engine(port_mmio);
+               ahci_stop_engine(ap);
+               ahci_start_engine(ap);
        }
 
        /* perform recovery */
@@ -1352,36 +1414,26 @@ static void ahci_vt8251_error_handler(struct ata_port *ap)
 static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
 
-       if (qc->flags & ATA_QCFLAG_FAILED)
-               qc->err_mask |= AC_ERR_OTHER;
-
-       if (qc->err_mask) {
+       if (qc->flags & ATA_QCFLAG_FAILED) {
                /* make DMA engine forget about the failed command */
-               ahci_stop_engine(port_mmio);
-               ahci_start_engine(port_mmio);
+               ahci_stop_engine(ap);
+               ahci_start_engine(ap);
        }
 }
 
 #ifdef CONFIG_PM
 static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
 {
-       struct ahci_host_priv *hpriv = ap->host->private_data;
-       struct ahci_port_priv *pp = ap->private_data;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
        const char *emsg = NULL;
        int rc;
 
-       rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
+       rc = ahci_deinit_port(ap, &emsg);
        if (rc == 0)
-               ahci_power_down(port_mmio, hpriv->cap);
+               ahci_power_down(ap);
        else {
                ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc);
-               ahci_init_port(port_mmio, hpriv->cap,
-                              pp->cmd_slot_dma, pp->rx_fis_dma);
+               ahci_init_port(ap);
        }
 
        return rc;
@@ -1389,13 +1441,8 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
 
 static int ahci_port_resume(struct ata_port *ap)
 {
-       struct ahci_port_priv *pp = ap->private_data;
-       struct ahci_host_priv *hpriv = ap->host->private_data;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
-
-       ahci_power_up(port_mmio, hpriv->cap);
-       ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
+       ahci_power_up(ap);
+       ahci_init_port(ap);
 
        return 0;
 }
@@ -1423,8 +1470,6 @@ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
 static int ahci_pci_device_resume(struct pci_dev *pdev)
 {
        struct ata_host *host = dev_get_drvdata(&pdev->dev);
-       struct ahci_host_priv *hpriv = host->private_data;
-       void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
        int rc;
 
        rc = ata_pci_device_do_resume(pdev);
@@ -1432,12 +1477,11 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
                return rc;
 
        if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
-               rc = ahci_reset_controller(mmio, pdev);
+               rc = ahci_reset_controller(host);
                if (rc)
                        return rc;
 
-               ahci_init_controller(mmio, pdev, host->n_ports,
-                                    host->ports[0]->flags, hpriv);
+               ahci_init_controller(host);
        }
 
        ata_host_resume(host);
@@ -1449,10 +1493,7 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
 static int ahci_port_start(struct ata_port *ap)
 {
        struct device *dev = ap->host->dev;
-       struct ahci_host_priv *hpriv = ap->host->private_data;
        struct ahci_port_priv *pp;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
        void *mem;
        dma_addr_t mem_dma;
        int rc;
@@ -1500,85 +1541,29 @@ static int ahci_port_start(struct ata_port *ap)
        ap->private_data = pp;
 
        /* power up port */
-       ahci_power_up(port_mmio, hpriv->cap);
+       ahci_power_up(ap);
 
        /* initialize port */
-       ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
+       ahci_init_port(ap);
 
        return 0;
 }
 
 static void ahci_port_stop(struct ata_port *ap)
 {
-       struct ahci_host_priv *hpriv = ap->host->private_data;
-       void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
-       void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
        const char *emsg = NULL;
        int rc;
 
        /* de-initialize port */
-       rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
+       rc = ahci_deinit_port(ap, &emsg);
        if (rc)
                ata_port_printk(ap, KERN_WARNING, "%s (%d)\n", emsg, rc);
 }
 
-static void ahci_setup_port(struct ata_ioports *port, void __iomem *base,
-                           unsigned int port_idx)
+static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
 {
-       VPRINTK("ENTER, base==0x%lx, port_idx %u\n", base, port_idx);
-       base = ahci_port_base(base, port_idx);
-       VPRINTK("base now==0x%lx\n", base);
-
-       port->cmd_addr          = base;
-       port->scr_addr          = base + PORT_SCR;
-
-       VPRINTK("EXIT\n");
-}
-
-static int ahci_host_init(struct ata_probe_ent *probe_ent)
-{
-       struct ahci_host_priv *hpriv = probe_ent->private_data;
-       struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
-       void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
-       unsigned int i, cap_n_ports, using_dac;
        int rc;
 
-       rc = ahci_reset_controller(mmio, pdev);
-       if (rc)
-               return rc;
-
-       hpriv->cap = readl(mmio + HOST_CAP);
-       hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
-       cap_n_ports = ahci_nr_ports(hpriv->cap);
-
-       VPRINTK("cap 0x%x  port_map 0x%x  n_ports %d\n",
-               hpriv->cap, hpriv->port_map, cap_n_ports);
-
-       if (probe_ent->port_flags & AHCI_FLAG_HONOR_PI) {
-               unsigned int n_ports = cap_n_ports;
-               u32 port_map = hpriv->port_map;
-               int max_port = 0;
-
-               for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) {
-                       if (port_map & (1 << i)) {
-                               n_ports--;
-                               port_map &= ~(1 << i);
-                               max_port = i;
-                       } else
-                               probe_ent->dummy_port_mask |= 1 << i;
-               }
-
-               if (n_ports || port_map)
-                       dev_printk(KERN_WARNING, &pdev->dev,
-                                  "nr_ports (%u) and implemented port map "
-                                  "(0x%x) don't match\n",
-                                  cap_n_ports, hpriv->port_map);
-
-               probe_ent->n_ports = max_port + 1;
-       } else
-               probe_ent->n_ports = cap_n_ports;
-
-       using_dac = hpriv->cap & HOST_CAP_64;
        if (using_dac &&
            !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
                rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
@@ -1604,23 +1589,14 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
                        return rc;
                }
        }
-
-       for (i = 0; i < probe_ent->n_ports; i++)
-               ahci_setup_port(&probe_ent->port[i], mmio, i);
-
-       ahci_init_controller(mmio, pdev, probe_ent->n_ports,
-                            probe_ent->port_flags, hpriv);
-
-       pci_set_master(pdev);
-
        return 0;
 }
 
-static void ahci_print_info(struct ata_probe_ent *probe_ent)
+static void ahci_print_info(struct ata_host *host)
 {
-       struct ahci_host_priv *hpriv = probe_ent->private_data;
-       struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
-       void __iomem *mmio = probe_ent->iomap[AHCI_PCI_BAR];
+       struct ahci_host_priv *hpriv = host->private_data;
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
        u32 vers, cap, impl, speed;
        const char *speed_s;
        u16 cc;
@@ -1690,11 +1666,12 @@ static void ahci_print_info(struct ata_probe_ent *probe_ent)
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       unsigned int board_idx = (unsigned int) ent->driver_data;
+       struct ata_port_info pi = ahci_port_info[ent->driver_data];
+       const struct ata_port_info *ppi[] = { &pi, NULL };
        struct device *dev = &pdev->dev;
-       struct ata_probe_ent *probe_ent;
        struct ahci_host_priv *hpriv;
-       int rc;
+       struct ata_host *host;
+       int i, rc;
 
        VPRINTK("ENTER\n");
 
@@ -1703,6 +1680,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* acquire resources */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
@@ -1716,44 +1694,49 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (pci_enable_msi(pdev))
                pci_intx(pdev, 1);
 
-       probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
-
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
        hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
        if (!hpriv)
                return -ENOMEM;
 
-       probe_ent->sht          = ahci_port_info[board_idx].sht;
-       probe_ent->port_flags   = ahci_port_info[board_idx].flags;
-       probe_ent->pio_mask     = ahci_port_info[board_idx].pio_mask;
-       probe_ent->udma_mask    = ahci_port_info[board_idx].udma_mask;
-       probe_ent->port_ops     = ahci_port_info[board_idx].port_ops;
+       /* save initial config */
+       ahci_save_initial_config(pdev, &pi, hpriv);
 
-               probe_ent->irq = pdev->irq;
-               probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->iomap = pcim_iomap_table(pdev);
-       probe_ent->private_data = hpriv;
+       /* prepare host */
+       if (!(pi.flags & AHCI_FLAG_NO_NCQ) && (hpriv->cap & HOST_CAP_NCQ))
+               pi.flags |= ATA_FLAG_NCQ;
+
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, fls(hpriv->port_map));
+       if (!host)
+               return -ENOMEM;
+       host->iomap = pcim_iomap_table(pdev);
+       host->private_data = hpriv;
+
+       for (i = 0; i < host->n_ports; i++) {
+               if (hpriv->port_map & (1 << i)) {
+                       struct ata_port *ap = host->ports[i];
+                       void __iomem *port_mmio = ahci_port_base(ap);
+
+                       ap->ioaddr.cmd_addr = port_mmio;
+                       ap->ioaddr.scr_addr = port_mmio + PORT_SCR;
+               } else
+                       host->ports[i]->ops = &ata_dummy_port_ops;
+       }
 
        /* initialize adapter */
-       rc = ahci_host_init(probe_ent);
+       rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
        if (rc)
                return rc;
 
-       if (!(probe_ent->port_flags & AHCI_FLAG_NO_NCQ) &&
-           (hpriv->cap & HOST_CAP_NCQ))
-               probe_ent->port_flags |= ATA_FLAG_NCQ;
-
-       ahci_print_info(probe_ent);
+       rc = ahci_reset_controller(host);
+       if (rc)
+               return rc;
 
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
+       ahci_init_controller(host);
+       ahci_print_info(host);
 
-       devm_kfree(dev, probe_ent);
-       return 0;
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED,
+                                &ahci_sht);
 }
 
 static int __init ahci_init(void)
index d8e79882b8809a97df8eff73efd87f9e228d1bc7..92a491ddd03055555c2926ecf16f23c6a4526749 100644 (file)
  *     A generic parallel ATA driver using libata
  */
 
-/**
- *     generic_pre_reset               -       probe begin
- *     @ap: ATA port
- *
- *     Set up cable type and use generic probe init
- */
-
-static int generic_pre_reset(struct ata_port *ap)
-{
-       ap->cbl = ATA_CBL_PATA80;
-       return ata_std_prereset(ap);
-}
-
-
-/**
- *     generic_error_handler - Probe specified port on PATA host controller
- *     @ap: Port to probe
- *     @classes:
- *
- *     LOCKING:
- *     None (inherited from caller).
- */
-
-
-static void generic_error_handler(struct ata_port *ap)
-{
-       ata_bmdma_drive_eh(ap, generic_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
 /**
  *     generic_set_mode        -       mode setting
  *     @ap: interface to set up
@@ -144,8 +115,9 @@ static struct ata_port_operations generic_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = generic_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_unknown,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
index b952c584338fb4fe3f797435a1f720c8b6070ef4..55d306a3e5386e779e12d040a9156040d93a5c69 100644 (file)
@@ -93,7 +93,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "ata_piix"
-#define DRV_VERSION    "2.10ac1"
+#define DRV_VERSION    "2.11"
 
 enum {
        PIIX_IOCFG              = 0x54, /* IDE I/O configuration register */
@@ -155,11 +155,11 @@ struct piix_host_priv {
 static int piix_init_one (struct pci_dev *pdev,
                                    const struct pci_device_id *ent);
 static void piix_pata_error_handler(struct ata_port *ap);
-static void ich_pata_error_handler(struct ata_port *ap);
 static void piix_sata_error_handler(struct ata_port *ap);
 static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev);
 static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev);
 static void ich_set_dmamode (struct ata_port *ap, struct ata_device *adev);
+static int ich_pata_cable_detect(struct ata_port *ap);
 
 static unsigned int in_module_init = 1;
 
@@ -305,6 +305,7 @@ static const struct ata_port_operations piix_pata_ops = {
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = piix_pata_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = ata_cable_40wire,
 
        .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
@@ -336,8 +337,9 @@ static const struct ata_port_operations ich_pata_ops = {
 
        .freeze                 = ata_bmdma_freeze,
        .thaw                   = ata_bmdma_thaw,
-       .error_handler          = ich_pata_error_handler,
+       .error_handler          = piix_pata_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = ich_pata_cable_detect,
 
        .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
@@ -580,12 +582,13 @@ static const struct ich_laptop ich_laptop[] = {
        /* devid, subvendor, subdev */
        { 0x27DF, 0x0005, 0x0280 },     /* ICH7 on Acer 5602WLMi */
        { 0x27DF, 0x1025, 0x0110 },     /* ICH7 on Acer 3682WLMi */
+       { 0x27DF, 0x1043, 0x1267 },     /* ICH7 on Asus W5F */
        /* end marker */
        { 0, }
 };
 
 /**
- *     piix_pata_cbl_detect - Probe host controller cable detect info
+ *     ich_pata_cable_detect - Probe host controller cable detect info
  *     @ap: Port for which cable detect info is desired
  *
  *     Read 80c cable indicator from ATA PCI device's PCI config
@@ -595,23 +598,18 @@ static const struct ich_laptop ich_laptop[] = {
  *     None (inherited from caller).
  */
 
-static void ich_pata_cbl_detect(struct ata_port *ap)
+static int ich_pata_cable_detect(struct ata_port *ap)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        const struct ich_laptop *lap = &ich_laptop[0];
        u8 tmp, mask;
 
-       /* no 80c support in host controller? */
-       if ((ap->udma_mask & ~ATA_UDMA_MASK_40C) == 0)
-               goto cbl40;
-
        /* Check for specials - Acer Aspire 5602WLMi */
        while (lap->device) {
                if (lap->device == pdev->device &&
                    lap->subvendor == pdev->subsystem_vendor &&
                    lap->subdevice == pdev->subsystem_device) {
-                       ap->cbl = ATA_CBL_PATA40_SHORT;
-                       return;
+                       return ATA_CBL_PATA40_SHORT;
                }
                lap++;
        }
@@ -620,20 +618,14 @@ static void ich_pata_cbl_detect(struct ata_port *ap)
        mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
        pci_read_config_byte(pdev, PIIX_IOCFG, &tmp);
        if ((tmp & mask) == 0)
-               goto cbl40;
-
-       ap->cbl = ATA_CBL_PATA80;
-       return;
-
-cbl40:
-       ap->cbl = ATA_CBL_PATA40;
+               return ATA_CBL_PATA40;
+       return ATA_CBL_PATA80;
 }
 
 /**
  *     piix_pata_prereset - prereset for PATA host controller
  *     @ap: Target port
  *
- *
  *     LOCKING:
  *     None (inherited from caller).
  */
@@ -643,8 +635,6 @@ static int piix_pata_prereset(struct ata_port *ap)
 
        if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
                return -ENOENT;
-
-       ap->cbl = ATA_CBL_PATA40;
        return ata_std_prereset(ap);
 }
 
@@ -655,30 +645,6 @@ static void piix_pata_error_handler(struct ata_port *ap)
 }
 
 
-/**
- *     ich_pata_prereset - prereset for PATA host controller
- *     @ap: Target port
- *
- *
- *     LOCKING:
- *     None (inherited from caller).
- */
-static int ich_pata_prereset(struct ata_port *ap)
-{
-       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-
-       if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
-               return -ENOENT;
-       ich_pata_cbl_detect(ap);
-       return ata_std_prereset(ap);
-}
-
-static void ich_pata_error_handler(struct ata_port *ap)
-{
-       ata_bmdma_drive_eh(ap, ich_pata_prereset, ata_std_softreset, NULL,
-                          ata_std_postreset);
-}
-
 static void piix_sata_error_handler(struct ata_port *ap)
 {
        ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
index 0abd72d0dec215bb2fa529c4c84b3c8abfe81646..ca67484af1ebe2259164f5b3531d6ee8056ac89f 100644 (file)
@@ -72,7 +72,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
 static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
 static void ata_dev_xfermask(struct ata_device *dev);
 
-static unsigned int ata_print_id = 1;
+unsigned int ata_print_id = 1;
 static struct workqueue_struct *ata_wq;
 
 struct workqueue_struct *ata_aux_wq;
@@ -89,6 +89,10 @@ int libata_fua = 0;
 module_param_named(fua, libata_fua, int, 0444);
 MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)");
 
+static int ata_ignore_hpa = 0;
+module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644);
+MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk)");
+
 static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ;
 module_param(ata_probe_timeout, int, 0444);
 MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)");
@@ -808,6 +812,205 @@ void ata_id_c_string(const u16 *id, unsigned char *s,
        *p = '\0';
 }
 
+static u64 ata_tf_to_lba48(struct ata_taskfile *tf)
+{
+       u64 sectors = 0;
+
+       sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40;
+       sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32;
+       sectors |= (tf->hob_lbal & 0xff) << 24;
+       sectors |= (tf->lbah & 0xff) << 16;
+       sectors |= (tf->lbam & 0xff) << 8;
+       sectors |= (tf->lbal & 0xff);
+
+       return ++sectors;
+}
+
+static u64 ata_tf_to_lba(struct ata_taskfile *tf)
+{
+       u64 sectors = 0;
+
+       sectors |= (tf->device & 0x0f) << 24;
+       sectors |= (tf->lbah & 0xff) << 16;
+       sectors |= (tf->lbam & 0xff) << 8;
+       sectors |= (tf->lbal & 0xff);
+
+       return ++sectors;
+}
+
+/**
+ *     ata_read_native_max_address_ext -       LBA48 native max query
+ *     @dev: Device to query
+ *
+ *     Perform an LBA48 size query upon the device in question. Return the
+ *     actual LBA48 size or zero if the command fails.
+ */
+
+static u64 ata_read_native_max_address_ext(struct ata_device *dev)
+{
+       unsigned int err;
+       struct ata_taskfile tf;
+
+       ata_tf_init(dev, &tf);
+
+       tf.command = ATA_CMD_READ_NATIVE_MAX_EXT;
+       tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
+       tf.protocol |= ATA_PROT_NODATA;
+       tf.device |= 0x40;
+
+       err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+       if (err)
+               return 0;
+
+       return ata_tf_to_lba48(&tf);
+}
+
+/**
+ *     ata_read_native_max_address     -       LBA28 native max query
+ *     @dev: Device to query
+ *
+ *     Performa an LBA28 size query upon the device in question. Return the
+ *     actual LBA28 size or zero if the command fails.
+ */
+
+static u64 ata_read_native_max_address(struct ata_device *dev)
+{
+       unsigned int err;
+       struct ata_taskfile tf;
+
+       ata_tf_init(dev, &tf);
+
+       tf.command = ATA_CMD_READ_NATIVE_MAX;
+       tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
+       tf.protocol |= ATA_PROT_NODATA;
+       tf.device |= 0x40;
+
+       err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+       if (err)
+               return 0;
+
+       return ata_tf_to_lba(&tf);
+}
+
+/**
+ *     ata_set_native_max_address_ext  -       LBA48 native max set
+ *     @dev: Device to query
+ *
+ *     Perform an LBA48 size set max upon the device in question. Return the
+ *     actual LBA48 size or zero if the command fails.
+ */
+
+static u64 ata_set_native_max_address_ext(struct ata_device *dev, u64 new_sectors)
+{
+       unsigned int err;
+       struct ata_taskfile tf;
+
+       new_sectors--;
+
+       ata_tf_init(dev, &tf);
+
+       tf.command = ATA_CMD_SET_MAX_EXT;
+       tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
+       tf.protocol |= ATA_PROT_NODATA;
+       tf.device |= 0x40;
+
+       tf.lbal = (new_sectors >> 0) & 0xff;
+       tf.lbam = (new_sectors >> 8) & 0xff;
+       tf.lbah = (new_sectors >> 16) & 0xff;
+
+       tf.hob_lbal = (new_sectors >> 24) & 0xff;
+       tf.hob_lbam = (new_sectors >> 32) & 0xff;
+       tf.hob_lbah = (new_sectors >> 40) & 0xff;
+
+       err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+       if (err)
+               return 0;
+
+       return ata_tf_to_lba48(&tf);
+}
+
+/**
+ *     ata_set_native_max_address      -       LBA28 native max set
+ *     @dev: Device to query
+ *
+ *     Perform an LBA28 size set max upon the device in question. Return the
+ *     actual LBA28 size or zero if the command fails.
+ */
+
+static u64 ata_set_native_max_address(struct ata_device *dev, u64 new_sectors)
+{
+       unsigned int err;
+       struct ata_taskfile tf;
+
+       new_sectors--;
+
+       ata_tf_init(dev, &tf);
+
+       tf.command = ATA_CMD_SET_MAX;
+       tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
+       tf.protocol |= ATA_PROT_NODATA;
+
+       tf.lbal = (new_sectors >> 0) & 0xff;
+       tf.lbam = (new_sectors >> 8) & 0xff;
+       tf.lbah = (new_sectors >> 16) & 0xff;
+       tf.device |= ((new_sectors >> 24) & 0x0f) | 0x40;
+
+       err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+       if (err)
+               return 0;
+
+       return ata_tf_to_lba(&tf);
+}
+
+/**
+ *     ata_hpa_resize          -       Resize a device with an HPA set
+ *     @dev: Device to resize
+ *
+ *     Read the size of an LBA28 or LBA48 disk with HPA features and resize
+ *     it if required to the full size of the media. The caller must check
+ *     the drive has the HPA feature set enabled.
+ */
+
+static u64 ata_hpa_resize(struct ata_device *dev)
+{
+       u64 sectors = dev->n_sectors;
+       u64 hpa_sectors;
+       
+       if (ata_id_has_lba48(dev->id))
+               hpa_sectors = ata_read_native_max_address_ext(dev);
+       else
+               hpa_sectors = ata_read_native_max_address(dev);
+
+       /* if no hpa, both should be equal */
+       ata_dev_printk(dev, KERN_INFO, "%s 1: sectors = %lld, "
+                               "hpa_sectors = %lld\n",
+               __FUNCTION__, (long long)sectors, (long long)hpa_sectors);
+
+       if (hpa_sectors > sectors) {
+               ata_dev_printk(dev, KERN_INFO,
+                       "Host Protected Area detected:\n"
+                       "\tcurrent size: %lld sectors\n"
+                       "\tnative size: %lld sectors\n",
+                       (long long)sectors, (long long)hpa_sectors);
+
+               if (ata_ignore_hpa) {
+                       if (ata_id_has_lba48(dev->id))
+                               hpa_sectors = ata_set_native_max_address_ext(dev, hpa_sectors);
+                       else
+                               hpa_sectors = ata_set_native_max_address(dev,
+                                                               hpa_sectors);
+
+                       if (hpa_sectors) {
+                               ata_dev_printk(dev, KERN_INFO, "native size "
+                                       "increased to %lld sectors\n",
+                                       (long long)hpa_sectors);
+                               return hpa_sectors;
+                       }
+               }
+       }
+       return sectors;
+}
+
 static u64 ata_id_n_sectors(const u16 *id)
 {
        if (ata_id_has_lba(id)) {
@@ -1270,12 +1473,16 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
        if (ap->ops->post_internal_cmd)
                ap->ops->post_internal_cmd(qc);
 
-       if ((qc->flags & ATA_QCFLAG_FAILED) && !qc->err_mask) {
-               if (ata_msg_warn(ap))
-                       ata_dev_printk(dev, KERN_WARNING,
-                               "zero err_mask for failed "
-                               "internal command, assuming AC_ERR_OTHER\n");
-               qc->err_mask |= AC_ERR_OTHER;
+       /* perform minimal error analysis */
+       if (qc->flags & ATA_QCFLAG_FAILED) {
+               if (qc->result_tf.command & (ATA_ERR | ATA_DF))
+                       qc->err_mask |= AC_ERR_DEV;
+
+               if (!qc->err_mask)
+                       qc->err_mask |= AC_ERR_OTHER;
+
+               if (qc->err_mask & ~AC_ERR_OTHER)
+                       qc->err_mask &= ~AC_ERR_OTHER;
        }
 
        /* finish up */
@@ -1379,30 +1586,44 @@ unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd)
  *     Check if the current speed of the device requires IORDY. Used
  *     by various controllers for chip configuration.
  */
-
 unsigned int ata_pio_need_iordy(const struct ata_device *adev)
 {
-       int pio;
-       int speed = adev->pio_mode - XFER_PIO_0;
-
-       if (speed < 2)
+       /* Controller doesn't support  IORDY. Probably a pointless check
+          as the caller should know this */
+       if (adev->ap->flags & ATA_FLAG_NO_IORDY)
                return 0;
-       if (speed > 2)
+       /* PIO3 and higher it is mandatory */
+       if (adev->pio_mode > XFER_PIO_2)
+               return 1;
+       /* We turn it on when possible */
+       if (ata_id_has_iordy(adev->id))
                return 1;
+       return 0;
+}
 
+/**
+ *     ata_pio_mask_no_iordy   -       Return the non IORDY mask
+ *     @adev: ATA device
+ *
+ *     Compute the highest mode possible if we are not using iordy. Return
+ *     -1 if no iordy mode is available.
+ */
+static u32 ata_pio_mask_no_iordy(const struct ata_device *adev)
+{
        /* If we have no drive specific rule, then PIO 2 is non IORDY */
-
        if (adev->id[ATA_ID_FIELD_VALID] & 2) { /* EIDE */
-               pio = adev->id[ATA_ID_EIDE_PIO];
+               u16 pio = adev->id[ATA_ID_EIDE_PIO];
                /* Is the speed faster than the drive allows non IORDY ? */
                if (pio) {
                        /* This is cycle times not frequency - watch the logic! */
                        if (pio > 240)  /* PIO2 is 240nS per cycle */
-                               return 1;
-                       return 0;
+                               return 3 << ATA_SHIFT_PIO;
+                       return 7 << ATA_SHIFT_PIO;
                }
        }
-       return 0;
+       return 3 << ATA_SHIFT_PIO;
 }
 
 /**
@@ -1431,13 +1652,13 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
        struct ata_taskfile tf;
        unsigned int err_mask = 0;
        const char *reason;
+       int tried_spinup = 0;
        int rc;
 
        if (ata_msg_ctl(ap))
                ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __FUNCTION__);
 
        ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
-
  retry:
        ata_tf_init(dev, &tf);
 
@@ -1494,6 +1715,32 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
                        goto err_out;
        }
 
+       if (!tried_spinup && (id[2] == 0x37c8 || id[2] == 0x738c)) {
+               tried_spinup = 1;
+               /*
+                * Drive powered-up in standby mode, and requires a specific
+                * SET_FEATURES spin-up subcommand before it will accept
+                * anything other than the original IDENTIFY command.
+                */
+               ata_tf_init(dev, &tf);
+               tf.command = ATA_CMD_SET_FEATURES;
+               tf.feature = SETFEATURES_SPINUP;
+               tf.protocol = ATA_PROT_NODATA;
+               tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+               err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+               if (err_mask) {
+                       rc = -EIO;
+                       reason = "SPINUP failed";
+                       goto err_out;
+               }
+               /*
+                * If the drive initially returned incomplete IDENTIFY info,
+                * we now must reissue the IDENTIFY command.
+                */
+               if (id[2] == 0x37c8)
+                       goto retry;
+       }
+
        if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) {
                /*
                 * The exact sequence expected by certain pre-ATA4 drives is:
@@ -1560,20 +1807,6 @@ static void ata_dev_config_ncq(struct ata_device *dev,
                snprintf(desc, desc_sz, "NCQ (depth %d/%d)", hdepth, ddepth);
 }
 
-static void ata_set_port_max_cmd_len(struct ata_port *ap)
-{
-       int i;
-
-       if (ap->scsi_host) {
-               unsigned int len = 0;
-
-               for (i = 0; i < ATA_MAX_DEVICES; i++)
-                       len = max(len, ap->device[i].cdb_len);
-
-               ap->scsi_host->max_cmd_len = len;
-       }
-}
-
 /**
  *     ata_dev_configure - Configure the specified ATA/ATAPI device
  *     @dev: Target device to configure
@@ -1658,6 +1891,7 @@ int ata_dev_configure(struct ata_device *dev)
                        snprintf(revbuf, 7, "ATA-%d",  ata_id_major_version(id));
 
                dev->n_sectors = ata_id_n_sectors(id);
+               dev->n_sectors_boot = dev->n_sectors;
 
                /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
                ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
@@ -1684,6 +1918,9 @@ int ata_dev_configure(struct ata_device *dev)
                                        dev->flags |= ATA_DFLAG_FLUSH_EXT;
                        }
 
+                       if (ata_id_hpa_enabled(dev->id))
+                               dev->n_sectors = ata_hpa_resize(dev);
+
                        /* config NCQ */
                        ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
 
@@ -1773,8 +2010,6 @@ int ata_dev_configure(struct ata_device *dev)
                }
        }
 
-       ata_set_port_max_cmd_len(ap);
-
        /* limit bridge transfers to udma5, 200 sectors */
        if (ata_dev_knobble(dev)) {
                if (ata_msg_drv(ap) && print_info)
@@ -1785,14 +2020,15 @@ int ata_dev_configure(struct ata_device *dev)
        }
 
        if (ata_device_blacklisted(dev) & ATA_HORKAGE_MAX_SEC_128)
-               dev->max_sectors = min(ATA_MAX_SECTORS_128, dev->max_sectors);
+               dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,
+                                        dev->max_sectors);
 
        /* limit ATAPI DMA to R/W commands only */
        if (ata_device_blacklisted(dev) & ATA_HORKAGE_DMA_RW_ONLY)
                dev->horkage |= ATA_HORKAGE_DMA_RW_ONLY;
 
        if (ap->ops->dev_config)
-               ap->ops->dev_config(ap, dev);
+               ap->ops->dev_config(dev);
 
        if (ata_msg_probe(ap))
                ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n",
@@ -1806,6 +2042,56 @@ err_out_nosup:
        return rc;
 }
 
+/**
+ *     ata_cable_40wire        -       return 40 wire cable type
+ *     @ap: port
+ *
+ *     Helper method for drivers which want to hardwire 40 wire cable
+ *     detection.
+ */
+
+int ata_cable_40wire(struct ata_port *ap)
+{
+       return ATA_CBL_PATA40;
+}
+
+/**
+ *     ata_cable_80wire        -       return 80 wire cable type
+ *     @ap: port
+ *
+ *     Helper method for drivers which want to hardwire 80 wire cable
+ *     detection.
+ */
+
+int ata_cable_80wire(struct ata_port *ap)
+{
+       return ATA_CBL_PATA80;
+}
+
+/**
+ *     ata_cable_unknown       -       return unknown PATA cable.
+ *     @ap: port
+ *
+ *     Helper method for drivers which have no PATA cable detection.
+ */
+
+int ata_cable_unknown(struct ata_port *ap)
+{
+       return ATA_CBL_PATA_UNK;
+}
+
+/**
+ *     ata_cable_sata  -       return SATA cable type
+ *     @ap: port
+ *
+ *     Helper method for drivers which have SATA cables
+ */
+
+int ata_cable_sata(struct ata_port *ap)
+{
+       return ATA_CBL_SATA;
+}
+
 /**
  *     ata_bus_probe - Reset and probe ATA bus
  *     @ap: Bus to probe
@@ -1876,6 +2162,10 @@ int ata_bus_probe(struct ata_port *ap)
                        goto fail;
        }
 
+       /* Now ask for the cable type as PDIAG- should have been released */
+       if (ap->ops->cable_detect)
+               ap->cbl = ap->ops->cable_detect(ap);
+
        /* After the identify sequence we can now set up the devices. We do
           this in the normal order so that the user doesn't get confused */
 
@@ -1958,7 +2248,7 @@ void ata_port_probe(struct ata_port *ap)
  *     LOCKING:
  *     None.
  */
-static void sata_print_link_status(struct ata_port *ap)
+void sata_print_link_status(struct ata_port *ap)
 {
        u32 sstatus, scontrol, tmp;
 
@@ -2352,6 +2642,12 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
                t->active += (t->cycle - (t->active + t->recover)) / 2;
                t->recover = t->cycle - t->active;
        }
+       
+       /* In a few cases quantisation may produce enough errors to
+          leave t->cycle too low for the sum of active and recovery
+          if so we must correct this */
+       if (t->active + t->recover > t->cycle)
+               t->cycle = t->active + t->recover;
 
        return 0;
 }
@@ -2481,12 +2777,13 @@ static int ata_dev_set_mode(struct ata_device *dev)
 }
 
 /**
- *     ata_set_mode - Program timings and issue SET FEATURES - XFER
+ *     ata_do_set_mode - Program timings and issue SET FEATURES - XFER
  *     @ap: port on which timings will be programmed
  *     @r_failed_dev: out paramter for failed device
  *
- *     Set ATA device disk transfer mode (PIO3, UDMA6, etc.).  If
- *     ata_set_mode() fails, pointer to the failing device is
+ *     Standard implementation of the function used to tune and set
+ *     ATA device disk transfer mode (PIO3, UDMA6, etc.).  If
+ *     ata_dev_set_mode() fails, pointer to the failing device is
  *     returned in @r_failed_dev.
  *
  *     LOCKING:
@@ -2495,14 +2792,12 @@ static int ata_dev_set_mode(struct ata_device *dev)
  *     RETURNS:
  *     0 on success, negative errno otherwise
  */
-int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
+
+int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
 {
        struct ata_device *dev;
        int i, rc = 0, used_dma = 0, found = 0;
 
-       /* has private set_mode? */
-       if (ap->ops->set_mode)
-               return ap->ops->set_mode(ap, r_failed_dev);
 
        /* step 1: calculate xfer_mask */
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
@@ -2586,6 +2881,29 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
        return rc;
 }
 
+/**
+ *     ata_set_mode - Program timings and issue SET FEATURES - XFER
+ *     @ap: port on which timings will be programmed
+ *     @r_failed_dev: out paramter for failed device
+ *
+ *     Set ATA device disk transfer mode (PIO3, UDMA6, etc.).  If
+ *     ata_set_mode() fails, pointer to the failing device is
+ *     returned in @r_failed_dev.
+ *
+ *     LOCKING:
+ *     PCI/etc. bus probe sem.
+ *
+ *     RETURNS:
+ *     0 on success, negative errno otherwise
+ */
+int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
+{
+       /* has private set_mode? */
+       if (ap->ops->set_mode)
+               return ap->ops->set_mode(ap, r_failed_dev);
+       return ata_do_set_mode(ap, r_failed_dev);
+}
+
 /**
  *     ata_tf_to_host - issue ATA taskfile to host controller
  *     @ap: port to which command is being issued
@@ -3267,6 +3585,11 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
                               "%llu != %llu\n",
                               (unsigned long long)dev->n_sectors,
                               (unsigned long long)new_n_sectors);
+               /* Are we the boot time size - if so we appear to be the
+                  same disk at this point and our HPA got reapplied */
+               if (ata_ignore_hpa && dev->n_sectors_boot == new_n_sectors 
+                   && ata_id_hpa_enabled(new_id))
+                       return 1;
                return 0;
        }
 
@@ -3441,19 +3764,7 @@ static void ata_dev_xfermask(struct ata_device *dev)
        xfer_mask = ata_pack_xfermask(ap->pio_mask,
                                      ap->mwdma_mask, ap->udma_mask);
 
-       /* Apply cable rule here.  Don't apply it early because when
-        * we handle hot plug the cable type can itself change.
-        */
-       if (ap->cbl == ATA_CBL_PATA40)
-               xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
-       /* Apply drive side cable rule. Unknown or 80 pin cables reported
-        * host side are checked drive side as well. Cases where we know a
-        * 40wire cable is used safely for 80 are not checked here.
-        */
-        if (ata_drive_40wire(dev->id) && (ap->cbl == ATA_CBL_PATA_UNK || ap->cbl == ATA_CBL_PATA80))
-               xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
-
-
+       /* drive modes available */
        xfer_mask &= ata_pack_xfermask(dev->pio_mask,
                                       dev->mwdma_mask, dev->udma_mask);
        xfer_mask &= ata_id_xfermask(dev->id);
@@ -3482,8 +3793,30 @@ static void ata_dev_xfermask(struct ata_device *dev)
                               "other device, disabling DMA\n");
        }
 
+       if (ap->flags & ATA_FLAG_NO_IORDY)
+               xfer_mask &= ata_pio_mask_no_iordy(dev);
+
        if (ap->ops->mode_filter)
-               xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask);
+               xfer_mask = ap->ops->mode_filter(dev, xfer_mask);
+
+       /* Apply cable rule here.  Don't apply it early because when
+        * we handle hot plug the cable type can itself change.
+        * Check this last so that we know if the transfer rate was
+        * solely limited by the cable.
+        * Unknown or 80 wire cables reported host side are checked
+        * drive side as well. Cases where we know a 40wire cable
+        * is used safely for 80 are not checked here.
+        */
+       if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA))
+               /* UDMA/44 or higher would be available */
+               if((ap->cbl == ATA_CBL_PATA40) ||
+                   (ata_drive_40wire(dev->id) &&
+                    (ap->cbl == ATA_CBL_PATA_UNK ||
+                     ap->cbl == ATA_CBL_PATA80))) {
+                       ata_dev_printk(dev, KERN_WARNING,
+                                "limited to UDMA/33 due to 40-wire cable\n");
+                       xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
+               }
 
        ata_unpack_xfermask(xfer_mask, &dev->pio_mask,
                            &dev->mwdma_mask, &dev->udma_mask);
@@ -4022,10 +4355,10 @@ void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
 
 
 /**
- *     ata_pio_sector - Transfer ATA_SECT_SIZE (512 bytes) of data.
+ *     ata_pio_sector - Transfer a sector of data.
  *     @qc: Command on going
  *
- *     Transfer ATA_SECT_SIZE of data from/to the ATA device.
+ *     Transfer qc->sect_size bytes of data from/to the ATA device.
  *
  *     LOCKING:
  *     Inherited from caller.
@@ -4040,7 +4373,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
        unsigned int offset;
        unsigned char *buf;
 
-       if (qc->curbytes == qc->nbytes - ATA_SECT_SIZE)
+       if (qc->curbytes == qc->nbytes - qc->sect_size)
                ap->hsm_task_state = HSM_ST_LAST;
 
        page = sg[qc->cursg].page;
@@ -4060,17 +4393,17 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
                buf = kmap_atomic(page, KM_IRQ0);
 
                /* do the actual data transfer */
-               ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write);
+               ap->ops->data_xfer(qc->dev, buf + offset, qc->sect_size, do_write);
 
                kunmap_atomic(buf, KM_IRQ0);
                local_irq_restore(flags);
        } else {
                buf = page_address(page);
-               ap->ops->data_xfer(qc->dev, buf + offset, ATA_SECT_SIZE, do_write);
+               ap->ops->data_xfer(qc->dev, buf + offset, qc->sect_size, do_write);
        }
 
-       qc->curbytes += ATA_SECT_SIZE;
-       qc->cursg_ofs += ATA_SECT_SIZE;
+       qc->curbytes += qc->sect_size;
+       qc->cursg_ofs += qc->sect_size;
 
        if (qc->cursg_ofs == (&sg[qc->cursg])->length) {
                qc->cursg++;
@@ -4079,10 +4412,10 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
 }
 
 /**
- *     ata_pio_sectors - Transfer one or many 512-byte sectors.
+ *     ata_pio_sectors - Transfer one or many sectors.
  *     @qc: Command on going
  *
- *     Transfer one or many ATA_SECT_SIZE of data from/to the
+ *     Transfer one or many sectors of data from/to the
  *     ATA device for the DRQ request.
  *
  *     LOCKING:
@@ -4097,7 +4430,7 @@ static void ata_pio_sectors(struct ata_queued_cmd *qc)
 
                WARN_ON(qc->dev->multi_count == 0);
 
-               nsect = min((qc->nbytes - qc->curbytes) / ATA_SECT_SIZE,
+               nsect = min((qc->nbytes - qc->curbytes) / qc->sect_size,
                            qc->dev->multi_count);
                while (nsect--)
                        ata_pio_sector(qc);
@@ -5577,42 +5910,35 @@ void ata_dev_init(struct ata_device *dev)
 }
 
 /**
- *     ata_port_init - Initialize an ata_port structure
- *     @ap: Structure to initialize
- *     @host: Collection of hosts to which @ap belongs
- *     @ent: Probe information provided by low-level driver
- *     @port_no: Port number associated with this ata_port
+ *     ata_port_alloc - allocate and initialize basic ATA port resources
+ *     @host: ATA host this allocated port belongs to
  *
- *     Initialize a new ata_port structure.
+ *     Allocate and initialize basic ATA port resources.
+ *
+ *     RETURNS:
+ *     Allocate ATA port on success, NULL on failure.
  *
  *     LOCKING:
- *     Inherited from caller.
+ *     Inherited from calling layer (may sleep).
  */
-void ata_port_init(struct ata_port *ap, struct ata_host *host,
-                  const struct ata_probe_ent *ent, unsigned int port_no)
+struct ata_port *ata_port_alloc(struct ata_host *host)
 {
+       struct ata_port *ap;
        unsigned int i;
 
+       DPRINTK("ENTER\n");
+
+       ap = kzalloc(sizeof(*ap), GFP_KERNEL);
+       if (!ap)
+               return NULL;
+
        ap->lock = &host->lock;
        ap->flags = ATA_FLAG_DISABLED;
-       ap->print_id = ata_print_id++;
+       ap->print_id = -1;
        ap->ctl = ATA_DEVCTL_OBS;
        ap->host = host;
-       ap->dev = ent->dev;
-       ap->port_no = port_no;
-       if (port_no == 1 && ent->pinfo2) {
-               ap->pio_mask = ent->pinfo2->pio_mask;
-               ap->mwdma_mask = ent->pinfo2->mwdma_mask;
-               ap->udma_mask = ent->pinfo2->udma_mask;
-               ap->flags |= ent->pinfo2->flags;
-               ap->ops = ent->pinfo2->port_ops;
-       } else {
-               ap->pio_mask = ent->pio_mask;
-               ap->mwdma_mask = ent->mwdma_mask;
-               ap->udma_mask = ent->udma_mask;
-               ap->flags |= ent->port_flags;
-               ap->ops = ent->port_ops;
-       }
+       ap->dev = host->dev;
+
        ap->hw_sata_spd_limit = UINT_MAX;
        ap->active_tag = ATA_TAG_POISON;
        ap->last_ctl = 0xFF;
@@ -5632,10 +5958,7 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host,
        INIT_LIST_HEAD(&ap->eh_done_q);
        init_waitqueue_head(&ap->eh_wait_q);
 
-       /* set cable type */
        ap->cbl = ATA_CBL_NONE;
-       if (ap->flags & ATA_FLAG_SATA)
-               ap->cbl = ATA_CBL_SATA;
 
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                struct ata_device *dev = &ap->device[i];
@@ -5648,100 +5971,209 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host,
        ap->stats.unhandled_irq = 1;
        ap->stats.idle_irq = 1;
 #endif
+       return ap;
+}
 
-       memcpy(&ap->ioaddr, &ent->port[port_no], sizeof(struct ata_ioports));
+static void ata_host_release(struct device *gendev, void *res)
+{
+       struct ata_host *host = dev_get_drvdata(gendev);
+       int i;
+
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+
+               if (!ap)
+                       continue;
+
+               if ((host->flags & ATA_HOST_STARTED) && ap->ops->port_stop)
+                       ap->ops->port_stop(ap);
+       }
+
+       if ((host->flags & ATA_HOST_STARTED) && host->ops->host_stop)
+               host->ops->host_stop(host);
+
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+
+               if (!ap)
+                       continue;
+
+               if (ap->scsi_host)
+                       scsi_host_put(ap->scsi_host);
+
+               kfree(ap);
+               host->ports[i] = NULL;
+       }
+
+       dev_set_drvdata(gendev, NULL);
 }
 
 /**
- *     ata_port_init_shost - Initialize SCSI host associated with ATA port
- *     @ap: ATA port to initialize SCSI host for
- *     @shost: SCSI host associated with @ap
+ *     ata_host_alloc - allocate and init basic ATA host resources
+ *     @dev: generic device this host is associated with
+ *     @max_ports: maximum number of ATA ports associated with this host
  *
- *     Initialize SCSI host @shost associated with ATA port @ap.
+ *     Allocate and initialize basic ATA host resources.  LLD calls
+ *     this function to allocate a host, initializes it fully and
+ *     attaches it using ata_host_register().
+ *
+ *     @max_ports ports are allocated and host->n_ports is
+ *     initialized to @max_ports.  The caller is allowed to decrease
+ *     host->n_ports before calling ata_host_register().  The unused
+ *     ports will be automatically freed on registration.
+ *
+ *     RETURNS:
+ *     Allocate ATA host on success, NULL on failure.
  *
  *     LOCKING:
- *     Inherited from caller.
+ *     Inherited from calling layer (may sleep).
  */
-static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost)
+struct ata_host *ata_host_alloc(struct device *dev, int max_ports)
 {
-       ap->scsi_host = shost;
+       struct ata_host *host;
+       size_t sz;
+       int i;
+
+       DPRINTK("ENTER\n");
+
+       if (!devres_open_group(dev, NULL, GFP_KERNEL))
+               return NULL;
+
+       /* alloc a container for our list of ATA ports (buses) */
+       sz = sizeof(struct ata_host) + (max_ports + 1) * sizeof(void *);
+       /* alloc a container for our list of ATA ports (buses) */
+       host = devres_alloc(ata_host_release, sz, GFP_KERNEL);
+       if (!host)
+               goto err_out;
+
+       devres_add(dev, host);
+       dev_set_drvdata(dev, host);
 
-       shost->unique_id = ap->print_id;
-       shost->max_id = 16;
-       shost->max_lun = 1;
-       shost->max_channel = 1;
-       shost->max_cmd_len = 12;
+       spin_lock_init(&host->lock);
+       host->dev = dev;
+       host->n_ports = max_ports;
+
+       /* allocate ports bound to this host */
+       for (i = 0; i < max_ports; i++) {
+               struct ata_port *ap;
+
+               ap = ata_port_alloc(host);
+               if (!ap)
+                       goto err_out;
+
+               ap->port_no = i;
+               host->ports[i] = ap;
+       }
+
+       devres_remove_group(dev, NULL);
+       return host;
+
+ err_out:
+       devres_release_group(dev, NULL);
+       return NULL;
 }
 
 /**
- *     ata_port_add - Attach low-level ATA driver to system
- *     @ent: Information provided by low-level driver
- *     @host: Collections of ports to which we add
- *     @port_no: Port number associated with this host
+ *     ata_host_alloc_pinfo - alloc host and init with port_info array
+ *     @dev: generic device this host is associated with
+ *     @ppi: array of ATA port_info to initialize host with
+ *     @n_ports: number of ATA ports attached to this host
  *
- *     Attach low-level ATA driver to system.
- *
- *     LOCKING:
- *     PCI/etc. bus probe sem.
+ *     Allocate ATA host and initialize with info from @ppi.  If NULL
+ *     terminated, @ppi may contain fewer entries than @n_ports.  The
+ *     last entry will be used for the remaining ports.
  *
  *     RETURNS:
- *     New ata_port on success, for NULL on error.
+ *     Allocate ATA host on success, NULL on failure.
+ *
+ *     LOCKING:
+ *     Inherited from calling layer (may sleep).
  */
-static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
-                                     struct ata_host *host,
-                                     unsigned int port_no)
+struct ata_host *ata_host_alloc_pinfo(struct device *dev,
+                                     const struct ata_port_info * const * ppi,
+                                     int n_ports)
 {
-       struct Scsi_Host *shost;
-       struct ata_port *ap;
-
-       DPRINTK("ENTER\n");
+       const struct ata_port_info *pi;
+       struct ata_host *host;
+       int i, j;
 
-       if (!ent->port_ops->error_handler &&
-           !(ent->port_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) {
-               printk(KERN_ERR "ata%u: no reset mechanism available\n",
-                      port_no);
+       host = ata_host_alloc(dev, n_ports);
+       if (!host)
                return NULL;
-       }
 
-       shost = scsi_host_alloc(ent->sht, sizeof(struct ata_port));
-       if (!shost)
-               return NULL;
+       for (i = 0, j = 0, pi = NULL; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
 
-       shost->transportt = &ata_scsi_transport_template;
+               if (ppi[j])
+                       pi = ppi[j++];
 
-       ap = ata_shost_to_port(shost);
+               ap->pio_mask = pi->pio_mask;
+               ap->mwdma_mask = pi->mwdma_mask;
+               ap->udma_mask = pi->udma_mask;
+               ap->flags |= pi->flags;
+               ap->ops = pi->port_ops;
 
-       ata_port_init(ap, host, ent, port_no);
-       ata_port_init_shost(ap, shost);
+               if (!host->ops && (pi->port_ops != &ata_dummy_port_ops))
+                       host->ops = pi->port_ops;
+               if (!host->private_data && pi->private_data)
+                       host->private_data = pi->private_data;
+       }
 
-       return ap;
+       return host;
 }
 
-static void ata_host_release(struct device *gendev, void *res)
+/**
+ *     ata_host_start - start and freeze ports of an ATA host
+ *     @host: ATA host to start ports for
+ *
+ *     Start and then freeze ports of @host.  Started status is
+ *     recorded in host->flags, so this function can be called
+ *     multiple times.  Ports are guaranteed to get started only
+ *     once.  If host->ops isn't initialized yet, its set to the
+ *     first non-dummy port ops.
+ *
+ *     LOCKING:
+ *     Inherited from calling layer (may sleep).
+ *
+ *     RETURNS:
+ *     0 if all ports are started successfully, -errno otherwise.
+ */
+int ata_host_start(struct ata_host *host)
 {
-       struct ata_host *host = dev_get_drvdata(gendev);
-       int i;
+       int i, rc;
+
+       if (host->flags & ATA_HOST_STARTED)
+               return 0;
 
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
 
-               if (ap && ap->ops->port_stop)
-                       ap->ops->port_stop(ap);
+               if (!host->ops && !ata_port_is_dummy(ap))
+                       host->ops = ap->ops;
+
+               if (ap->ops->port_start) {
+                       rc = ap->ops->port_start(ap);
+                       if (rc) {
+                               ata_port_printk(ap, KERN_ERR, "failed to "
+                                               "start port (errno=%d)\n", rc);
+                               goto err_out;
+                       }
+               }
+
+               ata_eh_freeze_port(ap);
        }
 
-       if (host->ops->host_stop)
-               host->ops->host_stop(host);
+       host->flags |= ATA_HOST_STARTED;
+       return 0;
 
-       for (i = 0; i < host->n_ports; i++) {
+ err_out:
+       while (--i >= 0) {
                struct ata_port *ap = host->ports[i];
 
-               if (ap)
-                       scsi_host_put(ap->scsi_host);
-
-               host->ports[i] = NULL;
+               if (ap->ops->port_stop)
+                       ap->ops->port_stop(ap);
        }
-
-       dev_set_drvdata(gendev, NULL);
+       return rc;
 }
 
 /**
@@ -5755,7 +6187,7 @@ static void ata_host_release(struct device *gendev, void *res)
  *     PCI/etc. bus probe sem.
  *
  */
-
+/* KILLME - the only user left is ipr */
 void ata_host_init(struct ata_host *host, struct device *dev,
                   unsigned long flags, const struct ata_port_operations *ops)
 {
@@ -5766,155 +6198,95 @@ void ata_host_init(struct ata_host *host, struct device *dev,
 }
 
 /**
- *     ata_device_add - Register hardware device with ATA and SCSI layers
- *     @ent: Probe information describing hardware device to be registered
+ *     ata_host_register - register initialized ATA host
+ *     @host: ATA host to register
+ *     @sht: template for SCSI host
  *
- *     This function processes the information provided in the probe
- *     information struct @ent, allocates the necessary ATA and SCSI
- *     host information structures, initializes them, and registers
- *     everything with requisite kernel subsystems.
- *
- *     This function requests irqs, probes the ATA bus, and probes
- *     the SCSI bus.
+ *     Register initialized ATA host.  @host is allocated using
+ *     ata_host_alloc() and fully initialized by LLD.  This function
+ *     starts ports, registers @host with ATA and SCSI layers and
+ *     probe registered devices.
  *
  *     LOCKING:
- *     PCI/etc. bus probe sem.
+ *     Inherited from calling layer (may sleep).
  *
  *     RETURNS:
- *     Number of ports registered.  Zero on error (no ports registered).
+ *     0 on success, -errno otherwise.
  */
-int ata_device_add(const struct ata_probe_ent *ent)
+int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
 {
-       unsigned int i;
-       struct device *dev = ent->dev;
-       struct ata_host *host;
-       int rc;
-
-       DPRINTK("ENTER\n");
+       int i, rc;
 
-       if (ent->irq == 0) {
-               dev_printk(KERN_ERR, dev, "is not available: No interrupt assigned.\n");
-               return 0;
+       /* host must have been started */
+       if (!(host->flags & ATA_HOST_STARTED)) {
+               dev_printk(KERN_ERR, host->dev,
+                          "BUG: trying to register unstarted host\n");
+               WARN_ON(1);
+               return -EINVAL;
        }
 
-       if (!devres_open_group(dev, ata_device_add, GFP_KERNEL))
-               return 0;
+       /* Blow away unused ports.  This happens when LLD can't
+        * determine the exact number of ports to allocate at
+        * allocation time.
+        */
+       for (i = host->n_ports; host->ports[i]; i++)
+               kfree(host->ports[i]);
 
-       /* alloc a container for our list of ATA ports (buses) */
-       host = devres_alloc(ata_host_release, sizeof(struct ata_host) +
-                           (ent->n_ports * sizeof(void *)), GFP_KERNEL);
-       if (!host)
-               goto err_out;
-       devres_add(dev, host);
-       dev_set_drvdata(dev, host);
+       /* give ports names and add SCSI hosts */
+       for (i = 0; i < host->n_ports; i++)
+               host->ports[i]->print_id = ata_print_id++;
 
-       ata_host_init(host, dev, ent->_host_flags, ent->port_ops);
-       host->n_ports = ent->n_ports;
-       host->irq = ent->irq;
-       host->irq2 = ent->irq2;
-       host->iomap = ent->iomap;
-       host->private_data = ent->private_data;
+       rc = ata_scsi_add_hosts(host, sht);
+       if (rc)
+               return rc;
 
-       /* register each port bound to this device */
+       /* set cable, sata_spd_limit and report */
        for (i = 0; i < host->n_ports; i++) {
-               struct ata_port *ap;
-               unsigned long xfer_mode_mask;
-               int irq_line = ent->irq;
+               struct ata_port *ap = host->ports[i];
+               int irq_line;
+               u32 scontrol;
+               unsigned long xfer_mask;
 
-               ap = ata_port_add(ent, host, i);
-               host->ports[i] = ap;
-               if (!ap)
-                       goto err_out;
+               /* set SATA cable type if still unset */
+               if (ap->cbl == ATA_CBL_NONE && (ap->flags & ATA_FLAG_SATA))
+                       ap->cbl = ATA_CBL_SATA;
 
-               /* dummy? */
-               if (ent->dummy_port_mask & (1 << i)) {
-                       ata_port_printk(ap, KERN_INFO, "DUMMY\n");
-                       ap->ops = &ata_dummy_port_ops;
-                       continue;
-               }
-
-               /* start port */
-               rc = ap->ops->port_start(ap);
-               if (rc) {
-                       host->ports[i] = NULL;
-                       scsi_host_put(ap->scsi_host);
-                       goto err_out;
+               /* init sata_spd_limit to the current value */
+               if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
+                       int spd = (scontrol >> 4) & 0xf;
+                       ap->hw_sata_spd_limit &= (1 << spd) - 1;
                }
+               ap->sata_spd_limit = ap->hw_sata_spd_limit;
 
-               /* Report the secondary IRQ for second channel legacy */
-               if (i == 1 && ent->irq2)
-                       irq_line = ent->irq2;
+               /* report the secondary IRQ for second channel legacy */
+               irq_line = host->irq;
+               if (i == 1 && host->irq2)
+                       irq_line = host->irq2;
 
-               xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) |
-                               (ap->mwdma_mask << ATA_SHIFT_MWDMA) |
-                               (ap->pio_mask << ATA_SHIFT_PIO);
+               xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask,
+                                             ap->udma_mask);
 
                /* print per-port info to dmesg */
-               ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p "
-                               "ctl 0x%p bmdma 0x%p irq %d\n",
-                               ap->flags & ATA_FLAG_SATA ? 'S' : 'P',
-                               ata_mode_string(xfer_mode_mask),
-                               ap->ioaddr.cmd_addr,
-                               ap->ioaddr.ctl_addr,
-                               ap->ioaddr.bmdma_addr,
-                               irq_line);
-
-               /* freeze port before requesting IRQ */
-               ata_eh_freeze_port(ap);
-       }
-
-       /* obtain irq, that may be shared between channels */
-       rc = devm_request_irq(dev, ent->irq, ent->port_ops->irq_handler,
-                             ent->irq_flags, DRV_NAME, host);
-       if (rc) {
-               dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
-                          ent->irq, rc);
-               goto err_out;
-       }
-
-       /* do we have a second IRQ for the other channel, eg legacy mode */
-       if (ent->irq2) {
-               /* We will get weird core code crashes later if this is true
-                  so trap it now */
-               BUG_ON(ent->irq == ent->irq2);
-
-               rc = devm_request_irq(dev, ent->irq2,
-                               ent->port_ops->irq_handler, ent->irq_flags,
-                               DRV_NAME, host);
-               if (rc) {
-                       dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
-                                  ent->irq2, rc);
-                       goto err_out;
-               }
+               if (!ata_port_is_dummy(ap))
+                       ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%p "
+                                       "ctl 0x%p bmdma 0x%p irq %d\n",
+                                       ap->cbl == ATA_CBL_SATA ? 'S' : 'P',
+                                       ata_mode_string(xfer_mask),
+                                       ap->ioaddr.cmd_addr,
+                                       ap->ioaddr.ctl_addr,
+                                       ap->ioaddr.bmdma_addr,
+                                       irq_line);
+               else
+                       ata_port_printk(ap, KERN_INFO, "DUMMY\n");
        }
 
-       /* resource acquisition complete */
-       devres_remove_group(dev, ata_device_add);
-
        /* perform each probe synchronously */
        DPRINTK("probe begin\n");
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
-               u32 scontrol;
                int rc;
 
-               /* init sata_spd_limit to the current value */
-               if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
-                       int spd = (scontrol >> 4) & 0xf;
-                       ap->hw_sata_spd_limit &= (1 << spd) - 1;
-               }
-               ap->sata_spd_limit = ap->hw_sata_spd_limit;
-
-               rc = scsi_add_host(ap->scsi_host, dev);
-               if (rc) {
-                       ata_port_printk(ap, KERN_ERR, "scsi_add_host failed\n");
-                       /* FIXME: do something useful here */
-                       /* FIXME: handle unconditional calls to
-                        * scsi_scan_host and ata_host_remove, below,
-                        * at the very least
-                        */
-               }
-
+               /* probe */
                if (ap->ops->error_handler) {
                        struct ata_eh_info *ehi = &ap->eh_info;
                        unsigned long flags;
@@ -5959,15 +6331,51 @@ int ata_device_add(const struct ata_probe_ent *ent)
                ata_scsi_scan_host(ap);
        }
 
-       VPRINTK("EXIT, returning %u\n", ent->n_ports);
-       return ent->n_ports; /* success */
-
- err_out:
-       devres_release_group(dev, ata_device_add);
-       VPRINTK("EXIT, returning %d\n", rc);
        return 0;
 }
 
+/**
+ *     ata_host_activate - start host, request IRQ and register it
+ *     @host: target ATA host
+ *     @irq: IRQ to request
+ *     @irq_handler: irq_handler used when requesting IRQ
+ *     @irq_flags: irq_flags used when requesting IRQ
+ *     @sht: scsi_host_template to use when registering the host
+ *
+ *     After allocating an ATA host and initializing it, most libata
+ *     LLDs perform three steps to activate the host - start host,
+ *     request IRQ and register it.  This helper takes necessasry
+ *     arguments and performs the three steps in one go.
+ *
+ *     LOCKING:
+ *     Inherited from calling layer (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
+ */
+int ata_host_activate(struct ata_host *host, int irq,
+                     irq_handler_t irq_handler, unsigned long irq_flags,
+                     struct scsi_host_template *sht)
+{
+       int rc;
+
+       rc = ata_host_start(host);
+       if (rc)
+               return rc;
+
+       rc = devm_request_irq(host->dev, irq, irq_handler, irq_flags,
+                             dev_driver_string(host->dev), host);
+       if (rc)
+               return rc;
+
+       rc = ata_host_register(host, sht);
+       /* if failed, just free the IRQ and leave ports alone */
+       if (rc)
+               devm_free_irq(host->dev, irq, host);
+
+       return rc;
+}
+
 /**
  *     ata_port_detach - Detach ATA port in prepration of device removal
  *     @ap: ATA port to be detached
@@ -6043,32 +6451,6 @@ void ata_host_detach(struct ata_host *host)
                ata_port_detach(host->ports[i]);
 }
 
-struct ata_probe_ent *
-ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
-{
-       struct ata_probe_ent *probe_ent;
-
-       probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (!probe_ent) {
-               printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
-                      kobject_name(&(dev->kobj)));
-               return NULL;
-       }
-
-       INIT_LIST_HEAD(&probe_ent->node);
-       probe_ent->dev = dev;
-
-       probe_ent->sht = port->sht;
-       probe_ent->port_flags = port->flags;
-       probe_ent->pio_mask = port->pio_mask;
-       probe_ent->mwdma_mask = port->mwdma_mask;
-       probe_ent->udma_mask = port->udma_mask;
-       probe_ent->port_ops = port->port_ops;
-       probe_ent->private_data = port->private_data;
-
-       return probe_ent;
-}
-
 /**
  *     ata_std_ports - initialize ioaddr with standard port offsets.
  *     @ioaddr: IO address structure to be initialized
@@ -6334,6 +6716,10 @@ const struct ata_port_operations ata_dummy_port_ops = {
        .port_stop              = ata_dummy_noret,
 };
 
+const struct ata_port_info ata_dummy_port_info = {
+       .port_ops               = &ata_dummy_port_ops,
+};
+
 /*
  * libata is essentially a library of internal helper functions for
  * low-level ATA host controller drivers.  As such, the API/ABI is
@@ -6345,10 +6731,15 @@ EXPORT_SYMBOL_GPL(sata_deb_timing_normal);
 EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug);
 EXPORT_SYMBOL_GPL(sata_deb_timing_long);
 EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
+EXPORT_SYMBOL_GPL(ata_dummy_port_info);
 EXPORT_SYMBOL_GPL(ata_std_bios_param);
 EXPORT_SYMBOL_GPL(ata_std_ports);
 EXPORT_SYMBOL_GPL(ata_host_init);
-EXPORT_SYMBOL_GPL(ata_device_add);
+EXPORT_SYMBOL_GPL(ata_host_alloc);
+EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo);
+EXPORT_SYMBOL_GPL(ata_host_start);
+EXPORT_SYMBOL_GPL(ata_host_register);
+EXPORT_SYMBOL_GPL(ata_host_activate);
 EXPORT_SYMBOL_GPL(ata_host_detach);
 EXPORT_SYMBOL_GPL(ata_sg_init);
 EXPORT_SYMBOL_GPL(ata_sg_init_one);
@@ -6360,6 +6751,7 @@ EXPORT_SYMBOL_GPL(ata_tf_load);
 EXPORT_SYMBOL_GPL(ata_tf_read);
 EXPORT_SYMBOL_GPL(ata_noop_dev_select);
 EXPORT_SYMBOL_GPL(ata_std_dev_select);
+EXPORT_SYMBOL_GPL(sata_print_link_status);
 EXPORT_SYMBOL_GPL(ata_tf_to_fis);
 EXPORT_SYMBOL_GPL(ata_tf_from_fis);
 EXPORT_SYMBOL_GPL(ata_check_status);
@@ -6367,6 +6759,7 @@ EXPORT_SYMBOL_GPL(ata_altstatus);
 EXPORT_SYMBOL_GPL(ata_exec_command);
 EXPORT_SYMBOL_GPL(ata_port_start);
 EXPORT_SYMBOL_GPL(ata_interrupt);
+EXPORT_SYMBOL_GPL(ata_do_set_mode);
 EXPORT_SYMBOL_GPL(ata_data_xfer);
 EXPORT_SYMBOL_GPL(ata_data_xfer_noirq);
 EXPORT_SYMBOL_GPL(ata_qc_prep);
@@ -6429,7 +6822,8 @@ EXPORT_SYMBOL_GPL(ata_timing_merge);
 
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL_GPL(pci_test_config_bits);
-EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
+EXPORT_SYMBOL_GPL(ata_pci_init_native_host);
+EXPORT_SYMBOL_GPL(ata_pci_prepare_native_host);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
 #ifdef CONFIG_PM
@@ -6461,3 +6855,8 @@ EXPORT_SYMBOL_GPL(ata_dummy_irq_on);
 EXPORT_SYMBOL_GPL(ata_irq_ack);
 EXPORT_SYMBOL_GPL(ata_dummy_irq_ack);
 EXPORT_SYMBOL_GPL(ata_dev_try_classify);
+
+EXPORT_SYMBOL_GPL(ata_cable_40wire);
+EXPORT_SYMBOL_GPL(ata_cable_80wire);
+EXPORT_SYMBOL_GPL(ata_cable_unknown);
+EXPORT_SYMBOL_GPL(ata_cable_sata);
index 39f556c0299265ffb99a4430588f7aa9cac194ff..2bff9adcacf15de02b7f0f6c35f83116410df606 100644 (file)
@@ -1056,7 +1056,7 @@ static void ata_eh_analyze_serror(struct ata_port *ap)
        }
        if (serror & SERR_INTERNAL) {
                err_mask |= AC_ERR_SYSTEM;
-               action |= ATA_EH_SOFTRESET;
+               action |= ATA_EH_HARDRESET;
        }
        if (serror & (SERR_PHYRDY_CHG | SERR_DEV_XCHG))
                ata_ehi_hotplugged(&ehc->i);
@@ -1151,7 +1151,9 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
                return ATA_EH_SOFTRESET;
        }
 
-       if (!(qc->err_mask & AC_ERR_DEV))
+       if (stat & (ATA_ERR | ATA_DF))
+               qc->err_mask |= AC_ERR_DEV;
+       else
                return 0;
 
        switch (qc->dev->class) {
@@ -1669,7 +1671,10 @@ static int ata_eh_reset(struct ata_port *ap, int classify,
                                reset == softreset ? "soft" : "hard");
 
        /* mark that this EH session started with reset */
-       ehc->i.flags |= ATA_EHI_DID_RESET;
+       if (reset == hardreset)
+               ehc->i.flags |= ATA_EHI_DID_HARDRESET;
+       else
+               ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
 
        rc = ata_do_reset(ap, reset, classes);
 
@@ -1808,6 +1813,10 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
                }
        }
 
+       /* PDIAG- should have been released, ask cable type if post-reset */
+       if ((ehc->i.flags & ATA_EHI_DID_RESET) && ap->ops->cable_detect)
+               ap->cbl = ap->ops->cable_detect(ap);
+
        /* Configure new devices forward such that user doesn't see
         * device detection messages backwards.
         */
index e9364434182c437fe8e0cb73e38d60a73803ed29..9afba2ba489e52097bc5fca2fe8fd98747b6b887 100644 (file)
@@ -104,7 +104,7 @@ static const u8 def_control_mpage[CONTROL_MPAGE_LEN] = {
  * libata transport template.  libata doesn't do real transport stuff.
  * It just needs the eh_timed_out hook.
  */
-struct scsi_transport_template ata_scsi_transport_template = {
+static struct scsi_transport_template ata_scsi_transport_template = {
        .eh_strategy_handler    = ata_scsi_error,
        .eh_timed_out           = ata_scsi_timed_out,
        .user_scan              = ata_scsi_user_scan,
@@ -2678,6 +2678,18 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
                tf->device = qc->dev->devno ?
                        tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
 
+       /* READ/WRITE LONG use a non-standard sect_size */
+       qc->sect_size = ATA_SECT_SIZE;
+       switch (tf->command) {
+       case ATA_CMD_READ_LONG:
+       case ATA_CMD_READ_LONG_ONCE:
+       case ATA_CMD_WRITE_LONG:
+       case ATA_CMD_WRITE_LONG_ONCE:
+               if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1)
+                       goto invalid_fld;
+               qc->sect_size = scmd->request_bufflen;
+       }
+
        /*
         * Filter SET_FEATURES - XFER MODE command -- otherwise,
         * SET_FEATURES - XFER MODE must be preceded/succeeded
@@ -2792,8 +2804,9 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd,
 {
        int rc = 0;
 
-       if (unlikely(!scmd->cmd_len)) {
-               ata_dev_printk(dev, KERN_WARNING, "WARNING: zero len CDB\n");
+       if (unlikely(!scmd->cmd_len || scmd->cmd_len > dev->cdb_len)) {
+               DPRINTK("bad CDB len=%u, max=%u\n",
+                       scmd->cmd_len, dev->cdb_len);
                scmd->result = DID_ERROR << 16;
                done(scmd);
                return 0;
@@ -2948,6 +2961,48 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
        }
 }
 
+int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
+{
+       int i, rc;
+
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+               struct Scsi_Host *shost;
+
+               rc = -ENOMEM;
+               shost = scsi_host_alloc(sht, sizeof(struct ata_port *));
+               if (!shost)
+                       goto err_alloc;
+
+               *(struct ata_port **)&shost->hostdata[0] = ap;
+               ap->scsi_host = shost;
+
+               shost->transportt = &ata_scsi_transport_template;
+               shost->unique_id = ap->print_id;
+               shost->max_id = 16;
+               shost->max_lun = 1;
+               shost->max_channel = 1;
+               shost->max_cmd_len = 16;
+
+               rc = scsi_add_host(ap->scsi_host, ap->host->dev);
+               if (rc)
+                       goto err_add;
+       }
+
+       return 0;
+
+ err_add:
+       scsi_host_put(host->ports[i]->scsi_host);
+ err_alloc:
+       while (--i >= 0) {
+               struct Scsi_Host *shost = host->ports[i]->scsi_host;
+
+               scsi_remove_host(shost);
+               scsi_host_put(shost);
+       }
+       return rc;
+}
+
 void ata_scsi_scan_host(struct ata_port *ap)
 {
        unsigned int i;
@@ -3224,21 +3279,21 @@ struct ata_port *ata_sas_port_alloc(struct ata_host *host,
                                    struct ata_port_info *port_info,
                                    struct Scsi_Host *shost)
 {
-       struct ata_port *ap = kzalloc(sizeof(*ap), GFP_KERNEL);
-       struct ata_probe_ent *ent;
+       struct ata_port *ap;
 
+       ap = ata_port_alloc(host);
        if (!ap)
                return NULL;
 
-       ent = ata_probe_ent_alloc(host->dev, port_info);
-       if (!ent) {
-               kfree(ap);
-               return NULL;
-       }
-
-       ata_port_init(ap, host, ent, 0);
+       ap->port_no = 0;
        ap->lock = shost->host_lock;
-       devm_kfree(host->dev, ent);
+       ap->pio_mask = port_info->pio_mask;
+       ap->mwdma_mask = port_info->mwdma_mask;
+       ap->udma_mask = port_info->udma_mask;
+       ap->flags |= port_info->flags;
+       ap->ops = port_info->port_ops;
+       ap->cbl = ATA_CBL_SATA;
+
        return ap;
 }
 EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
@@ -3294,8 +3349,10 @@ int ata_sas_port_init(struct ata_port *ap)
 {
        int rc = ap->ops->port_start(ap);
 
-       if (!rc)
+       if (!rc) {
+               ap->print_id = ata_print_id++;
                rc = ata_bus_probe(ap);
+       }
 
        return rc;
 }
index 2ffcca063d80adc3405ab16c484ab7da8788a5d5..8af18ad1ca7f4de2856d6a21b7b495771305120f 100644 (file)
@@ -526,168 +526,399 @@ static int ata_resources_present(struct pci_dev *pdev, int port)
        port = port * 2;
        for (i = 0; i < 2; i ++) {
                if (pci_resource_start(pdev, port + i) == 0 ||
-                       pci_resource_len(pdev, port + i) == 0)
-               return 0;
+                   pci_resource_len(pdev, port + i) == 0)
+                       return 0;
        }
        return 1;
 }
 
 /**
- *     ata_pci_init_native_mode - Initialize native-mode driver
- *     @pdev:  pci device to be initialized
- *     @port:  array[2] of pointers to port info structures.
- *     @ports: bitmap of ports present
- *
- *     Utility function which allocates and initializes an
- *     ata_probe_ent structure for a standard dual-port
- *     PIO-based IDE controller.  The returned ata_probe_ent
- *     structure can be passed to ata_device_add().  The returned
- *     ata_probe_ent structure should then be freed with kfree().
- *
- *     The caller need only pass the address of the primary port, the
- *     secondary will be deduced automatically. If the device has non
- *     standard secondary port mappings this function can be called twice,
- *     once for each interface.
+ *     ata_pci_init_bmdma - acquire PCI BMDMA resources and init ATA host
+ *     @host: target ATA host
+ *
+ *     Acquire PCI BMDMA resources and initialize @host accordingly.
+ *
+ *     LOCKING:
+ *     Inherited from calling layer (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
  */
+static int ata_pci_init_bmdma(struct ata_host *host)
+{
+       struct device *gdev = host->dev;
+       struct pci_dev *pdev = to_pci_dev(gdev);
+       int i, rc;
+
+       /* TODO: If we get no DMA mask we should fall back to PIO */
+       rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+       if (rc)
+               return rc;
+       rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+       if (rc)
+               return rc;
+
+       /* request and iomap DMA region */
+       rc = pcim_iomap_regions(pdev, 1 << 4, DRV_NAME);
+       if (rc) {
+               dev_printk(KERN_ERR, gdev, "failed to request/iomap BAR4\n");
+               return -ENOMEM;
+       }
+       host->iomap = pcim_iomap_table(pdev);
+
+       for (i = 0; i < 2; i++) {
+               struct ata_port *ap = host->ports[i];
+               void __iomem *bmdma = host->iomap[4] + 8 * i;
+
+               if (ata_port_is_dummy(ap))
+                       continue;
+
+               ap->ioaddr.bmdma_addr = bmdma;
+               if ((!(ap->flags & ATA_FLAG_IGN_SIMPLEX)) &&
+                   (ioread8(bmdma + 2) & 0x80))
+                       host->flags |= ATA_HOST_SIMPLEX;
+       }
+
+       return 0;
+}
 
-struct ata_probe_ent *
-ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int ports)
+/**
+ *     ata_pci_init_native_host - acquire native ATA resources and init host
+ *     @host: target ATA host
+ *     @port_mask: ports to consider
+ *
+ *     Acquire native PCI ATA resources for @host and initialize
+ *     @host accordoingly.
+ *
+ *     LOCKING:
+ *     Inherited from calling layer (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
+ */
+int ata_pci_init_native_host(struct ata_host *host, unsigned int port_mask)
 {
-       struct ata_probe_ent *probe_ent;
-       int i, p = 0;
-       void __iomem * const *iomap;
-
-       /* iomap BARs */
-       for (i = 0; i < 4; i++) {
-               if (pcim_iomap(pdev, i, 0) == NULL) {
-                       dev_printk(KERN_ERR, &pdev->dev,
-                                  "failed to iomap PCI BAR %d\n", i);
-                       return NULL;
+       struct device *gdev = host->dev;
+       struct pci_dev *pdev = to_pci_dev(gdev);
+       int i, rc;
+
+       /* Discard disabled ports.  Some controllers show their unused
+        * channels this way.  Disabled ports are made dummy.
+        */
+       for (i = 0; i < 2; i++) {
+               if ((port_mask & (1 << i)) && !ata_resources_present(pdev, i)) {
+                       host->ports[i]->ops = &ata_dummy_port_ops;
+                       port_mask &= ~(1 << i);
                }
        }
 
-       pcim_iomap(pdev, 4, 0); /* may fail */
-       iomap = pcim_iomap_table(pdev);
-
-       /* alloc and init probe_ent */
-       probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
-       if (!probe_ent)
-               return NULL;
-
-       probe_ent->irq = pdev->irq;
-       probe_ent->irq_flags = IRQF_SHARED;
-
-       /* Discard disabled ports. Some controllers show their
-          unused channels this way */
-       if (ata_resources_present(pdev, 0) == 0)
-               ports &= ~ATA_PORT_PRIMARY;
-       if (ata_resources_present(pdev, 1) == 0)
-               ports &= ~ATA_PORT_SECONDARY;
-
-       if (ports & ATA_PORT_PRIMARY) {
-               probe_ent->port[p].cmd_addr = iomap[0];
-               probe_ent->port[p].altstatus_addr =
-               probe_ent->port[p].ctl_addr = (void __iomem *)
-                       ((unsigned long)iomap[1] | ATA_PCI_CTL_OFS);
-               if (iomap[4]) {
-                       if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
-                           (ioread8(iomap[4] + 2) & 0x80))
-                               probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
-                       probe_ent->port[p].bmdma_addr = iomap[4];
-               }
-               ata_std_ports(&probe_ent->port[p]);
-               p++;
+       if (!port_mask) {
+               dev_printk(KERN_ERR, gdev, "no available port\n");
+               return -ENODEV;
        }
 
-       if (ports & ATA_PORT_SECONDARY) {
-               probe_ent->port[p].cmd_addr = iomap[2];
-               probe_ent->port[p].altstatus_addr =
-               probe_ent->port[p].ctl_addr = (void __iomem *)
-                       ((unsigned long)iomap[3] | ATA_PCI_CTL_OFS);
-               if (iomap[4]) {
-                       if ((!(port[p]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
-                           (ioread8(iomap[4] + 10) & 0x80))
-                               probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
-                       probe_ent->port[p].bmdma_addr = iomap[4] + 8;
+       /* request, iomap BARs and init port addresses accordingly */
+       for (i = 0; i < 2; i++) {
+               struct ata_port *ap = host->ports[i];
+               int base = i * 2;
+               void __iomem * const *iomap;
+
+               if (!(port_mask & (1 << i)))
+                       continue;
+
+               rc = pcim_iomap_regions(pdev, 0x3 << base, DRV_NAME);
+               if (rc) {
+                       dev_printk(KERN_ERR, gdev, "failed to request/iomap "
+                                  "BARs for port %d (errno=%d)\n", i, rc);
+                       if (rc == -EBUSY)
+                               pcim_pin_device(pdev);
+                       return rc;
                }
-               ata_std_ports(&probe_ent->port[p]);
-               probe_ent->pinfo2 = port[1];
-               p++;
+               host->iomap = iomap = pcim_iomap_table(pdev);
+
+               ap->ioaddr.cmd_addr = iomap[base];
+               ap->ioaddr.altstatus_addr =
+               ap->ioaddr.ctl_addr = (void __iomem *)
+                       ((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS);
+               ata_std_ports(&ap->ioaddr);
        }
 
-       probe_ent->n_ports = p;
-       return probe_ent;
+       return 0;
 }
 
-static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
-                               struct ata_port_info **port, int port_mask)
+/**
+ *     ata_pci_prepare_native_host - helper to prepare native PCI ATA host
+ *     @pdev: target PCI device
+ *     @ppi: array of port_info
+ *     @n_ports: number of ports to allocate
+ *     @r_host: out argument for the initialized ATA host
+ *
+ *     Helper to allocate ATA host for @pdev, acquire all native PCI
+ *     resources and initialize it accordingly in one go.
+ *
+ *     LOCKING:
+ *     Inherited from calling layer (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
+ */
+int ata_pci_prepare_native_host(struct pci_dev *pdev,
+                               const struct ata_port_info * const * ppi,
+                               int n_ports, struct ata_host **r_host)
+{
+       struct ata_host *host;
+       unsigned int port_mask;
+       int rc;
+
+       if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
+               return -ENOMEM;
+
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
+       if (!host) {
+               dev_printk(KERN_ERR, &pdev->dev,
+                          "failed to allocate ATA host\n");
+               rc = -ENOMEM;
+               goto err_out;
+       }
+
+       port_mask = ATA_PORT_PRIMARY;
+       if (n_ports > 1)
+               port_mask |= ATA_PORT_SECONDARY;
+
+       rc = ata_pci_init_native_host(host, port_mask);
+       if (rc)
+               goto err_out;
+
+       /* init DMA related stuff */
+       rc = ata_pci_init_bmdma(host);
+       if (rc)
+               goto err_bmdma;
+
+       devres_remove_group(&pdev->dev, NULL);
+       *r_host = host;
+       return 0;
+
+ err_bmdma:
+       /* This is necessary because PCI and iomap resources are
+        * merged and releasing the top group won't release the
+        * acquired resources if some of those have been acquired
+        * before entering this function.
+        */
+       pcim_iounmap_regions(pdev, 0xf);
+ err_out:
+       devres_release_group(&pdev->dev, NULL);
+       return rc;
+}
+
+struct ata_legacy_devres {
+       unsigned int    mask;
+       unsigned long   cmd_port[2];
+       void __iomem *  cmd_addr[2];
+       void __iomem *  ctl_addr[2];
+       unsigned int    irq[2];
+       void *          irq_dev_id[2];
+};
+
+static void ata_legacy_free_irqs(struct ata_legacy_devres *legacy_dr)
 {
-       struct ata_probe_ent *probe_ent;
-       void __iomem *iomap[5] = { }, *bmdma;
-
-       if (port_mask & ATA_PORT_PRIMARY) {
-               iomap[0] = devm_ioport_map(&pdev->dev, ATA_PRIMARY_CMD, 8);
-               iomap[1] = devm_ioport_map(&pdev->dev, ATA_PRIMARY_CTL, 1);
-               if (!iomap[0] || !iomap[1])
-                       return NULL;
+       int i;
+
+       for (i = 0; i < 2; i++) {
+               if (!legacy_dr->irq[i])
+                       continue;
+
+               free_irq(legacy_dr->irq[i], legacy_dr->irq_dev_id[i]);
+               legacy_dr->irq[i] = 0;
+               legacy_dr->irq_dev_id[i] = NULL;
        }
+}
+
+static void ata_legacy_release(struct device *gdev, void *res)
+{
+       struct ata_legacy_devres *this = res;
+       int i;
 
-       if (port_mask & ATA_PORT_SECONDARY) {
-               iomap[2] = devm_ioport_map(&pdev->dev, ATA_SECONDARY_CMD, 8);
-               iomap[3] = devm_ioport_map(&pdev->dev, ATA_SECONDARY_CTL, 1);
-               if (!iomap[2] || !iomap[3])
-                       return NULL;
+       ata_legacy_free_irqs(this);
+
+       for (i = 0; i < 2; i++) {
+               if (this->cmd_addr[i])
+                       ioport_unmap(this->cmd_addr[i]);
+               if (this->ctl_addr[i])
+                       ioport_unmap(this->ctl_addr[i]);
+               if (this->cmd_port[i])
+                       release_region(this->cmd_port[i], 8);
        }
+}
 
-       bmdma = pcim_iomap(pdev, 4, 16); /* may fail */
-
-       /* alloc and init probe_ent */
-       probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
-       if (!probe_ent)
-               return NULL;
-
-       probe_ent->n_ports = 2;
-       probe_ent->irq_flags = IRQF_SHARED;
-
-       if (port_mask & ATA_PORT_PRIMARY) {
-               probe_ent->irq = ATA_PRIMARY_IRQ(pdev);
-               probe_ent->port[0].cmd_addr = iomap[0];
-               probe_ent->port[0].altstatus_addr =
-               probe_ent->port[0].ctl_addr = iomap[1];
-               if (bmdma) {
-                       probe_ent->port[0].bmdma_addr = bmdma;
-                       if ((!(port[0]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
-                           (ioread8(bmdma + 2) & 0x80))
-                               probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
-               }
-               ata_std_ports(&probe_ent->port[0]);
-       } else
-               probe_ent->dummy_port_mask |= ATA_PORT_PRIMARY;
+static int ata_init_legacy_port(struct ata_port *ap,
+                               struct ata_legacy_devres *legacy_dr)
+{
+       struct ata_host *host = ap->host;
+       int port_no = ap->port_no;
+       unsigned long cmd_port, ctl_port;
+
+       if (port_no == 0) {
+               cmd_port = ATA_PRIMARY_CMD;
+               ctl_port = ATA_PRIMARY_CTL;
+       } else {
+               cmd_port = ATA_SECONDARY_CMD;
+               ctl_port = ATA_SECONDARY_CTL;
+       }
 
-       if (port_mask & ATA_PORT_SECONDARY) {
-               if (probe_ent->irq)
-                       probe_ent->irq2 = ATA_SECONDARY_IRQ(pdev);
+       /* request cmd_port */
+       if (request_region(cmd_port, 8, "libata"))
+               legacy_dr->cmd_port[port_no] = cmd_port;
+       else {
+               dev_printk(KERN_WARNING, host->dev,
+                          "0x%0lX IDE port busy\n", cmd_port);
+               return -EBUSY;
+       }
+
+       /* iomap cmd and ctl ports */
+       legacy_dr->cmd_addr[port_no] = ioport_map(cmd_port, 8);
+       legacy_dr->ctl_addr[port_no] = ioport_map(ctl_port, 1);
+       if (!legacy_dr->cmd_addr[port_no] || !legacy_dr->ctl_addr[port_no])
+               return -ENOMEM;
+
+       /* init IO addresses */
+       ap->ioaddr.cmd_addr = legacy_dr->cmd_addr[port_no];
+       ap->ioaddr.altstatus_addr = legacy_dr->ctl_addr[port_no];
+       ap->ioaddr.ctl_addr = legacy_dr->ctl_addr[port_no];
+       ata_std_ports(&ap->ioaddr);
+
+       return 0;
+}
+
+/**
+ *     ata_init_legacy_host - acquire legacy ATA resources and init ATA host
+ *     @host: target ATA host
+ *     @legacy_mask: out parameter, mask indicating ports is in legacy mode
+ *     @was_busy: out parameter, indicates whether any port was busy
+ *
+ *     Acquire legacy ATA resources for ports.
+ *
+ *     LOCKING:
+ *     Inherited from calling layer (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
+ */
+static int ata_init_legacy_host(struct ata_host *host,
+                               unsigned int *legacy_mask, int *was_busy)
+{
+       struct device *gdev = host->dev;
+       struct ata_legacy_devres *legacy_dr;
+       int i, rc;
+
+       if (!devres_open_group(gdev, NULL, GFP_KERNEL))
+               return -ENOMEM;
+
+       rc = -ENOMEM;
+       legacy_dr = devres_alloc(ata_legacy_release, sizeof(*legacy_dr),
+                                GFP_KERNEL);
+       if (!legacy_dr)
+               goto err_out;
+       devres_add(gdev, legacy_dr);
+
+       for (i = 0; i < 2; i++) {
+               *legacy_mask &= ~(1 << i);
+               rc = ata_init_legacy_port(host->ports[i], legacy_dr);
+               if (rc == 0)
+                       legacy_dr->mask |= 1 << i;
+               else if (rc == -EBUSY)
+                       (*was_busy)++;
+       }
+
+       if (!legacy_dr->mask)
+               return -EBUSY;
+
+       for (i = 0; i < 2; i++)
+               if (!(legacy_dr->mask & (1 << i)))
+                       host->ports[i]->ops = &ata_dummy_port_ops;
+
+       *legacy_mask |= legacy_dr->mask;
+
+       devres_remove_group(gdev, NULL);
+       return 0;
+
+ err_out:
+       devres_release_group(gdev, NULL);
+       return rc;
+}
+
+/**
+ *     ata_request_legacy_irqs - request legacy ATA IRQs
+ *     @host: target ATA host
+ *     @handler: array of IRQ handlers
+ *     @irq_flags: array of IRQ flags
+ *     @dev_id: array of IRQ dev_ids
+ *
+ *     Request legacy IRQs for non-dummy legacy ports in @host.  All
+ *     IRQ parameters are passed as array to allow ports to have
+ *     separate IRQ handlers.
+ *
+ *     LOCKING:
+ *     Inherited from calling layer (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
+ */
+static int ata_request_legacy_irqs(struct ata_host *host,
+                                  irq_handler_t const *handler,
+                                  const unsigned int *irq_flags,
+                                  void * const *dev_id)
+{
+       struct device *gdev = host->dev;
+       struct ata_legacy_devres *legacy_dr;
+       int i, rc;
+
+       legacy_dr = devres_find(host->dev, ata_legacy_release, NULL, NULL);
+       BUG_ON(!legacy_dr);
+
+       for (i = 0; i < 2; i++) {
+               unsigned int irq;
+
+               /* FIXME: ATA_*_IRQ() should take generic device not pci_dev */
+               if (i == 0)
+                       irq = ATA_PRIMARY_IRQ(to_pci_dev(gdev));
                else
-                       probe_ent->irq = ATA_SECONDARY_IRQ(pdev);
-               probe_ent->port[1].cmd_addr = iomap[2];
-               probe_ent->port[1].altstatus_addr =
-               probe_ent->port[1].ctl_addr = iomap[3];
-               if (bmdma) {
-                       probe_ent->port[1].bmdma_addr = bmdma + 8;
-                       if ((!(port[1]->flags & ATA_FLAG_IGN_SIMPLEX)) &&
-                           (ioread8(bmdma + 10) & 0x80))
-                               probe_ent->_host_flags |= ATA_HOST_SIMPLEX;
+                       irq = ATA_SECONDARY_IRQ(to_pci_dev(gdev));
+
+               if (!(legacy_dr->mask & (1 << i)))
+                       continue;
+
+               if (!handler[i]) {
+                       dev_printk(KERN_ERR, gdev,
+                                  "NULL handler specified for port %d\n", i);
+                       rc = -EINVAL;
+                       goto err_out;
+               }
+
+               rc = request_irq(irq, handler[i], irq_flags[i], DRV_NAME,
+                                dev_id[i]);
+               if (rc) {
+                       dev_printk(KERN_ERR, gdev,
+                               "irq %u request failed (errno=%d)\n", irq, rc);
+                       goto err_out;
                }
-               ata_std_ports(&probe_ent->port[1]);
 
-               /* FIXME: could be pointing to stack area; must copy */
-               probe_ent->pinfo2 = port[1];
-       } else
-               probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY;
+               /* record irq allocation in legacy_dr */
+               legacy_dr->irq[i] = irq;
+               legacy_dr->irq_dev_id[i] = dev_id[i];
 
-       return probe_ent;
-}
+               /* only used to print info */
+               if (i == 0)
+                       host->irq = irq;
+               else
+                       host->irq2 = irq;
+       }
 
+       return 0;
+
+ err_out:
+       ata_legacy_free_irqs(legacy_dr);
+       return rc;
+}
 
 /**
  *     ata_pci_init_one - Initialize/register PCI IDE host controller
@@ -718,8 +949,8 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                      unsigned int n_ports)
 {
        struct device *dev = &pdev->dev;
-       struct ata_probe_ent *probe_ent = NULL;
-       struct ata_port_info *port[2];
+       struct ata_host *host = NULL;
+       const struct ata_port_info *port[2];
        u8 mask;
        unsigned int legacy_mode = 0;
        int rc;
@@ -743,7 +974,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
 
           Checking dev->is_enabled is insufficient as this is not set at
           boot for the primary video which is BIOS enabled
-         */
+         */
 
        rc = pcim_enable_device(pdev);
        if (rc)
@@ -769,96 +1000,68 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
 #endif
        }
 
+       /* alloc and init host */
+       host = ata_host_alloc_pinfo(dev, port, 2);
+       if (!host) {
+               dev_printk(KERN_ERR, &pdev->dev,
+                          "failed to allocate ATA host\n");
+               rc = -ENOMEM;
+               goto err_out;
+       }
+
        if (!legacy_mode) {
-               rc = pci_request_regions(pdev, DRV_NAME);
-               if (rc) {
-                       pcim_pin_device(pdev);
+               unsigned int port_mask;
+
+               port_mask = ATA_PORT_PRIMARY;
+               if (n_ports > 1)
+                       port_mask |= ATA_PORT_SECONDARY;
+
+               rc = ata_pci_init_native_host(host, port_mask);
+               if (rc)
                        goto err_out;
-               }
        } else {
-               /* Deal with combined mode hack. This side of the logic all
-                  goes away once the combined mode hack is killed in 2.6.21 */
-               if (!devm_request_region(dev, ATA_PRIMARY_CMD, 8, "libata")) {
-                       struct resource *conflict, res;
-                       res.start = ATA_PRIMARY_CMD;
-                       res.end = ATA_PRIMARY_CMD + 8 - 1;
-                       conflict = ____request_resource(&ioport_resource, &res);
-                       while (conflict->child)
-                               conflict = ____request_resource(conflict, &res);
-                       if (!strcmp(conflict->name, "libata"))
-                               legacy_mode |= ATA_PORT_PRIMARY;
-                       else {
-                               pcim_pin_device(pdev);
-                               printk(KERN_WARNING "ata: 0x%0X IDE port busy\n" \
-                                                   "ata: conflict with %s\n",
-                                                   ATA_PRIMARY_CMD,
-                                                   conflict->name);
-                       }
-               } else
-                       legacy_mode |= ATA_PORT_PRIMARY;
-
-               if (!devm_request_region(dev, ATA_SECONDARY_CMD, 8, "libata")) {
-                       struct resource *conflict, res;
-                       res.start = ATA_SECONDARY_CMD;
-                       res.end = ATA_SECONDARY_CMD + 8 - 1;
-                       conflict = ____request_resource(&ioport_resource, &res);
-                       while (conflict->child)
-                               conflict = ____request_resource(conflict, &res);
-                       if (!strcmp(conflict->name, "libata"))
-                               legacy_mode |= ATA_PORT_SECONDARY;
-                       else {
-                               pcim_pin_device(pdev);
-                               printk(KERN_WARNING "ata: 0x%X IDE port busy\n" \
-                                                   "ata: conflict with %s\n",
-                                                   ATA_SECONDARY_CMD,
-                                                   conflict->name);
-                       }
-               } else
-                       legacy_mode |= ATA_PORT_SECONDARY;
-
-               if (legacy_mode & ATA_PORT_PRIMARY)
-                       pci_request_region(pdev, 1, DRV_NAME);
-               if (legacy_mode & ATA_PORT_SECONDARY)
-                       pci_request_region(pdev, 3, DRV_NAME);
-               /* If there is a DMA resource, allocate it */
-               pci_request_region(pdev, 4, DRV_NAME);
-       }
+               int was_busy = 0;
 
-       /* we have legacy mode, but all ports are unavailable */
-       if (legacy_mode == (1 << 3)) {
-               rc = -EBUSY;
-               goto err_out;
+               rc = ata_init_legacy_host(host, &legacy_mode, &was_busy);
+               if (was_busy)
+                       pcim_pin_device(pdev);
+               if (rc)
+                       goto err_out;
+
+               /* request respective PCI regions, may fail */
+               rc = pci_request_region(pdev, 1, DRV_NAME);
+               rc = pci_request_region(pdev, 3, DRV_NAME);
        }
 
-       /* TODO: If we get no DMA mask we should fall back to PIO */
-       rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
-       if (rc)
-               goto err_out;
-       rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+       /* init BMDMA, may fail */
+       ata_pci_init_bmdma(host);
+       pci_set_master(pdev);
+
+       /* start host and request IRQ */
+       rc = ata_host_start(host);
        if (rc)
                goto err_out;
 
-       if (legacy_mode) {
-               probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode);
-       } else {
-               if (n_ports == 2)
-                       probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
-               else
-                       probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY);
+       if (!legacy_mode)
+               rc = devm_request_irq(dev, pdev->irq,
+                                     port_info[0]->port_ops->irq_handler,
+                                     IRQF_SHARED, DRV_NAME, host);
+       else {
+               irq_handler_t handler[2] = { host->ops->irq_handler,
+                                            host->ops->irq_handler };
+               unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED };
+               void *dev_id[2] = { host, host };
+
+               rc = ata_request_legacy_irqs(host, handler, irq_flags, dev_id);
        }
-       if (!probe_ent) {
-               rc = -ENOMEM;
+       if (rc)
                goto err_out;
-       }
-
-       pci_set_master(pdev);
 
-       if (!ata_device_add(probe_ent)) {
-               rc = -ENODEV;
+       /* register */
+       rc = ata_host_register(host, port_info[0]->sht);
+       if (rc)
                goto err_out;
-       }
 
-       devm_kfree(dev, probe_ent);
        devres_remove_group(dev, NULL);
        return 0;
 
@@ -893,12 +1096,12 @@ int ata_pci_clear_simplex(struct pci_dev *pdev)
        return 0;
 }
 
-unsigned long ata_pci_default_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long xfer_mask)
+unsigned long ata_pci_default_filter(struct ata_device *adev, unsigned long xfer_mask)
 {
        /* Filter out DMA modes if the device has been configured by
           the BIOS as PIO only */
 
-       if (ap->ioaddr.bmdma_addr == 0)
+       if (adev->ap->ioaddr.bmdma_addr == 0)
                xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
        return xfer_mask;
 }
index 1f1e3a51f85965f7cebadb3f6b10cfbdb07afb29..5f4d40cd32888a9aaae5c3dc76a2bb3d84bd69aa 100644 (file)
@@ -52,6 +52,7 @@ enum {
        ATA_DNXFER_QUIET        = (1 << 31),
 };
 
+extern unsigned int ata_print_id;
 extern struct workqueue_struct *ata_aux_wq;
 extern int atapi_enabled;
 extern int atapi_dmadir;
@@ -92,10 +93,7 @@ extern int ata_flush_cache(struct ata_device *dev);
 extern void ata_dev_init(struct ata_device *dev);
 extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg);
 extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
-extern void ata_port_init(struct ata_port *ap, struct ata_host *host,
-                         const struct ata_probe_ent *ent, unsigned int port_no);
-extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev,
-                                                const struct ata_port_info *port);
+extern struct ata_port *ata_port_alloc(struct ata_host *host);
 
 /* libata-acpi.c */
 #ifdef CONFIG_SATA_ACPI
@@ -113,8 +111,8 @@ static inline int ata_acpi_push_id(struct ata_port *ap, unsigned int ix)
 #endif
 
 /* libata-scsi.c */
-extern struct scsi_transport_template ata_scsi_transport_template;
-
+extern int ata_scsi_add_hosts(struct ata_host *host,
+                             struct scsi_host_template *sht);
 extern void ata_scsi_scan_host(struct ata_port *ap);
 extern int ata_scsi_offline_dev(struct ata_device *dev);
 extern void ata_scsi_hotplug(struct work_struct *work);
index 11ea552a58cac00507f7853e1e53a598ec5afe41..d40edebb510a59ba41b6fbbd1600a8d9530a19a8 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/dmi.h>
 
 #define DRV_NAME "pata_ali"
-#define DRV_VERSION "0.7.3"
+#define DRV_VERSION "0.7.4"
 
 /*
  *     Cable special cases
@@ -89,59 +89,6 @@ static int ali_c2_cable_detect(struct ata_port *ap)
                return ATA_CBL_PATA80;
 }
 
-/**
- *     ali_early_error_handler -       reset for eary chip
- *     @ap: ATA port
- *
- *     Handle the reset callback for the later chips with cable detect
- */
-
-static int ali_c2_pre_reset(struct ata_port *ap)
-{
-       ap->cbl = ali_c2_cable_detect(ap);
-       return ata_std_prereset(ap);
-}
-
-static void ali_c2_error_handler(struct ata_port *ap)
-{
-       ata_bmdma_drive_eh(ap, ali_c2_pre_reset,
-                              ata_std_softreset, NULL,
-                              ata_std_postreset);
-}
-
-/**
- *     ali_early_cable_detect  -       cable detection
- *     @ap: ATA port
- *
- *     Perform cable detection for older chipsets. This turns out to be
- *     rather easy to implement
- */
-
-static int ali_early_cable_detect(struct ata_port *ap)
-{
-       return ATA_CBL_PATA40;
-}
-
-/**
- *     ali_early_probe_init    -       reset for early chip
- *     @ap: ATA port
- *
- *     Handle the reset callback for the early (pre cable detect) chips.
- */
-
-static int ali_early_pre_reset(struct ata_port *ap)
-{
-       ap->cbl = ali_early_cable_detect(ap);
-       return ata_std_prereset(ap);
-}
-
-static void ali_early_error_handler(struct ata_port *ap)
-{
-       return ata_bmdma_drive_eh(ap, ali_early_pre_reset,
-                                    ata_std_softreset, NULL,
-                                    ata_std_postreset);
-}
-
 /**
  *     ali_20_filter           -       filter for earlier ALI DMA
  *     @ap: ALi ATA port
@@ -151,7 +98,7 @@ static void ali_early_error_handler(struct ata_port *ap)
  *     fix that later on. Also ensure we do not do UDMA on WDC drives
  */
 
-static unsigned long ali_20_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
+static unsigned long ali_20_filter(struct ata_device *adev, unsigned long mask)
 {
        char model_num[ATA_ID_PROD_LEN + 1];
        /* No DMA on anything but a disk for now */
@@ -160,7 +107,7 @@ static unsigned long ali_20_filter(const struct ata_port *ap, struct ata_device
        ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
        if (strstr(model_num, "WDC"))
                return mask &= ~ATA_MASK_UDMA;
-       return ata_pci_default_filter(ap, adev, mask);
+       return ata_pci_default_filter(adev, mask);
 }
 
 /**
@@ -314,7 +261,6 @@ static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev)
 
 /**
  *     ali_lock_sectors        -       Keep older devices to 255 sector mode
- *     @ap: ATA port
  *     @adev: Device
  *
  *     Called during the bus probe for each device that is found. We use
@@ -324,7 +270,7 @@ static void ali_set_dmamode(struct ata_port *ap, struct ata_device *adev)
  *     slower PIO methods
  */
 
-static void ali_lock_sectors(struct ata_port *ap, struct ata_device *adev)
+static void ali_lock_sectors(struct ata_device *adev)
 {
        adev->max_sectors = 255;
 }
@@ -366,8 +312,9 @@ static struct ata_port_operations ali_early_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = ali_early_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
@@ -402,8 +349,9 @@ static struct ata_port_operations ali_20_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = ali_early_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -440,8 +388,9 @@ static struct ata_port_operations ali_c2_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = ali_c2_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ali_c2_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -477,8 +426,9 @@ static struct ata_port_operations ali_c5_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = ali_c2_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ali_c2_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
index 18381762908bf8b474918bc5c4f93c5fcca7026c..536ee892ab72da7aa2b789010c1bf60381de893d 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_amd"
-#define DRV_VERSION "0.2.8"
+#define DRV_VERSION "0.3.8"
 
 /**
  *     timing_setup            -       shared timing computation and load
@@ -119,32 +119,25 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse
 }
 
 /**
- *     amd_probe_init          -       cable detection
+ *     amd_probe_init          -       perform reset handling
  *     @ap: ATA port
  *
- *     Perform cable detection. The BIOS stores this in PCI config
- *     space for us.
+ *     Reset sequence checking enable bits to see which ports are
+ *     active.
  */
 
 static int amd_pre_reset(struct ata_port *ap)
 {
-       static const u32 bitmask[2] = {0x03, 0x0C};
        static const struct pci_bits amd_enable_bits[] = {
                { 0x40, 1, 0x02, 0x02 },
                { 0x40, 1, 0x01, 0x01 }
        };
 
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-       u8 ata66;
 
        if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no]))
                return -ENOENT;
 
-       pci_read_config_byte(pdev, 0x42, &ata66);
-       if (ata66 & bitmask[ap->port_no])
-               ap->cbl = ATA_CBL_PATA80;
-       else
-               ap->cbl = ATA_CBL_PATA40;
        return ata_std_prereset(ap);
 
 }
@@ -156,28 +149,16 @@ static void amd_error_handler(struct ata_port *ap)
                                      ata_std_postreset);
 }
 
-static int amd_early_pre_reset(struct ata_port *ap)
+static int amd_cable_detect(struct ata_port *ap)
 {
+       static const u32 bitmask[2] = {0x03, 0x0C};
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-       static struct pci_bits amd_enable_bits[] = {
-               { 0x40, 1, 0x02, 0x02 },
-               { 0x40, 1, 0x01, 0x01 }
-       };
-
-       if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no]))
-               return -ENOENT;
-
-       /* No host side cable detection */
-       ap->cbl = ATA_CBL_PATA80;
-       return ata_std_prereset(ap);
-
-}
+       u8 ata66;
 
-static void amd_early_error_handler(struct ata_port *ap)
-{
-       ata_bmdma_drive_eh(ap, amd_early_pre_reset,
-                              ata_std_softreset, NULL,
-                              ata_std_postreset);
+       pci_read_config_byte(pdev, 0x42, &ata66);
+       if (ata66 & bitmask[ap->port_no])
+               return ATA_CBL_PATA80;
+       return ATA_CBL_PATA40;
 }
 
 /**
@@ -247,31 +228,16 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev)
  */
 
 static int nv_pre_reset(struct ata_port *ap) {
-       static const u8 bitmask[2] = {0x03, 0x0C};
        static const struct pci_bits nv_enable_bits[] = {
                { 0x50, 1, 0x02, 0x02 },
                { 0x50, 1, 0x01, 0x01 }
        };
 
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-       u8 ata66;
-       u16 udma;
 
        if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no]))
                return -ENOENT;
 
-       pci_read_config_byte(pdev, 0x52, &ata66);
-       if (ata66 & bitmask[ap->port_no])
-               ap->cbl = ATA_CBL_PATA80;
-       else
-               ap->cbl = ATA_CBL_PATA40;
-
-       /* We now have to double check because the Nvidia boxes BIOS
-          doesn't always set the cable bits but does set mode bits */
-
-       pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma);
-       if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400)
-               ap->cbl = ATA_CBL_PATA80;
        return ata_std_prereset(ap);
 }
 
@@ -281,6 +247,29 @@ static void nv_error_handler(struct ata_port *ap)
                               ata_std_softreset, NULL,
                               ata_std_postreset);
 }
+
+static int nv_cable_detect(struct ata_port *ap)
+{
+       static const u8 bitmask[2] = {0x03, 0x0C};
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+       u8 ata66;
+       u16 udma;
+       int cbl;
+
+       pci_read_config_byte(pdev, 0x52, &ata66);
+       if (ata66 & bitmask[ap->port_no])
+               cbl = ATA_CBL_PATA80;
+       else
+               cbl = ATA_CBL_PATA40;
+
+       /* We now have to double check because the Nvidia boxes BIOS
+          doesn't always set the cable bits but does set mode bits */
+       pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma);
+       if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400)
+               cbl = ATA_CBL_PATA80;
+       return cbl;
+}
+
 /**
  *     nv100_set_piomode       -       set initial PIO mode data
  *     @ap: ATA interface
@@ -353,8 +342,9 @@ static struct ata_port_operations amd33_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = amd_early_error_handler,
+       .error_handler  = amd_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -387,8 +377,9 @@ static struct ata_port_operations amd66_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = amd_early_error_handler,
+       .error_handler  = amd_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_unknown,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -423,6 +414,7 @@ static struct ata_port_operations amd100_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = amd_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_unknown,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -457,6 +449,7 @@ static struct ata_port_operations amd133_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = amd_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = amd_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -491,6 +484,7 @@ static struct ata_port_operations nv100_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = nv_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = nv_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -525,6 +519,7 @@ static struct ata_port_operations nv133_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = nv_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = nv_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
index 21c30282717ccafea9a541f9173552467bec932a..00e9ec342db001cda8e2ff32e9e29435f10fb92e 100644 (file)
@@ -49,8 +49,6 @@ static int artop6210_pre_reset(struct ata_port *ap)
 
        if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
                return -ENOENT;
-
-       ap->cbl = ATA_CBL_PATA40;
        return ata_std_prereset(ap);
 }
 
@@ -85,18 +83,28 @@ static int artop6260_pre_reset(struct ata_port *ap)
        };
 
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-       u8 tmp;
 
        /* Odd numbered device ids are the units with enable bits (the -R cards) */
        if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
                return -ENOENT;
+       return ata_std_prereset(ap);
+}
 
+/**
+ *     artop6260_cable_detect  -       identify cable type
+ *     @ap: Port
+ *
+ *     Identify the cable type for the ARTOp interface in question
+ */
+static int artop6260_cable_detect(struct ata_port *ap)
+{
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+       u8 tmp;
        pci_read_config_byte(pdev, 0x49, &tmp);
        if (tmp & (1 << ap->port_no))
-               ap->cbl = ATA_CBL_PATA40;
-       else
-               ap->cbl = ATA_CBL_PATA80;
-       return ata_std_prereset(ap);
+               return ATA_CBL_PATA40;
+       return ATA_CBL_PATA80;
 }
 
 /**
@@ -225,7 +233,7 @@ static void artop6260_set_piomode(struct ata_port *ap, struct ata_device *adev)
 /**
  *     artop6210_set_dmamode - Initialize host controller PATA PIO timings
  *     @ap: Port whose timings we are configuring
- *     @adev: um
+ *     @adev: Device whose timings we are configuring
  *
  *     Set DMA mode for device, in host controller PCI config space.
  *
@@ -333,6 +341,7 @@ static const struct ata_port_operations artop6210_ops = {
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = artop6210_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = ata_cable_40wire,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
@@ -366,6 +375,7 @@ static const struct ata_port_operations artop6260_ops = {
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = artop6260_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = artop6260_cable_detect,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
index 51d9923be02efe9e03f75b107f7ba97581f4db60..39c871a3ddac9578fb8a3be5437eb2ecc69667b4 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_atiixp"
-#define DRV_VERSION "0.4.4"
+#define DRV_VERSION "0.4.5"
 
 enum {
        ATIIXP_IDE_PIO_TIMING   = 0x40,
@@ -35,23 +35,15 @@ enum {
 
 static int atiixp_pre_reset(struct ata_port *ap)
 {
-       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        static const struct pci_bits atiixp_enable_bits[] = {
                { 0x48, 1, 0x01, 0x00 },
                { 0x48, 1, 0x08, 0x00 }
        };
-       u8 udma;
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
        if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no]))
                return -ENOENT;
 
-       /* Hack from drivers/ide/pci. Really we want to know how to do the
-          raw detection not play follow the bios mode guess */
-       pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma);
-       if ((udma & 0x07) >= 0x04 || (udma & 0x70) >= 0x40)
-               ap->cbl = ATA_CBL_PATA80;
-       else
-               ap->cbl = ATA_CBL_PATA40;
        return ata_std_prereset(ap);
 }
 
@@ -60,6 +52,19 @@ static void atiixp_error_handler(struct ata_port *ap)
        ata_bmdma_drive_eh(ap, atiixp_pre_reset, ata_std_softreset, NULL,   ata_std_postreset);
 }
 
+static int atiixp_cable_detect(struct ata_port *ap)
+{
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+       u8 udma;
+
+       /* Hack from drivers/ide/pci. Really we want to know how to do the
+          raw detection not play follow the bios mode guess */
+       pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ap->port_no, &udma);
+       if ((udma & 0x07) >= 0x04 || (udma & 0x70) >= 0x40)
+               return  ATA_CBL_PATA80;
+       return ATA_CBL_PATA40;
+}
+
 /**
  *     atiixp_set_pio_timing   -       set initial PIO mode data
  *     @ap: ATA interface
@@ -245,6 +250,7 @@ static struct ata_port_operations atiixp_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = atiixp_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = atiixp_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = atiixp_bmdma_start,
diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c
new file mode 100644 (file)
index 0000000..2105985
--- /dev/null
@@ -0,0 +1,312 @@
+/*
+ * pata_cmd640.c       - CMD640 PCI PATA for new ATA layer
+ *                       (C) 2007 Red Hat Inc
+ *                       Alan Cox <alan@redhat.com>
+ *
+ * Based upon
+ *  linux/drivers/ide/pci/cmd640.c             Version 1.02  Sep 01, 1996
+ *
+ *  Copyright (C) 1995-1996  Linus Torvalds & authors (see driver)
+ *
+ *     This drives only the PCI version of the controller. If you have a
+ *     VLB one then we have enough docs to support it but you can write
+ *     your own code.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+
+#define DRV_NAME "pata_cmd640"
+#define DRV_VERSION "0.0.5"
+
+struct cmd640_reg {
+       int last;
+       u8 reg58[ATA_MAX_DEVICES];
+};
+
+enum {
+       CFR = 0x50,
+       CNTRL = 0x51,
+       CMDTIM = 0x52,
+       ARTIM0 = 0x53,
+       DRWTIM0 = 0x54,
+       ARTIM23 = 0x57,
+       DRWTIM23 = 0x58,
+       BRST = 0x59
+};
+
+/**
+ *     cmd640_set_piomode      -       set initial PIO mode data
+ *     @ap: ATA port
+ *     @adev: ATA device
+ *
+ *     Called to do the PIO mode setup.
+ */
+
+static void cmd640_set_piomode(struct ata_port *ap, struct ata_device *adev)
+{
+       struct cmd640_reg *timing = ap->private_data;
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+       struct ata_timing t;
+       const unsigned long T = 1000000 / 33;
+       const u8 setup_data[] = { 0x40, 0x40, 0x40, 0x80, 0x00 };
+       u8 reg;
+       int arttim = ARTIM0 + 2 * adev->devno;
+       struct ata_device *pair = ata_dev_pair(adev);
+
+       if (ata_timing_compute(adev, adev->pio_mode, &t, T, 0) < 0) {
+               printk(KERN_ERR DRV_NAME ": mode computation failed.\n");
+               return;
+       }
+
+       /* The second channel has shared timings and the setup timing is
+          messy to switch to merge it for worst case */
+       if (ap->port_no && pair) {
+               struct ata_timing p;
+               ata_timing_compute(pair, pair->pio_mode, &p, T, 1);
+               ata_timing_merge(&p, &t, &t, ATA_TIMING_SETUP);
+       }
+
+       /* Make the timings fit */
+       if (t.recover > 16) {
+               t.active += t.recover - 16;
+               t.recover = 16;
+       }
+       if (t.active > 16)
+               t.active = 16;
+
+       /* Now convert the clocks into values we can actually stuff into
+          the chip */
+
+       if (t.recover > 1)
+               t.recover--;    /* 640B only */
+       else
+               t.recover = 15;
+
+       if (t.setup > 4)
+               t.setup = 0xC0;
+       else
+               t.setup = setup_data[t.setup];
+
+       if (ap->port_no == 0) {
+               t.active &= 0x0F;       /* 0 = 16 */
+
+               /* Load setup timing */
+               pci_read_config_byte(pdev, arttim, &reg);
+               reg &= 0x3F;
+               reg |= t.setup;
+               pci_write_config_byte(pdev, arttim, reg);
+
+               /* Load active/recovery */
+               pci_write_config_byte(pdev, arttim + 1, (t.active << 4) | t.recover);
+       } else {
+               /* Save the shared timings for channel, they will be loaded
+                  by qc_issue_prot. Reloading the setup time is expensive 
+                  so we keep a merged one loaded */
+               pci_read_config_byte(pdev, ARTIM23, &reg);
+               reg &= 0x3F;
+               reg |= t.setup;
+               pci_write_config_byte(pdev, ARTIM23, reg);
+               timing->reg58[adev->devno] = (t.active << 4) | t.recover;
+       }
+}
+
+
+/**
+ *     cmd640_qc_issue_prot    -       command preparation hook
+ *     @qc: Command to be issued
+ *
+ *     Channel 1 has shared timings. We must reprogram the
+ *     clock each drive 2/3 switch we do.
+ */
+
+static unsigned int cmd640_qc_issue_prot(struct ata_queued_cmd *qc)
+{
+       struct ata_port *ap = qc->ap;
+       struct ata_device *adev = qc->dev;
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+       struct cmd640_reg *timing = ap->private_data;
+
+       if (ap->port_no != 0 && adev->devno != timing->last) {
+               pci_write_config_byte(pdev, DRWTIM23, timing->reg58[adev->devno]);
+               timing->last = adev->devno;
+       }
+       return ata_qc_issue_prot(qc);
+}
+
+/**
+ *     cmd640_port_start       -       port setup
+ *     @ap: ATA port being set up
+ *
+ *     The CMD640 needs to maintain private data structures so we
+ *     allocate space here.
+ */
+
+static int cmd640_port_start(struct ata_port *ap)
+{
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+       struct cmd640_reg *timing;
+
+       int ret = ata_port_start(ap);
+       if (ret < 0)
+               return ret;
+
+       timing = devm_kzalloc(&pdev->dev, sizeof(struct cmd640_reg), GFP_KERNEL);
+       if (timing == NULL)
+               return -ENOMEM;
+       timing->last = -1;      /* Force a load */
+       ap->private_data = timing;
+       return ret;
+}
+
+static struct scsi_host_template cmd640_sht = {
+       .module                 = THIS_MODULE,
+       .name                   = DRV_NAME,
+       .ioctl                  = ata_scsi_ioctl,
+       .queuecommand           = ata_scsi_queuecmd,
+       .can_queue              = ATA_DEF_QUEUE,
+       .this_id                = ATA_SHT_THIS_ID,
+       .sg_tablesize           = LIBATA_MAX_PRD,
+       .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
+       .emulated               = ATA_SHT_EMULATED,
+       .use_clustering         = ATA_SHT_USE_CLUSTERING,
+       .proc_name              = DRV_NAME,
+       .dma_boundary           = ATA_DMA_BOUNDARY,
+       .slave_configure        = ata_scsi_slave_config,
+       .slave_destroy          = ata_scsi_slave_destroy,
+       .bios_param             = ata_std_bios_param,
+#ifdef CONFIG_PM
+       .resume                 = ata_scsi_device_resume,
+       .suspend                = ata_scsi_device_suspend,
+#endif
+};
+
+static struct ata_port_operations cmd640_port_ops = {
+       .port_disable   = ata_port_disable,
+       .set_piomode    = cmd640_set_piomode,
+       .mode_filter    = ata_pci_default_filter,
+       .tf_load        = ata_tf_load,
+       .tf_read        = ata_tf_read,
+       .check_status   = ata_check_status,
+       .exec_command   = ata_exec_command,
+       .dev_select     = ata_std_dev_select,
+
+       .freeze         = ata_bmdma_freeze,
+       .thaw           = ata_bmdma_thaw,
+       .error_handler  = ata_bmdma_error_handler,
+       .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
+
+       .bmdma_setup    = ata_bmdma_setup,
+       .bmdma_start    = ata_bmdma_start,
+       .bmdma_stop     = ata_bmdma_stop,
+       .bmdma_status   = ata_bmdma_status,
+
+       .qc_prep        = ata_qc_prep,
+       .qc_issue       = cmd640_qc_issue_prot,
+
+       /* In theory this is not needed once we kill the prefetcher */
+       .data_xfer      = ata_data_xfer_noirq,
+
+       .irq_handler    = ata_interrupt,
+       .irq_clear      = ata_bmdma_irq_clear,
+       .irq_on         = ata_irq_on,
+       .irq_ack        = ata_irq_ack,
+
+       .port_start     = cmd640_port_start,
+};
+
+static void cmd640_hardware_init(struct pci_dev *pdev)
+{
+       u8 r;
+       u8 ctrl;
+
+       /* CMD640 detected, commiserations */
+       pci_write_config_byte(pdev, 0x5B, 0x00);
+       /* Get version info */
+       pci_read_config_byte(pdev, CFR, &r);
+       /* PIO0 command cycles */
+       pci_write_config_byte(pdev, CMDTIM, 0);
+       /* 512 byte bursts (sector) */
+       pci_write_config_byte(pdev, BRST, 0x40);
+       /* 
+        * A reporter a long time ago
+        * Had problems with the data fifo
+        * So don't run the risk
+        * Of putting crap on the disk
+        * For its better just to go slow
+        */
+       /* Do channel 0 */
+       pci_read_config_byte(pdev, CNTRL, &ctrl);
+       pci_write_config_byte(pdev, CNTRL, ctrl | 0xC0);
+       /* Ditto for channel 1 */
+       pci_read_config_byte(pdev, ARTIM23, &ctrl);
+       ctrl |= 0x0C;
+       pci_write_config_byte(pdev, ARTIM23, ctrl);
+}
+
+static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+       static struct ata_port_info info = {
+               .sht = &cmd640_sht,
+               .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
+               .pio_mask = 0x1f,
+               .port_ops = &cmd640_port_ops
+       };
+
+       static struct ata_port_info *port_info[2] = { &info, &info };
+
+       cmd640_hardware_init(pdev);
+       return ata_pci_init_one(pdev, port_info, 2);
+}
+
+static int cmd640_reinit_one(struct pci_dev *pdev)
+{
+       cmd640_hardware_init(pdev);
+#ifdef CONFIG_PM
+       return ata_pci_device_resume(pdev);
+#else
+       return 0;
+#endif
+}
+
+static const struct pci_device_id cmd640[] = {
+       { PCI_VDEVICE(CMD, 0x640), 0 },
+       { },
+};
+
+static struct pci_driver cmd640_pci_driver = {
+       .name           = DRV_NAME,
+       .id_table       = cmd640,
+       .probe          = cmd640_init_one,
+       .remove         = ata_pci_remove_one,
+#ifdef CONFIG_PM
+       .suspend        = ata_pci_device_suspend,
+#endif
+       .resume         = cmd640_reinit_one,
+};
+
+static int __init cmd640_init(void)
+{
+       return pci_register_driver(&cmd640_pci_driver);
+}
+
+static void __exit cmd640_exit(void)
+{
+       pci_unregister_driver(&cmd640_pci_driver);
+}
+
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("low-level driver for CMD640 PATA controllers");
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pci, cmd640);
+MODULE_VERSION(DRV_VERSION);
+
+module_init(cmd640_init);
+module_exit(cmd640_exit);
index 5b13bdd1edc0863049143034b7b23b8d1ef60b3a..3989cc577fcd503b6e073a001f89eb72d935b6f0 100644 (file)
@@ -75,13 +75,7 @@ enum {
        DTPR1           = 0x7C
 };
 
-static int cmd64x_pre_reset(struct ata_port *ap)
-{
-       ap->cbl = ATA_CBL_PATA40;
-       return ata_std_prereset(ap);
-}
-
-static int cmd648_pre_reset(struct ata_port *ap)
+static int cmd648_cable_detect(struct ata_port *ap)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u8 r;
@@ -89,21 +83,8 @@ static int cmd648_pre_reset(struct ata_port *ap)
        /* Check cable detect bits */
        pci_read_config_byte(pdev, BMIDECSR, &r);
        if (r & (1 << ap->port_no))
-               ap->cbl = ATA_CBL_PATA80;
-       else
-               ap->cbl = ATA_CBL_PATA40;
-
-       return ata_std_prereset(ap);
-}
-
-static void cmd64x_error_handler(struct ata_port *ap)
-{
-       return ata_bmdma_drive_eh(ap, cmd64x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
-static void cmd648_error_handler(struct ata_port *ap)
-{
-       ata_bmdma_drive_eh(ap, cmd648_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+               return ATA_CBL_PATA80;
+       return ATA_CBL_PATA40;
 }
 
 /**
@@ -304,8 +285,9 @@ static struct ata_port_operations cmd64x_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = cmd64x_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -338,8 +320,9 @@ static struct ata_port_operations cmd646r1_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = cmd64x_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -372,8 +355,9 @@ static struct ata_port_operations cmd648_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = cmd648_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = cmd648_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
index 55cc293e74873d176aa78606f16253c0d5b82422..79bef0d1fad337106eb77d419bf192090834fc80 100644 (file)
@@ -139,18 +139,6 @@ static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev)
        cs5520_set_timings(ap, adev, adev->pio_mode);
 }
 
-
-static int cs5520_pre_reset(struct ata_port *ap)
-{
-       ap->cbl = ATA_CBL_PATA40;
-       return ata_std_prereset(ap);
-}
-
-static void cs5520_error_handler(struct ata_port *ap)
-{
-       return ata_bmdma_drive_eh(ap, cs5520_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
 static struct scsi_host_template cs5520_sht = {
        .module                 = THIS_MODULE,
        .name                   = DRV_NAME,
@@ -186,8 +174,9 @@ static struct ata_port_operations cs5520_port_ops = {
 
        .freeze                 = ata_bmdma_freeze,
        .thaw                   = ata_bmdma_thaw,
-       .error_handler          = cs5520_error_handler,
+       .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = ata_cable_40wire,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
@@ -197,7 +186,6 @@ static struct ata_port_operations cs5520_port_ops = {
        .qc_issue               = ata_qc_issue_prot,
        .data_xfer              = ata_data_xfer,
 
-       .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -205,91 +193,104 @@ static struct ata_port_operations cs5520_port_ops = {
        .port_start             = ata_port_start,
 };
 
-static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
+static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
 {
+       struct ata_port_info pi = {
+               .flags          = ATA_FLAG_SLAVE_POSS,
+               .pio_mask       = 0x1f,
+               .port_ops       = &cs5520_port_ops,
+       };
+       const struct ata_port_info *ppi[2];
        u8 pcicfg;
-       void __iomem *iomap[5];
-       static struct ata_probe_ent probe[2];
-       int ports = 0;
+       void *iomap[5];
+       struct ata_host *host;
+       struct ata_ioports *ioaddr;
+       int i, rc;
 
        /* IDE port enable bits */
-       pci_read_config_byte(dev, 0x60, &pcicfg);
+       pci_read_config_byte(pdev, 0x60, &pcicfg);
 
        /* Check if the ATA ports are enabled */
        if ((pcicfg & 3) == 0)
                return -ENODEV;
 
+       ppi[0] = ppi[1] = &ata_dummy_port_info;
+       if (pcicfg & 1)
+               ppi[0] = &pi;
+       if (pcicfg & 2)
+               ppi[1] = &pi;
+
        if ((pcicfg & 0x40) == 0) {
-               printk(KERN_WARNING DRV_NAME ": DMA mode disabled. Enabling.\n");
-               pci_write_config_byte(dev, 0x60, pcicfg | 0x40);
+               dev_printk(KERN_WARNING, &pdev->dev,
+                          "DMA mode disabled. Enabling.\n");
+               pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
        }
 
+       pi.mwdma_mask = id->driver_data;
+
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
+       if (!host)
+               return -ENOMEM;
+
        /* Perform set up for DMA */
-       if (pci_enable_device_bars(dev, 1<<2)) {
+       if (pci_enable_device_bars(pdev, 1<<2)) {
                printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n");
                return -ENODEV;
        }
-       pci_set_master(dev);
-       if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
+
+       if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
                printk(KERN_ERR DRV_NAME ": unable to configure DMA mask.\n");
                return -ENODEV;
        }
-       if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
+       if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
                printk(KERN_ERR DRV_NAME ": unable to configure consistent DMA mask.\n");
                return -ENODEV;
        }
 
-       /* Map IO ports */
-       iomap[0] = devm_ioport_map(&dev->dev, 0x1F0, 8);
-       iomap[1] = devm_ioport_map(&dev->dev, 0x3F6, 1);
-       iomap[2] = devm_ioport_map(&dev->dev, 0x170, 8);
-       iomap[3] = devm_ioport_map(&dev->dev, 0x376, 1);
-       iomap[4] = pcim_iomap(dev, 2, 0);
+       /* Map IO ports and initialize host accordingly */
+       iomap[0] = devm_ioport_map(&pdev->dev, 0x1F0, 8);
+       iomap[1] = devm_ioport_map(&pdev->dev, 0x3F6, 1);
+       iomap[2] = devm_ioport_map(&pdev->dev, 0x170, 8);
+       iomap[3] = devm_ioport_map(&pdev->dev, 0x376, 1);
+       iomap[4] = pcim_iomap(pdev, 2, 0);
 
        if (!iomap[0] || !iomap[1] || !iomap[2] || !iomap[3] || !iomap[4])
                return -ENOMEM;
 
-       /* We have to do our own plumbing as the PCI setup for this
-          chipset is non-standard so we can't punt to the libata code */
-
-       INIT_LIST_HEAD(&probe[0].node);
-       probe[0].dev = pci_dev_to_dev(dev);
-       probe[0].port_ops = &cs5520_port_ops;
-       probe[0].sht = &cs5520_sht;
-       probe[0].pio_mask = 0x1F;
-       probe[0].mwdma_mask = id->driver_data;
-       probe[0].irq = 14;
-       probe[0].irq_flags = 0;
-       probe[0].port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST;
-       probe[0].n_ports = 1;
-       probe[0].port[0].cmd_addr = iomap[0];
-       probe[0].port[0].ctl_addr = iomap[1];
-       probe[0].port[0].altstatus_addr = iomap[1];
-       probe[0].port[0].bmdma_addr = iomap[4];
-
-       /* The secondary lurks at different addresses but is otherwise
-          the same beastie */
-
-       probe[1] = probe[0];
-       INIT_LIST_HEAD(&probe[1].node);
-       probe[1].irq = 15;
-       probe[1].port[0].cmd_addr = iomap[2];
-       probe[1].port[0].ctl_addr = iomap[3];
-       probe[1].port[0].altstatus_addr = iomap[3];
-       probe[1].port[0].bmdma_addr = iomap[4] + 8;
-
-       /* Let libata fill in the port details */
-       ata_std_ports(&probe[0].port[0]);
-       ata_std_ports(&probe[1].port[0]);
-
-       /* Now add the ports that are active */
-       if (pcicfg & 1)
-               ports += ata_device_add(&probe[0]);
-       if (pcicfg & 2)
-               ports += ata_device_add(&probe[1]);
-       if (ports)
-               return 0;
-       return -ENODEV;
+       ioaddr = &host->ports[0]->ioaddr;
+       ioaddr->cmd_addr = iomap[0];
+       ioaddr->ctl_addr = iomap[1];
+       ioaddr->altstatus_addr = iomap[1];
+       ioaddr->bmdma_addr = iomap[4];
+       ata_std_ports(ioaddr);
+
+       ioaddr = &host->ports[1]->ioaddr;
+       ioaddr->cmd_addr = iomap[2];
+       ioaddr->ctl_addr = iomap[3];
+       ioaddr->altstatus_addr = iomap[3];
+       ioaddr->bmdma_addr = iomap[4] + 8;
+       ata_std_ports(ioaddr);
+
+       /* activate the host */
+       pci_set_master(pdev);
+       rc = ata_host_start(host);
+       if (rc)
+               return rc;
+
+       for (i = 0; i < 2; i++) {
+               static const int irq[] = { 14, 15 };
+               struct ata_port *ap = host->ports[0];
+
+               if (ata_port_is_dummy(ap))
+                       continue;
+
+               rc = devm_request_irq(&pdev->dev, irq[ap->port_no],
+                                     ata_interrupt, 0, DRV_NAME, host);
+               if (rc)
+                       return rc;
+       }
+
+       return ata_host_register(host, &cs5520_sht);
 }
 
 /**
index db63e80e608b3b65baefaba969c2706baf92d802..29642d5ee1891ee3d3aef8e40d51008f986b2fbc 100644 (file)
@@ -160,18 +160,6 @@ static unsigned int cs5530_qc_issue_prot(struct ata_queued_cmd *qc)
        return ata_qc_issue_prot(qc);
 }
 
-static int cs5530_pre_reset(struct ata_port *ap)
-{
-       ap->cbl = ATA_CBL_PATA40;
-       return ata_std_prereset(ap);
-}
-
-static void cs5530_error_handler(struct ata_port *ap)
-{
-       return ata_bmdma_drive_eh(ap, cs5530_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
-
 static struct scsi_host_template cs5530_sht = {
        .module                 = THIS_MODULE,
        .name                   = DRV_NAME,
@@ -213,8 +201,9 @@ static struct ata_port_operations cs5530_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = cs5530_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = cs5530_qc_issue_prot,
index 1572e5c9031af86c58c5d8a009854144e5fecc59..08cccc9c659b9cebbbe7ff13fe2c1a1cdd292d2c 100644 (file)
 #define CS5535_BAD_PIO(timings) ( (timings&~0x80000000UL)==0x00009172 )
 
 /**
- *     cs5535_pre_reset        -       detect cable type
+ *     cs5535_cable_detect     -       detect cable type
  *     @ap: Port to detect on
  *
  *     Perform cable detection for ATA66 capable cable. Return a libata
  *     cable type.
  */
 
-static int cs5535_pre_reset(struct ata_port *ap)
+static int cs5535_cable_detect(struct ata_port *ap)
 {
        u8 cable;
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
        pci_read_config_byte(pdev, CS5535_CABLE_DETECT, &cable);
        if (cable & 1)
-               ap->cbl = ATA_CBL_PATA80;
+               return ATA_CBL_PATA80;
        else
-               ap->cbl = ATA_CBL_PATA40;
-       return ata_std_prereset(ap);
-}
-
-/**
- *     cs5535_error_handler            -       reset/probe
- *     @ap: Port to reset
- *
- *     Reset and configure a port
- */
-
-static void cs5535_error_handler(struct ata_port *ap)
-{
-       ata_bmdma_drive_eh(ap, cs5535_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+               return ATA_CBL_PATA40;
 }
 
 /**
@@ -205,8 +192,9 @@ static struct ata_port_operations cs5535_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = cs5535_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = cs5535_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
index f69dde5f70665a37e2a019a23f7563177f1cbabf..6ec049c3b1dcf4e0fbe03b374a0d17f69672a405 100644 (file)
@@ -41,17 +41,6 @@ enum {
        CY82_INDEX_TIMEOUT      = 0x32
 };
 
-static int cy82c693_pre_reset(struct ata_port *ap)
-{
-       ap->cbl = ATA_CBL_PATA40;
-       return ata_std_prereset(ap);
-}
-
-static void cy82c693_error_handler(struct ata_port *ap)
-{
-       ata_bmdma_drive_eh(ap, cy82c693_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
 /**
  *     cy82c693_set_piomode    -       set initial PIO mode data
  *     @ap: ATA interface
@@ -156,8 +145,9 @@ static struct ata_port_operations cy82c693_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = cy82c693_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
index dac7a6554f6c28c0febe60cb9320c61130b33bd0..a3216850bba15e10938da4f2335f50e863b516e5 100644 (file)
 #include <linux/ata.h>
 
 #define DRV_NAME       "pata_efar"
-#define DRV_VERSION    "0.4.3"
+#define DRV_VERSION    "0.4.4"
 
 /**
- *     efar_pre_reset  -       check for 40/80 pin
+ *     efar_pre_reset  -       Enable bits
  *     @ap: Port
  *
  *     Perform cable detection for the EFAR ATA interface. This is
@@ -38,18 +38,11 @@ static int efar_pre_reset(struct ata_port *ap)
                { 0x41U, 1U, 0x80UL, 0x80UL },  /* port 0 */
                { 0x43U, 1U, 0x80UL, 0x80UL },  /* port 1 */
        };
-
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-       u8 tmp;
 
        if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->port_no]))
                return -ENOENT;
 
-       pci_read_config_byte(pdev, 0x47, &tmp);
-       if (tmp & (2 >> ap->port_no))
-               ap->cbl = ATA_CBL_PATA40;
-       else
-               ap->cbl = ATA_CBL_PATA80;
        return ata_std_prereset(ap);
 }
 
@@ -66,6 +59,25 @@ static void efar_error_handler(struct ata_port *ap)
        ata_bmdma_drive_eh(ap, efar_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
 }
 
+/**
+ *     efar_cable_detect       -       check for 40/80 pin
+ *     @ap: Port
+ *
+ *     Perform cable detection for the EFAR ATA interface. This is
+ *     different to the PIIX arrangement
+ */
+
+static int efar_cable_detect(struct ata_port *ap)
+{
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+       u8 tmp;
+
+       pci_read_config_byte(pdev, 0x47, &tmp);
+       if (tmp & (2 >> ap->port_no))
+               return ATA_CBL_PATA40;
+       return ATA_CBL_PATA80;
+}
+
 /**
  *     efar_set_piomode - Initialize host controller PATA PIO timings
  *     @ap: Port whose timings we are configuring
@@ -256,6 +268,7 @@ static const struct ata_port_operations efar_ops = {
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = efar_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = efar_cable_detect,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
index baf35f87603061220fb7da4930fa0de0e7e967e3..93cfa6d300a5a08196d789817a4c93938b7b1da6 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "pata_hpt366"
-#define DRV_VERSION    "0.6.0"
+#define DRV_VERSION    "0.6.1"
 
 struct hpt_clock {
        u8      xfer_speed;
@@ -169,13 +169,12 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr, cons
 
 /**
  *     hpt366_filter   -       mode selection filter
- *     @ap: ATA interface
  *     @adev: ATA device
  *
  *     Block UDMA on devices that cause trouble with this controller.
  */
 
-static unsigned long hpt366_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
+static unsigned long hpt366_filter(struct ata_device *adev, unsigned long mask)
 {
        if (adev->class == ATA_DEV_ATA) {
                if (hpt_dma_blacklisted(adev, "UDMA",  bad_ata33))
@@ -185,7 +184,7 @@ static unsigned long hpt366_filter(const struct ata_port *ap, struct ata_device
                if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4))
                        mask &= ~(0x0F << ATA_SHIFT_UDMA);
        }
-       return ata_pci_default_filter(ap, adev, mask);
+       return ata_pci_default_filter(adev, mask);
 }
 
 /**
@@ -210,24 +209,28 @@ static u32 hpt36x_find_mode(struct ata_port *ap, int speed)
        return 0xffffffffU;     /* silence compiler warning */
 }
 
+static int hpt36x_cable_detect(struct ata_port *ap)
+{
+       u8 ata66;
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+
+       pci_read_config_byte(pdev, 0x5A, &ata66);
+       if (ata66 & (1 << ap->port_no))
+               return ATA_CBL_PATA40;
+       return ATA_CBL_PATA80;
+}
+
 static int hpt36x_pre_reset(struct ata_port *ap)
 {
        static const struct pci_bits hpt36x_enable_bits[] = {
                { 0x50, 1, 0x04, 0x04 },
                { 0x54, 1, 0x04, 0x04 }
        };
-
-       u8 ata66;
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
        if (!pci_test_config_bits(pdev, &hpt36x_enable_bits[ap->port_no]))
                return -ENOENT;
 
-       pci_read_config_byte(pdev, 0x5A, &ata66);
-       if (ata66 & (1 << ap->port_no))
-               ap->cbl = ATA_CBL_PATA40;
-       else
-               ap->cbl = ATA_CBL_PATA80;
        return ata_std_prereset(ap);
 }
 
@@ -354,6 +357,7 @@ static struct ata_port_operations hpt366_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = hpt36x_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = hpt36x_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
index f331eeeafa0f39d75302023953c676910d446e64..41d8312963474447feb7faf6284a80efaa00cc53 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright (C) 1999-2003             Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001         Sun Microsystems, Inc.
  * Portions Copyright (C) 2003         Red Hat Inc
+ * Portions Copyright (C) 2005-2006    MontaVista Software, Inc.
  *
  * TODO
  *     PLL mode
@@ -25,7 +26,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "pata_hpt37x"
-#define DRV_VERSION    "0.6.0"
+#define DRV_VERSION    "0.6.5"
 
 struct hpt_clock {
        u8      xfer_speed;
@@ -61,201 +62,75 @@ struct hpt_chip {
  * 31     FIFO enable.
  */
 
-/* from highpoint documentation. these are old values */
-static const struct hpt_clock hpt370_timings_33[] = {
-/*     {       XFER_UDMA_5,    0x1A85F442,     0x16454e31      }, */
-       {       XFER_UDMA_5,    0x16454e31      },
-       {       XFER_UDMA_4,    0x16454e31      },
-       {       XFER_UDMA_3,    0x166d4e31      },
-       {       XFER_UDMA_2,    0x16494e31      },
-       {       XFER_UDMA_1,    0x164d4e31      },
-       {       XFER_UDMA_0,    0x16514e31      },
-
-       {       XFER_MW_DMA_2,  0x26514e21      },
-       {       XFER_MW_DMA_1,  0x26514e33      },
-       {       XFER_MW_DMA_0,  0x26514e97      },
-
-       {       XFER_PIO_4,     0x06514e21      },
-       {       XFER_PIO_3,     0x06514e22      },
-       {       XFER_PIO_2,     0x06514e33      },
-       {       XFER_PIO_1,     0x06914e43      },
-       {       XFER_PIO_0,     0x06914e57      },
-       {       0,              0x06514e57      }
+static struct hpt_clock hpt37x_timings_33[] = {
+       { XFER_UDMA_6,          0x12446231 },   /* 0x12646231 ?? */
+       { XFER_UDMA_5,          0x12446231 },
+       { XFER_UDMA_4,          0x12446231 },
+       { XFER_UDMA_3,          0x126c6231 },
+       { XFER_UDMA_2,          0x12486231 },
+       { XFER_UDMA_1,          0x124c6233 },
+       { XFER_UDMA_0,          0x12506297 },
+
+       { XFER_MW_DMA_2,        0x22406c31 },
+       { XFER_MW_DMA_1,        0x22406c33 },
+       { XFER_MW_DMA_0,        0x22406c97 },
+
+       { XFER_PIO_4,           0x06414e31 },
+       { XFER_PIO_3,           0x06414e42 },
+       { XFER_PIO_2,           0x06414e53 },
+       { XFER_PIO_1,           0x06814e93 },
+       { XFER_PIO_0,           0x06814ea7 }
 };
 
-static const struct hpt_clock hpt370_timings_66[] = {
-       {       XFER_UDMA_5,    0x14846231      },
-       {       XFER_UDMA_4,    0x14886231      },
-       {       XFER_UDMA_3,    0x148c6231      },
-       {       XFER_UDMA_2,    0x148c6231      },
-       {       XFER_UDMA_1,    0x14906231      },
-       {       XFER_UDMA_0,    0x14986231      },
-
-       {       XFER_MW_DMA_2,  0x26514e21      },
-       {       XFER_MW_DMA_1,  0x26514e33      },
-       {       XFER_MW_DMA_0,  0x26514e97      },
-
-       {       XFER_PIO_4,     0x06514e21      },
-       {       XFER_PIO_3,     0x06514e22      },
-       {       XFER_PIO_2,     0x06514e33      },
-       {       XFER_PIO_1,     0x06914e43      },
-       {       XFER_PIO_0,     0x06914e57      },
-       {       0,              0x06514e57      }
+static struct hpt_clock hpt37x_timings_50[] = {
+       { XFER_UDMA_6,          0x12848242 },
+       { XFER_UDMA_5,          0x12848242 },
+       { XFER_UDMA_4,          0x12ac8242 },
+       { XFER_UDMA_3,          0x128c8242 },
+       { XFER_UDMA_2,          0x120c8242 },
+       { XFER_UDMA_1,          0x12148254 },
+       { XFER_UDMA_0,          0x121882ea },
+
+       { XFER_MW_DMA_2,        0x22808242 },
+       { XFER_MW_DMA_1,        0x22808254 },
+       { XFER_MW_DMA_0,        0x228082ea },
+
+       { XFER_PIO_4,           0x0a81f442 },
+       { XFER_PIO_3,           0x0a81f443 },
+       { XFER_PIO_2,           0x0a81f454 },
+       { XFER_PIO_1,           0x0ac1f465 },
+       { XFER_PIO_0,           0x0ac1f48a }
 };
 
-/* these are the current (4 sep 2001) timings from highpoint */
-static const struct hpt_clock hpt370a_timings_33[] = {
-       {       XFER_UDMA_5,    0x12446231      },
-       {       XFER_UDMA_4,    0x12446231      },
-       {       XFER_UDMA_3,    0x126c6231      },
-       {       XFER_UDMA_2,    0x12486231      },
-       {       XFER_UDMA_1,    0x124c6233      },
-       {       XFER_UDMA_0,    0x12506297      },
-
-       {       XFER_MW_DMA_2,  0x22406c31      },
-       {       XFER_MW_DMA_1,  0x22406c33      },
-       {       XFER_MW_DMA_0,  0x22406c97      },
-
-       {       XFER_PIO_4,     0x06414e31      },
-       {       XFER_PIO_3,     0x06414e42      },
-       {       XFER_PIO_2,     0x06414e53      },
-       {       XFER_PIO_1,     0x06814e93      },
-       {       XFER_PIO_0,     0x06814ea7      },
-       {       0,              0x06814ea7      }
+static struct hpt_clock hpt37x_timings_66[] = {
+       { XFER_UDMA_6,          0x1c869c62 },
+       { XFER_UDMA_5,          0x1cae9c62 },   /* 0x1c8a9c62 */
+       { XFER_UDMA_4,          0x1c8a9c62 },
+       { XFER_UDMA_3,          0x1c8e9c62 },
+       { XFER_UDMA_2,          0x1c929c62 },
+       { XFER_UDMA_1,          0x1c9a9c62 },
+       { XFER_UDMA_0,          0x1c829c62 },
+
+       { XFER_MW_DMA_2,        0x2c829c62 },
+       { XFER_MW_DMA_1,        0x2c829c66 },
+       { XFER_MW_DMA_0,        0x2c829d2e },
+
+       { XFER_PIO_4,           0x0c829c62 },
+       { XFER_PIO_3,           0x0c829c84 },
+       { XFER_PIO_2,           0x0c829ca6 },
+       { XFER_PIO_1,           0x0d029d26 },
+       { XFER_PIO_0,           0x0d029d5e }
 };
 
-/* 2x 33MHz timings */
-static const struct hpt_clock hpt370a_timings_66[] = {
-       {       XFER_UDMA_5,    0x1488e673      },
-       {       XFER_UDMA_4,    0x1488e673      },
-       {       XFER_UDMA_3,    0x1498e673      },
-       {       XFER_UDMA_2,    0x1490e673      },
-       {       XFER_UDMA_1,    0x1498e677      },
-       {       XFER_UDMA_0,    0x14a0e73f      },
-
-       {       XFER_MW_DMA_2,  0x2480fa73      },
-       {       XFER_MW_DMA_1,  0x2480fa77      },
-       {       XFER_MW_DMA_0,  0x2480fb3f      },
-
-       {       XFER_PIO_4,     0x0c82be73      },
-       {       XFER_PIO_3,     0x0c82be95      },
-       {       XFER_PIO_2,     0x0c82beb7      },
-       {       XFER_PIO_1,     0x0d02bf37      },
-       {       XFER_PIO_0,     0x0d02bf5f      },
-       {       0,              0x0d02bf5f      }
-};
-
-static const struct hpt_clock hpt370a_timings_50[] = {
-       {       XFER_UDMA_5,    0x12848242      },
-       {       XFER_UDMA_4,    0x12ac8242      },
-       {       XFER_UDMA_3,    0x128c8242      },
-       {       XFER_UDMA_2,    0x120c8242      },
-       {       XFER_UDMA_1,    0x12148254      },
-       {       XFER_UDMA_0,    0x121882ea      },
-
-       {       XFER_MW_DMA_2,  0x22808242      },
-       {       XFER_MW_DMA_1,  0x22808254      },
-       {       XFER_MW_DMA_0,  0x228082ea      },
-
-       {       XFER_PIO_4,     0x0a81f442      },
-       {       XFER_PIO_3,     0x0a81f443      },
-       {       XFER_PIO_2,     0x0a81f454      },
-       {       XFER_PIO_1,     0x0ac1f465      },
-       {       XFER_PIO_0,     0x0ac1f48a      },
-       {       0,              0x0ac1f48a      }
-};
-
-static const struct hpt_clock hpt372_timings_33[] = {
-       {       XFER_UDMA_6,    0x1c81dc62      },
-       {       XFER_UDMA_5,    0x1c6ddc62      },
-       {       XFER_UDMA_4,    0x1c8ddc62      },
-       {       XFER_UDMA_3,    0x1c8edc62      },      /* checkme */
-       {       XFER_UDMA_2,    0x1c91dc62      },
-       {       XFER_UDMA_1,    0x1c9adc62      },      /* checkme */
-       {       XFER_UDMA_0,    0x1c82dc62      },      /* checkme */
-
-       {       XFER_MW_DMA_2,  0x2c829262      },
-       {       XFER_MW_DMA_1,  0x2c829266      },      /* checkme */
-       {       XFER_MW_DMA_0,  0x2c82922e      },      /* checkme */
-
-       {       XFER_PIO_4,     0x0c829c62      },
-       {       XFER_PIO_3,     0x0c829c84      },
-       {       XFER_PIO_2,     0x0c829ca6      },
-       {       XFER_PIO_1,     0x0d029d26      },
-       {       XFER_PIO_0,     0x0d029d5e      },
-       {       0,              0x0d029d5e      }
-};
-
-static const struct hpt_clock hpt372_timings_50[] = {
-       {       XFER_UDMA_5,    0x12848242      },
-       {       XFER_UDMA_4,    0x12ac8242      },
-       {       XFER_UDMA_3,    0x128c8242      },
-       {       XFER_UDMA_2,    0x120c8242      },
-       {       XFER_UDMA_1,    0x12148254      },
-       {       XFER_UDMA_0,    0x121882ea      },
-
-       {       XFER_MW_DMA_2,  0x22808242      },
-       {       XFER_MW_DMA_1,  0x22808254      },
-       {       XFER_MW_DMA_0,  0x228082ea      },
-
-       {       XFER_PIO_4,     0x0a81f442      },
-       {       XFER_PIO_3,     0x0a81f443      },
-       {       XFER_PIO_2,     0x0a81f454      },
-       {       XFER_PIO_1,     0x0ac1f465      },
-       {       XFER_PIO_0,     0x0ac1f48a      },
-       {       0,              0x0a81f443      }
-};
-
-static const struct hpt_clock hpt372_timings_66[] = {
-       {       XFER_UDMA_6,    0x1c869c62      },
-       {       XFER_UDMA_5,    0x1cae9c62      },
-       {       XFER_UDMA_4,    0x1c8a9c62      },
-       {       XFER_UDMA_3,    0x1c8e9c62      },
-       {       XFER_UDMA_2,    0x1c929c62      },
-       {       XFER_UDMA_1,    0x1c9a9c62      },
-       {       XFER_UDMA_0,    0x1c829c62      },
-
-       {       XFER_MW_DMA_2,  0x2c829c62      },
-       {       XFER_MW_DMA_1,  0x2c829c66      },
-       {       XFER_MW_DMA_0,  0x2c829d2e      },
-
-       {       XFER_PIO_4,     0x0c829c62      },
-       {       XFER_PIO_3,     0x0c829c84      },
-       {       XFER_PIO_2,     0x0c829ca6      },
-       {       XFER_PIO_1,     0x0d029d26      },
-       {       XFER_PIO_0,     0x0d029d5e      },
-       {       0,              0x0d029d26      }
-};
-
-static const struct hpt_clock hpt374_timings_33[] = {
-       {       XFER_UDMA_6,    0x12808242      },
-       {       XFER_UDMA_5,    0x12848242      },
-       {       XFER_UDMA_4,    0x12ac8242      },
-       {       XFER_UDMA_3,    0x128c8242      },
-       {       XFER_UDMA_2,    0x120c8242      },
-       {       XFER_UDMA_1,    0x12148254      },
-       {       XFER_UDMA_0,    0x121882ea      },
-
-       {       XFER_MW_DMA_2,  0x22808242      },
-       {       XFER_MW_DMA_1,  0x22808254      },
-       {       XFER_MW_DMA_0,  0x228082ea      },
-
-       {       XFER_PIO_4,     0x0a81f442      },
-       {       XFER_PIO_3,     0x0a81f443      },
-       {       XFER_PIO_2,     0x0a81f454      },
-       {       XFER_PIO_1,     0x0ac1f465      },
-       {       XFER_PIO_0,     0x0ac1f48a      },
-       {       0,              0x06814e93      }
-};
 
 static const struct hpt_chip hpt370 = {
        "HPT370",
        48,
        {
-               hpt370_timings_33,
+               hpt37x_timings_33,
                NULL,
                NULL,
-               hpt370_timings_66
+               NULL
        }
 };
 
@@ -263,10 +138,10 @@ static const struct hpt_chip hpt370a = {
        "HPT370A",
        48,
        {
-               hpt370a_timings_33,
+               hpt37x_timings_33,
                NULL,
-               hpt370a_timings_50,
-               hpt370a_timings_66
+               hpt37x_timings_50,
+               NULL
        }
 };
 
@@ -274,10 +149,10 @@ static const struct hpt_chip hpt372 = {
        "HPT372",
        55,
        {
-               hpt372_timings_33,
+               hpt37x_timings_33,
                NULL,
-               hpt372_timings_50,
-               hpt372_timings_66
+               hpt37x_timings_50,
+               hpt37x_timings_66
        }
 };
 
@@ -285,10 +160,10 @@ static const struct hpt_chip hpt302 = {
        "HPT302",
        66,
        {
-               hpt372_timings_33,
+               hpt37x_timings_33,
                NULL,
-               hpt372_timings_50,
-               hpt372_timings_66
+               hpt37x_timings_50,
+               hpt37x_timings_66
        }
 };
 
@@ -296,10 +171,10 @@ static const struct hpt_chip hpt371 = {
        "HPT371",
        66,
        {
-               hpt372_timings_33,
+               hpt37x_timings_33,
                NULL,
-               hpt372_timings_50,
-               hpt372_timings_66
+               hpt37x_timings_50,
+               hpt37x_timings_66
        }
 };
 
@@ -307,10 +182,10 @@ static const struct hpt_chip hpt372a = {
        "HPT372A",
        66,
        {
-               hpt372_timings_33,
+               hpt37x_timings_33,
                NULL,
-               hpt372_timings_50,
-               hpt372_timings_66
+               hpt37x_timings_50,
+               hpt37x_timings_66
        }
 };
 
@@ -318,7 +193,7 @@ static const struct hpt_chip hpt374 = {
        "HPT374",
        48,
        {
-               hpt374_timings_33,
+               hpt37x_timings_33,
                NULL,
                NULL,
                NULL
@@ -397,13 +272,12 @@ static const char *bad_ata100_5[] = {
 
 /**
  *     hpt370_filter   -       mode selection filter
- *     @ap: ATA interface
  *     @adev: ATA device
  *
  *     Block UDMA on devices that cause trouble with this controller.
  */
 
-static unsigned long hpt370_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
+static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask)
 {
        if (adev->class == ATA_DEV_ATA) {
                if (hpt_dma_blacklisted(adev, "UDMA", bad_ata33))
@@ -411,24 +285,23 @@ static unsigned long hpt370_filter(const struct ata_port *ap, struct ata_device
                if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
                        mask &= ~(0x1F << ATA_SHIFT_UDMA);
        }
-       return ata_pci_default_filter(ap, adev, mask);
+       return ata_pci_default_filter(adev, mask);
 }
 
 /**
  *     hpt370a_filter  -       mode selection filter
- *     @ap: ATA interface
  *     @adev: ATA device
  *
  *     Block UDMA on devices that cause trouble with this controller.
  */
 
-static unsigned long hpt370a_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
+static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
 {
        if (adev->class != ATA_DEV_ATA) {
                if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
                        mask &= ~ (0x1F << ATA_SHIFT_UDMA);
        }
-       return ata_pci_default_filter(ap, adev, mask);
+       return ata_pci_default_filter(adev, mask);
 }
 
 /**
@@ -462,8 +335,7 @@ static int hpt37x_pre_reset(struct ata_port *ap)
                ap->cbl = ATA_CBL_PATA80;
 
        /* Reset the state machine */
-       pci_write_config_byte(pdev, 0x50, 0x37);
-       pci_write_config_byte(pdev, 0x54, 0x37);
+       pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
        udelay(100);
 
        return ata_std_prereset(ap);
@@ -513,8 +385,7 @@ static int hpt374_pre_reset(struct ata_port *ap)
                ap->cbl = ATA_CBL_PATA80;
 
        /* Reset the state machine */
-       pci_write_config_byte(pdev, 0x50, 0x37);
-       pci_write_config_byte(pdev, 0x54, 0x37);
+       pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
        udelay(100);
 
        return ata_std_prereset(ap);
@@ -1032,6 +903,24 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .udma_mask = 0x3f,
                .port_ops = &hpt370a_port_ops
        };
+       /* HPT370 - UDMA100 */
+       static struct ata_port_info info_hpt370_33 = {
+               .sht = &hpt37x_sht,
+               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .pio_mask = 0x1f,
+               .mwdma_mask = 0x07,
+               .udma_mask = 0x0f,
+               .port_ops = &hpt370_port_ops
+       };
+       /* HPT370A - UDMA100 */
+       static struct ata_port_info info_hpt370a_33 = {
+               .sht = &hpt37x_sht,
+               .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
+               .pio_mask = 0x1f,
+               .mwdma_mask = 0x07,
+               .udma_mask = 0x0f,
+               .port_ops = &hpt370a_port_ops
+       };
        /* HPT371, 372 and friends - UDMA133 */
        static struct ata_port_info info_hpt372 = {
                .sht = &hpt37x_sht,
@@ -1067,7 +956,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 
        u8 irqmask;
        u32 class_rev;
+       u8 mcr1;
        u32 freq;
+       int prefer_dpll = 1;
+       
+       unsigned long iobase = pci_resource_start(dev, 4);
 
        const struct hpt_chip *chip_table;
        int clock_slot;
@@ -1088,10 +981,12 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                        case 3:
                                port = &info_hpt370;
                                chip_table = &hpt370;
+                               prefer_dpll = 0;
                                break;
                        case 4:
                                port = &info_hpt370a;
                                chip_table = &hpt370a;
+                               prefer_dpll = 0;
                                break;
                        case 5:
                                port = &info_hpt372;
@@ -1119,8 +1014,16 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                                chip_table = &hpt302;
                                break;
                        case PCI_DEVICE_ID_TTI_HPT371:
+                               if (class_rev > 1)
+                                       return -ENODEV;
                                port = &info_hpt372;
                                chip_table = &hpt371;
+                               /* Single channel device, master is not present
+                                  but the BIOS (or us for non x86) must mark it
+                                  absent */
+                               pci_read_config_byte(dev, 0x50, &mcr1);
+                               mcr1 &= ~0x04;
+                               pci_write_config_byte(dev, 0x50, mcr1);
                                break;
                        case PCI_DEVICE_ID_TTI_HPT374:
                                chip_table = &hpt374;
@@ -1150,8 +1053,18 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
         */
 
        pci_write_config_byte(dev, 0x5b, 0x23);
+       
+       /*
+        * HighPoint does this for HPT372A.
+        * NOTE: This register is only writeable via I/O space.
+        */
+       if (chip_table == &hpt372a)
+               outb(0x0e, iobase + 0x9c);
 
-       pci_read_config_dword(dev, 0x70, &freq);
+       /* Some devices do not let this value be accessed via PCI space
+          according to the old driver */
+
+       freq = inl(iobase + 0x90);
        if ((freq >> 12) != 0xABCDE) {
                int i;
                u8 sr;
@@ -1162,7 +1075,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                /* This is the process the HPT371 BIOS is reported to use */
                for(i = 0; i < 128; i++) {
                        pci_read_config_byte(dev, 0x78, &sr);
-                       total += sr;
+                       total += sr & 0x1FF;
                        udelay(15);
                }
                freq = total / 128;
@@ -1173,15 +1086,27 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
         *      Turn the frequency check into a band and then find a timing
         *      table to match it.
         */
-
+        
        clock_slot = hpt37x_clock_slot(freq, chip_table->base);
-       if (chip_table->clocks[clock_slot] == NULL) {
+       if (chip_table->clocks[clock_slot] == NULL || prefer_dpll) {
                /*
                 *      We need to try PLL mode instead
+                *
+                *      For non UDMA133 capable devices we should
+                *      use a 50MHz DPLL by choice
                 */
-               unsigned int f_low = (MHz[clock_slot] * chip_table->base) / 192;
-               unsigned int f_high = f_low + 2;
+               unsigned int f_low, f_high;
                int adjust;
+               
+               clock_slot = 2;
+               if (port->udma_mask & 0xE0)
+                       clock_slot = 3;
+               
+               f_low = (MHz[clock_slot] * chip_table->base) / 192;
+               f_high = f_low + 2;
+
+               /* Select the DPLL clock. */
+               pci_write_config_byte(dev, 0x5b, 0x21);
 
                for(adjust = 0; adjust < 8; adjust++) {
                        if (hpt37x_calibrate_dpll(dev))
@@ -1197,25 +1122,27 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                        printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n");
                        return -ENODEV;
                }
-               /* Check if this works for all cases */
-               port->private_data = (void *)hpt370_timings_66;
+               if (clock_slot == 3)
+                       port->private_data = (void *)hpt37x_timings_66;
+               else
+                       port->private_data = (void *)hpt37x_timings_50;
 
                printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[clock_slot]);
        } else {
                port->private_data = (void *)chip_table->clocks[clock_slot];
                /*
-                *      Perform a final fixup. The 371 and 372 clock determines
-                *      if UDMA133 is available.
-                */
-
-               if (clock_slot == 2 && chip_table == &hpt372) { /* 50Mhz */
-                       printk(KERN_WARNING "pata_hpt37x: No UDMA133 support available with 50MHz bus clock.\n");
-                       if (port == &info_hpt372)
-                               port = &info_hpt372_50;
-                       else BUG();
-               }
+                *      Perform a final fixup. Note that we will have used the
+                *      DPLL on the HPT372 which means we don't have to worry
+                *      about lack of UDMA133 support on lower clocks
+                */
+
+               if (clock_slot < 2 && port == &info_hpt370)
+                       port = &info_hpt370_33;
+               if (clock_slot < 2 && port == &info_hpt370a)
+                       port = &info_hpt370a_33;
                printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]);
        }
+
        port_info[0] = port_info[1] = port;
        /* Now kick off ATA set up */
        return ata_pci_init_one(dev, port_info, 2);
index 65f2e180e7fa285644e9bf38522d39846da446b5..6a34521b9e01a7ded70309d3b528c0d7b4f1410e 100644 (file)
@@ -8,10 +8,10 @@
  * Copyright (C) 1999-2003             Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001         Sun Microsystems, Inc.
  * Portions Copyright (C) 2003         Red Hat Inc
+ * Portions Copyright (C) 2005-2006    MontaVista Software, Inc.
  *
  *
  * TODO
- *     371N
  *     Work out best PLL policy
  */
 
@@ -25,7 +25,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "pata_hpt3x2n"
-#define DRV_VERSION    "0.3.2"
+#define DRV_VERSION    "0.3.3"
 
 enum {
        HPT_PCI_FAST    =       (1 << 31),
@@ -115,14 +115,13 @@ static u32 hpt3x2n_find_mode(struct ata_port *ap, int speed)
 }
 
 /**
- *     hpt3x2n_pre_reset       -       reset the hpt3x2n bus
- *     @ap: ATA port to reset
+ *     hpt3x2n_cable_detect    -       Detect the cable type
+ *     @ap: ATA port to detect on
  *
- *     Perform the initial reset handling for the 3x2n series controllers.
- *     Reset the hardware and state machine, obtain the cable type.
+ *     Return the cable type attached to this port
  */
 
-static int hpt3xn_pre_reset(struct ata_port *ap)
+static int hpt3x2n_cable_detect(struct ata_port *ap)
 {
        u8 scr2, ata66;
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
@@ -135,15 +134,26 @@ static int hpt3xn_pre_reset(struct ata_port *ap)
        pci_write_config_byte(pdev, 0x5B, scr2);
 
        if (ata66 & (1 << ap->port_no))
-               ap->cbl = ATA_CBL_PATA40;
+               return ATA_CBL_PATA40;
        else
-               ap->cbl = ATA_CBL_PATA80;
+               return ATA_CBL_PATA80;
+}
+
+/**
+ *     hpt3x2n_pre_reset       -       reset the hpt3x2n bus
+ *     @ap: ATA port to reset
+ *     @deadline: deadline jiffies for the operation
+ *
+ *     Perform the initial reset handling for the 3x2n series controllers.
+ *     Reset the hardware and state machine,
+ */
 
+static int hpt3xn_pre_reset(struct ata_port *ap)
+{
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        /* Reset the state machine */
-       pci_write_config_byte(pdev, 0x50, 0x37);
-       pci_write_config_byte(pdev, 0x54, 0x37);
+       pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
        udelay(100);
-
        return ata_std_prereset(ap);
 }
 
@@ -364,6 +374,7 @@ static struct ata_port_operations hpt3x2n_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = hpt3x2n_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = hpt3x2n_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -422,8 +433,9 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev)
 {
        unsigned long freq;
        u32 fcnt;
+       unsigned long iobase = pci_resource_start(pdev, 4);
 
-       pci_read_config_dword(pdev, 0x70/*CHECKME*/, &fcnt);
+       fcnt = inl(iobase + 0x90);      /* Not PCI readable for some chips */
        if ((fcnt >> 12) != 0xABCDE) {
                printk(KERN_WARNING "hpt3xn: BIOS clock data not set.\n");
                return 33;      /* Not BIOS set */
@@ -492,6 +504,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        unsigned int pci_mhz;
        unsigned int f_low, f_high;
        int adjust;
+       unsigned long iobase = pci_resource_start(dev, 4);
 
        pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
        class_rev &= 0xFF;
@@ -501,6 +514,11 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                        if (class_rev < 6)
                                return -ENODEV;
                        break;
+               case PCI_DEVICE_ID_TTI_HPT371:
+                       if (class_rev < 2)
+                               return -ENODEV;
+                       /* 371N if rev > 1 */
+                       break;
                case PCI_DEVICE_ID_TTI_HPT372:
                        /* 372N if rev >= 1*/
                        if (class_rev == 0)
@@ -528,6 +546,19 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        irqmask &= ~0x10;
        pci_write_config_byte(dev, 0x5a, irqmask);
 
+       /*
+        * HPT371 chips physically have only one channel, the secondary one,
+        * but the primary channel registers do exist!  Go figure...
+        * So,  we manually disable the non-existing channel here
+        * (if the BIOS hasn't done this already).
+        */
+       if (dev->device == PCI_DEVICE_ID_TTI_HPT371) {
+               u8 mcr1;
+               pci_read_config_byte(dev, 0x50, &mcr1);
+               mcr1 &= ~0x04;
+               pci_write_config_byte(dev, 0x50, mcr1);
+       }
+
        /* Tune the PLL. HPT recommend using 75 for SATA, 66 for UDMA133 or
           50 for UDMA100. Right now we always use 66 */
 
@@ -546,14 +577,24 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                        break;
                pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
        }
-       if (adjust == 8)
-               printk(KERN_WARNING "hpt3xn: DPLL did not stabilize.\n");
+       if (adjust == 8) {
+               printk(KERN_WARNING "hpt3x2n: DPLL did not stabilize.\n");
+               return -ENODEV;
+       }
 
        /* Set our private data up. We only need a few flags so we use
           it directly */
        port->private_data = NULL;
-       if (pci_mhz > 60)
+       if (pci_mhz > 60) {
                port->private_data = (void *)PCI66;
+               /*
+                * On  HPT371N, if ATA clock is 66 MHz we must set bit 2 in
+                * the MISC. register to stretch the UltraDMA Tss timing.
+                * NOTE: This register is only writeable via I/O space.
+                */
+               if (dev->device == PCI_DEVICE_ID_TTI_HPT371)
+                       outb(inb(iobase + 0x9c) | 0x04, iobase + 0x9c);
+       }
 
        /* Now kick off ATA set up */
        port_info[0] = port_info[1] = port;
@@ -562,6 +603,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 
 static const struct pci_device_id hpt3x2n[] = {
        { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
+       { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT371), },
        { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372), },
        { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT302), },
        { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT372N), },
index 813485c8526c433a0d7931ea429351680ef7aeb5..ac28ec8c50aa61a19f03c704c843f50b8709ba05 100644 (file)
 #define DRV_NAME       "pata_hpt3x3"
 #define DRV_VERSION    "0.4.2"
 
-static int hpt3x3_probe_init(struct ata_port *ap)
-{
-       ap->cbl = ATA_CBL_PATA40;
-       return ata_std_prereset(ap);
-}
-
-/**
- *     hpt3x3_probe_reset      -       reset the hpt3x3 bus
- *     @ap: ATA port to reset
- *
- *     Perform the housekeeping when doing an ATA bus reeset. We just
- *     need to force the cable type.
- */
-
-static void hpt3x3_error_handler(struct ata_port *ap)
-{
-       return ata_bmdma_drive_eh(ap, hpt3x3_probe_init, ata_std_softreset, NULL, ata_std_postreset);
-}
-
 /**
  *     hpt3x3_set_piomode              -       PIO setup
  *     @ap: ATA interface
@@ -139,8 +120,9 @@ static struct ata_port_operations hpt3x3_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = hpt3x3_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
index 1a61cc89174191cb65e9e8ef6474b6cf74b633d2..d042efdfbac4d5483f277306146dbd9384b32b7e 100644 (file)
@@ -49,13 +49,13 @@ static struct ata_port_operations isapnp_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
 
        .data_xfer      = ata_data_xfer,
 
-       .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
        .irq_on         = ata_irq_on,
        .irq_ack        = ata_irq_ack,
@@ -74,8 +74,10 @@ static struct ata_port_operations isapnp_port_ops = {
 
 static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev_id)
 {
-       struct ata_probe_ent ae;
+       struct ata_host *host;
+       struct ata_port *ap;
        void __iomem *cmd_addr, *ctl_addr;
+       int rc;
 
        if (pnp_port_valid(idev, 0) == 0)
                return -ENODEV;
@@ -84,34 +86,36 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
        if (pnp_irq_valid(idev, 0) == 0)
                return -ENODEV;
 
+       /* allocate host */
+       host = ata_host_alloc(&idev->dev, 1);
+       if (!host)
+               return -ENOMEM;
+
+       /* acquire resources and fill host */
        cmd_addr = devm_ioport_map(&idev->dev, pnp_port_start(idev, 0), 8);
        if (!cmd_addr)
                return -ENOMEM;
 
-       memset(&ae, 0, sizeof(struct ata_probe_ent));
-       INIT_LIST_HEAD(&ae.node);
-       ae.dev = &idev->dev;
-       ae.port_ops = &isapnp_port_ops;
-       ae.sht = &isapnp_sht;
-       ae.n_ports = 1;
-       ae.pio_mask = 1;                /* ISA so PIO 0 cycles */
-       ae.irq = pnp_irq(idev, 0);
-       ae.irq_flags = 0;
-       ae.port_flags = ATA_FLAG_SLAVE_POSS;
-       ae.port[0].cmd_addr = cmd_addr;
+       ap = host->ports[0];
+
+       ap->ops = &isapnp_port_ops;
+       ap->pio_mask = 1;
+       ap->flags |= ATA_FLAG_SLAVE_POSS;
+
+       ap->ioaddr.cmd_addr = cmd_addr;
 
        if (pnp_port_valid(idev, 1) == 0) {
                ctl_addr = devm_ioport_map(&idev->dev,
                                           pnp_port_start(idev, 1), 1);
-               ae.port[0].altstatus_addr = ctl_addr;
-               ae.port[0].ctl_addr = ctl_addr;
-               ae.port_flags |= ATA_FLAG_SRST;
+               ap->ioaddr.altstatus_addr = ctl_addr;
+               ap->ioaddr.ctl_addr = ctl_addr;
        }
-       ata_std_ports(&ae.port[0]);
 
-       if (ata_device_add(&ae) == 0)
-               return -ENODEV;
-       return 0;
+       ata_std_ports(&ap->ioaddr);
+
+       /* activate */
+       return ata_host_activate(host, pnp_irq(idev, 0), ata_interrupt, 0,
+                                &isapnp_sht);
 }
 
 /**
index ea734701555ee8d0f1ecb9810fdf561a755b33ed..011306ef8334f8d7b701d6748190cb858fd79602 100644 (file)
@@ -25,8 +25,8 @@
  *     it8213_pre_reset        -       check for 40/80 pin
  *     @ap: Port
  *
- *     Perform cable detection for the 8213 ATA interface. This is
- *     different to the PIIX arrangement
+ *     Filter out ports by the enable bits before doing the normal reset
+ *     and probe.
  */
 
 static int it8213_pre_reset(struct ata_port *ap)
@@ -34,23 +34,14 @@ static int it8213_pre_reset(struct ata_port *ap)
        static const struct pci_bits it8213_enable_bits[] = {
                { 0x41U, 1U, 0x80UL, 0x80UL },  /* port 0 */
        };
-
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-       u8 tmp;
-
        if (!pci_test_config_bits(pdev, &it8213_enable_bits[ap->port_no]))
                return -ENOENT;
-
-       pci_read_config_byte(pdev, 0x42, &tmp);
-       if (tmp & 2)    /* The initial docs are incorrect */
-               ap->cbl = ATA_CBL_PATA40;
-       else
-               ap->cbl = ATA_CBL_PATA80;
        return ata_std_prereset(ap);
 }
 
 /**
- *     it8213_probe_reset - Probe specified port on PATA host controller
+ *     it8213_error_handler - Probe specified port on PATA host controller
  *     @ap: Port to probe
  *
  *     LOCKING:
@@ -62,10 +53,28 @@ static void it8213_error_handler(struct ata_port *ap)
        ata_bmdma_drive_eh(ap, it8213_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
 }
 
+/**
+ *     it8213_cable_detect     -       check for 40/80 pin
+ *     @ap: Port
+ *
+ *     Perform cable detection for the 8213 ATA interface. This is
+ *     different to the PIIX arrangement
+ */
+
+static int it8213_cable_detect(struct ata_port *ap)
+{
+       struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+       u8 tmp;
+       pci_read_config_byte(pdev, 0x42, &tmp);
+       if (tmp & 2)    /* The initial docs are incorrect */
+               return ATA_CBL_PATA40;
+       return ATA_CBL_PATA80;
+}
+
 /**
  *     it8213_set_piomode - Initialize host controller PATA PIO timings
  *     @ap: Port whose timings we are configuring
- *     @adev: um
+ *     @adev: Device whose timings we are configuring
  *
  *     Set PIO mode for device, in host controller PCI config space.
  *
@@ -268,6 +277,7 @@ static const struct ata_port_operations it8213_ops = {
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = it8213_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = it8213_cable_detect,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
index 35ecb2ba067b8b09453d0236071c4bde42a51214..f1f8cec8c224aad4ae1375eb0ea551a810652966 100644 (file)
@@ -80,7 +80,7 @@
 
 
 #define DRV_NAME "pata_it821x"
-#define DRV_VERSION "0.3.4"
+#define DRV_VERSION "0.3.6"
 
 struct it821x_dev
 {
@@ -112,31 +112,6 @@ struct it821x_dev
 
 static int it8212_noraid;
 
-/**
- *     it821x_pre_reset        -       probe
- *     @ap: ATA port
- *
- *     Set the cable type
- */
-
-static int it821x_pre_reset(struct ata_port *ap)
-{
-       ap->cbl = ATA_CBL_PATA80;
-       return ata_std_prereset(ap);
-}
-
-/**
- *     it821x_error_handler    -       probe/reset
- *     @ap: ATA port
- *
- *     Set the cable type and trigger a probe
- */
-
-static void it821x_error_handler(struct ata_port *ap)
-{
-       return ata_bmdma_drive_eh(ap, it821x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
 /**
  *     it821x_program  -       program the PIO/MWDMA registers
  *     @ap: ATA port
@@ -520,7 +495,6 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused
 
 /**
  *     it821x_dev_config       -       Called each device identify
- *     @ap: ATA port
  *     @adev: Device that has just been identified
  *
  *     Perform the initial setup needed for each device that is chip
@@ -531,7 +505,7 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused
  *     basically we need to filter commands for this chip.
  */
 
-static void it821x_dev_config(struct ata_port *ap, struct ata_device *adev)
+static void it821x_dev_config(struct ata_device *adev)
 {
        unsigned char model_num[ATA_ID_PROD_LEN + 1];
 
@@ -667,8 +641,9 @@ static struct ata_port_operations it821x_smart_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = it821x_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_unknown,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -703,8 +678,9 @@ static struct ata_port_operations it821x_passthru_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = it821x_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_unknown,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = it821x_passthru_bmdma_start,
index c6f0e192755156523ccb3cb93cf84e656c2833fe..420c343e57111107d88684557e8ea753f485fb39 100644 (file)
@@ -129,8 +129,8 @@ static struct ata_port_operations ixp4xx_port_ops = {
        .qc_issue       = ata_qc_issue_prot,
        .eng_timeout    = ata_eng_timeout,
        .data_xfer      = ixp4xx_mmio_data_xfer,
+       .cable_detect   = ata_cable_40wire,
 
-       .irq_handler    = ata_interrupt,
        .irq_clear      = ixp4xx_irq_clear,
        .irq_on         = ata_irq_on,
        .irq_ack        = ata_irq_ack,
@@ -173,12 +173,12 @@ static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
 
 static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
 {
-       int ret;
        unsigned int irq;
        struct resource *cs0, *cs1;
-       struct ata_probe_ent ae;
-
+       struct ata_host *host;
+       struct ata_port *ap;
        struct ixp4xx_pata_data *data = pdev->dev.platform_data;
+       int rc;
 
        cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -186,6 +186,12 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
        if (!cs0 || !cs1)
                return -EINVAL;
 
+       /* allocate host */
+       host = ata_host_alloc(&pdev->dev, 1);
+       if (!host)
+               return -ENOMEM;
+
+       /* acquire resources and fill host */
        pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
 
        data->cs0 = devm_ioremap(&pdev->dev, cs0->start, 0x1000);
@@ -199,32 +205,22 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
        *data->cs0_cfg = data->cs0_bits;
        *data->cs1_cfg = data->cs1_bits;
 
-       memset(&ae, 0, sizeof(struct ata_probe_ent));
-       INIT_LIST_HEAD(&ae.node);
+       ap = host->ports[0];
 
-       ae.dev          = &pdev->dev;
-       ae.port_ops     = &ixp4xx_port_ops;
-       ae.sht          = &ixp4xx_sht;
-       ae.n_ports      = 1;
-       ae.pio_mask     = 0x1f; /* PIO4 */
-       ae.irq          = irq;
-       ae.irq_flags    = 0;
-       ae.port_flags   = ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY
-                       | ATA_FLAG_NO_ATAPI | ATA_FLAG_SRST;
+       ap->ops = &ixp4xx_port_ops;
+       ap->pio_mask = 0x1f; /* PIO4 */
+       ap->flags |= ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY | ATA_FLAG_NO_ATAPI;
 
        /* run in polling mode if no irq has been assigned */
        if (!irq)
-               ae.port_flags |= ATA_FLAG_PIO_POLLING;
+               ap->flags |= ATA_FLAG_PIO_POLLING;
 
-       ixp4xx_setup_port(&ae.port[0], data);
+       ixp4xx_setup_port(&ap->ioaddr, data);
 
        dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
 
-       ret = ata_device_add(&ae);
-       if (ret == 0)
-               return -ENODEV;
-
-       return 0;
+       /* activate host */
+       return ata_host_activate(host, irq, ata_interrupt, 0, &ixp4xx_sht);
 }
 
 static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
index 86fbcd6a742b5dbb486b471806e496ef8ebf6712..707099291e017ae5beca51a8f866a6b1df99ebd1 100644 (file)
@@ -162,6 +162,7 @@ static struct ata_port_operations simple_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
@@ -185,6 +186,7 @@ static struct ata_port_operations legacy_port_ops = {
        .check_status   = ata_check_status,
        .exec_command   = ata_exec_command,
        .dev_select     = ata_std_dev_select,
+       .cable_detect   = ata_cable_40wire,
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
@@ -305,6 +307,7 @@ static struct ata_port_operations pdc20230_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
@@ -360,6 +363,7 @@ static struct ata_port_operations ht6560a_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
@@ -426,6 +430,7 @@ static struct ata_port_operations ht6560b_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
@@ -547,6 +552,7 @@ static struct ata_port_operations opti82c611a_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
@@ -680,6 +686,7 @@ static struct ata_port_operations opti82c46x_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = opti82c46x_qc_issue_prot,
@@ -709,7 +716,8 @@ static struct ata_port_operations opti82c46x_port_ops = {
 static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl, int irq)
 {
        struct legacy_data *ld = &legacy_data[nr_legacy_host];
-       struct ata_probe_ent ae;
+       struct ata_host *host;
+       struct ata_port *ap;
        struct platform_device *pdev;
        struct ata_port_operations *ops = &legacy_port_ops;
        void __iomem *io_addr, *ctrl_addr;
@@ -791,24 +799,23 @@ static __init int legacy_init_one(int port, unsigned long io, unsigned long ctrl
        if (ops == &legacy_port_ops && (autospeed & mask))
                ops = &simple_port_ops;
 
-       memset(&ae, 0, sizeof(struct ata_probe_ent));
-       INIT_LIST_HEAD(&ae.node);
-       ae.dev = &pdev->dev;
-       ae.port_ops = ops;
-       ae.sht = &legacy_sht;
-       ae.n_ports = 1;
-       ae.pio_mask = pio_modes;
-       ae.irq = irq;
-       ae.irq_flags = 0;
-       ae.port_flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST|iordy;
-       ae.port[0].cmd_addr = io_addr;
-       ae.port[0].altstatus_addr = ctrl_addr;
-       ae.port[0].ctl_addr = ctrl_addr;
-       ata_std_ports(&ae.port[0]);
-       ae.private_data = ld;
-
-       ret = -ENODEV;
-       if (!ata_device_add(&ae))
+       ret = -ENOMEM;
+       host = ata_host_alloc(&pdev->dev, 1);
+       if (!host)
+               goto fail;
+       ap = host->ports[0];
+
+       ap->ops = ops;
+       ap->pio_mask = pio_modes;
+       ap->flags |= ATA_FLAG_SLAVE_POSS | iordy;
+       ap->ioaddr.cmd_addr = io_addr;
+       ap->ioaddr.altstatus_addr = ctrl_addr;
+       ap->ioaddr.ctl_addr = ctrl_addr;
+       ata_std_ports(&ap->ioaddr);
+       ap->private_data = ld;
+
+       ret = ata_host_activate(host, irq, ata_interrupt, 0, &legacy_sht);
+       if (ret)
                goto fail;
 
        legacy_host[nr_legacy_host++] = dev_get_drvdata(&pdev->dev);
index 6dd7c4ef3e66bbd93832a2b4e36398a36f5756e2..d9b94a1b6954ed384b3d351858cd91f4a7baed70 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/ata.h>
 
 #define DRV_NAME       "pata_marvell"
-#define DRV_VERSION    "0.1.1"
+#define DRV_VERSION    "0.1.4"
 
 /**
  *     marvell_pre_reset       -       check for 40/80 pin
@@ -52,22 +52,23 @@ static int marvell_pre_reset(struct ata_port *ap)
        if ((pdev->device == 0x6145) && (ap->port_no == 0) &&
            (!(devices & 0x10)))        /* PATA enable ? */
                return -ENOENT;
+       return ata_std_prereset(ap);
+}
 
+static int marvell_cable_detect(struct ata_port *ap)
+{
        /* Cable type */
        switch(ap->port_no)
        {
        case 0:
                if (ioread8(ap->ioaddr.bmdma_addr + 1) & 1)
-                       ap->cbl = ATA_CBL_PATA40;
-               else
-                       ap->cbl = ATA_CBL_PATA80;
-               break;
-
+                       return ATA_CBL_PATA40;
+               return ATA_CBL_PATA80;
        case 1: /* Legacy SATA port */
-               ap->cbl = ATA_CBL_SATA;
-               break;
+               return ATA_CBL_SATA;
        }
-       return ata_std_prereset(ap);
+       BUG();
+       return 0;       /* Our BUG macro needs the right markup */
 }
 
 /**
@@ -123,6 +124,7 @@ static const struct ata_port_operations marvell_ops = {
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = marvell_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = marvell_cable_detect,
 
        /* BMDMA handling is PCI ATA format, use helpers */
        .bmdma_setup            = ata_bmdma_setup,
index 882c36eaf2935ce8e1184c56cc915b699e2aee61..9587a89f9683d98d46b4e359441b35dc598c11a9 100644 (file)
@@ -24,7 +24,7 @@
 
 
 #define DRV_NAME       "mpc52xx_ata"
-#define DRV_VERSION    "0.1.0"
+#define DRV_VERSION    "0.1.0ac2"
 
 
 /* Private structures used by the driver */
@@ -297,38 +297,37 @@ static struct ata_port_operations mpc52xx_ata_port_ops = {
        .freeze                 = ata_bmdma_freeze,
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = mpc52xx_ata_error_handler,
+       .cable_detect           = ata_cable_40wire,
        .qc_prep                = ata_qc_prep,
        .qc_issue               = ata_qc_issue_prot,
        .data_xfer              = ata_data_xfer,
-       .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
        .port_start             = ata_port_start,
 };
 
-static struct ata_probe_ent mpc52xx_ata_probe_ent = {
-       .port_ops       = &mpc52xx_ata_port_ops,
-       .sht            = &mpc52xx_ata_sht,
-       .n_ports        = 1,
-       .pio_mask       = 0x1f,         /* Up to PIO4 */
-       .mwdma_mask     = 0x00,         /* No MWDMA   */
-       .udma_mask      = 0x00,         /* No UDMA    */
-       .port_flags     = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
-       .irq_flags      = 0,
-};
-
 static int __devinit
 mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv)
 {
-       struct ata_probe_ent *ae = &mpc52xx_ata_probe_ent;
-       struct ata_ioports *aio = &ae->port[0];
-       int rv;
-
-       INIT_LIST_HEAD(&ae->node);
-       ae->dev = dev;
-       ae->irq = priv->ata_irq;
-
+       struct ata_host *host;
+       struct ata_port *ap;
+       struct ata_ioports *aio;
+       int rc;
+
+       host = ata_host_alloc(dev, 1);
+       if (!host)
+               return -ENOMEM;
+
+       ap = host->ports[0];
+       ap->flags               |= ATA_FLAG_SLAVE_POSS;
+       ap->pio_mask            = 0x1f; /* Up to PIO4 */
+       ap->mwdma_mask          = 0x00; /* No MWDMA   */
+       ap->udma_mask           = 0x00; /* No UDMA    */
+       ap->ops                 = &mpc52xx_ata_port_ops;
+       host->private_data      = priv;
+
+       aio = &ap->ioaddr;
        aio->cmd_addr           = NULL; /* Don't have a classic reg block */
        aio->altstatus_addr     = &priv->ata_regs->tf_control;
        aio->ctl_addr           = &priv->ata_regs->tf_control;
@@ -343,11 +342,9 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv)
        aio->status_addr        = &priv->ata_regs->tf_command;
        aio->command_addr       = &priv->ata_regs->tf_command;
 
-       ae->private_data = priv;
-
-       rv = ata_device_add(ae);
-
-       return rv ? 0 : -EINVAL;
+       /* activate host */
+       return ata_host_activate(host, priv->ata_irq, ata_interrupt, 0,
+                                &mpc52xx_ata_sht);
 }
 
 static struct mpc52xx_ata_priv *
index 4abe45ac19a2c121c03655875dd63b951c2c6d35..987c5fafab087e72b1490c30ca9983d0bb506f3b 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_mpiix"
-#define DRV_VERSION "0.7.5"
+#define DRV_VERSION "0.7.6"
 
 enum {
        IDETIM = 0x6C,          /* IDE control register */
@@ -53,7 +53,6 @@ static int mpiix_pre_reset(struct ata_port *ap)
 
        if (!pci_test_config_bits(pdev, &mpiix_enable_bits))
                return -ENOENT;
-       ap->cbl = ATA_CBL_PATA40;
        return ata_std_prereset(ap);
 }
 
@@ -185,12 +184,12 @@ static struct ata_port_operations mpiix_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = mpiix_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = mpiix_qc_issue_prot,
        .data_xfer      = ata_data_xfer,
 
-       .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
        .irq_on         = ata_irq_on,
        .irq_ack        = ata_irq_ack,
@@ -201,8 +200,9 @@ static struct ata_port_operations mpiix_port_ops = {
 static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
        /* Single threaded by the PCI probe logic */
-       static struct ata_probe_ent probe;
        static int printed_version;
+       struct ata_host *host;
+       struct ata_port *ap;
        void __iomem *cmd_addr, *ctl_addr;
        u16 idetim;
        int irq;
@@ -210,6 +210,10 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
 
+       host = ata_host_alloc(&dev->dev, 1);
+       if (!host)
+               return -ENOMEM;
+
        /* MPIIX has many functions which can be turned on or off according
           to other devices present. Make sure IDE is enabled before we try
           and use it */
@@ -238,27 +242,21 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
           without BARs set fools the setup.  #2 If you pci_disable_device
           the MPIIX your box goes castors up */
 
-       INIT_LIST_HEAD(&probe.node);
-       probe.dev = pci_dev_to_dev(dev);
-       probe.port_ops = &mpiix_port_ops;
-       probe.sht = &mpiix_sht;
-       probe.pio_mask = 0x1F;
-       probe.irq_flags = IRQF_SHARED;
-       probe.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
-       probe.n_ports = 1;
+       ap = host->ports[0];
+       ap->ops = &mpiix_port_ops;
+       ap->pio_mask = 0x1F;
+       ap->flags |= ATA_FLAG_SLAVE_POSS;
 
-       probe.irq = irq;
-       probe.port[0].cmd_addr = cmd_addr;
-       probe.port[0].ctl_addr = ctl_addr;
-       probe.port[0].altstatus_addr = ctl_addr;
+       ap->ioaddr.cmd_addr = cmd_addr;
+       ap->ioaddr.ctl_addr = ctl_addr;
+       ap->ioaddr.altstatus_addr = ctl_addr;
 
        /* Let libata fill in the port details */
-       ata_std_ports(&probe.port[0]);
+       ata_std_ports(&ap->ioaddr);
 
-       /* Now add the port that is active */
-       if (ata_device_add(&probe))
-               return 0;
-       return -ENODEV;
+       /* activate host */
+       return ata_host_activate(host, irq, ata_interrupt, IRQF_SHARED,
+                                &mpiix_sht);
 }
 
 static const struct pci_device_id mpiix[] = {
index 38f99b38a5ea97a861e1a8cb2d1d27f324ea38cc..dbba5b77d79c907e0444a89a1732848cab277891 100644 (file)
 #include <linux/ata.h>
 
 #define DRV_NAME       "pata_netcell"
-#define DRV_VERSION    "0.1.6"
-
-/**
- *     netcell_probe_init      -       check for 40/80 pin
- *     @ap: Port
- *
- *     Cables are handled by the RAID controller. Report 80 pin.
- */
-
-static int netcell_pre_reset(struct ata_port *ap)
-{
-       ap->cbl = ATA_CBL_PATA80;
-       return ata_std_prereset(ap);
-}
-
-/**
- *     netcell_probe_reset - Probe specified port on PATA host controller
- *     @ap: Port to probe
- *
- *     LOCKING:
- *     None (inherited from caller).
- */
-
-static void netcell_error_handler(struct ata_port *ap)
-{
-       return ata_bmdma_drive_eh(ap, netcell_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
+#define DRV_VERSION    "0.1.7"
 
 /* No PIO or DMA methods needed for this device */
 
@@ -81,8 +55,9 @@ static const struct ata_port_operations netcell_ops = {
 
        .freeze                 = ata_bmdma_freeze,
        .thaw                   = ata_bmdma_thaw,
-       .error_handler          = netcell_error_handler,
+       .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = ata_cable_80wire,
 
        /* BMDMA handling is PCI ATA format, use helpers */
        .bmdma_setup            = ata_bmdma_setup,
index 9944a28daa9c681874413ea23f8d95a938dc678a..078aeda9cf8d81eacea9e824adec6f199d683a52 100644 (file)
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_ns87410"
-#define DRV_VERSION "0.4.3"
+#define DRV_VERSION "0.4.6"
 
 /**
  *     ns87410_pre_reset               -       probe begin
  *     @ap: ATA port
  *
- *     Set up cable type and use generic probe init
+ *     Check enabled ports
  */
 
 static int ns87410_pre_reset(struct ata_port *ap)
@@ -47,7 +47,6 @@ static int ns87410_pre_reset(struct ata_port *ap)
 
        if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->port_no]))
                return -ENOENT;
-       ap->cbl = ATA_CBL_PATA40;
        return ata_std_prereset(ap);
 }
 
@@ -177,6 +176,7 @@ static struct ata_port_operations ns87410_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = ns87410_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ns87410_qc_issue_prot,
index da68cd19efd612cfc5f5bde902b98605ab23683f..dea4690340d1ed291cfd58c011d4f40ab55c11a1 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/ata.h>
 
 #define DRV_NAME       "pata_oldpiix"
-#define DRV_VERSION    "0.5.4"
+#define DRV_VERSION    "0.5.5"
 
 /**
  *     oldpiix_pre_reset               -       probe begin
@@ -44,7 +44,6 @@ static int oldpiix_pre_reset(struct ata_port *ap)
 
        if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->port_no]))
                return -ENOENT;
-       ap->cbl = ATA_CBL_PATA40;
        return ata_std_prereset(ap);
 }
 
@@ -65,7 +64,7 @@ static void oldpiix_pata_error_handler(struct ata_port *ap)
 /**
  *     oldpiix_set_piomode - Initialize host controller PATA PIO timings
  *     @ap: Port whose timings we are configuring
- *     @adev: um
+ *     @adev: Device whose timings we are configuring
  *
  *     Set PIO mode for device, in host controller PCI config space.
  *
@@ -255,6 +254,7 @@ static const struct ata_port_operations oldpiix_pata_ops = {
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = oldpiix_pata_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = ata_cable_40wire,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
index 3fd3a35c2241bf1015189e25db264389480ef128..13b63e21838d9ff94c0be60051c5a6e1190e78ee 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_opti"
-#define DRV_VERSION "0.2.8"
+#define DRV_VERSION "0.2.9"
 
 enum {
        READ_REG        = 0,    /* index of Read cycle timing register */
@@ -61,8 +61,6 @@ static int opti_pre_reset(struct ata_port *ap)
 
        if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->port_no]))
                return -ENOENT;
-
-       ap->cbl = ATA_CBL_PATA40;
        return ata_std_prereset(ap);
 }
 
@@ -198,6 +196,7 @@ static struct ata_port_operations opti_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = opti_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
index 9764907e8a134e20a238478bab1f932d9f224c0e..b70e04c144dfa591ec6afe925b9b9acaa756b118 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_optidma"
-#define DRV_VERSION "0.2.4"
+#define DRV_VERSION "0.3.2"
 
 enum {
        READ_REG        = 0,    /* index of Read cycle timing register */
@@ -62,7 +62,6 @@ static int optidma_pre_reset(struct ata_port *ap)
        if (ap->port_no && !pci_test_config_bits(pdev, &optidma_enable_bits))
                return -ENOENT;
 
-       ap->cbl = ATA_CBL_PATA40;
        return ata_std_prereset(ap);
 }
 
@@ -115,7 +114,7 @@ static void optidma_lock(struct ata_port *ap)
 }
 
 /**
- *     optidma_set_mode        -       set mode data
+ *     optidma_mode_setup      -       set mode data
  *     @ap: ATA interface
  *     @adev: ATA device
  *     @mode: Mode to set
@@ -128,7 +127,7 @@ static void optidma_lock(struct ata_port *ap)
  *     IRQ here we depend on the host set locking to avoid catastrophe.
  */
 
-static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode)
+static void optidma_mode_setup(struct ata_port *ap, struct ata_device *adev, u8 mode)
 {
        struct ata_device *pair = ata_dev_pair(adev);
        int pio = adev->pio_mode - XFER_PIO_0;
@@ -202,7 +201,7 @@ static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo
 }
 
 /**
- *     optiplus_set_mode       -       DMA setup for Firestar Plus
+ *     optiplus_mode_setup     -       DMA setup for Firestar Plus
  *     @ap: ATA port
  *     @adev: device
  *     @mode: desired mode
@@ -213,7 +212,7 @@ static void optidma_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mo
  *     one
  */
 
-static void optiplus_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode)
+static void optiplus_mode_setup(struct ata_port *ap, struct ata_device *adev, u8 mode)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u8 udcfg;
@@ -225,7 +224,7 @@ static void optiplus_set_mode(struct ata_port *ap, struct ata_device *adev, u8 m
        pci_read_config_byte(pdev, 0x44, &udcfg);
        if (mode <= XFER_UDMA_0) {
                udcfg &= ~(1 << unit);
-               optidma_set_mode(ap, adev, adev->dma_mode);
+               optidma_mode_setup(ap, adev, adev->dma_mode);
        } else {
                udcfg |=  (1 << unit);
                if (ap->port_no) {
@@ -253,7 +252,7 @@ static void optiplus_set_mode(struct ata_port *ap, struct ata_device *adev, u8 m
 
 static void optidma_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
 {
-       optidma_set_mode(ap, adev, adev->pio_mode);
+       optidma_mode_setup(ap, adev, adev->pio_mode);
 }
 
 /**
@@ -268,7 +267,7 @@ static void optidma_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
 
 static void optidma_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
 {
-       optidma_set_mode(ap, adev, adev->dma_mode);
+       optidma_mode_setup(ap, adev, adev->dma_mode);
 }
 
 /**
@@ -283,7 +282,7 @@ static void optidma_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
 
 static void optiplus_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
 {
-       optiplus_set_mode(ap, adev, adev->pio_mode);
+       optiplus_mode_setup(ap, adev, adev->pio_mode);
 }
 
 /**
@@ -298,7 +297,7 @@ static void optiplus_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
 
 static void optiplus_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
 {
-       optiplus_set_mode(ap, adev, adev->dma_mode);
+       optiplus_mode_setup(ap, adev, adev->dma_mode);
 }
 
 /**
@@ -322,26 +321,29 @@ static u8 optidma_make_bits43(struct ata_device *adev)
 }
 
 /**
- *     optidma_post_set_mode   -       finalize PCI setup
+ *     optidma_set_mode        -       mode setup
  *     @ap: port to set up
  *
- *     Finalise the configuration by writing the nibble of extra bits
- *     of data into the chip.
+ *     Use the standard setup to tune the chipset and then finalise the
+ *     configuration by writing the nibble of extra bits of data into
+ *     the chip.
  */
 
-static void optidma_post_set_mode(struct ata_port *ap)
+static int optidma_set_mode(struct ata_port *ap, struct ata_device **r_failed)
 {
        u8 r;
        int nybble = 4 * ap->port_no;
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-
-       pci_read_config_byte(pdev, 0x43, &r);
-
-       r &= (0x0F << nybble);
-       r |= (optidma_make_bits43(&ap->device[0]) +
-            (optidma_make_bits43(&ap->device[0]) << 2)) << nybble;
-
-       pci_write_config_byte(pdev, 0x43, r);
+       int rc  = ata_do_set_mode(ap, r_failed);
+       if (rc == 0) {
+               pci_read_config_byte(pdev, 0x43, &r);
+
+               r &= (0x0F << nybble);
+               r |= (optidma_make_bits43(&ap->device[0]) +
+                    (optidma_make_bits43(&ap->device[0]) << 2)) << nybble;
+               pci_write_config_byte(pdev, 0x43, r);
+       }
+       return rc;
 }
 
 static struct scsi_host_template optidma_sht = {
@@ -381,7 +383,8 @@ static struct ata_port_operations optidma_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
        .error_handler  = optidma_error_handler,
-       .post_set_mode  = optidma_post_set_mode,
+       .set_mode       = optidma_set_mode,
+       .cable_detect   = ata_cable_40wire,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -416,7 +419,8 @@ static struct ata_port_operations optiplus_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
        .error_handler  = optidma_error_handler,
-       .post_set_mode  = optidma_post_set_mode,
+       .set_mode       = optidma_set_mode,
+       .cable_detect   = ata_cable_40wire,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
index 103720f873c8f31d8384b0f54b5b97975c2ad3bb..75dc84797ff322eb9b9ffce033c2581dc5f5f4c2 100644 (file)
@@ -42,7 +42,7 @@
 
 
 #define DRV_NAME "pata_pcmcia"
-#define DRV_VERSION "0.3.0"
+#define DRV_VERSION "0.3.1"
 
 /*
  *     Private data structure to glue stuff together
@@ -54,6 +54,39 @@ struct ata_pcmcia_info {
        dev_node_t      node;
 };
 
+/**
+ *     pcmcia_set_mode -       PCMCIA specific mode setup
+ *     @ap: Port
+ *     @r_failed_dev: Return pointer for failed device
+ *
+ *     Perform the tuning and setup of the devices and timings, which
+ *     for PCMCIA is the same as any other controller. We wrap it however
+ *     as we need to spot hardware with incorrect or missing master/slave
+ *     decode, which alas is embarrassingly common in the PC world
+ */
+
+static int pcmcia_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
+{
+       struct ata_device *master = &ap->device[0];
+       struct ata_device *slave = &ap->device[1];
+
+       if (!ata_dev_enabled(master) || !ata_dev_enabled(slave))
+               return ata_do_set_mode(ap, r_failed_dev);
+
+       if (memcmp(master->id + ATA_ID_FW_REV,  slave->id + ATA_ID_FW_REV,
+                          ATA_ID_FW_REV_LEN + ATA_ID_PROD_LEN) == 0)
+       {
+               /* Suspicious match, but could be two cards from
+                  the same vendor - check serial */
+               if (memcmp(master->id + ATA_ID_SERNO, slave->id + ATA_ID_SERNO,
+                          ATA_ID_SERNO_LEN) == 0 && master->id[ATA_ID_SERNO] >> 8) {
+                       ata_dev_printk(slave, KERN_WARNING, "is a ghost device, ignoring.\n");
+                       ata_dev_disable(slave);
+               }
+       }
+       return ata_do_set_mode(ap, r_failed_dev);
+}
+
 static struct scsi_host_template pcmcia_sht = {
        .module                 = THIS_MODULE,
        .name                   = DRV_NAME,
@@ -73,6 +106,7 @@ static struct scsi_host_template pcmcia_sht = {
 };
 
 static struct ata_port_operations pcmcia_port_ops = {
+       .set_mode       = pcmcia_set_mode,
        .port_disable   = ata_port_disable,
        .tf_load        = ata_tf_load,
        .tf_read        = ata_tf_read,
@@ -84,13 +118,13 @@ static struct ata_port_operations pcmcia_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
 
        .data_xfer      = ata_data_xfer_noirq,
 
-       .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
        .irq_on         = ata_irq_on,
        .irq_ack        = ata_irq_ack,
@@ -111,7 +145,8 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 
 static int pcmcia_init_one(struct pcmcia_device *pdev)
 {
-       struct ata_probe_ent ae;
+       struct ata_host *host;
+       struct ata_port *ap;
        struct ata_pcmcia_info *info;
        tuple_t tuple;
        struct {
@@ -255,24 +290,24 @@ next_entry:
         *      Having done the PCMCIA plumbing the ATA side is relatively
         *      sane.
         */
-
-       memset(&ae, 0, sizeof(struct ata_probe_ent));
-       INIT_LIST_HEAD(&ae.node);
-       ae.dev = &pdev->dev;
-       ae.port_ops = &pcmcia_port_ops;
-       ae.sht = &pcmcia_sht;
-       ae.n_ports = 1;
-       ae.pio_mask = 1;                /* ISA so PIO 0 cycles */
-       ae.irq = pdev->irq.AssignedIRQ;
-       ae.irq_flags = IRQF_SHARED;
-       ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
-       ae.port[0].cmd_addr = io_addr;
-       ae.port[0].altstatus_addr = ctl_addr;
-       ae.port[0].ctl_addr = ctl_addr;
-       ata_std_ports(&ae.port[0]);
-
-       ret = -ENODEV;
-       if (ata_device_add(&ae) == 0)
+       ret = -ENOMEM;
+       host = ata_host_alloc(&pdev->dev, 1);
+       if (!host)
+               goto failed;
+       ap = host->ports[0];
+
+       ap->ops = &pcmcia_port_ops;
+       ap->pio_mask = 1;               /* ISA so PIO 0 cycles */
+       ap->flags |= ATA_FLAG_SLAVE_POSS;
+       ap->ioaddr.cmd_addr = io_addr;
+       ap->ioaddr.altstatus_addr = ctl_addr;
+       ap->ioaddr.ctl_addr = ctl_addr;
+       ata_std_ports(&ap->ioaddr);
+
+       /* activate */
+       ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_interrupt,
+                               IRQF_SHARED, &pcmcia_sht);
+       if (ret)
                goto failed;
 
        info->ndev = 1;
index 93bcdadb7be3a17c8ff82f00dc5a7425cf3c9d26..a61cbc110688d1bf97859666aaa5fc7462cf7d2c 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "pata_pdc2027x"
-#define DRV_VERSION    "0.8"
+#define DRV_VERSION    "0.9"
 #undef PDC_DEBUG
 
 #ifdef PDC_DEBUG
@@ -66,8 +66,10 @@ static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *e
 static void pdc2027x_error_handler(struct ata_port *ap);
 static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev);
 static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev);
-static void pdc2027x_post_set_mode(struct ata_port *ap);
 static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc);
+static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask);
+static int pdc2027x_cable_detect(struct ata_port *ap);
+static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed);
 
 /*
  * ATA Timing Tables based on 133MHz controller clock.
@@ -146,6 +148,7 @@ static struct scsi_host_template pdc2027x_sht = {
 
 static struct ata_port_operations pdc2027x_pata100_ops = {
        .port_disable           = ata_port_disable,
+       .mode_filter            = ata_pci_default_filter,
 
        .tf_load                = ata_tf_load,
        .tf_read                = ata_tf_read,
@@ -166,8 +169,8 @@ static struct ata_port_operations pdc2027x_pata100_ops = {
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = pdc2027x_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = pdc2027x_cable_detect,
 
-       .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -179,7 +182,8 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
        .port_disable           = ata_port_disable,
        .set_piomode            = pdc2027x_set_piomode,
        .set_dmamode            = pdc2027x_set_dmamode,
-       .post_set_mode          = pdc2027x_post_set_mode,
+       .set_mode               = pdc2027x_set_mode,
+       .mode_filter            = pdc2027x_mode_filter,
 
        .tf_load                = ata_tf_load,
        .tf_read                = ata_tf_read,
@@ -200,8 +204,8 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = pdc2027x_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = pdc2027x_cable_detect,
 
-       .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -212,7 +216,6 @@ static struct ata_port_operations pdc2027x_pata133_ops = {
 static struct ata_port_info pdc2027x_port_info[] = {
        /* PDC_UDMA_100 */
        {
-               .sht            = &pdc2027x_sht,
                .flags          = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
                                  ATA_FLAG_MMIO,
                .pio_mask       = 0x1f, /* pio0-4 */
@@ -222,7 +225,6 @@ static struct ata_port_info pdc2027x_port_info[] = {
        },
        /* PDC_UDMA_133 */
        {
-               .sht            = &pdc2027x_sht,
                .flags          = ATA_FLAG_NO_LEGACY | ATA_FLAG_SLAVE_POSS |
                                  ATA_FLAG_MMIO,
                .pio_mask       = 0x1f, /* pio0-4 */
@@ -261,7 +263,7 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade
 }
 
 /**
- *     pdc2027x_pata_cbl_detect - Probe host controller cable detect info
+ *     pdc2027x_pata_cable_detect - Probe host controller cable detect info
  *     @ap: Port for which cable detect info is desired
  *
  *     Read 80c cable indicator from Promise extended register.
@@ -270,7 +272,7 @@ static inline void __iomem *dev_mmio(struct ata_port *ap, struct ata_device *ade
  *     LOCKING:
  *     None (inherited from caller).
  */
-static void pdc2027x_cbl_detect(struct ata_port *ap)
+static int pdc2027x_cable_detect(struct ata_port *ap)
 {
        u32 cgcr;
 
@@ -281,13 +283,10 @@ static void pdc2027x_cbl_detect(struct ata_port *ap)
 
        PDPRINTK("No cable or 80-conductor cable on port %d\n", ap->port_no);
 
-       ap->cbl = ATA_CBL_PATA80;
-       return;
-
+       return ATA_CBL_PATA80;
 cbl40:
        printk(KERN_INFO DRV_NAME ": 40-conductor cable detected on port %d\n", ap->port_no);
-       ap->cbl = ATA_CBL_PATA40;
-       ap->udma_mask &= ATA_UDMA_MASK_40C;
+       return ATA_CBL_PATA40;
 }
 
 /**
@@ -314,7 +313,6 @@ static int pdc2027x_prereset(struct ata_port *ap)
        /* Check whether port enabled */
        if (!pdc2027x_port_enabled(ap))
                return -ENOENT;
-       pdc2027x_cbl_detect(ap);
        return ata_std_prereset(ap);
 }
 
@@ -333,6 +331,32 @@ static void pdc2027x_error_handler(struct ata_port *ap)
        ata_bmdma_drive_eh(ap, pdc2027x_prereset, ata_std_softreset, NULL, ata_std_postreset);
 }
 
+/**
+ *     pdc2720x_mode_filter    -       mode selection filter
+ *     @adev: ATA device
+ *     @mask: list of modes proposed
+ *
+ *     Block UDMA on devices that cause trouble with this controller.
+ */
+
+static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long mask)
+{
+       unsigned char model_num[ATA_ID_PROD_LEN + 1];
+       struct ata_device *pair = ata_dev_pair(adev);
+
+       if (adev->class != ATA_DEV_ATA || adev->devno == 0 || pair == NULL)
+               return ata_pci_default_filter(adev, mask);
+
+       /* Check for slave of a Maxtor at UDMA6 */
+       ata_id_c_string(pair->id, model_num, ATA_ID_PROD,
+                         ATA_ID_PROD_LEN + 1);
+       /* If the master is a maxtor in UDMA6 then the slave should not use UDMA 6 */
+       if(strstr(model_num, "Maxtor") == 0 && pair->dma_mode == XFER_UDMA_6)
+               mask &= ~ (1 << (6 + ATA_SHIFT_UDMA));
+
+       return ata_pci_default_filter(adev, mask);
+}
+
 /**
  *     pdc2027x_set_piomode - Initialize host controller PATA PIO timings
  *     @ap: Port to configure
@@ -444,17 +468,22 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
 }
 
 /**
- *     pdc2027x_post_set_mode - Set the timing registers back to correct values.
+ *     pdc2027x_set_mode - Set the timing registers back to correct values.
  *     @ap: Port to configure
+ *     @r_failed: Returned device for failure
  *
  *     The pdc2027x hardware will look at "SET FEATURES" and change the timing registers
  *     automatically. The values set by the hardware might be incorrect, under 133Mhz PLL.
  *     This function overwrites the possibly incorrect values set by the hardware to be correct.
  */
-static void pdc2027x_post_set_mode(struct ata_port *ap)
+static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed)
 {
        int i;
 
+       i = ata_do_set_mode(ap, r_failed);
+       if (i < 0)
+               return i;
+
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                struct ata_device *dev = &ap->device[i];
 
@@ -476,6 +505,7 @@ static void pdc2027x_post_set_mode(struct ata_port *ap)
                        }
                }
        }
+       return 0;
 }
 
 /**
@@ -521,12 +551,12 @@ static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc)
 
 /**
  * pdc_read_counter - Read the ctr counter
- * @probe_ent: for the port address
+ * @host: target ATA host
  */
 
-static long pdc_read_counter(struct ata_probe_ent *probe_ent)
+static long pdc_read_counter(struct ata_host *host)
 {
-       void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
+       void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
        long counter;
        int retry = 1;
        u32 bccrl, bccrh, bccrlv, bccrhv;
@@ -564,12 +594,12 @@ retry:
  * adjust_pll - Adjust the PLL input clock in Hz.
  *
  * @pdc_controller: controller specific information
- * @probe_ent: For the port address
+ * @host: target ATA host
  * @pll_clock: The input of PLL in HZ
  */
-static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsigned int board_idx)
+static void pdc_adjust_pll(struct ata_host *host, long pll_clock, unsigned int board_idx)
 {
-       void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
+       void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
        u16 pll_ctl;
        long pll_clock_khz = pll_clock / 1000;
        long pout_required = board_idx? PDC_133_MHZ:PDC_100_MHZ;
@@ -649,19 +679,19 @@ static void pdc_adjust_pll(struct ata_probe_ent *probe_ent, long pll_clock, unsi
 
 /**
  * detect_pll_input_clock - Detect the PLL input clock in Hz.
- * @probe_ent: for the port address
+ * @host: target ATA host
  * Ex. 16949000 on 33MHz PCI bus for pdc20275.
  *     Half of the PCI clock.
  */
-static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
+static long pdc_detect_pll_input_clock(struct ata_host *host)
 {
-       void __iomem *mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
+       void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
        u32 scr;
        long start_count, end_count;
        long pll_clock;
 
        /* Read current counter value */
-       start_count = pdc_read_counter(probe_ent);
+       start_count = pdc_read_counter(host);
 
        /* Start the test mode */
        scr = readl(mmio_base + PDC_SYS_CTL);
@@ -673,7 +703,7 @@ static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
        mdelay(100);
 
        /* Read the counter values again */
-       end_count = pdc_read_counter(probe_ent);
+       end_count = pdc_read_counter(host);
 
        /* Stop the test mode */
        scr = readl(mmio_base + PDC_SYS_CTL);
@@ -692,11 +722,10 @@ static long pdc_detect_pll_input_clock(struct ata_probe_ent *probe_ent)
 
 /**
  * pdc_hardware_init - Initialize the hardware.
- * @pdev: instance of pci_dev found
- * @pdc_controller: controller specific information
- * @pe:  for the port address
+ * @host: target ATA host
+ * @board_idx: board identifier
  */
-static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, unsigned int board_idx)
+static int pdc_hardware_init(struct ata_host *host, unsigned int board_idx)
 {
        long pll_clock;
 
@@ -706,15 +735,15 @@ static int pdc_hardware_init(struct pci_dev *pdev, struct ata_probe_ent *pe, uns
         * Ex. 25MHz or 40MHz, we have to adjust the cycle_time.
         * The pdc20275 controller employs PLL circuit to help correct timing registers setting.
         */
-       pll_clock = pdc_detect_pll_input_clock(pe);
+       pll_clock = pdc_detect_pll_input_clock(host);
 
        if (pll_clock < 0) /* counter overflow? Try again. */
-               pll_clock = pdc_detect_pll_input_clock(pe);
+               pll_clock = pdc_detect_pll_input_clock(host);
 
-       dev_printk(KERN_INFO, &pdev->dev, "PLL input clock %ld kHz\n", pll_clock/1000);
+       dev_printk(KERN_INFO, host->dev, "PLL input clock %ld kHz\n", pll_clock/1000);
 
        /* Adjust PLL control register */
-       pdc_adjust_pll(pe, pll_clock, board_idx);
+       pdc_adjust_pll(host, pll_clock, board_idx);
 
        return 0;
 }
@@ -746,8 +775,7 @@ static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base)
  * Called when an instance of PCI adapter is inserted.
  * This function checks whether the hardware is supported,
  * initialize hardware and register an instance of ata_host to
- * libata by providing struct ata_probe_ent and ata_device_add().
- * (implements struct pci_driver.probe() )
+ * libata.  (implements struct pci_driver.probe() )
  *
  * @pdev: instance of pci_dev found
  * @ent:  matching entry in the id_tbl[]
@@ -756,14 +784,21 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
 {
        static int printed_version;
        unsigned int board_idx = (unsigned int) ent->driver_data;
-
-       struct ata_probe_ent *probe_ent;
+       const struct ata_port_info *ppi[] =
+               { &pdc2027x_port_info[board_idx], NULL };
+       struct ata_host *host;
        void __iomem *mmio_base;
        int rc;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* alloc host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
+       if (!host)
+               return -ENOMEM;
+
+       /* acquire resources and fill host */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
@@ -771,6 +806,7 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
        rc = pcim_iomap_regions(pdev, 1 << PDC_MMIO_BAR, DRV_NAME);
        if (rc)
                return rc;
+       host->iomap = pcim_iomap_table(pdev);
 
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
@@ -780,46 +816,22 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
        if (rc)
                return rc;
 
-       /* Prepare the probe entry */
-       probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
-
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       probe_ent->sht          = pdc2027x_port_info[board_idx].sht;
-       probe_ent->port_flags   = pdc2027x_port_info[board_idx].flags;
-       probe_ent->pio_mask     = pdc2027x_port_info[board_idx].pio_mask;
-       probe_ent->mwdma_mask   = pdc2027x_port_info[board_idx].mwdma_mask;
-       probe_ent->udma_mask    = pdc2027x_port_info[board_idx].udma_mask;
-       probe_ent->port_ops     = pdc2027x_port_info[board_idx].port_ops;
+       mmio_base = host->iomap[PDC_MMIO_BAR];
 
-               probe_ent->irq = pdev->irq;
-               probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->iomap = pcim_iomap_table(pdev);
+       pdc_ata_setup_port(&host->ports[0]->ioaddr, mmio_base + 0x17c0);
+       host->ports[0]->ioaddr.bmdma_addr = mmio_base + 0x1000;
+       pdc_ata_setup_port(&host->ports[1]->ioaddr, mmio_base + 0x15c0);
+       host->ports[1]->ioaddr.bmdma_addr = mmio_base + 0x1008;
 
-       mmio_base = probe_ent->iomap[PDC_MMIO_BAR];
-
-       pdc_ata_setup_port(&probe_ent->port[0], mmio_base + 0x17c0);
-       probe_ent->port[0].bmdma_addr = mmio_base + 0x1000;
-       pdc_ata_setup_port(&probe_ent->port[1], mmio_base + 0x15c0);
-       probe_ent->port[1].bmdma_addr = mmio_base + 0x1008;
-
-       probe_ent->n_ports = 2;
-
-       pci_set_master(pdev);
        //pci_enable_intx(pdev);
 
        /* initialize adapter */
-       if (pdc_hardware_init(pdev, probe_ent, board_idx) != 0)
+       if (pdc_hardware_init(host, board_idx) != 0)
                return -EIO;
 
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(&pdev->dev, probe_ent);
-       return 0;
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+                                &pdc2027x_sht);
 }
 
 /**
index 0a149339891395d6264f7c3f1b01be7dde85cb84..ee636beb05e132f7da4ca127d569702c5eb4d6fc 100644 (file)
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_pdc202xx_old"
-#define DRV_VERSION "0.4.0"
+#define DRV_VERSION "0.4.2"
 
-/**
- *     pdc2024x_pre_reset              -       probe begin
- *     @ap: ATA port
- *
- *     Set up cable type and use generic probe init
- */
-
-static int pdc2024x_pre_reset(struct ata_port *ap)
-{
-       ap->cbl = ATA_CBL_PATA40;
-       return ata_std_prereset(ap);
-}
-
-
-static void pdc2024x_error_handler(struct ata_port *ap)
-{
-       ata_bmdma_drive_eh(ap, pdc2024x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
-
-static int pdc2026x_pre_reset(struct ata_port *ap)
+static int pdc2026x_cable_detect(struct ata_port *ap)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u16 cis;
 
        pci_read_config_word(pdev, 0x50, &cis);
        if (cis & (1 << (10 + ap->port_no)))
-               ap->cbl = ATA_CBL_PATA80;
-       else
-               ap->cbl = ATA_CBL_PATA40;
-
-       return ata_std_prereset(ap);
-}
-
-static void pdc2026x_error_handler(struct ata_port *ap)
-{
-       ata_bmdma_drive_eh(ap, pdc2026x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+               return ATA_CBL_PATA80;
+       return ATA_CBL_PATA40;
 }
 
 /**
@@ -244,7 +216,6 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc)
 
 /**
  *     pdc2026x_dev_config     -       device setup hook
- *     @ap: ATA port
  *     @adev: newly found device
  *
  *     Perform chip specific early setup. We need to lock the transfer
@@ -252,7 +223,7 @@ static void pdc2026x_bmdma_stop(struct ata_queued_cmd *qc)
  *     barf.
  */
 
-static void pdc2026x_dev_config(struct ata_port *ap, struct ata_device *adev)
+static void pdc2026x_dev_config(struct ata_device *adev)
 {
        adev->max_sectors = 256;
 }
@@ -292,8 +263,9 @@ static struct ata_port_operations pdc2024x_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = pdc2024x_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -326,8 +298,9 @@ static struct ata_port_operations pdc2026x_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = pdc2026x_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = pdc2026x_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = pdc2026x_bmdma_start,
index 4b82a5435a4ebfc1f558afa89bf088bb9d4dc565..a0a650c7f272042ae71458259fc1566aa66e91a9 100644 (file)
@@ -80,13 +80,13 @@ static struct ata_port_operations pata_platform_port_ops = {
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = ata_cable_unknown,
 
        .qc_prep                = ata_qc_prep,
        .qc_issue               = ata_qc_issue_prot,
 
        .data_xfer              = ata_data_xfer_noirq,
 
-       .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -135,7 +135,8 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr,
 static int __devinit pata_platform_probe(struct platform_device *pdev)
 {
        struct resource *io_res, *ctl_res;
-       struct ata_probe_ent ae;
+       struct ata_host *host;
+       struct ata_port *ap;
        unsigned int mmio;
 
        /*
@@ -175,44 +176,41 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
        /*
         * Now that that's out of the way, wire up the port..
         */
-       memset(&ae, 0, sizeof(struct ata_probe_ent));
-       INIT_LIST_HEAD(&ae.node);
-       ae.dev = &pdev->dev;
-       ae.port_ops = &pata_platform_port_ops;
-       ae.sht = &pata_platform_sht;
-       ae.n_ports = 1;
-       ae.pio_mask = pio_mask;
-       ae.irq = platform_get_irq(pdev, 0);
-       ae.irq_flags = 0;
-       ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
+       host = ata_host_alloc(&pdev->dev, 1);
+       if (!host)
+               return -ENOMEM;
+       ap = host->ports[0];
+
+       ap->ops = &pata_platform_port_ops;
+       ap->pio_mask = pio_mask;
+       ap->flags |= ATA_FLAG_SLAVE_POSS;
 
        /*
         * Handle the MMIO case
         */
        if (mmio) {
-               ae.port[0].cmd_addr = devm_ioremap(&pdev->dev, io_res->start,
+               ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, io_res->start,
                                io_res->end - io_res->start + 1);
-               ae.port[0].ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
+               ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
                                ctl_res->end - ctl_res->start + 1);
        } else {
-               ae.port[0].cmd_addr = devm_ioport_map(&pdev->dev, io_res->start,
+               ap->ioaddr.cmd_addr = devm_ioport_map(&pdev->dev, io_res->start,
                                io_res->end - io_res->start + 1);
-               ae.port[0].ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start,
+               ap->ioaddr.ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start,
                                ctl_res->end - ctl_res->start + 1);
        }
-       if (!ae.port[0].cmd_addr || !ae.port[0].ctl_addr) {
+       if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) {
                dev_err(&pdev->dev, "failed to map IO/CTL base\n");
                return -ENOMEM;
        }
 
-       ae.port[0].altstatus_addr = ae.port[0].ctl_addr;
+       ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
 
-       pata_platform_setup_port(&ae.port[0], pdev->dev.platform_data);
+       pata_platform_setup_port(&ap->ioaddr, pdev->dev.platform_data);
 
-       if (unlikely(ata_device_add(&ae) == 0))
-               return -ENODEV;
-
-       return 0;
+       /* activate */
+       return ata_host_activate(host, platform_get_irq(pdev, 0), ata_interrupt,
+                                0, &pata_platform_sht);
 }
 
 /**
index c3810012f3f4af7d873ecd120fda194974528dae..27685ce63ceb27a92f8780c6c1c6aca48aa5745d 100644 (file)
@@ -183,13 +183,13 @@ static struct ata_port_operations qdi6500_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = qdi_qc_issue_prot,
 
        .data_xfer      = qdi_data_xfer,
 
-       .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
        .irq_on         = ata_irq_on,
        .irq_ack        = ata_irq_ack,
@@ -211,13 +211,13 @@ static struct ata_port_operations qdi6580_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = qdi_qc_issue_prot,
 
        .data_xfer      = qdi_data_xfer,
 
-       .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
        .irq_on         = ata_irq_on,
        .irq_ack        = ata_irq_ack,
@@ -238,8 +238,9 @@ static struct ata_port_operations qdi6580_port_ops = {
 
 static __init int qdi_init_one(unsigned long port, int type, unsigned long io, int irq, int fast)
 {
-       struct ata_probe_ent ae;
        struct platform_device *pdev;
+       struct ata_host *host;
+       struct ata_port *ap;
        void __iomem *io_addr, *ctl_addr;
        int ret;
 
@@ -257,34 +258,31 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
        if (!io_addr || !ctl_addr)
                goto fail;
 
-       memset(&ae, 0, sizeof(struct ata_probe_ent));
-       INIT_LIST_HEAD(&ae.node);
-       ae.dev = &pdev->dev;
+       ret = -ENOMEM;
+       host = ata_host_alloc(&pdev->dev, 1);
+       if (!host)
+               goto fail;
+       ap = host->ports[0];
 
        if (type == 6580) {
-               ae.port_ops = &qdi6580_port_ops;
-               ae.pio_mask = 0x1F;
-               ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
+               ap->ops = &qdi6580_port_ops;
+               ap->pio_mask = 0x1F;
+               ap->flags |= ATA_FLAG_SLAVE_POSS;
        } else {
-               ae.port_ops = &qdi6500_port_ops;
-               ae.pio_mask = 0x07;     /* Actually PIO3 !IORDY is possible */
-               ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
-                               ATA_FLAG_NO_IORDY;
+               ap->ops = &qdi6500_port_ops;
+               ap->pio_mask = 0x07;    /* Actually PIO3 !IORDY is possible */
+               ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY;
        }
 
-       ae.sht = &qdi_sht;
-       ae.n_ports = 1;
-       ae.irq = irq;
-       ae.irq_flags = 0;
-       ae.port[0].cmd_addr = io_addr;
-       ae.port[0].altstatus_addr = ctl_addr;
-       ae.port[0].ctl_addr = ctl_addr;
-       ata_std_ports(&ae.port[0]);
+       ap->ioaddr.cmd_addr = io_addr;
+       ap->ioaddr.altstatus_addr = ctl_addr;
+       ap->ioaddr.ctl_addr = ctl_addr;
+       ata_std_ports(&ap->ioaddr);
 
        /*
         *      Hook in a private data structure per channel
         */
-       ae.private_data = &qdi_data[nr_qdi_host];
+       ap->private_data = &qdi_data[nr_qdi_host];
 
        qdi_data[nr_qdi_host].timing = port;
        qdi_data[nr_qdi_host].fast = fast;
@@ -292,8 +290,9 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
 
        printk(KERN_INFO DRV_NAME": qd%d at 0x%lx.\n", type, io);
 
-       ret = -ENODEV;
-       if (!ata_device_add(&ae))
+       /* activate */
+       ret = ata_host_activate(host, irq, ata_interrupt, 0, &qdi_sht);
+       if (ret)
                goto fail;
 
        qdi_host[nr_qdi_host++] = dev_get_drvdata(&pdev->dev);
index 9a9132c9e3317a034ab0f402cc45ae1f6289ac39..1c54673e008d0a0d2f5e7c3f821ac260d162522d 100644 (file)
 #include <linux/ata.h>
 
 #define DRV_NAME       "pata_radisys"
-#define DRV_VERSION    "0.4.1"
-
-/**
- *     radisys_probe_init              -       probe begin
- *     @ap: ATA port
- *
- *     Set up cable type and use generic probe init
- */
-
-static int radisys_pre_reset(struct ata_port *ap)
-{
-       ap->cbl = ATA_CBL_PATA80;
-       return ata_std_prereset(ap);
-}
-
-
-/**
- *     radisys_pata_error_handler - Probe specified port on PATA host controller
- *     @ap: Port to probe
- *     @classes:
- *
- *     LOCKING:
- *     None (inherited from caller).
- */
-
-static void radisys_pata_error_handler(struct ata_port *ap)
-{
-       ata_bmdma_drive_eh(ap, radisys_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
+#define DRV_VERSION    "0.4.4"
 
 /**
  *     radisys_set_piomode - Initialize host controller PATA PIO timings
- *     @ap: Port whose timings we are configuring
- *     @adev: um
+ *     @ap: ATA port
+ *     @adev: Device whose timings we are configuring
  *
  *     Set PIO mode for device, in host controller PCI config space.
  *
@@ -248,8 +220,9 @@ static const struct ata_port_operations radisys_pata_ops = {
 
        .freeze                 = ata_bmdma_freeze,
        .thaw                   = ata_bmdma_thaw,
-       .error_handler          = radisys_pata_error_handler,
+       .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = ata_cable_unknown,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
index f522daa2a6aa3c274befa168bca47fd2cd620643..85c45290eeee9972c1c59b27737d43f03a6b9b5b 100644 (file)
 #define DRV_VERSION    "0.2.3"
 
 
-/**
- *     rz1000_prereset         -       probe begin
- *     @ap: ATA port
- *
- *     Set up cable type and use generics
- */
-
-static int rz1000_prereset(struct ata_port *ap)
-{
-       ap->cbl = ATA_CBL_PATA40;
-       return ata_std_prereset(ap);
-}
-
-/**
- *     rz1000_error_handler            -       probe reset
- *     @ap: ATA port
- *
- *     Perform the ATA standard reset sequence
- */
-
-static void rz1000_error_handler(struct ata_port *ap)
-{
-       ata_bmdma_drive_eh(ap, rz1000_prereset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
 /**
  *     rz1000_set_mode         -       mode setting function
  *     @ap: ATA interface
@@ -122,8 +97,9 @@ static struct ata_port_operations rz1000_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = rz1000_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
index 93b3ed0f9e8ac9a448102073535e51f04cdceacb..66e8ff467c8d1b7771ce282627070dc0a2e4d05f 100644 (file)
@@ -216,6 +216,7 @@ static struct ata_port_operations sc1200_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
index f3ed141fdc0ea59554473ea2030bdb5fd9160f1d..5df354d573e8183c5174b8049bbf69b9860b7fb8 100644 (file)
@@ -1016,7 +1016,6 @@ static const struct ata_port_operations scc_pata_ops = {
        .error_handler          = scc_error_handler,
        .post_internal_cmd      = scc_bmdma_stop,
 
-       .irq_handler            = ata_interrupt,
        .irq_clear              = scc_bmdma_irq_clear,
        .irq_on                 = scc_irq_on,
        .irq_ack                = scc_irq_ack,
@@ -1027,7 +1026,6 @@ static const struct ata_port_operations scc_pata_ops = {
 
 static struct ata_port_info scc_port_info[] = {
        {
-               .sht            = &scc_sht,
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x00,
@@ -1040,10 +1038,10 @@ static struct ata_port_info scc_port_info[] = {
  *     scc_reset_controller - initialize SCC PATA controller.
  */
 
-static int scc_reset_controller(struct ata_probe_ent *probe_ent)
+static int scc_reset_controller(struct ata_host *host)
 {
-       void __iomem *ctrl_base = probe_ent->iomap[SCC_CTRL_BAR];
-       void __iomem *bmid_base = probe_ent->iomap[SCC_BMID_BAR];
+       void __iomem *ctrl_base = host->iomap[SCC_CTRL_BAR];
+       void __iomem *bmid_base = host->iomap[SCC_BMID_BAR];
        void __iomem *cckctrl_port = ctrl_base + SCC_CTL_CCKCTRL;
        void __iomem *mode_port = ctrl_base + SCC_CTL_MODEREG;
        void __iomem *ecmode_port = ctrl_base + SCC_CTL_ECMODE;
@@ -1104,17 +1102,15 @@ static void scc_setup_ports (struct ata_ioports *ioaddr, void __iomem *base)
        ioaddr->command_addr = ioaddr->cmd_addr + SCC_REG_CMD;
 }
 
-static int scc_host_init(struct ata_probe_ent *probe_ent)
+static int scc_host_init(struct ata_host *host)
 {
-       struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
+       struct pci_dev *pdev = to_pci_dev(host->dev);
        int rc;
 
-       rc = scc_reset_controller(probe_ent);
+       rc = scc_reset_controller(host);
        if (rc)
                return rc;
 
-       probe_ent->n_ports = 1;
-
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
                return rc;
@@ -1122,7 +1118,7 @@ static int scc_host_init(struct ata_probe_ent *probe_ent)
        if (rc)
                return rc;
 
-       scc_setup_ports(&probe_ent->port[0], probe_ent->iomap[SCC_BMID_BAR]);
+       scc_setup_ports(&host->ports[0]->ioaddr, host->iomap[SCC_BMID_BAR]);
 
        pci_set_master(pdev);
 
@@ -1145,14 +1141,18 @@ static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
        unsigned int board_idx = (unsigned int) ent->driver_data;
+       const struct ata_port_info *ppi[] = { &scc_port_info[board_idx], NULL };
        struct device *dev = &pdev->dev;
-       struct ata_probe_ent *probe_ent;
        int rc;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "version " DRV_VERSION "\n");
 
+       host = ata_port_alloc_pinfo(&pdev->dev, ppi, 1);
+       if (!host)
+               return -ENOMEM;
+
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
@@ -1162,33 +1162,14 @@ static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                pcim_pin_device(pdev);
        if (rc)
                return rc;
+       host->iomap = pcim_iomap_table(pdev);
 
-       probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (!probe_ent)
-               return -ENOMEM;
-
-       probe_ent->dev = dev;
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       probe_ent->sht          = scc_port_info[board_idx].sht;
-       probe_ent->port_flags   = scc_port_info[board_idx].flags;
-       probe_ent->pio_mask     = scc_port_info[board_idx].pio_mask;
-       probe_ent->udma_mask    = scc_port_info[board_idx].udma_mask;
-       probe_ent->port_ops     = scc_port_info[board_idx].port_ops;
-
-       probe_ent->irq = pdev->irq;
-       probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->iomap = pcim_iomap_table(pdev);
-
-       rc = scc_host_init(probe_ent);
+       rc = scc_host_init(host);
        if (rc)
                return rc;
 
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(dev, probe_ent);
-       return 0;
+       return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+                                &scc_sht);
 }
 
 static struct pci_driver scc_pci_driver = {
index 598eef810a74ab605001bb48e1191d42b7a99e4a..3956ef26936d3005d601f9ad231effb3be89b83a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * ata-serverworks.c   - Serverworks PATA for new ATA layer
+ * pata_serverworks.c  - Serverworks PATA for new ATA layer
  *                       (C) 2005 Red Hat Inc
  *                       Alan Cox <alan@redhat.com>
  *
@@ -137,14 +137,14 @@ static struct sv_cable_table cable_detect[] = {
 };
 
 /**
- *     serverworks_pre_reset           -       cable detection
+ *     serverworks_cable_detect        -       cable detection
  *     @ap: ATA port
  *
  *     Perform cable detection according to the device and subvendor
  *     identifications
  */
 
-static int serverworks_pre_reset(struct ata_port *ap) {
+static int serverworks_cable_detect(struct ata_port *ap) {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        struct sv_cable_table *cb = cable_detect;
 
@@ -152,8 +152,7 @@ static int serverworks_pre_reset(struct ata_port *ap) {
                if (cb->device == pdev->device &&
                    (cb->subvendor == pdev->subsystem_vendor ||
                      cb->subvendor == PCI_ANY_ID)) {
-                       ap->cbl = cb->cable_detect(ap);
-                       return ata_std_prereset(ap);
+                       return cb->cable_detect(ap);
                }
                cb++;
        }
@@ -162,11 +161,6 @@ static int serverworks_pre_reset(struct ata_port *ap) {
        return -1;      /* kill compiler warning */
 }
 
-static void serverworks_error_handler(struct ata_port *ap)
-{
-       return ata_bmdma_drive_eh(ap, serverworks_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
 /**
  *     serverworks_is_csb      -       Check for CSB or OSB
  *     @pdev: PCI device to check
@@ -191,31 +185,31 @@ static u8 serverworks_is_csb(struct pci_dev *pdev)
 
 /**
  *     serverworks_osb4_filter -       mode selection filter
- *     @ap: ATA interface
  *     @adev: ATA device
+ *     @mask: Mask of proposed modes
  *
  *     Filter the offered modes for the device to apply controller
  *     specific rules. OSB4 requires no UDMA for disks due to a FIFO
  *     bug we hit.
  */
 
-static unsigned long serverworks_osb4_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
+static unsigned long serverworks_osb4_filter(struct ata_device *adev, unsigned long mask)
 {
        if (adev->class == ATA_DEV_ATA)
                mask &= ~ATA_MASK_UDMA;
-       return ata_pci_default_filter(ap, adev, mask);
+       return ata_pci_default_filter(adev, mask);
 }
 
 
 /**
  *     serverworks_csb_filter  -       mode selection filter
- *     @ap: ATA interface
  *     @adev: ATA device
+ *     @mask: Mask of proposed modes
  *
  *     Check the blacklist and disable UDMA5 if matched
  */
 
-static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct ata_device *adev, unsigned long mask)
+static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned long mask)
 {
        const char *p;
        char model_num[ATA_ID_PROD_LEN + 1];
@@ -223,7 +217,7 @@ static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct at
 
        /* Disk, UDMA */
        if (adev->class != ATA_DEV_ATA)
-               return ata_pci_default_filter(ap, adev, mask);
+               return ata_pci_default_filter(adev, mask);
 
        /* Actually do need to check */
        ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
@@ -232,7 +226,7 @@ static unsigned long serverworks_csb_filter(const struct ata_port *ap, struct at
                if (!strcmp(p, model_num))
                        mask &= ~(0x1F << ATA_SHIFT_UDMA);
        }
-       return ata_pci_default_filter(ap, adev, mask);
+       return ata_pci_default_filter(adev, mask);
 }
 
 
@@ -339,8 +333,9 @@ static struct ata_port_operations serverworks_osb4_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = serverworks_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = serverworks_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -374,8 +369,9 @@ static struct ata_port_operations serverworks_csb_port_ops = {
 
        .freeze         = ata_bmdma_freeze,
        .thaw           = ata_bmdma_thaw,
-       .error_handler  = serverworks_error_handler,
+       .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = serverworks_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
index dab2889a556f4ab28305bfaf985f7cf7107c5f6a..6770820cfca9c74c08f8e7e9eb8759429be6b624 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_sil680"
-#define DRV_VERSION "0.4.5"
+#define DRV_VERSION "0.4.6"
 
 /**
  *     sil680_selreg           -       return register base
@@ -91,12 +91,6 @@ static int sil680_cable_detect(struct ata_port *ap) {
                return ATA_CBL_PATA40;
 }
 
-static int sil680_pre_reset(struct ata_port *ap)
-{
-       ap->cbl = sil680_cable_detect(ap);
-       return ata_std_prereset(ap);
-}
-
 /**
  *     sil680_bus_reset        -       reset the SIL680 bus
  *     @ap: ATA port to reset
@@ -119,7 +113,7 @@ static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes)
 
 static void sil680_error_handler(struct ata_port *ap)
 {
-       ata_bmdma_drive_eh(ap, sil680_pre_reset, sil680_bus_reset, NULL, ata_std_postreset);
+       ata_bmdma_drive_eh(ap, ata_std_prereset, sil680_bus_reset, NULL, ata_std_postreset);
 }
 
 /**
@@ -257,6 +251,7 @@ static struct ata_port_operations sil680_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = sil680_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = sil680_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
index 8dc3bc4f5863dc33ea1832083ef3a6325d896b1f..a3fbcee6fb330185ebf97ba10ecf9cb711862530 100644 (file)
@@ -35,7 +35,7 @@
 #include "sis.h"
 
 #define DRV_NAME       "pata_sis"
-#define DRV_VERSION    "0.5.0"
+#define DRV_VERSION    "0.5.1"
 
 struct sis_chipset {
        u16 device;                     /* PCI host ID */
@@ -86,106 +86,55 @@ static int sis_port_base(struct ata_device *adev)
 }
 
 /**
- *     sis_133_pre_reset       -       check for 40/80 pin
+ *     sis_133_cable_detect    -       check for 40/80 pin
  *     @ap: Port
  *
  *     Perform cable detection for the later UDMA133 capable
  *     SiS chipset.
  */
 
-static int sis_133_pre_reset(struct ata_port *ap)
+static int sis_133_cable_detect(struct ata_port *ap)
 {
-       static const struct pci_bits sis_enable_bits[] = {
-               { 0x4aU, 1U, 0x02UL, 0x02UL },  /* port 0 */
-               { 0x4aU, 1U, 0x04UL, 0x04UL },  /* port 1 */
-       };
-
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u16 tmp;
 
-       if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
-               return -ENOENT;
-
        /* The top bit of this register is the cable detect bit */
        pci_read_config_word(pdev, 0x50 + 2 * ap->port_no, &tmp);
        if ((tmp & 0x8000) && !sis_short_ata40(pdev))
-               ap->cbl = ATA_CBL_PATA40;
-       else
-               ap->cbl = ATA_CBL_PATA80;
-
-       return ata_std_prereset(ap);
+               return ATA_CBL_PATA40;
+       return ATA_CBL_PATA80;
 }
 
 /**
- *     sis_error_handler - Probe specified port on PATA host controller
- *     @ap: Port to probe
- *
- *     LOCKING:
- *     None (inherited from caller).
- */
-
-static void sis_133_error_handler(struct ata_port *ap)
-{
-       ata_bmdma_drive_eh(ap, sis_133_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
-
-/**
- *     sis_66_pre_reset        -       check for 40/80 pin
+ *     sis_66_cable_detect     -       check for 40/80 pin
  *     @ap: Port
  *
  *     Perform cable detection on the UDMA66, UDMA100 and early UDMA133
  *     SiS IDE controllers.
  */
 
-static int sis_66_pre_reset(struct ata_port *ap)
+static int sis_66_cable_detect(struct ata_port *ap)
 {
-       static const struct pci_bits sis_enable_bits[] = {
-               { 0x4aU, 1U, 0x02UL, 0x02UL },  /* port 0 */
-               { 0x4aU, 1U, 0x04UL, 0x04UL },  /* port 1 */
-       };
-
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u8 tmp;
 
-       if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) {
-               ata_port_disable(ap);
-               ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n");
-               return 0;
-       }
        /* Older chips keep cable detect in bits 4/5 of reg 0x48 */
        pci_read_config_byte(pdev, 0x48, &tmp);
        tmp >>= ap->port_no;
        if ((tmp & 0x10) && !sis_short_ata40(pdev))
-               ap->cbl = ATA_CBL_PATA40;
-       else
-               ap->cbl = ATA_CBL_PATA80;
-
-       return ata_std_prereset(ap);
+               return ATA_CBL_PATA40;
+       return ATA_CBL_PATA80;
 }
 
-/**
- *     sis_66_error_handler - Probe specified port on PATA host controller
- *     @ap: Port to probe
- *     @classes:
- *
- *     LOCKING:
- *     None (inherited from caller).
- */
-
-static void sis_66_error_handler(struct ata_port *ap)
-{
-       ata_bmdma_drive_eh(ap, sis_66_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
 
 /**
- *     sis_old_pre_reset               -       probe begin
+ *     sis_pre_reset           -       probe begin
  *     @ap: ATA port
  *
  *     Set up cable type and use generic probe init
  */
 
-static int sis_old_pre_reset(struct ata_port *ap)
+static int sis_pre_reset(struct ata_port *ap)
 {
        static const struct pci_bits sis_enable_bits[] = {
                { 0x4aU, 1U, 0x02UL, 0x02UL },  /* port 0 */
@@ -194,27 +143,23 @@ static int sis_old_pre_reset(struct ata_port *ap)
 
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
-       if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) {
-               ata_port_disable(ap);
-               ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n");
-               return 0;
-       }
-       ap->cbl = ATA_CBL_PATA40;
+       if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no]))
+               return -ENOENT;
        return ata_std_prereset(ap);
 }
 
 
 /**
- *     sis_old_error_handler - Probe specified port on PATA host controller
+ *     sis_error_handler - Probe specified port on PATA host controller
  *     @ap: Port to probe
  *
  *     LOCKING:
  *     None (inherited from caller).
  */
 
-static void sis_old_error_handler(struct ata_port *ap)
+static void sis_error_handler(struct ata_port *ap)
 {
-       ata_bmdma_drive_eh(ap, sis_old_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+       ata_bmdma_drive_eh(ap, sis_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
 }
 
 /**
@@ -494,7 +439,7 @@ static void sis_133_early_set_dmamode (struct ata_port *ap, struct ata_device *a
        int drive_pci = sis_port_base(adev);
        u16 timing;
 
-       const u16 udma_bits[]  = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
+       static const u16 udma_bits[]  = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
 
        pci_read_config_word(pdev, drive_pci, &timing);
 
@@ -531,8 +476,8 @@ static void sis_133_set_dmamode (struct ata_port *ap, struct ata_device *adev)
        u32 reg54;
 
        /* bits 4- cycle time 8 - cvs time */
-       const u32 timing_u100[] = { 0x6B0, 0x470, 0x350, 0x140, 0x120, 0x110, 0x000 };
-       const u32 timing_u133[] = { 0x9F0, 0x6A0, 0x470, 0x250, 0x230, 0x220, 0x210 };
+       static const u32 timing_u100[] = { 0x6B0, 0x470, 0x350, 0x140, 0x120, 0x110, 0x000 };
+       static const u32 timing_u133[] = { 0x9F0, 0x6A0, 0x470, 0x250, 0x230, 0x220, 0x210 };
 
        /* If bit 14 is set then the registers are mapped at 0x70 not 0x40 */
        pci_read_config_dword(pdev, 0x54, &reg54);
@@ -595,8 +540,9 @@ static const struct ata_port_operations sis_133_ops = {
 
        .freeze                 = ata_bmdma_freeze,
        .thaw                   = ata_bmdma_thaw,
-       .error_handler          = sis_133_error_handler,
+       .error_handler          = sis_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = sis_133_cable_detect,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
@@ -628,8 +574,9 @@ static const struct ata_port_operations sis_133_early_ops = {
 
        .freeze                 = ata_bmdma_freeze,
        .thaw                   = ata_bmdma_thaw,
-       .error_handler          = sis_66_error_handler,
+       .error_handler          = sis_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = sis_66_cable_detect,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
@@ -661,9 +608,9 @@ static const struct ata_port_operations sis_100_ops = {
 
        .freeze                 = ata_bmdma_freeze,
        .thaw                   = ata_bmdma_thaw,
-       .error_handler          = sis_66_error_handler,
+       .error_handler          = sis_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
-
+       .cable_detect           = sis_66_cable_detect,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
@@ -692,10 +639,11 @@ static const struct ata_port_operations sis_66_ops = {
        .check_status           = ata_check_status,
        .exec_command           = ata_exec_command,
        .dev_select             = ata_std_dev_select,
+       .cable_detect           = sis_66_cable_detect,
 
        .freeze                 = ata_bmdma_freeze,
        .thaw                   = ata_bmdma_thaw,
-       .error_handler          = sis_66_error_handler,
+       .error_handler          = sis_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
 
        .bmdma_setup            = ata_bmdma_setup,
@@ -728,8 +676,9 @@ static const struct ata_port_operations sis_old_ops = {
 
        .freeze                 = ata_bmdma_freeze,
        .thaw                   = ata_bmdma_thaw,
-       .error_handler          = sis_old_error_handler,
+       .error_handler          = sis_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = ata_cable_40wire,
 
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
index b681441cfcb96a96a17ed5492d6c985961427d07..da9e22b257532f10fb7e930117b379426b956fea 100644 (file)
@@ -58,7 +58,6 @@ static int sl82c105_pre_reset(struct ata_port *ap)
 
        if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no]))
                return -ENOENT;
-       ap->cbl = ATA_CBL_PATA40;
        return ata_std_prereset(ap);
 }
 
@@ -238,6 +237,7 @@ static struct ata_port_operations sl82c105_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = sl82c105_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = sl82c105_bmdma_start,
index 71418f2a0cdb702408fde99a2203ddb1441106c9..e618ffd6e944b392ac35458ee5cd3dc7c73fc264 100644 (file)
@@ -43,7 +43,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_triflex"
-#define DRV_VERSION "0.2.7"
+#define DRV_VERSION "0.2.8"
 
 /**
  *     triflex_prereset                -       probe begin
@@ -63,7 +63,6 @@ static int triflex_prereset(struct ata_port *ap)
 
        if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no]))
                return -ENOENT;
-       ap->cbl = ATA_CBL_PATA40;
        return ata_std_prereset(ap);
 }
 
@@ -214,6 +213,7 @@ static struct ata_port_operations triflex_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = triflex_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = triflex_bmdma_start,
index 946ade0e1f1b3e7a43a7a09ec5a2406afde85834..96b71791d2f48edc8109d606a7a7d76c074df51b 100644 (file)
@@ -62,7 +62,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME "pata_via"
-#define DRV_VERSION "0.2.1"
+#define DRV_VERSION "0.3.1"
 
 /*
  *     The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
@@ -135,16 +135,23 @@ static const struct via_isa_bridge {
  */
 
 static int via_cable_detect(struct ata_port *ap) {
+       const struct via_isa_bridge *config = ap->host->private_data;
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u32 ata66;
 
+       /* Early chips are 40 wire */
+       if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
+               return ATA_CBL_PATA40;
+       /* UDMA 66 chips have only drive side logic */
+       else if((config->flags & VIA_UDMA) < VIA_UDMA_100)
+               return ATA_CBL_PATA_UNK;
+       /* UDMA 100 or later */
        pci_read_config_dword(pdev, 0x50, &ata66);
        /* Check both the drive cable reporting bits, we might not have
           two drives */
        if (ata66 & (0x10100000 >> (16 * ap->port_no)))
                return ATA_CBL_PATA80;
-       else
-               return ATA_CBL_PATA40;
+       return ATA_CBL_PATA40;
 }
 
 static int via_pre_reset(struct ata_port *ap)
@@ -156,22 +163,10 @@ static int via_pre_reset(struct ata_port *ap)
                        { 0x40, 1, 0x02, 0x02 },
                        { 0x40, 1, 0x01, 0x01 }
                };
-
                struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-
                if (!pci_test_config_bits(pdev, &via_enable_bits[ap->port_no]))
                        return -ENOENT;
        }
-
-       if ((config->flags & VIA_UDMA) >= VIA_UDMA_100)
-               ap->cbl = via_cable_detect(ap);
-       /* The UDMA66 series has no cable detect so do drive side detect */
-       else if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
-               ap->cbl = ATA_CBL_PATA40;
-       else
-               ap->cbl = ATA_CBL_PATA_UNK;
-
-
        return ata_std_prereset(ap);
 }
 
@@ -327,6 +322,7 @@ static struct ata_port_operations via_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = via_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = via_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
@@ -362,6 +358,7 @@ static struct ata_port_operations via_port_ops_noirq = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = via_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = via_cable_detect,
 
        .bmdma_setup    = ata_bmdma_setup,
        .bmdma_start    = ata_bmdma_start,
index 6c111035fc84da35b2ffa7e4bcf42fcb4951a960..cc4ad271afb58be4b21010216efd3146c8ddb9df 100644 (file)
@@ -8,7 +8,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/blkdev.h>
 #include <linux/delay.h>
@@ -36,7 +35,7 @@ static int probe_winbond = 1;
 static int probe_winbond;
 #endif
 
-static spinlock_t winbond_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(winbond_lock);
 
 static void winbond_writecfg(unsigned long port, u8 reg, u8 val)
 {
@@ -152,13 +151,13 @@ static struct ata_port_operations winbond_port_ops = {
        .thaw           = ata_bmdma_thaw,
        .error_handler  = ata_bmdma_error_handler,
        .post_internal_cmd = ata_bmdma_post_internal_cmd,
+       .cable_detect   = ata_cable_40wire,
 
        .qc_prep        = ata_qc_prep,
        .qc_issue       = ata_qc_issue_prot,
 
        .data_xfer      = winbond_data_xfer,
 
-       .irq_handler    = ata_interrupt,
        .irq_clear      = ata_bmdma_irq_clear,
        .irq_on         = ata_irq_on,
        .irq_ack        = ata_irq_ack,
@@ -179,11 +178,9 @@ static struct ata_port_operations winbond_port_ops = {
 
 static __init int winbond_init_one(unsigned long port)
 {
-       struct ata_probe_ent ae;
        struct platform_device *pdev;
-       int ret;
        u8 reg;
-       int i;
+       int i, rc;
 
        reg = winbond_readcfg(port, 0x81);
        reg |= 0x80;    /* jumpered mode off */
@@ -202,58 +199,56 @@ static __init int winbond_init_one(unsigned long port)
 
        for (i = 0; i < 2 ; i ++) {
                unsigned long cmd_port = 0x1F0 - (0x80 * i);
+               struct ata_host *host;
+               struct ata_port *ap;
                void __iomem *cmd_addr, *ctl_addr;
 
-               if (reg & (1 << i)) {
-                       /*
-                        *      Fill in a probe structure first of all
-                        */
-
-                       pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0);
-                       if (IS_ERR(pdev))
-                               return PTR_ERR(pdev);
-
-                       cmd_addr = devm_ioport_map(&pdev->dev, cmd_port, 8);
-                       ctl_addr = devm_ioport_map(&pdev->dev, cmd_port + 0x0206, 1);
-                       if (!cmd_addr || !ctl_addr) {
-                               platform_device_unregister(pdev);
-                               return -ENOMEM;
-                       }
-
-                       memset(&ae, 0, sizeof(struct ata_probe_ent));
-                       INIT_LIST_HEAD(&ae.node);
-                       ae.dev = &pdev->dev;
-
-                       ae.port_ops = &winbond_port_ops;
-                       ae.pio_mask = 0x1F;
-
-                       ae.sht = &winbond_sht;
-
-                       ae.n_ports = 1;
-                       ae.irq = 14 + i;
-                       ae.irq_flags = 0;
-                       ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
-                       ae.port[0].cmd_addr = cmd_addr;
-                       ae.port[0].altstatus_addr = ctl_addr;
-                       ae.port[0].ctl_addr = ctl_addr;
-                       ata_std_ports(&ae.port[0]);
-                       /*
-                        *      Hook in a private data structure per channel
-                        */
-                       ae.private_data = &winbond_data[nr_winbond_host];
-                       winbond_data[nr_winbond_host].config = port;
-                       winbond_data[nr_winbond_host].platform_dev = pdev;
-
-                       ret = ata_device_add(&ae);
-                       if (ret == 0) {
-                               platform_device_unregister(pdev);
-                               return -ENODEV;
-                       }
-                       winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev);
-               }
+               if (!(reg & (1 << i)))
+                       continue;
+
+               pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0);
+               if (IS_ERR(pdev))
+                       return PTR_ERR(pdev);
+
+               rc = -ENOMEM;
+               host = ata_host_alloc(&pdev->dev, 1);
+               if (!host)
+                       goto err_unregister;
+
+               rc = -ENOMEM;
+               cmd_addr = devm_ioport_map(&pdev->dev, cmd_port, 8);
+               ctl_addr = devm_ioport_map(&pdev->dev, cmd_port + 0x0206, 1);
+               if (!cmd_addr || !ctl_addr)
+                       goto err_unregister;
+
+               ap = host->ports[0];
+               ap->ops = &winbond_port_ops;
+               ap->pio_mask = 0x1F;
+               ap->flags |= ATA_FLAG_SLAVE_POSS;
+               ap->ioaddr.cmd_addr = cmd_addr;
+               ap->ioaddr.altstatus_addr = ctl_addr;
+               ap->ioaddr.ctl_addr = ctl_addr;
+               ata_std_ports(&ap->ioaddr);
+
+               /* hook in a private data structure per channel */
+               host->private_data = &winbond_data[nr_winbond_host];
+               winbond_data[nr_winbond_host].config = port;
+               winbond_data[nr_winbond_host].platform_dev = pdev;
+
+               /* activate */
+               rc = ata_host_activate(host, 14 + i, ata_interrupt, 0,
+                                      &winbond_sht);
+               if (rc)
+                       goto err_unregister;
+
+               winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev);
        }
 
        return 0;
+
+ err_unregister:
+       platform_device_unregister(pdev);
+       return rc;
 }
 
 /**
index 5dd3ca8b5f29fb273303810d488c318d80ce7287..52b69530ab29d768b8d71cebc15e5a5fa2b61341 100644 (file)
@@ -52,9 +52,9 @@
 /* macro to calculate base address for ADMA regs */
 #define ADMA_REGS(base,port_no)                ((base) + 0x80 + ((port_no) * 0x20))
 
-/* macro to obtain addresses from ata_host */
-#define ADMA_HOST_REGS(host,port_no) \
-       ADMA_REGS((host)->iomap[ADMA_MMIO_BAR], port_no)
+/* macro to obtain addresses from ata_port */
+#define ADMA_PORT_REGS(ap) \
+       ADMA_REGS((ap)->host->iomap[ADMA_MMIO_BAR], ap->port_no)
 
 enum {
        ADMA_MMIO_BAR           = 4,
@@ -128,7 +128,6 @@ struct adma_port_priv {
 
 static int adma_ata_init_one (struct pci_dev *pdev,
                                const struct pci_device_id *ent);
-static irqreturn_t adma_intr (int irq, void *dev_instance);
 static int adma_port_start(struct ata_port *ap);
 static void adma_host_stop(struct ata_host *host);
 static void adma_port_stop(struct ata_port *ap);
@@ -172,7 +171,6 @@ static const struct ata_port_operations adma_ata_ops = {
        .qc_issue               = adma_qc_issue,
        .eng_timeout            = adma_eng_timeout,
        .data_xfer              = ata_data_xfer,
-       .irq_handler            = adma_intr,
        .irq_clear              = adma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -186,7 +184,6 @@ static const struct ata_port_operations adma_ata_ops = {
 static struct ata_port_info adma_port_info[] = {
        /* board_1841_idx */
        {
-               .sht            = &adma_ata_sht,
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST |
                                  ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO |
                                  ATA_FLAG_PIO_POLLING,
@@ -229,8 +226,10 @@ static void adma_irq_clear(struct ata_port *ap)
        /* nothing */
 }
 
-static void adma_reset_engine(void __iomem *chan)
+static void adma_reset_engine(struct ata_port *ap)
 {
+       void __iomem *chan = ADMA_PORT_REGS(ap);
+
        /* reset ADMA to idle state */
        writew(aPIOMD4 | aNIEN | aRSTADM, chan + ADMA_CONTROL);
        udelay(2);
@@ -241,14 +240,14 @@ static void adma_reset_engine(void __iomem *chan)
 static void adma_reinit_engine(struct ata_port *ap)
 {
        struct adma_port_priv *pp = ap->private_data;
-       void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
+       void __iomem *chan = ADMA_PORT_REGS(ap);
 
        /* mask/clear ATA interrupts */
        writeb(ATA_NIEN, ap->ioaddr.ctl_addr);
        ata_check_status(ap);
 
        /* reset the ADMA engine */
-       adma_reset_engine(chan);
+       adma_reset_engine(ap);
 
        /* set in-FIFO threshold to 0x100 */
        writew(0x100, chan + ADMA_FIFO_IN);
@@ -268,7 +267,7 @@ static void adma_reinit_engine(struct ata_port *ap)
 
 static inline void adma_enter_reg_mode(struct ata_port *ap)
 {
-       void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
+       void __iomem *chan = ADMA_PORT_REGS(ap);
 
        writew(aPIOMD4, chan + ADMA_CONTROL);
        readb(chan + ADMA_STATUS);      /* flush */
@@ -415,7 +414,7 @@ static void adma_qc_prep(struct ata_queued_cmd *qc)
 static inline void adma_packet_start(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
-       void __iomem *chan = ADMA_HOST_REGS(ap->host, ap->port_no);
+       void __iomem *chan = ADMA_PORT_REGS(ap);
 
        VPRINTK("ENTER, ap %p\n", ap);
 
@@ -453,7 +452,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host *host)
                struct ata_port *ap = host->ports[port_no];
                struct adma_port_priv *pp;
                struct ata_queued_cmd *qc;
-               void __iomem *chan = ADMA_HOST_REGS(host, port_no);
+               void __iomem *chan = ADMA_PORT_REGS(ap);
                u8 status = readb(chan + ADMA_STATUS);
 
                if (status == 0)
@@ -575,7 +574,7 @@ static int adma_port_start(struct ata_port *ap)
 
 static void adma_port_stop(struct ata_port *ap)
 {
-       adma_reset_engine(ADMA_HOST_REGS(ap->host, ap->port_no));
+       adma_reset_engine(ap);
 }
 
 static void adma_host_stop(struct ata_host *host)
@@ -583,21 +582,19 @@ static void adma_host_stop(struct ata_host *host)
        unsigned int port_no;
 
        for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
-               adma_reset_engine(ADMA_HOST_REGS(host, port_no));
+               adma_reset_engine(host->ports[port_no]);
 }
 
-static void adma_host_init(unsigned int chip_id,
-                               struct ata_probe_ent *probe_ent)
+static void adma_host_init(struct ata_host *host, unsigned int chip_id)
 {
        unsigned int port_no;
-       void __iomem *mmio_base = probe_ent->iomap[ADMA_MMIO_BAR];
 
        /* enable/lock aGO operation */
-       writeb(7, mmio_base + ADMA_MODE_LOCK);
+       writeb(7, host->iomap[ADMA_MMIO_BAR] + ADMA_MODE_LOCK);
 
        /* reset the ADMA logic */
        for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
-               adma_reset_engine(ADMA_REGS(mmio_base, port_no));
+               adma_reset_engine(host->ports[port_no]);
 }
 
 static int adma_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base)
@@ -623,14 +620,21 @@ static int adma_ata_init_one(struct pci_dev *pdev,
                             const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct ata_probe_ent *probe_ent = NULL;
-       void __iomem *mmio_base;
        unsigned int board_idx = (unsigned int) ent->driver_data;
+       const struct ata_port_info *ppi[] = { &adma_port_info[board_idx], NULL };
+       struct ata_host *host;
+       void __iomem *mmio_base;
        int rc, port_no;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* alloc host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, ADMA_PORTS);
+       if (!host)
+               return -ENOMEM;
+
+       /* acquire resources and fill host */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
@@ -641,46 +645,23 @@ static int adma_ata_init_one(struct pci_dev *pdev,
        rc = pcim_iomap_regions(pdev, 1 << ADMA_MMIO_BAR, DRV_NAME);
        if (rc)
                return rc;
-       mmio_base = pcim_iomap_table(pdev)[ADMA_MMIO_BAR];
+       host->iomap = pcim_iomap_table(pdev);
+       mmio_base = host->iomap[ADMA_MMIO_BAR];
 
        rc = adma_set_dma_masks(pdev, mmio_base);
        if (rc)
                return rc;
 
-       probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
-
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       probe_ent->sht          = adma_port_info[board_idx].sht;
-       probe_ent->port_flags   = adma_port_info[board_idx].flags;
-       probe_ent->pio_mask     = adma_port_info[board_idx].pio_mask;
-       probe_ent->mwdma_mask   = adma_port_info[board_idx].mwdma_mask;
-       probe_ent->udma_mask    = adma_port_info[board_idx].udma_mask;
-       probe_ent->port_ops     = adma_port_info[board_idx].port_ops;
-
-       probe_ent->irq          = pdev->irq;
-       probe_ent->irq_flags    = IRQF_SHARED;
-       probe_ent->n_ports      = ADMA_PORTS;
-       probe_ent->iomap        = pcim_iomap_table(pdev);
-
-       for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
-               adma_ata_setup_port(&probe_ent->port[port_no],
+       for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
+               adma_ata_setup_port(&host->ports[port_no]->ioaddr,
                                    ADMA_ATA_REGS(mmio_base, port_no));
-       }
-
-       pci_set_master(pdev);
 
        /* initialize adapter */
-       adma_host_init(board_idx, probe_ent);
+       adma_host_init(host, board_idx);
 
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(&pdev->dev, probe_ent);
-       return 0;
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, adma_intr, IRQF_SHARED,
+                                &adma_ata_sht);
 }
 
 static int __init adma_ata_init(void)
index 1e21688bfcf2f4992fd493de5299e5beb679b7c7..f099a1d83a000b7bb02dacc145259c59334c765e 100644 (file)
@@ -488,11 +488,11 @@ static void inic_error_handler(struct ata_port *ap)
 static void inic_post_internal_cmd(struct ata_queued_cmd *qc)
 {
        /* make DMA engine forget about the failed command */
-       if (qc->err_mask)
+       if (qc->flags & ATA_QCFLAG_FAILED)
                inic_reset_port(inic_port_base(qc->ap));
 }
 
-static void inic_dev_config(struct ata_port *ap, struct ata_device *dev)
+static void inic_dev_config(struct ata_device *dev)
 {
        /* inic can only handle upto LBA28 max sectors */
        if (dev->max_sectors > ATA_MAX_SECTORS)
@@ -559,7 +559,6 @@ static struct ata_port_operations inic_port_ops = {
        .bmdma_stop             = inic_bmdma_stop,
        .bmdma_status           = inic_bmdma_status,
 
-       .irq_handler            = inic_interrupt,
        .irq_clear              = inic_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -580,7 +579,6 @@ static struct ata_port_operations inic_port_ops = {
 };
 
 static struct ata_port_info inic_port_info = {
-       .sht                    = &inic_sht,
        /* For some reason, ATA_PROT_ATAPI is broken on this
         * controller, and no, PIO_POLLING does't fix it.  It somehow
         * manages to report the wrong ireason and ignoring ireason
@@ -642,7 +640,9 @@ static int inic_pci_device_resume(struct pci_dev *pdev)
        void __iomem *mmio_base = host->iomap[MMIO_BAR];
        int rc;
 
-       ata_pci_device_do_resume(pdev);
+       rc = ata_pci_device_do_resume(pdev);
+       if (rc)
+               return rc;
 
        if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
                rc = init_controller(mmio_base, hpriv->cached_hctl);
@@ -659,8 +659,8 @@ static int inic_pci_device_resume(struct pci_dev *pdev)
 static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct ata_port_info *pinfo = &inic_port_info;
-       struct ata_probe_ent *probe_ent;
+       const struct ata_port_info *ppi[] = { &inic_port_info, NULL };
+       struct ata_host *host;
        struct inic_host_priv *hpriv;
        void __iomem * const *iomap;
        int i, rc;
@@ -668,6 +668,15 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* alloc host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, NR_PORTS);
+       hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+       if (!host || !hpriv)
+               return -ENOMEM;
+
+       host->private_data = hpriv;
+
+       /* acquire resources and fill host */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
@@ -675,7 +684,22 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME);
        if (rc)
                return rc;
-       iomap = pcim_iomap_table(pdev);
+       host->iomap = iomap = pcim_iomap_table(pdev);
+
+       for (i = 0; i < NR_PORTS; i++) {
+               struct ata_ioports *port = &host->ports[i]->ioaddr;
+               void __iomem *port_base = iomap[MMIO_BAR] + i * PORT_SIZE;
+
+               port->cmd_addr = iomap[2 * i];
+               port->altstatus_addr =
+               port->ctl_addr = (void __iomem *)
+                       ((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS);
+               port->scr_addr = port_base + PORT_SCR;
+
+               ata_std_ports(port);
+       }
+
+       hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL);
 
        /* Set dma_mask.  This devices doesn't support 64bit addressing. */
        rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
@@ -692,43 +716,6 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                return rc;
        }
 
-       probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
-       hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
-       if (!probe_ent || !hpriv)
-               return -ENOMEM;
-
-       probe_ent->dev = &pdev->dev;
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       probe_ent->sht                  = pinfo->sht;
-       probe_ent->port_flags           = pinfo->flags;
-       probe_ent->pio_mask             = pinfo->pio_mask;
-       probe_ent->mwdma_mask           = pinfo->mwdma_mask;
-       probe_ent->udma_mask            = pinfo->udma_mask;
-       probe_ent->port_ops             = pinfo->port_ops;
-       probe_ent->n_ports              = NR_PORTS;
-
-       probe_ent->irq = pdev->irq;
-       probe_ent->irq_flags = IRQF_SHARED;
-
-       probe_ent->iomap = iomap;
-
-       for (i = 0; i < NR_PORTS; i++) {
-               struct ata_ioports *port = &probe_ent->port[i];
-               void __iomem *port_base = iomap[MMIO_BAR] + i * PORT_SIZE;
-
-               port->cmd_addr = iomap[2 * i];
-               port->altstatus_addr =
-               port->ctl_addr = (void __iomem *)
-                       ((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS);
-               port->scr_addr = port_base + PORT_SCR;
-
-               ata_std_ports(port);
-       }
-
-       probe_ent->private_data = hpriv;
-       hpriv->cached_hctl = readw(iomap[MMIO_BAR] + HOST_CTL);
-
        rc = init_controller(iomap[MMIO_BAR], hpriv->cached_hctl);
        if (rc) {
                dev_printk(KERN_ERR, &pdev->dev,
@@ -737,13 +724,8 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 
        pci_set_master(pdev);
-
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(&pdev->dev, probe_ent);
-
-       return 0;
+       return ata_host_activate(host, pdev->irq, inic_interrupt, IRQF_SHARED,
+                                &inic_sht);
 }
 
 static const struct pci_device_id inic_pci_tbl[] = {
index a65ba636aaa8eeb0ddb66b160f4a5749409c1106..cb9b9ac12b4c1cf3689757bafe9be68f46f59ab5 100644 (file)
@@ -253,10 +253,7 @@ enum {
 #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE)
 
 enum {
-       /* Our DMA boundary is determined by an ePRD being unable to handle
-        * anything larger than 64KB
-        */
-       MV_DMA_BOUNDARY         = 0xffffU,
+       MV_DMA_BOUNDARY         = 0xffffffffU,
 
        EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U,
 
@@ -350,7 +347,6 @@ static void mv_port_stop(struct ata_port *ap);
 static void mv_qc_prep(struct ata_queued_cmd *qc);
 static void mv_qc_prep_iie(struct ata_queued_cmd *qc);
 static unsigned int mv_qc_issue(struct ata_queued_cmd *qc);
-static irqreturn_t mv_interrupt(int irq, void *dev_instance);
 static void mv_eng_timeout(struct ata_port *ap);
 static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 
@@ -384,10 +380,10 @@ static struct scsi_host_template mv_sht = {
        .queuecommand           = ata_scsi_queuecmd,
        .can_queue              = MV_USE_Q_DEPTH,
        .this_id                = ATA_SHT_THIS_ID,
-       .sg_tablesize           = MV_MAX_SG_CT / 2,
+       .sg_tablesize           = MV_MAX_SG_CT,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
-       .use_clustering         = ATA_SHT_USE_CLUSTERING,
+       .use_clustering         = 1,
        .proc_name              = DRV_NAME,
        .dma_boundary           = MV_DMA_BOUNDARY,
        .slave_configure        = ata_scsi_slave_config,
@@ -405,6 +401,7 @@ static const struct ata_port_operations mv5_ops = {
        .dev_select             = ata_std_dev_select,
 
        .phy_reset              = mv_phy_reset,
+       .cable_detect           = ata_cable_sata,
 
        .qc_prep                = mv_qc_prep,
        .qc_issue               = mv_qc_issue,
@@ -412,7 +409,6 @@ static const struct ata_port_operations mv5_ops = {
 
        .eng_timeout            = mv_eng_timeout,
 
-       .irq_handler            = mv_interrupt,
        .irq_clear              = mv_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -434,6 +430,7 @@ static const struct ata_port_operations mv6_ops = {
        .dev_select             = ata_std_dev_select,
 
        .phy_reset              = mv_phy_reset,
+       .cable_detect           = ata_cable_sata,
 
        .qc_prep                = mv_qc_prep,
        .qc_issue               = mv_qc_issue,
@@ -441,7 +438,6 @@ static const struct ata_port_operations mv6_ops = {
 
        .eng_timeout            = mv_eng_timeout,
 
-       .irq_handler            = mv_interrupt,
        .irq_clear              = mv_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -463,6 +459,7 @@ static const struct ata_port_operations mv_iie_ops = {
        .dev_select             = ata_std_dev_select,
 
        .phy_reset              = mv_phy_reset,
+       .cable_detect           = ata_cable_sata,
 
        .qc_prep                = mv_qc_prep_iie,
        .qc_issue               = mv_qc_issue,
@@ -470,7 +467,6 @@ static const struct ata_port_operations mv_iie_ops = {
 
        .eng_timeout            = mv_eng_timeout,
 
-       .irq_handler            = mv_interrupt,
        .irq_clear              = mv_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -484,35 +480,30 @@ static const struct ata_port_operations mv_iie_ops = {
 
 static const struct ata_port_info mv_port_info[] = {
        {  /* chip_504x */
-               .sht            = &mv_sht,
                .flags          = MV_COMMON_FLAGS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &mv5_ops,
        },
        {  /* chip_508x */
-               .sht            = &mv_sht,
                .flags          = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &mv5_ops,
        },
        {  /* chip_5080 */
-               .sht            = &mv_sht,
                .flags          = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC),
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &mv5_ops,
        },
        {  /* chip_604x */
-               .sht            = &mv_sht,
                .flags          = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &mv6_ops,
        },
        {  /* chip_608x */
-               .sht            = &mv_sht,
                .flags          = (MV_COMMON_FLAGS | MV_6XXX_FLAGS |
                                   MV_FLAG_DUAL_HC),
                .pio_mask       = 0x1f, /* pio0-4 */
@@ -520,14 +511,12 @@ static const struct ata_port_info mv_port_info[] = {
                .port_ops       = &mv6_ops,
        },
        {  /* chip_6042 */
-               .sht            = &mv_sht,
                .flags          = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 */
                .port_ops       = &mv_iie_ops,
        },
        {  /* chip_7042 */
-               .sht            = &mv_sht,
                .flags          = (MV_COMMON_FLAGS | MV_6XXX_FLAGS),
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 */
@@ -551,6 +540,9 @@ static const struct pci_device_id mv_pci_tbl[] = {
 
        { PCI_VDEVICE(TTI, 0x2310), chip_7042 },
 
+       /* add Marvell 7042 support */
+       { PCI_VDEVICE(MARVELL, 0x7042), chip_7042 },
+
        { }                     /* terminate list */
 };
 
@@ -585,6 +577,39 @@ static const struct mv_hw_ops mv6xxx_ops = {
 static int msi;              /* Use PCI msi; either zero (off, default) or non-zero */
 
 
+/* move to PCI layer or libata core? */
+static int pci_go_64(struct pci_dev *pdev)
+{
+       int rc;
+
+       if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
+               rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+               if (rc) {
+                       rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+                       if (rc) {
+                               dev_printk(KERN_ERR, &pdev->dev,
+                                          "64-bit DMA enable failed\n");
+                               return rc;
+                       }
+               }
+       } else {
+               rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+               if (rc) {
+                       dev_printk(KERN_ERR, &pdev->dev,
+                                  "32-bit DMA enable failed\n");
+                       return rc;
+               }
+               rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+               if (rc) {
+                       dev_printk(KERN_ERR, &pdev->dev,
+                                  "32-bit consistent DMA enable failed\n");
+                       return rc;
+               }
+       }
+
+       return rc;
+}
+
 /*
  * Functions
  */
@@ -798,20 +823,18 @@ static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in)
 {
        unsigned int ofs = mv_scr_offset(sc_reg_in);
 
-       if (0xffffffffU != ofs) {
+       if (0xffffffffU != ofs)
                return readl(mv_ap_base(ap) + ofs);
-       } else {
+       else
                return (u32) ofs;
-       }
 }
 
 static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
 {
        unsigned int ofs = mv_scr_offset(sc_reg_in);
 
-       if (0xffffffffU != ofs) {
+       if (0xffffffffU != ofs)
                writelfl(val, mv_ap_base(ap) + ofs);
-       }
 }
 
 static void mv_edma_cfg(struct mv_host_priv *hpriv, void __iomem *port_mmio)
@@ -959,38 +982,30 @@ static void mv_port_stop(struct ata_port *ap)
  *      LOCKING:
  *      Inherited from caller.
  */
-static void mv_fill_sg(struct ata_queued_cmd *qc)
+static unsigned int mv_fill_sg(struct ata_queued_cmd *qc)
 {
        struct mv_port_priv *pp = qc->ap->private_data;
-       unsigned int i = 0;
+       unsigned int n_sg = 0;
        struct scatterlist *sg;
+       struct mv_sg *mv_sg;
 
+       mv_sg = pp->sg_tbl;
        ata_for_each_sg(sg, qc) {
-               dma_addr_t addr;
-               u32 sg_len, len, offset;
-
-               addr = sg_dma_address(sg);
-               sg_len = sg_dma_len(sg);
-
-               while (sg_len) {
-                       offset = addr & MV_DMA_BOUNDARY;
-                       len = sg_len;
-                       if ((offset + sg_len) > 0x10000)
-                               len = 0x10000 - offset;
+               dma_addr_t addr = sg_dma_address(sg);
+               u32 sg_len = sg_dma_len(sg);
 
-                       pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff);
-                       pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16);
-                       pp->sg_tbl[i].flags_size = cpu_to_le32(len & 0xffff);
+               mv_sg->addr = cpu_to_le32(addr & 0xffffffff);
+               mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16);
+               mv_sg->flags_size = cpu_to_le32(sg_len & 0xffff);
 
-                       sg_len -= len;
-                       addr += len;
+               if (ata_sg_is_last(sg, qc))
+                       mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
 
-                       if (!sg_len && ata_sg_is_last(sg, qc))
-                               pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
-
-                       i++;
-               }
+               mv_sg++;
+               n_sg++;
        }
+
+       return n_sg;
 }
 
 static inline unsigned mv_inc_q_index(unsigned index)
@@ -1320,17 +1335,15 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
        int shift, port, port0, hard_port, handled;
        unsigned int err_mask;
 
-       if (hc == 0) {
+       if (hc == 0)
                port0 = 0;
-       } else {
+       else
                port0 = MV_PORTS_PER_HC;
-       }
 
        /* we'll need the HC success int register in most cases */
        hc_irq_cause = readl(hc_mmio + HC_IRQ_CAUSE_OFS);
-       if (hc_irq_cause) {
+       if (hc_irq_cause)
                writelfl(~hc_irq_cause, hc_mmio + HC_IRQ_CAUSE_OFS);
-       }
 
        VPRINTK("ENTER, hc%u relevant=0x%08x HC IRQ cause=0x%08x\n",
                hc,relevant,hc_irq_cause);
@@ -1425,9 +1438,8 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
        /* check the cases where we either have nothing pending or have read
         * a bogus register value which can indicate HW removal or PCI fault
         */
-       if (!irq_stat || (0xffffffffU == irq_stat)) {
+       if (!irq_stat || (0xffffffffU == irq_stat))
                return IRQ_NONE;
-       }
 
        n_hcs = mv_get_hc_count(host->ports[0]->flags);
        spin_lock(&host->lock);
@@ -1952,7 +1964,6 @@ comreset_retry:
                ata_port_disable(ap);
                return;
        }
-       ap->cbl = ATA_CBL_SATA;
 
        /* even after SStatus reflects that device is ready,
         * it seems to take a while for link to be fully
@@ -2077,9 +2088,10 @@ static void mv_port_init(struct ata_ioports *port,  void __iomem *port_mmio)
                readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS));
 }
 
-static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
-                     unsigned int board_idx)
+static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
 {
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       struct mv_host_priv *hpriv = host->private_data;
        u8 rev_id;
        u32 hp_flags = hpriv->hp_flags;
 
@@ -2177,8 +2189,8 @@ static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
 
 /**
  *      mv_init_host - Perform some early initialization of the host.
- *     @pdev: host PCI device
- *      @probe_ent: early data struct representing the host
+ *     @host: ATA host to initialize
+ *      @board_idx: controller index
  *
  *      If possible, do an early global reset of the host.  Then do
  *      our port init and clear/unmask all/relevant host interrupts.
@@ -2186,24 +2198,23 @@ static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv,
  *      LOCKING:
  *      Inherited from caller.
  */
-static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
-                       unsigned int board_idx)
+static int mv_init_host(struct ata_host *host, unsigned int board_idx)
 {
        int rc = 0, n_hc, port, hc;
-       void __iomem *mmio = probe_ent->iomap[MV_PRIMARY_BAR];
-       struct mv_host_priv *hpriv = probe_ent->private_data;
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       void __iomem *mmio = host->iomap[MV_PRIMARY_BAR];
+       struct mv_host_priv *hpriv = host->private_data;
 
        /* global interrupt mask */
        writel(0, mmio + HC_MAIN_IRQ_MASK_OFS);
 
-       rc = mv_chip_id(pdev, hpriv, board_idx);
+       rc = mv_chip_id(host, board_idx);
        if (rc)
                goto done;
 
-       n_hc = mv_get_hc_count(probe_ent->port_flags);
-       probe_ent->n_ports = MV_PORTS_PER_HC * n_hc;
+       n_hc = mv_get_hc_count(host->ports[0]->flags);
 
-       for (port = 0; port < probe_ent->n_ports; port++)
+       for (port = 0; port < host->n_ports; port++)
                hpriv->ops->read_preamp(hpriv, port, mmio);
 
        rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
@@ -2214,7 +2225,7 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
        hpriv->ops->reset_bus(pdev, mmio);
        hpriv->ops->enable_leds(hpriv, mmio);
 
-       for (port = 0; port < probe_ent->n_ports; port++) {
+       for (port = 0; port < host->n_ports; port++) {
                if (IS_60XX(hpriv)) {
                        void __iomem *port_mmio = mv_port_base(mmio, port);
 
@@ -2227,9 +2238,9 @@ static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent,
                hpriv->ops->phy_errata(hpriv, mmio, port);
        }
 
-       for (port = 0; port < probe_ent->n_ports; port++) {
+       for (port = 0; port < host->n_ports; port++) {
                void __iomem *port_mmio = mv_port_base(mmio, port);
-               mv_port_init(&probe_ent->port[port], port_mmio);
+               mv_port_init(&host->ports[port]->ioaddr, port_mmio);
        }
 
        for (hc = 0; hc < n_hc; hc++) {
@@ -2268,17 +2279,17 @@ done:
 
 /**
  *      mv_print_info - Dump key info to kernel log for perusal.
- *      @probe_ent: early data struct representing the host
+ *      @host: ATA host to print info about
  *
  *      FIXME: complete this.
  *
  *      LOCKING:
  *      Inherited from caller.
  */
-static void mv_print_info(struct ata_probe_ent *probe_ent)
+static void mv_print_info(struct ata_host *host)
 {
-       struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
-       struct mv_host_priv *hpriv = probe_ent->private_data;
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       struct mv_host_priv *hpriv = host->private_data;
        u8 rev_id, scc;
        const char *scc_s;
 
@@ -2297,7 +2308,7 @@ static void mv_print_info(struct ata_probe_ent *probe_ent)
 
        dev_printk(KERN_INFO, &pdev->dev,
               "%u slots %u ports %s mode IRQ via %s\n",
-              (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports,
+              (unsigned)MV_MAX_Q_DEPTH, host->n_ports,
               scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx");
 }
 
@@ -2312,50 +2323,42 @@ static void mv_print_info(struct ata_probe_ent *probe_ent)
 static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version = 0;
-       struct device *dev = &pdev->dev;
-       struct ata_probe_ent *probe_ent;
-       struct mv_host_priv *hpriv;
        unsigned int board_idx = (unsigned int)ent->driver_data;
-       int rc;
+       const struct ata_port_info *ppi[] = { &mv_port_info[board_idx], NULL };
+       struct ata_host *host;
+       struct mv_host_priv *hpriv;
+       int n_ports, rc;
 
        if (!printed_version++)
                dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* allocate host */
+       n_ports = mv_get_hc_count(ppi[0]->flags) * MV_PORTS_PER_HC;
+
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+       hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+       if (!host || !hpriv)
+               return -ENOMEM;
+       host->private_data = hpriv;
+
+       /* acquire resources */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
-       pci_set_master(pdev);
 
        rc = pcim_iomap_regions(pdev, 1 << MV_PRIMARY_BAR, DRV_NAME);
        if (rc == -EBUSY)
                pcim_pin_device(pdev);
        if (rc)
                return rc;
+       host->iomap = pcim_iomap_table(pdev);
 
-       probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
-
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
-       if (!hpriv)
-               return -ENOMEM;
-
-       probe_ent->sht = mv_port_info[board_idx].sht;
-       probe_ent->port_flags = mv_port_info[board_idx].flags;
-       probe_ent->pio_mask = mv_port_info[board_idx].pio_mask;
-       probe_ent->udma_mask = mv_port_info[board_idx].udma_mask;
-       probe_ent->port_ops = mv_port_info[board_idx].port_ops;
-
-       probe_ent->irq = pdev->irq;
-       probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->iomap = pcim_iomap_table(pdev);
-       probe_ent->private_data = hpriv;
+       rc = pci_go_64(pdev);
+       if (rc)
+               return rc;
 
        /* initialize adapter */
-       rc = mv_init_host(pdev, probe_ent, board_idx);
+       rc = mv_init_host(host, board_idx);
        if (rc)
                return rc;
 
@@ -2364,13 +2367,11 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                pci_intx(pdev, 1);
 
        mv_dump_pci_cfg(pdev, 0x68);
-       mv_print_info(probe_ent);
+       mv_print_info(host);
 
-       if (ata_device_add(probe_ent) == 0)
-               return -ENODEV;
-
-       devm_kfree(dev, probe_ent);
-       return 0;
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, mv_interrupt, IRQF_SHARED,
+                                &mv_sht);
 }
 
 static int __init mv_init(void)
index 9d9670a9b117e67d3689b8f5b2a1aa4b586f9ac6..02169740ed245dd2bddc51f9297edf790b07768e 100644 (file)
@@ -260,6 +260,7 @@ static int nv_adma_port_resume(struct ata_port *ap);
 static void nv_adma_error_handler(struct ata_port *ap);
 static void nv_adma_host_stop(struct ata_host *host);
 static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc);
+static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
 
 enum nv_host_type
 {
@@ -368,7 +369,6 @@ static const struct ata_port_operations nv_generic_ops = {
        .error_handler          = nv_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
        .data_xfer              = ata_data_xfer,
-       .irq_handler            = nv_generic_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -395,7 +395,6 @@ static const struct ata_port_operations nv_nf2_ops = {
        .error_handler          = nv_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
        .data_xfer              = ata_data_xfer,
-       .irq_handler            = nv_nf2_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -422,7 +421,6 @@ static const struct ata_port_operations nv_ck804_ops = {
        .error_handler          = nv_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
        .data_xfer              = ata_data_xfer,
-       .irq_handler            = nv_ck804_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -435,7 +433,7 @@ static const struct ata_port_operations nv_ck804_ops = {
 static const struct ata_port_operations nv_adma_ops = {
        .port_disable           = ata_port_disable,
        .tf_load                = ata_tf_load,
-       .tf_read                = ata_tf_read,
+       .tf_read                = nv_adma_tf_read,
        .check_atapi_dma        = nv_adma_check_atapi_dma,
        .exec_command           = ata_exec_command,
        .check_status           = ata_check_status,
@@ -451,7 +449,6 @@ static const struct ata_port_operations nv_adma_ops = {
        .error_handler          = nv_adma_error_handler,
        .post_internal_cmd      = nv_adma_post_internal_cmd,
        .data_xfer              = ata_data_xfer,
-       .irq_handler            = nv_adma_interrupt,
        .irq_clear              = nv_adma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -476,6 +473,7 @@ static struct ata_port_info nv_port_info[] = {
                .mwdma_mask     = NV_MWDMA_MASK,
                .udma_mask      = NV_UDMA_MASK,
                .port_ops       = &nv_generic_ops,
+               .irq_handler    = nv_generic_interrupt,
        },
        /* nforce2/3 */
        {
@@ -486,6 +484,7 @@ static struct ata_port_info nv_port_info[] = {
                .mwdma_mask     = NV_MWDMA_MASK,
                .udma_mask      = NV_UDMA_MASK,
                .port_ops       = &nv_nf2_ops,
+               .irq_handler    = nv_nf2_interrupt,
        },
        /* ck804 */
        {
@@ -496,6 +495,7 @@ static struct ata_port_info nv_port_info[] = {
                .mwdma_mask     = NV_MWDMA_MASK,
                .udma_mask      = NV_UDMA_MASK,
                .port_ops       = &nv_ck804_ops,
+               .irq_handler    = nv_ck804_interrupt,
        },
        /* ADMA */
        {
@@ -507,6 +507,7 @@ static struct ata_port_info nv_port_info[] = {
                .mwdma_mask     = NV_MWDMA_MASK,
                .udma_mask      = NV_UDMA_MASK,
                .port_ops       = &nv_adma_ops,
+               .irq_handler    = nv_adma_interrupt,
        },
 };
 
@@ -667,6 +668,18 @@ static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc)
        return !(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE);
 }
 
+static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+       /* Since commands where a result TF is requested are not
+          executed in ADMA mode, the only time this function will be called
+          in ADMA mode will be if a command fails. In this case we
+          don't care about going into register mode with ADMA commands
+          pending, as the commands will all shortly be aborted anyway. */
+       nv_adma_register_mode(ap);
+
+       ata_tf_read(ap, tf);
+}
+
 static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb)
 {
        unsigned int idx = 0;
@@ -738,19 +751,11 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
                return 1;
        }
 
-       if (flags & NV_CPB_RESP_DONE) {
+       if (likely(flags & NV_CPB_RESP_DONE)) {
                struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num);
                VPRINTK("CPB flags done, flags=0x%x\n", flags);
                if (likely(qc)) {
-                       /* Grab the ATA port status for non-NCQ commands.
-                          For NCQ commands the current status may have nothing to do with
-                          the command just completed. */
-                       if (qc->tf.protocol != ATA_PROT_NCQ) {
-                               u8 ata_status = readb(pp->ctl_block + (ATA_REG_STATUS * 4));
-                               qc->err_mask |= ac_err_mask(ata_status);
-                       }
-                       DPRINTK("Completing qc from tag %d with err_mask %u\n",cpb_num,
-                               qc->err_mask);
+                       DPRINTK("Completing qc from tag %d\n",cpb_num);
                        ata_qc_complete(qc);
                } else {
                        struct ata_eh_info *ehi = &ap->eh_info;
@@ -1074,14 +1079,14 @@ static int nv_adma_port_resume(struct ata_port *ap)
 }
 #endif
 
-static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int port)
+static void nv_adma_setup_port(struct ata_port *ap)
 {
-       void __iomem *mmio = probe_ent->iomap[NV_MMIO_BAR];
-       struct ata_ioports *ioport = &probe_ent->port[port];
+       void __iomem *mmio = ap->host->iomap[NV_MMIO_BAR];
+       struct ata_ioports *ioport = &ap->ioaddr;
 
        VPRINTK("ENTER\n");
 
-       mmio += NV_ADMA_PORT + port * NV_ADMA_PORT_SIZE;
+       mmio += NV_ADMA_PORT + ap->port_no * NV_ADMA_PORT_SIZE;
 
        ioport->cmd_addr        = mmio;
        ioport->data_addr       = mmio + (ATA_REG_DATA * 4);
@@ -1098,9 +1103,9 @@ static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int por
        ioport->ctl_addr        = mmio + 0x20;
 }
 
-static int nv_adma_host_init(struct ata_probe_ent *probe_ent)
+static int nv_adma_host_init(struct ata_host *host)
 {
-       struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
+       struct pci_dev *pdev = to_pci_dev(host->dev);
        unsigned int i;
        u32 tmp32;
 
@@ -1115,8 +1120,8 @@ static int nv_adma_host_init(struct ata_probe_ent *probe_ent)
 
        pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, tmp32);
 
-       for (i = 0; i < probe_ent->n_ports; i++)
-               nv_adma_setup_port(probe_ent, i);
+       for (i = 0; i < host->n_ports; i++)
+               nv_adma_setup_port(host->ports[i]);
 
        return 0;
 }
@@ -1167,9 +1172,11 @@ static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc)
        struct nv_adma_port_priv *pp = qc->ap->private_data;
 
        /* ADMA engine can only be used for non-ATAPI DMA commands,
-          or interrupt-driven no-data commands. */
+          or interrupt-driven no-data commands, where a result taskfile
+          is not required. */
        if((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) ||
-          (qc->tf.flags & ATA_TFLAG_POLLING))
+          (qc->tf.flags & ATA_TFLAG_POLLING) ||
+          (qc->flags & ATA_QCFLAG_RESULT_TF))
                return 1;
 
        if((qc->flags & ATA_QCFLAG_DMAMAP) ||
@@ -1473,14 +1480,13 @@ static void nv_adma_error_handler(struct ata_port *ap)
 static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version = 0;
-       struct ata_port_info *ppi[2];
-       struct ata_probe_ent *probe_ent;
+       const struct ata_port_info *ppi[2];
+       struct ata_host *host;
        struct nv_host_priv *hpriv;
        int rc;
        u32 bar;
        void __iomem *base;
        unsigned long type = ent->driver_data;
-       int mask_set = 0;
 
         // Make sure this is a SATA controller by counting the number of bars
         // (NVIDIA SATA controllers will always have six bars).  Otherwise,
@@ -1496,50 +1502,38 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                return rc;
 
-       rc = pci_request_regions(pdev, DRV_NAME);
-       if (rc) {
-               pcim_pin_device(pdev);
-               return rc;
-       }
-
-       if(type >= CK804 && adma_enabled) {
+       /* determine type and allocate host */
+       if (type >= CK804 && adma_enabled) {
                dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n");
                type = ADMA;
-               if(!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
-                  !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
-                       mask_set = 1;
-       }
-
-       if(!mask_set) {
-               rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
-               if (rc)
-                       return rc;
-               rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
-               if (rc)
-                       return rc;
        }
 
-       rc = -ENOMEM;
+       ppi[0] = ppi[1] = &nv_port_info[type];
+       rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
+       if (rc)
+               return rc;
 
        hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
        if (!hpriv)
                return -ENOMEM;
+       hpriv->type = type;
+       host->private_data = hpriv;
 
-       ppi[0] = ppi[1] = &nv_port_info[type];
-       probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
-       if (!probe_ent)
-               return -ENOMEM;
-
-       if (!pcim_iomap(pdev, NV_MMIO_BAR, 0))
-               return -EIO;
-       probe_ent->iomap = pcim_iomap_table(pdev);
+       /* set 64bit dma masks, may fail */
+       if (type == ADMA) {
+               if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0)
+                       pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+       }
 
-       probe_ent->private_data = hpriv;
-       hpriv->type = type;
+       /* request and iomap NV_MMIO_BAR */
+       rc = pcim_iomap_regions(pdev, 1 << NV_MMIO_BAR, DRV_NAME);
+       if (rc)
+               return rc;
 
-       base = probe_ent->iomap[NV_MMIO_BAR];
-       probe_ent->port[0].scr_addr = base + NV_PORT0_SCR_REG_OFFSET;
-       probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET;
+       /* configure SCR access */
+       base = host->iomap[NV_MMIO_BAR];
+       host->ports[0]->ioaddr.scr_addr = base + NV_PORT0_SCR_REG_OFFSET;
+       host->ports[1]->ioaddr.scr_addr = base + NV_PORT1_SCR_REG_OFFSET;
 
        /* enable SATA space for CK804 */
        if (type >= CK804) {
@@ -1550,20 +1544,16 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
        }
 
-       pci_set_master(pdev);
-
+       /* init ADMA */
        if (type == ADMA) {
-               rc = nv_adma_host_init(probe_ent);
+               rc = nv_adma_host_init(host);
                if (rc)
                        return rc;
        }
 
-       rc = ata_device_add(probe_ent);
-       if (rc != NV_PORTS)
-               return -ENODEV;
-
-       devm_kfree(&pdev->dev, probe_ent);
-       return 0;
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, ppi[0]->irq_handler,
+                                IRQF_SHARED, ppi[0]->sht);
 }
 
 static void nv_remove_one (struct pci_dev *pdev)
index 2339813ce9f646caf678172bbb85e045d157f2c7..f56549b90aa63e3d4849dcef9e491dc519ebacfb 100644 (file)
 #include "sata_promise.h"
 
 #define DRV_NAME       "sata_promise"
-#define DRV_VERSION    "2.00"
+#define DRV_VERSION    "2.05"
 
 
 enum {
+       PDC_MAX_PORTS           = 4,
        PDC_MMIO_BAR            = 3,
 
        /* register offsets */
@@ -70,14 +71,31 @@ enum {
        PDC_TBG_MODE            = 0x41C, /* TBG mode (not SATAII) */
        PDC_SLEW_CTL            = 0x470, /* slew rate control reg (not SATAII) */
 
-       PDC_ERR_MASK            = (1<<19) | (1<<20) | (1<<21) | (1<<22) |
-                                 (1<<8) | (1<<9) | (1<<10),
+       /* PDC_GLOBAL_CTL bit definitions */
+       PDC_PH_ERR              = (1 <<  8), /* PCI error while loading packet */
+       PDC_SH_ERR              = (1 <<  9), /* PCI error while loading S/G table */
+       PDC_DH_ERR              = (1 << 10), /* PCI error while loading data */
+       PDC2_HTO_ERR            = (1 << 12), /* host bus timeout */
+       PDC2_ATA_HBA_ERR        = (1 << 13), /* error during SATA DATA FIS transmission */
+       PDC2_ATA_DMA_CNT_ERR    = (1 << 14), /* DMA DATA FIS size differs from S/G count */
+       PDC_OVERRUN_ERR         = (1 << 19), /* S/G byte count larger than HD requires */
+       PDC_UNDERRUN_ERR        = (1 << 20), /* S/G byte count less than HD requires */
+       PDC_DRIVE_ERR           = (1 << 21), /* drive error */
+       PDC_PCI_SYS_ERR         = (1 << 22), /* PCI system error */
+       PDC1_PCI_PARITY_ERR     = (1 << 23), /* PCI parity error (from SATA150 driver) */
+       PDC1_ERR_MASK           = PDC1_PCI_PARITY_ERR,
+       PDC2_ERR_MASK           = PDC2_HTO_ERR | PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR,
+       PDC_ERR_MASK            = (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC_OVERRUN_ERR
+                                  | PDC_UNDERRUN_ERR | PDC_DRIVE_ERR | PDC_PCI_SYS_ERR
+                                  | PDC1_ERR_MASK | PDC2_ERR_MASK),
 
        board_2037x             = 0,    /* FastTrak S150 TX2plus */
-       board_20319             = 1,    /* FastTrak S150 TX4 */
-       board_20619             = 2,    /* FastTrak TX4000 */
-       board_2057x             = 3,    /* SATAII150 Tx2plus */
-       board_40518             = 4,    /* SATAII150 Tx4 */
+       board_2037x_pata        = 1,    /* FastTrak S150 TX2plus PATA port */
+       board_20319             = 2,    /* FastTrak S150 TX4 */
+       board_20619             = 3,    /* FastTrak TX4000 */
+       board_2057x             = 4,    /* SATAII150 Tx2plus */
+       board_2057x_pata        = 5,    /* SATAII150 Tx2plus */
+       board_40518             = 6,    /* SATAII150 Tx4 */
 
        PDC_HAS_PATA            = (1 << 1), /* PDC20375/20575 has PATA */
 
@@ -100,8 +118,10 @@ enum {
                                  ATA_FLAG_MMIO |
                                  ATA_FLAG_PIO_POLLING,
 
-       /* hp->flags bits */
-       PDC_FLAG_GEN_II         = (1 << 0),
+       /* ap->flags bits */
+       PDC_FLAG_GEN_II         = (1 << 24),
+       PDC_FLAG_SATA_PATA      = (1 << 25), /* supports SATA + PATA */
+       PDC_FLAG_4_PORTS        = (1 << 26), /* 4 ports */
 };
 
 
@@ -110,28 +130,25 @@ struct pdc_port_priv {
        dma_addr_t              pkt_dma;
 };
 
-struct pdc_host_priv {
-       unsigned long           flags;
-       unsigned long           port_flags[ATA_MAX_PORTS];
-};
-
 static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static irqreturn_t pdc_interrupt (int irq, void *dev_instance);
-static int pdc_port_start(struct ata_port *ap);
+static int pdc_common_port_start(struct ata_port *ap);
+static int pdc_sata_port_start(struct ata_port *ap);
 static void pdc_qc_prep(struct ata_queued_cmd *qc);
 static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
 static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
 static int pdc_check_atapi_dma(struct ata_queued_cmd *qc);
-static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc);
+static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc);
 static void pdc_irq_clear(struct ata_port *ap);
 static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
 static void pdc_freeze(struct ata_port *ap);
 static void pdc_thaw(struct ata_port *ap);
-static void pdc_error_handler(struct ata_port *ap);
+static void pdc_pata_error_handler(struct ata_port *ap);
+static void pdc_sata_error_handler(struct ata_port *ap);
 static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
-
+static int pdc_pata_cable_detect(struct ata_port *ap);
+static int pdc_sata_cable_detect(struct ata_port *ap);
 
 static struct scsi_host_template pdc_ata_sht = {
        .module                 = THIS_MODULE,
@@ -164,17 +181,17 @@ static const struct ata_port_operations pdc_sata_ops = {
        .qc_issue               = pdc_qc_issue_prot,
        .freeze                 = pdc_freeze,
        .thaw                   = pdc_thaw,
-       .error_handler          = pdc_error_handler,
+       .error_handler          = pdc_sata_error_handler,
        .post_internal_cmd      = pdc_post_internal_cmd,
+       .cable_detect           = pdc_sata_cable_detect,
        .data_xfer              = ata_data_xfer,
-       .irq_handler            = pdc_interrupt,
        .irq_clear              = pdc_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 
        .scr_read               = pdc_sata_scr_read,
        .scr_write              = pdc_sata_scr_write,
-       .port_start             = pdc_port_start,
+       .port_start             = pdc_sata_port_start,
 };
 
 /* First-generation chips need a more restrictive ->check_atapi_dma op */
@@ -185,23 +202,23 @@ static const struct ata_port_operations pdc_old_sata_ops = {
        .check_status           = ata_check_status,
        .exec_command           = pdc_exec_command_mmio,
        .dev_select             = ata_std_dev_select,
-       .check_atapi_dma        = pdc_old_check_atapi_dma,
+       .check_atapi_dma        = pdc_old_sata_check_atapi_dma,
 
        .qc_prep                = pdc_qc_prep,
        .qc_issue               = pdc_qc_issue_prot,
        .freeze                 = pdc_freeze,
        .thaw                   = pdc_thaw,
-       .error_handler          = pdc_error_handler,
+       .error_handler          = pdc_sata_error_handler,
        .post_internal_cmd      = pdc_post_internal_cmd,
+       .cable_detect           = pdc_sata_cable_detect,
        .data_xfer              = ata_data_xfer,
-       .irq_handler            = pdc_interrupt,
        .irq_clear              = pdc_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 
        .scr_read               = pdc_sata_scr_read,
        .scr_write              = pdc_sata_scr_write,
-       .port_start             = pdc_port_start,
+       .port_start             = pdc_sata_port_start,
 };
 
 static const struct ata_port_operations pdc_pata_ops = {
@@ -217,32 +234,41 @@ static const struct ata_port_operations pdc_pata_ops = {
        .qc_issue               = pdc_qc_issue_prot,
        .freeze                 = pdc_freeze,
        .thaw                   = pdc_thaw,
-       .error_handler          = pdc_error_handler,
+       .error_handler          = pdc_pata_error_handler,
        .post_internal_cmd      = pdc_post_internal_cmd,
+       .cable_detect           = pdc_pata_cable_detect,
        .data_xfer              = ata_data_xfer,
-       .irq_handler            = pdc_interrupt,
        .irq_clear              = pdc_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 
-       .port_start             = pdc_port_start,
+       .port_start             = pdc_common_port_start,
 };
 
 static const struct ata_port_info pdc_port_info[] = {
        /* board_2037x */
        {
-               .sht            = &pdc_ata_sht,
-               .flags          = PDC_COMMON_FLAGS,
+               .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
+                                 PDC_FLAG_SATA_PATA,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &pdc_old_sata_ops,
        },
 
+       /* board_2037x_pata */
+       {
+               .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .port_ops       = &pdc_pata_ops,
+       },
+
        /* board_20319 */
        {
-               .sht            = &pdc_ata_sht,
-               .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SATA,
+               .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
+                                 PDC_FLAG_4_PORTS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
@@ -251,8 +277,8 @@ static const struct ata_port_info pdc_port_info[] = {
 
        /* board_20619 */
        {
-               .sht            = &pdc_ata_sht,
-               .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
+               .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS |
+                                 PDC_FLAG_4_PORTS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
@@ -261,18 +287,28 @@ static const struct ata_port_info pdc_port_info[] = {
 
        /* board_2057x */
        {
-               .sht            = &pdc_ata_sht,
-               .flags          = PDC_COMMON_FLAGS,
+               .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
+                                 PDC_FLAG_GEN_II | PDC_FLAG_SATA_PATA,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &pdc_sata_ops,
        },
 
+       /* board_2057x_pata */
+       {
+               .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS,
+                                 PDC_FLAG_GEN_II,
+               .pio_mask       = 0x1f, /* pio0-4 */
+               .mwdma_mask     = 0x07, /* mwdma0-2 */
+               .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
+               .port_ops       = &pdc_pata_ops,
+       },
+
        /* board_40518 */
        {
-               .sht            = &pdc_ata_sht,
-               .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SATA,
+               .flags          = PDC_COMMON_FLAGS | ATA_FLAG_SATA |
+                                 PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS,
                .pio_mask       = 0x1f, /* pio0-4 */
                .mwdma_mask     = 0x07, /* mwdma0-2 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
@@ -313,18 +349,12 @@ static struct pci_driver pdc_ata_pci_driver = {
 };
 
 
-static int pdc_port_start(struct ata_port *ap)
+static int pdc_common_port_start(struct ata_port *ap)
 {
        struct device *dev = ap->host->dev;
-       struct pdc_host_priv *hp = ap->host->private_data;
        struct pdc_port_priv *pp;
        int rc;
 
-       /* fix up port flags and cable type for SATA+PATA chips */
-       ap->flags |= hp->port_flags[ap->port_no];
-       if (ap->flags & ATA_FLAG_SATA)
-               ap->cbl = ATA_CBL_SATA;
-
        rc = ata_port_start(ap);
        if (rc)
                return rc;
@@ -339,8 +369,19 @@ static int pdc_port_start(struct ata_port *ap)
 
        ap->private_data = pp;
 
+       return 0;
+}
+
+static int pdc_sata_port_start(struct ata_port *ap)
+{
+       int rc;
+
+       rc = pdc_common_port_start(ap);
+       if (rc)
+               return rc;
+
        /* fix up PHYMODE4 align timing */
-       if ((hp->flags & PDC_FLAG_GEN_II) && sata_scr_valid(ap)) {
+       if (ap->flags & PDC_FLAG_GEN_II) {
                void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr;
                unsigned int tmp;
 
@@ -374,23 +415,25 @@ static void pdc_reset_port(struct ata_port *ap)
        readl(mmio);    /* flush */
 }
 
-static void pdc_pata_cbl_detect(struct ata_port *ap)
+static int pdc_pata_cable_detect(struct ata_port *ap)
 {
        u8 tmp;
        void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr + PDC_CTLSTAT + 0x03;
 
        tmp = readb(mmio);
+       if (tmp & 0x01)
+               return ATA_CBL_PATA40;
+       return ATA_CBL_PATA80;
+}
 
-       if (tmp & 0x01) {
-               ap->cbl = ATA_CBL_PATA40;
-               ap->udma_mask &= ATA_UDMA_MASK_40C;
-       } else
-               ap->cbl = ATA_CBL_PATA80;
+static int pdc_sata_cable_detect(struct ata_port *ap)
+{
+       return ATA_CBL_SATA;
 }
 
 static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
 {
-       if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA)
+       if (sc_reg > SCR_CONTROL)
                return 0xffffffffU;
        return readl(ap->ioaddr.scr_addr + (sc_reg * 4));
 }
@@ -399,7 +442,7 @@ static u32 pdc_sata_scr_read (struct ata_port *ap, unsigned int sc_reg)
 static void pdc_sata_scr_write (struct ata_port *ap, unsigned int sc_reg,
                               u32 val)
 {
-       if (sc_reg > SCR_CONTROL || ap->cbl != ATA_CBL_SATA)
+       if (sc_reg > SCR_CONTROL)
                return;
        writel(val, ap->ioaddr.scr_addr + (sc_reg * 4));
 }
@@ -555,52 +598,79 @@ static void pdc_thaw(struct ata_port *ap)
        readl(mmio + PDC_CTLSTAT); /* flush */
 }
 
-static int pdc_pre_reset(struct ata_port *ap)
-{
-       if (!sata_scr_valid(ap))
-               pdc_pata_cbl_detect(ap);
-       return ata_std_prereset(ap);
-}
-
-static void pdc_error_handler(struct ata_port *ap)
+static void pdc_common_error_handler(struct ata_port *ap, ata_reset_fn_t hardreset)
 {
-       ata_reset_fn_t hardreset;
-
        if (!(ap->pflags & ATA_PFLAG_FROZEN))
                pdc_reset_port(ap);
 
-       hardreset = NULL;
-       if (sata_scr_valid(ap))
-               hardreset = sata_std_hardreset;
-
        /* perform recovery */
-       ata_do_eh(ap, pdc_pre_reset, ata_std_softreset, hardreset,
+       ata_do_eh(ap, ata_std_prereset, ata_std_softreset, hardreset,
                  ata_std_postreset);
 }
 
+static void pdc_pata_error_handler(struct ata_port *ap)
+{
+       pdc_common_error_handler(ap, NULL);
+}
+
+static void pdc_sata_error_handler(struct ata_port *ap)
+{
+       pdc_common_error_handler(ap, sata_std_hardreset);
+}
+
 static void pdc_post_internal_cmd(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
 
-       if (qc->flags & ATA_QCFLAG_FAILED)
-               qc->err_mask |= AC_ERR_OTHER;
-
        /* make DMA engine forget about the failed command */
-       if (qc->err_mask)
+       if (qc->flags & ATA_QCFLAG_FAILED)
                pdc_reset_port(ap);
 }
 
+static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc,
+                          u32 port_status, u32 err_mask)
+{
+       struct ata_eh_info *ehi = &ap->eh_info;
+       unsigned int ac_err_mask = 0;
+
+       ata_ehi_clear_desc(ehi);
+       ata_ehi_push_desc(ehi, "port_status 0x%08x", port_status);
+       port_status &= err_mask;
+
+       if (port_status & PDC_DRIVE_ERR)
+               ac_err_mask |= AC_ERR_DEV;
+       if (port_status & (PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR))
+               ac_err_mask |= AC_ERR_HSM;
+       if (port_status & (PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR))
+               ac_err_mask |= AC_ERR_ATA_BUS;
+       if (port_status & (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC2_HTO_ERR
+                          | PDC_PCI_SYS_ERR | PDC1_PCI_PARITY_ERR))
+               ac_err_mask |= AC_ERR_HOST_BUS;
+
+       if (sata_scr_valid(ap))
+               ehi->serror |= pdc_sata_scr_read(ap, SCR_ERROR);
+
+       qc->err_mask |= ac_err_mask;
+
+       pdc_reset_port(ap);
+}
+
 static inline unsigned int pdc_host_intr( struct ata_port *ap,
                                           struct ata_queued_cmd *qc)
 {
        unsigned int handled = 0;
-       u32 tmp;
-       void __iomem *mmio = ap->ioaddr.cmd_addr + PDC_GLOBAL_CTL;
+       void __iomem *port_mmio = ap->ioaddr.cmd_addr;
+       u32 port_status, err_mask;
 
-       tmp = readl(mmio);
-       if (tmp & PDC_ERR_MASK) {
-               qc->err_mask |= AC_ERR_DEV;
-               pdc_reset_port(ap);
+       err_mask = PDC_ERR_MASK;
+       if (ap->flags & PDC_FLAG_GEN_II)
+               err_mask &= ~PDC1_ERR_MASK;
+       else
+               err_mask &= ~PDC2_ERR_MASK;
+       port_status = readl(port_mmio + PDC_GLOBAL_CTL);
+       if (unlikely(port_status & err_mask)) {
+               pdc_error_intr(ap, qc, port_status, err_mask);
+               return 1;
        }
 
        switch (qc->tf.protocol) {
@@ -767,44 +837,40 @@ static int pdc_check_atapi_dma(struct ata_queued_cmd *qc)
        return pio;
 }
 
-static int pdc_old_check_atapi_dma(struct ata_queued_cmd *qc)
+static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc)
 {
-       struct ata_port *ap = qc->ap;
-
        /* First generation chips cannot use ATAPI DMA on SATA ports */
-       if (sata_scr_valid(ap))
-               return 1;
-       return pdc_check_atapi_dma(qc);
+       return 1;
 }
 
-static void pdc_ata_setup_port(struct ata_ioports *port, void __iomem *base,
-                              void __iomem *scr_addr)
+static void pdc_ata_setup_port(struct ata_port *ap,
+                              void __iomem *base, void __iomem *scr_addr)
 {
-       port->cmd_addr          = base;
-       port->data_addr         = base;
-       port->feature_addr      =
-       port->error_addr        = base + 0x4;
-       port->nsect_addr        = base + 0x8;
-       port->lbal_addr         = base + 0xc;
-       port->lbam_addr         = base + 0x10;
-       port->lbah_addr         = base + 0x14;
-       port->device_addr       = base + 0x18;
-       port->command_addr      =
-       port->status_addr       = base + 0x1c;
-       port->altstatus_addr    =
-       port->ctl_addr          = base + 0x38;
-       port->scr_addr          = scr_addr;
+       ap->ioaddr.cmd_addr             = base;
+       ap->ioaddr.data_addr            = base;
+       ap->ioaddr.feature_addr         =
+       ap->ioaddr.error_addr           = base + 0x4;
+       ap->ioaddr.nsect_addr           = base + 0x8;
+       ap->ioaddr.lbal_addr            = base + 0xc;
+       ap->ioaddr.lbam_addr            = base + 0x10;
+       ap->ioaddr.lbah_addr            = base + 0x14;
+       ap->ioaddr.device_addr          = base + 0x18;
+       ap->ioaddr.command_addr         =
+       ap->ioaddr.status_addr          = base + 0x1c;
+       ap->ioaddr.altstatus_addr       =
+       ap->ioaddr.ctl_addr             = base + 0x38;
+       ap->ioaddr.scr_addr             = scr_addr;
 }
 
 
-static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
+static void pdc_host_init(struct ata_host *host)
 {
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
-       struct pdc_host_priv *hp = pe->private_data;
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
+       int is_gen2 = host->ports[0]->flags & PDC_FLAG_GEN_II;
        int hotplug_offset;
        u32 tmp;
 
-       if (hp->flags & PDC_FLAG_GEN_II)
+       if (is_gen2)
                hotplug_offset = PDC2_SATA_PLUG_CSR;
        else
                hotplug_offset = PDC_SATA_PLUG_CSR;
@@ -818,7 +884,7 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
        /* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */
        tmp = readl(mmio + PDC_FLASH_CTL);
        tmp |= 0x02000; /* bit 13 (enable bmr burst) */
-       if (!(hp->flags & PDC_FLAG_GEN_II))
+       if (!is_gen2)
                tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */
        writel(tmp, mmio + PDC_FLASH_CTL);
 
@@ -831,7 +897,7 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
        writel(tmp | 0xff0000, mmio + hotplug_offset);
 
        /* don't initialise TBG or SLEW on 2nd generation chips */
-       if (hp->flags & PDC_FLAG_GEN_II)
+       if (is_gen2)
                return;
 
        /* reduce TBG clock to 133 Mhz. */
@@ -853,16 +919,16 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
 static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct ata_probe_ent *probe_ent;
-       struct pdc_host_priv *hp;
+       const struct ata_port_info *pi = &pdc_port_info[ent->driver_data];
+       const struct ata_port_info *ppi[PDC_MAX_PORTS];
+       struct ata_host *host;
        void __iomem *base;
-       unsigned int board_idx = (unsigned int) ent->driver_data;
-       int rc;
-       u8 tmp;
+       int n_ports, i, rc;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* enable and acquire resources */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
@@ -872,89 +938,49 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
                pcim_pin_device(pdev);
        if (rc)
                return rc;
+       base = pcim_iomap_table(pdev)[PDC_MMIO_BAR];
 
-       rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
-       if (rc)
-               return rc;
-       rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
-       if (rc)
-               return rc;
-
-       probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
+       /* determine port configuration and setup host */
+       n_ports = 2;
+       if (pi->flags & PDC_FLAG_4_PORTS)
+               n_ports = 4;
+       for (i = 0; i < n_ports; i++)
+               ppi[i] = pi;
 
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
+       if (pi->flags & PDC_FLAG_SATA_PATA) {
+               u8 tmp = readb(base + PDC_FLASH_CTL+1);
+               if (!(tmp & 0x80)) {
+                       ppi[n_ports++] = pi + 1;
+                       dev_printk(KERN_INFO, &pdev->dev, "PATA port found\n");
+               }
+       }
 
-       hp = devm_kzalloc(&pdev->dev, sizeof(*hp), GFP_KERNEL);
-       if (hp == NULL)
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+       if (!host) {
+               dev_printk(KERN_ERR, &pdev->dev, "failed to allocate host\n");
                return -ENOMEM;
-
-       probe_ent->private_data = hp;
-
-       probe_ent->sht          = pdc_port_info[board_idx].sht;
-       probe_ent->port_flags   = pdc_port_info[board_idx].flags;
-       probe_ent->pio_mask     = pdc_port_info[board_idx].pio_mask;
-       probe_ent->mwdma_mask   = pdc_port_info[board_idx].mwdma_mask;
-       probe_ent->udma_mask    = pdc_port_info[board_idx].udma_mask;
-       probe_ent->port_ops     = pdc_port_info[board_idx].port_ops;
-
-               probe_ent->irq = pdev->irq;
-               probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->iomap = pcim_iomap_table(pdev);
-
-       base = probe_ent->iomap[PDC_MMIO_BAR];
-
-       pdc_ata_setup_port(&probe_ent->port[0], base + 0x200, base + 0x400);
-       pdc_ata_setup_port(&probe_ent->port[1], base + 0x280, base + 0x500);
-
-       /* notice 4-port boards */
-       switch (board_idx) {
-       case board_40518:
-               hp->flags |= PDC_FLAG_GEN_II;
-               /* Fall through */
-       case board_20319:
-                       probe_ent->n_ports = 4;
-               pdc_ata_setup_port(&probe_ent->port[2], base + 0x300, base + 0x600);
-               pdc_ata_setup_port(&probe_ent->port[3], base + 0x380, base + 0x700);
-               break;
-       case board_2057x:
-               hp->flags |= PDC_FLAG_GEN_II;
-               /* Fall through */
-       case board_2037x:
-               /* TX2plus boards also have a PATA port */
-               tmp = readb(base + PDC_FLASH_CTL+1);
-               if (!(tmp & 0x80)) {
-                       probe_ent->n_ports = 3;
-                       pdc_ata_setup_port(&probe_ent->port[2], base + 0x300, NULL);
-                       hp->port_flags[2] = ATA_FLAG_SLAVE_POSS;
-                       printk(KERN_INFO DRV_NAME " PATA port found\n");
-               } else
-                       probe_ent->n_ports = 2;
-               hp->port_flags[0] = ATA_FLAG_SATA;
-               hp->port_flags[1] = ATA_FLAG_SATA;
-               break;
-       case board_20619:
-               probe_ent->n_ports = 4;
-               pdc_ata_setup_port(&probe_ent->port[2], base + 0x300, NULL);
-               pdc_ata_setup_port(&probe_ent->port[3], base + 0x380, NULL);
-               break;
-       default:
-               BUG();
-               break;
        }
+       host->iomap = pcim_iomap_table(pdev);
 
-       pci_set_master(pdev);
+       for (i = 0; i < host->n_ports; i++)
+               pdc_ata_setup_port(host->ports[i],
+                                  base + 0x200 + i * 0x80,
+                                  base + 0x400 + i * 0x100);
 
        /* initialize adapter */
-       pdc_host_init(board_idx, probe_ent);
+       pdc_host_init(host);
 
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
+       rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+       if (rc)
+               return rc;
+       rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+       if (rc)
+               return rc;
 
-       devm_kfree(&pdev->dev, probe_ent);
-       return 0;
+       /* start host, request IRQ and attach */
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, pdc_interrupt, IRQF_SHARED,
+                                &pdc_ata_sht);
 }
 
 
index 8786b45f291b8d62af9ddb6fd3bc585d7c659201..f5a05de0093de45156a02c01542fa97b592f6f4c 100644 (file)
@@ -114,7 +114,6 @@ struct qs_port_priv {
 static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static irqreturn_t qs_intr (int irq, void *dev_instance);
 static int qs_port_start(struct ata_port *ap);
 static void qs_host_stop(struct ata_host *host);
 static void qs_phy_reset(struct ata_port *ap);
@@ -158,7 +157,6 @@ static const struct ata_port_operations qs_ata_ops = {
        .qc_issue               = qs_qc_issue,
        .data_xfer              = ata_data_xfer,
        .eng_timeout            = qs_eng_timeout,
-       .irq_handler            = qs_intr,
        .irq_clear              = qs_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -173,7 +171,6 @@ static const struct ata_port_operations qs_ata_ops = {
 static const struct ata_port_info qs_port_info[] = {
        /* board_2068_idx */
        {
-               .sht            = &qs_ata_sht,
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_SATA_RESET |
                                  //FIXME ATA_FLAG_SRST |
@@ -530,16 +527,16 @@ static void qs_host_stop(struct ata_host *host)
        writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
 }
 
-static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
+static void qs_host_init(struct ata_host *host, unsigned int chip_id)
 {
-       void __iomem *mmio_base = pe->iomap[QS_MMIO_BAR];
+       void __iomem *mmio_base = host->iomap[QS_MMIO_BAR];
        unsigned int port_no;
 
        writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */
        writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */
 
        /* reset each channel in turn */
-       for (port_no = 0; port_no < pe->n_ports; ++port_no) {
+       for (port_no = 0; port_no < host->n_ports; ++port_no) {
                u8 __iomem *chan = mmio_base + (port_no * 0x4000);
                writeb(QS_CTR1_RDEV|QS_CTR1_RCHN, chan + QS_CCT_CTR1);
                writeb(QS_CTR0_REG, chan + QS_CCT_CTR0);
@@ -547,7 +544,7 @@ static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
        }
        writeb(QS_SERD3_PHY_ENA, mmio_base + QS_HVS_SERD3); /* enable phy */
 
-       for (port_no = 0; port_no < pe->n_ports; ++port_no) {
+       for (port_no = 0; port_no < host->n_ports; ++port_no) {
                u8 __iomem *chan = mmio_base + (port_no * 0x4000);
                /* set FIFO depths to same settings as Windows driver */
                writew(32, chan + QS_CFC_HUFT);
@@ -607,14 +604,20 @@ static int qs_ata_init_one(struct pci_dev *pdev,
                                const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct ata_probe_ent *probe_ent;
-       void __iomem * const *iomap;
        unsigned int board_idx = (unsigned int) ent->driver_data;
+       const struct ata_port_info *ppi[] = { &qs_port_info[board_idx], NULL };
+       struct ata_host *host;
        int rc, port_no;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* alloc host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, QS_PORTS);
+       if (!host)
+               return -ENOMEM;
+
+       /* acquire resources and fill host */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
@@ -625,47 +628,24 @@ static int qs_ata_init_one(struct pci_dev *pdev,
        rc = pcim_iomap_regions(pdev, 1 << QS_MMIO_BAR, DRV_NAME);
        if (rc)
                return rc;
-       iomap = pcim_iomap_table(pdev);
+       host->iomap = pcim_iomap_table(pdev);
 
-       rc = qs_set_dma_masks(pdev, iomap[QS_MMIO_BAR]);
+       rc = qs_set_dma_masks(pdev, host->iomap[QS_MMIO_BAR]);
        if (rc)
                return rc;
 
-       probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
-
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       probe_ent->sht          = qs_port_info[board_idx].sht;
-       probe_ent->port_flags   = qs_port_info[board_idx].flags;
-       probe_ent->pio_mask     = qs_port_info[board_idx].pio_mask;
-       probe_ent->mwdma_mask   = qs_port_info[board_idx].mwdma_mask;
-       probe_ent->udma_mask    = qs_port_info[board_idx].udma_mask;
-       probe_ent->port_ops     = qs_port_info[board_idx].port_ops;
-
-       probe_ent->irq          = pdev->irq;
-       probe_ent->irq_flags    = IRQF_SHARED;
-       probe_ent->iomap        = iomap;
-       probe_ent->n_ports      = QS_PORTS;
-
-       for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) {
+       for (port_no = 0; port_no < host->n_ports; ++port_no) {
                void __iomem *chan =
-                       probe_ent->iomap[QS_MMIO_BAR] + (port_no * 0x4000);
-               qs_ata_setup_port(&probe_ent->port[port_no], chan);
+                       host->iomap[QS_MMIO_BAR] + (port_no * 0x4000);
+               qs_ata_setup_port(&host->ports[port_no]->ioaddr, chan);
        }
 
-       pci_set_master(pdev);
-
        /* initialize adapter */
-       qs_host_init(board_idx, probe_ent);
+       qs_host_init(host, board_idx);
 
-       if (ata_device_add(probe_ent) != QS_PORTS)
-               return -EIO;
-
-       devm_kfree(&pdev->dev, probe_ent);
-       return 0;
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, qs_intr, IRQF_SHARED,
+                                &qs_ata_sht);
 }
 
 static int __init qs_ata_init(void)
index 917b7ea4ef7c203b0bd4ebc5abd83aad5ceb4420..0a1e417f309c5342aaaf763fa2ddc595e414fed7 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "sata_sil"
-#define DRV_VERSION    "2.1"
+#define DRV_VERSION    "2.2"
 
 enum {
        SIL_MMIO_BAR            = 5,
@@ -114,11 +114,10 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
 #ifdef CONFIG_PM
 static int sil_pci_device_resume(struct pci_dev *pdev);
 #endif
-static void sil_dev_config(struct ata_port *ap, struct ata_device *dev);
+static void sil_dev_config(struct ata_device *dev);
 static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
-static void sil_post_set_mode (struct ata_port *ap);
-static irqreturn_t sil_interrupt(int irq, void *dev_instance);
+static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed);
 static void sil_freeze(struct ata_port *ap);
 static void sil_thaw(struct ata_port *ap);
 
@@ -197,7 +196,7 @@ static const struct ata_port_operations sil_ops = {
        .check_status           = ata_check_status,
        .exec_command           = ata_exec_command,
        .dev_select             = ata_std_dev_select,
-       .post_set_mode          = sil_post_set_mode,
+       .set_mode               = sil_set_mode,
        .bmdma_setup            = ata_bmdma_setup,
        .bmdma_start            = ata_bmdma_start,
        .bmdma_stop             = ata_bmdma_stop,
@@ -209,7 +208,6 @@ static const struct ata_port_operations sil_ops = {
        .thaw                   = sil_thaw,
        .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
-       .irq_handler            = sil_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -221,7 +219,6 @@ static const struct ata_port_operations sil_ops = {
 static const struct ata_port_info sil_port_info[] = {
        /* sil_3112 */
        {
-               .sht            = &sil_sht,
                .flags          = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
@@ -230,7 +227,6 @@ static const struct ata_port_info sil_port_info[] = {
        },
        /* sil_3112_no_sata_irq */
        {
-               .sht            = &sil_sht,
                .flags          = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE |
                                  SIL_FLAG_NO_SATA_IRQ,
                .pio_mask       = 0x1f,                 /* pio0-4 */
@@ -240,7 +236,6 @@ static const struct ata_port_info sil_port_info[] = {
        },
        /* sil_3512 */
        {
-               .sht            = &sil_sht,
                .flags          = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
@@ -249,7 +244,6 @@ static const struct ata_port_info sil_port_info[] = {
        },
        /* sil_3114 */
        {
-               .sht            = &sil_sht,
                .flags          = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
@@ -297,7 +291,16 @@ static unsigned char sil_get_device_cache_line(struct pci_dev *pdev)
        return cache_line;
 }
 
-static void sil_post_set_mode (struct ata_port *ap)
+/**
+ *     sil_set_mode            -       wrap set_mode functions
+ *     @ap: port to set up
+ *     @r_failed: returned device when we fail
+ *
+ *     Wrap the libata method for device setup as after the setup we need
+ *     to inspect the results and do some configuration work
+ */
+
+static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed)
 {
        struct ata_host *host = ap->host;
        struct ata_device *dev;
@@ -305,6 +308,11 @@ static void sil_post_set_mode (struct ata_port *ap)
        void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode;
        u32 tmp, dev_mode[2];
        unsigned int i;
+       int rc;
+       
+       rc = ata_do_set_mode(ap, r_failed);
+       if (rc)
+               return rc;
 
        for (i = 0; i < 2; i++) {
                dev = &ap->device[i];
@@ -323,6 +331,7 @@ static void sil_post_set_mode (struct ata_port *ap)
        tmp |= (dev_mode[1] << 4);
        writel(tmp, addr);
        readl(addr);    /* flush */
+       return 0;
 }
 
 static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_reg)
@@ -521,7 +530,6 @@ static void sil_thaw(struct ata_port *ap)
 
 /**
  *     sil_dev_config - Apply device/host-specific errata fixups
- *     @ap: Port containing device to be examined
  *     @dev: Device to be examined
  *
  *     After the IDENTIFY [PACKET] DEVICE step is complete, and a
@@ -548,8 +556,9 @@ static void sil_thaw(struct ata_port *ap)
  *     appreciated.
  *     - But then again UDMA5 is hardly anything to complain about
  */
-static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
+static void sil_dev_config(struct ata_device *dev)
 {
+       struct ata_port *ap = dev->ap;
        int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
        unsigned int n, quirks = 0;
        unsigned char model_num[ATA_ID_PROD_LEN + 1];
@@ -583,10 +592,10 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
        }
 }
 
-static void sil_init_controller(struct pci_dev *pdev,
-                               int n_ports, unsigned long port_flags,
-                               void __iomem *mmio_base)
+static void sil_init_controller(struct ata_host *host)
 {
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+       void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR];
        u8 cls;
        u32 tmp;
        int i;
@@ -596,7 +605,7 @@ static void sil_init_controller(struct pci_dev *pdev,
        if (cls) {
                cls >>= 3;
                cls++;  /* cls = (line_size/8)+1 */
-               for (i = 0; i < n_ports; i++)
+               for (i = 0; i < host->n_ports; i++)
                        writew(cls << 8 | cls,
                               mmio_base + sil_port[i].fifo_cfg);
        } else
@@ -604,10 +613,10 @@ static void sil_init_controller(struct pci_dev *pdev,
                           "cache line size not set.  Driver may not function\n");
 
        /* Apply R_ERR on DMA activate FIS errata workaround */
-       if (port_flags & SIL_FLAG_RERR_ON_DMA_ACT) {
+       if (host->ports[0]->flags & SIL_FLAG_RERR_ON_DMA_ACT) {
                int cnt;
 
-               for (i = 0, cnt = 0; i < n_ports; i++) {
+               for (i = 0, cnt = 0; i < host->n_ports; i++) {
                        tmp = readl(mmio_base + sil_port[i].sfis_cfg);
                        if ((tmp & 0x3) != 0x01)
                                continue;
@@ -620,7 +629,7 @@ static void sil_init_controller(struct pci_dev *pdev,
                }
        }
 
-       if (n_ports == 4) {
+       if (host->n_ports == 4) {
                /* flip the magic "make 4 ports work" bit */
                tmp = readl(mmio_base + sil_port[2].bmdma);
                if ((tmp & SIL_INTR_STEERING) == 0)
@@ -632,15 +641,26 @@ static void sil_init_controller(struct pci_dev *pdev,
 static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct device *dev = &pdev->dev;
-       struct ata_probe_ent *probe_ent;
+       int board_id = ent->driver_data;
+       const struct ata_port_info *ppi[] = { &sil_port_info[board_id], NULL };
+       struct ata_host *host;
        void __iomem *mmio_base;
-       int rc;
+       int n_ports, rc;
        unsigned int i;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* allocate host */
+       n_ports = 2;
+       if (board_id == sil_3114)
+               n_ports = 4;
+
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+       if (!host)
+               return -ENOMEM;
+
+       /* acquire resources and fill host */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
@@ -650,6 +670,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                pcim_pin_device(pdev);
        if (rc)
                return rc;
+       host->iomap = pcim_iomap_table(pdev);
 
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
@@ -658,45 +679,25 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                return rc;
 
-       probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
+       mmio_base = host->iomap[SIL_MMIO_BAR];
 
-       INIT_LIST_HEAD(&probe_ent->node);
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       probe_ent->port_ops = sil_port_info[ent->driver_data].port_ops;
-       probe_ent->sht = sil_port_info[ent->driver_data].sht;
-       probe_ent->n_ports = (ent->driver_data == sil_3114) ? 4 : 2;
-       probe_ent->pio_mask = sil_port_info[ent->driver_data].pio_mask;
-       probe_ent->mwdma_mask = sil_port_info[ent->driver_data].mwdma_mask;
-       probe_ent->udma_mask = sil_port_info[ent->driver_data].udma_mask;
-               probe_ent->irq = pdev->irq;
-               probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->port_flags = sil_port_info[ent->driver_data].flags;
-
-       probe_ent->iomap = pcim_iomap_table(pdev);
-
-       mmio_base = probe_ent->iomap[SIL_MMIO_BAR];
-
-       for (i = 0; i < probe_ent->n_ports; i++) {
-               probe_ent->port[i].cmd_addr = mmio_base + sil_port[i].tf;
-               probe_ent->port[i].altstatus_addr =
-               probe_ent->port[i].ctl_addr = mmio_base + sil_port[i].ctl;
-               probe_ent->port[i].bmdma_addr = mmio_base + sil_port[i].bmdma;
-               probe_ent->port[i].scr_addr = mmio_base + sil_port[i].scr;
-               ata_std_ports(&probe_ent->port[i]);
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_ioports *ioaddr = &host->ports[i]->ioaddr;
+
+               ioaddr->cmd_addr = mmio_base + sil_port[i].tf;
+               ioaddr->altstatus_addr =
+               ioaddr->ctl_addr = mmio_base + sil_port[i].ctl;
+               ioaddr->bmdma_addr = mmio_base + sil_port[i].bmdma;
+               ioaddr->scr_addr = mmio_base + sil_port[i].scr;
+               ata_std_ports(ioaddr);
        }
 
-       sil_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags,
-                           mmio_base);
+       /* initialize and activate */
+       sil_init_controller(host);
 
        pci_set_master(pdev);
-
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(dev, probe_ent);
-       return 0;
+       return ata_host_activate(host, pdev->irq, sil_interrupt, IRQF_SHARED,
+                                &sil_sht);
 }
 
 #ifdef CONFIG_PM
@@ -709,8 +710,7 @@ static int sil_pci_device_resume(struct pci_dev *pdev)
        if (rc)
                return rc;
 
-       sil_init_controller(pdev, host->n_ports, host->ports[0]->flags,
-                           host->iomap[SIL_MMIO_BAR]);
+       sil_init_controller(host);
        ata_host_resume(host);
 
        return 0;
index 5614df8c1ce2809bed166aa3b0f70d63e112819f..e6223ba667daca271a19e1c541470d80463c2a9a 100644 (file)
@@ -323,7 +323,7 @@ struct sil24_port_priv {
        struct ata_taskfile tf;                 /* Cached taskfile registers */
 };
 
-static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev);
+static void sil24_dev_config(struct ata_device *dev);
 static u8 sil24_check_status(struct ata_port *ap);
 static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
 static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
@@ -331,7 +331,6 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
 static void sil24_qc_prep(struct ata_queued_cmd *qc);
 static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
 static void sil24_irq_clear(struct ata_port *ap);
-static irqreturn_t sil24_interrupt(int irq, void *dev_instance);
 static void sil24_freeze(struct ata_port *ap);
 static void sil24_thaw(struct ata_port *ap);
 static void sil24_error_handler(struct ata_port *ap);
@@ -401,7 +400,6 @@ static const struct ata_port_operations sil24_ops = {
        .qc_prep                = sil24_qc_prep,
        .qc_issue               = sil24_qc_issue,
 
-       .irq_handler            = sil24_interrupt,
        .irq_clear              = sil24_irq_clear,
        .irq_on                 = ata_dummy_irq_on,
        .irq_ack                = ata_dummy_irq_ack,
@@ -424,10 +422,9 @@ static const struct ata_port_operations sil24_ops = {
 #define SIL24_NPORTS2FLAG(nports)      ((((unsigned)(nports) - 1) & 0x3) << 30)
 #define SIL24_FLAG2NPORTS(flag)                ((((flag) >> 30) & 0x3) + 1)
 
-static struct ata_port_info sil24_port_info[] = {
+static const struct ata_port_info sil24_port_info[] = {
        /* sil_3124 */
        {
-               .sht            = &sil24_sht,
                .flags          = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
                                  SIL24_FLAG_PCIX_IRQ_WOC,
                .pio_mask       = 0x1f,                 /* pio0-4 */
@@ -437,7 +434,6 @@ static struct ata_port_info sil24_port_info[] = {
        },
        /* sil_3132 */
        {
-               .sht            = &sil24_sht,
                .flags          = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
@@ -446,7 +442,6 @@ static struct ata_port_info sil24_port_info[] = {
        },
        /* sil_3131/sil_3531 */
        {
-               .sht            = &sil24_sht,
                .flags          = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
                .pio_mask       = 0x1f,                 /* pio0-4 */
                .mwdma_mask     = 0x07,                 /* mwdma0-2 */
@@ -462,9 +457,9 @@ static int sil24_tag(int tag)
        return tag;
 }
 
-static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
+static void sil24_dev_config(struct ata_device *dev)
 {
-       void __iomem *port = ap->ioaddr.cmd_addr;
+       void __iomem *port = dev->ap->ioaddr.cmd_addr;
 
        if (dev->cdb_len == 16)
                writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
@@ -924,11 +919,8 @@ static void sil24_post_internal_cmd(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
 
-       if (qc->flags & ATA_QCFLAG_FAILED)
-               qc->err_mask |= AC_ERR_OTHER;
-
        /* make DMA engine forget about the failed command */
-       if (qc->err_mask)
+       if (qc->flags & ATA_QCFLAG_FAILED)
                sil24_init_port(ap);
 }
 
@@ -964,11 +956,10 @@ static int sil24_port_start(struct ata_port *ap)
        return 0;
 }
 
-static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
-                                 unsigned long port_flags,
-                                 void __iomem *host_base,
-                                 void __iomem *port_base)
+static void sil24_init_controller(struct ata_host *host)
 {
+       void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
+       void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
        u32 tmp;
        int i;
 
@@ -979,7 +970,7 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
        writel(0, host_base + HOST_CTRL);
 
        /* init ports */
-       for (i = 0; i < n_ports; i++) {
+       for (i = 0; i < host->n_ports; i++) {
                void __iomem *port = port_base + i * PORT_REGS_SIZE;
 
                /* Initial PHY setting */
@@ -993,12 +984,12 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
                                                PORT_CS_PORT_RST,
                                                PORT_CS_PORT_RST, 10, 100);
                        if (tmp & PORT_CS_PORT_RST)
-                               dev_printk(KERN_ERR, &pdev->dev,
+                               dev_printk(KERN_ERR, host->dev,
                                           "failed to clear port RST\n");
                }
 
                /* Configure IRQ WoC */
-               if (port_flags & SIL24_FLAG_PCIX_IRQ_WOC)
+               if (host->ports[0]->flags & SIL24_FLAG_PCIX_IRQ_WOC)
                        writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT);
                else
                        writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
@@ -1026,18 +1017,17 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
 static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version = 0;
-       struct device *dev = &pdev->dev;
-       unsigned int board_id = (unsigned int)ent->driver_data;
-       struct ata_port_info *pinfo = &sil24_port_info[board_id];
-       struct ata_probe_ent *probe_ent;
-       void __iomem *host_base;
-       void __iomem *port_base;
+       struct ata_port_info pi = sil24_port_info[ent->driver_data];
+       const struct ata_port_info *ppi[] = { &pi, NULL };
+       void __iomem * const *iomap;
+       struct ata_host *host;
        int i, rc;
        u32 tmp;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* acquire resources */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
@@ -1047,33 +1037,36 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                                DRV_NAME);
        if (rc)
                return rc;
+       iomap = pcim_iomap_table(pdev);
 
-       /* allocate & init probe_ent */
-       probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (!probe_ent)
-               return -ENOMEM;
+       /* apply workaround for completion IRQ loss on PCI-X errata */
+       if (pi.flags & SIL24_FLAG_PCIX_IRQ_WOC) {
+               tmp = readl(iomap[SIL24_HOST_BAR] + HOST_CTRL);
+               if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
+                       dev_printk(KERN_INFO, &pdev->dev,
+                                  "Applying completion IRQ loss on PCI-X "
+                                  "errata fix\n");
+               else
+                       pi.flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
+       }
 
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
+       /* allocate and fill host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi,
+                                   SIL24_FLAG2NPORTS(ppi[0]->flags));
+       if (!host)
+               return -ENOMEM;
+       host->iomap = iomap;
 
-       probe_ent->sht          = pinfo->sht;
-       probe_ent->port_flags   = pinfo->flags;
-       probe_ent->pio_mask     = pinfo->pio_mask;
-       probe_ent->mwdma_mask   = pinfo->mwdma_mask;
-       probe_ent->udma_mask    = pinfo->udma_mask;
-       probe_ent->port_ops     = pinfo->port_ops;
-       probe_ent->n_ports      = SIL24_FLAG2NPORTS(pinfo->flags);
+       for (i = 0; i < host->n_ports; i++) {
+               void __iomem *port = iomap[SIL24_PORT_BAR] + i * PORT_REGS_SIZE;
 
-       probe_ent->irq = pdev->irq;
-       probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->iomap = pcim_iomap_table(pdev);
+               host->ports[i]->ioaddr.cmd_addr = port;
+               host->ports[i]->ioaddr.scr_addr = port + PORT_SCONTROL;
 
-       host_base = probe_ent->iomap[SIL24_HOST_BAR];
-       port_base = probe_ent->iomap[SIL24_PORT_BAR];
+               ata_std_ports(&host->ports[i]->ioaddr);
+       }
 
-       /*
-        * Configure the device
-        */
+       /* configure and activate the device */
        if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
                rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
                if (rc) {
@@ -1099,36 +1092,11 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                }
        }
 
-       /* Apply workaround for completion IRQ loss on PCI-X errata */
-       if (probe_ent->port_flags & SIL24_FLAG_PCIX_IRQ_WOC) {
-               tmp = readl(host_base + HOST_CTRL);
-               if (tmp & (HOST_CTRL_TRDY | HOST_CTRL_STOP | HOST_CTRL_DEVSEL))
-                       dev_printk(KERN_INFO, &pdev->dev,
-                                  "Applying completion IRQ loss on PCI-X "
-                                  "errata fix\n");
-               else
-                       probe_ent->port_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
-       }
-
-       for (i = 0; i < probe_ent->n_ports; i++) {
-               void __iomem *port = port_base + i * PORT_REGS_SIZE;
-
-               probe_ent->port[i].cmd_addr = port;
-               probe_ent->port[i].scr_addr = port + PORT_SCONTROL;
-
-               ata_std_ports(&probe_ent->port[i]);
-       }
-
-       sil24_init_controller(pdev, probe_ent->n_ports, probe_ent->port_flags,
-                             host_base, port_base);
+       sil24_init_controller(host);
 
        pci_set_master(pdev);
-
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(dev, probe_ent);
-       return 0;
+       return ata_host_activate(host, pdev->irq, sil24_interrupt, IRQF_SHARED,
+                                &sil24_sht);
 }
 
 #ifdef CONFIG_PM
@@ -1136,7 +1104,6 @@ static int sil24_pci_device_resume(struct pci_dev *pdev)
 {
        struct ata_host *host = dev_get_drvdata(&pdev->dev);
        void __iomem *host_base = host->iomap[SIL24_HOST_BAR];
-       void __iomem *port_base = host->iomap[SIL24_PORT_BAR];
        int rc;
 
        rc = ata_pci_device_do_resume(pdev);
@@ -1146,8 +1113,7 @@ static int sil24_pci_device_resume(struct pci_dev *pdev)
        if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
                writel(HOST_CTRL_GLOBAL_RST, host_base + HOST_CTRL);
 
-       sil24_init_controller(pdev, host->n_ports, host->ports[0]->flags,
-                             host_base, port_base);
+       sil24_init_controller(host);
 
        ata_host_resume(host);
 
index a787f0d4a5baeea3d9da9f2c63dd025e9f078d92..d8ee062e82fce91fafc91348296bc3ec75e930b9 100644 (file)
@@ -121,7 +121,6 @@ static const struct ata_port_operations sis_ops = {
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
-       .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -131,7 +130,6 @@ static const struct ata_port_operations sis_ops = {
 };
 
 static struct ata_port_info sis_port_info = {
-       .sht            = &sis_sht,
        .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
        .pio_mask       = 0x1f,
        .mwdma_mask     = 0x7,
@@ -256,12 +254,13 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
 static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct ata_probe_ent *probe_ent = NULL;
-       int rc;
+       struct ata_port_info pi = sis_port_info;
+       const struct ata_port_info *ppi[2] = { &pi, &pi };
+       struct ata_host *host;
        u32 genctl, val;
-       struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi };
        u8 pmr;
        u8 port2_start = 0x20;
+       int rc;
 
        if (!printed_version++)
                dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
@@ -270,19 +269,6 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                return rc;
 
-       rc = pci_request_regions(pdev, DRV_NAME);
-       if (rc) {
-               pcim_pin_device(pdev);
-               return rc;
-       }
-
-       rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
-       if (rc)
-               return rc;
-       rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
-       if (rc)
-               return rc;
-
        /* check and see if the SCRs are in IO space or PCI cfg space */
        pci_read_config_dword(pdev, SIS_GENCTL, &genctl);
        if ((genctl & GENCTL_IOMAPPED_SCR) == 0)
@@ -349,30 +335,26 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                break;
        }
 
-       probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
-       if (!probe_ent)
-               return -ENOMEM;
+       rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
+       if (rc)
+               return rc;
 
-       if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) {
+       if (!(pi.flags & SIS_FLAG_CFGSCR)) {
                void __iomem *mmio;
 
-               mmio = pcim_iomap(pdev, SIS_SCR_PCI_BAR, 0);
-               if (!mmio)
-                       return -ENOMEM;
+               rc = pcim_iomap_regions(pdev, 1 << SIS_SCR_PCI_BAR, DRV_NAME);
+               if (rc)
+                       return rc;
+               mmio = host->iomap[SIS_SCR_PCI_BAR];
 
-               probe_ent->port[0].scr_addr = mmio;
-               probe_ent->port[1].scr_addr = mmio + port2_start;
+               host->ports[0]->ioaddr.scr_addr = mmio;
+               host->ports[1]->ioaddr.scr_addr = mmio + port2_start;
        }
 
        pci_set_master(pdev);
        pci_intx(pdev, 1);
-
-       if (!ata_device_add(probe_ent))
-               return -EIO;
-
-       devm_kfree(&pdev->dev, probe_ent);
-       return 0;
-
+       return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+                                &sis_sht);
 }
 
 static int __init sis_init(void)
index b121195cc598c6a9f4dccd6bbe21580e187ad7c9..cc07aac10e8ce37a0ee818f5ec982b3fc602c509 100644 (file)
@@ -56,7 +56,9 @@
 #define DRV_VERSION    "2.1"
 
 enum {
-       K2_FLAG_NO_ATAPI_DMA            = (1 << 29),
+       /* ap->flags bits */
+       K2_FLAG_SATA_8_PORTS            = (1 << 24),
+       K2_FLAG_NO_ATAPI_DMA            = (1 << 25),
 
        /* Taskfile registers offsets */
        K2_SATA_TF_CMD_OFFSET           = 0x00,
@@ -90,17 +92,6 @@ enum {
        board_svw8                      = 1,
 };
 
-static const struct k2_board_info {
-       unsigned int            n_ports;
-       unsigned long           port_flags;
-} k2_board_info[] = {
-       /* board_svw4 */
-       { 4, K2_FLAG_NO_ATAPI_DMA },
-
-       /* board_svw8 */
-       { 8, K2_FLAG_NO_ATAPI_DMA },
-};
-
 static u8 k2_stat_check_status(struct ata_port *ap);
 
 
@@ -354,7 +345,6 @@ static const struct ata_port_operations k2_sata_ops = {
        .thaw                   = ata_bmdma_thaw,
        .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
-       .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -363,6 +353,28 @@ static const struct ata_port_operations k2_sata_ops = {
        .port_start             = ata_port_start,
 };
 
+static const struct ata_port_info k2_port_info[] = {
+       /* board_svw4 */
+       {
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA,
+               .pio_mask       = 0x1f,
+               .mwdma_mask     = 0x07,
+               .udma_mask      = 0x7f,
+               .port_ops       = &k2_sata_ops,
+       },
+       /* board_svw8 */
+       {
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO | K2_FLAG_NO_ATAPI_DMA |
+                                 K2_FLAG_SATA_8_PORTS,
+               .pio_mask       = 0x1f,
+               .mwdma_mask     = 0x07,
+               .udma_mask      = 0x7f,
+               .port_ops       = &k2_sata_ops,
+       },
+};
+
 static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
 {
        port->cmd_addr          = base + K2_SATA_TF_CMD_OFFSET;
@@ -386,17 +398,24 @@ static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
 static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct device *dev = &pdev->dev;
-       struct ata_probe_ent *probe_ent;
+       const struct ata_port_info *ppi[] =
+               { &k2_port_info[ent->driver_data], NULL };
+       struct ata_host *host;
        void __iomem *mmio_base;
-       const struct k2_board_info *board_info =
-                       &k2_board_info[ent->driver_data];
-       int rc;
-       int i;
+       int n_ports, i, rc;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* allocate host */
+       n_ports = 4;
+       if (ppi[0]->flags & K2_FLAG_SATA_8_PORTS)
+               n_ports = 8;
+
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
+       if (!host)
+               return -ENOMEM;
+
        /*
         * If this driver happens to only be useful on Apple's K2, then
         * we should check that here as it has a normal Serverworks ID
@@ -404,6 +423,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
+
        /*
         * Check if we have resources mapped at all (second function may
         * have been disabled by firmware)
@@ -417,6 +437,15 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
                pcim_pin_device(pdev);
        if (rc)
                return rc;
+       host->iomap = pcim_iomap_table(pdev);
+       mmio_base = host->iomap[5];
+
+       /* different controllers have different number of ports - currently 4 or 8 */
+       /* All ports are on the same function. Multi-function device is no
+        * longer available. This should not be seen in any system. */
+       for (i = 0; i < host->n_ports; i++)
+               k2_sata_setup_port(&host->ports[i]->ioaddr,
+                                  mmio_base + i * K2_SATA_PORT_OFFSET);
 
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
@@ -425,38 +454,6 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        if (rc)
                return rc;
 
-       probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
-
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       probe_ent->sht = &k2_sata_sht;
-       probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                               ATA_FLAG_MMIO | board_info->port_flags;
-       probe_ent->port_ops = &k2_sata_ops;
-       probe_ent->n_ports = 4;
-       probe_ent->irq = pdev->irq;
-       probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->iomap = pcim_iomap_table(pdev);
-
-       /* We don't care much about the PIO/UDMA masks, but the core won't like us
-        * if we don't fill these
-        */
-       probe_ent->pio_mask = 0x1f;
-       probe_ent->mwdma_mask = 0x7;
-       probe_ent->udma_mask = 0x7f;
-
-       mmio_base = probe_ent->iomap[5];
-
-       /* different controllers have different number of ports - currently 4 or 8 */
-       /* All ports are on the same function. Multi-function device is no
-        * longer available. This should not be seen in any system. */
-       for (i = 0; i < board_info->n_ports; i++)
-               k2_sata_setup_port(&probe_ent->port[i],
-                                  mmio_base + i * K2_SATA_PORT_OFFSET);
-
        /* Clear a magic bit in SCR1 according to Darwin, those help
         * some funky seagate drives (though so far, those were already
         * set by the firmware on the machines I had access to)
@@ -469,12 +466,8 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
        writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
 
        pci_set_master(pdev);
-
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(dev, probe_ent);
-       return 0;
+       return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+                                &k2_sata_sht);
 }
 
 /* 0x240 is device ID for Apple K2 device
index 1a081c3a8c06a24b3cd4ba51e6d643435ed2ca21..3a4f44559d0ae556176ac908c89989487ba75654 100644 (file)
@@ -151,24 +151,23 @@ struct pdc_host_priv {
 
 
 static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance);
 static void pdc_eng_timeout(struct ata_port *ap);
 static void pdc_20621_phy_reset (struct ata_port *ap);
 static int pdc_port_start(struct ata_port *ap);
 static void pdc20621_qc_prep(struct ata_queued_cmd *qc);
 static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
 static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
-static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe);
-static int pdc20621_detect_dimm(struct ata_probe_ent *pe);
-static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe,
+static unsigned int pdc20621_dimm_init(struct ata_host *host);
+static int pdc20621_detect_dimm(struct ata_host *host);
+static unsigned int pdc20621_i2c_read(struct ata_host *host,
                                      u32 device, u32 subaddr, u32 *pdata);
-static int pdc20621_prog_dimm0(struct ata_probe_ent *pe);
-static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe);
+static int pdc20621_prog_dimm0(struct ata_host *host);
+static unsigned int pdc20621_prog_dimm_global(struct ata_host *host);
 #ifdef ATA_VERBOSE_DEBUG
-static void pdc20621_get_from_dimm(struct ata_probe_ent *pe,
+static void pdc20621_get_from_dimm(struct ata_host *host,
                                   void *psource, u32 offset, u32 size);
 #endif
-static void pdc20621_put_to_dimm(struct ata_probe_ent *pe,
+static void pdc20621_put_to_dimm(struct ata_host *host,
                                 void *psource, u32 offset, u32 size);
 static void pdc20621_irq_clear(struct ata_port *ap);
 static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc);
@@ -204,7 +203,6 @@ static const struct ata_port_operations pdc_20621_ops = {
        .qc_issue               = pdc20621_qc_issue_prot,
        .data_xfer              = ata_data_xfer,
        .eng_timeout            = pdc_eng_timeout,
-       .irq_handler            = pdc20621_interrupt,
        .irq_clear              = pdc20621_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -214,7 +212,6 @@ static const struct ata_port_operations pdc_20621_ops = {
 static const struct ata_port_info pdc_port_info[] = {
        /* board_20621 */
        {
-               .sht            = &pdc_sata_sht,
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_SRST | ATA_FLAG_MMIO |
                                  ATA_FLAG_NO_ATAPI | ATA_FLAG_PIO_POLLING,
@@ -882,15 +879,15 @@ static void pdc_sata_setup_port(struct ata_ioports *port, void __iomem *base)
 
 
 #ifdef ATA_VERBOSE_DEBUG
-static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource,
+static void pdc20621_get_from_dimm(struct ata_host *host, void *psource,
                                   u32 offset, u32 size)
 {
        u32 window_size;
        u16 idx;
        u8 page_mask;
        long dist;
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
-       void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
+       void __iomem *dimm_mmio = host->iomap[PDC_DIMM_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
@@ -937,15 +934,15 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource,
 #endif
 
 
-static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
+static void pdc20621_put_to_dimm(struct ata_host *host, void *psource,
                                 u32 offset, u32 size)
 {
        u32 window_size;
        u16 idx;
        u8 page_mask;
        long dist;
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
-       void __iomem *dimm_mmio = pe->iomap[PDC_DIMM_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
+       void __iomem *dimm_mmio = host->iomap[PDC_DIMM_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
@@ -987,10 +984,10 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource,
 }
 
 
-static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device,
+static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device,
                                      u32 subaddr, u32 *pdata)
 {
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
        u32 i2creg  = 0;
        u32 status;
        u32 count =0;
@@ -1023,17 +1020,17 @@ static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device,
 }
 
 
-static int pdc20621_detect_dimm(struct ata_probe_ent *pe)
+static int pdc20621_detect_dimm(struct ata_host *host)
 {
        u32 data=0 ;
-       if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
+       if (pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
                             PDC_DIMM_SPD_SYSTEM_FREQ, &data)) {
                if (data == 100)
                        return 100;
        } else
                return 0;
 
-       if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) {
+       if (pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) {
                if(data <= 0x75)
                        return 133;
        } else
@@ -1043,13 +1040,13 @@ static int pdc20621_detect_dimm(struct ata_probe_ent *pe)
 }
 
 
-static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
+static int pdc20621_prog_dimm0(struct ata_host *host)
 {
        u32 spd0[50];
        u32 data = 0;
        int size, i;
        u8 bdimmsize;
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
        static const struct {
                unsigned int reg;
                unsigned int ofs;
@@ -1072,7 +1069,7 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
        mmio += PDC_CHIP0_OFS;
 
        for(i=0; i<ARRAY_SIZE(pdc_i2c_read_data); i++)
-               pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
+               pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
                                  pdc_i2c_read_data[i].reg,
                                  &spd0[pdc_i2c_read_data[i].ofs]);
 
@@ -1108,11 +1105,11 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe)
 }
 
 
-static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe)
+static unsigned int pdc20621_prog_dimm_global(struct ata_host *host)
 {
        u32 data, spd0;
        int error, i;
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
@@ -1129,7 +1126,7 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe)
        readl(mmio + PDC_SDRAM_CONTROL_OFFSET);
 
        /* Turn on for ECC */
-       pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
+       pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
                          PDC_DIMM_SPD_TYPE, &spd0);
        if (spd0 == 0x02) {
                data |= (0x01 << 16);
@@ -1156,7 +1153,7 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe)
 }
 
 
-static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
+static unsigned int pdc20621_dimm_init(struct ata_host *host)
 {
        int speed, size, length;
        u32 addr,spd0,pci_status;
@@ -1166,7 +1163,7 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
        u32 ticks=0;
        u32 clock=0;
        u32 fparam=0;
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
@@ -1225,18 +1222,18 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
           Read SPD of DIMM by I2C interface,
           and program the DIMM Module Controller.
        */
-       if (!(speed = pdc20621_detect_dimm(pe))) {
+       if (!(speed = pdc20621_detect_dimm(host))) {
                printk(KERN_ERR "Detect Local DIMM Fail\n");
                return 1;       /* DIMM error */
        }
        VPRINTK("Local DIMM Speed = %d\n", speed);
 
        /* Programming DIMM0 Module Control Register (index_CID0:80h) */
-       size = pdc20621_prog_dimm0(pe);
+       size = pdc20621_prog_dimm0(host);
        VPRINTK("Local DIMM Size = %dMB\n",size);
 
        /* Programming DIMM Module Global Control Register (index_CID0:88h) */
-       if (pdc20621_prog_dimm_global(pe)) {
+       if (pdc20621_prog_dimm_global(host)) {
                printk(KERN_ERR "Programming DIMM Module Global Control Register Fail\n");
                return 1;
        }
@@ -1249,20 +1246,20 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
                                '9','8','0','3','1','6','1','2',0,0};
                u8 test_parttern2[40] = {0};
 
-               pdc20621_put_to_dimm(pe, (void *) test_parttern2, 0x10040, 40);
-               pdc20621_put_to_dimm(pe, (void *) test_parttern2, 0x40, 40);
+               pdc20621_put_to_dimm(host, (void *) test_parttern2, 0x10040, 40);
+               pdc20621_put_to_dimm(host, (void *) test_parttern2, 0x40, 40);
 
-               pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x10040, 40);
-               pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40);
+               pdc20621_put_to_dimm(host, (void *) test_parttern1, 0x10040, 40);
+               pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x40, 40);
                printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
                       test_parttern2[1], &(test_parttern2[2]));
-               pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x10040,
+               pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x10040,
                                       40);
                printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
                       test_parttern2[1], &(test_parttern2[2]));
 
-               pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x40, 40);
-               pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40);
+               pdc20621_put_to_dimm(host, (void *) test_parttern1, 0x40, 40);
+               pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x40, 40);
                printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
                       test_parttern2[1], &(test_parttern2[2]));
        }
@@ -1270,14 +1267,14 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
 
        /* ECC initiliazation. */
 
-       pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS,
+       pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
                          PDC_DIMM_SPD_TYPE, &spd0);
        if (spd0 == 0x02) {
                VPRINTK("Start ECC initialization\n");
                addr = 0;
                length = size * 1024 * 1024;
                while (addr < length) {
-                       pdc20621_put_to_dimm(pe, (void *) &tmp, addr,
+                       pdc20621_put_to_dimm(host, (void *) &tmp, addr,
                                             sizeof(u32));
                        addr += sizeof(u32);
                }
@@ -1287,10 +1284,10 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
 }
 
 
-static void pdc_20621_init(struct ata_probe_ent *pe)
+static void pdc_20621_init(struct ata_host *host)
 {
        u32 tmp;
-       void __iomem *mmio = pe->iomap[PDC_MMIO_BAR];
+       void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
@@ -1321,15 +1318,25 @@ static void pdc_20621_init(struct ata_probe_ent *pe)
 static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct ata_probe_ent *probe_ent;
+       const struct ata_port_info *ppi[] =
+               { &pdc_port_info[ent->driver_data], NULL };
+       struct ata_host *host;
        void __iomem *base;
        struct pdc_host_priv *hpriv;
-       unsigned int board_idx = (unsigned int) ent->driver_data;
        int rc;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* allocate host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, 4);
+       hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
+       if (!host || !hpriv)
+               return -ENOMEM;
+
+       host->private_data = hpriv;
+
+       /* acquire resources and fill host */
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
@@ -1340,7 +1347,15 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
                pcim_pin_device(pdev);
        if (rc)
                return rc;
+       host->iomap = pcim_iomap_table(pdev);
+
+       base = host->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS;
+       pdc_sata_setup_port(&host->ports[0]->ioaddr, base + 0x200);
+       pdc_sata_setup_port(&host->ports[1]->ioaddr, base + 0x280);
+       pdc_sata_setup_port(&host->ports[2]->ioaddr, base + 0x300);
+       pdc_sata_setup_port(&host->ports[3]->ioaddr, base + 0x380);
 
+       /* configure and activate */
        rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
        if (rc)
                return rc;
@@ -1348,50 +1363,13 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
        if (rc)
                return rc;
 
-       probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
+       if (pdc20621_dimm_init(host))
                return -ENOMEM;
-
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
-       if (!hpriv)
-               return -ENOMEM;
-
-       probe_ent->sht          = pdc_port_info[board_idx].sht;
-       probe_ent->port_flags   = pdc_port_info[board_idx].flags;
-       probe_ent->pio_mask     = pdc_port_info[board_idx].pio_mask;
-       probe_ent->mwdma_mask   = pdc_port_info[board_idx].mwdma_mask;
-       probe_ent->udma_mask    = pdc_port_info[board_idx].udma_mask;
-       probe_ent->port_ops     = pdc_port_info[board_idx].port_ops;
-
-               probe_ent->irq = pdev->irq;
-               probe_ent->irq_flags = IRQF_SHARED;
-       probe_ent->iomap = pcim_iomap_table(pdev);
-
-       probe_ent->private_data = hpriv;
-       base = probe_ent->iomap[PDC_MMIO_BAR] + PDC_CHIP0_OFS;
-
-       probe_ent->n_ports = 4;
-       pdc_sata_setup_port(&probe_ent->port[0], base + 0x200);
-       pdc_sata_setup_port(&probe_ent->port[1], base + 0x280);
-       pdc_sata_setup_port(&probe_ent->port[2], base + 0x300);
-       pdc_sata_setup_port(&probe_ent->port[3], base + 0x380);
+       pdc_20621_init(host);
 
        pci_set_master(pdev);
-
-       /* initialize adapter */
-       /* initialize local dimm */
-       if (pdc20621_dimm_init(probe_ent))
-               return -ENOMEM;
-       pdc_20621_init(probe_ent);
-
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(&pdev->dev, probe_ent);
-       return 0;
+       return ata_host_activate(host, pdev->irq, pdc20621_interrupt,
+                                IRQF_SHARED, &pdc_sata_sht);
 }
 
 
index d659ace80f4f6c985f6da071a61b9d42ff93b8a5..f74e383de08303546259f0d1f817c77043788000 100644 (file)
@@ -115,7 +115,6 @@ static const struct ata_port_operations uli_ops = {
        .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
 
-       .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -127,7 +126,6 @@ static const struct ata_port_operations uli_ops = {
 };
 
 static struct ata_port_info uli_port_info = {
-       .sht            = &uli_sht,
        .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                          ATA_FLAG_IGN_SIMPLEX,
        .pio_mask       = 0x1f,         /* pio0-4 */
@@ -185,12 +183,13 @@ static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
 static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
-       struct ata_probe_ent *probe_ent;
-       struct ata_port_info *ppi[2];
-       int rc;
+       const struct ata_port_info *ppi[] = { &uli_port_info, NULL };
        unsigned int board_idx = (unsigned int) ent->driver_data;
+       struct ata_host *host;
        struct uli_priv *hpriv;
        void __iomem * const *iomap;
+       struct ata_ioports *ioaddr;
+       int n_ports, rc;
 
        if (!printed_version++)
                dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
@@ -199,54 +198,42 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                return rc;
 
-       rc = pci_request_regions(pdev, DRV_NAME);
-       if (rc) {
-               pcim_pin_device(pdev);
-               return rc;
-       }
-
-       rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
-       if (rc)
-               return rc;
-       rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+       n_ports = 2;
+       if (board_idx == uli_5287)
+               n_ports = 4;
+       rc = ata_pci_prepare_native_host(pdev, ppi, n_ports, &host);
        if (rc)
                return rc;
 
-       ppi[0] = ppi[1] = &uli_port_info;
-       probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
-       if (!probe_ent)
-               return -ENOMEM;
-
        hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
        if (!hpriv)
                return -ENOMEM;
+       host->private_data = hpriv;
 
-       probe_ent->private_data = hpriv;
-
-       iomap = pcim_iomap_table(pdev);
+       iomap = host->iomap;
 
        switch (board_idx) {
        case uli_5287:
                hpriv->scr_cfg_addr[0] = ULI5287_BASE;
                hpriv->scr_cfg_addr[1] = ULI5287_BASE + ULI5287_OFFS;
-                       probe_ent->n_ports = 4;
 
-               probe_ent->port[2].cmd_addr = iomap[0] + 8;
-               probe_ent->port[2].altstatus_addr =
-               probe_ent->port[2].ctl_addr = (void __iomem *)
+               ioaddr = &host->ports[2]->ioaddr;
+               ioaddr->cmd_addr = iomap[0] + 8;
+               ioaddr->altstatus_addr =
+               ioaddr->ctl_addr = (void __iomem *)
                        ((unsigned long)iomap[1] | ATA_PCI_CTL_OFS) + 4;
-               probe_ent->port[2].bmdma_addr = iomap[4] + 16;
+               ioaddr->bmdma_addr = iomap[4] + 16;
                hpriv->scr_cfg_addr[2] = ULI5287_BASE + ULI5287_OFFS*4;
+               ata_std_ports(ioaddr);
 
-               probe_ent->port[3].cmd_addr = iomap[2] + 8;
-               probe_ent->port[3].altstatus_addr =
-               probe_ent->port[3].ctl_addr = (void __iomem *)
+               ioaddr = &host->ports[3]->ioaddr;
+               ioaddr->cmd_addr = iomap[2] + 8;
+               ioaddr->altstatus_addr =
+               ioaddr->ctl_addr = (void __iomem *)
                        ((unsigned long)iomap[3] | ATA_PCI_CTL_OFS) + 4;
-               probe_ent->port[3].bmdma_addr = iomap[4] + 24;
+               ioaddr->bmdma_addr = iomap[4] + 24;
                hpriv->scr_cfg_addr[3] = ULI5287_BASE + ULI5287_OFFS*5;
-
-               ata_std_ports(&probe_ent->port[2]);
-               ata_std_ports(&probe_ent->port[3]);
+               ata_std_ports(ioaddr);
                break;
 
        case uli_5289:
@@ -266,12 +253,8 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 
        pci_set_master(pdev);
        pci_intx(pdev, 1);
-
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(&pdev->dev, probe_ent);
-       return 0;
+       return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+                                &uli_sht);
 }
 
 static int __init uli_init(void)
index 598e6a26a481a7934d8ae14121e395844c1f22dd..1d855f55f5f710edd378110740b76042afe37005 100644 (file)
@@ -64,8 +64,6 @@ enum {
        PORT0                   = (1 << 1),
        PORT1                   = (1 << 0),
        ALL_PORTS               = PORT0 | PORT1,
-       PATA_PORT               = 2,    /* PATA is port 2 */
-       N_PORTS                 = 3,
 
        NATIVE_MODE_ALL         = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
 
@@ -78,11 +76,9 @@ static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 static void svia_noop_freeze(struct ata_port *ap);
 static void vt6420_error_handler(struct ata_port *ap);
-static void vt6421_sata_error_handler(struct ata_port *ap);
-static void vt6421_pata_error_handler(struct ata_port *ap);
+static int vt6421_pata_cable_detect(struct ata_port *ap);
 static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev);
 static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev);
-static int vt6421_port_start(struct ata_port *ap);
 
 static const struct pci_device_id svia_pci_tbl[] = {
        { PCI_VDEVICE(VIA, 0x5337), vt6420 },
@@ -141,7 +137,6 @@ static const struct ata_port_operations vt6420_sata_ops = {
        .error_handler          = vt6420_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
 
-       .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -172,15 +167,15 @@ static const struct ata_port_operations vt6421_pata_ops = {
 
        .freeze                 = ata_bmdma_freeze,
        .thaw                   = ata_bmdma_thaw,
-       .error_handler          = vt6421_pata_error_handler,
+       .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = vt6421_pata_cable_detect,
 
-       .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
 
-       .port_start             = vt6421_port_start,
+       .port_start             = ata_port_start,
 };
 
 static const struct ata_port_operations vt6421_sata_ops = {
@@ -203,10 +198,10 @@ static const struct ata_port_operations vt6421_sata_ops = {
 
        .freeze                 = ata_bmdma_freeze,
        .thaw                   = ata_bmdma_thaw,
-       .error_handler          = vt6421_sata_error_handler,
+       .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
+       .cable_detect           = ata_cable_sata,
 
-       .irq_handler            = ata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -214,11 +209,10 @@ static const struct ata_port_operations vt6421_sata_ops = {
        .scr_read               = svia_scr_read,
        .scr_write              = svia_scr_write,
 
-       .port_start             = vt6421_port_start,
+       .port_start             = ata_port_start,
 };
 
-static struct ata_port_info vt6420_port_info = {
-       .sht            = &svia_sht,
+static const struct ata_port_info vt6420_port_info = {
        .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
        .pio_mask       = 0x1f,
        .mwdma_mask     = 0x07,
@@ -226,6 +220,22 @@ static struct ata_port_info vt6420_port_info = {
        .port_ops       = &vt6420_sata_ops,
 };
 
+static struct ata_port_info vt6421_sport_info = {
+       .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
+       .pio_mask       = 0x1f,
+       .mwdma_mask     = 0x07,
+       .udma_mask      = 0x7f,
+       .port_ops       = &vt6421_sata_ops,
+};
+
+static struct ata_port_info vt6421_pport_info = {
+       .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY,
+       .pio_mask       = 0x1f,
+       .mwdma_mask     = 0,
+       .udma_mask      = 0x7f,
+       .port_ops       = &vt6421_pata_ops,
+};
+
 MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers");
 MODULE_LICENSE("GPL");
@@ -330,35 +340,15 @@ static void vt6420_error_handler(struct ata_port *ap)
                                  NULL, ata_std_postreset);
 }
 
-static int vt6421_pata_prereset(struct ata_port *ap)
+static int vt6421_pata_cable_detect(struct ata_port *ap)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        u8 tmp;
 
        pci_read_config_byte(pdev, PATA_UDMA_TIMING, &tmp);
        if (tmp & 0x10)
-               ap->cbl = ATA_CBL_PATA40;
-       else
-               ap->cbl = ATA_CBL_PATA80;
-       return 0;
-}
-
-static void vt6421_pata_error_handler(struct ata_port *ap)
-{
-       return ata_bmdma_drive_eh(ap, vt6421_pata_prereset, ata_std_softreset,
-                                 NULL, ata_std_postreset);
-}
-
-static int vt6421_sata_prereset(struct ata_port *ap)
-{
-       ap->cbl = ATA_CBL_SATA;
-       return 0;
-}
-
-static void vt6421_sata_error_handler(struct ata_port *ap)
-{
-       return ata_bmdma_drive_eh(ap, vt6421_sata_prereset, ata_std_softreset,
-                                 NULL, ata_std_postreset);
+               return ATA_CBL_PATA40;
+       return ATA_CBL_PATA80;
 }
 
 static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev)
@@ -375,16 +365,6 @@ static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev)
        pci_write_config_byte(pdev, PATA_UDMA_TIMING, udma_bits[adev->pio_mode - XFER_UDMA_0]);
 }
 
-static int vt6421_port_start(struct ata_port *ap)
-{
-       if (ap->port_no == PATA_PORT) {
-               ap->ops = &vt6421_pata_ops;
-               ap->mwdma_mask = 0;
-               ap->flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST;
-       }
-       return ata_port_start(ap);
-}
-
 static const unsigned int svia_bar_sizes[] = {
        8, 4, 8, 4, 16, 256
 };
@@ -403,79 +383,78 @@ static void __iomem * vt6421_scr_addr(void __iomem *addr, unsigned int port)
        return addr + (port * 64);
 }
 
-static void vt6421_init_addrs(struct ata_probe_ent *probe_ent,
-                             void __iomem * const *iomap, unsigned int port)
+static void vt6421_init_addrs(struct ata_port *ap)
 {
-       void __iomem *reg_addr = iomap[port];
-       void __iomem *bmdma_addr = iomap[4] + (port * 8);
-
-       probe_ent->port[port].cmd_addr = reg_addr;
-       probe_ent->port[port].altstatus_addr =
-       probe_ent->port[port].ctl_addr = (void __iomem *)
+       void __iomem * const * iomap = ap->host->iomap;
+       void __iomem *reg_addr = iomap[ap->port_no];
+       void __iomem *bmdma_addr = iomap[4] + (ap->port_no * 8);
+       struct ata_ioports *ioaddr = &ap->ioaddr;
+
+       ioaddr->cmd_addr = reg_addr;
+       ioaddr->altstatus_addr =
+       ioaddr->ctl_addr = (void __iomem *)
                ((unsigned long)(reg_addr + 8) | ATA_PCI_CTL_OFS);
-       probe_ent->port[port].bmdma_addr = bmdma_addr;
-       probe_ent->port[port].scr_addr = vt6421_scr_addr(iomap[5], port);
+       ioaddr->bmdma_addr = bmdma_addr;
+       ioaddr->scr_addr = vt6421_scr_addr(iomap[5], ap->port_no);
 
-       ata_std_ports(&probe_ent->port[port]);
+       ata_std_ports(ioaddr);
 }
 
-static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev)
+static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
 {
-       struct ata_probe_ent *probe_ent;
-       struct ata_port_info *ppi[2];
-       void __iomem *bar5;
+       const struct ata_port_info *ppi[] = { &vt6420_port_info, NULL };
+       struct ata_host *host;
+       int rc;
 
-       ppi[0] = ppi[1] = &vt6420_port_info;
-       probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
-       if (!probe_ent)
-               return NULL;
+       rc = ata_pci_prepare_native_host(pdev, ppi, 2, &host);
+       if (rc)
+               return rc;
+       *r_host = host;
 
-       bar5 = pcim_iomap(pdev, 5, 0);
-       if (!bar5) {
+       rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME);
+       if (rc) {
                dev_printk(KERN_ERR, &pdev->dev, "failed to iomap PCI BAR 5\n");
-               return NULL;
+               return rc;
        }
 
-       probe_ent->port[0].scr_addr = svia_scr_addr(bar5, 0);
-       probe_ent->port[1].scr_addr = svia_scr_addr(bar5, 1);
+       host->ports[0]->ioaddr.scr_addr = svia_scr_addr(host->iomap[5], 0);
+       host->ports[1]->ioaddr.scr_addr = svia_scr_addr(host->iomap[5], 1);
 
-       return probe_ent;
+       return 0;
 }
 
-static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev)
+static int vt6421_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
 {
-       struct ata_probe_ent *probe_ent;
-       unsigned int i;
+       const struct ata_port_info *ppi[] =
+               { &vt6421_sport_info, &vt6421_sport_info, &vt6421_pport_info };
+       struct ata_host *host;
+       int i, rc;
+
+       *r_host = host = ata_host_alloc_pinfo(&pdev->dev, ppi, ARRAY_SIZE(ppi));
+       if (!host) {
+               dev_printk(KERN_ERR, &pdev->dev, "failed to allocate host\n");
+               return -ENOMEM;
+       }
 
-       probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (!probe_ent)
-               return NULL;
-
-       memset(probe_ent, 0, sizeof(*probe_ent));
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
-       probe_ent->sht          = &svia_sht;
-       probe_ent->port_flags   = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY;
-       probe_ent->port_ops     = &vt6421_sata_ops;
-       probe_ent->n_ports      = N_PORTS;
-       probe_ent->irq          = pdev->irq;
-       probe_ent->irq_flags    = IRQF_SHARED;
-       probe_ent->pio_mask     = 0x1f;
-       probe_ent->mwdma_mask   = 0x07;
-       probe_ent->udma_mask    = 0x7f;
-
-       for (i = 0; i < 6; i++)
-               if (!pcim_iomap(pdev, i, 0)) {
-                       dev_printk(KERN_ERR, &pdev->dev,
-                                  "failed to iomap PCI BAR %d\n", i);
-                       return NULL;
-               }
+       rc = pcim_iomap_regions(pdev, 0x1f, DRV_NAME);
+       if (rc) {
+               dev_printk(KERN_ERR, &pdev->dev, "failed to request/iomap "
+                          "PCI BARs (errno=%d)\n", rc);
+               return rc;
+       }
+       host->iomap = pcim_iomap_table(pdev);
 
-       for (i = 0; i < N_PORTS; i++)
-               vt6421_init_addrs(probe_ent, pcim_iomap_table(pdev), i);
+       for (i = 0; i < host->n_ports; i++)
+               vt6421_init_addrs(host->ports[i]);
 
-       return probe_ent;
+       rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+       if (rc)
+               return rc;
+       rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+       if (rc)
+               return rc;
+
+       return 0;
 }
 
 static void svia_configure(struct pci_dev *pdev)
@@ -522,7 +501,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        static int printed_version;
        unsigned int i;
        int rc;
-       struct ata_probe_ent *probe_ent;
+       struct ata_host *host;
        int board_id = (int) ent->driver_data;
        const int *bar_sizes;
        u8 tmp8;
@@ -534,12 +513,6 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                return rc;
 
-       rc = pci_request_regions(pdev, DRV_NAME);
-       if (rc) {
-               pcim_pin_device(pdev);
-               return rc;
-       }
-
        if (board_id == vt6420) {
                pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
                if (tmp8 & SATA_2DEV) {
@@ -565,32 +538,18 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                        return -ENODEV;
                }
 
-       rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
-       if (rc)
-               return rc;
-       rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
-       if (rc)
-               return rc;
-
        if (board_id == vt6420)
-               probe_ent = vt6420_init_probe_ent(pdev);
+               rc = vt6420_prepare_host(pdev, &host);
        else
-               probe_ent = vt6421_init_probe_ent(pdev);
-
-       if (!probe_ent) {
-               dev_printk(KERN_ERR, &pdev->dev, "out of memory\n");
-               return -ENOMEM;
-       }
+               rc = vt6421_prepare_host(pdev, &host);
+       if (rc)
+               return rc;
 
        svia_configure(pdev);
 
        pci_set_master(pdev);
-
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(&pdev->dev, probe_ent);
-       return 0;
+       return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
+                                &svia_sht);
 }
 
 static int __init svia_init(void)
index 170bad1b415b01765276b7578f6675804e7afb6d..80126f835d323897ec8ace75110cc3dbbc78d133 100644 (file)
@@ -333,7 +333,6 @@ static const struct ata_port_operations vsc_sata_ops = {
        .thaw                   = vsc_thaw,
        .error_handler          = ata_bmdma_error_handler,
        .post_internal_cmd      = ata_bmdma_post_internal_cmd,
-       .irq_handler            = vsc_sata_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
        .irq_on                 = ata_irq_on,
        .irq_ack                = ata_irq_ack,
@@ -367,30 +366,50 @@ static void __devinit vsc_sata_setup_port(struct ata_ioports *port,
 
 static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
+       static const struct ata_port_info pi = {
+               .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
+                                 ATA_FLAG_MMIO,
+               .pio_mask       = 0x1f,
+               .mwdma_mask     = 0x07,
+               .udma_mask      = 0x7f,
+               .port_ops       = &vsc_sata_ops,
+       };
+       const struct ata_port_info *ppi[] = { &pi, NULL };
        static int printed_version;
-       struct ata_probe_ent *probe_ent;
+       struct ata_host *host;
        void __iomem *mmio_base;
-       int rc;
+       int i, rc;
        u8 cls;
 
        if (!printed_version++)
                dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
 
+       /* allocate host */
+       host = ata_host_alloc_pinfo(&pdev->dev, ppi, 4);
+       if (!host)
+               return -ENOMEM;
+
        rc = pcim_enable_device(pdev);
        if (rc)
                return rc;
 
-       /*
-        * Check if we have needed resource mapped.
-        */
+       /* check if we have needed resource mapped */
        if (pci_resource_len(pdev, 0) == 0)
                return -ENODEV;
 
+       /* map IO regions and intialize host accordingly */
        rc = pcim_iomap_regions(pdev, 1 << VSC_MMIO_BAR, DRV_NAME);
        if (rc == -EBUSY)
                pcim_pin_device(pdev);
        if (rc)
                return rc;
+       host->iomap = pcim_iomap_table(pdev);
+
+       mmio_base = host->iomap[VSC_MMIO_BAR];
+
+       for (i = 0; i < host->n_ports; i++)
+               vsc_sata_setup_port(&host->ports[i]->ioaddr,
+                                   mmio_base + (i + 1) * VSC_SATA_PORT_OFFSET);
 
        /*
         * Use 32 bit DMA mask, because 64 bit address support is poor.
@@ -402,12 +421,6 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
        if (rc)
                return rc;
 
-       probe_ent = devm_kzalloc(&pdev->dev, sizeof(*probe_ent), GFP_KERNEL);
-       if (probe_ent == NULL)
-               return -ENOMEM;
-       probe_ent->dev = pci_dev_to_dev(pdev);
-       INIT_LIST_HEAD(&probe_ent->node);
-
        /*
         * Due to a bug in the chip, the default cache line size can't be
         * used (unless the default is non-zero).
@@ -418,33 +431,6 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
 
        if (pci_enable_msi(pdev) == 0)
                pci_intx(pdev, 0);
-       else
-               probe_ent->irq_flags = IRQF_SHARED;
-
-       probe_ent->sht = &vsc_sata_sht;
-       probe_ent->port_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
-                               ATA_FLAG_MMIO;
-       probe_ent->port_ops = &vsc_sata_ops;
-       probe_ent->n_ports = 4;
-       probe_ent->irq = pdev->irq;
-       probe_ent->iomap = pcim_iomap_table(pdev);
-
-       /* We don't care much about the PIO/UDMA masks, but the core won't like us
-        * if we don't fill these
-        */
-       probe_ent->pio_mask = 0x1f;
-       probe_ent->mwdma_mask = 0x07;
-       probe_ent->udma_mask = 0x7f;
-
-       mmio_base = probe_ent->iomap[VSC_MMIO_BAR];
-
-       /* We have 4 ports per PCI function */
-       vsc_sata_setup_port(&probe_ent->port[0], mmio_base + 1 * VSC_SATA_PORT_OFFSET);
-       vsc_sata_setup_port(&probe_ent->port[1], mmio_base + 2 * VSC_SATA_PORT_OFFSET);
-       vsc_sata_setup_port(&probe_ent->port[2], mmio_base + 3 * VSC_SATA_PORT_OFFSET);
-       vsc_sata_setup_port(&probe_ent->port[3], mmio_base + 4 * VSC_SATA_PORT_OFFSET);
-
-       pci_set_master(pdev);
 
        /*
         * Config offset 0x98 is "Extended Control and Status Register 0"
@@ -454,11 +440,9 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
         */
        pci_write_config_dword(pdev, 0x98, 0);
 
-       if (!ata_device_add(probe_ent))
-               return -ENODEV;
-
-       devm_kfree(&pdev->dev, probe_ent);
-       return 0;
+       pci_set_master(pdev);
+       return ata_host_activate(host, pdev->irq, vsc_sata_interrupt,
+                                IRQF_SHARED, &vsc_sata_sht);
 }
 
 static const struct pci_device_id vsc_sata_pci_tbl[] = {
index 65d6f23ead4151ae6953477f6eeed653df0cdd06..3411483240cd7166db36d84c8760b18c67b0cf59 100644 (file)
@@ -1303,119 +1303,6 @@ static void __init quirk_alder_ioapic(struct pci_dev *pdev)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_EESSC,      quirk_alder_ioapic );
 #endif
 
-enum ide_combined_type { COMBINED = 0, IDE = 1, LIBATA = 2 };
-/* Defaults to combined */
-static enum ide_combined_type combined_mode;
-
-static int __init combined_setup(char *str)
-{
-       if (!strncmp(str, "ide", 3))
-               combined_mode = IDE;
-       else if (!strncmp(str, "libata", 6))
-               combined_mode = LIBATA;
-       else /* "combined" or anything else defaults to old behavior */
-               combined_mode = COMBINED;
-
-       return 1;
-}
-__setup("combined_mode=", combined_setup);
-
-#ifdef CONFIG_SATA_INTEL_COMBINED
-static void __devinit quirk_intel_ide_combined(struct pci_dev *pdev)
-{
-       u8 prog, comb, tmp;
-       int ich = 0;
-
-       /*
-        * Narrow down to Intel SATA PCI devices.
-        */
-       switch (pdev->device) {
-       /* PCI ids taken from drivers/scsi/ata_piix.c */
-       case 0x24d1:
-       case 0x24df:
-       case 0x25a3:
-       case 0x25b0:
-               ich = 5;
-               break;
-       case 0x2651:
-       case 0x2652:
-       case 0x2653:
-       case 0x2680:    /* ESB2 */
-               ich = 6;
-               break;
-       case 0x27c0:
-       case 0x27c4:
-               ich = 7;
-               break;
-       case 0x2828:    /* ICH8M */
-               ich = 8;
-               break;
-       default:
-               /* we do not handle this PCI device */
-               return;
-       }
-
-       /*
-        * Read combined mode register.
-        */
-       pci_read_config_byte(pdev, 0x90, &tmp); /* combined mode reg */
-
-       if (ich == 5) {
-               tmp &= 0x6;  /* interesting bits 2:1, PATA primary/secondary */
-               if (tmp == 0x4)         /* bits 10x */
-                       comb = (1 << 0);        /* SATA port 0, PATA port 1 */
-               else if (tmp == 0x6)    /* bits 11x */
-                       comb = (1 << 2);        /* PATA port 0, SATA port 1 */
-               else
-                       return;                 /* not in combined mode */
-       } else {
-               WARN_ON((ich != 6) && (ich != 7) && (ich != 8));
-               tmp &= 0x3;  /* interesting bits 1:0 */
-               if (tmp & (1 << 0))
-                       comb = (1 << 2);        /* PATA port 0, SATA port 1 */
-               else if (tmp & (1 << 1))
-                       comb = (1 << 0);        /* SATA port 0, PATA port 1 */
-               else
-                       return;                 /* not in combined mode */
-       }
-
-       /*
-        * Read programming interface register.
-        * (Tells us if it's legacy or native mode)
-        */
-       pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
-
-       /* if SATA port is in native mode, we're ok. */
-       if (prog & comb)
-               return;
-
-       /* Don't reserve any so the IDE driver can get them (but only if
-        * combined_mode=ide).
-        */
-       if (combined_mode == IDE)
-               return;
-
-       /* Grab them both for libata if combined_mode=libata. */
-       if (combined_mode == LIBATA) {
-               request_region(0x1f0, 8, "libata");     /* port 0 */
-               request_region(0x170, 8, "libata");     /* port 1 */
-               return;
-       }
-
-       /* SATA port is in legacy mode.  Reserve port so that
-        * IDE driver does not attempt to use it.  If request_region
-        * fails, it will be obvious at boot time, so we don't bother
-        * checking return values.
-        */
-       if (comb == (1 << 0))
-               request_region(0x1f0, 8, "libata");     /* port 0 */
-       else
-               request_region(0x170, 8, "libata");     /* port 1 */
-}
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,    PCI_ANY_ID,      quirk_intel_ide_combined );
-#endif /* CONFIG_SATA_INTEL_COMBINED */
-
-
 int pcie_mch_quirk;
 EXPORT_SYMBOL(pcie_mch_quirk);
 
index 95045e33710d488b758374d17956f0f4074b837a..e9bd29975db4361913161ee5b1d24b88ff5c0ef9 100644 (file)
@@ -3770,7 +3770,8 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg,
  * Return value:
  *     0 on success / non-zero on failure
  **/
-static int ipr_sata_reset(struct ata_port *ap, unsigned int *classes)
+static int ipr_sata_reset(struct ata_port *ap, unsigned int *classes,
+                               unsigned long deadline)
 {
        struct ipr_sata_port *sata_port = ap->private_data;
        struct ipr_ioa_cfg *ioa_cfg = sata_port->ioa_cfg;
index 6caeb98e29ddd942c6defabc3eace48702f63b52..edb31bfff68fb3586097173f5dc61b7b215333ab 100644 (file)
@@ -159,11 +159,19 @@ enum {
        ATA_CMD_INIT_DEV_PARAMS = 0x91,
        ATA_CMD_READ_NATIVE_MAX = 0xF8,
        ATA_CMD_READ_NATIVE_MAX_EXT = 0x27,
+       ATA_CMD_SET_MAX         = 0xF9,
+       ATA_CMD_SET_MAX_EXT     = 0x37,
        ATA_CMD_READ_LOG_EXT    = 0x2f,
 
        /* READ_LOG_EXT pages */
        ATA_LOG_SATA_NCQ        = 0x10,
 
+       /* READ/WRITE LONG (obsolete) */
+       ATA_CMD_READ_LONG       = 0x22,
+       ATA_CMD_READ_LONG_ONCE  = 0x23,
+       ATA_CMD_WRITE_LONG      = 0x32,
+       ATA_CMD_WRITE_LONG_ONCE = 0x33,
+
        /* SETFEATURES stuff */
        SETFEATURES_XFER        = 0x03,
        XFER_UDMA_7             = 0x47,
@@ -194,6 +202,8 @@ enum {
        SETFEATURES_WC_ON       = 0x02, /* Enable write cache */
        SETFEATURES_WC_OFF      = 0x82, /* Disable write cache */
 
+       SETFEATURES_SPINUP      = 0x07, /* Spin-up drive */
+
        /* ATAPI stuff */
        ATAPI_PKT_DMA           = (1 << 0),
        ATAPI_DMADIR            = (1 << 2),     /* ATAPI data dir:
index 6859a3b14088459fef9de4e373f36ea0009a0f3a..71ea92319241ef55579609a081a6ff60bc403bf8 100644 (file)
@@ -99,7 +99,6 @@ extern struct resource ioport_resource;
 extern struct resource iomem_resource;
 
 extern int request_resource(struct resource *root, struct resource *new);
-extern struct resource * ____request_resource(struct resource *root, struct resource *new);
 extern int release_resource(struct resource *new);
 extern int insert_resource(struct resource *parent, struct resource *new);
 extern int allocate_resource(struct resource *root, struct resource *new,
index 0cfbcb6f08eb79a1841ddb7cc7ccabc7370188d2..d8cfc72ea9c110937161c910813a5f59d447b3b6 100644 (file)
@@ -210,6 +210,7 @@ enum {
 
        /* host set flags */
        ATA_HOST_SIMPLEX        = (1 << 0),     /* Host is simplex, one DMA channel per host only */
+       ATA_HOST_STARTED        = (1 << 1),     /* Host started */
 
        /* various lengths of time */
        ATA_TMOUT_BOOT          = 30 * HZ,      /* heuristic */
@@ -281,11 +282,13 @@ enum {
        ATA_EHI_NO_AUTOPSY      = (1 << 2),  /* no autopsy */
        ATA_EHI_QUIET           = (1 << 3),  /* be quiet */
 
-       ATA_EHI_DID_RESET       = (1 << 16), /* already reset this port */
-       ATA_EHI_PRINTINFO       = (1 << 17), /* print configuration info */
-       ATA_EHI_SETMODE         = (1 << 18), /* configure transfer mode */
-       ATA_EHI_POST_SETMODE    = (1 << 19), /* revaildating after setmode */
+       ATA_EHI_DID_SOFTRESET   = (1 << 16), /* already soft-reset this port */
+       ATA_EHI_DID_HARDRESET   = (1 << 17), /* already soft-reset this port */
+       ATA_EHI_PRINTINFO       = (1 << 18), /* print configuration info */
+       ATA_EHI_SETMODE         = (1 << 19), /* configure transfer mode */
+       ATA_EHI_POST_SETMODE    = (1 << 20), /* revaildating after setmode */
 
+       ATA_EHI_DID_RESET       = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET,
        ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK,
 
        /* max repeat if error condition is still set after ->error_handler */
@@ -367,34 +370,6 @@ struct ata_ioports {
        void __iomem            *scr_addr;
 };
 
-struct ata_probe_ent {
-       struct list_head        node;
-       struct device           *dev;
-       const struct ata_port_operations *port_ops;
-       struct scsi_host_template *sht;
-       struct ata_ioports      port[ATA_MAX_PORTS];
-       unsigned int            n_ports;
-       unsigned int            dummy_port_mask;
-       unsigned int            pio_mask;
-       unsigned int            mwdma_mask;
-       unsigned int            udma_mask;
-       unsigned long           irq;
-       unsigned long           irq2;
-       unsigned int            irq_flags;
-       unsigned long           port_flags;
-       unsigned long           _host_flags;
-       void __iomem * const    *iomap;
-       void                    *private_data;
-
-       /* port_info for the secondary port.  Together with irq2, it's
-        * used to implement non-uniform secondary port.  Currently,
-        * the only user is ata_piix combined mode.  This workaround
-        * will be removed together with ata_probe_ent when init model
-        * is updated.
-        */
-       const struct ata_port_info *pinfo2;
-};
-
 struct ata_host {
        spinlock_t              lock;
        struct device           *dev;
@@ -427,6 +402,7 @@ struct ata_queued_cmd {
        int                     dma_dir;
 
        unsigned int            pad_len;
+       unsigned int            sect_size;
 
        unsigned int            nbytes;
        unsigned int            curbytes;
@@ -472,6 +448,7 @@ struct ata_device {
        struct scsi_device      *sdev;          /* attached SCSI device */
        /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
        u64                     n_sectors;      /* size of device, if ATA */
+       u64                     n_sectors_boot; /* size of ATA device at startup */
        unsigned int            class;          /* ATA_DEV_xxx */
        u16                     id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
        u8                      pio_mode;
@@ -597,11 +574,11 @@ struct ata_port {
 struct ata_port_operations {
        void (*port_disable) (struct ata_port *);
 
-       void (*dev_config) (struct ata_port *, struct ata_device *);
+       void (*dev_config) (struct ata_device *);
 
        void (*set_piomode) (struct ata_port *, struct ata_device *);
        void (*set_dmamode) (struct ata_port *, struct ata_device *);
-       unsigned long (*mode_filter) (const struct ata_port *, struct ata_device *, unsigned long);
+       unsigned long (*mode_filter) (struct ata_device *, unsigned long);
 
        void (*tf_load) (struct ata_port *ap, const struct ata_taskfile *tf);
        void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
@@ -616,6 +593,8 @@ struct ata_port_operations {
 
        void (*post_set_mode) (struct ata_port *ap);
 
+       int (*cable_detect) (struct ata_port *ap);
+
        int  (*check_atapi_dma) (struct ata_queued_cmd *qc);
 
        void (*bmdma_setup) (struct ata_queued_cmd *qc);
@@ -664,6 +643,7 @@ struct ata_port_info {
        unsigned long           mwdma_mask;
        unsigned long           udma_mask;
        const struct ata_port_operations *port_ops;
+       irq_handler_t           irq_handler;
        void                    *private_data;
 };
 
@@ -686,6 +666,7 @@ extern const unsigned long sata_deb_timing_hotplug[];
 extern const unsigned long sata_deb_timing_long[];
 
 extern const struct ata_port_operations ata_dummy_port_ops;
+extern const struct ata_port_info ata_dummy_port_info;
 
 static inline const unsigned long *
 sata_ehc_deb_timing(struct ata_eh_context *ehc)
@@ -701,6 +682,7 @@ static inline int ata_port_is_dummy(struct ata_port *ap)
        return ap->ops == &ata_dummy_port_ops;
 }
 
+extern void sata_print_link_status(struct ata_port *ap);
 extern void ata_port_probe(struct ata_port *);
 extern void __sata_phy_reset(struct ata_port *ap);
 extern void sata_phy_reset(struct ata_port *ap);
@@ -728,7 +710,15 @@ extern int ata_pci_device_resume(struct pci_dev *pdev);
 #endif
 extern int ata_pci_clear_simplex(struct pci_dev *pdev);
 #endif /* CONFIG_PCI */
-extern int ata_device_add(const struct ata_probe_ent *ent);
+extern struct ata_host *ata_host_alloc(struct device *dev, int max_ports);
+extern struct ata_host *ata_host_alloc_pinfo(struct device *dev,
+                       const struct ata_port_info * const * ppi, int n_ports);
+extern int ata_host_start(struct ata_host *host);
+extern int ata_host_register(struct ata_host *host,
+                            struct scsi_host_template *sht);
+extern int ata_host_activate(struct ata_host *host, int irq,
+                            irq_handler_t irq_handler, unsigned long irq_flags,
+                            struct scsi_host_template *sht);
 extern void ata_host_detach(struct ata_host *host);
 extern void ata_host_init(struct ata_host *, struct device *,
                          unsigned long, const struct ata_port_operations *);
@@ -828,11 +818,17 @@ extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
 extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
                                       int queue_depth);
 extern struct ata_device *ata_dev_pair(struct ata_device *adev);
+extern int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
 extern u8 ata_irq_on(struct ata_port *ap);
 extern u8 ata_dummy_irq_on(struct ata_port *ap);
 extern u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq);
 extern u8 ata_dummy_irq_ack(struct ata_port *ap, unsigned int chk_drq);
 
+extern int ata_cable_40wire(struct ata_port *ap);
+extern int ata_cable_80wire(struct ata_port *ap);
+extern int ata_cable_sata(struct ata_port *ap);
+extern int ata_cable_unknown(struct ata_port *ap);
+
 /*
  * Timing helpers
  */
@@ -870,10 +866,13 @@ struct pci_bits {
        unsigned long           val;
 };
 
-extern struct ata_probe_ent *
-ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int portmask);
+extern int ata_pci_init_native_host(struct ata_host *host,
+                                   unsigned int port_mask);
+extern int ata_pci_prepare_native_host(struct pci_dev *pdev,
+                               const struct ata_port_info * const * ppi,
+                               int n_ports, struct ata_host **r_host);
 extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
-extern unsigned long ata_pci_default_filter(const struct ata_port *, struct ata_device *, unsigned long);
+extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long);
 #endif /* CONFIG_PCI */
 
 /*
@@ -1173,6 +1172,7 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
        qc->n_elem = 0;
        qc->err_mask = 0;
        qc->pad_len = 0;
+       qc->sect_size = ATA_SECT_SIZE;
 
        ata_tf_init(qc->dev, &qc->tf);
 
@@ -1220,7 +1220,7 @@ static inline void ata_pad_free(struct ata_port *ap, struct device *dev)
 
 static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host)
 {
-       return (struct ata_port *) &host->hostdata[0];
+       return *(struct ata_port **)&host->hostdata[0];
 }
 
 #endif /* __LINUX_LIBATA_H__ */
index a3ad76221c6ff23d2e6b3c07d874f37aeac79354..972491089ac9622884a4cfb1a4c6d5861754a6c2 100644 (file)
@@ -838,6 +838,7 @@ void __iomem * pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);
 void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr);
 void __iomem * const * pcim_iomap_table(struct pci_dev *pdev);
 int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name);
+void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask);
 
 extern int pci_pci_problems;
 #define PCIPCI_FAIL            1       /* No PCI PCI DMA */
index 600308fdf9ce31b6ece7efc34dbbc6fe633888e6..5f21b0f68b428263496a91c95f635d856cd5b421 100644 (file)
 #define PCI_DEVICE_ID_ATI_IXP400_SATA   0x4379
 #define PCI_DEVICE_ID_ATI_IXP400_SATA2 0x437a
 #define PCI_DEVICE_ID_ATI_IXP600_SATA  0x4380
-#define PCI_DEVICE_ID_ATI_IXP600_SRAID 0x4381
 #define PCI_DEVICE_ID_ATI_IXP600_SMBUS 0x4385
 #define PCI_DEVICE_ID_ATI_IXP600_IDE   0x438c
 
index bdb55a33f9691e2f79765eeba502d075f71d067c..9bd14fd3e6de5bcb5be171a8d3e8772a3a0cf91a 100644 (file)
@@ -212,27 +212,6 @@ int request_resource(struct resource *root, struct resource *new)
 
 EXPORT_SYMBOL(request_resource);
 
-/**
- * ____request_resource - reserve a resource, with resource conflict returned
- * @root: root resource descriptor
- * @new: resource descriptor desired by caller
- *
- * Returns:
- * On success, NULL is returned.
- * On error, a pointer to the conflicting resource is returned.
- */
-struct resource *____request_resource(struct resource *root, struct resource *new)
-{
-       struct resource *conflict;
-
-       write_lock(&resource_lock);
-       conflict = __request_resource(root, new);
-       write_unlock(&resource_lock);
-       return conflict;
-}
-
-EXPORT_SYMBOL(____request_resource);
-
 /**
  * release_resource - release a previously reserved resource
  * @old: resource pointer
index eb38849aa71702445e7e8e42744ad384fe512f48..b1d336ce7f3d0c34f694844c8bd7dfd0f1dc687d 100644 (file)
@@ -296,5 +296,31 @@ int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name)
        return rc;
 }
 EXPORT_SYMBOL(pcim_iomap_regions);
+
+/**
+ * pcim_iounmap_regions - Unmap and release PCI BARs
+ * @pdev: PCI device to map IO resources for
+ * @mask: Mask of BARs to unmap and release
+ *
+ * Unamp and release regions specified by @mask.
+ */
+void pcim_iounmap_regions(struct pci_dev *pdev, u16 mask)
+{
+       void __iomem * const *iomap;
+       int i;
+
+       iomap = pcim_iomap_table(pdev);
+       if (!iomap)
+               return;
+
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+               if (!(mask & (1 << i)))
+                       continue;
+
+               pcim_iounmap(pdev, iomap[i]);
+               pci_release_region(pdev, i);
+       }
+}
+EXPORT_SYMBOL(pcim_iounmap_regions);
 #endif
 #endif
This page took 0.228487 seconds and 5 git commands to generate.