usbhost_storage.c 72 KB

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