diff options
| author | sakumisu <[email protected]> | 2024-06-02 11:20:13 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-06-02 11:20:13 +0800 |
| commit | 62d321caa028dee04bf0b43fc0abb68b40e80ddd (patch) | |
| tree | 31fa88156af25b434a194398154dc8027d6b413d /components/drivers/usb/usbhost | |
| parent | 658813213e5ad1dc81739746f6001099c6cc9e41 (diff) | |
refactor(drivers/usb):replace rtt usb stack with cherryusb (#8799)
Diffstat (limited to 'components/drivers/usb/usbhost')
| -rw-r--r-- | components/drivers/usb/usbhost/SConscript | 34 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/class/adk.c | 426 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/class/adk.h | 43 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/class/hid.c | 410 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/class/hid.h | 41 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/class/mass.c | 647 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/class/mass.h | 50 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/class/udisk.c | 456 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/class/ukbd.c | 93 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/class/umouse.c | 190 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/core/driver.c | 147 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/core/hub.c | 727 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/core/usbhost.c | 76 | ||||
| -rw-r--r-- | components/drivers/usb/usbhost/core/usbhost_core.c | 586 |
14 files changed, 0 insertions, 3926 deletions
diff --git a/components/drivers/usb/usbhost/SConscript b/components/drivers/usb/usbhost/SConscript deleted file mode 100644 index aa5385d52a..0000000000 --- a/components/drivers/usb/usbhost/SConscript +++ /dev/null @@ -1,34 +0,0 @@ -Import('RTT_ROOT') -from building import * - -cwd = GetCurrentDir() -src = Split(""" -core/usbhost_core.c -core/driver.c -core/usbhost.c -core/hub.c -""") - -if GetDepend('RT_USBH_ADK'): - src += Glob('class/adk.c') - src += Glob('class/adkapp.c') - -if GetDepend('RT_USBH_MSTORAGE'): - src += Glob('class/mass.c') - src += Glob('class/udisk.c') - -if GetDepend('RT_USBH_HID'): - src += Glob('class/hid.c') - -if GetDepend('RT_USBH_HID_MOUSE'): - src += Glob('class/umouse.c') - -if GetDepend('RT_USBH_HID_KEYBOARD'): - src += Glob('class/ukbd.c') - -CPPPATH = [cwd, cwd + '/class', cwd + '/core', \ - cwd + '/include', cwd + '../../../include'] - -group = DefineGroup('rt_usbh', src, depend = ['RT_USING_USB_HOST'], CPPPATH = CPPPATH) - -Return('group') diff --git a/components/drivers/usb/usbhost/class/adk.c b/components/drivers/usb/usbhost/class/adk.c deleted file mode 100644 index 4c51fa8692..0000000000 --- a/components/drivers/usb/usbhost/class/adk.c +++ /dev/null @@ -1,426 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-12 Yi Qiu first version - */ - -#include <rtthread.h> -#include <drivers/usb_host.h> -#include "adk.h" - -#ifdef RT_USBH_ADK - -#define DBG_TAG "usbhost.adk" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -static struct uclass_driver adk_driver; -static const char* _adk_manufacturer = RT_NULL; -static const char* _adk_model = RT_NULL; -static const char* _adk_description = RT_NULL; -static const char* _adk_version = RT_NULL; -static const char* _adk_uri = RT_NULL; -static const char* _adk_serial = RT_NULL; - -rt_err_t rt_usbh_adk_set_string(const char* manufacturer, const char* model, - const char* description, const char* _version, const char* uri, - const char* serial) -{ - _adk_manufacturer = manufacturer; - _adk_model = model; - _adk_description = description; - _adk_version = _version; - _adk_uri = uri; - _adk_serial = serial; - - return RT_EOK; -} - -#ifdef RT_USING_MODULE -#include <rtm.h> - -RTM_EXPORT(rt_usbh_adk_set_string); -#endif - -/** - * This function will do USB_REQ_GET_PROTOCOL request to set idle period to the usb adk device - * - * @param intf the interface instance. - * @duration the idle period of requesting data. - * @report_id the report id - * - * @return the error code, RT_EOK on successfully. -*/ -static rt_err_t rt_usbh_adk_get_protocol(struct uintf* intf, rt_uint16_t *protocol) -{ - struct urequest setup; - uinst_t device; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(intf != RT_NULL); - RT_ASSERT(intf->device != RT_NULL); - - device = intf->device; - - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_VENDOR | - USB_REQ_TYPE_DEVICE; - setup.request = USB_REQ_GET_PROTOCOL; - setup.index = 0; - setup.length = 2; - setup.value = 0; - - if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, (void*)protocol, 2, - timeout) == 0) return RT_EOK; - else return -RT_FALSE; -} - -/** - * This function will do USB_REQ_SEND_STRING request to set idle period to the usb adk device - * - * @param intf the interface instance. - * @duration the idle period of requesting data. - * @report_id the report id - * - * @return the error code, RT_EOK on successfully. -*/ -static rt_err_t rt_usbh_adk_send_string(struct uintf* intf, rt_uint16_t index, - const char* str) -{ - struct urequest setup; - uinst_t device; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(intf != RT_NULL); - RT_ASSERT(intf->device != RT_NULL); - - device = intf->device; - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_VENDOR | - USB_REQ_TYPE_DEVICE; - setup.request = USB_REQ_SEND_STRING; - setup.index = index; - setup.length = rt_strlen(str) + 1; - setup.value = 0; - - if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, (void*)str, - rt_strlen(str) + 1, timeout) == 0) return RT_EOK; - else return -RT_FALSE; -} - -/** - * This function will do USB_REQ_START request to set idle period to the usb adk device - * - * @param intf the interface instance. - * @duration the idle period of requesting data. - * @report_id the report id - * - * @return the error code, RT_EOK on successfully. -*/ -static rt_err_t rt_usbh_adk_start(struct uintf* intf) -{ - struct urequest setup; - uinst_t device; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(intf != RT_NULL); - RT_ASSERT(intf->device != RT_NULL); - - device = intf->device; - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_VENDOR | - USB_REQ_TYPE_DEVICE; - setup.request = USB_REQ_START; - setup.index = 0; - setup.length = 0; - setup.value = 0; - - if(rt_usb_hcd_control_xfer(device->hcd, device, &setup, RT_NULL, 0, - timeout) == 0) return RT_EOK; - else return -RT_FALSE; -} - -/** - * This function will read data from usb adk device - * - * @param intf the interface instance. - * - * @return the error code, RT_EOK on successfully. -*/ -static rt_ssize_t rt_usbh_adk_read(rt_device_t device, rt_off_t pos, void* buffer, - rt_size_t size) -{ - uadk_t adk; - rt_size_t length; - struct uintf* intf; - - /* check parameter */ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(buffer != RT_NULL); - - intf = (struct uintf*)device->user_data; - adk = (uadk_t)intf->user_data; - - length = rt_usb_hcd_bulk_xfer(intf->device->hcd, adk->pipe_in, - buffer, size, 300); - - return length; - -} - -/** - * This function will write data to usb adk device - * - * @param intf the interface instance. - * - * @return the error code, RT_EOK on successfully. -*/ -static rt_ssize_t rt_usbh_adk_write (rt_device_t device, rt_off_t pos, const void* buffer, - rt_size_t size) -{ - uadk_t adk; - rt_size_t length; - struct uintf* intf; - - RT_ASSERT(buffer != RT_NULL); - - intf = (struct uintf*)device->user_data; - adk = (uadk_t)intf->user_data; - - length = rt_usb_hcd_bulk_xfer(intf->device->hcd, adk->pipe_out, - (void*)buffer, size, 300); - - return length; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops adk_device_ops = -{ - RT_NULL; - RT_NULL; - RT_NULL; - rt_usbh_adk_read; - rt_usbh_adk_write; - RT_NULL; -}; -#endif - -/** - * This function will run adk class driver when usb device is detected and identified - * as a adk class device, it will continue the enumulate process. - * - * @param arg the argument. - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t rt_usbh_adk_enable(void* arg) -{ - int i = 0; - uadk_t adk; - struct uintf* intf = (struct uintf*)arg; - udev_desc_t dev_desc; - rt_uint16_t protocol; - rt_err_t ret; - - /* parameter check */ - if(intf == RT_NULL) - { - rt_kprintf("the interface is not available\n"); - return -RT_EIO; - } - - LOG_D("rt_usbh_adk_run"); - - dev_desc = &intf->device->dev_desc; - if(dev_desc->idVendor == USB_ACCESSORY_VENDOR_ID && - (dev_desc->idProduct == USB_ACCESSORY_PRODUCT_ID || - dev_desc->idProduct == USB_ACCESSORY_ADB_PRODUCT_ID)) - { - if(intf->intf_desc->bInterfaceSubClass != 0xFF) return -RT_ERROR; - - LOG_D("found android accessory device"); - } - else - { - LOG_D("switch device"); - - if((ret = rt_usbh_adk_get_protocol(intf, &protocol)) != RT_EOK) - { - rt_kprintf("rt_usbh_adk_get_protocol failed\n"); - return ret; - } - - if(protocol != 1) - { - rt_kprintf("read protocol failed\n"); - return -RT_ERROR; - } - - rt_usbh_adk_send_string(intf, - ACCESSORY_STRING_MANUFACTURER, _adk_manufacturer); - rt_usbh_adk_send_string(intf, - ACCESSORY_STRING_MODEL, _adk_model); - rt_usbh_adk_send_string(intf, - ACCESSORY_STRING_DESCRIPTION, _adk_description); - rt_usbh_adk_send_string(intf, - ACCESSORY_STRING_VERSION, _adk_version); - rt_usbh_adk_send_string(intf, - ACCESSORY_STRING_URI, _adk_uri); - rt_usbh_adk_send_string(intf, - ACCESSORY_STRING_SERIAL, _adk_serial); - - LOG_D("manufacturer %s", _adk_manufacturer); - LOG_D("model %s", _adk_model); - LOG_D("description %s", _adk_description); - LOG_D("version %s", _adk_version); - LOG_D("uri %s", _adk_uri); - LOG_D("serial %s", _adk_serial); - - if((ret = rt_usbh_adk_start(intf)) != RT_EOK) - { - rt_kprintf("rt_usbh_adk_start failed\n"); - return ret; - } - - return RT_EOK; - } - - adk = rt_malloc(sizeof(struct uadkinst)); - RT_ASSERT(adk != RT_NULL); - - /* initilize the data structure */ - rt_memset(adk, 0, sizeof(struct uadkinst)); - intf->user_data = (void*)adk; - - for(i=0; i<intf->intf_desc->bNumEndpoints; i++) - { - uep_desc_t ep_desc; - - /* get endpoint descriptor from interface descriptor */ - rt_usbh_get_endpoint_descriptor(intf->intf_desc, i, &ep_desc); - if(ep_desc == RT_NULL) - { - rt_kprintf("rt_usb_get_endpoint_descriptor error\n"); - return -RT_ERROR; - } - - /* the endpoint type of adk class should be BULK */ - if((ep_desc->bmAttributes & USB_EP_ATTR_TYPE_MASK) != USB_EP_ATTR_BULK) - continue; - - /* allocate pipes according to the endpoint type */ - if(ep_desc->bEndpointAddress & USB_DIR_IN) - { - /* allocate an in pipe for the adk instance */ - ret = rt_usb_hcd_alloc_pipe(intf->device->hcd, &adk->pipe_in, - intf, ep_desc, RT_NULL); - if(ret != RT_EOK) return ret; - } - else - { - /* allocate an output pipe for the adk instance */ - ret = rt_usb_hcd_alloc_pipe(intf->device->hcd, &adk->pipe_out, - intf, ep_desc, RT_NULL); - if(ret != RT_EOK) return ret; - } - } - - /* check pipes infomation */ - if(adk->pipe_in == RT_NULL || adk->pipe_out == RT_NULL) - { - rt_kprintf("pipe error, unsupported device\n"); - return -RT_ERROR; - } - - /* set configuration */ - ret = rt_usbh_set_configure(intf->device, 1); - if(ret != RT_EOK) return ret; - - /* register adk device */ - adk->device.type = RT_Device_Class_Char; -#ifdef RT_USING_DEVICE_OPS - adk->device.ops = &adk_device_ops; -#else - adk->device.init = RT_NULL; - adk->device.open = RT_NULL; - adk->device.close = RT_NULL; - adk->device.read = rt_usbh_adk_read; - adk->device.write = rt_usbh_adk_write; - adk->device.control = RT_NULL; -#endif - adk->device.user_data = (void*)intf; - - rt_device_register(&adk->device, "adkdev", RT_DEVICE_FLAG_RDWR); - - return RT_EOK; -} - -/** - * This function will be invoked when usb device plug out is detected and it would clean - * and release all hub class related resources. - * - * @param arg the argument. - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t rt_usbh_adk_disable(void* arg) -{ - uadk_t adk; - struct uintf* intf = (struct uintf*)arg; - - RT_ASSERT(intf != RT_NULL); - - LOG_D("rt_usbh_adk_stop"); - - adk = (uadk_t)intf->user_data; - if(adk == RT_NULL) - { - rt_free(intf); - return RT_EOK; - } - - if(adk->pipe_in != RT_NULL) - rt_usb_hcd_free_pipe(intf->device->hcd, adk->pipe_in); - - if(adk->pipe_out != RT_NULL) - rt_usb_hcd_free_pipe(intf->device->hcd, adk->pipe_out); - - /* unregister adk device */ - rt_device_unregister(&adk->device); - - /* free adk instance */ - if(adk != RT_NULL) - { - rt_free(adk); - } - - /* free interface instance */ - rt_free(intf); - - return RT_EOK; -} - -/** - * This function will register adk class driver to the usb class driver manager. - * and it should be invoked in the usb system initialization. - * - * @return the error code, RT_EOK on successfully. - */ -ucd_t rt_usbh_class_driver_adk(void) -{ - adk_driver.class_code = USB_CLASS_ADK; - - adk_driver.enable = rt_usbh_adk_enable; - adk_driver.disable = rt_usbh_adk_disable; - - return &adk_driver; -} - -#endif - diff --git a/components/drivers/usb/usbhost/class/adk.h b/components/drivers/usb/usbhost/class/adk.h deleted file mode 100644 index 67c3392d7a..0000000000 --- a/components/drivers/usb/usbhost/class/adk.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-12 Yi Qiu first version - */ - -#ifndef __ADK_H__ -#define __ADK_H__ - -#include <rtthread.h> - -struct uadkinst -{ - upipe_t pipe_in; - upipe_t pipe_out; - - struct rt_device device; -}; -typedef struct uadkinst* uadk_t; - -#define USB_ACCESSORY_VENDOR_ID 0x18D1 -#define USB_ACCESSORY_PRODUCT_ID 0x2D00 -#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01 - -#define ACCESSORY_STRING_MANUFACTURER 0 -#define ACCESSORY_STRING_MODEL 1 -#define ACCESSORY_STRING_DESCRIPTION 2 -#define ACCESSORY_STRING_VERSION 3 -#define ACCESSORY_STRING_URI 4 -#define ACCESSORY_STRING_SERIAL 5 - -#define USB_REQ_GET_PROTOCOL 51 -#define USB_REQ_SEND_STRING 52 -#define USB_REQ_START 53 - -#define USB_CLASS_ADK 0xff - -#endif - diff --git a/components/drivers/usb/usbhost/class/hid.c b/components/drivers/usb/usbhost/class/hid.c deleted file mode 100644 index 5911faf1aa..0000000000 --- a/components/drivers/usb/usbhost/class/hid.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-12 Yi Qiu first version - * 2021-02-23 Leslie Lee update with current usb api - */ - -#include <rtthread.h> -#include <drivers/usb_host.h> -#include "hid.h" - -#ifdef RT_USBH_HID - -#define DBG_TAG "usbhost.hid" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -static struct uclass_driver hid_driver; -static rt_list_t _protocal_list; - -/** - * This function will do USB_REQ_SET_IDLE request to set idle period to the usb hid device - * - * @param intf the interface instance. - * @duration the idle period of requesting data. - * @report_id the report id - * - * @return the error code, RT_EOK on successfully. -*/ -rt_err_t rt_usbh_hid_set_idle(struct uhintf* intf, int duration, int report_id) -{ - struct urequest setup; - struct uinstance* device; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(intf != RT_NULL); - RT_ASSERT(intf->device != RT_NULL); - - device = intf->device; - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS | - USB_REQ_TYPE_INTERFACE; - setup.bRequest = USB_REQ_SET_IDLE; - setup.wIndex = 0; - setup.wLength = 0; - setup.wValue = (duration << 8 )| report_id; - - if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8) - if (rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, RT_NULL, 0, timeout) == 0) - return RT_EOK; - - return -RT_FALSE; -} - -/** - * This function will do USB_REQ_GET_REPORT request to get report from the usb hid device - * - * @param intf the interface instance. - * @buffer the data buffer to save usb report descriptor. - * @param nbytes the size of buffer - * - * @return the error code, RT_EOK on successfully. -*/ -rt_err_t rt_usbh_hid_get_report(struct uhintf* intf, rt_uint8_t type, - rt_uint8_t id, rt_uint8_t *buffer, rt_size_t size) -{ - struct urequest setup; - struct uinstance* device; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(intf != RT_NULL); - RT_ASSERT(intf->device != RT_NULL); - - device = intf->device; - - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | - USB_REQ_TYPE_INTERFACE; - setup.bRequest = USB_REQ_GET_REPORT; - setup.wIndex = intf->intf_desc->bInterfaceNumber; - setup.wLength = size; - setup.wValue = (type << 8 ) + id; - - if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8) - { - if (rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, size, timeout) == size) - { - if (rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_out, RT_NULL, 0, timeout) == 0) - { - return RT_EOK; - } - } - } - else - return -RT_FALSE; - return -RT_FALSE; -} - -/** - * This function will do USB_REQ_SET_REPORT request to set report to the usb hid device - * - * @param intf the interface instance. - * @buffer the data buffer to save usb report descriptor. - * @param nbytes the size of buffer - * - * @return the error code, RT_EOK on successfully. -*/ -rt_err_t rt_usbh_hid_set_report(struct uhintf* intf, rt_uint8_t *buffer, rt_size_t size) -{ - struct urequest setup; - struct uinstance* device; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(intf != RT_NULL); - RT_ASSERT(intf->device != RT_NULL); - - device = intf->device; - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS | - USB_REQ_TYPE_INTERFACE; - setup.bRequest = USB_REQ_SET_REPORT; - setup.wIndex = intf->intf_desc->bInterfaceNumber; - setup.wLength = size; - setup.wValue = 0x02 << 8; - - if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8) - return RT_EOK; - else - return -RT_FALSE; -} - -/** - * This function will do USB_REQ_SET_PROTOCOL request to set protocal to the usb hid device. - * - * @param intf the interface instance. - * @param protocol the protocol id. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hid_set_protocal(struct uhintf* intf, int protocol) -{ - struct urequest setup; - struct uinstance* device; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(intf != RT_NULL); - RT_ASSERT(intf->device != RT_NULL); - - device = intf->device; - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS | - USB_REQ_TYPE_INTERFACE; - setup.bRequest = USB_REQ_SET_PROTOCOL; - setup.wIndex = 0; - setup.wLength = 0; - setup.wValue = protocol; - - if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8) - return RT_EOK; - else - return -RT_FALSE; -} - -/** - * This function will do USB_REQ_GET_DESCRIPTOR request for the device instance - * to set feature of the hub port. - * - * @param intf the interface instance. - * @buffer the data buffer to save usb report descriptor. - * @param nbytes the size of buffer - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hid_get_report_descriptor(struct uhintf* intf, - rt_uint8_t *buffer, rt_size_t size) -{ - struct urequest setup; - struct uinstance* device; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(intf != RT_NULL); - RT_ASSERT(intf->device != RT_NULL); - - device = intf->device; - - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_STANDARD| - USB_REQ_TYPE_INTERFACE; - setup.bRequest = USB_REQ_GET_DESCRIPTOR; - setup.wIndex = 0; - setup.wLength = size; - setup.wValue = USB_DESC_TYPE_REPORT << 8; - - if (rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8) - { - if (rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, size, timeout) == size) - { - if (rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_out, RT_NULL, 0, timeout) == 0) - { - return RT_EOK; - } - } - } - else - return -RT_FALSE; - return -RT_FALSE; -} - -/** - * This function will register specified hid protocal to protocal list - * - * @param protocal the specified protocal. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hid_protocal_register(uprotocal_t protocal) -{ - RT_ASSERT(protocal != RT_NULL); - - if (protocal == RT_NULL) return -RT_ERROR; - - /* insert class driver into driver list */ - rt_list_insert_after(&_protocal_list, &(protocal->list)); - - return RT_EOK; -} - -/** - * This function is the callback function of hid's int endpoint, it is invoked when data comes. - * - * @param context the context of the callback function. - * - * @return none. - */ -static void rt_usbh_hid_callback(void* context) -{ - upipe_t pipe; - struct uhid* hid; - int timeout = USB_TIMEOUT_LONG; - - /* parameter check */ - RT_ASSERT(context != RT_NULL); - - pipe = (upipe_t)context; - hid = (struct uhid*)((struct uhintf*)pipe->inst)->user_data; - - /* invoke protocal callback function */ - hid->protocal->callback((void*)hid); - - /* parameter check */ - RT_ASSERT(((struct uhintf*)pipe->inst)->device->hcd != RT_NULL); - - rt_usb_hcd_pipe_xfer(((struct uhintf*)pipe->inst)->device->hcd, pipe, - hid->buffer, pipe->ep.wMaxPacketSize, timeout); -} - -/** - * This function will find specified hid protocal from protocal list - * - * @param pro_id the protocal id. - * - * @return the found protocal or RT_NULL if there is no this protocal. - */ -static uprotocal_t rt_usbh_hid_protocal_find(int pro_id) -{ - struct rt_list_node *node; - - /* try to find protocal object */ - for (node = _protocal_list.next; node != &_protocal_list; node = node->next) - { - uprotocal_t protocal = - (uprotocal_t)rt_list_entry(node, struct uprotocal, list); - if (protocal->pro_id == pro_id) return protocal; - } - - /* not found */ - return RT_NULL; -} - -/** - * This function will run hid class driver when usb device is detected and identified - * as a hid class device, it will continue the enumulate process. - * - * @param arg the argument. - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t rt_usbh_hid_enable(void* arg) -{ - int i = 0, pro_id; - uprotocal_t protocal; - struct uhid* hid; - struct uhintf* intf = (struct uhintf*)arg; - - /* parameter check */ - if(intf == RT_NULL) - { - rt_kprintf("the interface is not available\n"); - return -RT_EIO; - } - - pro_id = intf->intf_desc->bInterfaceProtocol; - - LOG_D("HID device enable, protocal id %d", pro_id); - - protocal = rt_usbh_hid_protocal_find(pro_id); - if(protocal == RT_NULL) - { - rt_kprintf("can't find hid protocal %d\n", pro_id); - intf->user_data = RT_NULL; - return -RT_ERROR; - } - - hid = rt_malloc(sizeof(struct uhid)); - RT_ASSERT(hid != RT_NULL); - - /* initilize the data structure */ - rt_memset(hid, 0, sizeof(struct uhid)); - intf->user_data = (void*)hid; - hid->protocal = protocal; - - for(i=0; i<intf->intf_desc->bNumEndpoints; i++) - { - rt_err_t ret; - uep_desc_t ep_desc; - - /* get endpoint descriptor */ - rt_usbh_get_endpoint_descriptor(intf->intf_desc, i, &ep_desc); - if(ep_desc == RT_NULL) - { - rt_kprintf("rt_usbh_get_endpoint_descriptor error\n"); - return -RT_ERROR; - } - - if(USB_EP_ATTR(ep_desc->bmAttributes) != USB_EP_ATTR_INT) - continue; - - if(!(ep_desc->bEndpointAddress & USB_DIR_IN)) continue; - - ret = rt_usb_hcd_alloc_pipe(intf->device->hcd, &hid->pipe_in, - intf->device, ep_desc); - if(ret != RT_EOK) return ret; - } - - /* initialize hid protocal */ - hid->protocal->init((void*)intf); - - return RT_EOK; -} - -/** - * This function will be invoked when usb device plug out is detected and it would clean - * and release all hub class related resources. - * - * @param arg the argument. - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t rt_usbh_hid_disable(void* arg) -{ - struct uhid* hid; - struct uhintf* intf = (struct uhintf*)arg; - - RT_ASSERT(intf != RT_NULL); - - LOG_D("rt_usbh_hid_disable"); - - hid = (struct uhid*)intf->user_data; - if(hid != RT_NULL) - { - if(hid->pipe_in != RT_NULL) - { - /* free the HID in pipe */ - rt_usb_hcd_free_pipe(intf->device->hcd, hid->pipe_in); - } - - /* free the hid instance */ - rt_free(hid); - } - - return RT_EOK; -} - -/** - * This function will register hid class driver to the usb class driver manager. - * and it should be invoked in the usb system initialization. - * - * @return the error code, RT_EOK on successfully. - */ -ucd_t rt_usbh_class_driver_hid(void) -{ - rt_list_init(&_protocal_list); - - hid_driver.class_code = USB_CLASS_HID; - - hid_driver.enable = rt_usbh_hid_enable; - hid_driver.disable = rt_usbh_hid_disable; - - return &hid_driver; -} - -#endif - diff --git a/components/drivers/usb/usbhost/class/hid.h b/components/drivers/usb/usbhost/class/hid.h deleted file mode 100644 index c7e88b66b8..0000000000 --- a/components/drivers/usb/usbhost/class/hid.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-12 Yi Qiu first version - */ - -#ifndef __HID_H__ -#define __HID_H__ - -#include <rtthread.h> - -struct uhid -{ - upipe_t pipe_in; - rt_uint8_t buffer[8]; - uprotocal_t protocal; -}; -typedef struct uhid uhid_t; - -#define USB_REQ_GET_REPORT 0x01 -#define USB_REQ_GET_IDLE 0x02 -#define USB_REQ_GET_PROTOCOL 0x03 -#define USB_REQ_SET_REPORT 0x09 -#define USB_REQ_SET_IDLE 0x0a -#define USB_REQ_SET_PROTOCOL 0x0b - -#define USB_HID_KEYBOARD 1 -#define USB_HID_MOUSE 2 - -rt_err_t rt_usbh_hid_set_idle(struct uhintf* intf, int duration, int report_id); -rt_err_t rt_usbh_hid_get_report(struct uhintf* intf, rt_uint8_t type, rt_uint8_t id, rt_uint8_t *buffer, rt_size_t size); -rt_err_t rt_usbh_hid_set_report(struct uhintf* intf, rt_uint8_t *buffer, rt_size_t size); -rt_err_t rt_usbh_hid_set_protocal(struct uhintf* intf, int protocol); -rt_err_t rt_usbh_hid_get_report_descriptor(struct uhintf* intf, rt_uint8_t *buffer, rt_size_t size); -rt_err_t rt_usbh_hid_protocal_register(uprotocal_t protocal); - -#endif diff --git a/components/drivers/usb/usbhost/class/mass.c b/components/drivers/usb/usbhost/class/mass.c deleted file mode 100644 index c29cd30ee4..0000000000 --- a/components/drivers/usb/usbhost/class/mass.c +++ /dev/null @@ -1,647 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-12 Yi Qiu first version - */ - -#include <rtthread.h> -#include <drivers/usb_host.h> -#include "mass.h" - -#ifdef RT_USBH_MSTORAGE - -#define DBG_TAG "usbhost.mass" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -extern rt_err_t rt_udisk_run(struct uhintf* intf); -extern rt_err_t rt_udisk_stop(struct uhintf* intf); - -static struct uclass_driver storage_driver; - -/** - * This function will do USBREQ_GET_MAX_LUN request for the usb interface instance. - * - * @param intf the interface instance. - * @param max_lun the buffer to save max_lun. - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t _pipe_check(struct uhintf* intf, upipe_t pipe) -{ - struct uinstance* device; - rt_err_t ret; - ustor_t stor; - int size = 0; - struct ustorage_csw csw; - - if(intf == RT_NULL || pipe == RT_NULL) - { - rt_kprintf("the interface is not available\n"); - return -RT_EIO; - } - - /* get usb device instance from the interface instance */ - device = intf->device; - - /* get storage instance from the interface instance */ - stor = (ustor_t)intf->user_data; - - /* check pipe status */ - if(pipe->status == UPIPE_STATUS_OK) return RT_EOK; - - if(pipe->status == UPIPE_STATUS_ERROR) - { - rt_kprintf("pipe status error\n"); - return -RT_EIO; - } - if(pipe->status == UPIPE_STATUS_STALL) - { - /* clear the pipe stall status */ - ret = rt_usbh_clear_feature(device, pipe->ep.bEndpointAddress, - USB_FEATURE_ENDPOINT_HALT); - if(ret != RT_EOK) return ret; - } - - - rt_thread_delay(50); - - rt_kprintf("pipes1 0x%x, 0x%x\n", stor->pipe_in, stor->pipe_out); - - stor->pipe_in->status = UPIPE_STATUS_OK; - - LOG_D("clean storage in pipe stall"); - - /* it should receive csw after clear the stall feature */ - size = rt_usb_hcd_pipe_xfer(stor->pipe_in->inst->hcd, - stor->pipe_in, &csw, SIZEOF_CSW, 100); - if(size != SIZEOF_CSW) - { - rt_kprintf("receive the csw after stall failed\n"); - return -RT_EIO; - } - - return -RT_ERROR; -} - -/** - * This function will do USBREQ_GET_MAX_LUN request for the usb interface instance. - * - * @param intf the interface instance. - * @param max_lun the buffer to save max_lun. - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t rt_usb_bulk_only_xfer(struct uhintf* intf, - ustorage_cbw_t cmd, rt_uint8_t* buffer, int timeout) -{ - rt_size_t size; - rt_err_t ret; - upipe_t pipe; - struct ustorage_csw csw; - ustor_t stor; - - RT_ASSERT(cmd != RT_NULL); - - if(intf == RT_NULL) - { - rt_kprintf("the interface is not available\n"); - return -RT_EIO; - } - - /* get storage instance from the interface instance */ - stor = (ustor_t)intf->user_data; - - do - { - /* send the cbw */ - size = rt_usb_hcd_pipe_xfer(stor->pipe_out->inst->hcd, stor->pipe_out, - cmd, SIZEOF_CBW, timeout); - if(size != SIZEOF_CBW) - { - rt_kprintf("CBW size error\n"); - return -RT_EIO; - } - if(cmd->xfer_len != 0) - { - pipe = (cmd->dflags == CBWFLAGS_DIR_IN) ? stor->pipe_in : - stor->pipe_out; - size = rt_usb_hcd_pipe_xfer(pipe->inst->hcd, pipe, (void*)buffer, - cmd->xfer_len, timeout); - if(size != cmd->xfer_len) - { - rt_kprintf("request size %d, transfer size %d\n", - cmd->xfer_len, size); - break; - } - } - - /* receive the csw */ - size = rt_usb_hcd_pipe_xfer(stor->pipe_in->inst->hcd, stor->pipe_in, - &csw, SIZEOF_CSW, timeout); - if(size != SIZEOF_CSW) - { - rt_kprintf("csw size error\n"); - return -RT_EIO; - } - }while(0); - - /* check in pipes status */ - ret = _pipe_check(intf, stor->pipe_in); - if(ret != RT_EOK) - { - rt_kprintf("in pipe error\n"); - return ret; - } - - /* check out pipes status */ - ret = _pipe_check(intf, stor->pipe_out); - if(ret != RT_EOK) - { - rt_kprintf("out pipe error\n"); - return ret; - } - - /* check csw status */ - if(csw.signature != CSW_SIGNATURE || csw.tag != CBW_TAG_VALUE) - { - rt_kprintf("csw signature error\n"); - return -RT_EIO; - } - - if(csw.status != 0) - { - //rt_kprintf("csw status error:%d\n",csw.status); - return -RT_ERROR; - } - - return RT_EOK; -} - -/** - * This function will do USBREQ_GET_MAX_LUN request for the usb interface instance. - * - * @param intf the interface instance. - * @param max_lun the buffer to save max_lun. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_storage_get_max_lun(struct uhintf* intf, rt_uint8_t* max_lun) -{ - struct uinstance* device; - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - if(intf == RT_NULL) - { - rt_kprintf("the interface is not available\n"); - return -RT_EIO; - } - - /* parameter check */ - RT_ASSERT(intf->device != RT_NULL); - LOG_D("rt_usbh_storage_get_max_lun"); - - /* get usb device instance from the interface instance */ - device = intf->device; - - /* construct the request */ - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | - USB_REQ_TYPE_INTERFACE; - setup.bRequest = USBREQ_GET_MAX_LUN; - setup.wValue = intf->intf_desc->bInterfaceNumber; - setup.wIndex = 0; - setup.wLength = 1; - - /* do control transfer request */ - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) - { - return -RT_EIO; - } - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, max_lun, 1, timeout) != 1) - { - return -RT_EIO; - } - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_out, RT_NULL, 0, timeout) != 0) - { - return -RT_EIO; - } - return RT_EOK; -} - -/** - * This function will do USBREQ_MASS_STORAGE_RESET request for the usb interface instance. - * - * @param intf the interface instance. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_storage_reset(struct uhintf* intf) -{ - struct urequest setup; - struct uinstance* device; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - if(intf == RT_NULL) - { - rt_kprintf("the interface is not available\n"); - return -RT_EIO; - } - - RT_ASSERT(intf->device != RT_NULL); - LOG_D("rt_usbh_storage_reset"); - - /* get usb device instance from the interface instance */ - device = intf->device; - - /* construct the request */ - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS | - USB_REQ_TYPE_INTERFACE; - setup.bRequest = USBREQ_MASS_STORAGE_RESET; - setup.wIndex = intf->intf_desc->bInterfaceNumber; - setup.wLength = 0; - setup.wValue = 0; - - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) - { - return -RT_EIO; - } - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, RT_NULL, 0, timeout) != 0) - { - return -RT_EIO; - } - return RT_EOK; -} - -/** - * This function will execute SCSI_READ_10 command to read data from the usb device. - * - * @param intf the interface instance. - * @param buffer the data buffer to save read data - * @param sector the start sector address to read. - * @param sector the sector count to read. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_storage_read10(struct uhintf* intf, rt_uint8_t *buffer, - rt_uint32_t sector, rt_size_t count, int timeout) -{ - struct ustorage_cbw cmd; - - /* parameter check */ - if(intf == RT_NULL) - { - rt_kprintf("interface is not available\n"); - return -RT_EIO; - } - - RT_ASSERT(intf->device != RT_NULL); - LOG_D("rt_usbh_storage_read10"); - - /* construct the command block wrapper */ - rt_memset(&cmd, 0, sizeof(struct ustorage_cbw)); - cmd.signature = CBW_SIGNATURE; - cmd.tag = CBW_TAG_VALUE; - cmd.xfer_len = SECTOR_SIZE * count; - cmd.dflags = CBWFLAGS_DIR_IN; - cmd.lun = 0; - cmd.cb_len = 10; - cmd.cb[0] = SCSI_READ_10; - cmd.cb[1] = 0; - cmd.cb[2] = (rt_uint8_t)(sector >> 24); - cmd.cb[3] = (rt_uint8_t)(sector >> 16); - cmd.cb[4] = (rt_uint8_t)(sector >> 8); - cmd.cb[5] = (rt_uint8_t)sector; - cmd.cb[6] = 0; - cmd.cb[7] = (count & 0xff00) >> 8; - cmd.cb[8] = (rt_uint8_t) count & 0xff; - - return rt_usb_bulk_only_xfer(intf, &cmd, buffer, timeout); -} - -/** - * This function will execute SCSI_WRITE_10 command to write data to the usb device. - * - * @param intf the interface instance. - * @param buffer the data buffer to save write data - * @param sector the start sector address to write. - * @param sector the sector count to write. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_storage_write10(struct uhintf* intf, rt_uint8_t *buffer, - rt_uint32_t sector, rt_size_t count, int timeout) -{ - struct ustorage_cbw cmd; - - /* parameter check */ - if(intf == RT_NULL) - { - rt_kprintf("the interface is not available\n"); - return -RT_EIO; - } - - RT_ASSERT(intf->device != RT_NULL); - LOG_D("rt_usbh_storage_write10"); - - /* construct the command block wrapper */ - rt_memset(&cmd, 0, sizeof(struct ustorage_cbw)); - cmd.signature = CBW_SIGNATURE; - cmd.tag = CBW_TAG_VALUE; - cmd.xfer_len = SECTOR_SIZE * count; - cmd.dflags = CBWFLAGS_DIR_OUT; - cmd.lun = 0; - cmd.cb_len = 10; - cmd.cb[0] = SCSI_WRITE_10; - cmd.cb[1] = 0; - cmd.cb[2] = (rt_uint8_t)(sector >> 24); - cmd.cb[3] = (rt_uint8_t)(sector >> 16); - cmd.cb[4] = (rt_uint8_t)(sector >> 8); - cmd.cb[5] = (rt_uint8_t)sector; - cmd.cb[6] = 0; - cmd.cb[7] = (count & 0xff00) >> 8; - cmd.cb[8] = (rt_uint8_t) count & 0xff; - - return rt_usb_bulk_only_xfer(intf, &cmd, buffer, timeout); -} - -/** - * This function will execute SCSI_REQUEST_SENSE command to get sense data. - * - * @param intf the interface instance. - * @param buffer the data buffer to save sense data - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_storage_request_sense(struct uhintf* intf, rt_uint8_t* buffer) -{ - struct ustorage_cbw cmd; - int timeout = USB_TIMEOUT_LONG; - - /* parameter check */ - if(intf == RT_NULL) - { - rt_kprintf("the interface is not available\n"); - return -RT_EIO; - } - - RT_ASSERT(intf->device != RT_NULL); - LOG_D("rt_usbh_storage_request_sense"); - - /* construct the command block wrapper */ - rt_memset(&cmd, 0, sizeof(struct ustorage_cbw)); - cmd.signature = CBW_SIGNATURE; - cmd.tag = CBW_TAG_VALUE; - cmd.xfer_len = 18; - cmd.dflags = CBWFLAGS_DIR_IN; - cmd.lun = 0; - cmd.cb_len = 6; - cmd.cb[0] = SCSI_REQUEST_SENSE; - cmd.cb[4] = 18; - - return rt_usb_bulk_only_xfer(intf, &cmd, buffer, timeout); -} - -/** - * This function will execute SCSI_TEST_UNIT_READY command to get unit ready status. - * - * @param intf the interface instance. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_storage_test_unit_ready(struct uhintf* intf) -{ - struct ustorage_cbw cmd; - int timeout = USB_TIMEOUT_LONG; - - /* parameter check */ - if(intf == RT_NULL) - { - rt_kprintf("the interface is not available\n"); - return -RT_EIO; - } - - RT_ASSERT(intf->device != RT_NULL); - LOG_D("rt_usbh_storage_test_unit_ready"); - - /* construct the command block wrapper */ - rt_memset(&cmd, 0, sizeof(struct ustorage_cbw)); - cmd.signature = CBW_SIGNATURE; - cmd.tag = CBW_TAG_VALUE; - cmd.xfer_len = 0; - cmd.dflags = CBWFLAGS_DIR_OUT; - cmd.lun = 0; - cmd.cb_len = 12; - cmd.cb[0] = SCSI_TEST_UNIT_READY; - - return rt_usb_bulk_only_xfer(intf, &cmd, RT_NULL, timeout); -} - -/** - * This function will execute SCSI_INQUIRY_CMD command to get inquiry data. - * - * @param intf the interface instance. - * @param buffer the data buffer to save inquiry data - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_storage_inquiry(struct uhintf* intf, rt_uint8_t* buffer) -{ - struct ustorage_cbw cmd; - int timeout = USB_TIMEOUT_LONG; - - /* parameter check */ - if(intf == RT_NULL) - { - rt_kprintf("the interface is not available\n"); - return -RT_EIO; - } - - RT_ASSERT(intf->device != RT_NULL); - LOG_D("rt_usbh_storage_inquiry"); - - /* construct the command block wrapper */ - rt_memset(&cmd, 0, sizeof(struct ustorage_cbw)); - cmd.signature = CBW_SIGNATURE; - cmd.tag = CBW_TAG_VALUE; - cmd.xfer_len = 36; - cmd.dflags = CBWFLAGS_DIR_IN; - cmd.lun = 0; - cmd.cb_len = 6;//12 - cmd.cb[0] = SCSI_INQUIRY_CMD; - cmd.cb[4] = 36; - - return rt_usb_bulk_only_xfer(intf, &cmd, buffer, timeout); -} - -/** - * This function will execute SCSI_READ_CAPACITY command to get capacity data. - * - * @param intf the interface instance. - * @param buffer the data buffer to save capacity data - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_storage_get_capacity(struct uhintf* intf, rt_uint8_t* buffer) -{ - struct ustorage_cbw cmd; - int timeout = USB_TIMEOUT_LONG; - - /* parameter check */ - if(intf == RT_NULL) - { - rt_kprintf("the interface is not available\n"); - return -RT_EIO; - } - - RT_ASSERT(intf->device != RT_NULL); - LOG_D("rt_usbh_storage_get_capacity"); - - /* construct the command block wrapper */ - rt_memset(&cmd, 0, sizeof(struct ustorage_cbw)); - cmd.signature = CBW_SIGNATURE; - cmd.tag = CBW_TAG_VALUE; - cmd.xfer_len = 8; - cmd.dflags = CBWFLAGS_DIR_IN; - cmd.lun = 0; - cmd.cb_len = 12; - cmd.cb[0] = SCSI_READ_CAPACITY; - - return rt_usb_bulk_only_xfer(intf, &cmd, buffer, timeout); -} - -/** - * This function will run mass storage class driver when usb device is detected - * and identified as a mass storage class device, it will continue to do the enumulate - * process. - * - * @param arg the argument. - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t rt_usbh_storage_enable(void* arg) -{ - int i = 0; - rt_err_t ret; - ustor_t stor; - struct uhintf* intf = (struct uhintf*)arg; - - /* parameter check */ - if(intf == RT_NULL) - { - rt_kprintf("the interface is not available\n"); - return -RT_EIO; - } - - LOG_D("subclass %d, protocal %d", - intf->intf_desc->bInterfaceSubClass, - intf->intf_desc->bInterfaceProtocol); - - LOG_D("rt_usbh_storage_run"); - - /* only support SCSI subclass and bulk only protocal */ - - stor = rt_malloc(sizeof(struct ustor)); - RT_ASSERT(stor != RT_NULL); - - /* initilize the data structure */ - rt_memset(stor, 0, sizeof(struct ustor)); - intf->user_data = (void*)stor; - - for(i=0; i<intf->intf_desc->bNumEndpoints; i++) - { - uep_desc_t ep_desc; - - /* get endpoint descriptor from interface descriptor */ - rt_usbh_get_endpoint_descriptor(intf->intf_desc, i, &ep_desc); - if(ep_desc == RT_NULL) - { - rt_kprintf("rt_usb_get_endpoint_descriptor error\n"); - return -RT_ERROR; - } - - /* the endpoint type of mass storage class should be BULK */ - if((ep_desc->bmAttributes & USB_EP_ATTR_TYPE_MASK) != USB_EP_ATTR_BULK) - continue; - - /* allocate pipes according to the endpoint type */ - if(ep_desc->bEndpointAddress & USB_DIR_IN) - { - /* alloc an in pipe for the storage instance */ - stor->pipe_in = rt_usb_instance_find_pipe(intf->device,ep_desc->bEndpointAddress); - } - else - { - /* alloc an output pipe for the storage instance */ - stor->pipe_out = rt_usb_instance_find_pipe(intf->device,ep_desc->bEndpointAddress); - } - } - - /* check pipes infomation */ - if(stor->pipe_in == RT_NULL || stor->pipe_out == RT_NULL) - { - rt_kprintf("pipe error, unsupported device\n"); - return -RT_ERROR; - } - - /* should implement as callback */ - ret = rt_udisk_run(intf); - if(ret != RT_EOK) return ret; - - return RT_EOK; -} - -/** - * This function will be invoked when usb device plug out is detected and it would clean - * and release all mass storage class related resources. - * - * @param arg the argument. - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t rt_usbh_storage_disable(void* arg) -{ - ustor_t stor; - struct uhintf* intf = (struct uhintf*)arg; - - /* parameter check */ - RT_ASSERT(intf != RT_NULL); - RT_ASSERT(intf->user_data != RT_NULL); - RT_ASSERT(intf->device != RT_NULL); - - LOG_D("rt_usbh_storage_stop"); - - /* get storage instance from interface instance */ - stor = (ustor_t)intf->user_data; - - rt_udisk_stop(intf); - - - /* free storage instance */ - if(stor != RT_NULL) rt_free(stor); - return RT_EOK; -} - -/** - * This function will register mass storage class driver to the usb class driver manager. - * and it should be invoked in the usb system initialization. - * - * @return the error code, RT_EOK on successfully. - */ -ucd_t rt_usbh_class_driver_storage(void) -{ - storage_driver.class_code = USB_CLASS_MASS_STORAGE; - - storage_driver.enable = rt_usbh_storage_enable; - storage_driver.disable = rt_usbh_storage_disable; - - return &storage_driver; -} - -#endif - diff --git a/components/drivers/usb/usbhost/class/mass.h b/components/drivers/usb/usbhost/class/mass.h deleted file mode 100644 index 6d54dd66a7..0000000000 --- a/components/drivers/usb/usbhost/class/mass.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-12 Yi Qiu first version - */ - -#ifndef __MASS_H__ -#define __MASS_H__ - -#include <rtthread.h> -#include "dfs_fs.h" - -#define MAX_PARTITION_COUNT 4 -#define SECTOR_SIZE 512 - -struct ustor_data -{ - struct dfs_partition part; - struct uhintf* intf; - int udisk_id; - const char path; -}; - -struct ustor -{ - upipe_t pipe_in; - upipe_t pipe_out; - rt_uint32_t capicity[2]; - - struct rt_device dev[MAX_PARTITION_COUNT]; - rt_uint8_t dev_cnt; -}; -typedef struct ustor* ustor_t; - -rt_err_t rt_usbh_storage_get_max_lun(struct uhintf* intf, rt_uint8_t* max_lun); -rt_err_t rt_usbh_storage_reset(struct uhintf* intf); -rt_err_t rt_usbh_storage_read10(struct uhintf* intf, rt_uint8_t *buffer, - rt_uint32_t sector, rt_size_t count, int timeout); -rt_err_t rt_usbh_storage_write10(struct uhintf* intf, rt_uint8_t *buffer, - rt_uint32_t sector, rt_size_t count, int timeout); -rt_err_t rt_usbh_storage_request_sense(struct uhintf* intf, rt_uint8_t* buffer); -rt_err_t rt_usbh_storage_test_unit_ready(struct uhintf* intf); -rt_err_t rt_usbh_storage_inquiry(struct uhintf* intf, rt_uint8_t* buffer); -rt_err_t rt_usbh_storage_get_capacity(struct uhintf* intf, rt_uint8_t* buffer); - -#endif diff --git a/components/drivers/usb/usbhost/class/udisk.c b/components/drivers/usb/usbhost/class/udisk.c deleted file mode 100644 index 07815e5996..0000000000 --- a/components/drivers/usb/usbhost/class/udisk.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-12 Yi Qiu first version - */ - -#include <rtthread.h> -#include <dfs_fs.h> -#include <drivers/usb_host.h> -#include "mass.h" - -#define DBG_TAG "usbhost.udisk" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -#ifdef RT_USBH_MSTORAGE - -#define UDISK_MAX_COUNT 8 -static rt_uint8_t _udisk_idset = 0; - -static int udisk_get_id(void) -{ - int i; - - for(i=0; i< UDISK_MAX_COUNT; i++) - { - if((_udisk_idset & (1 << i)) != 0) continue; - else break; - } - - /* it should not happen */ - if(i == UDISK_MAX_COUNT) RT_ASSERT(0); - - _udisk_idset |= (1 << i); - return i; -} - -static void udisk_free_id(int id) -{ - RT_ASSERT(id < UDISK_MAX_COUNT) - - _udisk_idset &= ~(1 << id); -} - -/** - * This function will initialize the udisk device - * - * @param dev the pointer of device driver structure - * - * @return RT_EOK - */ -static rt_err_t rt_udisk_init(rt_device_t dev) -{ - return RT_EOK; -} - -/** - * This function will read some data from a device. - * - * @param dev the pointer of device driver structure - * @param pos the position of reading - * @param buffer the data buffer to save read data - * @param size the size of buffer - * - * @return the actually read size on successful, otherwise negative returned. - */ -static rt_ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void* buffer, - rt_size_t size) -{ - rt_err_t ret; - struct uhintf* intf; - struct ustor_data* data; - int timeout = USB_TIMEOUT_LONG; - - /* check parameter */ - RT_ASSERT(dev != RT_NULL); - RT_ASSERT(buffer != RT_NULL); - - if(size > 4096) timeout *= 2; - - data = (struct ustor_data*)dev->user_data; - intf = data->intf; - - ret = rt_usbh_storage_read10(intf, (rt_uint8_t*)buffer, pos, size, timeout); - - if (ret != RT_EOK) - { - rt_kprintf("usb mass_storage read failed\n"); - return 0; - } - - return size; -} - -/** - * This function will write some data to a device. - * - * @param dev the pointer of device driver structure - * @param pos the position of written - * @param buffer the data buffer to be written to device - * @param size the size of buffer - * - * @return the actually written size on successful, otherwise negative returned. - */ -static rt_ssize_t rt_udisk_write (rt_device_t dev, rt_off_t pos, const void* buffer, - rt_size_t size) -{ - rt_err_t ret; - struct uhintf* intf; - struct ustor_data* data; - int timeout = USB_TIMEOUT_LONG; - - /* check parameter */ - RT_ASSERT(dev != RT_NULL); - RT_ASSERT(buffer != RT_NULL); - - if(size * SECTOR_SIZE > 4096) timeout *= 2; - - data = (struct ustor_data*)dev->user_data; - intf = data->intf; - - ret = rt_usbh_storage_write10(intf, (rt_uint8_t*)buffer, pos, size, timeout); - if (ret != RT_EOK) - { - rt_kprintf("usb mass_storage write %d sector failed\n", size); - return 0; - } - - return size; -} - -/** - * This function will execute SCSI_INQUIRY_CMD command to get inquiry data. - * - * @param intf the interface instance. - * @param buffer the data buffer to save inquiry data - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t rt_udisk_control(rt_device_t dev, int cmd, void *args) -{ - ustor_t stor; - struct ustor_data* data; - - /* check parameter */ - RT_ASSERT(dev != RT_NULL); - - data = (struct ustor_data*)dev->user_data; - stor = (ustor_t)data->intf->user_data; - - if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME) - { - struct rt_device_blk_geometry *geometry; - - geometry = (struct rt_device_blk_geometry *)args; - if (geometry == RT_NULL) return -RT_ERROR; - - geometry->bytes_per_sector = SECTOR_SIZE; - geometry->block_size = stor->capicity[1]; - geometry->sector_count = stor->capicity[0]; - } - - return RT_EOK; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops udisk_device_ops = -{ - rt_udisk_init, - RT_NULL, - RT_NULL, - rt_udisk_read, - rt_udisk_write, - rt_udisk_control -}; -#endif - -/** - * This function will run udisk driver when usb disk is detected. - * - * @param intf the usb interface instance. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_udisk_run(struct uhintf* intf) -{ - int i = 0; - rt_err_t ret; - char dname[8]; - char sname[8]; - rt_uint8_t max_lun, *sector, sense[18], inquiry[36]; - struct dfs_partition part[MAX_PARTITION_COUNT]; - ustor_t stor; - - /* check parameter */ - RT_ASSERT(intf != RT_NULL); - - /* set interface */ -// ret = rt_usbh_set_interface(intf->device, intf->intf_desc->bInterfaceNumber); -// if(ret != RT_EOK) -// rt_usbh_clear_feature(intf->device, 0, USB_FEATURE_ENDPOINT_HALT); - /* reset mass storage class device */ - ret = rt_usbh_storage_reset(intf); - if(ret != RT_EOK) return ret; - - stor = (ustor_t)intf->user_data; - - /* get max logic unit number */ - ret = rt_usbh_storage_get_max_lun(intf, &max_lun); - if(ret != RT_EOK) - rt_usbh_clear_feature(intf->device, 0, USB_FEATURE_ENDPOINT_HALT); - - /* reset pipe in endpoint */ - if(stor->pipe_in->status == UPIPE_STATUS_STALL) - { - ret = rt_usbh_clear_feature(intf->device, - stor->pipe_in->ep.bEndpointAddress, USB_FEATURE_ENDPOINT_HALT); - if(ret != RT_EOK) return ret; - } - - - /* reset pipe out endpoint */ - if(stor->pipe_out->status == UPIPE_STATUS_STALL) - { - ret = rt_usbh_clear_feature(intf->device, - stor->pipe_out->ep.bEndpointAddress, USB_FEATURE_ENDPOINT_HALT); - if(ret != RT_EOK) return ret; - } - - while((ret = rt_usbh_storage_inquiry(intf, inquiry)) != RT_EOK) - { - if(ret == -RT_EIO) return ret; - - rt_thread_delay(5); - if(i++ < 10) continue; - rt_kprintf("rt_usbh_storage_inquiry error\n"); - return -RT_ERROR; - } - - i = 0; - - /* wait device ready */ - while((ret = rt_usbh_storage_test_unit_ready(intf)) != RT_EOK) - { - if(ret == -RT_EIO) return ret; - - ret = rt_usbh_storage_request_sense(intf, sense); - if(ret == -RT_EIO) return ret; - - rt_thread_delay(10); - if(i++ < 10) continue; - - rt_kprintf("rt_usbh_storage_test_unit_ready error\n"); - return -RT_ERROR; - } - - i = 0; - rt_memset(stor->capicity, 0, sizeof(stor->capicity)); - - /* get storage capacity */ - while((ret = rt_usbh_storage_get_capacity(intf, - (rt_uint8_t*)stor->capicity)) != RT_EOK) - { - if(ret == -RT_EIO) return ret; - - rt_thread_delay(50); - if(i++ < 10) continue; - - stor->capicity[0] = 2880; - stor->capicity[1] = 0x200; - - rt_kprintf("rt_usbh_storage_get_capacity error\n"); - break; - } - - stor->capicity[0] = uswap_32(stor->capicity[0]); - stor->capicity[1] = uswap_32(stor->capicity[1]); - stor->capicity[0] += 1; - - LOG_D("capicity %d, block size %d", - stor->capicity[0], stor->capicity[1]); - - /* get the first sector to read partition table */ - sector = (rt_uint8_t*) rt_malloc (SECTOR_SIZE); - if (sector == RT_NULL) - { - rt_kprintf("allocate partition sector buffer failed\n"); - return -RT_ERROR; - } - - rt_memset(sector, 0, SECTOR_SIZE); - - LOG_D("read partition table"); - - /* get the partition table */ - ret = rt_usbh_storage_read10(intf, sector, 0, 1, USB_TIMEOUT_LONG); - if(ret != RT_EOK) - { - rt_kprintf("read parition table error\n"); - - rt_free(sector); - return -RT_ERROR; - } - - LOG_D("finished reading partition"); - - for(i=0; i<MAX_PARTITION_COUNT; i++) - { - /* get the first partition */ - ret = dfs_filesystem_get_partition(&part[i], sector, i); - if (ret == RT_EOK) - { - struct ustor_data* data = rt_malloc(sizeof(struct ustor_data)); - if (data == RT_NULL) - { - LOG_E("Allocate partition data buffer failed."); - continue; - } - rt_memset(data, 0, sizeof(struct ustor_data)); - data->intf = intf; - data->udisk_id = udisk_get_id(); - rt_snprintf(dname, 6, "ud%d-%d", data->udisk_id, i); - rt_snprintf(sname, 8, "sem_ud%d", i); - data->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); - - /* register sdcard device */ - stor->dev[i].type = RT_Device_Class_Block; -#ifdef RT_USING_DEVICE_OPS - stor->dev[i].ops = &udisk_device_ops; -#else - stor->dev[i].init = rt_udisk_init; - stor->dev[i].read = rt_udisk_read; - stor->dev[i].write = rt_udisk_write; - stor->dev[i].control = rt_udisk_control; -#endif - stor->dev[i].user_data = (void*)data; - - rt_device_register(&stor->dev[i], dname, RT_DEVICE_FLAG_RDWR | - RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); - - stor->dev_cnt++; - if (dfs_mount(stor->dev[i].parent.name, UDISK_MOUNTPOINT, "elm", - 0, 0) == 0) - { - LOG_D("udisk part %d mount successfully", i); - } - else - { - LOG_D("udisk part %d mount failed", i); - } - } - else - { - if(i == 0) - { - struct ustor_data* data = rt_malloc(sizeof(struct ustor_data)); - if (data == RT_NULL) - { - LOG_E("Allocate partition data buffer failed."); - break; - } - rt_memset(data, 0, sizeof(struct ustor_data)); - data->udisk_id = udisk_get_id(); - - /* there is no partition table */ - data->part.offset = 0; - data->part.size = 0; - data->intf = intf; - data->part.lock = rt_sem_create("sem_ud", 1, RT_IPC_FLAG_FIFO); - - rt_snprintf(dname, 7, "udisk%d", data->udisk_id); - - /* register sdcard device */ - stor->dev[0].type = RT_Device_Class_Block; -#ifdef RT_USING_DEVICE_OPS - stor->dev[i].ops = &udisk_device_ops; -#else - stor->dev[0].init = rt_udisk_init; - stor->dev[0].read = rt_udisk_read; - stor->dev[0].write = rt_udisk_write; - stor->dev[0].control = rt_udisk_control; -#endif - stor->dev[0].user_data = (void*)data; - - rt_device_register(&stor->dev[0], dname, - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE - | RT_DEVICE_FLAG_STANDALONE); - - stor->dev_cnt++; - if (dfs_mount(stor->dev[0].parent.name, UDISK_MOUNTPOINT, - "elm", 0, 0) == 0) - { - rt_kprintf("Mount FAT on Udisk successful.\n"); - } - else - { - rt_kprintf("Mount FAT on Udisk failed.\n"); - } - } - - break; - } - } - - rt_free(sector); - - return RT_EOK; -} - -/** - * This function will be invoked when usb disk plug out is detected and it would clean - * and release all udisk related resources. - * - * @param intf the usb interface instance. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_udisk_stop(struct uhintf* intf) -{ - int i; - ustor_t stor; - struct ustor_data* data; - - /* check parameter */ - RT_ASSERT(intf != RT_NULL); - RT_ASSERT(intf->device != RT_NULL); - - stor = (ustor_t)intf->user_data; - RT_ASSERT(stor != RT_NULL); - - for(i=0; i<stor->dev_cnt; i++) - { - rt_device_t dev = &stor->dev[i]; - data = (struct ustor_data*)dev->user_data; - - /* unmount filesystem */ - dfs_unmount(UDISK_MOUNTPOINT); - - /* delete semaphore */ - rt_sem_delete(data->part.lock); - udisk_free_id(data->udisk_id); - rt_free(data); - - /* unregister device */ - rt_device_unregister(&stor->dev[i]); - } - - return RT_EOK; -} - -#endif - diff --git a/components/drivers/usb/usbhost/class/ukbd.c b/components/drivers/usb/usbhost/class/ukbd.c deleted file mode 100644 index db080ed406..0000000000 --- a/components/drivers/usb/usbhost/class/ukbd.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-01-03 Yi Qiu first version - */ - -#include <rtthread.h> -#include <drivers/usb_host.h> -#include "hid.h" - -#if defined(RT_USBH_HID) && defined(RT_USBH_HID_KEYBOARD) - -#define DBG_TAG "usbhost.ukbd" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -static struct uprotocal kbd_protocal; - -static rt_err_t rt_usbh_hid_kbd_callback(void* arg) -{ - int int1, int2; - struct uhid* hid; - - hid = (struct uhid*)arg; - - int1 = *(rt_uint32_t*)hid->buffer; - int2 = *(rt_uint32_t*)(&hid->buffer[4]); - - if(int1 != 0 || int2 != 0) - { - LOG_D("key down 0x%x, 0x%x", int1, int2); - } - - return RT_EOK; -} - -static rt_thread_t kbd_thread; -static void kbd_task(void* param) -{ - struct uhintf* intf = (struct uhintf*)param; - while (1) - { - if (rt_usb_hcd_pipe_xfer(intf->device->hcd, ((struct uhid*)intf->user_data)->pipe_in, - ((struct uhid*)intf->user_data)->buffer, ((struct uhid*)intf->user_data)->pipe_in->ep.wMaxPacketSize, - USB_TIMEOUT_BASIC) == 0) - { - break; - } - - rt_usbh_hid_kbd_callback(intf->user_data); - } -} - - -static rt_err_t rt_usbh_hid_kbd_init(void* arg) -{ - struct uhintf* intf = (struct uhintf*)arg; - - RT_ASSERT(intf != RT_NULL); - - rt_usbh_hid_set_protocal(intf, 0); - - rt_usbh_hid_set_idle(intf, 10, 0); - - LOG_D("start usb keyboard"); - - kbd_thread = rt_thread_create("kbd0", kbd_task, intf, 1024, 8, 100); - rt_thread_startup(kbd_thread); - - return RT_EOK; -} - -/** - * This function will define the hid keyboard protocal, it will be register to the protocal list. - * - * @return the keyboard protocal structure. - */ -uprotocal_t rt_usbh_hid_protocal_kbd(void) -{ - kbd_protocal.pro_id = USB_HID_KEYBOARD; - - kbd_protocal.init = rt_usbh_hid_kbd_init; - kbd_protocal.callback = rt_usbh_hid_kbd_callback; - - return &kbd_protocal; -} - -#endif - diff --git a/components/drivers/usb/usbhost/class/umouse.c b/components/drivers/usb/usbhost/class/umouse.c deleted file mode 100644 index dfd6e9081c..0000000000 --- a/components/drivers/usb/usbhost/class/umouse.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-01-03 Yi Qiu first version - */ - -#include <rtthread.h> -#include <drivers/usb_host.h> -#include "hid.h" - -#ifdef RT_USING_RTGUI -#include <rtgui/event.h> -#include <rtgui/rtgui_server.h> -#include "drv_lcd.h" -#endif - -#if defined(RT_USBH_HID) && defined(RT_USBH_HID_MOUSE) - -#define DBG_TAG "usbhost.umouse" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -static struct uprotocal mouse_protocal; - -#ifdef RT_USING_RTGUI -#define LKEY_PRESS 0x01 -#define RKEY_PRESS 0x02 -#define MKEY_PRESS 0x04 -#define MOUSE_SCALING 0x02 - -static rt_bool_t lkey_down=RT_FALSE; -//static rt_bool_t rkey_down=RT_FALSE; -//static rt_bool_t mkey_down=RT_FALSE; -static struct rtgui_event_mouse emouse; -#endif - -static rt_err_t rt_usbh_hid_mouse_callback(void* arg) -{ - struct uhid* hid; -#ifdef RT_USING_RTGUI - rt_uint16_t xoffset=0; - rt_uint16_t yoffset=0; -#endif - hid = (struct uhid*)arg; - - LOG_D("hid 0x%x 0x%x", - *(rt_uint32_t*)hid->buffer, - *(rt_uint32_t*)(&hid->buffer[4])); -#ifdef RT_USING_RTGUI - if(hid->buffer[1]!=0) - { - if(hid->buffer[1]>127) - { - xoffset=(256-hid->buffer[1])*MOUSE_SCALING; - if(emouse.x>xoffset) - { - emouse.x-=xoffset; - } - else - { - emouse.x=0; - } - } - else - { - xoffset=(hid->buffer[1])*MOUSE_SCALING; - if((emouse.x+xoffset)<480) - { - emouse.x+=xoffset; - } - else - { - emouse.x=480; - } - } - } - if(hid->buffer[2]!=0) - { - - if(hid->buffer[2]>127) - { - yoffset=(256-hid->buffer[2])*MOUSE_SCALING; - if(emouse.y>yoffset) - { - emouse.y-=yoffset; - } - else - { - emouse.y=0; - } - } - else - { - yoffset=hid->buffer[2]*MOUSE_SCALING; - if(emouse.y+yoffset<272) - { - emouse.y+=yoffset; - } - else - { - emouse.y=272; - } - } - } - if(xoffset!=0||yoffset!=0) - { - cursor_set_position(emouse.x,emouse.y); - } - if(hid->buffer[0]&LKEY_PRESS) - { - if(lkey_down==RT_FALSE) - { - // rt_kprintf("mouse left key press down\n"); - emouse.button = (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN); - rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); - lkey_down=RT_TRUE; - } - } - else if(lkey_down==RT_TRUE) - { - // rt_kprintf("mouse left key press up\n"); - emouse.button = (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP); - rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse)); - lkey_down=RT_FALSE; - } -#endif - return RT_EOK; -} - -static rt_thread_t mouse_thread; -static void mouse_task(void* param) -{ - struct uhintf* intf = (struct uhintf*)param; - while (1) - { - if (rt_usb_hcd_pipe_xfer(intf->device->hcd, ((struct uhid*)intf->user_data)->pipe_in, - ((struct uhid*)intf->user_data)->buffer, ((struct uhid*)intf->user_data)->pipe_in->ep.wMaxPacketSize, - USB_TIMEOUT_BASIC) == 0) - { - break; - } - - rt_usbh_hid_mouse_callback(intf->user_data); - } -} - - -static rt_err_t rt_usbh_hid_mouse_init(void* arg) -{ - struct uhintf* intf = (struct uhintf*)arg; - - RT_ASSERT(intf != RT_NULL); - - rt_usbh_hid_set_protocal(intf, 0); - - rt_usbh_hid_set_idle(intf, 0, 0); - - mouse_thread = rt_thread_create("mouse0", mouse_task, intf, 1024, 8, 100); - rt_thread_startup(mouse_thread); - - LOG_D("start usb mouse"); -#ifdef RT_USING_RTGUI - RTGUI_EVENT_MOUSE_BUTTON_INIT(&emouse); - emouse.wid = RT_NULL; - cursor_display(RT_TRUE); -#endif - return RT_EOK; -} - -/** - * This function will define the hid mouse protocal, it will be register to the protocal list. - * - * @return the keyboard protocal structure. - */ -uprotocal_t rt_usbh_hid_protocal_mouse(void) -{ - mouse_protocal.pro_id = USB_HID_MOUSE; - - mouse_protocal.init = rt_usbh_hid_mouse_init; - mouse_protocal.callback = rt_usbh_hid_mouse_callback; - - return &mouse_protocal; -} - -#endif - diff --git a/components/drivers/usb/usbhost/core/driver.c b/components/drivers/usb/usbhost/core/driver.c deleted file mode 100644 index 28a79dfa7f..0000000000 --- a/components/drivers/usb/usbhost/core/driver.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-03-12 Yi Qiu first version - * 2021-02-23 Leslie Lee provide possibility for multi usb host - */ - -#include <rtthread.h> -#include <rtservice.h> -#include <drivers/usb_host.h> - -static rt_list_t _driver_list; -static rt_bool_t _driver_list_created = RT_FALSE; - -/** - * This function will initilize the usb class driver related data structure, - * and it should be invoked in the usb system initialization. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_class_driver_init(void) -{ - if (_driver_list_created == RT_FALSE) - { - rt_list_init(&_driver_list); - _driver_list_created = RT_TRUE; - } - return RT_EOK; -} - -/** - * This function will register an usb class driver to the class driver manager. - * - * @param drv the pointer of the usb class driver. - * - * @return the error code, RT_EOK on successfully. - */ - -rt_err_t rt_usbh_class_driver_register(ucd_t drv) -{ - if (drv == RT_NULL) return -RT_ERROR; - - if (rt_usbh_class_driver_find(drv->class_code, drv->subclass_code) == RT_NULL) - { - /* insert class driver into driver list */ - rt_list_insert_after(&_driver_list, &(drv->list)); - } - - return RT_EOK; -} - -/** - * This function will removes a previously registed usb class driver. - * - * @param drv the pointer of the usb class driver structure. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_class_driver_unregister(ucd_t drv) -{ - RT_ASSERT(drv != RT_NULL); - - /* remove class driver from driver list */ - rt_list_remove(&(drv->list)); - - return RT_EOK; -} - -/** - * This function will run an usb class driver. - * - * @param drv the pointer of usb class driver. - * @param args the parameter of run function. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_class_driver_enable(ucd_t drv, void* args) -{ - RT_ASSERT(drv != RT_NULL); - - if(drv->enable != RT_NULL) - drv->enable(args); - - return RT_EOK; -} - -/** - * This function will stop a usb class driver. - * - * @param drv the pointer of usb class driver structure. - * @param args the argument of the stop function. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_class_driver_disable(ucd_t drv, void* args) -{ - RT_ASSERT(drv != RT_NULL); - - if(drv->disable != RT_NULL) - drv->disable(args); - - return RT_EOK; -} - - -/** - * This function finds a usb class driver by specified class code and subclass code. - * - * @param class_code the usb class driver's class code. - * @param subclass_code the usb class driver's sub class code. - * - * @return the registered usb class driver on successful, or RT_NULL on failure. - */ -ucd_t rt_usbh_class_driver_find(int class_code, int subclass_code) -{ - struct rt_list_node *node; - - /* enter critical */ - if (rt_thread_self() != RT_NULL) - rt_enter_critical(); - - /* try to find driver object */ - for (node = _driver_list.next; node != &_driver_list; node = node->next) - { - ucd_t drv = - (ucd_t)rt_list_entry(node, struct uclass_driver, list); - if (drv->class_code == class_code) - { - /* leave critical */ - if (rt_thread_self() != RT_NULL) - rt_exit_critical(); - - return drv; - } - } - - /* leave critical */ - if (rt_thread_self() != RT_NULL) - rt_exit_critical(); - - /* not found */ - return RT_NULL; -} diff --git a/components/drivers/usb/usbhost/core/hub.c b/components/drivers/usb/usbhost/core/hub.c deleted file mode 100644 index d8e6716099..0000000000 --- a/components/drivers/usb/usbhost/core/hub.c +++ /dev/null @@ -1,727 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-12 Yi Qiu first version - * 2021-02-23 Leslie Lee provide possibility for multi usb host - */ - -#include <rtthread.h> -#include <drivers/usb_host.h> - -#define USB_THREAD_STACK_SIZE 4096 - -#define DBG_TAG "usb.host.hub" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - - -// static struct rt_messagequeue *usb_mq; -static struct uclass_driver hub_driver; -// static struct uhub root_hub; - -static rt_err_t root_hub_ctrl(struct uhcd *hcd, rt_uint16_t port, rt_uint8_t cmd, void *args) -{ - switch(cmd) - { - case RH_GET_PORT_STATUS: - (*(rt_uint32_t *)args) = hcd->roothub->port_status[port-1]; - break; - case RH_SET_PORT_STATUS: - hcd->roothub->port_status[port-1] = (*(rt_uint32_t *)args); - break; - case RH_CLEAR_PORT_FEATURE: - switch(((rt_uint32_t)args)) - { - case PORT_FEAT_C_CONNECTION: - hcd->roothub->port_status[port-1] &= ~PORT_CCSC; - break; - case PORT_FEAT_C_ENABLE: - hcd->roothub->port_status[port-1] &= ~PORT_PESC; - break; - case PORT_FEAT_C_SUSPEND: - hcd->roothub->port_status[port-1] &= ~PORT_PSSC; - break; - case PORT_FEAT_C_OVER_CURRENT: - hcd->roothub->port_status[port-1] &= ~PORT_POCIC; - break; - case PORT_FEAT_C_RESET: - hcd->roothub->port_status[port-1] &= ~PORT_PRSC; - break; - } - break; - case RH_SET_PORT_FEATURE: - switch((rt_uint32_t)args) - { - case PORT_FEAT_CONNECTION: - hcd->roothub->port_status[port-1] |= PORT_CCSC; - break; - case PORT_FEAT_ENABLE: - hcd->roothub->port_status[port-1] |= PORT_PESC; - break; - case PORT_FEAT_SUSPEND: - hcd->roothub->port_status[port-1] |= PORT_PSSC; - break; - case PORT_FEAT_OVER_CURRENT: - hcd->roothub->port_status[port-1] |= PORT_POCIC; - break; - case PORT_FEAT_RESET: - hcd->ops->reset_port(port); - break; - case PORT_FEAT_POWER: - break; - case PORT_FEAT_LOWSPEED: - break; - case PORT_FEAT_HIGHSPEED: - break; - } - break; - default: - return -RT_ERROR; - } - return RT_EOK; -} -void rt_usbh_root_hub_connect_handler(struct uhcd *hcd, rt_uint8_t port, rt_bool_t isHS) -{ - struct uhost_msg msg; - msg.type = USB_MSG_CONNECT_CHANGE; - msg.content.hub = hcd->roothub; - hcd->roothub->port_status[port - 1] |= PORT_CCS | PORT_CCSC; - if(isHS) - { - hcd->roothub->port_status[port - 1] &= ~PORT_LSDA; - } - else - { - hcd->roothub->port_status[port - 1] |= PORT_LSDA; - } - rt_usbh_event_signal(hcd, &msg); -} - -void rt_usbh_root_hub_disconnect_handler(struct uhcd *hcd, rt_uint8_t port) -{ - struct uhost_msg msg; - msg.type = USB_MSG_CONNECT_CHANGE; - msg.content.hub = hcd->roothub; - hcd->roothub->port_status[port - 1] |= PORT_CCSC; - hcd->roothub->port_status[port - 1] &= ~PORT_CCS; - rt_usbh_event_signal(hcd, &msg); -} - -/** - * This function will do USB_REQ_GET_DESCRIPTOR bRequest for the device instance - * to get usb hub descriptor. - * - * @param intf the interface instance. - * @buffer the data buffer to save usb hub descriptor. - * @param nbytes the size of buffer - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer, rt_size_t nbytes) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE; - setup.bRequest = USB_REQ_GET_DESCRIPTOR; - setup.wIndex = 0; - setup.wLength = nbytes; - setup.wValue = USB_DESC_TYPE_HUB << 8; - - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8) - { - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, nbytes, timeout) == nbytes) - { - return RT_EOK; - } - } - return -RT_FALSE; -} - -/** - * This function will do USB_REQ_GET_STATUS bRequest for the device instance - * to get usb hub status. - * - * @param intf the interface instance. - * @buffer the data buffer to save usb hub status. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_get_status(struct uinstance* device, rt_uint32_t* buffer) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(device != RT_NULL); - - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE; - setup.bRequest = USB_REQ_GET_STATUS; - setup.wIndex = 0; - setup.wLength = 4; - setup.wValue = 0; - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8) - { - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, 4, timeout) == 4) - { - return RT_EOK; - } - } - return -RT_FALSE; -} - -/** - * This function will do USB_REQ_GET_STATUS bRequest for the device instance - * to get hub port status. - * - * @param intf the interface instance. - * @port the hub port to get status. - * @buffer the data buffer to save usb hub status. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_get_port_status(uhub_t hub, rt_uint16_t port, rt_uint32_t* buffer) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(hub != RT_NULL); - - /* get roothub port status */ - if(hub->is_roothub) - { - root_hub_ctrl(hub->hcd, port, RH_GET_PORT_STATUS, - (void*)buffer); - return RT_EOK; - } - - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_OTHER; - setup.bRequest = USB_REQ_GET_STATUS; - setup.wIndex = port; - setup.wLength = 4; - setup.wValue = 0; - - if(rt_usb_hcd_setup_xfer(hub->hcd, hub->self->pipe_ep0_out, &setup, timeout) == 8) - { - if(rt_usb_hcd_pipe_xfer(hub->hcd, hub->self->pipe_ep0_in, buffer, 4, timeout) == 4) - { - return RT_EOK; - } - } - return -RT_FALSE; -} - -/** - * This function will do USB_REQ_CLEAR_FEATURE bRequest for the device instance - * to clear feature of the hub port. - * - * @param intf the interface instance. - * @port the hub port. - * @feature feature to be cleared. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_clear_port_feature(uhub_t hub, rt_uint16_t port, rt_uint16_t feature) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(hub != RT_NULL); - - /* clear roothub feature */ - if(hub->is_roothub) - { - root_hub_ctrl(hub->hcd, port, RH_CLEAR_PORT_FEATURE, - (void*)(rt_uint32_t)feature); - return RT_EOK; - } - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS | - USB_REQ_TYPE_OTHER; - setup.bRequest = USB_REQ_CLEAR_FEATURE; - setup.wIndex = port; - setup.wLength = 0; - setup.wValue = feature; - - if(rt_usb_hcd_setup_xfer(hub->hcd, hub->self->pipe_ep0_out, &setup, timeout) == 8) - { - return RT_EOK; - } - return -RT_FALSE; -} - -/** - * This function will do USB_REQ_SET_FEATURE bRequest for the device instance - * to set feature of the hub port. - * - * @param intf the interface instance. - * @port the hub port. - * @feature feature to be set. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_set_port_feature(uhub_t hub, rt_uint16_t port, - rt_uint16_t feature) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* parameter check */ - RT_ASSERT(hub != RT_NULL); - - /* clear roothub feature */ - if(hub->is_roothub) - { - root_hub_ctrl(hub->hcd, port, RH_SET_PORT_FEATURE, - (void*)(rt_uint32_t)feature); - return RT_EOK; - } - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_CLASS | - USB_REQ_TYPE_OTHER; - setup.bRequest = USB_REQ_SET_FEATURE; - setup.wIndex = port; - setup.wLength = 0; - setup.wValue = feature; - - if(rt_usb_hcd_setup_xfer(hub->hcd, hub->self->pipe_ep0_out, &setup, timeout) == 8) - { - return RT_EOK; - } - else return -RT_FALSE; -} - -/** - * This function will rest hub port, it is invoked when sub device attached to the hub port. - * - * @param intf the interface instance. - * @param port the hub port. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_reset_port(uhub_t hub, rt_uint16_t port) -{ - rt_err_t ret; - rt_uint32_t pstatus; - - /* parameter check */ - RT_ASSERT(hub != RT_NULL); - - rt_thread_delay(50); - - /* reset hub port */ - ret = rt_usbh_hub_set_port_feature(hub, port, PORT_FEAT_RESET); - if(ret != RT_EOK) return ret; - - while(1) - { - ret = rt_usbh_hub_get_port_status(hub, port, &pstatus); - if(!(pstatus & PORT_PRS)) break; - } - - /* clear port reset feature */ - ret = rt_usbh_hub_clear_port_feature(hub, port, PORT_FEAT_C_RESET); - if(ret != RT_EOK) return ret; - - rt_thread_delay(50); - - return RT_EOK; -} - -/** - * This function will do debouce, it is invoked when sub device attached to the hub port. - * - * @param device the usb instance. - * @param port the hub port. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_hub_port_debounce(uhub_t hub, rt_uint16_t port) -{ - rt_err_t ret; - int i = 0, times = 20; - rt_uint32_t pstatus; - rt_bool_t connect = RT_TRUE; - int delayticks = USB_DEBOUNCE_TIME / times; - if (delayticks < 1) - delayticks = 1; - - /* parameter check */ - RT_ASSERT(hub != RT_NULL); - - for(i=0; i<times; i++) - { - ret = rt_usbh_hub_get_port_status(hub, port, &pstatus); - if(ret != RT_EOK) return ret; - - if(!(pstatus & PORT_CCS)) - { - connect = RT_FALSE; - break; - } - - rt_thread_delay(delayticks); - } - - if(connect) return RT_EOK; - else return -RT_ERROR; -} - -/** - * This function will poll all the hub ports to detect port status, especially connect and - * disconnect events. - * - * @param intf the interface instance. - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t rt_usbh_hub_port_change(uhub_t hub) -{ - int i; - rt_bool_t reconnect; - - /* parameter check */ - RT_ASSERT(hub != RT_NULL); - - /* get usb device instance */ - for (i = 0; i < hub->num_ports; i++) - { - rt_err_t ret; - struct uinstance* device; - rt_uint32_t pstatus = 0; - - reconnect = RT_FALSE; - - /* get hub port status */ - ret = rt_usbh_hub_get_port_status(hub, i + 1, &pstatus); - if(ret != RT_EOK) continue; - - LOG_D("port %d status 0x%x", i + 1, pstatus); - - /* check port status change */ - if (pstatus & PORT_CCSC) - { - /* clear port status change feature */ - rt_usbh_hub_clear_port_feature(hub, i + 1, PORT_FEAT_C_CONNECTION); - reconnect = RT_TRUE; - } - - if(pstatus & PORT_PESC) - { - rt_usbh_hub_clear_port_feature(hub, i + 1, PORT_FEAT_C_ENABLE); - reconnect = RT_TRUE; - } - - if(reconnect) - { - if(hub->child[i] != RT_NULL && hub->child[i]->status != DEV_STATUS_IDLE) - { - rt_usbh_detach_instance(hub->child[i]); - - /* Child device have been detach. Set hub->child[i] to NULL. */ - hub->child[i] = RT_NULL; - } - - ret = rt_usbh_hub_port_debounce(hub, i + 1); - if(ret != RT_EOK) continue; - - /* allocate an usb instance for new connected device */ - device = rt_usbh_alloc_instance(hub->hcd); - if(device == RT_NULL) break; - - /* set usb device speed */ - device->speed = (pstatus & PORT_LSDA) ? 1 : 0; - device->parent_hub = hub; - device->hcd = hub->hcd; - device->port = i + 1; - hub->child[i] = device; - - /* reset usb roothub port */ - rt_usbh_hub_reset_port(hub, i + 1); - - /* attatch the usb instance to the hcd */ - rt_usbh_attatch_instance(device); - } - } - - return RT_EOK; -} - -/** - * This function is the callback function of hub's int endpoint, it is invoked when data comes. - * - * @param context the context of the callback function. - * - * @return none. - */ -static void rt_usbh_hub_irq(void* context) -{ - upipe_t pipe; - uhub_t hub; - int timeout = USB_TIMEOUT_BASIC; - - RT_ASSERT(context != RT_NULL); - - pipe = (upipe_t)context; - hub = (uhub_t)pipe->user_data; - - if(pipe->status != UPIPE_STATUS_OK) - { - LOG_D("hub irq error"); - return; - } - - rt_usbh_hub_port_change(hub); - - LOG_D("hub int xfer..."); - - /* parameter check */ - RT_ASSERT(pipe->inst->hcd != RT_NULL); - - rt_usb_hcd_pipe_xfer(hub->self->hcd, pipe, hub->buffer, pipe->ep.wMaxPacketSize, timeout); -} - -/** - * This function will run usb hub class driver when usb hub is detected and identified - * as a hub class device, it will continue to do the enumulate process. - * - * @param arg the argument. - * - * @return the error code, RT_EOK on successfully. - */ - -static rt_err_t rt_usbh_hub_enable(void *arg) -{ - int i = 0; - rt_err_t ret = RT_EOK; - uep_desc_t ep_desc = RT_NULL; - uhub_t hub; - struct uinstance* device; - struct uhintf* intf = (struct uhintf*)arg; - upipe_t pipe_in = RT_NULL; - int timeout = USB_TIMEOUT_LONG; - /* paremeter check */ - RT_ASSERT(intf != RT_NULL); - - /* get usb device instance */ - device = intf->device; - - /* create a hub instance */ - hub = rt_malloc(sizeof(struct uhub)); - RT_ASSERT(hub != RT_NULL); - rt_memset(hub, 0, sizeof(struct uhub)); - - /* make interface instance's user data point to hub instance */ - intf->user_data = (void*)hub; - - /* get hub descriptor head */ - ret = rt_usbh_hub_get_descriptor(device, (rt_uint8_t*)&hub->hub_desc, 8); - if(ret != RT_EOK) - { - rt_kprintf("get hub descriptor failed\n"); - return -RT_ERROR; - } - - /* get full hub descriptor */ - ret = rt_usbh_hub_get_descriptor(device, (rt_uint8_t*)&hub->hub_desc, - hub->hub_desc.length); - if(ret != RT_EOK) - { - rt_kprintf("get hub descriptor again failed\n"); - return -RT_ERROR; - } - - /* get hub ports number */ - /* If hub device supported ports over USB_HUB_PORT_NUM(Ex: 8 port hub). Set hub->num_ports to USB_HUB_PORT_NUM */ - if(hub->hub_desc.num_ports > USB_HUB_PORT_NUM) - hub->num_ports = USB_HUB_PORT_NUM; - else - hub->num_ports = hub->hub_desc.num_ports; - - hub->hcd = device->hcd; - hub->self = device; - - /* reset all hub ports */ - for (i = 0; i < hub->num_ports; i++) - { - rt_usbh_hub_set_port_feature(hub, i + 1, PORT_FEAT_POWER); - rt_thread_delay(hub->hub_desc.pwron_to_good - * 2 * RT_TICK_PER_SECOND / 1000 ); - } - - if(intf->intf_desc->bNumEndpoints != 1) - return -RT_ERROR; - - /* get endpoint descriptor from interface descriptor */ - rt_usbh_get_endpoint_descriptor(intf->intf_desc, 0, &ep_desc); - if(ep_desc == RT_NULL) - { - rt_kprintf("rt_usb_get_endpoint_descriptor error\n"); - return -RT_ERROR; - } - - /* the endpoint type of hub class should be interrupt */ - if( USB_EP_ATTR(ep_desc->bmAttributes) == USB_EP_ATTR_INT) - { - /* the endpoint direction of hub class should be in */ - if(ep_desc->bEndpointAddress & USB_DIR_IN) - { - /* allocate a pipe according to the endpoint type */ - pipe_in = rt_usb_instance_find_pipe(device,ep_desc->bEndpointAddress); - if(pipe_in == RT_NULL) - { - return -RT_ERROR; - } - rt_usb_pipe_add_callback(pipe_in,rt_usbh_hub_irq); - } - else return -RT_ERROR; - } - - /* parameter check */ - RT_ASSERT(device->hcd != RT_NULL); - pipe_in->user_data = hub; - rt_usb_hcd_pipe_xfer(hub->hcd, pipe_in, hub->buffer, - pipe_in->ep.wMaxPacketSize, timeout); - return RT_EOK; -} - -/** - * This function will be invoked when usb hub plug out is detected and it would clean - * and release all hub class related resources. - * - * @param arg the argument. - * - * @return the error code, RT_EOK on successfully. - */ -static rt_err_t rt_usbh_hub_disable(void* arg) -{ - int i; - uhub_t hub; - struct uhintf* intf = (struct uhintf*)arg; - - /* paremeter check */ - RT_ASSERT(intf != RT_NULL); - - LOG_D("rt_usbh_hub_stop"); - hub = (uhub_t)intf->user_data; - - for(i=0; i<hub->num_ports; i++) - { - if(hub->child[i] != RT_NULL) - rt_usbh_detach_instance(hub->child[i]); - } - - if(hub != RT_NULL) rt_free(hub); - - return RT_EOK; -} - -/** - * This function will register hub class driver to the usb class driver manager. - * and it should be invoked in the usb system initialization. - * - * @return the error code, RT_EOK on successfully. - */ -ucd_t rt_usbh_class_driver_hub(void) -{ - hub_driver.class_code = USB_CLASS_HUB; - - hub_driver.enable = rt_usbh_hub_enable; - hub_driver.disable = rt_usbh_hub_disable; - - return &hub_driver; -} - -/** - * This function is the main entry of usb hub thread, it is in charge of - * processing all messages received from the usb message buffer. - * - * @param parameter the parameter of the usb host thread. - * - * @return none. - */ -static void rt_usbh_hub_thread_entry(void* parameter) -{ - uhcd_t hcd = (uhcd_t)parameter; - while(1) - { - struct uhost_msg msg; - - /* receive message */ - if (rt_mq_recv(hcd->usb_mq, &msg, sizeof(struct uhost_msg), RT_WAITING_FOREVER) < 0) - continue; - - switch (msg.type) - { - case USB_MSG_CONNECT_CHANGE: - rt_usbh_hub_port_change(msg.content.hub); - break; - case USB_MSG_CALLBACK: - /* invoke callback */ - msg.content.cb.function(msg.content.cb.context); - break; - default: - break; - } - } -} - -/** - * This function will post an message to the usb message queue, - * - * @param msg the message to be posted - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_event_signal(uhcd_t hcd, struct uhost_msg* msg) -{ - RT_ASSERT(msg != RT_NULL); - - /* send message to usb message queue */ - rt_mq_send(hcd->usb_mq, (void*)msg, sizeof(struct uhost_msg)); - - return RT_EOK; -} - -/** - * This function will initialize usb hub thread. - * - * @return none. - * - */ -void rt_usbh_hub_init(uhcd_t hcd) -{ - rt_thread_t thread; - /* create root hub for hcd */ - hcd->roothub = rt_malloc(sizeof(struct uhub)); - if(hcd->roothub == RT_NULL) - { - LOG_E("hcd->roothub: allocate buffer failed."); - return; - } - rt_memset(hcd->roothub, 0, sizeof(struct uhub)); - hcd->roothub->is_roothub = RT_TRUE; - hcd->roothub->hcd = hcd; - hcd->roothub->num_ports = hcd->num_ports; - /* create usb message queue */ - - hcd->usb_mq = rt_mq_create(hcd->parent.parent.name, 32, 16, RT_IPC_FLAG_FIFO); - - /* create usb hub thread */ - thread = rt_thread_create(hcd->parent.parent.name, rt_usbh_hub_thread_entry, hcd, - USB_THREAD_STACK_SIZE, 8, 20); - if(thread != RT_NULL) - { - /* startup usb host thread */ - rt_thread_startup(thread); - } -} diff --git a/components/drivers/usb/usbhost/core/usbhost.c b/components/drivers/usb/usbhost/core/usbhost.c deleted file mode 100644 index a4cdc12e5e..0000000000 --- a/components/drivers/usb/usbhost/core/usbhost.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-12 Yi Qiu first version - * 2021-02-23 Leslie Lee provide possibility for multi usb host - */ -#include <rtthread.h> -#include <drivers/usb_host.h> - -#define USB_HOST_CONTROLLER_NAME "usbh" - -#if defined(RT_USBH_HID_KEYBOARD) || defined(RT_USBH_HID_MOUSE) -#include <hid.h> -#endif - -/** - * This function will initialize the usb host stack, all the usb class driver and - * host controller driver are also be initialized here. - * - * @return none. - */ -rt_err_t rt_usb_host_init(const char *name) -{ - ucd_t drv; - rt_device_t uhc; - - uhc = rt_device_find(name); - if(uhc == RT_NULL) - { - rt_kprintf("can't find usb host controller %s\n", name); - return -RT_ERROR; - } - - /* initialize usb hub */ - rt_usbh_hub_init((uhcd_t)uhc); - - /* initialize class driver */ - rt_usbh_class_driver_init(); - -#ifdef RT_USBH_MSTORAGE - /* register mass storage class driver */ - drv = rt_usbh_class_driver_storage(); - rt_usbh_class_driver_register(drv); -#endif -#ifdef RT_USBH_HID - extern ucd_t rt_usbh_class_driver_hid(void); - /* register mass storage class driver */ - drv = rt_usbh_class_driver_hid(); - rt_usbh_class_driver_register(drv); -#ifdef RT_USBH_HID_MOUSE - { - extern uprotocal_t rt_usbh_hid_protocal_mouse(void); - rt_usbh_hid_protocal_register(rt_usbh_hid_protocal_mouse()); - } -#endif -#ifdef RT_USBH_HID_KEYBOARD - { - extern uprotocal_t rt_usbh_hid_protocal_kbd(void); - rt_usbh_hid_protocal_register(rt_usbh_hid_protocal_kbd()); - } -#endif -#endif - - /* register hub class driver */ - drv = rt_usbh_class_driver_hub(); - rt_usbh_class_driver_register(drv); - - /* initialize usb host controller */ - rt_device_init(uhc); - - return RT_EOK; -} diff --git a/components/drivers/usb/usbhost/core/usbhost_core.c b/components/drivers/usb/usbhost/core/usbhost_core.c deleted file mode 100644 index fae5ba75fb..0000000000 --- a/components/drivers/usb/usbhost/core/usbhost_core.c +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-12-12 Yi Qiu first version - */ - -#include <rtthread.h> -#include <drivers/usb_host.h> - -#define DBG_TAG "usbhost.core" -#define DBG_LVL DBG_INFO -#include <rtdbg.h> - -static struct uinstance dev[USB_MAX_DEVICE]; - -/** - * This function will allocate an usb device instance from system. - * - * @param parent the hub instance to which the new allocated device attached. - * @param port the hub port. - * - * @return the allocate instance on successful, or RT_NULL on failure. - */ -uinst_t rt_usbh_alloc_instance(uhcd_t uhcd) -{ - int i; - - /* lock scheduler */ - rt_enter_critical(); - - for(i=0; i<USB_MAX_DEVICE; i++) - { - /* to find an idle instance handle */ - if(dev[i].status != DEV_STATUS_IDLE) continue; - - /* initialize the usb device instance */ - rt_memset(&dev[i], 0, sizeof(struct uinstance)); - - dev[i].status = DEV_STATUS_BUSY; - dev[i].index = i + 1; - dev[i].address = 0; - dev[i].max_packet_size = 0x8; - rt_list_init(&dev[i].pipe); - dev[i].hcd = uhcd; - /* unlock scheduler */ - rt_exit_critical(); - return &dev[i]; - } - - /* unlock scheduler */ - rt_exit_critical(); - - return RT_NULL; -} - -/** - * This function will attatch an usb device instance to a host controller, - * and do device enumunation process. - * - * @param hcd the host controller driver. - * @param device the usb device instance. - * - * @return the error code, RT_EOK on successfully. - */ -static struct uendpoint_descriptor ep0_out_desc = -{ - /*endpoint descriptor*/ - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - 0x00 | USB_DIR_OUT, - USB_EP_ATTR_CONTROL, - 0x00, - 0x00, -}; -static struct uendpoint_descriptor ep0_in_desc = -{ - /*endpoint descriptor*/ - USB_DESC_LENGTH_ENDPOINT, - USB_DESC_TYPE_ENDPOINT, - 0x00 | USB_DIR_IN, - USB_EP_ATTR_CONTROL, - 0x00, - 0x00, -}; -rt_err_t rt_usbh_attatch_instance(uinst_t device) -{ - int i = 0; - rt_err_t ret = RT_EOK; - struct uconfig_descriptor cfg_desc; - udev_desc_t dev_desc; - uintf_desc_t intf_desc; - uep_desc_t ep_desc; - rt_uint8_t ep_index; - upipe_t pipe; - ucd_t drv; - - RT_ASSERT(device != RT_NULL); - - rt_memset(&cfg_desc, 0, sizeof(struct uconfig_descriptor)); - dev_desc = &device->dev_desc; - - /* alloc address 0 ep0 pipe*/ - ep0_out_desc.wMaxPacketSize = 8; - ep0_in_desc.wMaxPacketSize = 8; - rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_out, device, &ep0_out_desc); - rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_in, device, &ep0_in_desc); - - LOG_D("start enumnation"); - - /* get device descriptor head */ - ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_DEVICE, (void*)dev_desc, 8); - if(ret != RT_EOK) - { - rt_kprintf("get device descriptor head failed\n"); - return ret; - } - - /* reset bus */ - rt_usbh_hub_reset_port(device->parent_hub, device->port); - rt_thread_delay(2); - rt_usbh_hub_clear_port_feature(device->parent_hub, i + 1, PORT_FEAT_C_CONNECTION); - /* set device address */ - ret = rt_usbh_set_address(device); - if(ret != RT_EOK) - { - rt_kprintf("set device address failed\n"); - return ret; - } - /* free address 0 ep0 pipe*/ - - rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_out); - rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_in); - - /* set device max packet size */ - ep0_out_desc.wMaxPacketSize = device->dev_desc.bMaxPacketSize0; - ep0_in_desc.wMaxPacketSize = device->dev_desc.bMaxPacketSize0; - - /* alloc true address ep0 pipe*/ - rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_out, device, &ep0_out_desc); - rt_usb_hcd_alloc_pipe(device->hcd, &device->pipe_ep0_in, device, &ep0_in_desc); - LOG_D("get device descriptor length %d", - dev_desc->bLength); - - /* get full device descriptor again */ - ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_DEVICE, (void*)dev_desc, dev_desc->bLength); - if(ret != RT_EOK) - { - rt_kprintf("get full device descriptor failed\n"); - return ret; - } - - LOG_D("Vendor ID 0x%x", dev_desc->idVendor); - LOG_D("Product ID 0x%x", dev_desc->idProduct); - - /* get configuration descriptor head */ - ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_CONFIGURATION, &cfg_desc, 18); - if(ret != RT_EOK) - { - rt_kprintf("get configuration descriptor head failed\n"); - return ret; - } - - /* alloc memory for configuration descriptor */ - device->cfg_desc = (ucfg_desc_t)rt_malloc(cfg_desc.wTotalLength); - if(device->cfg_desc == RT_NULL) - { - return -RT_ENOMEM; - } - rt_memset(device->cfg_desc, 0, cfg_desc.wTotalLength); - - /* get full configuration descriptor */ - ret = rt_usbh_get_descriptor(device, USB_DESC_TYPE_CONFIGURATION, - device->cfg_desc, cfg_desc.wTotalLength); - if(ret != RT_EOK) - { - rt_kprintf("get full configuration descriptor failed\n"); - return ret; - } - - /* set configuration */ - ret = rt_usbh_set_configure(device, 1); - if(ret != RT_EOK) - { - return ret; - } - for(i=0; i<device->cfg_desc->bNumInterfaces; i++) - { - /* get interface descriptor through configuration descriptor */ - ret = rt_usbh_get_interface_descriptor(device->cfg_desc, i, &intf_desc); - if(ret != RT_EOK) - { - rt_kprintf("rt_usb_get_interface_descriptor error\n"); - return -RT_ERROR; - } - - LOG_D("interface class 0x%x, subclass 0x%x", - intf_desc->bInterfaceClass, - intf_desc->bInterfaceSubClass); - /* alloc pipe*/ - for(ep_index = 0; ep_index < intf_desc->bNumEndpoints; ep_index++) - { - rt_usbh_get_endpoint_descriptor(intf_desc, ep_index, &ep_desc); - if(ep_desc != RT_NULL) - { - if(rt_usb_hcd_alloc_pipe(device->hcd, &pipe, device, ep_desc) != RT_EOK) - { - rt_kprintf("alloc pipe failed\n"); - return -RT_ERROR; - } - rt_usb_instance_add_pipe(device,pipe); - } - else - { - rt_kprintf("get endpoint desc failed\n"); - return -RT_ERROR; - } - } - /* find driver by class code found in interface descriptor */ - drv = rt_usbh_class_driver_find(intf_desc->bInterfaceClass, - intf_desc->bInterfaceSubClass); - - if(drv != RT_NULL) - { - /* allocate memory for interface device */ - device->intf[i] = (struct uhintf*)rt_malloc(sizeof(struct uhintf)); - if(device->intf[i] == RT_NULL) - { - return -RT_ENOMEM; - } - device->intf[i]->drv = drv; - device->intf[i]->device = device; - device->intf[i]->intf_desc = intf_desc; - device->intf[i]->user_data = RT_NULL; - - /* open usb class driver */ - ret = rt_usbh_class_driver_enable(drv, (void*)device->intf[i]); - if(ret != RT_EOK) - { - rt_kprintf("interface %d run class driver error\n", i); - } - } - else - { - rt_kprintf("find usb device driver failed\n"); - continue; - } - } - - return RT_EOK; -} - -/** - * This function will detach an usb device instance from its host controller, - * and release all resource. - * - * @param device the usb device instance. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_detach_instance(uinst_t device) -{ - int i = 0; - rt_list_t * l; - if(device == RT_NULL) - { - rt_kprintf("no usb instance to detach\n"); - return -RT_ERROR; - } - - /* free configration descriptor */ - if (device->cfg_desc) { - for (i = 0; i < device->cfg_desc->bNumInterfaces; i++) - { - if (device->intf[i] == RT_NULL) continue; - if (device->intf[i]->drv == RT_NULL) continue; - - RT_ASSERT(device->intf[i]->device == device); - - LOG_D("free interface instance %d", i); - rt_usbh_class_driver_disable(device->intf[i]->drv, (void*)device->intf[i]); - rt_free(device->intf[i]); - } - rt_free(device->cfg_desc); - } - - rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_out); - rt_usb_hcd_free_pipe(device->hcd,device->pipe_ep0_in); - - while(device->pipe.next!= &device->pipe) - { - l = device->pipe.next; - rt_list_remove(l); - rt_usb_hcd_free_pipe(device->hcd,rt_list_entry(l,struct upipe,list)); - } - rt_memset(device, 0, sizeof(struct uinstance)); - - return RT_EOK; -} - -/** - * This function will do USB_REQ_GET_DESCRIPTO' bRequest for the usb device instance, - * - * @param device the usb device instance. - * @param type the type of descriptor bRequest. - * @param buffer the data buffer to save requested data - * @param nbytes the size of buffer - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_get_descriptor(uinst_t device, rt_uint8_t type, void* buffer, - int nbytes) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - RT_ASSERT(device != RT_NULL); - - setup.request_type = USB_REQ_TYPE_DIR_IN | USB_REQ_TYPE_STANDARD | - USB_REQ_TYPE_DEVICE; - setup.bRequest = USB_REQ_GET_DESCRIPTOR; - setup.wIndex = 0; - setup.wLength = nbytes; - setup.wValue = type << 8; - - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) == 8) - { - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, buffer, nbytes, timeout) == nbytes) - { - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_out, RT_NULL, 0, timeout) == 0) - { - return RT_EOK; - } - } - } - return -RT_ERROR; -} - -/** - * This function will set an address to the usb device. - * - * @param device the usb device instance. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_set_address(uinst_t device) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - RT_ASSERT(device != RT_NULL); - - LOG_D("rt_usb_set_address"); - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD | - USB_REQ_TYPE_DEVICE; - setup.bRequest = USB_REQ_SET_ADDRESS; - setup.wIndex = 0; - setup.wLength = 0; - setup.wValue = device->index; - - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) - { - return -RT_ERROR; - } - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, RT_NULL, 0, timeout) == 0) - { - device->address = device->index; - } - - return RT_EOK; -} - -/** - * This function will set a configuration to the usb device. - * - * @param device the usb device instance. - * @param config the configuration number. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_set_configure(uinst_t device, int config) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* check parameter */ - RT_ASSERT(device != RT_NULL); - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD | - USB_REQ_TYPE_DEVICE; - setup.bRequest = USB_REQ_SET_CONFIGURATION; - setup.wIndex = 0; - setup.wLength = 0; - setup.wValue = config; - - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) - { - return -RT_ERROR; - } - if(rt_usb_hcd_pipe_xfer(device->hcd, device->pipe_ep0_in, RT_NULL, 0, timeout) != 0) - { - return -RT_ERROR; - } - return RT_EOK; -} - -/** - * This function will set an interface to the usb device. - * - * @param device the usb device instance. - * @param intf the interface number. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_set_interface(uinst_t device, int intf) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* check parameter */ - RT_ASSERT(device != RT_NULL); - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD | - USB_REQ_TYPE_INTERFACE; - setup.bRequest = USB_REQ_SET_INTERFACE; - setup.wIndex = 0; - setup.wLength = 0; - setup.wValue = intf; - - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) - { - return -RT_ERROR; - } - - return RT_EOK; -} - -/** - * This function will clear feature for the endpoint of the usb device. - * - * @param device the usb device instance. - * @param endpoint the endpoint number of the usb device. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_clear_feature(uinst_t device, int endpoint, int feature) -{ - struct urequest setup; - int timeout = USB_TIMEOUT_BASIC; - - /* check parameter */ - RT_ASSERT(device != RT_NULL); - - setup.request_type = USB_REQ_TYPE_DIR_OUT | USB_REQ_TYPE_STANDARD | - USB_REQ_TYPE_ENDPOINT; - setup.bRequest = USB_REQ_CLEAR_FEATURE; - setup.wIndex = endpoint; - setup.wLength = 0; - setup.wValue = feature; - - if(rt_usb_hcd_setup_xfer(device->hcd, device->pipe_ep0_out, &setup, timeout) != 8) - { - return -RT_ERROR; - } - - return RT_EOK; -} - -/** - * This function will get an interface descriptor from the configuration descriptor. - * - * @param cfg_desc the point of configuration descriptor structure. - * @param num the number of interface descriptor. - * @intf_desc the point of interface descriptor point. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_get_interface_descriptor(ucfg_desc_t cfg_desc, int num, - uintf_desc_t* intf_desc) -{ - rt_uint32_t ptr, depth = 0; - udesc_t desc; - - /* check parameter */ - RT_ASSERT(cfg_desc != RT_NULL); - - ptr = (rt_uint32_t)cfg_desc + cfg_desc->bLength; - while(ptr < (rt_uint32_t)cfg_desc + cfg_desc->wTotalLength) - { - if(depth++ > 0x20) - { - *intf_desc = RT_NULL; - return -RT_EIO; - } - desc = (udesc_t)ptr; - if(desc->type == USB_DESC_TYPE_INTERFACE) - { - if(((uintf_desc_t)desc)->bInterfaceNumber == num) - { - *intf_desc = (uintf_desc_t)desc; - - LOG_D("rt_usb_get_interface_descriptor: %d", num); - return RT_EOK; - } - } - ptr = (rt_uint32_t)desc + desc->bLength; - } - - rt_kprintf("rt_usb_get_interface_descriptor %d failed\n", num); - return -RT_EIO; -} - -/** - * This function will get an endpoint descriptor from the interface descriptor. - * - * @param intf_desc the point of interface descriptor structure. - * @param num the number of endpoint descriptor. - * @param ep_desc the point of endpoint descriptor point. - * - * @return the error code, RT_EOK on successfully. - */ -rt_err_t rt_usbh_get_endpoint_descriptor(uintf_desc_t intf_desc, int num, - uep_desc_t* ep_desc) -{ - int count = 0, depth = 0; - rt_uint32_t ptr; - udesc_t desc; - - /* check parameter */ - RT_ASSERT(intf_desc != RT_NULL); - RT_ASSERT(num < intf_desc->bNumEndpoints); - *ep_desc = RT_NULL; - - ptr = (rt_uint32_t)intf_desc + intf_desc->bLength; - while(count < intf_desc->bNumEndpoints) - { - if(depth++ > 0x20) - { - *ep_desc = RT_NULL; - return -RT_EIO; - } - desc = (udesc_t)ptr; - if(desc->type == USB_DESC_TYPE_ENDPOINT) - { - if(num == count) - { - *ep_desc = (uep_desc_t)desc; - - LOG_D("rt_usb_get_endpoint_descriptor: %d", num); - return RT_EOK; - } - else count++; - } - ptr = (rt_uint32_t)desc + desc->bLength; - } - - rt_kprintf("rt_usb_get_endpoint_descriptor %d failed\n", num); - return -RT_EIO; -} - -int rt_usb_hcd_pipe_xfer(uhcd_t hcd, upipe_t pipe, void* buffer, int nbytes, int timeout) -{ - rt_size_t remain_size; - rt_size_t send_size; - remain_size = nbytes; - rt_uint8_t * pbuffer = (rt_uint8_t *)buffer; - do - { - LOG_D("pipe transform remain size,: %d", remain_size); - send_size = (remain_size > pipe->ep.wMaxPacketSize) ? pipe->ep.wMaxPacketSize : remain_size; - if(hcd->ops->pipe_xfer(pipe, USBH_PID_DATA, pbuffer, send_size, timeout) == send_size) - { - remain_size -= send_size; - pbuffer += send_size; - } - else - { - return 0; - } - }while(remain_size > 0); - return nbytes; -} |
