aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-core.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2005-12-13 00:48:31 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-12-13 01:34:45 -0500
commita2a7a662f80d8b7f2295a36de1f9b033ed0b910c (patch)
treea04872ba93c1eff094d2d37a0435e1d965d43f22 /drivers/scsi/libata-core.c
parent575ab52a218e4ff0667a6cbd972c3af443ee8713 (diff)
[PATCH] libata: implement ata_exec_internal()
This patch implements ata_exec_internal() function which performs libata internal command execution. Previously, this was done by each user by manually initializing a qc, issueing it, waiting for its completion and handling errors. In addition to obvious code factoring, using ata_exec_internal() fixes the following bugs. * qc not freed on issue failure * ap->qactive clearing could race with the next internal command * race between timeout handling and irq * ignoring error condition not represented in tf->status Also, qc & hardware are not accessed anymore once it's completed, making internal commands more conformant with general semantics. ata_exec_internal() also makes it easy to issue internal commands from multiple threads if that becomes necessary. This patch only implements ata_exec_internal(). A following patch will convert all users. Signed-off-by: Tejun Heo <htejun@gmail.com> -- Jeff, all patches have been regenerated against upstream branch as of today. (575ab52a218e4ff0667a6cbd972c3af443ee8713) Also, I took out a debug printk from ata_exec_internal (don't know how that one got left there). Other than that, all patches are identical to the previous posting. Thanks. :-) Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r--drivers/scsi/libata-core.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index a0060cf31e0d..de80abeab065 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1046,6 +1046,105 @@ static unsigned int ata_pio_modes(const struct ata_device *adev)
1046 return modes; 1046 return modes;
1047} 1047}
1048 1048
1049struct ata_exec_internal_arg {
1050 unsigned int err_mask;
1051 struct ata_taskfile *tf;
1052 struct completion *waiting;
1053};
1054
1055int ata_qc_complete_internal(struct ata_queued_cmd *qc)
1056{
1057 struct ata_exec_internal_arg *arg = qc->private_data;
1058 struct completion *waiting = arg->waiting;
1059
1060 if (!(qc->err_mask & ~AC_ERR_DEV))
1061 qc->ap->ops->tf_read(qc->ap, arg->tf);
1062 arg->err_mask = qc->err_mask;
1063 arg->waiting = NULL;
1064 complete(waiting);
1065
1066 return 0;
1067}
1068
1069/**
1070 * ata_exec_internal - execute libata internal command
1071 * @ap: Port to which the command is sent
1072 * @dev: Device to which the command is sent
1073 * @tf: Taskfile registers for the command and the result
1074 * @dma_dir: Data tranfer direction of the command
1075 * @buf: Data buffer of the command
1076 * @buflen: Length of data buffer
1077 *
1078 * Executes libata internal command with timeout. @tf contains
1079 * command on entry and result on return. Timeout and error
1080 * conditions are reported via return value. No recovery action
1081 * is taken after a command times out. It's caller's duty to
1082 * clean up after timeout.
1083 *
1084 * LOCKING:
1085 * None. Should be called with kernel context, might sleep.
1086 */
1087
1088static unsigned
1089ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
1090 struct ata_taskfile *tf,
1091 int dma_dir, void *buf, unsigned int buflen)
1092{
1093 u8 command = tf->command;
1094 struct ata_queued_cmd *qc;
1095 DECLARE_COMPLETION(wait);
1096 unsigned long flags;
1097 struct ata_exec_internal_arg arg;
1098
1099 spin_lock_irqsave(&ap->host_set->lock, flags);
1100
1101 qc = ata_qc_new_init(ap, dev);
1102 BUG_ON(qc == NULL);
1103
1104 qc->tf = *tf;
1105 qc->dma_dir = dma_dir;
1106 if (dma_dir != DMA_NONE) {
1107 ata_sg_init_one(qc, buf, buflen);
1108 qc->nsect = buflen / ATA_SECT_SIZE;
1109 }
1110
1111 arg.waiting = &wait;
1112 arg.tf = tf;
1113 qc->private_data = &arg;
1114 qc->complete_fn = ata_qc_complete_internal;
1115
1116 if (ata_qc_issue(qc))
1117 goto issue_fail;
1118
1119 spin_unlock_irqrestore(&ap->host_set->lock, flags);
1120
1121 if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) {
1122 spin_lock_irqsave(&ap->host_set->lock, flags);
1123
1124 /* We're racing with irq here. If we lose, the
1125 * following test prevents us from completing the qc
1126 * again. If completion irq occurs after here but
1127 * before the caller cleans up, it will result in a
1128 * spurious interrupt. We can live with that.
1129 */
1130 if (arg.waiting) {
1131 qc->err_mask = AC_ERR_OTHER;
1132 ata_qc_complete(qc);
1133 printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n",
1134 ap->id, command);
1135 }
1136
1137 spin_unlock_irqrestore(&ap->host_set->lock, flags);
1138 }
1139
1140 return arg.err_mask;
1141
1142 issue_fail:
1143 ata_qc_free(qc);
1144 spin_unlock_irqrestore(&ap->host_set->lock, flags);
1145 return AC_ERR_OTHER;
1146}
1147
1049static int ata_qc_wait_err(struct ata_queued_cmd *qc, 1148static int ata_qc_wait_err(struct ata_queued_cmd *qc,
1050 struct completion *wait) 1149 struct completion *wait)
1051{ 1150{