Jeff,

This looked prime to cut since ahci_remove_one() was a functionally
identical to ata_pci_remove_one() except for the interrupt disable
(have_msi) bits, which fit nicely into ahci_host_stop().  However,

1) Will it work?

2) Isn't it wrong for the IRQ disable at the chip to occur *after*
free_irq() is called to disconnect the handler (independent of
question 1...since this is the case currently)?  Granted, all of the
ports have gone through scsi_remove_host() but theoretically there
still is a possibility the chip could interrupt.

If I'm wrong on both counts I'll blame it on need for sleep... :-)
BR

This patch depends on the PCI INTx patch (but will probably work w/o):
http://lkml.org/lkml/2005/8/15/165


Signed-off-by: Brett Russ <[EMAIL PROTECTED]>


Index: linux-2.6.13/drivers/scsi/ahci.c
===================================================================
--- linux-2.6.13.orig/drivers/scsi/ahci.c
+++ linux-2.6.13/drivers/scsi/ahci.c
@@ -187,7 +187,6 @@ static void ahci_qc_prep(struct ata_queu
 static u8 ahci_check_status(struct ata_port *ap);
 static u8 ahci_check_err(struct ata_port *ap);
 static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd 
*qc);
-static void ahci_remove_one (struct pci_dev *pdev);
 
 static Scsi_Host_Template ahci_sht = {
        .module                 = THIS_MODULE,
@@ -277,7 +276,7 @@ static struct pci_driver ahci_pci_driver
        .name                   = DRV_NAME,
        .id_table               = ahci_pci_tbl,
        .probe                  = ahci_init_one,
-       .remove                 = ahci_remove_one,
+       .remove                 = ata_pci_remove_one,
 };
 
 
@@ -294,6 +293,13 @@ static inline void *ahci_port_base (void
 static void ahci_host_stop(struct ata_host_set *host_set)
 {
        struct ahci_host_priv *hpriv = host_set->private_data;
+       struct pci_dev *pdev = to_pci_dev(host_set->dev);
+
+       if (hpriv->flags & AHCI_FLAG_MSI)
+               pci_disable_msi(pdev);
+       else
+               pci_intx(pdev, 0);
+
        kfree(hpriv);
 
        ata_host_stop(host_set);
@@ -1036,43 +1042,6 @@ err_out:
        return rc;
 }
 
-static void ahci_remove_one (struct pci_dev *pdev)
-{
-       struct device *dev = pci_dev_to_dev(pdev);
-       struct ata_host_set *host_set = dev_get_drvdata(dev);
-       struct ahci_host_priv *hpriv = host_set->private_data;
-       struct ata_port *ap;
-       unsigned int i;
-       int have_msi;
-
-       for (i = 0; i < host_set->n_ports; i++) {
-               ap = host_set->ports[i];
-
-               scsi_remove_host(ap->host);
-       }
-
-       have_msi = hpriv->flags & AHCI_FLAG_MSI;
-       free_irq(host_set->irq, host_set);
-
-       for (i = 0; i < host_set->n_ports; i++) {
-               ap = host_set->ports[i];
-
-               ata_scsi_release(ap->host);
-               scsi_host_put(ap->host);
-       }
-
-       host_set->ops->host_stop(host_set);
-       kfree(host_set);
-
-       if (have_msi)
-               pci_disable_msi(pdev);
-       else
-               pci_intx(pdev, 0);
-       pci_release_regions(pdev);
-       pci_disable_device(pdev);
-       dev_set_drvdata(dev, NULL);
-}
-
 static int __init ahci_init(void)
 {
        return pci_module_init(&ahci_pci_driver);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to