Skip to contentSkip to conversation

implement ata_link, take 3

PATCH In review Tejun Heo 2 participants 22 messages Oct 15, 2006 – Nov 1, 2006

Subsystems (2)
lore
Share & tools
lore

Tejun Heo

author
#0 lore raw

PATCH 1/1 implement ata_link, take 3

Hello, all.

This is the third take of implement ata_link patchset. This patchset contains 18 patches which can be categorized as follows.

#01-03: prep
#04-05: implement ata_link
#06-09: make libata deal with link instead of port #10-12: misc link stuff (link init, reset_tries, ata_link_abort()) #13-19: add ap->pmp_link[] and update libata to deal with multiple
links

ata_link abstracts PHY and sits between ata_port and ata_device. The following attributes are moved to ata_link from ata_port.

- active command state (active_tag, sactive)
- [hw_]sata_spd_limit
- eh_info and eh_context
- device array

With above and a few extra fields, a link can fully host attached devices including qc management and EH/hotplug. This patchset makes libata ready to handle PM links.

Changes from the last take[L] are.

* updated to fit new #upstream
* __dev1 trick removed

This patchset is against

upstream (da54f5fe54c7d75e2db7d17961fb36a8c28a8501)
+ [1] hp-poll patchset, take #5
+ [2] vt8251-ahci patchset, take #2

Thanks.

--
tejun

[L] http://article.gmane.org/gmane.linux.ide/11928
[1] http://article.gmane.org/gmane.linux.ide/13467
[2] http://article.gmane.org/gmane.linux.ide/13471

author
#1 lore raw

PATCH 1/18 libata: generate hotplug event on SError read failure

ata_eh_autopsy() used to schedule hardreset for phys which failed to return SError, which isn't enough for some cases. Assume the worst and generate hotplug event instead. Note that scr_read() is guaranteed to succeed for host ports. This change affects only PMP links.

---
 drivers/ata/libata-eh.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
drivers/ata/libata-eh.c +4 -2
index 6787fbc..2067db0 100644
@@ -1327,8 +1327,10 @@ static void ata_eh_autopsy(struct ata_po
 	if (rc == 0) {
 		ehc->i.serror |= serror;
 		ata_eh_analyze_serror(ap);
-	} else if (rc != -EOPNOTSUPP)
-		ehc->i.action |= ATA_EH_HARDRESET;
+	} else if (rc != -EOPNOTSUPP) {
+		/* hmmm, assume the worst and generate hotplug event */
+		__ata_ehi_hotplugged(&ehc->i);
+	}
 
 	/* analyze NCQ failure */
 	ata_eh_analyze_ncq_error(ap);
Signature · 1 line
1.4.2.3
author
#2 lore raw

PATCH 2/18 libata-link: separate out ata_eh_handle_dev_fail()

In reply to Tejun Heo

Separate out ata_eh_handle_dev_fail() from ata_eh_recover(). This is in preparation of ata_link and PMP support.

---
 drivers/ata/libata-eh.c |   91 ++++++++++++++++++++++++++---------------------
 1 files changed, 50 insertions(+), 41 deletions(-)
drivers/ata/libata-eh.c +50 -41
index 2067db0..2cbd19d 100644
@@ -1911,6 +1911,55 @@ static int ata_eh_skip_recovery(struct a
 	return 1;
 }
 
+static void ata_eh_handle_dev_fail(struct ata_device *dev, int err,
+				   int down_xfermask)
+{
+	struct ata_port *ap = dev->ap;
+	struct ata_eh_context *ehc = &ap->eh_context;
+
+	switch (err) {
+	case -ENODEV:
+		/* device missing, schedule probing */
+		ehc->i.probe_mask |= (1 << dev->devno);
+	case -EINVAL:
+		ehc->tries[dev->devno] = 0;
+		break;
+	case -EIO:
+		sata_down_spd_limit(ap);
+	default:
+		ehc->tries[dev->devno]--;
+		if (down_xfermask &&
+		    ata_down_xfermask_limit(dev, ehc->tries[dev->devno] == 1))
+			ehc->tries[dev->devno] = 0;
+	}
+
+	if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
+		/* disable device if it has used up all its chances */
+		ata_dev_disable(dev);
+
+		/* detach if offline */
+		if (ata_port_offline(ap))
+			ata_eh_detach_dev(dev);
+
+		/* probe if requested */
+		if ((ehc->i.probe_mask & (1 << dev->devno)) &&
+		    !(ehc->did_probe_mask & (1 << dev->devno))) {
+			ata_eh_detach_dev(dev);
+			ata_dev_init(dev);
+
+			ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
+			ehc->did_probe_mask |= (1 << dev->devno);
+			ehc->i.action |= ATA_EH_SOFTRESET;
+		}
+	} else {
+		/* soft didn't work?  be haaaaard */
+		if (ehc->i.flags & ATA_EHI_DID_RESET)
+			ehc->i.action |= ATA_EH_HARDRESET;
+		else
+			ehc->i.action |= ATA_EH_SOFTRESET;
+	}
+}
+
 /**
  *	ata_eh_recover - recover host port after error
  *	@ap: host port to recover
@@ -2022,47 +2071,7 @@ static int ata_eh_recover(struct ata_por
 	goto out;
 
  dev_fail:
-	switch (rc) {
-	case -ENODEV:
-		/* device missing, schedule probing */
-		ehc->i.probe_mask |= (1 << dev->devno);
-	case -EINVAL:
-		ehc->tries[dev->devno] = 0;
-		break;
-	case -EIO:
-		sata_down_spd_limit(ap);
-	default:
-		ehc->tries[dev->devno]--;
-		if (down_xfermask &&
-		    ata_down_xfermask_limit(dev, ehc->tries[dev->devno] == 1))
-			ehc->tries[dev->devno] = 0;
-	}
-
-	if (ata_dev_enabled(dev) && !ehc->tries[dev->devno]) {
-		/* disable device if it has used up all its chances */
-		ata_dev_disable(dev);
-
-		/* detach if offline */
-		if (ata_port_offline(ap))
-			ata_eh_detach_dev(dev);
-
-		/* probe if requested */
-		if ((ehc->i.probe_mask & (1 << dev->devno)) &&
-		    !(ehc->did_probe_mask & (1 << dev->devno))) {
-			ata_eh_detach_dev(dev);
-			ata_dev_init(dev);
-
-			ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
-			ehc->did_probe_mask |= (1 << dev->devno);
-			ehc->i.action |= ATA_EH_SOFTRESET;
-		}
-	} else {
-		/* soft didn't work?  be haaaaard */
-		if (ehc->i.flags & ATA_EHI_DID_RESET)
-			ehc->i.action |= ATA_EH_HARDRESET;
-		else
-			ehc->i.action |= ATA_EH_SOFTRESET;
-	}
+	ata_eh_handle_dev_fail(dev, rc, down_xfermask);
 
 	if (ata_port_nr_enabled(ap)) {
 		ata_port_printk(ap, KERN_WARNING, "failed to recover some "
Signature · 1 line
1.4.2.3
author
#3 lore raw

PATCH 3/18 libata-link: add PMP related ATA constants

In reply to Tejun Heo

Add Port Multiplier related ATA constants and macros. Some of these will be used by ata_link implementation.

---
 include/linux/ata.h |   29 +++++++++++++++++++++++++++++
 1 files changed, 29 insertions(+), 0 deletions(-)
include/linux/ata.h +29 -0
index 1df9416..123f316 100644
@@ -156,6 +156,8 @@ enum {
 	ATA_CMD_READ_NATIVE_MAX	= 0xF8,
 	ATA_CMD_READ_NATIVE_MAX_EXT = 0x27,
 	ATA_CMD_READ_LOG_EXT	= 0x2f,
+	ATA_CMD_PMP_READ	= 0xE4,
+	ATA_CMD_PMP_WRITE	= 0xE8,
 
 	/* READ_LOG_EXT pages */
 	ATA_LOG_SATA_NCQ	= 0x10,
@@ -196,6 +198,28 @@ enum {
 						   0=to device, 1=to host */
 	ATAPI_CDB_LEN		= 16,
 
+	/* PMP stuff */
+	SATA_PMP_MAX_PORTS	= 15,
+	SATA_PMP_CTRL_PORT	= 15,
+
+	SATA_PMP_GSCR_DWORDS	= 128,
+	SATA_PMP_GSCR_PROD_ID	= 0,
+	SATA_PMP_GSCR_REV	= 1,
+	SATA_PMP_GSCR_PORT_INFO	= 2,
+	SATA_PMP_GSCR_ERROR	= 32,
+	SATA_PMP_GSCR_ERROR_EN	= 33,
+	SATA_PMP_GSCR_FEAT	= 64,
+	SATA_PMP_GSCR_FEAT_EN	= 96,
+
+	SATA_PMP_PSCR_STATUS	= 0,
+	SATA_PMP_PSCR_ERROR	= 1,
+	SATA_PMP_PSCR_CONTROL	= 2,
+
+	SATA_PMP_FEAT_BIST	= (1 << 0),
+	SATA_PMP_FEAT_PMREQ	= (1 << 1),
+	SATA_PMP_FEAT_DYNSSC	= (1 << 2),
+	SATA_PMP_FEAT_NOTIFY	= (1 << 3),
+
 	/* cable types */
 	ATA_CBL_NONE		= 0,
 	ATA_CBL_PATA40		= 1,
@@ -396,4 +420,9 @@ static inline int lba_48_ok(u64 block, u
 	return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536);
 }
 
+#define sata_pmp_gscr_vendor(gscr)	((gscr)[SATA_PMP_GSCR_PROD_ID] & 0xffff)
+#define sata_pmp_gscr_devid(gscr)	((gscr)[SATA_PMP_GSCR_PROD_ID] >> 16)
+#define sata_pmp_gscr_rev(gscr)		(((gscr)[SATA_PMP_GSCR_REV] >> 8) & 0xff)
+#define sata_pmp_gscr_ports(gscr)	((gscr)[SATA_PMP_GSCR_PORT_INFO] & 0xf)
+
 #endif /* __LINUX_ATA_H__ */
Signature · 1 line
1.4.2.3
author
#4 lore raw

PATCH 4/18 libata-link: introduce ata_link

In reply to Tejun Heo

Introduce ata_link. It abstracts PHY and sits between ata_port and ata_device. This new level of abstraction is necessary to support SATA Port Multiplier, which basically adds a bunch of links (PHYs) to a ATA host port. Fields related to command execution, spd_limit and EH are per-link and thus moved to ata_link.

This patch only defines the host link. Multiple link handling will be added later. Also, a lot of ap->link derefences are added but many of them will be removed as each part is converted to deal directly with ata_link instead of ata_port.

This patch introduces no behavior change.

---
 drivers/ata/ahci.c          |   20 +++---
 drivers/ata/ata_generic.c   |    2 -
 drivers/ata/ata_piix.c      |    2 -
 drivers/ata/libata-core.c   |  147 +++++++++++++++++++++++--------------------
 drivers/ata/libata-eh.c     |  106 ++++++++++++++++---------------
 drivers/ata/libata-scsi.c   |   46 +++++++------
 drivers/ata/libata-sff.c    |    4 +
 drivers/ata/pata_it821x.c   |    4 +
 drivers/ata/pata_optidma.c  |    4 +
 drivers/ata/pata_pdc2027x.c |    2 -
 drivers/ata/pata_rz1000.c   |    2 -
 drivers/ata/pata_sis.c      |    2 -
 drivers/ata/pdc_adma.c      |    4 +
 drivers/ata/sata_mv.c       |    6 +-
 drivers/ata/sata_nv.c       |    4 +
 drivers/ata/sata_promise.c  |    4 +
 drivers/ata/sata_qstor.c    |    4 +
 drivers/ata/sata_sil.c      |    8 +-
 drivers/ata/sata_sil24.c    |   10 +--
 drivers/ata/sata_sx4.c      |    4 +
 drivers/ata/sata_via.c      |    2 -
 drivers/ata/sata_vsc.c      |    2 -
 include/linux/libata.h      |   38 +++++++----
 23 files changed, 225 insertions(+), 202 deletions(-)
drivers/ata/ahci.c +10 -10
index 584b6c6..1494c04 100644
@@ -776,7 +776,7 @@ static int ahci_softreset(struct ata_por
 	/* restart engine */
 	ahci_start_engine(port_mmio);
 
-	ata_tf_init(ap->device, &tf);
+	ata_tf_init(ap->link.device, &tf);
 	fis = pp->cmd_tbl;
 
 	/* issue the first D2H Register FIS */
@@ -853,7 +853,7 @@ static int ahci_hardreset(struct ata_por
 	ahci_stop_engine(port_mmio);
 
 	/* clear D2H reception area to properly wait for D2H FIS */
-	ata_tf_init(ap->device, &tf);
+	ata_tf_init(ap->link.device, &tf);
 	tf.command = 0xff;
 	ata_tf_to_fis(&tf, d2h_fis, 0);
 
@@ -880,7 +880,7 @@ static int ahci_vt8251_hardreset(struct 
 
 	ahci_stop_engine(port_mmio);
 
-	rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context));
+	rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->link.eh_context));
 
 	/* vt8251 needs SError cleared for the port to operate */
 	ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR));
@@ -997,7 +997,7 @@ static void ahci_qc_prep(struct ata_queu
 static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
 {
 	struct ahci_port_priv *pp = ap->private_data;
-	struct ata_eh_info *ehi = &ap->eh_info;
+	struct ata_eh_info *ehi = &ap->link.eh_info;
 	unsigned int err_mask = 0, action = 0;
 	struct ata_queued_cmd *qc;
 	u32 serror;
@@ -1044,7 +1044,7 @@ static void ahci_error_intr(struct ata_p
 	ehi->serror |= serror;
 	ehi->action |= action;
 
-	qc = ata_qc_from_tag(ap, ap->active_tag);
+	qc = ata_qc_from_tag(ap, ap->link.active_tag);
 	if (qc)
 		qc->err_mask |= err_mask;
 	else
@@ -1060,7 +1060,7 @@ static void ahci_host_intr(struct ata_po
 {
 	void __iomem *mmio = ap->host->mmio_base;
 	void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
-	struct ata_eh_info *ehi = &ap->eh_info;
+	struct ata_eh_info *ehi = &ap->link.eh_info;
 	u32 status, qc_active;
 	int rc;
 
@@ -1072,7 +1072,7 @@ static void ahci_host_intr(struct ata_po
 		return;
 	}
 
-	if (ap->sactive)
+	if (ap->link.sactive)
 		qc_active = readl(port_mmio + PORT_SCR_ACT);
 	else
 		qc_active = readl(port_mmio + PORT_CMD_ISSUE);
@@ -1090,17 +1090,17 @@ static void ahci_host_intr(struct ata_po
 	/* hmmm... a spurious interupt */
 
 	/* some devices send D2H reg with I bit set during NCQ command phase */
-	if (ap->sactive && status & PORT_IRQ_D2H_REG_FIS)
+	if (ap->link.sactive && status & PORT_IRQ_D2H_REG_FIS)
 		return;
 
 	/* ignore interim PIO setup fis interrupts */
-	if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS))
+	if (ata_tag_valid(ap->link.active_tag) && (status & PORT_IRQ_PIOS_FIS))
 		return;
 
 	if (ata_ratelimit())
 		ata_port_printk(ap, KERN_INFO, "spurious interrupt "
 				"(irq_stat 0x%x active_tag %d sactive 0x%x)\n",
-				status, ap->active_tag, ap->sactive);
+				status, ap->link.active_tag, ap->link.sactive);
 }
 
 static void ahci_irq_clear(struct ata_port *ap)
drivers/ata/ata_generic.c +1 -1
index 75e0bb5..eac2c16 100644
@@ -81,7 +81,7 @@ static void generic_set_mode(struct ata_
 		dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
 
 	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		struct ata_device *dev = &ap->device[i];
+		struct ata_device *dev = &ap->link.device[i];
 		if (ata_dev_enabled(dev)) {
 			/* We don't really care */
 			dev->pio_mode = XFER_PIO_0;
drivers/ata/ata_piix.c +1 -1
index 99a4ce5..245a671 100644
@@ -700,7 +700,7 @@ static int ich_pata_prereset(struct ata_
 
 	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;
+		ap->link.eh_context.i.action &= ~ATA_EH_RESET_MASK;
 		return 0;
 	}
 
drivers/ata/libata-core.c +78 -69

465 lines not on this page · raw message

drivers/ata/libata-eh.c +54 -52

360 lines not on this page · raw message

drivers/ata/libata-scsi.c +24 -22

153 lines not on this page · raw message

drivers/ata/libata-sff.c +2 -2
index 06daaa3..083234c 100644
@@ -714,12 +714,12 @@ void ata_bmdma_drive_eh(struct ata_port 
 			ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
 			ata_postreset_fn_t postreset)
 {
-	struct ata_eh_context *ehc = &ap->eh_context;
+	struct ata_eh_context *ehc = &ap->link.eh_context;
 	struct ata_queued_cmd *qc;
 	unsigned long flags;
 	int thaw = 0;
 
-	qc = __ata_qc_from_tag(ap, ap->active_tag);
+	qc = __ata_qc_from_tag(ap, ap->link.active_tag);
 	if (qc && !(qc->flags & ATA_QCFLAG_FAILED))
 		qc = NULL;
 
drivers/ata/pata_it821x.c +2 -2
index 18ff3e5..d883906 100644
@@ -416,7 +416,7 @@ static void it821x_passthru_dev_select(s
 {
 	struct it821x_dev *itdev = ap->private_data;
 	if (itdev && device != itdev->last_device) {
-		struct ata_device *adev = &ap->device[device];
+		struct ata_device *adev = &ap->link.device[device];
 		it821x_program(ap, adev, itdev->pio[adev->devno]);
 		itdev->last_device = device;
 	}
@@ -494,7 +494,7 @@ static void it821x_smart_set_mode(struct
 		dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
 
 	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		struct ata_device *dev = &ap->device[i];
+		struct ata_device *dev = &ap->link.device[i];
 		if (ata_dev_enabled(dev)) {
 			/* We don't really care */
 			dev->pio_mode = XFER_PIO_0;
drivers/ata/pata_optidma.c +2 -2
index c6906b4..c58c135 100644
@@ -338,8 +338,8 @@ static void optidma_post_set_mode(struct
 	pci_read_config_byte(pdev, 0x43, &r);
 
 	r &= (0x0F << nybble);
-	r |= (optidma_make_bits43(&ap->device[0]) +
-	     (optidma_make_bits43(&ap->device[0]) << 2)) << nybble;
+	r |= (optidma_make_bits43(&ap->link.device[0]) +
+	     (optidma_make_bits43(&ap->link.device[0]) << 2)) << nybble;
 
 	pci_write_config_byte(pdev, 0x43, r);
 }
drivers/ata/pata_pdc2027x.c +1 -1
index 56e0287..09c01ca 100644
@@ -456,7 +456,7 @@ static void pdc2027x_post_set_mode(struc
 	int i;
 
 	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		struct ata_device *dev = &ap->device[i];
+		struct ata_device *dev = &ap->link.device[i];
 
 		if (ata_dev_enabled(dev)) {
 
drivers/ata/pata_rz1000.c +1 -1
index 4533b63..b59fafd 100644
@@ -63,7 +63,7 @@ static void rz1000_set_mode(struct ata_p
 	int i;
 
 	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		struct ata_device *dev = &ap->device[i];
+		struct ata_device *dev = &ap->link.device[i];
 		if (ata_dev_enabled(dev)) {
 			/* We don't really care */
 			dev->pio_mode = XFER_PIO_0;
drivers/ata/pata_sis.c +1 -1
index b9ffafb..886e449 100644
@@ -53,7 +53,7 @@ struct sis_chipset {
 
 static int sis_port_base(struct ata_device *adev)
 {
-	return  0x40 + (4 * adev->ap->port_no) +  (2 * adev->devno);
+	return  0x40 + (4 * adev->link->ap->port_no) +  (2 * adev->devno);
 }
 
 /**
drivers/ata/pdc_adma.c +2 -2
index 9021e34..53f523e 100644
@@ -461,7 +461,7 @@ static inline unsigned int adma_intr_pkt
 		pp = ap->private_data;
 		if (!pp || pp->state != adma_state_pkt)
 			continue;
-		qc = ata_qc_from_tag(ap, ap->active_tag);
+		qc = ata_qc_from_tag(ap, ap->link.active_tag);
 		if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
 			if ((status & (aPERR | aPSD | aUIRQ)))
 				qc->err_mask |= AC_ERR_OTHER;
@@ -486,7 +486,7 @@ static inline unsigned int adma_intr_mmi
 			struct adma_port_priv *pp = ap->private_data;
 			if (!pp || pp->state != adma_state_mmio)
 				continue;
-			qc = ata_qc_from_tag(ap, ap->active_tag);
+			qc = ata_qc_from_tag(ap, ap->link.active_tag);
 			if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
 
 				/* check main status, clearing INTRQ */
drivers/ata/sata_mv.c +3 -3
index 1b8e0eb..9776a67 100644
@@ -1417,7 +1417,7 @@ static void mv_host_intr(struct ata_host
 		}
 
 		if (handled) {
-			qc = ata_qc_from_tag(ap, ap->active_tag);
+			qc = ata_qc_from_tag(ap, ap->link.active_tag);
 			if (qc && (qc->flags & ATA_QCFLAG_ACTIVE)) {
 				VPRINTK("port %u IRQ found for qc, "
 					"ata_status 0x%x\n", port,ata_status);
@@ -1938,7 +1938,7 @@ static void __mv_phy_reset(struct ata_po
 	struct mv_host_priv *hpriv = ap->host->private_data;
 	void __iomem *port_mmio = mv_ap_base(ap);
 	struct ata_taskfile tf;
-	struct ata_device *dev = &ap->device[0];
+	struct ata_device *dev = &ap->link.device[0];
 	unsigned long timeout;
 	int retry = 5;
 	u32 sstatus;
@@ -2045,7 +2045,7 @@ static void mv_eng_timeout(struct ata_po
 	mv_dump_all_regs(ap->host->mmio_base, ap->port_no,
 			 to_pci_dev(ap->host->dev));
 
-	qc = ata_qc_from_tag(ap, ap->active_tag);
+	qc = ata_qc_from_tag(ap, ap->link.active_tag);
         printk(KERN_ERR "mmio_base %p ap %p qc %p scsi_cmnd %p &cmnd %p\n",
 	       ap->host->mmio_base, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd);
 
drivers/ata/sata_nv.c +2 -2
index fcdae1a..f5c22de 100644
@@ -297,7 +297,7 @@ static irqreturn_t nv_generic_interrupt(
 		    !(ap->flags & ATA_FLAG_DISABLED)) {
 			struct ata_queued_cmd *qc;
 
-			qc = ata_qc_from_tag(ap, ap->active_tag);
+			qc = ata_qc_from_tag(ap, ap->link.active_tag);
 			if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
 				handled += ata_host_intr(ap, qc);
 			else
@@ -315,7 +315,7 @@ static irqreturn_t nv_generic_interrupt(
 
 static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
 {
-	struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
+	struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
 	int handled;
 
 	/* freeze if hotplugged */
drivers/ata/sata_promise.c +2 -2
index 72eda51..f9faf80 100644
@@ -436,7 +436,7 @@ static void pdc_eng_timeout(struct ata_p
 
 	spin_lock_irqsave(&host->lock, flags);
 
-	qc = ata_qc_from_tag(ap, ap->active_tag);
+	qc = ata_qc_from_tag(ap, ap->link.active_tag);
 
 	switch (qc->tf.protocol) {
 	case ATA_PROT_DMA:
@@ -543,7 +543,7 @@ static irqreturn_t pdc_interrupt (int ir
 		    !(ap->flags & ATA_FLAG_DISABLED)) {
 			struct ata_queued_cmd *qc;
 
-			qc = ata_qc_from_tag(ap, ap->active_tag);
+			qc = ata_qc_from_tag(ap, ap->link.active_tag);
 			if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
 				handled += pdc_host_intr(ap, qc);
 		}
drivers/ata/sata_qstor.c +2 -2
index 710909d..bf1f3e2 100644
@@ -400,7 +400,7 @@ static inline unsigned int qs_intr_pkt(s
 				struct qs_port_priv *pp = ap->private_data;
 				if (!pp || pp->state != qs_state_pkt)
 					continue;
-				qc = ata_qc_from_tag(ap, ap->active_tag);
+				qc = ata_qc_from_tag(ap, ap->link.active_tag);
 				if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
 					switch (sHST) {
 					case 0: /* successful CPB */
@@ -433,7 +433,7 @@ static inline unsigned int qs_intr_mmio(
 			struct qs_port_priv *pp = ap->private_data;
 			if (!pp || pp->state != qs_state_mmio)
 				continue;
-			qc = ata_qc_from_tag(ap, ap->active_tag);
+			qc = ata_qc_from_tag(ap, ap->link.active_tag);
 			if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
 
 				/* check main status, clearing INTRQ */
drivers/ata/sata_sil.c +4 -4
index 1b2e36a..3d6e355 100644
@@ -303,7 +303,7 @@ static void sil_post_set_mode (struct at
 	unsigned int i;
 
 	for (i = 0; i < 2; i++) {
-		dev = &ap->device[i];
+		dev = &ap->link.device[i];
 		if (!ata_dev_enabled(dev))
 			dev_mode[i] = 0;	/* PIO0/1/2 */
 		else if (dev->flags & ATA_DFLAG_PIO)
@@ -357,7 +357,7 @@ static void sil_scr_write (struct ata_po
 
 static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
 {
-	struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
+	struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
 	u8 status;
 
 	if (unlikely(bmdma2 & SIL_DMA_SATA_IRQ)) {
@@ -376,8 +376,8 @@ static void sil_host_intr(struct ata_por
 		 * repeat probing needlessly.
 		 */
 		if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
-			ata_ehi_hotplugged(&ap->eh_info);
-			ap->eh_info.serror |= serror;
+			ata_ehi_hotplugged(&ap->link.eh_info);
+			ap->link.eh_info.serror |= serror;
 		}
 
 		goto freeze;
drivers/ata/sata_sil24.c +5 -5
index c84efc3..ea1e3e5 100644
@@ -764,7 +764,7 @@ static void sil24_thaw(struct ata_port *
 static void sil24_error_intr(struct ata_port *ap)
 {
 	void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
-	struct ata_eh_info *ehi = &ap->eh_info;
+	struct ata_eh_info *ehi = &ap->link.eh_info;
 	int freeze = 0;
 	u32 irq_stat;
 
@@ -816,7 +816,7 @@ static void sil24_error_intr(struct ata_
 		}
 
 		/* record error info */
-		qc = ata_qc_from_tag(ap, ap->active_tag);
+		qc = ata_qc_from_tag(ap, ap->link.active_tag);
 		if (qc) {
 			sil24_update_tf(ap);
 			qc->err_mask |= err_mask;
@@ -860,7 +860,7 @@ static inline void sil24_host_intr(struc
 	if (rc > 0)
 		return;
 	if (rc < 0) {
-		struct ata_eh_info *ehi = &ap->eh_info;
+		struct ata_eh_info *ehi = &ap->link.eh_info;
 		ehi->err_mask |= AC_ERR_HSM;
 		ehi->action |= ATA_EH_SOFTRESET;
 		ata_port_freeze(ap);
@@ -870,7 +870,7 @@ static inline void sil24_host_intr(struc
 	if (ata_ratelimit())
 		ata_port_printk(ap, KERN_INFO, "spurious interrupt "
 			"(slot_stat 0x%x active_tag %d sactive 0x%x)\n",
-			slot_stat, ap->active_tag, ap->sactive);
+			slot_stat, ap->link.active_tag, ap->link.sactive);
 }
 
 static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
@@ -912,7 +912,7 @@ static irqreturn_t sil24_interrupt(int i
 
 static void sil24_error_handler(struct ata_port *ap)
 {
-	struct ata_eh_context *ehc = &ap->eh_context;
+	struct ata_eh_context *ehc = &ap->link.eh_context;
 
 	if (sil24_init_port(ap)) {
 		ata_eh_freeze_port(ap);
drivers/ata/sata_sx4.c +2 -2
index ae7992d..6ad990d 100644
@@ -837,7 +837,7 @@ static irqreturn_t pdc20621_interrupt (i
 		    !(ap->flags & ATA_FLAG_DISABLED)) {
 			struct ata_queued_cmd *qc;
 
-			qc = ata_qc_from_tag(ap, ap->active_tag);
+			qc = ata_qc_from_tag(ap, ap->link.active_tag);
 			if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
 				handled += pdc20621_host_intr(ap, qc, (i > 4),
 							      mmio_base);
@@ -864,7 +864,7 @@ static void pdc_eng_timeout(struct ata_p
 
 	spin_lock_irqsave(&host->lock, flags);
 
-	qc = ata_qc_from_tag(ap, ap->active_tag);
+	qc = ata_qc_from_tag(ap, ap->link.active_tag);
 
 	switch (qc->tf.protocol) {
 	case ATA_PROT_DMA:
drivers/ata/sata_via.c +1 -1
index f4455a1..6978bc8 100644
@@ -224,7 +224,7 @@ static void svia_scr_write (struct ata_p
  */
 static int vt6420_prereset(struct ata_port *ap)
 {
-	struct ata_eh_context *ehc = &ap->eh_context;
+	struct ata_eh_context *ehc = &ap->link.eh_context;
 	unsigned long timeout = jiffies + (HZ * 5);
 	u32 sstatus, scontrol;
 	int online;
drivers/ata/sata_vsc.c +1 -1
index c92fb0d..631b0cd 100644
@@ -231,7 +231,7 @@ static irqreturn_t vsc_sata_interrupt (i
 			if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
 				struct ata_queued_cmd *qc;
 
-				qc = ata_qc_from_tag(ap, ap->active_tag);
+				qc = ata_qc_from_tag(ap, ap->link.active_tag);
 				if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
 					handled += ata_host_intr(ap, qc);
 				else if (is_vsc_sata_int_err(i, int_status)) {
include/linux/libata.h +24 -14
index 832c500..fb6d334 100644
@@ -467,7 +467,7 @@ struct ata_ering {
 };
 
 struct ata_device {
-	struct ata_port		*ap;
+	struct ata_link		*link;
 	unsigned int		devno;		/* 0 or 1 */
 	unsigned long		flags;		/* ATA_DFLAG_xxx */
 	struct scsi_device	*sdev;		/* attached SCSI device */
@@ -527,6 +527,23 @@ struct ata_eh_context {
 	unsigned int		did_probe_mask;
 };
 
+struct ata_link {
+	struct ata_port		*ap;
+
+	unsigned int		active_tag;	/* active tag on this link */
+	u32			sactive;	/* active NCQ commands */
+
+	unsigned int		hw_sata_spd_limit;
+	unsigned int		sata_spd_limit;
+
+	/* record runtime error info, protected by host_set lock */
+	struct ata_eh_info	eh_info;
+	/* EH context */
+	struct ata_eh_context	eh_context;
+
+	struct ata_device	device[ATA_MAX_DEVICES];
+};
+
 struct ata_port {
 	struct Scsi_Host	*scsi_host; /* our co-allocated scsi host */
 	const struct ata_port_operations *ops;
@@ -550,22 +567,12 @@ struct ata_port {
 	unsigned int		mwdma_mask;
 	unsigned int		udma_mask;
 	unsigned int		cbl;	/* cable type; ATA_CBL_xxx */
-	unsigned int		hw_sata_spd_limit;
-	unsigned int		sata_spd_limit;	/* SATA PHY speed limit */
-
-	/* record runtime error info, protected by host lock */
-	struct ata_eh_info	eh_info;
-	/* EH context owned by EH */
-	struct ata_eh_context	eh_context;
-
-	struct ata_device	device[ATA_MAX_DEVICES];
 
 	struct ata_queued_cmd	qcmd[ATA_MAX_QUEUE];
 	unsigned long		qc_allocated;
 	unsigned int		qc_active;
 
-	unsigned int		active_tag;
-	u32			sactive;
+	struct ata_link		link;	/* host default link */
 
 	struct ata_port_stats	stats;
 	struct ata_host		*host;
@@ -898,8 +905,11 @@ extern void ata_do_eh(struct ata_port *a
 #define ata_port_printk(ap, lv, fmt, args...) \
 	printk(lv"ata%u: "fmt, (ap)->id , ##args)
 
+#define ata_link_printk(link, lv, fmt, args...) \
+	printk(lv"ata%u: "fmt, (link)->ap->id , ##args)
+
 #define ata_dev_printk(dev, lv, fmt, args...) \
-	printk(lv"ata%u.%02u: "fmt, (dev)->ap->id, (dev)->devno , ##args)
+	printk(lv"ata%u.%02u: "fmt, (dev)->link->ap->id, (dev)->devno , ##args)
 
 /*
  * ata_eh_info helpers
@@ -1137,7 +1147,7 @@ static inline void ata_tf_init(struct at
 {
 	memset(tf, 0, sizeof(*tf));
 
-	tf->ctl = dev->ap->ctl;
+	tf->ctl = dev->link->ap->ctl;
 	if (dev->devno == 0)
 		tf->device = ATA_DEVICE_OBS;
 	else
Signature · 1 line
1.4.2.3
author
#5 lore raw

PATCH 5/18 libata-link: implement and use link/device iterators

In reply to Tejun Heo

Multiple links and different number of devices per link should be considered to iterate over links and devices. This patch implements and uses link and device iterators - ata_port_for_each_link() and ata_link_for_each_dev() - and ata_link_max_devices().

This change makes a lot of functions iterate over only possible devices instead of from dev 0 to dev ATA_MAX_DEVICES. All such changes have been examined and nothing should be broken.

While at it, add a separating comment before device helpers to distinguish them better from link helpers and others.

---
 drivers/ata/ata_generic.c   |    7 +-
 drivers/ata/ata_piix.c      |    9 ++-
 drivers/ata/libata-core.c   |   74 ++++++++++------------
 drivers/ata/libata-eh.c     |  142 ++++++++++++++++++++-----------------------
 drivers/ata/libata-scsi.c   |   26 +++-----
 drivers/ata/pata_it821x.c   |    7 +-
 drivers/ata/pata_legacy.c   |    5 +-
 drivers/ata/pata_pdc2027x.c |    6 +-
 drivers/ata/pata_rz1000.c   |    5 +-
 include/linux/libata.h      |   14 +++-
 10 files changed, 137 insertions(+), 158 deletions(-)
drivers/ata/ata_generic.c +3 -4
index eac2c16..e060fee 100644
@@ -74,21 +74,20 @@ static void generic_error_handler(struct
 static void generic_set_mode(struct ata_port *ap)
 {
 	int dma_enabled = 0;
-	int i;
+	struct ata_device *dev;
 
 	/* Bits 5 and 6 indicate if DMA is active on master/slave */
 	if (ap->ioaddr.bmdma_addr)
 		dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
 
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		struct ata_device *dev = &ap->link.device[i];
+	ata_link_for_each_dev(dev, &ap->link) {
 		if (ata_dev_enabled(dev)) {
 			/* We don't really care */
 			dev->pio_mode = XFER_PIO_0;
 			dev->dma_mode = XFER_MW_DMA_0;
 			/* We do need the right mode information for DMA or PIO
 			   and this comes from the current configuration flags */
-			if (dma_enabled & (1 << (5 + i))) {
+			if (dma_enabled & (1 << (5 + dev->devno))) {
 				dev->xfer_mode = XFER_MW_DMA_0;
 				dev->xfer_shift = ATA_SHIFT_MWDMA;
 				dev->flags &= ~ATA_DFLAG_PIO;
drivers/ata/ata_piix.c +5 -4
index 245a671..ffeaf65 100644
@@ -774,7 +774,8 @@ static unsigned int piix_sata_present_ma
 static int piix_sata_softreset(struct ata_port *ap, unsigned int *classes)
 {
 	unsigned int present_mask;
-	int i, rc;
+	struct ata_device *dev;
+	int rc;
 
 	present_mask = piix_sata_present_mask(ap);
 
@@ -782,9 +783,9 @@ static int piix_sata_softreset(struct at
 	if (rc)
 		return rc;
 
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		if (!(present_mask & (1 << i)))
-			classes[i] = ATA_DEV_NONE;
+	ata_link_for_each_dev(dev, &ap->link) {
+		if (!(present_mask & (1 << dev->devno)))
+			classes[dev->devno] = ATA_DEV_NONE;
 	}
 
 	return 0;
drivers/ata/libata-core.c +32 -42

190 lines not on this page · raw message

drivers/ata/libata-eh.c +67 -75

327 lines not on this page · raw message

drivers/ata/libata-scsi.c +10 -16
index a8d988e..771097d 100644
@@ -543,7 +543,7 @@ int ata_scsi_device_resume(struct scsi_d
 	/* We don't want autopsy and verbose EH messages.  Disable
 	 * those if we're the only device on this link.
 	 */
-	if (ata_port_max_devices(ap) == 1)
+	if (ata_link_max_devices(dev->link) == 1)
 		ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
 
 	ata_port_schedule_eh(ap);
@@ -2521,7 +2521,7 @@ static unsigned int atapi_xlat(struct at
 
 static struct ata_device * ata_find_dev(struct ata_port *ap, int id)
 {
-	if (likely(id < ATA_MAX_DEVICES))
+	if (likely(id < ata_link_max_devices(&ap->link)))
 		return &ap->link.device[id];
 	return NULL;
 }
@@ -2975,19 +2975,18 @@ void ata_scsi_simulate(struct ata_device
 
 void ata_scsi_scan_host(struct ata_port *ap)
 {
-	unsigned int i;
+	struct ata_device *dev;
 
 	if (ap->flags & ATA_FLAG_DISABLED)
 		return;
 
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		struct ata_device *dev = &ap->link.device[i];
+	ata_link_for_each_dev(dev, &ap->link) {
 		struct scsi_device *sdev;
 
 		if (!ata_dev_enabled(dev) || dev->sdev)
 			continue;
 
-		sdev = __scsi_add_device(ap->scsi_host, 0, i, 0, NULL);
+		sdev = __scsi_add_device(ap->scsi_host, 0, dev->devno, 0, NULL);
 		if (!IS_ERR(sdev)) {
 			dev->sdev = sdev;
 			scsi_device_put(sdev);
@@ -3093,7 +3092,7 @@ static void ata_scsi_remove_dev(struct a
 void ata_scsi_hotplug(void *data)
 {
 	struct ata_port *ap = data;
-	int i;
+	struct ata_device *dev;
 
 	if (ap->pflags & ATA_PFLAG_UNLOADING) {
 		DPRINTK("ENTER/EXIT - unloading\n");
@@ -3103,8 +3102,7 @@ void ata_scsi_hotplug(void *data)
 	DPRINTK("ENTER\n");
 
 	/* unplug detached devices */
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		struct ata_device *dev = &ap->link.device[i];
+	ata_link_for_each_dev(dev, &ap->link) {
 		unsigned long flags;
 
 		if (!(dev->flags & ATA_DFLAG_DETACHED))
@@ -3124,8 +3122,7 @@ void ata_scsi_hotplug(void *data)
 	 * failed silently.  Requeue if there are enabled but
 	 * unattached devices.
 	 */
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		struct ata_device *dev = &ap->link.device[i];
+	ata_link_for_each_dev(dev, &ap->link) {
 		if (ata_dev_enabled(dev) && !dev->sdev) {
 			queue_delayed_work(ata_aux_wq, &ap->hotplug_task, HZ);
 			break;
@@ -3169,7 +3166,7 @@ static int ata_scsi_user_scan(struct Scs
 	spin_lock_irqsave(ap->lock, flags);
 
 	if (id == SCAN_WILD_CARD) {
-		ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1;
+		ehi->probe_mask |= (1 << ata_link_max_devices(&ap->link)) - 1;
 		ehi->action |= ATA_EH_SOFTRESET;
 	} else {
 		struct ata_device *dev = ata_find_dev(ap, id);
@@ -3206,11 +3203,8 @@ void ata_scsi_dev_rescan(void *data)
 {
 	struct ata_port *ap = data;
 	struct ata_device *dev;
-	unsigned int i;
-
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		dev = &ap->link.device[i];
 
+	ata_link_for_each_dev(dev, &ap->link) {
 		if (ata_dev_enabled(dev) && dev->sdev)
 			scsi_rescan_device(&(dev->sdev->sdev_gendev));
 	}
drivers/ata/pata_it821x.c +3 -4
index d883906..98fcd8a 100644
@@ -486,22 +486,21 @@ static unsigned int it821x_passthru_qc_i
 static void it821x_smart_set_mode(struct ata_port *ap)
 {
 	int dma_enabled = 0;
-	int i;
+	struct ata_device *dev;
 
 	/* Bits 5 and 6 indicate if DMA is active on master/slave */
 	/* It is possible that BMDMA isn't allocated */
 	if (ap->ioaddr.bmdma_addr)
 		dma_enabled = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
 
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		struct ata_device *dev = &ap->link.device[i];
+	ata_link_for_each_dev(dev, &ap->link) {
 		if (ata_dev_enabled(dev)) {
 			/* We don't really care */
 			dev->pio_mode = XFER_PIO_0;
 			dev->dma_mode = XFER_MW_DMA_0;
 			/* We do need the right mode information for DMA or PIO
 			   and this comes from the current configuration flags */
-			if (dma_enabled & (1 << (5 + i))) {
+			if (dma_enabled & (1 << (5 + dev->devno))) {
 				dev->xfer_mode = XFER_MW_DMA_0;
 				dev->xfer_shift = ATA_SHIFT_MWDMA;
 				dev->flags &= ~ATA_DFLAG_PIO;
drivers/ata/pata_legacy.c +2 -3
index 10231ef..613c915 100644
@@ -107,10 +107,9 @@ static int pio_mask = 0x1F;		/* PIO rang
 
 static void legacy_set_mode(struct ata_port *ap)
 {
-	int i;
+	struct ata_device *dev;
 
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		struct ata_device *dev = &ap->device[i];
+	ata_link_for_each_dev(dev, &ap->link) {
 		if (ata_dev_enabled(dev)) {
 			dev->pio_mode = XFER_PIO_0;
 			dev->xfer_mode = XFER_PIO_0;
drivers/ata/pata_pdc2027x.c +2 -4
index 09c01ca..6d60dbe 100644
@@ -453,11 +453,9 @@ static void pdc2027x_set_dmamode(struct 
  */
 static void pdc2027x_post_set_mode(struct ata_port *ap)
 {
-	int i;
-
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		struct ata_device *dev = &ap->link.device[i];
+	struct ata_device *dev;
 
+	ata_link_for_each_dev(dev, &ap->link) {
 		if (ata_dev_enabled(dev)) {
 
 			pdc2027x_set_piomode(ap, dev);
drivers/ata/pata_rz1000.c +2 -3
index b59fafd..c231631 100644
@@ -60,10 +60,9 @@ static void rz1000_error_handler(struct 
 
 static void rz1000_set_mode(struct ata_port *ap)
 {
-	int i;
+	struct ata_device *dev;
 
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		struct ata_device *dev = &ap->link.device[i];
+	ata_link_for_each_dev(dev, &ap->link) {
 		if (ata_dev_enabled(dev)) {
 			/* We don't really care */
 			dev->pio_mode = XFER_PIO_0;
include/linux/libata.h +11 -3
index fb6d334..48503d4 100644
@@ -1032,15 +1032,23 @@ static inline unsigned int ata_dev_ready
 }
 
 /*
- * port helpers
+ * link helpers
  */
-static inline int ata_port_max_devices(const struct ata_port *ap)
+static inline int ata_link_max_devices(const struct ata_link *link)
 {
-	if (ap->flags & ATA_FLAG_SLAVE_POSS)
+	if (link->ap->flags & ATA_FLAG_SLAVE_POSS)
 		return 2;
 	return 1;
 }
 
+#define ata_port_for_each_link(lk, ap) \
+	for ((lk) = &(ap)->link; (lk); (lk) = NULL)
+
+#define ata_link_for_each_dev(dev, link) \
+	for ((dev) = (link)->device; \
+	     (dev) - (link)->device < ata_link_max_devices(link) || (dev = NULL); \
+	     (dev)++)
+
 
 static inline u8 ata_chk_status(struct ata_port *ap)
 {
Signature · 1 line
1.4.2.3
author
#6 lore raw

PATCH 6/18 libata-link: linkify PHY-related functions

In reply to Tejun Heo

Make the following PHY-related functions to deal with ata_link instead of ata_port.

* sata_print_link_status()
* sata_down_spd_limit()
* ata_set_sata_spd_limit() and friends
* sata_link_debounce/resume()
* sata_scr_valid/read/write/write_flush()
* ata_link_on/offline()

This patch introduces no behavior change.

---
 drivers/ata/ahci.c        |    6 +
 drivers/ata/libata-core.c |  231 ++++++++++++++++++++++++---------------------
 drivers/ata/libata-eh.c   |   24 +++--
 drivers/ata/libata-sff.c  |    2 
 drivers/ata/libata.h      |    4 -
 drivers/ata/sata_mv.c     |   14 +--
 drivers/ata/sata_sil24.c  |   10 +-
 include/linux/libata.h    |   19 ++--
 8 files changed, 166 insertions(+), 144 deletions(-)
drivers/ata/ahci.c +3 -3
index 1494c04..2888144 100644
@@ -747,7 +747,7 @@ static int ahci_softreset(struct ata_por
 
 	DPRINTK("ENTER\n");
 
-	if (ata_port_offline(ap)) {
+	if (ata_link_offline(&ap->link)) {
 		DPRINTK("PHY reports no device\n");
 		*class = ATA_DEV_NONE;
 		return 0;
@@ -820,7 +820,7 @@ static int ahci_softreset(struct ata_por
 	msleep(150);
 
 	*class = ATA_DEV_NONE;
-	if (ata_port_online(ap)) {
+	if (ata_link_online(&ap->link)) {
 		if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
 			rc = -EIO;
 			reason = "device not ready";
@@ -861,7 +861,7 @@ static int ahci_hardreset(struct ata_por
 
 	ahci_start_engine(port_mmio);
 
-	if (rc == 0 && ata_port_online(ap))
+	if (rc == 0 && ata_link_online(&ap->link))
 		*class = ahci_dev_classify(ap);
 	if (*class == ATA_DEV_UNKNOWN)
 		*class = ATA_DEV_NONE;
drivers/ata/libata-core.c +125 -106

650 lines not on this page · raw message

drivers/ata/libata-eh.c +13 -11
index bfae7fa..9cf41c4 100644
@@ -1290,7 +1290,7 @@ static int ata_eh_speed_down(struct ata_
 		return 0;
 
 	/* speed down SATA link speed if possible */
-	if (sata_down_spd_limit(dev->link->ap) == 0)
+	if (sata_down_spd_limit(dev->link) == 0)
 		return ATA_EH_HARDRESET;
 
 	/* lower transfer mode */
@@ -1315,7 +1315,8 @@ static int ata_eh_speed_down(struct ata_
  */
 static void ata_eh_autopsy(struct ata_port *ap)
 {
-	struct ata_eh_context *ehc = &ap->link.eh_context;
+	struct ata_link *link = &ap->link;
+	struct ata_eh_context *ehc = &link->eh_context;
 	unsigned int all_err_mask = 0;
 	int tag, is_io = 0;
 	u32 serror;
@@ -1327,7 +1328,7 @@ static void ata_eh_autopsy(struct ata_po
 		return;
 
 	/* obtain and analyze SError */
-	rc = sata_scr_read(ap, SCR_ERROR, &serror);
+	rc = sata_scr_read(link, SCR_ERROR, &serror);
 	if (rc == 0) {
 		ehc->i.serror |= serror;
 		ata_eh_analyze_serror(ap);
@@ -1515,7 +1516,8 @@ static int ata_eh_reset(struct ata_port 
 			ata_prereset_fn_t prereset, ata_reset_fn_t softreset,
 			ata_reset_fn_t hardreset, ata_postreset_fn_t postreset)
 {
-	struct ata_eh_context *ehc = &ap->link.eh_context;
+	struct ata_link *link = &ap->link;
+	struct ata_eh_context *ehc = &link->eh_context;
 	unsigned int *classes = ehc->classes;
 	int tries = ATA_EH_RESET_TRIES;
 	int verbose = !(ehc->i.flags & ATA_EHI_QUIET);
@@ -1532,7 +1534,7 @@ static int ata_eh_reset(struct ata_port 
 	 */
 	action = ehc->i.action;
 	ehc->i.action &= ~ATA_EH_RESET_MASK;
-	if (softreset && (!hardreset || (!sata_set_spd_needed(ap) &&
+	if (softreset && (!hardreset || (!sata_set_spd_needed(link) &&
 					 !(action & ATA_EH_HARDRESET))))
 		ehc->i.action |= ATA_EH_SOFTRESET;
 	else
@@ -1558,7 +1560,7 @@ static int ata_eh_reset(struct ata_port 
 		reset = softreset;
 	else {
 		/* prereset told us not to reset, bang classes and return */
-		ata_link_for_each_dev(dev, &ap->link)
+		ata_link_for_each_dev(dev, link)
 			classes[dev->devno] = ATA_DEV_NONE;
 		return 0;
 	}
@@ -1625,7 +1627,7 @@ static int ata_eh_reset(struct ata_port 
 		ssleep(5);
 
 		if (reset == hardreset)
-			sata_down_spd_limit(ap);
+			sata_down_spd_limit(link);
 		if (hardreset)
 			reset = hardreset;
 		goto retry;
@@ -1635,7 +1637,7 @@ static int ata_eh_reset(struct ata_port 
 		/* After the reset, the device state is PIO 0 and the
 		 * controller state is undefined.  Record the mode.
 		 */
-		ata_link_for_each_dev(dev, &ap->link)
+		ata_link_for_each_dev(dev, link)
 			dev->pio_mode = XFER_PIO_0;
 
 		if (postreset)
@@ -1663,7 +1665,7 @@ static int ata_eh_revalidate_and_attach(
 		unsigned int action = ata_eh_dev_action(dev);
 
 		if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) {
-			if (ata_port_offline(ap)) {
+			if (ata_link_offline(dev->link)) {
 				rc = -EIO;
 				break;
 			}
@@ -1920,7 +1922,7 @@ static void ata_eh_handle_dev_fail(struc
 		ehc->tries[dev->devno] = 0;
 		break;
 	case -EIO:
-		sata_down_spd_limit(ap);
+		sata_down_spd_limit(&ap->link);
 	default:
 		ehc->tries[dev->devno]--;
 		if (down_xfermask &&
@@ -1933,7 +1935,7 @@ static void ata_eh_handle_dev_fail(struc
 		ata_dev_disable(dev);
 
 		/* detach if offline */
-		if (ata_port_offline(ap))
+		if (ata_link_offline(&ap->link))
 			ata_eh_detach_dev(dev);
 
 		/* probe if requested */
drivers/ata/libata-sff.c +1 -1
index 083234c..336805e 100644
@@ -776,7 +776,7 @@ void ata_bmdma_error_handler(struct ata_
 	ata_reset_fn_t hardreset;
 
 	hardreset = NULL;
-	if (sata_scr_valid(ap))
+	if (sata_scr_valid(&ap->link))
 		hardreset = sata_std_hardreset;
 
 	ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, hardreset,
drivers/ata/libata.h +2 -2
index 017dc08..d8e9f4e 100644
@@ -54,8 +54,8 @@ extern unsigned int ata_do_simple_cmd(st
 extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
 			   int post_reset, u16 *id);
 extern int ata_dev_configure(struct ata_device *dev, int print_info);
-extern int sata_down_spd_limit(struct ata_port *ap);
-extern int sata_set_spd_needed(struct ata_port *ap);
+extern int sata_down_spd_limit(struct ata_link *link);
+extern int sata_set_spd_needed(struct ata_link *link);
 extern int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0);
 extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
 extern void ata_qc_free(struct ata_queued_cmd *qc);
drivers/ata/sata_mv.c +7 -7
index 9776a67..a56cb24 100644
@@ -1311,8 +1311,8 @@ static void mv_err_intr(struct ata_port 
 	edma_err_cause = readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
 
 	if (EDMA_ERR_SERR & edma_err_cause) {
-		sata_scr_read(ap, SCR_ERROR, &serr);
-		sata_scr_write_flush(ap, SCR_ERROR, serr);
+		sata_scr_read(&ap->link, SCR_ERROR, &serr);
+		sata_scr_write_flush(&ap->link, SCR_ERROR, serr);
 	}
 	if (EDMA_ERR_SELF_DIS & edma_err_cause) {
 		struct mv_port_priv *pp	= ap->private_data;
@@ -1951,15 +1951,15 @@ static void __mv_phy_reset(struct ata_po
 
 	/* Issue COMRESET via SControl */
 comreset_retry:
-	sata_scr_write_flush(ap, SCR_CONTROL, 0x301);
+	sata_scr_write_flush(&ap->link, SCR_CONTROL, 0x301);
 	__msleep(1, can_sleep);
 
-	sata_scr_write_flush(ap, SCR_CONTROL, 0x300);
+	sata_scr_write_flush(&ap->link, SCR_CONTROL, 0x300);
 	__msleep(20, can_sleep);
 
 	timeout = jiffies + msecs_to_jiffies(200);
 	do {
-		sata_scr_read(ap, SCR_STATUS, &sstatus);
+		sata_scr_read(&ap->link, SCR_STATUS, &sstatus);
 		if (((sstatus & 0x3) == 3) || ((sstatus & 0x3) == 0))
 			break;
 
@@ -1976,10 +1976,10 @@ comreset_retry:
 		"SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS),
 		mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL));
 
-	if (ata_port_online(ap)) {
+	if (ata_link_online(&ap->link)) {
 		ata_port_probe(ap);
 	} else {
-		sata_scr_read(ap, SCR_STATUS, &sstatus);
+		sata_scr_read(&ap->link, SCR_STATUS, &sstatus);
 		ata_port_printk(ap, KERN_INFO,
 				"no device found (phy stat %08x)\n", sstatus);
 		ata_port_disable(ap);
drivers/ata/sata_sil24.c +5 -5
index ea1e3e5..29de9bd 100644
@@ -551,7 +551,7 @@ static int sil24_softreset(struct ata_po
 
 	DPRINTK("ENTER\n");
 
-	if (ata_port_offline(ap)) {
+	if (ata_link_offline(&ap->link)) {
 		DPRINTK("PHY reports no device\n");
 		*class = ATA_DEV_NONE;
 		goto out;
@@ -608,10 +608,10 @@ static int sil24_hardreset(struct ata_po
 	u32 tmp;
 
 	/* sil24 does the right thing(tm) without any protection */
-	sata_set_spd(ap);
+	sata_set_spd(&ap->link);
 
 	tout_msec = 100;
-	if (ata_port_online(ap))
+	if (ata_link_online(&ap->link))
 		tout_msec = 5000;
 
 	writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
@@ -621,14 +621,14 @@ static int sil24_hardreset(struct ata_po
 	/* SStatus oscillates between zero and valid status after
 	 * DEV_RST, debounce it.
 	 */
-	rc = sata_phy_debounce(ap, sata_deb_timing_long);
+	rc = sata_link_debounce(&ap->link, sata_deb_timing_long);
 	if (rc) {
 		reason = "PHY debouncing failed";
 		goto err;
 	}
 
 	if (tmp & PORT_CS_DEV_RST) {
-		if (ata_port_offline(ap))
+		if (ata_link_offline(&ap->link))
 			return 0;
 		reason = "link not ready";
 		goto err;
include/linux/libata.h +10 -9
index 48503d4..315ab6f 100644
@@ -710,9 +710,10 @@ extern void ata_port_probe(struct ata_po
 extern void __sata_phy_reset(struct ata_port *ap);
 extern void sata_phy_reset(struct ata_port *ap);
 extern void ata_bus_reset(struct ata_port *ap);
-extern int sata_set_spd(struct ata_port *ap);
-extern int sata_phy_debounce(struct ata_port *ap, const unsigned long *param);
-extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param);
+extern int sata_set_spd(struct ata_link *link);
+extern int sata_link_debounce(struct ata_link *link,
+			      const unsigned long *params);
+extern int sata_link_resume(struct ata_link *link, const unsigned long *params);
 extern int ata_std_prereset(struct ata_port *ap);
 extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes);
 extern int sata_port_hardreset(struct ata_port *ap,
@@ -753,12 +754,12 @@ extern int ata_sas_slave_configure(struc
 extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
 			    struct ata_port *ap);
 extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
-extern int sata_scr_valid(struct ata_port *ap);
-extern int sata_scr_read(struct ata_port *ap, int reg, u32 *val);
-extern int sata_scr_write(struct ata_port *ap, int reg, u32 val);
-extern int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val);
-extern int ata_port_online(struct ata_port *ap);
-extern int ata_port_offline(struct ata_port *ap);
+extern int sata_scr_valid(struct ata_link *link);
+extern int sata_scr_read(struct ata_link *link, int reg, u32 *val);
+extern int sata_scr_write(struct ata_link *link, int reg, u32 val);
+extern int sata_scr_write_flush(struct ata_link *link, int reg, u32 val);
+extern int ata_link_online(struct ata_link *link);
+extern int ata_link_offline(struct ata_link *link);
 extern int ata_scsi_device_resume(struct scsi_device *);
 extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg);
 extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
Signature · 1 line
1.4.2.3
author
#7 lore raw

PATCH 7/18 libata-link: linkify EH action helpers

In reply to Tejun Heo

Make ata_eh_about_to_do() and ata_eh_done() deal with ata_link instead of ata_port.

This patch introduces no behavior change.

---
 drivers/ata/libata-eh.c |   43 ++++++++++++++++++++++---------------------
 1 files changed, 22 insertions(+), 21 deletions(-)
drivers/ata/libata-eh.c +22 -21
index 9cf41c4..7c089d3 100644
@@ -766,23 +766,24 @@ static void ata_eh_detach_dev(struct ata
 
 /**
  *	ata_eh_about_to_do - about to perform eh_action
- *	@ap: target ATA port
+ *	@link: target ATA link
  *	@dev: target ATA dev for per-dev action (can be NULL)
  *	@action: action about to be performed
  *
  *	Called just before performing EH actions to clear related bits
- *	in @ap->link.eh_info such that eh actions are not
- *	unnecessarily repeated.
+ *	in @link->eh_info such that eh actions are not unnecessarily
+ *	repeated.
  *
  *	LOCKING:
  *	None.
  */
-static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev,
+static void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
 			       unsigned int action)
 {
+	struct ata_port *ap = link->ap;
+	struct ata_eh_info *ehi = &link->eh_info;
+	struct ata_eh_context *ehc = &link->eh_context;
 	unsigned long flags;
-	struct ata_eh_info *ehi = &ap->link.eh_info;
-	struct ata_eh_context *ehc = &ap->link.eh_context;
 
 	spin_lock_irqsave(ap->lock, flags);
 
@@ -799,7 +800,7 @@ static void ata_eh_about_to_do(struct at
 		ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK;
 	}
 
-	ata_eh_clear_action(&ap->link, dev, ehi, action);
+	ata_eh_clear_action(link, dev, ehi, action);
 
 	if (!(ehc->i.flags & ATA_EHI_QUIET))
 		ap->pflags |= ATA_PFLAG_RECOVERED;
@@ -809,20 +810,20 @@ static void ata_eh_about_to_do(struct at
 
 /**
  *	ata_eh_done - EH action complete
- *	@ap: target ATA port
+*	@ap: target ATA port
  *	@dev: target ATA dev for per-dev action (can be NULL)
  *	@action: action just completed
  *
  *	Called right after performing EH actions to clear related bits
- *	in @ap->link.eh_context.
+ *	in @link->eh_context.
  *
  *	LOCKING:
  *	None.
  */
-static void ata_eh_done(struct ata_port *ap, struct ata_device *dev,
+static void ata_eh_done(struct ata_link *link, struct ata_device *dev,
 			unsigned int action)
 {
-	struct ata_eh_context *ehc = &ap->link.eh_context;
+	struct ata_eh_context *ehc = &link->eh_context;
 
 	/* if reset is complete, clear all reset actions & reset modifier */
 	if (action & ATA_EH_RESET_MASK) {
@@ -830,7 +831,7 @@ static void ata_eh_done(struct ata_port 
 		ehc->i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK;
 	}
 
-	ata_eh_clear_action(&ap->link, dev, &ehc->i, action);
+	ata_eh_clear_action(link, dev, &ehc->i, action);
 }
 
 /**
@@ -1527,7 +1528,7 @@ static int ata_eh_reset(struct ata_port 
 	int did_followup_srst, rc;
 
 	/* about to reset */
-	ata_eh_about_to_do(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK);
+	ata_eh_about_to_do(link, NULL, ehc->i.action & ATA_EH_RESET_MASK);
 
 	/* Determine which reset to use and record in ehc->i.action.
 	 * prereset() may examine and modify it.
@@ -1600,7 +1601,7 @@ static int ata_eh_reset(struct ata_port 
 			return -EINVAL;
 		}
 
-		ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK);
+		ata_eh_about_to_do(link, NULL, ATA_EH_RESET_MASK);
 		rc = ata_do_reset(ap, reset, classes);
 
 		if (rc == 0 && classify &&
@@ -1644,7 +1645,7 @@ static int ata_eh_reset(struct ata_port 
 			postreset(ap, classes);
 
 		/* reset successful, schedule revalidation */
-		ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK);
+		ata_eh_done(link, NULL, ehc->i.action & ATA_EH_RESET_MASK);
 		ehc->i.action |= ATA_EH_REVALIDATE;
 	}
 
@@ -1670,13 +1671,13 @@ static int ata_eh_revalidate_and_attach(
 				break;
 			}
 
-			ata_eh_about_to_do(ap, dev, ATA_EH_REVALIDATE);
+			ata_eh_about_to_do(&ap->link, dev, ATA_EH_REVALIDATE);
 			rc = ata_dev_revalidate(dev,
 					ehc->i.flags & ATA_EHI_DID_RESET);
 			if (rc)
 				break;
 
-			ata_eh_done(ap, dev, ATA_EH_REVALIDATE);
+			ata_eh_done(&ap->link, dev, ATA_EH_REVALIDATE);
 
 			/* schedule the scsi_rescan_device() here */
 			queue_work(ata_aux_wq, &(ap->scsi_rescan_task));
@@ -1740,7 +1741,7 @@ static int ata_eh_suspend(struct ata_por
 
 		WARN_ON(dev->flags & ATA_DFLAG_SUSPENDED);
 
-		ata_eh_about_to_do(ap, dev, ATA_EH_SUSPEND);
+		ata_eh_about_to_do(&ap->link, dev, ATA_EH_SUSPEND);
 
 		if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
 			/* flush cache */
@@ -1763,7 +1764,7 @@ static int ata_eh_suspend(struct ata_por
 		dev->flags |= ATA_DFLAG_SUSPENDED;
 		spin_unlock_irqrestore(ap->lock, flags);
 
-		ata_eh_done(ap, dev, ATA_EH_SUSPEND);
+		ata_eh_done(&ap->link, dev, ATA_EH_SUSPEND);
 	}
 
 	if (rc)
@@ -1833,7 +1834,7 @@ static int ata_eh_resume(struct ata_port
 		if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME))
 			continue;
 
-		ata_eh_about_to_do(ap, dev, ATA_EH_RESUME);
+		ata_eh_about_to_do(&ap->link, dev, ATA_EH_RESUME);
 
 		if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
 			err_mask = ata_do_simple_cmd(dev,
@@ -1847,7 +1848,7 @@ static int ata_eh_resume(struct ata_port
 			}
 		}
 
-		ata_eh_done(ap, dev, ATA_EH_RESUME);
+		ata_eh_done(&ap->link, dev, ATA_EH_RESUME);
 	}
 
 	if (rc)
Signature · 1 line
1.4.2.3
author
#8 lore raw

PATCH 8/18 libata-link: linkify reset

In reply to Tejun Heo

Make reset methods and related functions deal with ata_link instead of ata_port.

* ata_do_reset()
* ata_eh_reset()
* all prereset/reset/postreset methods and related functions

This patch introduces no behavior change.

---
 drivers/ata/ahci.c              |   30 +++++++++++--------
 drivers/ata/ata_generic.c       |    8 +++--
 drivers/ata/ata_piix.c          |   27 +++++++++--------
 drivers/ata/libata-core.c       |   62 +++++++++++++++++++--------------------
 drivers/ata/libata-eh.c         |   38 ++++++++++++------------
 drivers/ata/pata_ali.c          |   16 +++++-----
 drivers/ata/pata_amd.c          |   24 +++++++++------
 drivers/ata/pata_artop.c        |   12 ++++----
 drivers/ata/pata_atiixp.c       |    5 ++-
 drivers/ata/pata_cmd64x.c       |   11 ++++---
 drivers/ata/pata_cs5520.c       |    6 ++--
 drivers/ata/pata_cs5530.c       |    6 ++--
 drivers/ata/pata_cs5535.c       |    5 ++-
 drivers/ata/pata_cypress.c      |    6 ++--
 drivers/ata/pata_efar.c         |    7 +++-
 drivers/ata/pata_hpt366.c       |    5 ++-
 drivers/ata/pata_hpt37x.c       |   12 ++++----
 drivers/ata/pata_hpt3x2n.c      |    7 +++-
 drivers/ata/pata_hpt3x3.c       |    6 ++--
 drivers/ata/pata_it821x.c       |    8 +++--
 drivers/ata/pata_jmicron.c      |    9 +++---
 drivers/ata/pata_mpiix.c        |    5 ++-
 drivers/ata/pata_netcell.c      |    8 +++--
 drivers/ata/pata_ns87410.c      |    7 +++-
 drivers/ata/pata_oldpiix.c      |    7 +++-
 drivers/ata/pata_opti.c         |    7 +++-
 drivers/ata/pata_optidma.c      |    7 +++-
 drivers/ata/pata_pdc2027x.c     |   10 +++---
 drivers/ata/pata_pdc202xx_old.c |   13 ++++----
 drivers/ata/pata_radisys.c      |    8 +++--
 drivers/ata/pata_rz1000.c       |    8 +++--
 drivers/ata/pata_serverworks.c  |    8 +++--
 drivers/ata/pata_sil680.c       |   13 ++++----
 drivers/ata/pata_sis.c          |   21 ++++++++-----
 drivers/ata/pata_sl82c105.c     |    5 ++-
 drivers/ata/pata_triflex.c      |    7 +++-
 drivers/ata/pata_via.c          |    5 ++-
 drivers/ata/sata_nv.c           |    4 +--
 drivers/ata/sata_sil24.c        |   20 +++++++------
 drivers/ata/sata_via.c          |    5 ++-
 include/linux/libata.h          |   17 ++++++-----
 41 files changed, 267 insertions(+), 228 deletions(-)
drivers/ata/ahci.c +17 -13
index 2888144..08611e2 100644
@@ -733,8 +733,9 @@ static int ahci_clo(struct ata_port *ap)
 	return 0;
 }
 
-static int ahci_softreset(struct ata_port *ap, unsigned int *class)
+static int ahci_softreset(struct ata_link *link, unsigned int *class)
 {
+	struct ata_port *ap = link->ap;
 	struct ahci_port_priv *pp = ap->private_data;
 	void __iomem *mmio = ap->host->mmio_base;
 	void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
@@ -747,7 +748,7 @@ static int ahci_softreset(struct ata_por
 
 	DPRINTK("ENTER\n");
 
-	if (ata_link_offline(&ap->link)) {
+	if (ata_link_offline(link)) {
 		DPRINTK("PHY reports no device\n");
 		*class = ATA_DEV_NONE;
 		return 0;
@@ -776,7 +777,7 @@ static int ahci_softreset(struct ata_por
 	/* restart engine */
 	ahci_start_engine(port_mmio);
 
-	ata_tf_init(ap->link.device, &tf);
+	ata_tf_init(link->device, &tf);
 	fis = pp->cmd_tbl;
 
 	/* issue the first D2H Register FIS */
@@ -820,7 +821,7 @@ static int ahci_softreset(struct ata_por
 	msleep(150);
 
 	*class = ATA_DEV_NONE;
-	if (ata_link_online(&ap->link)) {
+	if (ata_link_online(link)) {
 		if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
 			rc = -EIO;
 			reason = "device not ready";
@@ -835,12 +836,13 @@ static int ahci_softreset(struct ata_por
  fail_restart:
 	ahci_start_engine(port_mmio);
  fail:
-	ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason);
+	ata_link_printk(link, KERN_ERR, "softreset failed (%s)\n", reason);
 	return rc;
 }
 
-static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
+static int ahci_hardreset(struct ata_link *link, unsigned int *class)
 {
+	struct ata_port *ap = link->ap;
 	struct ahci_port_priv *pp = ap->private_data;
 	u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
 	struct ata_taskfile tf;
@@ -853,15 +855,15 @@ static int ahci_hardreset(struct ata_por
 	ahci_stop_engine(port_mmio);
 
 	/* clear D2H reception area to properly wait for D2H FIS */
-	ata_tf_init(ap->link.device, &tf);
+	ata_tf_init(link->device, &tf);
 	tf.command = 0xff;
 	ata_tf_to_fis(&tf, d2h_fis, 0);
 
-	rc = sata_std_hardreset(ap, class);
+	rc = sata_std_hardreset(link, class);
 
 	ahci_start_engine(port_mmio);
 
-	if (rc == 0 && ata_link_online(&ap->link))
+	if (rc == 0 && ata_link_online(link))
 		*class = ahci_dev_classify(ap);
 	if (*class == ATA_DEV_UNKNOWN)
 		*class = ATA_DEV_NONE;
@@ -870,8 +872,9 @@ static int ahci_hardreset(struct ata_por
 	return rc;
 }
 
-static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
+static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class)
 {
+	struct ata_port *ap = link->ap;
 	void __iomem *mmio = ap->host->mmio_base;
 	void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
 	int rc;
@@ -880,7 +883,7 @@ static int ahci_vt8251_hardreset(struct 
 
 	ahci_stop_engine(port_mmio);
 
-	rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->link.eh_context));
+	rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context));
 
 	/* vt8251 needs SError cleared for the port to operate */
 	ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR));
@@ -895,12 +898,13 @@ static int ahci_vt8251_hardreset(struct 
 	return rc ?: -EAGAIN;
 }
 
-static void ahci_postreset(struct ata_port *ap, unsigned int *class)
+static void ahci_postreset(struct ata_link *link, unsigned int *class)
 {
+	struct ata_port *ap = link->ap;
 	void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
 	u32 new_tmp, tmp;
 
-	ata_std_postreset(ap, class);
+	ata_std_postreset(link, class);
 
 	/* Make sure port's ATAPI bit is set appropriately */
 	new_tmp = tmp = readl(port_mmio + PORT_CMD);
drivers/ata/ata_generic.c +4 -4
index e060fee..05160bc 100644
@@ -34,15 +34,15 @@ #define DRV_VERSION "0.2.7"
 
 /**
  *	generic_pre_reset		-	probe begin
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Set up cable type and use generic probe init
  */
 
-static int generic_pre_reset(struct ata_port *ap)
+static int generic_pre_reset(struct ata_link *link)
 {
-	ap->cbl = ATA_CBL_PATA80;
-	return ata_std_prereset(ap);
+	link->ap->cbl = ATA_CBL_PATA80;
+	return ata_std_prereset(link);
 }
 
 
drivers/ata/ata_piix.c +15 -12
index ffeaf65..fa7d79d 100644
@@ -662,21 +662,22 @@ cbl40:
 
 /**
  *	piix_pata_prereset - prereset for PATA host controller
- *	@ap: Target port
+ *	@link: Target link
  *
  *
  *	LOCKING:
  *	None (inherited from caller).
  */
-static int piix_pata_prereset(struct ata_port *ap)
+static int piix_pata_prereset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
 	if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
 		return -ENOENT;
 		
 	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 static void piix_pata_error_handler(struct ata_port *ap)
@@ -688,25 +689,26 @@ static void piix_pata_error_handler(stru
 
 /**
  *	ich_pata_prereset - prereset for PATA host controller
- *	@ap: Target port
+ *	@link: Target link
  *
  *
  *	LOCKING:
  *	None (inherited from caller).
  */
-static int ich_pata_prereset(struct ata_port *ap)
+static int ich_pata_prereset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
 	if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) {
 		ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n");
-		ap->link.eh_context.i.action &= ~ATA_EH_RESET_MASK;
+		link->eh_context.i.action &= ~ATA_EH_RESET_MASK;
 		return 0;
 	}
 
 	ich_pata_cbl_detect(ap);
 
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 static void ich_pata_error_handler(struct ata_port *ap)
@@ -758,10 +760,10 @@ static unsigned int piix_sata_present_ma
 
 /**
  *	piix_sata_softreset - reset SATA host port via ATA SRST
- *	@ap: port to reset
+ *	@link: link to reset
  *	@classes: resulting classes of attached devices
  *
- *	Reset SATA host port via ATA SRST.  On controllers with
+ *	Reset SATA host link via ATA SRST.  On controllers with
  *	reliable PCS present bits, the bits are used to determine
  *	device presence.
  *
@@ -771,19 +773,20 @@ static unsigned int piix_sata_present_ma
  *	RETURNS:
  *	0 on success, -errno otherwise.
  */
-static int piix_sata_softreset(struct ata_port *ap, unsigned int *classes)
+static int piix_sata_softreset(struct ata_link *link, unsigned int *classes)
 {
+	struct ata_port *ap = link->ap;
 	unsigned int present_mask;
 	struct ata_device *dev;
 	int rc;
 
 	present_mask = piix_sata_present_mask(ap);
 
-	rc = ata_std_softreset(ap, classes);
+	rc = ata_std_softreset(link, classes);
 	if (rc)
 		return rc;
 
-	ata_link_for_each_dev(dev, &ap->link) {
+	ata_link_for_each_dev(dev, link) {
 		if (!(present_mask & (1 << dev->devno)))
 			classes[dev->devno] = ATA_DEV_NONE;
 	}
drivers/ata/libata-core.c +30 -32

180 lines not on this page · raw message

drivers/ata/libata-eh.c +19 -19
index 7c089d3..80f2fa0 100644
@@ -1470,16 +1470,16 @@ static void ata_eh_report(struct ata_por
 	}
 }
 
-static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
+static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
 			unsigned int *classes)
 {
 	struct ata_device *dev;
 	int rc;
 
-	ata_link_for_each_dev(dev, &ap->link)
+	ata_link_for_each_dev(dev, link)
 		classes[dev->devno] = ATA_DEV_UNKNOWN;
 
-	rc = reset(ap, classes);
+	rc = reset(link, classes);
 	if (rc)
 		return rc;
 
@@ -1487,12 +1487,12 @@ static int ata_do_reset(struct ata_port 
 	 * is complete and convert all ATA_DEV_UNKNOWN to
 	 * ATA_DEV_NONE.
 	 */
-	ata_link_for_each_dev(dev, &ap->link)
+	ata_link_for_each_dev(dev, link)
 		if (classes[dev->devno] != ATA_DEV_UNKNOWN)
 			break;
 
 	if (dev) {
-		ata_link_for_each_dev(dev, &ap->link) {
+		ata_link_for_each_dev(dev, link) {
 			if (classes[dev->devno] == ATA_DEV_UNKNOWN)
 				classes[dev->devno] = ATA_DEV_NONE;
 		}
@@ -1513,11 +1513,10 @@ static int ata_eh_followup_srst_needed(i
 	return 0;
 }
 
-static int ata_eh_reset(struct ata_port *ap, int classify,
+static int ata_eh_reset(struct ata_link *link, int classify,
 			ata_prereset_fn_t prereset, ata_reset_fn_t softreset,
 			ata_reset_fn_t hardreset, ata_postreset_fn_t postreset)
 {
-	struct ata_link *link = &ap->link;
 	struct ata_eh_context *ehc = &link->eh_context;
 	unsigned int *classes = ehc->classes;
 	int tries = ATA_EH_RESET_TRIES;
@@ -1542,13 +1541,14 @@ static int ata_eh_reset(struct ata_port 
 		ehc->i.action |= ATA_EH_HARDRESET;
 
 	if (prereset) {
-		rc = prereset(ap);
+		rc = prereset(link);
 		if (rc) {
 			if (rc == -ENOENT) {
-				ata_port_printk(ap, KERN_DEBUG, "port disabled. ignoring.\n");
+				ata_link_printk(link, KERN_DEBUG,
+						"link disabled. ignoring.\n");
 				ehc->i.action &= ~ATA_EH_RESET_MASK;
 			} else
-				ata_port_printk(ap, KERN_ERR,
+				ata_link_printk(link, KERN_ERR,
 					"prereset failed (errno=%d)\n", rc);
 			return rc;
 		}
@@ -1568,7 +1568,7 @@ static int ata_eh_reset(struct ata_port 
 
 	/* did prereset() screw up?  if so, fix up to avoid oopsing */
 	if (!reset) {
-		ata_port_printk(ap, KERN_ERR, "BUG: prereset() requested "
+		ata_link_printk(link, KERN_ERR, "BUG: prereset() requested "
 				"invalid reset type\n");
 		if (softreset)
 			reset = softreset;
@@ -1579,13 +1579,13 @@ static int ata_eh_reset(struct ata_port 
  retry:
 	/* shut up during boot probing */
 	if (verbose)
-		ata_port_printk(ap, KERN_INFO, "%s resetting port\n",
+		ata_link_printk(link, KERN_INFO, "%s resetting port\n",
 				reset == softreset ? "soft" : "hard");
 
 	/* mark that this EH session started with reset */
 	ehc->i.flags |= ATA_EHI_DID_RESET;
 
-	rc = ata_do_reset(ap, reset, classes);
+	rc = ata_do_reset(link, reset, classes);
 
 	did_followup_srst = 0;
 	if (reset == hardreset &&
@@ -1595,18 +1595,18 @@ static int ata_eh_reset(struct ata_port 
 		reset = softreset;
 
 		if (!reset) {
-			ata_port_printk(ap, KERN_ERR,
+			ata_link_printk(link, KERN_ERR,
 					"follow-up softreset required "
 					"but no softreset avaliable\n");
 			return -EINVAL;
 		}
 
 		ata_eh_about_to_do(link, NULL, ATA_EH_RESET_MASK);
-		rc = ata_do_reset(ap, reset, classes);
+		rc = ata_do_reset(link, reset, classes);
 
 		if (rc == 0 && classify &&
 		    classes[0] == ATA_DEV_UNKNOWN) {
-			ata_port_printk(ap, KERN_ERR,
+			ata_link_printk(link, KERN_ERR,
 					"classification failed\n");
 			return -EINVAL;
 		}
@@ -1623,7 +1623,7 @@ static int ata_eh_reset(struct ata_port 
 		} else
 			type = "hard";
 
-		ata_port_printk(ap, KERN_WARNING,
+		ata_link_printk(link, KERN_WARNING,
 				"%sreset failed, retrying in 5 secs\n", type);
 		ssleep(5);
 
@@ -1642,7 +1642,7 @@ static int ata_eh_reset(struct ata_port 
 			dev->pio_mode = XFER_PIO_0;
 
 		if (postreset)
-			postreset(ap, classes);
+			postreset(link, classes);
 
 		/* reset successful, schedule revalidation */
 		ata_eh_done(link, NULL, ehc->i.action & ATA_EH_RESET_MASK);
@@ -2029,7 +2029,7 @@ static int ata_eh_recover(struct ata_por
 	if (ehc->i.action & ATA_EH_RESET_MASK) {
 		ata_eh_freeze_port(ap);
 
-		rc = ata_eh_reset(ap, ata_port_nr_vacant(ap), prereset,
+		rc = ata_eh_reset(&ap->link, ata_port_nr_vacant(ap), prereset,
 				  softreset, hardreset, postreset);
 		if (rc) {
 			ata_port_printk(ap, KERN_ERR,
drivers/ata/pata_ali.c +8 -8
index 9860178..6a888c3 100644
@@ -91,15 +91,15 @@ static int ali_c2_cable_detect(struct at
 
 /**
  *	ali_early_error_handler	-	reset for eary chip
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Handle the reset callback for the later chips with cable detect
  */
 
-static int ali_c2_pre_reset(struct ata_port *ap)
+static int ali_c2_pre_reset(struct ata_link *link)
 {
-	ap->cbl = ali_c2_cable_detect(ap);
-	return ata_std_prereset(ap);
+	link->ap->cbl = ali_c2_cable_detect(link->ap);
+	return ata_std_prereset(link);
 }
 
 static void ali_c2_error_handler(struct ata_port *ap)
@@ -124,15 +124,15 @@ static int ali_early_cable_detect(struct
 
 /**
  *	ali_early_probe_init	-	reset for early chip
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Handle the reset callback for the early (pre cable detect) chips.
  */
 
-static int ali_early_pre_reset(struct ata_port *ap)
+static int ali_early_pre_reset(struct ata_link *link)
 {
-	ap->cbl = ali_early_cable_detect(ap);
-	return ata_std_prereset(ap);
+	link->ap->cbl = ali_early_cable_detect(link->ap);
+	return ata_std_prereset(link);
 }
 
 static void ali_early_error_handler(struct ata_port *ap)
drivers/ata/pata_amd.c +14 -10
index 29234c8..725dd15 100644
@@ -119,14 +119,14 @@ static void timing_setup(struct ata_port
 }
 
 /**
- *	amd_probe_init		-	cable detection
- *	@ap: ATA port
+ *	amd_pre_reset		-	cable detection
+ *	@link: ATA link
  *
  *	Perform cable detection. The BIOS stores this in PCI config
  *	space for us.
  */
 
-static int amd_pre_reset(struct ata_port *ap)
+static int amd_pre_reset(struct ata_link *link)
 {
 	static const u32 bitmask[2] = {0x03, 0xC0};
 	static const struct pci_bits amd_enable_bits[] = {
@@ -134,6 +134,7 @@ static int amd_pre_reset(struct ata_port
 		{ 0x40, 1, 0x01, 0x01 }
 	};
 
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u8 ata66;
 
@@ -145,7 +146,7 @@ static int amd_pre_reset(struct ata_port
 		ap->cbl = ATA_CBL_PATA80;
 	else
 		ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 
 }
 
@@ -156,20 +157,22 @@ static void amd_error_handler(struct ata
 				      ata_std_postreset);
 }
 
-static int amd_early_pre_reset(struct ata_port *ap)
+static int amd_early_pre_reset(struct ata_link *link)
 {
-	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	static struct pci_bits amd_enable_bits[] = {
 		{ 0x40, 1, 0x02, 0x02 },
 		{ 0x40, 1, 0x01, 0x01 }
 	};
 
+	struct ata_port *ap = link->ap;
+	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
+
 	if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no]))
 		return -ENOENT;
 
 	/* No host side cable detection */
 	ap->cbl = ATA_CBL_PATA80;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 
 }
 
@@ -240,19 +243,20 @@ static void amd133_set_dmamode(struct at
 
 /**
  *	nv_probe_init	-	cable detection
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Perform cable detection. The BIOS stores this in PCI config
  *	space for us.
  */
 
-static int nv_pre_reset(struct ata_port *ap) {
+static int nv_pre_reset(struct ata_link *link) {
 	static const u8 bitmask[2] = {0x03, 0xC0};
 	static const struct pci_bits nv_enable_bits[] = {
 		{ 0x50, 1, 0x02, 0x02 },
 		{ 0x50, 1, 0x01, 0x01 }
 	};
 
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u8 ata66;
 	u16 udma;
@@ -272,7 +276,7 @@ static int nv_pre_reset(struct ata_port 
 	pci_read_config_word(pdev, 0x62 - 2 * ap->port_no, &udma);
 	if ((udma & 0xC4) == 0xC4 || (udma & 0xC400) == 0xC400)
 		ap->cbl = ATA_CBL_PATA80;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 static void nv_error_handler(struct ata_port *ap)
drivers/ata/pata_artop.c +7 -5
index 690828e..fe06611 100644
@@ -39,8 +39,9 @@ #define DRV_VERSION	"0.4.2"
 
 static int clock = 0;
 
-static int artop6210_pre_reset(struct ata_port *ap)
+static int artop6210_pre_reset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	const struct pci_bits artop_enable_bits[] = {
 		{ 0x4AU, 1U, 0x02UL, 0x02UL },	/* port 0 */
@@ -51,7 +52,7 @@ static int artop6210_pre_reset(struct at
 		return -ENOENT;
 
 	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
@@ -71,19 +72,20 @@ static void artop6210_error_handler(stru
 
 /**
  *	artop6260_pre_reset	-	check for 40/80 pin
- *	@ap: Port
+ *	@link: link
  *
  *	The ARTOP hardware reports the cable detect bits in register 0x49.
  *	Nothing complicated needed here.
  */
 
-static int artop6260_pre_reset(struct ata_port *ap)
+static int artop6260_pre_reset(struct ata_link *link)
 {
 	static const struct pci_bits artop_enable_bits[] = {
 		{ 0x4AU, 1U, 0x02UL, 0x02UL },	/* port 0 */
 		{ 0x4AU, 1U, 0x04UL, 0x04UL },	/* port 1 */
 	};
 
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u8 tmp;
 
@@ -96,7 +98,7 @@ static int artop6260_pre_reset(struct at
 		ap->cbl = ATA_CBL_PATA40;
 	else
 		ap->cbl = ATA_CBL_PATA80;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_atiixp.c +3 -2
index 1ce28d2..dbe5dbd 100644
@@ -33,8 +33,9 @@ enum {
 	ATIIXP_IDE_UDMA_MODE 	= 0x56
 };
 
-static int atiixp_pre_reset(struct ata_port *ap)
+static int atiixp_pre_reset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	static struct pci_bits atiixp_enable_bits[] = {
 		{ 0x48, 1, 0x01, 0x00 },
@@ -45,7 +46,7 @@ static int atiixp_pre_reset(struct ata_p
 		return -ENOENT;
 
 	ap->cbl = ATA_CBL_PATA80;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 static void atiixp_error_handler(struct ata_port *ap)
drivers/ata/pata_cmd64x.c +6 -5
index b9bbd1d..ec5a2b3 100644
@@ -75,14 +75,15 @@ enum {
 	DTPR1		= 0x7C
 };
 
-static int cmd64x_pre_reset(struct ata_port *ap)
+static int cmd64x_pre_reset(struct ata_link *link)
 {
-	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	link->ap->cbl = ATA_CBL_PATA40;
+	return ata_std_prereset(link);
 }
 
-static int cmd648_pre_reset(struct ata_port *ap)
+static int cmd648_pre_reset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u8 r;
 
@@ -93,7 +94,7 @@ static int cmd648_pre_reset(struct ata_p
 	else
 		ap->cbl = ATA_CBL_PATA40;
 
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 static void cmd64x_error_handler(struct ata_port *ap)
drivers/ata/pata_cs5520.c +3 -3
index 2cd3c0f..b1020c0 100644
@@ -140,10 +140,10 @@ static void cs5520_set_piomode(struct at
 }
 
 
-static int cs5520_pre_reset(struct ata_port *ap)
+static int cs5520_pre_reset(struct ata_link *link)
 {
-	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	link->ap->cbl = ATA_CBL_PATA40;
+	return ata_std_prereset(link);
 }
 
 static void cs5520_error_handler(struct ata_port *ap)
drivers/ata/pata_cs5530.c +3 -3
index a07cc81..f88e20a 100644
@@ -153,10 +153,10 @@ static unsigned int cs5530_qc_issue_prot
 	return ata_qc_issue_prot(qc);
 }
 
-static int cs5530_pre_reset(struct ata_port *ap)
+static int cs5530_pre_reset(struct ata_link *link)
 {
-	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	link->ap->cbl = ATA_CBL_PATA40;
+	return ata_std_prereset(link);
 }
 
 static void cs5530_error_handler(struct ata_port *ap)
drivers/ata/pata_cs5535.c +3 -2
index f8def3f..f35b98a 100644
@@ -77,9 +77,10 @@ #define CS5535_BAD_PIO(timings) ( (timin
  *	cable type.
  */
 
-static int cs5535_pre_reset(struct ata_port *ap)
+static int cs5535_pre_reset(struct ata_link *link)
 {
 	u8 cable;
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
 	pci_read_config_byte(pdev, CS5535_CABLE_DETECT, &cable);
@@ -87,7 +88,7 @@ static int cs5535_pre_reset(struct ata_p
 		ap->cbl = ATA_CBL_PATA80;
 	else
 		ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_cypress.c +3 -3
index 247b436..d9d4a4f 100644
@@ -41,10 +41,10 @@ enum {
 	CY82_INDEX_TIMEOUT	= 0x32
 };
 
-static int cy82c693_pre_reset(struct ata_port *ap)
+static int cy82c693_pre_reset(struct ata_link *link)
 {
-	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	link->ap->cbl = ATA_CBL_PATA40;
+	return ata_std_prereset(link);
 }
 
 static void cy82c693_error_handler(struct ata_port *ap)
drivers/ata/pata_efar.c +4 -3
index ef18c60..7223c88 100644
@@ -26,19 +26,20 @@ #define DRV_VERSION	"0.4.2"
 
 /**
  *	efar_pre_reset	-	check for 40/80 pin
- *	@ap: Port
+ *	@link: ATA link
  *
  *	Perform cable detection for the EFAR ATA interface. This is
  *	different to the PIIX arrangement
  */
 
-static int efar_pre_reset(struct ata_port *ap)
+static int efar_pre_reset(struct ata_link *link)
 {
 	static const struct pci_bits efar_enable_bits[] = {
 		{ 0x41U, 1U, 0x80UL, 0x80UL },	/* port 0 */
 		{ 0x43U, 1U, 0x80UL, 0x80UL },	/* port 1 */
 	};
 
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u8 tmp;
 
@@ -50,7 +51,7 @@ static int efar_pre_reset(struct ata_por
 		ap->cbl = ATA_CBL_PATA40;
 	else
 		ap->cbl = ATA_CBL_PATA80;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_hpt366.c +3 -2
index 6d3e4c0..044745f 100644
@@ -220,9 +220,10 @@ static u32 hpt36x_find_mode(struct ata_p
 	return 0xffffffffU;	/* silence compiler warning */
 }
 
-static int hpt36x_pre_reset(struct ata_port *ap)
+static int hpt36x_pre_reset(struct ata_link *link)
 {
 	u8 ata66;
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
 	pci_read_config_byte(pdev, 0x5A, &ata66);
@@ -230,7 +231,7 @@ static int hpt36x_pre_reset(struct ata_p
 		ap->cbl = ATA_CBL_PATA40;
 	else
 		ap->cbl = ATA_CBL_PATA80;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_hpt37x.c +7 -5
index 7350443..88fd6ec 100644
@@ -444,14 +444,15 @@ static unsigned long hpt370a_filter(cons
 
 /**
  *	hpt37x_pre_reset	-	reset the hpt37x bus
- *	@ap: ATA port to reset
+ *	@link: ATA link to reset
  *
  *	Perform the initial reset handling for the 370/372 and 374 func 0
  */
 
-static int hpt37x_pre_reset(struct ata_port *ap)
+static int hpt37x_pre_reset(struct ata_link *link)
 {
 	u8 scr2, ata66;
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
 	pci_read_config_byte(pdev, 0x5B, &scr2);
@@ -471,7 +472,7 @@ static int hpt37x_pre_reset(struct ata_p
 	pci_write_config_byte(pdev, 0x54, 0x37);
 	udelay(100);
 
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
@@ -486,11 +487,12 @@ static void hpt37x_error_handler(struct 
 	ata_bmdma_drive_eh(ap, hpt37x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
 }
 
-static int hpt374_pre_reset(struct ata_port *ap)
+static int hpt374_pre_reset(struct ata_link *link)
 {
 	u16 mcr3, mcr6;
 	u8 ata66;
 
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	/* Do the extra channel work */
 	pci_read_config_word(pdev, 0x52, &mcr3);
@@ -515,7 +517,7 @@ static int hpt374_pre_reset(struct ata_p
 	pci_write_config_byte(pdev, 0x54, 0x37);
 	udelay(100);
 
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_hpt3x2n.c +4 -3
index 58cfb2b..389d6b1 100644
@@ -116,15 +116,16 @@ static u32 hpt3x2n_find_mode(struct ata_
 
 /**
  *	hpt3x2n_pre_reset	-	reset the hpt3x2n bus
- *	@ap: ATA port to reset
+ *	@link: ATA link to reset
  *
  *	Perform the initial reset handling for the 3x2n series controllers.
  *	Reset the hardware and state machine, obtain the cable type.
  */
 
-static int hpt3xn_pre_reset(struct ata_port *ap)
+static int hpt3xn_pre_reset(struct ata_link *link)
 {
 	u8 scr2, ata66;
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
 	pci_read_config_byte(pdev, 0x5B, &scr2);
@@ -144,7 +145,7 @@ static int hpt3xn_pre_reset(struct ata_p
 	pci_write_config_byte(pdev, 0x54, 0x37);
 	udelay(100);
 
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_hpt3x3.c +3 -3
index 3334d72..8dd6773 100644
@@ -25,10 +25,10 @@ #include <linux/libata.h>
 #define DRV_NAME	"pata_hpt3x3"
 #define DRV_VERSION	"0.4.1"
 
-static int hpt3x3_probe_init(struct ata_port *ap)
+static int hpt3x3_probe_init(struct ata_link *link)
 {
-	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	link->ap->cbl = ATA_CBL_PATA40;
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_it821x.c +4 -4
index 98fcd8a..9964c04 100644
@@ -114,15 +114,15 @@ static int it8212_noraid;
 
 /**
  *	it821x_pre_reset	-	probe
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Set the cable type
  */
 
-static int it821x_pre_reset(struct ata_port *ap)
+static int it821x_pre_reset(struct ata_link *link)
 {
-	ap->cbl = ATA_CBL_PATA80;
-	return ata_std_prereset(ap);
+	link->ap->cbl = ATA_CBL_PATA80;
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_jmicron.c +5 -4
index 52a2bdf..b26a732 100644
@@ -29,18 +29,19 @@ typedef enum {
 
 /**
  *	jmicron_pre_reset	-	check for 40/80 pin
- *	@ap: Port
+ *	@link: ATA link
  *
  *	Perform the PATA port setup we need.
-
+ *
  *	On the Jmicron 361/363 there is a single PATA port that can be mapped
  *	either as primary or secondary (or neither). We don't do any policy
  *	and setup here. We assume that has been done by init_one and the
  *	BIOS.
  */
 
-static int jmicron_pre_reset(struct ata_port *ap)
+static int jmicron_pre_reset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u32 control;
 	u32 control5;
@@ -102,7 +103,7 @@ static int jmicron_pre_reset(struct ata_
 		ap->cbl = ATA_CBL_SATA;
 		break;
 	}
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_mpiix.c +3 -2
index 9dfe3e9..417b999 100644
@@ -46,8 +46,9 @@ enum {
 	SECONDARY = (1 << 14)
 };
 
-static int mpiix_pre_reset(struct ata_port *ap)
+static int mpiix_pre_reset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	static const struct pci_bits mpiix_enable_bits[] = {
 		{ 0x6D, 1, 0x80, 0x80 },
@@ -57,7 +58,7 @@ static int mpiix_pre_reset(struct ata_po
 	if (!pci_test_config_bits(pdev, &mpiix_enable_bits[ap->port_no]))
 		return -ENOENT;
 	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_netcell.c +4 -4
index f5672de..8f02493 100644
@@ -20,15 +20,15 @@ #define DRV_VERSION	"0.1.5"
 
 /**
  *	netcell_probe_init	-	check for 40/80 pin
- *	@ap: Port
+ *	@link: ATA link
  *
  *	Cables are handled by the RAID controller. Report 80 pin.
  */
 
-static int netcell_pre_reset(struct ata_port *ap)
+static int netcell_pre_reset(struct ata_link *link)
 {
-	ap->cbl = ATA_CBL_PATA80;
-	return ata_std_prereset(ap);
+	link->ap->cbl = ATA_CBL_PATA80;
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_ns87410.c +4 -3
index 2a3dbee..d534c1a 100644
@@ -32,13 +32,14 @@ #define DRV_VERSION "0.4.2"
 
 /**
  *	ns87410_pre_reset		-	probe begin
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Set up cable type and use generic probe init
  */
 
-static int ns87410_pre_reset(struct ata_port *ap)
+static int ns87410_pre_reset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	static const struct pci_bits ns87410_enable_bits[] = {
 		{ 0x43, 1, 0x08, 0x08 },
@@ -48,7 +49,7 @@ static int ns87410_pre_reset(struct ata_
 	if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->port_no]))
 		return -ENOENT;
 	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_oldpiix.c +4 -3
index fc947df..21d34cb 100644
@@ -29,13 +29,14 @@ #define DRV_VERSION	"0.5.2"
 
 /**
  *	oldpiix_pre_reset		-	probe begin
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Set up cable type and use generic probe init
  */
 
-static int oldpiix_pre_reset(struct ata_port *ap)
+static int oldpiix_pre_reset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	static const struct pci_bits oldpiix_enable_bits[] = {
 		{ 0x41U, 1U, 0x80UL, 0x80UL },	/* port 0 */
@@ -45,7 +46,7 @@ static int oldpiix_pre_reset(struct ata_
 	if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->port_no]))
 		return -ENOENT;
 	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_opti.c +4 -3
index a7320ba..8d9a5dc 100644
@@ -46,13 +46,14 @@ enum {
 
 /**
  *	opti_pre_reset		-	probe begin
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Set up cable type and use generic probe init
  */
 
-static int opti_pre_reset(struct ata_port *ap)
+static int opti_pre_reset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	static const struct pci_bits opti_enable_bits[] = {
 		{ 0x45, 1, 0x80, 0x00 },
@@ -63,7 +64,7 @@ static int opti_pre_reset(struct ata_por
 		return -ENOENT;
 
 	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_optidma.c +4 -3
index c58c135..1c9a643 100644
@@ -47,13 +47,14 @@ static int pci_clock;	/* 0 = 33 1 = 25 *
 
 /**
  *	optidma_pre_reset		-	probe begin
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Set up cable type and use generic probe init
  */
 
-static int optidma_pre_reset(struct ata_port *ap)
+static int optidma_pre_reset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	static const struct pci_bits optidma_enable_bits = {
 		0x40, 1, 0x08, 0x00
@@ -63,7 +64,7 @@ static int optidma_pre_reset(struct ata_
 		return -ENOENT;
 
 	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_pdc2027x.c +5 -5
index 6d60dbe..cecd573 100644
@@ -301,7 +301,7 @@ static inline int pdc2027x_port_enabled(
 
 /**
  *	pdc2027x_prereset - prereset for PATA host controller
- *	@ap: Target port
+ *	@link: Target link
  *
  *	Probeinit including cable detection.
  *
@@ -309,13 +309,13 @@ static inline int pdc2027x_port_enabled(
  *	None (inherited from caller).
  */
 
-static int pdc2027x_prereset(struct ata_port *ap)
+static int pdc2027x_prereset(struct ata_link *link)
 {
 	/* Check whether port enabled */
-	if (!pdc2027x_port_enabled(ap))
+	if (!pdc2027x_port_enabled(link->ap))
 		return -ENOENT;
-	pdc2027x_cbl_detect(ap);
-	return ata_std_prereset(ap);
+	pdc2027x_cbl_detect(link->ap);
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_pdc202xx_old.c +7 -6
index 5ba9eb2..6eed7d4 100644
@@ -25,15 +25,15 @@ #define DRV_VERSION "0.2.1"
 
 /**
  *	pdc2024x_pre_reset		-	probe begin
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Set up cable type and use generic probe init
  */
 
-static int pdc2024x_pre_reset(struct ata_port *ap)
+static int pdc2024x_pre_reset(struct ata_link *link)
 {
-	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	link->ap->cbl = ATA_CBL_PATA40;
+	return ata_std_prereset(link);
 }
 
 
@@ -43,8 +43,9 @@ static void pdc2024x_error_handler(struc
 }
 
 
-static int pdc2026x_pre_reset(struct ata_port *ap)
+static int pdc2026x_pre_reset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u16 cis;
 
@@ -54,7 +55,7 @@ static int pdc2026x_pre_reset(struct ata
 	else
 		ap->cbl = ATA_CBL_PATA40;
 
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 static void pdc2026x_error_handler(struct ata_port *ap)
drivers/ata/pata_radisys.c +4 -4
index 1af83d7..c8c2774 100644
@@ -28,15 +28,15 @@ #define DRV_VERSION	"0.4.1"
 
 /**
  *	radisys_probe_init		-	probe begin
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Set up cable type and use generic probe init
  */
 
-static int radisys_pre_reset(struct ata_port *ap)
+static int radisys_pre_reset(struct ata_link *link)
 {
-	ap->cbl = ATA_CBL_PATA80;
-	return ata_std_prereset(ap);
+	link->ap->cbl = ATA_CBL_PATA80;
+	return ata_std_prereset(link);
 }
 
 
drivers/ata/pata_rz1000.c +4 -4
index c231631..1b9f035 100644
@@ -26,15 +26,15 @@ #define DRV_VERSION	"0.2.2"
 
 /**
  *	rz1000_prereset		-	probe begin
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Set up cable type and use generics
  */
 
-static int rz1000_prereset(struct ata_port *ap)
+static int rz1000_prereset(struct ata_link *link)
 {
-	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	link->ap->cbl = ATA_CBL_PATA40;
+	return ata_std_prereset(link);
 }
 
 /**
drivers/ata/pata_serverworks.c +5 -3
index 5bbf76e..84b05ef 100644
@@ -138,13 +138,15 @@ static struct sv_cable_table cable_detec
 
 /**
  *	serverworks_pre_reset		-	cable detection
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Perform cable detection according to the device and subvendor
  *	identifications
  */
 
-static int serverworks_pre_reset(struct ata_port *ap) {
+static int serverworks_pre_reset(struct ata_link *link)
+{
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	struct sv_cable_table *cb = cable_detect;
 
@@ -153,7 +155,7 @@ static int serverworks_pre_reset(struct 
 		    (cb->subvendor == pdev->subsystem_vendor ||
 		      cb->subvendor == PCI_ANY_ID)) {
 			ap->cbl = cb->cable_detect(ap);
-			return ata_std_prereset(ap);
+			return ata_std_prereset(link);
 		}
 		cb++;
 	}
drivers/ata/pata_sil680.c +7 -6
index 4a2b72b..a96c042 100644
@@ -91,21 +91,22 @@ static int sil680_cable_detect(struct at
 		return ATA_CBL_PATA40;
 }
 
-static int sil680_pre_reset(struct ata_port *ap)
+static int sil680_pre_reset(struct ata_link *link)
 {
-	ap->cbl = sil680_cable_detect(ap);
-	return ata_std_prereset(ap);
+	link->ap->cbl = sil680_cable_detect(link->ap);
+	return ata_std_prereset(link);
 }
 
 /**
  *	sil680_bus_reset	-	reset the SIL680 bus
- *	@ap: ATA port to reset
+ *	@link: ATA link to reset
  *
  *	Perform the SIL680 housekeeping when doing an ATA bus reset
  */
 
-static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes)
+static int sil680_bus_reset(struct ata_link *link, unsigned int *classes)
 {
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	unsigned long addr = sil680_selreg(ap, 0);
 	u8 reset;
@@ -114,7 +115,7 @@ static int sil680_bus_reset(struct ata_p
 	pci_write_config_byte(pdev, addr, reset | 0x03);
 	udelay(25);
 	pci_write_config_byte(pdev, addr, reset);
-	return ata_std_softreset(ap, classes);
+	return ata_std_softreset(link, classes);
 }
 
 static void sil680_error_handler(struct ata_port *ap)
drivers/ata/pata_sis.c +12 -9
index 886e449..ce620c5 100644
@@ -58,19 +58,20 @@ static int sis_port_base(struct ata_devi
 
 /**
  *	sis_133_pre_reset	-	check for 40/80 pin
- *	@ap: Port
+ *	@link: ATA link
  *
  *	Perform cable detection for the later UDMA133 capable
  *	SiS chipset.
  */
 
-static int sis_133_pre_reset(struct ata_port *ap)
+static int sis_133_pre_reset(struct ata_link *link)
 {
 	static const struct pci_bits sis_enable_bits[] = {
 		{ 0x4aU, 1U, 0x02UL, 0x02UL },	/* port 0 */
 		{ 0x4aU, 1U, 0x04UL, 0x04UL },	/* port 1 */
 	};
 
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u16 tmp;
 
@@ -84,7 +85,7 @@ static int sis_133_pre_reset(struct ata_
 	else
 		ap->cbl = ATA_CBL_PATA80;
 
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
@@ -103,19 +104,20 @@ static void sis_133_error_handler(struct
 
 /**
  *	sis_66_pre_reset	-	check for 40/80 pin
- *	@ap: Port
+ *	@link: ATA link
  *
  *	Perform cable detection on the UDMA66, UDMA100 and early UDMA133
  *	SiS IDE controllers.
  */
 
-static int sis_66_pre_reset(struct ata_port *ap)
+static int sis_66_pre_reset(struct ata_link *link)
 {
 	static const struct pci_bits sis_enable_bits[] = {
 		{ 0x4aU, 1U, 0x02UL, 0x02UL },	/* port 0 */
 		{ 0x4aU, 1U, 0x04UL, 0x04UL },	/* port 1 */
 	};
 
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 	u8 tmp;
 
@@ -132,7 +134,7 @@ static int sis_66_pre_reset(struct ata_p
 	else
 		ap->cbl = ATA_CBL_PATA80;
 
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 /**
@@ -151,18 +153,19 @@ static void sis_66_error_handler(struct 
 
 /**
  *	sis_old_pre_reset		-	probe begin
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Set up cable type and use generic probe init
  */
 
-static int sis_old_pre_reset(struct ata_port *ap)
+static int sis_old_pre_reset(struct ata_link *link)
 {
 	static const struct pci_bits sis_enable_bits[] = {
 		{ 0x4aU, 1U, 0x02UL, 0x02UL },	/* port 0 */
 		{ 0x4aU, 1U, 0x04UL, 0x04UL },	/* port 1 */
 	};
 
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
 	if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) {
@@ -171,7 +174,7 @@ static int sis_old_pre_reset(struct ata_
 		return 0;
 	}
 	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 
drivers/ata/pata_sl82c105.c +3 -2
index 08a6dc8..30794d1 100644
@@ -41,18 +41,19 @@ enum {
  *	Set up cable type and use generic probe init
  */
 
-static int sl82c105_pre_reset(struct ata_port *ap)
+static int sl82c105_pre_reset(struct ata_link *link)
 {
 	static const struct pci_bits sl82c105_enable_bits[] = {
 		{ 0x40, 1, 0x01, 0x01 },
 		{ 0x40, 1, 0x10, 0x10 }
 	};
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
 	if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no]))
 		return -ENOENT;
 	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 
drivers/ata/pata_triflex.c +4 -3
index 9640f80..a8d7078 100644
@@ -47,24 +47,25 @@ #define DRV_VERSION "0.2.5"
 
 /**
  *	triflex_prereset		-	probe begin
- *	@ap: ATA port
+ *	@link: ATA link
  *
  *	Set up cable type and use generic probe init
  */
 
-static int triflex_prereset(struct ata_port *ap)
+static int triflex_prereset(struct ata_link *link)
 {
 	static const struct pci_bits triflex_enable_bits[] = {
 		{ 0x80, 1, 0x01, 0x01 },
 		{ 0x80, 1, 0x02, 0x02 }
 	};
 
+	struct ata_port *ap = link->ap;
 	struct pci_dev *pdev = to_pci_dev(ap->host->dev);
 
 	if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no]))
 		return -ENOENT;
 	ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 
drivers/ata/pata_via.c +3 -2
index 1e7be9e..4fd6fee 100644
@@ -143,8 +143,9 @@ static int via_cable_detect(struct ata_p
 		return ATA_CBL_PATA40;
 }
 
-static int via_pre_reset(struct ata_port *ap)
+static int via_pre_reset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	const struct via_isa_bridge *config = ap->host->private_data;
 
 	if (!(config->flags & VIA_NO_ENABLES)) {
@@ -163,7 +164,7 @@ static int via_pre_reset(struct ata_port
 		ap->cbl = via_cable_detect(ap);
 	else
 		ap->cbl = ATA_CBL_PATA40;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(link);
 }
 
 
drivers/ata/sata_nv.c +2 -2
index f5c22de..34a8b18 100644
@@ -452,7 +452,7 @@ static void nv_ck804_thaw(struct ata_por
 	writeb(mask, mmio_base + NV_INT_ENABLE_CK804);
 }
 
-static int nv_hardreset(struct ata_port *ap, unsigned int *class)
+static int nv_hardreset(struct ata_link *link, unsigned int *class)
 {
 	unsigned int dummy;
 
@@ -460,7 +460,7 @@ static int nv_hardreset(struct ata_port 
 	 * some controllers.  Don't classify on hardreset.  For more
 	 * info, see http://bugme.osdl.org/show_bug.cgi?id=3352
 	 */
-	return sata_std_hardreset(ap, &dummy);
+	return sata_std_hardreset(link, &dummy);
 }
 
 static void nv_error_handler(struct ata_port *ap)
drivers/ata/sata_sil24.c +11 -9
index 29de9bd..8d6651f 100644
@@ -540,8 +540,9 @@ static int sil24_init_port(struct ata_po
 	return 0;
 }
 
-static int sil24_softreset(struct ata_port *ap, unsigned int *class)
+static int sil24_softreset(struct ata_link *link, unsigned int *class)
 {
+	struct ata_port *ap = link->ap;
 	void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
 	struct sil24_port_priv *pp = ap->private_data;
 	struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
@@ -551,7 +552,7 @@ static int sil24_softreset(struct ata_po
 
 	DPRINTK("ENTER\n");
 
-	if (ata_link_offline(&ap->link)) {
+	if (ata_link_offline(link)) {
 		DPRINTK("PHY reports no device\n");
 		*class = ATA_DEV_NONE;
 		goto out;
@@ -596,22 +597,23 @@ static int sil24_softreset(struct ata_po
 	return 0;
 
  err:
-	ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason);
+	ata_link_printk(link, KERN_ERR, "softreset failed (%s)\n", reason);
 	return -EIO;
 }
 
-static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
+static int sil24_hardreset(struct ata_link *link, unsigned int *class)
 {
+	struct ata_port *ap = link->ap;
 	void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
 	const char *reason;
 	int tout_msec, rc;
 	u32 tmp;
 
 	/* sil24 does the right thing(tm) without any protection */
-	sata_set_spd(&ap->link);
+	sata_set_spd(link);
 
 	tout_msec = 100;
-	if (ata_link_online(&ap->link))
+	if (ata_link_online(link))
 		tout_msec = 5000;
 
 	writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
@@ -621,14 +623,14 @@ static int sil24_hardreset(struct ata_po
 	/* SStatus oscillates between zero and valid status after
 	 * DEV_RST, debounce it.
 	 */
-	rc = sata_link_debounce(&ap->link, sata_deb_timing_long);
+	rc = sata_link_debounce(link, sata_deb_timing_long);
 	if (rc) {
 		reason = "PHY debouncing failed";
 		goto err;
 	}
 
 	if (tmp & PORT_CS_DEV_RST) {
-		if (ata_link_offline(&ap->link))
+		if (ata_link_offline(link))
 			return 0;
 		reason = "link not ready";
 		goto err;
@@ -643,7 +645,7 @@ static int sil24_hardreset(struct ata_po
 	return -EAGAIN;
 
  err:
-	ata_port_printk(ap, KERN_ERR, "hardreset failed (%s)\n", reason);
+	ata_link_printk(link, KERN_ERR, "hardreset failed (%s)\n", reason);
 	return -EIO;
 }
 
drivers/ata/sata_via.c +3 -2
index 6978bc8..02d2088 100644
@@ -205,7 +205,7 @@ static void svia_scr_write (struct ata_p
 
 /**
  *	vt6420_prereset - prereset for vt6420
- *	@ap: target ATA port
+ *	@link: target ATA link
  *
  *	SCR registers on vt6420 are pieces of shit and may hang the
  *	whole machine completely if accessed with the wrong timing.
@@ -222,8 +222,9 @@ static void svia_scr_write (struct ata_p
  *	RETURNS:
  *	0 on success, -errno otherwise.
  */
-static int vt6420_prereset(struct ata_port *ap)
+static int vt6420_prereset(struct ata_link *link)
 {
+	struct ata_port *ap = link->ap;
 	struct ata_eh_context *ehc = &ap->link.eh_context;
 	unsigned long timeout = jiffies + (HZ * 5);
 	u32 sstatus, scontrol;
include/linux/libata.h +9 -8
index 315ab6f..6241891 100644
@@ -337,13 +337,14 @@ enum ata_completion_errors {
 struct scsi_device;
 struct ata_port_operations;
 struct ata_port;
+struct ata_link;
 struct ata_queued_cmd;
 
 /* typedefs */
 typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
-typedef int (*ata_prereset_fn_t)(struct ata_port *ap);
-typedef int (*ata_reset_fn_t)(struct ata_port *ap, unsigned int *classes);
-typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *classes);
+typedef int (*ata_prereset_fn_t)(struct ata_link *link);
+typedef int (*ata_reset_fn_t)(struct ata_link *link, unsigned int *classes);
+typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes);
 
 struct ata_ioports {
 	unsigned long		cmd_addr;
@@ -714,12 +715,12 @@ extern int sata_set_spd(struct ata_link 
 extern int sata_link_debounce(struct ata_link *link,
 			      const unsigned long *params);
 extern int sata_link_resume(struct ata_link *link, const unsigned long *params);
-extern int ata_std_prereset(struct ata_port *ap);
-extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes);
-extern int sata_port_hardreset(struct ata_port *ap,
+extern int ata_std_prereset(struct ata_link *link);
+extern int ata_std_softreset(struct ata_link *link, unsigned int *classes);
+extern int sata_link_hardreset(struct ata_link *link,
 			       const unsigned long *timing);
-extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class);
-extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
+extern int sata_std_hardreset(struct ata_link *link, unsigned int *class);
+extern void ata_std_postreset(struct ata_link *link, unsigned int *classes);
 extern void sata_std_hp_poll_activate(struct ata_port *ap);
 extern int sata_std_hp_poll(struct ata_port *ap);
 extern int ata_dev_revalidate(struct ata_device *dev, int post_reset);
Signature · 1 line
1.4.2.3
author
#9 lore raw

PATCH 9/18 libata-link: linkify config/EH related functions

In reply to Tejun Heo

Make the following functions deal with ata_link instead of ata_port.

* ata_set_mode()
* ata_eh_autopsy() and related functions
* ata_eh_report() and related functions
* suspend/resume related functions
* ata_eh_recover() and related functions

---
 drivers/ata/libata-core.c |    8 +-
 drivers/ata/libata-eh.c   |  163 ++++++++++++++++++++++++---------------------
 drivers/ata/libata.h      |    3 +
 3 files changed, 92 insertions(+), 82 deletions(-)
drivers/ata/libata-core.c +4 -4
index 5293fe0..6a3442b 100644
@@ -1638,7 +1638,7 @@ int ata_bus_probe(struct ata_port *ap)
 	}
 
 	/* configure transfer mode */
-	rc = ata_set_mode(ap, &dev);
+	rc = ata_set_mode(&ap->link, &dev);
 	if (rc) {
 		down_xfermask = 1;
 		goto fail;
@@ -2180,7 +2180,7 @@ static int ata_dev_set_mode(struct ata_d
 
 /**
  *	ata_set_mode - Program timings and issue SET FEATURES - XFER
- *	@ap: port on which timings will be programmed
+ *	@link: link on which timings will be programmed
  *	@r_failed_dev: out paramter for failed device
  *
  *	Set ATA device disk transfer mode (PIO3, UDMA6, etc.).  If
@@ -2193,9 +2193,9 @@ static int ata_dev_set_mode(struct ata_d
  *	RETURNS:
  *	0 on success, negative errno otherwise
  */
-int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
+int ata_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
 {
-	struct ata_link *link = &ap->link;
+	struct ata_port *ap = link->ap;
 	struct ata_device *dev;
 	int rc = 0, used_dma = 0, found = 0;
 
drivers/ata/libata-eh.c +86 -77

499 lines not on this page · raw message

drivers/ata/libata.h +2 -1
index d8e9f4e..92ae977 100644
@@ -57,7 +57,8 @@ extern int ata_dev_configure(struct ata_
 extern int sata_down_spd_limit(struct ata_link *link);
 extern int sata_set_spd_needed(struct ata_link *link);
 extern int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0);
-extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
+extern int ata_set_mode(struct ata_link *link,
+			struct ata_device **r_failed_dev);
 extern void ata_qc_free(struct ata_queued_cmd *qc);
 extern void ata_qc_issue(struct ata_queued_cmd *qc);
 extern void __ata_qc_complete(struct ata_queued_cmd *qc);
Signature · 1 line
1.4.2.3
author
#10 lore raw

PATCH 10/18 libata-link: separate out link initialization functions

In reply to Tejun Heo

Separate out link initialization into ata_link_init() and ata_link_init_sata_spd_limit().

---
 drivers/ata/libata-core.c |   80 +++++++++++++++++++++++++++++++++++----------
 1 files changed, 62 insertions(+), 18 deletions(-)
drivers/ata/libata-core.c +62 -18
index 6a3442b..f5a9ac2 100644
@@ -5392,6 +5392,66 @@ void ata_dev_init(struct ata_device *dev
 }
 
 /**
+ *	ata_link_init - Initialize an ata_link structure
+ *	@ap: ATA port link is attached to
+ *	@link: Link structure to initialize
+ *
+ *	Initialize @link.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep)
+ */
+static void ata_link_init(struct ata_port *ap, struct ata_link *link)
+{
+	struct ata_device *dev;
+
+	/* clear everything except for devices */
+	memset(link, 0, offsetof(struct ata_link, device[0]));
+
+	link->ap = ap;
+	link->active_tag = ATA_TAG_POISON;
+	link->hw_sata_spd_limit = UINT_MAX;
+
+	ata_link_for_each_dev(dev, link) {
+		dev->link = link;
+		dev->devno = dev - link->device;
+		ata_dev_init(dev);
+	}
+}
+
+/**
+ *	sata_link_init_spd_limit - Initialize link->sata_spd_limit
+ *	@link: Link to configure sata_spd_limit for
+ *
+ *	Initialize @link->[hw_]sata_spd_limit to the currently
+ *	configured value.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ *
+ *	RETURNS:
+ *	0 on success, -errno on failure.
+ */
+static int sata_link_init_spd_limit(struct ata_link *link)
+{
+
+	u32 scontrol, spd;
+	int rc;
+
+	rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
+	if (rc)
+		return rc;
+
+	spd = (scontrol >> 4) & 0xf;
+	if (spd)
+		link->hw_sata_spd_limit &= (1 << spd) - 1;
+
+	link->sata_spd_limit = link->hw_sata_spd_limit;
+
+	return 0;
+}
+
+/**
  *	ata_port_init - Initialize an ata_port structure
  *	@ap: Structure to initialize
  *	@host: Collection of hosts to which @ap belongs
@@ -5406,8 +5466,6 @@ void ata_dev_init(struct ata_device *dev
 void ata_port_init(struct ata_port *ap, struct ata_host *host,
 		   const struct ata_probe_ent *ent, unsigned int port_no)
 {
-	unsigned int i;
-
 	ap->lock = &host->lock;
 	ap->flags = ATA_FLAG_DISABLED;
 	ap->id = ata_unique_id++;
@@ -5428,8 +5486,6 @@ void ata_port_init(struct ata_port *ap, 
 		ap->flags |= ent->port_flags;
 		ap->ops = ent->port_ops;
 	}
-	ap->link.hw_sata_spd_limit = UINT_MAX;
-	ap->link.active_tag = ATA_TAG_POISON;
 	ap->last_ctl = 0xFF;
 
 #if defined(ATA_VERBOSE_DEBUG)
@@ -5452,14 +5508,7 @@ #endif
 	if (ap->flags & ATA_FLAG_SATA)
 		ap->cbl = ATA_CBL_SATA;
 
-	ap->link.ap = ap;
-
-	for (i = 0; i < ata_link_max_devices(&ap->link); i++) {
-		struct ata_device *dev = &ap->link.device[i];
-		dev->link = &ap->link;
-		dev->devno = i;
-		ata_dev_init(dev);
-	}
+	ata_link_init(ap, &ap->link);
 
 #ifdef ATA_IRQ_TRAP
 	ap->stats.unhandled_irq = 1;
@@ -5677,15 +5726,10 @@ int ata_device_add(const struct ata_prob
 	DPRINTK("probe begin\n");
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
-		u32 scontrol;
 		int rc;
 
 		/* init sata_spd_limit to the current value */
-		if (sata_scr_read(&ap->link, SCR_CONTROL, &scontrol) == 0) {
-			int spd = (scontrol >> 4) & 0xf;
-			ap->link.hw_sata_spd_limit &= (1 << spd) - 1;
-		}
-		ap->link.sata_spd_limit = ap->link.hw_sata_spd_limit;
+		sata_link_init_spd_limit(&ap->link);
 
 		rc = scsi_add_host(ap->scsi_host, dev);
 		if (rc) {
Signature · 1 line
1.4.2.3
#11 lore raw

Re: [PATCH 10/18] [PATCH] libata-link: separate out link initialization functions

Quoted 2 lines · Tejun Heo

Separate out link initialization into ata_link_init() and ata_link_init_sata_spd_limit().

pushing the bounds of good taste, with a long function name :)

author
#12 lore raw

PATCH 11/18 libata-link: implement link->reset_tries

In reply to Tejun Heo

Make reset_tries per-link property. PMP links will use different value from host links.

---
 drivers/ata/libata-core.c |    1 +
 drivers/ata/libata-eh.c   |    2 +-
 include/linux/libata.h    |    2 ++
 3 files changed, 4 insertions(+), 1 deletions(-)
drivers/ata/libata-core.c +1 -0
index f5a9ac2..67e08e3 100644
@@ -5411,6 +5411,7 @@ static void ata_link_init(struct ata_por
 	link->ap = ap;
 	link->active_tag = ATA_TAG_POISON;
 	link->hw_sata_spd_limit = UINT_MAX;
+	link->reset_tries = ATA_EH_RESET_TRIES;
 
 	ata_link_for_each_dev(dev, link) {
 		dev->link = link;
drivers/ata/libata-eh.c +1 -1
index c75f9b0..9b16bc6 100644
@@ -1522,7 +1522,7 @@ static int ata_eh_reset(struct ata_link 
 {
 	struct ata_eh_context *ehc = &link->eh_context;
 	unsigned int *classes = ehc->classes;
-	int tries = ATA_EH_RESET_TRIES;
+	int tries = link->reset_tries;
 	int verbose = !(ehc->i.flags & ATA_EHI_QUIET);
 	struct ata_device *dev;
 	unsigned int action;
include/linux/libata.h +2 -0
index 6241891..02e21a7 100644
@@ -537,6 +537,8 @@ struct ata_link {
 	unsigned int		hw_sata_spd_limit;
 	unsigned int		sata_spd_limit;
 
+	int			reset_tries;
+
 	/* record runtime error info, protected by host_set lock */
 	struct ata_eh_info	eh_info;
 	/* EH context */
Signature · 1 line
1.4.2.3
author
#13 lore raw

PATCH 12/18 libata-link: implement ata_link_abort()

In reply to Tejun Heo

Implement ata_link_abort().

---
 drivers/ata/libata-core.c |    1 +
 drivers/ata/libata-eh.c   |   50 ++++++++++++++++++++++++++++++++-------------
 include/linux/libata.h    |    1 +
 3 files changed, 38 insertions(+), 14 deletions(-)
drivers/ata/libata-core.c +1 -0
index 67e08e3..2813bb8 100644
@@ -6349,6 +6349,7 @@ EXPORT_SYMBOL_GPL(ata_scsi_device_resume
 
 EXPORT_SYMBOL_GPL(ata_eng_timeout);
 EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
+EXPORT_SYMBOL_GPL(ata_link_abort);
 EXPORT_SYMBOL_GPL(ata_port_abort);
 EXPORT_SYMBOL_GPL(ata_port_freeze);
 EXPORT_SYMBOL_GPL(ata_eh_freeze_port);
drivers/ata/libata-eh.c +36 -14

68 lines not on this page · raw message

include/linux/libata.h +1 -0
index 02e21a7..e4fd809 100644
@@ -890,6 +890,7 @@ #endif /* CONFIG_PCI */
 extern void ata_eng_timeout(struct ata_port *ap);
 
 extern void ata_port_schedule_eh(struct ata_port *ap);
+extern int ata_link_abort(struct ata_link *link);
 extern int ata_port_abort(struct ata_port *ap);
 extern int ata_port_freeze(struct ata_port *ap);
 
Signature · 1 line
1.4.2.3
author
#14 lore raw

PATCH 13/18 libata-link: add PMP links

In reply to Tejun Heo

Add link->pmp, ap->nr_pmp_links, ap->pmp_link[], and implement/update link helpers.

printk helpers are updated such that port and link are identifed as 'ataP:' if no PMP is attached, while device is identified as 'ataP.DD:'. If PMP is attached, they become 'ataP:', 'ataP.LL:' and 'ataP.LL' - ie. link and device are identified their PMP number.

If PPM is attached (ap->nr_pmp_links != 0), ata_for_each_link() iterates over PMP links, while __ata_for_each_link() iterates over the host link + PMP links. If PMP is not attached (ap->nr_pmp_links == 0), both iterate over only the host link.

---
 drivers/ata/libata-core.c |    6 +++--
 include/linux/libata.h    |   52 ++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 50 insertions(+), 8 deletions(-)
drivers/ata/libata-core.c +4 -2
index 2813bb8..0ef6ab0 100644
@@ -5395,13 +5395,14 @@ void ata_dev_init(struct ata_device *dev
  *	ata_link_init - Initialize an ata_link structure
  *	@ap: ATA port link is attached to
  *	@link: Link structure to initialize
+ *	@pmp: Port multiplier port number
  *
  *	Initialize @link.
  *
  *	LOCKING:
  *	Kernel thread context (may sleep)
  */
-static void ata_link_init(struct ata_port *ap, struct ata_link *link)
+static void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
 {
 	struct ata_device *dev;
 
@@ -5409,6 +5410,7 @@ static void ata_link_init(struct ata_por
 	memset(link, 0, offsetof(struct ata_link, device[0]));
 
 	link->ap = ap;
+	link->pmp = pmp;
 	link->active_tag = ATA_TAG_POISON;
 	link->hw_sata_spd_limit = UINT_MAX;
 	link->reset_tries = ATA_EH_RESET_TRIES;
@@ -5509,7 +5511,7 @@ #endif
 	if (ap->flags & ATA_FLAG_SATA)
 		ap->cbl = ATA_CBL_SATA;
 
-	ata_link_init(ap, &ap->link);
+	ata_link_init(ap, &ap->link, 0);
 
 #ifdef ATA_IRQ_TRAP
 	ap->stats.unhandled_irq = 1;
include/linux/libata.h +46 -6

84 lines not on this page · raw message

Signature · 1 line
1.4.2.3
author
#15 lore raw

PATCH 14/18 libata-link: update ata_scsi_error() to handle PMP links

In reply to Tejun Heo

Update ata_scsi_error() to handle PMP links. As error conditions can occur on both host and PMP links, __ata_port_for_each_link() is used.

---
 drivers/ata/libata-eh.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)
drivers/ata/libata-eh.c +9 -4
index d1927a7..5ce1e16 100644
@@ -272,15 +272,19 @@ void ata_scsi_error(struct Scsi_Host *ho
  repeat:
 	/* invoke error handler */
 	if (ap->ops->error_handler) {
+		struct ata_link *link;
+
 		/* process port resume request */
 		ata_eh_handle_port_resume(ap);
 
 		/* fetch & clear EH info */
 		spin_lock_irqsave(ap->lock, flags);
 
-		memset(&ap->link.eh_context, 0, sizeof(ap->link.eh_context));
-		ap->link.eh_context.i = ap->link.eh_info;
-		memset(&ap->link.eh_info, 0, sizeof(ap->link.eh_info));
+		__ata_port_for_each_link(link, ap) {
+			memset(&link->eh_context, 0, sizeof(link->eh_context));
+			link->eh_context.i = link->eh_info;
+			memset(&link->eh_info, 0, sizeof(link->eh_info));
+		}
 
 		ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS;
 		ap->pflags &= ~ATA_PFLAG_EH_PENDING;
@@ -315,7 +319,8 @@ void ata_scsi_error(struct Scsi_Host *ho
 		}
 
 		/* this run is complete, make sure EH info is clear */
-		memset(&ap->link.eh_info, 0, sizeof(ap->link.eh_info));
+		__ata_port_for_each_link(link, ap)
+			memset(&link->eh_info, 0, sizeof(link->eh_info));
 
 		/* Clear host_eh_scheduled while holding ap->lock such
 		 * that if exception occurs after this point but
Signature · 1 line
1.4.2.3
author
#16 lore raw

PATCH 15/18 libata-link: update ata_dev_configure() to deal with PMP links

In reply to Tejun Heo

Update ata_dev_configure() to deal with PMP links.

---
 drivers/ata/libata-core.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)
drivers/ata/libata-core.c +6 -3
index 0ef6ab0..98ed9fd 100644
@@ -1363,10 +1363,13 @@ static void ata_set_port_max_cmd_len(str
 {
 	if (ap->scsi_host) {
 		unsigned int len = 0;
-		struct ata_device *dev;
+		struct ata_link *link;
 
-		ata_link_for_each_dev(dev, &ap->link)
-			len = max(len, dev->cdb_len);
+		ata_port_for_each_link(link, ap) {
+			struct ata_device *dev;
+			ata_link_for_each_dev(dev, link)
+				len = max(len, dev->cdb_len);
+		}
 
 		ap->scsi_host->max_cmd_len = len;
 	}
Signature · 1 line
1.4.2.3
author
#17 lore raw

PATCH 16/18 libata-link: update EH to deal with PMP links

In reply to Tejun Heo

Update ata_eh_autopsy(), ata_eh_report() and ata_eh_recover() to deal with PMP links. ata_eh_autopsy() and ata_eh_report() updates are straightforward. They just repeat the same operation over all configured links.

ata_eh_recover() update is more complex as it first processes all resets and then performs the rest. This is necessary as thawing with some links in unknown state can be dangerous. ehi->action is cleared on successful recovery of a link to avoid repeating recovery due to failures in other links.

ata_eh_recover() iterates over only PMP links if PMP is attached, and, on failure, the failing link is returned in @failed_link instead of disabling devices directly. These are to integrate ata_eh_recover() into PMP EH later.

---
 drivers/ata/libata-eh.c |  248 ++++++++++++++++++++++++++++++++---------------
 1 files changed, 170 insertions(+), 78 deletions(-)
drivers/ata/libata-eh.c +170 -78
index 5ce1e16..1389a1f 100644
@@ -1332,8 +1332,8 @@ static int ata_eh_speed_down(struct ata_
 }
 
 /**
- *	ata_eh_autopsy - analyze error and determine recovery action
- *	@link: ATA link to perform autopsy on
+ *	ata_eh_link_autopsy - analyze error and determine recovery action
+ *	@link: host link to perform autopsy on
  *
  *	Analyze why @link failed and determine which recovery actions
  *	are needed.  This function also sets more detailed AC_ERR_*
@@ -1342,7 +1342,7 @@ static int ata_eh_speed_down(struct ata_
  *	LOCKING:
  *	Kernel thread context (may sleep).
  */
-static void ata_eh_autopsy(struct ata_link *link)
+static void ata_eh_link_autopsy(struct ata_link *link)
 {
 	struct ata_port *ap = link->ap;
 	struct ata_eh_context *ehc = &link->eh_context;
@@ -1432,7 +1432,25 @@ static void ata_eh_autopsy(struct ata_li
 }
 
 /**
- *	ata_eh_report - report error handling to user
+ *	ata_eh_autopsy - analyze error and determine recovery action
+ *	@ap: host port to perform autopsy on
+ *
+ *	Analyze all links of @ap and determine why they failed and
+ *	which recovery actions are needed.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep).
+ */
+static void ata_eh_autopsy(struct ata_port *ap)
+{
+	struct ata_link *link;
+
+	__ata_port_for_each_link(link, ap)
+		ata_eh_link_autopsy(link);
+}
+
+/**
+ *	ata_eh_link_report - report error handling to user
  *	@link: ATA link EH is going on
  *
  *	Report EH to user.
@@ -1440,7 +1458,7 @@ static void ata_eh_autopsy(struct ata_li
  *	LOCKING:
  *	None.
  */
-static void ata_eh_report(struct ata_link *link)
+static void ata_eh_link_report(struct ata_link *link)
 {
 	struct ata_port *ap = link->ap;
 	struct ata_eh_context *ehc = &link->eh_context;
@@ -1500,6 +1518,23 @@ static void ata_eh_report(struct ata_lin
 	}
 }
 
+/**
+ *	ata_eh_report - report error handling to user
+ *	@ap: ATA port to report EH about
+ *
+ *	Report EH to user.
+ *
+ *	LOCKING:
+ *	None.
+ */
+static void ata_eh_report(struct ata_port *ap)
+{
+	struct ata_link *link;
+
+	__ata_port_for_each_link(link, ap)
+		ata_eh_link_report(link);
+}
+
 static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
 			unsigned int *classes)
 {
@@ -1904,6 +1939,17 @@ static int ata_link_nr_enabled(struct at
 	return cnt;
 }
 
+static int ata_port_nr_enabled(struct ata_port *ap)
+{
+	struct ata_link *link;
+	int cnt = 0;
+
+	ata_port_for_each_link(link, ap)
+		cnt += ata_link_nr_enabled(link);
+
+	return cnt;
+}
+
 static int ata_link_nr_vacant(struct ata_link *link)
 {
 	struct ata_device *dev;
@@ -2000,12 +2046,13 @@ static void ata_eh_handle_dev_fail(struc
  *	@softreset: softreset method (can be NULL)
  *	@hardreset: hardreset method (can be NULL)
  *	@postreset: postreset method (can be NULL)
+ *	@r_failed_link: out parameter for failed link
  *
  *	This is the alpha and omega, eum and yang, heart and soul of
  *	libata exception handling.  On entry, actions required to
- *	recover the port and hotplug requests are recorded in
- *	eh_context.  This function executes all the operations with
- *	appropriate retrials and fallbacks to resurrect failed
+ *	recover each link and hotplug requests are recorded in the
+ *	link's eh_context.  This function executes all the operations
+ *	with appropriate retrials and fallbacks to resurrect failed
  *	devices, detach goners and greet newcomers.
  *
  *	LOCKING:
@@ -2016,115 +2063,147 @@ static void ata_eh_handle_dev_fail(struc
  */
 static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
 			  ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
-			  ata_postreset_fn_t postreset)
+			  ata_postreset_fn_t postreset,
+			  struct ata_link **r_failed_link)
 {
-	struct ata_link *link = &ap->link;
-	struct ata_eh_context *ehc = &link->eh_context;
+	struct ata_link *link;
 	struct ata_device *dev;
-	int down_xfermask, rc;
+	int nr_failed_devs;
+	int reset, rc;
 
 	DPRINTK("ENTER\n");
 
 	/* prep for recovery */
-	ata_link_for_each_dev(dev, link) {
-		ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
+	ata_port_for_each_link(link, ap) {
+		struct ata_eh_context *ehc = &link->eh_context;
 
-		/* process hotplug request */
-		if (dev->flags & ATA_DFLAG_DETACH)
-			ata_eh_detach_dev(dev);
+		ata_link_for_each_dev(dev, link) {
+			ehc->tries[dev->devno] = ATA_EH_DEV_TRIES;
 
-		if (!ata_dev_enabled(dev) &&
-		    ((ehc->i.probe_mask & (1 << dev->devno)) &&
-		     !(ehc->did_probe_mask & (1 << dev->devno)))) {
-			ata_eh_detach_dev(dev);
-			ata_dev_init(dev);
-			ehc->did_probe_mask |= (1 << dev->devno);
-			ehc->i.action |= ATA_EH_SOFTRESET;
+			/* process hotplug request */
+			if (dev->flags & ATA_DFLAG_DETACH)
+				ata_eh_detach_dev(dev);
+
+			if (!ata_dev_enabled(dev) &&
+			    (ehc->i.probe_mask & (1 << dev->devno) &&
+			     !(ehc->did_probe_mask & (1 << dev->devno)))) {
+				ata_eh_detach_dev(dev);
+				ata_dev_init(dev);
+				ehc->did_probe_mask |= (1 << dev->devno);
+				ehc->i.action |= ATA_EH_SOFTRESET;
+			}
 		}
 	}
 
  retry:
-	down_xfermask = 0;
 	rc = 0;
+	nr_failed_devs = 0;
+	reset = 0;
 
 	/* if UNLOADING, finish immediately */
 	if (ap->pflags & ATA_PFLAG_UNLOADING)
 		goto out;
 
-	/* prep for resume */
-	ata_eh_prep_resume(link);
+	/* prep for EH */
+	ata_port_for_each_link(link, ap) {
+		struct ata_eh_context *ehc = &link->eh_context;
 
-	/* skip EH if possible. */
-	if (ata_eh_skip_recovery(link))
-		ehc->i.action = 0;
+		/* prep for resume */
+		ata_eh_prep_resume(link);
 
-	ata_link_for_each_dev(dev, link)
-		ehc->classes[dev->devno] = ATA_DEV_UNKNOWN;
+		/* skip EH if possible. */
+		if (ata_eh_skip_recovery(link))
+			ehc->i.action = 0;
+
+		/* do we need to reset? */
+		if (ehc->i.action & ATA_EH_RESET_MASK)
+			reset = 1;
+
+		ata_link_for_each_dev(dev, link)
+			ehc->classes[dev->devno] = ATA_DEV_UNKNOWN;
+	}
 
 	/* reset */
-	if (ehc->i.action & ATA_EH_RESET_MASK) {
+	if (reset) {
 		ata_eh_freeze_port(ap);
 
-		rc = ata_eh_reset(link, ata_link_nr_vacant(link), prereset,
-				  softreset, hardreset, postreset);
-		if (rc) {
-			ata_link_printk(link, KERN_ERR,
-					"reset failed, giving up\n");
-			goto out;
+		ata_port_for_each_link(link, ap) {
+			struct ata_eh_context *ehc = &link->eh_context;
+
+			if (!(ehc->i.action & ATA_EH_RESET_MASK))
+				continue;
+
+			rc = ata_eh_reset(link, ata_link_nr_vacant(link),
+					  prereset, softreset, hardreset,
+					  postreset);
+			if (rc) {
+				ata_link_printk(link, KERN_ERR,
+						"reset failed, giving up\n");
+				goto out;
+			}
 		}
 
 		ata_eh_thaw_port(ap);
 	}
 
-	/* revalidate existing devices and attach new ones */
-	rc = ata_eh_revalidate_and_attach(link, &dev);
-	if (rc)
-		goto dev_fail;
+	/* the rest */
+	ata_port_for_each_link(link, ap) {
+		struct ata_eh_context *ehc = &link->eh_context;
+		int down_xfermask = 0;
 
-	/* resume devices */
-	rc = ata_eh_resume(link, &dev);
-	if (rc)
-		goto dev_fail;
+		/* revalidate existing devices and attach new ones */
+		rc = ata_eh_revalidate_and_attach(link, &dev);
+		if (rc)
+			goto dev_fail;
 
-	/* configure transfer mode if the port has been reset */
-	if (ehc->i.flags & ATA_EHI_DID_RESET) {
-		rc = ata_set_mode(link, &dev);
-		if (rc) {
-			down_xfermask = 1;
+		/* resume devices */
+		rc = ata_eh_resume(link, &dev);
+		if (rc)
 			goto dev_fail;
+
+		/* configure transfer mode if the port has been reset */
+		if (ehc->i.flags & ATA_EHI_DID_RESET) {
+			rc = ata_set_mode(link, &dev);
+			if (rc) {
+				down_xfermask = 1;
+				goto dev_fail;
+			}
 		}
-	}
 
-	/* suspend devices */
-	rc = ata_eh_suspend(link, &dev);
-	if (rc)
-		goto dev_fail;
+		/* suspend devices */
+		rc = ata_eh_suspend(link, &dev);
+		if (rc)
+			goto dev_fail;
 
-	goto out;
+		/* this link is okay now */
+		ehc->i.flags = 0;
+		continue;
 
- dev_fail:
-	ata_eh_handle_dev_fail(dev, rc, down_xfermask);
+	dev_fail:
+		ata_eh_handle_dev_fail(dev, rc, down_xfermask);
+		nr_failed_devs++;
 
-	if (ata_link_nr_enabled(link)) {
-		ata_link_printk(link, KERN_WARNING, "failed to recover some "
-				"devices, retrying in 5 secs\n");
-		ssleep(5);
-	} else {
-		/* no device left, repeat fast */
-		msleep(500);
+		if (ap->pflags & ATA_PFLAG_FROZEN)
+			break;
 	}
 
-	goto retry;
-
- out:
-	if (rc) {
-		/* recovery failed, activate hp-poll */
-		ata_hp_poll_activate(ap);
+	if (nr_failed_devs) {
+		if (ata_port_nr_enabled(ap)) {
+			ata_port_printk(ap, KERN_WARNING, "failed to recover "
+					"some devices, retrying in 5 secs\n");
+			ssleep(5);
+		} else {
+			/* no device left, repeat fast */
+			msleep(500);
+		}
 
-		ata_link_for_each_dev(dev, link);
-			ata_dev_disable(dev);
+		goto retry;
 	}
 
+ out:
+	if (rc && r_failed_link)
+		*r_failed_link = link;
+
 	DPRINTK("EXIT, rc=%d\n", rc);
 	return rc;
 }
@@ -2188,9 +2267,22 @@ void ata_do_eh(struct ata_port *ap, ata_
 	       ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
 	       ata_postreset_fn_t postreset)
 {
-	ata_eh_autopsy(&ap->link);
-	ata_eh_report(&ap->link);
-	ata_eh_recover(ap, prereset, softreset, hardreset, postreset);
+	struct ata_device *dev;
+	int rc;
+
+	ata_eh_autopsy(ap);
+	ata_eh_report(ap);
+
+	rc = ata_eh_recover(ap, prereset, softreset, hardreset, postreset,
+			    NULL);
+	if (rc) {
+		/* recovery failed, activate hp-poll */
+		ata_hp_poll_activate(ap);
+
+		ata_link_for_each_dev(dev, &ap->link)
+			ata_dev_disable(dev);
+	}
+
 	ata_eh_finish(ap);
 }
 
Signature · 1 line
1.4.2.3
author
#18 lore raw

PATCH 17/18 libata-link: update hotplug to handle PMP links

In reply to Tejun Heo

Update hotplug to handle PMP links. When PMP is attached, the PMP number corresponds to I of SCSI C:H:I:L.

---
 drivers/ata/libata-core.c |    7 ++-
 drivers/ata/libata-scsi.c |  110 ++++++++++++++++++++++++++++++++-------------
 2 files changed, 82 insertions(+), 35 deletions(-)
drivers/ata/libata-core.c +5 -2
index 98ed9fd..cc21698 100644
@@ -5827,6 +5827,7 @@ err_out:
 void ata_port_detach(struct ata_port *ap)
 {
 	unsigned long flags;
+	struct ata_link *link;
 	struct ata_device *dev;
 
 	if (!ap->ops->error_handler)
@@ -5844,8 +5845,10 @@ void ata_port_detach(struct ata_port *ap
 	 */
 	spin_lock_irqsave(ap->lock, flags);
 
-	ata_link_for_each_dev(dev, &ap->link)
-		ata_dev_disable(dev);
+	ata_port_for_each_link(link, ap) {
+		ata_link_for_each_dev(dev, link)
+			ata_dev_disable(dev);
+	}
 
 	spin_unlock_irqrestore(ap->lock, flags);
 
drivers/ata/libata-scsi.c +77 -33

180 lines not on this page · raw message

Signature · 1 line
1.4.2.3
author
#19 lore raw

PATCH 18/18 libata-link: update Power Management to handle PMP links

In reply to Tejun Heo

Update Power Management to consider PMP links.

---
 drivers/ata/libata-core.c |   20 +++++++++++++-------
 drivers/ata/libata-eh.c   |   16 ++++++++++------
 2 files changed, 23 insertions(+), 13 deletions(-)
drivers/ata/libata-core.c +13 -7
index cc21698..0c94b65 100644
@@ -5195,6 +5195,7 @@ static int ata_host_request_pm(struct at
 
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
+		struct ata_link *link;
 
 		/* Previous resume operation might still be in
 		 * progress.  Wait for PM_PENDING to clear.
@@ -5214,8 +5215,10 @@ static int ata_host_request_pm(struct at
 		}
 
 		ap->pflags |= ATA_PFLAG_PM_PENDING;
-		ap->link.eh_info.action |= action;
-		ap->link.eh_info.flags |= ehi_flags;
+		__ata_port_for_each_link(link, ap) {
+			link->eh_info.action |= action;
+			link->eh_info.flags |= ehi_flags;
+		}
 
 		ata_port_schedule_eh(ap);
 
@@ -5262,15 +5265,18 @@ int ata_host_suspend(struct ata_host *ho
 	 */
 	for (i = 0; i < host->n_ports; i++) {
 		struct ata_port *ap = host->ports[i];
+		struct ata_link *link;
 		struct ata_device *dev;
 
-		ata_link_for_each_dev(dev, &ap->link) {
-			if (ata_dev_ready(dev)) {
-				ata_port_printk(ap, KERN_WARNING,
+		ata_port_for_each_link(link, ap) {
+			ata_link_for_each_dev(dev, link) {
+				if (ata_dev_ready(dev)) {
+					ata_port_printk(ap, KERN_WARNING,
 						"suspend failed, device %d "
 						"still active\n", dev->devno);
-				rc = -EBUSY;
-				goto fail;
+					rc = -EBUSY;
+					goto fail;
+				}
 			}
 		}
 	}
drivers/ata/libata-eh.c +10 -6
index 1389a1f..ead460b 100644
@@ -2378,17 +2378,21 @@ static void ata_eh_handle_port_resume(st
 	/* give devices time to request EH */
 	timeout = jiffies + HZ; /* 1s max */
 	while (1) {
+		struct ata_link *link;
 		struct ata_device *dev;
 
-		ata_link_for_each_dev(dev, &ap->link) {
-			unsigned int action = ata_eh_dev_action(dev);
+		ata_port_for_each_link(link, ap) {
+			ata_link_for_each_dev(dev, link) {
+				unsigned int action = ata_eh_dev_action(dev);
 
-			if ((dev->flags & ATA_DFLAG_SUSPENDED) &&
-			    !(action & ATA_EH_RESUME))
-				break;
+				if ((dev->flags & ATA_DFLAG_SUSPENDED) &&
+				    !(action & ATA_EH_RESUME))
+					goto out_of_loop;
+			}
 		}
+	out_of_loop:
 
-		if (dev == NULL || time_after(jiffies, timeout))
+		if (link == NULL || time_after(jiffies, timeout))
 			break;
 		msleep(10);
 	}
Signature · 1 line
1.4.2.3
author
#20 lore raw
In reply to Tejun Heo
Quoted 26 lines · Tejun Heo

Hello, all.

This is the third take of implement ata_link patchset. This patchset contains 18 patches which can be categorized as follows.

#01-03: prep
#04-05: implement ata_link
#06-09: make libata deal with link instead of port #10-12: misc link stuff (link init, reset_tries, ata_link_abort()) #13-19: add ap->pmp_link[] and update libata to deal with multiple
links

ata_link abstracts PHY and sits between ata_port and ata_device. The following attributes are moved to ata_link from ata_port.

- active command state (active_tag, sactive)
- [hw_]sata_spd_limit
- eh_info and eh_context
- device array

With above and a few extra fields, a link can fully host attached devices including qc management and EH/hotplug. This patchset makes libata ready to handle PM links.

Changes from the last take[L] are.

Quoted 8 lines

* updated to fit new #upstream
* __dev1 trick removed

This patchset is against

upstream (da54f5fe54c7d75e2db7d17961fb36a8c28a8501)
+ [1] hp-poll patchset, take #5
+ [2] vt8251-ahci patchset, take #2

Forgot about git tree, sorry. This patchset can be accessed via the following git tree.

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

Signature · 1 line
tejun
#21 lore raw
In reply to Tejun Heo
Quoted 26 lines · Tejun Heo

Hello, all.

This is the third take of implement ata_link patchset. This patchset contains 18 patches which can be categorized as follows.

#01-03: prep
#04-05: implement ata_link
#06-09: make libata deal with link instead of port #10-12: misc link stuff (link init, reset_tries, ata_link_abort()) #13-19: add ap->pmp_link[] and update libata to deal with multiple
links

ata_link abstracts PHY and sits between ata_port and ata_device. The following attributes are moved to ata_link from ata_port.

- active command state (active_tag, sactive)
- [hw_]sata_spd_limit
- eh_info and eh_context
- device array

With above and a few extra fields, a link can fully host attached devices including qc management and EH/hotplug. This patchset makes libata ready to handle PM links.

Changes from the last take[L] are.

Quoted 8 lines

* updated to fit new #upstream
* __dev1 trick removed

This patchset is against

upstream (da54f5fe54c7d75e2db7d17961fb36a8c28a8501)
+ [1] hp-poll patchset, take #5
+ [2] vt8251-ahci patchset, take #2

ACK patchset