[PATCH] libata: rework legacy handling to remove much of the cruft
[deliverable/linux.git] / drivers / scsi / libata-bmdma.c
index 9ce221f25954426af69ce124bb11a4beaf0feff2..e694f6075c3bd355986e81b5fefc2d3d919e2968 100644 (file)
@@ -797,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
@@ -880,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]);
@@ -893,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;
 }
@@ -950,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).
  *
@@ -960,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;
@@ -1009,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 */
@@ -1055,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;
        }
@@ -1073,35 +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) {
-               struct device *dev = &pdev->dev;
-               struct ata_host_set *host_set = NULL;
-
-               if (legacy_mode & (1 << 0)) {
-                       ata_device_add(probe_ent);
-                       host_set = dev_get_drvdata(dev);
-               }
-
-               if (legacy_mode & (1 << 1)) {
-                       ata_device_add(probe_ent2);
-                       if (host_set) {
-                               host_set->next = dev_get_drvdata(dev);
-                               dev_set_drvdata(dev, host_set);
-                       }
-               }
-       } 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.02783 seconds and 5 git commands to generate.