Esempio n. 1
0
void
ida_intr(void *data)
{
	struct ida_softc *ida;
	struct ida_qcb *qcb;
	bus_addr_t completed;

	ida = (struct ida_softc *)data;

	mtx_lock(&ida->lock);
	if (ida->cmd.int_pending(ida) == 0) {
		mtx_unlock(&ida->lock);
		return;				/* not our interrupt */
	}

	while ((completed = ida->cmd.done(ida)) != 0) {
		qcb = idahwqcbptov(ida, completed & ~3);

		if (qcb == NULL || qcb->state != QCB_ACTIVE) {
			device_printf(ida->dev,
			    "ignoring completion %jx\n", (intmax_t)completed);
			continue;
		}
		/* Handle "Bad Command List" errors. */
		if ((completed & 3) && (qcb->hwqcb->req.error == 0))
			qcb->hwqcb->req.error = CMD_REJECTED;
		ida_done(ida, qcb);
	}
	ida_startio(ida);
	mtx_unlock(&ida->lock);
}
Esempio n. 2
0
static int
ida_wait(struct ida_softc *ida, struct ida_qcb *qcb)
{
	struct ida_qcb *qcb_done = NULL;
	bus_addr_t completed;
	int delay;

	if (ida->flags & IDA_INTERRUPTS) {
		if (tsleep((caddr_t)qcb, 0, "idacmd", 5 * hz))
			return (ETIMEDOUT);
		return (0);
	}

again:
	delay = 5 * 1000 * 100;			/* 5 sec delay */
	while ((completed = ida->cmd.done(ida)) == 0) {
		if (delay-- == 0)
			return (ETIMEDOUT);
		DELAY(10);
	}

	qcb_done = idahwqcbptov(ida, completed & ~3);
	if (qcb_done != qcb)
		goto again;
	ida_done(ida, qcb);
	return (0);
}
Esempio n. 3
0
static int
ida_wait(struct ida_softc *ida, struct ida_qcb *qcb)
{
	struct ida_qcb *qcb_done = NULL;
	bus_addr_t completed;
	int delay;

	if (!dumping)
		mtx_assert(&ida->lock, MA_OWNED);
	if (ida->flags & IDA_INTERRUPTS) {
		if (mtx_sleep(qcb, &ida->lock, PRIBIO, "idacmd", 5 * hz)) {
			qcb->state = QCB_TIMEDOUT;
			return (ETIMEDOUT);
		}
		return (0);
	}

again:
	delay = 5 * 1000 * 100;			/* 5 sec delay */
	while ((completed = ida->cmd.done(ida)) == 0) {
		if (delay-- == 0) {
			qcb->state = QCB_TIMEDOUT;
			return (ETIMEDOUT);
		}
		DELAY(10);
	}

	qcb_done = idahwqcbptov(ida, completed & ~3);
	if (qcb_done != qcb)
		goto again;
	ida_done(ida, qcb);
	return (0);
}
Esempio n. 4
0
void
ida_intr(void *data)
{
	struct ida_softc *ida;
	struct ida_qcb *qcb;
	bus_addr_t completed;

	ida = (struct ida_softc *)data;

	if (ida->cmd.int_pending(ida) == 0)
		return;				/* not our interrupt */

	while ((completed = ida->cmd.done(ida)) != 0) {
		qcb = idahwqcbptov(ida, completed & ~3);

		if (qcb == NULL || qcb->state != QCB_ACTIVE) {
			device_printf(ida->dev,
			    "ignoring completion %jx\n", (uintmax_t)completed);
			continue;
		}
		ida_done(ida, qcb);
	}
	ida_start(ida);
}