Date: Mon, 06 Aug 2007 13:11:04 +0400 From: Alexander Shiryaev <coumarin@gmail.com> To: freebsd-usb@freebsd.org, pldrouin@cyberfingers.net Subject: Re: Problem with libusb on FreeBSD? Message-ID: <46B6E5A8.20002@gmail.com>
next in thread | raw e-mail | index | archive | help
I have the same problem, with other device model. If do not touch control endpoint for interrupt and bulk endpoints search (i.e. open /dev/ugen0.1 and /dev/igen0.2 immediately), then there is no problems. For example, this test will be passed: #include <sys/types.h> #include <sys/ioctl.h> #include <dev/usb/usb.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <stdio.h> #include <err.h> #include <assert.h> #define OUT_BULK_DEV "/dev/ugen0.2" #define IN_INTR_DEV "/dev/ugen0.1" #define IN_BULK_DEV "/dev/ugen0.3" struct packet { u_int8_t packet_type; u_int8_t reserved1[3]; u_int16_t packet_id; u_int8_t reserved2[2]; u_int32_t data_size; }; #define USB_PROTOCOL_LAYER 0 #define APPLICATION_LAYER 20 #define PID_DATA_AVAILABLE 2 #define PID_START_SESSION 5 #define PID_SESSION_STARTED 6 #define PID_PROTOCOL_ARRAY 253 #define PID_PRODUCT_RQST 254 #define PID_PRODUCT_DATA 255 static u_int8_t const START_SESSION_REQ[] = { USB_PROTOCOL_LAYER, 0, 0, 0, PID_START_SESSION, 0, 0, 0, 0, 0, 0, 0 }; static u_int8_t const A000_REQ[] = { APPLICATION_LAYER, 0, 0, 0, PID_PRODUCT_RQST, 0, 0, 0, 0, 0, 0, 0 }; #define BUF_SIZE 1024 static int out, in_intr, in_bulk; static void dump (u_int8_t buf[], u_int32_t len) { u_int32_t i; if (len == 0) { printf("EMPTY\n"); } else { for (i = 0; i < len; i++) { printf("%2x", buf[i]); if (i % 16 == 15) printf("\n"); else printf(" "); } if (len % 16 != 0) printf("\n"); } } static void send_req (u_int8_t const req[], int len) { size_t done; done = write(out, req, len); if (done == -1) err(1, NULL); printf("write: %d\n", done); assert(done == len); } static int response_received (u_int8_t packet_type, u_int16_t packet_id, u_int8_t data[], int len) { switch (packet_type) { case USB_PROTOCOL_LAYER: switch (packet_id) { case PID_DATA_AVAILABLE: printf("data available\n"); errx(1, "not implemented"); /* TODO: switch input to in_bulk */ break; case PID_SESSION_STARTED: printf("session started\n"); send_req(A000_REQ, sizeof(A000_REQ)); break; default: errx(1, "invalid packet id"); } break; case APPLICATION_LAYER: switch (packet_id) { case PID_PRODUCT_DATA: break; case PID_PROTOCOL_ARRAY: return 1; break; default: errx(1, "invalid packet id"); } break; default: errx(1, "invalid packet type"); } return 0; } static size_t read1 (int in, void *buf, int len) { int done, d; done = 0; while (done < len) { d = read(in, buf, len - done); printf("read1: %d\n", d); done += d; }; return done; } static void start_loop () { int terminate = 0; size_t done; struct packet packet; u_int8_t buf[BUF_SIZE]; do { done = read1(in_intr, buf, sizeof(packet)); if (done == -1) err(1, NULL); printf("intr read: %d\n", done); assert(done == sizeof(packet)); dump(buf, done); memcpy(&packet, buf, done); if ((packet.reserved1[0] != 0) || (packet.reserved1[1] != 0) || (packet.reserved1[2] != 0) || (packet.reserved2[0] != 0) || (packet.reserved2[1] != 0)) { errx(1, "inalid packet"); } done = read1(in_intr, buf, packet.data_size); if (done == -1) err(1, NULL); printf("intr expected: %d, intr read: %d\n", packet.data_size, done); assert(done == packet.data_size); dump(buf, done); terminate = response_received(packet.packet_type, packet.packet_id, buf, packet.data_size); } while (!terminate); } int main () { out = open(OUT_BULK_DEV, O_WRONLY); if (out == -1) err(1, OUT_BULK_DEV); in_intr = open(IN_INTR_DEV, O_RDONLY); if (in_intr == -1) err(1, IN_INTR_DEV); in_bulk = open(IN_BULK_DEV, O_RDONLY); if (in_bulk == -1) err(1, IN_BULK_DEV); send_req(START_SESSION_REQ, sizeof(START_SESSION_REQ)); start_loop(); printf("all done\n"); return 0; } Best regards, Alexander.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?46B6E5A8.20002>