r4208 - developers/werner/ahrt/host/tmc

werner at sita.openmoko.org werner at sita.openmoko.org
Fri Mar 14 15:22:14 CET 2008


Author: werner
Date: 2008-03-14 15:22:08 +0100 (Fri, 14 Mar 2008)
New Revision: 4208

Modified:
   developers/werner/ahrt/host/tmc/io.c
   developers/werner/ahrt/host/tmc/io.h
   developers/werner/ahrt/host/tmc/tmc.c
   developers/werner/ahrt/host/tmc/usbtmc.c
Log:
- tmc.c (tmc_open): send DCI after opening a session
- tmc.c (tmc_read): handle read errors
- io.c (read_buf): don't leak buffer memory
- io.h, io.c (io_cancel_buf): new function to deallocate a buffer without
  reading it
- usbtmc.c (struct usbtmc_dsc, get_eps): record maximum packet size (for use by
  usbtmc_dci)
- usbtmc.c (usbtmc_clear): implement the INITATE_CLEAR procedure
- usbtmc.c (usbtmc_abort_out): implement part of the ABORT_BULK_OUT procedure
- usbtmc.c (usbtmc_dci): attempt to cancel any ongoing transfer
- usbtmc.c (debug), io.h (debug), io.c (debug): moved local "debug" from
  usbtmc.c to io.c and made it global



Modified: developers/werner/ahrt/host/tmc/io.c
===================================================================
--- developers/werner/ahrt/host/tmc/io.c	2008-03-14 12:11:45 UTC (rev 4207)
+++ developers/werner/ahrt/host/tmc/io.c	2008-03-14 14:22:08 UTC (rev 4208)
@@ -23,7 +23,9 @@
 #include "io.h"
 
 
+int debug = 1;
 
+
 /* ----- Asynchronous I/O -------------------------------------------------- */
 
 
@@ -195,6 +197,16 @@
 	}
 	memcpy(buf, d->buf, len);
 //fprintf(stderr, "(%.*s) %d\n", len, d->buf, len);
+	free(d->buf);
 	free(d);
 	return len;
 }
+
+
+void io_cancel_buf(void *dsc)
+{
+	struct io_sync_buf *d = dsc;
+
+	free(d->buf);
+	free(d);
+}

Modified: developers/werner/ahrt/host/tmc/io.h
===================================================================
--- developers/werner/ahrt/host/tmc/io.h	2008-03-14 12:11:45 UTC (rev 4207)
+++ developers/werner/ahrt/host/tmc/io.h	2008-03-14 14:22:08 UTC (rev 4208)
@@ -30,6 +30,7 @@
 void io_push_buf(void *dsc, const struct timeval *tv, const void *buf,
     size_t len, int end);
 size_t io_read_buf(void *dsc, void *buf, size_t size);
+void io_cancel_buf(void *dsc);
 
 
 struct proto_ops {
@@ -41,6 +42,8 @@
 };
 
 
+extern int debug;
+
 extern struct proto_ops telnet_ops; /* TELNET-like */
 extern struct proto_ops usbtmc_ops; /* USBTMC */
 extern struct proto_ops tty_ops; /* TTY */

Modified: developers/werner/ahrt/host/tmc/tmc.c
===================================================================
--- developers/werner/ahrt/host/tmc/tmc.c	2008-03-14 12:11:45 UTC (rev 4207)
+++ developers/werner/ahrt/host/tmc/tmc.c	2008-03-14 14:22:08 UTC (rev 4208)
@@ -43,8 +43,11 @@
 	dsc->ops = ops;
 	dsc->proto_dsc = ops->open(argc, argv);
 	dsc->running = 0;
-	if (dsc->proto_dsc)
-		return dsc;
+	if (dsc->proto_dsc) {
+		if (!ops->dci(dsc->proto_dsc))
+			return dsc;
+		ops->close(dsc->proto_dsc);
+	}
 	free(dsc);
 	return NULL;
 }
@@ -79,8 +82,10 @@
 		return -1;
 	}
 	io_dsc = io_create_buf();
-	/* @@@FIXME: handle read error */
-	dsc->ops->read(dsc->proto_dsc, io_push_buf, io_dsc);
+	if (dsc->ops->read(dsc->proto_dsc, io_push_buf, io_dsc) < 0) {
+		io_cancel_buf(io_dsc);
+		return -1;
+	}
 	return io_read_buf(io_dsc, buf, size);
 }
 

Modified: developers/werner/ahrt/host/tmc/usbtmc.c
===================================================================
--- developers/werner/ahrt/host/tmc/usbtmc.c	2008-03-14 12:11:45 UTC (rev 4207)
+++ developers/werner/ahrt/host/tmc/usbtmc.c	2008-03-14 14:22:08 UTC (rev 4208)
@@ -43,15 +43,27 @@
 #endif
 
 #define SIZE_IOBUFFER 4096
-#define DEV_DEP_MSG_OUT	1
-#define DEV_DEP_MSG_IN	2
-#define INITIATE_ABORT_BULK_IN 3
 
+#define DEV_DEP_MSG_OUT			1
+#define DEV_DEP_MSG_IN			2
 
+#define INITIATE_ABORT_BULK_OUT		1
+#define CHECK_ABORT_BULK_OUT_STATUS	2
+#define INITIATE_ABORT_BULK_IN		3
+#define CHECK_ABORT_BULK_STATUS		4
+#define INITIATE_CLEAR			5
+#define CHECK_CLEAR_STATUS		6
+
+#define STATUS_SUCCESS			0x01
+#define STATUS_PENDING			0x02
+#define STATUS_FAILED			0x80
+
+
 struct usbtmc_dsc {
 	usb_dev_handle *handle;		/* USB device handle */
 	uint8_t ep_int_in, ep_bulk_in, ep_bulk_out; /* endpoints */
 	uint8_t bTag;			/* sequence number */
+	uint16_t max_packet;		/* maximum ep_bulk_in packet size */
 	unsigned long timeout;		/* timeout in milliseconds */
 	int retry;			/* retry after timeouts */
 	void *last_buf;			/* last buffer sent */
@@ -59,9 +71,6 @@
 };
 
 
-static int debug = 0;
-
-
 /* ----- Debugging --------------------------------------------------------- */
 
 
@@ -123,6 +132,7 @@
 				return -1;
 			}
 			d->ep_bulk_in = ep->bEndpointAddress;
+			d->max_packet = ep->wMaxPacketSize;
 			break;
 		case USB_ENDPOINT_TYPE_BULK:
 			if (d->ep_bulk_out) {
@@ -268,6 +278,8 @@
 	uint8_t buf[2];
 	ssize_t got;
 
+	if (debug)
+		fprintf(stderr, "INITIATE_ABORT_BULK_IN\n");
 	got = usb_control_msg(d->handle,
 	    USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
 	    INITIATE_ABORT_BULK_IN,
@@ -285,6 +297,106 @@
 }
 
 
+static void usbtmc_abort_out(struct usbtmc_dsc *d)
+{
+	uint8_t buf[2];
+	ssize_t got;
+
+	if (debug)
+		fprintf(stderr, "INITIATE_ABORT_BULK_OUT\n");
+	got = usb_control_msg(d->handle,
+	    USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
+	    INITIATE_ABORT_BULK_OUT,
+	    d->bTag,
+	    d->ep_bulk_out,
+	    (void *) buf, 2, d->timeout);
+	if (got < 0) {
+		fprintf(stderr, "INITIATE_ABORT_BULK_OUT error %d\n",
+		    (int) got);
+		return;
+	}
+	fprintf(stderr, "status 0x%02x bTag 0x%02x\n", buf[0], buf[1]);
+
+	/* depending on status, do more */
+}
+
+
+static int usbtmc_clear(struct usbtmc_dsc *d)
+{
+	uint8_t buf[SIZE_IOBUFFER];
+	ssize_t got;
+	int error;
+
+	if (debug)
+		fprintf(stderr, "INITIATE_CLEAR\n");
+	got = usb_control_msg(d->handle,
+	    USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+	    INITIATE_CLEAR,
+	    0,
+	    0, /* interface number */
+	    (void *) buf, 1, d->timeout);
+	if (got < 0) {
+		fprintf(stderr, "INITIATE_CLEAR error %d\n", (int) got);
+		return -1;
+	}
+
+	if (debug)
+		fprintf(stderr, "INITIATE_CLEAR status 0x%02x\n", buf[0]);
+	if (buf[0] != STATUS_SUCCESS)
+		return 0;
+
+	while (1) {
+		if (debug)
+			fprintf(stderr, "CHECK_CLEAR_STATUS\n");
+		got = usb_control_msg(d->handle,
+		    USB_ENDPOINT_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+		    CHECK_CLEAR_STATUS,
+		    0,
+		    0, /* interface number */
+		    (void *) buf, 2, d->timeout);
+		if (got < 0) {
+			fprintf(stderr, "CHECK_CLEAR_STATUS error %d\n",
+			    (int) got);
+			return -1;
+		}
+
+		if (debug)
+			fprintf(stderr,
+			    "CHECK_CLEAR_STATUS status 0x%02x, 0x%02x\n",
+			    buf[0], buf[1]);
+		if (buf[0] != STATUS_PENDING)
+			break;
+
+		if (!(buf[1] & 1))
+			continue;
+
+		if (debug)
+			fprintf(stderr, "%d vs %d\n",
+			    SIZE_IOBUFFER, d->max_packet);
+		do {
+			got = usb_bulk_read(d->handle, d->ep_bulk_in,
+			    (void *) buf, SIZE_IOBUFFER, d->timeout);
+			if (got < 0) {
+				fprintf(stderr, "read error %d\n", (int) got);
+				return -1;
+			}
+			dump("RECV: discarding", buf, got);
+		}
+		while (got != d->max_packet);
+	}
+
+	if (debug)
+		fprintf(stderr, "usb_clear_halt\n");
+	error = usb_clear_halt(d->handle, d->ep_bulk_out);
+	if (error) {
+		fprintf(stderr, "usb_clear_halt error %d\n", error);
+		return -1;
+	}
+
+	return 0;
+}
+
+
 static void usage(void)
 {
 	fprintf(stderr,
@@ -541,7 +653,18 @@
 
 static int usbtmc_dci(void *dsc)
 {
-	/* @@@FIXME: implement later */
+	struct usbtmc_dsc *d = dsc;
+
+	/*
+	 * @@@FIXME: This doesn't seem work yet. The goal is to abort an
+	 * on-going transfer, e.g., from a READ? with many samples. It succeeds
+	 * to interrupt the transfer sometimes, but not all the time.
+	 */
+	if (debug)
+		fprintf(stderr, "DCI\n");
+	//usbtmc_clear(d);
+	usbtmc_abort_in(d);
+	//usbtmc_abort_out(d);
 	return 0;
 }
 





More information about the commitlog mailing list