Skip to contentSkip to conversation

libata: several fixes against libata-dev#upstream-fixes

PATCH In review Tejun Heo 2 participants 7 messages Aug 4, 2006 – Aug 9, 2006

Subsystems (2)
lore
Share & tools
lore

Tejun Heo

author
#0 lore raw

PATCH 1/1 libata: several fixes against libata-dev#upstream-fixes

Hello, Jeff.

This patchset contains fixes against libata-dev#upstream-fixes[1].

#01    : fix ata_port_detach() dangling SCSI host bug
#02    : fix host_set private_data init bug
#03    : fix double free of host_set->mmio_base

#04-05 : fix ata_device_add() error path

#02, #04-05 are taken from rework-host_set patchset and #01, #03 are new. I left rework-host_set as update to #upstream as it is too much for .18-rcX.

This patchset is available in the following git tree.

http://htj.dyndns.org/git/?p=libata-tj.git;a=shortlog;h=tj-upstream-fixes
git://htj.dyndns.org/libata-tj tj-upstream-fixes

Thanks.

--
tejun

[1] f1d39b291e2263f5e2f2ec5d4061802f76d8ae67

author
#1 lore raw

PATCH 1/5 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.

---

 drivers/scsi/libata-core.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

c3cf30a989efec8144225517e0b2f82c955e3966

drivers/scsi/libata-core.c +2 -1
index 386e5f2..bca92dd 100644
@@ -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);
 }
Signature · 1 line
1.3.2
author
#2 lore raw

PATCH 2/5 ata_piix: fix host_set private_data intialization

In reply to Tejun Heo

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.

---

 drivers/scsi/ata_piix.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

f814b75f4ed2ed58cd7bc876a0a9406f984aac6d

drivers/scsi/ata_piix.c +1 -0
index 19745a3..298e464 100644
@@ -828,6 +828,7 @@ static void __devinit piix_init_sata_map
 		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;
Signature · 1 line
1.3.2
author
#3 lore raw

PATCH 3/5 sata_sil24: don't set probe_ent->mmio_base

In reply to Tejun Heo

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.

---

 drivers/scsi/sata_sil24.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

f31e945c50e47b7163c6018928aa93b66e8f22f0

drivers/scsi/sata_sil24.c +0 -1
index 2e0f4a4..3f368c7 100644
@@ -1106,7 +1106,6 @@ static int sil24_init_one(struct pci_dev
 
 	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;
Signature · 1 line
1.3.2
author
#4 lore raw

PATCH 4/5 manually inline ata_host_remove()

In reply to Tejun Heo

(tj: this is for the following ata_device_add() fix)

---

 drivers/scsi/libata-core.c |   31 ++++++-------------------------
 1 files changed, 6 insertions(+), 25 deletions(-)

6543bc0777fadf129d8ee7ac82e0090fb0480403

drivers/scsi/libata-core.c +6 -25
index bca92dd..509b048 100644
@@ -5185,28 +5185,6 @@ void ata_host_stop (struct ata_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_prob
 
 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 *h
 	DPRINTK("ENTER\n");
 
 	ap->ops->port_disable(ap);
-	ata_host_remove(ap, 0);
+	ap->ops->port_stop(ap);
 
 	DPRINTK("EXIT\n");
 	return 1;
Signature · 1 line
1.3.2
author
#5 lore raw

PATCH 5/5 libata: fix ata_device_add() error path

In reply to Tejun Heo

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 <[email protected]>. The second problem was mentioned and fixed by Jeff Garzik <[email protected]> in a larger cleanup patch.

Cc Dave Jones <[email protected]>
Cc Jeff Garzik <[email protected]>

---

 drivers/scsi/libata-core.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

77f3f879387cc5fce6c7a4ca7777c586fe6291cd

drivers/scsi/libata-core.c +4 -4
index 509b048..16fc2dd 100644
@@ -5511,10 +5511,10 @@ int ata_device_add(const struct ata_prob
 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);
Signature · 1 line
1.3.2
#6 lore raw
In reply to Tejun Heo
Quoted 9 lines · Tejun Heo

Hello, Jeff.

This patchset contains fixes against libata-dev#upstream-fixes[1].

#01    : fix ata_port_detach() dangling SCSI host bug
#02    : fix host_set private_data init bug
#03    : fix double free of host_set->mmio_base

#04-05 : fix ata_device_add() error path

Quoted 8 lines

#02, #04-05 are taken from rework-host_set patchset and #01, #03 are new. I left rework-host_set as update to #upstream as it is too much for .18-rcX.

This patchset is available in the following git tree.

http://htj.dyndns.org/git/?p=libata-tj.git;a=shortlog;h=tj-upstream-fixes
git://htj.dyndns.org/libata-tj tj-upstream-fixes

pulled