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

VxWorks

开发平台:

C/C++

  1. /* usbTargPhilipsD12EvalLib.c - emulates Philips PDIUSBD12 eval firmware */
  2. /* Copyright 2000 Wind River Systems, Inc. */
  3. /*
  4. Modification history
  5. --------------------
  6. 01d,19mar00,rcb  Add handling for CLEAR_FEATURE...Newer Philips test
  7.  program now invokes this function.
  8. 01c,23nov99,rcb  Change #include ../xxx references to lower case.
  9. 01b,12nov99,rcb  Shorted path names...affects "#include" directives.
  10. 01a,03sep99,rcb  First.
  11. */
  12. /*
  13. DESCRIPTION
  14. The Philips PDIUSBD12 evaluation kit is shipped with sample firmware.  The
  15. "firmware" is a program which runs under MS-DOS and responds to certain standard
  16. and "vendor specific" USB requests.  A custom Windows application - also provided
  17. by Philips - can be used to exercise this "firmware".
  18. In order to provide a different example of working target behavoir, this module
  19. emulates the behavoir of the Philips evaluation firmware, allowing this target
  20. module to work with the Philips Windows-based exerciser program.  The "scan",
  21. "print", and "loopback" portions of that test work correctly.  The "LED buttons"
  22. supported by the Philips firmware are not emulated, and do nothing.
  23. It is the caller's responsibility to initialize usbTargLib and attach a USB TCD 
  24. to it. When attaching a TCD to usbTargLib, the caller must pass a pointer to a
  25. table of callbacks required by usbTargLib.  The address of this table and the
  26. "callback parameter" required by these callbacks may be obtained by calling
  27. usbTargPhilipsD12EvalCallbackInfo().  It is not necessary to initialize the 
  28. usbTartPhilipsD12EvalLib or to shut it down.  It performs all of its operations
  29. in response to callbacks from usbTargLib.
  30. */
  31. /* includes */
  32. #include "usb/usbPlatform.h"
  33. #include "string.h"
  34. #include "usb/usb.h"
  35. #include "usb/usbDescrCopyLib.h"     /* USB utility functions */
  36. #include "usb/target/usbTargLib.h" /* USB target functions */
  37. #include "drv/usb/target/usbPdiusbd12.h" /* Philips definitions */
  38. #include "drv/usb/target/usbTargPhilipsD12EvalLib.h" /* our API */
  39. /* defines */
  40. #define BULK_BFR_LEN     64000     /* size used by Philips */
  41. /* string identifiers */
  42. #define UNICODE_ENGLISH     0x409
  43. #define ID_STR_MFG     1
  44. #define ID_STR_MFG_VAL     "Wind River Systems"
  45. #define ID_STR_PROD     2
  46. #define ID_STR_PROD_VAL     "Philips firmware emulator"
  47. /* descriptor constants */
  48. #define CONFIG_VAL 1
  49. #define NUM_ENDPOINTS 4
  50. #define CONFIG_DESCRIPTOR_LENGTH    
  51.     USB_CONFIG_DESCR_LEN + USB_INTERFACE_DESCR_LEN + 
  52.     (NUM_ENDPOINTS * USB_ENDPOINT_DESCR_LEN)
  53. /* vendor specific commands */
  54. #define READ_WRITE_REGISTER 12
  55. /* wIndex parameters to the vendor specific READ_WRITE_REGISTER cmd */
  56. #define SETUP_DMA_REQUEST 0x0471
  57. #define GET_FIRMWARE_VERSION 0x0472
  58. #define GET_SET_TWAIN_REQUEST 0x0473
  59. /* typedefs */
  60. /* IO_REQUEST is the parameter to the SETUP_DMA_REQUEST vendor-specific
  61.  * command.
  62.  */
  63. #define IO_REQUEST_LEN 6
  64. typedef struct io_request {
  65.     UINT8 bytes [IO_REQUEST_LEN];
  66. } IO_REQUEST, *pIO_REQUEST;
  67. /* forward declarations */
  68. LOCAL STATUS mngmtFunc
  69.     (
  70.     pVOID param,
  71.     USB_TARG_CHANNEL targChannel,
  72.     UINT16 mngmtCode
  73.     );
  74. LOCAL STATUS featureClear
  75.     (
  76.     pVOID param,
  77.     USB_TARG_CHANNEL targChannel,
  78.     UINT8 requestType,
  79.     UINT16 feature,
  80.     UINT16 index
  81.     );
  82. LOCAL STATUS configurationGet
  83.     (
  84.     pVOID param,
  85.     USB_TARG_CHANNEL targChannel,
  86.     pUINT8 pConfiguration
  87.     );
  88. LOCAL STATUS configurationSet
  89.     (
  90.     pVOID param,
  91.     USB_TARG_CHANNEL targChannel,
  92.     UINT8 configuration
  93.     );
  94. LOCAL STATUS descriptorGet
  95.     (
  96.     pVOID param,
  97.     USB_TARG_CHANNEL targChannel,
  98.     UINT8 requestType,
  99.     UINT8 descriptorType,
  100.     UINT8 descriptorIndex,
  101.     UINT16 languageId,
  102.     UINT16 length,
  103.     pUINT8 pBfr,
  104.     pUINT16 pActLen
  105.     );
  106. LOCAL STATUS interfaceGet
  107.     (
  108.     pVOID param,
  109.     USB_TARG_CHANNEL targChannel,
  110.     UINT16 interfaceIndex,
  111.     pUINT8 pAlternateSetting
  112.     );
  113. LOCAL STATUS interfaceSet
  114.     (
  115.     pVOID param,
  116.     USB_TARG_CHANNEL targChannel,
  117.     UINT16 interfaceIndex,
  118.     UINT8 alternateSetting
  119.     );
  120. LOCAL STATUS vendorSpecific
  121.     (
  122.     pVOID param,
  123.     USB_TARG_CHANNEL targChannel,
  124.     UINT8 requestType,
  125.     UINT8 request,
  126.     UINT16 value,
  127.     UINT16 index,
  128.     UINT16 length
  129.     );
  130. LOCAL STATUS initBulkErp 
  131.     (
  132.     USB_TARG_PIPE pipeHandle,
  133.     UINT16 pid,
  134.     UINT16 bfrOffset,
  135.     UINT16 length
  136.     );
  137. /* locals */
  138. LOCAL USB_TARG_CALLBACK_TABLE usbTargPrnCallbackTable =
  139.     {
  140.     mngmtFunc, /* mngmtFunc */
  141.     featureClear, /* featureClear */
  142.     NULL, /* featureSet */
  143.     configurationGet, /* configurationGet */
  144.     configurationSet, /* configurationSet */
  145.     descriptorGet, /* descriptorGet */
  146.     NULL, /* descriptorSet */
  147.     interfaceGet, /* interfaceGet */
  148.     interfaceSet, /* interfaceSet */
  149.     NULL, /* statusGet */
  150.     NULL, /* addressSet */
  151.     NULL, /* synchFrameGet */
  152.     vendorSpecific, /* vendorSpecific */
  153.     };
  154. LOCAL USB_TARG_CHANNEL channel;
  155. LOCAL UINT16 numEndpoints;
  156. LOCAL pUSB_TARG_ENDPOINT_INFO pEndpoints;
  157. LOCAL UINT16 curConfiguration;
  158. LOCAL UINT16 curAlternateSetting;
  159. LOCAL USB_TARG_PIPE bulkOutPipeHandle;
  160. LOCAL USB_TARG_PIPE bulkInPipeHandle;
  161. LOCAL USB_ERP payloadErp;
  162. LOCAL IO_REQUEST ioRequest;
  163. LOCAL USB_ERP bulkErp;
  164. LOCAL pUINT8 bulkBfr;
  165. LOCAL BOOL bulkInUse;
  166. LOCAL UINT32 bulkCanceled;
  167. LOCAL UINT32 bulkErrors;
  168. LOCAL UINT8 fwVersion = 0x01;     /* version for PDIUSBD12 PC kit */
  169. /* descriptors */
  170. LOCAL USB_LANGUAGE_DESCR langDescr =
  171.     {sizeof (USB_LANGUAGE_DESCR), USB_DESCR_STRING, 
  172. {TO_LITTLEW (UNICODE_ENGLISH)}};
  173. LOCAL char *pStrMfg = ID_STR_MFG_VAL;
  174. LOCAL char *pStrProd = ID_STR_PROD_VAL;
  175. LOCAL USB_DEVICE_DESCR devDescr =
  176.     {
  177.     USB_DEVICE_DESCR_LEN,     /* bLength */
  178.     USB_DESCR_DEVICE,     /* bDescriptorType */
  179.     TO_LITTLEW (0x0100),     /* bcdUsb */
  180.     0xdc, /* test class */     /* bDeviceClass */
  181.     0,     /* bDeviceSubclass */
  182.     0,     /* bDeviceProtocol */
  183.     USB_MIN_CTRL_PACKET_SIZE,     /* maxPacketSize0 */
  184.     TO_LITTLEW (0x0471),     /* idVendor */
  185.     TO_LITTLEW (0x0222),     /* idProduct */
  186.     TO_LITTLEW (0x0100),     /* bcdDevice */
  187.     ID_STR_MFG,      /* iManufacturer */
  188.     ID_STR_PROD,     /* iProduct */
  189.     0,     /* iSerialNumber */
  190.     1     /* bNumConfigurations */
  191.     };
  192. LOCAL USB_CONFIG_DESCR configDescr =
  193.     {
  194.     USB_CONFIG_DESCR_LEN,     /* bLength */
  195.     USB_DESCR_CONFIGURATION,     /* bDescriptorType */
  196.     TO_LITTLEW (CONFIG_DESCRIPTOR_LENGTH), /* wTotalLength */
  197.     1,     /* bNumInterfaces */
  198.     CONFIG_VAL,      /* bConfigurationValue */
  199.     0,     /* iConfiguration */
  200.     USB_ATTR_SELF_POWERED,     /* bmAttributes */
  201.     0     /* MaxPower */
  202.     };
  203. LOCAL USB_INTERFACE_DESCR ifDescr =
  204.     {
  205.     USB_INTERFACE_DESCR_LEN,     /* bLength */
  206.     USB_DESCR_INTERFACE,     /* bDescriptorType */
  207.     0,     /* bInterfaceNumber */
  208.     0,     /* bAlternateSetting */
  209.     NUM_ENDPOINTS,     /* bNumEndpoints */
  210.     0xdc, /* test class */     /* bInterfaceClass */
  211.     0xa0,     /* bInterfaceSubClass */
  212.     0xb0,     /* bInterfaceProtocol */
  213.     0     /* iInterface */
  214.     };
  215. LOCAL USB_ENDPOINT_DESCR epDescr1 =
  216.     {
  217.     USB_ENDPOINT_DESCR_LEN,     /* bLength */
  218.     USB_DESCR_ENDPOINT,      /* bDescriptorType */
  219.     0x81,     /* bEndpointAddress */
  220.     USB_ATTR_INTERRUPT,      /* bmAttributes */
  221.     USB_MIN_CTRL_PACKET_SIZE,     /* maxPacketSize */
  222.     10     /* bInterval */
  223.     };
  224. LOCAL USB_ENDPOINT_DESCR epDescr2 =
  225.     {
  226.     USB_ENDPOINT_DESCR_LEN,     /* bLength */
  227.     USB_DESCR_ENDPOINT,      /* bDescriptorType */
  228.     0x01,     /* bEndpointAddress */
  229.     USB_ATTR_INTERRUPT,      /* bmAttributes */
  230.     USB_MIN_CTRL_PACKET_SIZE,     /* maxPacketSize */
  231.     10     /* bInterval */
  232.     };
  233. LOCAL USB_ENDPOINT_DESCR epDescr3 =
  234.     {
  235.     USB_ENDPOINT_DESCR_LEN,     /* bLength */
  236.     USB_DESCR_ENDPOINT,      /* bDescriptorType */
  237.     0x82,     /* bEndpointAddress */
  238.     USB_ATTR_BULK,     /* bmAttributes */
  239.     USB_MIN_CTRL_PACKET_SIZE,     /* maxPacketSize */
  240.     0     /* bInterval */
  241.     };
  242. LOCAL USB_ENDPOINT_DESCR epDescr4 =
  243.     {
  244.     USB_ENDPOINT_DESCR_LEN,     /* bLength */
  245.     USB_DESCR_ENDPOINT,      /* bDescriptorType */
  246.     0x02,     /* bEndpointAddress */
  247.     USB_ATTR_BULK,     /* bmAttributes */
  248.     USB_MIN_CTRL_PACKET_SIZE,     /* maxPacketSize */
  249.     0     /* bInterval */
  250.     };
  251. /* functions */
  252. /***************************************************************************
  253. *
  254. * usbTargPhilipsD12EvalCallbackInfo - returns callback table
  255. *
  256. * RETURNS: N/A
  257. */
  258. VOID usbTargPhilipsD12EvalCallbackInfo
  259.     (
  260.     pUSB_TARG_CALLBACK_TABLE *ppCallbacks,
  261.     pVOID *pCallbackParam
  262.     )
  263.     {
  264.     if (ppCallbacks != NULL)
  265. *ppCallbacks = &usbTargPrnCallbackTable;
  266.     if (pCallbackParam != NULL)
  267. *pCallbackParam = NULL;
  268.     }
  269. /***************************************************************************
  270. *
  271. * mngmtFunc - invoked by usbTargLib for connection management events
  272. *
  273. * RETURNS: OK if able to handle event, or ERROR if unable to handle event
  274. */
  275. LOCAL STATUS mngmtFunc
  276.     (
  277.     pVOID param,
  278.     USB_TARG_CHANNEL targChannel,
  279.     UINT16 mngmtCode     /* management code */
  280.     )
  281.     {
  282.     switch (mngmtCode)
  283. {
  284. case TCD_MNGMT_ATTACH:
  285.     /* Initialize global data */
  286.     channel = targChannel;
  287.     usbTargEndpointInfoGet (targChannel, &numEndpoints, &pEndpoints);
  288.     curConfiguration = 0;
  289.     curAlternateSetting = 0;
  290.     bulkInPipeHandle = NULL;
  291.     bulkOutPipeHandle = NULL;
  292.     bulkCanceled = 0;
  293.     bulkErrors = 0;
  294.     /* Initialize control pipe maxPacketSize. */
  295.     devDescr.maxPacketSize0 = pEndpoints [0].maxPacketSize;
  296.     /* Initialize bulk endpoint max packet size. */
  297.     epDescr1.maxPacketSize = 
  298. pEndpoints [D12_ENDPOINT_1_IN].intInMaxPacketSize;
  299.     epDescr2.maxPacketSize =
  300. pEndpoints [D12_ENDPOINT_1_OUT].intOutMaxPacketSize;
  301.     epDescr3.maxPacketSize =
  302. pEndpoints [D12_ENDPOINT_2_IN].bulkInMaxPacketSize;
  303.     epDescr4.maxPacketSize =
  304. pEndpoints [D12_ENDPOINT_2_OUT].bulkOutMaxPacketSize;
  305.     
  306.     /* Allocate buffer */
  307.     if ((bulkBfr = OSS_MALLOC (BULK_BFR_LEN)) == NULL)
  308. return ERROR;
  309.     break;
  310. case TCD_MNGMT_DETACH:
  311.     /* De-allocate buffer */
  312.     if (bulkBfr != NULL)
  313. {
  314. OSS_FREE (bulkBfr);
  315. bulkBfr = NULL;
  316. }
  317.     break;
  318. case TCD_MNGMT_BUS_RESET:
  319. case TCD_MNGMT_VBUS_LOST:
  320.     /* revert to power-ON configuration */
  321.     configurationSet (param, targChannel, 0);
  322.     break;     
  323. default:
  324.     break;
  325. }
  326.     return OK;
  327.     }
  328. /***************************************************************************
  329. *
  330. * featureClear - invoked by usbTargLib for CLEAR_FEATURE request
  331. *
  332. * RETURNS: OK, or ERROR if unable to clear requested feature
  333. */
  334. LOCAL STATUS featureClear
  335.     (
  336.     pVOID param,
  337.     USB_TARG_CHANNEL targChannel,
  338.     UINT8 requestType,
  339.     UINT16 feature,
  340.     UINT16 index
  341.     )
  342.     {
  343.     return OK;
  344.     }
  345. /***************************************************************************
  346. *
  347. * configurationGet - invoked by usbTargLib for GET_CONFIGURATION request
  348. *
  349. * RETURNS: OK, or ERROR if unable to return configuration setting
  350. */
  351. LOCAL STATUS configurationGet
  352.     (
  353.     pVOID param,
  354.     USB_TARG_CHANNEL targChannel,
  355.     pUINT8 pConfiguration
  356.     )
  357.     {
  358.     *pConfiguration = curConfiguration;
  359.     return OK;
  360.     }
  361. /***************************************************************************
  362. *
  363. * configurationSet - invoked by usbTargLib for SET_CONFIGURATION request
  364. *
  365. * RETURNS: OK, or ERROR if unable to set specified configuration
  366. */
  367. LOCAL STATUS configurationSet
  368.     (
  369.     pVOID param,
  370.     USB_TARG_CHANNEL targChannel,
  371.     UINT8 configuration
  372.     )
  373.     {
  374.     if (configuration > CONFIG_VAL)
  375. return ERROR;
  376.     if ((curConfiguration = configuration) == CONFIG_VAL)
  377. {
  378. /* Enable the pipes if not already enabled. */
  379. if (bulkOutPipeHandle == NULL)
  380.     {
  381.     /* Create a pipe */
  382.     if (usbTargPipeCreate (targChannel, D12_ENDPOINT_2_OUT, 0,
  383. 2, configuration, 0, USB_XFRTYPE_BULK, USB_DIR_OUT, 
  384. &bulkOutPipeHandle) != OK)
  385. return ERROR;
  386.     }
  387. if (bulkInPipeHandle == NULL)
  388.     {
  389.     if (usbTargPipeCreate (targChannel, D12_ENDPOINT_2_IN, 0,
  390. 2, configuration, 0, USB_XFRTYPE_BULK, USB_DIR_IN,
  391. &bulkInPipeHandle) != OK)
  392. return ERROR;
  393.     }
  394. }
  395.     else
  396. {
  397. /* Disable the pipes */
  398. if (bulkOutPipeHandle != NULL)
  399.     {
  400.     usbTargPipeDestroy (bulkOutPipeHandle);
  401.     bulkOutPipeHandle = NULL;
  402.     }
  403. if (bulkInPipeHandle != NULL)
  404.     {
  405.     usbTargPipeDestroy (bulkInPipeHandle);
  406.     bulkInPipeHandle = NULL;
  407.     }
  408. }
  409.     return OK;
  410.     }
  411. /***************************************************************************
  412. *
  413. * descriptorGet - invoked by usbTargLib for GET_DESCRIPTOR request
  414. *
  415. * RETURNS: OK, or ERROR if unable to return requested descriptor
  416. */
  417. LOCAL STATUS descriptorGet
  418.     (
  419.     pVOID param,
  420.     USB_TARG_CHANNEL targChannel,
  421.     UINT8 requestType,
  422.     UINT8 descriptorType,
  423.     UINT8 descriptorIndex,
  424.     UINT16 languageId,
  425.     UINT16 length,
  426.     pUINT8 pBfr,
  427.     pUINT16 pActLen
  428.     )
  429.     {
  430.     UINT8 bfr [USB_MAX_DESCR_LEN];
  431.     UINT16 actLen;
  432.     /* Determine type of descriptor being requested. */
  433.     if (requestType == (USB_RT_DEV_TO_HOST | USB_RT_STANDARD | USB_RT_DEVICE))
  434. {
  435. switch (descriptorType)
  436.     {
  437.     case USB_DESCR_DEVICE:  
  438. usbDescrCopy (pBfr, &devDescr, length, pActLen);
  439. break;
  440.     case USB_DESCR_CONFIGURATION:
  441. memcpy (bfr, &configDescr, USB_CONFIG_DESCR_LEN);
  442. memcpy (&bfr [USB_CONFIG_DESCR_LEN], &ifDescr,
  443.     USB_INTERFACE_DESCR_LEN);
  444. memcpy (&bfr [USB_CONFIG_DESCR_LEN + USB_INTERFACE_DESCR_LEN],
  445.     &epDescr1, USB_ENDPOINT_DESCR_LEN);
  446. memcpy (&bfr [USB_CONFIG_DESCR_LEN + USB_INTERFACE_DESCR_LEN +
  447.     USB_ENDPOINT_DESCR_LEN], &epDescr2, USB_ENDPOINT_DESCR_LEN);
  448. memcpy (&bfr [USB_CONFIG_DESCR_LEN + USB_INTERFACE_DESCR_LEN +
  449.     USB_ENDPOINT_DESCR_LEN * 2], &epDescr3, USB_ENDPOINT_DESCR_LEN);
  450. memcpy (&bfr [USB_CONFIG_DESCR_LEN + USB_INTERFACE_DESCR_LEN +
  451.     USB_ENDPOINT_DESCR_LEN * 3], &epDescr4, USB_ENDPOINT_DESCR_LEN);
  452. actLen = min (length, CONFIG_DESCRIPTOR_LENGTH);
  453. memcpy (pBfr, bfr, actLen);
  454. *pActLen = actLen;
  455. break;
  456.     case USB_DESCR_INTERFACE:
  457. usbDescrCopy (pBfr, &ifDescr, length, pActLen);
  458. break;
  459.     case USB_DESCR_ENDPOINT:
  460. switch (descriptorIndex)
  461.     {
  462.     case 0: usbDescrCopy (pBfr, &epDescr1, length, pActLen); break;
  463.     case 1: usbDescrCopy (pBfr, &epDescr2, length, pActLen); break;
  464.     case 2: usbDescrCopy (pBfr, &epDescr3, length, pActLen); break;
  465.     case 3: usbDescrCopy (pBfr, &epDescr4, length, pActLen); break;
  466.     }
  467. break;
  468.     
  469.     case USB_DESCR_STRING:
  470. switch (descriptorIndex)
  471.     {
  472.     case 0: /* language descriptor */
  473. usbDescrCopy (pBfr, &langDescr, length, pActLen);
  474. break;
  475.     case ID_STR_MFG:
  476. usbDescrStrCopy (pBfr, pStrMfg, length, pActLen);
  477. break;
  478.     case ID_STR_PROD:
  479. usbDescrStrCopy (pBfr, pStrProd, length, pActLen);
  480. break;
  481.     default:
  482. return ERROR;
  483.     }
  484. break;
  485.     default:
  486. return ERROR;
  487.     }
  488. }
  489.     else
  490. {
  491. return ERROR;
  492. }
  493.     return OK;
  494.     }
  495. /***************************************************************************
  496. *
  497. * interfaceGet - invoked by usbTargLib for GET_INTERFACE request
  498. *
  499. * RETURNS: OK, or ERROR if unable to return interface setting
  500. */
  501. LOCAL STATUS interfaceGet
  502.     (
  503.     pVOID param,
  504.     USB_TARG_CHANNEL targChannel,
  505.     UINT16 interfaceIndex,
  506.     pUINT8 pAlternateSetting
  507.     )
  508.     {
  509.     *pAlternateSetting = curAlternateSetting;
  510.     return OK;
  511.     }
  512. /***************************************************************************
  513. *
  514. * interfaceSet - invoked by usbTargLib for SET_INTERFACE request
  515. *
  516. * RETURNS: OK, or ERROR if unable to set specified interface
  517. */
  518. LOCAL STATUS interfaceSet
  519.     (
  520.     pVOID param,
  521.     USB_TARG_CHANNEL targChannel,
  522.     UINT16 interfaceIndex,
  523.     UINT8 alternateSetting
  524.     )
  525.     {
  526.     curAlternateSetting = alternateSetting;
  527.     return OK;
  528.     }
  529. /***************************************************************************
  530. *
  531. * bulkErpCallback - called when report ERP terminates
  532. *
  533. * RETURNS: N/A
  534. */
  535. LOCAL VOID bulkErpCallback
  536.     (
  537.     pVOID p /* pointer to ERP */
  538.     )
  539.     {
  540.     pUSB_ERP pErp = (pUSB_ERP) p;
  541.     if (pErp->result == S_usbTcdLib_ERP_CANCELED)
  542. bulkCanceled++;
  543.     else if (pErp->result != OK)
  544. bulkErrors++;
  545.     bulkInUse = FALSE;
  546.     }
  547. /***************************************************************************
  548. *
  549. * initBulkErp - listen for output printer data
  550. *
  551. * RETURNS: OK, or ERROR if unable to submit ERP.
  552. */
  553. LOCAL STATUS initBulkErp 
  554.     (
  555.     USB_TARG_PIPE pipeHandle,
  556.     UINT16 pid,
  557.     UINT16 bfrOffset,
  558.     UINT16 length
  559.     )
  560.     {
  561.     if (bulkBfr == NULL)
  562. return ERROR;
  563.     if (bulkInUse)
  564. return ERROR;
  565.     /* Initialize bulk ERP */
  566.     memset (&bulkErp, 0, sizeof (bulkErp));
  567.     bulkErp.erpLen = sizeof (bulkErp);
  568.     bulkErp.userCallback = bulkErpCallback;
  569.     bulkErp.bfrCount = 1;
  570.     bulkErp.bfrList [0].pid = pid;
  571.     bulkErp.bfrList [0].pBfr = bulkBfr + bfrOffset;
  572.     bulkErp.bfrList [0].bfrLen = length;
  573.     bulkInUse = TRUE;
  574.     if (usbTargTransfer (pipeHandle, &bulkErp) != OK)
  575. {
  576. bulkInUse = FALSE;
  577. return ERROR;
  578. }
  579.     return OK;
  580.     }
  581. /***************************************************************************
  582. *
  583. * setupDmaRequestCallback - called when payload received
  584. *
  585. * RETURNS: N/A
  586. */
  587. LOCAL VOID setupDmaRequestCallback
  588.     (
  589.     pVOID p
  590.     )
  591.     {
  592.     pUSB_ERP pErp = (pUSB_ERP) p;
  593.     UINT16 bfrOffset;
  594.     UINT16 length;
  595.     UINT8 command;
  596.     if (pErp->result == OK)
  597. {
  598. /* Examine the IO_REQUEST passed in the payload. */
  599. bfrOffset = ioRequest.bytes [0] | (ioRequest.bytes [1] << 8);
  600. length = ioRequest.bytes [3] | (ioRequest.bytes [4] << 8);
  601. command = ioRequest.bytes [5];
  602. if ((command & 0x1) != 0)
  603.     {
  604.     /* read request */
  605.     initBulkErp (bulkInPipeHandle, USB_PID_IN, bfrOffset, length);
  606.     }
  607. else
  608.     {
  609.     /* write request */
  610.     initBulkErp (bulkOutPipeHandle, USB_PID_OUT, bfrOffset, length);
  611.     }
  612. /* Send an acknowledgement of the command. */
  613. usbTargControlResponseSend (channel, NULL, 0);
  614. }
  615.     }
  616. /***************************************************************************
  617. *
  618. * vendorSpecific - invoked by usbTargLib for VENDOR_SPECIFIC request
  619. *
  620. * RETURNS: OK, or ERROR if unable to process vendor-specific request
  621. */
  622. LOCAL STATUS vendorSpecific
  623.     (
  624.     pVOID param,
  625.     USB_TARG_CHANNEL targChannel,
  626.     UINT8 requestType,
  627.     UINT8 request,
  628.     UINT16 value,
  629.     UINT16 index,
  630.     UINT16 length
  631.     )
  632.     {
  633.     if ((requestType & (USB_RT_CATEGORY_MASK | USB_RT_RECIPIENT_MASK)) 
  634. == (USB_RT_VENDOR | USB_RT_DEVICE))
  635. {
  636. switch (request)
  637.     {
  638.     case READ_WRITE_REGISTER:
  639. if ((requestType & USB_RT_DIRECTION_MASK) != 0 &&
  640.     value == 0 && length == sizeof (fwVersion) &&
  641.     index == GET_FIRMWARE_VERSION)
  642.     {
  643.     /* Send firmware version back to host. */
  644.     return usbTargControlResponseSend (targChannel,
  645. sizeof (fwVersion), &fwVersion);
  646.     }
  647. else if ((requestType & USB_RT_DIRECTION_MASK) == 0 &&
  648.     value == 0 && length == IO_REQUEST_LEN && 
  649.     index == SETUP_DMA_REQUEST)
  650.     {
  651.     /* Fetch the payload for the command. */
  652.     memset (&payloadErp, 0, sizeof (payloadErp));
  653.     payloadErp.erpLen = sizeof (payloadErp);
  654.     payloadErp.userCallback = setupDmaRequestCallback;
  655.     payloadErp.dataToggle = USB_DATA1;
  656.     payloadErp.bfrCount = 1;
  657.     payloadErp.bfrList [0].pid = USB_PID_OUT;
  658.     payloadErp.bfrList [0].pBfr = (pUINT8) &ioRequest;
  659.     payloadErp.bfrList [0].bfrLen = IO_REQUEST_LEN;
  660.     return usbTargControlPayloadRcv (targChannel,
  661. &payloadErp);
  662.     }
  663. break;
  664.     default:
  665. break;
  666.     }
  667. }
  668.     return ERROR;
  669.     }
  670. /* End of file. */