usbhost_xboxcontroller.c 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329
  1. /****************************************************************************
  2. * drivers/usbhost/usbhost_xboxcontroller.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 <assert.h>
  28. #include <errno.h>
  29. #include <debug.h>
  30. #include <fcntl.h>
  31. #include <poll.h>
  32. #include <nuttx/irq.h>
  33. #include <nuttx/kmalloc.h>
  34. #include <nuttx/kthread.h>
  35. #include <nuttx/fs/fs.h>
  36. #include <nuttx/arch.h>
  37. #include <nuttx/wqueue.h>
  38. #include <nuttx/signal.h>
  39. #include <nuttx/semaphore.h>
  40. #include <nuttx/usb/usb.h>
  41. #include <nuttx/usb/usbhost.h>
  42. #include <nuttx/input/xbox-controller.h>
  43. /****************************************************************************
  44. * Pre-processor Definitions
  45. ****************************************************************************/
  46. /* Configuration ************************************************************/
  47. #ifndef CONFIG_SCHED_WORKQUEUE
  48. # warning "Worker thread support is required (CONFIG_SCHED_WORKQUEUE)"
  49. #endif
  50. #ifndef CONFIG_XBOXCONTROLLER_DEFPRIO
  51. # define CONFIG_XBOXCONTROLLER_DEFPRIO 50
  52. #endif
  53. #ifndef CONFIG_XBOXCONTROLLER_STACKSIZE
  54. # define CONFIG_XBOXCONTROLLER_STACKSIZE 1024
  55. #endif
  56. #ifndef CONFIG_XBOXCONTROLLER_NPOLLWAITERS
  57. # define CONFIG_XBOXCONTROLLER_NPOLLWAITERS 2
  58. #endif
  59. /* Driver support ***********************************************************/
  60. /* This format is used to construct the /dev/xbox[n] device driver path. It
  61. * defined here so that it will be used consistently in all places.
  62. */
  63. #define DEV_FORMAT "/dev/xbox%c"
  64. #define DEV_NAMELEN 11
  65. /* Used in usbhost_cfgdesc() */
  66. #define USBHOST_IFFOUND 0x01
  67. #define USBHOST_EPINFOUND 0x02 /* Required interrupt IN EP descriptor found */
  68. #define USBHOST_EPOUTFOUND 0x04 /* Required interrupt OUT EP descriptor found */
  69. #define USBHOST_ALLFOUND 0x07
  70. #define USBHOST_MAX_CREFS 0x7fff
  71. /* Received message types */
  72. #define USBHOST_WAITING_CONNECTION 0x02
  73. #define USBHOST_GUIDE_BUTTON_STATUS 0x07
  74. #define USBHOST_BUTTON_DATA 0x20
  75. /* Button definitions */
  76. #define XBOX_BUTTON_GUIDE_INDEX 4
  77. #define XBOX_BUTTON_SYNC_INDEX 4
  78. #define XBOX_BUTTON_SYNC_MASK (1 << 0)
  79. #define XBOX_BUTTON_START_INDEX 4
  80. #define XBOX_BUTTON_START_MASK (1 << 2)
  81. #define XBOX_BUTTON_BACK_INDEX 4
  82. #define XBOX_BUTTON_BACK_MASK (1 << 3)
  83. #define XBOX_BUTTON_A_INDEX 4
  84. #define XBOX_BUTTON_A_MASK (1 << 4)
  85. #define XBOX_BUTTON_B_INDEX 4
  86. #define XBOX_BUTTON_B_MASK (1 << 5)
  87. #define XBOX_BUTTON_X_INDEX 4
  88. #define XBOX_BUTTON_X_MASK (1 << 6)
  89. #define XBOX_BUTTON_Y_INDEX 4
  90. #define XBOX_BUTTON_Y_MASK (1 << 7)
  91. #define XBOX_BUTTON_DPAD_UP_INDEX 5
  92. #define XBOX_BUTTON_DPAD_UP_MASK (1 << 0)
  93. #define XBOX_BUTTON_DPAD_DOWN_INDEX 5
  94. #define XBOX_BUTTON_DPAD_DOWN_MASK (1 << 1)
  95. #define XBOX_BUTTON_DPAD_LEFT_INDEX 5
  96. #define XBOX_BUTTON_DPAD_LEFT_MASK (1 << 2)
  97. #define XBOX_BUTTON_DPAD_RIGHT_INDEX 5
  98. #define XBOX_BUTTON_DPAD_RIGHT_MASK (1 << 3)
  99. #define XBOX_BUTTON_BUMPER_LEFT_INDEX 5
  100. #define XBOX_BUTTON_BUMPER_LEFT_MASK (1 << 4)
  101. #define XBOX_BUTTON_BUMPER_RIGHT_INDEX 5
  102. #define XBOX_BUTTON_BUMPER_RIGHT_MASK (1 << 5)
  103. #define XBOX_BUTTON_STICK_LEFT_INDEX 5
  104. #define XBOX_BUTTON_STICK_LEFT_MASK (1 << 6)
  105. #define XBOX_BUTTON_STICK_RIGHT_INDEX 5
  106. #define XBOX_BUTTON_STICK_RIGHT_MASK (1 << 7)
  107. #define XBOX_BUTTON_TRIGGER_LEFT 3
  108. #define XBOX_BUTTON_TRIGGER_RIGHT 4
  109. #define XBOX_BUTTON_STICK_LEFT_X 5
  110. #define XBOX_BUTTON_STICK_LEFT_Y 6
  111. #define XBOX_BUTTON_STICK_RIGHT_X 7
  112. #define XBOX_BUTTON_STICK_RIGHT_Y 8
  113. #define XBOX_BUTTON_SET(buffer, index, mask) \
  114. ((((buffer)[(index)] & (mask)) != 0) ? true : false);
  115. /****************************************************************************
  116. * Private Types
  117. ****************************************************************************/
  118. /* This structure contains the internal, private state of the USB host class
  119. * driver.
  120. */
  121. struct usbhost_state_s
  122. {
  123. /* This is the externally visible portion of the state */
  124. struct usbhost_class_s usbclass;
  125. /* The remainder of the fields are provide to the class driver */
  126. char devchar; /* Character identifying the /dev/xbox[n] device */
  127. volatile bool disconnected; /* TRUE: Device has been disconnected */
  128. volatile bool polling; /* TRUE: Poll thread is running */
  129. volatile bool open; /* TRUE: The controller device is open */
  130. volatile bool valid; /* TRUE: New sample data is available */
  131. volatile bool initialized; /* TRUE: The initialization packet has been sent */
  132. uint8_t ifno; /* Interface number */
  133. uint8_t nwaiters; /* Number of threads waiting for controller data */
  134. sem_t waitsem; /* Used to wait for controller data */
  135. int16_t crefs; /* Reference count on the driver instance */
  136. sem_t exclsem; /* Used to maintain mutual exclusive access */
  137. struct work_s work; /* For interacting with the worker thread */
  138. FAR uint8_t *tbuffer; /* The allocated transfer buffer */
  139. FAR uint8_t obuffer[20]; /* The fixed output transfer buffer */
  140. size_t tbuflen; /* Size of the allocated transfer buffer */
  141. usbhost_ep_t epin; /* IN endpoint */
  142. usbhost_ep_t epout; /* OUT endpoint */
  143. pid_t pollpid; /* PID of the poll task */
  144. size_t out_seq_num; /* The sequence number for outgoing packets */
  145. struct xbox_controller_buttonstate_s rpt; /* The latest report out of the controller. */
  146. /* The following is a list if poll structures of threads waiting for
  147. * driver events. The 'struct pollfd' reference for each open is also
  148. * retained in the f_priv field of the 'struct file'.
  149. */
  150. struct pollfd *fds[CONFIG_XBOXCONTROLLER_NPOLLWAITERS];
  151. };
  152. /****************************************************************************
  153. * Private Function Prototypes
  154. ****************************************************************************/
  155. /* Semaphores */
  156. static int usbhost_takesem(FAR sem_t *sem);
  157. static void usbhost_forcetake(FAR sem_t *sem);
  158. #define usbhost_givesem(s) nxsem_post(s);
  159. /* Memory allocation services */
  160. static inline FAR struct usbhost_state_s *usbhost_allocclass(void);
  161. static inline void usbhost_freeclass(FAR struct usbhost_state_s *usbclass);
  162. /* Device name management */
  163. static int usbhost_allocdevno(FAR struct usbhost_state_s *priv);
  164. static void usbhost_freedevno(FAR struct usbhost_state_s *priv);
  165. static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv,
  166. FAR char *devname);
  167. /* Worker thread actions */
  168. static void usbhost_destroy(FAR void *arg);
  169. /* Polling support */
  170. static void usbhost_pollnotify(FAR struct usbhost_state_s *dev);
  171. static int usbhost_xboxcontroller_poll(int argc, char *argv[]);
  172. /* Helpers for usbhost_connect() */
  173. static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
  174. FAR const uint8_t *configdesc,
  175. int desclen);
  176. static inline int usbhost_devinit(FAR struct usbhost_state_s *priv);
  177. /* (Little Endian) Data helpers */
  178. static inline uint16_t usbhost_getle16(const uint8_t *val);
  179. static inline void usbhost_putle16(uint8_t *dest, uint16_t val);
  180. static inline uint32_t usbhost_getle32(const uint8_t *val);
  181. #if 0 /* Not used */
  182. static void usbhost_putle32(uint8_t *dest, uint32_t val);
  183. #endif
  184. /* Transfer descriptor memory management */
  185. static inline int usbhost_talloc(FAR struct usbhost_state_s *priv);
  186. static inline int usbhost_tfree(FAR struct usbhost_state_s *priv);
  187. /* struct usbhost_registry_s methods */
  188. static struct usbhost_class_s *
  189. usbhost_create(FAR struct usbhost_hubport_s *hport,
  190. FAR const struct usbhost_id_s *id);
  191. /* struct usbhost_class_s methods */
  192. static int usbhost_connect(FAR struct usbhost_class_s *usbclass,
  193. FAR const uint8_t *configdesc, int desclen);
  194. static int usbhost_disconnected(FAR struct usbhost_class_s *usbclass);
  195. /* Driver methods. We export the controller as a standard character driver */
  196. static int usbhost_open(FAR struct file *filep);
  197. static int usbhost_close(FAR struct file *filep);
  198. static ssize_t usbhost_read(FAR struct file *filep,
  199. FAR char *buffer, size_t len);
  200. static ssize_t usbhost_write(FAR struct file *filep,
  201. FAR const char *buffer, size_t len);
  202. static int usbhost_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
  203. static int usbhost_poll(FAR struct file *filep, FAR struct pollfd *fds,
  204. bool setup);
  205. /****************************************************************************
  206. * Private Data
  207. ****************************************************************************/
  208. /* This structure provides the registry entry ID information that will be
  209. * used to associate the USB class driver to a connected USB device.
  210. */
  211. static const struct usbhost_id_s g_xboxcontroller_id[] =
  212. {
  213. /* XBox One classic controller */
  214. {
  215. USB_CLASS_VENDOR_SPEC, /* base -- Must be one of the USB_CLASS_* definitions in usb.h */
  216. 0x0047, /* subclass -- depends on the device */
  217. 0x00d0, /* proto -- depends on the device */
  218. 0x045e, /* vid */
  219. 0x02dd /* pid */
  220. },
  221. /* XBox One S controller */
  222. {
  223. USB_CLASS_VENDOR_SPEC, /* base -- Must be one of the USB_CLASS_* definitions in usb.h */
  224. 0x0047, /* subclass -- depends on the device */
  225. 0x00d0, /* proto -- depends on the device */
  226. 0x045e, /* vid */
  227. 0x02ea /* pid */
  228. }
  229. };
  230. /* This is the USB host storage class's registry entry */
  231. static struct usbhost_registry_s g_xboxcontroller =
  232. {
  233. NULL, /* flink */
  234. usbhost_create, /* create */
  235. 2, /* nids */
  236. g_xboxcontroller_id /* id[] */
  237. };
  238. /* The configuration information for the block file device. */
  239. static const struct file_operations g_xboxcontroller_fops =
  240. {
  241. usbhost_open, /* open */
  242. usbhost_close, /* close */
  243. usbhost_read, /* read */
  244. usbhost_write, /* write */
  245. NULL, /* seek */
  246. usbhost_ioctl, /* ioctl */
  247. usbhost_poll /* poll */
  248. };
  249. /* This is a bitmap that is used to allocate device names /dev/xboxa-z. */
  250. static uint32_t g_devinuse;
  251. /* The following are used to managed the class creation operation */
  252. static sem_t g_exclsem; /* For mutually exclusive thread creation */
  253. static sem_t g_syncsem; /* Thread data passing interlock */
  254. static struct usbhost_state_s *g_priv; /* Data passed to thread */
  255. /****************************************************************************
  256. * Private Functions
  257. ****************************************************************************/
  258. /****************************************************************************
  259. * Name: usbhost_takesem
  260. *
  261. * Description:
  262. * This is just a wrapper to handle the annoying behavior of semaphore
  263. * waits that return due to the receipt of a signal.
  264. *
  265. ****************************************************************************/
  266. static int usbhost_takesem(FAR sem_t *sem)
  267. {
  268. return nxsem_wait_uninterruptible(sem);
  269. }
  270. /****************************************************************************
  271. * Name: usbhost_forcetake
  272. *
  273. * Description:
  274. * This is just another wrapper but this one continues even if the thread
  275. * is canceled. This must be done in certain conditions where were must
  276. * continue in order to clean-up resources.
  277. *
  278. ****************************************************************************/
  279. static void usbhost_forcetake(FAR sem_t *sem)
  280. {
  281. int ret;
  282. do
  283. {
  284. ret = nxsem_wait_uninterruptible(sem);
  285. /* The only expected error would -ECANCELED meaning that the
  286. * parent thread has been canceled. We have to continue and
  287. * terminate the poll in this case.
  288. */
  289. DEBUGASSERT(ret == OK || ret == -ECANCELED);
  290. }
  291. while (ret < 0);
  292. }
  293. /****************************************************************************
  294. * Name: usbhost_allocclass
  295. *
  296. * Description:
  297. * This is really part of the logic that implements the create() method
  298. * of struct usbhost_registry_s. This function allocates memory for one
  299. * new class instance.
  300. *
  301. * Input Parameters:
  302. * None
  303. *
  304. * Returned Value:
  305. * On success, this function will return a non-NULL instance of struct
  306. * usbhost_class_s. NULL is returned on failure; this function will
  307. * will fail only if there are insufficient resources to create another
  308. * USB host class instance.
  309. *
  310. ****************************************************************************/
  311. static inline FAR struct usbhost_state_s *usbhost_allocclass(void)
  312. {
  313. FAR struct usbhost_state_s *priv;
  314. DEBUGASSERT(!up_interrupt_context());
  315. priv = (FAR struct usbhost_state_s *)
  316. kmm_malloc(sizeof(struct usbhost_state_s));
  317. uinfo("Allocated: %p\n", priv);
  318. return priv;
  319. }
  320. /****************************************************************************
  321. * Name: usbhost_freeclass
  322. *
  323. * Description:
  324. * Free a class instance previously allocated by usbhost_allocclass().
  325. *
  326. * Input Parameters:
  327. * usbclass - A reference to the class instance to be freed.
  328. *
  329. * Returned Value:
  330. * None
  331. *
  332. ****************************************************************************/
  333. static inline void usbhost_freeclass(FAR struct usbhost_state_s *usbclass)
  334. {
  335. DEBUGASSERT(usbclass != NULL);
  336. /* Free the class instance (perhaps calling sched_kmm_free() in case we are
  337. * executing from an interrupt handler.
  338. */
  339. uinfo("Freeing: %p\n", usbclass);
  340. kmm_free(usbclass);
  341. }
  342. /****************************************************************************
  343. * Name: Device name management
  344. *
  345. * Description:
  346. * Some tiny functions to coordinate management of device names.
  347. *
  348. ****************************************************************************/
  349. static int usbhost_allocdevno(FAR struct usbhost_state_s *priv)
  350. {
  351. irqstate_t flags;
  352. int devno;
  353. flags = enter_critical_section();
  354. for (devno = 0; devno < 26; devno++)
  355. {
  356. uint32_t bitno = 1 << devno;
  357. if ((g_devinuse & bitno) == 0)
  358. {
  359. g_devinuse |= bitno;
  360. priv->devchar = 'a' + devno;
  361. leave_critical_section(flags);
  362. return OK;
  363. }
  364. }
  365. leave_critical_section(flags);
  366. return -EMFILE;
  367. }
  368. static void usbhost_freedevno(FAR struct usbhost_state_s *priv)
  369. {
  370. int devno = 'a' - priv->devchar;
  371. if (devno >= 0 && devno < 26)
  372. {
  373. irqstate_t flags = enter_critical_section();
  374. g_devinuse &= ~(1 << devno);
  375. leave_critical_section(flags);
  376. }
  377. }
  378. static inline void usbhost_mkdevname(FAR struct usbhost_state_s *priv,
  379. FAR char *devname)
  380. {
  381. snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->devchar);
  382. }
  383. /****************************************************************************
  384. * Name: usbhost_destroy
  385. *
  386. * Description:
  387. * The USB device has been disconnected and the reference count on the USB
  388. * host class instance has gone to 1.. Time to destroy the USB host class
  389. * instance.
  390. *
  391. * Input Parameters:
  392. * arg - A reference to the class instance to be destroyed.
  393. *
  394. * Returned Value:
  395. * None
  396. *
  397. ****************************************************************************/
  398. static void usbhost_destroy(FAR void *arg)
  399. {
  400. FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)arg;
  401. FAR struct usbhost_hubport_s *hport;
  402. char devname[DEV_NAMELEN];
  403. DEBUGASSERT(priv != NULL && priv->usbclass.hport != NULL);
  404. uinfo("crefs: %d\n", priv->crefs);
  405. hport = priv->usbclass.hport;
  406. DEBUGASSERT(hport->drvr);
  407. uinfo("crefs: %d\n", priv->crefs);
  408. /* Unregister the driver */
  409. uinfo("Unregister driver\n");
  410. usbhost_mkdevname(priv, devname);
  411. unregister_driver(devname);
  412. /* Release the device name used by this connection */
  413. usbhost_freedevno(priv);
  414. /* Free the interrupt endpoints */
  415. if (priv->epin)
  416. {
  417. DRVR_EPFREE(hport->drvr, priv->epin);
  418. }
  419. /* Free any transfer buffers */
  420. usbhost_tfree(priv);
  421. /* Destroy the semaphores */
  422. nxsem_destroy(&priv->exclsem);
  423. nxsem_destroy(&priv->waitsem);
  424. /* Disconnect the USB host device */
  425. DRVR_DISCONNECT(hport->drvr, hport);
  426. /* Free the function address assigned to this device */
  427. usbhost_devaddr_destroy(hport, hport->funcaddr);
  428. hport->funcaddr = 0;
  429. /* And free the class instance. */
  430. usbhost_freeclass(priv);
  431. }
  432. /****************************************************************************
  433. * Name: usbhost_pollnotify
  434. *
  435. * Description:
  436. * Wake any threads waiting for controller data
  437. *
  438. * Input Parameters:
  439. * priv - A reference to the controller state structure.
  440. *
  441. * Returned Value:
  442. * None
  443. *
  444. ****************************************************************************/
  445. static void usbhost_pollnotify(FAR struct usbhost_state_s *priv)
  446. {
  447. int i;
  448. /* If there are threads waiting for read data, then signal one of them
  449. * that the read data is available.
  450. */
  451. if (priv->nwaiters > 0)
  452. {
  453. nxsem_post(&priv->waitsem);
  454. }
  455. /* If there are threads waiting on poll() for controller data to become
  456. * available, then wake them up now. NOTE: we wake up all waiting threads
  457. * because we do not know that they are going to do. If they all try to
  458. * read the data, then some make end up blocking after all.
  459. */
  460. for (i = 0; i < CONFIG_XBOXCONTROLLER_NPOLLWAITERS; i++)
  461. {
  462. FAR struct pollfd *fds = priv->fds[i];
  463. if (fds)
  464. {
  465. fds->revents |= POLLIN;
  466. iinfo("Report events: %02x\n", fds->revents);
  467. nxsem_post(fds->sem);
  468. }
  469. }
  470. }
  471. /****************************************************************************
  472. * Name: usbhost_xboxcontroller_poll
  473. *
  474. * Description:
  475. * Periodically check for new controller data.
  476. *
  477. * Input Parameters:
  478. * arg - A reference to the class instance to be destroyed.
  479. *
  480. * Returned Value:
  481. * None
  482. *
  483. ****************************************************************************/
  484. static int usbhost_xboxcontroller_poll(int argc, char *argv[])
  485. {
  486. FAR struct usbhost_state_s *priv;
  487. FAR struct usbhost_hubport_s *hport;
  488. irqstate_t flags;
  489. #if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_INFO)
  490. unsigned int npolls = 0;
  491. #endif
  492. unsigned int nerrors = 0;
  493. ssize_t nbytes;
  494. int ret = OK;
  495. /* Synchronize with the start-up logic. Get the private instance, re-start
  496. * the start-up logic, and wait a bit to make sure that all of the class
  497. * creation logic has a chance to run to completion.
  498. *
  499. * NOTE: that the reference count is *not* incremented here. When the
  500. * driver structure was created, it was created with a reference count of
  501. * one. This thread is responsible for that count. The count will be
  502. * decrement when this thread exits.
  503. */
  504. priv = g_priv;
  505. DEBUGASSERT(priv != NULL && priv->usbclass.hport != NULL);
  506. hport = priv->usbclass.hport;
  507. priv->polling = true;
  508. usbhost_givesem(&g_syncsem);
  509. nxsig_sleep(1);
  510. /* Loop here until the device is disconnected */
  511. uinfo("Entering poll loop\n");
  512. while (!priv->disconnected)
  513. {
  514. /* Read the next ccontroller report. We will stall here until the
  515. * controller sends data.
  516. */
  517. nbytes = DRVR_TRANSFER(hport->drvr, priv->epin,
  518. priv->tbuffer, priv->tbuflen);
  519. /* Check for errors -- Bail if an excessive number of consecutive
  520. * errors are encountered.
  521. */
  522. if (nbytes < 0)
  523. {
  524. /* If DRVR_TRANSFER() returns EAGAIN, that simply means that
  525. * the devices was not ready and has NAK'ed the transfer. That
  526. * should not be treated as an error (unless it persists for a
  527. * long time).
  528. */
  529. if (nbytes != -EAGAIN)
  530. {
  531. uerr("ERROR: DRVR_TRANSFER returned: %d/%u\n",
  532. (int)nbytes, nerrors);
  533. if (++nerrors > 200)
  534. {
  535. uerr(" Too many errors... aborting: %d\n", nerrors);
  536. ret = (int)nbytes;
  537. break;
  538. }
  539. }
  540. }
  541. /* The report was received correctly. */
  542. else
  543. {
  544. /* Success, reset the error counter */
  545. nerrors = 0;
  546. /* The type of message is in the first byte */
  547. switch (priv->tbuffer[0])
  548. {
  549. case USBHOST_WAITING_CONNECTION:
  550. /* Send the initialization message when we received the
  551. * the first waiting connection message.
  552. */
  553. if (!priv->initialized)
  554. {
  555. /* Get exclusive access to the controller state data */
  556. ret = usbhost_takesem(&priv->exclsem);
  557. if (ret < 0)
  558. {
  559. goto exitloop;
  560. }
  561. priv->tbuffer[0] = 0x05;
  562. priv->tbuffer[1] = 0x20;
  563. priv->tbuffer[2] = priv->out_seq_num++;
  564. priv->tbuffer[3] = 0x01;
  565. priv->tbuffer[4] = 0x00;
  566. nbytes = DRVR_TRANSFER(hport->drvr, priv->epout,
  567. priv->tbuffer, 5);
  568. priv->initialized = true;
  569. /* Release our lock on the state structure */
  570. usbhost_givesem(&priv->exclsem);
  571. }
  572. break;
  573. case USBHOST_GUIDE_BUTTON_STATUS:
  574. /* Get exclusive access to the controller state data */
  575. ret = usbhost_takesem(&priv->exclsem);
  576. if (ret < 0)
  577. {
  578. goto exitloop;
  579. }
  580. /* Read the data out of the controller report. */
  581. priv->rpt.guide =
  582. (priv->tbuffer[XBOX_BUTTON_GUIDE_INDEX] != 0) ? true : false;
  583. priv->valid = true;
  584. /* The One X controller requires an ACK of the guide button
  585. * status message.
  586. */
  587. if (priv->tbuffer[1] == 0x30)
  588. {
  589. static const uint8_t guide_button_report_ack[] =
  590. {
  591. 0x01, 0x20, 0x00, 0x09, 0x00, 0x07, 0x20, 0x02,
  592. 0x00, 0x00, 0x00, 0x00, 0x00
  593. };
  594. /* Remember the input packet sequence number. */
  595. uint8_t seq_num = priv->tbuffer[2];
  596. /* Copy the ACK packet into the transfer buffer. */
  597. memcpy(priv->tbuffer, guide_button_report_ack,
  598. sizeof(guide_button_report_ack));
  599. /* Ensure the sequence number is the same as the input
  600. * packet.
  601. */
  602. priv->tbuffer[2] = seq_num;
  603. /* Perform the transfer. */
  604. nbytes =
  605. DRVR_TRANSFER(hport->drvr, priv->epout, priv->tbuffer,
  606. sizeof(guide_button_report_ack));
  607. }
  608. /* Notify any waiters that new controller data is available */
  609. usbhost_pollnotify(priv);
  610. /* Release our lock on the state structure */
  611. usbhost_givesem(&priv->exclsem);
  612. break;
  613. case USBHOST_BUTTON_DATA:
  614. /* Ignore the controller data if no task has opened the
  615. * driver.
  616. */
  617. if (priv->open)
  618. {
  619. /* Get exclusive access to the controller state data */
  620. ret = usbhost_takesem(&priv->exclsem);
  621. if (ret < 0)
  622. {
  623. goto exitloop;
  624. }
  625. /* Read the data out of the controller report. */
  626. priv->rpt.sync =
  627. XBOX_BUTTON_SET(priv->tbuffer,
  628. XBOX_BUTTON_SYNC_INDEX,
  629. XBOX_BUTTON_SYNC_MASK);
  630. priv->rpt.start =
  631. XBOX_BUTTON_SET(priv->tbuffer,
  632. XBOX_BUTTON_START_INDEX,
  633. XBOX_BUTTON_START_MASK);
  634. priv->rpt.back =
  635. XBOX_BUTTON_SET(priv->tbuffer,
  636. XBOX_BUTTON_BACK_INDEX,
  637. XBOX_BUTTON_BACK_MASK);
  638. priv->rpt.a =
  639. XBOX_BUTTON_SET(priv->tbuffer,
  640. XBOX_BUTTON_A_INDEX,
  641. XBOX_BUTTON_A_MASK);
  642. priv->rpt.b =
  643. XBOX_BUTTON_SET(priv->tbuffer,
  644. XBOX_BUTTON_B_INDEX,
  645. XBOX_BUTTON_B_MASK);
  646. priv->rpt.x =
  647. XBOX_BUTTON_SET(priv->tbuffer,
  648. XBOX_BUTTON_X_INDEX,
  649. XBOX_BUTTON_X_MASK);
  650. priv->rpt.y =
  651. XBOX_BUTTON_SET(priv->tbuffer,
  652. XBOX_BUTTON_Y_INDEX,
  653. XBOX_BUTTON_Y_MASK);
  654. priv->rpt.dpad_up =
  655. XBOX_BUTTON_SET(priv->tbuffer,
  656. XBOX_BUTTON_DPAD_UP_INDEX,
  657. XBOX_BUTTON_DPAD_UP_MASK);
  658. priv->rpt.dpad_down =
  659. XBOX_BUTTON_SET(priv->tbuffer,
  660. XBOX_BUTTON_DPAD_DOWN_INDEX,
  661. XBOX_BUTTON_DPAD_DOWN_MASK);
  662. priv->rpt.dpad_left =
  663. XBOX_BUTTON_SET(priv->tbuffer,
  664. XBOX_BUTTON_DPAD_LEFT_INDEX,
  665. XBOX_BUTTON_DPAD_LEFT_MASK);
  666. priv->rpt.dpad_right =
  667. XBOX_BUTTON_SET(priv->tbuffer,
  668. XBOX_BUTTON_DPAD_RIGHT_INDEX,
  669. XBOX_BUTTON_DPAD_RIGHT_MASK);
  670. priv->rpt.bumper_left =
  671. XBOX_BUTTON_SET(priv->tbuffer,
  672. XBOX_BUTTON_BUMPER_LEFT_INDEX,
  673. XBOX_BUTTON_BUMPER_LEFT_MASK);
  674. priv->rpt.bumper_right =
  675. XBOX_BUTTON_SET(priv->tbuffer,
  676. XBOX_BUTTON_BUMPER_RIGHT_INDEX,
  677. XBOX_BUTTON_BUMPER_RIGHT_MASK);
  678. priv->rpt.stick_click_left =
  679. XBOX_BUTTON_SET(priv->tbuffer,
  680. XBOX_BUTTON_STICK_LEFT_INDEX,
  681. XBOX_BUTTON_STICK_LEFT_MASK);
  682. priv->rpt.stick_click_right =
  683. XBOX_BUTTON_SET(priv->tbuffer,
  684. XBOX_BUTTON_STICK_RIGHT_INDEX,
  685. XBOX_BUTTON_STICK_RIGHT_MASK);
  686. priv->rpt.trigger_left =
  687. ((int16_t *)(priv->tbuffer))[XBOX_BUTTON_TRIGGER_LEFT];
  688. priv->rpt.trigger_right =
  689. ((int16_t *)(priv->tbuffer))[XBOX_BUTTON_TRIGGER_RIGHT];
  690. priv->rpt.stick_left_x =
  691. ((int16_t *)(priv->tbuffer))[XBOX_BUTTON_STICK_LEFT_X];
  692. priv->rpt.stick_left_y =
  693. ((int16_t *)(priv->tbuffer))[XBOX_BUTTON_STICK_LEFT_Y];
  694. priv->rpt.stick_right_x =
  695. ((int16_t *)(priv->tbuffer))[XBOX_BUTTON_STICK_RIGHT_X];
  696. priv->rpt.stick_right_y =
  697. ((int16_t *)(priv->tbuffer))[XBOX_BUTTON_STICK_RIGHT_Y];
  698. priv->valid = true;
  699. /* Notify any waiters that new controller data is
  700. * available.
  701. */
  702. usbhost_pollnotify(priv);
  703. /* Release our lock on the state structure */
  704. usbhost_givesem(&priv->exclsem);
  705. }
  706. break;
  707. default:
  708. uinfo("Received message type: %x\n", priv->tbuffer[0]);
  709. }
  710. }
  711. /* If USB debug is on, then provide some periodic indication that
  712. * polling is still happening.
  713. */
  714. #if defined(CONFIG_DEBUG_USB) && defined(CONFIG_DEBUG_INFO)
  715. npolls++;
  716. if ((npolls & 31) == 0)
  717. {
  718. uinfo("Still polling: %d\n", npolls);
  719. }
  720. #endif
  721. }
  722. exitloop:
  723. /* We get here when the driver is removed, when too many errors have
  724. * been encountered, or when the thread is canceled.
  725. *
  726. * Make sure that we have exclusive access to the private data structure.
  727. * There may now be other tasks with the character driver open and actively
  728. * trying to interact with the class driver.
  729. */
  730. usbhost_forcetake(&priv->exclsem);
  731. /* Indicate that we are no longer running and decrement the reference
  732. * count held by this thread. If there are no other users of the class,
  733. * we can destroy it now. Otherwise, we have to wait until the all
  734. * of the file descriptors are closed.
  735. */
  736. uinfo("Controller removed, polling halted\n");
  737. flags = enter_critical_section();
  738. priv->polling = false;
  739. /* Decrement the reference count held by this thread. */
  740. DEBUGASSERT(priv->crefs > 0);
  741. priv->crefs--;
  742. /* There are two possibilities:
  743. * 1) The reference count is greater than zero. This means that there
  744. * are still open references to the controller driver. In this case
  745. * we need to wait until usbhost_close() is called and all of the
  746. * open driver references are decremented. Then usbhost_destroy() can
  747. * be called from usbhost_close().
  748. * 2) The reference count is now zero. This means that there are no
  749. * further open references and we can call usbhost_destroy() now.
  750. */
  751. if (priv->crefs < 1)
  752. {
  753. /* Unregister the driver and destroy the instance (while we hold
  754. * the semaphore!)
  755. */
  756. usbhost_destroy(priv);
  757. }
  758. else
  759. {
  760. /* No, we will destroy the driver instance when it is final open
  761. * reference is closed
  762. */
  763. usbhost_givesem(&priv->exclsem);
  764. }
  765. leave_critical_section(flags);
  766. return ret;
  767. }
  768. /****************************************************************************
  769. * Name: usbhost_sample
  770. *
  771. * Description:
  772. * Check if new controller data is available
  773. *
  774. * Input Parameters:
  775. * priv - controller state instance
  776. * sample - The location to return the sample data
  777. *
  778. ****************************************************************************/
  779. static int usbhost_sample(FAR struct usbhost_state_s *priv,
  780. FAR struct xbox_controller_buttonstate_s *sample)
  781. {
  782. irqstate_t flags;
  783. int ret = -EAGAIN;
  784. /* Interrupts me be disabled when this is called to (1) prevent posting
  785. * of semaphores from interrupt handlers, and (2) to prevent sampled data
  786. * from changing until it has been reported.
  787. */
  788. flags = enter_critical_section();
  789. /* Is there new mouse data available? */
  790. if (priv->valid)
  791. {
  792. /* Return a copy of the sampled data. */
  793. memcpy(sample, &priv->rpt,
  794. sizeof(struct xbox_controller_buttonstate_s));
  795. /* The sample has been reported and is no longer valid */
  796. priv->valid = false;
  797. ret = OK;
  798. }
  799. leave_critical_section(flags);
  800. return ret;
  801. }
  802. /****************************************************************************
  803. * Name: usbhost_waitsample
  804. *
  805. * Description:
  806. * Wait for the next valid controller sample
  807. *
  808. * Input Parameters:
  809. * priv - controller state instance
  810. * sample - The location to return the sample data
  811. *
  812. ****************************************************************************/
  813. static int usbhost_waitsample(FAR struct usbhost_state_s *priv,
  814. FAR struct xbox_controller_buttonstate_s *sample)
  815. {
  816. irqstate_t flags;
  817. int ret;
  818. /* Interrupts me be disabled when this is called to (1) prevent posting
  819. * of semaphores from interrupt handlers, and (2) to prevent sampled data
  820. * from changing until it has been reported.
  821. *
  822. * In addition, we will also disable pre-emption to prevent other threads
  823. * from getting control while we muck with the semaphores.
  824. */
  825. sched_lock();
  826. flags = enter_critical_section();
  827. /* Now release the semaphore that manages mutually exclusive access to
  828. * the device structure. This may cause other tasks to become ready to
  829. * run, but they cannot run yet because pre-emption is disabled.
  830. */
  831. nxsem_post(&priv->exclsem);
  832. /* Try to get the a sample... if we cannot, then wait on the semaphore
  833. * that is posted when new sample data is available.
  834. */
  835. while (usbhost_sample(priv, sample) < 0)
  836. {
  837. /* Wait for a change in the HIDMOUSE state */
  838. iinfo("Waiting..\n");
  839. priv->nwaiters++;
  840. ret = nxsem_wait(&priv->waitsem);
  841. priv->nwaiters--;
  842. if (ret < 0)
  843. {
  844. ierr("ERROR: nxsem_wait: %d\n", ret);
  845. goto errout;
  846. }
  847. /* Did the controller become disconnected while we were waiting */
  848. if (priv->disconnected)
  849. {
  850. ret = -ENODEV;
  851. goto errout;
  852. }
  853. }
  854. iinfo("Sampled\n");
  855. /* Re-acquire the semaphore that manages mutually exclusive access to
  856. * the device structure. We may have to wait here. But we have our
  857. * sample. Interrupts and pre-emption will be re-enabled while we wait.
  858. */
  859. ret = nxsem_wait(&priv->exclsem);
  860. errout:
  861. /* Then re-enable interrupts. We might get interrupt here and there
  862. * could be a new sample. But no new threads will run because we still
  863. * have pre-emption disabled.
  864. */
  865. leave_critical_section(flags);
  866. /* Restore pre-emption. We might get suspended here but that is okay
  867. * because we already have our sample. Note: this means that if there
  868. * were two threads reading from the HIDMOUSE for some reason, the data
  869. * might be read out of order.
  870. */
  871. sched_unlock();
  872. return ret;
  873. }
  874. /****************************************************************************
  875. * Name: usbhost_cfgdesc
  876. *
  877. * Description:
  878. * This function implements the connect() method of struct
  879. * usbhost_class_s. This method is a callback into the class
  880. * implementation. It is used to provide the device's configuration
  881. * descriptor to the class so that the class may initialize properly
  882. *
  883. * Input Parameters:
  884. * priv - The USB host class instance.
  885. * configdesc - A pointer to a uint8_t buffer container the configuration
  886. * descriptor.
  887. * desclen - The length in bytes of the configuration descriptor.
  888. *
  889. * Returned Value:
  890. * On success, zero (OK) is returned. On a failure, a negated errno value
  891. * is returned indicating the nature of the failure
  892. *
  893. * Assumptions:
  894. * This function will *not* be called from an interrupt handler.
  895. *
  896. ****************************************************************************/
  897. static inline int usbhost_cfgdesc(FAR struct usbhost_state_s *priv,
  898. FAR const uint8_t *configdesc, int desclen)
  899. {
  900. FAR struct usbhost_hubport_s *hport;
  901. FAR struct usb_cfgdesc_s *cfgdesc;
  902. FAR struct usb_desc_s *desc;
  903. FAR struct usbhost_epdesc_s epindesc;
  904. FAR struct usbhost_epdesc_s epoutdesc;
  905. int remaining;
  906. uint8_t found = 0;
  907. bool done = false;
  908. int ret;
  909. DEBUGASSERT(priv != NULL && priv->usbclass.hport &&
  910. configdesc != NULL && desclen >= sizeof(struct usb_cfgdesc_s));
  911. hport = priv->usbclass.hport;
  912. /* Keep the compiler from complaining about uninitialized variables */
  913. memset(&epindesc, 0, sizeof(struct usbhost_epdesc_s));
  914. memset(&epoutdesc, 0, sizeof(struct usbhost_epdesc_s));
  915. /* Verify that we were passed a configuration descriptor */
  916. cfgdesc = (FAR struct usb_cfgdesc_s *)configdesc;
  917. if (cfgdesc->type != USB_DESC_TYPE_CONFIG)
  918. {
  919. return -EINVAL;
  920. }
  921. /* Get the total length of the configuration descriptor (little endian).
  922. * It might be a good check to get the number of interfaces here too.
  923. */
  924. remaining = (int)usbhost_getle16(cfgdesc->totallen);
  925. /* Skip to the next entry descriptor */
  926. configdesc += cfgdesc->len;
  927. remaining -= cfgdesc->len;
  928. /* Loop where there are more dscriptors to examine */
  929. while (remaining >= sizeof(struct usb_desc_s) && !done)
  930. {
  931. /* What is the next descriptor? */
  932. desc = (FAR struct usb_desc_s *)configdesc;
  933. switch (desc->type)
  934. {
  935. /* Interface descriptor. We really should get the number of endpoints
  936. * from this descriptor too.
  937. */
  938. case USB_DESC_TYPE_INTERFACE:
  939. {
  940. uinfo("Interface descriptor\n");
  941. DEBUGASSERT(remaining >= USB_SIZEOF_IFDESC);
  942. /* Did we already find what we needed from a preceding
  943. * interface?
  944. */
  945. if ((found & USBHOST_ALLFOUND) == USBHOST_ALLFOUND)
  946. {
  947. /* Yes.. then break out of the loop and use the preceding
  948. * interface.
  949. */
  950. done = true;
  951. }
  952. else
  953. {
  954. /* Otherwise, discard any endpoints previously found */
  955. found = USBHOST_IFFOUND;
  956. }
  957. }
  958. break;
  959. /* Endpoint descriptor. Here, we expect two bulk endpoints, an IN
  960. * and an OUT.
  961. */
  962. case USB_DESC_TYPE_ENDPOINT:
  963. {
  964. FAR struct usb_epdesc_s *epdesc =
  965. (FAR struct usb_epdesc_s *)configdesc;
  966. uinfo("Endpoint descriptor\n");
  967. DEBUGASSERT(remaining >= USB_SIZEOF_EPDESC);
  968. /* Check for a interrupt endpoint. */
  969. if ((epdesc->attr & USB_EP_ATTR_XFERTYPE_MASK) ==
  970. USB_EP_ATTR_XFER_INT)
  971. {
  972. /* Yes.. it is a interrupt endpoint. IN or OUT? */
  973. if (USB_ISEPOUT(epdesc->addr))
  974. {
  975. /* It is an OUT interrupt endpoint. There should be only
  976. * one interrupt OUT endpoint.
  977. */
  978. if ((found & USBHOST_EPOUTFOUND) != 0)
  979. {
  980. /* Oops.. more than one endpoint. We don't know
  981. * what to do with this.
  982. */
  983. return -EINVAL;
  984. }
  985. found |= USBHOST_EPOUTFOUND;
  986. /* Save the bulk OUT endpoint information */
  987. epoutdesc.hport = hport;
  988. epoutdesc.addr = epdesc->addr &
  989. USB_EP_ADDR_NUMBER_MASK;
  990. epoutdesc.in = false;
  991. epoutdesc.xfrtype = USB_EP_ATTR_XFER_INT;
  992. epoutdesc.interval = epdesc->interval;
  993. epoutdesc.mxpacketsize =
  994. usbhost_getle16(epdesc->mxpacketsize);
  995. uerr("Interrupt OUT EP addr:%d mxpacketsize:%d\n",
  996. epoutdesc.addr, epoutdesc.mxpacketsize);
  997. }
  998. else
  999. {
  1000. /* It is an IN interrupt endpoint. There should be only
  1001. * one interrupt IN endpoint.
  1002. */
  1003. if ((found & USBHOST_EPINFOUND) != 0)
  1004. {
  1005. /* Oops.. more than one endpoint. We don't know
  1006. * what to do with this.
  1007. */
  1008. return -EINVAL;
  1009. }
  1010. found |= USBHOST_EPINFOUND;
  1011. /* Save the bulk IN endpoint information */
  1012. epindesc.hport = hport;
  1013. epindesc.addr = epdesc->addr &
  1014. USB_EP_ADDR_NUMBER_MASK;
  1015. epindesc.in = true;
  1016. epindesc.xfrtype = USB_EP_ATTR_XFER_INT;
  1017. epindesc.interval = epdesc->interval;
  1018. epindesc.mxpacketsize =
  1019. usbhost_getle16(epdesc->mxpacketsize);
  1020. uerr("Interrupt IN EP addr:%d mxpacketsize:%d\n",
  1021. epindesc.addr, epindesc.mxpacketsize);
  1022. }
  1023. }
  1024. }
  1025. break;
  1026. /* Other descriptors are just ignored for now */
  1027. default:
  1028. break;
  1029. }
  1030. /* If we found everything we need with this interface, then break out
  1031. * of the loop early.
  1032. */
  1033. if (found == USBHOST_ALLFOUND)
  1034. {
  1035. done = true;
  1036. }
  1037. /* Increment the address of the next descriptor */
  1038. configdesc += desc->len;
  1039. remaining -= desc->len;
  1040. }
  1041. /* Sanity checking... did we find all of things that we need? */
  1042. if (found != USBHOST_ALLFOUND)
  1043. {
  1044. uerr("ERROR: Found IF:%s BIN:%s EPOUT:%s\n",
  1045. (found & USBHOST_IFFOUND) != 0 ? "YES" : "NO",
  1046. (found & USBHOST_EPINFOUND) != 0 ? "YES" : "NO",
  1047. (found & USBHOST_EPOUTFOUND) != 0 ? "YES" : "NO");
  1048. return -EINVAL;
  1049. }
  1050. /* We are good... Allocate the endpoints */
  1051. ret = DRVR_EPALLOC(hport->drvr, &epoutdesc, &priv->epout);
  1052. if (ret < 0)
  1053. {
  1054. uerr("ERROR: Failed to allocate Interrupt OUT endpoint\n");
  1055. return ret;
  1056. }
  1057. ret = DRVR_EPALLOC(hport->drvr, &epindesc, &priv->epin);
  1058. if (ret < 0)
  1059. {
  1060. uerr("ERROR: Failed to allocate Interrupt IN endpoint\n");
  1061. DRVR_EPFREE(hport->drvr, priv->epout);
  1062. return ret;
  1063. }
  1064. uinfo("Endpoints allocated\n");
  1065. return OK;
  1066. }
  1067. /****************************************************************************
  1068. * Name: usbhost_devinit
  1069. *
  1070. * Description:
  1071. * The USB device has been successfully connected. This completes the
  1072. * initialization operations. It is first called after the
  1073. * configuration descriptor has been received.
  1074. *
  1075. * This function is called from the connect() method. This function always
  1076. * executes on the thread of the caller of connect().
  1077. *
  1078. * Input Parameters:
  1079. * priv - A reference to the class instance.
  1080. *
  1081. * Returned Value:
  1082. * None
  1083. *
  1084. ****************************************************************************/
  1085. static inline int usbhost_devinit(FAR struct usbhost_state_s *priv)
  1086. {
  1087. char devname[DEV_NAMELEN];
  1088. int ret = OK;
  1089. /* Set aside a transfer buffer for exclusive use by the class driver */
  1090. ret = usbhost_talloc(priv);
  1091. if (ret < 0)
  1092. {
  1093. uerr("ERROR: Failed to allocate transfer buffer\n");
  1094. return ret;
  1095. }
  1096. /* Increment the reference count. This will prevent usbhost_destroy() from
  1097. * being called asynchronously if the device is removed.
  1098. */
  1099. priv->crefs++;
  1100. DEBUGASSERT(priv->crefs == 2);
  1101. /* Start a worker task to poll the USB device. It would be nice to use
  1102. * the NuttX worker thread to do this, but this task needs to wait for
  1103. * events and activities on the worker thread should not involve
  1104. * significant waiting. Having a dedicated thread is more efficient in
  1105. * this sense, but requires more memory resources, primarily for the
  1106. * dedicated stack (CONFIG_XBOXCONTROLLER_STACKSIZE).
  1107. */
  1108. /* The inputs to a task started by kthread_create() are very awkward for
  1109. * this purpose. They are really designed for command line tasks
  1110. * (argc/argv). So the following is kludge pass binary data when the
  1111. * controller poll task is started.
  1112. *
  1113. * First, make sure we have exclusive access to g_priv (what is the
  1114. * likelihood of this being used? About zero, but we protect it anyway).
  1115. */
  1116. ret = usbhost_takesem(&g_exclsem);
  1117. if (ret < 0)
  1118. {
  1119. usbhost_tfree(priv);
  1120. goto errout;
  1121. }
  1122. g_priv = priv;
  1123. uinfo("Starting thread\n");
  1124. priv->pollpid = kthread_create("xbox", CONFIG_XBOXCONTROLLER_DEFPRIO,
  1125. CONFIG_XBOXCONTROLLER_STACKSIZE,
  1126. (main_t)usbhost_xboxcontroller_poll,
  1127. (FAR char * const *)NULL);
  1128. if (priv->pollpid < 0)
  1129. {
  1130. /* Failed to started the poll thread... probably due to memory
  1131. * resources.
  1132. */
  1133. usbhost_givesem(&g_exclsem);
  1134. ret = priv->pollpid;
  1135. goto errout;
  1136. }
  1137. /* Now wait for the poll task to get properly initialized */
  1138. usbhost_forcetake(&g_syncsem);
  1139. usbhost_givesem(&g_exclsem);
  1140. /* Configure the device */
  1141. /* Register the driver */
  1142. uinfo("Register block driver\n");
  1143. usbhost_mkdevname(priv, devname);
  1144. ret = register_driver(devname, &g_xboxcontroller_fops, 0666, priv);
  1145. /* Check if we successfully initialized. We now have to be concerned
  1146. * about asynchronous modification of crefs because the block
  1147. * driver has been registered.
  1148. */
  1149. errout:
  1150. usbhost_forcetake(&priv->exclsem);
  1151. priv->crefs--;
  1152. usbhost_givesem(&priv->exclsem);
  1153. return ret;
  1154. }
  1155. /****************************************************************************
  1156. * Name: usbhost_getle16
  1157. *
  1158. * Description:
  1159. * Get a (possibly unaligned) 16-bit little endian value.
  1160. *
  1161. * Input Parameters:
  1162. * val - A pointer to the first byte of the little endian value.
  1163. *
  1164. * Returned Value:
  1165. * A uint16_t representing the whole 16-bit integer value
  1166. *
  1167. ****************************************************************************/
  1168. static inline uint16_t usbhost_getle16(const uint8_t *val)
  1169. {
  1170. return (uint16_t)val[1] << 8 | (uint16_t)val[0];
  1171. }
  1172. /****************************************************************************
  1173. * Name: usbhost_putle16
  1174. *
  1175. * Description:
  1176. * Put a (possibly unaligned) 16-bit little endian value.
  1177. *
  1178. * Input Parameters:
  1179. * dest - A pointer to the first byte to save the little endian value.
  1180. * val - The 16-bit value to be saved.
  1181. *
  1182. * Returned Value:
  1183. * None
  1184. *
  1185. ****************************************************************************/
  1186. static void usbhost_putle16(uint8_t *dest, uint16_t val)
  1187. {
  1188. dest[0] = val & 0xff; /* Little endian means LS byte first in byte stream */
  1189. dest[1] = val >> 8;
  1190. }
  1191. /****************************************************************************
  1192. * Name: usbhost_getle32
  1193. *
  1194. * Description:
  1195. * Get a (possibly unaligned) 32-bit little 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 Value:
  1202. * None
  1203. *
  1204. ****************************************************************************/
  1205. static inline uint32_t usbhost_getle32(const uint8_t *val)
  1206. {
  1207. /* Little endian means LS halfword first in byte stream */
  1208. return (uint32_t)usbhost_getle16(&val[2]) << 16 |
  1209. (uint32_t)usbhost_getle16(val);
  1210. }
  1211. /****************************************************************************
  1212. * Name: usbhost_putle32
  1213. *
  1214. * Description:
  1215. * Put a (possibly unaligned) 32-bit little endian value.
  1216. *
  1217. * Input Parameters:
  1218. * dest - A pointer to the first byte to save the little endian value.
  1219. * val - The 32-bit value to be saved.
  1220. *
  1221. * Returned Value:
  1222. * None
  1223. *
  1224. ****************************************************************************/
  1225. #if 0 /* Not used */
  1226. static void usbhost_putle32(uint8_t *dest, uint32_t val)
  1227. {
  1228. /* Little endian means LS halfword first in byte stream */
  1229. usbhost_putle16(dest, (uint16_t)(val & 0xffff));
  1230. usbhost_putle16(dest + 2, (uint16_t)(val >> 16));
  1231. }
  1232. #endif
  1233. /****************************************************************************
  1234. * Name: usbhost_talloc
  1235. *
  1236. * Description:
  1237. * Allocate transfer buffer memory.
  1238. *
  1239. * Input Parameters:
  1240. * priv - A reference to the class instance.
  1241. *
  1242. * Returned Value:
  1243. * On success, zero (OK) is returned. On failure, an negated errno value
  1244. * is returned to indicate the nature of the failure.
  1245. *
  1246. ****************************************************************************/
  1247. static inline int usbhost_talloc(FAR struct usbhost_state_s *priv)
  1248. {
  1249. FAR struct usbhost_hubport_s *hport;
  1250. DEBUGASSERT(priv != NULL && priv->usbclass.hport != NULL &&
  1251. priv->tbuffer == NULL);
  1252. hport = priv->usbclass.hport;
  1253. return DRVR_ALLOC(hport->drvr, &priv->tbuffer, &priv->tbuflen);
  1254. }
  1255. /****************************************************************************
  1256. * Name: usbhost_tfree
  1257. *
  1258. * Description:
  1259. * Free transfer buffer memory.
  1260. *
  1261. * Input Parameters:
  1262. * priv - A reference to the class instance.
  1263. *
  1264. * Returned Value:
  1265. * On success, zero (OK) is returned. On failure, an negated errno value
  1266. * is returned to indicate the nature of the failure.
  1267. *
  1268. ****************************************************************************/
  1269. static inline int usbhost_tfree(FAR struct usbhost_state_s *priv)
  1270. {
  1271. FAR struct usbhost_hubport_s *hport;
  1272. int result = OK;
  1273. DEBUGASSERT(priv != NULL && priv->usbclass.hport != NULL);
  1274. if (priv->tbuffer)
  1275. {
  1276. hport = priv->usbclass.hport;
  1277. result = DRVR_FREE(hport->drvr, priv->tbuffer);
  1278. priv->tbuffer = NULL;
  1279. priv->tbuflen = 0;
  1280. }
  1281. return result;
  1282. }
  1283. /****************************************************************************
  1284. * struct usbhost_registry_s methods
  1285. ****************************************************************************/
  1286. /****************************************************************************
  1287. * Name: usbhost_create
  1288. *
  1289. * Description:
  1290. * This function implements the create() method of struct
  1291. * usbhost_registry_s. The create() method is a callback into the class
  1292. * implementation. It is used to (1) create a new instance of the USB
  1293. * host class state and to (2) bind a USB host driver "session" to the
  1294. * class instance. Use of this create() method will support environments
  1295. * where there may be multiple USB ports and multiple USB devices
  1296. * simultaneously connected.
  1297. *
  1298. * Input Parameters:
  1299. * hport - The hub hat manages the new class instance.
  1300. * id - In the case where the device supports multiple base classes,
  1301. * subclasses, or protocols, this specifies which to configure for.
  1302. *
  1303. * Returned Value:
  1304. * On success, this function will return a non-NULL instance of struct
  1305. * usbhost_class_s that can be used by the USB host driver to communicate
  1306. * with the USB host class. NULL is returned on failure; this function
  1307. * will fail only if the hport input parameter is NULL or if there are
  1308. * insufficient resources to create another USB host class instance.
  1309. *
  1310. ****************************************************************************/
  1311. static FAR struct usbhost_class_s *
  1312. usbhost_create(FAR struct usbhost_hubport_s *hport,
  1313. FAR const struct usbhost_id_s *id)
  1314. {
  1315. FAR struct usbhost_state_s *priv;
  1316. /* Allocate a USB host class instance */
  1317. priv = usbhost_allocclass();
  1318. if (priv)
  1319. {
  1320. /* Initialize the allocated storage class instance */
  1321. memset(priv, 0, sizeof(struct usbhost_state_s));
  1322. /* Assign a device number to this class instance */
  1323. if (usbhost_allocdevno(priv) == OK)
  1324. {
  1325. /* Initialize class method function pointers */
  1326. priv->usbclass.hport = hport;
  1327. priv->usbclass.connect = usbhost_connect;
  1328. priv->usbclass.disconnected = usbhost_disconnected;
  1329. /* The initial reference count is 1... One reference is held by the
  1330. * driver.
  1331. */
  1332. priv->crefs = 1;
  1333. /* Initialize semaphores (this works okay in the interrupt
  1334. * context).
  1335. */
  1336. nxsem_init(&priv->exclsem, 0, 1);
  1337. nxsem_init(&priv->waitsem, 0, 0);
  1338. /* The waitsem semaphore is used for signaling and, hence, should
  1339. * not have priority inheritance enabled.
  1340. */
  1341. nxsem_set_protocol(&priv->waitsem, SEM_PRIO_NONE);
  1342. /* Return the instance of the USB class driver */
  1343. return &priv->usbclass;
  1344. }
  1345. }
  1346. /* An error occurred. Free the allocation and return NULL on all failures */
  1347. if (priv)
  1348. {
  1349. usbhost_freeclass(priv);
  1350. }
  1351. return NULL;
  1352. }
  1353. /****************************************************************************
  1354. * struct usbhost_class_s methods
  1355. ****************************************************************************/
  1356. /****************************************************************************
  1357. * Name: usbhost_connect
  1358. *
  1359. * Description:
  1360. * This function implements the connect() method of struct
  1361. * usbhost_class_s. This method is a callback into the class
  1362. * implementation. It is used to provide the device's configuration
  1363. * descriptor to the class so that the class may initialize properly
  1364. *
  1365. * Input Parameters:
  1366. * usbclass - The USB host class entry previously obtained from a call to
  1367. * create().
  1368. * configdesc - A pointer to a uint8_t buffer container the configuration
  1369. * descriptor.
  1370. * desclen - The length in bytes of the configuration descriptor.
  1371. *
  1372. * Returned Value:
  1373. * On success, zero (OK) is returned. On a failure, a negated errno value
  1374. * is returned indicating the nature of the failure
  1375. *
  1376. * NOTE that the class instance remains valid upon return with a failure.
  1377. * It is the responsibility of the higher level enumeration logic to call
  1378. * CLASS_DISCONNECTED to free up the class driver resources.
  1379. *
  1380. * Assumptions:
  1381. * - This function will *not* be called from an interrupt handler.
  1382. * - If this function returns an error, the USB host controller driver
  1383. * must call to DISCONNECTED method to recover from the error
  1384. *
  1385. ****************************************************************************/
  1386. static int usbhost_connect(FAR struct usbhost_class_s *usbclass,
  1387. FAR const uint8_t *configdesc, int desclen)
  1388. {
  1389. FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)usbclass;
  1390. int ret;
  1391. DEBUGASSERT(priv != NULL &&
  1392. configdesc != NULL &&
  1393. desclen >= sizeof(struct usb_cfgdesc_s));
  1394. /* Parse the configuration descriptor to get the endpoints */
  1395. ret = usbhost_cfgdesc(priv, configdesc, desclen);
  1396. if (ret < 0)
  1397. {
  1398. uerr("ERROR: usbhost_cfgdesc() failed: %d\n", ret);
  1399. }
  1400. else
  1401. {
  1402. /* Now configure the device and register the NuttX driver */
  1403. ret = usbhost_devinit(priv);
  1404. if (ret < 0)
  1405. {
  1406. uerr("ERROR: usbhost_devinit() failed: %d\n", ret);
  1407. }
  1408. }
  1409. return ret;
  1410. }
  1411. /****************************************************************************
  1412. * Name: usbhost_disconnected
  1413. *
  1414. * Description:
  1415. * This function implements the disconnected() method of struct
  1416. * usbhost_class_s. This method is a callback into the class
  1417. * implementation. It is used to inform the class that the USB device has
  1418. * been disconnected.
  1419. *
  1420. * Input Parameters:
  1421. * usbclass - The USB host class entry previously obtained from a call to
  1422. * create().
  1423. *
  1424. * Returned Value:
  1425. * On success, zero (OK) is returned. On a failure, a negated errno value
  1426. * is returned indicating the nature of the failure
  1427. *
  1428. * Assumptions:
  1429. * This function may be called from an interrupt handler.
  1430. *
  1431. ****************************************************************************/
  1432. static int usbhost_disconnected(struct usbhost_class_s *usbclass)
  1433. {
  1434. FAR struct usbhost_state_s *priv = (FAR struct usbhost_state_s *)usbclass;
  1435. int i;
  1436. DEBUGASSERT(priv != NULL);
  1437. /* Set an indication to any users of the device that the device is no
  1438. * longer available.
  1439. */
  1440. priv->disconnected = true;
  1441. uinfo("Disconnected\n");
  1442. /* Are there a thread(s) waiting for controller data that will never
  1443. * come?
  1444. */
  1445. for (i = 0; i < priv->nwaiters; i++)
  1446. {
  1447. /* Yes.. wake them up */
  1448. usbhost_givesem(&priv->waitsem);
  1449. }
  1450. /* Possibilities:
  1451. *
  1452. * - Failure occurred before the controller poll task was started
  1453. * successfully. In this case, the disconnection will have to be
  1454. * handled on the worker task.
  1455. * - Failure occurred after the controller poll task was started
  1456. * successfully. In this case, the disconnection can be performed on
  1457. * the mouse poll thread.
  1458. */
  1459. if (priv->polling)
  1460. {
  1461. /* The polling task is still alive. Signal the mouse polling task.
  1462. * When that task wakes up, it will decrement the reference count and,
  1463. * perhaps, destroy the class instance. Then it will exit.
  1464. */
  1465. nxsig_kill(priv->pollpid, SIGALRM);
  1466. }
  1467. else
  1468. {
  1469. /* In the case where the failure occurs before the polling task was
  1470. * started. Now what? We are probably executing from an interrupt
  1471. * handler here. We will use the worker thread. This is kind of
  1472. * wasteful and begs for a re-design.
  1473. */
  1474. DEBUGASSERT(priv->work.worker == NULL);
  1475. work_queue(HPWORK, &priv->work, usbhost_destroy, priv, 0);
  1476. }
  1477. return OK;
  1478. }
  1479. /****************************************************************************
  1480. * Character driver methods
  1481. ****************************************************************************/
  1482. /****************************************************************************
  1483. * Name: usbhost_open
  1484. *
  1485. * Description:
  1486. * Standard character driver open method.
  1487. *
  1488. ****************************************************************************/
  1489. static int usbhost_open(FAR struct file *filep)
  1490. {
  1491. FAR struct inode *inode;
  1492. FAR struct usbhost_state_s *priv;
  1493. irqstate_t flags;
  1494. int ret;
  1495. uinfo("Entry\n");
  1496. DEBUGASSERT(filep && filep->f_inode);
  1497. inode = filep->f_inode;
  1498. priv = inode->i_private;
  1499. /* Make sure that we have exclusive access to the private data structure */
  1500. DEBUGASSERT(priv && priv->crefs > 0 && priv->crefs < USBHOST_MAX_CREFS);
  1501. ret = usbhost_takesem(&priv->exclsem);
  1502. if (ret < 0)
  1503. {
  1504. return ret;
  1505. }
  1506. /* Check if the controller device is still connected. We need to disable
  1507. * interrupts momentarily to assure that there are no asynchronous
  1508. * disconnect events.
  1509. */
  1510. flags = enter_critical_section();
  1511. if (priv->disconnected)
  1512. {
  1513. /* No... the driver is no longer bound to the class. That means that
  1514. * the USB storage device is no longer connected. Refuse any further
  1515. * attempts to open the driver.
  1516. */
  1517. ret = -ENODEV;
  1518. }
  1519. else
  1520. {
  1521. /* Was the driver previously open? We need to perform special
  1522. * initialization on the first time that the driver is opened.
  1523. */
  1524. if (!priv->open)
  1525. {
  1526. /* Set the thresholding values so that the first button press
  1527. * will be reported.
  1528. */
  1529. #ifdef NEVER
  1530. priv->xlast = INVALID_POSITION_B16;
  1531. priv->ylast = INVALID_POSITION_B16;
  1532. #ifdef CONFIG_INPUT_MOUSE_WHEEL
  1533. priv->wlast = INVALID_POSITION_B16;
  1534. #endif
  1535. /* Set the reported position to the center of the range */
  1536. priv->xaccum = (HIDMOUSE_XMAX_B16 >> 1);
  1537. priv->yaccum = (HIDMOUSE_YMAX_B16 >> 1);
  1538. #endif
  1539. }
  1540. /* Otherwise, just increment the reference count on the driver */
  1541. priv->crefs++;
  1542. priv->open = true;
  1543. ret = OK;
  1544. }
  1545. leave_critical_section(flags);
  1546. usbhost_givesem(&priv->exclsem);
  1547. return ret;
  1548. }
  1549. /****************************************************************************
  1550. * Name: usbhost_close
  1551. *
  1552. * Description:
  1553. * Standard character driver close method.
  1554. *
  1555. ****************************************************************************/
  1556. static int usbhost_close(FAR struct file *filep)
  1557. {
  1558. FAR struct inode *inode;
  1559. FAR struct usbhost_state_s *priv;
  1560. irqstate_t flags;
  1561. int ret;
  1562. uinfo("Entry\n");
  1563. DEBUGASSERT(filep && filep->f_inode);
  1564. inode = filep->f_inode;
  1565. priv = inode->i_private;
  1566. /* Decrement the reference count on the driver */
  1567. DEBUGASSERT(priv->crefs >= 1);
  1568. ret = usbhost_takesem(&priv->exclsem);
  1569. if (ret < 0)
  1570. {
  1571. return ret;
  1572. }
  1573. /* We need to disable interrupts momentarily to assure that there are no
  1574. * asynchronous poll or disconnect events.
  1575. */
  1576. flags = enter_critical_section();
  1577. priv->crefs--;
  1578. /* Check if the USB controller device is still connected. If the device is
  1579. * no longer connected, then unregister the driver and free the driver
  1580. * class instance.
  1581. */
  1582. if (priv->disconnected)
  1583. {
  1584. /* If the reference count is one or less then there are two
  1585. * possibilities:
  1586. *
  1587. * 1) It might be zero meaning that the polling thread has already
  1588. * exited and decremented its count.
  1589. * 2) If might be one meaning either that (a) the polling thread is
  1590. * still running and still holds a count, or (b) the polling thread
  1591. * has exited, but there is still an outstanding open reference.
  1592. */
  1593. if (priv->crefs == 0 || (priv->crefs == 1 && priv->polling))
  1594. {
  1595. /* Yes.. In either case, then the driver is no longer open */
  1596. priv->open = false;
  1597. /* Check if the USB keyboard device is still connected. */
  1598. if (priv->crefs == 0)
  1599. {
  1600. /* The polling thread is no longer running */
  1601. DEBUGASSERT(!priv->polling);
  1602. /* If the device is no longer connected, unregister the driver
  1603. * and free the driver class instance.
  1604. */
  1605. usbhost_destroy(priv);
  1606. /* Skip giving the semaphore... it is no longer valid */
  1607. leave_critical_section(flags);
  1608. return OK;
  1609. }
  1610. else /* if (priv->crefs == 1) */
  1611. {
  1612. /* The polling thread is still running. Signal it so that it
  1613. * will wake up and call usbhost_destroy(). The particular
  1614. * signal that we use does not matter in this case.
  1615. */
  1616. nxsig_kill(priv->pollpid, SIGALRM);
  1617. }
  1618. }
  1619. }
  1620. usbhost_givesem(&priv->exclsem);
  1621. leave_critical_section(flags);
  1622. return OK;
  1623. }
  1624. /****************************************************************************
  1625. * Name: usbhost_read
  1626. *
  1627. * Description:
  1628. * Standard character driver read method.
  1629. *
  1630. ****************************************************************************/
  1631. static ssize_t usbhost_read(FAR struct file *filep, FAR char *buffer,
  1632. size_t len)
  1633. {
  1634. FAR struct inode *inode;
  1635. FAR struct usbhost_state_s *priv;
  1636. FAR struct xbox_controller_buttonstate_s sample;
  1637. int ret;
  1638. DEBUGASSERT(filep && filep->f_inode && buffer);
  1639. inode = filep->f_inode;
  1640. priv = inode->i_private;
  1641. /* Make sure that we have exclusive access to the private data structure */
  1642. DEBUGASSERT(priv && priv->crefs > 0 && priv->crefs < USBHOST_MAX_CREFS);
  1643. ret = usbhost_takesem(&priv->exclsem);
  1644. if (ret < 0)
  1645. {
  1646. return ret;
  1647. }
  1648. /* Check if the controller is still connected. We need to disable
  1649. * interrupts momentarily to assure that there are no asynchronous
  1650. * disconnect events.
  1651. */
  1652. if (priv->disconnected)
  1653. {
  1654. /* No... the driver is no longer bound to the class. That means that
  1655. * the USB controller is no longer connected. Refuse any further
  1656. * attempts to access the driver.
  1657. */
  1658. ret = -ENODEV;
  1659. goto errout;
  1660. }
  1661. /* Try to read sample data. */
  1662. ret = usbhost_sample(priv, &sample);
  1663. if (ret < 0)
  1664. {
  1665. /* Sample data is not available now. We would ave to wait to get
  1666. * receive sample data. If the user has specified the O_NONBLOCK
  1667. * option, then just return an error.
  1668. */
  1669. if (filep->f_oflags & O_NONBLOCK)
  1670. {
  1671. /* Yes.. then return a failure */
  1672. ret = -EAGAIN;
  1673. goto errout;
  1674. }
  1675. /* Wait for sample data */
  1676. ret = usbhost_waitsample(priv, &sample);
  1677. ret = 0;
  1678. if (ret < 0)
  1679. {
  1680. /* We might have been awakened by a signal */
  1681. ierr("ERROR: usbhost_waitsample: %d\n", ret);
  1682. goto errout;
  1683. }
  1684. }
  1685. /* We now have sampled controller data that we can report to the caller. */
  1686. memcpy(buffer, &sample, sizeof(struct xbox_controller_buttonstate_s));
  1687. ret = sizeof(struct xbox_controller_buttonstate_s);
  1688. errout:
  1689. usbhost_givesem(&priv->exclsem);
  1690. iinfo("Returning: %d\n", ret);
  1691. return (ssize_t)ret;
  1692. }
  1693. /****************************************************************************
  1694. * Name: usbhost_write
  1695. *
  1696. * Description:
  1697. * Standard character driver write method.
  1698. *
  1699. ****************************************************************************/
  1700. static ssize_t usbhost_write(FAR struct file *filep, FAR const char *buffer,
  1701. size_t len)
  1702. {
  1703. /* Not implemented. */
  1704. return -ENOSYS;
  1705. }
  1706. /****************************************************************************
  1707. * Name: usbhost_ioctl
  1708. *
  1709. * Description:
  1710. * Standard character driver ioctl method.
  1711. *
  1712. ****************************************************************************/
  1713. static int usbhost_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
  1714. {
  1715. FAR struct inode *inode;
  1716. FAR struct usbhost_state_s *priv;
  1717. int ret = 0;
  1718. int nbytes;
  1719. FAR struct usbhost_hubport_s *hport;
  1720. static uint8_t rumble_cmd[] =
  1721. {
  1722. 0x09, 0x00, 0x00, 0x09, 0x00, 0x0f, 0x00,
  1723. 0x00, 0x00, 0x00, 0xff, 0x00, 0xff
  1724. };
  1725. uinfo("Entered\n");
  1726. DEBUGASSERT(filep && filep->f_inode && buffer);
  1727. inode = filep->f_inode;
  1728. priv = inode->i_private;
  1729. hport = priv->usbclass.hport;
  1730. /* Check if the controller is still connected. We need to disable
  1731. * interrupts momentarily to assure that there are no asynchronous
  1732. * disconnect events.
  1733. */
  1734. if (priv->disconnected)
  1735. {
  1736. /* No... the driver is no longer bound to the class. That means that
  1737. * the USB controller is no longer connected. Refuse any further
  1738. * attempts to access the driver.
  1739. */
  1740. ret = -ENODEV;
  1741. goto errout;
  1742. }
  1743. /* Determine which IOCTL command to execute. */
  1744. switch (cmd)
  1745. {
  1746. case XBOX_CONTROLLER_IOCTL_RUMBLE:
  1747. /* The least significant byte is the weak actuator strength.
  1748. * The second byte is the strong actuator strength.
  1749. */
  1750. memcpy(priv->obuffer, rumble_cmd, sizeof(rumble_cmd));
  1751. priv->obuffer[2] = priv->out_seq_num++;
  1752. priv->obuffer[8] = (arg >> 1) & 0xff; /* Strong (left actuator) */
  1753. priv->obuffer[9] = arg & 0xff; /* Weak (right actuator) */
  1754. /* Perform the transfer. */
  1755. nbytes = DRVR_TRANSFER(hport->drvr, priv->epout,
  1756. priv->obuffer, sizeof(rumble_cmd));
  1757. /* Did we encounter an error? */
  1758. if (nbytes < 0)
  1759. {
  1760. ret = nbytes;
  1761. }
  1762. break;
  1763. default:
  1764. ret = -ENOTTY;
  1765. goto errout;
  1766. }
  1767. errout:
  1768. iinfo("Returning: %d\n", ret);
  1769. return ret;
  1770. }
  1771. /****************************************************************************
  1772. * Name: usbhost_poll
  1773. *
  1774. * Description:
  1775. * Standard character driver poll method.
  1776. *
  1777. ****************************************************************************/
  1778. static int usbhost_poll(FAR struct file *filep, FAR struct pollfd *fds,
  1779. bool setup)
  1780. {
  1781. FAR struct inode *inode;
  1782. FAR struct usbhost_state_s *priv;
  1783. int ret;
  1784. int i;
  1785. DEBUGASSERT(filep && filep->f_inode && fds);
  1786. inode = filep->f_inode;
  1787. priv = inode->i_private;
  1788. /* Make sure that we have exclusive access to the private data structure */
  1789. DEBUGASSERT(priv);
  1790. ret = usbhost_takesem(&priv->exclsem);
  1791. if (ret < 0)
  1792. {
  1793. return ret;
  1794. }
  1795. /* Check if the controller is still connected. We need to disable
  1796. * interrupts momentarily to assure that there are no asynchronous
  1797. * disconnect events.
  1798. */
  1799. if (priv->disconnected)
  1800. {
  1801. /* No... the driver is no longer bound to the class. That means that
  1802. * the USB controller is no longer connected. Refuse any further
  1803. * attempts to access the driver.
  1804. */
  1805. ret = -ENODEV;
  1806. }
  1807. else if (setup)
  1808. {
  1809. /* This is a request to set up the poll. Find an available slot for
  1810. * the poll structure reference
  1811. */
  1812. for (i = 0; i < CONFIG_XBOXCONTROLLER_NPOLLWAITERS; i++)
  1813. {
  1814. /* Find an available slot */
  1815. if (!priv->fds[i])
  1816. {
  1817. /* Bind the poll structure and this slot */
  1818. priv->fds[i] = fds;
  1819. fds->priv = &priv->fds[i];
  1820. break;
  1821. }
  1822. }
  1823. if (i >= CONFIG_XBOXCONTROLLER_NPOLLWAITERS)
  1824. {
  1825. fds->priv = NULL;
  1826. ret = -EBUSY;
  1827. goto errout;
  1828. }
  1829. /* Should we immediately notify on any of the requested events? Notify
  1830. * the POLLIN event if there is buffered controller data.
  1831. */
  1832. if (priv->valid)
  1833. {
  1834. usbhost_pollnotify(priv);
  1835. }
  1836. }
  1837. else
  1838. {
  1839. /* This is a request to tear down the poll. */
  1840. struct pollfd **slot = (struct pollfd **)fds->priv;
  1841. DEBUGASSERT(slot);
  1842. /* Remove all memory of the poll setup */
  1843. *slot = NULL;
  1844. fds->priv = NULL;
  1845. }
  1846. errout:
  1847. nxsem_post(&priv->exclsem);
  1848. return ret;
  1849. }
  1850. /****************************************************************************
  1851. * Public Functions
  1852. ****************************************************************************/
  1853. /****************************************************************************
  1854. * Name: usbhost_xboxcontroller_init
  1855. *
  1856. * Description:
  1857. * Initialize the USB class driver. This function should be called
  1858. * be platform-specific code in order to initialize and register support
  1859. * for the USB host class device.
  1860. *
  1861. * Input Parameters:
  1862. * None
  1863. *
  1864. * Returned Value:
  1865. * On success this function will return zero (OK); A negated errno value
  1866. * will be returned on failure.
  1867. *
  1868. ****************************************************************************/
  1869. int usbhost_xboxcontroller_init(void)
  1870. {
  1871. /* Perform any one-time initialization of the class implementation */
  1872. nxsem_init(&g_exclsem, 0, 1);
  1873. nxsem_init(&g_syncsem, 0, 0);
  1874. /* The g_syncsem semaphore is used for signaling and, hence, should not
  1875. * have priority inheritance enabled.
  1876. */
  1877. nxsem_set_protocol(&g_syncsem, SEM_PRIO_NONE);
  1878. /* Advertise our availability to support (certain) devices */
  1879. return usbhost_registerclass(&g_xboxcontroller);
  1880. }