From c3cf30a989efec8144225517e0b2f82c955e3966 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 5 Aug 2006 03:59:11 +0900 Subject: [PATCH] libata: fix ata_port_detach() for old EH ports ata_prot_detach() did nothing for old EH ports and thus SCSI hosts associated with those ports are left dangling after they are detached leaving stale devices and causing oops eventually. Make ata_port_detach() remove SCSI hosts for old EH ports. Signed-off-by: Tejun Heo --- drivers/scsi/libata-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 386e5f21e191..bca92dd3a454 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -5558,7 +5558,7 @@ void ata_port_detach(struct ata_port *ap) int i; if (!ap->ops->error_handler) - return; + goto skip_eh; /* tell EH we're leaving & flush EH */ spin_lock_irqsave(ap->lock, flags); @@ -5594,6 +5594,7 @@ void ata_port_detach(struct ata_port *ap) cancel_delayed_work(&ap->hotplug_task); flush_workqueue(ata_aux_wq); + skip_eh: /* remove the associated SCSI host */ scsi_remove_host(ap->host); } -- cgit v1.2.3-59-g8ed1b From f814b75f4ed2ed58cd7bc876a0a9406f984aac6d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 5 Aug 2006 03:59:13 +0900 Subject: [PATCH] ata_piix: fix host_set private_data intialization To get host_set->private_data initialized reliably, all pinfos need to point to the same hpriv. Restore pinfo->private_data after pata pinfo assignment. Signed-off-by: Tejun Heo --- drivers/scsi/ata_piix.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 19745a31072b..298e4643b969 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c @@ -828,6 +828,7 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev, case IDE: WARN_ON((i & 1) || map[i + 1] != IDE); pinfo[i / 2] = piix_port_info[ich5_pata]; + pinfo[i / 2].private_data = hpriv; i++; printk(" IDE IDE"); break; -- cgit v1.2.3-59-g8ed1b From f31e945c50e47b7163c6018928aa93b66e8f22f0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 5 Aug 2006 03:59:15 +0900 Subject: [PATCH] sata_sil24: don't set probe_ent->mmio_base sata_sil24 doesn't make use of probe_ent->mmio_base and setting this field causes the area to be released twice on detach. Don't set probe_ent->mmio_base. Signed-off-by: Tejun Heo --- drivers/scsi/sata_sil24.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index 2e0f4a4076af..3f368c7d3ef9 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c @@ -1106,7 +1106,6 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) probe_ent->irq = pdev->irq; probe_ent->irq_flags = IRQF_SHARED; - probe_ent->mmio_base = port_base; probe_ent->private_data = hpriv; hpriv->host_base = host_base; -- cgit v1.2.3-59-g8ed1b From 6543bc0777fadf129d8ee7ac82e0090fb0480403 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sat, 5 Aug 2006 03:59:17 +0900 Subject: [PATCH] [libata] manually inline ata_host_remove() (tj: this is for the following ata_device_add() fix) Signed-off-by: Jeff Garzik Signed-off-by: Tejun Heo --- drivers/scsi/libata-core.c | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index bca92dd3a454..509b04889983 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -5185,28 +5185,6 @@ void ata_host_stop (struct ata_host_set *host_set) iounmap(host_set->mmio_base); } - -/** - * ata_host_remove - Unregister SCSI host structure with upper layers - * @ap: Port to unregister - * @do_unregister: 1 if we fully unregister, 0 to just stop the port - * - * LOCKING: - * Inherited from caller. - */ - -static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister) -{ - struct Scsi_Host *sh = ap->host; - - DPRINTK("ENTER\n"); - - if (do_unregister) - scsi_remove_host(sh); - - ap->ops->port_stop(ap); -} - /** * ata_dev_init - Initialize an ata_device structure * @dev: Device structure to initialize @@ -5532,8 +5510,11 @@ int ata_device_add(const struct ata_probe_ent *ent) err_out: for (i = 0; i < count; i++) { - ata_host_remove(host_set->ports[i], 1); - scsi_host_put(host_set->ports[i]->host); + struct ata_port *ap = host_set->ports[i]; + + scsi_remove_host(ap->host); + ap->ops->port_stop(ap); + scsi_host_put(ap->host); } err_free_ret: kfree(host_set); @@ -5663,7 +5644,7 @@ int ata_scsi_release(struct Scsi_Host *host) DPRINTK("ENTER\n"); ap->ops->port_disable(ap); - ata_host_remove(ap, 0); + ap->ops->port_stop(ap); DPRINTK("EXIT\n"); return 1; -- cgit v1.2.3-59-g8ed1b From 77f3f879387cc5fce6c7a4ca7777c586fe6291cd Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 5 Aug 2006 03:59:19 +0900 Subject: [PATCH] libata: fix ata_device_add() error path In the error path, ata_device_add() * dereferences null host_set->ports[] element. * calls scsi_remove_host() on not-yet-added shost. This patch fixes both bugs. The first problem was spotted and initial patch submitted by Dave Jones . The second problem was mentioned and fixed by Jeff Garzik in a larger cleanup patch. Cc: Dave Jones Cc: Jeff Garzik Signed-off-by: Tejun Heo --- drivers/scsi/libata-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 509b04889983..16fc2dd8f2f7 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -5511,10 +5511,10 @@ int ata_device_add(const struct ata_probe_ent *ent) err_out: for (i = 0; i < count; i++) { struct ata_port *ap = host_set->ports[i]; - - scsi_remove_host(ap->host); - ap->ops->port_stop(ap); - scsi_host_put(ap->host); + if (ap) { + ap->ops->port_stop(ap); + scsi_host_put(ap->host); + } } err_free_ret: kfree(host_set); -- cgit v1.2.3-59-g8ed1b