usbdmsc.c 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412
  1. //*****************************************************************************
  2. //
  3. // usbdmsc.c - USB mass storage device class driver.
  4. //
  5. // Copyright (c) 2009-2010 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Texas Instruments (TI) is supplying this software for use solely and
  9. // exclusively on TI's microcontroller products. The software is owned by
  10. // TI and/or its suppliers, and is protected under applicable copyright
  11. // laws. You may not combine this software with "viral" open-source
  12. // software in order to form a larger program.
  13. //
  14. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  15. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  16. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  18. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  19. // DAMAGES, FOR ANY REASON WHATSOEVER.
  20. //
  21. // This is part of revision 6288 of the Stellaris USB Library.
  22. //
  23. //*****************************************************************************
  24. //#include "inc/hw_memmap.h"
  25. #include "hw_usb.h"
  26. #include "hw_types.h"
  27. #include "debug.h"
  28. #include "interrupt.h"
  29. #include "usb.h"
  30. #include "cppi41dma.h"
  31. #include "usblib.h"
  32. #include "usbmsc.h"
  33. #include "usbdevice.h"
  34. #include "usbdmsc.h"
  35. #include "usblibpriv.h"
  36. #include <string.h>
  37. #include <delay.h>
  38. #include <perf.h>
  39. //*****************************************************************************
  40. //
  41. //! \addtogroup msc_device_class_api
  42. //! @{
  43. //
  44. //*****************************************************************************
  45. //*****************************************************************************
  46. //
  47. // These defines control the sizes of USB transfers for data and commands.
  48. //
  49. //*****************************************************************************
  50. #define MAX_TRANSFER_SIZE USB_PACKET_LENGTH
  51. #define COMMAND_BUFFER_SIZE 64
  52. //*****************************************************************************
  53. //
  54. // DMA configuration Parameters
  55. //
  56. //*****************************************************************************
  57. #define DMA_TX_MAX_CHUNK_SIZE (MAX_TRANSFER_SIZE*8) // 512 blocks size, 8 blocks
  58. #define DMA_RX_MAX_CHUNK_SIZE MAX_TRANSFER_SIZE // 1 block
  59. //*****************************************************************************
  60. //
  61. // The subset of endpoint status flags that we consider to be reception
  62. // errors. These are passed to the client via USB_EVENT_ERROR if seen.
  63. //
  64. //*****************************************************************************
  65. #define USB_RX_ERROR_FLAGS (USBERR_DEV_RX_DATA_ERROR | \
  66. USBERR_DEV_RX_OVERRUN | \
  67. USBERR_DEV_RX_FIFO_FULL)
  68. //*****************************************************************************
  69. //
  70. // These are fields that are used by the USB descriptors for the Mass Storage
  71. // Class.
  72. //
  73. //*****************************************************************************
  74. #define USB_MSC_SUBCLASS_SCSI 0x6
  75. #define USB_MSC_PROTO_BULKONLY 0x50
  76. //*****************************************************************************
  77. //
  78. // Endpoints to use for each of the required endpoints in the driver.
  79. //
  80. //*****************************************************************************
  81. #define DATA_IN_ENDPOINT USB_EP_1
  82. #define DATA_IN_DMA_CHANNEL USB_EP_1// UDMA_CHANNEL_USBEP1TX
  83. #define DATA_OUT_ENDPOINT USB_EP_1
  84. #define DATA_OUT_DMA_CHANNEL USB_EP_1//UDMA_CHANNEL_USBEP1RX
  85. //*****************************************************************************
  86. //
  87. // Maximum packet size for the bulk endpoints is 64 bytes.
  88. //
  89. //*****************************************************************************
  90. #define DATA_IN_EP_MAX_SIZE MAX_TRANSFER_SIZE
  91. #define DATA_OUT_EP_MAX_SIZE MAX_TRANSFER_SIZE
  92. //*****************************************************************************
  93. //
  94. // The local buffer used to read in commands and process them.
  95. //
  96. //*****************************************************************************
  97. unsigned char g_pucCommand[COMMAND_BUFFER_SIZE];
  98. unsigned char intStatus = 0;
  99. unsigned int g_bytesRead = 0;
  100. unsigned int g_bytesWritten = 0;
  101. //*****************************************************************************
  102. //
  103. // The current transfer state is held in these variables.
  104. //
  105. //*****************************************************************************
  106. static tMSCCSW g_sSCSICSW={0,0,0,0};
  107. unsigned short gDMAflag =0;
  108. //*****************************************************************************
  109. //
  110. // The current state for the SCSI commands that are being handled and are
  111. // stored in the tMSCInstance.ucSCSIState structure member.
  112. //
  113. //*****************************************************************************
  114. //
  115. // No command in process.
  116. //
  117. #define STATE_SCSI_IDLE 0x00
  118. //
  119. // Sending and reading logical blocks.
  120. //
  121. #define STATE_SCSI_SEND_BLOCKS 0x01
  122. //
  123. // Receiving and writing logical blocks.
  124. //
  125. #define STATE_SCSI_RECEIVE_BLOCKS 0x02
  126. //
  127. // Send the status once the previous transfer is complete.
  128. //
  129. #define STATE_SCSI_SEND_STATUS 0x03
  130. //
  131. // Status was prepared to be sent and now waiting for it to have gone out.
  132. //
  133. #define STATE_SCSI_SENT_STATUS 0x04
  134. #define STATE_SCSI_COMMAND_RCVD 0x05
  135. //*****************************************************************************
  136. //
  137. // USB instance Object
  138. //
  139. //*****************************************************************************
  140. extern tUSBInstanceObject g_USBInstance[];
  141. //*****************************************************************************
  142. //
  143. // Device Descriptor. This is stored in RAM to allow several fields to be
  144. // changed at runtime based on the client's requirements.
  145. //
  146. //*****************************************************************************
  147. static const unsigned char g_pMSCDeviceDescriptor[] =
  148. {
  149. 18, // Size of this structure.
  150. USB_DTYPE_DEVICE, // Type of this structure.
  151. USBShort(0x200), // USB version 1.1 (if we say 2.0, hosts assume
  152. // high-speed - see USB 2.0 spec 9.2.6.6)
  153. 0, // USB Device Class (spec 5.1.1)
  154. 0, // USB Device Sub-class (spec 5.1.1)
  155. 0, // USB Device protocol (spec 5.1.1)
  156. 64, // Maximum packet size for default pipe.
  157. USBShort(0), // Vendor ID (filled in during USBDCDCInit).
  158. USBShort(0), // Product ID (filled in during USBDCDCInit).
  159. USBShort(0x100), // Device Version BCD.
  160. 1, // Manufacturer string identifier.
  161. 2, // Product string identifier.
  162. 3, // Product serial number.
  163. 1 // Number of configurations.
  164. };
  165. //*****************************************************************************
  166. //
  167. // Mass storage device configuration descriptor.
  168. //
  169. // It is vital that the configuration descriptor bConfigurationValue field
  170. // (byte 6) is 1 for the first configuration and increments by 1 for each
  171. // additional configuration defined here. This relationship is assumed in the
  172. // device stack for simplicity even though the USB 2.0 specification imposes
  173. // no such restriction on the bConfigurationValue values.
  174. //
  175. // Note that this structure is deliberately located in RAM since we need to
  176. // be able to patch some values in it based on client requirements.
  177. //
  178. //*****************************************************************************
  179. static unsigned char g_pMSCDescriptor[] =
  180. {
  181. //
  182. // Configuration descriptor header.
  183. //
  184. 9, // Size of the configuration descriptor.
  185. USB_DTYPE_CONFIGURATION, // Type of this descriptor.
  186. USBShort(32), // The total size of this full structure.
  187. 1, // The number of interfaces in this
  188. // configuration.
  189. 1, // The unique value for this configuration.
  190. 0, // The string identifier that describes this
  191. // configuration.
  192. USB_CONF_ATTR_SELF_PWR, // Bus Powered, Self Powered, remote wake up.
  193. 250, // The maximum power in 2mA increments.
  194. };
  195. //*****************************************************************************
  196. //
  197. // The remainder of the configuration descriptor is stored in flash since we
  198. // don't need to modify anything in it at runtime.
  199. //
  200. //*****************************************************************************
  201. const unsigned char g_pMSCInterface[] =
  202. {
  203. //
  204. // Vendor-specific Interface Descriptor.
  205. //
  206. 9, // Size of the interface descriptor.
  207. USB_DTYPE_INTERFACE, // Type of this descriptor.
  208. 0, // The index for this interface.
  209. 0, // The alternate setting for this interface.
  210. 2, // The number of endpoints used by this
  211. // interface.
  212. USB_CLASS_MASS_STORAGE, // The interface class
  213. USB_MSC_SUBCLASS_SCSI, // The interface sub-class.
  214. USB_MSC_PROTO_BULKONLY, // The interface protocol for the sub-class
  215. // specified above.
  216. 0, // The string index for this interface.
  217. //
  218. // Endpoint Descriptor
  219. //
  220. 7, // The size of the endpoint descriptor.
  221. USB_DTYPE_ENDPOINT, // Descriptor type is an endpoint.
  222. USB_EP_DESC_IN | USB_EP_TO_INDEX(DATA_IN_ENDPOINT),
  223. USB_EP_ATTR_BULK, // Endpoint is a bulk endpoint.
  224. USBShort(DATA_IN_EP_MAX_SIZE), // The maximum packet size.
  225. 0, // The polling interval for this endpoint.
  226. //
  227. // Endpoint Descriptor
  228. //
  229. 7, // The size of the endpoint descriptor.
  230. USB_DTYPE_ENDPOINT, // Descriptor type is an endpoint.
  231. USB_EP_DESC_OUT | USB_EP_TO_INDEX(DATA_OUT_ENDPOINT),
  232. USB_EP_ATTR_BULK, // Endpoint is a bulk endpoint.
  233. USBShort(DATA_OUT_EP_MAX_SIZE), // The maximum packet size.
  234. 0, // The polling interval for this endpoint.
  235. };
  236. //*****************************************************************************
  237. //
  238. // The mass storage configuration descriptor is defined as two sections,
  239. // one containing just the 9 byte USB configuration descriptor and the other
  240. // containing everything else that is sent to the host along with it.
  241. //
  242. //*****************************************************************************
  243. const tConfigSection g_sMSCConfigSection =
  244. {
  245. sizeof(g_pMSCDescriptor),
  246. g_pMSCDescriptor
  247. };
  248. const tConfigSection g_sMSCInterfaceSection =
  249. {
  250. sizeof(g_pMSCInterface),
  251. g_pMSCInterface
  252. };
  253. //*****************************************************************************
  254. //
  255. // This array lists all the sections that must be concatenated to make a
  256. // single, complete bulk device configuration descriptor.
  257. //
  258. //*****************************************************************************
  259. const tConfigSection *g_psMSCSections[] =
  260. {
  261. &g_sMSCConfigSection,
  262. &g_sMSCInterfaceSection
  263. };
  264. #define NUM_MSC_SECTIONS (sizeof(g_psMSCSections) / sizeof(tConfigSection *))
  265. //*****************************************************************************
  266. //
  267. // The header for the single configuration we support. This is the root of
  268. // the data structure that defines all the bits and pieces that are pulled
  269. // together to generate the configuration descriptor.
  270. //
  271. //*****************************************************************************
  272. const tConfigHeader g_sMSCConfigHeader =
  273. {
  274. NUM_MSC_SECTIONS,
  275. g_psMSCSections
  276. };
  277. //*****************************************************************************
  278. //
  279. // Configuration Descriptor.
  280. //
  281. //*****************************************************************************
  282. const tConfigHeader * const g_pMSCConfigDescriptors[] =
  283. {
  284. &g_sMSCConfigHeader
  285. };
  286. //*****************************************************************************
  287. //
  288. // Various internal handlers needed by this class.
  289. //
  290. //*****************************************************************************
  291. static void HandleDisconnect(void *pvInstance);
  292. static void ConfigChangeHandler(void *pvInstance, unsigned int ulValue,
  293. unsigned int ulIndex);
  294. static void HandleEndpoints(void *pvInstance, unsigned int ulStatus,
  295. unsigned int ulIndex);
  296. static void HandleRequests(void *pvInstance, tUSBRequest *pUSBRequest,
  297. unsigned int ulIndex);
  298. static void USBDSCSISendStatus(const tUSBDMSCDevice *psDevice,
  299. unsigned int ulIndex);
  300. unsigned int USBDSCSICommand(const tUSBDMSCDevice *psDevice,
  301. tMSCCBW *pSCSICBW, unsigned int ulIndex);
  302. static void HandleDevice(void *pvInstance, unsigned int ulRequest,
  303. void *pvRequestData);
  304. //*****************************************************************************
  305. //
  306. // The FIFO configuration for USB mass storage class device.
  307. //
  308. //*****************************************************************************
  309. const tFIFOConfig g_sUSBMSCFIFOConfig =
  310. {
  311. //
  312. // IN endpoints.
  313. //
  314. {
  315. { 1, false, USB_EP_DEV_IN | USB_EP_DMA_MODE_1 | USB_EP_AUTO_SET },
  316. { 1, false, USB_EP_DEV_IN },
  317. { 1, false, USB_EP_DEV_IN },
  318. { 1, false, USB_EP_DEV_IN },
  319. { 1, false, USB_EP_DEV_IN },
  320. { 1, false, USB_EP_DEV_IN },
  321. { 1, false, USB_EP_DEV_IN },
  322. { 1, false, USB_EP_DEV_IN },
  323. { 1, false, USB_EP_DEV_IN },
  324. { 1, false, USB_EP_DEV_IN },
  325. { 1, false, USB_EP_DEV_IN },
  326. { 1, false, USB_EP_DEV_IN },
  327. { 1, false, USB_EP_DEV_IN },
  328. { 1, false, USB_EP_DEV_IN },
  329. { 1, false, USB_EP_DEV_IN }
  330. },
  331. //
  332. // OUT endpoints.
  333. //
  334. {
  335. { 1, false, USB_EP_DEV_OUT | USB_EP_DMA_MODE_1 | USB_EP_AUTO_CLEAR },
  336. { 1, false, USB_EP_DEV_OUT },
  337. { 1, false, USB_EP_DEV_OUT },
  338. { 1, false, USB_EP_DEV_OUT },
  339. { 1, false, USB_EP_DEV_OUT },
  340. { 1, false, USB_EP_DEV_OUT },
  341. { 1, false, USB_EP_DEV_OUT },
  342. { 1, false, USB_EP_DEV_OUT },
  343. { 1, false, USB_EP_DEV_OUT },
  344. { 1, false, USB_EP_DEV_OUT },
  345. { 1, false, USB_EP_DEV_OUT },
  346. { 1, false, USB_EP_DEV_OUT },
  347. { 1, false, USB_EP_DEV_OUT },
  348. { 1, false, USB_EP_DEV_OUT },
  349. { 1, false, USB_EP_DEV_OUT }
  350. },
  351. };
  352. //*****************************************************************************
  353. //
  354. // The device information structure for the USB MSC device.
  355. //
  356. //*****************************************************************************
  357. tDeviceInfo g_sMSCDeviceInfo =
  358. {
  359. //
  360. // Device event handler callbacks.
  361. //
  362. {
  363. //
  364. // GetDescriptor
  365. //
  366. 0,
  367. //
  368. // RequestHandler
  369. //
  370. HandleRequests,
  371. //
  372. // InterfaceChange
  373. //
  374. 0,
  375. //
  376. // ConfigChange
  377. //
  378. ConfigChangeHandler,
  379. //
  380. // DataReceived
  381. //
  382. 0,
  383. //
  384. // DataSentCallback
  385. //
  386. 0,
  387. //
  388. // ResetHandler
  389. //
  390. 0,
  391. //
  392. // SuspendHandler
  393. //
  394. 0,
  395. //
  396. // ResumeHandler
  397. //
  398. 0,
  399. //
  400. // DisconnectHandler
  401. //
  402. HandleDisconnect,
  403. //
  404. // EndpointHandler
  405. //
  406. HandleEndpoints,
  407. //
  408. // Device handler
  409. //
  410. HandleDevice
  411. },
  412. g_pMSCDeviceDescriptor,
  413. g_pMSCConfigDescriptors,
  414. 0,
  415. 0,
  416. &g_sUSBDefaultFIFOConfig
  417. //&g_sUSBMSCFIFOConfig
  418. };
  419. //*****************************************************************************
  420. //
  421. //! This function is used by an application if it can detect insertion or
  422. //! removal of the media.
  423. //!
  424. //! \param pvInstance is the mass storage device instance that had a media
  425. //! change.
  426. //! \param eMediaStatus is the updated status for the media.
  427. //!
  428. //! This function should be called by an application when it detects a change
  429. //! in the status of the media in use by the USB mass storage class. The
  430. //! \e eMediaStatus parameter will indicate the new status of the media and
  431. //! can also indicate that the application has no knowledge of the media state.
  432. //!
  433. //! There are currently the three following values for the \e eMediaStatus
  434. //! parameter:
  435. //! - USBDMSC_MEDIA_PRESENT indicates that the media is present or has been
  436. //! added.
  437. //! - USBDMSC_MEDIA_NOTPRESENT indicates that the media is not present or was
  438. //! removed.
  439. //! - USBDMSC_MEDIA_UNKNOWN indicates that the application has no knowledge of
  440. //! the media state and the USB mass storage class.
  441. //!
  442. //! It will be left up to the application to call this function whenever it
  443. //! detects a change or simply call it once with USBDMSC_MEDIA_UNKNOWN and
  444. //! allow the mass storage class to infer the state from the remaining device
  445. //! APIs.
  446. //!
  447. //! \note It is recommended that the application use this function to inform
  448. //! the mass storage class of media state changes as it will lead to a more
  449. //! responsive system.
  450. //!
  451. //! \return None.
  452. //
  453. //*****************************************************************************
  454. void
  455. USBDMSCMediaChange(void *pvInstance, tUSBDMSCMediaStatus eMediaStatus)
  456. {
  457. const tUSBDMSCDevice *psDevice;
  458. //
  459. // Create a device instance pointer.
  460. //
  461. psDevice = pvInstance;
  462. //
  463. // Save the current media status.
  464. //
  465. psDevice->psPrivateData->eMediaStatus = eMediaStatus;
  466. }
  467. //*****************************************************************************
  468. //
  469. // This function is called to handle the interrupts on the Bulk endpoints for
  470. // the mass storage class.
  471. //
  472. //*****************************************************************************
  473. static void
  474. HandleEndpoints(void *pvInstance, unsigned int ulStatus, unsigned int ulIndex)
  475. {
  476. tUSBDMSCDevice *psDevice;
  477. tMSCInstance *psInst;
  478. tMSCCBW *pSCSICBW;
  479. unsigned int pendReg = 0;
  480. #ifdef DMA_MODE
  481. unsigned int rxBuffer;
  482. unsigned int txBuffer;
  483. unsigned int dmaStatus = 0;
  484. unsigned int nBlocks;
  485. #else
  486. unsigned int ulMaxsize = MAX_TRANSFER_SIZE;
  487. unsigned int ulSize;
  488. #endif
  489. ASSERT(pvInstance != 0);
  490. //
  491. // Determine if the serial device is in single or composite mode because
  492. // the meaning of ulIndex is different in both cases.
  493. //
  494. psDevice = pvInstance;
  495. //
  496. // Initialize the workspace in the passed instance structure.
  497. //
  498. psInst = psDevice->psPrivateData;
  499. #ifdef DMA_MODE
  500. // Get the Starvation interrupt status
  501. CppiDmaGetINTD0Status(g_USBInstance[ulIndex].uiUSBInstance);
  502. // Get the DMA Interrupt status
  503. pendReg = CppiDmaGetPendStatus(g_USBInstance[ulIndex].uiUSBInstance);
  504. #endif
  505. //
  506. // Handler for the bulk IN data endpoint.
  507. //
  508. if(ulStatus & (1 << USB_EP_TO_INDEX(psInst->ucINEndpoint))
  509. || (pendReg & CPDMA_TX_PENDING))
  510. {
  511. #ifdef DMA_MODE
  512. if(pendReg & CPDMA_TX_PENDING)
  513. {
  514. dmaStatus = dmaTxCompletion(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucINEndpoint);
  515. }
  516. #endif
  517. switch(psInst->ucSCSIState)
  518. {
  519. //
  520. // Handle the case where we are sending out data due to a read
  521. // command.
  522. //
  523. case STATE_SCSI_SEND_BLOCKS:
  524. {
  525. #ifndef DMA_MODE
  526. //
  527. // Decrement the number of bytes left to send.
  528. //
  529. psInst->ulBytesToTransfer -= MAX_TRANSFER_SIZE;
  530. //
  531. //Add the bytes transfered
  532. //
  533. g_bytesRead = g_bytesRead + MAX_TRANSFER_SIZE;
  534. #else //
  535. // Check if DMA is completed, Check the remaining bytes
  536. //
  537. if(dmaStatus == DMA_TX_COMPLETED)
  538. {
  539. if(psInst->ulBytesToTransfer > DMA_TX_MAX_CHUNK_SIZE)
  540. {
  541. psInst->ulBytesToTransfer -= DMA_TX_MAX_CHUNK_SIZE;
  542. g_bytesRead = g_bytesRead + DMA_TX_MAX_CHUNK_SIZE;
  543. }
  544. else
  545. {
  546. g_bytesRead = g_bytesRead +psInst->ulBytesToTransfer;
  547. psInst->ulBytesToTransfer = 0;
  548. }
  549. }
  550. #endif
  551. //
  552. // If we are done then move on to the status phase.
  553. //
  554. if(psInst->ulBytesToTransfer == 0)
  555. {
  556. //
  557. // Set the status so that it can be sent when this
  558. // response has has be successfully sent.
  559. //
  560. g_sSCSICSW.bCSWStatus = 0;
  561. g_sSCSICSW.dCSWDataResidue = 0;
  562. g_bytesRead = 0;
  563. //
  564. // Send back the status once this transfer is complete.
  565. //
  566. psInst->ucSCSIState = STATE_SCSI_SEND_STATUS;
  567. #ifdef DMA_MODE
  568. //
  569. //Disable the RX and TX DMA before sending the CSW
  570. //DMA is not used to send the CSW.
  571. //
  572. disableCoreTxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucINEndpoint);
  573. disableCoreRxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucOUTEndpoint);
  574. #endif
  575. USBDSCSISendStatus(psDevice, ulIndex);
  576. if(psDevice->pfnEventCallback)
  577. {
  578. psDevice->pfnEventCallback(0, USBD_MSC_EVENT_IDLE, 0,
  579. 0);
  580. }
  581. //
  582. // The transfer is complete so don't read anymore data.
  583. //
  584. break;
  585. }
  586. #ifndef DMA_MODE
  587. if(g_bytesRead == DEVICE_BLOCK_SIZE)
  588. {
  589. //
  590. // Move on to the next Logical Block.
  591. //
  592. psInst->ulCurrentLBA++;
  593. g_bytesRead = 0;
  594. }
  595. #endif
  596. //
  597. // Read the new data and send it out.
  598. //
  599. #ifdef DMA_MODE
  600. if(dmaStatus == DMA_TX_COMPLETED)
  601. {
  602. //
  603. //If current DMA is operation is completed, check how may byets remaining
  604. //to send
  605. //
  606. g_bytesRead = 0;
  607. psInst->ulCurrentLBA += (DMA_TX_MAX_CHUNK_SIZE / MAX_TRANSFER_SIZE);
  608. nBlocks = psInst->ulBytesToTransfer / MAX_TRANSFER_SIZE;
  609. if(nBlocks > (DMA_TX_MAX_CHUNK_SIZE / MAX_TRANSFER_SIZE))
  610. nBlocks = (DMA_TX_MAX_CHUNK_SIZE / MAX_TRANSFER_SIZE);
  611. //Allocate buffer for the remaining data
  612. txBuffer = (unsigned int)cppiDmaAllocnBuffer(nBlocks);
  613. if(NULL!=(void *)txBuffer)
  614. {
  615. //
  616. //Read the blocks and send it out
  617. //
  618. psDevice->sMediaFunctions.BlockRead(psInst->pvMedia,
  619. (unsigned char *)txBuffer, psInst->ulCurrentLBA, nBlocks);
  620. doDmaTxTransfer(g_USBInstance[ulIndex].uiUSBInstance, (unsigned char *)txBuffer,
  621. (nBlocks * DEVICE_BLOCK_SIZE), psInst->ucINEndpoint);
  622. }
  623. }
  624. #else
  625. //
  626. // Read the new data and send it out.
  627. //
  628. psDevice->sMediaFunctions.BlockRead(psInst->pvMedia,
  629. (unsigned char *)psInst->pulBuffer,
  630. psInst->ulCurrentLBA, 1);
  631. USBEndpointDataPut(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint,
  632. (unsigned char *)psInst->pulBuffer, MAX_TRANSFER_SIZE);
  633. USBEndpointDataSend(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, USB_TRANS_IN);
  634. #endif
  635. break;
  636. }
  637. //
  638. // Handle sending status.
  639. //
  640. case STATE_SCSI_SEND_STATUS:
  641. {
  642. #ifdef DMA_MODE
  643. //
  644. //Disable the RX and TX DMA before sending the CSW
  645. //DMA is not used to send the CSW.
  646. //
  647. disableCoreTxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucINEndpoint);
  648. disableCoreRxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucOUTEndpoint);
  649. #endif
  650. //
  651. // Indicate success and no extra data coming.
  652. //
  653. USBDSCSISendStatus(psDevice, ulIndex);
  654. break;
  655. }
  656. //
  657. // Handle completing sending status.
  658. //
  659. case STATE_SCSI_SENT_STATUS:
  660. {
  661. #ifdef DMA_MODE
  662. disableCoreTxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucINEndpoint);
  663. disableCoreRxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucOUTEndpoint);
  664. #endif
  665. psInst->ucSCSIState = STATE_SCSI_IDLE;
  666. #ifdef PROFILE_USB_MSC_READ
  667. if(fReadEnabled)
  668. {
  669. g_USBPerfInfo[ulPerfInfoCounter++].ulTimeInTicks = PerfTimerStop();
  670. fReadEnabled = 0;
  671. if (ulPerfInfoCounter==5000)
  672. ulPerfInfoCounter=4999;
  673. }
  674. #endif//PROFILE_USB_MSC_READ
  675. #ifdef PROFILE_USB_MSC_WRITE
  676. if(fWriteEnabled)
  677. {
  678. g_USBPerfInfo[ulPerfInfoCounter++].ulTimeInTicks = PerfTimerStop();
  679. fWriteEnabled = 0;
  680. if (ulPerfInfoCounter==5000)
  681. ulPerfInfoCounter=4999;
  682. }
  683. #endif//PROFILE_USB_MSC_WRITE
  684. break;
  685. }
  686. //
  687. // These cases should not occur as the being in the IDLE state due
  688. // to an IN interrupt is invalid.
  689. //
  690. case STATE_SCSI_IDLE:
  691. default:
  692. {
  693. break;
  694. }
  695. }
  696. }
  697. //
  698. // Handler for the bulk OUT data endpoint.
  699. //
  700. if(ulStatus & (0x10000 << USB_EP_TO_INDEX(psInst->ucOUTEndpoint))
  701. || (pendReg & CPDMA_RX_PENDING))
  702. {
  703. switch(psInst->ucSCSIState)
  704. {
  705. //
  706. // Receiving and writing bytes to the storage device.
  707. //
  708. case STATE_SCSI_RECEIVE_BLOCKS:
  709. {
  710. #ifndef DMA_MODE
  711. //
  712. //Get the data from the FIFO and send Ack
  713. //
  714. USBEndpointDataGet(psInst->ulUSBBase, psInst->ucOUTEndpoint,
  715. (unsigned char *)psInst->pulBuffer, &ulMaxsize);
  716. USBDevEndpointDataAck(psInst->ulUSBBase, psInst->ucOUTEndpoint, false);
  717. //
  718. //Write the data to the block media
  719. //
  720. psDevice->sMediaFunctions.BlockWrite(psInst->pvMedia,
  721. (unsigned char *)psInst->pulBuffer,
  722. psInst->ulCurrentLBA, 1);
  723. #endif
  724. #ifdef DMA_MODE
  725. //
  726. //During receive operation, we need to wait in loop till we recive all data
  727. //
  728. while(CppiDmaGetPendStatus(g_USBInstance[ulIndex].uiUSBInstance) & CPDMA_RX_PENDING)
  729. {
  730. //Decrement the bytes recived
  731. psInst->ulBytesToTransfer -= DMA_RX_MAX_CHUNK_SIZE;
  732. g_bytesWritten = g_bytesWritten + DMA_RX_MAX_CHUNK_SIZE;
  733. #else
  734. psInst->ulBytesToTransfer -= MAX_TRANSFER_SIZE;
  735. g_bytesWritten = g_bytesWritten + MAX_TRANSFER_SIZE;
  736. #endif
  737. #ifdef DMA_MODE
  738. //
  739. //Get the data from the RX completeion queue
  740. //
  741. rxBuffer = dmaRxCompletion(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucOUTEndpoint);
  742. //
  743. //Write the data to the block media
  744. //
  745. psDevice->sMediaFunctions.BlockWrite(psInst->pvMedia,
  746. (unsigned char *)rxBuffer, psInst->ulCurrentLBA, 1);
  747. //
  748. //Load another BD to the receive queue
  749. //
  750. doDmaRxTransfer(g_USBInstance[ulIndex].uiUSBInstance, MAX_TRANSFER_SIZE,
  751. (unsigned char *)rxBuffer, psInst->ucOUTEndpoint);
  752. #endif
  753. if(g_bytesWritten == DEVICE_BLOCK_SIZE)
  754. {
  755. g_bytesWritten = 0;
  756. psInst->ulCurrentLBA++;
  757. }
  758. #ifdef DMA_MODE
  759. }
  760. cppiDmaHandleError(g_USBInstance[ulIndex].uiUSBInstance);
  761. #endif
  762. //
  763. // Check if all bytes have been received.
  764. //
  765. if(psInst->ulBytesToTransfer == 0)
  766. {
  767. //
  768. // Set the status so that it can be sent when this response
  769. // has be successfully sent.
  770. //
  771. g_sSCSICSW.bCSWStatus = 0;
  772. g_sSCSICSW.dCSWDataResidue = 0;
  773. g_bytesWritten = 0;
  774. psInst->ucSCSIState = STATE_SCSI_SEND_STATUS;
  775. #ifdef DMA_MODE
  776. //
  777. //Disable the RX and TX DMA before sending the CSW
  778. //DMA is not used to send the CSW.
  779. //
  780. disableCoreRxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucOUTEndpoint);
  781. disableCoreTxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucINEndpoint);
  782. #endif
  783. //
  784. // Indicate success and no extra data coming.
  785. //
  786. USBDSCSISendStatus(psDevice, ulIndex);
  787. }
  788. break;
  789. }
  790. //
  791. // If there is an OUT transfer in idle state then it was a new
  792. // command.
  793. //
  794. case STATE_SCSI_IDLE:
  795. {
  796. //
  797. // Attempt to handle the new command.
  798. //
  799. #ifdef DMA_MODE
  800. //
  801. //Enable the RX DMA as it is disabled during last CSW
  802. //
  803. enableCoreRxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucOUTEndpoint);
  804. while(!(CppiDmaGetPendStatus(g_USBInstance[ulIndex].uiUSBInstance) & CPDMA_RX_PENDING));
  805. rxBuffer = dmaRxCompletion(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucOUTEndpoint);
  806. pSCSICBW = (tMSCCBW *)rxBuffer;
  807. //
  808. //Recceive the command
  809. //
  810. doDmaRxTransfer(g_USBInstance[ulIndex].uiUSBInstance, MAX_TRANSFER_SIZE,
  811. (unsigned char *)rxBuffer, psInst->ucOUTEndpoint);
  812. #else
  813. ulSize = COMMAND_BUFFER_SIZE;
  814. //
  815. // Receive the command.
  816. //
  817. USBEndpointDataGet(psInst->ulUSBBase, psInst->ucOUTEndpoint,
  818. g_pucCommand, &ulSize);
  819. pSCSICBW = (tMSCCBW *)g_pucCommand;
  820. //
  821. // Acknowledge the OUT data packet.
  822. //
  823. USBDevEndpointDataAck(psInst->ulUSBBase, psInst->ucOUTEndpoint,
  824. false);
  825. #endif
  826. //
  827. // If this is a valid CBW then handle it.
  828. //
  829. if(pSCSICBW->dCBWSignature == CBW_SIGNATURE)
  830. {
  831. g_sSCSICSW.dCSWSignature = CSW_SIGNATURE;
  832. g_sSCSICSW.dCSWTag = pSCSICBW->dCBWTag;
  833. g_sSCSICSW.dCSWDataResidue = 0;
  834. g_sSCSICSW.bCSWStatus = 0;
  835. USBDSCSICommand(psDevice, pSCSICBW, ulIndex);
  836. }
  837. else
  838. {
  839. //
  840. // Just return to the idle state since we are now out of
  841. // sync with the host. This should not happen, but this
  842. // should allow the device to synchronize with the host
  843. // controller.
  844. //
  845. psInst->ucSCSIState = STATE_SCSI_IDLE;
  846. }
  847. break;
  848. }
  849. default:
  850. {
  851. break;
  852. }
  853. }
  854. }
  855. }
  856. //*****************************************************************************
  857. //
  858. // Device instance specific handler.
  859. //
  860. //*****************************************************************************
  861. static void
  862. HandleDevice(void *pvInstance, unsigned int ulRequest, void *pvRequestData)
  863. {
  864. tMSCInstance *psInst;
  865. unsigned char *pucData;
  866. //
  867. // Create the serial instance data.
  868. //
  869. psInst = ((tUSBDMSCDevice *)pvInstance)->psPrivateData;
  870. //
  871. // Create the char array used by the events supported by the USB CDC
  872. // serial class.
  873. //
  874. pucData = (unsigned char *)pvRequestData;
  875. switch(ulRequest)
  876. {
  877. //
  878. // This was an interface change event.
  879. //
  880. case USB_EVENT_COMP_IFACE_CHANGE:
  881. {
  882. psInst->ucInterface = pucData[1];
  883. break;
  884. }
  885. //
  886. // This was an endpoint change event.
  887. //
  888. case USB_EVENT_COMP_EP_CHANGE:
  889. {
  890. //
  891. // Determine if this is an IN or OUT endpoint that has changed.
  892. //
  893. if(pucData[0] & USB_EP_DESC_IN)
  894. {
  895. psInst->ucINEndpoint = INDEX_TO_USB_EP((pucData[1] & 0x7f));
  896. }
  897. else
  898. {
  899. //
  900. // Extract the new endpoint number.
  901. //
  902. psInst->ucOUTEndpoint = INDEX_TO_USB_EP(pucData[1] & 0x7f);
  903. }
  904. break;
  905. }
  906. default:
  907. {
  908. break;
  909. }
  910. }
  911. }
  912. //*****************************************************************************
  913. //
  914. // This function is called by the USB device stack whenever the device is
  915. // disconnected from the host.
  916. //
  917. //*****************************************************************************
  918. static void
  919. HandleDisconnect(void *pvInstance)
  920. {
  921. const tUSBDMSCDevice *psDevice;
  922. ASSERT(pvInstance != 0);
  923. memset(&g_sSCSICSW, 0, sizeof(g_sSCSICSW));
  924. //
  925. // Create the instance pointer.
  926. //
  927. psDevice = (const tUSBDMSCDevice *)pvInstance;
  928. psDevice->psPrivateData->ucSCSIState = STATE_SCSI_IDLE;
  929. psDevice->psPrivateData->ulBytesToTransfer = 0;
  930. psDevice->psPrivateData->ulCurrentLBA = 0;
  931. //
  932. // Close the drive requested.
  933. //
  934. if(psDevice->psPrivateData->pvMedia != 0)
  935. {
  936. psDevice->psPrivateData->pvMedia = 0;
  937. psDevice->sMediaFunctions.Close(0);
  938. }
  939. //
  940. // If we have a control callback, let the client know we are open for
  941. // business.
  942. //
  943. if(psDevice->pfnEventCallback)
  944. {
  945. //
  946. // Pass the connected event to the client.
  947. //
  948. psDevice->pfnEventCallback(pvInstance, USB_EVENT_DISCONNECTED, 0, 0);
  949. }
  950. //UARTprintf("------------------------------------------------------------\n");
  951. }
  952. //*****************************************************************************
  953. //
  954. // This function is called by the USB device stack whenever the device
  955. // configuration changes.
  956. //
  957. //*****************************************************************************
  958. static void
  959. ConfigChangeHandler(void *pvInstance, unsigned int ulValue,
  960. unsigned int ulIndex)
  961. {
  962. tMSCInstance *psInst;
  963. const tUSBDMSCDevice *psDevice;
  964. ASSERT(pvInstance != 0);
  965. //
  966. // Create the instance pointer.
  967. //
  968. psDevice = (const tUSBDMSCDevice *)pvInstance;
  969. //
  970. // Create the serial instance data.
  971. //
  972. psInst = psDevice->psPrivateData;
  973. //
  974. // Insure that DMA is disable whenever the configuration is set.
  975. //
  976. USBEndpointDMADisable(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, USB_EP_DEV_IN);
  977. USBEndpointDMADisable(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucOUTEndpoint, USB_EP_DEV_OUT);
  978. //
  979. // If we have a control callback, let the client know we are open for
  980. // business.
  981. //
  982. if(psDevice->pfnEventCallback)
  983. {
  984. //
  985. // Pass the connected event to the client.
  986. //
  987. psDevice->pfnEventCallback(pvInstance, USB_EVENT_CONNECTED, 0, 0);
  988. }
  989. }
  990. //*****************************************************************************
  991. //
  992. //! This function should be called once for the mass storage class device to
  993. //! initialized basic operation and prepare for enumeration.
  994. //!
  995. //! \param ulIndex is the index of the USB controller to initialize for
  996. //! mass storage class device operation.
  997. //! \param psDevice points to a structure containing parameters customizing
  998. //! the operation of the mass storage device.
  999. //!
  1000. //! In order for an application to initialize the USB device mass storage
  1001. //! class, it must first call this function with the a valid mass storage
  1002. //! device class structure in the \e psDevice parameter. This allows this
  1003. //! function to initialize the USB controller and device code to be prepared to
  1004. //! enumerate and function as a USB mass storage device.
  1005. //!
  1006. //! This function returns a void pointer that must be passed in to all other
  1007. //! APIs used by the mass storage class.
  1008. //!
  1009. //! See the documentation on the tUSBDMSCDevice structure for more information
  1010. //! on how to properly fill the structure members.
  1011. //!
  1012. //! \return Returns 0 on failure or a non-zero void pointer on success.
  1013. //
  1014. //*****************************************************************************
  1015. void *
  1016. USBDMSCInit(unsigned int ulIndex, const tUSBDMSCDevice *psDevice)
  1017. {
  1018. //
  1019. // Check parameter validity.
  1020. //
  1021. ASSERT(ulIndex == 0);
  1022. ASSERT(psDevice);
  1023. ASSERT(psDevice->ppStringDescriptors);
  1024. ASSERT(psDevice->psPrivateData);
  1025. USBDMSCCompositeInit(ulIndex, psDevice);
  1026. //
  1027. // All is well so now pass the descriptors to the lower layer and put
  1028. // the bulk device on the bus.
  1029. //
  1030. USBDCDInit(ulIndex, psDevice->psPrivateData->psDevInfo);
  1031. //
  1032. // Return the pointer to the instance indicating that everything went well.
  1033. //
  1034. return ((void *)psDevice);
  1035. }
  1036. //*****************************************************************************
  1037. //
  1038. //! This function should be called once for the mass storage class device to
  1039. //! initialized basic operation and prepare for enumeration.
  1040. //!
  1041. //! \param ulIndex is the index of the USB controller to initialize for
  1042. //! mass storage class device operation.
  1043. //! \param psDevice points to a structure containing parameters customizing
  1044. //! the operation of the mass storage device.
  1045. //!
  1046. //! An application wishing to make use of a composite
  1047. //! USB bulk communication channel for MSC class needs to call this function.
  1048. //! This function is used for initializing an instance related information of the
  1049. //! MSC device.
  1050. //!
  1051. //! This function returns a void pointer that must be passed in to all other
  1052. //! APIs used by the mass storage class.
  1053. //!
  1054. //! See the documentation on the tUSBDMSCDevice structure for more information
  1055. //! on how to properly fill the structure members.
  1056. //!
  1057. //! \return Returns 0 on failure or a non-zero void pointer on success.
  1058. //
  1059. //*****************************************************************************
  1060. void *
  1061. USBDMSCCompositeInit(unsigned int ulIndex, const tUSBDMSCDevice *psDevice)
  1062. {
  1063. tMSCInstance *psInst;
  1064. tDeviceDescriptor *psDevDesc;
  1065. //
  1066. // Check parameter validity.
  1067. //
  1068. ASSERT(ulIndex == 0);
  1069. ASSERT(psDevice);
  1070. ASSERT(psDevice->ppStringDescriptors);
  1071. ASSERT(psDevice->psPrivateData);
  1072. if(ulIndex == 0)
  1073. {
  1074. g_USBInstance[ulIndex].uiUSBInstance = ulIndex;
  1075. g_USBInstance[ulIndex].uiBaseAddr = USB0_BASE;
  1076. g_USBInstance[ulIndex].uiSubBaseAddr = USB_0_OTGBASE;
  1077. g_USBInstance[ulIndex].uiInterruptNum = SYS_INT_USB0;
  1078. g_USBInstance[ulIndex].uiSubInterruptNum = SYS_INT_USBSSINT;
  1079. g_USBInstance[ulIndex].uiPHYConfigRegAddr = CFGCHIP2_USBPHYCTRL;
  1080. }
  1081. #if (USB_NUM_INSTANCE == 2)
  1082. else if(ulIndex == 1)
  1083. {
  1084. g_USBInstance[ulIndex].uiUSBInstance = ulIndex;
  1085. g_USBInstance[ulIndex].uiBaseAddr = USB1_BASE;
  1086. g_USBInstance[ulIndex].uiSubBaseAddr = USB_1_OTGBASE;
  1087. g_USBInstance[ulIndex].uiInterruptNum = SYS_INT_USB1;
  1088. g_USBInstance[ulIndex].uiSubInterruptNum = SYS_INT_USBSSINT;
  1089. g_USBInstance[ulIndex].uiPHYConfigRegAddr = CFGCHIP2_USB1PHYCTRL;
  1090. }
  1091. #endif
  1092. //
  1093. // Initialize the workspace in the passed instance structure.
  1094. //
  1095. psInst = psDevice->psPrivateData;
  1096. psInst->psConfDescriptor = (tConfigDescriptor *)g_pMSCDescriptor;
  1097. psInst->psDevInfo = &g_sMSCDeviceInfo;
  1098. psInst->ulUSBBase = g_USBInstance[ulIndex].uiBaseAddr;
  1099. psInst->bConnected = false;
  1100. psInst->eMediaStatus = USBDMSC_MEDIA_UNKNOWN;
  1101. //
  1102. // Set the initial interface and endpoints.
  1103. //
  1104. psInst->ucInterface = 0;
  1105. psInst->ucOUTEndpoint = DATA_OUT_ENDPOINT;
  1106. psInst->ucOUTDMA = DATA_OUT_DMA_CHANNEL;
  1107. psInst->ucINEndpoint = DATA_IN_ENDPOINT;
  1108. psInst->ucINDMA = DATA_IN_DMA_CHANNEL;
  1109. //
  1110. // Set the initial SCSI state to idle.
  1111. //
  1112. psInst->ucSCSIState = STATE_SCSI_IDLE;
  1113. //
  1114. // Fix up the device descriptor with the client-supplied values.
  1115. //
  1116. psDevDesc = (tDeviceDescriptor *)psInst->psDevInfo->pDeviceDescriptor;
  1117. psDevDesc->idVendor = psDevice->usVID;
  1118. psDevDesc->idProduct = psDevice->usPID;
  1119. //
  1120. // Fix up the configuration descriptor with client-supplied values.
  1121. //
  1122. psInst->psConfDescriptor->bmAttributes = psDevice->ucPwrAttributes;
  1123. psInst->psConfDescriptor->bMaxPower =
  1124. (unsigned char)(psDevice->usMaxPowermA / 2);
  1125. //
  1126. // Plug in the client's string stable to the device information
  1127. // structure.
  1128. //
  1129. psInst->psDevInfo->ppStringDescriptors = psDevice->ppStringDescriptors;
  1130. psInst->psDevInfo->ulNumStringDescriptors
  1131. = psDevice->ulNumStringDescriptors;
  1132. psInst->psDevInfo->pvInstance = (void *)psDevice;
  1133. //
  1134. // Open the drive requested.
  1135. //
  1136. psInst->pvMedia = psDevice->sMediaFunctions.Open(0);
  1137. if(psInst->pvMedia == 0)
  1138. {
  1139. //
  1140. // There is no media currently present.
  1141. //
  1142. psInst->ucSenseKey = SCSI_RS_KEY_NOT_READY;
  1143. psInst->usAddSenseCode = SCSI_RS_MED_NOT_PRSNT;
  1144. }
  1145. else
  1146. {
  1147. //
  1148. // Media is now ready for use.
  1149. //
  1150. psInst->ucSenseKey = SCSI_RS_KEY_UNIT_ATTN;
  1151. psInst->usAddSenseCode = SCSI_RS_MED_NOTRDY2RDY;
  1152. }
  1153. //
  1154. // Enable Clocking to the USB controller.
  1155. //
  1156. USBModuleClkEnable(ulIndex, g_USBInstance[ulIndex].uiBaseAddr);
  1157. //
  1158. // Turn on USB Phy clock.
  1159. //
  1160. UsbPhyOn(ulIndex);
  1161. //
  1162. // Return the pointer to the instance indicating that everything went well.
  1163. //
  1164. return((void *)psDevice);
  1165. }
  1166. //*****************************************************************************
  1167. //
  1168. //! Shuts down the mass storage device.
  1169. //!
  1170. //! \param pvInstance is the pointer to the device instance structure as
  1171. //! returned by USBDMSCInit() or USBDMSCInitComposite().
  1172. //!
  1173. //! This function terminates mass storage operation for the instance supplied
  1174. //! and removes the device from the USB bus. Following this call, the
  1175. //! \e psDevice instance may not me used in any other call to the mass storage
  1176. //! device other than USBDMSCInit() or USBDMSCInitComposite().
  1177. //!
  1178. //! \return None.
  1179. //
  1180. //*****************************************************************************
  1181. void
  1182. USBDMSCTerm(void *pvInstance)
  1183. {
  1184. const tUSBDMSCDevice *psDevice;
  1185. ASSERT(pvInstance != 0);
  1186. //
  1187. // Create a device instance pointer.
  1188. //
  1189. psDevice = pvInstance;
  1190. //
  1191. // If the media was opened the close it out.
  1192. //
  1193. if(psDevice->psPrivateData->pvMedia == 0)
  1194. {
  1195. psDevice->psPrivateData->pvMedia = 0;
  1196. psDevice->sMediaFunctions.Close(0);
  1197. }
  1198. //
  1199. // Cleanly exit device mode.
  1200. //
  1201. USBDCDTerm(0);
  1202. }
  1203. //*****************************************************************************
  1204. //
  1205. // This function is called by the USB device stack whenever a non-standard
  1206. // request is received.
  1207. //
  1208. // \param pvInstance is instance data for this request.
  1209. // \param pUSBRequest points to the request received.
  1210. //
  1211. // This call parses the provided request structure to determine the command.
  1212. // The only mass storage command supported over endpoint 0 is the Get Max LUN
  1213. // command.
  1214. //
  1215. // \return None.
  1216. //
  1217. //*****************************************************************************
  1218. static void
  1219. HandleRequests(void *pvInstance, tUSBRequest *pUSBRequest,
  1220. unsigned int ulIndex)
  1221. {
  1222. //
  1223. // This class only support a single LUN.
  1224. //
  1225. static const unsigned char ucMaxLun = 0;
  1226. ASSERT(pvInstance != 0);
  1227. //
  1228. // Determine the type of request.
  1229. //
  1230. switch(pUSBRequest->bRequest)
  1231. {
  1232. //
  1233. // A Set Report request is received from the host when it sends an
  1234. // Output report via endpoint 0.
  1235. //
  1236. case USBREQ_GET_MAX_LUN:
  1237. {
  1238. //
  1239. // Send our response to the host.
  1240. //
  1241. USBDCDSendDataEP0(0, (unsigned char *)&ucMaxLun, 1);
  1242. break;
  1243. }
  1244. //
  1245. // This request was not recognized so stall.
  1246. //
  1247. default:
  1248. {
  1249. USBDCDStallEP0(ulIndex);
  1250. break;
  1251. }
  1252. }
  1253. }
  1254. //*****************************************************************************
  1255. //
  1256. // This function is used to handle the SCSI Inquiry command when it is received
  1257. // from the host.
  1258. //
  1259. //*****************************************************************************
  1260. static void
  1261. USBDSCSIInquiry(const tUSBDMSCDevice *psDevice, unsigned int ulIndex)
  1262. {
  1263. int iIdx;
  1264. tMSCInstance *psInst;
  1265. #ifdef DMA_MODE
  1266. unsigned char *cmdBuffer;
  1267. #endif
  1268. //
  1269. // Create the serial instance data.
  1270. //
  1271. psInst = psDevice->psPrivateData;
  1272. //
  1273. // Direct Access device, Removable storage and SCSI 1 responses.
  1274. //
  1275. #ifdef _TMS320C6X
  1276. _mem4(&g_pucCommand[0]) = SCSI_INQ_PDT_SBC | (SCSI_INQ_RMB << 8);
  1277. #else
  1278. *(unsigned int *)&g_pucCommand[0] = SCSI_INQ_PDT_SBC | (SCSI_INQ_RMB << 8);
  1279. #endif
  1280. //
  1281. // Additional Length is fixed at 31 bytes.
  1282. //
  1283. #ifdef _TMS320C6X
  1284. _mem4(&g_pucCommand[4]) = 31;
  1285. #else
  1286. *(unsigned int *)&g_pucCommand[4] = 31;
  1287. #endif
  1288. //
  1289. // Copy the Vendor string.
  1290. //
  1291. for(iIdx = 0; iIdx < 8; iIdx++)
  1292. {
  1293. g_pucCommand[iIdx + 8] = psDevice->pucVendor[iIdx];
  1294. }
  1295. //
  1296. // Copy the Product string.
  1297. //
  1298. for(iIdx = 0; iIdx < 16; iIdx++)
  1299. {
  1300. g_pucCommand[iIdx + 16] = psDevice->pucProduct[iIdx];
  1301. }
  1302. //
  1303. // Copy the Version string.
  1304. //
  1305. for(iIdx = 0; iIdx < 4; iIdx++)
  1306. {
  1307. g_pucCommand[iIdx + 32] = psDevice->pucVersion[iIdx];
  1308. }
  1309. #ifdef DMA_MODE
  1310. //
  1311. //Allocate buffer for the command
  1312. //
  1313. cmdBuffer = (unsigned char*)cppiDmaAllocBuffer();
  1314. memcpy(cmdBuffer, g_pucCommand, 36);
  1315. //
  1316. //send command response
  1317. //
  1318. doDmaTxTransfer(g_USBInstance[ulIndex].uiUSBInstance, cmdBuffer, 36, psInst->ucINEndpoint);
  1319. enableCoreTxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucINEndpoint);
  1320. #else
  1321. //
  1322. // Send the SCSI Inquiry Response.
  1323. //
  1324. USBEndpointDataPut(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, g_pucCommand, 36);
  1325. //
  1326. // Send the data to the host.
  1327. //
  1328. USBEndpointDataSend(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, USB_TRANS_IN);
  1329. #endif
  1330. //
  1331. // Set the status so that it can be sent when this response has
  1332. // has be successfully sent.
  1333. //
  1334. g_sSCSICSW.bCSWStatus = 0;
  1335. g_sSCSICSW.dCSWDataResidue = 0;
  1336. psInst->ucSCSIState = STATE_SCSI_SEND_STATUS;
  1337. }
  1338. //*****************************************************************************
  1339. //
  1340. // This function is used to handle the SCSI Read Capacities command when it is
  1341. // received from the host.
  1342. //
  1343. //*****************************************************************************
  1344. static void
  1345. USBDSCSIReadCapacities(const tUSBDMSCDevice *psDevice, unsigned int ulIndex)
  1346. {
  1347. unsigned int ulBlocks;
  1348. tMSCInstance *psInst;
  1349. #ifdef DMA_MODE
  1350. unsigned char *cmdBuffer;
  1351. #endif
  1352. //
  1353. // Get our instance data pointer.
  1354. //
  1355. psInst = psDevice->psPrivateData;
  1356. if(psInst->pvMedia != 0)
  1357. {
  1358. ulBlocks = psDevice->sMediaFunctions.NumBlocks(psInst->pvMedia);
  1359. #ifdef _TMS320C6X
  1360. _mem4(&g_pucCommand[0]) = 0x08000000;
  1361. #else
  1362. *(unsigned int *)&g_pucCommand[0] = 0x08000000;
  1363. #endif
  1364. //
  1365. // Fill in the number of blocks, the bytes endianness must be changed.
  1366. //
  1367. g_pucCommand[4] = ulBlocks >> 24;
  1368. g_pucCommand[5] = 0xff & (ulBlocks >> 16);
  1369. g_pucCommand[6] = 0xff & (ulBlocks >> 8);
  1370. g_pucCommand[7] = 0xff & (ulBlocks);
  1371. //
  1372. // Current media capacity
  1373. //
  1374. g_pucCommand[8] = 0x02;
  1375. //
  1376. // Fill in the block size, which is fixed at DEVICE_BLOCK_SIZE.
  1377. //
  1378. g_pucCommand[9] = 0xff & (DEVICE_BLOCK_SIZE >> 16);
  1379. g_pucCommand[10] = 0xff & (DEVICE_BLOCK_SIZE >> 8);
  1380. g_pucCommand[11] = 0xff & DEVICE_BLOCK_SIZE;
  1381. //
  1382. // Send out the 12 bytes that are in this response.
  1383. //
  1384. #ifdef DMA_MODE
  1385. //
  1386. //Allocate buffer for the command
  1387. //
  1388. cmdBuffer = (unsigned char*)cppiDmaAllocBuffer();
  1389. ASSERT(NULL!=(void*)cmdBuffer);
  1390. memcpy(cmdBuffer, g_pucCommand, 12);
  1391. //
  1392. //Send the command response
  1393. //
  1394. doDmaTxTransfer(g_USBInstance[ulIndex].uiUSBInstance, cmdBuffer, 12, psInst->ucINEndpoint);
  1395. enableCoreTxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucINEndpoint);
  1396. #else
  1397. USBEndpointDataPut(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, g_pucCommand, 12);
  1398. USBEndpointDataSend(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, USB_TRANS_IN);
  1399. #endif
  1400. //
  1401. // Set the status so that it can be sent when this response has
  1402. // has be successfully sent.
  1403. //
  1404. g_sSCSICSW.bCSWStatus = 0;
  1405. g_sSCSICSW.dCSWDataResidue = 0;
  1406. }
  1407. else
  1408. {
  1409. //
  1410. // Set the status so that it can be sent when this response has
  1411. // has be successfully sent.
  1412. //
  1413. g_sSCSICSW.bCSWStatus = 1;
  1414. g_sSCSICSW.dCSWDataResidue = 0;
  1415. //
  1416. // Stall the IN endpoint
  1417. //
  1418. USBDevEndpointStall(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, USB_EP_DEV_IN);
  1419. //
  1420. // Mark the sense code as valid and indicate that these is no media
  1421. // present.
  1422. //
  1423. psInst->ucErrorCode = SCSI_RS_VALID | SCSI_RS_CUR_ERRORS;
  1424. psInst->ucSenseKey = SCSI_RS_KEY_NOT_READY;
  1425. psInst->usAddSenseCode = SCSI_RS_MED_NOT_PRSNT;
  1426. }
  1427. psInst->ucSCSIState = STATE_SCSI_SEND_STATUS;
  1428. }
  1429. //*****************************************************************************
  1430. //
  1431. // This function is used to handle the SCSI Read Capacity command when it is
  1432. // received from the host.
  1433. //
  1434. //*****************************************************************************
  1435. static void
  1436. USBDSCSIReadCapacity(const tUSBDMSCDevice *psDevice, unsigned int ulIndex)
  1437. {
  1438. unsigned int ulBlocks;
  1439. tMSCInstance *psInst;
  1440. #ifdef DMA_MODE
  1441. unsigned char *cmdBuffer;
  1442. #endif
  1443. //
  1444. // Get our instance data pointer.
  1445. //
  1446. psInst = psDevice->psPrivateData;
  1447. ulBlocks = psDevice->sMediaFunctions.NumBlocks(psInst->pvMedia);
  1448. //
  1449. // Only decrement if any blocks were found.
  1450. //
  1451. if(ulBlocks != 0)
  1452. {
  1453. //
  1454. // One less than the maximum number is the last addressable
  1455. // block.
  1456. //
  1457. ulBlocks--;
  1458. }
  1459. if(psInst->pvMedia != 0)
  1460. {
  1461. //
  1462. // Fill in the number of blocks, the bytes endianness must be changed.
  1463. //
  1464. g_pucCommand[0] = 0xff & (ulBlocks >> 24);
  1465. g_pucCommand[1] = 0xff & (ulBlocks >> 16);
  1466. g_pucCommand[2] = 0xff & (ulBlocks >> 8);
  1467. g_pucCommand[3] = 0xff & (ulBlocks);
  1468. g_pucCommand[4] = 0;
  1469. //
  1470. // Fill in the block size, which is fixed at DEVICE_BLOCK_SIZE.
  1471. //
  1472. g_pucCommand[5] = 0xff & (DEVICE_BLOCK_SIZE >> 16);
  1473. g_pucCommand[6] = 0xff & (DEVICE_BLOCK_SIZE >> 8);
  1474. g_pucCommand[7] = 0xff & DEVICE_BLOCK_SIZE;
  1475. //
  1476. // Send the SCSI Inquiry Response.
  1477. //
  1478. #ifdef DMA_MODE
  1479. //
  1480. //Allocate buffer for the command
  1481. //
  1482. cmdBuffer = (unsigned char*)cppiDmaAllocBuffer();
  1483. ASSERT(NULL!=(void*)cmdBuffer);
  1484. memcpy(cmdBuffer, g_pucCommand, 8);
  1485. //
  1486. //Send the command response
  1487. //
  1488. doDmaTxTransfer(g_USBInstance[ulIndex].uiUSBInstance, cmdBuffer, 8, psInst->ucINEndpoint);
  1489. enableCoreTxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucINEndpoint);
  1490. #else
  1491. USBEndpointDataPut(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, g_pucCommand, 8);
  1492. USBEndpointDataSend(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, USB_TRANS_IN);
  1493. #endif
  1494. //
  1495. // Set the status so that it can be sent when this response has
  1496. // has be successfully sent.
  1497. //
  1498. g_sSCSICSW.bCSWStatus = 0;
  1499. g_sSCSICSW.dCSWDataResidue = 0;
  1500. }
  1501. else
  1502. {
  1503. //
  1504. // Set the status so that it can be sent when this response has
  1505. // has be successfully sent.
  1506. //
  1507. g_sSCSICSW.bCSWStatus = 1;
  1508. g_sSCSICSW.dCSWDataResidue = 0;
  1509. //
  1510. // Stall the IN endpoint
  1511. //
  1512. USBDevEndpointStall(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, USB_EP_DEV_IN);
  1513. //
  1514. // Mark the sense code as valid and indicate that these is no media
  1515. // present.
  1516. //
  1517. psInst->ucErrorCode = SCSI_RS_VALID | SCSI_RS_CUR_ERRORS;
  1518. psInst->ucSenseKey = SCSI_RS_KEY_NOT_READY;
  1519. psInst->usAddSenseCode = SCSI_RS_MED_NOT_PRSNT;
  1520. }
  1521. psInst->ucSCSIState = STATE_SCSI_SEND_STATUS;
  1522. }
  1523. //*****************************************************************************
  1524. //
  1525. // This function is used to handle the SCSI Request Sense command when it is
  1526. // received from the host.
  1527. //
  1528. //*****************************************************************************
  1529. static void
  1530. USBDSCSIRequestSense(const tUSBDMSCDevice *psDevice, unsigned int ulIndex)
  1531. {
  1532. tMSCInstance *psInst;
  1533. #ifdef DMA_MODE
  1534. unsigned char *cmdBuffer;
  1535. #endif
  1536. //
  1537. // Get our instance data pointer.
  1538. //
  1539. psInst = psDevice->psPrivateData;
  1540. //
  1541. // The request sense response.
  1542. //
  1543. g_pucCommand[0] = psInst->ucErrorCode;
  1544. g_pucCommand[1] = 0;
  1545. g_pucCommand[2] = psInst->ucSenseKey;
  1546. g_pucCommand[3] = 0;
  1547. g_pucCommand[4] = 0;
  1548. g_pucCommand[5] = 0;
  1549. g_pucCommand[6] = 0;
  1550. //*(unsigned long *)&g_pucCommand[3] = 0;
  1551. //
  1552. // There are 10 more bytes of data.
  1553. //
  1554. g_pucCommand[7] = 10;
  1555. // *(unsigned long *)&g_pucCommand[8] = 0;
  1556. g_pucCommand[8] = 0;
  1557. g_pucCommand[9] = 0;
  1558. g_pucCommand[10] = 0;
  1559. g_pucCommand[11] = 0;
  1560. //
  1561. // Transition from not ready to ready.
  1562. //
  1563. g_pucCommand[12] = 0xff & (psInst->usAddSenseCode >> 8);
  1564. g_pucCommand[12] = 0xff & (psInst->usAddSenseCode);
  1565. // *(unsigned short *)&g_pucCommand[12] = psInst->usAddSenseCode;
  1566. // *(unsigned long *)&g_pucCommand[14] = 0;
  1567. g_pucCommand[14] = 0;
  1568. g_pucCommand[15] = 0;
  1569. g_pucCommand[16] = 0;
  1570. g_pucCommand[17] = 0;
  1571. //
  1572. // Send the SCSI Inquiry Response.
  1573. //
  1574. #ifdef DMA_MODE
  1575. //
  1576. //Allocate buffer for the command
  1577. //
  1578. cmdBuffer = (unsigned char*)cppiDmaAllocBuffer();
  1579. memcpy(cmdBuffer, g_pucCommand, 18);
  1580. //
  1581. //send the command response
  1582. //
  1583. doDmaTxTransfer(g_USBInstance[ulIndex].uiUSBInstance, cmdBuffer, 18, psInst->ucINEndpoint);
  1584. enableCoreTxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucINEndpoint);
  1585. #else
  1586. USBEndpointDataPut(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, g_pucCommand, 18);
  1587. USBEndpointDataSend(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, USB_TRANS_IN);
  1588. #endif
  1589. //
  1590. // Reset the valid flag on errors.
  1591. //
  1592. psInst->ucErrorCode = SCSI_RS_CUR_ERRORS;
  1593. //
  1594. // Set the status so that it can be sent when this response has
  1595. // has be successfully sent.
  1596. //
  1597. g_sSCSICSW.bCSWStatus = 0;
  1598. g_sSCSICSW.dCSWDataResidue = 0;
  1599. //
  1600. // Move on to the status phase.
  1601. //
  1602. psInst->ucSCSIState = STATE_SCSI_SEND_STATUS;
  1603. }
  1604. //*****************************************************************************
  1605. //
  1606. // This function is used to handle the SCSI Read 10 command when it is
  1607. // received from the host.
  1608. //
  1609. //*****************************************************************************
  1610. static void
  1611. USBDSCSIRead10(const tUSBDMSCDevice *psDevice, tMSCCBW *pSCSICBW,
  1612. unsigned int ulIndex)
  1613. {
  1614. tMSCInstance *psInst;
  1615. unsigned int usNumBlocks;
  1616. #ifdef DMA_MODE
  1617. unsigned int txBuffer;
  1618. unsigned int nBlocks;
  1619. #endif
  1620. //
  1621. // Default the number of blocks.
  1622. //
  1623. usNumBlocks = 0;
  1624. //
  1625. // Get our instance data pointer.
  1626. //
  1627. psInst = psDevice->psPrivateData;
  1628. if(psInst->pvMedia != 0)
  1629. {
  1630. //
  1631. // Get the logical block from the CBW structure. This switching
  1632. // is required to convert from big to little endian.
  1633. //
  1634. psInst->ulCurrentLBA = (pSCSICBW->CBWCB[2] << 24) |
  1635. (pSCSICBW->CBWCB[3] << 16) |
  1636. (pSCSICBW->CBWCB[4] << 8) |
  1637. (pSCSICBW->CBWCB[5] << 0);
  1638. //
  1639. // More bytes to read.
  1640. //
  1641. usNumBlocks = (pSCSICBW->CBWCB[7] << 8) | pSCSICBW->CBWCB[8];
  1642. #ifdef PROFILE_USB_MSC_READ
  1643. g_USBPerfInfo[ulPerfInfoCounter].ulBytesToTransfer = (DEVICE_BLOCK_SIZE * usNumBlocks);
  1644. PerfTimerStart();
  1645. fReadEnabled = 1;
  1646. #endif//PROFILE_USB_MSC_READ
  1647. #ifdef DMA_MODE
  1648. if(usNumBlocks > (DMA_TX_MAX_CHUNK_SIZE / MAX_TRANSFER_SIZE))
  1649. nBlocks = (DMA_TX_MAX_CHUNK_SIZE / MAX_TRANSFER_SIZE);
  1650. else
  1651. nBlocks = usNumBlocks;
  1652. //
  1653. //Allocate buffer for TX data
  1654. //
  1655. txBuffer=(unsigned int)cppiDmaAllocnBuffer(nBlocks);
  1656. //
  1657. // Read the next logical block from the storage device.
  1658. //
  1659. if(NULL!=(void *)txBuffer)
  1660. {
  1661. if(psDevice->sMediaFunctions.BlockRead(psInst->pvMedia,
  1662. ((unsigned char *)txBuffer),
  1663. psInst->ulCurrentLBA, nBlocks) == 0)
  1664. {
  1665. psInst->pvMedia = 0;
  1666. psDevice->sMediaFunctions.Close(0);
  1667. }
  1668. }
  1669. #else
  1670. //
  1671. // Read the next logical block from the storage device.
  1672. //
  1673. if(psDevice->sMediaFunctions.BlockRead(psInst->pvMedia,
  1674. ((unsigned char *)psInst->pulBuffer),
  1675. psInst->ulCurrentLBA, 1) == 0)
  1676. {
  1677. psInst->pvMedia = 0;
  1678. psDevice->sMediaFunctions.Close(0);
  1679. }
  1680. #endif
  1681. }
  1682. //
  1683. // If there is media present then start transferring the data.
  1684. //
  1685. if(psInst->pvMedia != 0)
  1686. {
  1687. //
  1688. // Schedule the remaining bytes to send.
  1689. //
  1690. psInst->ulBytesToTransfer = (DEVICE_BLOCK_SIZE * usNumBlocks);
  1691. #ifdef DMA_MODE
  1692. //
  1693. //Load the DMA queue with the data buffer
  1694. //
  1695. doDmaTxTransfer(g_USBInstance[ulIndex].uiUSBInstance, (unsigned char *)txBuffer,
  1696. (nBlocks *DEVICE_BLOCK_SIZE), psInst->ucINEndpoint);
  1697. //
  1698. //Enable the DMA for TX operation
  1699. //
  1700. enableCoreTxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucINEndpoint);
  1701. #else
  1702. USBEndpointDataPut(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint,
  1703. (unsigned char *)psInst->pulBuffer,
  1704. MAX_TRANSFER_SIZE);
  1705. USBEndpointDataSend(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint,
  1706. USB_TRANS_IN);
  1707. #endif
  1708. //
  1709. // Move on and start sending blocks.
  1710. //
  1711. psInst->ucSCSIState = STATE_SCSI_SEND_BLOCKS;
  1712. if(psDevice->pfnEventCallback)
  1713. {
  1714. psDevice->pfnEventCallback(0, USBD_MSC_EVENT_READING, 0, 0);
  1715. }
  1716. }
  1717. else
  1718. {
  1719. //
  1720. // Set the status so that it can be sent when this response has
  1721. // has be successfully sent.
  1722. //
  1723. g_sSCSICSW.bCSWStatus = 1;
  1724. g_sSCSICSW.dCSWDataResidue = 0;
  1725. //
  1726. // Stall the IN endpoint
  1727. //
  1728. USBDevEndpointStall(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, USB_EP_DEV_IN);
  1729. //
  1730. // Mark the sense code as valid and indicate that these is no media
  1731. // present.
  1732. //
  1733. psInst->ucErrorCode = SCSI_RS_VALID | SCSI_RS_CUR_ERRORS;
  1734. psInst->ucSenseKey = SCSI_RS_KEY_NOT_READY;
  1735. psInst->usAddSenseCode = SCSI_RS_MED_NOT_PRSNT;
  1736. psInst->ucSCSIState = STATE_SCSI_SEND_STATUS;
  1737. }
  1738. }
  1739. //*****************************************************************************
  1740. //
  1741. // This function is used to handle the SCSI Read 10 command when it is
  1742. // received from the host.
  1743. //
  1744. //*****************************************************************************
  1745. static void
  1746. USBDSCSIWrite10(const tUSBDMSCDevice *psDevice, tMSCCBW *pSCSICBW,
  1747. unsigned int ulIndex)
  1748. {
  1749. unsigned short usNumBlocks;
  1750. tMSCInstance *psInst;
  1751. //
  1752. // Get our instance data pointer.
  1753. //
  1754. psInst = psDevice->psPrivateData;
  1755. //
  1756. // If there is media present then start transferring the data.
  1757. //
  1758. if(psInst->pvMedia != 0)
  1759. {
  1760. //
  1761. // Get the logical block from the CBW structure. This switching
  1762. // is required to convert from big to little endian.
  1763. //
  1764. psInst->ulCurrentLBA = (pSCSICBW->CBWCB[2] << 24) |
  1765. (pSCSICBW->CBWCB[3] << 16) |
  1766. (pSCSICBW->CBWCB[4] << 8) |
  1767. (pSCSICBW->CBWCB[5] << 0);
  1768. //
  1769. // More bytes to read.
  1770. //
  1771. usNumBlocks = (pSCSICBW->CBWCB[7] << 8) | pSCSICBW->CBWCB[8];
  1772. psInst->ulBytesToTransfer = DEVICE_BLOCK_SIZE * usNumBlocks;
  1773. //UARTprintf("#Blocks: %30d, #Bytes: %30d \n", usNumBlocks, psInst->ulBytesToTransfer);
  1774. #ifdef PROFILE_USB_MSC_WRITE
  1775. g_USBPerfInfo[ulPerfInfoCounter].ulBytesToTransfer = psInst->ulBytesToTransfer;
  1776. PerfTimerStart();
  1777. fWriteEnabled = 1;
  1778. #endif//PROFILE_USB_MSC_WRITE
  1779. //
  1780. // Start sending logical blocks, these are always multiples of
  1781. // DEVICE_BLOCK_SIZE bytes.
  1782. //
  1783. psInst->ucSCSIState = STATE_SCSI_RECEIVE_BLOCKS;
  1784. #ifdef DMA_MODE
  1785. enableCoreRxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucOUTEndpoint);
  1786. #endif
  1787. //
  1788. // Notify the application of the write event.
  1789. //
  1790. if(psDevice->pfnEventCallback)
  1791. {
  1792. psDevice->pfnEventCallback(0, USBD_MSC_EVENT_WRITING, 0, 0);
  1793. }
  1794. }
  1795. else
  1796. {
  1797. //
  1798. // Set the status so that it can be sent when this response has
  1799. // has be successfully sent.
  1800. //
  1801. g_sSCSICSW.bCSWStatus = 1;
  1802. g_sSCSICSW.dCSWDataResidue = 0;
  1803. //
  1804. // Stall the IN endpoint
  1805. //
  1806. USBDevEndpointStall(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucOUTEndpoint, USB_EP_DEV_OUT);
  1807. //
  1808. // Mark the sense code as valid and indicate that these is no media
  1809. // present.
  1810. //
  1811. psInst->ucErrorCode = SCSI_RS_VALID | SCSI_RS_CUR_ERRORS;
  1812. psInst->ucSenseKey = SCSI_RS_KEY_NOT_READY;
  1813. psInst->usAddSenseCode = SCSI_RS_MED_NOT_PRSNT;
  1814. psInst->ucSCSIState = STATE_SCSI_SEND_STATUS;
  1815. }
  1816. }
  1817. //*****************************************************************************
  1818. //
  1819. // This function is used to handle the SCSI Mode Sense 6 command when it is
  1820. // received from the host.
  1821. //
  1822. //*****************************************************************************
  1823. static void
  1824. USBDSCSIModeSense6(const tUSBDMSCDevice *psDevice, tMSCCBW *pSCSICBW,
  1825. unsigned int ulIndex)
  1826. {
  1827. tMSCInstance *psInst;
  1828. #ifdef DMA_MODE
  1829. unsigned char *cmdBuffer;
  1830. #endif
  1831. //
  1832. // Get our instance data pointer.
  1833. //
  1834. psInst = psDevice->psPrivateData;
  1835. //
  1836. // If there is media present send the response.
  1837. //
  1838. if(psInst->pvMedia != 0)
  1839. {
  1840. //
  1841. // Three extra bytes in this response.
  1842. //
  1843. g_pucCommand[0] = 3;
  1844. g_pucCommand[1] = 0;
  1845. g_pucCommand[2] = 0;
  1846. g_pucCommand[3] = 0;
  1847. //
  1848. // Manually send the response back to the host.
  1849. //
  1850. #ifdef DMA_MODE
  1851. //
  1852. //Allocate buffer for the command
  1853. //
  1854. cmdBuffer = (unsigned char*)cppiDmaAllocBuffer();
  1855. memcpy(cmdBuffer, g_pucCommand, 4);
  1856. //
  1857. //Send the command response
  1858. //
  1859. doDmaTxTransfer(g_USBInstance[ulIndex].uiUSBInstance, cmdBuffer, 4, psInst->ucINEndpoint);
  1860. enableCoreTxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucINEndpoint);
  1861. #else
  1862. USBEndpointDataPut(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, g_pucCommand, 4);
  1863. USBEndpointDataSend(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, USB_TRANS_IN);
  1864. #endif
  1865. //
  1866. // Set the status so that it can be sent when this response has
  1867. // has be successfully sent.
  1868. //
  1869. g_sSCSICSW.bCSWStatus = 0;
  1870. g_sSCSICSW.dCSWDataResidue = pSCSICBW->dCBWDataTransferLength - 4;
  1871. }
  1872. else
  1873. {
  1874. //
  1875. // Set the status so that it can be sent when this response has
  1876. // has be successfully sent.
  1877. //
  1878. g_sSCSICSW.bCSWStatus = 1;
  1879. g_sSCSICSW.dCSWDataResidue = 0;
  1880. //
  1881. // Stall the IN endpoint
  1882. //
  1883. USBDevEndpointStall(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, USB_EP_DEV_IN);
  1884. //
  1885. // Mark the sense code as valid and indicate that these is no media
  1886. // present.
  1887. //
  1888. psInst->ucErrorCode = SCSI_RS_VALID | SCSI_RS_CUR_ERRORS;
  1889. psInst->ucSenseKey = SCSI_RS_KEY_NOT_READY;
  1890. psInst->usAddSenseCode = SCSI_RS_MED_NOT_PRSNT;
  1891. }
  1892. psInst->ucSCSIState = STATE_SCSI_SEND_STATUS;
  1893. }
  1894. //*****************************************************************************
  1895. //
  1896. // This function is used to send out the response data based on the current
  1897. // status of the mass storage class.
  1898. //
  1899. //*****************************************************************************
  1900. static void
  1901. USBDSCSISendStatus(const tUSBDMSCDevice *psDevice, unsigned int ulIndex)
  1902. {
  1903. tMSCInstance *psInst;
  1904. //
  1905. // Get our instance data pointer.
  1906. //
  1907. psInst = psDevice->psPrivateData;
  1908. //
  1909. // Respond with the requested status.
  1910. //
  1911. USBEndpointDataPut(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint,
  1912. (unsigned char *)&g_sSCSICSW, 13);
  1913. USBEndpointDataSend(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint, USB_TRANS_IN);
  1914. //
  1915. // Move the state to status sent so that the next interrupt will move the
  1916. // statue to idle.
  1917. //
  1918. psInst->ucSCSIState = STATE_SCSI_SENT_STATUS;
  1919. }
  1920. //*****************************************************************************
  1921. //
  1922. // This function is used to handle all SCSI commands.
  1923. //
  1924. //*****************************************************************************
  1925. unsigned int
  1926. USBDSCSICommand(const tUSBDMSCDevice *psDevice, tMSCCBW *pSCSICBW,
  1927. unsigned int ulIndex)
  1928. {
  1929. unsigned int ulRetCode;
  1930. unsigned int ulTransferLength;
  1931. tMSCInstance *psInst;
  1932. //
  1933. // Get our instance data pointer.
  1934. //
  1935. psInst = psDevice->psPrivateData;
  1936. //
  1937. // Initialize the return code.
  1938. //
  1939. ulRetCode = 1;
  1940. //
  1941. // Save the transfer length because it may be overwritten by some calls.
  1942. //
  1943. ulTransferLength = pSCSICBW->dCBWDataTransferLength;
  1944. switch(pSCSICBW->CBWCB[0])
  1945. {
  1946. //
  1947. // Respond to the SCSI Inquiry command.
  1948. //
  1949. case SCSI_INQUIRY_CMD:
  1950. {
  1951. USBDSCSIInquiry(psDevice, ulIndex);
  1952. break;
  1953. }
  1954. //
  1955. // Respond to the test unit ready command.
  1956. //
  1957. case SCSI_TEST_UNIT_READY:
  1958. {
  1959. g_sSCSICSW.dCSWDataResidue = 0;
  1960. if(psInst->pvMedia != 0)
  1961. {
  1962. //
  1963. // Set the status to success for now, this could be different
  1964. // if there is no media present.
  1965. //
  1966. g_sSCSICSW.bCSWStatus = 0;
  1967. }
  1968. else
  1969. {
  1970. //
  1971. // Since there was no media, check for media here.
  1972. //
  1973. psInst->pvMedia = psDevice->sMediaFunctions.Open(0);
  1974. //
  1975. // If it is still not present then fail this command.
  1976. //
  1977. if(psInst->pvMedia != 0)
  1978. {
  1979. g_sSCSICSW.bCSWStatus = 0;
  1980. }
  1981. else
  1982. {
  1983. g_sSCSICSW.bCSWStatus = 1;
  1984. }
  1985. }
  1986. break;
  1987. }
  1988. //
  1989. // Handle the Read Capacities command.
  1990. //
  1991. case SCSI_READ_CAPACITIES:
  1992. {
  1993. USBDSCSIReadCapacities(psDevice, ulIndex);
  1994. break;
  1995. }
  1996. //
  1997. // Handle the Read Capacity command.
  1998. //
  1999. case SCSI_READ_CAPACITY:
  2000. {
  2001. USBDSCSIReadCapacity(psDevice, ulIndex);
  2002. break;
  2003. }
  2004. //
  2005. // Handle the Request Sense command.
  2006. //
  2007. case SCSI_REQUEST_SENSE:
  2008. {
  2009. USBDSCSIRequestSense(psDevice, ulIndex);
  2010. break;
  2011. }
  2012. //
  2013. // Handle the Read 10 command.
  2014. //
  2015. case SCSI_READ_10:
  2016. {
  2017. USBDSCSIRead10(psDevice, pSCSICBW, ulIndex);
  2018. break;
  2019. }
  2020. //
  2021. // Handle the Write 10 command.
  2022. //
  2023. case SCSI_WRITE_10:
  2024. {
  2025. USBDSCSIWrite10(psDevice, pSCSICBW, ulIndex);
  2026. break;
  2027. }
  2028. //
  2029. // Handle the Mode Sense 6 command.
  2030. //
  2031. case SCSI_MODE_SENSE_6:
  2032. {
  2033. USBDSCSIModeSense6(psDevice, pSCSICBW, ulIndex);
  2034. break;
  2035. }
  2036. case SCSI_VERIFY_10:
  2037. {
  2038. psInst->ucSCSIState = STATE_SCSI_IDLE;
  2039. g_sSCSICSW.bCSWStatus = 0;
  2040. g_sSCSICSW.dCSWDataResidue = pSCSICBW->dCBWDataTransferLength;
  2041. break;
  2042. }
  2043. default:
  2044. {
  2045. psInst->ucSCSIState = STATE_SCSI_IDLE;
  2046. //
  2047. // Set the status so that it can be sent when this response has
  2048. // has be successfully sent.
  2049. //
  2050. g_sSCSICSW.bCSWStatus = 1;
  2051. g_sSCSICSW.dCSWDataResidue = pSCSICBW->dCBWDataTransferLength;
  2052. //
  2053. // If there is data then there is more work to do.
  2054. //
  2055. if(pSCSICBW->dCBWDataTransferLength != 0)
  2056. {
  2057. if(pSCSICBW->bmCBWFlags & CBWFLAGS_DIR_IN)
  2058. {
  2059. //
  2060. // Stall the IN endpoint
  2061. //
  2062. USBDevEndpointStall(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucINEndpoint,
  2063. USB_EP_DEV_IN);
  2064. }
  2065. else
  2066. {
  2067. //
  2068. // Stall the OUT endpoint
  2069. //
  2070. USBDevEndpointStall(g_USBInstance[ulIndex].uiBaseAddr, psInst->ucOUTEndpoint,
  2071. USB_EP_DEV_OUT);
  2072. }
  2073. //
  2074. // Send the status once the stall occurs.
  2075. //
  2076. psInst->ucSCSIState = STATE_SCSI_SEND_STATUS;
  2077. }
  2078. //
  2079. // Set the sense codes.
  2080. //
  2081. psInst->ucErrorCode = SCSI_RS_VALID | SCSI_RS_CUR_ERRORS;
  2082. psInst->ucSenseKey = SCSI_RS_KEY_ILGL_RQST;
  2083. psInst->usAddSenseCode = SCSI_RS_PV_INVALID;
  2084. break;
  2085. }
  2086. }
  2087. //
  2088. // If there is no data then send out the current status.
  2089. //
  2090. if(ulTransferLength == 0)
  2091. {
  2092. #ifdef DMA_MODE
  2093. disableCoreTxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucINEndpoint);
  2094. disableCoreRxDMA(g_USBInstance[ulIndex].uiUSBInstance, psInst->ucOUTEndpoint);
  2095. #endif
  2096. USBDSCSISendStatus(psDevice, ulIndex);
  2097. }
  2098. return(ulRetCode);
  2099. }
  2100. //*****************************************************************************
  2101. //
  2102. // Close the Doxygen group.
  2103. //! @}
  2104. //
  2105. //*****************************************************************************