usbHcdLib.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:14k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* usbHcdLib.c - Implements HCD functional API */
  2. /* Copyright 2000 Wind River Systems, Inc. */
  3. /*
  4. Modification history
  5. --------------------
  6. 01e,26jan00,rcb  Change <bytesPerFrame> parameter in usbHcdPipeCreate() to
  7.  <bandwidth> and redefined as UINT32.
  8. 01d,29nov99,rcb  Remove obsolete function usbHcdBusReset().
  9.  Increase frame number fields to 32 bits.
  10. 01c,23nov99,rcb  Replace bandwidth alloc/release functions with pipe
  11.  create/destroy functions...generalizes approach for use
  12.  with OHCI HCD.
  13. 01b,07sep99,rcb  Add support for management callback param in attach.
  14.  Add set-bus-state API.
  15. 01a,09jun99,rcb  First.
  16. */
  17. /*
  18. DESCRIPTION
  19. This file implements the functional interface to the HCD.
  20. */
  21. /* includes */
  22. #include "usb/usbPlatform.h"
  23. #include "string.h"
  24. #include "usb/usbHcdLib.h" /* our API */
  25. /* functions */
  26. /***************************************************************************
  27. *
  28. * hrbInit - Initialize an HCD request block
  29. *
  30. * RETURNS: N/A
  31. */
  32. LOCAL VOID hrbInit 
  33.     (
  34.     pHRB_HEADER pHrb, 
  35.     pHCD_NEXUS pNexus, 
  36.     UINT16 function,
  37.     UINT16 totalLen
  38.     )
  39.     {
  40.     memset (pHrb, 0, totalLen);
  41.     if (pNexus != NULL)
  42. pHrb->handle = pNexus->handle;
  43.     pHrb->function = function;
  44.     pHrb->hrbLength = totalLen;
  45.     }
  46. /***************************************************************************
  47. *
  48. * usbHcdAttach - Attach to the HCD
  49. *
  50. * Attempts to connect the caller to the HCD.  The <param> value is HCD-
  51. * implementation-specific.  Returns an HCD_CLIENT_HANDLE if the HCD was
  52. * able to initialize properly. If <pBusCount> is not NULL, also returns
  53. * number of buses managed through this nexus.
  54. *
  55. * <callback> is an optional pointer to a routine which should be invoked
  56. * if the HCD detects "management events" (e.g., remote wakeup/resume).
  57. * <callbackParam> is a caller-defined parameter which will be passed to
  58. * the <callback> routine each time it is invoked.
  59. *
  60. * RETURNS: OK, or ERROR if unable to initialize HCD.
  61. */
  62. STATUS usbHcdAttach
  63.     (
  64.     HCD_EXEC_FUNC hcdExecFunc,     /* HCD's primary entry point */
  65.     pVOID param,     /* HCD-specific param */
  66.     USB_HCD_MNGMT_CALLBACK callback,/* management callback */
  67.     pVOID callbackParam,     /* parameter to management callback */
  68.     pHCD_NEXUS pNexus,     /* nexus will be initialized on return */
  69.     pUINT16 pBusCount
  70.     )
  71.     {
  72.     HRB_ATTACH hrb;
  73.     STATUS s;
  74.     /* Initialize HRB */
  75.     hrbInit (&hrb.header, NULL, HCD_FNC_ATTACH, sizeof (hrb));
  76.     hrb.param = param;
  77.     hrb.mngmtCallback = callback;
  78.     hrb.mngmtCallbackParam = callbackParam;
  79.     /* Execute HRB */
  80.     s = (*hcdExecFunc) ((pVOID) &hrb);
  81.     /* Return results */
  82.     
  83.     if (pNexus != NULL)
  84. {
  85. pNexus->hcdExecFunc = hcdExecFunc;
  86. pNexus->handle = hrb.header.handle;
  87. }
  88.     if (pBusCount != NULL)
  89. *pBusCount = hrb.busCount;
  90.     return s;
  91.     }
  92. /***************************************************************************
  93. *
  94. * usbHcdDetach - Detach from the HCD
  95. *
  96. * Disconnects a caller which has previously attached to an HCD.
  97. *
  98. * RETURNS: OK, or ERROR if unable to shutdown HCD.
  99. */
  100. STATUS usbHcdDetach
  101.     (
  102.     pHCD_NEXUS pNexus     /* client's nexus */
  103.     )
  104.     {
  105.     HRB_DETACH hrb;
  106.     /* Initialize HRB */
  107.     hrbInit (&hrb.header, pNexus, HCD_FNC_DETACH, sizeof (hrb));
  108.     /* Execute HRB */
  109.     return (*pNexus->hcdExecFunc) ((pVOID) &hrb);
  110.     }
  111. /***************************************************************************
  112. *
  113. * usbHcdSetBusState - sets bus suspend/resume state
  114. *
  115. * Sets the state for <bus> no as specified in <busState>.  <busState>
  116. * is a bit mask.  Typically, the caller will set USB_BUS_SUSPEND or
  117. * USB_BUS_RESUME to suspend or resume the indicated bus.
  118. *
  119. * RETURNS: OK, or ERROR if unable to place bus in specified state
  120. */
  121. STATUS usbHcdSetBusState
  122.     (
  123.     pHCD_NEXUS pNexus,     /* client's nexus */
  124.     UINT16 busNo,     /* bus number */
  125.     UINT16 busState     /* desired bus state */
  126.     )
  127.     {
  128.     HRB_SET_BUS_STATE hrb;
  129.     /* Initialize HRB */
  130.     hrbInit (&hrb.header, pNexus, HCD_FNC_SET_BUS_STATE, sizeof (hrb));
  131.     hrb.busNo = busNo;
  132.     hrb.busState = busState;
  133.     /* Execute HRB */
  134.     return (*pNexus->hcdExecFunc) ((pVOID) &hrb);
  135.     }
  136. /***************************************************************************
  137. *
  138. * usbHcdCurrentFrameGet - Returns current frame number for a bus
  139. *
  140. * Returns the current <pFrameNo> and the frame window, <pFrameWindow>
  141. * for the specified bus.
  142. *
  143. * RETURNS: OK, or ERROR if unable to retrieve current frame number.
  144. */
  145. STATUS usbHcdCurrentFrameGet
  146.     (
  147.     pHCD_NEXUS pNexus,     /* client's nexus */
  148.     UINT16 busNo,     /* bus number */
  149.     pUINT32 pFrameNo,     /* current frame number */
  150.     pUINT32 pFrameWindow     /* size of frame window */
  151.     )
  152.     {
  153.     HRB_CURRENT_FRAME_GET hrb;
  154.     STATUS s;
  155.     /* Initialize HRB */
  156.     hrbInit (&hrb.header, pNexus, HCD_FNC_CURRENT_FRAME_GET, sizeof (hrb));
  157.     hrb.busNo = busNo;
  158.     /* Execute HRB */
  159.     s = (*pNexus->hcdExecFunc) ((pVOID) &hrb);
  160.     /* return results */
  161.     if (pFrameNo != NULL)
  162. *pFrameNo = hrb.frameNo;
  163.     if (pFrameWindow != NULL)
  164. *pFrameWindow = hrb.frameWindow;
  165.     return s;
  166.     }
  167. /***************************************************************************
  168. *
  169. * usbHcdIrpSubmit - Submits an IRP to the HCD for execution
  170. *
  171. * This function passes the <pIrp> to the HCD for scheduling.  The function
  172. * returns as soon as the HCD has queued/scheduled the IRP.  The <pIrp>
  173. * must include a non-NULL <callback> which will be invoked upon IRP
  174. * completion.
  175. *
  176. * RETURNS: OK, or ERROR if unable to submit IRP for transfer.
  177. */
  178. STATUS usbHcdIrpSubmit
  179.     (
  180.     pHCD_NEXUS pNexus,     /* client's nexus */
  181.     HCD_PIPE_HANDLE pipeHandle,     /* pipe to which IRP is directed */
  182.     pUSB_IRP pIrp     /* IRP to be executed */
  183.     )
  184.     {
  185.     HRB_IRP_SUBMIT hrb;
  186.     /* Initialize HRB */
  187.     hrbInit (&hrb.header, pNexus, HCD_FNC_IRP_SUBMIT, sizeof (hrb));
  188.     hrb.pipeHandle = pipeHandle;
  189.     hrb.pIrp = pIrp;
  190.     /* Execute HRB */
  191.     return (*pNexus->hcdExecFunc) ((pVOID) &hrb);
  192.     }
  193. /***************************************************************************
  194. *
  195. * usbHcdIrpCancel - Requests the HCD to cancel a pending IRP
  196. *
  197. * This function requests the HCD to cancel the specified <pIrp>.  If
  198. * the IRP can be canceled before it completes execution normally, its 
  199. * result will be set to S_usbHcdLib_IRP_CANCELED and the IRPs callback
  200. * will be invoked.
  201. *
  202. * There is no guarantee that an IRP, once submitted to the HCD, can be
  203. * canceled before it otherwise completes normally (or times out).
  204. *
  205. * RETURNS: OK, or ERROR if unable to cancel transfer.
  206. */
  207. STATUS usbHcdIrpCancel
  208.     (
  209.     pHCD_NEXUS pNexus,     /* client's nexus */
  210.     pUSB_IRP pIrp     /* IRP to be canceled */
  211.     )
  212.     {
  213.     HRB_IRP_CANCEL hrb;
  214.     /* Initialize HRB */
  215.     hrbInit (&hrb.header, pNexus, HCD_FNC_IRP_CANCEL, sizeof (hrb));
  216.     hrb.pIrp = pIrp;
  217.     /* Execute HRB */
  218.     return (*pNexus->hcdExecFunc) ((pVOID) &hrb);
  219.     }
  220. /***************************************************************************
  221. *
  222. * usbHcdPipeCreate - create a pipe and calculate / reserve bus bandwidth
  223. *
  224. * The USBD calls this function to notify the HCD that it is attempting to
  225. * create a new pipe.  The USBD passes the type of pipe in <transferType>.
  226. *
  227. * If the pipe is an interrupt or isochronous pipe, the HCD calculates the 
  228. * amount of time a transfer of a given number of bytes will require on the 
  229. * bus - measured in nanoseconds (10E-9 seconds).  The formulas used here are 
  230. * taken from Section 5.9.3 of Revision 1.1 of the USB spec.
  231. *
  232. * If enough bus bandwidth is available, then that amount of bandwidth will
  233. * be reserved by the HCD.  Reserved bandwidth must later be released using 
  234. * usbHcdPipeDestroy().
  235. *
  236. * <transferType>, <direction>, and <speed> should describe the characteristics
  237. * of the pipe/transfer as USB_XFRTYPE_xxxx, USB_DIR_xxxx, and USB_SPEED_xxxx,
  238. * repsectively.  <packetSize> is the size of packets to be used.
  239. *
  240. * For interrupt pipes, <bandwidth> is the total number of bytes which will 
  241. * be sent each frame.  For isochronous pipes, <bandwidth> is the number of
  242. * bytes per second.  <bandwidth> should be 0 for control and bulk pipes.
  243. *
  244. * The worst-case transfer time is returned in <pTime>.
  245. *
  246. * The HCD will return an HCD_PIPE_HANDLE in <pPipeHandle>.  The USBD will use
  247. * this HCD_PIPE_HANDLE to identify the pipe in the future.  
  248. *
  249. * RETURNS: OK, or ERROR if unable to reserve bandwdith.
  250. */
  251. STATUS usbHcdPipeCreate
  252.     (
  253.     pHCD_NEXUS pNexus,     /* client's nexus */
  254.     UINT16 busNo,     /* bus number for IRP */
  255.     UINT16 busAddress,     /* bus address of USB device */
  256.     UINT16 endpoint,     /* endpoint on device */
  257.     UINT16 transferType,     /* transfer type */
  258.     UINT16 direction,     /* pipe/transfer direction */
  259.     UINT16 speed,     /* transfer speed */
  260.     UINT16 maxPacketSize,     /* packet size */
  261.     UINT32 bandwidth,     /* bandwidth required by pipe */
  262.     UINT16 interval,     /* service interval */
  263.     pUINT32 pTime,     /* calculated packet time on return */
  264.     pHCD_PIPE_HANDLE pPipeHandle    /* HCD pipe handle */
  265.     )
  266.     {
  267.     HRB_PIPE_CREATE hrb;
  268.     STATUS s;
  269.     /* Initialize HRB */
  270.     hrbInit (&hrb.header, pNexus, HCD_FNC_PIPE_CREATE, sizeof (hrb));
  271.     hrb.busNo = busNo;
  272.     hrb.busAddress = busAddress;
  273.     hrb.endpoint = endpoint;
  274.     hrb.transferType = transferType;
  275.     hrb.direction = direction;
  276.     hrb.speed = speed;
  277.     hrb.maxPacketSize = maxPacketSize;
  278.     hrb.bandwidth = bandwidth;
  279.     hrb.interval = interval;
  280.     /* Execute HRB */
  281.     s = (*pNexus->hcdExecFunc) ((pVOID) &hrb);
  282.     /* return results */
  283.     if (pTime != NULL)
  284. *pTime = hrb.time;
  285.     if (pPipeHandle != NULL)
  286. *pPipeHandle = hrb.pipeHandle;
  287.     return s;
  288.     }
  289.     
  290. /***************************************************************************
  291. *
  292. * usbHcdPipeDestroy - destroys pipe and releases previously allocated bandwidth
  293. *
  294. * Destroys the pipe identified by <pipeHandle> and releases any bandwidth used
  295. * by the pipe.
  296. *
  297. * RETURNS: OK, or ERROR if HCD fails to destroy pipe.
  298. */
  299. STATUS usbHcdPipeDestroy
  300.     (
  301.     pHCD_NEXUS pNexus,     /* client's nexus */
  302.     HCD_PIPE_HANDLE pipeHandle     /* pipe to be destroyed */
  303.     )
  304.     {
  305.     HRB_PIPE_DESTROY hrb;
  306.     /* Initialize HRB */
  307.     hrbInit (&hrb.header, pNexus, HCD_FNC_PIPE_DESTROY, sizeof (hrb));
  308.     hrb.pipeHandle = pipeHandle;
  309.     /* Execute HRB */
  310.     return (*pNexus->hcdExecFunc) ((pVOID) &hrb);
  311.     }
  312. /***************************************************************************
  313. *
  314. * usbHcdPipeModify - modify characteristics of an existing pipe
  315. *
  316. * Two characteristics of a pipe, the device's USB bus address and the 
  317. * maximum packet size, may change after a pipe is first created.  Typically,
  318. * this will happen only with the default control pipe for a given device,
  319. * which must be created before issuing SET_ADDRESS to the device and before
  320. * reading the device descriptor to determine the maximum packet size supported
  321. * by the default control endpoint.  The USBD will typically use this function
  322. * to update either the <busAddress> or the <maxPacketSize> for the indicated
  323. * <pipeHandle>.  If either <busAddress> or <maxPacketSize> is 0, then the
  324. * corresponding pipe attribute remains unchanged.  
  325. *
  326. * RETURNS: OK, or ERROR if HCD fails to modify pipe
  327. */
  328. STATUS usbHcdPipeModify
  329.     (
  330.     pHCD_NEXUS pNexus,     /* client's nexus */
  331.     HCD_PIPE_HANDLE pipeHandle,     /* pipe to be modified */
  332.     UINT16 busAddress,     /* new bus address or 0 */
  333.     UINT16 maxPacketSize     /* new max packet size or 0 */
  334.     )
  335.     {
  336.     HRB_PIPE_MODIFY hrb;
  337.     /* Initialize HRB */
  338.     hrbInit (&hrb.header, pNexus, HCD_FNC_PIPE_MODIFY, sizeof (hrb));
  339.     hrb.pipeHandle = pipeHandle;
  340.     hrb.busAddress = busAddress;
  341.     hrb.maxPacketSize = maxPacketSize;
  342.     /* Execute HRB */
  343.     return (*pNexus->hcdExecFunc) ((pVOID) &hrb);
  344.     }
  345. /***************************************************************************
  346. *
  347. * usbHcdSofIntervalGet - retrieves SOF interval for a bus
  348. *
  349. * Returns the SOF interval for <busNo> in <pSofInterval>.  The SOF 
  350. * interval is expressed in terms of high-speed bit times, and is typically
  351. * close to 12,000.
  352. *
  353. * RETURNS: OK, or ERROR if HCD failed to retrieve SOF interval
  354. */
  355. STATUS usbHcdSofIntervalGet
  356.     (
  357.     pHCD_NEXUS pNexus,     /* client's nexus */
  358.     UINT16 busNo,     /* bus number */
  359.     pUINT16 pSofInterval     /* bfr to receive SOF interval */
  360.     )
  361.     {
  362.     HRB_SOF_INTERVAL_GET_SET hrb;
  363.     STATUS s;
  364.     /* Initialize HRB */
  365.     hrbInit (&hrb.header, pNexus, HCD_FNC_SOF_INTERVAL_GET, sizeof (hrb));
  366.     hrb.busNo = busNo;
  367.     /* Execute HRB */
  368.     s = (*pNexus->hcdExecFunc) ((pVOID) &hrb);
  369.     /* return results */
  370.     if (pSofInterval != NULL)
  371. *pSofInterval = hrb.sofInterval;
  372.     return s;
  373.     }
  374. /***************************************************************************
  375. *
  376. * usbHcdSofIntervalSet - sets SOF interval for a bus
  377. *
  378. * Sets the SOF interval for <busNo> to <sofInterval>.  <sofInterval>
  379. * must express the new SOF interval in terms of high-speed bit times, and
  380. * should be in the neighborhood of 12,000.  Certain HCD implementations
  381. * may impose narrower or wider limits on the allowable <sofInterval>.
  382. *
  383. * RETURNS: OK, or ERROR if HCD failed to set SOF interval.
  384. */
  385. STATUS usbHcdSofIntervalSet
  386.     (
  387.     pHCD_NEXUS pNexus,     /* client's nexus */
  388.     UINT16 busNo,     /* bus number */
  389.     UINT16 sofInterval     /* new SOF interval */
  390.     )
  391.     {
  392.     HRB_SOF_INTERVAL_GET_SET hrb;
  393.     /* Initialize HRB */
  394.     hrbInit (&hrb.header, pNexus, HCD_FNC_SOF_INTERVAL_SET, sizeof (hrb));
  395.     hrb.busNo = busNo;
  396.     hrb.sofInterval = sofInterval;
  397.     /* Execute HRB */
  398.     return (*pNexus->hcdExecFunc) ((pVOID) &hrb);
  399.     }
  400. /* End of file. */