diff options
Diffstat (limited to 'nuttx/drivers/usbdev/usbmsc.h')
-rw-r--r-- | nuttx/drivers/usbdev/usbmsc.h | 689 |
1 files changed, 689 insertions, 0 deletions
diff --git a/nuttx/drivers/usbdev/usbmsc.h b/nuttx/drivers/usbdev/usbmsc.h new file mode 100644 index 000000000..910aef8bd --- /dev/null +++ b/nuttx/drivers/usbdev/usbmsc.h @@ -0,0 +1,689 @@ +/**************************************************************************** + * drivers/usbdev/usbmsc.h + * + * Copyright (C) 2008-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * Mass storage class device. Bulk-only with SCSI subclass. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __DRIVERS_USBDEV_USBMSC_H +#define __DRIVERS_USBDEV_USBMSC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/types.h> +#include <stdint.h> +#include <stdbool.h> +#include <pthread.h> +#include <queue.h> + +#include <nuttx/fs.h> +#include <nuttx/usb/storage.h> +#include <nuttx/usb/usbdev.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ +/* If the USB mass storage device is configured as part of a composite device + * then both CONFIG_USBDEV_COMPOSITE and CONFIG_USBMSC_COMPOSITE must be + * defined. + */ + +#ifndef CONFIG_USBDEV_COMPOSITE +# undef CONFIG_USBMSC_COMPOSITE +#endif + +#if defined(CONFIG_USBMSC_COMPOSITE) && !defined(CONFIG_USBMSC_STRBASE) +# define CONFIG_USBMSC_STRBASE (4) +#endif + +/* Interface IDs. If the mass storage driver is built as a component of a + * composite device, then the interface IDs may need to be offset. + */ + +#ifndef CONFIG_USBMSC_COMPOSITE +# undef CONFIG_USBMSC_IFNOBASE +# define CONFIG_USBMSC_IFNOBASE 0 +#endif + +#ifndef CONFIG_USBMSC_IFNOBASE +# define CONFIG_USBMSC_IFNOBASE 0 +#endif + +/* Number of requests in the write queue */ + +#ifndef CONFIG_USBMSC_NWRREQS +# define CONFIG_USBMSC_NWRREQS 4 +#endif + +/* Number of requests in the read queue */ + +#ifndef CONFIG_USBMSC_NRDREQS +# define CONFIG_USBMSC_NRDREQS 4 +#endif + +/* Logical endpoint numbers / max packet sizes */ + +#ifndef CONFIG_USBMSC_EPBULKOUT +# warning "EPBULKOUT not defined in the configuration" +# define CONFIG_USBMSC_EPBULKOUT 2 +#endif + +#ifndef CONFIG_USBMSC_EPBULKIN +# warning "EPBULKIN not defined in the configuration" +# define CONFIG_USBMSC_EPBULKIN 3 +#endif + +/* Packet and request buffer sizes */ + +#ifndef CONFIG_USBMSC_COMPOSITE +# ifndef CONFIG_USBMSC_EP0MAXPACKET +# define CONFIG_USBMSC_EP0MAXPACKET 64 +# endif +#endif + +#ifndef CONFIG_USBMSC_BULKINREQLEN +# ifdef CONFIG_USBDEV_DUALSPEED +# define CONFIG_USBMSC_BULKINREQLEN 512 +# else +# define CONFIG_USBMSC_BULKINREQLEN 64 +# endif +#else +# ifdef CONFIG_USBDEV_DUALSPEED +# if CONFIG_USBMSC_BULKINREQLEN < 512 +# warning "Bulk in buffer size smaller than max packet" +# undef CONFIG_USBMSC_BULKINREQLEN +# define CONFIG_USBMSC_BULKINREQLEN 512 +# endif +# else +# if CONFIG_USBMSC_BULKINREQLEN < 64 +# warning "Bulk in buffer size smaller than max packet" +# undef CONFIG_USBMSC_BULKINREQLEN +# define CONFIG_USBMSC_BULKINREQLEN 64 +# endif +# endif +#endif + +#ifndef CONFIG_USBMSC_BULKOUTREQLEN +# ifdef CONFIG_USBDEV_DUALSPEED +# define CONFIG_USBMSC_BULKOUTREQLEN 512 +# else +# define CONFIG_USBMSC_BULKOUTREQLEN 64 +# endif +#else +# ifdef CONFIG_USBDEV_DUALSPEED +# if CONFIG_USBMSC_BULKOUTREQLEN < 512 +# warning "Bulk in buffer size smaller than max packet" +# undef CONFIG_USBMSC_BULKOUTREQLEN +# define CONFIG_USBMSC_BULKOUTREQLEN 512 +# endif +# else +# if CONFIG_USBMSC_BULKOUTREQLEN < 64 +# warning "Bulk in buffer size smaller than max packet" +# undef CONFIG_USBMSC_BULKOUTREQLEN +# define CONFIG_USBMSC_BULKOUTREQLEN 64 +# endif +# endif +#endif + +/* Vendor and product IDs and strings */ + +#ifndef CONFIG_USBMSC_COMPOSITE +# ifndef CONFIG_USBMSC_VENDORID +# warning "CONFIG_USBMSC_VENDORID not defined" +# define CONFIG_USBMSC_VENDORID 0x584e +# endif + +# ifndef CONFIG_USBMSC_PRODUCTID +# warning "CONFIG_USBMSC_PRODUCTID not defined" +# define CONFIG_USBMSC_PRODUCTID 0x5342 +# endif + +# ifndef CONFIG_USBMSC_VERSIONNO +# define CONFIG_USBMSC_VERSIONNO (0x0399) +# endif + +# ifndef CONFIG_USBMSC_VENDORSTR +# warning "No Vendor string specified" +# define CONFIG_USBMSC_VENDORSTR "NuttX" +# endif + +# ifndef CONFIG_USBMSC_PRODUCTSTR +# warning "No Product string specified" +# define CONFIG_USBMSC_PRODUCTSTR "USBdev Storage" +# endif + +# undef CONFIG_USBMSC_SERIALSTR +# define CONFIG_USBMSC_SERIALSTR "0101" +#endif + +#undef CONFIG_USBMSC_CONFIGSTR +#define CONFIG_USBMSC_CONFIGSTR "Bulk" + +/* Debug -- must be consistent with include/debug.h */ + +#ifdef CONFIG_CPP_HAVE_VARARGS +# ifdef CONFIG_DEBUG +# ifdef CONFIG_ARCH_LOWPUTC +# define dbgprintf(format, arg...) lib_lowprintf(format, ##arg) +# else +# define dbgprintf(format, arg...) lib_rawprintf(format, ##arg) +# endif +# else +# define dbgprintf(x...) +# endif +#else +# ifdef CONFIG_DEBUG +# ifdef CONFIG_ARCH_LOWPUTC +# define dbgprintf lib_lowprintf +# else +# define dbgprintf lib_rawprintf +# endif +# else +# define dbgprintf (void) +# endif +#endif + +/* Packet and request buffer sizes */ + +#ifndef CONFIG_USBMSC_EP0MAXPACKET +# define CONFIG_USBMSC_EP0MAXPACKET 64 +#endif + +/* USB Controller */ + +#ifndef CONFIG_USBDEV_SELFPOWERED +# define SELFPOWERED USB_CONFIG_ATT_SELFPOWER +#else +# define SELFPOWERED (0) +#endif + +#ifndef CONFIG_USBDEV_REMOTEWAKEUP +# define REMOTEWAKEUP USB_CONFIG_ATTR_WAKEUP +#else +# define REMOTEWAKEUP (0) +#endif + +#ifndef CONFIG_USBDEV_MAXPOWER +# define CONFIG_USBDEV_MAXPOWER 100 +#endif + +/* Current state of the worker thread */ + +#define USBMSC_STATE_NOTSTARTED (0) /* Thread has not yet been started */ +#define USBMSC_STATE_STARTED (1) /* Started, but is not yet initialized */ +#define USBMSC_STATE_IDLE (2) /* Started and waiting for commands */ +#define USBMSC_STATE_CMDPARSE (3) /* Processing a received command */ +#define USBMSC_STATE_CMDREAD (4) /* Processing a SCSI read command */ +#define USBMSC_STATE_CMDWRITE (5) /* Processing a SCSI write command */ +#define USBMSC_STATE_CMDFINISH (6) /* Finish command processing */ +#define USBMSC_STATE_CMDSTATUS (7) /* Processing the final status of the command */ +#define USBMSC_STATE_TERMINATED (8) /* Thread has exitted */ + +/* Event communicated to worker thread */ + +#define USBMSC_EVENT_NOEVENTS (0) /* There are no outstanding events */ +#define USBMSC_EVENT_READY (1 << 0) /* Initialization is complete */ +#define USBMSC_EVENT_RDCOMPLETE (1 << 1) /* A read has completed there is data to be processed */ +#define USBMSC_EVENT_WRCOMPLETE (1 << 2) /* A write has completed and a request is available */ +#define USBMSC_EVENT_TERMINATEREQUEST (1 << 3) /* Shutdown requested */ +#define USBMSC_EVENT_DISCONNECT (1 << 4) /* USB disconnect received */ +#define USBMSC_EVENT_RESET (1 << 5) /* USB storage setup reset received */ +#define USBMSC_EVENT_CFGCHANGE (1 << 6) /* USB setup configuration change received */ +#define USBMSC_EVENT_IFCHANGE (1 << 7) /* USB setup interface change received */ +#define USBMSC_EVENT_ABORTBULKOUT (1 << 8) /* SCSI receive failure */ + +/* SCSI command flags (passed to usbmsc_setupcmd()) */ + +#define USBMSC_FLAGS_DIRMASK (0x03) /* Bits 0-1: Data direction */ +#define USBMSC_FLAGS_DIRNONE (0x00) /* No data to send */ +#define USBMSC_FLAGS_DIRHOST2DEVICE (0x01) /* Host-to-device */ +#define USBMSC_FLAGS_DIRDEVICE2HOST (0x02) /* Device-to-host */ +#define USBMSC_FLAGS_BLOCKXFR (0x04) /* Bit 2: Command is a block transfer request */ +#define USBMSC_FLAGS_LUNNOTNEEDED (0x08) /* Bit 3: Command does not require a valid LUN */ +#define USBMSC_FLAGS_UACOKAY (0x10) /* Bit 4: Command OK if unit attention condition */ +#define USBMSC_FLAGS_RETAINSENSEDATA (0x20) /* Bit 5: Do not clear sense data */ + +/* Descriptors **************************************************************/ + +/* Big enough to hold our biggest descriptor */ + +#define USBMSC_MXDESCLEN (64) + +/* String language */ + +#define USBMSC_STR_LANGUAGE (0x0409) /* en-us */ + +/* Descriptor strings */ + +#ifndef CONFIG_USBMSC_COMPOSITE +# define USBMSC_MANUFACTURERSTRID (1) +# define USBMSC_PRODUCTSTRID (2) +# define USBMSC_SERIALSTRID (3) +# define USBMSC_CONFIGSTRID (4) +# define USBMSC_INTERFACESTRID USBMSC_CONFIGSTRID + +# undef CONFIG_USBMSC_STRBASE +# define CONFIG_USBMSC_STRBASE (4) +#else +# define USBMSC_INTERFACESTRID (CONFIG_USBMSC_STRBASE+1) +#endif +#define USBMSC_LASTSTRID USBMSC_INTERFACESTRID + +#define USBMSC_NCONFIGS (1) /* Number of configurations supported */ + +/* Configuration Descriptor */ + +#define USBMSC_NINTERFACES (1) /* Number of interfaces in the configuration */ +#define USBMSC_INTERFACEID (CONFIG_USBMSC_IFNOBASE+0) +#define USBMSC_ALTINTERFACEID USBMSC_INTERFACEID + +#define USBMSC_CONFIGIDNONE (0) /* Config ID means to return to address mode */ +#define USBMSC_CONFIGID (1) /* The only supported configuration ID */ + +/* Interface description */ + +#define USBMSC_NENDPOINTS (2) /* Number of endpoints in the interface */ + +/* Endpoint configuration */ + +#define USBMSC_EPOUTBULK_ADDR (CONFIG_USBMSC_EPBULKOUT) +#define USBMSC_EPOUTBULK_ATTR (USB_EP_ATTR_XFER_BULK) + +#define USBMSC_EPINBULK_ADDR (USB_DIR_IN|CONFIG_USBMSC_EPBULKIN) +#define USBMSC_EPINBULK_ATTR (USB_EP_ATTR_XFER_BULK) + +#define USBMSC_HSBULKMAXPACKET (512) +#define USBMSC_HSBULKMXPKTSHIFT (9) +#define USBMSC_HSBULKMXPKTMASK (0x000001ff) +#define USBMSC_FSBULKMAXPACKET (64) +#define USBMSC_FSBULKMXPKTSHIFT (6) +#define USBMSC_FSBULKMXPKTMASK (0x0000003f) + +/* Macros for dual speed vs. full speed only operation */ + +#ifdef CONFIG_USBDEV_DUALSPEED +# define USBMSC_EPBULKINDESC(hs) \ + usbmsc_getepdesc((hs) ? USBMSC_EPHSBULKIN : USBMSC_EPFSBULKIN) +# define USBMSC_EPBULKOUTDESC(hs) \ + usbmsc_getepdesc((hs) ? USBMSC_EPHSBULKOUT : USBMSC_EPFSBULKOUT) +# define USBMSC_BULKMAXPACKET(hs) \ + ((hs) ? USBMSC_HSBULKMAXPACKET : USBMSC_FSBULKMAXPACKET) +# define USBMSC_BULKMXPKTSHIFT(d) \ + (((d)->speed==USB_SPEED_HIGH) ? USBMSC_HSBULKMXPKTSHIFT : USBMSC_FSBULKMXPKTSHIFT) +# define USBMSC_BULKMXPKTMASK(d) \ + (((d)->speed==USB_SPEED_HIGH) ? USBMSC_HSBULKMXPKTMASK : USBMSC_FSBULKMXPKTMASK) +#else +# define USBMSC_EPBULKINDESC(d) usbmsc_getepdesc(USBMSC_EPFSBULKIN) +# define USBMSC_EPBULKOUTDESC(d) usbmsc_getepdesc(USBMSC_EPFSBULKOUT) +# define USBMSC_BULKMAXPACKET(hs) USBMSC_FSBULKMAXPACKET +# define USBMSC_BULKMXPKTSHIFT(d) USBMSC_FSBULKMXPKTSHIFT +# define USBMSC_BULKMXPKTMASK(d) USBMSC_FSBULKMXPKTMASK +#endif + +/* Configuration descriptor size */ + +#ifndef CONFIG_USBMSC_COMPOSITE + +/* Number of individual descriptors in the configuration descriptor: + * (1) Configuration descriptor + (1) interface descriptor + (2) interface + * descriptors. + */ + +# define USBMSC_CFGGROUP_SIZE (4) + +/* The size of the config descriptor: (9 + 9 + 2*7) = 32 */ + +# define SIZEOF_USBMSC_CFGDESC \ + (USB_SIZEOF_CFGDESC + USB_SIZEOF_IFDESC + 2*USB_SIZEOF_EPDESC) +#else + +/* Number of individual descriptors in the configuration descriptor: + * (1) interface descriptor + (2) interface descriptors. + */ + +# define USBMSC_CFGGROUP_SIZE (3) + +/* The size of the config descriptor: (9 + 2*7) = 23 */ + +# define SIZEOF_USBMSC_CFGDESC (USB_SIZEOF_IFDESC + 2*USB_SIZEOF_EPDESC) +#endif + +/* Block driver helpers *****************************************************/ + +#define USBMSC_DRVR_READ(l,b,s,n) ((l)->inode->u.i_bops->read((l)->inode,b,s,n)) +#define USBMSC_DRVR_WRITE(l,b,s,n) ((l)->inode->u.i_bops->write((l)->inode,b,s,n)) +#define USBMSC_DRVR_GEOMETRY(l,g) ((l)->inode->u.i_bops->geometry((l)->inode,g)) + +/* Everpresent MIN/MAX macros ***********************************************/ + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ +/* Endpoint descriptors */ + +enum usbmsc_epdesc_e +{ + USBMSC_EPFSBULKOUT = 0, /* Full speed bulk OUT endpoint descriptor */ + USBMSC_EPFSBULKIN /* Full speed bulk IN endpoint descriptor */ +#ifdef CONFIG_USBDEV_DUALSPEED + , + USBMSC_EPHSBULKOUT, /* High speed bulk OUT endpoint descriptor */ + USBMSC_EPHSBULKIN /* High speed bulk IN endpoint descriptor */ +#endif +}; + +/* Container to support a list of requests */ + +struct usbmsc_req_s +{ + FAR struct usbmsc_req_s *flink; /* Implements a singly linked list */ + FAR struct usbdev_req_s *req; /* The contained request */ +}; + +/* This structure describes one LUN: */ + +struct usbmsc_lun_s +{ + struct inode *inode; /* Inode structure of open'ed block driver */ + uint8_t readonly:1; /* Media is read-only */ + uint8_t locked:1; /* Media removal is prevented */ + uint16_t sectorsize; /* The size of one sector */ + uint32_t sd; /* Sense data */ + uint32_t sdinfo; /* Sense data information */ + uint32_t uad; /* Unit needs attention data */ + off_t startsector; /* Sector offset to start of partition */ + size_t nsectors; /* Number of sectors in the partition */ +}; + +/* Describes the overall state of the driver */ + +struct usbmsc_dev_s +{ + FAR struct usbdev_s *usbdev; /* usbdev driver pointer (Non-null if registered) */ + + /* Worker thread interface */ + + pthread_t thread; /* The worker thread */ + pthread_mutex_t mutex; /* Mutually exclusive access to resources*/ + pthread_cond_t cond; /* Used to signal worker thread */ + volatile uint8_t thstate; /* State of the worker thread */ + volatile uint16_t theventset; /* Set of pending events signaled to worker thread */ + volatile uint8_t thvalue; /* Value passed with the event (must persist) */ + + /* Storage class configuration and state */ + + uint8_t nluns:4; /* Number of LUNs */ + uint8_t config; /* Configuration number */ + + /* Endpoints */ + + FAR struct usbdev_ep_s *epbulkin; /* Bulk IN endpoint structure */ + FAR struct usbdev_ep_s *epbulkout; /* Bulk OUT endpoint structure */ + FAR struct usbdev_req_s *ctrlreq; /* Control request (for ep0 setup responses) */ + + /* SCSI command processing */ + + struct usbmsc_lun_s *lun; /* Currently selected LUN */ + struct usbmsc_lun_s *luntab; /* Allocated table of all LUNs */ + uint8_t cdb[USBMSC_MAXCDBLEN]; /* Command data (cdb[]) from CBW */ + uint8_t phaseerror:1; /* Need to send phase sensing status */ + uint8_t shortpacket:1; /* Host transmission stopped unexpectedly */ + uint8_t cbwdir:2; /* Direction from CBW. See USBMSC_FLAGS_DIR* definitions */ + uint8_t cdblen; /* Length of cdb[] from CBW */ + uint8_t cbwlun; /* LUN from the CBW */ + uint16_t nsectbytes; /* Bytes buffered in iobuffer[] */ + uint16_t nreqbytes; /* Bytes buffered in head write requests */ + uint16_t iosize; /* Size of iobuffer[] */ + uint32_t cbwlen; /* Length of data from CBW */ + uint32_t cbwtag; /* Tag from the CBW */ + union + { + uint32_t xfrlen; /* Read/Write: Sectors remaining to be transferred */ + uint32_t alloclen; /* Other device-to-host: Host allocation length */ + } u; + uint32_t sector; /* Current sector (relative to lun->startsector) */ + uint32_t residue; /* Untransferred amount reported in the CSW */ + uint8_t *iobuffer; /* Buffer for data transfers */ + + /* Write request list */ + + struct sq_queue_s wrreqlist; /* List of empty write request containers */ + struct sq_queue_s rdreqlist; /* List of filled read request containers */ + + /* Pre-allocated write request containers. The write requests will + * be linked in a free list (wrreqlist), and used to send requests to + * EPBULKIN; Read requests will be queued in the EBULKOUT. + */ + + struct usbmsc_req_s wrreqs[CONFIG_USBMSC_NWRREQS]; + struct usbmsc_req_s rdreqs[CONFIG_USBMSC_NRDREQS]; +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +# define EXTERN extern "C" +extern "C" +{ +#else +# define EXTERN extern +#endif + +/* String *******************************************************************/ + +/* Mass storage class vendor/product/serial number strings */ + +#ifndef CONFIG_USBMSC_COMPOSITE +EXTERN const char g_mscvendorstr[]; +EXTERN const char g_mscproductstr[]; +EXTERN const char g_mscserialstr[]; + +/* If we are using a composite device, then vendor/product/serial number strings + * are provided by the composite device logic. + */ + +#else +EXTERN const char g_compvendorstr[]; +EXTERN const char g_compproductstr[]; +EXTERN const char g_compserialstr[]; + +#define g_mscvendorstr g_compvendorstr +#define g_mscproductstr g_compproductstr +#define g_mscserialstr g_compserialstr +#endif +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: usbmsc_mkstrdesc + * + * Description: + * Construct a string descriptor + * + ************************************************************************************/ + +struct usb_strdesc_s; +int usbmsc_mkstrdesc(uint8_t id, struct usb_strdesc_s *strdesc); + +/************************************************************************************ + * Name: usbmsc_getepdesc + * + * Description: + * Return a pointer to the raw device descriptor + * + ************************************************************************************/ + +#ifndef CONFIG_USBMSC_COMPOSITE +FAR const struct usb_devdesc_s *usbmsc_getdevdesc(void); +#endif + +/************************************************************************************ + * Name: usbmsc_getepdesc + * + * Description: + * Return a pointer to the raw endpoint descriptor (used for configuring endpoints) + * + ************************************************************************************/ + +struct usb_epdesc_s; +FAR const struct usb_epdesc_s *usbmsc_getepdesc(enum usbmsc_epdesc_e epid); + +/************************************************************************************ + * Name: usbmsc_mkcfgdesc + * + * Description: + * Construct the configuration descriptor + * + ************************************************************************************/ + +#ifdef CONFIG_USBDEV_DUALSPEED +int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, uint8_t speed, uint8_t type); +#else +int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf); +#endif + +/************************************************************************************ + * Name: usbmsc_getqualdesc + * + * Description: + * Return a pointer to the raw qual descriptor + * + ************************************************************************************/ + +#if !defined(CONFIG_USBMSC_COMPOSITE) && defined(CONFIG_USBDEV_DUALSPEED) +FAR const struct usb_qualdesc_s *usbmsc_getqualdesc(void); +#endif + +/**************************************************************************** + * Name: usbmsc_workerthread + * + * Description: + * This is the main function of the USB storage worker thread. It loops + * until USB-related events occur, then processes those events accordingly + * + ****************************************************************************/ + +EXTERN void *usbmsc_workerthread(void *arg); + +/**************************************************************************** + * Name: usbmsc_setconfig + * + * Description: + * Set the device configuration by allocating and configuring endpoints and + * by allocating and queue read and write requests. + * + ****************************************************************************/ + +EXTERN int usbmsc_setconfig(FAR struct usbmsc_dev_s *priv, uint8_t config); + +/**************************************************************************** + * Name: usbmsc_resetconfig + * + * Description: + * Mark the device as not configured and disable all endpoints. + * + ****************************************************************************/ + +EXTERN void usbmsc_resetconfig(FAR struct usbmsc_dev_s *priv); + +/**************************************************************************** + * Name: usbmsc_wrcomplete + * + * Description: + * Handle completion of write request. This function probably executes + * in the context of an interrupt handler. + * + ****************************************************************************/ + +EXTERN void usbmsc_wrcomplete(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *req); + +/**************************************************************************** + * Name: usbmsc_rdcomplete + * + * Description: + * Handle completion of read request on the bulk OUT endpoint. This + * is handled like the receipt of serial data on the "UART" + * + ****************************************************************************/ + +EXTERN void usbmsc_rdcomplete(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *req); + +/**************************************************************************** + * Name: usbmsc_deferredresponse + * + * Description: + * Some EP0 setup request cannot be responded to immediately becuase they + * require some asynchronous action from the SCSI worker thread. This + * function is provided for the SCSI thread to make that deferred response. + * The specific requests that require this deferred response are: + * + * 1. USB_REQ_SETCONFIGURATION, + * 2. USB_REQ_SETINTERFACE, or + * 3. USBMSC_REQ_MSRESET + * + * In all cases, the success reponse is a zero-length packet; the failure + * response is an EP0 stall. + * + * Input parameters: + * priv - Private state structure for this USB storage instance + * stall - true is the action failed and a stall is required + * + ****************************************************************************/ + +EXTERN void usbmsc_deferredresponse(FAR struct usbmsc_dev_s *priv, bool failed); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* #define __DRIVERS_USBDEV_USBMSC_H */ |