Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 11549b08 authored by Mike Lockwood's avatar Mike Lockwood Committed by Android (Google) Code Review
Browse files

Merge "libusbhost: Add support for creating a usb_device struct from an existing fd"

parents bf5ababd cd185f23
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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()
 */
+51 −23
Original line number Diff line number Diff line
@@ -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)
{
    if (device->writeable)
        return 1;

    int fd = open(device->dev_name, O_RDWR);
    if (fd >= 0) {
        close(device->fd);
    free(device);
        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 {
    if (!usb_device_reopen_writeable(device))
        return -1;
        }
    }

    memset(&ctrl, 0, sizeof(ctrl));
    ctrl.bRequestType = requestType;