# drivers/usb/function/msc_bulk_function.c File Reference

USB Mass Storage Class Bulk-only function driver. More...

`#include <assert.h>`
`#include <atomic.h>`
`#include <byteorder.h>`
`#include <dmapool.h>`
`#include <interrupt.h>`
`#include <physmem.h>`
`#include <status-codes.h>`
`#include <string.h>`
`#include <types.h>`
`#include <util.h>`
`#include <block/device.h>`
`#include <scsi/cdb.h>`
`#include <scsi/spc_protocol.h>`
`#include <scsi/sbc_protocol.h>`
`#include <usb/function_core.h>`
`#include <usb/msc_function.h>`
`#include <usb/msc_protocol.h>`
`#include <usb/request.h>`
`#include <usb/usb_protocol.h>`
`#include <usb/udc.h>`
`#include <app/config_usb.h>`

Include dependency graph for msc_bulk_function.c:

Go to the source code of this file.

## Data Structures
struct | msc_func
| A Mass Storage Class interface instance. More...
## Defines
#define | MSC_MAX_NR_SEGS (2)
| Maximum number of pending block buffer segments.
## Functions
static void | msc_queue_empty (struct msc_func *msc)
| Current transfer is done; run any registered busy callback functions and clear it.
static int | msc_submit_read_buffers (struct msc_func *msc, struct block_device *bdev, struct block_request *breq, uint32_t nr_blocks)
static void | msc_read_worker (struct msc_func *msc)
static void | msc_do_read (struct msc_func *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_func *msc, struct block_device *bdev, uint32_t nr_blocks)
static void | msc_write_worker (void *data)

## Detailed Description

USB Mass Storage Class Bulk-only function driver.

This function driver implements the USB Mass Storage Class Bulk-Only interface.

- Compiler: IAR EWAVR32 and GNU GCC for AVR32
- Supported devices: All devices with a USB device controller
- AppNote:

This driver aims to conform with the following standards:

- Universal Serial Bus Specification Revision 2.0
- USB Mass Storage Class Specification Overview Revision 1.2
- USB Mass Storage Class Bulk-Only Transport Revision 1.0
- SCSI Architecture Model - 3 (SAM-3)
- SCSI Primary Commands - 3 (SPC-3)
- SCSI Block Commands - 2 (SBC-2)

Author:
  Atmel Corporation: http://www.atmel.com
  Support and FAQ: http://support.atmel.no/

Definition in file msc_bulk_function.c.

## Define Documentation

#define MSC_MAX_NR_SEGS (2)

Maximum number of pending block buffer segments.

Definition at line 89 of file msc_bulk_function.c.

Referenced by msc_read_worker(), and msc_write_worker().

## Function Documentation

static void msc_do_read | ( | struct msc_func * | 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 1329 of file msc_bulk_function.c.

References assert, msc_func::bdev, BLK_OP_READ, msc_func::blk_segs_pending, msc_func::block_req, block_device::block_size, msc_func::blocks_queued, msc_func::blocks_total, block_request::buf_list_done, msc_func::busy_asc, block_request::context, cpu_irq_restore(), cpu_irq_save(), dbg_verbose, usb_msc_cbw::dCBWDataTransferLength, msc_submit_read_buffers(), msc_func::not_ready, msc_func::queue_locked, block_request::req_done, block_request::req_started, unlikely, USB_CBW_DIRECTION_IN, USB_CSW_STATUS_FAIL, USB_CSW_STATUS_PASS, msc_func::usb_reqs_pending, and msc_func::xfer_in_progress.

Here is the call graph for this function:

static void msc_queue_empty | ( | struct msc_func * | msc | ) | `[static]`

Current transfer is done; run any registered busy callback functions and clear it.

For internal use only.

Definition at line 292 of file msc_bulk_function.c.

References msc_func::busy_cb, msc_func::busy_cb_data, cpu_irq_restore(), cpu_irq_save(), dbg_verbose, msc_func::not_ready, and msc_func::xfer_in_progress.

Here is the call graph for this function:

static void msc_read_worker | ( | struct msc_func * | msc | ) | `[static]`

For internal use only.

This function is called each time one of the following happens:

- A USB read data request is done
- The block device has started processing our request

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 1166 of file msc_bulk_function.c.

References assert, msc_func::bdev, msc_func::blk_segs_pending, msc_func::block_req, msc_func::blocks_queued, msc_func::blocks_total, cpu_irq_disable, cpu_irq_enable, dbg_verbose, MSC_MAX_NR_SEGS, msc_submit_read_buffers(), msc_func::queue_locked, and block_request::status.

Here is the call graph for this function:

static int msc_submit_read_buffers | ( | struct msc_func * | 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

- we have submitted enough to store all the data we intend to read, or
- we have reached the maximum amount of data for a single buffer list, or
- there's no more buffer memory available, or
- the request was ended prematurely

Returns:
  The number of blocks covered by the submitted buffers

Definition at line 1122 of file msc_bulk_function.c.

References msc_func::blk_segs_pending, block_device::block_size, block_submit_buf_list(), msc_func::blocks_queued, dbg_verbose, slist_init(), and unlikely.

Referenced by msc_do_read(), and msc_read_worker().

Here is the call graph for this function:

static int msc_submit_write_data_req | ( | struct msc_func * | 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

- we have submitted enough to receive all the data we intend to write, or
- we have reached the maximum amount of data for a single buffer list, or
- there's no more buffer memory available

Returns:
  The number of blocks covered by the submitted request

Definition at line 1409 of file msc_bulk_function.c.

References block_device::block_size, msc_func::blocks_queued, usb_request::buf_list, msc_func::bulk_out_ep, usb_request::context, dbg_verbose, usb_request::req_done, msc_func::udc, udc_ep_submit_out_req(), unlikely, usb_req_alloc(), usb_req_free(), and msc_func::usb_reqs_pending.

Referenced by msc_write_worker().

Here is the call graph for this function:

static void msc_write_worker | ( | void * | data | ) | `[static]`

For internal use only.

This workqueue function is queued each time one of the following happens:

- The block device has started processing our write request
- The block device is done processing one buffer list

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 1453 of file msc_bulk_function.c.

References assert, msc_func::bdev, msc_func::block_req, msc_func::blocks_queued, msc_func::blocks_total, cpu_irq_disable, cpu_irq_enable, dbg_verbose, MSC_MAX_NR_SEGS, msc_submit_write_data_req(), msc_func::queue_locked, block_request::status, and msc_func::usb_reqs_pending.

Here is the call graph for this function: