adbd: Support for new f_fs descriptor format

The patch "[RFC] usb: gadget: f_fs: Add flags
to  descriptors block" marks the current
usb_functionfs_descs_head format deprecated
and introduces support for sending SuperSpeed
descriptors.

This CL makes adbd to send Descriptors in the
new format. Adbd would fall back to the old
format, if kernel is not able to recognize
the new format. This is done to prevent
adbd from breaking in the older versions
of the kernel.

Bug: 17394972
Change-Id: I1acf684ef8a4dcc612ac20b5abe1e27b43901031
Signed-off-by: Badhri Jagan Sridharan <badhri@google.com>
This commit is contained in:
Badhri Jagan Sridharan 2014-10-27 18:32:35 -07:00
parent f997340fe8
commit b5b43043fa

View file

@ -52,7 +52,35 @@ struct usb_handle
int bulk_in; /* "in" from the host's perspective => sink for adbd */ int bulk_in; /* "in" from the host's perspective => sink for adbd */
}; };
static const struct { struct func_desc {
struct usb_interface_descriptor intf;
struct usb_endpoint_descriptor_no_audio source;
struct usb_endpoint_descriptor_no_audio sink;
} __attribute__((packed));
struct desc_v1 {
struct usb_functionfs_descs_head_v1 {
__le32 magic;
__le32 length;
__le32 fs_count;
__le32 hs_count;
} __attribute__((packed)) header;
struct func_desc fs_descs, hs_descs;
} __attribute__((packed));
struct desc_v2 {
struct usb_functionfs_descs_head_v2 {
__le32 magic;
__le32 length;
__le32 flags;
__le32 fs_count;
__le32 hs_count;
__le32 ss_count;
} __attribute__((packed)) header;
struct func_desc fs_descs, hs_descs;
} __attribute__((packed));
/*static const struct {
struct usb_functionfs_descs_head header; struct usb_functionfs_descs_head header;
struct { struct {
struct usb_interface_descriptor intf; struct usb_interface_descriptor intf;
@ -66,57 +94,60 @@ static const struct {
.fs_count = 3, .fs_count = 3,
.hs_count = 3, .hs_count = 3,
}, },
.fs_descs = {
.intf = { */
.bLength = sizeof(descriptors.fs_descs.intf),
.bDescriptorType = USB_DT_INTERFACE, struct func_desc fs_descriptors = {
.bInterfaceNumber = 0, .intf = {
.bNumEndpoints = 2, .bLength = sizeof(fs_descriptors.intf),
.bInterfaceClass = ADB_CLASS, .bDescriptorType = USB_DT_INTERFACE,
.bInterfaceSubClass = ADB_SUBCLASS, .bInterfaceNumber = 0,
.bInterfaceProtocol = ADB_PROTOCOL, .bNumEndpoints = 2,
.iInterface = 1, /* first string from the provided table */ .bInterfaceClass = ADB_CLASS,
}, .bInterfaceSubClass = ADB_SUBCLASS,
.source = { .bInterfaceProtocol = ADB_PROTOCOL,
.bLength = sizeof(descriptors.fs_descs.source), .iInterface = 1, /* first string from the provided table */
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 1 | USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = MAX_PACKET_SIZE_FS,
},
.sink = {
.bLength = sizeof(descriptors.fs_descs.sink),
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 2 | USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = MAX_PACKET_SIZE_FS,
},
}, },
.hs_descs = { .source = {
.intf = { .bLength = sizeof(fs_descriptors.source),
.bLength = sizeof(descriptors.hs_descs.intf), .bDescriptorType = USB_DT_ENDPOINT,
.bDescriptorType = USB_DT_INTERFACE, .bEndpointAddress = 1 | USB_DIR_OUT,
.bInterfaceNumber = 0, .bmAttributes = USB_ENDPOINT_XFER_BULK,
.bNumEndpoints = 2, .wMaxPacketSize = MAX_PACKET_SIZE_FS,
.bInterfaceClass = ADB_CLASS, },
.bInterfaceSubClass = ADB_SUBCLASS, .sink = {
.bInterfaceProtocol = ADB_PROTOCOL, .bLength = sizeof(fs_descriptors.sink),
.iInterface = 1, /* first string from the provided table */ .bDescriptorType = USB_DT_ENDPOINT,
}, .bEndpointAddress = 2 | USB_DIR_IN,
.source = { .bmAttributes = USB_ENDPOINT_XFER_BULK,
.bLength = sizeof(descriptors.hs_descs.source), .wMaxPacketSize = MAX_PACKET_SIZE_FS,
.bDescriptorType = USB_DT_ENDPOINT, },
.bEndpointAddress = 1 | USB_DIR_OUT, };
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = MAX_PACKET_SIZE_HS, struct func_desc hs_descriptors = {
}, .intf = {
.sink = { .bLength = sizeof(hs_descriptors.intf),
.bLength = sizeof(descriptors.hs_descs.sink), .bDescriptorType = USB_DT_INTERFACE,
.bDescriptorType = USB_DT_ENDPOINT, .bInterfaceNumber = 0,
.bEndpointAddress = 2 | USB_DIR_IN, .bNumEndpoints = 2,
.bmAttributes = USB_ENDPOINT_XFER_BULK, .bInterfaceClass = ADB_CLASS,
.wMaxPacketSize = MAX_PACKET_SIZE_HS, .bInterfaceSubClass = ADB_SUBCLASS,
}, .bInterfaceProtocol = ADB_PROTOCOL,
.iInterface = 1, /* first string from the provided table */
},
.source = {
.bLength = sizeof(hs_descriptors.source),
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 1 | USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = MAX_PACKET_SIZE_HS,
},
.sink = {
.bLength = sizeof(hs_descriptors.sink),
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 2 | USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = MAX_PACKET_SIZE_HS,
}, },
}; };
@ -267,6 +298,18 @@ static void usb_adb_init()
static void init_functionfs(struct usb_handle *h) static void init_functionfs(struct usb_handle *h)
{ {
ssize_t ret; ssize_t ret;
struct desc_v1 v1_descriptor;
struct desc_v2 v2_descriptor;
v2_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2);
v2_descriptor.header.length = cpu_to_le32(sizeof(v2_descriptor));
v2_descriptor.header.flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC;
v2_descriptor.header.fs_count = 3;
v2_descriptor.header.hs_count = 3;
v2_descriptor.header.ss_count = 0;
v2_descriptor.fs_descs = fs_descriptors;
v2_descriptor.hs_descs = hs_descriptors;
D("OPENING %s\n", USB_FFS_ADB_EP0); D("OPENING %s\n", USB_FFS_ADB_EP0);
h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR); h->control = adb_open(USB_FFS_ADB_EP0, O_RDWR);
@ -275,10 +318,20 @@ static void init_functionfs(struct usb_handle *h)
goto err; goto err;
} }
ret = adb_write(h->control, &descriptors, sizeof(descriptors)); ret = adb_write(h->control, &v2_descriptor, sizeof(v2_descriptor));
if (ret < 0) { if (ret < 0) {
D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno); v1_descriptor.header.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC);
goto err; v1_descriptor.header.length = cpu_to_le32(sizeof(v1_descriptor));
v1_descriptor.header.fs_count = 3;
v1_descriptor.header.hs_count = 3;
v1_descriptor.fs_descs = fs_descriptors;
v1_descriptor.hs_descs = hs_descriptors;
D("[ %s: Switching to V1_descriptor format errno=%d ]\n", USB_FFS_ADB_EP0, errno);
ret = adb_write(h->control, &v1_descriptor, sizeof(v1_descriptor));
if (ret < 0) {
D("[ %s: write descriptors failed: errno=%d ]\n", USB_FFS_ADB_EP0, errno);
goto err;
}
} }
ret = adb_write(h->control, &strings, sizeof(strings)); ret = adb_write(h->control, &strings, sizeof(strings));