PERFORCE change 153010 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat Nov 15 09:16:38 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=153010
Change 153010 by hselasky at 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);
}
More information about the p4-projects
mailing list