|
Data Structures | |
| struct | msc_interface |
| A Mass Storage Class interface instance. More... | |
Defines | |
| #define | MSC_MAX_NR_SEGS (2) |
| Maximum number of pending block buffer segments. | |
| #define | MSC_MAX_SERIAL_LEN 20 |
| Maximum number of characters in the device serial number. | |
Functions | |
| static void | msc_queue_empty (struct msc_interface *msc) |
| Current transfer is done; run any registered busy callback functions and clear it. | |
| static int | msc_submit_read_buffers (struct msc_interface *msc, struct block_device *bdev, struct block_request *breq, uint32_t nr_blocks) |
| static void | msc_read_worker (struct msc_interface *msc) |
| static void | msc_do_read (struct msc_interface *msc, struct udc *udc, struct usb_msc_cbw *cbw, uint32_t lba, uint32_t nr_blocks) |
| static int | msc_submit_write_data_req (struct msc_interface *msc, struct block_device *bdev, uint32_t nr_blocks) |
| static void | msc_write_worker (void *data) |
| status_t | udi_msc_enable (struct udc *udc, struct udm_interface *iface, uint16_t setting) |
| Enable the MSC interface. | |
| void | udi_msc_disable (struct udc *udc, struct udm_interface *iface) |
| Disable the MSC interface. | |
| status_t | udi_msc_setup (struct udc *udc, struct udm_interface *iface, struct usb_setup_req *req) |
| Handle a setup request directed at the MSC interface. | |
| status_t | udi_msc_get_iface_descriptor (struct udm_interface *iface, struct usb_request *req, enum usb_device_speed speed, uint16_t len) |
| Get the interface descriptor for the MSC interface. | |
| void | udi_msc_free_descriptor (struct udm_interface *iface, struct usb_request *req) |
| Free the memory allocated by msc_get_iface_descriptor(). | |
| void | udi_msc_set_busy (struct udm_interface *iface, uint16_t asc, void(*queue_empty)(void *data), void *data) |
| Reject data transfer requests. | |
| void | udi_msc_set_ready (struct udm_interface *iface) |
| Allow data transfer requests. | |
This driver implements a USB Mass Storage Class Bulk-only interface. Command, data and status transfers are all sent over two Bulk endpoints (one in and one out); also known as Bulk-Bulk-Bulk (BBB). This is the approach which has proven to give the best performance while using the least amount of resources (e.g. endpoints); other approaches like Command-Bulk-Interrupt (CBI) are not recommended for new devices according to the MSC Specification Overview.
This driver aims to conform with the following standards:
| #define MSC_MAX_NR_SEGS (2) |
Maximum number of pending block buffer segments.
Definition at line 78 of file msc_bulk.c.
Referenced by msc_read_worker(), and msc_write_worker().
| #define MSC_MAX_SERIAL_LEN 20 |
Maximum number of characters in the device serial number.
Note that there's usually no point in having more than 12 characters.
Definition at line 71 of file udi_msc_bulk.h.
| static void msc_do_read | ( | struct msc_interface * | msc, | |
| struct udc * | udc, | |||
| struct usb_msc_cbw * | cbw, | |||
| uint32_t | lba, | |||
| uint32_t | nr_blocks | |||
| ) | [static] |
For internal use only.
This function handles the READ(6) and READ(10) commands. It returns after submitting zero or more buffers; if no buffers is submitted, a CSW packet is sent to the host immediately, possibly after stalling one or more endpoints.
Definition at line 1286 of file msc_bulk.c.
References assert, atomic_write(), msc_interface::bdev, msc_interface::blk_blocks_pending, BLK_OP_READ, blkdev_get_block_size(), msc_interface::block_req, msc_interface::blocks_queued, msc_interface::blocks_total, msc_interface::busy_asc, block_request::context, cpu_irq_restore(), cpu_irq_save(), dbg_verbose, usb_msc_cbw::dCBWDataTransferLength, le32_to_cpu(), msc_submit_read_buffers(), msc_interface::not_ready, msc_interface::queue_locked, block_request::req_done, unlikely, USB_CBW_DIRECTION_IN, USB_CSW_STATUS_FAIL, USB_CSW_STATUS_PASS, msc_interface::usb_reqs_pending, and msc_interface::xfer_in_progress.
| static void msc_queue_empty | ( | struct msc_interface * | msc | ) | [static] |
Current transfer is done; run any registered busy callback functions and clear it.
For internal use only.
Definition at line 229 of file msc_bulk.c.
References msc_interface::busy_cb, msc_interface::busy_cb_data, cpu_irq_restore(), cpu_irq_save(), dbg_verbose, msc_interface::not_ready, and msc_interface::xfer_in_progress.
| static void msc_read_worker | ( | struct msc_interface * | msc | ) | [static] |
For internal use only.
This function is called each time one of the following happens:
The function will then try to keep both the block device and the USB controller as busy as possible by submitting new requests and buffer lists.
Definition at line 1111 of file msc_bulk.c.
References assert, atomic_read(), msc_interface::bdev, msc_interface::blk_blocks_pending, blkdev_get_block_size(), msc_interface::block_req, msc_interface::blocks_queued, msc_interface::blocks_total, cpu_irq_disable, cpu_irq_enable, dbg_verbose, MSC_MAX_NR_SEGS, msc_submit_read_buffers(), msc_interface::queue_locked, and block_request::status.
| static int msc_submit_read_buffers | ( | struct msc_interface * | msc, | |
| struct block_device * | bdev, | |||
| struct block_request * | breq, | |||
| uint32_t | nr_blocks | |||
| ) | [static] |
For internal use only.
Submit a list of buffers for storing data read from the block device. We will stop submitting buffers when
Definition at line 1067 of file msc_bulk.c.
References atomic_add(), atomic_sub(), msc_interface::blk_blocks_pending, blkdev_get_block_size(), block_submit_buf_list(), msc_interface::blocks_queued, dbg_verbose, slist_init(), and unlikely.
Referenced by msc_do_read(), and msc_read_worker().
| static int msc_submit_write_data_req | ( | struct msc_interface * | msc, | |
| struct block_device * | bdev, | |||
| uint32_t | nr_blocks | |||
| ) | [static] |
For internal use only.
Submit a USB OUT request for receiving data to be written to the block device. We will add buffers to the request until
Definition at line 1366 of file msc_bulk.c.
References atomic_inc, blkdev_get_block_size(), msc_interface::blocks_queued, usb_request::buf_list, msc_interface::bulk_out_ep, usb_request::context, dbg_verbose, usb_request::req_done, msc_interface::udc, udc_ep_submit_out_req(), unlikely, usb_req_alloc(), usb_req_free(), and msc_interface::usb_reqs_pending.
Referenced by msc_write_worker().
| static void msc_write_worker | ( | void * | data | ) | [static] |
For internal use only.
This function is called each time one of the following happens:
The function will then try to keep both the block device and the USB controller as busy as possible by submitting new requests and buffer lists.
Definition at line 1409 of file msc_bulk.c.
References assert, atomic_read(), msc_interface::bdev, msc_interface::block_req, msc_interface::blocks_queued, msc_interface::blocks_total, cpu_irq_disable, cpu_irq_enable, dbg_verbose, MSC_MAX_NR_SEGS, msc_submit_write_data_req(), msc_interface::queue_locked, block_request::status, and msc_interface::usb_reqs_pending.
| void udi_msc_disable | ( | struct udc * | udc, | |
| struct udm_interface * | iface | |||
| ) |
Disable the MSC interface.
This function is normally called by the UDM layer, but the application may call it directly if the UDM layer isn't used.
| udc | The USB Device Controller which received the request | |
| iface | The UDM interface object representing this interface |
| status_t udi_msc_enable | ( | struct udc * | udc, | |
| struct udm_interface * | iface, | |||
| uint16_t | setting | |||
| ) |
Enable the MSC interface.
This function is normally called by the UDM layer, but the application may call it directly if the UDM layer isn't used.
| udc | The USB Device Controller which received the Set Configuration or Set Interface request. | |
| iface | The UDM interface object representing this interface | |
| setting | The alternate setting to be enabled. If a Set Interface request was received, pass wValue converted to native endian; otherwise, pass 0. |
| STATUS_OK | The interface was successfully enabled | |
| STATUS_INVALID_ARG | setting is not supported | |
| negative | Failed to enable the interface |
| void udi_msc_free_descriptor | ( | struct udm_interface * | iface, | |
| struct usb_request * | req | |||
| ) |
Free the memory allocated by msc_get_iface_descriptor().
This function is normally called by the UDM layer, but the application may call it directly if the UDM layer isn't used.
After the configuration descriptor has been successfully sent to the host, this function should be called for each interface in the same order that get_iface_descriptor() was called earlier as long as there are buffers left in req's buffer list. The buffers used by the CDC Data Class Interface are removed from req's buffer list.
| iface | The UDM interface object representing this interface | |
| req | The USB request which was used to send the configuration descriptor |
| status_t udi_msc_get_iface_descriptor | ( | struct udm_interface * | iface, | |
| struct usb_request * | req, | |||
| enum usb_device_speed | speed, | |||
| uint16_t | len | |||
| ) |
Get the interface descriptor for the MSC interface.
This function is normally called by the UDM layer, but the application may call it directly if the UDM layer isn't used.
| iface | The UDM interface object representing this interface | |
| req | The USB request being used to send the configuration descriptor. Zero or more buffers containing the interface descriptor data will be added to this request. | |
| speed | Get interface descriptors matching this speed. May be different from the current speed if the "other speed" configuration descriptor was requested. | |
| len | The number of bytes available for the descriptor data |
| void udi_msc_set_busy | ( | struct udm_interface * | iface, | |
| uint16_t | asc, | |||
| void(*)(void *data) | queue_empty, | |||
| void * | data | |||
| ) |
Reject data transfer requests.
After the queue_empty callback has been called, all data transfer requests from the host are rejected with sense key NOT_READY and Additional Sense Code (Qualifier) as specified by asc.
| iface | The MSC interface | |
| asc | ASC/ASCQ pair to return in the sense data | |
| queue_empty | Callback to be called after any ongoing transfers have completed | |
| data | Arbitrary data pointer to be passed to queue_empty |
| void udi_msc_set_ready | ( | struct udm_interface * | iface | ) |
Allow data transfer requests.
After this function returns, the MSC interface iface will no longer reject data transfers from the host.
| status_t udi_msc_setup | ( | struct udc * | udc, | |
| struct udm_interface * | iface, | |||
| struct usb_setup_req * | req | |||
| ) |
Handle a setup request directed at the MSC interface.
This function is normally called by the UDM layer, but the application may call it directly if the UDM layer isn't used.
| udc | The USB Device Controller which received the request | |
| iface | The UDM interface object representing this interface | |
| setup | The unparsed SETUP request to be handled |
| STATUS_OK | The request was handled successfully | |
| negative | The request failed, so ep0 should be STALLed. |
1.6.3