[PATCH] libata: rework legacy handling to remove much of the cruft
[deliverable/linux.git] / drivers / scsi / libata-bmdma.c
index 6d30d2c52960235be0c5152303fc3590a5080bf4..e694f6075c3bd355986e81b5fefc2d3d919e2968 100644 (file)
@@ -32,7 +32,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/libata.h>
@@ -695,6 +694,7 @@ void ata_bmdma_thaw(struct ata_port *ap)
 /**
  *     ata_bmdma_drive_eh - Perform EH with given methods for BMDMA controller
  *     @ap: port to handle error for
+ *     @prereset: prereset method (can be NULL)
  *     @softreset: softreset method (can be NULL)
  *     @hardreset: hardreset method (can be NULL)
  *     @postreset: postreset method (can be NULL)
@@ -710,10 +710,10 @@ void ata_bmdma_thaw(struct ata_port *ap)
  *     LOCKING:
  *     Kernel thread context (may sleep)
  */
-void ata_bmdma_drive_eh(struct ata_port *ap, ata_reset_fn_t softreset,
-                       ata_reset_fn_t hardreset, ata_postreset_fn_t postreset)
+void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
+                       ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
+                       ata_postreset_fn_t postreset)
 {
-       struct ata_host_set *host_set = ap->host_set;
        struct ata_eh_context *ehc = &ap->eh_context;
        struct ata_queued_cmd *qc;
        unsigned long flags;
@@ -724,7 +724,7 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_reset_fn_t softreset,
                qc = NULL;
 
        /* reset PIO HSM and stop DMA engine */
-       spin_lock_irqsave(&host_set->lock, flags);
+       spin_lock_irqsave(ap->lock, flags);
 
        ap->hsm_task_state = HSM_ST_IDLE;
 
@@ -753,13 +753,13 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_reset_fn_t softreset,
        ata_chk_status(ap);
        ap->ops->irq_clear(ap);
 
-       spin_unlock_irqrestore(&host_set->lock, flags);
+       spin_unlock_irqrestore(ap->lock, flags);
 
        if (thaw)
                ata_eh_thaw_port(ap);
 
        /* PIO and DMA engines have been stopped, perform recovery */
-       ata_do_eh(ap, softreset, hardreset, postreset);
+       ata_do_eh(ap, prereset, softreset, hardreset, postreset);
 }
 
 /**
@@ -779,7 +779,8 @@ void ata_bmdma_error_handler(struct ata_port *ap)
        if (sata_scr_valid(ap))
                hardreset = sata_std_hardreset;
 
-       ata_bmdma_drive_eh(ap, ata_std_softreset, hardreset, ata_std_postreset);
+       ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, hardreset,
+                          ata_std_postreset);
 }
 
 /**
@@ -796,32 +797,6 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
 }
 
 #ifdef CONFIG_PCI
-static 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 = kzalloc(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->host_flags = port->host_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;
-
-       return probe_ent;
-}
-
-
 /**
  *     ata_pci_init_native_mode - Initialize native-mode driver
  *     @pdev:  pci device to be initialized
@@ -852,7 +827,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
                return NULL;
 
        probe_ent->irq = pdev->irq;
-       probe_ent->irq_flags = SA_SHIRQ;
+       probe_ent->irq_flags = IRQF_SHARED;
        probe_ent->private_data = port[0]->private_data;
 
        if (ports & ATA_PORT_PRIMARY) {
@@ -879,7 +854,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
                if (bmdma) {
                        bmdma += 8;
                        if(inb(bmdma + 2) & 0x80)
-                       probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
+                               probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
                        probe_ent->port[p].bmdma_addr = bmdma;
                }
                ata_std_ports(&probe_ent->port[p]);
@@ -892,44 +867,55 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int
 
 
 static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
-                               struct ata_port_info *port, int port_num)
+                               struct ata_port_info **port, int port_mask)
 {
        struct ata_probe_ent *probe_ent;
-       unsigned long bmdma;
+       unsigned long bmdma = pci_resource_start(pdev, 4);
+
+       int port_num = 0;
 
-       probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
+       probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]);
        if (!probe_ent)
                return NULL;
 
        probe_ent->legacy_mode = 1;
-       probe_ent->n_ports = 1;
-       probe_ent->hard_port_no = port_num;
-       probe_ent->private_data = port->private_data;
-
-       switch(port_num)
-       {
-               case 0:
-                       probe_ent->irq = 14;
-                       probe_ent->port[0].cmd_addr = 0x1f0;
-                       probe_ent->port[0].altstatus_addr =
-                       probe_ent->port[0].ctl_addr = 0x3f6;
-                       break;
-               case 1:
+       probe_ent->hard_port_no = 0;
+       probe_ent->private_data = port[0]->private_data;
+
+       if (port_mask & ATA_PORT_PRIMARY) {
+               probe_ent->irq = 14;
+               probe_ent->port[port_num].cmd_addr = ATA_PRIMARY_CMD;
+               probe_ent->port[port_num].altstatus_addr =
+               probe_ent->port[port_num].ctl_addr = ATA_PRIMARY_CTL;
+               if (bmdma) {
+                       probe_ent->port[0].bmdma_addr = bmdma;
+                       if (inb(bmdma + 2) & 0x80)
+                               probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
+               }
+               ata_std_ports(&probe_ent->port[port_num]);
+               port_num ++;
+       }
+       if (port_mask & ATA_PORT_SECONDARY) {
+               if (port_num == 1)
+                       probe_ent->irq2 = 15;
+               else {
+                       /* Secondary only. IRQ 15 only and "first" port is port 1 */
                        probe_ent->irq = 15;
-                       probe_ent->port[0].cmd_addr = 0x170;
-                       probe_ent->port[0].altstatus_addr =
-                       probe_ent->port[0].ctl_addr = 0x376;
-                       break;
+                       probe_ent->hard_port_no = 1;
+               }
+               probe_ent->port[port_num].cmd_addr = ATA_SECONDARY_CMD;
+               probe_ent->port[port_num].altstatus_addr =
+               probe_ent->port[port_num].ctl_addr = ATA_SECONDARY_CTL;
+               if (bmdma) {
+                       probe_ent->port[port_num].bmdma_addr = bmdma + 8;
+                       if (inb(bmdma + 10) & 0x80)
+                               probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
+               }
+               ata_std_ports(&probe_ent->port[port_num]);
+               port_num ++;
        }
 
-       bmdma = pci_resource_start(pdev, 4);
-       if (bmdma != 0) {
-               bmdma += 8 * port_num;
-               probe_ent->port[0].bmdma_addr = bmdma;
-               if (inb(bmdma + 2) & 0x80)
-                       probe_ent->host_set_flags |= ATA_HOST_SIMPLEX;
-       }
-       ata_std_ports(&probe_ent->port[0]);
+       probe_ent->n_ports = port_num;
 
        return probe_ent;
 }
@@ -949,6 +935,10 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
  *     regions, sets the dma mask, enables bus master mode, and calls
  *     ata_device_add()
  *
+ *     ASSUMPTION:
+ *     Nobody makes a single channel controller that appears solely as
+ *     the secondary legacy port on PCI.
+ *
  *     LOCKING:
  *     Inherited from PCI layer (may sleep).
  *
@@ -959,7 +949,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
 int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                      unsigned int n_ports)
 {
-       struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL;
+       struct ata_probe_ent *probe_ent = NULL;
        struct ata_port_info *port[2];
        u8 tmp8, mask;
        unsigned int legacy_mode = 0;
@@ -1008,35 +998,34 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                goto err_out;
        }
 
-       /* FIXME: Should use platform specific mappers for legacy port ranges */
        if (legacy_mode) {
-               if (!request_region(0x1f0, 8, "libata")) {
+               if (!request_region(ATA_PRIMARY_CMD, 8, "libata")) {
                        struct resource *conflict, res;
-                       res.start = 0x1f0;
-                       res.end = 0x1f0 + 8 - 1;
+                       res.start = ATA_PRIMARY_CMD;
+                       res.end = ATA_PRIMARY_CMD + 8 - 1;
                        conflict = ____request_resource(&ioport_resource, &res);
                        if (!strcmp(conflict->name, "libata"))
-                               legacy_mode |= (1 << 0);
+                               legacy_mode |= ATA_PORT_PRIMARY;
                        else {
                                disable_dev_on_err = 0;
-                               printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n");
+                               printk(KERN_WARNING "ata: 0x%0X IDE port busy\n", ATA_PRIMARY_CMD);
                        }
                } else
-                       legacy_mode |= (1 << 0);
+                       legacy_mode |= ATA_PORT_PRIMARY;
 
-               if (!request_region(0x170, 8, "libata")) {
+               if (!request_region(ATA_SECONDARY_CMD, 8, "libata")) {
                        struct resource *conflict, res;
-                       res.start = 0x170;
-                       res.end = 0x170 + 8 - 1;
+                       res.start = ATA_SECONDARY_CMD;
+                       res.end = ATA_SECONDARY_CMD + 8 - 1;
                        conflict = ____request_resource(&ioport_resource, &res);
                        if (!strcmp(conflict->name, "libata"))
-                               legacy_mode |= (1 << 1);
+                               legacy_mode |= ATA_PORT_SECONDARY;
                        else {
                                disable_dev_on_err = 0;
-                               printk(KERN_WARNING "ata: 0x170 IDE port busy\n");
+                               printk(KERN_WARNING "ata: 0x%X IDE port busy\n", ATA_SECONDARY_CMD);
                        }
                } else
-                       legacy_mode |= (1 << 1);
+                       legacy_mode |= ATA_PORT_SECONDARY;
        }
 
        /* we have legacy mode, but all ports are unavailable */
@@ -1054,17 +1043,14 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
                goto err_out_regions;
 
        if (legacy_mode) {
-               if (legacy_mode & (1 << 0))
-                       probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0);
-               if (legacy_mode & (1 << 1))
-                       probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1);
+               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 (!probe_ent && !probe_ent2) {
+       if (!probe_ent) {
                rc = -ENOMEM;
                goto err_out_regions;
        }
@@ -1072,24 +1058,17 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
        pci_set_master(pdev);
 
        /* FIXME: check ata_device_add return */
-       if (legacy_mode) {
-               if (legacy_mode & (1 << 0))
-                       ata_device_add(probe_ent);
-               if (legacy_mode & (1 << 1))
-                       ata_device_add(probe_ent2);
-       } else
-               ata_device_add(probe_ent);
+       ata_device_add(probe_ent);
 
        kfree(probe_ent);
-       kfree(probe_ent2);
 
        return 0;
 
 err_out_regions:
-       if (legacy_mode & (1 << 0))
-               release_region(0x1f0, 8);
-       if (legacy_mode & (1 << 1))
-               release_region(0x170, 8);
+       if (legacy_mode & ATA_PORT_PRIMARY)
+               release_region(ATA_PRIMARY_CMD, 8);
+       if (legacy_mode & ATA_PORT_SECONDARY)
+               release_region(ATA_SECONDARY_CMD, 8);
        pci_release_regions(pdev);
 err_out:
        if (disable_dev_on_err)
This page took 0.030549 seconds and 5 git commands to generate.