Add a callout to dump card status on command queue timeouts.

This commit is contained in:
Matthew N. Dodd 2004-12-14 17:45:30 +00:00
parent fc601c53dc
commit 84339b16c1
2 changed files with 48 additions and 1 deletions

View File

@ -63,6 +63,7 @@ static void ida_construct_qcb(struct ida_softc *ida);
static void ida_start(struct ida_softc *ida);
static void ida_done(struct ida_softc *ida, struct ida_qcb *qcb);
static int ida_wait(struct ida_softc *ida, struct ida_qcb *qcb);
static void ida_timeout (void *arg);
static d_ioctl_t ida_ioctl;
static struct cdevsw ida_cdevsw = {
@ -77,6 +78,8 @@ ida_free(struct ida_softc *ida)
{
int i;
callout_stop(&ida->ch);
for (i = 0; i < ida->num_qcbs; i++)
bus_dmamap_destroy(ida->buffer_dmat, ida->qcbs[i].dmamap);
@ -260,6 +263,8 @@ ida_init(struct ida_softc *ida)
ida_alloc_qcb(ida); /* allocate an initial qcb */
callout_init(&ida->ch, CALLOUT_MPSAFE);
return (0);
}
@ -459,8 +464,14 @@ ida_start(struct ida_softc *ida)
STAILQ_REMOVE_HEAD(&ida->qcb_queue, link.stqe);
/*
* XXX
* place the qcb on an active list and set a timeout?
* place the qcb on an active list?
*/
/* Set a timeout. */
if (!ida->qactive)
callout_reset(&ida->ch, hz * 5, ida_timeout, ida);
ida->qactive++;
qcb->state = QCB_ACTIVE;
ida->cmd.submit(ida, qcb);
}
@ -573,12 +584,44 @@ ida_done(struct ida_softc *ida, struct ida_qcb *qcb)
idad_intr(qcb->buf);
}
ida->qactive--;
/* Reschedule or cancel timeout */
if (ida->qactive)
callout_reset(&ida->ch, hz * 5, ida_timeout, ida);
else
callout_stop(&ida->ch);
qcb->state = QCB_FREE;
qcb->buf = NULL;
SLIST_INSERT_HEAD(&ida->free_qcbs, qcb, link.sle);
ida_construct_qcb(ida);
}
static void
ida_timeout (void *arg)
{
struct ida_softc *ida;
ida = (struct ida_softc *)arg;
device_printf(ida->dev, "%s() qactive %d\n", __func__, ida->qactive);
if (ida->flags & IDA_INTERRUPTS)
device_printf(ida->dev, "IDA_INTERRUPTS\n");
device_printf(ida->dev, "\t R_CMD_FIFO: %08x\n"
"\t R_DONE_FIFO: %08x\n"
"\t R_INT_MASK: %08x\n"
"\t R_STATUS: %08x\n"
"\tR_INT_PENDING: %08x\n",
ida_inl(ida, R_CMD_FIFO),
ida_inl(ida, R_DONE_FIFO),
ida_inl(ida, R_INT_MASK),
ida_inl(ida, R_STATUS),
ida_inl(ida, R_INT_PENDING));
return;
}
/*
* IOCTL stuff follows.
*/

View File

@ -126,6 +126,8 @@ struct ida_access {
struct ida_softc {
device_t dev;
int unit;
struct callout ch;
struct cdev *ida_dev_t;
int regs_res_type;
@ -153,6 +155,8 @@ struct ida_softc {
int num_qcbs;
int flags;
int qactive;
struct ida_hardware_qcb *hwqcbs; /* HW QCB array */
struct ida_qcb *qcbs; /* kernel QCB array */
SLIST_HEAD(, ida_qcb) free_qcbs;