summaryrefslogtreecommitdiffstats
path: root/libusbhost
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@android.com>2010-12-12 14:17:02 -0800
committerMike Lockwood <lockwood@android.com>2010-12-13 19:08:14 -0800
commitcd185f23cc6f062b252d1d19bca55e721290ee62 (patch)
tree41c5e6bdb183e430732f9eb1cab4e820a2c471f6 /libusbhost
parent127fd070f038825fc05624e2e3632c47999ffb19 (diff)
downloadsystem_core-cd185f23cc6f062b252d1d19bca55e721290ee62.zip
system_core-cd185f23cc6f062b252d1d19bca55e721290ee62.tar.gz
system_core-cd185f23cc6f062b252d1d19bca55e721290ee62.tar.bz2
libusbhost: Add support for creating a usb_device struct from an existing fd
We will use this for sharing USB file descriptors across address spaces via Binder Change-Id: Iadbd3e0a4178f79d1d778fdfd5175f6fe0e2aaf5 Signed-off-by: Mike Lockwood <lockwood@android.com>
Diffstat (limited to 'libusbhost')
-rw-r--r--libusbhost/usbhost.c74
1 files changed, 51 insertions, 23 deletions
diff --git a/libusbhost/usbhost.c b/libusbhost/usbhost.c
index 98ccf7c..93c6dd3 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;