usbhost_storage.c 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314
  1. /****************************************************************************
  2. * drivers/usbhost/usbhost_storage.c
  3. *
  4. * Copyright (C) 2010-2013, 2015-2016 Gregory Nutt. All rights reserved.
  5. * Author: Gregory Nutt <gnutt@nuttx.org>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Included Files
  37. ****************************************************************************/
  38. #include <nuttx/config.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <unistd.h>
  43. #include <semaphore.h>
  44. #include <assert.h>
  45. #include <errno.h>
  46. #include <debug.h>
  47. #include <nuttx/irq.h>
  48. #include <nuttx/kmalloc.h>
  49. #include <nuttx/fs/fs.h>
  50. #include <nuttx/arch.h>
  51. #include <nuttx/wqueue.h>
  52. #include <nuttx/scsi.h>
  53. #include <nuttx/usb/usb.h>
  54. #include <nuttx/usb/usbhost.h>
  55. #include <nuttx/usb/storage.h>
  56. #include <nuttx/usb/usbhost_devaddr.h>
  57. /* Don't compile if prerequisites are not met */
  58. #if defined(CONFIG_USBHOST) && !defined(CONFIG_USBHOST_BULK_DISABLE) && \
  59. !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
  60. /****************************************************************************
  61. * Pre-processor Definitions
  62. ****************************************************************************/
  63. /* Configuration ************************************************************/
  64. #ifndef CONFIG_SCHED_WORKQUEUE
  65. # warning "Worker thread support is required (CONFIG_SCHED_WORKQUEUE)"
  66. #endif
  67. /* If the create() method is called by the USB host device driver from an
  68. * interrupt handler, then it will be unable to call kmm_malloc() in order to
  69. * allocate a new class instance. If the create() method is called from the
  70. * interrupt level, then class instances must be pre-allocated.
  71. */
  72. #ifndef CONFIG_USBHOST_NPREALLOC
  73. # define CONFIG_USBHOST_NPREALLOC 0
  74. #endif
  75. #if CONFIG_USBHOST_NPREALLOC > 26
  76. # error "Currently limited to 26 devices /dev/sda-z"
  77. #endif
  78. /* Driver support ***********************************************************/
  79. /* This format is used to construct the /dev/sd[n] device driver path. It
  80. * defined here so that it will be used consistently in all places.
  81. */
  82. #define DEV_FORMAT "/dev/sd%c"
  83. #define DEV_NAMELEN 10
  84. /* Used in usbhost_connect() */
  85. #define USBHOST_IFFOUND 0x01
  86. #define USBHOST_BINFOUND 0x02
  87. #define USBHOST_BOUTFOUND 0x04
  88. #define USBHOST_ALLFOUND 0x07
  89. #define USBHOST_RETRY_USEC (50*1000) /* Retry each 50 milliseconds */
  90. #define USBHOST_MAX_RETRIES 100 /* Give up after 5 seconds */
  91. #define USBHOST_MAX_CREFS INT16_MAX /* Max cref count before signed overflow */
  92. /****************************************************************************
  93. * Private Types
  94. ****************************************************************************/
  95. /* This structure contains the internal, private state of the USB host mass
  96. * storage class.
  97. */
  98. struct usbhost_state_s
  99. {
  100. /* This is the externally visible portion of the state */
  101. struct usbhost_class_s usbclass;
  102. /* The remainder of the fields are provide to the mass storage class */
  103. char sdchar; /* Character identifying the /dev/sd[n] device */
  104. volatile bool disconnected; /* TRUE: Device has been disconnected */
  105. uint8_t ifno; /* Interface number */
  106. int16_t crefs; /* Reference count on the driver instance */
  107. uint16_t blocksize; /* Block size of USB mass storage device */
  108. uint32_t nblocks; /* Number of blocks on the USB mass storage device */
  109. sem_t exclsem; /* Used to maintain mutual exclusive access */
  110. struct work_s work; /* For interacting with the worker thread */
  111. FAR uint8_t *tbuffer; /* The allocated transfer buffer */
  112. size_t tbuflen; /* Size of the allocated transfer buffer */
  113. usbhost_ep_t bulkin; /* Bulk IN endpoint */
  114. usbhost_ep_t bulkout; /* Bulk OUT endpoint */
  115. };
  116. /* This is how struct usbhost_state_s looks to the free list logic */
  117. struct usbhost_freestate_s
  118. {
  119. FAR struct usbhost_freestate_s *flink;
  120. };
  121. /****************************************************************************
  122. * Private Function Prototypes
  123. ****************************************************************************/
  124. /* Semaphores */
  125. static void usbhost_takesem(sem_t *sem);
  126. #define usbhost_givesem(s) sem_post(s);
  127. /* Memory allocation services */
  128. static inline FAR struct usbhost_state_s *usbhost_allocclass(void);
  129. static inline void usbhost_freeclass(FAR struct usbhost_state_s *usbclass);
  130. /* Device name management */
  131. static int usbhost_allocdevno(FAR struct usbhost_state_s *priv);
  132. static void usbhost_freedevno(FAR struct usbhost_state_s *priv);
  133. static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv,
  134. FAR char *devname);
  135. /* CBW/CSW debug helpers */
  136. #if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_INFO)
  137. static void usbhost_dumpcbw(FAR struct usbmsc_cbw_s *cbw);
  138. static void usbhost_dumpcsw(FAR struct usbmsc_csw_s *csw);
  139. #else
  140. # define usbhost_dumpcbw(cbw);
  141. # define usbhost_dumpcsw(csw);
  142. #endif
  143. /* CBW helpers */
  144. static inline void usbhost_requestsensecbw(FAR struct usbmsc_cbw_s *cbw);
  145. static inline void usbhost_testunitreadycbw(FAR struct usbmsc_cbw_s *cbw);
  146. static inline void usbhost_readcapacitycbw(FAR struct usbmsc_cbw_s *cbw);
  147. static inline void usbhost_inquirycbw (FAR struct usbmsc_cbw_s *cbw);
  148. static inline void usbhost_readcbw (size_t startsector, uint16_t blocksize,
  149. unsigned int nsectors,
  150. FAR struct usbmsc_cbw_s *cbw);
  151. static inline void usbhost_writecbw(size_t startsector, uint16_t blocksize,
  152. unsigned int nsectors,
  153. FAR struct usbmsc_cbw_s *cbw);
  154. /* Command helpers */
  155. static inline int usbhost_maxlunreq(FAR struct usbhost_state_s *priv);
  156. static inline int usbhost_testunitready(FAR struct usbhost_state_s *priv);
  157. static inline int usbhost_requestsense(FAR struct usbhost_state_s *priv);
  158. static inline int usbhost_readcapacity(FAR struct usbhost_state_s *priv);
  159. static inline int usbhost_inquiry(FAR struct usbhost_state_s *priv);
  160. /* Worker thread actions */
  161. static void usbhost_destroy(FAR void *arg);
  162. /* Helpers for usbhost_connect() */
  163. static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
  164. FAR const uint8_t *configdesc, int desclen);
  165. static inline int usbhost_initvolume(FAR struct usbhost_state_s *priv);
  166. /* (Little Endian) Data helpers */
  167. static inline uint16_t usbhost_getle16(const uint8_t *val);
  168. static inline uint16_t usbhost_getbe16(const uint8_t *val);
  169. static inline void usbhost_putle16(uint8_t *dest, uint16_t val);
  170. static inline void usbhost_putbe16(uint8_t *dest, uint16_t val);
  171. static inline uint32_t usbhost_getle32(const uint8_t *val);
  172. static inline uint32_t usbhost_getbe32(const uint8_t *val);
  173. static void usbhost_putle32(uint8_t *dest, uint32_t val);
  174. static void usbhost_putbe32(uint8_t *dest, uint32_t val);
  175. /* Transfer descriptor memory management */
  176. static inline int usbhost_talloc(FAR struct usbhost_state_s *priv);
  177. static inline int usbhost_tfree(FAR struct usbhost_state_s *priv);
  178. static FAR struct usbmsc_cbw_s *usbhost_cbwalloc(FAR struct usbhost_state_s *priv);
  179. /* struct usbhost_registry_s methods */
  180. static struct usbhost_class_s *
  181. usbhost_create(FAR struct usbhost_hubport_s *hport,
  182. FAR const struct usbhost_id_s *id);
  183. /* struct usbhost_class_s methods */
  184. static int usbhost_connect(FAR struct usbhost_class_s *usbclass,
  185. FAR const uint8_t *configdesc, int desclen);
  186. static int usbhost_disconnected(FAR struct usbhost_class_s *usbclass);
  187. /* struct block_operations methods */
  188. static int usbhost_open(FAR struct inode *inode);
  189. static int usbhost_close(FAR struct inode *inode);
  190. static ssize_t usbhost_read(FAR struct inode *inode, FAR unsigned char *buffer,
  191. size_t startsector, unsigned int nsectors);
  192. #ifdef CONFIG_FS_WRITABLE
  193. static ssize_t usbhost_write(FAR struct inode *inode,
  194. FAR const unsigned char *buffer, size_t startsector,
  195. unsigned int nsectors);
  196. #endif
  197. static int usbhost_geometry(FAR struct inode *inode,
  198. FAR struct geometry *geometry);
  199. static int usbhost_ioctl(FAR struct inode *inode, int cmd,
  200. unsigned long arg);
  201. /****************************************************************************
  202. * Private Data
  203. ****************************************************************************/
  204. /* This structure provides the registry entry ID information that will be
  205. * used to associate the USB host mass storage class to a connected USB
  206. * device.
  207. */
  208. static const const struct usbhost_id_s g_id =
  209. {
  210. USB_CLASS_MASS_STORAGE, /* base */
  211. USBMSC_SUBCLASS_SCSI, /* subclass */
  212. USBMSC_PROTO_BULKONLY, /* proto */
  213. 0, /* vid */
  214. 0 /* pid */
  215. };
  216. /* This is the USB host storage class's registry entry */
  217. static struct usbhost_registry_s g_storage =
  218. {
  219. NULL, /* flink */
  220. usbhost_create, /* create */
  221. 1, /* nids */
  222. &g_id /* id[] */
  223. };
  224. /* Block driver operations. This is the interface exposed to NuttX by the
  225. * class that permits it to behave like a block driver.
  226. */
  227. static const struct block_operations g_bops =
  228. {
  229. usbhost_open, /* open */
  230. usbhost_close, /* close */
  231. usbhost_read, /* read */
  232. #ifdef CONFIG_FS_WRITABLE
  233. usbhost_write, /* write */
  234. #else
  235. NULL, /* write */
  236. #endif
  237. usbhost_geometry, /* geometry */
  238. usbhost_ioctl /* ioctl */
  239. };
  240. /* This is an array of pre-allocated USB host storage class instances */
  241. #if CONFIG_USBHOST_NPREALLOC > 0
  242. static struct usbhost_state_s g_prealloc[CONFIG_USBHOST_NPREALLOC];
  243. #endif
  244. /* This is a list of free, pre-allocated USB host storage class instances */
  245. #if CONFIG_USBHOST_NPREALLOC > 0
  246. static FAR struct usbhost_freestate_s *g_freelist;
  247. #endif
  248. /* This is a bitmap that is used to allocate device names /dev/sda-z. */
  249. static uint32_t g_devinuse;
  250. /****************************************************************************
  251. * Private Functions
  252. ****************************************************************************/
  253. /****************************************************************************
  254. * Name: usbhost_takesem
  255. *
  256. * Description:
  257. * This is just a wrapper to handle the annoying behavior of semaphore
  258. * waits that return due to the receipt of a signal.
  259. *
  260. ****************************************************************************/
  261. static void usbhost_takesem(sem_t *sem)
  262. {
  263. /* Take the semaphore (perhaps waiting) */
  264. while (sem_wait(sem) != 0)
  265. {
  266. /* The only case that an error should occur here is if the wait was
  267. * awakened by a signal.
  268. */
  269. ASSERT(errno == EINTR);
  270. }
  271. }
  272. /****************************************************************************
  273. * Name: usbhost_allocclass
  274. *
  275. * Description:
  276. * This is really part of the logic that implements the create() method
  277. * of struct usbhost_registry_s. This function allocates memory for one
  278. * new class instance.
  279. *
  280. * Input Parameters:
  281. * None
  282. *
  283. * Returned Values:
  284. * On success, this function will return a non-NULL instance of struct
  285. * usbhost_class_s. NULL is returned on failure; this function will
  286. * will fail only if there are insufficient resources to create another
  287. * USB host class instance.
  288. *
  289. ****************************************************************************/
  290. #if CONFIG_USBHOST_NPREALLOC > 0
  291. static inline FAR struct usbhost_state_s *usbhost_allocclass(void)
  292. {
  293. FAR struct usbhost_freestate_s *entry;
  294. irqstate_t flags;
  295. /* We may be executing from an interrupt handler so we need to take one of
  296. * our pre-allocated class instances from the free list.
  297. */
  298. flags = enter_critical_section();
  299. entry = g_freelist;
  300. if (entry)
  301. {
  302. g_freelist = entry->flink;
  303. }
  304. leave_critical_section(flags);
  305. uinfo("Allocated: %p\n", entry);
  306. return (FAR struct usbhost_state_s *)entry;
  307. }
  308. #else
  309. static inline FAR struct usbhost_state_s *usbhost_allocclass(void)
  310. {
  311. FAR struct usbhost_state_s *priv;
  312. /* We are not executing from an interrupt handler so we can just call
  313. * kmm_malloc() to get memory for the class instance.
  314. */
  315. DEBUGASSERT(!up_interrupt_context());
  316. priv = (FAR struct usbhost_state_s *)kmm_malloc(sizeof(struct usbhost_state_s));
  317. uinfo("Allocated: %p\n", priv);
  318. return priv;
  319. }
  320. #endif
  321. /****************************************************************************
  322. * Name: usbhost_freeclass
  323. *
  324. * Description:
  325. * Free a class instance previously allocated by usbhost_allocclass().
  326. *
  327. * Input Parameters:
  328. * usbclass - A reference to the class instance to be freed.
  329. *
  330. * Returned Values:
  331. * None
  332. *
  333. ****************************************************************************/
  334. #if CONFIG_USBHOST_NPREALLOC > 0
  335. static inline void usbhost_freeclass(FAR struct usbhost_state_s *usbclass)
  336. {
  337. FAR struct usbhost_freestate_s *entry = (FAR struct usbhost_freestate_s *)usbclass;
  338. irqstate_t flags;
  339. DEBUGASSERT(entry != NULL);
  340. uinfo("Freeing: %p\n", entry);
  341. /* Just put the pre-allocated class structure back on the freelist */
  342. flags = enter_critical_section();
  343. entry->flink = g_freelist;
  344. g_freelist = entry;
  345. leave_critical_section(flags);
  346. }
  347. #else
  348. static inline void usbhost_freeclass(FAR struct usbhost_state_s *usbclass)
  349. {
  350. DEBUGASSERT(usbclass != NULL);
  351. /* Free the class instance (calling sched_kfree() in case we are executing
  352. * from an interrupt handler.
  353. */
  354. uinfo("Freeing: %p\n", usbclass);
  355. sched_kfree(usbclass);
  356. }
  357. #endif
  358. /****************************************************************************
  359. * Name: Device name management
  360. *
  361. * Description:
  362. * Some tiny functions to coordinate management of mass storage device names.
  363. *
  364. ****************************************************************************/
  365. static int usbhost_allocdevno(FAR struct usbhost_state_s *priv)
  366. {
  367. irqstate_t flags;
  368. int devno;
  369. flags = enter_critical_section();
  370. for (devno = 0; devno < 26; devno++)
  371. {
  372. uint32_t bitno = 1 << devno;
  373. if ((g_devinuse & bitno) == 0)
  374. {
  375. g_devinuse |= bitno;
  376. priv->sdchar = 'a' + devno;
  377. leave_critical_section(flags);
  378. return OK;
  379. }
  380. }
  381. leave_critical_section(flags);
  382. return -EMFILE;
  383. }
  384. static void usbhost_freedevno(FAR struct usbhost_state_s *priv)
  385. {
  386. int devno = 'a' - priv->sdchar;
  387. if (devno >= 0 && devno < 26)
  388. {
  389. irqstate_t flags = enter_critical_section();
  390. g_devinuse &= ~(1 << devno);
  391. leave_critical_section(flags);
  392. }
  393. }
  394. static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv, char *devname)
  395. {
  396. (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->sdchar);
  397. }
  398. /****************************************************************************
  399. * Name: CBW/CSW debug helpers
  400. *
  401. * Description:
  402. * The following functions are helper functions used to dump CBWs and CSWs.
  403. *
  404. * Input Parameters:
  405. * cbw/csw - A reference to the CBW/CSW to dump.
  406. *
  407. * Returned Values:
  408. * None
  409. *
  410. ****************************************************************************/
  411. #if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_INFO)
  412. static void usbhost_dumpcbw(FAR struct usbmsc_cbw_s *cbw)
  413. {
  414. int i;
  415. uinfo("CBW:\n");
  416. uinfo(" signature: %08x\n", usbhost_getle32(cbw->signature));
  417. uinfo(" tag: %08x\n", usbhost_getle32(cbw->tag));
  418. uinfo(" datlen: %08x\n", usbhost_getle32(cbw->datlen));
  419. uinfo(" flags: %02x\n", cbw->flags);
  420. uinfo(" lun: %02x\n", cbw->lun);
  421. uinfo(" cdblen: %02x\n", cbw->cdblen);
  422. uinfo("CDB:\n");
  423. for (i = 0; i < cbw->cdblen; i += 8)
  424. {
  425. uinfo(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
  426. cbw->cdb[i], cbw->cdb[i+1], cbw->cdb[i+2], cbw->cdb[i+3],
  427. cbw->cdb[i+4], cbw->cdb[i+5], cbw->cdb[i+6], cbw->cdb[i+7]);
  428. }
  429. }
  430. static void usbhost_dumpcsw(FAR struct usbmsc_csw_s *csw)
  431. {
  432. uinfo("CSW:\n");
  433. uinfo(" signature: %08x\n", usbhost_getle32(csw->signature));
  434. uinfo(" tag: %08x\n", usbhost_getle32(csw->tag));
  435. uinfo(" residue: %08x\n", usbhost_getle32(csw->residue));
  436. uinfo(" status: %02x\n", csw->status);
  437. }
  438. #endif
  439. /****************************************************************************
  440. * Name: CBW helpers
  441. *
  442. * Description:
  443. * The following functions are helper functions used to format CBWs.
  444. *
  445. * Input Parameters:
  446. * cbw - A reference to allocated and initialized CBW to be built.
  447. *
  448. * Returned Values:
  449. * None
  450. *
  451. ****************************************************************************/
  452. static inline void usbhost_requestsensecbw(FAR struct usbmsc_cbw_s *cbw)
  453. {
  454. FAR struct scsicmd_requestsense_s *reqsense;
  455. /* Format the CBW */
  456. usbhost_putle32(cbw->datlen, SCSIRESP_FIXEDSENSEDATA_SIZEOF);
  457. cbw->flags = USBMSC_CBWFLAG_IN;
  458. cbw->cdblen = SCSICMD_REQUESTSENSE_SIZEOF;
  459. /* Format the CDB */
  460. reqsense = (FAR struct scsicmd_requestsense_s *)cbw->cdb;
  461. reqsense->opcode = SCSI_CMD_REQUESTSENSE;
  462. reqsense->alloclen = SCSIRESP_FIXEDSENSEDATA_SIZEOF;
  463. usbhost_dumpcbw(cbw);
  464. }
  465. static inline void usbhost_testunitreadycbw(FAR struct usbmsc_cbw_s *cbw)
  466. {
  467. /* Format the CBW */
  468. cbw->cdblen = SCSICMD_TESTUNITREADY_SIZEOF;
  469. /* Format the CDB */
  470. cbw->cdb[0] = SCSI_CMD_TESTUNITREADY;
  471. usbhost_dumpcbw(cbw);
  472. }
  473. static inline void usbhost_readcapacitycbw(FAR struct usbmsc_cbw_s *cbw)
  474. {
  475. FAR struct scsicmd_readcapacity10_s *rcap10;
  476. /* Format the CBW */
  477. usbhost_putle32(cbw->datlen, SCSIRESP_READCAPACITY10_SIZEOF);
  478. cbw->flags = USBMSC_CBWFLAG_IN;
  479. cbw->cdblen = SCSICMD_READCAPACITY10_SIZEOF;
  480. /* Format the CDB */
  481. rcap10 = (FAR struct scsicmd_readcapacity10_s *)cbw->cdb;
  482. rcap10->opcode = SCSI_CMD_READCAPACITY10;
  483. usbhost_dumpcbw(cbw);
  484. }
  485. static inline void usbhost_inquirycbw (FAR struct usbmsc_cbw_s *cbw)
  486. {
  487. FAR struct scscicmd_inquiry_s *inq;
  488. /* Format the CBW */
  489. usbhost_putle32(cbw->datlen, SCSIRESP_INQUIRY_SIZEOF);
  490. cbw->flags = USBMSC_CBWFLAG_IN;
  491. cbw->cdblen = SCSICMD_INQUIRY_SIZEOF;
  492. /* Format the CDB */
  493. inq = (FAR struct scscicmd_inquiry_s *)cbw->cdb;
  494. inq->opcode = SCSI_CMD_INQUIRY;
  495. usbhost_putbe16(inq->alloclen, SCSIRESP_INQUIRY_SIZEOF);
  496. usbhost_dumpcbw(cbw);
  497. }
  498. static inline void
  499. usbhost_readcbw (size_t startsector, uint16_t blocksize,
  500. unsigned int nsectors, FAR struct usbmsc_cbw_s *cbw)
  501. {
  502. FAR struct scsicmd_read10_s *rd10;
  503. /* Format the CBW */
  504. usbhost_putle32(cbw->datlen, blocksize * nsectors);
  505. cbw->flags = USBMSC_CBWFLAG_IN;
  506. cbw->cdblen = SCSICMD_READ10_SIZEOF;
  507. /* Format the CDB */
  508. rd10 = (FAR struct scsicmd_read10_s *)cbw->cdb;
  509. rd10->opcode = SCSI_CMD_READ10;
  510. usbhost_putbe32(rd10->lba, startsector);
  511. usbhost_putbe16(rd10->xfrlen, nsectors);
  512. usbhost_dumpcbw(cbw);
  513. }
  514. static inline void
  515. usbhost_writecbw(size_t startsector, uint16_t blocksize,
  516. unsigned int nsectors, FAR struct usbmsc_cbw_s *cbw)
  517. {
  518. FAR struct scsicmd_write10_s *wr10;
  519. /* Format the CBW */
  520. usbhost_putle32(cbw->datlen, blocksize * nsectors);
  521. cbw->cdblen = SCSICMD_WRITE10_SIZEOF;
  522. /* Format the CDB */
  523. wr10 = (FAR struct scsicmd_write10_s *)cbw->cdb;
  524. wr10->opcode = SCSI_CMD_WRITE10;
  525. usbhost_putbe32(wr10->lba, startsector);
  526. usbhost_putbe16(wr10->xfrlen, nsectors);
  527. usbhost_dumpcbw(cbw);
  528. }
  529. /****************************************************************************
  530. * Name: Command helpers
  531. *
  532. * Description:
  533. * The following functions are helper functions used to send commands.
  534. *
  535. * Input Parameters:
  536. * priv - A reference to the class instance.
  537. *
  538. * Returned Values:
  539. * None
  540. *
  541. ****************************************************************************/
  542. static inline int usbhost_maxlunreq(FAR struct usbhost_state_s *priv)
  543. {
  544. FAR struct usb_ctrlreq_s *req = (FAR struct usb_ctrlreq_s *)priv->tbuffer;
  545. FAR struct usbhost_hubport_s *hport;
  546. DEBUGASSERT(priv && priv->tbuffer);
  547. int ret;
  548. /* Request maximum logical unit number. NOTE: On an IN transaction, The
  549. * req and buffer pointers passed to DRVR_CTRLIN may refer to the same
  550. * allocated memory.
  551. */
  552. uinfo("Request maximum logical unit number\n");
  553. memset(req, 0, sizeof(struct usb_ctrlreq_s));
  554. req->type = USB_DIR_IN | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE;
  555. req->req = USBMSC_REQ_GETMAXLUN;
  556. usbhost_putle16(req->len, 1);
  557. DEBUGASSERT(priv->usbclass.hport);
  558. hport = priv->usbclass.hport;
  559. ret = DRVR_CTRLIN(hport->drvr, hport->ep0, req, priv->tbuffer);
  560. if (ret < 0)
  561. {
  562. /* Devices that do not support multiple LUNs may stall this command.
  563. * On a failure, a single LUN is assumed.
  564. */
  565. *(priv->tbuffer) = 0;
  566. }
  567. return OK;
  568. }
  569. static inline int usbhost_testunitready(FAR struct usbhost_state_s *priv)
  570. {
  571. FAR struct usbhost_hubport_s *hport;
  572. FAR struct usbmsc_cbw_s *cbw;
  573. ssize_t nbytes;
  574. DEBUGASSERT(priv->usbclass.hport);
  575. hport = priv->usbclass.hport;
  576. /* Initialize a CBW (re-using the allocated transfer buffer) */
  577. cbw = usbhost_cbwalloc(priv);
  578. if (!cbw)
  579. {
  580. uerr("ERROR: Failed to create CBW\n");
  581. return -ENOMEM;
  582. }
  583. /* Construct and send the CBW */
  584. usbhost_testunitreadycbw(cbw);
  585. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout,
  586. (FAR uint8_t *)cbw, USBMSC_CBW_SIZEOF);
  587. if (nbytes >= 0)
  588. {
  589. /* Receive the CSW */
  590. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkin,
  591. priv->tbuffer, USBMSC_CSW_SIZEOF);
  592. if (nbytes >= 0)
  593. {
  594. usbhost_dumpcsw((FAR struct usbmsc_csw_s *)priv->tbuffer);
  595. }
  596. }
  597. return nbytes < 0 ? (int)nbytes : OK;
  598. }
  599. static inline int usbhost_requestsense(FAR struct usbhost_state_s *priv)
  600. {
  601. FAR struct usbhost_hubport_s *hport;
  602. FAR struct usbmsc_cbw_s *cbw;
  603. ssize_t nbytes;
  604. DEBUGASSERT(priv->usbclass.hport);
  605. hport = priv->usbclass.hport;
  606. /* Initialize a CBW (re-using the allocated transfer buffer) */
  607. cbw = usbhost_cbwalloc(priv);
  608. if (!cbw)
  609. {
  610. uerr("ERROR: Failed to create CBW\n");
  611. return -ENOMEM;
  612. }
  613. /* Construct and send the CBW */
  614. usbhost_requestsensecbw(cbw);
  615. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout,
  616. (FAR uint8_t *)cbw, USBMSC_CBW_SIZEOF);
  617. if (nbytes >= 0)
  618. {
  619. /* Receive the sense data response */
  620. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkin,
  621. priv->tbuffer, SCSIRESP_FIXEDSENSEDATA_SIZEOF);
  622. if (nbytes >= 0)
  623. {
  624. /* Receive the CSW */
  625. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkin,
  626. priv->tbuffer, USBMSC_CSW_SIZEOF);
  627. if (nbytes >= 0)
  628. {
  629. usbhost_dumpcsw((FAR struct usbmsc_csw_s *)priv->tbuffer);
  630. }
  631. }
  632. }
  633. return nbytes < 0 ? (int)nbytes : OK;
  634. }
  635. static inline int usbhost_readcapacity(FAR struct usbhost_state_s *priv)
  636. {
  637. FAR struct usbhost_hubport_s *hport;
  638. FAR struct usbmsc_cbw_s *cbw;
  639. FAR struct scsiresp_readcapacity10_s *resp;
  640. ssize_t nbytes;
  641. DEBUGASSERT(priv->usbclass.hport);
  642. hport = priv->usbclass.hport;
  643. /* Initialize a CBW (re-using the allocated transfer buffer) */
  644. cbw = usbhost_cbwalloc(priv);
  645. if (!cbw)
  646. {
  647. uerr("ERROR: Failed to create CBW\n");
  648. return -ENOMEM;
  649. }
  650. /* Construct and send the CBW */
  651. usbhost_readcapacitycbw(cbw);
  652. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout,
  653. (FAR uint8_t *)cbw, USBMSC_CBW_SIZEOF);
  654. if (nbytes >= 0)
  655. {
  656. /* Receive the read capacity CBW IN response */
  657. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkin,
  658. priv->tbuffer, SCSIRESP_READCAPACITY10_SIZEOF);
  659. if (nbytes >= 0)
  660. {
  661. /* Save the capacity information */
  662. resp = (FAR struct scsiresp_readcapacity10_s *)priv->tbuffer;
  663. priv->nblocks = usbhost_getbe32(resp->lba) + 1;
  664. priv->blocksize = usbhost_getbe32(resp->blklen);
  665. /* Receive the CSW */
  666. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkin,
  667. priv->tbuffer, USBMSC_CSW_SIZEOF);
  668. if (nbytes >= 0)
  669. {
  670. usbhost_dumpcsw((FAR struct usbmsc_csw_s *)priv->tbuffer);
  671. }
  672. }
  673. }
  674. return nbytes < 0 ? (int)nbytes : OK;
  675. }
  676. static inline int usbhost_inquiry(FAR struct usbhost_state_s *priv)
  677. {
  678. FAR struct usbhost_hubport_s *hport;
  679. FAR struct usbmsc_cbw_s *cbw;
  680. ssize_t nbytes;
  681. DEBUGASSERT(priv->usbclass.hport);
  682. hport = priv->usbclass.hport;
  683. /* Initialize a CBW (re-using the allocated transfer buffer) */
  684. cbw = usbhost_cbwalloc(priv);
  685. if (!cbw)
  686. {
  687. uerr("ERROR: Failed to create CBW\n");
  688. return -ENOMEM;
  689. }
  690. /* Construct and send the CBW */
  691. usbhost_inquirycbw(cbw);
  692. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout,
  693. (FAR uint8_t *)cbw, USBMSC_CBW_SIZEOF);
  694. if (nbytes >= 0)
  695. {
  696. /* Receive the CBW IN response */
  697. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkin,
  698. priv->tbuffer, SCSIRESP_INQUIRY_SIZEOF);
  699. if (nbytes >= 0)
  700. {
  701. #if 0
  702. FAR struct scsiresp_inquiry_s *resp;
  703. /* TODO: If USB debug is enabled, dump the response data here */
  704. resp = (FAR struct scsiresp_inquiry_s *)priv->tbuffer;
  705. #endif
  706. /* Receive the CSW */
  707. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkin,
  708. priv->tbuffer, USBMSC_CSW_SIZEOF);
  709. if (nbytes >= 0)
  710. {
  711. usbhost_dumpcsw((FAR struct usbmsc_csw_s *)priv->tbuffer);
  712. }
  713. }
  714. }
  715. return nbytes < 0 ? (int)nbytes : OK;
  716. }
  717. /****************************************************************************
  718. * Name: usbhost_destroy
  719. *
  720. * Description:
  721. * The USB mass storage device has been disconnected and the reference count
  722. * on the USB host class instance has gone to 1.. Time to destroy the USB
  723. * host class instance.
  724. *
  725. * Input Parameters:
  726. * arg - A reference to the class instance to be destroyed.
  727. *
  728. * Returned Values:
  729. * None
  730. *
  731. ****************************************************************************/
  732. static void usbhost_destroy(FAR void *arg)
  733. {
  734. FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)arg;
  735. FAR struct usbhost_hubport_s *hport;
  736. char devname[DEV_NAMELEN];
  737. DEBUGASSERT(priv != NULL && priv->usbclass.hport != NULL);
  738. hport = priv->usbclass.hport;
  739. uinfo("crefs: %d\n", priv->crefs);
  740. /* Unregister the block driver */
  741. usbhost_mkdevname(priv, devname);
  742. (void)unregister_blockdriver(devname);
  743. /* Release the device name used by this connection */
  744. usbhost_freedevno(priv);
  745. /* Free the bulk endpoints */
  746. if (priv->bulkout)
  747. {
  748. DRVR_EPFREE(hport->drvr, priv->bulkout);
  749. }
  750. if (priv->bulkin)
  751. {
  752. DRVR_EPFREE(hport->drvr, priv->bulkin);
  753. }
  754. /* Free any transfer buffers */
  755. usbhost_tfree(priv);
  756. /* Destroy the semaphores */
  757. sem_destroy(&priv->exclsem);
  758. /* Disconnect the USB host device */
  759. DRVR_DISCONNECT(hport->drvr, hport);
  760. /* Free the function address assigned to this device */
  761. usbhost_devaddr_destroy(hport, hport->funcaddr);
  762. hport->funcaddr = 0;
  763. /* And free the class instance. */
  764. usbhost_freeclass(priv);
  765. }
  766. /****************************************************************************
  767. * Name: usbhost_cfgdesc
  768. *
  769. * Description:
  770. * This function implements the connect() method of struct
  771. * usbhost_class_s. This method is a callback into the class
  772. * implementation. It is used to provide the device's configuration
  773. * descriptor to the class so that the class may initialize properly
  774. *
  775. * Input Parameters:
  776. * priv - The USB host class instance.
  777. * configdesc - A pointer to a uint8_t buffer container the configuration
  778. * descriptor.
  779. * desclen - The length in bytes of the configuration descriptor.
  780. *
  781. * Returned Values:
  782. * On success, zero (OK) is returned. On a failure, a negated errno value is
  783. * returned indicating the nature of the failure
  784. *
  785. * Assumptions:
  786. * This function will *not* be called from an interrupt handler.
  787. *
  788. ****************************************************************************/
  789. static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
  790. FAR const uint8_t *configdesc, int desclen)
  791. {
  792. FAR struct usbhost_hubport_s *hport;
  793. FAR struct usb_cfgdesc_s *cfgdesc;
  794. FAR struct usb_desc_s *desc;
  795. FAR struct usbhost_epdesc_s bindesc;
  796. FAR struct usbhost_epdesc_s boutdesc;
  797. int remaining;
  798. uint8_t found = 0;
  799. int ret;
  800. DEBUGASSERT(priv != NULL && priv->usbclass.hport &&
  801. configdesc != NULL && desclen >= sizeof(struct usb_cfgdesc_s));
  802. hport = priv->usbclass.hport;
  803. /* Keep the compiler from complaining about uninitialized variables */
  804. memset(&bindesc, 0, sizeof(struct usbhost_epdesc_s));
  805. memset(&boutdesc, 0, sizeof(struct usbhost_epdesc_s));
  806. /* Verify that we were passed a configuration descriptor */
  807. cfgdesc = (FAR struct usb_cfgdesc_s *)configdesc;
  808. if (cfgdesc->type != USB_DESC_TYPE_CONFIG)
  809. {
  810. return -EINVAL;
  811. }
  812. /* Get the total length of the configuration descriptor (little endian).
  813. * It might be a good check to get the number of interfaces here too.
  814. */
  815. remaining = (int)usbhost_getle16(cfgdesc->totallen);
  816. /* Skip to the next entry descriptor */
  817. configdesc += cfgdesc->len;
  818. remaining -= cfgdesc->len;
  819. /* Loop where there are more dscriptors to examine */
  820. while (remaining >= sizeof(struct usb_desc_s))
  821. {
  822. /* What is the next descriptor? */
  823. desc = (FAR struct usb_desc_s *)configdesc;
  824. switch (desc->type)
  825. {
  826. /* Interface descriptor. We really should get the number of endpoints
  827. * from this descriptor too.
  828. */
  829. case USB_DESC_TYPE_INTERFACE:
  830. {
  831. FAR struct usb_ifdesc_s *ifdesc = (FAR struct usb_ifdesc_s *)configdesc;
  832. uinfo("Interface descriptor\n");
  833. DEBUGASSERT(remaining >= USB_SIZEOF_IFDESC);
  834. /* Save the interface number and mark ONLY the interface found */
  835. priv->ifno = ifdesc->ifno;
  836. found = USBHOST_IFFOUND;
  837. }
  838. break;
  839. /* Endpoint descriptor. We expect two bulk endpoints, an IN and an
  840. * OUT.
  841. */
  842. case USB_DESC_TYPE_ENDPOINT:
  843. {
  844. FAR struct usb_epdesc_s *epdesc = (FAR struct usb_epdesc_s *)configdesc;
  845. uinfo("Endpoint descriptor\n");
  846. DEBUGASSERT(remaining >= USB_SIZEOF_EPDESC);
  847. /* Check for a bulk endpoint. We only support the bulk-only
  848. * protocol so I suppose anything else should really be an error.
  849. */
  850. if ((epdesc->attr & USB_EP_ATTR_XFERTYPE_MASK) == USB_EP_ATTR_XFER_BULK)
  851. {
  852. /* Yes.. it is a bulk endpoint. IN or OUT? */
  853. if (USB_ISEPOUT(epdesc->addr))
  854. {
  855. /* It is an OUT bulk endpoint. There should be only one
  856. * bulk OUT endpoint.
  857. */
  858. if ((found & USBHOST_BOUTFOUND) != 0)
  859. {
  860. /* Oops.. more than one endpoint. We don't know
  861. * what to do with this.
  862. */
  863. return -EINVAL;
  864. }
  865. found |= USBHOST_BOUTFOUND;
  866. /* Save the bulk OUT endpoint information */
  867. boutdesc.hport = hport;
  868. boutdesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
  869. boutdesc.in = false;
  870. boutdesc.xfrtype = USB_EP_ATTR_XFER_BULK;
  871. boutdesc.interval = epdesc->interval;
  872. boutdesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
  873. uinfo("Bulk OUT EP addr:%d mxpacketsize:%d\n",
  874. boutdesc.addr, boutdesc.mxpacketsize);
  875. }
  876. else
  877. {
  878. /* It is an IN bulk endpoint. There should be only one
  879. * bulk IN endpoint.
  880. */
  881. if ((found & USBHOST_BINFOUND) != 0)
  882. {
  883. /* Oops.. more than one endpoint. We don't know
  884. * what to do with this.
  885. */
  886. return -EINVAL;
  887. }
  888. found |= USBHOST_BINFOUND;
  889. /* Save the bulk IN endpoint information */
  890. bindesc.hport = hport;
  891. bindesc.addr = epdesc->addr & USB_EP_ADDR_NUMBER_MASK;
  892. bindesc.in = 1;
  893. bindesc.xfrtype = USB_EP_ATTR_XFER_BULK;
  894. bindesc.interval = epdesc->interval;
  895. bindesc.mxpacketsize = usbhost_getle16(epdesc->mxpacketsize);
  896. uinfo("Bulk IN EP addr:%d mxpacketsize:%d\n",
  897. bindesc.addr, bindesc.mxpacketsize);
  898. }
  899. }
  900. }
  901. break;
  902. /* Other descriptors are just ignored for now */
  903. default:
  904. break;
  905. }
  906. /* If we found everything we need with this interface, then break out
  907. * of the loop early.
  908. */
  909. if (found == USBHOST_ALLFOUND)
  910. {
  911. break;
  912. }
  913. /* Increment the address of the next descriptor */
  914. configdesc += desc->len;
  915. remaining -= desc->len;
  916. }
  917. /* Sanity checking... did we find all of things that we need? Hmmm.. I wonder..
  918. * can we work read-only or write-only if only one bulk endpoint found?
  919. */
  920. if (found != USBHOST_ALLFOUND)
  921. {
  922. uerr("ERROR: Found IF:%s BIN:%s BOUT:%s\n",
  923. (found & USBHOST_IFFOUND) != 0 ? "YES" : "NO",
  924. (found & USBHOST_BINFOUND) != 0 ? "YES" : "NO",
  925. (found & USBHOST_BOUTFOUND) != 0 ? "YES" : "NO");
  926. return -EINVAL;
  927. }
  928. /* We are good... Allocate the endpoints */
  929. ret = DRVR_EPALLOC(hport->drvr, &boutdesc, &priv->bulkout);
  930. if (ret < 0)
  931. {
  932. uerr("ERROR: Failed to allocate Bulk OUT endpoint\n");
  933. return ret;
  934. }
  935. ret = DRVR_EPALLOC(hport->drvr, &bindesc, &priv->bulkin);
  936. if (ret < 0)
  937. {
  938. uerr("ERROR: Failed to allocate Bulk IN endpoint\n");
  939. (void)DRVR_EPFREE(hport->drvr, priv->bulkout);
  940. return ret;
  941. }
  942. uinfo("Endpoints allocated\n");
  943. return OK;
  944. }
  945. /****************************************************************************
  946. * Name: usbhost_initvolume
  947. *
  948. * Description:
  949. * The USB mass storage device has been successfully connected. This
  950. * completes the initialization operations. It is first called after the
  951. * configuration descriptor has been received.
  952. *
  953. * This function is called from the connect() method. This function always
  954. * executes on the thread of the caller of connect().
  955. *
  956. * Input Parameters:
  957. * priv - A reference to the class instance.
  958. *
  959. * Returned Values:
  960. * None
  961. *
  962. ****************************************************************************/
  963. static inline int usbhost_initvolume(FAR struct usbhost_state_s *priv)
  964. {
  965. FAR struct usbmsc_csw_s *csw;
  966. unsigned int retries;
  967. int ret = OK;
  968. DEBUGASSERT(priv != NULL);
  969. /* Set aside a transfer buffer for exclusive use by the mass storage driver */
  970. ret = usbhost_talloc(priv);
  971. if (ret < 0)
  972. {
  973. uerr("ERROR: Failed to allocate transfer buffer\n");
  974. return ret;
  975. }
  976. /* Increment the reference count. This will prevent usbhost_destroy() from
  977. * being called asynchronously if the device is removed.
  978. */
  979. priv->crefs++;
  980. DEBUGASSERT(priv->crefs == 2);
  981. /* Request the maximum logical unit number */
  982. uinfo("Get max LUN\n");
  983. ret = usbhost_maxlunreq(priv);
  984. for (retries = 0; retries < USBHOST_MAX_RETRIES /* && ret >= 0 */; retries++)
  985. {
  986. uinfo("Test unit ready, retries=%d\n", retries);
  987. /* Wait just a bit */
  988. usleep(USBHOST_RETRY_USEC);
  989. /* Send TESTUNITREADY to see if the unit is ready. The most likely error
  990. * error that can occur here is a a stall which simply means that the
  991. * the device is not yet able to respond.
  992. */
  993. ret = usbhost_testunitready(priv);
  994. if (ret >= 0)
  995. {
  996. /* Is the unit is ready */
  997. csw = (FAR struct usbmsc_csw_s *)priv->tbuffer;
  998. if (csw->status == 0)
  999. {
  1000. /* Yes... break out of the loop */
  1001. break;
  1002. }
  1003. /* No.. Request mode sense information. The REQUEST SENSE command
  1004. * is sent only "to clear interlocked unit attention conditions."
  1005. * The returned status is ignored here.
  1006. */
  1007. uinfo("Request sense\n");
  1008. ret = usbhost_requestsense(priv);
  1009. }
  1010. /* It is acceptable for a mass storage device to respond to the
  1011. * Test Unit Ready and Request Sense commands with a stall if it is
  1012. * unable to respond. But other failures mean that something is
  1013. * wrong and a device reset is in order. The transfer functions will
  1014. * return -EPERM if the transfer failed due to a stall.
  1015. */
  1016. if (ret < 0 && ret != -EPERM)
  1017. {
  1018. uerr("ERROR: DRVR_TRANSFER returned: %d\n", ret);
  1019. break;
  1020. }
  1021. }
  1022. /* Did the unit become ready? Did an error occur? Or did we time out? */
  1023. if (retries >= USBHOST_MAX_RETRIES)
  1024. {
  1025. uerr("ERROR: Timeout!\n");
  1026. ret = -ETIMEDOUT;
  1027. }
  1028. if (ret >= 0)
  1029. {
  1030. /* Get the capacity of the volume */
  1031. uinfo("Read capacity\n");
  1032. ret = usbhost_readcapacity(priv);
  1033. if (ret >= 0)
  1034. {
  1035. /* Check the CSW for errors */
  1036. csw = (FAR struct usbmsc_csw_s *)priv->tbuffer;
  1037. if (csw->status != 0)
  1038. {
  1039. uerr("ERROR: CSW status error: %d\n", csw->status);
  1040. ret = -ENODEV;
  1041. }
  1042. }
  1043. }
  1044. /* Get information about the volume */
  1045. if (ret >= 0)
  1046. {
  1047. /* Inquiry */
  1048. uinfo("Inquiry\n");
  1049. ret = usbhost_inquiry(priv);
  1050. if (ret >= 0)
  1051. {
  1052. /* Check the CSW for errors */
  1053. csw = (FAR struct usbmsc_csw_s *)priv->tbuffer;
  1054. if (csw->status != 0)
  1055. {
  1056. uerr("ERROR: CSW status error: %d\n", csw->status);
  1057. ret = -ENODEV;
  1058. }
  1059. }
  1060. }
  1061. /* Register the block driver */
  1062. if (ret >= 0)
  1063. {
  1064. char devname[DEV_NAMELEN];
  1065. uinfo("Register block driver\n");
  1066. usbhost_mkdevname(priv, devname);
  1067. ret = register_blockdriver(devname, &g_bops, 0, priv);
  1068. }
  1069. /* Decrement the reference count. We incremented the reference count
  1070. * above so that usbhost_destroy() could not be called. We now have to
  1071. * be concerned about asynchronous modification of crefs because the block
  1072. * driver has been registerd.
  1073. */
  1074. usbhost_takesem(&priv->exclsem);
  1075. DEBUGASSERT(priv->crefs >= 2);
  1076. /* Decrement the reference count */
  1077. priv->crefs--;
  1078. /* Check if we successfully initialized. If so, handle a corner case
  1079. * where (1) open() has been called so the reference count was > 2, but
  1080. * the device has been disconnected. In this case, the class instance
  1081. * needs to persist until close()
  1082. * is called.
  1083. */
  1084. if (ret >= 0 && priv->crefs <= 1 && priv->disconnected)
  1085. {
  1086. /* The will cause the enumeration logic to disconnect the class
  1087. * driver.
  1088. */
  1089. ret = -ENODEV;
  1090. }
  1091. /* Release the semaphore... there is a race condition here.
  1092. * Decrementing the reference count and releasing the semaphore
  1093. * allows usbhost_destroy() to execute (on the worker thread);
  1094. * the class driver instance could get destroyed before we are
  1095. * ready to handle it!
  1096. */
  1097. usbhost_givesem(&priv->exclsem);
  1098. return ret;
  1099. }
  1100. /****************************************************************************
  1101. * Name: usbhost_getle16
  1102. *
  1103. * Description:
  1104. * Get a (possibly unaligned) 16-bit little endian value.
  1105. *
  1106. * Input Parameters:
  1107. * val - A pointer to the first byte of the little endian value.
  1108. *
  1109. * Returned Values:
  1110. * A uint16_t representing the whole 16-bit integer value
  1111. *
  1112. ****************************************************************************/
  1113. static inline uint16_t usbhost_getle16(const uint8_t *val)
  1114. {
  1115. return (uint16_t)val[1] << 8 | (uint16_t)val[0];
  1116. }
  1117. /****************************************************************************
  1118. * Name: usbhost_getbe16
  1119. *
  1120. * Description:
  1121. * Get a (possibly unaligned) 16-bit big endian value.
  1122. *
  1123. * Input Parameters:
  1124. * val - A pointer to the first byte of the big endian value.
  1125. *
  1126. * Returned Values:
  1127. * A uint16_t representing the whole 16-bit integer value
  1128. *
  1129. ****************************************************************************/
  1130. static inline uint16_t usbhost_getbe16(const uint8_t *val)
  1131. {
  1132. return (uint16_t)val[0] << 8 | (uint16_t)val[1];
  1133. }
  1134. /****************************************************************************
  1135. * Name: usbhost_putle16
  1136. *
  1137. * Description:
  1138. * Put a (possibly unaligned) 16-bit little endian value.
  1139. *
  1140. * Input Parameters:
  1141. * dest - A pointer to the first byte to save the little endian value.
  1142. * val - The 16-bit value to be saved.
  1143. *
  1144. * Returned Values:
  1145. * None
  1146. *
  1147. ****************************************************************************/
  1148. static void usbhost_putle16(uint8_t *dest, uint16_t val)
  1149. {
  1150. dest[0] = val & 0xff; /* Little endian means LS byte first in byte stream */
  1151. dest[1] = val >> 8;
  1152. }
  1153. /****************************************************************************
  1154. * Name: usbhost_putbe16
  1155. *
  1156. * Description:
  1157. * Put a (possibly unaligned) 16-bit big endian value.
  1158. *
  1159. * Input Parameters:
  1160. * dest - A pointer to the first byte to save the big endian value.
  1161. * val - The 16-bit value to be saved.
  1162. *
  1163. * Returned Values:
  1164. * None
  1165. *
  1166. ****************************************************************************/
  1167. static void usbhost_putbe16(uint8_t *dest, uint16_t val)
  1168. {
  1169. dest[0] = val >> 8; /* Big endian means MS byte first in byte stream */
  1170. dest[1] = val & 0xff;
  1171. }
  1172. /****************************************************************************
  1173. * Name: usbhost_getle32
  1174. *
  1175. * Description:
  1176. * Get a (possibly unaligned) 32-bit little endian value.
  1177. *
  1178. * Input Parameters:
  1179. * dest - A pointer to the first byte to save the big endian value.
  1180. * val - The 32-bit value to be saved.
  1181. *
  1182. * Returned Values:
  1183. * None
  1184. *
  1185. ****************************************************************************/
  1186. static inline uint32_t usbhost_getle32(const uint8_t *val)
  1187. {
  1188. /* Little endian means LS halfword first in byte stream */
  1189. return (uint32_t)usbhost_getle16(&val[2]) << 16 | (uint32_t)usbhost_getle16(val);
  1190. }
  1191. /****************************************************************************
  1192. * Name: usbhost_getbe32
  1193. *
  1194. * Description:
  1195. * Get a (possibly unaligned) 32-bit big endian value.
  1196. *
  1197. * Input Parameters:
  1198. * dest - A pointer to the first byte to save the big endian value.
  1199. * val - The 32-bit value to be saved.
  1200. *
  1201. * Returned Values:
  1202. * None
  1203. *
  1204. ****************************************************************************/
  1205. static inline uint32_t usbhost_getbe32(const uint8_t *val)
  1206. {
  1207. /* Big endian means MS halfword first in byte stream */
  1208. return (uint32_t)usbhost_getbe16(val) << 16 | (uint32_t)usbhost_getbe16(&val[2]);
  1209. }
  1210. /****************************************************************************
  1211. * Name: usbhost_putle32
  1212. *
  1213. * Description:
  1214. * Put a (possibly unaligned) 32-bit little endian value.
  1215. *
  1216. * Input Parameters:
  1217. * dest - A pointer to the first byte to save the little endian value.
  1218. * val - The 32-bit value to be saved.
  1219. *
  1220. * Returned Values:
  1221. * None
  1222. *
  1223. ****************************************************************************/
  1224. static void usbhost_putle32(uint8_t *dest, uint32_t val)
  1225. {
  1226. /* Little endian means LS halfword first in byte stream */
  1227. usbhost_putle16(dest, (uint16_t)(val & 0xffff));
  1228. usbhost_putle16(dest+2, (uint16_t)(val >> 16));
  1229. }
  1230. /****************************************************************************
  1231. * Name: usbhost_putbe32
  1232. *
  1233. * Description:
  1234. * Put a (possibly unaligned) 32-bit big endian value.
  1235. *
  1236. * Input Parameters:
  1237. * dest - A pointer to the first byte to save the big endian value.
  1238. * val - The 32-bit value to be saved.
  1239. *
  1240. * Returned Values:
  1241. * None
  1242. *
  1243. ****************************************************************************/
  1244. static void usbhost_putbe32(uint8_t *dest, uint32_t val)
  1245. {
  1246. /* Big endian means MS halfword first in byte stream */
  1247. usbhost_putbe16(dest, (uint16_t)(val >> 16));
  1248. usbhost_putbe16(dest+2, (uint16_t)(val & 0xffff));
  1249. }
  1250. /****************************************************************************
  1251. * Name: usbhost_talloc
  1252. *
  1253. * Description:
  1254. * Allocate transfer buffer memory.
  1255. *
  1256. * Input Parameters:
  1257. * priv - A reference to the class instance.
  1258. *
  1259. * Returned Values:
  1260. * On sucess, zero (OK) is returned. On failure, an negated errno value
  1261. * is returned to indicate the nature of the failure.
  1262. *
  1263. ****************************************************************************/
  1264. static inline int usbhost_talloc(FAR struct usbhost_state_s *priv)
  1265. {
  1266. FAR struct usbhost_hubport_s *hport;
  1267. DEBUGASSERT(priv != NULL && priv->usbclass.hport != NULL &&
  1268. priv->tbuffer == NULL);
  1269. hport = priv->usbclass.hport;
  1270. return DRVR_ALLOC(hport->drvr, &priv->tbuffer, &priv->tbuflen);
  1271. }
  1272. /****************************************************************************
  1273. * Name: usbhost_tfree
  1274. *
  1275. * Description:
  1276. * Free transfer buffer memory.
  1277. *
  1278. * Input Parameters:
  1279. * priv - A reference to the class instance.
  1280. *
  1281. * Returned Values:
  1282. * On sucess, zero (OK) is returned. On failure, an negated errno value
  1283. * is returned to indicate the nature of the failure.
  1284. *
  1285. ****************************************************************************/
  1286. static inline int usbhost_tfree(FAR struct usbhost_state_s *priv)
  1287. {
  1288. FAR struct usbhost_hubport_s *hport;
  1289. int result = OK;
  1290. DEBUGASSERT(priv != NULL && priv->usbclass.hport != NULL);
  1291. if (priv->tbuffer)
  1292. {
  1293. hport = priv->usbclass.hport;
  1294. result = DRVR_FREE(hport->drvr, priv->tbuffer);
  1295. priv->tbuffer = NULL;
  1296. priv->tbuflen = 0;
  1297. }
  1298. return result;
  1299. }
  1300. /****************************************************************************
  1301. * Name: usbhost_cbwalloc
  1302. *
  1303. * Description:
  1304. * Initialize a CBW (re-using the allocated transfer buffer). Upon
  1305. * successful return, the CBW is cleared and has the CBW signature in place.
  1306. *
  1307. * Input Parameters:
  1308. * priv - A reference to the class instance.
  1309. *
  1310. * Returned Values:
  1311. * None
  1312. *
  1313. ****************************************************************************/
  1314. static FAR struct usbmsc_cbw_s *usbhost_cbwalloc(FAR struct usbhost_state_s *priv)
  1315. {
  1316. FAR struct usbmsc_cbw_s *cbw = NULL;
  1317. DEBUGASSERT(priv->tbuffer && priv->tbuflen >= sizeof(struct usbmsc_cbw_s));
  1318. /* Initialize the CBW sructure */
  1319. cbw = (FAR struct usbmsc_cbw_s *)priv->tbuffer;
  1320. memset(cbw, 0, sizeof(struct usbmsc_cbw_s));
  1321. usbhost_putle32(cbw->signature, USBMSC_CBW_SIGNATURE);
  1322. return cbw;
  1323. }
  1324. /****************************************************************************
  1325. * struct usbhost_registry_s methods
  1326. ****************************************************************************/
  1327. /****************************************************************************
  1328. * Name: usbhost_create
  1329. *
  1330. * Description:
  1331. * This function implements the create() method of struct usbhost_registry_s.
  1332. * The create() method is a callback into the class implementation. It is
  1333. * used to (1) create a new instance of the USB host class state and to (2)
  1334. * bind a USB host driver "session" to the class instance. Use of this
  1335. * create() method will support environments where there may be multiple
  1336. * USB ports and multiple USB devices simultaneously connected.
  1337. *
  1338. * Input Parameters:
  1339. * hport - The hub port that manages the new class instance.
  1340. * id - In the case where the device supports multiple base classes,
  1341. * subclasses, or protocols, this specifies which to configure for.
  1342. *
  1343. * Returned Values:
  1344. * On success, this function will return a non-NULL instance of struct
  1345. * usbhost_class_s that can be used by the USB host driver to communicate
  1346. * with the USB host class. NULL is returned on failure; this function
  1347. * will fail only if the hport input parameter is NULL or if there are
  1348. * insufficient resources to create another USB host class instance.
  1349. *
  1350. ****************************************************************************/
  1351. static FAR struct usbhost_class_s *
  1352. usbhost_create(FAR struct usbhost_hubport_s *hport,
  1353. FAR const struct usbhost_id_s *id)
  1354. {
  1355. FAR struct usbhost_state_s *priv;
  1356. /* Allocate a USB host mass storage class instance */
  1357. priv = usbhost_allocclass();
  1358. if (priv)
  1359. {
  1360. /* Initialize the allocated storage class instance */
  1361. memset(priv, 0, sizeof(struct usbhost_state_s));
  1362. /* Assign a device number to this class instance */
  1363. if (usbhost_allocdevno(priv) == OK)
  1364. {
  1365. /* Initialize class method function pointers */
  1366. priv->usbclass.hport = hport;
  1367. priv->usbclass.connect = usbhost_connect;
  1368. priv->usbclass.disconnected = usbhost_disconnected;
  1369. /* The initial reference count is 1... One reference is held by the driver */
  1370. priv->crefs = 1;
  1371. /* Initialize semaphores (this works okay in the interrupt context) */
  1372. sem_init(&priv->exclsem, 0, 1);
  1373. /* NOTE: We do not yet know the geometry of the USB mass storage device */
  1374. /* Return the instance of the USB mass storage class */
  1375. return &priv->usbclass;
  1376. }
  1377. }
  1378. /* An error occurred. Free the allocation and return NULL on all failures */
  1379. if (priv)
  1380. {
  1381. usbhost_freeclass(priv);
  1382. }
  1383. return NULL;
  1384. }
  1385. /****************************************************************************
  1386. * struct usbhost_class_s methods
  1387. ****************************************************************************/
  1388. /****************************************************************************
  1389. * Name: usbhost_connect
  1390. *
  1391. * Description:
  1392. * This function implements the connect() method of struct
  1393. * usbhost_class_s. This method is a callback into the class
  1394. * implementation. It is used to provide the device's configuration
  1395. * descriptor to the class so that the class may initialize properly
  1396. *
  1397. * Input Parameters:
  1398. * usbclass - The USB host class entry previously obtained from a call to
  1399. * create().
  1400. * configdesc - A pointer to a uint8_t buffer container the configuration
  1401. * descriptor.
  1402. * desclen - The length in bytes of the configuration descriptor.
  1403. *
  1404. * Returned Values:
  1405. * On success, zero (OK) is returned. On a failure, a negated errno value is
  1406. * returned indicating the nature of the failure
  1407. *
  1408. * NOTE that the class instance remains valid upon return with a failure. It is
  1409. * the responsibility of the higher level enumeration logic to call
  1410. * CLASS_DISCONNECTED to free up the class driver resources.
  1411. *
  1412. * Assumptions:
  1413. * - This function will *not* be called from an interrupt handler.
  1414. * - If this function returns an error, the USB host controller driver
  1415. * must call to DISCONNECTED method to recover from the error
  1416. *
  1417. ****************************************************************************/
  1418. static int usbhost_connect(FAR struct usbhost_class_s *usbclass,
  1419. FAR const uint8_t *configdesc, int desclen)
  1420. {
  1421. FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)usbclass;
  1422. int ret;
  1423. DEBUGASSERT(priv != NULL &&
  1424. configdesc != NULL &&
  1425. desclen >= sizeof(struct usb_cfgdesc_s));
  1426. /* Parse the configuration descriptor to get the bulk I/O endpoints */
  1427. ret = usbhost_cfgdesc(priv, configdesc, desclen);
  1428. if (ret < 0)
  1429. {
  1430. uerr("ERROR: usbhost_cfgdesc() failed: %d\n", ret);
  1431. }
  1432. else
  1433. {
  1434. /* Now configure the LUNs and register the block driver(s) */
  1435. ret = usbhost_initvolume(priv);
  1436. if (ret < 0)
  1437. {
  1438. uerr("ERROR: usbhost_initvolume() failed: %d\n", ret);
  1439. }
  1440. }
  1441. return ret;
  1442. }
  1443. /****************************************************************************
  1444. * Name: usbhost_disconnected
  1445. *
  1446. * Description:
  1447. * This function implements the disconnected() method of struct
  1448. * usbhost_class_s. This method is a callback into the class
  1449. * implementation. It is used to inform the class that the USB device has
  1450. * been disconnected.
  1451. *
  1452. * Input Parameters:
  1453. * usbclass - The USB host class entry previously obtained from a call to
  1454. * create().
  1455. *
  1456. * Returned Values:
  1457. * On success, zero (OK) is returned. On a failure, a negated errno value
  1458. * is returned indicating the nature of the failure
  1459. *
  1460. * Assumptions:
  1461. * This function may be called from an interrupt handler.
  1462. *
  1463. ****************************************************************************/
  1464. static int usbhost_disconnected(struct usbhost_class_s *usbclass)
  1465. {
  1466. FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)usbclass;
  1467. irqstate_t flags;
  1468. DEBUGASSERT(priv != NULL);
  1469. /* Set an indication to any users of the mass storage device that the device
  1470. * is no longer available.
  1471. */
  1472. flags = enter_critical_section();
  1473. priv->disconnected = true;
  1474. /* Now check the number of references on the class instance. If it is one,
  1475. * then we can free the class instance now. Otherwise, we will have to
  1476. * wait until the holders of the references free them by closing the
  1477. * block driver.
  1478. */
  1479. uinfo("crefs: %d\n", priv->crefs);
  1480. if (priv->crefs == 1)
  1481. {
  1482. /* Destroy the class instance. If we are executing from an interrupt
  1483. * handler, then defer the destruction to the worker thread.
  1484. * Otherwise, destroy the instance now.
  1485. */
  1486. if (up_interrupt_context())
  1487. {
  1488. /* Destroy the instance on the worker thread. */
  1489. uinfo("Queuing destruction: worker %p->%p\n", priv->work.worker, usbhost_destroy);
  1490. DEBUGASSERT(priv->work.worker == NULL);
  1491. (void)work_queue(HPWORK, &priv->work, usbhost_destroy, priv, 0);
  1492. }
  1493. else
  1494. {
  1495. /* Do the work now */
  1496. usbhost_destroy(priv);
  1497. }
  1498. }
  1499. leave_critical_section(flags);
  1500. return OK;
  1501. }
  1502. /****************************************************************************
  1503. * struct block_operations methods
  1504. ****************************************************************************/
  1505. /****************************************************************************
  1506. * Name: usbhost_open
  1507. *
  1508. * Description: Open the block device
  1509. *
  1510. ****************************************************************************/
  1511. static int usbhost_open(FAR struct inode *inode)
  1512. {
  1513. FAR struct usbhost_state_s *priv;
  1514. irqstate_t flags;
  1515. int ret;
  1516. uinfo("Entry\n");
  1517. DEBUGASSERT(inode && inode->i_private);
  1518. priv = (FAR struct usbhost_state_s *)inode->i_private;
  1519. /* Make sure that we have exclusive access to the private data structure */
  1520. DEBUGASSERT(priv->crefs > 0 && priv->crefs < USBHOST_MAX_CREFS);
  1521. usbhost_takesem(&priv->exclsem);
  1522. /* Check if the mass storage device is still connected. We need to disable
  1523. * interrupts momentarily to assure that there are no asynchronous disconnect
  1524. * events.
  1525. */
  1526. flags = enter_critical_section();
  1527. if (priv->disconnected)
  1528. {
  1529. /* No... the block driver is no longer bound to the class. That means that
  1530. * the USB storage device is no longer connected. Refuse any further
  1531. * attempts to open the driver.
  1532. */
  1533. ret = -ENODEV;
  1534. }
  1535. else
  1536. {
  1537. /* Otherwise, just increment the reference count on the driver */
  1538. priv->crefs++;
  1539. ret = OK;
  1540. }
  1541. leave_critical_section(flags);
  1542. usbhost_givesem(&priv->exclsem);
  1543. return ret;
  1544. }
  1545. /****************************************************************************
  1546. * Name: usbhost_close
  1547. *
  1548. * Description: close the block device
  1549. *
  1550. ****************************************************************************/
  1551. static int usbhost_close(FAR struct inode *inode)
  1552. {
  1553. FAR struct usbhost_state_s *priv;
  1554. irqstate_t flags;
  1555. uinfo("Entry\n");
  1556. DEBUGASSERT(inode && inode->i_private);
  1557. priv = (FAR struct usbhost_state_s *)inode->i_private;
  1558. /* Decrement the reference count on the block driver */
  1559. DEBUGASSERT(priv->crefs > 1);
  1560. usbhost_takesem(&priv->exclsem);
  1561. priv->crefs--;
  1562. /* Release the semaphore. The following operations when crefs == 1 are
  1563. * safe because we know that there is no outstanding open references to
  1564. * the block driver.
  1565. */
  1566. usbhost_givesem(&priv->exclsem);
  1567. /* We need to disable interrupts momentarily to assure that there are
  1568. * no asynchronous disconnect events.
  1569. */
  1570. flags = enter_critical_section();
  1571. /* Check if the USB mass storage device is still connected. If the
  1572. * storage device is not connected and the reference count just
  1573. * decremented to one, then unregister the block driver and free
  1574. * the class instance.
  1575. */
  1576. if (priv->crefs <= 1 && priv->disconnected)
  1577. {
  1578. /* Destroy the class instance */
  1579. DEBUGASSERT(priv->crefs == 1);
  1580. usbhost_destroy(priv);
  1581. }
  1582. leave_critical_section(flags);
  1583. return OK;
  1584. }
  1585. /****************************************************************************
  1586. * Name: usbhost_read
  1587. *
  1588. * Description:
  1589. * Read the specified numer of sectors from the read-ahead buffer or from
  1590. * the physical device.
  1591. *
  1592. ****************************************************************************/
  1593. static ssize_t usbhost_read(FAR struct inode *inode, unsigned char *buffer,
  1594. size_t startsector, unsigned int nsectors)
  1595. {
  1596. FAR struct usbhost_state_s *priv;
  1597. FAR struct usbhost_hubport_s *hport;
  1598. ssize_t nbytes = 0;
  1599. DEBUGASSERT(inode && inode->i_private);
  1600. priv = (FAR struct usbhost_state_s *)inode->i_private;
  1601. DEBUGASSERT(priv->usbclass.hport);
  1602. hport = priv->usbclass.hport;
  1603. uinfo("startsector: %d nsectors: %d sectorsize: %d\n",
  1604. startsector, nsectors, priv->blocksize);
  1605. /* Check if the mass storage device is still connected */
  1606. if (priv->disconnected)
  1607. {
  1608. /* No... the block driver is no longer bound to the class. That means
  1609. * that the USB storage device is no longer connected. Refuse any
  1610. * attempt to read from the device.
  1611. */
  1612. nbytes = -ENODEV;
  1613. }
  1614. else if (nsectors > 0)
  1615. {
  1616. FAR struct usbmsc_cbw_s *cbw;
  1617. usbhost_takesem(&priv->exclsem);
  1618. /* Assume allocation failure */
  1619. nbytes = -ENOMEM;
  1620. /* Initialize a CBW (re-using the allocated transfer buffer) */
  1621. cbw = usbhost_cbwalloc(priv);
  1622. if (cbw)
  1623. {
  1624. /* Loop in the event that EAGAIN is returned (mean that the
  1625. * transaction was NAKed and we should try again.
  1626. */
  1627. do
  1628. {
  1629. /* Assume some device failure */
  1630. nbytes = -ENODEV;
  1631. /* Construct and send the CBW */
  1632. usbhost_readcbw(startsector, priv->blocksize, nsectors, cbw);
  1633. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout,
  1634. (FAR uint8_t *)cbw, USBMSC_CBW_SIZEOF);
  1635. if (nbytes >= 0)
  1636. {
  1637. /* Receive the user data */
  1638. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkin,
  1639. buffer, priv->blocksize * nsectors);
  1640. if (nbytes >= 0)
  1641. {
  1642. /* Receive the CSW */
  1643. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkin,
  1644. priv->tbuffer, USBMSC_CSW_SIZEOF);
  1645. if (nbytes >= 0)
  1646. {
  1647. FAR struct usbmsc_csw_s *csw;
  1648. /* Check the CSW status */
  1649. csw = (FAR struct usbmsc_csw_s *)priv->tbuffer;
  1650. if (csw->status != 0)
  1651. {
  1652. uerr("ERROR: CSW status error: %d\n", csw->status);
  1653. nbytes = -ENODEV;
  1654. }
  1655. }
  1656. }
  1657. }
  1658. }
  1659. while (nbytes == -EAGAIN);
  1660. }
  1661. usbhost_givesem(&priv->exclsem);
  1662. }
  1663. /* On success, return the number of blocks read */
  1664. return nbytes < 0 ? (int)nbytes : nsectors;
  1665. }
  1666. /****************************************************************************
  1667. * Name: usbhost_write
  1668. *
  1669. * Description:
  1670. * Write the specified number of sectors to the write buffer or to the
  1671. * physical device.
  1672. *
  1673. ****************************************************************************/
  1674. #ifdef CONFIG_FS_WRITABLE
  1675. static ssize_t usbhost_write(FAR struct inode *inode, const unsigned char *buffer,
  1676. size_t startsector, unsigned int nsectors)
  1677. {
  1678. FAR struct usbhost_state_s *priv;
  1679. FAR struct usbhost_hubport_s *hport;
  1680. ssize_t nbytes;
  1681. uinfo("sector: %d nsectors: %d sectorsize: %d\n");
  1682. DEBUGASSERT(inode && inode->i_private);
  1683. priv = (FAR struct usbhost_state_s *)inode->i_private;
  1684. DEBUGASSERT(priv->usbclass.hport);
  1685. hport = priv->usbclass.hport;
  1686. /* Check if the mass storage device is still connected */
  1687. if (priv->disconnected)
  1688. {
  1689. /* No... the block driver is no longer bound to the class. That means
  1690. * that the USB storage device is no longer connected. Refuse any
  1691. * attempt to write to the device.
  1692. */
  1693. nbytes = -ENODEV;
  1694. }
  1695. else
  1696. {
  1697. FAR struct usbmsc_cbw_s *cbw;
  1698. usbhost_takesem(&priv->exclsem);
  1699. /* Assume allocation failure */
  1700. nbytes = -ENOMEM;
  1701. /* Initialize a CBW (re-using the allocated transfer buffer) */
  1702. cbw = usbhost_cbwalloc(priv);
  1703. if (cbw)
  1704. {
  1705. /* Assume some device failure */
  1706. nbytes = -ENODEV;
  1707. /* Construct and send the CBW */
  1708. usbhost_writecbw(startsector, priv->blocksize, nsectors, cbw);
  1709. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout,
  1710. (FAR uint8_t *)cbw, USBMSC_CBW_SIZEOF);
  1711. if (nbytes >= 0)
  1712. {
  1713. /* Send the user data */
  1714. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkout,
  1715. (FAR uint8_t *)buffer, priv->blocksize * nsectors);
  1716. if (nbytes >= 0)
  1717. {
  1718. /* Receive the CSW */
  1719. nbytes = DRVR_TRANSFER(hport->drvr, priv->bulkin,
  1720. priv->tbuffer, USBMSC_CSW_SIZEOF);
  1721. if (nbytes >= 0)
  1722. {
  1723. FAR struct usbmsc_csw_s *csw;
  1724. /* Check the CSW status */
  1725. csw = (FAR struct usbmsc_csw_s *)priv->tbuffer;
  1726. if (csw->status != 0)
  1727. {
  1728. uerr("ERROR: CSW status error: %d\n", csw->status);
  1729. nbytes = -ENODEV;
  1730. }
  1731. }
  1732. }
  1733. }
  1734. }
  1735. usbhost_givesem(&priv->exclsem);
  1736. }
  1737. /* On success, return the number of blocks written */
  1738. return nbytes < 0 ? (int)nbytes : nsectors;
  1739. }
  1740. #endif
  1741. /****************************************************************************
  1742. * Name: usbhost_geometry
  1743. *
  1744. * Description: Return device geometry
  1745. *
  1746. ****************************************************************************/
  1747. static int usbhost_geometry(FAR struct inode *inode, struct geometry *geometry)
  1748. {
  1749. FAR struct usbhost_state_s *priv;
  1750. int ret = -EINVAL;
  1751. uinfo("Entry\n");
  1752. DEBUGASSERT(inode && inode->i_private);
  1753. /* Check if the mass storage device is still connected */
  1754. priv = (FAR struct usbhost_state_s *)inode->i_private;
  1755. if (priv->disconnected)
  1756. {
  1757. /* No... the block driver is no longer bound to the class. That means
  1758. * that the USB storage device is no longer connected. Refuse to
  1759. * return any geometry info.
  1760. */
  1761. ret = -ENODEV;
  1762. }
  1763. else if (geometry)
  1764. {
  1765. /* Return the geometry of the USB mass storage device */
  1766. usbhost_takesem(&priv->exclsem);
  1767. geometry->geo_available = true;
  1768. geometry->geo_mediachanged = false;
  1769. #ifdef CONFIG_FS_WRITABLE
  1770. geometry->geo_writeenabled = true;
  1771. #else
  1772. geometry->geo_writeenabled = false;
  1773. #endif
  1774. geometry->geo_nsectors = priv->nblocks;
  1775. geometry->geo_sectorsize = priv->blocksize;
  1776. usbhost_givesem(&priv->exclsem);
  1777. uinfo("nsectors: %ld sectorsize: %d\n",
  1778. (long)geometry->geo_nsectors, geometry->geo_sectorsize);
  1779. ret = OK;
  1780. }
  1781. return ret;
  1782. }
  1783. /****************************************************************************
  1784. * Name: usbhost_ioctl
  1785. *
  1786. * Description: Return device geometry
  1787. *
  1788. ****************************************************************************/
  1789. static int usbhost_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
  1790. {
  1791. FAR struct usbhost_state_s *priv;
  1792. int ret;
  1793. uinfo("Entry\n");
  1794. DEBUGASSERT(inode && inode->i_private);
  1795. priv = (FAR struct usbhost_state_s *)inode->i_private;
  1796. /* Check if the mass storage device is still connected */
  1797. if (priv->disconnected)
  1798. {
  1799. /* No... the block driver is no longer bound to the class. That means
  1800. * that the USB storage device is no longer connected. Refuse to
  1801. * process any ioctl commands.
  1802. */
  1803. ret = -ENODEV;
  1804. }
  1805. else
  1806. {
  1807. /* Process the IOCTL by command */
  1808. usbhost_takesem(&priv->exclsem);
  1809. switch (cmd)
  1810. {
  1811. /* Add support for ioctl commands here */
  1812. default:
  1813. ret = -ENOTTY;
  1814. break;
  1815. }
  1816. usbhost_givesem(&priv->exclsem);
  1817. }
  1818. return ret;
  1819. }
  1820. /****************************************************************************
  1821. * Public Functions
  1822. ****************************************************************************/
  1823. /****************************************************************************
  1824. * Name: usbhost_msc_initialize
  1825. *
  1826. * Description:
  1827. * Initialize the USB host storage class. This function should be called
  1828. * be platform-specific code in order to initialize and register support
  1829. * for the USB host storage class.
  1830. *
  1831. * Input Parameters:
  1832. * None
  1833. *
  1834. * Returned Values:
  1835. * On success this function will return zero (OK); A negated errno value
  1836. * will be returned on failure.
  1837. *
  1838. ****************************************************************************/
  1839. int usbhost_msc_initialize(void)
  1840. {
  1841. /* If we have been configured to use pre-allocated storage class instances,
  1842. * then place all of the pre-allocated USB host storage class instances
  1843. * into a free list.
  1844. */
  1845. #if CONFIG_USBHOST_NPREALLOC > 0
  1846. FAR struct usbhost_freestate_s *entry;
  1847. int i;
  1848. g_freelist = NULL;
  1849. for (i = 0; i < CONFIG_USBHOST_NPREALLOC; i++)
  1850. {
  1851. entry = (FAR struct usbhost_freestate_s *)&g_prealloc[i];
  1852. entry->flink = g_freelist;
  1853. g_freelist = entry;
  1854. }
  1855. #endif
  1856. /* Advertise our availability to support (certain) mass storage devices */
  1857. return usbhost_registerclass(&g_storage);
  1858. }
  1859. #endif /* CONFIG_USBHOST && !CONFIG_USBHOST_BULK_DISABLE && !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 */