Commit 5160acf2 authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

+enable_panic

parent 163a9091
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* *
* *
* libata documentation is available via 'make {ps|pdf}docs', * libata documentation is available via 'make {ps|pdf}docs',
* as Documentation/DocBook/libata.* * as Documentation/driver-api/libata.rst
* *
* Hardware documentation available from http://www.t13.org/ and * Hardware documentation available from http://www.t13.org/ and
* http://www.sata-io.org/ * http://www.sata-io.org/
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include <linux/libata.h> #include <linux/libata.h>
#include <trace/events/libata.h>
#include "libata.h" #include "libata.h"
enum { enum {
...@@ -548,6 +549,7 @@ enum blk_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd) ...@@ -548,6 +549,7 @@ enum blk_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
DPRINTK("EXIT, ret=%d\n", ret); DPRINTK("EXIT, ret=%d\n", ret);
return ret; return ret;
} }
EXPORT_SYMBOL(ata_scsi_timed_out);
static void ata_eh_unload(struct ata_port *ap) static void ata_eh_unload(struct ata_port *ap)
{ {
...@@ -605,7 +607,7 @@ void ata_scsi_error(struct Scsi_Host *host) ...@@ -605,7 +607,7 @@ void ata_scsi_error(struct Scsi_Host *host)
ata_scsi_port_error_handler(host, ap); ata_scsi_port_error_handler(host, ap);
/* finish or retry handled scmd's and clean up */ /* finish or retry handled scmd's and clean up */
WARN_ON(host->host_failed || !list_empty(&eh_work_q)); WARN_ON(!list_empty(&eh_work_q));
DPRINTK("EXIT\n"); DPRINTK("EXIT\n");
} }
...@@ -643,12 +645,11 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, ...@@ -643,12 +645,11 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
* completions are honored. A scmd is determined to have * completions are honored. A scmd is determined to have
* timed out iff its associated qc is active and not failed. * timed out iff its associated qc is active and not failed.
*/ */
spin_lock_irqsave(ap->lock, flags);
if (ap->ops->error_handler) { if (ap->ops->error_handler) {
struct scsi_cmnd *scmd, *tmp; struct scsi_cmnd *scmd, *tmp;
int nr_timedout = 0; int nr_timedout = 0;
spin_lock_irqsave(ap->lock, flags);
/* This must occur under the ap->lock as we don't want /* This must occur under the ap->lock as we don't want
a polled recovery to race the real interrupt handler a polled recovery to race the real interrupt handler
...@@ -698,12 +699,11 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, ...@@ -698,12 +699,11 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
if (nr_timedout) if (nr_timedout)
__ata_port_freeze(ap); __ata_port_freeze(ap);
spin_unlock_irqrestore(ap->lock, flags);
/* initialize eh_tries */ /* initialize eh_tries */
ap->eh_tries = ATA_EH_MAX_TRIES; ap->eh_tries = ATA_EH_MAX_TRIES;
} else }
spin_unlock_wait(ap->lock); spin_unlock_irqrestore(ap->lock, flags);
} }
EXPORT_SYMBOL(ata_scsi_cmd_error_handler); EXPORT_SYMBOL(ata_scsi_cmd_error_handler);
...@@ -968,7 +968,7 @@ static void ata_eh_set_pending(struct ata_port *ap, int fastdrain) ...@@ -968,7 +968,7 @@ static void ata_eh_set_pending(struct ata_port *ap, int fastdrain)
void ata_qc_schedule_eh(struct ata_queued_cmd *qc) void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
{ {
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
struct request_queue *q; struct request_queue *q = qc->scsicmd->device->request_queue;
unsigned long flags; unsigned long flags;
WARN_ON(!ap->ops->error_handler); WARN_ON(!ap->ops->error_handler);
...@@ -981,12 +981,9 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc) ...@@ -981,12 +981,9 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
* Note that ATA_QCFLAG_FAILED is unconditionally set after * Note that ATA_QCFLAG_FAILED is unconditionally set after
* this function completes. * this function completes.
*/ */
if (qc->scsicmd != NULL) {
q = qc->scsicmd->device->request_queue;
spin_lock_irqsave(q->queue_lock, flags); spin_lock_irqsave(q->queue_lock, flags);
blk_abort_request(qc->scsicmd->request); blk_abort_request(qc->scsicmd->request);
spin_unlock_irqrestore(q->queue_lock, flags); spin_unlock_irqrestore(q->queue_lock, flags);
}
} }
/** /**
...@@ -1435,7 +1432,7 @@ void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev, ...@@ -1435,7 +1432,7 @@ void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
/** /**
* ata_eh_done - EH action complete * ata_eh_done - EH action complete
* @ap: target ATA port * @link: ATA link for which EH actions are complete
* @dev: target ATA dev for per-dev action (can be NULL) * @dev: target ATA dev for per-dev action (can be NULL)
* @action: action just completed * @action: action just completed
* *
...@@ -1488,46 +1485,6 @@ static const char *ata_err_string(unsigned int err_mask) ...@@ -1488,46 +1485,6 @@ static const char *ata_err_string(unsigned int err_mask)
return "unknown error"; return "unknown error";
} }
/**
* 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
*
* Read log page using READ_LOG_EXT command.
*
* LOCKING:
* Kernel thread context (may sleep).
*
* RETURNS:
* 0 on success, AC_ERR_* mask otherwise.
*/
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 - log 0x%x, page 0x%x\n", log, page);
ata_tf_init(dev, &tf);
tf.command = ATA_CMD_READ_LOG_EXT;
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;
tf.protocol = ATA_PROT_PIO;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
buf, sectors * ATA_SECT_SIZE, 0);
DPRINTK("EXIT, err_mask=%x\n", err_mask);
return err_mask;
}
/** /**
* ata_eh_read_log_10h - Read log page 10h for NCQ error details * ata_eh_read_log_10h - Read log page 10h for NCQ error details
* @dev: Device to read log page 10h from * @dev: Device to read log page 10h from
...@@ -1578,6 +1535,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev, ...@@ -1578,6 +1535,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev,
tf->hob_lbah = buf[10]; tf->hob_lbah = buf[10];
tf->nsect = buf[12]; tf->nsect = buf[12];
tf->hob_nsect = buf[13]; tf->hob_nsect = buf[13];
if (ata_id_has_ncq_autosense(dev->id))
tf->auxiliary = buf[14] << 16 | buf[15] << 8 | buf[16];
return 0; return 0;
} }
...@@ -1613,6 +1572,56 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key) ...@@ -1613,6 +1572,56 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key)
return err_mask; return err_mask;
} }
/**
* ata_eh_request_sense - perform REQUEST_SENSE_DATA_EXT
* @qc: qc to perform REQUEST_SENSE_SENSE_DATA_EXT to
* @cmd: scsi command for which the sense code should be set
*
* Perform REQUEST_SENSE_DATA_EXT after the device reported CHECK
* SENSE. This function is an EH helper.
*
* LOCKING:
* Kernel thread context (may sleep).
*/
static void ata_eh_request_sense(struct ata_queued_cmd *qc,
struct scsi_cmnd *cmd)
{
struct ata_device *dev = qc->dev;
struct ata_taskfile tf;
unsigned int err_mask;
if (qc->ap->pflags & ATA_PFLAG_FROZEN) {
ata_dev_warn(dev, "sense data available but port frozen\n");
return;
}
if (!cmd || qc->flags & ATA_QCFLAG_SENSE_VALID)
return;
if (!ata_id_sense_reporting_enabled(dev->id)) {
ata_dev_warn(qc->dev, "sense data reporting disabled\n");
return;
}
DPRINTK("ATA request sense\n");
ata_tf_init(dev, &tf);
tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
tf.flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
tf.command = ATA_CMD_REQ_SENSE_DATA;
tf.protocol = ATA_PROT_NODATA;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
/* Ignore err_mask; ATA_ERR might be set */
if (tf.command & ATA_SENSE) {
ata_scsi_set_sense(dev, cmd, tf.lbah, tf.lbam, tf.lbal);
qc->flags |= ATA_QCFLAG_SENSE_VALID;
} else {
ata_dev_warn(dev, "request sense failed stat %02x emask %x\n",
tf.command, err_mask);
}
}
/** /**
* atapi_eh_request_sense - perform ATAPI REQUEST_SENSE * atapi_eh_request_sense - perform ATAPI REQUEST_SENSE
* @dev: device to perform REQUEST_SENSE to * @dev: device to perform REQUEST_SENSE to
...@@ -1775,6 +1784,18 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) ...@@ -1775,6 +1784,18 @@ void ata_eh_analyze_ncq_error(struct ata_link *link)
memcpy(&qc->result_tf, &tf, sizeof(tf)); memcpy(&qc->result_tf, &tf, sizeof(tf));
qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48; qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ;
if ((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary) {
char sense_key, asc, ascq;
sense_key = (qc->result_tf.auxiliary >> 16) & 0xff;
asc = (qc->result_tf.auxiliary >> 8) & 0xff;
ascq = qc->result_tf.auxiliary & 0xff;
ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, ascq);
ata_scsi_set_sense_information(dev, qc->scsicmd,
&qc->result_tf);
qc->flags |= ATA_QCFLAG_SENSE_VALID;
}
ehc->i.err_mask &= ~AC_ERR_DEV; ehc->i.err_mask &= ~AC_ERR_DEV;
} }
...@@ -1804,14 +1825,23 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, ...@@ -1804,14 +1825,23 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
return ATA_EH_RESET; return ATA_EH_RESET;
} }
if (stat & (ATA_ERR | ATA_DF)) if (stat & (ATA_ERR | ATA_DF)) {
qc->err_mask |= AC_ERR_DEV; qc->err_mask |= AC_ERR_DEV;
else /*
* Sense data reporting does not work if the
* device fault bit is set.
*/
if (stat & ATA_DF)
stat &= ~ATA_SENSE;
} else {
return 0; return 0;
}
switch (qc->dev->class) { switch (qc->dev->class) {
case ATA_DEV_ATA: case ATA_DEV_ATA:
case ATA_DEV_ZAC: case ATA_DEV_ZAC:
if (stat & ATA_SENSE)
ata_eh_request_sense(qc, qc->scsicmd);
if (err & ATA_ICRC) if (err & ATA_ICRC)
qc->err_mask |= AC_ERR_ATA_BUS; qc->err_mask |= AC_ERR_ATA_BUS;
if (err & (ATA_UNC | ATA_AMNF)) if (err & (ATA_UNC | ATA_AMNF))
...@@ -1825,20 +1855,31 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, ...@@ -1825,20 +1855,31 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
tmp = atapi_eh_request_sense(qc->dev, tmp = atapi_eh_request_sense(qc->dev,
qc->scsicmd->sense_buffer, qc->scsicmd->sense_buffer,
qc->result_tf.feature >> 4); qc->result_tf.feature >> 4);
if (!tmp) { if (!tmp)
/* ATA_QCFLAG_SENSE_VALID is used to
* tell atapi_qc_complete() that sense
* data is already valid.
*
* TODO: interpret sense data and set
* appropriate err_mask.
*/
qc->flags |= ATA_QCFLAG_SENSE_VALID; qc->flags |= ATA_QCFLAG_SENSE_VALID;
} else else
qc->err_mask |= tmp; qc->err_mask |= tmp;
} }
} }
if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
int ret = scsi_check_sense(qc->scsicmd);
/*
* SUCCESS here means that the sense code could
* evaluated and should be passed to the upper layers
* for correct evaluation.
* FAILED means the sense code could not interpreted
* and the device would need to be reset.
* NEEDS_RETRY and ADD_TO_MLQUEUE means that the
* command would need to be retried.
*/
if (ret == NEEDS_RETRY || ret == ADD_TO_MLQUEUE) {
qc->flags |= ATA_QCFLAG_RETRY;
qc->err_mask |= AC_ERR_OTHER;
} else if (ret != SUCCESS) {
qc->err_mask |= AC_ERR_HSM;
}
}
if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS)) if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS))
action |= ATA_EH_RESET; action |= ATA_EH_RESET;
...@@ -1927,7 +1968,7 @@ static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg) ...@@ -1927,7 +1968,7 @@ static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg)
* This is to expedite speed down decisions right after device is * This is to expedite speed down decisions right after device is
* initially configured. * initially configured.
* *
* The followings are speed down rules. #1 and #2 deal with * The following are speed down rules. #1 and #2 deal with
* DUBIOUS errors. * DUBIOUS errors.
* *
* 1. If more than one DUBIOUS_ATA_BUS or DUBIOUS_TOUT_HSM errors * 1. If more than one DUBIOUS_ATA_BUS or DUBIOUS_TOUT_HSM errors
...@@ -2189,6 +2230,7 @@ static void ata_eh_link_autopsy(struct ata_link *link) ...@@ -2189,6 +2230,7 @@ static void ata_eh_link_autopsy(struct ata_link *link)
all_err_mask |= qc->err_mask; all_err_mask |= qc->err_mask;
if (qc->flags & ATA_QCFLAG_IO) if (qc->flags & ATA_QCFLAG_IO)
eflags |= ATA_EFLAG_IS_IO; eflags |= ATA_EFLAG_IS_IO;
trace_ata_eh_link_autopsy_qc(qc);
} }
/* enforce default EH actions */ /* enforce default EH actions */
...@@ -2223,7 +2265,7 @@ static void ata_eh_link_autopsy(struct ata_link *link) ...@@ -2223,7 +2265,7 @@ static void ata_eh_link_autopsy(struct ata_link *link)
eflags |= ATA_EFLAG_DUBIOUS_XFER; eflags |= ATA_EFLAG_DUBIOUS_XFER;
ehc->i.action |= ata_eh_speed_down(dev, eflags, all_err_mask); ehc->i.action |= ata_eh_speed_down(dev, eflags, all_err_mask);
} }
trace_ata_eh_link_autopsy(dev, ehc->i.action, all_err_mask);
DPRINTK("EXIT\n"); DPRINTK("EXIT\n");
} }
...@@ -2375,6 +2417,8 @@ const char *ata_get_cmd_descript(u8 command) ...@@ -2375,6 +2417,8 @@ const char *ata_get_cmd_descript(u8 command)
{ ATA_CMD_CFA_WRITE_MULT_NE, "CFA WRITE MULTIPLE WITHOUT ERASE" }, { ATA_CMD_CFA_WRITE_MULT_NE, "CFA WRITE MULTIPLE WITHOUT ERASE" },
{ ATA_CMD_REQ_SENSE_DATA, "REQUEST SENSE DATA EXT" }, { ATA_CMD_REQ_SENSE_DATA, "REQUEST SENSE DATA EXT" },
{ ATA_CMD_SANITIZE_DEVICE, "SANITIZE DEVICE" }, { ATA_CMD_SANITIZE_DEVICE, "SANITIZE DEVICE" },
{ ATA_CMD_ZAC_MGMT_IN, "ZAC MANAGEMENT IN" },
{ ATA_CMD_ZAC_MGMT_OUT, "ZAC MANAGEMENT OUT" },
{ ATA_CMD_READ_LONG, "READ LONG (with retries)" }, { ATA_CMD_READ_LONG, "READ LONG (with retries)" },
{ ATA_CMD_READ_LONG_ONCE, "READ LONG (without retries)" }, { ATA_CMD_READ_LONG_ONCE, "READ LONG (without retries)" },
{ ATA_CMD_WRITE_LONG, "WRITE LONG (with retries)" }, { ATA_CMD_WRITE_LONG, "WRITE LONG (with retries)" },
...@@ -2499,17 +2543,39 @@ static void ata_eh_link_report(struct ata_link *link) ...@@ -2499,17 +2543,39 @@ static void ata_eh_link_report(struct ata_link *link)
[DMA_TO_DEVICE] = "out", [DMA_TO_DEVICE] = "out",
[DMA_FROM_DEVICE] = "in", [DMA_FROM_DEVICE] = "in",
}; };
static const char *prot_str[] = { const char *prot_str = NULL;
[ATA_PROT_PIO] = "pio",
[ATA_PROT_DMA] = "dma",
[ATA_PROT_NCQ] = "ncq",
[ATAPI_PROT_PIO] = "pio",
[ATAPI_PROT_DMA] = "dma",
};
switch (qc->tf.protocol) {
case ATA_PROT_UNKNOWN:
prot_str = "unknown";
break;
case ATA_PROT_NODATA:
prot_str = "nodata";
break;
case ATA_PROT_PIO:
prot_str = "pio";
break;
case ATA_PROT_DMA:
prot_str = "dma";
break;
case ATA_PROT_NCQ:
prot_str = "ncq dma";
break;
case ATA_PROT_NCQ_NODATA:
prot_str = "ncq nodata";
break;
case ATAPI_PROT_NODATA:
prot_str = "nodata";
break;
case ATAPI_PROT_PIO:
prot_str = "pio";
break;
case ATAPI_PROT_DMA:
prot_str = "dma";
break;
}
snprintf(data_buf, sizeof(data_buf), " %s %u %s", snprintf(data_buf, sizeof(data_buf), " %s %u %s",
prot_str[qc->tf.protocol], qc->nbytes, prot_str, qc->nbytes, dma_str[qc->dma_dir]);
dma_str[qc->dma_dir]);
} }
if (ata_is_atapi(qc->tf.protocol)) { if (ata_is_atapi(qc->tf.protocol)) {
...@@ -2551,14 +2617,15 @@ static void ata_eh_link_report(struct ata_link *link) ...@@ -2551,14 +2617,15 @@ static void ata_eh_link_report(struct ata_link *link)
#ifdef CONFIG_ATA_VERBOSE_ERROR #ifdef CONFIG_ATA_VERBOSE_ERROR
if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ |
ATA_ERR)) { ATA_SENSE | ATA_ERR)) {
if (res->command & ATA_BUSY) if (res->command & ATA_BUSY)
ata_dev_err(qc->dev, "status: { Busy }\n"); ata_dev_err(qc->dev, "status: { Busy }\n");
else else
ata_dev_err(qc->dev, "status: { %s%s%s%s}\n", ata_dev_err(qc->dev, "status: { %s%s%s%s%s}\n",
res->command & ATA_DRDY ? "DRDY " : "", res->command & ATA_DRDY ? "DRDY " : "",
res->command & ATA_DF ? "DF " : "", res->command & ATA_DF ? "DF " : "",
res->command & ATA_DRQ ? "DRQ " : "", res->command & ATA_DRQ ? "DRQ " : "",
res->command & ATA_SENSE ? "SENSE " : "",
res->command & ATA_ERR ? "ERR " : ""); res->command & ATA_ERR ? "ERR " : "");
} }
...@@ -2574,6 +2641,7 @@ static void ata_eh_link_report(struct ata_link *link) ...@@ -2574,6 +2641,7 @@ static void ata_eh_link_report(struct ata_link *link)
#endif #endif
} }
} }
/** /**
* ata_eh_report - report error handling to user * ata_eh_report - report error handling to user
* @ap: ATA port to report EH about * @ap: ATA port to report EH about
...@@ -3071,7 +3139,7 @@ static void ata_eh_park_issue_cmd(struct ata_device *dev, int park) ...@@ -3071,7 +3139,7 @@ static void ata_eh_park_issue_cmd(struct ata_device *dev, int park)
} }
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
tf.protocol |= ATA_PROT_NODATA; tf.protocol = ATA_PROT_NODATA;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
if (park && (err_mask || tf.lbal != 0xc4)) { if (park && (err_mask || tf.lbal != 0xc4)) {
ata_dev_err(dev, "head unload failed!\n"); ata_dev_err(dev, "head unload failed!\n");
...@@ -3496,6 +3564,9 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, ...@@ -3496,6 +3564,9 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
} }
} }
link->last_lpm_change = jiffies;
link->flags |= ATA_LFLAG_CHANGED;
return 0; return 0;
fail: fail:
...@@ -4107,7 +4178,6 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) ...@@ -4107,7 +4178,6 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
struct ata_link *link; struct ata_link *link;
struct ata_device *dev; struct ata_device *dev;
unsigned long flags; unsigned long flags;
int rc = 0;
/* are we resuming? */ /* are we resuming? */
spin_lock_irqsave(ap->lock, flags); spin_lock_irqsave(ap->lock, flags);
...@@ -4134,7 +4204,7 @@ static void ata_eh_handle_port_resume(struct ata_port *ap) ...@@ -4134,7 +4204,7 @@ static void ata_eh_handle_port_resume(struct ata_port *ap)
ata_acpi_set_state(ap, ap->pm_mesg); ata_acpi_set_state(ap, ap->pm_mesg);
if (ap->ops->port_resume) if (ap->ops->port_resume)
rc = ap->ops->port_resume(ap); ap->ops->port_resume(ap);
/* tell ACPI that we're resuming */ /* tell ACPI that we're resuming */
ata_acpi_on_resume(ap); ata_acpi_on_resume(ap);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment