Skip to content
This repository has been archived by the owner on Oct 5, 2018. It is now read-only.

Usb negotiation #137

Open
wants to merge 3 commits into
base: hikey
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -2131,8 +2131,14 @@ void usb_disconnect(struct usb_device **pdev)
* this quiesces everything except pending urbs.
*/
usb_set_device_state(udev, USB_STATE_NOTATTACHED);
dev_info(&udev->dev, "USB disconnect, device number %d\n",
udev->devnum);
dev_info(&udev->dev, "USB disconnect, device number %d running at %s\n",
udev->devnum, usb_speed_string(udev->speed));

if (udev->speed < USB_SPEED_HIGH ) {
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
if (hcd->driver->change_bus_speed)
hcd->driver->change_bus_speed(hcd, 0);
}

usb_lock_device(udev);

Expand Down Expand Up @@ -4621,6 +4627,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
struct usb_port *port_dev = hub->ports[port1 - 1];
struct usb_device *udev = port_dev->child;
static int unreliable_port = -1;
unsigned long speed = USB_SPEED_SUPER;

/* Disconnect any existing devices under this port */
if (udev) {
Expand Down Expand Up @@ -4704,6 +4711,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
/* reset (non-USB 3.0 devices) and get descriptor */
usb_lock_port(port_dev);
status = hub_port_init(hub, udev, port1, i);
speed = udev->speed;
usb_unlock_port(port_dev);
if (status < 0)
goto loop;
Expand Down Expand Up @@ -4808,9 +4816,18 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
if (hub->hdev->parent ||
!hcd->driver->port_handed_over ||
!(hcd->driver->port_handed_over)(hcd, port1)) {
if (status != -ENOTCONN && status != -ENODEV)
dev_err(&port_dev->dev,
"unable to enumerate USB device\n");
if (status != -ENOTCONN && status != -ENODEV) {
dev_err(&port_dev->dev, "unable to enumerate USB device"
" at %s while bus at %s \n",
usb_speed_string(speed),
hdev->descriptor.bDeviceProtocol == USB_HUB_PR_FS ?
"FULL_SPEED" : "HIGH_SPEED");

if (speed < USB_SPEED_HIGH &&
hdev->descriptor.bDeviceProtocol > USB_HUB_PR_FS &&
hcd->driver->change_bus_speed)
hcd->driver->change_bus_speed(hcd, 1);
}
}

done:
Expand Down
43 changes: 31 additions & 12 deletions drivers/usb/dwc2/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@
#include "core.h"
#include "hcd.h"

struct wrapper_priv_data {
struct dwc2_hsotg *hsotg;
};

/* Gets the dwc2_hsotg from a usb_hcd */
static struct dwc2_hsotg *dwc2_hcd_to_hsotg(struct usb_hcd *hcd)
{
struct wrapper_priv_data *p;

p = (struct wrapper_priv_data *) &hcd->hcd_priv;
return p->hsotg;
}

/**
* dwc2_dump_channel_info() - Prints the state of a host channel
*
Expand Down Expand Up @@ -1339,6 +1352,23 @@ void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg,
}
}
}
/*
* 0: high speed
* 1: full speed
*/
static void dwc2_change_bus_speed(struct usb_hcd* hcd, int speed)
{
struct dwc2_hsotg *hsotg = dwc2_hcd_to_hsotg(hcd);
static int last_speed = 0;

if (speed == last_speed)
return;

hsotg->core_params->speed = speed;
queue_work(hsotg->wq_otg, &hsotg->wf_otg);

last_speed = speed;
}

static void dwc2_conn_id_status_change(struct work_struct *work)
{
Expand Down Expand Up @@ -2064,18 +2094,6 @@ void dwc2_hcd_dump_frrem(struct dwc2_hsotg *hsotg)
#endif
}

struct wrapper_priv_data {
struct dwc2_hsotg *hsotg;
};

/* Gets the dwc2_hsotg from a usb_hcd */
static struct dwc2_hsotg *dwc2_hcd_to_hsotg(struct usb_hcd *hcd)
{
struct wrapper_priv_data *p;

p = (struct wrapper_priv_data *) &hcd->hcd_priv;
return p->hsotg;
}

static int _dwc2_hcd_start(struct usb_hcd *hcd);

Expand Down Expand Up @@ -2676,6 +2694,7 @@ static struct hc_driver dwc2_hc_driver = {
.hub_status_data = _dwc2_hcd_hub_status_data,
.hub_control = _dwc2_hcd_hub_control,
.clear_tt_buffer_complete = _dwc2_hcd_clear_tt_buffer_complete,
.change_bus_speed = dwc2_change_bus_speed,
};

/*
Expand Down
4 changes: 2 additions & 2 deletions drivers/usb/dwc2/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ static const struct dwc2_core_params params_hisi = {
.otg_ver = 0, /* 1.3 */
.dma_enable = 1,
.dma_desc_enable = 0,
// .speed = 0, /* High Speed */
.speed = 1, /* Full Speed */
.speed = 0, /* High Speed */
// .speed = 1, /* Full Speed */
.enable_dynamic_fifo = 1,
.en_multiple_tx_fifo = 1,
.host_rx_fifo_size = 512,
Expand Down
1 change: 1 addition & 0 deletions include/linux/usb/hcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ struct hc_driver {
int (*disable_usb3_lpm_timeout)(struct usb_hcd *,
struct usb_device *, enum usb3_link_state state);
int (*find_raw_port_number)(struct usb_hcd *, int);
void (*change_bus_speed)(struct usb_hcd*, int);
};

static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd)
Expand Down