aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2010-12-13 19:09:18 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-12-13 19:09:18 -0800
commit11549b08a360bf528760c2af0c8007668335d970 (patch)
tree75bedf64dd293d40cedd1692eb448a4b55bf56c3
parentbf5ababdb03907f44437af3294be73ab239d6eb7 (diff)
parentcd185f23cc6f062b252d1d19bca55e721290ee62 (diff)
downloadsystem_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.h10
-rw-r--r--libusbhost/usbhost.c74
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;