diff options
Diffstat (limited to 'drivers/ata/libata-eh.c')
| -rw-r--r-- | drivers/ata/libata-eh.c | 454 | 
1 files changed, 299 insertions, 155 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 5e590504f3a..dad83df555c 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1,7 +1,7 @@  /*   *  libata-eh.c - libata error handling   * - *  Maintained by:  Jeff Garzik <jgarzik@pobox.com> + *  Maintained by:  Tejun Heo <tj@kernel.org>   *    		    Please ALWAYS copy linux-ide@vger.kernel.org   *		    on emails.   * @@ -34,6 +34,7 @@  #include <linux/kernel.h>  #include <linux/blkdev.h> +#include <linux/export.h>  #include <linux/pci.h>  #include <scsi/scsi.h>  #include <scsi/scsi_host.h> @@ -94,12 +95,13 @@ enum {   * represents timeout for that try.  The first try can be soft or   * hardreset.  All others are hardreset if available.  In most cases   * the first reset w/ 10sec timeout should succeed.  Following entries - * are mostly for error handling, hotplug and retarded devices. + * are mostly for error handling, hotplug and those outlier devices that + * take an exceptionally long time to recover from reset.   */  static const unsigned long ata_eh_reset_timeouts[] = {  	10000,	/* most drives spin up by 10sec */  	10000,	/* > 99% working drives spin up before 20sec */ -	35000,	/* give > 30 secs of idleness for retarded devices */ +	35000,	/* give > 30 secs of idleness for outlier devices */  	 5000,	/* and sweet one last chance */  	ULONG_MAX, /* > 1 min has elapsed, give up */  }; @@ -418,7 +420,7 @@ int ata_ering_map(struct ata_ering *ering,  	return rc;  } -int ata_ering_clear_cb(struct ata_ering_entry *ent, void *void_arg) +static int ata_ering_clear_cb(struct ata_ering_entry *ent, void *void_arg)  {  	ent->eflags |= ATA_EFLAG_OLD_ER;  	return 0; @@ -587,11 +589,43 @@ static void ata_eh_unload(struct ata_port *ap)  void ata_scsi_error(struct Scsi_Host *host)  {  	struct ata_port *ap = ata_shost_to_port(host); -	int i;  	unsigned long flags; +	LIST_HEAD(eh_work_q);  	DPRINTK("ENTER\n"); +	spin_lock_irqsave(host->host_lock, flags); +	list_splice_init(&host->eh_cmd_q, &eh_work_q); +	spin_unlock_irqrestore(host->host_lock, flags); + +	ata_scsi_cmd_error_handler(host, ap, &eh_work_q); + +	/* If we timed raced normal completion and there is nothing to +	   recover nr_timedout == 0 why exactly are we doing error recovery ? */ +	ata_scsi_port_error_handler(host, ap); + +	/* finish or retry handled scmd's and clean up */ +	WARN_ON(host->host_failed || !list_empty(&eh_work_q)); + +	DPRINTK("EXIT\n"); +} + +/** + * ata_scsi_cmd_error_handler - error callback for a list of commands + * @host:	scsi host containing the port + * @ap:		ATA port within the host + * @eh_work_q:	list of commands to process + * + * process the given list of commands and return those finished to the + * ap->eh_done_q.  This function is the first part of the libata error + * handler which processes a given list of failed commands. + */ +void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, +				struct list_head *eh_work_q) +{ +	int i; +	unsigned long flags; +  	/* make sure sff pio task is not running */  	ata_sff_flush_pio_task(ap); @@ -627,7 +661,7 @@ void ata_scsi_error(struct Scsi_Host *host)  		if (ap->ops->lost_interrupt)  			ap->ops->lost_interrupt(ap); -		list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) { +		list_for_each_entry_safe(scmd, tmp, eh_work_q, eh_entry) {  			struct ata_queued_cmd *qc;  			for (i = 0; i < ATA_MAX_QUEUE; i++) { @@ -671,8 +705,20 @@ void ata_scsi_error(struct Scsi_Host *host)  	} else  		spin_unlock_wait(ap->lock); -	/* If we timed raced normal completion and there is nothing to -	   recover nr_timedout == 0 why exactly are we doing error recovery ? */ +} +EXPORT_SYMBOL(ata_scsi_cmd_error_handler); + +/** + * ata_scsi_port_error_handler - recover the port after the commands + * @host:	SCSI host containing the port + * @ap:		the ATA port + * + * Handle the recovery of the port @ap after all the commands + * have been recovered. + */ +void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap) +{ +	unsigned long flags;  	/* invoke error handler */  	if (ap->ops->error_handler) { @@ -727,7 +773,7 @@ void ata_scsi_error(struct Scsi_Host *host)  		/* process port suspend request */  		ata_eh_handle_port_suspend(ap); -		/* Exception might have happend after ->error_handler +		/* Exception might have happened after ->error_handler  		 * recovered the port but before this point.  Repeat  		 * EH in such case.  		 */ @@ -738,8 +784,9 @@ void ata_scsi_error(struct Scsi_Host *host)  				spin_unlock_irqrestore(ap->lock, flags);  				goto repeat;  			} -			ata_port_printk(ap, KERN_ERR, "EH pending after %d " -					"tries, giving up\n", ATA_EH_MAX_TRIES); +			ata_port_err(ap, +				     "EH pending after %d tries, giving up\n", +				     ATA_EH_MAX_TRIES);  			ap->pflags &= ~ATA_PFLAG_EH_PENDING;  		} @@ -747,12 +794,12 @@ void ata_scsi_error(struct Scsi_Host *host)  		ata_for_each_link(link, ap, HOST_FIRST)  			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 -		 * before EH completion, SCSI midlayer will +		/* end eh (clear host_eh_scheduled) while holding +		 * ap->lock such that if exception occurs after this +		 * point but before EH completion, SCSI midlayer will  		 * re-initiate EH.  		 */ -		host->host_eh_scheduled = 0; +		ap->ops->end_eh(ap);  		spin_unlock_irqrestore(ap->lock, flags);  		ata_eh_release(ap); @@ -761,9 +808,6 @@ void ata_scsi_error(struct Scsi_Host *host)  		ap->ops->eng_timeout(ap);  	} -	/* finish or retry handled scmd's and clean up */ -	WARN_ON(host->host_failed || !list_empty(&host->eh_cmd_q)); -  	scsi_eh_flush_done_q(&ap->eh_done_q);  	/* clean up */ @@ -775,7 +819,7 @@ void ata_scsi_error(struct Scsi_Host *host)  		schedule_delayed_work(&ap->hotplug_task, 0);  	if (ap->pflags & ATA_PFLAG_RECOVERED) -		ata_port_printk(ap, KERN_INFO, "EH complete\n"); +		ata_port_info(ap, "EH complete\n");  	ap->pflags &= ~(ATA_PFLAG_SCSI_HOTPLUG | ATA_PFLAG_RECOVERED); @@ -784,9 +828,8 @@ void ata_scsi_error(struct Scsi_Host *host)  	wake_up_all(&ap->eh_wait_q);  	spin_unlock_irqrestore(ap->lock, flags); - -	DPRINTK("EXIT\n");  } +EXPORT_SYMBOL_GPL(ata_scsi_port_error_handler);  /**   *	ata_port_wait_eh - Wait for the currently pending EH to complete @@ -821,6 +864,7 @@ void ata_port_wait_eh(struct ata_port *ap)  		goto retry;  	}  } +EXPORT_SYMBOL_GPL(ata_port_wait_eh);  static int ata_eh_nr_in_flight(struct ata_port *ap)  { @@ -943,16 +987,13 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc)  }  /** - *	ata_port_schedule_eh - schedule error handling without a qc - *	@ap: ATA port to schedule EH for + * ata_std_sched_eh - non-libsas ata_ports issue eh with this common routine + * @ap: ATA port to schedule EH for   * - *	Schedule error handling for @ap.  EH will kick in as soon as - *	all commands are drained. - * - *	LOCKING: + *	LOCKING: inherited from ata_port_schedule_eh   *	spin_lock_irqsave(host lock)   */ -void ata_port_schedule_eh(struct ata_port *ap) +void ata_std_sched_eh(struct ata_port *ap)  {  	WARN_ON(!ap->ops->error_handler); @@ -964,6 +1005,44 @@ void ata_port_schedule_eh(struct ata_port *ap)  	DPRINTK("port EH scheduled\n");  } +EXPORT_SYMBOL_GPL(ata_std_sched_eh); + +/** + * ata_std_end_eh - non-libsas ata_ports complete eh with this common routine + * @ap: ATA port to end EH for + * + * In the libata object model there is a 1:1 mapping of ata_port to + * shost, so host fields can be directly manipulated under ap->lock, in + * the libsas case we need to hold a lock at the ha->level to coordinate + * these events. + * + *	LOCKING: + *	spin_lock_irqsave(host lock) + */ +void ata_std_end_eh(struct ata_port *ap) +{ +	struct Scsi_Host *host = ap->scsi_host; + +	host->host_eh_scheduled = 0; +} +EXPORT_SYMBOL(ata_std_end_eh); + + +/** + *	ata_port_schedule_eh - schedule error handling without a qc + *	@ap: ATA port to schedule EH for + * + *	Schedule error handling for @ap.  EH will kick in as soon as + *	all commands are drained. + * + *	LOCKING: + *	spin_lock_irqsave(host lock) + */ +void ata_port_schedule_eh(struct ata_port *ap) +{ +	/* see: ata_std_sched_eh, unless you know better */ +	ap->ops->sched_eh(ap); +}  static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link)  { @@ -1244,14 +1323,14 @@ void ata_eh_qc_complete(struct ata_queued_cmd *qc)   *	should be retried.  To be used from EH.   *   *	SCSI midlayer limits the number of retries to scmd->allowed. - *	scmd->retries is decremented for commands which get retried + *	scmd->allowed is incremented for commands which get retried   *	due to unrelated failures (qc->err_mask is zero).   */  void ata_eh_qc_retry(struct ata_queued_cmd *qc)  {  	struct scsi_cmnd *scmd = qc->scsicmd; -	if (!qc->err_mask && scmd->retries) -		scmd->retries--; +	if (!qc->err_mask) +		scmd->allowed++;  	__ata_eh_qc_complete(qc);  } @@ -1270,7 +1349,7 @@ void ata_dev_disable(struct ata_device *dev)  		return;  	if (ata_msg_drv(dev->link->ap)) -		ata_dev_printk(dev, KERN_WARNING, "disabled\n"); +		ata_dev_warn(dev, "disabled\n");  	ata_acpi_on_disable(dev);  	ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | ATA_DNXFER_QUIET);  	dev->class++; @@ -1409,6 +1488,7 @@ static const char *ata_err_string(unsigned int err_mask)  /**   *	ata_read_log_page - read a specific log page   *	@dev: target device + *	@log: log to read   *	@page: page to read   *	@buf: buffer to store read page   *	@sectors: number of sectors to read @@ -1421,17 +1501,18 @@ static const char *ata_err_string(unsigned int err_mask)   *	RETURNS:   *	0 on success, AC_ERR_* mask otherwise.   */ -static unsigned int ata_read_log_page(struct ata_device *dev, -				      u8 page, void *buf, unsigned int sectors) +unsigned int ata_read_log_page(struct ata_device *dev, u8 log, +			       u8 page, void *buf, unsigned int sectors)  {  	struct ata_taskfile tf;  	unsigned int err_mask; -	DPRINTK("read log page - page %d\n", page); +	DPRINTK("read log page - log 0x%x, page 0x%x\n", log, page);  	ata_tf_init(dev, &tf);  	tf.command = ATA_CMD_READ_LOG_EXT; -	tf.lbal = page; +	tf.lbal = log; +	tf.lbam = page;  	tf.nsect = sectors;  	tf.hob_nsect = sectors >> 8;  	tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_LBA48 | ATA_TFLAG_DEVICE; @@ -1467,7 +1548,7 @@ static int ata_eh_read_log_10h(struct ata_device *dev,  	u8 csum;  	int i; -	err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, buf, 1); +	err_mask = ata_read_log_page(dev, ATA_LOG_SATA_NCQ, 0, buf, 1);  	if (err_mask)  		return -EIO; @@ -1475,8 +1556,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev,  	for (i = 0; i < ATA_SECT_SIZE; i++)  		csum += buf[i];  	if (csum) -		ata_dev_printk(dev, KERN_WARNING, -			       "invalid checksum 0x%x on log page 10h\n", csum); +		ata_dev_warn(dev, "invalid checksum 0x%x on log page 10h\n", +			     csum);  	if (buf[0] & 0x80)  		return -ENOENT; @@ -1511,7 +1592,7 @@ static int ata_eh_read_log_10h(struct ata_device *dev,   *	RETURNS:   *	0 on success, AC_ERR_* mask on failure.   */ -static unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key) +unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key)  {  	u8 cdb[ATAPI_CDB_LEN] = { TEST_UNIT_READY, 0, 0, 0, 0, 0 };  	struct ata_taskfile tf; @@ -1544,7 +1625,7 @@ static unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key)   *	RETURNS:   *	0 on success, AC_ERR_* mask on failure   */ -static unsigned int atapi_eh_request_sense(struct ata_device *dev, +unsigned int atapi_eh_request_sense(struct ata_device *dev,  					   u8 *sense_buf, u8 dfl_sense_key)  {  	u8 cdb[ATAPI_CDB_LEN] = @@ -1618,7 +1699,7 @@ static void ata_eh_analyze_serror(struct ata_link *link)  	 * host links.  For disabled PMP links, only N bit is  	 * considered as X bit is left at 1 for link plugging.  	 */ -	if (link->lpm_policy != ATA_LPM_MAX_POWER) +	if (link->lpm_policy > ATA_LPM_MAX_POWER)  		hotplug_mask = 0;	/* hotplug doesn't work w/ LPM */  	else if (!(link->flags & ATA_LFLAG_DISABLED) || ata_is_host_link(link))  		hotplug_mask = SERR_PHYRDY_CHG | SERR_DEV_XCHG; @@ -1676,14 +1757,14 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)  	memset(&tf, 0, sizeof(tf));  	rc = ata_eh_read_log_10h(dev, &tag, &tf);  	if (rc) { -		ata_link_printk(link, KERN_ERR, "failed to read log page 10h " -				"(errno=%d)\n", rc); +		ata_link_err(link, "failed to read log page 10h (errno=%d)\n", +			     rc);  		return;  	}  	if (!(link->sactive & (1 << tag))) { -		ata_link_printk(link, KERN_ERR, "log page 10h reported " -				"inactive tag %d\n", tag); +		ata_link_err(link, "log page 10h reported inactive tag %d\n", +			     tag);  		return;  	} @@ -1702,7 +1783,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)   *   *	Analyze taskfile of @qc and further determine cause of   *	failure.  This function also requests ATAPI sense data if - *	avaliable. + *	available.   *   *	LOCKING:   *	Kernel thread context (may sleep). @@ -1730,7 +1811,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,  	case ATA_DEV_ATA:  		if (err & ATA_ICRC)  			qc->err_mask |= AC_ERR_ATA_BUS; -		if (err & ATA_UNC) +		if (err & (ATA_UNC | ATA_AMNF))  			qc->err_mask |= AC_ERR_MEDIA;  		if (err & ATA_IDNF)  			qc->err_mask |= AC_ERR_INVALID; @@ -1853,7 +1934,7 @@ static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg)   *	   occurred during last 5 mins, NCQ_OFF.   *   *	3. If more than 8 ATA_BUS, TOUT_HSM or UNK_DEV errors - *	   ocurred during last 5 mins, FALLBACK_TO_PIO + *	   occurred during last 5 mins, FALLBACK_TO_PIO   *   *	4. If more than 3 TOUT_HSM or UNK_DEV errors occurred   *	   during last 10 mins, NCQ_OFF. @@ -1948,8 +2029,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev,  	    (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ |  			   ATA_DFLAG_NCQ_OFF)) == ATA_DFLAG_NCQ) {  		dev->flags |= ATA_DFLAG_NCQ_OFF; -		ata_dev_printk(dev, KERN_WARNING, -			       "NCQ disabled due to excessive errors\n"); +		ata_dev_warn(dev, "NCQ disabled due to excessive errors\n");  		goto done;  	} @@ -2005,6 +2085,26 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev,  }  /** + *	ata_eh_worth_retry - analyze error and decide whether to retry + *	@qc: qc to possibly retry + * + *	Look at the cause of the error and decide if a retry + * 	might be useful or not.  We don't want to retry media errors + *	because the drive itself has probably already taken 10-30 seconds + *	doing its own internal retries before reporting the failure. + */ +static inline int ata_eh_worth_retry(struct ata_queued_cmd *qc) +{ +	if (qc->err_mask & AC_ERR_MEDIA) +		return 0;	/* don't retry media errors */ +	if (qc->flags & ATA_QCFLAG_IO) +		return 1;	/* otherwise retry anything from fs stack */ +	if (qc->err_mask & AC_ERR_INVALID) +		return 0;	/* don't retry these */ +	return qc->err_mask != AC_ERR_DEV;  /* retry if not dev error */ +} + +/**   *	ata_eh_link_autopsy - analyze error and determine recovery action   *	@link: host link to perform autopsy on   * @@ -2078,9 +2178,7 @@ static void ata_eh_link_autopsy(struct ata_link *link)  			qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);  		/* determine whether the command is worth retrying */ -		if (qc->flags & ATA_QCFLAG_IO || -		    (!(qc->err_mask & AC_ERR_INVALID) && -		     qc->err_mask != AC_ERR_DEV)) +		if (ata_eh_worth_retry(qc))  			qc->flags |= ATA_QCFLAG_RETRY;  		/* accumulate error info */ @@ -2196,6 +2294,7 @@ const char *ata_get_cmd_descript(u8 command)  		{ ATA_CMD_IDLE, 		"IDLE" },  		{ ATA_CMD_EDD, 			"EXECUTE DEVICE DIAGNOSTIC" },  		{ ATA_CMD_DOWNLOAD_MICRO,   	"DOWNLOAD MICROCODE" }, +		{ ATA_CMD_DOWNLOAD_MICRO_DMA,	"DOWNLOAD MICROCODE DMA" },  		{ ATA_CMD_NOP,			"NOP" },  		{ ATA_CMD_FLUSH, 		"FLUSH CACHE" },  		{ ATA_CMD_FLUSH_EXT, 		"FLUSH CACHE EXT" }, @@ -2216,6 +2315,8 @@ const char *ata_get_cmd_descript(u8 command)  		{ ATA_CMD_WRITE_QUEUED_FUA_EXT, "WRITE DMA QUEUED FUA EXT" },  		{ ATA_CMD_FPDMA_READ,		"READ FPDMA QUEUED" },  		{ ATA_CMD_FPDMA_WRITE,		"WRITE FPDMA QUEUED" }, +		{ ATA_CMD_FPDMA_SEND,		"SEND FPDMA QUEUED" }, +		{ ATA_CMD_FPDMA_RECV,		"RECEIVE FPDMA QUEUED" },  		{ ATA_CMD_PIO_READ,		"READ SECTOR(S)" },  		{ ATA_CMD_PIO_READ_EXT,		"READ SECTOR(S) EXT" },  		{ ATA_CMD_PIO_WRITE,		"WRITE SECTOR(S)" }, @@ -2242,12 +2343,15 @@ const char *ata_get_cmd_descript(u8 command)  		{ ATA_CMD_WRITE_LOG_EXT,	"WRITE LOG EXT" },  		{ ATA_CMD_READ_LOG_DMA_EXT,	"READ LOG DMA EXT" },  		{ ATA_CMD_WRITE_LOG_DMA_EXT, 	"WRITE LOG DMA EXT" }, +		{ ATA_CMD_TRUSTED_NONDATA,	"TRUSTED NON-DATA" },  		{ ATA_CMD_TRUSTED_RCV,		"TRUSTED RECEIVE" },  		{ ATA_CMD_TRUSTED_RCV_DMA, 	"TRUSTED RECEIVE DMA" },  		{ ATA_CMD_TRUSTED_SND,		"TRUSTED SEND" },  		{ ATA_CMD_TRUSTED_SND_DMA, 	"TRUSTED SEND DMA" },  		{ ATA_CMD_PMP_READ,		"READ BUFFER" }, +		{ ATA_CMD_PMP_READ_DMA,		"READ BUFFER DMA" },  		{ ATA_CMD_PMP_WRITE,		"WRITE BUFFER" }, +		{ ATA_CMD_PMP_WRITE_DMA,	"WRITE BUFFER DMA" },  		{ ATA_CMD_CONF_OVERLAY,		"DEVICE CONFIGURATION OVERLAY" },  		{ ATA_CMD_SEC_SET_PASS,		"SECURITY SET PASSWORD" },  		{ ATA_CMD_SEC_UNLOCK,		"SECURITY UNLOCK" }, @@ -2266,6 +2370,8 @@ const char *ata_get_cmd_descript(u8 command)  		{ ATA_CMD_CFA_TRANS_SECT,	"CFA TRANSLATE SECTOR" },  		{ ATA_CMD_CFA_ERASE,		"CFA ERASE SECTORS" },  		{ ATA_CMD_CFA_WRITE_MULT_NE, 	"CFA WRITE MULTIPLE WITHOUT ERASE" }, +		{ ATA_CMD_REQ_SENSE_DATA,	"REQUEST SENSE DATA EXT" }, +		{ ATA_CMD_SANITIZE_DEVICE,	"SANITIZE DEVICE" },  		{ ATA_CMD_READ_LONG,		"READ LONG (with retries)" },  		{ ATA_CMD_READ_LONG_ONCE,	"READ LONG (without retries)" },  		{ ATA_CMD_WRITE_LONG,		"WRITE LONG (with retries)" }, @@ -2297,7 +2403,7 @@ static void ata_eh_link_report(struct ata_link *link)  	struct ata_port *ap = link->ap;  	struct ata_eh_context *ehc = &link->eh_context;  	const char *frozen, *desc; -	char tries_buf[6]; +	char tries_buf[6] = "";  	int tag, nr_failed = 0;  	if (ehc->i.flags & ATA_EHI_QUIET) @@ -2328,30 +2434,29 @@ static void ata_eh_link_report(struct ata_link *link)  	if (ap->pflags & ATA_PFLAG_FROZEN)  		frozen = " frozen"; -	memset(tries_buf, 0, sizeof(tries_buf));  	if (ap->eh_tries < ATA_EH_MAX_TRIES) -		snprintf(tries_buf, sizeof(tries_buf) - 1, " t%d", +		snprintf(tries_buf, sizeof(tries_buf), " t%d",  			 ap->eh_tries);  	if (ehc->i.dev) { -		ata_dev_printk(ehc->i.dev, KERN_ERR, "exception Emask 0x%x " -			       "SAct 0x%x SErr 0x%x action 0x%x%s%s\n", -			       ehc->i.err_mask, link->sactive, ehc->i.serror, -			       ehc->i.action, frozen, tries_buf); +		ata_dev_err(ehc->i.dev, "exception Emask 0x%x " +			    "SAct 0x%x SErr 0x%x action 0x%x%s%s\n", +			    ehc->i.err_mask, link->sactive, ehc->i.serror, +			    ehc->i.action, frozen, tries_buf);  		if (desc) -			ata_dev_printk(ehc->i.dev, KERN_ERR, "%s\n", desc); +			ata_dev_err(ehc->i.dev, "%s\n", desc);  	} else { -		ata_link_printk(link, KERN_ERR, "exception Emask 0x%x " -				"SAct 0x%x SErr 0x%x action 0x%x%s%s\n", -				ehc->i.err_mask, link->sactive, ehc->i.serror, -				ehc->i.action, frozen, tries_buf); +		ata_link_err(link, "exception Emask 0x%x " +			     "SAct 0x%x SErr 0x%x action 0x%x%s%s\n", +			     ehc->i.err_mask, link->sactive, ehc->i.serror, +			     ehc->i.action, frozen, tries_buf);  		if (desc) -			ata_link_printk(link, KERN_ERR, "%s\n", desc); +			ata_link_err(link, "%s\n", desc);  	}  #ifdef CONFIG_ATA_VERBOSE_ERROR  	if (ehc->i.serror) -		ata_link_printk(link, KERN_ERR, +		ata_link_err(link,  		  "SError: { %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s}\n",  		  ehc->i.serror & SERR_DATA_RECOVERED ? "RecovData " : "",  		  ehc->i.serror & SERR_COMM_RECOVERED ? "RecovComm " : "", @@ -2416,11 +2521,11 @@ static void ata_eh_link_report(struct ata_link *link)  		} else {  			const char *descr = ata_get_cmd_descript(cmd->command);  			if (descr) -				ata_dev_printk(qc->dev, KERN_ERR, -					"failed command: %s\n", descr); +				ata_dev_err(qc->dev, "failed command: %s\n", +					    descr);  		} -		ata_dev_printk(qc->dev, KERN_ERR, +		ata_dev_err(qc->dev,  			"cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "  			"tag %d%s\n         %s"  			"res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x " @@ -2441,11 +2546,9 @@ static void ata_eh_link_report(struct ata_link *link)  		if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ |  				    ATA_ERR)) {  			if (res->command & ATA_BUSY) -				ata_dev_printk(qc->dev, KERN_ERR, -				  "status: { Busy }\n"); +				ata_dev_err(qc->dev, "status: { Busy }\n");  			else -				ata_dev_printk(qc->dev, KERN_ERR, -				  "status: { %s%s%s%s}\n", +				ata_dev_err(qc->dev, "status: { %s%s%s%s}\n",  				  res->command & ATA_DRDY ? "DRDY " : "",  				  res->command & ATA_DF ? "DF " : "",  				  res->command & ATA_DRQ ? "DRQ " : "", @@ -2453,12 +2556,12 @@ static void ata_eh_link_report(struct ata_link *link)  		}  		if (cmd->command != ATA_CMD_PACKET && -		    (res->feature & (ATA_ICRC | ATA_UNC | ATA_IDNF | -				     ATA_ABORTED))) -			ata_dev_printk(qc->dev, KERN_ERR, -			  "error: { %s%s%s%s}\n", +		    (res->feature & (ATA_ICRC | ATA_UNC | ATA_AMNF | +				     ATA_IDNF | ATA_ABORTED))) +			ata_dev_err(qc->dev, "error: { %s%s%s%s%s}\n",  			  res->feature & ATA_ICRC ? "ICRC " : "",  			  res->feature & ATA_UNC ? "UNC " : "", +			  res->feature & ATA_AMNF ? "AMNF " : "",  			  res->feature & ATA_IDNF ? "IDNF " : "",  			  res->feature & ATA_ABORTED ? "ABRT " : "");  #endif @@ -2495,8 +2598,7 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,  	return reset(link, classes, deadline);  } -static int ata_eh_followup_srst_needed(struct ata_link *link, -				       int rc, const unsigned int *classes) +static int ata_eh_followup_srst_needed(struct ata_link *link, int rc)  {  	if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link))  		return 0; @@ -2532,12 +2634,14 @@ int ata_eh_reset(struct ata_link *link, int classify,  	 */  	while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX)  		max_tries++; +	if (link->flags & ATA_LFLAG_RST_ONCE) +		max_tries = 1;  	if (link->flags & ATA_LFLAG_NO_HRST)  		hardreset = NULL;  	if (link->flags & ATA_LFLAG_NO_SRST)  		softreset = NULL; -	/* make sure each reset attemp is at least COOL_DOWN apart */ +	/* make sure each reset attempt is at least COOL_DOWN apart */  	if (ehc->i.flags & ATA_EHI_DID_RESET) {  		now = jiffies;  		WARN_ON(time_after(ehc->last_reset, now)); @@ -2562,6 +2666,7 @@ int ata_eh_reset(struct ata_link *link, int classify,  		 * bus as we may be talking too fast.  		 */  		dev->pio_mode = XFER_PIO_0; +		dev->dma_mode = 0xff;  		/* If the controller has a pio mode setup function  		 * then use it to set the chipset to rights. Don't @@ -2610,8 +2715,7 @@ int ata_eh_reset(struct ata_link *link, int classify,  		if (rc) {  			if (rc == -ENOENT) { -				ata_link_printk(link, KERN_DEBUG, -						"port disabled. ignoring.\n"); +				ata_link_dbg(link, "port disabled--ignoring\n");  				ehc->i.action &= ~ATA_EH_RESET;  				ata_for_each_dev(dev, link, ALL) @@ -2619,8 +2723,9 @@ int ata_eh_reset(struct ata_link *link, int classify,  				rc = 0;  			} else -				ata_link_printk(link, KERN_ERR, -					"prereset failed (errno=%d)\n", rc); +				ata_link_err(link, +					     "prereset failed (errno=%d)\n", +					     rc);  			goto out;  		} @@ -2649,8 +2754,8 @@ int ata_eh_reset(struct ata_link *link, int classify,  	if (reset) {  		if (verbose) -			ata_link_printk(link, KERN_INFO, "%s resetting link\n", -					reset == softreset ? "soft" : "hard"); +			ata_link_info(link, "%s resetting link\n", +				      reset == softreset ? "soft" : "hard");  		/* mark that this EH session started with reset */  		ehc->last_reset = jiffies; @@ -2670,8 +2775,7 @@ int ata_eh_reset(struct ata_link *link, int classify,  			int tmp;  			if (verbose) -				ata_link_printk(slave, KERN_INFO, -						"hard resetting link\n"); +				ata_link_info(slave, "hard resetting link\n");  			ata_eh_about_to_do(slave, NULL, ATA_EH_RESET);  			tmp = ata_do_reset(slave, reset, classes, deadline, @@ -2690,13 +2794,12 @@ int ata_eh_reset(struct ata_link *link, int classify,  		/* perform follow-up SRST if necessary */  		if (reset == hardreset && -		    ata_eh_followup_srst_needed(link, rc, classes)) { +		    ata_eh_followup_srst_needed(link, rc)) {  			reset = softreset;  			if (!reset) { -				ata_link_printk(link, KERN_ERR, -						"follow-up softreset required " -						"but no softreset avaliable\n"); +				ata_link_err(link, +	     "follow-up softreset required but no softreset available\n");  				failed_link = link;  				rc = -EINVAL;  				goto fail; @@ -2711,8 +2814,8 @@ int ata_eh_reset(struct ata_link *link, int classify,  		}  	} else {  		if (verbose) -			ata_link_printk(link, KERN_INFO, "no reset method " -					"available, skipping reset\n"); +			ata_link_info(link, +	"no reset method available, skipping reset\n");  		if (!(lflags & ATA_LFLAG_ASSUME_CLASS))  			lflags |= ATA_LFLAG_ASSUME_ATA;  	} @@ -2762,10 +2865,11 @@ int ata_eh_reset(struct ata_link *link, int classify,  	}  	/* -	 * Some controllers can't be frozen very well and may set -	 * spuruious error conditions during reset.  Clear accumulated -	 * error information.  As reset is the final recovery action, -	 * nothing is lost by doing this. +	 * Some controllers can't be frozen very well and may set spurious +	 * error conditions during reset.  Clear accumulated error +	 * information and re-thaw the port if frozen.  As reset is the +	 * final recovery action and we cross check link onlineness against +	 * device classification later, no hotplug event is lost by this.  	 */  	spin_lock_irqsave(link->ap->lock, flags);  	memset(&link->eh_info, 0, sizeof(link->eh_info)); @@ -2774,6 +2878,9 @@ int ata_eh_reset(struct ata_link *link, int classify,  	ap->pflags &= ~ATA_PFLAG_EH_PENDING;  	spin_unlock_irqrestore(link->ap->lock, flags); +	if (ap->pflags & ATA_PFLAG_FROZEN) +		ata_eh_thaw_port(ap); +  	/*  	 * Make sure onlineness and classification result correspond.  	 * Hotplug could have happened during reset and some @@ -2786,36 +2893,35 @@ int ata_eh_reset(struct ata_link *link, int classify,  	ata_for_each_dev(dev, link, ALL) {  		if (ata_phys_link_online(ata_dev_phys_link(dev))) {  			if (classes[dev->devno] == ATA_DEV_UNKNOWN) { -				ata_dev_printk(dev, KERN_DEBUG, "link online " -					       "but device misclassifed\n"); +				ata_dev_dbg(dev, "link online but device misclassified\n");  				classes[dev->devno] = ATA_DEV_NONE;  				nr_unknown++;  			}  		} else if (ata_phys_link_offline(ata_dev_phys_link(dev))) {  			if (ata_class_enabled(classes[dev->devno])) -				ata_dev_printk(dev, KERN_DEBUG, "link offline, " -					       "clearing class %d to NONE\n", -					       classes[dev->devno]); +				ata_dev_dbg(dev, +					    "link offline, clearing class %d to NONE\n", +					    classes[dev->devno]);  			classes[dev->devno] = ATA_DEV_NONE;  		} else if (classes[dev->devno] == ATA_DEV_UNKNOWN) { -			ata_dev_printk(dev, KERN_DEBUG, "link status unknown, " -				       "clearing UNKNOWN to NONE\n"); +			ata_dev_dbg(dev, +				    "link status unknown, clearing UNKNOWN to NONE\n");  			classes[dev->devno] = ATA_DEV_NONE;  		}  	}  	if (classify && nr_unknown) {  		if (try < max_tries) { -			ata_link_printk(link, KERN_WARNING, "link online but " -					"%d devices misclassified, retrying\n", -					nr_unknown); +			ata_link_warn(link, +				      "link online but %d devices misclassified, retrying\n", +				      nr_unknown);  			failed_link = link;  			rc = -EAGAIN;  			goto fail;  		} -		ata_link_printk(link, KERN_WARNING, -				"link online but %d devices misclassified, " -				"device detection might fail\n", nr_unknown); +		ata_link_warn(link, +			      "link online but %d devices misclassified, " +			      "device detection might fail\n", nr_unknown);  	}  	/* reset successful, schedule revalidation */ @@ -2845,14 +2951,23 @@ int ata_eh_reset(struct ata_link *link, int classify,  	    sata_scr_read(link, SCR_STATUS, &sstatus))  		rc = -ERESTART; -	if (rc == -ERESTART || try >= max_tries) +	if (try >= max_tries) { +		/* +		 * Thaw host port even if reset failed, so that the port +		 * can be retried on the next phy event.  This risks +		 * repeated EH runs but seems to be a better tradeoff than +		 * shutting down a port after a botched hotplug attempt. +		 */ +		if (ata_is_host_link(link)) +			ata_eh_thaw_port(ap);  		goto out; +	}  	now = jiffies;  	if (time_before(now, deadline)) {  		unsigned long delta = deadline - now; -		ata_link_printk(failed_link, KERN_WARNING, +		ata_link_warn(failed_link,  			"reset failed (errno=%d), retrying in %u secs\n",  			rc, DIV_ROUND_UP(jiffies_to_msecs(delta), 1000)); @@ -2862,6 +2977,16 @@ int ata_eh_reset(struct ata_link *link, int classify,  		ata_eh_acquire(ap);  	} +	/* +	 * While disks spinup behind PMP, some controllers fail sending SRST. +	 * They need to be reset - as well as the PMP - before retrying. +	 */ +	if (rc == -ERESTART) { +		if (ata_is_host_link(link)) +			ata_eh_thaw_port(ap); +		goto out; +	} +  	if (try == max_tries - 1) {  		sata_down_spd_limit(link, 0);  		if (slave) @@ -2893,7 +3018,7 @@ static inline void ata_eh_pull_park_action(struct ata_port *ap)  	 * ourselves at the beginning of each pass over the loop.  	 *  	 * Additionally, all write accesses to &ap->park_req_pending -	 * through INIT_COMPLETION() (see below) or complete_all() +	 * through reinit_completion() (see below) or complete_all()  	 * (see ata_scsi_park_store()) are protected by the host lock.  	 * As a result we have that park_req_pending.done is zero on  	 * exit from this function, i.e. when ATA_EH_PARK actions for @@ -2907,7 +3032,7 @@ static inline void ata_eh_pull_park_action(struct ata_port *ap)  	 */  	spin_lock_irqsave(ap->lock, flags); -	INIT_COMPLETION(ap->park_req_pending); +	reinit_completion(&ap->park_req_pending);  	ata_for_each_link(link, ap, EDGE) {  		ata_for_each_dev(dev, link, ALL) {  			struct ata_eh_info *ehi = &link->eh_info; @@ -2943,7 +3068,7 @@ static void ata_eh_park_issue_cmd(struct ata_device *dev, int park)  	tf.protocol |= ATA_PROT_NODATA;  	err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);  	if (park && (err_mask || tf.lbal != 0xc4)) { -		ata_dev_printk(dev, KERN_ERR, "head unload failed!\n"); +		ata_dev_err(dev, "head unload failed!\n");  		ehc->unloaded_mask &= ~(1 << dev->devno);  	}  } @@ -3154,8 +3279,9 @@ static int atapi_eh_clear_ua(struct ata_device *dev)  		err_mask = atapi_eh_tur(dev, &sense_key);  		if (err_mask != 0 && err_mask != AC_ERR_DEV) { -			ata_dev_printk(dev, KERN_WARNING, "TEST_UNIT_READY " -				"failed (err_mask=0x%x)\n", err_mask); +			ata_dev_warn(dev, +				     "TEST_UNIT_READY failed (err_mask=0x%x)\n", +				     err_mask);  			return -EIO;  		} @@ -3164,14 +3290,14 @@ static int atapi_eh_clear_ua(struct ata_device *dev)  		err_mask = atapi_eh_request_sense(dev, sense_buffer, sense_key);  		if (err_mask) { -			ata_dev_printk(dev, KERN_WARNING, "failed to clear " +			ata_dev_warn(dev, "failed to clear "  				"UNIT ATTENTION (err_mask=0x%x)\n", err_mask);  			return -EIO;  		}  	} -	ata_dev_printk(dev, KERN_WARNING, -		"UNIT ATTENTION persists after %d tries\n", ATA_EH_UA_TRIES); +	ata_dev_warn(dev, "UNIT ATTENTION persists after %d tries\n", +		     ATA_EH_UA_TRIES);  	return 0;  } @@ -3222,7 +3348,7 @@ static int ata_eh_maybe_retry_flush(struct ata_device *dev)  	tf.flags |= ATA_TFLAG_DEVICE;  	tf.protocol = ATA_PROT_NODATA; -	ata_dev_printk(dev, KERN_WARNING, "retrying FLUSH 0x%x Emask 0x%x\n", +	ata_dev_warn(dev, "retrying FLUSH 0x%x Emask 0x%x\n",  		       tf.command, qc->err_mask);  	err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); @@ -3237,7 +3363,7 @@ static int ata_eh_maybe_retry_flush(struct ata_device *dev)  		 */  		qc->scsicmd->allowed = max(qc->scsicmd->allowed, 1);  	} else { -		ata_dev_printk(dev, KERN_WARNING, "FLUSH failed Emask 0x%x\n", +		ata_dev_warn(dev, "FLUSH failed Emask 0x%x\n",  			       err_mask);  		rc = -EIO; @@ -3275,6 +3401,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,  	struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL;  	struct ata_eh_context *ehc = &link->eh_context;  	struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; +	enum ata_lpm_policy old_policy = link->lpm_policy; +	bool no_dipm = link->ap->flags & ATA_FLAG_NO_DIPM;  	unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM;  	unsigned int err_mask;  	int rc; @@ -3291,7 +3419,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,  	 */  	ata_for_each_dev(dev, link, ENABLED) {  		bool hipm = ata_id_has_hipm(dev->id); -		bool dipm = ata_id_has_dipm(dev->id); +		bool dipm = ata_id_has_dipm(dev->id) && !no_dipm;  		/* find the first enabled and LPM enabled devices */  		if (!link_dev) @@ -3309,9 +3437,9 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,  			err_mask = ata_dev_set_feature(dev,  					SETFEATURES_SATA_DISABLE, SATA_DIPM);  			if (err_mask && err_mask != AC_ERR_DEV) { -				ata_dev_printk(dev, KERN_WARNING, -					"failed to disable DIPM, Emask 0x%x\n", -					err_mask); +				ata_dev_warn(dev, +					     "failed to disable DIPM, Emask 0x%x\n", +					     err_mask);  				rc = -EIO;  				goto fail;  			} @@ -3338,13 +3466,22 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,  		goto fail;  	} +	/* +	 * Low level driver acked the transition.  Issue DIPM command +	 * with the new policy set. +	 */ +	link->lpm_policy = policy; +	if (ap && ap->slave_link) +		ap->slave_link->lpm_policy = policy; +  	/* host config updated, enable DIPM if transitioning to MIN_POWER */  	ata_for_each_dev(dev, link, ENABLED) { -		if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) { +		if (policy == ATA_LPM_MIN_POWER && !no_dipm && +		    ata_id_has_dipm(dev->id)) {  			err_mask = ata_dev_set_feature(dev,  					SETFEATURES_SATA_ENABLE, SATA_DIPM);  			if (err_mask && err_mask != AC_ERR_DEV) { -				ata_dev_printk(dev, KERN_WARNING, +				ata_dev_warn(dev,  					"failed to enable DIPM, Emask 0x%x\n",  					err_mask);  				rc = -EIO; @@ -3353,16 +3490,17 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,  		}  	} -	link->lpm_policy = policy; -	if (ap && ap->slave_link) -		ap->slave_link->lpm_policy = policy;  	return 0;  fail: +	/* restore the old policy */ +	link->lpm_policy = old_policy; +	if (ap && ap->slave_link) +		ap->slave_link->lpm_policy = old_policy; +  	/* if no device or only one more chance is left, disable LPM */  	if (!dev || ehc->tries[dev->devno] <= 2) { -		ata_link_printk(link, KERN_WARNING, -				"disabling LPM on the link\n"); +		ata_link_warn(link, "disabling LPM on the link\n");  		link->flags |= ATA_LFLAG_NO_LPM;  	}  	if (r_failed_dev) @@ -3370,7 +3508,7 @@ fail:  	return rc;  } -static int ata_link_nr_enabled(struct ata_link *link) +int ata_link_nr_enabled(struct ata_link *link)  {  	struct ata_device *dev;  	int cnt = 0; @@ -3430,7 +3568,8 @@ static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg  	u64 now = get_jiffies_64();  	int *trials = void_arg; -	if (ent->timestamp < now - min(now, interval)) +	if ((ent->eflags & ATA_EFLAG_OLD_ER) || +	    (ent->timestamp < now - min(now, interval)))  		return -1;  	(*trials)++; @@ -3633,8 +3772,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,  		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"); +			ata_link_err(link, "reset failed, giving up\n");  			goto out;  		}  	} @@ -3728,6 +3866,8 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,  				rc = atapi_eh_clear_ua(dev);  				if (rc)  					goto rest_fail; +				if (zpodd_dev_enabled(dev)) +					zpodd_post_poweron(dev);  			}  		} @@ -3893,11 +4033,12 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)  {  	unsigned long flags;  	int rc = 0; +	struct ata_device *dev;  	/* are we suspending? */  	spin_lock_irqsave(ap->lock, flags);  	if (!(ap->pflags & ATA_PFLAG_PM_PENDING) || -	    ap->pm_mesg.event == PM_EVENT_ON) { +	    ap->pm_mesg.event & PM_EVENT_RESUME) {  		spin_unlock_irqrestore(ap->lock, flags);  		return;  	} @@ -3905,6 +4046,18 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)  	WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); +	/* +	 * If we have a ZPODD attached, check its zero +	 * power ready status before the port is frozen. +	 * Only needed for runtime suspend. +	 */ +	if (PMSG_IS_AUTO(ap->pm_mesg)) { +		ata_for_each_dev(dev, &ap->link, ENABLED) { +			if (zpodd_dev_enabled(dev)) +				zpodd_on_suspend(dev); +		} +	} +  	/* tell ACPI we're suspending */  	rc = ata_acpi_on_suspend(ap);  	if (rc) @@ -3916,9 +4069,9 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)  	if (ap->ops->port_suspend)  		rc = ap->ops->port_suspend(ap, ap->pm_mesg); -	ata_acpi_set_state(ap, PMSG_SUSPEND); +	ata_acpi_set_state(ap, ap->pm_mesg);   out: -	/* report result */ +	/* update the flags */  	spin_lock_irqsave(ap->lock, flags);  	ap->pflags &= ~ATA_PFLAG_PM_PENDING; @@ -3927,11 +4080,6 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap)  	else if (ap->pflags & ATA_PFLAG_FROZEN)  		ata_port_schedule_eh(ap); -	if (ap->pm_result) { -		*ap->pm_result = rc; -		ap->pm_result = NULL; -	} -  	spin_unlock_irqrestore(ap->lock, flags);  	return; @@ -3956,7 +4104,7 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)  	/* are we resuming? */  	spin_lock_irqsave(ap->lock, flags);  	if (!(ap->pflags & ATA_PFLAG_PM_PENDING) || -	    ap->pm_mesg.event != PM_EVENT_ON) { +	    !(ap->pm_mesg.event & PM_EVENT_RESUME)) {  		spin_unlock_irqrestore(ap->lock, flags);  		return;  	} @@ -3975,7 +4123,7 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)  		ata_for_each_dev(dev, link, ALL)  			ata_ering_clear(&dev->ering); -	ata_acpi_set_state(ap, PMSG_ON); +	ata_acpi_set_state(ap, ap->pm_mesg);  	if (ap->ops->port_resume)  		rc = ap->ops->port_resume(ap); @@ -3983,13 +4131,9 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)  	/* tell ACPI that we're resuming */  	ata_acpi_on_resume(ap); -	/* report result */ +	/* update the flags */  	spin_lock_irqsave(ap->lock, flags);  	ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED); -	if (ap->pm_result) { -		*ap->pm_result = rc; -		ap->pm_result = NULL; -	}  	spin_unlock_irqrestore(ap->lock, flags);  }  #endif /* CONFIG_PM */  | 
