mirror of
https://github.com/apache/nuttx.git
synced 2026-05-21 21:34:07 +08:00
eacb4f0e84
commit69fcf3e849Author: Alan Carvalho de Assis <acassis@gmail.com> Date: Sun Jul 16 08:39:33 2017 -0600 Fix spark/stm32_composite.c: board_composite_connect cannot be static commit28eb253401Author: Gregory Nutt <gnutt@nuttx.org> Date: Sun Jul 16 08:36:01 2017 -0600 Composite: Final review for coding style before merge commite6af1b9994Author: Gregory Nutt <gnutt@nuttx.org> Date: Sun Jul 16 07:41:38 2017 -0600 Composite: Simplify some intiialization of data structures. commit771c367411Author: Gregory Nutt <gnutt@nuttx.org> Date: Sun Jul 16 07:15:08 2017 -0600 Cosmetic changes to alignment. commit5d67ddda4eAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Sun Jul 16 07:00:48 2017 -0600 USBMSC: Add missing logic to saved device description. commit0729151d29Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 17:11:41 2017 -0600 Trivial, costmetic commit74b916ff84Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 14:50:29 2017 -0600 Composite: Private functions need to be marked static. Move static functions out of 'Public Functions' to 'Private Functions' where they belong. Disable composite configuration 1 in all STM32 F1 configurations. commitcfaa4ece13Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 13:20:34 2017 -0600 Add some comments. commit8143563be6Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 12:33:10 2017 -0600 Spark: Need to condition out MSC logic in composite setup if there is no MSC in the composite. commit69d3a91ef1Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 11:03:33 2017 -0600 Composite: Remove all dependencies on CONFIG_SYSTEM_COMPOSITE_* configuration settings. Nothing in the OS can depend on external application settings. commit55a4388bbdAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 09:59:31 2017 -0600 All composite configurations now also support a dual CDC/ACM configuration. commit428f2147afAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 09:24:32 2017 -0600 Composite: Move board_msc* interfaces from apps/system/composite to the board specific OS logic where they belong. commitf1cc168a5cAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 08:56:33 2017 -0600 Refresh all composite configurations. commit246afcaa10Merge:919877191d02c6672868Author: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 08:22:26 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit919877191dAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jul 15 08:20:02 2017 -0600 Composite setup: Remove useless board_cdc* wrapper. commit82129cf8c6Merge:f2cb8b252a6537e4ea20Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 14 16:23:57 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commitf2cb8b252aAuthor: Alan Carvalho de Assis <acassis@gmail.com> Date: Fri Jul 14 10:19:35 2017 -0600 Composite: Fix for another cloned typo. commit676cfd526aAuthor: Alan Carvalho de Assis <acassis@gmail.com> Date: Fri Jul 14 09:11:37 2017 -0600 Composite: Fix some typos commit1ea0368c18Author: Alan Carvalho de Assis <acassis@gmail.com> Date: Fri Jul 14 09:10:18 2017 -0600 Composite: ./stm3210e-eval/src/stm32_composite.c commite485caced9Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 14 09:08:17 2017 -0600 Composite: I don't think the original code should have forced minor=0. commit6443c29621Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 14 07:15:38 2017 -0600 Composite: Flesh out support for all of other configurations that support composite. commit23cbc28b05Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 14 06:59:45 2017 -0600 Detangle use of board_xyzclassobject() and board_xyzuninitialize() commit1674cb8c8eMerge:6bc881a1925033a6def7Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jul 13 13:57:40 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit6bc881a192Merge:fe3af4941d85b8d16d8cAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Tue Jul 11 12:24:07 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commitfe3af4941dMerge:0f9ad16e181bc0eea143Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jul 10 11:07:36 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit0f9ad16e18Merge:a4cd90d4efaa2e9c15a5Author: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jul 7 20:26:53 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commita4cd90d4efMerge:8a4be7175e31f832d8c5Author: Gregory Nutt <gnutt@nuttx.org> Date: Wed Jul 5 11:12:52 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit8a4be7175eMerge:18a32ed2caae1771454aAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jun 30 16:14:04 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit18a32ed2caMerge:aaa81ce4976d8df90b79Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 29 10:18:16 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commitaaa81ce497Merge:4eb548226b8cb4636bb1Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 26 11:56:11 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit4eb548226bMerge:2327f5a1b4dc8eec0b61Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 19 17:27:00 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit2327f5a1b4Merge:49cd279fc699bf0b522bAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jun 16 17:30:03 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit49cd279fc6Merge:bb6a13f30a46f86982eeAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Wed Jun 14 09:17:49 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commitbb6a13f30aMerge:918480047aac93d4bda9Author: Gregory Nutt <gnutt@nuttx.org> Date: Mon Jun 5 17:40:06 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit918480047aMerge:e4d262436c4526cd665eAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Sat Jun 3 08:52:31 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commite4d262436cAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jun 2 07:19:27 2017 -0600 SAMV71-Xult Composite: Now can switch between two different composite configurations dynamically. commit815257743dAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Fri Jun 2 07:11:57 2017 -0600 usbdev composite and SAMV7-Xult: Move board-specific USB composite configuration out of boardctl.c and into board-specific logic where it belongs. Add a configuration option to the boardctl() calls to support multiple composite device configurations dynamically. commitac13619dc5Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 17:03:58 2017 -0600 Cosmetic commit9dd41bdd2fAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 17:02:43 2017 -0600 Composite: More compile-related fixes commitfc1438c95dMerge:049ccbfcbeff2b54a5e0Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 16:35:41 2017 -0600 Merge remote-tracking branch 'origin/master' into composite commit049ccbfcbeAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 16:35:16 2017 -0600 Composite: Add some structure definitions missed in first application of the patch. commitef33329e3aAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 16:14:46 2017 -0600 Add a warning commit89f77cd91aAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 16:11:27 2017 -0600 Fix some incomplete name changes commit0bb7af549aAuthor: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 15:09:50 2017 -0600 It is unnecessary to pack a structure that consists only of uint8_t data fields. commitbd9b548914Author: Gregory Nutt <gnutt@nuttx.org> Date: Thu Jun 1 15:05:41 2017 -0600 Remove COMPILE_TIME_ASSERTION commit7e6f481581Author: Frank Benkert <Frank.Benkert@avat.de> Date: Thu Jun 1 14:58:04 2017 -0600 Part II of the same big commit commitdcc9b07715Author: Frank Benkert <Frank.Benkert@avat.de> Date: Thu Jun 1 14:08:22 2017 -0600 [[This is part 1 or several commits]] We developed a huge Changeset over a year ago to make USB Composite configuration dynamical and be able to instanciate the CDCACM multiple times inside this device. We use this feature to switch between one in normal and up to three CDCACMs in maintenance boot. The control path starts in “boardctl.c” where the configuration for the device is constructed. There are still a few issues which I’ll ask you to have a look at before this beast can be merged. 1. To be able to construct the data dynamically I have changed some USB-Structs to be packed. Maybe there are additional structs to change (just for completeness – not for current functionality). 2. I’ve added the Macro “COMPILE_TIME_ASSERTION” two times (in usbmsc_desc.c and in cdcacm_desc.c) to stay private. Maybe you’ll find a better place. It’s used to check the size of the structs against the assumptions. 3. I’ve changed the interface for some USB-Functions to receive also the dynamic configuration. Maybe this can be done more elegant. 4. The original NuttX (without the patch) seems to have problems with a Composite device holding a CDCACM and an MSC. The “USB SET CONFIGURATION” request does not to work at all. This makes the test fail under Windows and under Linux. Applying this patch doesn’t change anything – because it only changes the configuration – not the behavior. Maybe you’ll have a look at this problem before applying the patch.
696 lines
24 KiB
C
696 lines
24 KiB
C
/****************************************************************************
|
|
* drivers/usbdev/usbmsc.h
|
|
*
|
|
* Copyright (C) 2008-2013, 2015, 2017 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 <queue.h>
|
|
#include <semaphore.h>
|
|
|
|
#include <nuttx/fs/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_COMPOSITE
|
|
# ifndef CONFIG_USBMSC_EPBULKOUT
|
|
# warning "EPBULKOUT not defined in the configuration"
|
|
# define CONFIG_USBMSC_EPBULKOUT 2
|
|
# endif
|
|
#endif
|
|
|
|
#ifndef CONFIG_USBMSC_COMPOSITE
|
|
# ifndef CONFIG_USBMSC_EPBULKIN
|
|
# warning "EPBULKIN not defined in the configuration"
|
|
# define CONFIG_USBMSC_EPBULKIN 3
|
|
# endif
|
|
#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"
|
|
|
|
/* SCSI daemon */
|
|
|
|
#ifndef CONFIG_USBMSC_SCSI_PRIO
|
|
# define CONFIG_USBMSC_SCSI_PRIO 128
|
|
#endif
|
|
|
|
#ifndef CONFIG_USBMSC_SCSI_STACKSIZE
|
|
# define CONFIG_USBMSC_SCSI_STACKSIZE 2048
|
|
#endif
|
|
|
|
/* Packet and request buffer sizes */
|
|
|
|
#ifndef CONFIG_USBMSC_EP0MAXPACKET
|
|
# define CONFIG_USBMSC_EP0MAXPACKET 64
|
|
#endif
|
|
|
|
/* USB Controller */
|
|
|
|
#ifdef CONFIG_USBDEV_SELFPOWERED
|
|
# define USBMSC_SELFPOWERED USB_CONFIG_ATTR_SELFPOWER
|
|
#else
|
|
# define USBMSC_SELFPOWERED (0)
|
|
#endif
|
|
|
|
#ifdef CONFIG_USBDEV_REMOTEWAKEUP
|
|
# define USBMSC_REMOTEWAKEUP USB_CONFIG_ATTR_WAKEUP
|
|
#else
|
|
# define USBMSC_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)
|
|
#define USBMSC_MAXSTRLEN (USBMSC_MXDESCLEN-2)
|
|
|
|
/* 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 (0)
|
|
#else
|
|
# define USBMSC_INTERFACESTRID (CONFIG_USBMSC_STRBASE+1)
|
|
#endif
|
|
|
|
#define USBMSC_LASTSTRID USBMSC_INTERFACESTRID
|
|
#define USBMSC_NSTRIDS (USBMSC_LASTSTRID - CONFIG_USBMSC_STRBASE)
|
|
|
|
/* Configuration Descriptor */
|
|
|
|
#define USBMSC_INTERFACEID (CONFIG_USBMSC_IFNOBASE+0)
|
|
#define USBMSC_ALTINTERFACEID (0)
|
|
|
|
#define USBMSC_CONFIGIDNONE (0) /* Config ID means to return to address mode */
|
|
|
|
/* Endpoint configuration */
|
|
|
|
#define USBMSC_MKEPBULKOUT(devDesc) ((devDesc)->epno[USBMSC_EP_BULKOUT_IDX])
|
|
#define USBMSC_EPOUTBULK_ATTR (USB_EP_ATTR_XFER_BULK)
|
|
|
|
#define USBMSC_MKEPBULKIN(devDesc) (USB_DIR_IN | (devDesc)->epno[USBMSC_EP_BULKIN_IDX])
|
|
#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)
|
|
|
|
/* Configuration descriptor size */
|
|
|
|
#ifndef CONFIG_USBMSC_COMPOSITE
|
|
|
|
/* The size of the config descriptor: (9 + 9 + 2*7) = 32 */
|
|
|
|
# define SIZEOF_USBMSC_CFGDESC \
|
|
(USB_SIZEOF_CFGDESC + USB_SIZEOF_IFDESC + USBMSC_NENDPOINTS * USB_SIZEOF_EPDESC)
|
|
|
|
#else
|
|
|
|
/* The size of the config descriptor: (9 + 2*7) = 23 */
|
|
|
|
# define SIZEOF_USBMSC_CFGDESC \
|
|
(USB_SIZEOF_IFDESC + USBMSC_NENDPOINTS * 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_EPBULKOUT = 0, /* Bulk OUT endpoint descriptor */
|
|
USBMSC_EPBULKIN /* Bulk IN endpoint descriptor */
|
|
};
|
|
|
|
/* 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
|
|
{
|
|
FAR 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 one instance of the driver */
|
|
|
|
struct usbmsc_dev_s
|
|
{
|
|
FAR struct usbdev_s *usbdev; /* usbdev driver pointer (Non-null if registered) */
|
|
|
|
/* SCSI worker kernel thread interface */
|
|
|
|
pid_t thpid; /* The worker thread task ID */
|
|
sem_t thsynch; /* Used to synchronizer terminal events */
|
|
sem_t thlock; /* Used to get exclusive access to the state data */
|
|
sem_t thwaitsem; /* Used to signal worker thread */
|
|
volatile bool thwaiting; /* True: worker thread is waiting for an event */
|
|
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 */
|
|
|
|
struct usbdev_description_s devdesc;
|
|
|
|
/* 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
|
|
|
|
/* Used to hand-off the state structure when the SCSI worker thread is started */
|
|
|
|
EXTERN FAR struct usbmsc_dev_s *g_usbmsc_handoff;
|
|
|
|
/****************************************************************************
|
|
* Public Function Prototypes
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Name: usbmsc_scsi_lock
|
|
*
|
|
* Description:
|
|
* Get exclusive access to SCSI state data.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void usbmsc_scsi_lock(FAR struct usbmsc_dev_s *priv);
|
|
|
|
/****************************************************************************
|
|
* Name: usbmsc_scsi_unlock
|
|
*
|
|
* Description:
|
|
* Relinquish exclusive access to SCSI state data.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define usbmsc_scsi_unlock(priv) sem_post(&priv->thlock)
|
|
|
|
/*****************************************************************************
|
|
* Name: usbmsc_scsi_signal
|
|
*
|
|
* Description:
|
|
* Signal the SCSI worker thread that SCSI events need service.
|
|
*
|
|
****************************************************************************/
|
|
|
|
void usbmsc_scsi_signal(FAR struct usbmsc_dev_s *priv);
|
|
|
|
/****************************************************************************
|
|
* Name: usbmsc_synch_signal
|
|
*
|
|
* Description:
|
|
* ACK controlling tasks request for synchronization.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#define usbmsc_synch_signal(priv) sem_post(&priv->thsynch)
|
|
|
|
/****************************************************************************
|
|
* 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_getdevdesc
|
|
*
|
|
* 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_copy_epdesc
|
|
*
|
|
* Description:
|
|
* Copies the requested Endpoint Description into the buffer given.
|
|
* Returns the number of Bytes filled in ( sizeof(struct usb_epdesc_s) ).
|
|
*
|
|
****************************************************************************/
|
|
|
|
int usbmsc_copy_epdesc(enum usbmsc_epdesc_e epid,
|
|
FAR struct usb_epdesc_s *epdesc,
|
|
FAR struct usbdev_description_s *devdesc,
|
|
bool hispeed);
|
|
|
|
/****************************************************************************
|
|
* Name: usbmsc_mkcfgdesc
|
|
*
|
|
* Description:
|
|
* Construct the configuration descriptor
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifdef CONFIG_USBDEV_DUALSPEED
|
|
int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, FAR struct usbdev_description_s *devdesc,
|
|
uint8_t speed, uint8_t type);
|
|
#else
|
|
int16_t usbmsc_mkcfgdesc(FAR uint8_t *buf, FAR struct usbdev_description_s *devdesc);
|
|
#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_scsi_main
|
|
*
|
|
* Description:
|
|
* This is the main function of the USB storage worker thread. It loops
|
|
* until USB-related events occur, then processes those events accordingly
|
|
*
|
|
****************************************************************************/
|
|
|
|
int usbmsc_scsi_main(int argc, char *argv[]);
|
|
|
|
/****************************************************************************
|
|
* Name: usbmsc_setconfig
|
|
*
|
|
* Description:
|
|
* Set the device configuration by allocating and configuring endpoints and
|
|
* by allocating and queue read and write requests.
|
|
*
|
|
****************************************************************************/
|
|
|
|
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.
|
|
*
|
|
****************************************************************************/
|
|
|
|
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.
|
|
*
|
|
****************************************************************************/
|
|
|
|
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"
|
|
*
|
|
****************************************************************************/
|
|
|
|
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
|
|
*
|
|
****************************************************************************/
|
|
|
|
void usbmsc_deferredresponse(FAR struct usbmsc_dev_s *priv, bool failed);
|
|
|
|
#undef EXTERN
|
|
#if defined(__cplusplus)
|
|
}
|
|
#endif
|
|
|
|
#endif /* __DRIVERS_USBDEV_USBMSC_H */
|