示例#1
0
/*
 * ppb_poll_bus()
 *
 * Polls the bus
 *
 * max is a delay in 10-milliseconds
 */
int
ppb_poll_bus(device_t bus, int max,
	     char mask, char status, int how)
{
	struct ppb_data *ppb = DEVTOSOFTC(bus);
	int i, j, error;
	char r;

	ppb_assert_locked(bus);

	/* try at least up to 10ms */
	for (j = 0; j < ((how & PPB_POLL) ? max : 1); j++) {
		for (i = 0; i < 10000; i++) {
			r = ppb_rstr(bus);
			DELAY(1);
			if ((r & mask) == status)
				return (0);
		}
	}

	if (!(how & PPB_POLL)) {
	   for (i = 0; max == PPB_FOREVER || i < max-1; i++) {
		if ((ppb_rstr(bus) & mask) == status)
			return (0);

		/* wait 10 ms */
		error = mtx_sleep((caddr_t)bus, ppb->ppc_lock, PPBPRI |
		    (how == PPB_NOINTR ? 0 : PCATCH), "ppbpoll", hz/100);
		if (error != EWOULDBLOCK)
			return (error);
	   }
	}

	return (EWOULDBLOCK);
}
示例#2
0
static int
lpbb_detect(device_t dev)
{
	device_t ppbus = device_get_parent(dev);

	ppb_lock(ppbus);
	if (ppb_request_bus(ppbus, dev, PPB_DONTWAIT)) {
		ppb_unlock(ppbus);
		device_printf(dev, "can't allocate ppbus\n");
		return (0);
	}

	lpbb_reset_bus(dev);

	if ((ppb_rstr(ppbus) & I2CKEY) ||
		((ppb_rstr(ppbus) & ALIM) != ALIM)) {
		ppb_release_bus(ppbus, dev);
		ppb_unlock(ppbus);
		return (0);
	}

	ppb_release_bus(ppbus, dev);
	ppb_unlock(ppbus);

	return (1);
}
示例#3
0
/*
 * byte_peripheral_outbyte()
 *
 * Write 1 byte in BYTE mode
 */
static int
byte_peripheral_outbyte(device_t bus, char *buffer, int last)
{
	int error = 0;

	/* Event 7 */
	if ((error = do_1284_wait(bus, nBUSY, nBUSY))) {
		ppb_1284_set_error(bus, PPB_TIMEOUT, 7);
		goto error;
	}

	/* check termination */
	if (!(ppb_rstr(bus) & SELECT)) {
		ppb_peripheral_terminate(bus, PPB_WAIT);
		goto error;
	}

	/* Event 15 - put byte on data lines */
#ifdef DEBUG_1284
	printf("B");
#endif
	ppb_wdtr(bus, *buffer);

	/* Event 9 */
	ppb_wctr(bus, (AUTOFEED | STROBE) & ~(nINIT | SELECTIN));

	/* Event 10 - wait data read */
	if ((error = do_peripheral_wait(bus, nBUSY, 0))) {
		ppb_1284_set_error(bus, PPB_TIMEOUT, 16);
		goto error;
	}

	/* Event 11 */
	if (!last) {
		ppb_wctr(bus, (AUTOFEED) & ~(nINIT | STROBE | SELECTIN));
	} else {
		ppb_wctr(bus, (nINIT) & ~(STROBE | SELECTIN | AUTOFEED));
	}

#if 0
	/* Event 16 - wait strobe */
	if ((error = do_peripheral_wait(bus, nACK | nBUSY, 0))) {
		ppb_1284_set_error(bus, PPB_TIMEOUT, 16);
		goto error;
	}
#endif

	/* check termination */
	if (!(ppb_rstr(bus) & SELECT)) {
		ppb_peripheral_terminate(bus, PPB_WAIT);
		goto error;
	}

error:
	return (error);
}
示例#4
0
/*
 * vpoio_wait()
 *
 * H_SELIN must be low.
 *
 * XXX should be ported to microseq
 */
static char
vpoio_wait(struct vpoio_data *vpo, int tmo)
{
	DECLARE_WAIT_MICROSEQUENCE;

	device_t ppbus = device_get_parent(vpo->vpo_dev);
	int ret, err;

#if 0	/* broken */
	if (ppb_poll_device(ppbus, 150, nBUSY, nBUSY, PPB_INTR))
		return (0);

	return (ppb_rstr(ppbus) & 0xf0);
#endif

	/*
	 * Return some status information.
	 * Semantics :	0xc0 = ZIP wants more data
	 *		0xd0 = ZIP wants to send more data
	 *		0xe0 = ZIP wants command
	 *		0xf0 = end of transfer, ZIP is sending status
	 */

	ppb_MS_init_msq(wait_microseq, 2,
			WAIT_RET, (void *)&ret,
			WAIT_TMO, tmo);

	ppb_MS_microseq(ppbus, vpo->vpo_dev, wait_microseq, &err);

	if (err)
		return (0);	 /* command timed out */

	return(ret);
}
示例#5
0
static int
lpbb_getsda(device_t dev)
{
	device_t ppbus = device_get_parent(dev);
	int rval;

	ppb_lock(ppbus);
	rval = ((ppb_rstr(ppbus) & SDA_in) == SDA_in);
	ppb_unlock(ppbus);
	return (rval);
}
示例#6
0
static int
ppb_1284_set_error(struct ppb_device *dev, int error, int event)
{
	/* do not accumulate errors */
	if ((dev->ppb->error == PPB_NO_ERROR) &&
			(dev->ppb->state != PPB_ERROR)) {
		dev->ppb->error = error;
		dev->ppb->state = PPB_ERROR;
	}

#ifdef DEBUG_1284
	printf("ppb1284: error=%d status=0x%x event=%d\n", error,
		ppb_rstr(dev) & 0xff, event);
#endif

	return (0);
}
示例#7
0
/*
 * ppb_get_status()
 *
 * Read the status register and update the status info
 */
int
ppb_get_status(device_t bus, struct ppb_status *status)
{
	register char r;

	ppb_assert_locked(bus);

	r = status->status = ppb_rstr(bus);

	status->timeout	= r & TIMEOUT;
	status->error	= !(r & nFAULT);
	status->select	= r & SELECT;
	status->paper_end = r & PERROR;
	status->ack	= !(r & nACK);
	status->busy	= !(r & nBUSY);

	return (0);
}
示例#8
0
static int
ppb_1284_set_error(device_t bus, int error, int event)
{
	struct ppb_data *ppb = DEVTOSOFTC(bus);

	/* do not accumulate errors */
	if ((ppb->error == PPB_NO_ERROR) &&
			(ppb->state != PPB_ERROR)) {
		ppb->error = error;
		ppb->state = PPB_ERROR;
	}

#ifdef DEBUG_1284
	printf("ppb1284: error=%d status=0x%x event=%d\n", error,
		ppb_rstr(bus) & 0xff, event);
#endif

	return (0);
}
/*
 * ppb_get_status()
 *
 * Read the status register and update the status info
 */
int
ppb_get_status(device_t bus, struct ppb_status *status)
{
#ifdef INVARIANTS
	struct ppb_data *ppb = DEVTOSOFTC(bus);
#endif
	register char r;

	mtx_assert(ppb->ppc_lock, MA_OWNED);

	r = status->status = ppb_rstr(bus);

	status->timeout	= r & TIMEOUT;
	status->error	= !(r & nFAULT);
	status->select	= r & SELECT;
	status->paper_end = r & PERROR;
	status->ack	= !(r & nACK);
	status->busy	= !(r & nBUSY);

	return (0);
}
示例#10
0
/*
 * nibble_1284_inbyte()
 *
 * Read 1 byte in NIBBLE mode
 */
int
nibble_1284_inbyte(device_t bus, char *buffer)
{
	char nibble[2];
	int i, error;

	for (i = 0; i < 2; i++) {

		/* Event 7 - ready to take data (nAUTO low) */
		ppb_wctr(bus, (nINIT | AUTOFEED) & ~(STROBE | SELECTIN));

		/* Event 8 - peripheral writes the first nibble */

		/* Event 9 - peripheral set nAck low */
		if ((error = do_1284_wait(bus, nACK, 0))) {
			ppb_1284_set_error(bus, PPB_TIMEOUT, 9);
			goto error;
		}

		/* read nibble */
		nibble[i] = ppb_rstr(bus);

		/* Event 10 - ack, nibble received */
		ppb_wctr(bus, nINIT & ~(AUTOFEED | STROBE | SELECTIN));

		/* Event 11 - wait ack from peripherial */
		if ((error = do_1284_wait(bus, nACK, nACK))) {
			ppb_1284_set_error(bus, PPB_TIMEOUT, 11);
			goto error;
		}
	}

	*buffer = ((nibble2char(nibble[1]) << 4) & 0xf0) |
				(nibble2char(nibble[0]) & 0x0f);

error:
	return (error);
}
示例#11
0
/*
 * spp_1284_read()
 *
 * Read in IEEE1284 NIBBLE/BYTE mode
 */
int
spp_1284_read(device_t bus, int mode, char *buffer, int max, int *read)
{
	int error = 0, len = 0;
	int terminate_after_transfer = 1;
	int state;

	*read = len = 0;

	state = ppb_1284_get_state(bus);

	switch (state) {
	case PPB_FORWARD_IDLE:
		if ((error = ppb_1284_negociate(bus, mode, 0)))
			return (error);
		break;

	case PPB_REVERSE_IDLE:
		terminate_after_transfer = 0;
		break;

	default:
		ppb_1284_terminate(bus);
		if ((error = ppb_1284_negociate(bus, mode, 0)))
			return (error);
		break;
	}

	while ((len < max) && !(ppb_rstr(bus) & (nFAULT))) {

		ppb_1284_set_state(bus, PPB_REVERSE_TRANSFER);

#ifdef DEBUG_1284
		printf("B");
#endif

		switch (mode) {
		case PPB_NIBBLE:
			/* read a byte, error means no more data */
			if (nibble_1284_inbyte(bus, buffer+len))
				goto end_while;
			break;
		case PPB_BYTE:
			if (byte_1284_inbyte(bus, buffer+len))
				goto end_while;
			break;
		default:
			error = EINVAL;
			goto end_while;
		}
		len ++;
	}
end_while:

	if (!error)
		ppb_1284_set_state(bus, PPB_REVERSE_IDLE);

	*read = len;

	if (terminate_after_transfer || error)
		ppb_1284_terminate(bus);

	return (error);
}
示例#12
0
/*
 * ppb_peripheral_negociate()
 *
 * Negociate the peripheral side
 */
int
ppb_peripheral_negociate(device_t bus, int mode, int options)
{
	int spin, request_mode, error = 0;
	char r;

	ppb_set_mode(bus, PPB_COMPATIBLE);
	ppb_1284_set_state(bus, PPB_PERIPHERAL_NEGOCIATION);

	/* compute ext. value */
	request_mode = ppb_request_mode(mode, options);

	/* wait host */
	spin = 10;
	while (spin-- && (ppb_rstr(bus) & nBUSY))
		DELAY(1);

	/* check termination */
	if (!(ppb_rstr(bus) & SELECT) || !spin) {
		error = ENODEV;
		goto error;
	}

	/* Event 4 - read ext. value */
	r = ppb_rdtr(bus);

	/* nibble mode is not supported */
	if ((r == (char)request_mode) ||
			(r == NIBBLE_1284_NORMAL)) {

		/* Event 5 - restore direction bit, no data avail */
		ppb_wctr(bus, (STROBE | nINIT) & ~(SELECTIN));
		DELAY(1);

		/* Event 6 */
		ppb_wctr(bus, (nINIT) & ~(SELECTIN | STROBE));

		if (r == NIBBLE_1284_NORMAL) {
#ifdef DEBUG_1284
			printf("R");
#endif
			ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 4);
			error = EINVAL;
			goto error;
		} else {
			ppb_1284_set_state(bus, PPB_PERIPHERAL_IDLE);
			switch (r) {
			case BYTE_1284_NORMAL:
				ppb_set_mode(bus, PPB_BYTE);
				break;
			default:
				break;
			}
#ifdef DEBUG_1284
			printf("A");
#endif
			/* negociation succeeds */
		}
	} else {
		/* Event 5 - mode not supported */
		ppb_wctr(bus, SELECTIN);
		DELAY(1);

		/* Event 6 */
		ppb_wctr(bus, (SELECTIN) & ~(STROBE | nINIT));
		ppb_1284_set_error(bus, PPB_MODE_UNSUPPORTED, 4);

#ifdef DEBUG_1284
		printf("r");
#endif
		error = EINVAL;
		goto error;
	}

	return (0);

error:
	ppb_peripheral_terminate(bus, PPB_WAIT);
	return (error);
}