libpayload udc: Deconfigure device when necessary

SET_CONFIGURATION(0) stops operation and is moves the
device to addressed mode.

BRANCH=none
BUG=none
TEST=USB device mode still works

Change-Id: I964d90ba8440b6f428896acc9fe63e1114390da6
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 402bc907222d07765b3438967edf26cc1a79d775
Original-Change-Id: Iebad024e1ed2e344dba73b73a9b385a4ac4cb450
Original-Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/250791
Original-Reviewed-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-on: http://review.coreboot.org/9785
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Patrick Georgi
2015-02-16 17:00:59 +01:00
parent ea0bdf2d54
commit bd6901e18f
2 changed files with 21 additions and 7 deletions

View File

@ -81,12 +81,8 @@ static struct usbdev_configuration *fetch_config(struct usbdev_ctrl *this,
return NULL;
}
static void enable_interface(struct usbdev_ctrl *this, int iface_num)
static void cease_operation(struct usbdev_ctrl *this)
{
struct usbdev_configuration *config = this->current_config;
struct usbdev_interface *iface = &config->interfaces[iface_num];
/* first: shut down all endpoints except EP0 */
int i;
for (i = 1; i < 16; i++) {
/* disable endpoints */
@ -94,8 +90,19 @@ static void enable_interface(struct usbdev_ctrl *this, int iface_num)
this->halt_ep(this, i, 1);
}
}
static void enable_interface(struct usbdev_ctrl *this, int iface_num)
{
struct usbdev_configuration *config = this->current_config;
struct usbdev_interface *iface = &config->interfaces[iface_num];
/* first: shut down all endpoints except EP0 */
cease_operation(this);
/* now enable all configured endpoints */
int epcount = iface->descriptor.bNumEndpoints;
int i;
for (i = 0; i < epcount; i++) {
int ep = iface->eps[i].bEndpointAddress;
int mps = iface->eps[i].wMaxPacketSize;
@ -139,8 +146,7 @@ static int setup_ep0(struct usbdev_ctrl *this, dev_req_t *dr)
this->current_config_id = dr->wValue;
if (dr->wValue == 0)
// TODO: reset device
return 1;
cease_operation(this);
if (config == NULL) {
this->stall(this, 0, 0, 1);