summaryrefslogtreecommitdiffstats
path: root/fastbootd/usb_linux_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'fastbootd/usb_linux_client.c')
-rw-r--r--fastbootd/usb_linux_client.c308
1 files changed, 0 insertions, 308 deletions
diff --git a/fastbootd/usb_linux_client.c b/fastbootd/usb_linux_client.c
deleted file mode 100644
index 64420e9..0000000
--- a/fastbootd/usb_linux_client.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <endian.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <sys/ioctl.h>
-#include <sys/types.h>
-
-#include <linux/usb/ch9.h>
-#include <linux/usb/functionfs.h>
-
-#include "debug.h"
-#include "transport.h"
-#include "utils.h"
-
-#define TRACE_TAG TRACE_USB
-
-#define MAX_PACKET_SIZE_FS 64
-#define MAX_PACKET_SIZE_HS 512
-
-#define cpu_to_le16(x) htole16(x)
-#define cpu_to_le32(x) htole32(x)
-
-#define FASTBOOT_CLASS 0xff
-#define FASTBOOT_SUBCLASS 0x42
-#define FASTBOOT_PROTOCOL 0x3
-
-#define USB_FFS_FASTBOOT_PATH "/dev/usb-ffs/adb/"
-#define USB_FFS_FASTBOOT_EP(x) USB_FFS_FASTBOOT_PATH#x
-
-#define USB_FFS_FASTBOOT_EP0 USB_FFS_FASTBOOT_EP(ep0)
-#define USB_FFS_FASTBOOT_OUT USB_FFS_FASTBOOT_EP(ep1)
-#define USB_FFS_FASTBOOT_IN USB_FFS_FASTBOOT_EP(ep2)
-
-#define container_of(ptr, type, member) \
- ((type*)((char*)(ptr) - offsetof(type, member)))
-
-struct usb_transport {
- struct transport transport;
-
- pthread_cond_t notify;
- pthread_mutex_t lock;
-
- int control;
- int bulk_out; /* "out" from the host's perspective => source for fastbootd */
- int bulk_in; /* "in" from the host's perspective => sink for fastbootd */
-};
-
-struct usb_handle {
- struct transport_handle handle;
-};
-
-static const struct {
- struct usb_functionfs_descs_head header;
- struct {
- struct usb_interface_descriptor intf;
- struct usb_endpoint_descriptor_no_audio source;
- struct usb_endpoint_descriptor_no_audio sink;
- } __attribute__((packed)) fs_descs, hs_descs;
-} __attribute__((packed)) descriptors = {
- .header = {
- .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC),
- .length = cpu_to_le32(sizeof(descriptors)),
- .fs_count = 3,
- .hs_count = 3,
- },
- .fs_descs = {
- .intf = {
- .bLength = sizeof(descriptors.fs_descs.intf),
- .bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = 0,
- .bNumEndpoints = 2,
- .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 = {
- .intf = {
- .bLength = sizeof(descriptors.hs_descs.intf),
- .bDescriptorType = USB_DT_INTERFACE,
- .bInterfaceNumber = 0,
- .bNumEndpoints = 2,
- .bInterfaceClass = FASTBOOT_CLASS,
- .bInterfaceSubClass = FASTBOOT_SUBCLASS,
- .bInterfaceProtocol = FASTBOOT_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,
- },
- },
-};
-
-#define STR_INTERFACE_ "Fastboot Interface"
-
-static const struct {
- struct usb_functionfs_strings_head header;
- struct {
- __le16 code;
- const char str1[sizeof(STR_INTERFACE_)];
- } __attribute__((packed)) lang0;
-} __attribute__((packed)) strings = {
- .header = {
- .magic = cpu_to_le32(FUNCTIONFS_STRINGS_MAGIC),
- .length = cpu_to_le32(sizeof(strings)),
- .str_count = cpu_to_le32(1),
- .lang_count = cpu_to_le32(1),
- },
- .lang0 = {
- cpu_to_le16(0x0409), /* en-us */
- STR_INTERFACE_,
- },
-};
-
-static int init_functionfs(struct usb_transport *usb_transport)
-{
- ssize_t ret;
-
- D(VERBOSE, "OPENING %s", USB_FFS_FASTBOOT_EP0);
- usb_transport->control = open(USB_FFS_FASTBOOT_EP0, O_RDWR);
- if (usb_transport->control < 0) {
- D(ERR, "[ %s: cannot open control endpoint: errno=%d]", USB_FFS_FASTBOOT_EP0, errno);
- goto err;
- }
-
- ret = write(usb_transport->control, &descriptors, sizeof(descriptors));
- 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));
- if (ret < 0) {
- D(ERR, "[ %s: writing strings failed: errno=%d]", USB_FFS_FASTBOOT_EP0, errno);
- goto err;
- }
-
- usb_transport->bulk_out = open(USB_FFS_FASTBOOT_OUT, O_RDWR);
- if (usb_transport->bulk_out < 0) {
- D(ERR, "[ %s: cannot open bulk-out ep: errno=%d ]", USB_FFS_FASTBOOT_OUT, errno);
- goto err;
- }
-
- usb_transport->bulk_in = open(USB_FFS_FASTBOOT_IN, O_RDWR);
- if (usb_transport->bulk_in < 0) {
- D(ERR, "[ %s: cannot open bulk-in ep: errno=%d ]", USB_FFS_FASTBOOT_IN, errno);
- goto err;
- }
-
- return 0;
-
-err:
- if (usb_transport->bulk_in > 0) {
- close(usb_transport->bulk_in);
- usb_transport->bulk_in = -1;
- }
- if (usb_transport->bulk_out > 0) {
- close(usb_transport->bulk_out);
- usb_transport->bulk_out = -1;
- }
- if (usb_transport->control > 0) {
- close(usb_transport->control);
- usb_transport->control = -1;
- }
- return -1;
-}
-
-static ssize_t usb_write(struct transport_handle *thandle, const void *data, size_t len)
-{
- ssize_t ret;
- struct transport *t = thandle->transport;
- struct usb_transport *usb_transport = container_of(t, struct usb_transport, transport);
-
- D(DEBUG, "about to write (fd=%d, len=%zu)", usb_transport->bulk_in, len);
- ret = bulk_write(usb_transport->bulk_in, data, len);
- if (ret < 0) {
- D(ERR, "ERROR: fd = %d, ret = %zd", usb_transport->bulk_in, ret);
- return -1;
- }
- D(DEBUG, "[ usb_write done fd=%d ]", usb_transport->bulk_in);
- return ret;
-}
-
-ssize_t usb_read(struct transport_handle *thandle, void *data, size_t len)
-{
- ssize_t ret;
- struct transport *t = thandle->transport;
- struct usb_transport *usb_transport = container_of(t, struct usb_transport, transport);
-
- D(DEBUG, "about to read (fd=%d, len=%zu)", usb_transport->bulk_out, len);
- ret = bulk_read(usb_transport->bulk_out, data, len);
- if (ret < 0) {
- D(ERR, "ERROR: fd = %d, ret = %zd", usb_transport->bulk_out, ret);
- return -1;
- }
- D(DEBUG, "[ usb_read done fd=%d ret=%zd]", usb_transport->bulk_out, ret);
- return ret;
-}
-
-void usb_close(struct transport_handle *thandle)
-{
- int err;
- struct transport *t = thandle->transport;
- struct usb_transport *usb_transport = container_of(t, struct usb_transport, transport);
-
- err = ioctl(usb_transport->bulk_in, FUNCTIONFS_CLEAR_HALT);
- if (err < 0)
- D(WARN, "[ kick: source (fd=%d) clear halt failed (%d) ]", usb_transport->bulk_in, errno);
-
- err = ioctl(usb_transport->bulk_out, FUNCTIONFS_CLEAR_HALT);
- if (err < 0)
- D(WARN, "[ kick: sink (fd=%d) clear halt failed (%d) ]", usb_transport->bulk_out, errno);
-
- pthread_mutex_lock(&usb_transport->lock);
- close(usb_transport->control);
- close(usb_transport->bulk_out);
- close(usb_transport->bulk_in);
- usb_transport->control = usb_transport->bulk_out = usb_transport->bulk_in = -1;
-
- pthread_cond_signal(&usb_transport->notify);
- pthread_mutex_unlock(&usb_transport->lock);
-}
-
-struct transport_handle *usb_connect(struct transport *transport)
-{
- int ret;
- struct usb_handle *usb_handle = calloc(sizeof(struct usb_handle), 1);
- struct usb_transport *usb_transport = container_of(transport, struct usb_transport, transport);
-
- pthread_mutex_lock(&usb_transport->lock);
- while (usb_transport->control != -1)
- pthread_cond_wait(&usb_transport->notify, &usb_transport->lock);
- pthread_mutex_unlock(&usb_transport->lock);
-
- ret = init_functionfs(usb_transport);
- if (ret < 0) {
- D(ERR, "usb connect: failed to initialize usb transport");
- return NULL;
- }
-
- D(DEBUG, "[ usb_thread - registering device ]");
- return &usb_handle->handle;
-}
-
-void usb_init()
-{
- struct usb_transport *usb_transport = calloc(1, sizeof(struct usb_transport));
-
- usb_transport->transport.connect = usb_connect;
- usb_transport->transport.close = usb_close;
- usb_transport->transport.read = usb_read;
- usb_transport->transport.write = usb_write;
- usb_transport->control = -1;
- usb_transport->bulk_out = -1;
- usb_transport->bulk_out = -1;
-
- pthread_cond_init(&usb_transport->notify, NULL);
- pthread_mutex_init(&usb_transport->lock, NULL);
-
- transport_register(&usb_transport->transport);
-}
-