aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-05-15 07:58:05 -0400
committerTejun Heo <htejun@gmail.com>2006-05-15 07:58:05 -0400
commitf686bcb8078ac7505ec88818886c2c72639f4fc5 (patch)
tree7c563e0032b2d85b631b617b8bb2a7a648607468
parentf69499f42caf74194df678c9c293f2ee0fe90bc3 (diff)
[PATCH] libata-eh-fw: implement new EH scheduling via error completion
There are several ways a qc can get schedule for EH in new EH. This patch implements one of them - completing a qc with ATA_QCFLAG_FAILED set or with non-zero qc->err_mask. ALL such qc's are examined by EH. New EH schedules a qc for EH from completion iff ->error_handler is implemented, qc is marked as failed or qc->err_mask is non-zero and the command is not an internal command (internal cmd is handled via ->post_internal_cmd). The EH scheduling itself is performed by asking SCSI midlayer to schedule EH for the specified scmd. For drivers implementing old-EH, nothing changes. As this change makes ata_qc_complete() rather large, it's not inlined anymore and __ata_qc_complete() is exported to other parts of libata for later use. Signed-off-by: Tejun Heo <htejun@gmail.com>
-rw-r--r--drivers/scsi/libata-core.c62
-rw-r--r--drivers/scsi/libata-eh.c27
-rw-r--r--drivers/scsi/libata.h2
-rw-r--r--include/linux/libata.h27
4 files changed, 91 insertions, 27 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 1c34c1427aa3..1f5c3270992a 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -4123,6 +4123,66 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
4123 qc->complete_fn(qc); 4123 qc->complete_fn(qc);
4124} 4124}
4125 4125
4126/**
4127 * ata_qc_complete - Complete an active ATA command
4128 * @qc: Command to complete
4129 * @err_mask: ATA Status register contents
4130 *
4131 * Indicate to the mid and upper layers that an ATA
4132 * command has completed, with either an ok or not-ok status.
4133 *
4134 * LOCKING:
4135 * spin_lock_irqsave(host_set lock)
4136 */
4137void ata_qc_complete(struct ata_queued_cmd *qc)
4138{
4139 struct ata_port *ap = qc->ap;
4140
4141 /* XXX: New EH and old EH use different mechanisms to
4142 * synchronize EH with regular execution path.
4143 *
4144 * In new EH, a failed qc is marked with ATA_QCFLAG_FAILED.
4145 * Normal execution path is responsible for not accessing a
4146 * failed qc. libata core enforces the rule by returning NULL
4147 * from ata_qc_from_tag() for failed qcs.
4148 *
4149 * Old EH depends on ata_qc_complete() nullifying completion
4150 * requests if ATA_QCFLAG_EH_SCHEDULED is set. Old EH does
4151 * not synchronize with interrupt handler. Only PIO task is
4152 * taken care of.
4153 */
4154 if (ap->ops->error_handler) {
4155 WARN_ON(ap->flags & ATA_FLAG_FROZEN);
4156
4157 if (unlikely(qc->err_mask))
4158 qc->flags |= ATA_QCFLAG_FAILED;
4159
4160 if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
4161 if (!ata_tag_internal(qc->tag)) {
4162 /* always fill result TF for failed qc */
4163 ap->ops->tf_read(ap, &qc->result_tf);
4164 ata_qc_schedule_eh(qc);
4165 return;
4166 }
4167 }
4168
4169 /* read result TF if requested */
4170 if (qc->flags & ATA_QCFLAG_RESULT_TF)
4171 ap->ops->tf_read(ap, &qc->result_tf);
4172
4173 __ata_qc_complete(qc);
4174 } else {
4175 if (qc->flags & ATA_QCFLAG_EH_SCHEDULED)
4176 return;
4177
4178 /* read result TF if failed or requested */
4179 if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF)
4180 ap->ops->tf_read(ap, &qc->result_tf);
4181
4182 __ata_qc_complete(qc);
4183 }
4184}
4185
4126static inline int ata_should_dma_map(struct ata_queued_cmd *qc) 4186static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
4127{ 4187{
4128 struct ata_port *ap = qc->ap; 4188 struct ata_port *ap = qc->ap;
@@ -5245,7 +5305,7 @@ EXPORT_SYMBOL_GPL(ata_device_add);
5245EXPORT_SYMBOL_GPL(ata_host_set_remove); 5305EXPORT_SYMBOL_GPL(ata_host_set_remove);
5246EXPORT_SYMBOL_GPL(ata_sg_init); 5306EXPORT_SYMBOL_GPL(ata_sg_init);
5247EXPORT_SYMBOL_GPL(ata_sg_init_one); 5307EXPORT_SYMBOL_GPL(ata_sg_init_one);
5248EXPORT_SYMBOL_GPL(__ata_qc_complete); 5308EXPORT_SYMBOL_GPL(ata_qc_complete);
5249EXPORT_SYMBOL_GPL(ata_qc_issue_prot); 5309EXPORT_SYMBOL_GPL(ata_qc_issue_prot);
5250EXPORT_SYMBOL_GPL(ata_tf_load); 5310EXPORT_SYMBOL_GPL(ata_tf_load);
5251EXPORT_SYMBOL_GPL(ata_tf_read); 5311EXPORT_SYMBOL_GPL(ata_tf_read);
diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c
index 959a1cdffac2..471846fe4b73 100644
--- a/drivers/scsi/libata-eh.c
+++ b/drivers/scsi/libata-eh.c
@@ -210,6 +210,33 @@ void ata_eng_timeout(struct ata_port *ap)
210 DPRINTK("EXIT\n"); 210 DPRINTK("EXIT\n");
211} 211}
212 212
213/**
214 * ata_qc_schedule_eh - schedule qc for error handling
215 * @qc: command to schedule error handling for
216 *
217 * Schedule error handling for @qc. EH will kick in as soon as
218 * other commands are drained.
219 *
220 * LOCKING:
221 * spin_lock_irqsave(host_set lock)
222 */
223void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
224{
225 struct ata_port *ap = qc->ap;
226
227 WARN_ON(!ap->ops->error_handler);
228
229 qc->flags |= ATA_QCFLAG_FAILED;
230 qc->ap->flags |= ATA_FLAG_EH_PENDING;
231
232 /* The following will fail if timeout has already expired.
233 * ata_scsi_error() takes care of such scmds on EH entry.
234 * Note that ATA_QCFLAG_FAILED is unconditionally set after
235 * this function completes.
236 */
237 scsi_req_abort_cmd(qc->scsicmd);
238}
239
213static void ata_eh_scsidone(struct scsi_cmnd *scmd) 240static void ata_eh_scsidone(struct scsi_cmnd *scmd)
214{ 241{
215 /* nada */ 242 /* nada */
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index c9ff83bbcfae..52622b7f8a9e 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -57,6 +57,7 @@ extern int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,
57 unsigned int *classes); 57 unsigned int *classes);
58extern void ata_qc_free(struct ata_queued_cmd *qc); 58extern void ata_qc_free(struct ata_queued_cmd *qc);
59extern void ata_qc_issue(struct ata_queued_cmd *qc); 59extern void ata_qc_issue(struct ata_queued_cmd *qc);
60extern void __ata_qc_complete(struct ata_queued_cmd *qc);
60extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); 61extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
61extern void ata_dev_select(struct ata_port *ap, unsigned int device, 62extern void ata_dev_select(struct ata_port *ap, unsigned int device,
62 unsigned int wait, unsigned int can_sleep); 63 unsigned int wait, unsigned int can_sleep);
@@ -101,5 +102,6 @@ extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
101/* libata-eh.c */ 102/* libata-eh.c */
102extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); 103extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
103extern void ata_scsi_error(struct Scsi_Host *host); 104extern void ata_scsi_error(struct Scsi_Host *host);
105extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
104 106
105#endif /* __LIBATA_H__ */ 107#endif /* __LIBATA_H__ */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index bfcefdca0616..6023f324e68e 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -605,7 +605,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc);
605extern void ata_bmdma_stop(struct ata_queued_cmd *qc); 605extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
606extern u8 ata_bmdma_status(struct ata_port *ap); 606extern u8 ata_bmdma_status(struct ata_port *ap);
607extern void ata_bmdma_irq_clear(struct ata_port *ap); 607extern void ata_bmdma_irq_clear(struct ata_port *ap);
608extern void __ata_qc_complete(struct ata_queued_cmd *qc); 608extern void ata_qc_complete(struct ata_queued_cmd *qc);
609extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, 609extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
610 void (*done)(struct scsi_cmnd *)); 610 void (*done)(struct scsi_cmnd *));
611extern int ata_std_bios_param(struct scsi_device *sdev, 611extern int ata_std_bios_param(struct scsi_device *sdev,
@@ -883,31 +883,6 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
883} 883}
884 884
885/** 885/**
886 * ata_qc_complete - Complete an active ATA command
887 * @qc: Command to complete
888 * @err_mask: ATA Status register contents
889 *
890 * Indicate to the mid and upper layers that an ATA
891 * command has completed, with either an ok or not-ok status.
892 *
893 * LOCKING:
894 * spin_lock_irqsave(host_set lock)
895 */
896static inline void ata_qc_complete(struct ata_queued_cmd *qc)
897{
898 struct ata_port *ap = qc->ap;
899
900 if (unlikely(qc->flags & ATA_QCFLAG_EH_SCHEDULED))
901 return;
902
903 /* read result TF if failed or requested */
904 if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF)
905 ap->ops->tf_read(ap, &qc->result_tf);
906
907 __ata_qc_complete(qc);
908}
909
910/**
911 * ata_irq_on - Enable interrupts on a port. 886 * ata_irq_on - Enable interrupts on a port.
912 * @ap: Port on which interrupts are enabled. 887 * @ap: Port on which interrupts are enabled.
913 * 888 *