linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHSET] libata: improve initialization and legacy handling, take#3
@ 2006-08-10  8:16 Tejun Heo
  2006-08-10  8:16 ` [PATCH 3/9] [libata] Kill 'count' var in ata_device_add() Tejun Heo
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-10  8:16 UTC (permalink / raw)
  To: jgarzik, alan, linux-ide, htejun

Hello, all.

This is the third take of improve-init-and-legacy patchset.  This
patchset contains patches from Jeff Garzik, Alan Cox and me to
fix/clean up initializaton and legacy handling.  Changes from the last
take[L] are

* adapted to Brian King's sas port alloc/init stuff (new patch added
  #01-update-ata_host_init-and-rename-it-to-ata_port_init_shost)

* fix-new-legacy-handling patch merged into rework-legacy-handling as
  Jeff suggested.

This patchset is against

  libata-dev#upstream [U] 

This patchset is available in the following git tree.

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

PATA drivers have been updated accordingly and available at (properly
merged)

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

Updated ALL branch is available at

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

PATA patch[1] hasn't been changed other than being rebased.

Thanks.

--
tejun

[L] http://article.gmane.org/gmane.linux.ide/12401
[U] 3f066887595de490c411762ce58a31412b09e939
[1] http://article.gmane.org/gmane.linux.ide/12355



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

* [PATCH 3/9] [libata] Kill 'count' var in ata_device_add()
  2006-08-10  8:16 [PATCHSET] libata: improve initialization and legacy handling, take#3 Tejun Heo
@ 2006-08-10  8:16 ` Tejun Heo
  2006-08-10  8:16 ` [PATCH 1/9] libata: update ata_host_init() and rename it to ata_port_init_shost() Tejun Heo
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-10  8:16 UTC (permalink / raw)
  To: jgarzik, alan, linux-ide; +Cc: Jeff Garzik, Tejun Heo

Eliminate redundant loop variable 'count'

Signed-off-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Tejun Heo <htejun@gmail.com>

---

 drivers/scsi/libata-core.c |   20 +++++++-------------
 1 files changed, 7 insertions(+), 13 deletions(-)

6d0500df5b37c94b779ac2c3f522ff917e039f99
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 3aa477a..38fc75d 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5403,7 +5403,7 @@ void ata_host_set_init(struct ata_host_s
  */
 int ata_device_add(const struct ata_probe_ent *ent)
 {
-	unsigned int count = 0, i;
+	unsigned int i;
 	struct device *dev = ent->dev;
 	struct ata_host_set *host_set;
 	int rc;
@@ -5422,7 +5422,7 @@ int ata_device_add(const struct ata_prob
 	host_set->private_data = ent->private_data;
 
 	/* register each port bound to this device */
-	for (i = 0; i < ent->n_ports; i++) {
+	for (i = 0; i < host_set->n_ports; i++) {
 		struct ata_port *ap;
 		unsigned long xfer_mode_mask;
 
@@ -5448,12 +5448,8 @@ int ata_device_add(const struct ata_prob
 		ata_chk_status(ap);
 		host_set->ops->irq_clear(ap);
 		ata_eh_freeze_port(ap);	/* freeze port before requesting IRQ */
-		count++;
 	}
 
-	if (!count)
-		goto err_free_ret;
-
 	/* obtain irq, that is shared between channels */
 	rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags,
 			 DRV_NAME, host_set);
@@ -5465,13 +5461,11 @@ int ata_device_add(const struct ata_prob
 
 	/* perform each probe synchronously */
 	DPRINTK("probe begin\n");
-	for (i = 0; i < count; i++) {
-		struct ata_port *ap;
+	for (i = 0; i < host_set->n_ports; i++) {
+		struct ata_port *ap = host_set->ports[i];
 		u32 scontrol;
 		int rc;
 
-		ap = host_set->ports[i];
-
 		/* init sata_spd_limit to the current value */
 		if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) {
 			int spd = (scontrol >> 4) & 0xf;
@@ -5527,7 +5521,7 @@ int ata_device_add(const struct ata_prob
 
 	/* probes are done, now scan each port's disk(s) */
 	DPRINTK("host probe begin\n");
-	for (i = 0; i < count; i++) {
+	for (i = 0; i < host_set->n_ports; i++) {
 		struct ata_port *ap = host_set->ports[i];
 
 		ata_scsi_scan_host(ap);
@@ -5539,14 +5533,14 @@ int ata_device_add(const struct ata_prob
 	return ent->n_ports; /* success */
 
 err_out:
-	for (i = 0; i < count; i++) {
+	for (i = 0; i < host_set->n_ports; i++) {
 		struct ata_port *ap = host_set->ports[i];
 		if (ap) {
 			ap->ops->port_stop(ap);
 			scsi_host_put(ap->host);
 		}
 	}
-err_free_ret:
+
 	kfree(host_set);
 	VPRINTK("EXIT, returning 0\n");
 	return 0;
-- 
1.3.2



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

* [PATCH 2/9] [libata] some function renaming
  2006-08-10  8:16 [PATCHSET] libata: improve initialization and legacy handling, take#3 Tejun Heo
                   ` (4 preceding siblings ...)
  2006-08-10  8:16 ` [PATCH 4/9] libata: implement per-dev xfermask Tejun Heo
@ 2006-08-10  8:16 ` Tejun Heo
  2006-08-10  8:16 ` [PATCH 7/9] libata: use dummy port for stolen legacy ports Tejun Heo
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-10  8:16 UTC (permalink / raw)
  To: jgarzik, alan, linux-ide; +Cc: Jeff Garzik, Tejun Heo

s/ata_host_add/ata_port_add/
s/ata_host_init/ata_port_init/

libata naming got stuck in the middle of a Great Renaming:

	ata_host -> ata_port
	ata_host_set -> ata_host

To eliminate confusion, let's just give up for now, and simply ensure
that things are internally consistent.

Signed-off-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Tejun Heo <htejun@gmail.com>

---

 drivers/scsi/libata-core.c |   21 ++++++++++-----------
 1 files changed, 10 insertions(+), 11 deletions(-)

996139f1ce50c56c5e66f86b6aba17ff5ea00b86
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index eb9de07..3aa477a 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5309,7 +5309,7 @@ static void ata_port_init_shost(struct a
 }
 
 /**
- *	ata_host_add - Attach low-level ATA driver to system
+ *	ata_port_add - Attach low-level ATA driver to system
  *	@ent: Information provided by low-level driver
  *	@host_set: Collections of ports to which we add
  *	@port_no: Port number associated with this host
@@ -5322,12 +5322,11 @@ static void ata_port_init_shost(struct a
  *	RETURNS:
  *	New ata_port on success, for NULL on error.
  */
-
-static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
+static struct ata_port * ata_port_add(const struct ata_probe_ent *ent,
 				      struct ata_host_set *host_set,
 				      unsigned int port_no)
 {
-	struct Scsi_Host *host;
+	struct Scsi_Host *shost;
 	struct ata_port *ap;
 	int rc;
 
@@ -5340,16 +5339,16 @@ static struct ata_port * ata_host_add(co
 		return NULL;
 	}
 
-	host = scsi_host_alloc(ent->sht, sizeof(struct ata_port));
-	if (!host)
+	shost = scsi_host_alloc(ent->sht, sizeof(struct ata_port));
+	if (!shost)
 		return NULL;
 
-	host->transportt = &ata_scsi_transport_template;
+	shost->transportt = &ata_scsi_transport_template;
 
-	ap = ata_shost_to_port(host);
+	ap = ata_shost_to_port(shost);
 
 	ata_port_init(ap, host_set, ent, port_no);
-	ata_port_init_shost(ap, host);
+	ata_port_init_shost(ap, shost);
 
 	rc = ap->ops->port_start(ap);
 	if (rc)
@@ -5358,7 +5357,7 @@ static struct ata_port * ata_host_add(co
 	return ap;
 
 err_out:
-	scsi_host_put(host);
+	scsi_host_put(shost);
 	return NULL;
 }
 
@@ -5427,7 +5426,7 @@ int ata_device_add(const struct ata_prob
 		struct ata_port *ap;
 		unsigned long xfer_mode_mask;
 
-		ap = ata_host_add(ent, host_set, i);
+		ap = ata_port_add(ent, host_set, i);
 		if (!ap)
 			goto err_out;
 
-- 
1.3.2



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

* [PATCH 6/9] libata: implement dummy port
  2006-08-10  8:16 [PATCHSET] libata: improve initialization and legacy handling, take#3 Tejun Heo
                   ` (2 preceding siblings ...)
  2006-08-10  8:16 ` [PATCH 5/9] libata: rework legacy handling to remove much of the cruft Tejun Heo
@ 2006-08-10  8:16 ` Tejun Heo
  2006-08-10  8:16 ` [PATCH 4/9] libata: implement per-dev xfermask Tejun Heo
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-10  8:16 UTC (permalink / raw)
  To: jgarzik, alan, linux-ide; +Cc: Tejun Heo

Implement dummy port which can be requested by setting appropriate bit
in probe_ent->dummy_port_mask.  The dummy port is used as placeholder
for stolen legacy port.  This allows libata to guarantee that
index_of(ap) == ap->port_no == actual_device_port_no, and thus to
remove error-prone ap->hard_port_no.

As it's used only when one port of a legacy controller is reserved by
some other entity (e.g. IDE), the focus is on keeping the added *code*
complexity at minimum, so dummy port allocates all libata core
resources and acts as a normal port.  It just has all dummy port_ops.

This patch only implements dummy port.  The following patch will make
libata use it for stolen legacy ports.

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

---

 drivers/scsi/libata-core.c |   61 +++++++++++++++++++++++++++++++++++++-------
 include/linux/libata.h     |    8 ++++++
 2 files changed, 59 insertions(+), 10 deletions(-)

dd5b06c490de72440ec39f814de99a714a45a1a9
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 3634279..f2e7e2f 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5311,7 +5311,6 @@ static struct ata_port * ata_port_add(co
 {
 	struct Scsi_Host *shost;
 	struct ata_port *ap;
-	int rc;
 
 	DPRINTK("ENTER\n");
 
@@ -5333,15 +5332,7 @@ static struct ata_port * ata_port_add(co
 	ata_port_init(ap, host_set, ent, port_no);
 	ata_port_init_shost(ap, shost);
 
-	rc = ap->ops->port_start(ap);
-	if (rc)
-		goto err_out;
-
 	return ap;
-
-err_out:
-	scsi_host_put(shost);
-	return NULL;
 }
 
 /**
@@ -5415,11 +5406,27 @@ int ata_device_add(const struct ata_prob
 		if (!ap)
 			goto err_out;
 
+		host_set->ports[i] = ap;
+
+		/* dummy? */
+		if (ent->dummy_port_mask & (1 << i)) {
+			ata_port_printk(ap, KERN_INFO, "DUMMY\n");
+			ap->ops = &ata_dummy_port_ops;
+			continue;
+		}
+
+		/* start port */
+		rc = ap->ops->port_start(ap);
+		if (rc) {
+			host_set->ports[i] = NULL;
+			scsi_host_put(ap->host);
+			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);
@@ -5941,6 +5948,39 @@ u32 ata_wait_register(void __iomem *reg,
 }
 
 /*
+ * Dummy port_ops
+ */
+static void ata_dummy_noret(struct ata_port *ap)	{ }
+static int ata_dummy_ret0(struct ata_port *ap)		{ return 0; }
+static void ata_dummy_qc_noret(struct ata_queued_cmd *qc) { }
+
+static u8 ata_dummy_check_status(struct ata_port *ap)
+{
+	return ATA_DRDY;
+}
+
+static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc)
+{
+	return AC_ERR_SYSTEM;
+}
+
+const struct ata_port_operations ata_dummy_port_ops = {
+	.port_disable		= ata_port_disable,
+	.check_status		= ata_dummy_check_status,
+	.check_altstatus	= ata_dummy_check_status,
+	.dev_select		= ata_noop_dev_select,
+	.qc_prep		= ata_noop_qc_prep,
+	.qc_issue		= ata_dummy_qc_issue,
+	.freeze			= ata_dummy_noret,
+	.thaw			= ata_dummy_noret,
+	.error_handler		= ata_dummy_noret,
+	.post_internal_cmd	= ata_dummy_qc_noret,
+	.irq_clear		= ata_dummy_noret,
+	.port_start		= ata_dummy_ret0,
+	.port_stop		= ata_dummy_noret,
+};
+
+/*
  * libata is essentially a library of internal helper functions for
  * low-level ATA host controller drivers.  As such, the API/ABI is
  * likely to change as new drivers are added and updated.
@@ -5950,6 +5990,7 @@ u32 ata_wait_register(void __iomem *reg,
 EXPORT_SYMBOL_GPL(sata_deb_timing_normal);
 EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug);
 EXPORT_SYMBOL_GPL(sata_deb_timing_long);
+EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
 EXPORT_SYMBOL_GPL(ata_std_bios_param);
 EXPORT_SYMBOL_GPL(ata_std_ports);
 EXPORT_SYMBOL_GPL(ata_host_set_init);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 4504776..30bfe8f 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -353,6 +353,7 @@ struct ata_probe_ent {
 	struct ata_ioports	port[ATA_MAX_PORTS];
 	unsigned int		n_ports;
 	unsigned int		hard_port_no;
+	unsigned int		dummy_port_mask;
 	unsigned int		pio_mask;
 	unsigned int		mwdma_mask;
 	unsigned int		udma_mask;
@@ -652,6 +653,8 @@ extern const unsigned long sata_deb_timi
 extern const unsigned long sata_deb_timing_hotplug[];
 extern const unsigned long sata_deb_timing_long[];
 
+extern const struct ata_port_operations ata_dummy_port_ops;
+
 static inline const unsigned long *
 sata_ehc_deb_timing(struct ata_eh_context *ehc)
 {
@@ -661,6 +664,11 @@ sata_ehc_deb_timing(struct ata_eh_contex
 		return sata_deb_timing_normal;
 }
 
+static inline int ata_port_is_dummy(struct ata_port *ap)
+{
+	return ap->ops == &ata_dummy_port_ops;
+}
+
 extern void ata_port_probe(struct ata_port *);
 extern void __sata_phy_reset(struct ata_port *ap);
 extern void sata_phy_reset(struct ata_port *ap);
-- 
1.3.2



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

* [PATCH 1/9] libata: update ata_host_init() and rename it to ata_port_init_shost()
  2006-08-10  8:16 [PATCHSET] libata: improve initialization and legacy handling, take#3 Tejun Heo
  2006-08-10  8:16 ` [PATCH 3/9] [libata] Kill 'count' var in ata_device_add() Tejun Heo
@ 2006-08-10  8:16 ` Tejun Heo
  2006-08-10  8:16 ` [PATCH 5/9] libata: rework legacy handling to remove much of the cruft Tejun Heo
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-10  8:16 UTC (permalink / raw)
  To: jgarzik, alan, linux-ide; +Cc: Tejun Heo

Update ata_host_init() such that it only initializes SCSI host related
stuff and doesn't call into ata_port_init(), and rename it to
ata_port_init_shost().

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

---

 drivers/scsi/libata-core.c |   33 +++++++++++++--------------------
 1 files changed, 13 insertions(+), 20 deletions(-)

4608c1608501cf2b0dc4478c9b6c3902db58408a
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 83d93fc..eb9de07 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5288,32 +5288,24 @@ #endif
 }
 
 /**
- *	ata_host_init - Initialize an ata_port structure
- *	@ap: Structure to initialize
- *	@host: associated SCSI mid-layer structure
- *	@host_set: Collection of hosts to which @ap belongs
- *	@ent: Probe information provided by low-level driver
- *	@port_no: Port number associated with this ata_port
+ *	ata_port_init_shost - Initialize SCSI host associated with ATA port
+ *	@ap: ATA port to initialize SCSI host for
+ *	@shost: SCSI host associated with @ap
  *
- *	Initialize a new ata_port structure, and its associated
- *	scsi_host.
+ *	Initialize SCSI host @shost associated with ATA port @ap.
  *
  *	LOCKING:
  *	Inherited from caller.
  */
-
-static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
-			  struct ata_host_set *host_set,
-			  const struct ata_probe_ent *ent, unsigned int port_no)
+static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost)
 {
-	ata_port_init(ap, host_set, ent, port_no);
-	ap->host = host;
+	ap->host = shost;
 
-	host->unique_id = ap->id;
-	host->max_id = 16;
-	host->max_lun = 1;
-	host->max_channel = 1;
-	host->max_cmd_len = 12;
+	shost->unique_id = ap->id;
+	shost->max_id = 16;
+	shost->max_lun = 1;
+	shost->max_channel = 1;
+	shost->max_cmd_len = 12;
 }
 
 /**
@@ -5356,7 +5348,8 @@ static struct ata_port * ata_host_add(co
 
 	ap = ata_shost_to_port(host);
 
-	ata_host_init(ap, host, host_set, ent, port_no);
+	ata_port_init(ap, host_set, ent, port_no);
+	ata_port_init_shost(ap, host);
 
 	rc = ap->ops->port_start(ap);
 	if (rc)
-- 
1.3.2



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

* [PATCH 5/9] libata: rework legacy handling to remove much of the cruft
  2006-08-10  8:16 [PATCHSET] libata: improve initialization and legacy handling, take#3 Tejun Heo
  2006-08-10  8:16 ` [PATCH 3/9] [libata] Kill 'count' var in ata_device_add() Tejun Heo
  2006-08-10  8:16 ` [PATCH 1/9] libata: update ata_host_init() and rename it to ata_port_init_shost() Tejun Heo
@ 2006-08-10  8:16 ` Tejun Heo
  2006-08-10  8:16 ` [PATCH 6/9] libata: implement dummy port Tejun Heo
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-10  8:16 UTC (permalink / raw)
  To: jgarzik, linux-ide; +Cc: Alan Cox, Alan Cox, Andrew Morton, Tejun Heo

Kill host_set->next
Fix simplex support
Allow per platform setting of IDE legacy bases

Some of this can be tidied further later on, in particular all the
legacy port gunge belongs as a PCI quirk/PCI header decode to understand
the special legacy IDE rules in the PCI spec.

Longer term Jeff also wants to move the request_irq/free_irq out of core
which will make this even cleaner.

tj: folded in three followup patches - ata_piix-fix, broken-arch-fix
and fix-new-legacy-handling, and separated per-dev xfermask into
separate patch preceding this one.  Folded in fixes are...

* ata_piix-fix: fix build failure due to host_set->next removal
* broken-arch-fix: add missing include/asm-*/libata-portmap.h
* fix-new-legacy-handling:
	* In ata_pci_init_legacy_port(), probe_num was incorrectly
          incremented during initialization of the secondary port and
          probe_ent->n_ports was incorrectly fixed to 1.

	* Both legacy ports ended up having the same hard_port_no.

	* When printing port information, both legacy ports printed
	  the first irq.

Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Tejun Heo <htejun@gmail.com>

---

 drivers/scsi/ata_piix.c              |    2 -
 drivers/scsi/libata-bmdma.c          |  135 ++++++++++++++++------------------
 drivers/scsi/libata-core.c           |   59 +++++++++------
 include/asm-alpha/libata-portmap.h   |    1 
 include/asm-generic/libata-portmap.h |   12 +++
 include/asm-i386/libata-portmap.h    |    1 
 include/asm-ia64/libata-portmap.h    |    1 
 include/asm-powerpc/libata-portmap.h |    1 
 include/asm-sparc/libata-portmap.h   |    1 
 include/asm-sparc64/libata-portmap.h |    1 
 include/asm-x86_64/libata-portmap.h  |    1 
 include/linux/libata.h               |    5 +
 12 files changed, 123 insertions(+), 97 deletions(-)
 create mode 100644 include/asm-alpha/libata-portmap.h
 create mode 100644 include/asm-generic/libata-portmap.h
 create mode 100644 include/asm-i386/libata-portmap.h
 create mode 100644 include/asm-ia64/libata-portmap.h
 create mode 100644 include/asm-powerpc/libata-portmap.h
 create mode 100644 include/asm-sparc/libata-portmap.h
 create mode 100644 include/asm-sparc64/libata-portmap.h
 create mode 100644 include/asm-x86_64/libata-portmap.h

2ec7df0457b710d9201f211dbccdbecf0ad38b7e
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 5e8afc8..40ecab5 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -932,8 +932,6 @@ static int piix_init_one (struct pci_dev
 
 static void piix_host_stop(struct ata_host_set *host_set)
 {
-	if (host_set->next == NULL)
-		kfree(host_set->private_data);
 	ata_host_stop(host_set);
 }
 
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
index 3268cf5..e694f60 100644
--- a/drivers/scsi/libata-bmdma.c
+++ b/drivers/scsi/libata-bmdma.c
@@ -854,7 +854,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]);
@@ -867,44 +867,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);
 
-	probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port);
+	int port_num = 0;
+
+	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;
 }
@@ -924,6 +935,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).
  *
@@ -934,7 +949,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;
@@ -983,35 +998,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 */
@@ -1029,17 +1043,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;
 	}
@@ -1047,35 +1058,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 4e6c2e8..3634279 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5223,8 +5223,9 @@ void ata_port_init(struct ata_port *ap, 
 	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->hard_port_no = port_no;
+	if (ent->legacy_mode)
+		ap->hard_port_no += ent->hard_port_no;
 	ap->pio_mask = ent->pio_mask;
 	ap->mwdma_mask = ent->mwdma_mask;
 	ap->udma_mask = ent->udma_mask;
@@ -5400,6 +5401,7 @@ int ata_device_add(const struct ata_prob
 	ata_host_set_init(host_set, dev, ent->host_set_flags, ent->port_ops);
 	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;
 
@@ -5407,11 +5409,16 @@ int ata_device_add(const struct ata_prob
 	for (i = 0; i < host_set->n_ports; i++) {
 		struct ata_port *ap;
 		unsigned long xfer_mode_mask;
+		int irq_line = ent->irq;
 
 		ap = ata_port_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) |
@@ -5419,20 +5426,20 @@ int ata_device_add(const struct ata_prob
 
 		/* 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",
+				"ctl 0x%lX bmdma 0x%lX irq %d\n",
 				ap->flags & ATA_FLAG_SATA ? 'S' : 'P',
 				ata_mode_string(xfer_mode_mask),
 				ap->ioaddr.cmd_addr,
 				ap->ioaddr.ctl_addr,
 				ap->ioaddr.bmdma_addr,
-				ent->irq);
+				irq_line);
 
 		ata_chk_status(ap);
 		host_set->ops->irq_clear(ap);
 		ata_eh_freeze_port(ap);	/* freeze port before requesting IRQ */
 	}
 
-	/* 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) {
@@ -5441,6 +5448,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_free_irq;
+		}
+	}
+
 	/* perform each probe synchronously */
 	DPRINTK("probe begin\n");
 	for (i = 0; i < host_set->n_ports; i++) {
@@ -5514,6 +5536,8 @@ int ata_device_add(const struct ata_prob
 	VPRINTK("EXIT, returning %u\n", ent->n_ports);
 	return ent->n_ports; /* success */
 
+err_out_free_irq:
+	free_irq(ent->irq, host_set);
 err_out:
 	for (i = 0; i < host_set->n_ports; i++) {
 		struct ata_port *ap = host_set->ports[i];
@@ -5605,6 +5629,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];
@@ -5614,10 +5640,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);
@@ -5735,11 +5762,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);
@@ -5807,14 +5831,6 @@ int ata_pci_device_suspend(struct pci_de
 	if (rc)
 		return rc;
 
-	if (host_set->next) {
-		rc = ata_host_set_suspend(host_set->next, mesg);
-		if (rc) {
-			ata_host_set_resume(host_set);
-			return rc;
-		}
-	}
-
 	ata_pci_device_do_suspend(pdev, mesg);
 
 	return 0;
@@ -5826,9 +5842,6 @@ int ata_pci_device_resume(struct pci_dev
 
 	ata_pci_device_do_resume(pdev);
 	ata_host_set_resume(host_set);
-	if (host_set->next)
-		ata_host_set_resume(host_set->next);
-
 	return 0;
 }
 #endif /* CONFIG_PCI */
diff --git a/include/asm-alpha/libata-portmap.h b/include/asm-alpha/libata-portmap.h
new file mode 100644
index 0000000..75484ef
--- /dev/null
+++ b/include/asm-alpha/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/asm-generic/libata-portmap.h b/include/asm-generic/libata-portmap.h
new file mode 100644
index 0000000..9202fd0
--- /dev/null
+++ b/include/asm-generic/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..75484ef
--- /dev/null
+++ b/include/asm-i386/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/asm-ia64/libata-portmap.h b/include/asm-ia64/libata-portmap.h
new file mode 100644
index 0000000..75484ef
--- /dev/null
+++ b/include/asm-ia64/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/asm-powerpc/libata-portmap.h b/include/asm-powerpc/libata-portmap.h
new file mode 100644
index 0000000..75484ef
--- /dev/null
+++ b/include/asm-powerpc/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/asm-sparc/libata-portmap.h b/include/asm-sparc/libata-portmap.h
new file mode 100644
index 0000000..75484ef
--- /dev/null
+++ b/include/asm-sparc/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/asm-sparc64/libata-portmap.h b/include/asm-sparc64/libata-portmap.h
new file mode 100644
index 0000000..75484ef
--- /dev/null
+++ b/include/asm-sparc64/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/asm-x86_64/libata-portmap.h b/include/asm-x86_64/libata-portmap.h
new file mode 100644
index 0000000..75484ef
--- /dev/null
+++ b/include/asm-x86_64/libata-portmap.h
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
diff --git a/include/linux/libata.h b/include/linux/libata.h
index cf5eb1d..4504776 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -36,6 +36,8 @@ #include <linux/ata.h>
 #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
@@ -356,6 +358,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;
@@ -367,6 +370,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;
@@ -374,7 +378,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];
 };
 
-- 
1.3.2



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

* [PATCH 4/9] libata: implement per-dev xfermask
  2006-08-10  8:16 [PATCHSET] libata: improve initialization and legacy handling, take#3 Tejun Heo
                   ` (3 preceding siblings ...)
  2006-08-10  8:16 ` [PATCH 6/9] libata: implement dummy port Tejun Heo
@ 2006-08-10  8:16 ` Tejun Heo
  2006-08-10  8:16 ` [PATCH 2/9] [libata] some function renaming Tejun Heo
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-10  8:16 UTC (permalink / raw)
  To: jgarzik, alan, linux-ide; +Cc: Tejun Heo

Implement per-dev xfermask.  libata used to determine xfermask
per-port - the fastest mode of the slowest device on the port.  This
patch enables per-dev xfermask.

Original patch is from Alan Cox <alan@redhat.com>.  The following
changes are made by me.

* simplex warning message is added
* remove disabled device handling code which is never invoked
  (originally for choosing port-wide lowest PIO mode)

Cc: Alan Cox <alan@redhat.com>
Signed-off-by: Tejun Heo <htejun@gmail.com>

---

 drivers/scsi/libata-core.c |   40 +++++++++++-----------------------------
 1 files changed, 11 insertions(+), 29 deletions(-)

37deecb5139ee431233781a9a093d9fcaab54c5b
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 38fc75d..4e6c2e8 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -3040,10 +3040,6 @@ static int ata_dma_blacklisted(const str
  *	known limits including host controller limits, device
  *	blacklist, etc...
  *
- *	FIXME: The current implementation limits all transfer modes to
- *	the fastest of the lowested device on the port.  This is not
- *	required on most controllers.
- *
  *	LOCKING:
  *	None.
  */
@@ -3052,8 +3048,8 @@ static void ata_dev_xfermask(struct ata_
 	struct ata_port *ap = dev->ap;
 	struct ata_host_set *hs = ap->host_set;
 	unsigned long xfer_mask;
-	int i;
 
+	/* controller modes available */
 	xfer_mask = ata_pack_xfermask(ap->pio_mask,
 				      ap->mwdma_mask, ap->udma_mask);
 
@@ -3063,34 +3059,20 @@ static void ata_dev_xfermask(struct ata_
 	if (ap->cbl == ATA_CBL_PATA40)
 		xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
 
-	/* FIXME: Use port-wide xfermask for now */
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		struct ata_device *d = &ap->device[i];
-
-		if (ata_dev_absent(d))
-			continue;
+	xfer_mask &= ata_pack_xfermask(dev->pio_mask,
+				       dev->mwdma_mask, dev->udma_mask);
+	xfer_mask &= ata_id_xfermask(dev->id);
 
-		if (ata_dev_disabled(d)) {
-			/* to avoid violating device selection timing */
-			xfer_mask &= ata_pack_xfermask(d->pio_mask,
-						       UINT_MAX, UINT_MAX);
-			continue;
-		}
-
-		xfer_mask &= ata_pack_xfermask(d->pio_mask,
-					       d->mwdma_mask, d->udma_mask);
-		xfer_mask &= ata_id_xfermask(d->id);
-		if (ata_dma_blacklisted(d))
-			xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
-	}
-
-	if (ata_dma_blacklisted(dev))
+	if (ata_dma_blacklisted(dev)) {
+		xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
 		ata_dev_printk(dev, KERN_WARNING,
 			       "device is on DMA blacklist, disabling DMA\n");
+	}
 
-	if (hs->flags & ATA_HOST_SIMPLEX) {
-		if (hs->simplex_claimed)
-			xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
+	if ((hs->flags & ATA_HOST_SIMPLEX) && hs->simplex_claimed) {
+		xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
+		ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by "
+			       "other device, disabling DMA\n");
 	}
 
 	if (ap->ops->mode_filter)
-- 
1.3.2



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

* [PATCH 9/9] libata: kill unused hard_port_no and legacy_mode
  2006-08-10  8:16 [PATCHSET] libata: improve initialization and legacy handling, take#3 Tejun Heo
                   ` (6 preceding siblings ...)
  2006-08-10  8:16 ` [PATCH 7/9] libata: use dummy port for stolen legacy ports Tejun Heo
@ 2006-08-10  8:16 ` Tejun Heo
  2006-08-10  8:16 ` [PATCH 8/9] libata: replace ap->hard_port_no with ap->port_no Tejun Heo
  2006-08-10 10:53 ` [PATCHSET] libata: improve initialization and legacy handling, take#3 Jeff Garzik
  9 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-10  8:16 UTC (permalink / raw)
  To: jgarzik, alan, linux-ide; +Cc: Tejun Heo

Kill unused probe_ent/ap->hard_port_no and probe_ent->legacy_mode.

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

---

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

4852ba24f647199be797545226c6d325db231937
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 2ef86b4..3f963f2 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5223,7 +5223,6 @@ void ata_port_init(struct ata_port *ap, 
 	ap->host_set = host_set;
 	ap->dev = ent->dev;
 	ap->port_no = port_no;
-	ap->hard_port_no = port_no;
 	ap->pio_mask = ent->pio_mask;
 	ap->mwdma_mask = ent->mwdma_mask;
 	ap->udma_mask = ent->udma_mask;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 30bfe8f..ed749f7 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -352,12 +352,10 @@ struct ata_probe_ent {
 	struct scsi_host_template *sht;
 	struct ata_ioports	port[ATA_MAX_PORTS];
 	unsigned int		n_ports;
-	unsigned int		hard_port_no;
 	unsigned int		dummy_port_mask;
 	unsigned int		pio_mask;
 	unsigned int		mwdma_mask;
 	unsigned int		udma_mask;
-	unsigned int		legacy_mode;
 	unsigned long		irq;
 	unsigned long		irq2;
 	unsigned int		irq_flags;
@@ -509,7 +507,6 @@ struct ata_port {
 	unsigned int		pflags; /* ATA_PFLAG_xxx */
 	unsigned int		id;	/* unique id req'd by scsi midlyr */
 	unsigned int		port_no; /* unique port #; from zero */
-	unsigned int		hard_port_no;	/* hardware port #; from zero */
 
 	struct ata_prd		*prd;	 /* our SG list */
 	dma_addr_t		prd_dma; /* and its DMA mapping */
-- 
1.3.2



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

* [PATCH 7/9] libata: use dummy port for stolen legacy ports
  2006-08-10  8:16 [PATCHSET] libata: improve initialization and legacy handling, take#3 Tejun Heo
                   ` (5 preceding siblings ...)
  2006-08-10  8:16 ` [PATCH 2/9] [libata] some function renaming Tejun Heo
@ 2006-08-10  8:16 ` Tejun Heo
  2006-08-10  8:16 ` [PATCH 9/9] libata: kill unused hard_port_no and legacy_mode Tejun Heo
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-10  8:16 UTC (permalink / raw)
  To: jgarzik, alan, linux-ide; +Cc: Tejun Heo

Use dummy port for stolen legacy ports.  This makes ap->port_no always
equal ap->hard_port_no.

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

---

 drivers/scsi/libata-bmdma.c |   41 +++++++++++++++++------------------------
 drivers/scsi/libata-core.c  |    2 --
 2 files changed, 17 insertions(+), 26 deletions(-)

c4b01f1de254820175fe2d02b4cf7c0fab335846
diff --git a/drivers/scsi/libata-bmdma.c b/drivers/scsi/libata-bmdma.c
index e694f60..158f62d 100644
--- a/drivers/scsi/libata-bmdma.c
+++ b/drivers/scsi/libata-bmdma.c
@@ -872,50 +872,43 @@ static struct ata_probe_ent *ata_pci_ini
 	struct ata_probe_ent *probe_ent;
 	unsigned long bmdma = pci_resource_start(pdev, 4);
 
-	int port_num = 0;
-
 	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->hard_port_no = 0;
+	probe_ent->n_ports = 2;
 	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;
+		probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD;
+		probe_ent->port[0].altstatus_addr =
+		probe_ent->port[0].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 ++;
-	}
+		ata_std_ports(&probe_ent->port[0]);
+	} else
+		probe_ent->dummy_port_mask |= ATA_PORT_PRIMARY;
+
 	if (port_mask & ATA_PORT_SECONDARY) {
-		if (port_num == 1)
+		if (probe_ent->irq)
 			probe_ent->irq2 = 15;
-		else {
-			/* Secondary only. IRQ 15 only and "first" port is port 1 */
+		else
 			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;
+		probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD;
+		probe_ent->port[1].altstatus_addr =
+		probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL;
 		if (bmdma) {
-			probe_ent->port[port_num].bmdma_addr = bmdma + 8;
+			probe_ent->port[1].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 ++;
-	}
-
-	probe_ent->n_ports = port_num;
+		ata_std_ports(&probe_ent->port[1]);
+	} else
+		probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY;
 
 	return probe_ent;
 }
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index f2e7e2f..2ef86b4 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -5224,8 +5224,6 @@ void ata_port_init(struct ata_port *ap, 
 	ap->dev = ent->dev;
 	ap->port_no = port_no;
 	ap->hard_port_no = port_no;
-	if (ent->legacy_mode)
-		ap->hard_port_no += ent->hard_port_no;
 	ap->pio_mask = ent->pio_mask;
 	ap->mwdma_mask = ent->mwdma_mask;
 	ap->udma_mask = ent->udma_mask;
-- 
1.3.2



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

* [PATCH 8/9] libata: replace ap->hard_port_no with ap->port_no
  2006-08-10  8:16 [PATCHSET] libata: improve initialization and legacy handling, take#3 Tejun Heo
                   ` (7 preceding siblings ...)
  2006-08-10  8:16 ` [PATCH 9/9] libata: kill unused hard_port_no and legacy_mode Tejun Heo
@ 2006-08-10  8:16 ` Tejun Heo
  2006-08-10 10:53 ` [PATCHSET] libata: improve initialization and legacy handling, take#3 Jeff Garzik
  9 siblings, 0 replies; 13+ messages in thread
From: Tejun Heo @ 2006-08-10  8:16 UTC (permalink / raw)
  To: jgarzik, alan, linux-ide; +Cc: Tejun Heo

Replace ap->hard_port_no with ap->port_no.

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

---

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

2a88d1ac8dca898a7fb602ddd581bf4d2977509d
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index 40ecab5..501755a 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -487,7 +487,7 @@ static void piix_pata_cbl_detect(struct 
 		goto cbl40;
 
 	/* check BIOS cable detect results */
-	mask = ap->hard_port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
+	mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
 	pci_read_config_byte(pdev, PIIX_IOCFG, &tmp);
 	if ((tmp & mask) == 0)
 		goto cbl40;
@@ -513,7 +513,7 @@ static int piix_pata_prereset(struct ata
 {
 	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
 
-	if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) {
+	if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) {
 		ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n");
 		ap->eh_context.i.action &= ~ATA_EH_RESET_MASK;
 		return 0;
@@ -550,7 +550,7 @@ static int piix_sata_prereset(struct ata
 	struct pci_dev *pdev = to_pci_dev(ap->host_set->dev);
 	struct piix_host_priv *hpriv = ap->host_set->private_data;
 	const unsigned int *map = hpriv->map;
-	int base = 2 * ap->hard_port_no;
+	int base = 2 * ap->port_no;
 	unsigned int present = 0;
 	int port, i;
 	u16 pcs;
@@ -601,7 +601,7 @@ static void piix_set_piomode (struct ata
 	unsigned int pio	= adev->pio_mode - XFER_PIO_0;
 	struct pci_dev *dev	= to_pci_dev(ap->host_set->dev);
 	unsigned int is_slave	= (adev->devno != 0);
-	unsigned int master_port= ap->hard_port_no ? 0x42 : 0x40;
+	unsigned int master_port= ap->port_no ? 0x42 : 0x40;
 	unsigned int slave_port	= 0x44;
 	u16 master_data;
 	u8 slave_data;
@@ -619,10 +619,10 @@ static void piix_set_piomode (struct ata
 		/* enable PPE, IE and TIME */
 		master_data |= 0x0070;
 		pci_read_config_byte(dev, slave_port, &slave_data);
-		slave_data &= (ap->hard_port_no ? 0x0f : 0xf0);
+		slave_data &= (ap->port_no ? 0x0f : 0xf0);
 		slave_data |=
 			(timings[pio][0] << 2) |
-			(timings[pio][1] << (ap->hard_port_no ? 4 : 0));
+			(timings[pio][1] << (ap->port_no ? 4 : 0));
 	} else {
 		master_data &= 0xccf8;
 		/* enable PPE, IE and TIME */
@@ -652,9 +652,9 @@ static void piix_set_dmamode (struct ata
 {
 	unsigned int udma	= adev->dma_mode; /* FIXME: MWDMA too */
 	struct pci_dev *dev	= to_pci_dev(ap->host_set->dev);
-	u8 maslave		= ap->hard_port_no ? 0x42 : 0x40;
+	u8 maslave		= ap->port_no ? 0x42 : 0x40;
 	u8 speed		= udma;
-	unsigned int drive_dn	= (ap->hard_port_no ? 2 : 0) + adev->devno;
+	unsigned int drive_dn	= (ap->port_no ? 2 : 0) + adev->devno;
 	int a_speed		= 3 << (drive_dn * 4);
 	int u_flag		= 1 << drive_dn;
 	int v_flag		= 0x01 << drive_dn;
-- 
1.3.2



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

* Re: [PATCHSET] libata: improve initialization and legacy handling, take#3
  2006-08-10  8:16 [PATCHSET] libata: improve initialization and legacy handling, take#3 Tejun Heo
                   ` (8 preceding siblings ...)
  2006-08-10  8:16 ` [PATCH 8/9] libata: replace ap->hard_port_no with ap->port_no Tejun Heo
@ 2006-08-10 10:53 ` Jeff Garzik
  2006-08-10 11:32   ` Tejun Heo
  9 siblings, 1 reply; 13+ messages in thread
From: Jeff Garzik @ 2006-08-10 10:53 UTC (permalink / raw)
  To: Tejun Heo; +Cc: alan, linux-ide

Tejun Heo wrote:
> Hello, all.
> 
> This is the third take of improve-init-and-legacy patchset.  This
> patchset contains patches from Jeff Garzik, Alan Cox and me to
> fix/clean up initializaton and legacy handling.  Changes from the last
> take[L] are
> 
> * adapted to Brian King's sas port alloc/init stuff (new patch added
>   #01-update-ata_host_init-and-rename-it-to-ata_port_init_shost)
> 
> * fix-new-legacy-handling patch merged into rework-legacy-handling as
>   Jeff suggested.
> 
> This patchset is against
> 
>   libata-dev#upstream [U] 
> 
> This patchset is available in the following git tree.
> 
>   http://htj.dyndns.org/git/?p=libata-tj.git;a=shortlog;h=tj-upstream
>   git://htj.dyndns.org/libata-tj tj-upstream

pulled


> PATA drivers have been updated accordingly and available at (properly
> merged)
> 
>   http://htj.dyndns.org/git/?p=libata-tj.git;a=shortlog;h=tj-pata-drivers
>   git://htj.dyndns.org/libata-tj tj-pata-drivers

pulled


> Updated ALL branch is available at
> 
>   http://htj.dyndns.org/git/?p=libata-tj.git;a=shortlog;h=tj-ALL
>   git://htj.dyndns.org/libata-tj tj-ALL

FWIW, I usually just update this manually.  The process I used for this 
email's pulls was

cd /spare/repo/libata-dev
git checkout upstream
git pull $url tj-upstream
git checkout pata-drivers
git pull . upstream
git pull $url tj-pata-drivers
git checkout ALL
git pull . pata-drivers

Thus, changes are pulled from upstream to downstream branches.

	Jeff




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

* Re: [PATCHSET] libata: improve initialization and legacy handling, take#3
  2006-08-10 10:53 ` [PATCHSET] libata: improve initialization and legacy handling, take#3 Jeff Garzik
@ 2006-08-10 11:32   ` Tejun Heo
  2006-08-10 11:59     ` Jeff Garzik
  0 siblings, 1 reply; 13+ messages in thread
From: Tejun Heo @ 2006-08-10 11:32 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: alan, linux-ide

Jeff Garzik wrote:
> Tejun Heo wrote:
>> Hello, all.
>>
>> This is the third take of improve-init-and-legacy patchset.  This
>> patchset contains patches from Jeff Garzik, Alan Cox and me to
>> fix/clean up initializaton and legacy handling.  Changes from the last
>> take[L] are
>>
>> * adapted to Brian King's sas port alloc/init stuff (new patch added
>>   #01-update-ata_host_init-and-rename-it-to-ata_port_init_shost)
>>
>> * fix-new-legacy-handling patch merged into rework-legacy-handling as
>>   Jeff suggested.
>>
>> This patchset is against
>>
>>   libata-dev#upstream [U]
>> This patchset is available in the following git tree.
>>
>>   http://htj.dyndns.org/git/?p=libata-tj.git;a=shortlog;h=tj-upstream
>>   git://htj.dyndns.org/libata-tj tj-upstream
> 
> pulled
> 
> 
>> PATA drivers have been updated accordingly and available at (properly
>> merged)
>>
>>   http://htj.dyndns.org/git/?p=libata-tj.git;a=shortlog;h=tj-pata-drivers
>>   git://htj.dyndns.org/libata-tj tj-pata-drivers
> 
> pulled
> 
> 
>> Updated ALL branch is available at
>>
>>   http://htj.dyndns.org/git/?p=libata-tj.git;a=shortlog;h=tj-ALL
>>   git://htj.dyndns.org/libata-tj tj-ALL
> 
> FWIW, I usually just update this manually.  The process I used for this 
> email's pulls was
> 
> cd /spare/repo/libata-dev
> git checkout upstream
> git pull $url tj-upstream
> git checkout pata-drivers
> git pull . upstream
> git pull $url tj-pata-drivers
> git checkout ALL
> git pull . pata-drivers
> 
> Thus, changes are pulled from upstream to downstream branches.

I see.  For this patchset though, pulling pata-drivers that way would 
give it a small window of commits (probably just one) where pata drivers 
won't build properly.  tj-pata-drivers was built by...

1. pulling #tj-upstream before removing old legacy handling
2. updating #tj-pata-drivers to use new legacy handling
3. killing old legacy handling in #tj-upstream
4. pulling again

Such that pata-drivers doesn't fail to build after upstream merge.  I 
won't make ALL branch from now on and tell you if merge needs some 
special ordering.

Thanks.

-- 
tejun

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

* Re: [PATCHSET] libata: improve initialization and legacy handling, take#3
  2006-08-10 11:32   ` Tejun Heo
@ 2006-08-10 11:59     ` Jeff Garzik
  0 siblings, 0 replies; 13+ messages in thread
From: Jeff Garzik @ 2006-08-10 11:59 UTC (permalink / raw)
  To: Tejun Heo; +Cc: alan, linux-ide

Tejun Heo wrote:
> I see.  For this patchset though, pulling pata-drivers that way would 
> give it a small window of commits (probably just one) where pata drivers 
> won't build properly.  tj-pata-drivers was built by...
> 
> 1. pulling #tj-upstream before removing old legacy handling
> 2. updating #tj-pata-drivers to use new legacy handling
> 3. killing old legacy handling in #tj-upstream
> 4. pulling again

Yeah, usually I fix up brokenness myself.  There is no perfect system :)


> Such that pata-drivers doesn't fail to build after upstream merge.  I 
> won't make ALL branch from now on and tell you if merge needs some 
> special ordering.

Yep, that sounds better.

	Jeff




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

end of thread, other threads:[~2006-08-10 11:59 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-10  8:16 [PATCHSET] libata: improve initialization and legacy handling, take#3 Tejun Heo
2006-08-10  8:16 ` [PATCH 3/9] [libata] Kill 'count' var in ata_device_add() Tejun Heo
2006-08-10  8:16 ` [PATCH 1/9] libata: update ata_host_init() and rename it to ata_port_init_shost() Tejun Heo
2006-08-10  8:16 ` [PATCH 5/9] libata: rework legacy handling to remove much of the cruft Tejun Heo
2006-08-10  8:16 ` [PATCH 6/9] libata: implement dummy port Tejun Heo
2006-08-10  8:16 ` [PATCH 4/9] libata: implement per-dev xfermask Tejun Heo
2006-08-10  8:16 ` [PATCH 2/9] [libata] some function renaming Tejun Heo
2006-08-10  8:16 ` [PATCH 7/9] libata: use dummy port for stolen legacy ports Tejun Heo
2006-08-10  8:16 ` [PATCH 9/9] libata: kill unused hard_port_no and legacy_mode Tejun Heo
2006-08-10  8:16 ` [PATCH 8/9] libata: replace ap->hard_port_no with ap->port_no Tejun Heo
2006-08-10 10:53 ` [PATCHSET] libata: improve initialization and legacy handling, take#3 Jeff Garzik
2006-08-10 11:32   ` Tejun Heo
2006-08-10 11:59     ` Jeff Garzik

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).