linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] libata: add host_set->next for legacy two host sets case
@ 2006-06-12  5:17 Tejun Heo
  2006-06-12  6:55 ` Jeff Garzik
  0 siblings, 1 reply; 13+ messages in thread
From: Tejun Heo @ 2006-06-12  5:17 UTC (permalink / raw)
  To: Jeff Garzik, linux-ide, Albert Lee

For a legacy ATA controller, libata registers two separate host sets.
There was no connection between the two hosts making it impossible to
traverse all ports related to the controller.  This patch adds
host_set->next which points to the second host_set and implements
ata_host_set_for_all_ports() which traverses all ports associated with
the controller.  This fixes the following bugs.

* On device removal, all ports hanging off the device are properly
  detached.  Prior to this patch, ports on the first host_set weren't
  detached casuing oops on driver unloading.

* On device removal, both host sets are freed

This will also be used by new power management code to suspend and
resume all ports of a controller.  host_set/port representation will
be improved to handle legacy controllers better and this host_set
linking hack will go away with it.

Signed-off-by: Tejun Heo <htejun@gmail.com>

---

 drivers/scsi/libata-bmdma.c |   15 +++++++++++++--
 drivers/scsi/libata-core.c  |   39 +++++++++++++++++++++++++++++++++------
 include/linux/libata.h      |    3 ++-
 3 files changed, 48 insertions(+), 9 deletions(-)

b1d1062e1b5b1de896b687118ed9a1926fd6f3b0
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
index 4bc0537..13fab97 100644
--- a/drivers/scsi/libata-bmdma.c
+++ b/drivers/scsi/libata-bmdma.c
@@ -1076,10 +1076,21 @@ int ata_pci_init_one (struct pci_dev *pd
 
 	/* FIXME: check ata_device_add return */
 	if (legacy_mode) {
-		if (legacy_mode & (1 << 0))
+		struct device *dev = &pdev->dev;
+		struct ata_host_set *host_set = NULL;
+
+		if (legacy_mode & (1 << 0)) {
 			ata_device_add(probe_ent);
-		if (legacy_mode & (1 << 1))
+			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);
 
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 014855e..357f253 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -94,6 +94,32 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
 
+static struct ata_port *__ata_host_set_next_port(struct ata_port *ap,
+						 int *p_idx,
+						 struct ata_host_set *host_set)
+{
+	int idx = ++(*p_idx);
+
+	if (idx >= host_set->n_ports && host_set->next) {
+		idx -= host_set->n_ports;
+		host_set = host_set->next;
+	}
+
+	if (idx < host_set->n_ports)
+		return host_set->ports[idx];
+
+	return NULL;
+}
+
+/* No, it's not for_each_port.  The following macro traverses not only
+ * host_set->ports but also host_set->next->ports.  Don't use it
+ * unless you know what you're doing.  It will go away once legacy
+ * host handling is improved.
+ */
+#define ata_host_set_for_all_ports(ap, idx, host_set) \
+	for (ap = host_set->ports[0], idx = 0; ap; \
+	     ap = __ata_host_set_next_port(ap, &idx, host_set))
+
 /**
  *	ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
  *	@tf: Taskfile to convert
@@ -5510,16 +5536,15 @@ void ata_port_detach(struct ata_port *ap
 
 void ata_host_set_remove(struct ata_host_set *host_set)
 {
-	unsigned int i;
+	struct ata_port *ap;
+	int i;
 
-	for (i = 0; i < host_set->n_ports; i++)
-		ata_port_detach(host_set->ports[i]);
+	ata_host_set_for_all_ports(ap, i, host_set)
+		ata_port_detach(ap);
 
 	free_irq(host_set->irq, host_set);
 
-	for (i = 0; i < host_set->n_ports; i++) {
-		struct ata_port *ap = host_set->ports[i];
-
+	ata_host_set_for_all_ports(ap, i, host_set) {
 		ata_scsi_release(ap->host);
 
 		if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
@@ -5537,6 +5562,8 @@ void ata_host_set_remove(struct ata_host
 	if (host_set->ops->host_stop)
 		host_set->ops->host_stop(host_set);
 
+	if (host_set->next)
+		kfree(host_set->next);
 	kfree(host_set);
 }
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 61eea57..f03b866 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -356,7 +356,8 @@ struct ata_host_set {
 	unsigned long		flags;
 	int			simplex_claimed;	/* Keep seperate in case we
 							   ever need to do this locked */
-	struct ata_port *	ports[0];
+	struct ata_host_set	*next;		/* for legacy mode */
+	struct ata_port		*ports[0];
 };
 
 struct ata_queued_cmd {
-- 
1.3.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] libata: add host_set->next for legacy two host sets case
  2006-06-12  5:17 [PATCH] libata: add host_set->next for legacy two host sets case Tejun Heo
@ 2006-06-12  6:55 ` Jeff Garzik
  2006-06-12  7:06   ` Tejun Heo
  2006-06-12 10:14   ` [PATCH] libata: add host_set->next for legacy two host_sets case, take #2 Tejun Heo
  0 siblings, 2 replies; 13+ messages in thread
From: Jeff Garzik @ 2006-06-12  6:55 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-ide, Albert Lee

Tejun Heo wrote:
> For a legacy ATA controller, libata registers two separate host sets.
> There was no connection between the two hosts making it impossible to
> traverse all ports related to the controller.  This patch adds
> host_set->next which points to the second host_set and implements
> ata_host_set_for_all_ports() which traverses all ports associated with
> the controller.  This fixes the following bugs.
> 
> * On device removal, all ports hanging off the device are properly
>   detached.  Prior to this patch, ports on the first host_set weren't
>   detached casuing oops on driver unloading.
> 
> * On device removal, both host sets are freed
> 
> This will also be used by new power management code to suspend and
> resume all ports of a controller.  host_set/port representation will
> be improved to handle legacy controllers better and this host_set
> linking hack will go away with it.
> 
> Signed-off-by: Tejun Heo <htejun@gmail.com>

NAK.  You don't want to iterate through multiple host sets, _inside_ of 
function ata_host_set_remove().  ata_host_set_remove() is called with a 
single host_set, and is designed to remove only a single host set.

The concept of a host_set list is OK, but I would rather that 
ata_pci_remove_one() be updated to something like

	host_set = get-drvdata(...)

	while (host_set)
		tmp = host_set
		host_set = host_set->next
		ata_host_set_remove(tmp)


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] libata: add host_set->next for legacy two host sets case
  2006-06-12  6:55 ` Jeff Garzik
@ 2006-06-12  7:06   ` Tejun Heo
  2006-06-12 10:14   ` [PATCH] libata: add host_set->next for legacy two host_sets case, take #2 Tejun Heo
  1 sibling, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-06-12  7:06 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-ide, Albert Lee

Jeff Garzik wrote:
> Tejun Heo wrote:
>> For a legacy ATA controller, libata registers two separate host sets.
>> There was no connection between the two hosts making it impossible to
>> traverse all ports related to the controller.  This patch adds
>> host_set->next which points to the second host_set and implements
>> ata_host_set_for_all_ports() which traverses all ports associated with
>> the controller.  This fixes the following bugs.
>>
>> * On device removal, all ports hanging off the device are properly
>>   detached.  Prior to this patch, ports on the first host_set weren't
>>   detached casuing oops on driver unloading.
>>
>> * On device removal, both host sets are freed
>>
>> This will also be used by new power management code to suspend and
>> resume all ports of a controller.  host_set/port representation will
>> be improved to handle legacy controllers better and this host_set
>> linking hack will go away with it.
>>
>> Signed-off-by: Tejun Heo <htejun@gmail.com>
> 
> NAK.  You don't want to iterate through multiple host sets, _inside_ of 
> function ata_host_set_remove().  ata_host_set_remove() is called with a 
> single host_set, and is designed to remove only a single host set.
> 
> The concept of a host_set list is OK, but I would rather that 
> ata_pci_remove_one() be updated to something like
> 
>     host_set = get-drvdata(...)
> 
>     while (host_set)
>         tmp = host_set
>         host_set = host_set->next
>         ata_host_set_remove(tmp)

I wanted to hide the second host_set behind the first one as there will 
be only one host_set in the future.  But, okay, will update as you said. 
  That should be less confusing.

-- 
tejun

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] libata: add host_set->next for legacy two host_sets case, take #2
  2006-06-12  6:55 ` Jeff Garzik
  2006-06-12  7:06   ` Tejun Heo
@ 2006-06-12 10:14   ` Tejun Heo
  2006-06-12 13:35     ` Jeff Garzik
  1 sibling, 1 reply; 13+ messages in thread
From: Tejun Heo @ 2006-06-12 10:14 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-ide, Albert Lee

For a legacy ATA controller, libata registers two separate host sets.
There was no connection between the two hosts making it impossible to
traverse all ports related to the controller.  This patch adds
host_set->next which points to the second host_set and makes
ata_host_set_remove() remove all associated host_sets and ports.

* On device removal, all ports hanging off the device are properly
  detached.  Prior to this patch, ports on the first host_set weren't
  detached casuing oops on driver unloading.

* On device removal, both host_sets are properly freed

This will also be used by new power management code to suspend and
resume all ports of a controller.  host_set/port representation will
be improved to handle legacy controllers better and this host_set
linking will go away with it.

Signed-off-by: Tejun Heo <htejun@gmail.com>

---

 drivers/scsi/libata-bmdma.c |   15 +++++++++++++--
 drivers/scsi/libata-core.c  |   44 +++++++++++++++++++++++--------------------
 include/linux/libata.h      |    3 ++-
 3 files changed, 39 insertions(+), 23 deletions(-)

b53ff57b968b2b6f07ae091d0d7d29f1e422fb3a
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
index 4bc0537..13fab97 100644
--- a/drivers/scsi/libata-bmdma.c
+++ b/drivers/scsi/libata-bmdma.c
@@ -1076,10 +1076,21 @@ int ata_pci_init_one (struct pci_dev *pd
 
 	/* FIXME: check ata_device_add return */
 	if (legacy_mode) {
-		if (legacy_mode & (1 << 0))
+		struct device *dev = &pdev->dev;
+		struct ata_host_set *host_set = NULL;
+
+		if (legacy_mode & (1 << 0)) {
 			ata_device_add(probe_ent);
-		if (legacy_mode & (1 << 1))
+			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);
 
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 014855e..43f88ef 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5507,37 +5507,41 @@ void ata_port_detach(struct ata_port *ap
  *	LOCKING:
  *	Inherited from calling layer (may sleep).
  */
-
 void ata_host_set_remove(struct ata_host_set *host_set)
 {
-	unsigned int i;
+	while (host_set) {
+		struct ata_host_set *next;
+		unsigned int i;
 
-	for (i = 0; i < host_set->n_ports; i++)
-		ata_port_detach(host_set->ports[i]);
+		for (i = 0; i < host_set->n_ports; i++)
+			ata_port_detach(host_set->ports[i]);
 
-	free_irq(host_set->irq, host_set);
+		free_irq(host_set->irq, host_set);
 
-	for (i = 0; i < host_set->n_ports; i++) {
-		struct ata_port *ap = host_set->ports[i];
+		for (i = 0; i < host_set->n_ports; i++) {
+			struct ata_port *ap = host_set->ports[i];
 
-		ata_scsi_release(ap->host);
+			ata_scsi_release(ap->host);
 
-		if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
-			struct ata_ioports *ioaddr = &ap->ioaddr;
+			if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
+				struct ata_ioports *ioaddr = &ap->ioaddr;
 
-			if (ioaddr->cmd_addr == 0x1f0)
-				release_region(0x1f0, 8);
-			else if (ioaddr->cmd_addr == 0x170)
-				release_region(0x170, 8);
-		}
+				if (ioaddr->cmd_addr == 0x1f0)
+					release_region(0x1f0, 8);
+				else if (ioaddr->cmd_addr == 0x170)
+					release_region(0x170, 8);
+			}
 
-		scsi_host_put(ap->host);
-	}
+			scsi_host_put(ap->host);
+		}
 
-	if (host_set->ops->host_stop)
-		host_set->ops->host_stop(host_set);
+		if (host_set->ops->host_stop)
+			host_set->ops->host_stop(host_set);
 
-	kfree(host_set);
+		next = host_set->next;
+		kfree(host_set);
+		host_set = next;
+	}
 }
 
 /**
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 61eea57..f03b866 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -356,7 +356,8 @@ struct ata_host_set {
 	unsigned long		flags;
 	int			simplex_claimed;	/* Keep seperate in case we
 							   ever need to do this locked */
-	struct ata_port *	ports[0];
+	struct ata_host_set	*next;		/* for legacy mode */
+	struct ata_port		*ports[0];
 };
 
 struct ata_queued_cmd {
-- 
1.3.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] libata: add host_set->next for legacy two host_sets case, take #2
  2006-06-12 10:14   ` [PATCH] libata: add host_set->next for legacy two host_sets case, take #2 Tejun Heo
@ 2006-06-12 13:35     ` Jeff Garzik
  2006-06-12 13:44       ` Tejun Heo
  2006-06-12 14:05       ` [PATCH] libata: add host_set->next for legacy two host_sets case, take #3 Tejun Heo
  0 siblings, 2 replies; 13+ messages in thread
From: Jeff Garzik @ 2006-06-12 13:35 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-ide, Albert Lee

Tejun Heo wrote:
> For a legacy ATA controller, libata registers two separate host sets.
> There was no connection between the two hosts making it impossible to
> traverse all ports related to the controller.  This patch adds
> host_set->next which points to the second host_set and makes
> ata_host_set_remove() remove all associated host_sets and ports.
> 
> * On device removal, all ports hanging off the device are properly
>   detached.  Prior to this patch, ports on the first host_set weren't
>   detached casuing oops on driver unloading.
> 
> * On device removal, both host_sets are properly freed
> 
> This will also be used by new power management code to suspend and
> resume all ports of a controller.  host_set/port representation will
> be improved to handle legacy controllers better and this host_set
> linking will go away with it.
> 
> Signed-off-by: Tejun Heo <htejun@gmail.com>

Same objection as before:  ata_host_set_remove() should only remove 
_one_ host_set.  Therefore, that function is ignorant of the linked 
list, and the caller is the one that is forced to manage the list.

	Jeff




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] libata: add host_set->next for legacy two host_sets case, take #2
  2006-06-12 13:35     ` Jeff Garzik
@ 2006-06-12 13:44       ` Tejun Heo
  2006-06-12 14:05       ` [PATCH] libata: add host_set->next for legacy two host_sets case, take #3 Tejun Heo
  1 sibling, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-06-12 13:44 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-ide, Albert Lee

Jeff Garzik wrote:
> Tejun Heo wrote:
>> For a legacy ATA controller, libata registers two separate host sets.
>> There was no connection between the two hosts making it impossible to
>> traverse all ports related to the controller.  This patch adds
>> host_set->next which points to the second host_set and makes
>> ata_host_set_remove() remove all associated host_sets and ports.
>>
>> * On device removal, all ports hanging off the device are properly
>>   detached.  Prior to this patch, ports on the first host_set weren't
>>   detached casuing oops on driver unloading.
>>
>> * On device removal, both host_sets are properly freed
>>
>> This will also be used by new power management code to suspend and
>> resume all ports of a controller.  host_set/port representation will
>> be improved to handle legacy controllers better and this host_set
>> linking will go away with it.
>>
>> Signed-off-by: Tejun Heo <htejun@gmail.com>
> 
> Same objection as before:  ata_host_set_remove() should only remove 
> _one_ host_set.  Therefore, that function is ignorant of the linked 
> list, and the caller is the one that is forced to manage the list.

Duh... I must be smoking something.  I thought I moved that loop out of 
that function.  :-(  Will submit again.

-- 
tejun

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] libata: add host_set->next for legacy two host_sets case, take #3
  2006-06-12 13:35     ` Jeff Garzik
  2006-06-12 13:44       ` Tejun Heo
@ 2006-06-12 14:05       ` Tejun Heo
  2006-06-12 14:24         ` Jeff Garzik
  2006-06-28 10:27         ` Albert Lee
  1 sibling, 2 replies; 13+ messages in thread
From: Tejun Heo @ 2006-06-12 14:05 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-ide, Albert Lee

For a legacy ATA controller, libata registers two separate host sets.
There was no connection between the two hosts making it impossible to
traverse all ports related to the controller.  This patch adds
host_set->next which points to the second host_set and makes
ata_pci_remove_one() remove all associated host_sets.

* On device removal, all ports hanging off the device are properly
  detached.  Prior to this patch, ports on the first host_set weren't
  detached casuing oops on driver unloading.

* On device removal, both host_sets are properly freed

This will also be used by new power management code to suspend and
resume all ports of a controller.  host_set/port representation will
be improved to handle legacy controllers better and this host_set
linking will go away with it.

Signed-off-by: Tejun Heo <htejun@gmail.com>

---

 drivers/scsi/libata-bmdma.c |   15 +++++++++++++--
 drivers/scsi/libata-core.c  |    4 ++++
 include/linux/libata.h      |    3 ++-
 3 files changed, 19 insertions(+), 3 deletions(-)

d785d4a8e1eb5210dc351585610244567a0d5d70
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
index 4bc0537..13fab97 100644
--- a/drivers/scsi/libata-bmdma.c
+++ b/drivers/scsi/libata-bmdma.c
@@ -1076,10 +1076,21 @@ int ata_pci_init_one (struct pci_dev *pd
 
 	/* FIXME: check ata_device_add return */
 	if (legacy_mode) {
-		if (legacy_mode & (1 << 0))
+		struct device *dev = &pdev->dev;
+		struct ata_host_set *host_set = NULL;
+
+		if (legacy_mode & (1 << 0)) {
 			ata_device_add(probe_ent);
-		if (legacy_mode & (1 << 1))
+			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);
 
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 014855e..d73cb36 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5621,8 +5621,12 @@ void ata_pci_remove_one (struct pci_dev 
 {
 	struct device *dev = pci_dev_to_dev(pdev);
 	struct ata_host_set *host_set = dev_get_drvdata(dev);
+	struct ata_host_set *host_set2 = host_set->next;
 
 	ata_host_set_remove(host_set);
+	if (host_set2)
+		ata_host_set_remove(host_set2);
+
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	dev_set_drvdata(dev, NULL);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 61eea57..f03b866 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -356,7 +356,8 @@ struct ata_host_set {
 	unsigned long		flags;
 	int			simplex_claimed;	/* Keep seperate in case we
 							   ever need to do this locked */
-	struct ata_port *	ports[0];
+	struct ata_host_set	*next;		/* for legacy mode */
+	struct ata_port		*ports[0];
 };
 
 struct ata_queued_cmd {
-- 
1.3.2


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] libata: add host_set->next for legacy two host_sets case, take #3
  2006-06-12 14:05       ` [PATCH] libata: add host_set->next for legacy two host_sets case, take #3 Tejun Heo
@ 2006-06-12 14:24         ` Jeff Garzik
  2006-06-28 10:27         ` Albert Lee
  1 sibling, 0 replies; 13+ messages in thread
From: Jeff Garzik @ 2006-06-12 14:24 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-ide, Albert Lee

Tejun Heo wrote:
> For a legacy ATA controller, libata registers two separate host sets.
> There was no connection between the two hosts making it impossible to
> traverse all ports related to the controller.  This patch adds
> host_set->next which points to the second host_set and makes
> ata_pci_remove_one() remove all associated host_sets.
> 
> * On device removal, all ports hanging off the device are properly
>   detached.  Prior to this patch, ports on the first host_set weren't
>   detached casuing oops on driver unloading.
> 
> * On device removal, both host_sets are properly freed
> 
> This will also be used by new power management code to suspend and
> resume all ports of a controller.  host_set/port representation will
> be improved to handle legacy controllers better and this host_set
> linking will go away with it.
> 
> Signed-off-by: Tejun Heo <htejun@gmail.com>

applied



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] libata: add host_set->next for legacy two host_sets case, take #3
  2006-06-12 14:05       ` [PATCH] libata: add host_set->next for legacy two host_sets case, take #3 Tejun Heo
  2006-06-12 14:24         ` Jeff Garzik
@ 2006-06-28 10:27         ` Albert Lee
  2006-06-28 10:42           ` Tejun Heo
  2006-06-28 11:38           ` Alan Cox
  1 sibling, 2 replies; 13+ messages in thread
From: Albert Lee @ 2006-06-28 10:27 UTC (permalink / raw)
  To: Tejun Heo
  Cc: Jeff Garzik, linux-ide, Alan Cox, Brian King, Doug Maxey,
	Unicorn Chang

Tejun Heo wrote:
> For a legacy ATA controller, libata registers two separate host sets.
> There was no connection between the two hosts making it impossible to
> traverse all ports related to the controller.  This patch adds
> host_set->next which points to the second host_set and makes
> ata_pci_remove_one() remove all associated host_sets.
> 
> * On device removal, all ports hanging off the device are properly
>   detached.  Prior to this patch, ports on the first host_set weren't
>   detached casuing oops on driver unloading.
> 
> * On device removal, both host_sets are properly freed
> 
> This will also be used by new power management code to suspend and
> resume all ports of a controller.  


> host_set/port representation will
> be improved to handle legacy controllers better and this host_set
> linking will go away with it.
> 

Hi Tejun,

Hmm, the current patch looks more like a temporary solution. The legacy mode
ATA_HOST_SIMPLEX host_set->flags could be assigned to both legacy ports.
In the long term, have one host_set for both legacy ports
instead of two host_sets for both legacy ports can fix the problem.

A patch was submitted by Unicorn, but it looks not good/elegant enough. :(
It will be nice if you have plan for furthur legacy two host_sets case fixes...

Thanks,

Albert



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] libata: add host_set->next for legacy two host_sets case, take #3
  2006-06-28 10:27         ` Albert Lee
@ 2006-06-28 10:42           ` Tejun Heo
  2006-06-28 10:53             ` Albert Lee
  2006-06-28 16:25             ` Alan Cox
  2006-06-28 11:38           ` Alan Cox
  1 sibling, 2 replies; 13+ messages in thread
From: Tejun Heo @ 2006-06-28 10:42 UTC (permalink / raw)
  To: albertl
  Cc: Jeff Garzik, linux-ide, Alan Cox, Brian King, Doug Maxey,
	Unicorn Chang

Albert Lee wrote:
> Hmm, the current patch looks more like a temporary solution. The legacy mode
> ATA_HOST_SIMPLEX host_set->flags could be assigned to both legacy ports.
> In the long term, have one host_set for both legacy ports
> instead of two host_sets for both legacy ports can fix the problem.
> 
> A patch was submitted by Unicorn, but it looks not good/elegant enough. :(
> It will be nice if you have plan for furthur legacy two host_sets case fixes...

Hello, Albert.

Yeap, this host_set->next thing is a temporary solution and we need to 
handle legacy ports in one host_set.  I've seen Unicorn's patches.  I 
agree that those are in the right direction but we seem to need more 
clean up in driver initialization code.  I'll look into it once the next 
iteration of PMP patches are finished.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] libata: add host_set->next for legacy two host_sets case, take #3
  2006-06-28 10:42           ` Tejun Heo
@ 2006-06-28 10:53             ` Albert Lee
  2006-06-28 16:25             ` Alan Cox
  1 sibling, 0 replies; 13+ messages in thread
From: Albert Lee @ 2006-06-28 10:53 UTC (permalink / raw)
  To: Tejun Heo
  Cc: albertl, Jeff Garzik, linux-ide, Alan Cox, Brian King, Doug Maxey,
	Unicorn Chang

Tejun Heo wrote:
> Albert Lee wrote:
> 
>> Hmm, the current patch looks more like a temporary solution. The
>> legacy mode
>> ATA_HOST_SIMPLEX host_set->flags could be assigned to both legacy ports.
>> In the long term, have one host_set for both legacy ports
>> instead of two host_sets for both legacy ports can fix the problem.
>>
>> A patch was submitted by Unicorn, but it looks not good/elegant
>> enough. :(
>> It will be nice if you have plan for furthur legacy two host_sets case
>> fixes...
> 
> 
> Hello, Albert.
> 
> Yeap, this host_set->next thing is a temporary solution and we need to
> handle legacy ports in one host_set.  I've seen Unicorn's patches.  I
> agree that those are in the right direction but we seem to need more
> clean up in driver initialization code.  I'll look into it once the next
> iteration of PMP patches are finished.

Great to hear that. Looking forward to it. :)
--
albert


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] libata: add host_set->next for legacy two host_sets case, take #3
  2006-06-28 10:27         ` Albert Lee
  2006-06-28 10:42           ` Tejun Heo
@ 2006-06-28 11:38           ` Alan Cox
  1 sibling, 0 replies; 13+ messages in thread
From: Alan Cox @ 2006-06-28 11:38 UTC (permalink / raw)
  To: albertl
  Cc: Tejun Heo, Jeff Garzik, linux-ide, Brian King, Doug Maxey,
	Unicorn Chang

Ar Mer, 2006-06-28 am 18:27 +0800, ysgrifennodd Albert Lee:
> Hmm, the current patch looks more like a temporary solution. The legacy mode
> ATA_HOST_SIMPLEX host_set->flags could be assigned to both legacy ports.
> In the long term, have one host_set for both legacy ports
> instead of two host_sets for both legacy ports can fix the problem.

I'm diddling with this at the moment. Following up on Jeffs request that
there should be a single host_set in such cases since its the same pci
device.

Alan


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] libata: add host_set->next for legacy two host_sets case, take #3
  2006-06-28 10:42           ` Tejun Heo
  2006-06-28 10:53             ` Albert Lee
@ 2006-06-28 16:25             ` Alan Cox
  1 sibling, 0 replies; 13+ messages in thread
From: Alan Cox @ 2006-06-28 16:25 UTC (permalink / raw)
  To: Tejun Heo
  Cc: albertl, Jeff Garzik, linux-ide, Brian King, Doug Maxey,
	Unicorn Chang

Ar Mer, 2006-06-28 am 19:42 +0900, ysgrifennodd Tejun Heo:
> clean up in driver initialization code.  I'll look into it once the next 
> iteration of PMP patches are finished.

This is what I have now on the host_set front which removes the chaining
of host sets and fixes simplex as well as cleaning up some other cases. 

Alan

diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
index 004e1a0..b1dfa8c 100644
--- a/drivers/scsi/libata-bmdma.c
+++ b/drivers/scsi/libata-bmdma.c
@@ -881,7 +881,7 @@ ata_pci_init_native_mode(struct pci_dev 
 		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]);
@@ -894,45 +894,55 @@ ata_pci_init_native_mode(struct pci_dev 
 
 
 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;
+	probe_ent->hard_port_no = 0;
+	probe_ent->private_data = port[0]->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->irq = 15;
-			probe_ent->port[0].cmd_addr = 0x170;
-			probe_ent->port[0].altstatus_addr =
-			probe_ent->port[0].ctl_addr = 0x376;
-			break;
+	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 ++;
 	}
-
-	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;
+	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->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;
+		port_num ++;
+		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 ++;
 	}
-	ata_std_ports(&probe_ent->port[0]);
-
 	return probe_ent;
 }
 
@@ -951,6 +961,10 @@ static struct ata_probe_ent *ata_pci_ini
  *	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).
  *
@@ -961,7 +975,7 @@ static struct ata_probe_ent *ata_pci_ini
 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;
@@ -1010,35 +1024,34 @@ int ata_pci_init_one (struct pci_dev *pd
 		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 */
@@ -1056,17 +1069,14 @@ int ata_pci_init_one (struct pci_dev *pd
 		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;
 	}
@@ -1074,35 +1084,17 @@ int ata_pci_init_one (struct pci_dev *pd
 	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)
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 6c66877..d48b93e 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5196,6 +5196,7 @@ static void ata_host_init(struct ata_por
 	ap->host_set = host_set;
 	ap->dev = ent->dev;
 	ap->port_no = port_no;
+
 	ap->hard_port_no =
 		ent->legacy_mode ? ent->hard_port_no : port_no;
 	ap->pio_mask = ent->pio_mask;
@@ -5331,6 +5332,7 @@ int ata_device_add(const struct ata_prob
 	host_set->dev = dev;
 	host_set->n_ports = ent->n_ports;
 	host_set->irq = ent->irq;
+	host_set->irq2 = ent->irq2;
 	host_set->mmio_base = ent->mmio_base;
 	host_set->private_data = ent->private_data;
 	host_set->ops = ent->port_ops;
@@ -5340,16 +5342,23 @@ int ata_device_add(const struct ata_prob
 	for (i = 0; i < ent->n_ports; i++) {
 		struct ata_port *ap;
 		unsigned long xfer_mode_mask;
+		int irq_line = ent->irq;
+
 
 		ap = ata_host_add(ent, host_set, i);
 		if (!ap)
 			goto err_out;
 
+		/* Report the secondary IRQ for second channel legacy */
+		if (i == 1 && ent->irq2)
+			irq_line = ent->irq2;
+
 		host_set->ports[i] = ap;
 		xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) |
 				(ap->mwdma_mask << ATA_SHIFT_MWDMA) |
 				(ap->pio_mask << ATA_SHIFT_PIO);
 
+		/* FIXME: maybe print both IRQ lines ? */
 		/* print per-port info to dmesg */
 		ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX "
 				"ctl 0x%lX bmdma 0x%lX irq %lu\n",
@@ -5369,7 +5378,7 @@ int ata_device_add(const struct ata_prob
 	if (!count)
 		goto err_free_ret;
 
-	/* obtain irq, that is shared between channels */
+	/* obtain irq, that may be shared between channels */
 	rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
 			 DRV_NAME, host_set);
 	if (rc) {
@@ -5378,6 +5387,21 @@ int ata_device_add(const struct ata_prob
 		goto err_out;
 	}
 
+	/* do we have a second IRQ for the other channel, eg legacy mode */
+	if (ent->irq2) {
+		/* We will get weird core code crashes later if this is true 
+		   so trap it now */
+		BUG_ON(ent->irq == ent->irq2);
+
+		rc = request_irq(ent->irq2, ent->port_ops->irq_handler, ent->irq_flags,
+			 DRV_NAME, host_set);
+		if (rc) {
+			dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n",
+				   ent->irq2, rc);
+			goto err_out;
+		}
+	}
+
 	/* perform each probe synchronously */
 	DPRINTK("probe begin\n");
 	for (i = 0; i < count; i++) {
@@ -5538,6 +5562,8 @@ void ata_host_set_remove(struct ata_host
 		ata_port_detach(host_set->ports[i]);
 
 	free_irq(host_set->irq, host_set);
+	if (host_set->irq2)
+		free_irq(host_set->irq2, host_set);
 
 	for (i = 0; i < host_set->n_ports; i++) {
 		struct ata_port *ap = host_set->ports[i];
@@ -5547,10 +5573,11 @@ void ata_host_set_remove(struct ata_host
 		if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {
 			struct ata_ioports *ioaddr = &ap->ioaddr;
 
-			if (ioaddr->cmd_addr == 0x1f0)
-				release_region(0x1f0, 8);
-			else if (ioaddr->cmd_addr == 0x170)
-				release_region(0x170, 8);
+			/* FIXME: Add -ac IDE pci mods to remove these special cases */
+			if (ioaddr->cmd_addr == ATA_PRIMARY_CMD)
+				release_region(ATA_PRIMARY_CMD, 8);
+			else if (ioaddr->cmd_addr == ATA_SECONDARY_CMD)
+				release_region(ATA_SECONDARY_CMD, 8);
 		}
 
 		scsi_host_put(ap->host);
@@ -5643,11 +5670,8 @@ void ata_pci_remove_one (struct pci_dev 
 {
 	struct device *dev = pci_dev_to_dev(pdev);
 	struct ata_host_set *host_set = dev_get_drvdata(dev);
-	struct ata_host_set *host_set2 = host_set->next;
 
 	ata_host_set_remove(host_set);
-	if (host_set2)
-		ata_host_set_remove(host_set2);
 
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
diff --git a/include/asm-alpha/libata-portmap.h b/include/asm-alpha/libata-portmap.h
new file mode 100644
index 0000000..9202fd0
--- /dev/null
+++ b/include/asm-alpha/libata-portmap.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_GENERIC_LIBATA_PORTMAP_H
+#define __ASM_GENERIC_LIBATA_PORTMAP_H
+
+#define ATA_PRIMARY_CMD		0x1F0
+#define ATA_PRIMARY_CTL		0x3F6
+#define ATA_PRIMARY_IRQ		14
+
+#define ATA_SECONDARY_CMD	0x170
+#define ATA_SECONDARY_CTL	0x376
+#define ATA_SECONDARY_IRQ	15
+
+#endif
diff --git a/include/asm-i386/libata-portmap.h b/include/asm-i386/libata-portmap.h
new file mode 100644
index 0000000..9202fd0
--- /dev/null
+++ b/include/asm-i386/libata-portmap.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_GENERIC_LIBATA_PORTMAP_H
+#define __ASM_GENERIC_LIBATA_PORTMAP_H
+
+#define ATA_PRIMARY_CMD		0x1F0
+#define ATA_PRIMARY_CTL		0x3F6
+#define ATA_PRIMARY_IRQ		14
+
+#define ATA_SECONDARY_CMD	0x170
+#define ATA_SECONDARY_CTL	0x376
+#define ATA_SECONDARY_IRQ	15
+
+#endif
diff --git a/include/asm-x86_64/libata-portmap.h b/include/asm-x86_64/libata-portmap.h
new file mode 100644
index 0000000..9202fd0
--- /dev/null
+++ b/include/asm-x86_64/libata-portmap.h
@@ -0,0 +1,12 @@
+#ifndef __ASM_GENERIC_LIBATA_PORTMAP_H
+#define __ASM_GENERIC_LIBATA_PORTMAP_H
+
+#define ATA_PRIMARY_CMD		0x1F0
+#define ATA_PRIMARY_CTL		0x3F6
+#define ATA_PRIMARY_IRQ		14
+
+#define ATA_SECONDARY_CMD	0x170
+#define ATA_SECONDARY_CTL	0x376
+#define ATA_SECONDARY_IRQ	15
+
+#endif
diff --git a/include/linux/libata.h b/include/linux/libata.h
index a14ebdb..4c05fee 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -35,6 +35,8 @@
 #include <linux/workqueue.h>
 #include <scsi/scsi_host.h>
 
+#include <asm/libata-portmap.h>
+
 /*
  * compile-time options: to be removed as soon as all the drivers are
  * converted to the new debugging mechanism
@@ -339,6 +341,7 @@ struct ata_probe_ent {
 	unsigned int		udma_mask;
 	unsigned int		legacy_mode;
 	unsigned long		irq;
+	unsigned long		irq2;
 	unsigned int		irq_flags;
 	unsigned long		host_flags;
 	unsigned long		host_set_flags;
@@ -350,6 +353,7 @@ struct ata_host_set {
 	spinlock_t		lock;
 	struct device 		*dev;
 	unsigned long		irq;
+	unsigned long		irq2;
 	void __iomem		*mmio_base;
 	unsigned int		n_ports;
 	void			*private_data;
@@ -357,7 +361,6 @@ struct ata_host_set {
 	unsigned long		flags;
 	int			simplex_claimed;	/* Keep seperate in case we
 							   ever need to do this locked */
-	struct ata_host_set	*next;		/* for legacy mode */
 	struct ata_port		*ports[0];
 };
 


^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2006-06-28 16:12 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-12  5:17 [PATCH] libata: add host_set->next for legacy two host sets case Tejun Heo
2006-06-12  6:55 ` Jeff Garzik
2006-06-12  7:06   ` Tejun Heo
2006-06-12 10:14   ` [PATCH] libata: add host_set->next for legacy two host_sets case, take #2 Tejun Heo
2006-06-12 13:35     ` Jeff Garzik
2006-06-12 13:44       ` Tejun Heo
2006-06-12 14:05       ` [PATCH] libata: add host_set->next for legacy two host_sets case, take #3 Tejun Heo
2006-06-12 14:24         ` Jeff Garzik
2006-06-28 10:27         ` Albert Lee
2006-06-28 10:42           ` Tejun Heo
2006-06-28 10:53             ` Albert Lee
2006-06-28 16:25             ` Alan Cox
2006-06-28 11:38           ` Alan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).