Date: Sat, 15 Nov 2008 17:16:37 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 153010 for review Message-ID: <200811151716.mAFHGbqY075099@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=153010 Change 153010 by hselasky@hselasky_laptop001 on 2008/11/15 17:16:35 Improve handling of set-config, set-alternate-index and device-reset in relation to libusb. Affected files ... .. //depot/projects/usb/src/lib/libusb20/libusb20.c#12 edit .. //depot/projects/usb/src/lib/libusb20/libusb20_ugen20.c#10 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#32 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_request.c#22 edit Differences ... ==== //depot/projects/usb/src/lib/libusb20/libusb20.c#12 (text+ko) ==== @@ -550,6 +550,9 @@ xfer->callback = &dummy_callback; } + /* set "nTransfer" early */ + pdev->nTransfer = nTransferMax; + error = (pdev->beMethods->open_device) (pdev, nTransferMax); if (error) { @@ -562,7 +565,6 @@ pdev->nTransfer = 0; } else { pdev->is_opened = 1; - pdev->nTransfer = nTransferMax; } return (error); } ==== //depot/projects/usb/src/lib/libusb20/libusb20_ugen20.c#10 (text+ko) ==== @@ -308,19 +308,62 @@ } static int -ugen20_open_device(struct libusb20_device *pdev, uint16_t nMaxTransfer) +ugen20_tr_renew(struct libusb20_device *pdev) { - struct usb2_fs_endpoint *pfse = NULL; + struct usb2_fs_uninit fs_uninit; struct usb2_fs_init fs_init; + struct usb2_fs_endpoint *pfse; + int error; uint32_t size; + uint16_t nMaxTransfer; + + nMaxTransfer = pdev->nTransfer; + error = 0; + + if (nMaxTransfer == 0) { + goto done; + } + size = nMaxTransfer * sizeof(*pfse); + + if (pdev->privBeData != NULL) { + memset(&fs_uninit, 0, sizeof(fs_uninit)); + if (ioctl(pdev->file, USB_FS_UNINIT, &fs_uninit)) { + /* ignore any errors of this kind */ + } + } else { + pfse = malloc(size); + if (pfse == NULL) { + error = LIBUSB20_ERROR_NO_MEM; + goto done; + } + pdev->privBeData = pfse; + } + + /* reset endpoint data */ + memset(pdev->privBeData, 0, size); + + memset(&fs_init, 0, sizeof(fs_init)); + + fs_init.pEndpoints = pdev->privBeData; + fs_init.ep_index_max = nMaxTransfer; + + if (ioctl(pdev->file, USB_FS_INIT, &fs_init)) { + error = LIBUSB20_ERROR_OTHER; + goto done; + } +done: + return (error); +} + +static int +ugen20_open_device(struct libusb20_device *pdev, uint16_t nMaxTransfer) +{ uint32_t plugtime; char buf[64]; int f; int g; int error; - memset(&fs_init, 0, sizeof(fs_init)); - snprintf(buf, sizeof(buf), "/dev/ugen%u.%u", pdev->bus_number, pdev->device_address); @@ -347,36 +390,27 @@ error = LIBUSB20_ERROR_NO_DEVICE; goto done; } - if (nMaxTransfer != 0) { + /* need to set this before "tr_renew()" */ + pdev->file = f; + pdev->file_ctrl = g; - size = nMaxTransfer * sizeof(*pfse); - - pfse = malloc(size); - if (!pfse) { - error = LIBUSB20_ERROR_NO_MEM; - goto done; - } - memset(pfse, 0, size); - - fs_init.pEndpoints = pfse; - fs_init.ep_index_max = nMaxTransfer; - - if (ioctl(f, USB_FS_INIT, &fs_init)) { - error = LIBUSB20_ERROR_OTHER; - goto done; - } + /* renew all USB transfers */ + error = ugen20_tr_renew(pdev); + if (error) { + goto done; } /* set methods */ pdev->methods = &libusb20_ugen20_device_methods; - pdev->privBeData = pfse; - pdev->file = f; - pdev->file_ctrl = g; - error = 0; + done: if (error) { - if (pfse) { - free(pfse); + if (pdev->privBeData) { + /* cleanup after "tr_renew()" */ + free(pdev->privBeData); + pdev->privBeData = NULL; } + pdev->file = -1; + pdev->file_ctrl = -1; close(f); close(g); } @@ -389,9 +423,8 @@ struct usb2_fs_uninit fs_uninit; int error = 0; - memset(&fs_uninit, 0, sizeof(fs_uninit)); - if (pdev->privBeData) { + memset(&fs_uninit, 0, sizeof(fs_uninit)); if (ioctl(pdev->file, USB_FS_UNINIT, &fs_uninit)) { error = LIBUSB20_ERROR_OTHER; } @@ -479,7 +512,7 @@ if (ioctl(pdev->file_ctrl, USB_SET_CONFIG, &temp)) { return (LIBUSB20_ERROR_OTHER); } - return (0); + return (ugen20_tr_renew(pdev)); } static int @@ -518,7 +551,7 @@ if (ioctl(pdev->file_ctrl, USB_SET_ALTINTERFACE, &alt_iface)) { return (LIBUSB20_ERROR_OTHER); } - return (0); + return (ugen20_tr_renew(pdev)); } static int @@ -529,7 +562,7 @@ if (ioctl(pdev->file_ctrl, USB_DEVICEENUMERATE, &temp)) { return (LIBUSB20_ERROR_OTHER); } - return (0); + return (ugen20_tr_renew(pdev)); } static int ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#32 (text+ko) ==== @@ -929,6 +929,12 @@ if (error) { return (error); } + /* get the device unconfigured */ + error = ugen_set_config(f, USB_UNCONFIG_INDEX); + if (error) { + return (error); + } + /* do a bus-reset */ mtx_lock(f->priv_mtx); error = usb2_req_re_enumerate(udev, f->priv_mtx); mtx_unlock(f->priv_mtx); @@ -936,6 +942,11 @@ if (error) { return (ENXIO); } + /* restore configuration to index 0 */ + error = ugen_set_config(f, 0); + if (error) { + return (error); + } return (0); } ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_request.c#22 (text+ko) ==== @@ -1314,6 +1314,10 @@ /*------------------------------------------------------------------------* * usb2_req_re_enumerate * + * NOTE: After this function returns the hardware is in the + * unconfigured state! The application is responsible for setting a + * new configuration. + * * Returns: * 0: Success * Else: Failure @@ -1369,12 +1373,5 @@ done: /* restore address */ udev->address = old_addr; - - if (err == 0) { - /* restore configuration */ - err = usb2_req_set_config(udev, mtx, udev->curr_config_no); - /* wait a little bit, just in case */ - usb2_pause_mtx(mtx, 10); - } return (err); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200811151716.mAFHGbqY075099>