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

VxWorks

开发平台:

C/C++

  1. /* usrUsbSpkrInit.c - Initialization of the USB Speaker driver */
  2. /* Copyright 1999-2002 Wind River Systems, Inc. */
  3. /*
  4. Modification history
  5. --------------------
  6. 01d,30jan02,wef fixed DevFind routine.
  7. 01c,07dec01,wef fixed some warnings.
  8. 01b,02feb01,wef Added ios functionality - allows for open, close, read,
  9.                 ioctl, etc access to the printer.
  10. 01a,01feb01,wef Created
  11. */
  12. /*
  13. DESCRIPTION
  14. This configlette initializes the USB speaker driver.  This assumes the
  15. USB host stack has already been initialized and has a host controller
  16. driver attached.   
  17. This configlette demonstrates how a user might integrate a USB class 
  18. driver into the vxWorks file system.  usbSpkrDevCreate () intalls a USB
  19. speaker and its associated driver functions into the driver table allowing
  20. the speaker to be accesed with standard fopen, close, read, write, etc. type
  21. calls.  The decision to keep this functionality out of the driver itself
  22. was made for backwards compatability reasons. 
  23. */
  24. /* includes */
  25. #include "drv/usb/usbSpeakerLib.h"
  26. #include "usb/tools/wavFormat.h" /* Microsoft .wav file format */
  27. #include "usb/usbAudio.h"
  28. #include "vxWorks.h"
  29. #include "iv.h"
  30. #include "ioLib.h"
  31. #include "iosLib.h"
  32. #include "tyLib.h"
  33. #include "intLib.h"
  34. #include "errnoLib.h"
  35. #include "sioLib.h"
  36. #include "stdlib.h"
  37. #include "stdio.h"
  38. #include "logLib.h"
  39. #include "selectLib.h"
  40. /* defines */
  41. #define TX_BUF_NUM 0x10000
  42. #define USB_SPKR_MUTEX_TAKE(tmout)
  43.     semTake (usbSpkrMutex, (int) (tmout))
  44. #define USB_SPKR_MUTEX_GIVE
  45.     semGive (usbSpkrMutex)
  46. #define USB_SPKR_LIST_SEM_TAKE(tmout)
  47.     semTake (usbSpkrListMutex, (int) (tmout))
  48. #define USB_SPKR_LIST_SEM_GIVE
  49.     semGive (usbSpkrListMutex)
  50. #define SPKR_NAME_LEN_MAX        100
  51. #define USB_SPKR_NAME "/usbSp/"
  52. /* data types */
  53. /* typedefs */
  54.  
  55. typedef struct usb_spkr_node
  56.     {
  57.     NODE node;
  58.     struct usb_spkr_dev * pUsbSpkrDev;
  59.     } USB_SPKR_NODE;
  60. typedef struct usb_spkr_dev /* USB_SPKR_DEV */
  61.     {
  62.     DEV_HDR ioDev;
  63.     SEQ_DEV * pSeqDev;
  64.     UINT16              numOpen;
  65.     UINT32              bufSize;
  66.     UCHAR *       buff;
  67.     SEL_WAKEUP_LIST     selList;
  68.     USB_SPKR_NODE * pUsbSpkrNode;
  69.     } USB_SPKR_DEV;
  70.  
  71. /* local variables */
  72. LOCAL SEM_ID    usbSpkrMutex; /* mutex semaphore */
  73. LOCAL SEM_ID    usbSpkrListMutex; /* mutex semaphore to protect list */
  74. LOCAL UINT32 spkrCount = 0;
  75. LOCAL LIST      usbSpkrList; /* all USB speakers in the system */
  76. LOCAL int usbSpkrDrvNum = 0; /* driver number */
  77. /* forward declarations */
  78. LOCAL void usbSpkrDrvAttachCallback (void * arg, SEQ_DEV *pSeqDev, 
  79.    UINT16 attachCode);
  80. LOCAL int usbSpkrRead (USB_SPKR_DEV * pUsbSpkrDev,UCHAR *buffer, 
  81.     UINT32 nBytes);
  82. LOCAL int usbSpkrClose (USB_SPKR_DEV * pUsbSpkrDev);
  83. LOCAL int usbSpkrWrite (USB_SPKR_DEV * pUsbSpkrDev, UCHAR * buffer,
  84.      UINT32 nBytes);
  85. LOCAL int usbSpkrOpen (USB_SPKR_DEV * pUsbSpkrDev, char * name,
  86.     int flags, int mode);
  87. LOCAL int  usbSpkrIoctl (USB_SPKR_DEV * pUsbSpkrDev, int request, void * arg);
  88. LOCAL STATUS  usbSpkrDevFind (SEQ_DEV * pSeqDev, USB_SPKR_DEV ** ppUsbSpkrDev);
  89. LOCAL STATUS usbSpkrDevDelete (USB_SPKR_DEV * pUsbSpkrDev);
  90. /*******************************************************************************
  91. *
  92. * usbSpkrDevCreate - create a VxWorks device for an USB speaker
  93. *
  94. * This routine creates a device on a specified serial channel.  Each channel
  95. * to be used should have exactly one device associated with it by calling
  96. * this routine.
  97. *
  98. * For instance, to create the device "/ /0", the proper call would be:
  99. * .CS
  100. *     usbSpkrDevCreate ("/usbSp/0", pSeqDev);
  101. * .CE
  102. * Where pSeqDev is the address of the underlying SEQ_DEV serial channel
  103. * descriptor (defined in sioLib.h).
  104. * This routine is typically called by the USB speaker driver, when it detects 
  105. * an insertion of a USB speaker.
  106. *
  107. * RETURNS: OK, or ERROR if the driver is not installed, or the
  108. * device already exists, or failed to allocate memory.
  109. */
  110. STATUS usbSpkrDevCreate
  111.     (
  112.     char * name,         /* name to use for this device      */
  113.     SEQ_DEV * pSeqDev /* pointer to core driver structure */
  114.     )
  115.     {
  116.     USB_SPKR_NODE * pUsbSpkrNode = NULL;   /* pointer to device node */
  117.     USB_SPKR_DEV * pUsbSpkrDev = NULL;     /* pointer to USB device */
  118.     /* Create the mutex semaphores */
  119.  
  120.     usbSpkrMutex = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE |
  121.       SEM_INVERSION_SAFE);
  122.  
  123.     usbSpkrListMutex = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE |
  124.   SEM_INVERSION_SAFE);
  125.  
  126.     /* initialize the linked list */
  127.  
  128.     lstInit (&usbSpkrList);
  129.     usbSpkrDrvNum = iosDrvInstall ((FUNCPTR) NULL, 
  130.   (FUNCPTR) usbSpkrDevDelete, 
  131.   (FUNCPTR) usbSpkrOpen, 
  132.   (FUNCPTR) usbSpkrClose, 
  133.   (FUNCPTR) usbSpkrRead, 
  134.   (FUNCPTR) usbSpkrWrite, 
  135.   (FUNCPTR) usbSpkrIoctl);
  136.     if (usbSpkrDrvNum <= 0)
  137.         {
  138.         errnoSet (S_ioLib_NO_DRIVER);
  139. printf ("There is no more room in the driver tablen");
  140. return (ERROR);
  141.         }
  142.     if (pSeqDev == (SEQ_DEV *) ERROR)
  143. {
  144. printf ("pSeqDev is ERRORn");
  145. return (ERROR);
  146. }
  147.     /* allocate memory for the device */
  148.     if ((pUsbSpkrDev = (USB_SPKR_DEV *) calloc (1, sizeof (USB_SPKR_DEV))) == NULL)
  149. {
  150. printf ("calloc returned NULL - out of memoryn");
  151. return (ERROR);
  152. }
  153.     pUsbSpkrDev->pSeqDev = pSeqDev;
  154.     /* allocate memory for this node, and populate it */
  155.     pUsbSpkrNode = (USB_SPKR_NODE *) calloc (1, sizeof (USB_SPKR_NODE));
  156.     /* record useful information */
  157.     pUsbSpkrNode->pUsbSpkrDev = pUsbSpkrDev;
  158.     pUsbSpkrDev->pUsbSpkrNode = pUsbSpkrNode;
  159.     /* add the node to the list */
  160.     USB_SPKR_LIST_SEM_TAKE (WAIT_FOREVER);
  161.     lstAdd (&usbSpkrList, (NODE *) pUsbSpkrNode);
  162.     USB_SPKR_LIST_SEM_GIVE;
  163.  
  164.     /* allow for select support */
  165.     selWakeupListInit (&pUsbSpkrDev->selList);
  166.     /* start the device in the only supported mode */
  167. /*    sioIoctl (pUsbSpkrDev->pSeqDev, SIO_MODE_SET, (void *) SIO_MODE_INT);*/
  168.     /* add the device to the I/O system */
  169.     return (iosDevAdd (&pUsbSpkrDev->ioDev, name, usbSpkrDrvNum));
  170.     }
  171. /*******************************************************************************
  172. *
  173. * usbSpkrDevDelete - delete a VxWorks device for an USB speaker
  174. *
  175. * This routine deletes a device on a specified serial channel.  
  176. *
  177. * This routine is typically called by the USB speaker driver, when it detects 
  178. * a removal of a USB speaker.
  179. *
  180. * RETURNS: OK, or ERROR if the driver is not installed.
  181. */
  182. LOCAL STATUS usbSpkrDevDelete
  183.     (
  184.     USB_SPKR_DEV * pUsbSpkrDev /* speaker device to read from */
  185.     )
  186.     {
  187.     int status = OK; /* holder for the return value */
  188.     if (usbSpkrDrvNum <= 0)
  189.         {
  190.         errnoSet (S_ioLib_NO_DRIVER);
  191.         return (ERROR);
  192.         }
  193.     /* remove the device from the I/O system */
  194.     iosDevDelete (&pUsbSpkrDev->ioDev);
  195.     /* remove from list */
  196.     USB_SPKR_LIST_SEM_TAKE (WAIT_FOREVER);
  197.     lstDelete (&usbSpkrList, (NODE *) pUsbSpkrDev->pUsbSpkrNode);
  198.     USB_SPKR_LIST_SEM_GIVE;
  199.     /* free memory for the device */
  200.     free (pUsbSpkrDev->pUsbSpkrNode);
  201.     free (pUsbSpkrDev);
  202.     return (status);
  203.     }
  204. /*************************************************************************
  205. *
  206. * usbSpkrDevFind - find the USB_SPKR_DEV device for an SIO channel
  207. *
  208. * RETURNS: OK, or ERROR
  209. */
  210.  
  211. LOCAL STATUS usbSpkrDevFind
  212.     (
  213.     SEQ_DEV * pSeqDev,          /* pointer to affected SEQ_DEV */
  214.     USB_SPKR_DEV ** ppUsbSpkrDev /* pointer to an USB_SPKR_DEV */
  215.     )
  216.     {
  217.     USB_SPKR_NODE *      pUsbSpkrNode = NULL;     /* pointer to USB device node */
  218.     USB_SPKR_DEV * pTempDev; /* pointer to an USB_SPKR_DEV */
  219.     if (pSeqDev == NULL)
  220.         return (ERROR);
  221.  
  222.     /* protect it from other module's routines */
  223.  
  224.     USB_SPKR_LIST_SEM_TAKE (WAIT_FOREVER);
  225.  
  226.     /* loop through all the devices */
  227.  
  228.     for (pUsbSpkrNode = (USB_SPKR_NODE *) lstFirst (&usbSpkrList);
  229.          pUsbSpkrNode != NULL;
  230.          pUsbSpkrNode = (USB_SPKR_NODE *) lstNext ((NODE *) pUsbSpkrNode))
  231.         {
  232.         pTempDev = pUsbSpkrNode->pUsbSpkrDev;
  233. /* return as soon as you find it */
  234. if (pTempDev->pSeqDev == pSeqDev)
  235.     {
  236.     * (UINT32 *) ppUsbSpkrDev = (UINT32) pTempDev;
  237.     USB_SPKR_LIST_SEM_GIVE;
  238.     return (OK);
  239.     }
  240.         }
  241.     USB_SPKR_LIST_SEM_GIVE;
  242.     return (ERROR);
  243.     }
  244. /*************************************************************************
  245. *
  246. * usbSpkrDrvAttachCallback - receives attach callbacks from speaker SIO driver
  247. *
  248. * RETURNS: N/A
  249. */
  250. LOCAL void usbSpkrDrvAttachCallback
  251.     (
  252.     void * arg, /* caller-defined argument */
  253.     SEQ_DEV *pSeqDev, /* pointer to affected SEQ_DEV */
  254.     UINT16 attachCode /* defined as USB_SPKR_xxxx */
  255.     )
  256.     {
  257.     USB_SPKR_DEV * pUsbSpkrDev = NULL; /* speaker device */
  258.     char spkrName [SPKR_NAME_LEN_MAX]; /* speaker name */
  259.     if (attachCode == USB_SPKR_ATTACH)
  260. {
  261. if (usbSpeakerSeqDevLock (pSeqDev) != OK)
  262.     {
  263.     printf("usbSpeakerSeqDevLock () returned ERRORn");
  264.     }
  265. else
  266.     {
  267.     sprintf (spkrName, "%s%d", USB_SPKR_NAME, spkrCount);
  268.     if (usbSpkrDevCreate (spkrName, pSeqDev) != OK)
  269. {
  270. printf("usbSpkrDevCreate() returned ERRORn");
  271. }
  272.     /* now we can increment the counter */
  273.     spkrCount++;
  274.     if (usbSpkrDevFind (pSeqDev, &pUsbSpkrDev) != OK)
  275. {
  276. printf("usbSpkrDevFind() returned ERRORn");
  277. return;
  278. }
  279.     printf("USB Speaker attached as %sn", spkrName);
  280.     }
  281. }
  282.     else if (attachCode == USB_SPKR_REMOVE)
  283. {
  284. /* find the related device */
  285. if (usbSpkrDevFind (pSeqDev, &pUsbSpkrDev) != OK)
  286.     {
  287.     printf ("usbSpkrDevFind could not find channel 0x%d", 
  288. (UINT32) pSeqDev);
  289.     return;
  290.     }
  291. /* delete the device */
  292. usbSpkrDevDelete (pUsbSpkrDev);
  293. if (usbSpeakerSeqDevUnlock (pSeqDev) != OK)
  294.     {
  295.     printf("usbSpeakerSeqDevUnlock () returned ERRORn");
  296.     return;
  297.     }
  298. sprintf (spkrName, "%s%d", USB_SPKR_NAME, spkrCount-1);
  299. printf ("USB Speaker %s removedn", spkrName);
  300. }
  301.     }
  302. /*******************************************************************************
  303. *
  304. * usbSpkrOpen - open a usbSpkrDrv serial device.
  305. *
  306. * Increments a counter that holds the number of open paths to device. 
  307. */
  308. LOCAL int usbSpkrOpen
  309.     (
  310.     USB_SPKR_DEV * pUsbSpkrDev,  /* speaker device to read from */
  311.     char     * name, /* device name */
  312.     int flags, /* flags */
  313.     int         mode /* mode selected */
  314.     )
  315.     {
  316.     pUsbSpkrDev->numOpen++;  /* increment number of open paths */
  317.     return ((int) pUsbSpkrDev);
  318.     }
  319. /*******************************************************************************
  320. *
  321. * usbSpkrDrvUnInit - shuts down an I/O USB speaker driver
  322. *
  323. *
  324. * This is supplied to for the user, but it should be noted that iosDrvRemove()
  325. * may cause unpredictable results.
  326. *
  327. */
  328. STATUS usbSpkrDrvUnInit (void)
  329.     {
  330.     if (!usbSpkrDrvNum)
  331. return (OK);
  332.     /* remove the driver */
  333.     if (iosDrvRemove (usbSpkrDrvNum, TRUE) != OK)
  334. {
  335. printf("iosDrvRemove () returned ERRORn");
  336. return (ERROR);
  337. }
  338.     /* HELP */
  339.     usbSpkrDrvNum = 0;
  340.     /* delete the mutex semaphores */
  341.  
  342.     if (semDelete (usbSpkrMutex) == ERROR)
  343. {
  344. printf("semDelete (usbSpkrMutex) returned ERRORn");
  345. return (ERROR);
  346. }
  347.     if (semDelete (usbSpkrListMutex) == ERROR)
  348. {
  349. printf("semDelete (usbSpkrListMutex) returned ERRORn");
  350. return (ERROR);
  351. }
  352.     /* unregister */
  353.  
  354.     if (usbSpeakerDynamicAttachUnRegister (usbSpkrDrvAttachCallback, 
  355.    (pVOID) NULL) 
  356. != OK)
  357. {
  358. printf("usbSpeakerDynamicAttachUnRegister () returned ERRORn");
  359. return (ERROR);
  360. }
  361.  
  362.     /* shutdown */
  363.     if (usbSpeakerDevShutdown () != OK)
  364. {
  365. printf("usbSpeakerDynamicAttachUnRegister () returned ERRORn");
  366. return (ERROR);
  367. }
  368.     return (OK);
  369.     }
  370. /*******************************************************************************
  371. *
  372. * usbSpkrClose - close a usbSpkrDrv serial device.
  373. *
  374. * Decrements the counter of open paths to device.
  375. *
  376. * RETURNS :
  377. */
  378. LOCAL int usbSpkrClose
  379.     (
  380.     USB_SPKR_DEV * pUsbSpkrDev          /* speaker device to read from */
  381.     )
  382.     {
  383.     return ((int) --pUsbSpkrDev->numOpen);
  384.     }
  385. /*******************************************************************************
  386. *
  387. * usbSpkrIoctl - issue device control commands
  388. *
  389. * This routine issues device control commands to an USB speaker device.
  390. *
  391. * RETURNS: depends on the function invoked.
  392. */
  393. LOCAL int usbSpkrIoctl
  394.     (
  395.     USB_SPKR_DEV * pUsbSpkrDev, /* speaker device to read from */
  396.     int request, /* request code */
  397.     void * arg /* some argument */
  398.     )
  399.     {
  400.     return ((*pUsbSpkrDev->pSeqDev->sd_ioctl) (pUsbSpkrDev->pSeqDev, 
  401.        request, 
  402.        arg));
  403.     }
  404. /*******************************************************************************
  405. *
  406. * usbSpkrRead - read from the USB speaker
  407. *
  408. * This routines is a no-op for a read from the USB speaker.
  409. *
  410. * RETURNS: OK or ERROR
  411. */
  412. LOCAL int usbSpkrRead
  413.     (
  414.     USB_SPKR_DEV * pUsbSpkrDev,           /* speaker device to read from */
  415.     UCHAR *pBuffer, 
  416.     UINT32 nBytes    
  417.     )
  418.     {
  419.     return ((*pUsbSpkrDev->pSeqDev->sd_seqRd) (pUsbSpkrDev->pSeqDev, 
  420.        nBytes, 
  421.        pBuffer, 
  422.        FALSE));
  423.     }
  424. /*******************************************************************************
  425. *
  426. * usbSpkrWrite - write to the USB speaker
  427. *
  428. * USB mice don't like to be written to.  The don't support this feature.
  429. *
  430. * RETURNS: OK or ERROR
  431. */
  432. int usbSpkrWrite
  433.     (
  434.     USB_SPKR_DEV * pUsbSpkrDev, /* speaker device to read from */
  435.     UCHAR * pBuffer, /* buffer of data to write  */
  436.     UINT32   nBytes /* number of bytes in buffer */
  437.     )
  438.     {
  439.     return ((*pUsbSpkrDev->pSeqDev->sd_seqWrt) (pUsbSpkrDev->pSeqDev, 
  440. nBytes, 
  441. pBuffer, 
  442. FALSE));
  443.     }
  444. /*****************************************************************************
  445. *
  446. * usrUsbSpkrInit - initialize the USB speaker driver
  447. *
  448. * This function initializes the USB speaker driver and registers for attach 
  449. * callbacks.  
  450. *
  451. * RETURNS: Nothing 
  452. */
  453. void usrUsbSpkrInit (void) 
  454.     {
  455.     /* Check if driver already installed */
  456.     if (usbSpkrDrvNum > 0)
  457. {
  458. printf ("Speaker already initilaized.n");
  459. }
  460.     if (usbSpeakerDevInit () == OK)
  461. {
  462.         printf ("usbSpeakerDevInit() returned OKn");
  463. if (usbSpeakerDynamicAttachRegister (usbSpkrDrvAttachCallback, 
  464.      (void *) NULL) 
  465.   != OK)
  466.     {
  467.     printf ("usbSpeakerDynamicAttachRegister() returned ERRORn");
  468.     }
  469. }
  470.     else
  471.         printf ("usbSpeakerDevInit() returned ERRORn");
  472.     }