aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/libata-core.c99
-rw-r--r--include/linux/libata.h2
2 files changed, 101 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{
diff --git a/include/linux/libata.h b/include/linux/libata.h
index e18ce039cdfd..833e57afd54c 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -135,6 +135,8 @@ enum {
135 ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* hueristic */ 135 ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* hueristic */
136 ATA_TMOUT_CDB = 30 * HZ, 136 ATA_TMOUT_CDB = 30 * HZ,
137 ATA_TMOUT_CDB_QUICK = 5 * HZ, 137 ATA_TMOUT_CDB_QUICK = 5 * HZ,
138 ATA_TMOUT_INTERNAL = 30 * HZ,
139 ATA_TMOUT_INTERNAL_QUICK = 5 * HZ,
138 140
139 /* ATA bus states */ 141 /* ATA bus states */
140 BUS_UNKNOWN = 0, 142 BUS_UNKNOWN = 0,