From cd185f23cc6f062b252d1d19bca55e721290ee62 Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Sun, 12 Dec 2010 14:17:02 -0800 Subject: 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 --- libusbhost/usbhost.c | 74 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 23 deletions(-) (limited to 'libusbhost') 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; -- cgit v1.1