|
@@ -73,7 +73,6 @@ static int fgb(u32 bitmap);
|
|
|
static int ata_choose_xfer_mode(const struct ata_port *ap,
|
|
|
u8 *xfer_mode_out,
|
|
|
unsigned int *xfer_shift_out);
|
|
|
-static void __ata_qc_complete(struct ata_queued_cmd *qc);
|
|
|
static void ata_pio_error(struct ata_port *ap);
|
|
|
|
|
|
static unsigned int ata_unique_id = 1;
|
|
@@ -1074,24 +1073,12 @@ static unsigned int ata_pio_modes(const struct ata_device *adev)
|
|
|
timing API will get this right anyway */
|
|
|
}
|
|
|
|
|
|
-struct ata_exec_internal_arg {
|
|
|
- unsigned int err_mask;
|
|
|
- struct ata_taskfile *tf;
|
|
|
- struct completion *waiting;
|
|
|
-};
|
|
|
-
|
|
|
-int ata_qc_complete_internal(struct ata_queued_cmd *qc)
|
|
|
+void ata_qc_complete_internal(struct ata_queued_cmd *qc)
|
|
|
{
|
|
|
- struct ata_exec_internal_arg *arg = qc->private_data;
|
|
|
- struct completion *waiting = arg->waiting;
|
|
|
+ struct completion *waiting = qc->private_data;
|
|
|
|
|
|
- if (!(qc->err_mask & ~AC_ERR_DEV))
|
|
|
- qc->ap->ops->tf_read(qc->ap, arg->tf);
|
|
|
- arg->err_mask = qc->err_mask;
|
|
|
- arg->waiting = NULL;
|
|
|
+ qc->ap->ops->tf_read(qc->ap, &qc->tf);
|
|
|
complete(waiting);
|
|
|
-
|
|
|
- return 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1122,7 +1109,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
|
|
|
struct ata_queued_cmd *qc;
|
|
|
DECLARE_COMPLETION(wait);
|
|
|
unsigned long flags;
|
|
|
- struct ata_exec_internal_arg arg;
|
|
|
+ unsigned int err_mask;
|
|
|
|
|
|
spin_lock_irqsave(&ap->host_set->lock, flags);
|
|
|
|
|
@@ -1136,9 +1123,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
|
|
|
qc->nsect = buflen / ATA_SECT_SIZE;
|
|
|
}
|
|
|
|
|
|
- arg.waiting = &wait;
|
|
|
- arg.tf = tf;
|
|
|
- qc->private_data = &arg;
|
|
|
+ qc->private_data = &wait;
|
|
|
qc->complete_fn = ata_qc_complete_internal;
|
|
|
|
|
|
if (ata_qc_issue(qc))
|
|
@@ -1155,7 +1140,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
|
|
|
* before the caller cleans up, it will result in a
|
|
|
* spurious interrupt. We can live with that.
|
|
|
*/
|
|
|
- if (arg.waiting) {
|
|
|
+ if (qc->flags & ATA_QCFLAG_ACTIVE) {
|
|
|
qc->err_mask = AC_ERR_OTHER;
|
|
|
ata_qc_complete(qc);
|
|
|
printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n",
|
|
@@ -1165,7 +1150,12 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
|
|
|
spin_unlock_irqrestore(&ap->host_set->lock, flags);
|
|
|
}
|
|
|
|
|
|
- return arg.err_mask;
|
|
|
+ *tf = qc->tf;
|
|
|
+ err_mask = qc->err_mask;
|
|
|
+
|
|
|
+ ata_qc_free(qc);
|
|
|
+
|
|
|
+ return err_mask;
|
|
|
|
|
|
issue_fail:
|
|
|
ata_qc_free(qc);
|
|
@@ -3779,21 +3769,6 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
|
|
|
return qc;
|
|
|
}
|
|
|
|
|
|
-static void __ata_qc_complete(struct ata_queued_cmd *qc)
|
|
|
-{
|
|
|
- struct ata_port *ap = qc->ap;
|
|
|
- unsigned int tag;
|
|
|
-
|
|
|
- qc->flags = 0;
|
|
|
- tag = qc->tag;
|
|
|
- if (likely(ata_tag_valid(tag))) {
|
|
|
- if (tag == ap->active_tag)
|
|
|
- ap->active_tag = ATA_TAG_POISON;
|
|
|
- qc->tag = ATA_TAG_POISON;
|
|
|
- clear_bit(tag, &ap->qactive);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* ata_qc_free - free unused ata_queued_cmd
|
|
|
* @qc: Command to complete
|
|
@@ -3806,9 +3781,19 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
|
|
|
*/
|
|
|
void ata_qc_free(struct ata_queued_cmd *qc)
|
|
|
{
|
|
|
+ struct ata_port *ap = qc->ap;
|
|
|
+ unsigned int tag;
|
|
|
+
|
|
|
assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */
|
|
|
|
|
|
- __ata_qc_complete(qc);
|
|
|
+ qc->flags = 0;
|
|
|
+ tag = qc->tag;
|
|
|
+ if (likely(ata_tag_valid(tag))) {
|
|
|
+ if (tag == ap->active_tag)
|
|
|
+ ap->active_tag = ATA_TAG_POISON;
|
|
|
+ qc->tag = ATA_TAG_POISON;
|
|
|
+ clear_bit(tag, &ap->qactive);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -3825,8 +3810,6 @@ void ata_qc_free(struct ata_queued_cmd *qc)
|
|
|
|
|
|
void ata_qc_complete(struct ata_queued_cmd *qc)
|
|
|
{
|
|
|
- int rc;
|
|
|
-
|
|
|
assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */
|
|
|
assert(qc->flags & ATA_QCFLAG_ACTIVE);
|
|
|
|
|
@@ -3840,17 +3823,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
|
|
|
qc->flags &= ~ATA_QCFLAG_ACTIVE;
|
|
|
|
|
|
/* call completion callback */
|
|
|
- rc = qc->complete_fn(qc);
|
|
|
-
|
|
|
- /* if callback indicates not to complete command (non-zero),
|
|
|
- * return immediately
|
|
|
- */
|
|
|
- if (rc != 0)
|
|
|
- return;
|
|
|
-
|
|
|
- __ata_qc_complete(qc);
|
|
|
-
|
|
|
- VPRINTK("EXIT\n");
|
|
|
+ qc->complete_fn(qc);
|
|
|
}
|
|
|
|
|
|
static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
|