Ejemplo n.º 1
0
int
ida_command(struct ida_softc *ida, int command, void *data, int datasize,
	int drive, u_int64_t pblkno, int flags)
{
	struct ida_hardware_qcb *hwqcb;
	struct ida_qcb *qcb;
	bus_dmasync_op_t op;
	int error;

	crit_enter();
	qcb = ida_get_qcb(ida);
	crit_exit();

	if (qcb == NULL) {
		kprintf("ida_command: out of QCBs");
		return (EAGAIN);
	}

	hwqcb = qcb->hwqcb;
	bzero(hwqcb, sizeof(struct ida_hdr) + sizeof(struct ida_req));

	bus_dmamap_load(ida->buffer_dmat, qcb->dmamap,
	    data, datasize, ida_setup_dmamap, hwqcb, 0);
	op = qcb->flags & DMA_DATA_IN ?
	    BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE;
	bus_dmamap_sync(ida->buffer_dmat, qcb->dmamap, op);

	hwqcb->hdr.drive = drive;
	hwqcb->req.blkno = pblkno;
	hwqcb->req.bcount = howmany(datasize, DEV_BSIZE);
	hwqcb->req.command = command;

	KKASSERT(pblkno < 0x100000000ULL);

	qcb->flags = flags | IDA_COMMAND;

	crit_enter();
	STAILQ_INSERT_TAIL(&ida->qcb_queue, qcb, link.stqe);
	ida_start(ida);
	error = ida_wait(ida, qcb);
	crit_exit();

	/* XXX should have status returned here? */
	/* XXX have "status pointer" area in QCB? */

	return (error);
}
Ejemplo n.º 2
0
int
ida_command(struct ida_softc *ida, int command, void *data, int datasize,
	int drive, u_int32_t pblkno, int flags)
{
	struct ida_hardware_qcb *hwqcb;
	struct ida_qcb *qcb;
	int error;

	if (!dumping)
		mtx_assert(&ida->lock, MA_OWNED);
	qcb = ida_get_qcb(ida);

	if (qcb == NULL) {
		device_printf(ida->dev, "out of QCBs\n");
		return (EAGAIN);
	}

	qcb->flags = flags | IDA_COMMAND;
	hwqcb = qcb->hwqcb;
	hwqcb->hdr.drive = drive;
	hwqcb->req.blkno = htole32(pblkno);
	hwqcb->req.bcount = htole16(howmany(datasize, DEV_BSIZE));
	hwqcb->req.command = command;

	error = ida_map_qcb(ida, qcb, data, datasize);
	if (error == 0) {
		error = ida_wait(ida, qcb);
		/* Don't free QCB on a timeout in case it later completes. */
		if (error)
			return (error);
		error = qcb->error;
	}

	/* XXX should have status returned here? */
	/* XXX have "status pointer" area in QCB? */

	ida_free_qcb(ida, qcb);
	return (error);
}