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

VxWorks

开发平台:

C/C++

  1. /* usbPciStub.c - System-specific PCI Functions */
  2. /* Copyright 2000 Wind River Systems, Inc. */
  3. /*
  4. Modification history
  5. --------------------
  6. 01a,22nov00,wef  First, created from 01h of the mcp750 bsp stub
  7. */
  8. /*
  9. DESCRIPTION
  10. This file defines a skeleton of functions to be used for accessing 
  11. the PCI bus capabilities.  These functions allow PCI device drivers 
  12. to be written independent of the underlying O/S's PCI access mechanisms.
  13. The name of each function in this group begins with "usb" to represent
  14. "Device Driver Services."
  15. */
  16. /* Includes */
  17. #include "vxWorks.h"
  18. #include "string.h"
  19. #include "sysLib.h"
  20. #include "cacheLib.h"
  21. #include "iv.h"
  22. #include "intLib.h"
  23. #include "drv/pci/pciConfigLib.h"   /* VxWorks PCI funcs */
  24. #include "usb/usbPlatform.h" /* Basic definitions */
  25. #include "usb/usbPciLib.h" /* Our API */
  26. #error "usbPciStub.c: Customize the USB PCI macros before first use"
  27. /*
  28.  * TODO: Read and update this stub file to customize it for this
  29.  * BSP.  Delete the #error statement above afterwards. Look for
  30.  * TODO references in this file.
  31.  */
  32. /*
  33.  * TODO: Adjust the 3 macros below as needed.
  34.  *
  35.  * USB_PCI_IO_OFFSET is the offset between a physical PCI IO address
  36.  * and the virtual address used to access it.  In this example code,
  37.  * PCI IO addresses map one-to-one with virtual IO addresses used
  38.  * by the sysInByte() and sysOutByte() routines.  In a memory
  39.  * mapped system it would be very unlikely for this value to be zero.
  40.  *
  41.  * USB_PCI_MEMIO_OFFSET is the offset between Memory IO (non prefetch)
  42.  * PCI physical addresses and the local virtual address that corresponds
  43.  * to it.
  44.  *
  45.  * USB_PCI_MEM_OFFSET is the offset between Memory (prefetchable) PCI
  46.  * physical addresses and the local virtual address that corresponds
  47.  * to it.
  48.  */
  49. #define USB_PCI_IO_OFFSET 0x0
  50. #define USB_PCI_MEMIO_OFFSET 0x0
  51. #define USB_PCI_MEM_OFFSET 0x0
  52. /*
  53.  * TODO: Define the following macros to describe how to connect
  54.  * and disconnect interrupts on your hardware.  This should
  55.  * normally be mapped to the pciIntLib functions.
  56.  */
  57. /* Interrupt enable/disable mappings */
  58. #define USB_INT_CONNECT(intNo, func, param) 
  59.     pciIntConnect (INUM_TO_IVEC(intNo), (VOIDFUNCPTR) func, (int) param)
  60. #define USB_INT_DISCONNECT(intNo, func, param) 
  61.     pciIntDisconnect2 (INUM_TO_IVEC(intNo), (VOIDFUNCPTR) func, (int) param)
  62. #define USB_INT_ENABLE(i) intEnable (i)
  63. #define USB_INT_DISABLE(i) intDisable (i)
  64. /*
  65.  * TODO: Define the following macros to read/write data
  66.  * to/from PCI I/O space as needed.  This may be I/O
  67.  * mapped accesses or memory accesses.  This example
  68.  * code assumes I/O mapped accesses using sysInByte
  69.  * functions provided by the BSP sysLib module.
  70.  */
  71. /* Map I/O functions to underlying system functions. */
  72. #define USB_PCI_IN_BYTE(a) sysInByte ((a) + USB_PCI_IO_OFFSET)
  73. #define USB_PCI_IN_WORD(a) sysInWord ((a) + USB_PCI_IO_OFFSET)
  74. #define USB_PCI_IN_DWORD(a) sysInLong ((a) + USB_PCI_IO_OFFSET)
  75. #define USB_PCI_OUT_BYTE(a,v) sysOutByte ((a) + USB_PCI_IO_OFFSET, (v))
  76. #define USB_PCI_OUT_WORD(a,v) sysOutWord ((a) + USB_PCI_IO_OFFSET, (v))
  77. #define USB_PCI_OUT_DWORD(a,v) sysOutLong ((a) + USB_PCI_IO_OFFSET, (v))
  78. /* code tracks usage count for interrupts 0..USB_MAX_INT_NO-1. */
  79. #define USB_MAX_INT_NO 16
  80. /* TODO: Leave the code below this point alone. */
  81. /* locals */
  82. LOCAL UINT16 intUsage [USB_MAX_INT_NO] = {0};
  83. /***************************************************************************
  84. *
  85. * usbPciClassFind - Locates PCI devices by class.
  86. *
  87. * A caller uses this function to locate a PCI device by its PCI class.
  88. * The caller must specify the <pciClass>, <subClass>, and <pgmIf> for the
  89. * device being sought. The function returns the first matching device
  90. * for <index> = 0, the second for <index> = 1, and so forth.  The
  91. * bus number, device number, and function number for the matching device 
  92. * are returned in the <pBusNo>, <pDeviceNo>, and <pFuncNo> buffers provided 
  93. * by the caller. 
  94. *
  95. *
  96. * RETURNS:
  97. * Returns TRUE if matching device found, FALSE if device not found.
  98. */
  99. BOOL usbPciClassFind
  100.     (
  101.     UINT8 pciClass, /* PCI device class */
  102.     UINT8 subClass, /* PCI device sub-class */
  103.     UINT8 pgmIf, /* Programming interface */
  104.     UINT16 index, /* Caller wants nth matching dev */
  105.     pUINT8 pBusNo, /* Bus number of matching dev */
  106.     pUINT8 pDeviceNo, /* Device number of matching dev */
  107.     pUINT8 pFuncNo /* Function number of matching dev */
  108.     )
  109.     {
  110.     int intBusNo; /* VxWorks returns "int" values */
  111.     int intDeviceNo;
  112.     int intFuncNo;
  113.     
  114.     /* Use the VxWorks PCI config. library to find a device within the
  115.     specified class. */
  116.     if (pciFindClass ((pciClass << 16) | (subClass << 8) | pgmIf, index,
  117. &intBusNo, &intDeviceNo, &intFuncNo) != OK)
  118. {
  119. return FALSE;
  120. }
  121.     else
  122. {
  123. if (pBusNo)
  124.      *pBusNo = (UINT8) intBusNo;
  125. if (pDeviceNo)
  126.      *pDeviceNo = (UINT8) intDeviceNo;
  127. if (pFuncNo)
  128.      *pFuncNo = (UINT8) intFuncNo;
  129. }
  130.     return TRUE;
  131.     }
  132. /***************************************************************************
  133. *
  134. * usbPciByteGet - Returns a UINT8 configuration value
  135. *
  136. * This function returns the UINT8 value at offset <regOffset> from 
  137. * the PCI configuration space of the device identified by <busNo>, 
  138. * <deviceNo>, and <funcNo>.
  139. *
  140. * RETURNS: UINT8 value read from device configuration space
  141. */
  142. UINT8 usbPciByteGet 
  143.     (
  144.     UINT8 busNo, /* Bus number of device */
  145.     UINT8 deviceNo, /* Device number of device */
  146.     UINT8 funcNo, /* Function number of device */
  147.     UINT16 regOffset /* Offset into PCI config space */
  148.     )
  149.     {
  150.     UINT8 value;
  151.     if (pciConfigInByte (busNo, deviceNo, funcNo, regOffset, &value) != OK)
  152. return 0;
  153.     return value;
  154.     }
  155. /***************************************************************************
  156. *
  157. * usbPciWordGet - Returns a UINT16 configuration value
  158. *
  159. * This function returns the UINT16 value at offset <regOffset> from 
  160. * the PCI configuration space of the device identified by <busNo>, 
  161. * <deviceNo>, and <funcNo>.
  162. *
  163. * NOTE: This function adjusts for big vs. little endian environments.
  164. *
  165. * RETURNS: UINT16 value read from device configuration space
  166. */
  167. UINT32 usbPciWordGet
  168.     (
  169.     UINT8 busNo, /* Bus number of device */
  170.     UINT8 deviceNo, /* Device number of device */
  171.     UINT8 funcNo, /* Function number of device */
  172.     UINT16 regOffset /* Offset into PCI config space */
  173.     )
  174.     {
  175.     UINT16 value;
  176.     if (pciConfigInWord (busNo, deviceNo, funcNo, regOffset, &value) != OK)
  177. return 0;
  178.     return value;
  179.     }
  180. /***************************************************************************
  181. *
  182. * usbPciDwordGet - Returns a UINT32 configuration value
  183. *
  184. * This function returns the UINT32 value at offset <regOffset> from 
  185. * the PCI configuration space of the device identified by <busNo>, 
  186. * <deviceNo>, and <funcNo>.
  187. *
  188. * NOTE: This function adjusts for big vs. little endian environments.
  189. *
  190. * RETURNS: UINT32 value read from device configuration space
  191. */
  192. UINT32 usbPciDwordGet
  193.     (
  194.     UINT8 busNo, /* Bus number of device */
  195.     UINT8 deviceNo, /* Device number of device */
  196.     UINT8 funcNo, /* Function number of device */
  197.     UINT16 regOffset /* Offset into PCI config space */
  198.     )
  199.     {
  200.     UINT32 value;
  201.     if (pciConfigInLong (busNo, deviceNo, funcNo, regOffset, &value) != OK)
  202. return 0;
  203.     return value;
  204.     }
  205. /***************************************************************************
  206. *
  207. * usbPciConfigHeaderGet - Reads a device's PCI configuration header
  208. *
  209. * This function reads the PCI configuration header for the device
  210. * identified by <busNo>, <deviceNo>, and <funcNo>.  The configuration
  211. * header is stored in the <pCfgHdr> buffer provided by the caller.
  212. *
  213. * This function initializes the <pCfgHdr> structure to zeros.  Any 
  214. * fields which cannot be read from the device's configuration header 
  215. * will remain zero upon return.  This function does not attempt to read
  216. * fields defined as "reserved" in the PCI configuration header.
  217. *
  218. * RETURNS: N/A
  219. */
  220. VOID usbPciConfigHeaderGet
  221.     (
  222.     UINT8 busNo, /* Bus number of device */
  223.     UINT8 deviceNo, /* Device number of device */
  224.     UINT8 funcNo, /* Function number of device */
  225.     pPCI_CFG_HEADER pCfgHdr /* Buffer provided by caller */
  226.     )
  227.     {
  228.     int i;
  229.     /* Do nothing if CfgHdr is NULL */
  230.     if (pCfgHdr == NULL)
  231. return;
  232.     /* Initialize the buffer to zeros. */
  233.     memset (pCfgHdr, 0, sizeof (*pCfgHdr));
  234.     /* Read and store each field in the PCI configuration header. */
  235.     pCfgHdr->vendorId = usbPciWordGet (busNo, deviceNo, funcNo, PCI_CFG_VENDOR_ID);
  236.     pCfgHdr->deviceId = usbPciWordGet (busNo, deviceNo, funcNo, PCI_CFG_DEVICE_ID);
  237.     pCfgHdr->command = usbPciWordGet (busNo, deviceNo, funcNo, PCI_CFG_COMMAND);
  238.     pCfgHdr->status = usbPciWordGet (busNo, deviceNo, funcNo, PCI_CFG_STATUS);
  239.     pCfgHdr->revisionId = usbPciByteGet (busNo, deviceNo, funcNo, PCI_CFG_REVISION);
  240.     pCfgHdr->pgmIf = usbPciByteGet (busNo, deviceNo, funcNo, PCI_CFG_PROGRAMMING_IF);
  241.     pCfgHdr->subClass = usbPciByteGet (busNo, deviceNo, funcNo, PCI_CFG_SUBCLASS);
  242.     pCfgHdr->pciClass = usbPciByteGet (busNo, deviceNo, funcNo, PCI_CFG_CLASS);
  243.     pCfgHdr->cacheLineSize = usbPciByteGet (busNo, deviceNo, funcNo, PCI_CFG_CACHE_LINE_SIZE);
  244.     pCfgHdr->latencyTimer = usbPciByteGet (busNo, deviceNo, funcNo, PCI_CFG_LATENCY_TIMER);
  245.     pCfgHdr->headerType = usbPciByteGet (busNo, deviceNo, funcNo, PCI_CFG_HEADER_TYPE);
  246.     pCfgHdr->bist = usbPciByteGet (busNo, deviceNo, funcNo, PCI_CFG_BIST);
  247.     for (i = 0; i < PCI_CFG_NUM_BASE_REG; i++)
  248. pCfgHdr->baseReg [i] = usbPciDwordGet (busNo, deviceNo, funcNo, 
  249.     PCI_CFG_BASE_ADDRESS_0 + i * sizeof (UINT32));
  250.     pCfgHdr->romBase = usbPciDwordGet (busNo, deviceNo, funcNo, PCI_CFG_EXPANSION_ROM);
  251.     pCfgHdr->intLine = usbPciByteGet (busNo, deviceNo, funcNo, PCI_CFG_DEV_INT_LINE);
  252.     pCfgHdr->intPin = usbPciByteGet (busNo, deviceNo, funcNo, PCI_CFG_DEV_INT_PIN);
  253.     pCfgHdr->minGrant = usbPciByteGet (busNo, deviceNo, funcNo, PCI_CFG_MIN_GRANT);
  254.     pCfgHdr->maxLatency = usbPciByteGet (busNo, deviceNo, funcNo, PCI_CFG_MAX_LATENCY);
  255.     }
  256. /***************************************************************************
  257. *
  258. * usbPciByteIn - input a byte from PCI I/O space
  259. *
  260. * Inputs a byte from a PCI I/O address <address>.
  261. *
  262. * RETURNS: byte input from i/o address
  263. */
  264. UINT8 usbPciByteIn
  265.     (
  266.     UINT32 address /* PCI I/O address */
  267.     )
  268.     {
  269.     return USB_PCI_IN_BYTE (address);
  270.     }
  271. /***************************************************************************
  272. *
  273. * usbPciWordIn - input a word from PCI I/O space
  274. *
  275. * Inputs a word from a PCI I/O address <address>.
  276. *
  277. * NOTE: This function adjusts for big vs. little endian environments.
  278. *
  279. * RETURNS: word input from i/o address
  280. */
  281. UINT16 usbPciWordIn
  282.     (
  283.     UINT32 address /* PCI I/O address */
  284.     )
  285.     {
  286.     UINT16 w = USB_PCI_IN_WORD (address);
  287.     return FROM_LITTLEW (w);
  288.     }
  289. /***************************************************************************
  290. *
  291. * usbPciDwordIn - input a dword from PCI I/O space
  292. *
  293. * Inputs a dword from a PCI I/O address <address>.
  294. *
  295. * NOTE: This function adjusts for big vs. little endian environments.
  296. *
  297. * RETURNS: dword input from i/o address
  298. */
  299. UINT32 usbPciDwordIn
  300.     (
  301.     UINT32 address /* PCI I/O address */
  302.     )
  303.     {
  304.     UINT32 l = USB_PCI_IN_DWORD (address);
  305.     return FROM_LITTLEL (l);
  306.     }
  307. /***************************************************************************
  308. *
  309. * usbPciByteOut - output a byte to PCI I/O space
  310. *
  311. * Outputs <value> to the PCI I/O address <address>.
  312. *
  313. * RETURNS: N/A
  314. */
  315. VOID usbPciByteOut
  316.     (
  317.     UINT32 address, /* PCI I/O address */
  318.     UINT8 value  /* value */
  319.     )
  320.     {
  321.     USB_PCI_OUT_BYTE (address, value);
  322.     CACHE_PIPE_FLUSH ();
  323.     }
  324. /***************************************************************************
  325. *
  326. * usbPciWordOut - outputs a word to PCI I/O space
  327. *
  328. * Outputs <value> to the PCI I/O address <address>.
  329. *
  330. * NOTE: This function adjusts for big vs. little endian environments.
  331. *
  332. * RETURNS: N/A
  333. */
  334. VOID usbPciWordOut
  335.     (
  336.     UINT32 address, /* PCI I/O address */
  337.     UINT16 value /* value */
  338.     )
  339.     {
  340.     UINT16 w = TO_LITTLEW (value);
  341.     USB_PCI_OUT_WORD (address, w);
  342.     CACHE_PIPE_FLUSH ();
  343.     }
  344. /***************************************************************************
  345. *
  346. * usbPciDwordOut - outputs a dword to PCI I/O space
  347. *
  348. * Outputs <value> to the PCI I/O address <address>.
  349. *
  350. * NOTE: This function adjusts for big vs. little endian environments.
  351. *
  352. * RETURNS: N/A
  353. */
  354. VOID usbPciDwordOut
  355.     (
  356.     UINT32 address, /* PCI I/O address */
  357.     UINT32 value /* value */
  358.     )
  359.     {
  360.     UINT32 l = TO_LITTLEL (value);
  361.     USB_PCI_OUT_DWORD (address, l);
  362.     CACHE_PIPE_FLUSH ();
  363.     }
  364. /***************************************************************************
  365. *
  366. * usbPciMemioOffset - Return PCI MEMIO to CPU MEMIO offset
  367. *
  368. * For memory-mapped I/O, the CPU's view of a memory address may not be the
  369. * same as that programmed into the base address register of a PCI adapter.
  370. * The CPU should add the value returned by this function to the BAR in order
  371. * to produce the correct CPU-visible memory address.
  372. *
  373. * RETURNS: USB_PCI_MEMIO_OFFSET
  374. */
  375. UINT32 usbPciMemioOffset (void)
  376.     {
  377.     return USB_PCI_MEMIO_OFFSET;
  378.     }
  379. /***************************************************************************
  380. *
  381. * usbMemToPci - Convert a memory address to a PCI-reachable memory address
  382. *
  383. * Converts <pMem> to an equivalent 32-bit memory address visible from the 
  384. * PCI bus.  This conversion is necessary to allow PCI bus masters to address
  385. * the same memory viewed by the processor.
  386. *
  387. * RETURNS: converted memory address
  388. */
  389. UINT32 usbMemToPci
  390.     (
  391.     pVOID pMem /* memory address to convert */
  392.     )
  393.     {
  394.     pVOID pPhys;
  395.     
  396.     /* The conversion is a two-step process.  First, we need to convert the
  397.      * logical processor address (virtual) to a physical address.  Then, we
  398.      * convert the physical address to one which can be seen from the PCI
  399.      * bus.
  400.      */
  401.     pPhys = CACHE_DRV_VIRT_TO_PHYS (&cacheUserFuncs, pMem);
  402.     return ((UINT32) pPhys) + USB_PCI_MEM_OFFSET;
  403.     }
  404. /***************************************************************************
  405. *
  406. * usbPciToMem - Convert a PCI-reachable address to a CPU-reachable pointer
  407. *
  408. * Converts <pciAdrs> to an equivalent CPU memory address.  
  409. *
  410. * RETURNS: pointer to PCI memory
  411. */
  412. pVOID usbPciToMem
  413.     (
  414.     UINT32 pciAdrs /* 32-bit PCI address to be converted */
  415.     )
  416.     {
  417.     return CACHE_DRV_PHYS_TO_VIRT (&cacheUserFuncs, 
  418. (void *) (pciAdrs - USB_PCI_MEM_OFFSET));
  419.     }
  420. /***************************************************************************
  421. *
  422. * usbPciMemInvalidate - Invalidate cache for a region of memory
  423. *
  424. * When another bus master, such as a PCI bus master, writes to memory, the
  425. * cache may need to be invalidated for that region of memory.
  426. *
  427. * NOTE: Returns immediately if size == 0.
  428. *
  429. * RETURNS: N/A
  430. */
  431. VOID usbPciMemInvalidate
  432.     (
  433.     pVOID pMem,  /* base of memory region to invalidate */
  434.     UINT32 size  /* size of region to invalidate */
  435.     )
  436.     {
  437.     if (size != 0)
  438. CACHE_USER_INVALIDATE (pMem, size);
  439.     }
  440. /***************************************************************************
  441. *
  442. * usbPciMemFlush - Flush a region of memory through the cache
  443. *
  444. * In systems which implement a non-write-thru cache, the processor may have
  445. * written data to memory which has not yet been flushed to the actual system
  446. * memory.  Before other bus masters may interrogate this memory, it may be
  447. * necessary to flush the cache.
  448. *
  449. * NOTE: Returns immediately if size == 0.
  450. *
  451. * RETURNS: N/A
  452. */
  453. VOID usbPciMemFlush
  454.     (
  455.     pVOID pMem,  /* base of memory region to invalidate */
  456.     UINT32 size  /* size of region to invalidate */
  457.     )
  458.     {
  459.     if (size != 0)
  460. CACHE_USER_FLUSH (pMem, size);
  461.     }
  462. /***************************************************************************
  463. *
  464. * usbPciIntConnect - Connect to a interrupt vector
  465. *
  466. * Connects the <func> to the interrupt number <intNo>. <param> is an
  467. * application-specific value which will be passed to <func> each time
  468. * the interrupt handler is invoked.  
  469. *
  470. * RETURNS: OK, or ERROR if unable to connect/enable interrupt
  471. */
  472. STATUS usbPciIntConnect
  473.     (
  474.     INT_HANDLER_PROTOTYPE func,     /* new interrupt handler */
  475.     pVOID param,     /* parameter for int handler */
  476.     UINT16 intNo     /* interrupt vector number */
  477.     )
  478.     {
  479.     if (USB_INT_CONNECT (intNo, func, param) != OK)
  480. return ERROR;
  481.     if (USB_INT_ENABLE (intNo) != OK)
  482. {
  483. USB_INT_DISCONNECT (intNo, func, param);
  484. return ERROR;
  485. }
  486.     if (intNo < USB_MAX_INT_NO) 
  487. intUsage [intNo]++;
  488.     return OK;
  489.     }
  490. /***************************************************************************
  491. *
  492. * usbPciIntDisconnect - Removes an interrupt handler
  493. *
  494. * Removes an interrupt handler installed by usbPciIntConnect().  <func>,
  495. * <param>, and <intNo> must match the corresponding parameters from an earlier 
  496. * call to usbPciIntConnect().
  497. *
  498. * RETURNS: N/A
  499. */
  500. VOID usbPciIntRestore
  501.     (
  502.     INT_HANDLER_PROTOTYPE func,     /* int handler to be removed */
  503.     pVOID param,     /* parameter for int handler */
  504.     UINT16 intNo     /* interrupt vector number */
  505.     )
  506.     {
  507.     if (intNo >= USB_MAX_INT_NO || 
  508. (intUsage [intNo] != 0 && --intUsage [intNo] == 0))
  509. {
  510. USB_INT_DISABLE (intNo);
  511. }
  512.     USB_INT_DISCONNECT (intNo, func, param);
  513.     }
  514. /* End of file. */