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>
This commit is contained in:
parent
127fd070f0
commit
cd185f23cc
2 changed files with 67 additions and 29 deletions
|
|
@ -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()
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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,23 +229,16 @@ 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);
|
||||
}
|
||||
|
||||
length = read(fd, device->desc, sizeof(device->desc));
|
||||
D("usb_device_open read returned %d errno %d\n", fd, errno);
|
||||
if (length < 0)
|
||||
goto fail;
|
||||
|
||||
device->fd = fd;
|
||||
device->desc_length = length;
|
||||
return device;
|
||||
fail:
|
||||
close(fd);
|
||||
free(device);
|
||||
return NULL;
|
||||
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)
|
||||
|
|
@ -258,6 +247,53 @@ void usb_device_close(struct usb_device *device)
|
|||
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_new read returned %d errno %d\n", fd, errno);
|
||||
if (length < 0)
|
||||
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;
|
||||
|
||||
failed:
|
||||
close(fd);
|
||||
free(device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int usb_device_reopen_writeable(struct usb_device *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)
|
||||
{
|
||||
return device->dev_name;
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue