From owner-freebsd-usb@FreeBSD.ORG Fri Nov 16 22:50:00 2012 Return-Path: Delivered-To: freebsd-usb@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 934BA4B6 for ; Fri, 16 Nov 2012 22:50:00 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) by mx1.freebsd.org (Postfix) with ESMTP id 66BEC8FC16 for ; Fri, 16 Nov 2012 22:50:00 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id qAGMo0w4032650 for ; Fri, 16 Nov 2012 22:50:00 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id qAGMo07M032649; Fri, 16 Nov 2012 22:50:00 GMT (envelope-from gnats) Resent-Date: Fri, 16 Nov 2012 22:50:00 GMT Resent-Message-Id: <201211162250.qAGMo07M032649@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-usb@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, "Wojciech A. Koszek" Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id EEF32452 for ; Fri, 16 Nov 2012 22:47:29 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22]) by mx1.freebsd.org (Postfix) with ESMTP id D5A518FC08 for ; Fri, 16 Nov 2012 22:47:29 +0000 (UTC) Received: from red.freebsd.org (localhost [127.0.0.1]) by red.freebsd.org (8.14.5/8.14.5) with ESMTP id qAGMlTgu057396 for ; Fri, 16 Nov 2012 22:47:29 GMT (envelope-from nobody@red.freebsd.org) Received: (from nobody@localhost) by red.freebsd.org (8.14.5/8.14.5/Submit) id qAGMlTm2057387; Fri, 16 Nov 2012 22:47:29 GMT (envelope-from nobody) Message-Id: <201211162247.qAGMlTm2057387@red.freebsd.org> Date: Fri, 16 Nov 2012 22:47:29 GMT From: "Wojciech A. Koszek" To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Subject: usb/173666: [USB, LIBUSB] usb_reset() behavior different between GNU/Linux and FreeBSD X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Nov 2012 22:50:00 -0000 >Number: 173666 >Category: usb >Synopsis: [USB, LIBUSB] usb_reset() behavior different between GNU/Linux and FreeBSD >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-usb >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Nov 16 22:50:00 UTC 2012 >Closed-Date: >Last-Modified: >Originator: Wojciech A. Koszek >Release: 9.0-RELEASE >Organization: FreeBSD >Environment: FreeBSD seu 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan 3 07:15:25 UTC 2012 root@obrian.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386 >Description: I have a driver written for libusb, which works fine under GNU/Linux and libusb. Device: gen0.2: at usbus0, cfg=0 md=HOST spd=LOW (1.5Mbps) pwr=ON (I used USB sniffer to uncover traffic based on what Windows was doing) Under Linux usb_reset()+usb_set_configuration() calls works fine. Under FreeBSD I have to disable calling usb_reset(), otherwise usb_set_configuration() fails with I/O error. =========== usb_relay.c ================ #include #include #include #include #include #include #include static int g_debug = 0; #define DBG(...) do { \ if (g_debug == 0) { \ break; \ } \ printf("%s(%d): ", __func__, __LINE__); \ printf(__VA_ARGS__); \ printf("\n"); \ } while (0) enum { CMD_QUERY, CMD_ON, CMD_FLASH, CMD_OFF }; static void usage(void) { printf("./usb_relay \n"); exit(1); } static struct usb_device * usb_dev_find(uint32_t look_vid, uint32_t look_pid) { struct usb_bus *busses; struct usb_bus *bus; struct usb_device *dev; struct usb_device_descriptor *desc; uint32_t vid, pid; usb_init(); usb_find_busses(); usb_find_devices(); busses = usb_get_busses(); for (bus = busses; bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { desc = &dev->descriptor; vid = desc->idVendor; pid = desc->idProduct; if ((vid == look_vid) && (pid == look_pid)) { return (dev); } } } return (NULL); } int main(int argc, char **argv) { struct usb_device *dev; struct usb_dev_handle *hptr; int o, ret, state, ep, ac, cmd; uint32_t data[2]; char **av; int i; while ((o = getopt(argc, argv, "dh")) != -1) { switch (o) { case 'd': g_debug++; break; case 'h': usage(); break; default: usage(); break; } } ac = argc - optind; av = argv + optind; cmd = CMD_QUERY; if (ac > 0) { if (strcmp(av[0], "on") == 0) { cmd = CMD_ON; } else if (strcmp(av[0], "off") == 0) { cmd = CMD_OFF; } else if (strcmp(av[0], "flash") == 0) { cmd = CMD_FLASH; } else { abort(); } } dev = usb_dev_find(0x07c3, 0x1283); if (dev == NULL) { printf("J283 not found!\n"); exit(1); } hptr = usb_open(dev); DBG("usb_open returned %p", hptr); #ifdef HAS_RESET ret = usb_reset(hptr); DBG("usb_reset returned %d: %s", ret, libusb_strerror(ret)); #endif ret = usb_set_configuration(hptr, 1); DBG("usb_reset returned %d: %s", ret, libusb_strerror(ret)); ret = usb_claim_interface(hptr, 1); DBG("usb_reset returned %d: %s", ret, libusb_strerror(ret)); data[0] = -1; data[1] = -1; ret = usb_control_msg(hptr, 0xc2, 176, 0x0, 0, (char *)data, 8, 400); DBG("usb_control_msg = %d %08x,%08x", ret, data[0], data[1]); ret = usb_control_msg(hptr, 0xc2, 184, 0x0, 0, (char *)data, 8, 400); DBG("usb_control_msg = %d %08x,%08x", ret, data[0], data[1]); if (cmd == CMD_QUERY) { state = data[0] & 1; printf("%s\n", state ? "on" : "off"); } else if (cmd == CMD_ON) { ret = usb_control_msg(hptr, 0xc2, 183, 0x0, 0, (char *)data, 8, 400); } else if (cmd == CMD_OFF) { ret = usb_control_msg(hptr, 0xc2, 182, 0x0, 0, (char *)data, 8, 400); } else if (cmd == CMD_FLASH) { ret = usb_control_msg(hptr, 0xc2, 177, 0x0, 0, (char *)data, 8, 400); } else { abort(); } exit(0); } >How-To-Repeat: seu# gcc -DHAS_RESET usb_relay.c -o usb_relay.has_reset -lusb seu# ./usb_relay.has_reset -d off && sleep 1 && ./usb_relay.has_reset -d on main(110): usb_open returned 0x28405480 main(113): usb_reset returned 0: Success main(117): usb_reset returned -1: I/O error main(119): usb_reset returned 0: Success main(124): usb_control_msg = -1 ffffffff,ffffffff main(126): usb_control_msg = -1 ffffffff,ffffffff main(110): usb_open returned 0x28405480 main(113): usb_reset returned 0: Success main(117): usb_reset returned -1: I/O error main(119): usb_reset returned 0: Success main(124): usb_control_msg = -1 ffffffff,ffffffff main(126): usb_control_msg = -1 ffffffff,ffffffff seu# seu# gcc usb_relay.c -o usb_relay -lusb seu# ./usb_relay -d off && sleep 1 && ./usb_relay -d on main(110): usb_open returned 0x28405480 main(117): usb_reset returned 0: Success main(119): usb_reset returned 0: Success main(124): usb_control_msg = 5 01000001,ffffff00 main(126): usb_control_msg = 5 01000001,ffffff00 main(110): usb_open returned 0x28405480 main(117): usb_reset returned 0: Success main(119): usb_reset returned 0: Success main(124): usb_control_msg = 5 01000001,ffffff00 main(126): usb_control_msg = 5 01000000,ffffff00 >Fix: >Release-Note: >Audit-Trail: >Unformatted: