Add a callout to dump card status on command queue timeouts.
This commit is contained in:
parent
fc601c53dc
commit
84339b16c1
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user