diff options
| author | Mike Lockwood <lockwood@android.com> | 2010-12-13 19:09:18 -0800 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-12-13 19:09:18 -0800 |
| commit | 11549b08a360bf528760c2af0c8007668335d970 (patch) | |
| tree | 75bedf64dd293d40cedd1692eb448a4b55bf56c3 | |
| parent | bf5ababdb03907f44437af3294be73ab239d6eb7 (diff) | |
| parent | cd185f23cc6f062b252d1d19bca55e721290ee62 (diff) | |
| download | system_core-11549b08a360bf528760c2af0c8007668335d970.tar.gz system_core-11549b08a360bf528760c2af0c8007668335d970.tar.bz2 system_core-11549b08a360bf528760c2af0c8007668335d970.zip | |
Merge "libusbhost: Add support for creating a usb_device struct from an existing fd"
| -rw-r--r-- | include/usbhost/usbhost.h | 10 | ||||
| -rw-r--r-- | libusbhost/usbhost.c | 74 |
2 files changed, 61 insertions, 23 deletions
diff --git a/include/usbhost/usbhost.h b/include/usbhost/usbhost.h index 5332acd3..57d9c37e 100644 --- a/include/usbhost/usbhost.h +++ b/include/usbhost/usbhost.h @@ -81,6 +81,16 @@ struct usb_device *usb_device_open(const char *dev_name); /* Releases all resources associated with the USB device */ void usb_device_close(struct usb_device *device); +/* Creates a usb_device object for already open USB device. + * This is intended to facilitate sharing USB devices across address spaces. + */ +struct usb_device *usb_device_new(const char *dev_name, int fd); + +/* Returns the file descriptor for the usb_device. Used in conjunction with + * usb_device_new() for sharing USB devices across address spaces. + */ +int usb_device_get_fd(struct usb_device *device); + /* Returns the name for the USB device, which is the same as * the dev_name passed to usb_device_open() */ diff --git a/libusbhost/usbhost.c b/libusbhost/usbhost.c index 98ccf7c5..93c6dd3a 100644 --- a/libusbhost/usbhost.c +++ b/libusbhost/usbhost.c @@ -214,11 +214,7 @@ void usb_host_run(struct usb_host_context *context, struct usb_device *usb_device_open(const char *dev_name) { - struct usb_device *device = calloc(1, sizeof(struct usb_device)); - int fd, length, did_retry = 0; - - strcpy(device->dev_name, dev_name); - device->writeable = 1; + int fd, did_retry = 0, writeable = 1; retry: fd = open(dev_name, O_RDWR); @@ -233,29 +229,69 @@ retry: goto retry; } - if (fd < 0) goto fail; - device->writeable = 0; + if (fd < 0) + return NULL; + writeable = 0; D("[ usb open read-only %s fd = %d]\n", dev_name, fd); } + struct usb_device* result = usb_device_new(dev_name, fd); + if (result) + result->writeable = writeable; + return result; +} + +void usb_device_close(struct usb_device *device) +{ + close(device->fd); + free(device); +} + +struct usb_device *usb_device_new(const char *dev_name, int fd) +{ + struct usb_device *device = calloc(1, sizeof(struct usb_device)); + int length; + + if (lseek(fd, 0, SEEK_SET) != 0) + goto failed; length = read(fd, device->desc, sizeof(device->desc)); - D("usb_device_open read returned %d errno %d\n", fd, errno); + D("usb_device_new read returned %d errno %d\n", fd, errno); if (length < 0) - goto fail; + goto failed; device->fd = fd; device->desc_length = length; + // assume we are writeable, since usb_device_get_fd will only return writeable fds + device->writeable = 1; return device; -fail: + +failed: close(fd); free(device); return NULL; } -void usb_device_close(struct usb_device *device) +static int usb_device_reopen_writeable(struct usb_device *device) { - close(device->fd); - free(device); + if (device->writeable) + return 1; + + int fd = open(device->dev_name, O_RDWR); + if (fd >= 0) { + close(device->fd); + device->fd = fd; + device->writeable = 1; + return 1; + } + D("usb_device_reopen_writeable failed errno %d\n", errno); + return 0; +} + +int usb_device_get_fd(struct usb_device *device) +{ + if (!usb_device_reopen_writeable(device)) + return -1; + return device->fd; } const char* usb_device_get_name(struct usb_device *device) @@ -300,16 +336,8 @@ int usb_device_send_control(struct usb_device *device, struct usbdevfs_ctrltransfer ctrl; // this usually requires read/write permission - if (!device->writeable) { - int fd = open(device->dev_name, O_RDWR); - if (fd > 0) { - close(device->fd); - device->fd = fd; - device->writeable = 1; - } else { - return -1; - } - } + if (!usb_device_reopen_writeable(device)) + return -1; memset(&ctrl, 0, sizeof(ctrl)); ctrl.bRequestType = requestType; |
