usbdevice/core: add reset function to support hotplug
When the USB got RESET packet from the host and the address is setup, all the classes will got reset. The reset is done by class stop and than class run. So the classes should reset their internal state in class_{run,stop}. Besides, the USB device driver could post a USB_MSG_RESET message on every RESET packet.
This commit is contained in:
parent
046182be94
commit
97a507e667
|
@ -145,6 +145,7 @@ enum udev_msg_type
|
||||||
USB_MSG_SETUP_NOTIFY,
|
USB_MSG_SETUP_NOTIFY,
|
||||||
USB_MSG_DATA_NOTIFY,
|
USB_MSG_DATA_NOTIFY,
|
||||||
USB_MSG_SOF,
|
USB_MSG_SOF,
|
||||||
|
USB_MSG_RESET,
|
||||||
};
|
};
|
||||||
typedef enum udev_msg_type udev_msg_type;
|
typedef enum udev_msg_type udev_msg_type;
|
||||||
|
|
||||||
|
|
|
@ -241,7 +241,7 @@ static rt_err_t _set_interface(struct udevice* device, ureq_t setup)
|
||||||
dcd_ep_stall(device->dcd, 0);
|
dcd_ep_stall(device->dcd, 0);
|
||||||
return -RT_ERROR;
|
return -RT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find the specified interface */
|
/* find the specified interface */
|
||||||
intf = rt_usbd_find_interface(device, setup->index & 0xFF, RT_NULL);
|
intf = rt_usbd_find_interface(device, setup->index & 0xFF, RT_NULL);
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ static rt_err_t _get_config(struct udevice* device, ureq_t setup)
|
||||||
RT_ASSERT(device->curr_cfg != RT_NULL);
|
RT_ASSERT(device->curr_cfg != RT_NULL);
|
||||||
|
|
||||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("_get_config\n"));
|
RT_DEBUG_LOG(RT_DEBUG_USB, ("_get_config\n"));
|
||||||
|
|
||||||
if (device->state == USB_STATE_CONFIGURED)
|
if (device->state == USB_STATE_CONFIGURED)
|
||||||
{
|
{
|
||||||
/* get current configuration */
|
/* get current configuration */
|
||||||
|
@ -318,7 +318,7 @@ static rt_err_t _set_config(struct udevice* device, ureq_t setup)
|
||||||
|
|
||||||
if (setup->value > device->dev_desc.bNumConfigurations)
|
if (setup->value > device->dev_desc.bNumConfigurations)
|
||||||
{
|
{
|
||||||
dcd_ep_stall(device->dcd, 0);
|
dcd_ep_stall(device->dcd, 0);
|
||||||
return -RT_ERROR;
|
return -RT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,9 +383,9 @@ static rt_err_t _set_address(struct udevice* device, ureq_t setup)
|
||||||
|
|
||||||
/* set address in device control driver */
|
/* set address in device control driver */
|
||||||
dcd_set_address(device->dcd, setup->value);
|
dcd_set_address(device->dcd, setup->value);
|
||||||
|
|
||||||
device->state = USB_STATE_ADDRESS;
|
device->state = USB_STATE_ADDRESS;
|
||||||
|
|
||||||
/* issue status stage */
|
/* issue status stage */
|
||||||
dcd_send_status(device->dcd);
|
dcd_send_status(device->dcd);
|
||||||
|
|
||||||
|
@ -412,7 +412,7 @@ static rt_err_t _request_interface(struct udevice* device, ureq_t setup)
|
||||||
RT_ASSERT(setup != RT_NULL);
|
RT_ASSERT(setup != RT_NULL);
|
||||||
|
|
||||||
RT_DEBUG_LOG(RT_DEBUG_USB, ("_request_interface\n"));
|
RT_DEBUG_LOG(RT_DEBUG_USB, ("_request_interface\n"));
|
||||||
|
|
||||||
intf = rt_usbd_find_interface(device, setup->index & 0xFF, &cls);
|
intf = rt_usbd_find_interface(device, setup->index & 0xFF, &cls);
|
||||||
if (intf != RT_NULL)
|
if (intf != RT_NULL)
|
||||||
{
|
{
|
||||||
|
@ -422,7 +422,7 @@ static rt_err_t _request_interface(struct udevice* device, ureq_t setup)
|
||||||
{
|
{
|
||||||
ret = -RT_ERROR;
|
ret = -RT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,6 +644,35 @@ rt_err_t _sof_notify(udevice_t device)
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will reset all class.
|
||||||
|
*
|
||||||
|
* @param device the usb device object.
|
||||||
|
*
|
||||||
|
* @return RT_EOK.
|
||||||
|
*/
|
||||||
|
rt_err_t _reset_notify(udevice_t device)
|
||||||
|
{
|
||||||
|
struct rt_list_node *i;
|
||||||
|
uclass_t cls;
|
||||||
|
|
||||||
|
RT_ASSERT(device != RT_NULL);
|
||||||
|
|
||||||
|
/* to notity every class that sof event comes */
|
||||||
|
for (i=device->curr_cfg->cls_list.next;
|
||||||
|
i!=&device->curr_cfg->cls_list; i=i->next)
|
||||||
|
{
|
||||||
|
cls = (uclass_t)rt_list_entry(i, struct uclass, list);
|
||||||
|
if(cls->ops->stop != RT_NULL)
|
||||||
|
cls->ops->stop(device, cls);
|
||||||
|
|
||||||
|
if(cls->ops->run != RT_NULL)
|
||||||
|
cls->ops->run(device, cls);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RT_EOK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function will create an usb device object.
|
* This function will create an usb device object.
|
||||||
*
|
*
|
||||||
|
@ -1360,6 +1389,10 @@ static void rt_usbd_thread_entry(void* parameter)
|
||||||
case USB_MSG_SETUP_NOTIFY:
|
case USB_MSG_SETUP_NOTIFY:
|
||||||
_setup_request(device, (ureq_t)msg.content.setup_msg.packet);
|
_setup_request(device, (ureq_t)msg.content.setup_msg.packet);
|
||||||
break;
|
break;
|
||||||
|
case USB_MSG_RESET:
|
||||||
|
if (device->state == USB_STATE_ADDRESS)
|
||||||
|
_reset_notify(device);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
rt_kprintf("unknown msg type\n");
|
rt_kprintf("unknown msg type\n");
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue