Skip to contentSkip to conversation

libata: improve initialization and legacy handling, take#3

PATCH In review Tejun Heo 2 participants 13 messages Aug 10, 2006

Subsystems (3)
lore
Share & tools
lore

Tejun Heo

author
#0 lore raw

PATCH 1/1 libata: improve initialization and legacy handling, take#3

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

author
#1 lore raw

PATCH 1/9 libata: update ata_host_init() and rename it to ata_port_init_shost()

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

---

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

4608c1608501cf2b0dc4478c9b6c3902db58408a

drivers/scsi/libata-core.c +13 -20
index 83d93fc..eb9de07 100644
@@ -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)
Signature · 1 line
1.3.2
author
#2 lore raw

PATCH 2/9 some function renaming

In reply to 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.

---

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

996139f1ce50c56c5e66f86b6aba17ff5ea00b86

drivers/scsi/libata-core.c +10 -11
index eb9de07..3aa477a 100644
@@ -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;
 
Signature · 1 line
1.3.2
author
#3 lore raw

PATCH 3/9 Kill 'count' var in ata_device_add()

In reply to Tejun Heo

Eliminate redundant loop variable 'count'

---

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

6d0500df5b37c94b779ac2c3f522ff917e039f99

drivers/scsi/libata-core.c +7 -13
index 3aa477a..38fc75d 100644
@@ -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;
Signature · 1 line
1.3.2
author
#4 lore raw

PATCH 4/9 libata: implement per-dev xfermask

In reply to 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 <[email protected]>. 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)

---

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

37deecb5139ee431233781a9a093d9fcaab54c5b

drivers/scsi/libata-core.c +11 -29
index 38fc75d..4e6c2e8 100644
@@ -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)
Signature · 1 line
1.3.2
author
#5 lore raw

PATCH 5/9 libata: rework legacy handling to remove much of the cruft

In reply to 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.

---

 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

drivers/scsi/ata_piix.c +0 -2
index 5e8afc8..40ecab5 100644
@@ -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);
 }
 
drivers/scsi/libata-bmdma.c +64 -71

215 lines not on this page · raw message

drivers/scsi/libata-core.c +36 -23

143 lines not on this page · raw message

include/asm-alpha/libata-portmap.h new file +1 -0
new file mode 100644
index 0000000..75484ef
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
include/asm-generic/libata-portmap.h new file +12 -0
new file mode 100644
index 0000000..9202fd0
@@ -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
include/asm-i386/libata-portmap.h new file +1 -0
new file mode 100644
index 0000000..75484ef
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
include/asm-ia64/libata-portmap.h new file +1 -0
new file mode 100644
index 0000000..75484ef
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
include/asm-powerpc/libata-portmap.h new file +1 -0
new file mode 100644
index 0000000..75484ef
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
include/asm-sparc/libata-portmap.h new file +1 -0
new file mode 100644
index 0000000..75484ef
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
include/asm-sparc64/libata-portmap.h new file +1 -0
new file mode 100644
index 0000000..75484ef
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
include/asm-x86_64/libata-portmap.h new file +1 -0
new file mode 100644
index 0000000..75484ef
@@ -0,0 +1 @@
+#include <asm-generic/libata-portmap.h>
include/linux/libata.h +4 -1
index cf5eb1d..4504776 100644
@@ -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];
 };
 
Signature · 1 line
1.3.2
author
#6 lore raw

PATCH 6/9 libata: implement dummy port

In reply to 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.

---

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

dd5b06c490de72440ec39f814de99a714a45a1a9

drivers/scsi/libata-core.c +51 -10
index 3634279..f2e7e2f 100644
@@ -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);
include/linux/libata.h +8 -0
index 4504776..30bfe8f 100644
@@ -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);
Signature · 1 line
1.3.2
author
#7 lore raw

PATCH 7/9 libata: use dummy port for stolen legacy ports

In reply to Tejun Heo

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

---

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

c4b01f1de254820175fe2d02b4cf7c0fab335846

drivers/scsi/libata-bmdma.c +17 -24
index e694f60..158f62d 100644
@@ -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;
 }
drivers/scsi/libata-core.c +0 -2
index f2e7e2f..2ef86b4 100644
@@ -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;
Signature · 1 line
1.3.2
author
#8 lore raw

PATCH 8/9 libata: replace ap->hard_port_no with ap->port_no

In reply to Tejun Heo

Replace ap->hard_port_no with ap->port_no.

---

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

2a88d1ac8dca898a7fb602ddd581bf4d2977509d

drivers/scsi/ata_piix.c +8 -8
index 40ecab5..501755a 100644
@@ -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;
Signature · 1 line
1.3.2
author
#9 lore raw

PATCH 9/9 libata: kill unused hard_port_no and legacy_mode

In reply to Tejun Heo

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

---

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

4852ba24f647199be797545226c6d325db231937

drivers/scsi/libata-core.c +0 -1
index 2ef86b4..3f963f2 100644
@@ -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;
include/linux/libata.h +0 -3
index 30bfe8f..ed749f7 100644
@@ -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 */
Signature · 1 line
1.3.2
#10 lore raw
In reply to Tejun Heo
Quoted 13 lines · Tejun Heo

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.

Quoted 8 lines

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

Quoted 5 lines

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

Quoted 4 lines

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

author
#11 lore raw
Quoted 50 lines · Jeff Garzik
Quoted 13 lines · Tejun Heo

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.

Quoted 7 lines

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

Quoted 5 lines

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

Quoted 4 lines

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

Quoted 1 line

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.

Signature · 1 line
tejun
#12 lore raw
Quoted 6 lines · Tejun Heo

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

Quoted 1 line

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