diff options
author | alfred <alfred@FreeBSD.org> | 2008-11-25 08:04:40 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2008-11-25 08:04:40 +0000 |
commit | b7b4347b8656d5371a99dda538c62e44892174b7 (patch) | |
tree | b851b7a53f0f261e0502bfc568ba90e068cfdcca /lib | |
parent | b0a070ce29c7f901038f9cfb6bfef9247d44075f (diff) | |
download | FreeBSD-src-b7b4347b8656d5371a99dda538c62e44892174b7.zip FreeBSD-src-b7b4347b8656d5371a99dda538c62e44892174b7.tar.gz |
src/lib/libusb20/libusb20_compat01.c
Fix some issues about re-scanning of the devices.
src/lib/libusb20/libusb20_ugen20.c
Fix issue about libusb20 having to release the
USB transfers before doing a SET_CONFIG, else
the kernel will kill the file handle.
src/sys/dev/usb2/core/usb2_device.
src/sys/dev/usb2/core/usb2_generic.c
src/sys/dev/usb2/core/usb2_generic.h
Add support for U3G devices.
Improve and cleanup FIFO free handling.
Improve device re-enumeration.
src/sys/dev/usb2/core/usb2_msctest.c
src/sys/dev/usb2/core/usb2_msctest.h
Fix some problems in the USB Mass Storage Test.
Add Huawei vendor specific quirks.
src/sys/dev/usb2/core/usb2_request.c
Improve device re-enumeration.
src/sys/dev/usb2/ethernet/if_aue2.c
src/sys/dev/usb2/include/usb2_devid.h
src/sys/dev/usb2/include/usb2_devtable.h
src/sys/dev/usb2/quirk/usb2_quirk.c
Integrate changes from the old USB driver.
src/sys/dev/usb2/include/usb2_standard.h
Add definition of USB3.0 structures from USB.org.
src/sys/dev/usb2/serial/u3g2.c
src/sys/dev/usb2/serial/ugensa2.c
src/sys/modules/usb2/Makefile
src/sys/modules/usb2/serial_3g/Makefile
Import U3G driver.
Submitted by: Hans Petter Selasky (usb4bsd)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libusb20/libusb20_compat01.c | 75 | ||||
-rw-r--r-- | lib/libusb20/libusb20_ugen20.c | 41 |
2 files changed, 70 insertions, 46 deletions
diff --git a/lib/libusb20/libusb20_compat01.c b/lib/libusb20/libusb20_compat01.c index b63c5e9..3700c7f 100644 --- a/lib/libusb20/libusb20_compat01.c +++ b/lib/libusb20/libusb20_compat01.c @@ -177,19 +177,42 @@ usb_open(struct usb_device *dev) if (err) return (NULL); + /* + * Dequeue USB device from backend queue so that it does not get + * freed when the backend is re-scanned: + */ + libusb20_be_dequeue_device(usb_backend, dev->dev); + return (dev->dev); } int -usb_close(usb_dev_handle * dev) +usb_close(usb_dev_handle * udev) { + struct usb_device *dev; int err; - err = libusb20_dev_close((void *)dev); + err = libusb20_dev_close((void *)udev); if (err) return (-1); + if (usb_backend != NULL) { + /* + * Enqueue USB device to backend queue so that it gets freed + * when the backend is re-scanned: + */ + libusb20_be_enqueue_device(usb_backend, (void *)udev); + } else { + /* + * The backend is gone. Free device data so that we + * don't start leaking memory! + */ + dev = usb_device(udev); + libusb20_dev_free((void *)udev); + LIST_DEL(usb_global_bus.devices, dev); + free(dev); + } return (0); } @@ -697,7 +720,8 @@ usb_set_configuration(usb_dev_handle * udev, int bConfigurationValue) /* "bConfigurationValue" not found */ return (-1); } - if ((dev->config + i)->bConfigurationValue == bConfigurationValue) { + if ((dev->config + i)->bConfigurationValue == + bConfigurationValue) { break; } } @@ -821,36 +845,28 @@ usb_find_devices(void) struct libusb20_device *pdev; struct usb_device *udev; struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; - struct libusb20_backend *pold; int err; /* cleanup after last device search */ - - pold = usb_backend; - - pdev = NULL; - while ((pdev = libusb20_be_device_foreach(pold, pdev))) { - if (!pdev->is_opened) { - /* - * if the device has not been opened we free the - * device data - */ - udev = pdev->priv01Data; - libusb20_be_dequeue_device(pold, pdev); - libusb20_dev_free(pdev); - if (udev != NULL) { - LIST_DEL(usb_global_bus.devices, udev); - free(udev); - } - pdev = NULL; /* restart search */ + /* close all opened devices, if any */ + + while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) { + udev = pdev->priv01Data; + libusb20_be_dequeue_device(usb_backend, pdev); + libusb20_dev_free(pdev); + if (udev != NULL) { + LIST_DEL(usb_global_bus.devices, udev); + free(udev); } } - /* do a new backend device search */ + /* free old USB backend, if any */ + + libusb20_be_free(usb_backend); + /* do a new backend device search */ usb_backend = libusb20_be_alloc_default(); if (usb_backend == NULL) { - usb_backend = pold; /* restore */ return (-1); } /* iterate all devices */ @@ -904,17 +920,6 @@ usb_find_devices(void) LIST_ADD(usb_global_bus.devices, udev); } - /* move old devices over to the new USB backend */ - - while ((pdev = libusb20_be_device_foreach(pold, pdev))) { - libusb20_be_dequeue_device(pold, pdev); - libusb20_be_enqueue_device(usb_backend, pdev); - } - - /* free old backend, if any */ - - libusb20_be_free(pold); - return (0); /* success */ } diff --git a/lib/libusb20/libusb20_ugen20.c b/lib/libusb20/libusb20_ugen20.c index 0ef5562..3646a59 100644 --- a/lib/libusb20/libusb20_ugen20.c +++ b/lib/libusb20/libusb20_ugen20.c @@ -307,10 +307,27 @@ ugen20_init_backend(struct libusb20_backend *pbe) return (0); /* success */ } +static void +ugen20_tr_release(struct libusb20_device *pdev) +{ + struct usb2_fs_uninit fs_uninit; + + if (pdev->nTransfer == 0) { + return; + } + /* release all pending USB transfers */ + 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 */ + } + } + return; +} + static int ugen20_tr_renew(struct libusb20_device *pdev) { - struct usb2_fs_uninit fs_uninit; struct usb2_fs_init fs_init; struct usb2_fs_endpoint *pfse; int error; @@ -325,12 +342,7 @@ ugen20_tr_renew(struct libusb20_device *pdev) } 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 { + if (pdev->privBeData == NULL) { pfse = malloc(size); if (pfse == NULL) { error = LIBUSB20_ERROR_NO_MEM; @@ -338,7 +350,6 @@ ugen20_tr_renew(struct libusb20_device *pdev) } pdev->privBeData = pfse; } - /* reset endpoint data */ memset(pdev->privBeData, 0, size); @@ -421,12 +432,11 @@ static int ugen20_close_device(struct libusb20_device *pdev) { struct usb2_fs_uninit fs_uninit; - int error = 0; if (pdev->privBeData) { memset(&fs_uninit, 0, sizeof(fs_uninit)); if (ioctl(pdev->file, USB_FS_UNINIT, &fs_uninit)) { - error = LIBUSB20_ERROR_OTHER; + /* ignore this error */ } free(pdev->privBeData); } @@ -436,7 +446,7 @@ ugen20_close_device(struct libusb20_device *pdev) close(pdev->file_ctrl); pdev->file = -1; pdev->file_ctrl = -1; - return (error); + return (0); /* success */ } static void @@ -509,6 +519,9 @@ ugen20_set_config_index(struct libusb20_device *pdev, uint8_t cfg_index) { int temp = cfg_index; + /* release all active USB transfers */ + ugen20_tr_release(pdev); + if (ioctl(pdev->file_ctrl, USB_SET_CONFIG, &temp)) { return (LIBUSB20_ERROR_OTHER); } @@ -548,6 +561,9 @@ ugen20_set_alt_index(struct libusb20_device *pdev, alt_iface.uai_interface_index = iface_index; alt_iface.uai_alt_index = alt_index; + /* release all active USB transfers */ + ugen20_tr_release(pdev); + if (ioctl(pdev->file_ctrl, USB_SET_ALTINTERFACE, &alt_iface)) { return (LIBUSB20_ERROR_OTHER); } @@ -559,6 +575,9 @@ ugen20_reset_device(struct libusb20_device *pdev) { int temp = 0; + /* release all active USB transfers */ + ugen20_tr_release(pdev); + if (ioctl(pdev->file_ctrl, USB_DEVICEENUMERATE, &temp)) { return (LIBUSB20_ERROR_OTHER); } |