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:
parent
ea0bdf2d54
commit
bd6901e18f
|
@ -138,6 +138,14 @@ static void chipidea_halt_ep(struct usbdev_ctrl *this, int ep, int in_dir)
|
|||
while (readl(&p->opreg->epflush))
|
||||
;
|
||||
clrbits_le32(&p->opreg->epctrl[ep], 1 << (7 + (in_dir ? 16 : 0)));
|
||||
|
||||
while (!SIMPLEQ_EMPTY(&p->job_queue[ep][in_dir])) {
|
||||
struct job *job = SIMPLEQ_FIRST(&p->job_queue[ep][in_dir]);
|
||||
if (job->autofree)
|
||||
free(job->data);
|
||||
|
||||
SIMPLEQ_REMOVE_HEAD(&p->job_queue[ep][in_dir], queue);
|
||||
}
|
||||
}
|
||||
|
||||
static void chipidea_start_ep(struct usbdev_ctrl *this,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue