From 8fd0a7f9c61dde28d90ec4c3661e9e0e8327f7fc Mon Sep 17 00:00:00 2001 From: shaolin Date: Sun, 16 Feb 2014 17:42:35 +0800 Subject: Update USB Device Stack to support more device controllers; Pass USB CV test verification; Code cleanup; --- components/drivers/usb/usbdevice/class/cdc_vcom.c | 557 ++++++----- components/drivers/usb/usbdevice/class/mstorage.c | 1055 +++++++++++++++------ components/drivers/usb/usbdevice/class/mstorage.h | 7 - 3 files changed, 1056 insertions(+), 563 deletions(-) (limited to 'components/drivers/usb/usbdevice/class') diff --git a/components/drivers/usb/usbdevice/class/cdc_vcom.c b/components/drivers/usb/usbdevice/class/cdc_vcom.c index 5f284b0294..33f9f7abef 100644 --- a/components/drivers/usb/usbdevice/class/cdc_vcom.c +++ b/components/drivers/usb/usbdevice/class/cdc_vcom.c @@ -20,34 +20,56 @@ * Change Logs: * Date Author Notes * 2012-10-02 Yi Qiu first version - * 2012-12-12 heyuanjie87 change endpoints and class handler + * 2012-12-12 heyuanjie87 change endpoints and function handler + * 2013-06-25 heyuanjie87 remove SOF mechinism + * 2013-07-20 Yi Qiu do more test */ #include +#include #include #include #include "cdc.h" #ifdef RT_USB_DEVICE_CDC +#define TX_TIMEOUT 100 #define CDC_RX_BUFSIZE 2048 -#define CDC_TX_BUFSIZE 2048 -static rt_uint8_t rx_rbp[CDC_RX_BUFSIZE]; -static rt_uint8_t tx_rbp[CDC_TX_BUFSIZE]; -static struct rt_ringbuffer rx_ringbuffer; -static struct rt_ringbuffer tx_ringbuffer; -static struct serial_ringbuffer vcom_int_rx; +#define CDC_MAX_PACKET_SIZE 64 +#define VCOM_DEVICE "vcom" -static struct rt_serial_device vcom_serial; - -#define CDC_MaxPacketSize 64 -ALIGN(RT_ALIGN_SIZE) -static rt_uint8_t rx_buf[CDC_RX_BUFSIZE]; ALIGN(RT_ALIGN_SIZE) -static rt_uint8_t tx_buf[CDC_TX_BUFSIZE]; +static rt_uint8_t vcom_thread_stack[512]; +static struct rt_thread vcom_thread; +#define VCOM_MQ_MSG_SZ 16 +#define VCOM_MQ_MAX_MSG 4 +/* internal of the message queue: every message is associated with a pointer, + * so in order to recveive VCOM_MQ_MAX_MSG messages, we have to allocate more + * than VCOM_MQ_MSG_SZ*VCOM_MQ_MAX_MSG memery. */ +static rt_uint8_t vcom_tx_thread_mq_pool[(VCOM_MQ_MSG_SZ+sizeof(void*))*VCOM_MQ_MAX_MSG]; +static struct rt_messagequeue vcom_tx_thread_mq; +static struct ucdc_line_coding line_coding; + +struct vcom +{ + struct rt_serial_device serial; + uep_t ep_out; + uep_t ep_in; + uep_t ep_cmd; + rt_bool_t connected; + rt_bool_t in_sending; + struct rt_completion wait; + rt_uint8_t rx_rbp[CDC_RX_BUFSIZE]; + struct rt_ringbuffer rx_ringbuffer; + struct serial_ringbuffer vcom_int_rx; +}; -volatile static rt_bool_t vcom_connected = RT_FALSE; -volatile static rt_bool_t vcom_in_sending = RT_FALSE; +struct vcom_tx_msg +{ + struct rt_serial_device * serial; + const char *buf; + rt_size_t size; +}; static struct udevice_descriptor dev_desc = { @@ -57,7 +79,7 @@ static struct udevice_descriptor dev_desc = USB_CLASS_CDC, //bDeviceClass; 0x00, //bDeviceSubClass; 0x00, //bDeviceProtocol; - CDC_MaxPacketSize, //bMaxPacketSize0; + CDC_MAX_PACKET_SIZE, //bMaxPacketSize0; _VENDOR_ID, //idVendor; _PRODUCT_ID, //idProduct; USB_BCD_DEVICE, //bcdDevice; @@ -67,6 +89,18 @@ static struct udevice_descriptor dev_desc = USB_DYNAMIC, //bNumConfigurations; }; +static struct usb_qualifier_descriptor dev_qualifier = +{ + sizeof(dev_qualifier), + USB_DESC_TYPE_DEVICEQUALIFIER, + 0x0200, + USB_CLASS_CDC, + 0x00, + 64, + 0x01, + 0, +}; + /* communcation interface descriptor */ const static struct ucdc_comm_descriptor _comm_desc = { @@ -85,19 +119,19 @@ const static struct ucdc_comm_descriptor _comm_desc = USB_DESC_LENGTH_INTERFACE, USB_DESC_TYPE_INTERFACE, USB_DYNAMIC, - 0x00, + 0x00, 0x01, USB_CDC_CLASS_COMM, USB_CDC_SUBCLASS_ACM, USB_CDC_PROTOCOL_V25TER, 0x00, - /* Header Functional Descriptor */ - 0x05, + /* Header Functional Descriptor */ + 0x05, USB_CDC_CS_INTERFACE, USB_CDC_SCS_HEADER, 0x0110, - /* Call Management Functional Descriptor */ - 0x05, + /* Call Management Functional Descriptor */ + 0x05, USB_CDC_CS_INTERFACE, USB_CDC_SCS_CALL_MGMT, 0x00, @@ -107,13 +141,13 @@ const static struct ucdc_comm_descriptor _comm_desc = USB_CDC_CS_INTERFACE, USB_CDC_SCS_ACM, 0x02, - /* Union Functional Descriptor */ + /* Union Functional Descriptor */ 0x05, USB_CDC_CS_INTERFACE, USB_CDC_SCS_UNION, USB_DYNAMIC, USB_DYNAMIC, - /* Endpoint Descriptor */ + /* Endpoint Descriptor */ USB_DESC_LENGTH_ENDPOINT, USB_DESC_TYPE_ENDPOINT, USB_DYNAMIC | USB_DIR_IN, @@ -130,23 +164,23 @@ const static struct ucdc_data_descriptor _data_desc = USB_DESC_TYPE_INTERFACE, USB_DYNAMIC, 0x00, - 0x02, + 0x02, USB_CDC_CLASS_DATA, - 0x00, - 0x00, - 0x00, + 0x00, + 0x00, + 0x00, /* endpoint, bulk out */ - USB_DESC_LENGTH_ENDPOINT, + USB_DESC_LENGTH_ENDPOINT, USB_DESC_TYPE_ENDPOINT, USB_DYNAMIC | USB_DIR_OUT, - USB_EP_ATTR_BULK, + USB_EP_ATTR_BULK, USB_CDC_BUFSIZE, - 0x00, + 0x00, /* endpoint, bulk in */ USB_DESC_LENGTH_ENDPOINT, USB_DESC_TYPE_ENDPOINT, USB_DYNAMIC | USB_DIR_IN, - USB_EP_ATTR_BULK, + USB_EP_ATTR_BULK, USB_CDC_BUFSIZE, 0x00, }; @@ -156,18 +190,24 @@ const static char* _ustring[] = "Language", "RT-Thread Team.", "RTT Virtual Serial", - "1.1.0", + "32021919830108", "Configuration", "Interface", }; +static void rt_usb_vcom_init(struct ufunction *func); -static void _vcom_reset_state(void) +static void _vcom_reset_state(ufunction_t func) { - int lvl = rt_hw_interrupt_disable(); - tx_ringbuffer.read_mirror = tx_ringbuffer.read_index = 0; - tx_ringbuffer.write_mirror = tx_ringbuffer.write_index = 0; - vcom_connected = RT_FALSE; - vcom_in_sending = RT_FALSE; + struct vcom* data; + int lvl; + + RT_ASSERT(func != RT_NULL) + + data = (struct vcom*)func->user_data; + + lvl = rt_hw_interrupt_disable(); + data->connected = RT_FALSE; + data->in_sending = RT_FALSE; /*rt_kprintf("reset USB serial\n", cnt);*/ rt_hw_interrupt_enable(lvl); } @@ -175,95 +215,73 @@ static void _vcom_reset_state(void) /** * This function will handle cdc bulk in endpoint request. * - * @param device the usb device object. + * @param func the usb function object. * @param size request size. * * @return RT_EOK. */ -static rt_err_t _ep_in_handler(udevice_t device, uclass_t cls, rt_size_t size) +static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size) { - rt_uint32_t level; - rt_uint32_t remain; - cdc_eps_t eps; + struct vcom *data; - eps = (cdc_eps_t)cls->eps; - level = rt_hw_interrupt_disable(); - remain = rt_ringbuffer_data_len(&tx_ringbuffer); - if (remain != 0) - { - /* although vcom_in_sending is set in SOF handler in the very - * beginning, we have to guarantee the state is right when start - * sending. There is at least one extreme case where we have finished the - * last IN transaction but the vcom_in_sending is RT_FALSE. - * - * Ok, what the extreme case is: pour data into vcom in loop. Open - * terminal on the PC, you will see the data. Then close it. So the - * data will be sent to the PC in the back. When the buffer of the PC - * driver is full. It will not send IN packet to the board and you will - * have no chance to clear vcom_in_sending in this function. The data - * will fill into the ringbuffer until it is full, and we will reset - * the state machine and clear vcom_in_sending. When you open the - * terminal on the PC again. The IN packet will appear on the line and - * we will, eventually, reach here with vcom_in_sending is clear. - */ - vcom_in_sending = RT_TRUE; - rt_ringbuffer_get(&tx_ringbuffer, eps->ep_in->buffer, remain); - rt_hw_interrupt_enable(level); - - /* send data to host */ - dcd_ep_write(device->dcd, eps->ep_in, eps->ep_in->buffer, remain); + RT_ASSERT(func != RT_NULL); - return RT_EOK; - } + RT_DEBUG_LOG(RT_DEBUG_USB, ("_ep_in_handler %d\n", size)); - if (size != 0 && - (size % CDC_MaxPacketSize) == 0) + data = (struct vcom*)func->user_data; + if ((size != 0) && (size % CDC_MAX_PACKET_SIZE == 0)) { /* don't have data right now. Send a zero-length-packet to * terminate the transaction. * * FIXME: actually, this might not be the right place to send zlp. * Only the rt_device_write could know how much data is sending. */ - vcom_in_sending = RT_TRUE; - rt_hw_interrupt_enable(level); - dcd_ep_write(device->dcd, eps->ep_in, RT_NULL, 0); - return RT_EOK; - } - else - { - vcom_in_sending = RT_FALSE; - rt_hw_interrupt_enable(level); + data->in_sending = RT_TRUE; + + data->ep_in->request.buffer = RT_NULL; + data->ep_in->request.size = 0; + data->ep_in->request.req_type = UIO_REQUEST_WRITE; + rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); + return RT_EOK; } + + rt_completion_done(&data->wait); + + return RT_EOK; } /** * This function will handle cdc bulk out endpoint request. * - * @param device the usb device object. + * @param func the usb function object. * @param size request size. * * @return RT_EOK. */ -static rt_err_t _ep_out_handler(udevice_t device, uclass_t cls, rt_size_t size) +static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size) { rt_uint32_t level; - cdc_eps_t eps; + struct vcom *data; - RT_ASSERT(device != RT_NULL); + RT_ASSERT(func != RT_NULL); - eps = (cdc_eps_t)cls->eps; + RT_DEBUG_LOG(RT_DEBUG_USB, ("_ep_out_handler %d\n", size)); + + data = (struct vcom*)func->user_data; /* receive data from USB VCOM */ level = rt_hw_interrupt_disable(); - rt_ringbuffer_put(&rx_ringbuffer, eps->ep_out->buffer, size); + rt_ringbuffer_put(&data->rx_ringbuffer, data->ep_out->buffer, size); rt_hw_interrupt_enable(level); /* notify receive data */ - rt_hw_serial_isr(&vcom_serial); + rt_hw_serial_isr(&data->serial); - dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, - eps->ep_out->ep_desc->wMaxPacketSize); + data->ep_out->request.buffer = data->ep_out->buffer; + data->ep_out->request.size = EP_MAXPACKET(data->ep_out); + data->ep_out->request.req_type = UIO_REQUEST_READ_BEST; + rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); return RT_EOK; } @@ -276,9 +294,9 @@ static rt_err_t _ep_out_handler(udevice_t device, uclass_t cls, rt_size_t size) * * @return RT_EOK. */ -static rt_err_t _ep_cmd_handler(udevice_t device, uclass_t cls, rt_size_t size) +static rt_err_t _ep_cmd_handler(ufunction_t func, rt_size_t size) { - RT_ASSERT(device != RT_NULL); + RT_ASSERT(func != RT_NULL); RT_DEBUG_LOG(RT_DEBUG_USB, ("_ep_cmd_handler\n")); @@ -301,14 +319,25 @@ static rt_err_t _cdc_get_line_coding(udevice_t device, ureq_t setup) RT_ASSERT(device != RT_NULL); RT_ASSERT(setup != RT_NULL); + RT_DEBUG_LOG(RT_DEBUG_USB, ("_cdc_get_line_coding\n")); + data.dwDTERate = 115200; data.bCharFormat = 0; data.bDataBits = 8; data.bParityType = 0; size = setup->length > 7 ? 7 : setup->length; - dcd_ep_write(device->dcd, 0, (void*)&data, size); + rt_usbd_ep0_write(device, (void*)&data, size); + + return RT_EOK; +} + +static rt_err_t _cdc_set_line_coding_callback(udevice_t device, rt_size_t size) +{ + RT_DEBUG_LOG(RT_DEBUG_USB, ("_cdc_set_line_coding_callback\n")); + dcd_ep0_send_status(device->dcd); + return RT_EOK; } @@ -322,21 +351,13 @@ static rt_err_t _cdc_get_line_coding(udevice_t device, ureq_t setup) */ static rt_err_t _cdc_set_line_coding(udevice_t device, ureq_t setup) { - struct ucdc_line_coding data; - rt_err_t ret; - RT_ASSERT(device != RT_NULL); RT_ASSERT(setup != RT_NULL); - rt_completion_init(&device->dcd->completion); + RT_DEBUG_LOG(RT_DEBUG_USB, ("_cdc_set_line_coding\n")); - dcd_ep_read(device->dcd, 0, (void*)&data, setup->length); - - ret = rt_completion_wait(&device->dcd->completion, 100); - if(ret != RT_EOK) - { - rt_kprintf("_cdc_set_line_coding timeout\n"); - } + rt_usbd_ep0_read(device, (void*)&line_coding, sizeof(struct ucdc_line_coding), + _cdc_set_line_coding_callback); return RT_EOK; } @@ -349,11 +370,16 @@ static rt_err_t _cdc_set_line_coding(udevice_t device, ureq_t setup) * * @return RT_EOK on successful. */ -static rt_err_t _interface_handler(udevice_t device, uclass_t cls, ureq_t setup) +static rt_err_t _interface_handler(ufunction_t func, ureq_t setup) { - RT_ASSERT(device != RT_NULL); + struct vcom *data; + + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); RT_ASSERT(setup != RT_NULL); + data = (struct vcom*)func->user_data; + switch(setup->request) { case CDC_SEND_ENCAPSULATED_COMMAND: @@ -367,14 +393,14 @@ static rt_err_t _interface_handler(udevice_t device, uclass_t cls, ureq_t setup) case CDC_CLEAR_COMM_FEATURE: break; case CDC_SET_LINE_CODING: - _cdc_set_line_coding(device, setup); - vcom_connected = RT_TRUE; + _cdc_set_line_coding(func->device, setup); + data->connected = RT_TRUE; break; case CDC_GET_LINE_CODING: - _cdc_get_line_coding(device, setup); + _cdc_get_line_coding(func->device, setup); break; case CDC_SET_CONTROL_LINE_STATE: - dcd_send_status(device->dcd); + dcd_ep0_send_status(func->device->dcd); break; case CDC_SEND_BREAK: break; @@ -387,92 +413,66 @@ static rt_err_t _interface_handler(udevice_t device, uclass_t cls, ureq_t setup) } /** - * This function will run cdc class, it will be called on handle set configuration request. + * This function will run cdc function, it will be called on handle set configuration request. * - * @param device the usb device object. + * @param func the usb function object. * * @return RT_EOK on successful. */ -static rt_err_t _class_run(udevice_t device, uclass_t cls) +static rt_err_t _function_enable(ufunction_t func) { - cdc_eps_t eps; - RT_ASSERT(device != RT_NULL); - - RT_DEBUG_LOG(RT_DEBUG_USB, ("cdc class run\n")); - eps = (cdc_eps_t)cls->eps; + struct vcom *data; - eps->ep_in->buffer = tx_buf; - eps->ep_out->buffer = rx_buf; + RT_ASSERT(func != RT_NULL); - _vcom_reset_state(); + RT_DEBUG_LOG(RT_DEBUG_USB, ("cdc function enable\n")); - dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, - eps->ep_out->ep_desc->wMaxPacketSize); + _vcom_reset_state(func); + + data = (struct vcom*)func->user_data; + data->ep_out->buffer = rt_malloc(CDC_RX_BUFSIZE); + data->ep_out->request.buffer = data->ep_out->buffer; + data->ep_out->request.size = EP_MAXPACKET(data->ep_out); + + data->ep_out->request.req_type = UIO_REQUEST_READ_BEST; + rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); + return RT_EOK; } /** - * This function will stop cdc class, it will be called on handle set configuration request. + * This function will stop cdc function, it will be called on handle set configuration request. * - * @param device the usb device object. + * @param func the usb function object. * * @return RT_EOK on successful. */ -static rt_err_t _class_stop(udevice_t device, uclass_t cls) +static rt_err_t _function_disable(ufunction_t func) { - RT_ASSERT(device != RT_NULL); + struct vcom *data; - RT_DEBUG_LOG(RT_DEBUG_USB, ("cdc class stop\n")); - - _vcom_reset_state(); - - return RT_EOK; -} + RT_ASSERT(func != RT_NULL); -/** - * This function will handle system sof event. - * - * @param device the usb device object. - * - * @return RT_EOK on successful. - */ -static rt_err_t _class_sof_handler(udevice_t device, uclass_t cls) -{ - rt_uint32_t level; - rt_size_t size; - cdc_eps_t eps; + RT_DEBUG_LOG(RT_DEBUG_USB, ("cdc function disable\n")); - if (vcom_connected != RT_TRUE) - return -RT_ERROR; + _vcom_reset_state(func); - if (vcom_in_sending) + data = (struct vcom*)func->user_data; + if(data->ep_out->buffer != RT_NULL) { - return RT_EOK; + rt_free(data->ep_out->buffer); + data->ep_out->buffer = RT_NULL; } - eps = (cdc_eps_t)cls->eps; - - size = rt_ringbuffer_data_len(&tx_ringbuffer); - if (size == 0) - return -RT_EFULL; - - level = rt_hw_interrupt_disable(); - rt_ringbuffer_get(&tx_ringbuffer, eps->ep_in->buffer, size); - rt_hw_interrupt_enable(level); - - /* send data to host */ - vcom_in_sending = RT_TRUE; - dcd_ep_write(device->dcd, eps->ep_in, eps->ep_in->buffer, size); - return RT_EOK; } -static struct uclass_ops ops = +static struct ufunction_ops ops = { - _class_run, - _class_stop, - _class_sof_handler, + _function_enable, + _function_disable, + RT_NULL, }; /** @@ -483,7 +483,8 @@ static struct uclass_ops ops = * * @return RT_EOK on successful. */ -static rt_err_t _cdc_descriptor_config(ucdc_comm_desc_t comm, rt_uint8_t cintf_nr, ucdc_data_desc_t data, rt_uint8_t dintf_nr) +static rt_err_t _cdc_descriptor_config(ucdc_comm_desc_t comm, + rt_uint8_t cintf_nr, ucdc_data_desc_t data, rt_uint8_t dintf_nr) { comm->call_mgmt_desc.data_interface = dintf_nr; comm->union_desc.master_interface = cintf_nr; @@ -496,16 +497,16 @@ static rt_err_t _cdc_descriptor_config(ucdc_comm_desc_t comm, rt_uint8_t cintf_n } /** - * This function will create a cdc class instance. + * This function will create a cdc function instance. * * @param device the usb device object. * * @return RT_EOK on successful. */ -uclass_t rt_usbd_class_cdc_create(udevice_t device) +ufunction_t rt_usbd_function_cdc_create(udevice_t device) { - uclass_t cdc; - cdc_eps_t eps; + ufunction_t func; + struct vcom* data; uintf_t intf_comm, intf_data; ualtsetting_t comm_setting, data_setting; ucdc_data_desc_t data_desc; @@ -516,19 +517,26 @@ uclass_t rt_usbd_class_cdc_create(udevice_t device) /* set usb device string description */ rt_usbd_device_set_string(device, _ustring); - /* create a cdc class */ - cdc = rt_usbd_class_create(device, &dev_desc, &ops); - /* create a cdc class endpoints collection */ - eps = rt_malloc(sizeof(struct cdc_eps)); - cdc->eps = (void*)eps; + + /* create a cdc function */ + func = rt_usbd_function_new(device, &dev_desc, &ops); + rt_usbd_device_set_qualifier(device, &dev_qualifier); + + /* allocate memory for cdc vcom data */ + data = (struct vcom*)rt_malloc(sizeof(struct vcom)); + rt_memset(data, 0, sizeof(struct vcom)); + func->user_data = (void*)data; + + /* initilize vcom */ + rt_usb_vcom_init(func); /* create a cdc communication interface and a cdc data interface */ - intf_comm = rt_usbd_interface_create(device, _interface_handler); - intf_data = rt_usbd_interface_create(device, _interface_handler); + intf_comm = rt_usbd_interface_new(device, _interface_handler); + intf_data = rt_usbd_interface_new(device, _interface_handler); /* create a communication alternate setting and a data alternate setting */ - comm_setting = rt_usbd_altsetting_create(sizeof(struct ucdc_comm_descriptor)); - data_setting = rt_usbd_altsetting_create(sizeof(struct ucdc_data_descriptor)); + comm_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_comm_descriptor)); + data_setting = rt_usbd_altsetting_new(sizeof(struct ucdc_data_descriptor)); /* config desc in alternate setting */ rt_usbd_altsetting_config_descriptor(comm_setting, &_comm_desc, @@ -537,39 +545,39 @@ uclass_t rt_usbd_class_cdc_create(udevice_t device) /* configure the cdc interface descriptor */ _cdc_descriptor_config(comm_setting->desc, intf_comm->intf_num, data_setting->desc, intf_data->intf_num); - /* create a bulk in and a bulk endpoint */ - data_desc = (ucdc_data_desc_t)data_setting->desc; - eps->ep_out = rt_usbd_endpoint_create(&data_desc->ep_out_desc, _ep_out_handler); - eps->ep_in = rt_usbd_endpoint_create(&data_desc->ep_in_desc, _ep_in_handler); - - /* add the bulk out and bulk in endpoints to the data alternate setting */ - rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_in); - rt_usbd_altsetting_add_endpoint(data_setting, eps->ep_out); - - /* add the data alternate setting to the data interface - then set default setting of the interface */ - rt_usbd_interface_add_altsetting(intf_data, data_setting); - rt_usbd_set_altsetting(intf_data, 0); - - /* add the cdc data interface to cdc class */ - rt_usbd_class_add_interface(cdc, intf_data); - /* create a command endpoint */ comm_desc = (ucdc_comm_desc_t)comm_setting->desc; - eps->ep_cmd = rt_usbd_endpoint_create(&comm_desc->ep_desc, _ep_cmd_handler); + data->ep_cmd = rt_usbd_endpoint_new(&comm_desc->ep_desc, _ep_cmd_handler); /* add the command endpoint to the cdc communication interface */ - rt_usbd_altsetting_add_endpoint(comm_setting, eps->ep_cmd); + rt_usbd_altsetting_add_endpoint(comm_setting, data->ep_cmd); /* add the communication alternate setting to the communication interface, then set default setting of the interface */ rt_usbd_interface_add_altsetting(intf_comm, comm_setting); rt_usbd_set_altsetting(intf_comm, 0); - /* add the communication interface to the cdc class */ - rt_usbd_class_add_interface(cdc, intf_comm); + /* add the communication interface to the cdc function */ + rt_usbd_function_add_interface(func, intf_comm); - return cdc; + /* create a bulk in and a bulk endpoint */ + data_desc = (ucdc_data_desc_t)data_setting->desc; + data->ep_out = rt_usbd_endpoint_new(&data_desc->ep_out_desc, _ep_out_handler); + data->ep_in = rt_usbd_endpoint_new(&data_desc->ep_in_desc, _ep_in_handler); + + /* add the bulk out and bulk in endpoints to the data alternate setting */ + rt_usbd_altsetting_add_endpoint(data_setting, data->ep_in); + rt_usbd_altsetting_add_endpoint(data_setting, data->ep_out); + + /* add the data alternate setting to the data interface + then set default setting of the interface */ + rt_usbd_interface_add_altsetting(intf_data, data_setting); + rt_usbd_set_altsetting(intf_data, 0); + + /* add the cdc data interface to cdc function */ + rt_usbd_function_add_interface(func, intf_data); + + return func; } /** @@ -597,80 +605,106 @@ static rt_err_t _vcom_control(struct rt_serial_device *serial, return RT_EOK; } -static int _vcom_putc(struct rt_serial_device *serial, char c) +static int _vcom_getc(struct rt_serial_device *serial) { + int result; + rt_uint8_t ch; rt_uint32_t level; - int cnt; + struct ufunction *func; + struct vcom *data; + + func = (struct ufunction*)serial->parent.user_data; + data = (struct vcom*)func->user_data; - if (vcom_connected != RT_TRUE) - { - return 0; - } - - /* if the buffer is full, there is a chance that the host would pull some - * data out soon. But we cannot rely on that and if we wait to long, just - * return. */ - for (cnt = 500; - rt_ringbuffer_space_len(&tx_ringbuffer) == 0 && cnt; - cnt--) - { - /*rt_kprintf("wait for %d\n", cnt);*/ - if (vcom_connected != RT_TRUE) - return 0; - } - if (cnt == 0) - { - /* OK, we believe that the connection is lost. So don't send any more - * data and act as the USB cable is not plugged in. Reset the VCOM - * state machine */ - _vcom_reset_state(); - return 0; - } + result = -1; level = rt_hw_interrupt_disable(); - if (rt_ringbuffer_space_len(&tx_ringbuffer)) + + if(rt_ringbuffer_getchar(&data->rx_ringbuffer, &ch) != 0) { - rt_ringbuffer_putchar(&tx_ringbuffer, c); + result = ch; } + rt_hw_interrupt_enable(level); - return 1; + return result; } -static int _vcom_getc(struct rt_serial_device *serial) +static rt_size_t _vcom_tx(struct rt_serial_device *serial, + const char *buf, rt_size_t size) { - int result; - rt_uint8_t ch; - rt_uint32_t level; + struct vcom_tx_msg msg; - result = -1; + RT_ASSERT(serial != RT_NULL); + RT_ASSERT(buf != RT_NULL); - level = rt_hw_interrupt_disable(); - if (rt_ringbuffer_data_len(&rx_ringbuffer)) + msg.buf = buf; + msg.serial = serial; + msg.size = size; + + if (rt_mq_send(&vcom_tx_thread_mq, (void*)&msg, + sizeof(struct vcom_tx_msg)) != RT_EOK) { - rt_ringbuffer_getchar(&rx_ringbuffer, &ch); - result = ch; + rt_kprintf("vcom send msg fail\n"); + return 0; } - rt_hw_interrupt_enable(level); - - return result; + + return size; } static const struct rt_uart_ops usb_vcom_ops = { _vcom_configure, _vcom_control, - _vcom_putc, + RT_NULL, _vcom_getc, + RT_NULL, + //_vcom_tx, }; -void rt_usb_vcom_init(void) +/* Vcom Tx Thread */ +static void vcom_tx_thread_entry(void* parameter) { - struct serial_configure config; + struct vcom_tx_msg msg; + + while (1) + { + if (rt_mq_recv(&vcom_tx_thread_mq, (void*)&msg, + sizeof(struct vcom_tx_msg), RT_WAITING_FOREVER) == RT_EOK) + { + struct ufunction *func; + struct vcom *data; + + func = (struct ufunction*)msg.serial->parent.user_data; + data = (struct vcom*)func->user_data; + if (!data->connected) + { + continue; + } + + rt_completion_init(&data->wait); + + data->ep_in->request.buffer = (void*)msg.buf; + data->ep_in->request.size = msg.size; + data->ep_in->request.req_type = UIO_REQUEST_WRITE; + rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); + + if (rt_completion_wait(&data->wait, TX_TIMEOUT) != RT_EOK) + { + rt_kprintf("vcom tx timeout\n"); + } + } + } +} +static void rt_usb_vcom_init(struct ufunction *func) +{ + rt_err_t result = RT_EOK; + struct serial_configure config; + struct vcom *data = (struct vcom*)func->user_data; + /* initialize ring buffer */ - rt_ringbuffer_init(&rx_ringbuffer, rx_rbp, CDC_RX_BUFSIZE); - rt_ringbuffer_init(&tx_ringbuffer, tx_rbp, CDC_TX_BUFSIZE); + rt_ringbuffer_init(&data->rx_ringbuffer, data->rx_rbp, CDC_RX_BUFSIZE); config.baud_rate = BAUD_RATE_115200; config.bit_order = BIT_ORDER_LSB; @@ -679,14 +713,25 @@ void rt_usb_vcom_init(void) config.stop_bits = STOP_BITS_1; config.invert = NRZ_NORMAL; - vcom_serial.ops = &usb_vcom_ops; - vcom_serial.int_rx = &vcom_int_rx; - vcom_serial.config = config; + data->serial.ops = &usb_vcom_ops; + data->serial.int_rx = &data->vcom_int_rx; + data->serial.config = config; /* register vcom device */ - rt_hw_serial_register(&vcom_serial, "vcom", - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, - RT_NULL); + rt_hw_serial_register(&data->serial, VCOM_DEVICE, + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX, + func); + + /* create an vcom message queue */ + rt_mq_init(&vcom_tx_thread_mq, "vcomq", vcom_tx_thread_mq_pool, VCOM_MQ_MSG_SZ, + sizeof(vcom_tx_thread_mq_pool), RT_IPC_FLAG_FIFO); + + /* init usb device thread */ + rt_thread_init(&vcom_thread, "vcom", vcom_tx_thread_entry, RT_NULL, + vcom_thread_stack, 512, 8, 20); + result = rt_thread_startup(&vcom_thread); + RT_ASSERT(result == RT_EOK); } #endif + diff --git a/components/drivers/usb/usbdevice/class/mstorage.c b/components/drivers/usb/usbdevice/class/mstorage.c index b0351f63e5..4ee45189f8 100644 --- a/components/drivers/usb/usbdevice/class/mstorage.c +++ b/components/drivers/usb/usbdevice/class/mstorage.c @@ -21,7 +21,8 @@ * Date Author Notes * 2012-10-01 Yi Qiu first version * 2012-11-25 Heyuanjie87 reduce the memory consumption - * 2012-12-09 Heyuanjie87 change class and endpoint handler + * 2012-12-09 Heyuanjie87 change function and endpoint handler + * 2013-07-25 Yi Qiu update for USB CV test */ #include @@ -31,19 +32,55 @@ #ifdef RT_USB_DEVICE_MSTORAGE -#define STATUS_CBW 0x00 -#define STATUS_CSW 0x01 -#define STATUS_RECEIVE 0x02 -#define STATUS_SEND 0x03 +enum STAT +{ + STAT_CBW, + STAT_CMD, + STAT_CSW, + STAT_RECEIVE, + STAT_SEND, +}; + +typedef enum +{ + FIXED, + COUNT, + BLOCK_COUNT, +}CB_SIZE_TYPE; -static int status = STATUS_CBW; -ALIGN(RT_ALIGN_SIZE) -static struct ustorage_csw csw; -static rt_device_t disk; -static rt_uint32_t _block; -static rt_uint32_t _count, _size; -static struct rt_device_blk_geometry geometry; -static rt_uint32_t _removed = 0; +typedef enum +{ + DIR_IN, + DIR_OUT, + DIR_NONE, +}CB_DIR; + +typedef rt_size_t (*cbw_handler)(ufunction_t func, ustorage_cbw_t cbw); + +struct scsi_cmd +{ + rt_uint16_t cmd; + cbw_handler handler; + rt_size_t cmd_len; + CB_SIZE_TYPE type; + rt_size_t data_size; + CB_DIR dir; +}; + +struct mstorage +{ + struct ustorage_csw csw_response; + uep_t ep_in; + uep_t ep_out; + int status; + rt_uint32_t cb_data_size; + rt_device_t disk; + rt_uint32_t block; + rt_int32_t count; + rt_int32_t size; + struct scsi_cmd* processing; + struct rt_device_blk_geometry geometry; +}; static struct udevice_descriptor dev_desc = { @@ -63,6 +100,18 @@ static struct udevice_descriptor dev_desc = USB_DYNAMIC, //bNumConfigurations; }; +static struct usb_qualifier_descriptor dev_qualifier = +{ + sizeof(dev_qualifier), + USB_DESC_TYPE_DEVICEQUALIFIER, + 0x0200, + USB_CLASS_MASS_STORAGE, + 0x00, + 64, + 0x01, + 0, +}; + const static struct umass_descriptor _mass_desc = { USB_DESC_LENGTH_INTERFACE, //bLength; @@ -95,270 +144,489 @@ const static char* _ustring[] = "Language", "RT-Thread Team.", "RTT Mass Storage", - "1.1.0", + "320219198301", "Configuration", "Interface", }; +static rt_size_t _test_unit_ready(ufunction_t func, ustorage_cbw_t cbw); +static rt_size_t _request_sense(ufunction_t func, ustorage_cbw_t cbw); +static rt_size_t _inquiry_cmd(ufunction_t func, ustorage_cbw_t cbw); +static rt_size_t _allow_removal(ufunction_t func, ustorage_cbw_t cbw); +static rt_size_t _start_stop(ufunction_t func, ustorage_cbw_t cbw); +static rt_size_t _mode_sense_6(ufunction_t func, ustorage_cbw_t cbw); +static rt_size_t _read_capacities(ufunction_t func, ustorage_cbw_t cbw); +static rt_size_t _read_capacity(ufunction_t func, ustorage_cbw_t cbw); +static rt_size_t _read_10(ufunction_t func, ustorage_cbw_t cbw); +static rt_size_t _write_10(ufunction_t func, ustorage_cbw_t cbw); +static rt_size_t _verify_10(ufunction_t func, ustorage_cbw_t cbw); + +static struct scsi_cmd cmd_data[] = +{ + {SCSI_TEST_UNIT_READY, _test_unit_ready, 6, FIXED, 0, DIR_NONE}, + {SCSI_REQUEST_SENSE, _request_sense, 6, COUNT, 0, DIR_IN}, + {SCSI_INQUIRY_CMD, _inquiry_cmd, 6, COUNT, 0, DIR_IN}, + {SCSI_ALLOW_REMOVAL, _allow_removal, 6, FIXED, 0, DIR_NONE}, + {SCSI_MODE_SENSE_6, _mode_sense_6, 6, COUNT, 0, DIR_IN}, + {SCSI_START_STOP, _start_stop, 6, FIXED, 0, DIR_NONE}, + {SCSI_READ_CAPACITIES, _read_capacities, 10, COUNT, 0, DIR_NONE}, + {SCSI_READ_CAPACITY, _read_capacity, 10, FIXED, 8, DIR_IN}, + {SCSI_READ_10, _read_10, 10, BLOCK_COUNT, 0, DIR_IN}, + {SCSI_WRITE_10, _write_10, 10, BLOCK_COUNT, 0, DIR_OUT}, + {SCSI_VERIFY_10, _verify_10, 10, FIXED, 0, DIR_NONE}, +}; + +static void _send_status(ufunction_t func) +{ + struct mstorage *data; + + RT_ASSERT(func != RT_NULL); + + RT_DEBUG_LOG(RT_DEBUG_USB, ("_send_status\n")); + + data = (struct mstorage*)func->user_data; + data->ep_in->request.buffer = (rt_uint8_t*)&data->csw_response; + data->ep_in->request.size = SIZEOF_CSW; + data->ep_in->request.req_type = UIO_REQUEST_WRITE; + rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); + data->status = STAT_CSW; +} + +static rt_size_t _test_unit_ready(ufunction_t func, ustorage_cbw_t cbw) +{ + struct mstorage *data; + + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); + + RT_DEBUG_LOG(RT_DEBUG_USB, ("_test_unit_ready\n")); + + data = (struct mstorage*)func->user_data; + data->csw_response.status = 0; + + return 0; +} + +static rt_size_t _allow_removal(ufunction_t func, ustorage_cbw_t cbw) +{ + struct mstorage *data; + + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); + + RT_DEBUG_LOG(RT_DEBUG_USB, ("_allow_removal\n")); + + data = (struct mstorage*)func->user_data; + data->csw_response.status = 0; + + return 0; +} + /** - * This function will allocate an usb device instance from system. + * This function will handle inquiry command request. * - * @param parent the hub instance to which the new allocated device attached. - * @param port the hub port. + * @param func the usb function object. + * @param cbw the command block wrapper. * - * @return the allocate instance on successful, or RT_NULL on failure. + * @return RT_EOK on successful. */ -static rt_err_t _inquiry_cmd(udevice_t device, uep_t ep_in) + +static rt_size_t _inquiry_cmd(ufunction_t func, ustorage_cbw_t cbw) { - rt_uint8_t data[36]; + struct mstorage *data; + rt_uint8_t *buf; + + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); + RT_ASSERT(cbw != RT_NULL); - *(rt_uint32_t*)&data[0] = 0x0 | (0x80 << 8); - *(rt_uint32_t*)&data[4] = 31; + RT_DEBUG_LOG(RT_DEBUG_USB, ("_inquiry_cmd\n")); - rt_memset(&data[8], 0x20, 28); - rt_memcpy(&data[8], "RTT", 3); - rt_memcpy(&data[16], "USB Disk", 8); + data = (struct mstorage*)func->user_data; + buf = data->ep_in->buffer; - dcd_ep_write(device->dcd, ep_in, (rt_uint8_t*)&data, 36); + *(rt_uint32_t*)&buf[0] = 0x0 | (0x80 << 8); + *(rt_uint32_t*)&buf[4] = 31; - return RT_EOK; + rt_memset(&buf[8], 0x20, 28); + rt_memcpy(&buf[8], "RTT", 3); + rt_memcpy(&buf[16], "USB Disk", 8); + + data->cb_data_size = MIN(data->cb_data_size, SIZEOF_INQUIRY_CMD); + data->ep_in->request.buffer = buf; + data->ep_in->request.size = data->cb_data_size; + data->ep_in->request.req_type = UIO_REQUEST_WRITE; + rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); + data->status = STAT_CMD; + + return data->cb_data_size; } /** * This function will handle sense request. * - * @param device the usb device object. + * @param func the usb function object. + * @param cbw the command block wrapper. * * @return RT_EOK on successful. */ -static rt_err_t _request_sense(udevice_t device, uep_t ep_in) +static rt_size_t _request_sense(ufunction_t func, ustorage_cbw_t cbw) { - struct request_sense_data data; - - data.ErrorCode = 0x70; - data.Valid = 0; - data.SenseKey = 2; //TODO - data.Information[0] = 0; - data.Information[1] = 0; - data.Information[2] = 0; - data.Information[3] = 0; - data.AdditionalSenseLength = 0x0a; - data.AdditionalSenseCode = 0x3a; //TODO - data.AdditionalSenseCodeQualifier =0; + struct mstorage *data; + struct request_sense_data *buf; - dcd_ep_write(device->dcd, ep_in, (rt_uint8_t*)&data, sizeof(struct request_sense_data)); + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); + RT_ASSERT(cbw != RT_NULL); - return RT_EOK; + RT_DEBUG_LOG(RT_DEBUG_USB, ("_request_sense\n")); + + data = (struct mstorage*)func->user_data; + buf = (struct request_sense_data *)data->ep_in->buffer; + + buf->ErrorCode = 0x70; + buf->Valid = 0; + buf->SenseKey = 2; + buf->Information[0] = 0; + buf->Information[1] = 0; + buf->Information[2] = 0; + buf->Information[3] = 0; + buf->AdditionalSenseLength = 0x0a; + buf->AdditionalSenseCode = 0x3a; + buf->AdditionalSenseCodeQualifier = 0; + + data->cb_data_size = MIN(data->cb_data_size, SIZEOF_REQUEST_SENSE); + data->ep_in->request.buffer = (rt_uint8_t*)data->ep_in->buffer; + data->ep_in->request.size = data->cb_data_size; + data->ep_in->request.req_type = UIO_REQUEST_WRITE; + rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); + data->status = STAT_CMD; + + return data->cb_data_size; } /** * This function will handle mode_sense_6 request. * - * @param device the usb device object. + * @param func the usb function object. + * @param cbw the command block wrapper. * * @return RT_EOK on successful. */ -static rt_err_t _mode_sense_6(udevice_t device, uep_t ep_in) +static rt_size_t _mode_sense_6(ufunction_t func, ustorage_cbw_t cbw) { - rt_uint8_t data[4]; + struct mstorage *data; + rt_uint8_t *buf; + + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); + RT_ASSERT(cbw != RT_NULL); - data[0]=3; - data[1]=0; - data[2]=0; - data[3]=0; + RT_DEBUG_LOG(RT_DEBUG_USB, ("_mode_sense_6\n")); - dcd_ep_write(device->dcd, ep_in, (rt_uint8_t*)&data, 4); + data = (struct mstorage*)func->user_data; + buf = data->ep_in->buffer; + buf[0] = 3; + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; - return RT_EOK; + data->cb_data_size = MIN(data->cb_data_size, SIZEOF_MODE_SENSE_6); + data->ep_in->request.buffer = buf; + data->ep_in->request.size = data->cb_data_size; + data->ep_in->request.req_type = UIO_REQUEST_WRITE; + rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); + data->status = STAT_CMD; + + return data->cb_data_size; } /** * This function will handle read_capacities request. * - * @param device the usb device object. + * @param func the usb function object. + * @param cbw the command block wrapper. * * @return RT_EOK on successful. */ -static rt_err_t _read_capacities(udevice_t device, uep_t ep_in) +static rt_size_t _read_capacities(ufunction_t func, ustorage_cbw_t cbw) { - rt_uint8_t data[12]; + struct mstorage *data; + rt_uint8_t *buf; rt_uint32_t sector_count, sector_size; - RT_ASSERT(device != RT_NULL); - - sector_count = geometry.sector_count; - sector_size = geometry.bytes_per_sector; - - *(rt_uint32_t*)&data[0] = 0x08000000; - data[4] = sector_count >> 24; - data[5] = 0xff & (sector_count >> 16); - data[6] = 0xff & (sector_count >> 8); - data[7] = 0xff & (sector_count); - data[8] = 0x02; - data[9] = 0xff & (sector_size >> 16); - data[10] = 0xff & (sector_size >> 8); - data[11] = 0xff & sector_size; - - dcd_ep_write(device->dcd, ep_in, (rt_uint8_t*)&data, 12); + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); + RT_ASSERT(cbw != RT_NULL); - return RT_EOK; + RT_DEBUG_LOG(RT_DEBUG_USB, ("_read_capacities\n")); + + data = (struct mstorage*)func->user_data; + buf = data->ep_in->buffer; + sector_count = data->geometry.sector_count; + sector_size = data->geometry.bytes_per_sector; + + *(rt_uint32_t*)&buf[0] = 0x08000000; + buf[4] = sector_count >> 24; + buf[5] = 0xff & (sector_count >> 16); + buf[6] = 0xff & (sector_count >> 8); + buf[7] = 0xff & (sector_count); + buf[8] = 0x02; + buf[9] = 0xff & (sector_size >> 16); + buf[10] = 0xff & (sector_size >> 8); + buf[11] = 0xff & sector_size; + + data->cb_data_size = MIN(data->cb_data_size, SIZEOF_READ_CAPACITIES); + data->ep_in->request.buffer = buf; + data->ep_in->request.size = data->cb_data_size; + data->ep_in->request.req_type = UIO_REQUEST_WRITE; + rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); + data->status = STAT_CMD; + + return data->cb_data_size; } /** * This function will handle read_capacity request. * - * @param device the usb device object. + * @param func the usb function object. + * @param cbw the command block wapper. * * @return RT_EOK on successful. */ -static rt_err_t _read_capacity(udevice_t device, uep_t ep_in) +static rt_size_t _read_capacity(ufunction_t func, ustorage_cbw_t cbw) { - rt_uint8_t data[8]; - rt_uint32_t sector_count, sector_size; + struct mstorage *data; - RT_ASSERT(device != RT_NULL); - - sector_count = geometry.sector_count; - sector_size = geometry.bytes_per_sector; - - data[0] = sector_count >> 24; - data[1] = 0xff & (sector_count >> 16); - data[2] = 0xff & (sector_count >> 8); - data[3] = 0xff & (sector_count); - data[4] = 0x0; - data[5] = 0xff & (sector_size >> 16); - data[6] = 0xff & (sector_size >> 8); - data[7] = 0xff & sector_size; + rt_uint8_t *buf; + rt_uint32_t sector_count, sector_size; - dcd_ep_write(device->dcd, ep_in, (rt_uint8_t*)&data, 8); + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); + RT_ASSERT(cbw != RT_NULL); - return RT_EOK; + RT_DEBUG_LOG(RT_DEBUG_USB, ("_read_capacity\n")); + + data = (struct mstorage*)func->user_data; + buf = data->ep_in->buffer; + sector_count = data->geometry.sector_count; + sector_size = data->geometry.bytes_per_sector; + + buf[0] = sector_count >> 24; + buf[1] = 0xff & (sector_count >> 16); + buf[2] = 0xff & (sector_count >> 8); + buf[3] = 0xff & (sector_count); + buf[4] = 0x0; + buf[5] = 0xff & (sector_size >> 16); + buf[6] = 0xff & (sector_size >> 8); + buf[7] = 0xff & sector_size; + + data->cb_data_size = MIN(data->cb_data_size, SIZEOF_READ_CAPACITY); + data->ep_in->request.buffer = buf; + data->ep_in->request.size = data->cb_data_size; + data->ep_in->request.req_type = UIO_REQUEST_WRITE; + rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); + data->status = STAT_CMD; + + return data->cb_data_size; } /** * This function will handle read_10 request. * - * @param device the usb device object. + * @param func the usb function object. * @param cbw the command block wrapper. * * @return RT_EOK on successful. */ -static rt_err_t _read_10(udevice_t device, ustorage_cbw_t cbw, uep_t ep_in) +static rt_size_t _read_10(ufunction_t func, ustorage_cbw_t cbw) { - RT_ASSERT(device != RT_NULL); + struct mstorage *data; + rt_size_t size; + + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); RT_ASSERT(cbw != RT_NULL); - _block = cbw->cb[2]<<24 | cbw->cb[3]<<16 | cbw->cb[4]<<8 | - cbw->cb[5]<<0 ; + data = (struct mstorage*)func->user_data; + data->block = cbw->cb[2]<<24 | cbw->cb[3]<<16 | cbw->cb[4]<<8 | + cbw->cb[5]<<0; + data->count = cbw->cb[7]<<8 | cbw->cb[8]<<0; - _count = cbw->cb[7]<<8 | cbw->cb[8]<<0 ; + RT_ASSERT(data->count < data->geometry.sector_count); - RT_ASSERT(_count < geometry.sector_count); - - rt_device_read(disk, _block, ep_in->buffer, 1); - dcd_ep_write(device->dcd, ep_in, ep_in->buffer, geometry.bytes_per_sector); - _count --; - if (_count) - { - _block ++; - status = STATUS_SEND; - } - else + data->csw_response.data_reside = data->cb_data_size; + size = rt_device_read(data->disk, data->block, data->ep_in->buffer, 1); + if(size == 0) { - status = STATUS_CSW; + rt_kprintf("read data error\n"); } - return RT_EOK; + data->ep_in->request.buffer = data->ep_in->buffer; + data->ep_in->request.size = data->geometry.bytes_per_sector; + data->ep_in->request.req_type = UIO_REQUEST_WRITE; + rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); + data->status = STAT_SEND; + + return data->geometry.bytes_per_sector; } /** * This function will handle write_10 request. * - * @param device the usb device object. + * @param func the usb function object. * @param cbw the command block wrapper. * * @return RT_EOK on successful. */ -static rt_err_t _write_10(udevice_t device, ustorage_cbw_t cbw, uep_t ep_out) +static rt_size_t _write_10(ufunction_t func, ustorage_cbw_t cbw) { - RT_ASSERT(device != RT_NULL); - RT_ASSERT(cbw != RT_NULL); - - _block = cbw->cb[2]<<24 | cbw->cb[3]<<16 | cbw->cb[4]<<8 | - cbw->cb[5]<<0 ; - _count = cbw->cb[7]<<8 | cbw->cb[8]<<0; - csw.data_reside = cbw->xfer_len; - _size = _count * geometry.bytes_per_sector; + struct mstorage *data; - RT_DEBUG_LOG(RT_DEBUG_USB, ("_write_10 count 0x%x 0x%x\n", - _count, geometry.sector_count)); - - dcd_ep_read(device->dcd, ep_out, ep_out->buffer, geometry.bytes_per_sector); + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); + RT_ASSERT(cbw != RT_NULL); - return RT_EOK; + data = (struct mstorage*)func->user_data; + + data->block = cbw->cb[2]<<24 | cbw->cb[3]<<16 | cbw->cb[4]<<8 | + cbw->cb[5]<<0; + data->count = cbw->cb[7]<<8 | cbw->cb[8]; + data->csw_response.data_reside = cbw->xfer_len; + data->size = data->count * data->geometry.bytes_per_sector; + + RT_DEBUG_LOG(RT_DEBUG_USB, ("_write_10 count 0x%x block 0x%x 0x%x\n", + data->count, data->block, data->geometry.sector_count)); + + data->csw_response.data_reside = data->cb_data_size; + + data->ep_out->request.buffer = data->ep_out->buffer; + data->ep_out->request.size = data->geometry.bytes_per_sector; + data->ep_out->request.req_type = UIO_REQUEST_READ_FULL; + rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); + data->status = STAT_RECEIVE; + + return data->geometry.bytes_per_sector; } /** * This function will handle verify_10 request. * - * @param device the usb device object. + * @param func the usb function object. * * @return RT_EOK on successful. */ -static rt_err_t _verify_10(udevice_t device) +static rt_size_t _verify_10(ufunction_t func, ustorage_cbw_t cbw) { - return RT_EOK; -} + struct mstorage *data; -static void _send_status(udevice_t device, mass_eps_t eps, ustorage_csw_t csw) -{ - dcd_ep_write(device->dcd, eps->ep_in, (rt_uint8_t*)csw, SIZEOF_CSW); - dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW); - status = STATUS_CBW; + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); + + RT_DEBUG_LOG(RT_DEBUG_USB, ("_verify_10\n")); + + data = (struct mstorage*)func->user_data; + data->csw_response.status = 0; + + return 0; } -static void _start_stop(ustorage_cbw_t cbw) +static rt_size_t _start_stop(ufunction_t func, + ustorage_cbw_t cbw) { - //TODO - _removed = 1; + struct mstorage *data; + + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); + + RT_DEBUG_LOG(RT_DEBUG_USB, ("_start_stop\n")); + + data = (struct mstorage*)func->user_data; + data->csw_response.status = 0; + + return 0; } -/** - * This function will handle mass storage bulk in endpoint request. - * - * @param device the usb device object. - * @param size request size. - * - * @return RT_EOK. - */ -static rt_err_t _ep_in_handler(udevice_t device, uclass_t cls, rt_size_t size) +static rt_err_t _ep_in_handler(ufunction_t func, rt_size_t size) { - mass_eps_t eps; - RT_ASSERT(device != RT_NULL); + struct mstorage *data; + + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); - eps = cls->eps; - if (status == STATUS_CSW) - { - _send_status(device, eps, &csw); - } - else if (status == STATUS_SEND) + RT_DEBUG_LOG(RT_DEBUG_USB, ("_ep_in_handler\n")); + + data = (struct mstorage*)func->user_data; + + switch(data->status) { - rt_device_read(disk, _block, eps->ep_in->buffer, 1); - dcd_ep_write(device->dcd, eps->ep_in, eps->ep_in->buffer, - geometry.bytes_per_sector); - _count --; - if (_count) + case STAT_CSW: + if(data->ep_in->request.size != SIZEOF_CSW) { - _block ++; - status = STATUS_SEND; + rt_kprintf("Size of csw command error\n"); + rt_usbd_ep_set_stall(func->device, data->ep_in); } else { - status = STATUS_CSW; + RT_DEBUG_LOG(RT_DEBUG_USB, ("return to cbw status\n")); + data->ep_out->request.buffer = data->ep_out->buffer; + data->ep_out->request.size = SIZEOF_CBW; + data->ep_out->request.req_type = UIO_REQUEST_READ_FULL; + rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); + data->status = STAT_CBW; } - } + break; + case STAT_CMD: + if(data->csw_response.data_reside == 0xFF) + { + data->csw_response.data_reside = 0; + } + else + { + data->csw_response.data_reside -= data->ep_in->request.size; + if(data->csw_response.data_reside != 0) + { + RT_DEBUG_LOG(RT_DEBUG_USB, ("data_reside %d, request %d\n", + data->csw_response.data_reside, data->ep_in->request.size)); + if(data->processing->dir == DIR_OUT) + { + rt_usbd_ep_set_stall(func->device, data->ep_out); + } + else + { + rt_usbd_ep_set_stall(func->device, data->ep_in); + } + data->csw_response.data_reside = 0; + } + } + _send_status(func); + break; + case STAT_SEND: + data->csw_response.data_reside -= data->ep_in->request.size; + data->count--; + data->block++; + if(data->count > 0 && data->csw_response.data_reside > 0) + { + if(rt_device_read(data->disk, data->block, data->ep_in->buffer, 1) == 0) + { + rt_kprintf("disk read error\n"); + rt_usbd_ep_set_stall(func->device, data->ep_in); + return -RT_ERROR; + } + + data->ep_in->request.buffer = data->ep_in->buffer; + data->ep_in->request.size = data->geometry.bytes_per_sector; + data->ep_in->request.req_type = UIO_REQUEST_WRITE; + rt_usbd_io_request(func->device, data->ep_in, &data->ep_in->request); + } + else + { + _send_status(func); + } + break; + } - return RT_EOK; + return RT_EOK; } #ifdef MASS_CBW_DUMP @@ -376,134 +644,283 @@ static void cbw_dump(struct ustorage_cbw* cbw) } #endif -/** - * This function will handle mass storage bulk out endpoint request. - * - * @param device the usb device object. - * @param size request size. - * - * @return RT_EOK. - */ -static rt_err_t _ep_out_handler(udevice_t device, uclass_t cls, rt_size_t size) +static struct scsi_cmd* _find_cbw_command(rt_uint16_t cmd) { - mass_eps_t eps; - RT_ASSERT(device != RT_NULL); + int i; - eps = (mass_eps_t)cls->eps; - if(status == STATUS_CBW) + for(i=0; iep_out->buffer; + return RT_NULL; +} - if(cbw->signature == CBW_SIGNATURE) - { - csw.signature = CSW_SIGNATURE; - csw.tag = cbw->tag; - csw.data_reside = 0; - csw.status = 0; - } - else - return -RT_ERROR; +static void _cb_len_calc(ufunction_t func, struct scsi_cmd* cmd, + ustorage_cbw_t cbw) +{ + struct mstorage *data; + + RT_ASSERT(func != RT_NULL); + RT_ASSERT(cmd != RT_NULL); + RT_ASSERT(cbw != RT_NULL); - switch(cbw->cb[0]) + data = (struct mstorage*)func->user_data; + if(cmd->cmd_len == 6) + { + switch(cmd->type) { - case SCSI_TEST_UNIT_READY: - csw.status = _removed; - _send_status(device, eps, &csw); - break; - case SCSI_REQUEST_SENSE: - _request_sense(device, eps->ep_in); - status = STATUS_CSW; - break; - case SCSI_INQUIRY_CMD: - _inquiry_cmd(device, eps->ep_in); - status = STATUS_CSW; - break; - case SCSI_MODE_SENSE_6: - _mode_sense_6(device, eps->ep_in); - status = STATUS_CSW; + case COUNT: + data->cb_data_size = cbw->cb[4]; break; - case SCSI_ALLOW_MEDIUM_REMOVAL: - _send_status(device, eps, &csw); + case BLOCK_COUNT: + data->cb_data_size = cbw->cb[4] * data->geometry.bytes_per_sector; break; - case SCSI_READ_CAPACITIES: - _read_capacities(device, eps->ep_in); - status = STATUS_CSW; + case FIXED: + data->cb_data_size = cmd->data_size; break; - case SCSI_READ_CAPACITY: - _read_capacity(device, eps->ep_in); - status = STATUS_CSW; + default: break; - case SCSI_READ_10: - _read_10(device, cbw, eps->ep_in); + } + } + else if(cmd->cmd_len == 10) + { + switch(cmd->type) + { + case COUNT: + data->cb_data_size = cbw->cb[7]<<8 | cbw->cb[8]; break; - case SCSI_WRITE_10: - _write_10(device, cbw, eps->ep_out); - status = STATUS_RECEIVE; + case BLOCK_COUNT: + data->cb_data_size = (cbw->cb[7]<<8 | cbw->cb[8]) * + data->geometry.bytes_per_sector; break; - case SCSI_VERIFY_10: - _verify_10(device); + case FIXED: + data->cb_data_size = cmd->data_size; break; - case SCSI_START_STOP: - _start_stop(cbw); - _send_status(device, eps, &csw); + default: break; } } - else if(status == STATUS_RECEIVE) + else + { + rt_kprintf("cmd_len error %d\n", cmd->cmd_len); + } +} + +static rt_bool_t _cbw_verify(ufunction_t func, struct scsi_cmd* cmd, + ustorage_cbw_t cbw) +{ + struct mstorage *data; + + RT_ASSERT(cmd != RT_NULL); + RT_ASSERT(cbw != RT_NULL); + RT_ASSERT(func != RT_NULL); + + data = (struct mstorage*)func->user_data; + if(cmd->cmd_len != cbw->cb_len) + { + rt_kprintf("cb_len error\n"); + cmd->cmd_len = cbw->cb_len; + } + + if(cbw->xfer_len > 0 && data->cb_data_size == 0) + { + rt_kprintf("xfer_len > 0 && data_size == 0\n"); + return RT_FALSE; + } + + if(cbw->xfer_len == 0 && data->cb_data_size > 0) + { + rt_kprintf("xfer_len == 0 && data_size > 0"); + return RT_FALSE; + } + + if((cbw->dflags & USB_DIR_IN) && cmd->dir == DIR_OUT || + !(cbw->dflags & USB_DIR_IN) && cmd->dir == DIR_IN) + { + rt_kprintf("dir error\n"); + return RT_FALSE; + } + + if(cbw->xfer_len > data->cb_data_size) + { + rt_kprintf("xfer_len > data_size\n"); + return RT_FALSE; + } + + if(cbw->xfer_len < data->cb_data_size) + { + rt_kprintf("xfer_len < data_size\n"); + data->cb_data_size = cbw->xfer_len; + data->csw_response.status = 1; + } + + return RT_TRUE; +} + +static rt_size_t _cbw_handler(ufunction_t func, struct scsi_cmd* cmd, + ustorage_cbw_t cbw) +{ + struct mstorage *data; + + RT_ASSERT(func != RT_NULL); + RT_ASSERT(cbw != RT_NULL); + RT_ASSERT(cmd->handler != RT_NULL); + + data = (struct mstorage*)func->user_data; + data->processing = cmd; + return cmd->handler(func, cbw); +} + +/** + * This function will handle mass storage bulk out endpoint request. + * + * @param func the usb function object. + * @param size request size. + * + * @return RT_EOK. + */ +static rt_err_t _ep_out_handler(ufunction_t func, rt_size_t size) +{ + struct mstorage *data; + struct scsi_cmd* cmd; + rt_size_t len; + struct ustorage_cbw* cbw; + + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); + + RT_DEBUG_LOG(RT_DEBUG_USB, ("_ep_out_handler %d\n", size)); + + data = (struct mstorage*)func->user_data; + cbw = (struct ustorage_cbw*)data->ep_out->buffer; + if(data->status == STAT_CBW) + { + /* dump cbw information */ + if(cbw->signature != CBW_SIGNATURE || size != SIZEOF_CBW) + { + goto exit; + } + + data->csw_response.signature = CSW_SIGNATURE; + data->csw_response.tag = cbw->tag; + data->csw_response.data_reside = cbw->xfer_len; + data->csw_response.status = 0; + + RT_DEBUG_LOG(RT_DEBUG_USB, ("ep_out reside %d\n", data->csw_response.data_reside)); + + cmd = _find_cbw_command(cbw->cb[0]); + if(cmd == RT_NULL) + { + rt_kprintf("can't find cbw command\n"); + goto exit; + } + + _cb_len_calc(func, cmd, cbw); + if(!_cbw_verify(func, cmd, cbw)) + { + goto exit; + } + + len = _cbw_handler(func, cmd, cbw); + if(len == 0) + { + _send_status(func); + } + + return RT_EOK; + } + else if(data->status == STAT_RECEIVE) { - RT_DEBUG_LOG(RT_DEBUG_USB, ("write size 0x%x block 0x%x oount 0x%x\n", - size, _block, _size)); + RT_DEBUG_LOG(RT_DEBUG_USB, ("\nwrite size %d block 0x%x oount 0x%x\n", + size, data->block, data->size)); + + data->size -= size; + data->csw_response.data_reside -= size; - _size -= size; - csw.data_reside -= size; + rt_device_write(data->disk, data->block, data->ep_out->buffer, 1); - rt_device_write(disk, _block, eps->ep_in->buffer, 1); - _block ++; - if(_size == 0) + if(data->csw_response.data_reside != 0) { - _send_status(device, eps, &csw); + data->ep_out->request.buffer = data->ep_out->buffer; + data->ep_out->request.size = data->geometry.bytes_per_sector; + data->ep_out->request.req_type = UIO_REQUEST_READ_FULL; + rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); + data->block ++; } else { - dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, - geometry.bytes_per_sector); + _send_status(func); } + + return RT_EOK; } - else + +exit: + if(data->csw_response.data_reside) { - rt_kprintf("none cbw status\n"); + if(cbw->dflags & USB_DIR_IN) + { + rt_usbd_ep_set_stall(func->device, data->ep_in); + } + else + { + rt_usbd_ep_set_stall(func->device, data->ep_in); + rt_usbd_ep_set_stall(func->device, data->ep_out); + } } - - return RT_EOK; + data->csw_response.status = 1; + _send_status(func); + + return -RT_ERROR; } - /** * This function will handle mass storage interface request. * - * @param device the usb device object. + * @param func the usb function object. * @param setup the setup request. * * @return RT_EOK on successful. */ -static rt_err_t _interface_handler(udevice_t device, uclass_t cls, ureq_t setup) +static rt_err_t _interface_handler(ufunction_t func, ureq_t setup) { rt_uint8_t lun = 0; - - RT_ASSERT(device != RT_NULL); + + RT_ASSERT(func != RT_NULL); + RT_ASSERT(func->device != RT_NULL); RT_ASSERT(setup != RT_NULL); - RT_DEBUG_LOG(RT_DEBUG_USB, ("_interface_handler\n")); + RT_DEBUG_LOG(RT_DEBUG_USB, ("mstorage_interface_handler\n")); switch(setup->request) { - case USBREQ_GET_MAX_LUN: - dcd_ep_write(device->dcd, 0, &lun, 1); + case USBREQ_GET_MAX_LUN: + + RT_DEBUG_LOG(RT_DEBUG_USB, ("USBREQ_GET_MAX_LUN\n")); + + if(setup->value || setup->length != 1) + { + rt_usbd_ep0_set_stall(func->device); + } + else + { + rt_usbd_ep0_write(func->device, &lun, 1); + } break; case USBREQ_MASS_STORAGE_RESET: + + RT_DEBUG_LOG(RT_DEBUG_USB, ("USBREQ_MASS_STORAGE_RESET\n")); + + if(setup->value || setup->length != 0) + { + rt_usbd_ep0_set_stall(func->device); + } + else + { + rt_usbd_ep0_write(func->device, RT_NULL, 0); + } break; default: rt_kprintf("unknown interface request\n"); @@ -514,81 +931,114 @@ static rt_err_t _interface_handler(udevice_t device, uclass_t cls, ureq_t setup) } /** - * This function will run mass storage class, it will be called on handle set configuration request. + * This function will run mass storage function, it will be called on handle set configuration request. * - * @param device the usb device object. + * @param func the usb function object. * * @return RT_EOK on successful. */ -static rt_err_t _class_run(udevice_t device, uclass_t cls) +static rt_err_t _function_enable(ufunction_t func) { - mass_eps_t eps; - rt_uint8_t *buffer; - RT_ASSERT(device != RT_NULL); + struct mstorage *data; + RT_ASSERT(func != RT_NULL); - RT_DEBUG_LOG(RT_DEBUG_USB, ("mass storage run\n")); - eps = (mass_eps_t)cls->eps; + RT_DEBUG_LOG(RT_DEBUG_USB, ("Mass storage function enabled\n")); + data = (struct mstorage*)func->user_data; - disk = rt_device_find(RT_USB_MSTORAGE_DISK_NAME); - if(disk == RT_NULL) + data->disk = rt_device_find(RT_USB_MSTORAGE_DISK_NAME); + if(data->disk == RT_NULL) { - rt_kprintf("no disk named %s\n", RT_USB_MSTORAGE_DISK_NAME); + rt_kprintf("no data->disk named %s\n", RT_USB_MSTORAGE_DISK_NAME); return -RT_ERROR; } - if(rt_device_control(disk, RT_DEVICE_CTRL_BLK_GETGEOME, (void*)&geometry) != RT_EOK) - return -RT_ERROR; - buffer = (rt_uint8_t*)rt_malloc(geometry.bytes_per_sector); - if(buffer == RT_NULL) + if(rt_device_open(data->disk, RT_DEVICE_OFLAG_RDWR) != RT_EOK) + { + rt_kprintf("disk open error\n"); + return -RT_ERROR; + } + + if(rt_device_control(data->disk, RT_DEVICE_CTRL_BLK_GETGEOME, + (void*)&data->geometry) != RT_EOK) + { + rt_kprintf("get disk info error\n"); + return -RT_ERROR; + } + + data->ep_in->buffer = (rt_uint8_t*)rt_malloc(data->geometry.bytes_per_sector); + if(data->ep_in->buffer == RT_NULL) + { + rt_kprintf("no memory\n"); return -RT_ENOMEM; - eps->ep_out->buffer = buffer; - eps->ep_in->buffer = buffer; - - dcd_ep_read(device->dcd, eps->ep_out, eps->ep_out->buffer, SIZEOF_CBW); - + } + data->ep_out->buffer = (rt_uint8_t*)rt_malloc(data->geometry.bytes_per_sector); + if(data->ep_out->buffer == RT_NULL) + { + rt_free(data->ep_in->buffer); + rt_kprintf("no memory\n"); + return -RT_ENOMEM; + } + + /* prepare to read CBW request */ + data->ep_out->request.buffer = data->ep_out->buffer; + data->ep_out->request.size = SIZEOF_CBW; + data->ep_out->request.req_type = UIO_REQUEST_READ_FULL; + rt_usbd_io_request(func->device, data->ep_out, &data->ep_out->request); + return RT_EOK; } /** - * This function will stop mass storage class, it will be called on handle set configuration request. + * This function will stop mass storage function, it will be called on handle set configuration request. * * @param device the usb device object. * * @return RT_EOK on successful. */ -static rt_err_t _class_stop(udevice_t device, uclass_t cls) +static rt_err_t _function_disable(ufunction_t func) { - mass_eps_t eps; - RT_ASSERT(device != RT_NULL); + struct mstorage *data; + RT_ASSERT(func != RT_NULL); + + RT_DEBUG_LOG(RT_DEBUG_USB, ("Mass storage function disabled\n")); - RT_DEBUG_LOG(RT_DEBUG_USB, ("mass storage stop\n")); - eps = (mass_eps_t)cls->eps; - rt_free(eps->ep_in->buffer); - eps->ep_out->buffer = RT_NULL; - eps->ep_in->buffer = RT_NULL; + data = (struct mstorage*)func->user_data; + if(data->ep_in->buffer != RT_NULL) + { + rt_free(data->ep_in->buffer); + data->ep_in->buffer = RT_NULL; + } + if(data->ep_out->buffer != RT_NULL) + { + rt_free(data->ep_out->buffer); + data->ep_out->buffer = RT_NULL; + } + + data->status = STAT_CBW; + return RT_EOK; } -static struct uclass_ops ops = +static struct ufunction_ops ops = { - _class_run, - _class_stop, + _function_enable, + _function_disable, RT_NULL, }; /** - * This function will create a mass storage class instance. + * This function will create a mass storage function instance. * * @param device the usb device object. * * @return RT_EOK on successful. */ -uclass_t rt_usbd_class_mstorage_create(udevice_t device) +ufunction_t rt_usbd_function_mstorage_create(udevice_t device) { uintf_t intf; - mass_eps_t eps; - uclass_t mstorage; + struct mstorage *data; + ufunction_t func; ualtsetting_t setting; umass_desc_t mass_desc; @@ -597,37 +1047,42 @@ uclass_t rt_usbd_class_mstorage_create(udevice_t device) /* set usb device string description */ rt_usbd_device_set_string(device, _ustring); - /* create a mass storage class */ - mstorage = rt_usbd_class_create(device, &dev_desc, &ops); - /* create a mass storage endpoints collection */ - eps = (mass_eps_t)rt_malloc(sizeof(struct mass_eps)); - mstorage->eps = (void*)eps; - - /* create an interface */ - intf = rt_usbd_interface_create(device, _interface_handler); - - /* create an alternate setting */ - setting = rt_usbd_altsetting_create(sizeof(struct umass_descriptor)); + + /* create a mass storage function */ + func = rt_usbd_function_new(device, &dev_desc, &ops); + device->dev_qualifier = &dev_qualifier; + + /* allocate memory for mass storage function data */ + data = (struct mstorage*)rt_malloc(sizeof(struct mstorage)); + rt_memset(data, 0, sizeof(struct mstorage)); + func->user_data = (void*)data; + + /* create an interface object */ + intf = rt_usbd_interface_new(device, _interface_handler); + + /* create an alternate setting object */ + setting = rt_usbd_altsetting_new(sizeof(struct umass_descriptor)); + /* config desc in alternate setting */ rt_usbd_altsetting_config_descriptor(setting, &_mass_desc, 0); /* create a bulk out and a bulk in endpoint */ mass_desc = (umass_desc_t)setting->desc; - eps->ep_in = rt_usbd_endpoint_create(&mass_desc->ep_in_desc, _ep_in_handler); - eps->ep_out = rt_usbd_endpoint_create(&mass_desc->ep_out_desc, _ep_out_handler); + data->ep_in = rt_usbd_endpoint_new(&mass_desc->ep_in_desc, _ep_in_handler); + data->ep_out = rt_usbd_endpoint_new(&mass_desc->ep_out_desc, _ep_out_handler); /* add the bulk out and bulk in endpoint to the alternate setting */ - rt_usbd_altsetting_add_endpoint(setting, eps->ep_out); - rt_usbd_altsetting_add_endpoint(setting, eps->ep_in); + rt_usbd_altsetting_add_endpoint(setting, data->ep_out); + rt_usbd_altsetting_add_endpoint(setting, data->ep_in); /* add the alternate setting to the interface, then set default setting */ rt_usbd_interface_add_altsetting(intf, setting); rt_usbd_set_altsetting(intf, 0); - /* add the interface to the mass storage class */ - rt_usbd_class_add_interface(mstorage, intf); + /* add the interface to the mass storage function */ + rt_usbd_function_add_interface(func, intf); - return mstorage; + return func; } #endif diff --git a/components/drivers/usb/usbdevice/class/mstorage.h b/components/drivers/usb/usbdevice/class/mstorage.h index 4d53222a00..0f448a07d5 100644 --- a/components/drivers/usb/usbdevice/class/mstorage.h +++ b/components/drivers/usb/usbdevice/class/mstorage.h @@ -59,13 +59,6 @@ struct request_sense_data rt_uint8_t Reserved4[4]; }request_sense_data_t; -struct mass_eps -{ - uep_t ep_in; - uep_t ep_out; -}; -typedef struct mass_eps* mass_eps_t; - #pragma pack() #endif -- cgit v1.3.1