am 83b4047b: Merge "adbd & fastbootd: Support for new f_fs descriptor format"

* commit '83b4047bc66729f8cf854c525e2bc8bac7c9587e':
  adbd & fastbootd: Support for new f_fs descriptor format
This commit is contained in:
Elliott Hughes 2014-12-10 02:32:00 +00:00 committed by Android Git Automerger
commit c162dbb2ff
2 changed files with 202 additions and 180 deletions

View file

@ -56,119 +56,85 @@ 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 {
__le32 magic; struct usb_interface_descriptor intf;
__le32 length; struct usb_endpoint_descriptor_no_audio source;
__le32 flags; struct usb_endpoint_descriptor_no_audio sink;
__le32 fs_count; } __attribute__((packed));
__le32 hs_count;
__le32 ss_count; struct desc_v1 {
struct { struct usb_functionfs_descs_head_v1 {
struct usb_interface_descriptor intf; __le32 magic;
struct usb_endpoint_descriptor_no_audio source; __le32 length;
struct usb_endpoint_descriptor_no_audio sink; __le32 fs_count;
} __attribute__((packed)) fs_descs, hs_descs; __le32 hs_count;
struct { } __attribute__((packed)) header;
struct usb_interface_descriptor intf; struct func_desc fs_descs, hs_descs;
struct usb_endpoint_descriptor_no_audio source; } __attribute__((packed));
struct usb_ss_ep_comp_descriptor source_comp;
struct usb_endpoint_descriptor_no_audio sink; struct desc_v2 {
struct usb_ss_ep_comp_descriptor sink_comp; struct usb_functionfs_descs_head_v2 {
} __attribute__((packed)) ss_descs; __le32 magic;
} __attribute__((packed)) descriptors = { __le32 length;
.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2), __le32 flags;
.length = cpu_to_le32(sizeof(descriptors)), __le32 fs_count;
.flags = cpu_to_le32(FUNCTIONFS_HAS_FS_DESC | __le32 hs_count;
FUNCTIONFS_HAS_HS_DESC | __le32 ss_count;
FUNCTIONFS_HAS_SS_DESC), } __attribute__((packed)) header;
.fs_count = 3, struct func_desc fs_descs, hs_descs;
.hs_count = 3, } __attribute__((packed));
.ss_count = 5,
.fs_descs = { struct func_desc fs_descriptors = {
.intf = { .intf = {
.bLength = sizeof(descriptors.fs_descs.intf), .bLength = sizeof(fs_descriptors.intf),
.bDescriptorType = USB_DT_INTERFACE, .bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0, .bInterfaceNumber = 0,
.bNumEndpoints = 2, .bNumEndpoints = 2,
.bInterfaceClass = ADB_CLASS, .bInterfaceClass = ADB_CLASS,
.bInterfaceSubClass = ADB_SUBCLASS, .bInterfaceSubClass = ADB_SUBCLASS,
.bInterfaceProtocol = ADB_PROTOCOL, .bInterfaceProtocol = ADB_PROTOCOL,
.iInterface = 1, /* first string from the provided table */ .iInterface = 1, /* first string from the provided table */
},
.source = {
.bLength = sizeof(descriptors.fs_descs.source),
.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,
.bInterfaceProtocol = ADB_PROTOCOL,
.iInterface = 1, /* first string from the provided table */
},
.source = {
.bLength = sizeof(descriptors.hs_descs.source),
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 1 | USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = MAX_PACKET_SIZE_HS,
},
.sink = {
.bLength = sizeof(descriptors.hs_descs.sink),
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 2 | USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = MAX_PACKET_SIZE_HS,
},
}, },
.ss_descs = { .sink = {
.intf = { .bLength = sizeof(fs_descriptors.sink),
.bLength = sizeof(descriptors.ss_descs.intf), .bDescriptorType = USB_DT_ENDPOINT,
.bDescriptorType = USB_DT_INTERFACE, .bEndpointAddress = 2 | USB_DIR_IN,
.bInterfaceNumber = 0, .bmAttributes = USB_ENDPOINT_XFER_BULK,
.bNumEndpoints = 2, .wMaxPacketSize = MAX_PACKET_SIZE_FS,
.bInterfaceClass = ADB_CLASS, },
.bInterfaceSubClass = ADB_SUBCLASS, };
.bInterfaceProtocol = ADB_PROTOCOL,
.iInterface = 1, /* first string from the provided table */ struct func_desc hs_descriptors = {
}, .intf = {
.source = { .bLength = sizeof(hs_descriptors.intf),
.bLength = sizeof(descriptors.ss_descs.source), .bDescriptorType = USB_DT_INTERFACE,
.bDescriptorType = USB_DT_ENDPOINT, .bInterfaceNumber = 0,
.bEndpointAddress = 1 | USB_DIR_OUT, .bNumEndpoints = 2,
.bmAttributes = USB_ENDPOINT_XFER_BULK, .bInterfaceClass = ADB_CLASS,
.wMaxPacketSize = MAX_PACKET_SIZE_SS, .bInterfaceSubClass = ADB_SUBCLASS,
}, .bInterfaceProtocol = ADB_PROTOCOL,
.source_comp = { .iInterface = 1, /* first string from the provided table */
.bLength = sizeof(descriptors.ss_descs.source_comp), },
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP, .source = {
}, .bLength = sizeof(hs_descriptors.source),
.sink = { .bDescriptorType = USB_DT_ENDPOINT,
.bLength = sizeof(descriptors.ss_descs.sink), .bEndpointAddress = 1 | USB_DIR_OUT,
.bDescriptorType = USB_DT_ENDPOINT, .bmAttributes = USB_ENDPOINT_XFER_BULK,
.bEndpointAddress = 2 | USB_DIR_IN, .wMaxPacketSize = MAX_PACKET_SIZE_HS,
.bmAttributes = USB_ENDPOINT_XFER_BULK, },
.wMaxPacketSize = MAX_PACKET_SIZE_SS, .sink = {
}, .bLength = sizeof(hs_descriptors.sink),
.sink_comp = { .bDescriptorType = USB_DT_ENDPOINT,
.bLength = sizeof(descriptors.ss_descs.sink_comp), .bEndpointAddress = 2 | USB_DIR_IN,
.bDescriptorType = USB_DT_SS_ENDPOINT_COMP, .bmAttributes = USB_ENDPOINT_XFER_BULK,
}, .wMaxPacketSize = MAX_PACKET_SIZE_HS,
}, },
}; };
@ -312,6 +278,17 @@ 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;
if (h->control < 0) { // might have already done this before if (h->control < 0) { // might have already done this before
D("OPENING %s\n", USB_FFS_ADB_EP0); D("OPENING %s\n", USB_FFS_ADB_EP0);
@ -321,10 +298,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));

View file

@ -69,71 +69,85 @@ struct usb_handle {
struct transport_handle handle; struct transport_handle handle;
}; };
static const struct { struct func_desc {
struct usb_functionfs_descs_head header; struct usb_interface_descriptor intf;
struct { struct usb_endpoint_descriptor_no_audio source;
struct usb_interface_descriptor intf; struct usb_endpoint_descriptor_no_audio sink;
struct usb_endpoint_descriptor_no_audio source; } __attribute__((packed));
struct usb_endpoint_descriptor_no_audio sink;
} __attribute__((packed)) fs_descs, hs_descs; struct desc_v1 {
} __attribute__((packed)) descriptors = { struct usb_functionfs_descs_head_v1 {
.header = { __le32 magic;
.magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC), __le32 length;
.length = cpu_to_le32(sizeof(descriptors)), __le32 fs_count;
.fs_count = 3, __le32 hs_count;
.hs_count = 3, } __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));
struct func_desc fs_descriptors = {
.intf = {
.bLength = sizeof(fs_descriptors.intf),
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = 0,
.bNumEndpoints = 2,
.bInterfaceClass = ADB_CLASS,
.bInterfaceSubClass = ADB_SUBCLASS,
.bInterfaceProtocol = ADB_PROTOCOL,
.iInterface = 1, /* first string from the provided table */
}, },
.fs_descs = { .source = {
.intf = { .bLength = sizeof(fs_descriptors.source),
.bLength = sizeof(descriptors.fs_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 = FASTBOOT_CLASS,
.bInterfaceSubClass = FASTBOOT_SUBCLASS,
.bInterfaceProtocol = FASTBOOT_PROTOCOL,
.iInterface = 1, /* first string from the provided table */
},
.source = {
.bLength = sizeof(descriptors.fs_descs.source),
.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 = { .sink = {
.intf = { .bLength = sizeof(fs_descriptors.sink),
.bLength = sizeof(descriptors.hs_descs.intf), .bDescriptorType = USB_DT_ENDPOINT,
.bDescriptorType = USB_DT_INTERFACE, .bEndpointAddress = 2 | USB_DIR_IN,
.bInterfaceNumber = 0, .bmAttributes = USB_ENDPOINT_XFER_BULK,
.bNumEndpoints = 2, .wMaxPacketSize = MAX_PACKET_SIZE_FS,
.bInterfaceClass = FASTBOOT_CLASS, },
.bInterfaceSubClass = FASTBOOT_SUBCLASS, };
.bInterfaceProtocol = FASTBOOT_PROTOCOL,
.iInterface = 1, /* first string from the provided table */ struct func_desc hs_descriptors = {
}, .intf = {
.source = { .bLength = sizeof(hs_descriptors.intf),
.bLength = sizeof(descriptors.hs_descs.source), .bDescriptorType = USB_DT_INTERFACE,
.bDescriptorType = USB_DT_ENDPOINT, .bInterfaceNumber = 0,
.bEndpointAddress = 1 | USB_DIR_OUT, .bNumEndpoints = 2,
.bmAttributes = USB_ENDPOINT_XFER_BULK, .bInterfaceClass = ADB_CLASS,
.wMaxPacketSize = MAX_PACKET_SIZE_HS, .bInterfaceSubClass = ADB_SUBCLASS,
}, .bInterfaceProtocol = ADB_PROTOCOL,
.sink = { .iInterface = 1, /* first string from the provided table */
.bLength = sizeof(descriptors.hs_descs.sink), },
.bDescriptorType = USB_DT_ENDPOINT, .source = {
.bEndpointAddress = 2 | USB_DIR_IN, .bLength = sizeof(hs_descriptors.source),
.bmAttributes = USB_ENDPOINT_XFER_BULK, .bDescriptorType = USB_DT_ENDPOINT,
.wMaxPacketSize = MAX_PACKET_SIZE_HS, .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,
}, },
}; };
@ -161,6 +175,17 @@ static const struct {
static int init_functionfs(struct usb_transport *usb_transport) static int init_functionfs(struct usb_transport *usb_transport)
{ {
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(VERBOSE, "OPENING %s", USB_FFS_FASTBOOT_EP0); D(VERBOSE, "OPENING %s", USB_FFS_FASTBOOT_EP0);
usb_transport->control = open(USB_FFS_FASTBOOT_EP0, O_RDWR); usb_transport->control = open(USB_FFS_FASTBOOT_EP0, O_RDWR);
@ -169,10 +194,20 @@ static int init_functionfs(struct usb_transport *usb_transport)
goto err; goto err;
} }
ret = write(usb_transport->control, &descriptors, sizeof(descriptors)); ret = write(usb_transport->control, &v2_descriptor, sizeof(v2_descriptor));
if (ret < 0) { if (ret < 0) {
D(ERR, "[ %s: write descriptors failed: errno=%d ]", USB_FFS_FASTBOOT_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_FASTBOOT_EP0, errno);
ret = write(usb_transport->control, &v1_descriptor, sizeof(v1_descriptor));
if (ret < 0) {
D(ERR, "[ %s: write descriptors failed: errno=%d ]", USB_FFS_FASTBOOT_EP0, errno);
goto err;
}
} }
ret = write(usb_transport->control, &strings, sizeof(strings)); ret = write(usb_transport->control, &strings, sizeof(strings));