Merge branch 'tmp'
This commit is contained in:
Коммит
7103c7bc86
|
@ -672,19 +672,13 @@ static void ahci_eng_timeout(struct ata_port *ap)
|
||||||
ap->id);
|
ap->id);
|
||||||
} else {
|
} else {
|
||||||
ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT));
|
ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT));
|
||||||
|
|
||||||
/* hack alert! We cannot use the supplied completion
|
|
||||||
* function from inside the ->eh_strategy_handler() thread.
|
|
||||||
* libata is the only user of ->eh_strategy_handler() in
|
|
||||||
* any kernel, so the default scsi_done() assumes it is
|
|
||||||
* not being called from the SCSI EH.
|
|
||||||
*/
|
|
||||||
qc->scsidone = scsi_finish_command;
|
|
||||||
qc->err_mask |= AC_ERR_TIMEOUT;
|
qc->err_mask |= AC_ERR_TIMEOUT;
|
||||||
ata_qc_complete(qc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&host_set->lock, flags);
|
spin_unlock_irqrestore(&host_set->lock, flags);
|
||||||
|
|
||||||
|
if (qc)
|
||||||
|
ata_eh_qc_complete(qc);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
|
static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
|
||||||
|
|
|
@ -3633,14 +3633,6 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
|
||||||
|
|
||||||
spin_lock_irqsave(&host_set->lock, flags);
|
spin_lock_irqsave(&host_set->lock, flags);
|
||||||
|
|
||||||
/* hack alert! We cannot use the supplied completion
|
|
||||||
* function from inside the ->eh_strategy_handler() thread.
|
|
||||||
* libata is the only user of ->eh_strategy_handler() in
|
|
||||||
* any kernel, so the default scsi_done() assumes it is
|
|
||||||
* not being called from the SCSI EH.
|
|
||||||
*/
|
|
||||||
qc->scsidone = scsi_finish_command;
|
|
||||||
|
|
||||||
switch (qc->tf.protocol) {
|
switch (qc->tf.protocol) {
|
||||||
|
|
||||||
case ATA_PROT_DMA:
|
case ATA_PROT_DMA:
|
||||||
|
@ -3666,12 +3658,13 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
|
||||||
|
|
||||||
/* complete taskfile transaction */
|
/* complete taskfile transaction */
|
||||||
qc->err_mask |= ac_err_mask(drv_stat);
|
qc->err_mask |= ac_err_mask(drv_stat);
|
||||||
ata_qc_complete(qc);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&host_set->lock, flags);
|
spin_unlock_irqrestore(&host_set->lock, flags);
|
||||||
|
|
||||||
|
ata_eh_qc_complete(qc);
|
||||||
|
|
||||||
DPRINTK("EXIT\n");
|
DPRINTK("EXIT\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4706,6 +4699,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host,
|
||||||
ap->last_ctl = 0xFF;
|
ap->last_ctl = 0xFF;
|
||||||
|
|
||||||
INIT_WORK(&ap->pio_task, ata_pio_task, ap);
|
INIT_WORK(&ap->pio_task, ata_pio_task, ap);
|
||||||
|
INIT_LIST_HEAD(&ap->eh_done_q);
|
||||||
|
|
||||||
for (i = 0; i < ATA_MAX_DEVICES; i++)
|
for (i = 0; i < ATA_MAX_DEVICES; i++)
|
||||||
ap->device[i].devno = i;
|
ap->device[i].devno = i;
|
||||||
|
@ -5449,6 +5443,8 @@ EXPORT_SYMBOL_GPL(ata_dev_classify);
|
||||||
EXPORT_SYMBOL_GPL(ata_dev_id_string);
|
EXPORT_SYMBOL_GPL(ata_dev_id_string);
|
||||||
EXPORT_SYMBOL_GPL(ata_dev_config);
|
EXPORT_SYMBOL_GPL(ata_dev_config);
|
||||||
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
|
EXPORT_SYMBOL_GPL(ata_scsi_simulate);
|
||||||
|
EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
|
||||||
|
EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
|
EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
|
||||||
EXPORT_SYMBOL_GPL(ata_timing_compute);
|
EXPORT_SYMBOL_GPL(ata_timing_compute);
|
||||||
|
|
|
@ -738,17 +738,64 @@ int ata_scsi_error(struct Scsi_Host *host)
|
||||||
ap = (struct ata_port *) &host->hostdata[0];
|
ap = (struct ata_port *) &host->hostdata[0];
|
||||||
ap->ops->eng_timeout(ap);
|
ap->ops->eng_timeout(ap);
|
||||||
|
|
||||||
/* TODO: this is per-command; when queueing is supported
|
assert(host->host_failed == 0 && list_empty(&host->eh_cmd_q));
|
||||||
* this code will either change or move to a more
|
|
||||||
* appropriate place
|
scsi_eh_flush_done_q(&ap->eh_done_q);
|
||||||
*/
|
|
||||||
host->host_failed--;
|
|
||||||
INIT_LIST_HEAD(&host->eh_cmd_q);
|
|
||||||
|
|
||||||
DPRINTK("EXIT\n");
|
DPRINTK("EXIT\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ata_eh_scsidone(struct scsi_cmnd *scmd)
|
||||||
|
{
|
||||||
|
/* nada */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __ata_eh_qc_complete(struct ata_queued_cmd *qc)
|
||||||
|
{
|
||||||
|
struct ata_port *ap = qc->ap;
|
||||||
|
struct scsi_cmnd *scmd = qc->scsicmd;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&ap->host_set->lock, flags);
|
||||||
|
qc->scsidone = ata_eh_scsidone;
|
||||||
|
ata_qc_complete(qc);
|
||||||
|
assert(!ata_tag_valid(qc->tag));
|
||||||
|
spin_unlock_irqrestore(&ap->host_set->lock, flags);
|
||||||
|
|
||||||
|
scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_eh_qc_complete - Complete an active ATA command from EH
|
||||||
|
* @qc: Command to complete
|
||||||
|
*
|
||||||
|
* Indicate to the mid and upper layers that an ATA command has
|
||||||
|
* completed. To be used from EH.
|
||||||
|
*/
|
||||||
|
void ata_eh_qc_complete(struct ata_queued_cmd *qc)
|
||||||
|
{
|
||||||
|
struct scsi_cmnd *scmd = qc->scsicmd;
|
||||||
|
scmd->retries = scmd->allowed;
|
||||||
|
__ata_eh_qc_complete(qc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_eh_qc_retry - Tell midlayer to retry an ATA command after EH
|
||||||
|
* @qc: Command to retry
|
||||||
|
*
|
||||||
|
* Indicate to the mid and upper layers that an ATA command
|
||||||
|
* should be retried. To be used from EH.
|
||||||
|
*
|
||||||
|
* SCSI midlayer limits the number of retries to scmd->allowed.
|
||||||
|
* This function might need to adjust scmd->retries for commands
|
||||||
|
* which get retried due to unrelated NCQ failures.
|
||||||
|
*/
|
||||||
|
void ata_eh_qc_retry(struct ata_queued_cmd *qc)
|
||||||
|
{
|
||||||
|
__ata_eh_qc_complete(qc);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
|
* ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
|
||||||
* @qc: Storage for translated ATA taskfile
|
* @qc: Storage for translated ATA taskfile
|
||||||
|
|
|
@ -1838,7 +1838,6 @@ static void mv_phy_reset(struct ata_port *ap)
|
||||||
static void mv_eng_timeout(struct ata_port *ap)
|
static void mv_eng_timeout(struct ata_port *ap)
|
||||||
{
|
{
|
||||||
struct ata_queued_cmd *qc;
|
struct ata_queued_cmd *qc;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id);
|
printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id);
|
||||||
DPRINTK("All regs @ start of eng_timeout\n");
|
DPRINTK("All regs @ start of eng_timeout\n");
|
||||||
|
@ -1857,17 +1856,8 @@ static void mv_eng_timeout(struct ata_port *ap)
|
||||||
printk(KERN_ERR "ata%u: BUG: timeout without command\n",
|
printk(KERN_ERR "ata%u: BUG: timeout without command\n",
|
||||||
ap->id);
|
ap->id);
|
||||||
} else {
|
} else {
|
||||||
/* hack alert! We cannot use the supplied completion
|
|
||||||
* function from inside the ->eh_strategy_handler() thread.
|
|
||||||
* libata is the only user of ->eh_strategy_handler() in
|
|
||||||
* any kernel, so the default scsi_done() assumes it is
|
|
||||||
* not being called from the SCSI EH.
|
|
||||||
*/
|
|
||||||
spin_lock_irqsave(&ap->host_set->lock, flags);
|
|
||||||
qc->scsidone = scsi_finish_command;
|
|
||||||
qc->err_mask |= AC_ERR_TIMEOUT;
|
qc->err_mask |= AC_ERR_TIMEOUT;
|
||||||
ata_qc_complete(qc);
|
ata_eh_qc_complete(qc);
|
||||||
spin_unlock_irqrestore(&ap->host_set->lock, flags);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -401,21 +401,12 @@ static void pdc_eng_timeout(struct ata_port *ap)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hack alert! We cannot use the supplied completion
|
|
||||||
* function from inside the ->eh_strategy_handler() thread.
|
|
||||||
* libata is the only user of ->eh_strategy_handler() in
|
|
||||||
* any kernel, so the default scsi_done() assumes it is
|
|
||||||
* not being called from the SCSI EH.
|
|
||||||
*/
|
|
||||||
qc->scsidone = scsi_finish_command;
|
|
||||||
|
|
||||||
switch (qc->tf.protocol) {
|
switch (qc->tf.protocol) {
|
||||||
case ATA_PROT_DMA:
|
case ATA_PROT_DMA:
|
||||||
case ATA_PROT_NODATA:
|
case ATA_PROT_NODATA:
|
||||||
printk(KERN_ERR "ata%u: command timeout\n", ap->id);
|
printk(KERN_ERR "ata%u: command timeout\n", ap->id);
|
||||||
drv_stat = ata_wait_idle(ap);
|
drv_stat = ata_wait_idle(ap);
|
||||||
qc->err_mask |= __ac_err_mask(drv_stat);
|
qc->err_mask |= __ac_err_mask(drv_stat);
|
||||||
ata_qc_complete(qc);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -425,12 +416,13 @@ static void pdc_eng_timeout(struct ata_port *ap)
|
||||||
ap->id, qc->tf.command, drv_stat);
|
ap->id, qc->tf.command, drv_stat);
|
||||||
|
|
||||||
qc->err_mask |= ac_err_mask(drv_stat);
|
qc->err_mask |= ac_err_mask(drv_stat);
|
||||||
ata_qc_complete(qc);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
spin_unlock_irqrestore(&host_set->lock, flags);
|
spin_unlock_irqrestore(&host_set->lock, flags);
|
||||||
|
if (qc)
|
||||||
|
ata_eh_qc_complete(qc);
|
||||||
DPRINTK("EXIT\n");
|
DPRINTK("EXIT\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -644,17 +644,9 @@ static void sil24_eng_timeout(struct ata_port *ap)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* hack alert! We cannot use the supplied completion
|
|
||||||
* function from inside the ->eh_strategy_handler() thread.
|
|
||||||
* libata is the only user of ->eh_strategy_handler() in
|
|
||||||
* any kernel, so the default scsi_done() assumes it is
|
|
||||||
* not being called from the SCSI EH.
|
|
||||||
*/
|
|
||||||
printk(KERN_ERR "ata%u: command timeout\n", ap->id);
|
printk(KERN_ERR "ata%u: command timeout\n", ap->id);
|
||||||
qc->scsidone = scsi_finish_command;
|
|
||||||
qc->err_mask |= AC_ERR_TIMEOUT;
|
qc->err_mask |= AC_ERR_TIMEOUT;
|
||||||
ata_qc_complete(qc);
|
ata_eh_qc_complete(qc);
|
||||||
|
|
||||||
sil24_reset_controller(ap);
|
sil24_reset_controller(ap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -872,20 +872,11 @@ static void pdc_eng_timeout(struct ata_port *ap)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hack alert! We cannot use the supplied completion
|
|
||||||
* function from inside the ->eh_strategy_handler() thread.
|
|
||||||
* libata is the only user of ->eh_strategy_handler() in
|
|
||||||
* any kernel, so the default scsi_done() assumes it is
|
|
||||||
* not being called from the SCSI EH.
|
|
||||||
*/
|
|
||||||
qc->scsidone = scsi_finish_command;
|
|
||||||
|
|
||||||
switch (qc->tf.protocol) {
|
switch (qc->tf.protocol) {
|
||||||
case ATA_PROT_DMA:
|
case ATA_PROT_DMA:
|
||||||
case ATA_PROT_NODATA:
|
case ATA_PROT_NODATA:
|
||||||
printk(KERN_ERR "ata%u: command timeout\n", ap->id);
|
printk(KERN_ERR "ata%u: command timeout\n", ap->id);
|
||||||
qc->err_mask |= __ac_err_mask(ata_wait_idle(ap));
|
qc->err_mask |= __ac_err_mask(ata_wait_idle(ap));
|
||||||
ata_qc_complete(qc);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -895,12 +886,13 @@ static void pdc_eng_timeout(struct ata_port *ap)
|
||||||
ap->id, qc->tf.command, drv_stat);
|
ap->id, qc->tf.command, drv_stat);
|
||||||
|
|
||||||
qc->err_mask |= ac_err_mask(drv_stat);
|
qc->err_mask |= ac_err_mask(drv_stat);
|
||||||
ata_qc_complete(qc);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
spin_unlock_irqrestore(&host_set->lock, flags);
|
spin_unlock_irqrestore(&host_set->lock, flags);
|
||||||
|
if (qc)
|
||||||
|
ata_eh_qc_complete(qc);
|
||||||
DPRINTK("EXIT\n");
|
DPRINTK("EXIT\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -401,6 +401,7 @@ struct ata_port {
|
||||||
unsigned long pio_task_timeout;
|
unsigned long pio_task_timeout;
|
||||||
|
|
||||||
u32 msg_enable;
|
u32 msg_enable;
|
||||||
|
struct list_head eh_done_q;
|
||||||
|
|
||||||
void *private_data;
|
void *private_data;
|
||||||
};
|
};
|
||||||
|
@ -493,6 +494,8 @@ extern int ata_scsi_detect(struct scsi_host_template *sht);
|
||||||
extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
|
extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
|
||||||
extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
|
extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
|
||||||
extern int ata_scsi_error(struct Scsi_Host *host);
|
extern int ata_scsi_error(struct Scsi_Host *host);
|
||||||
|
extern void ata_eh_qc_complete(struct ata_queued_cmd *qc);
|
||||||
|
extern void ata_eh_qc_retry(struct ata_queued_cmd *qc);
|
||||||
extern int ata_scsi_release(struct Scsi_Host *host);
|
extern int ata_scsi_release(struct Scsi_Host *host);
|
||||||
extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
|
extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
|
||||||
extern int ata_scsi_device_resume(struct scsi_device *);
|
extern int ata_scsi_device_resume(struct scsi_device *);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче