Merge branch 'tmp'

This commit is contained in:
Jeff Garzik 2006-01-27 02:29:20 -05:00
commit 628e386e27
3 changed files with 32 additions and 59 deletions

View File

@ -73,7 +73,6 @@ static int fgb(u32 bitmap);
static int ata_choose_xfer_mode(const struct ata_port *ap, static int ata_choose_xfer_mode(const struct ata_port *ap,
u8 *xfer_mode_out, u8 *xfer_mode_out,
unsigned int *xfer_shift_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 void ata_pio_error(struct ata_port *ap);
static unsigned int ata_unique_id = 1; 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 */ timing API will get this right anyway */
} }
struct ata_exec_internal_arg { void ata_qc_complete_internal(struct ata_queued_cmd *qc)
unsigned int err_mask;
struct ata_taskfile *tf;
struct completion *waiting;
};
int ata_qc_complete_internal(struct ata_queued_cmd *qc)
{ {
struct ata_exec_internal_arg *arg = qc->private_data; struct completion *waiting = qc->private_data;
struct completion *waiting = arg->waiting;
if (!(qc->err_mask & ~AC_ERR_DEV)) qc->ap->ops->tf_read(qc->ap, &qc->tf);
qc->ap->ops->tf_read(qc->ap, arg->tf);
arg->err_mask = qc->err_mask;
arg->waiting = NULL;
complete(waiting); complete(waiting);
return 0;
} }
/** /**
@ -1122,7 +1109,7 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
struct ata_queued_cmd *qc; struct ata_queued_cmd *qc;
DECLARE_COMPLETION(wait); DECLARE_COMPLETION(wait);
unsigned long flags; unsigned long flags;
struct ata_exec_internal_arg arg; unsigned int err_mask;
spin_lock_irqsave(&ap->host_set->lock, flags); 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; qc->nsect = buflen / ATA_SECT_SIZE;
} }
arg.waiting = &wait; qc->private_data = &wait;
arg.tf = tf;
qc->private_data = &arg;
qc->complete_fn = ata_qc_complete_internal; qc->complete_fn = ata_qc_complete_internal;
if (ata_qc_issue(qc)) 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 * before the caller cleans up, it will result in a
* spurious interrupt. We can live with that. * spurious interrupt. We can live with that.
*/ */
if (arg.waiting) { if (qc->flags & ATA_QCFLAG_ACTIVE) {
qc->err_mask = AC_ERR_OTHER; qc->err_mask = AC_ERR_OTHER;
ata_qc_complete(qc); ata_qc_complete(qc);
printk(KERN_WARNING "ata%u: qc timeout (cmd 0x%x)\n", 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); 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: issue_fail:
ata_qc_free(qc); ata_qc_free(qc);
@ -3779,21 +3769,6 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
return qc; 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 * ata_qc_free - free unused ata_queued_cmd
* @qc: Command to complete * @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) 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 */ 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) void ata_qc_complete(struct ata_queued_cmd *qc)
{ {
int rc;
assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */ assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */
assert(qc->flags & ATA_QCFLAG_ACTIVE); assert(qc->flags & ATA_QCFLAG_ACTIVE);
@ -3840,17 +3823,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
qc->flags &= ~ATA_QCFLAG_ACTIVE; qc->flags &= ~ATA_QCFLAG_ACTIVE;
/* call completion callback */ /* call completion callback */
rc = qc->complete_fn(qc); 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");
} }
static inline int ata_should_dma_map(struct ata_queued_cmd *qc) static inline int ata_should_dma_map(struct ata_queued_cmd *qc)

View File

@ -1219,7 +1219,7 @@ nothing_to_do:
return 1; return 1;
} }
static int ata_scsi_qc_complete(struct ata_queued_cmd *qc) static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
{ {
struct scsi_cmnd *cmd = qc->scsicmd; struct scsi_cmnd *cmd = qc->scsicmd;
u8 *cdb = cmd->cmnd; u8 *cdb = cmd->cmnd;
@ -1256,7 +1256,7 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc)
qc->scsidone(cmd); qc->scsidone(cmd);
return 0; ata_qc_free(qc);
} }
/** /**
@ -1982,7 +1982,7 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8
done(cmd); done(cmd);
} }
static int atapi_sense_complete(struct ata_queued_cmd *qc) static void atapi_sense_complete(struct ata_queued_cmd *qc)
{ {
if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0)) if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0))
/* FIXME: not quite right; we don't want the /* FIXME: not quite right; we don't want the
@ -1993,7 +1993,7 @@ static int atapi_sense_complete(struct ata_queued_cmd *qc)
ata_gen_ata_desc_sense(qc); ata_gen_ata_desc_sense(qc);
qc->scsidone(qc->scsicmd); qc->scsidone(qc->scsicmd);
return 0; ata_qc_free(qc);
} }
/* is it pointless to prefer PIO for "safety reasons"? */ /* is it pointless to prefer PIO for "safety reasons"? */
@ -2050,7 +2050,7 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
DPRINTK("EXIT\n"); DPRINTK("EXIT\n");
} }
static int atapi_qc_complete(struct ata_queued_cmd *qc) static void atapi_qc_complete(struct ata_queued_cmd *qc)
{ {
struct scsi_cmnd *cmd = qc->scsicmd; struct scsi_cmnd *cmd = qc->scsicmd;
unsigned int err_mask = qc->err_mask; unsigned int err_mask = qc->err_mask;
@ -2060,7 +2060,7 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc)
if (unlikely(err_mask & AC_ERR_DEV)) { if (unlikely(err_mask & AC_ERR_DEV)) {
cmd->result = SAM_STAT_CHECK_CONDITION; cmd->result = SAM_STAT_CHECK_CONDITION;
atapi_request_sense(qc); atapi_request_sense(qc);
return 1; return;
} }
else if (unlikely(err_mask)) else if (unlikely(err_mask))
@ -2100,7 +2100,7 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc)
} }
qc->scsidone(cmd); qc->scsidone(cmd);
return 0; ata_qc_free(qc);
} }
/** /**
* atapi_xlat - Initialize PACKET taskfile * atapi_xlat - Initialize PACKET taskfile

View File

@ -240,7 +240,7 @@ struct ata_port;
struct ata_queued_cmd; struct ata_queued_cmd;
/* typedefs */ /* typedefs */
typedef int (*ata_qc_cb_t) (struct ata_queued_cmd *qc); typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc);
struct ata_ioports { struct ata_ioports {
unsigned long cmd_addr; unsigned long cmd_addr;