コード例 #1
0
ファイル: usb.c プロジェクト: helaibai/usbip
static void
in_complete (io_context_t ctx, struct iocb *iocb, long res, long res2)
{
	int	status;

	if (verbose > 2)
		fprintf(stderr, "%s uiocb %p status %ld %ld\n",
				__FUNCTION__, iocb,
				res, res2);

	/* fail on short write _OR_ fault */
	if (res != iocb->u.c.nbytes || res2 != 0)
		goto fail;

	/* get data we'll write to the host */
	iocb->u.c.nbytes = fill_in_buf (iocb->u.c.buf, iosize);
	if (iocb->u.c.nbytes < 0) {
		fprintf (stderr, "%s %p refill fail, %d (%s)\n",
			__FUNCTION__, iocb,
			errno, strerror (errno));
		goto clean;
	}

	/* resubmit */
	status = io_submit (ctx, 1, &iocb);
	if (status == 1)
		return;
	fprintf (stderr, "%s %p resubmit fail, %d (%s)\n",
		__FUNCTION__, iocb,
		errno, strerror (errno));
	goto clean;

fail:
	if (res < 0)
		errno = -res;
	else if (res2 < 0)
		errno = -res2;
	fprintf (stderr, "%s %p fail %ld/%ld, %d (%s)\n",
		__FUNCTION__, iocb,
		res, iocb->u.c.nbytes,
		errno, strerror (errno));
clean:
	aio_in_pending--;
	return;
}
コード例 #2
0
ファイル: usb.c プロジェクト: helaibai/usbip
static void *simple_source_thread (void *param)
{
	char		*name = (char *) param;
	int		status;
	char		buf [USB_BUFSIZE];

	status = source_open (name);
	if (status < 0)
		return 0;
	source_fd = status;

	pthread_cleanup_push (close_fd, &source_fd);
	do {
		unsigned long	len;

		/* original LinuxThreads cancelation didn't work right
		 * so test for it explicitly.
		 */
		pthread_testcancel ();

		len = fill_in_buf (buf, sizeof buf);
		if (len > 0)
			status = write (source_fd, buf, len);
		else
			status = 0;

	} while (status > 0);
	if (status == 0) {
		if (verbose)
			fprintf (stderr, "done %s\n", __FUNCTION__);
	} else if (verbose > 2 || errno != ESHUTDOWN) /* normal disconnect */
		perror ("write");
	fflush (stdout);
	fflush (stderr);
	pthread_cleanup_pop (1);

	return 0;
}
コード例 #3
0
ファイル: usb.c プロジェクト: helaibai/usbip
static void *aio_in_thread (void *param)
{
	char		*name = (char *) param;
	int		status;
	io_context_t	ctx = 0;
	struct iocb	*queue, *iocb;
	unsigned	i;

	status = source_open (name);
	if (status < 0)
		return 0;
	source_fd = status;
	pthread_cleanup_push (close_fd, &source_fd);

	/* initialize i/o queue */
	status = io_setup (aio_in, &ctx);
	if (status < 0) {
		perror ("aio_in_thread, io_setup");
		return 0;
	}
	pthread_cleanup_push (queue_release, &ctx);

	if (aio_in == 0)
		aio_in = 1;
	queue = alloca (aio_in * sizeof *iocb);

	/* populate and (re)run the queue */
	for (i = 0, iocb = queue; i < aio_in; i++, iocb++) {
		char *buf = malloc (iosize);

		if (!buf) {
			fprintf(stderr, "%s can't get buffer[%d]\n",
				__FUNCTION__, i);
			return 0;
		}

		/* host receives the data we're writing */
		io_prep_pwrite (iocb, source_fd,
			buf, fill_in_buf (buf, iosize),
			0);
		io_set_callback (iocb, in_complete);
		iocb->key = USB_DIR_IN;

		status = io_submit (ctx, 1, &iocb);
		if (status < 0) {
			perror (__FUNCTION__);
			break;
		}
		aio_in_pending++;
		if (verbose > 2)
			fprintf(stderr, "%s submit uiocb %p\n",
				__FUNCTION__, iocb);
	}

	status = io_run (ctx, &aio_in_pending);
	if (status < 0)
		perror ("aio_in_thread, io_run");

	/* clean up */
	fflush (stderr);
	pthread_cleanup_pop (1);
	pthread_cleanup_pop (1);

	return 0;
}
コード例 #4
0
ファイル: i2c.c プロジェクト: thehobn/ec
int i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size,
	     uint8_t *in, int in_size, int flags)
{
	int i;
	int started = (flags & I2C_XFER_START) ? 0 : 1;
	uint8_t reg_sts;

	if (out_size == 0 && in_size == 0)
		return EC_SUCCESS;

	wait_idle(port);

	reg_sts = MEC1322_I2C_STATUS(port);
	if (!started &&
	    (((reg_sts & (STS_BER | STS_LAB)) || !(reg_sts & STS_NBB)) ||
			    (i2c_get_line_levels(port) != I2C_LINE_IDLE))) {
		CPRINTS("I2C%d bad status 0x%02x, SCL=%d, SDA=%d", port,
			reg_sts,
			i2c_get_line_levels(port) & I2C_LINE_SCL_HIGH,
			i2c_get_line_levels(port) & I2C_LINE_SDA_HIGH);

		/* Attempt to unwedge the port. */
		i2c_unwedge(port);

		/* Bus error, bus busy, or arbitration lost. Reset port. */
		reset_port(port);

		/*
		 * We don't know what edges the slave saw, so sleep long enough
		 * that the slave will see the new start condition below.
		 */
		usleep(1000);
	}

	if (out) {
		MEC1322_I2C_DATA(port) = (uint8_t)slave_addr;

		/*
		 * Clock out the slave address. Send START bit if start flag is
		 * set.
		 */
		MEC1322_I2C_CTRL(port) = CTRL_PIN | CTRL_ESO | CTRL_ENI |
					 CTRL_ACK | (started ? 0 : CTRL_STA);
		if (!started)
			started = 1;

		for (i = 0; i < out_size; ++i) {
			if (wait_byte_done(port))
				goto err_i2c_xfer;
			MEC1322_I2C_DATA(port) = out[i];
		}
		if (wait_byte_done(port))
			goto err_i2c_xfer;

		/*
		 * Send STOP bit if the stop flag is on, and caller
		 * doesn't expect to receive data.
		 */
		if ((flags & I2C_XFER_STOP) && in_size == 0) {
			MEC1322_I2C_CTRL(port) = CTRL_PIN | CTRL_ESO |
						 CTRL_STO | CTRL_ACK;
		}
	}

	if (in_size) {
		if (out_size) {
			/* resend start bit when change direction */
			MEC1322_I2C_CTRL(port) = CTRL_ESO | CTRL_STA |
						 CTRL_ACK | CTRL_ENI;
		}

		MEC1322_I2C_DATA(port) = (uint8_t)slave_addr | 0x01;

		if (!started) {
			started = 1;
			/* Clock out slave address with START bit */
			MEC1322_I2C_CTRL(port) = CTRL_PIN | CTRL_ESO |
						 CTRL_STA | CTRL_ACK | CTRL_ENI;
		}

		/* On MEC1322, first byte read is dummy read (slave addr) */
		in_size++;

		for (i = 0; i < in_size - 2; ++i) {
			if (wait_byte_done(port))
				goto err_i2c_xfer;
			fill_in_buf(in, i, MEC1322_I2C_DATA(port));
		}
		if (wait_byte_done(port))
			goto err_i2c_xfer;

		/*
		 * De-assert ACK bit before reading the next to last byte,
		 * so that the last byte is NACK'ed.
		 */
		MEC1322_I2C_CTRL(port) = CTRL_ESO | CTRL_ENI;
		fill_in_buf(in, in_size - 2, MEC1322_I2C_DATA(port));
		if (wait_byte_done(port))
			goto err_i2c_xfer;

		/* Send STOP if stop flag is set */
		MEC1322_I2C_CTRL(port) =
			CTRL_PIN | CTRL_ESO | CTRL_ACK |
			((flags & I2C_XFER_STOP) ? CTRL_STO : 0);

		/* Now read the last byte */
		fill_in_buf(in, in_size - 1, MEC1322_I2C_DATA(port));
	}

	/* Check for error conditions */
	if (MEC1322_I2C_STATUS(port) & (STS_LAB | STS_BER))
		return EC_ERROR_UNKNOWN;

	return EC_SUCCESS;
err_i2c_xfer:
	/* Send STOP and return error */
	MEC1322_I2C_CTRL(port) = CTRL_PIN | CTRL_ESO | CTRL_STO | CTRL_ACK;
	return EC_ERROR_UNKNOWN;
}