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