Beispiel #1
0
/*
 * ppb_MS_init()
 *
 * Initialize device dependent submicrosequence of the current mode
 *
 */
int
ppb_MS_init(device_t bus, device_t dev, struct ppb_microseq *loop, int opcode)
{
    struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev);
    struct ppb_xfer *xfer = mode2xfer(bus, ppbdev, opcode);

    xfer->loop = loop;

    return (0);
}
Beispiel #2
0
/*
 * ppb_MS_init()
 *
 * Initialize device dependent submicrosequence of the current mode
 *
 */
int
ppb_MS_init(device_t bus, device_t dev, struct ppb_microseq *loop, int opcode)
{
#ifdef INVARIANTS
	struct ppb_data *ppb = device_get_softc(bus);
#endif
	struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev);
	struct ppb_xfer *xfer = mode2xfer(bus, ppbdev, opcode);

	mtx_assert(ppb->ppc_lock, MA_OWNED);
	xfer->loop = loop;

	return (0);
}
Beispiel #3
0
/*
 * ppb_MS_microseq()
 *
 * Interprete a microsequence. Some microinstructions are executed at adapter
 * level to avoid function call overhead between ppbus and the adapter
 */
int
ppb_MS_microseq(device_t bus, device_t dev, struct ppb_microseq *msq, int *ret)
{
    struct ppb_data *ppb = (struct ppb_data *)device_get_softc(bus);
    struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev);

    struct ppb_microseq *mi;		/* current microinstruction */
    int error;

    struct ppb_xfer *xfer;

    /* microsequence executed to initialize the transfer */
    struct ppb_microseq initxfer[] = {
        MS_PTR(MS_UNKNOWN), 	/* set ptr to buffer */
        MS_SET(MS_UNKNOWN),	/* set transfer size */
        MS_RET(0)
    };

    if (ppb->ppb_owner != dev)
        return (EACCES);

#define INCR_PC (mi ++)

    mi = msq;
    for (;;) {
        switch (mi->opcode) {
        case MS_OP_PUT:
        case MS_OP_GET:

            /* attempt to choose the best mode for the device */
            xfer = mode2xfer(bus, ppbdev, mi->opcode);

            /* figure out if we should use ieee1284 code */
            if (!xfer->loop) {
                if (mi->opcode == MS_OP_PUT) {
                    if ((error = PPBUS_WRITE(
                                     device_get_parent(bus),
                                     (char *)mi->arg[0].p,
                                     mi->arg[1].i, 0)))
                        goto error;

                    INCR_PC;
                    goto next;
                } else
                    panic("%s: IEEE1284 read not supported", __func__);
            }

            /* XXX should use ppb_MS_init_msq() */
            initxfer[0].arg[0].p = mi->arg[0].p;
            initxfer[1].arg[0].i = mi->arg[1].i;

            /* initialize transfer */
            ppb_MS_microseq(bus, dev, initxfer, &error);

            if (error)
                goto error;

            /* the xfer microsequence should not contain any
             * MS_OP_PUT or MS_OP_GET!
             */
            ppb_MS_microseq(bus, dev, xfer->loop, &error);

            if (error)
                goto error;

            INCR_PC;
            break;

        case MS_OP_RET:
            if (ret)
                *ret = mi->arg[0].i;	/* return code */
            return (0);
            break;

        default:
            /* executing microinstructions at ppc level is
             * faster. This is the default if the microinstr
             * is unknown here
             */
            if ((error = PPBUS_EXEC_MICROSEQ(
                             device_get_parent(bus), &mi)))
                goto error;
            break;
        }
next:
        continue;
    }
error:
    return (error);
}