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

VxWorks

开发平台:

C/C++

  1. /* usrUsbPrnInit.c - Initialization of the USB Printer driver */
  2. /* Copyright 1999-2002 Wind River Systems, Inc. */
  3. /*
  4. Modification history
  5. --------------------
  6. 01d,08dec01,wef  fixing warnings
  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,23aug00,wef Created
  11. */
  12. /*
  13. DESCRIPTION
  14. This configlette initializes the USB printer 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.  usbPrnDevCreate () intalls a USB
  19. printer and its associated driver functions into the driver table allowing
  20. the printer 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/usbPrinterLib.h"
  26. #include "usb/usbPrinter.h"
  27. #include "vxWorks.h"
  28. #include "iv.h"
  29. #include "ioLib.h"
  30. #include "iosLib.h"
  31. #include "tyLib.h"
  32. #include "intLib.h"
  33. #include "errnoLib.h"
  34. #include "sioLib.h"
  35. #include "stdlib.h"
  36. #include "stdio.h"
  37. #include "logLib.h"
  38. #include "selectLib.h"
  39. /* defines */
  40. #define TX_BUF_NUM 0x10000
  41. #define USB_PRN_MUTEX_TAKE(tmout)
  42.     semTake (usbPrnMutex, (int) (tmout))
  43. #define USB_PRN_MUTEX_GIVE
  44.     semGive (usbPrnMutex)
  45. #define USB_PRN_LIST_SEM_TAKE(tmout)
  46.     semTake (usbPrnListMutex, (int) (tmout))
  47. #define USB_PRN_LIST_SEM_GIVE
  48.     semGive (usbPrnListMutex)
  49. #define PRN_NAME_LEN_MAX        100
  50. #define USB_PRN_NAME "/usbPr/"
  51. /* data types */
  52. /* typedefs */
  53.  
  54. typedef struct usb_prn_node
  55.     {
  56.     NODE node;
  57.     struct usb_prn_dev * pUsbPrnDev;
  58.     } USB_PRN_NODE;
  59. typedef struct usb_prn_dev /* USB_PRN_DEV */
  60.     {
  61.     DEV_HDR             ioDev;
  62.     SIO_CHAN    *       pSioChan;
  63.     UINT16              numOpen;
  64.     UINT32              bufSize;
  65.     UCHAR *       buff;
  66.     SEL_WAKEUP_LIST     selList;
  67.     USB_PRN_NODE * pUsbPrnNode;
  68.     } USB_PRN_DEV;
  69.  
  70. /* local variables */
  71. LOCAL SEM_ID    usbPrnMutex; /* mutex semaphore */
  72. LOCAL SEM_ID    usbPrnListMutex; /* mutex semaphore to protect list */
  73. LOCAL UCHAR * txCallbackBfr = NULL;
  74. LOCAL UINT32 txBytesNum = 0;
  75. LOCAL UINT32 prnCount = 0;
  76. LOCAL LIST      usbPrnList; /* all USB printers in the system */
  77. LOCAL int usbPrnDrvNum = 0; /* driver number */
  78. /* forward declarations */
  79. LOCAL void usbPrnDrvAttachCallback (void * arg, SIO_CHAN *pChan, 
  80.    UINT16 attachCode);
  81. LOCAL void usbPrnDrvAttachCallback (void * arg, SIO_CHAN *pChan, 
  82.  UINT16 attachCode);
  83. LOCAL int usbPrnRead (USB_PRN_DEV * pUsbPrnDev);
  84. LOCAL int usbPrnClose (USB_PRN_DEV * pUsbPrnDev);
  85. LOCAL int usbPrnWrite (USB_PRN_DEV * pUsbPrnDev, UCHAR * buffer,
  86.      UINT32 nBytes);
  87. LOCAL int usbPrnOpen (USB_PRN_DEV * pUsbPrnDev, char * name,
  88.     int flags, int mode);
  89. LOCAL STATUS usbPrnTxCallback (void *, char *);
  90. LOCAL int  usbPrnIoctl (USB_PRN_DEV * pUsbPrnDev, int request, void * arg);
  91. LOCAL STATUS  usbPrnDevFind (SIO_CHAN *pChan, USB_PRN_DEV * pUsbPrnDev);
  92. LOCAL STATUS usbPrnDevDelete (USB_PRN_DEV * pUsbPrnDev);
  93. /*******************************************************************************
  94. *
  95. * usbPrnDevCreate - create a VxWorks device for an USB printer
  96. *
  97. * This routine creates a device on a specified serial channel.  Each channel
  98. * to be used should have exactly one device associated with it by calling
  99. * this routine.
  100. *
  101. * For instance, to create the device "/ /0", the proper call would be:
  102. * .CS
  103. *     usbPrnDevCreate ("/usbPr/0", pSioChan);
  104. * .CE
  105. * Where pSioChan is the address of the underlying SIO_CHAN serial channel
  106. * descriptor (defined in sioLib.h).
  107. * This routine is typically called by the USB printer driver, when it detects 
  108. * an insertion of a USB printer.
  109. *
  110. * RETURNS: OK, or ERROR if the driver is not installed, or the
  111. * device already exists, or failed to allocate memory.
  112. */
  113. STATUS usbPrnDevCreate
  114.     (
  115.     char * name,         /* name to use for this device      */
  116.     SIO_CHAN * pSioChan /* pointer to core driver structure */
  117.     )
  118.     {
  119.     USB_PRN_NODE * pUsbPrnNode = NULL;   /* pointer to device node */
  120.     USB_PRN_DEV * pUsbPrnDev = NULL;     /* pointer to USB device */
  121.     /* Create the mutex semaphores */
  122.  
  123.     usbPrnMutex = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE |
  124.       SEM_INVERSION_SAFE);
  125.  
  126.     usbPrnListMutex = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE |
  127.   SEM_INVERSION_SAFE);
  128.  
  129.     /* initialize the linked list */
  130.  
  131.     lstInit (&usbPrnList);
  132.     usbPrnDrvNum = iosDrvInstall ((FUNCPTR) NULL, 
  133.   (FUNCPTR) usbPrnDevDelete, 
  134.   (FUNCPTR) usbPrnOpen, 
  135.   (FUNCPTR) usbPrnClose, 
  136.   (FUNCPTR) usbPrnRead, 
  137.   (FUNCPTR) usbPrnWrite, 
  138.   (FUNCPTR) usbPrnIoctl);
  139.     if (usbPrnDrvNum <= 0)
  140.         {
  141.         errnoSet (S_ioLib_NO_DRIVER);
  142.         return (ERROR);
  143.         }
  144.     if (pSioChan == (SIO_CHAN *) ERROR)
  145. {
  146.         return (ERROR);
  147. }
  148.     /* allocate memory for the device */
  149.     if ((pUsbPrnDev = (USB_PRN_DEV *) calloc (1, sizeof (USB_PRN_DEV))) == NULL)
  150.         return (ERROR);
  151.     pUsbPrnDev->pSioChan = pSioChan;
  152.     /* allocate memory for this node, and populate it */
  153.     pUsbPrnNode = (USB_PRN_NODE *) calloc (1, sizeof (USB_PRN_NODE));
  154.     /* record useful information */
  155.     pUsbPrnNode->pUsbPrnDev = pUsbPrnDev;
  156.     pUsbPrnDev->pUsbPrnNode = pUsbPrnNode;
  157.     /* add the node to the list */
  158.     USB_PRN_LIST_SEM_TAKE (WAIT_FOREVER);
  159.     lstAdd (&usbPrnList, (NODE *) pUsbPrnNode);
  160.     USB_PRN_LIST_SEM_GIVE;
  161.  
  162.     /* allow for select support */
  163.     selWakeupListInit (&pUsbPrnDev->selList);
  164.     /* start the device in the only supported mode */
  165.     sioIoctl (pUsbPrnDev->pSioChan, SIO_MODE_SET, (void *) SIO_MODE_INT);
  166.     /* add the device to the I/O system */
  167.     return (iosDevAdd (&pUsbPrnDev->ioDev, name, usbPrnDrvNum));
  168.     }
  169. /*******************************************************************************
  170. *
  171. * usbPrnDevDelete - delete a VxWorks device for an USB printer
  172. *
  173. * This routine deletes a device on a specified serial channel.  
  174. *
  175. * This routine is typically called by the USB printer driver, when it detects 
  176. * a removal of a USB printer.
  177. *
  178. * RETURNS: OK, or ERROR if the driver is not installed.
  179. */
  180. LOCAL STATUS usbPrnDevDelete
  181.     (
  182.     USB_PRN_DEV * pUsbPrnDev /* printer device to read from */
  183.     )
  184.     {
  185.     int status = OK; /* holder for the return value */
  186.     if (usbPrnDrvNum <= 0)
  187.         {
  188.         errnoSet (S_ioLib_NO_DRIVER);
  189.         return (ERROR);
  190.         }
  191.     /* remove the device from the I/O system */
  192.     iosDevDelete (&pUsbPrnDev->ioDev);
  193.     /* remove from list */
  194.     USB_PRN_LIST_SEM_TAKE (WAIT_FOREVER);
  195.     lstDelete (&usbPrnList, (NODE *) pUsbPrnDev->pUsbPrnNode);
  196.     USB_PRN_LIST_SEM_GIVE;
  197.     /* free memory for the device */
  198.     free (pUsbPrnDev->pUsbPrnNode);
  199.     free (pUsbPrnDev);
  200.     return (status);
  201.     }
  202. /*************************************************************************
  203. *
  204. * usbPrnDevFind - find the USB_PRN_DEV device for an SIO channel
  205. *
  206. * RETURNS: OK, or ERROR
  207. */
  208.  
  209. LOCAL STATUS usbPrnDevFind
  210.     (
  211.     SIO_CHAN * pChan,          /* pointer to affected SIO_CHAN */
  212.     USB_PRN_DEV * pUsbPrnDev /* pointer to an USB_PRN_DEV */
  213.     )
  214.     {
  215.     USB_PRN_NODE *      pUsbPrnNode = NULL;     /* pointer to USB device node */
  216.     USB_PRN_DEV * pTempDev; /* pointer to an USB_PRN_DEV */
  217.     if (pChan == NULL)
  218.         return (ERROR);
  219.  
  220.     /* protect it from other module's routines */
  221.  
  222.     USB_PRN_LIST_SEM_TAKE (WAIT_FOREVER);
  223.  
  224.     /* loop through all the devices */
  225.  
  226.     for (pUsbPrnNode = (USB_PRN_NODE *) lstFirst (&usbPrnList);
  227.          pUsbPrnNode != NULL;
  228.          pUsbPrnNode = (USB_PRN_NODE *) lstNext ((NODE *) pUsbPrnNode))
  229.         {
  230.         pTempDev = pUsbPrnNode->pUsbPrnDev;
  231. /* return as soon as you find it */
  232. if (pTempDev->pSioChan == pChan)
  233.     {
  234.     * (UINT32 *) pUsbPrnDev = (UINT32) pTempDev;
  235.     USB_PRN_LIST_SEM_GIVE;
  236.     return (OK);
  237.     }
  238.         }
  239.     USB_PRN_LIST_SEM_GIVE;
  240.     return (ERROR);
  241.     }
  242. /*************************************************************************
  243. *
  244. * usbPrnDrvAttachCallback - receives attach callbacks from printer SIO driver
  245. *
  246. * RETURNS: N/A
  247. */
  248. LOCAL void usbPrnDrvAttachCallback
  249.     (
  250.     void * arg, /* caller-defined argument */
  251.     SIO_CHAN *pChan, /* pointer to affected SIO_CHAN */
  252.     UINT16 attachCode /* defined as USB_KBD_xxxx */
  253.     )
  254.     {
  255.     UINT32 usbPrnDev; /* printer device */
  256.     char prnName [PRN_NAME_LEN_MAX]; /* printer name */
  257.  
  258.     /*  A printer has been attached. */
  259.     if (attachCode == USB_PRN_ATTACH)
  260. {
  261. /*  Lock this particular channel for this particular printer */
  262. if (usbPrinterSioChanLock (pChan) != OK)
  263.     {
  264.     printf("usbPrinterSioChanLock () returned ERRORn");
  265.     }
  266. else
  267.     {
  268.     /*  plugs the name /usbPr/x into the prnName variable */
  269.     sprintf (prnName, "%s%d", USB_PRN_NAME, prnCount);
  270.     /*  Create the printer device, do all the ios stuff (drvInstall, 
  271.      *  devAdd...) 
  272.      */
  273.     if (usbPrnDevCreate (prnName, pChan) != OK)
  274. {
  275. printf("usbPrnDevCreate() returned ERRORn");
  276. }
  277.     /* now we can increment the counter */
  278.     prnCount++;
  279.     if (usbPrnDevFind (pChan, (USB_PRN_DEV *) &usbPrnDev) != OK)
  280. {
  281. printf("usbPrnDevFind() returned ERRORn");
  282. return;
  283. }
  284.     /*  Install a callback to spew characters to the printer 
  285.      *  usbPrnTxCallback () handles sending chunks when the printer
  286.      *  is ready for them
  287.      */
  288.     if ((*pChan->pDrvFuncs->callbackInstall) (pChan, 
  289. SIO_CALLBACK_GET_TX_CHAR, 
  290. (STATUS  (*) (void *, ...)) usbPrnTxCallback, 
  291. (void *) usbPrnDev) 
  292. != OK)
  293. {
  294. printf("usbPrnTxCallback () failed to installn");
  295. }
  296.     printf("USB Printer attached as %sn", prnName);
  297.     }
  298. }
  299.     /* A printer has been detached */
  300.     else if (attachCode == USB_PRN_REMOVE)
  301. {
  302. /* find the related device */
  303. if (usbPrnDevFind (pChan, (USB_PRN_DEV *) &usbPrnDev) != OK)
  304.     {
  305.     printf ("usbPrnDevFind could not find channel 0x%d", (UINT32)pChan);
  306.     return;
  307.     }
  308. /* delete the device */
  309. usbPrnDevDelete ((USB_PRN_DEV *) usbPrnDev);
  310. /* Unlock this channel since the device that was plugged into it
  311.  * was removed
  312.  */
  313. if (usbPrinterSioChanUnlock (pChan) != OK)
  314.     {
  315.     printf("usbPrinterSioChanUnlock () returned ERRORn");
  316.     return;
  317.     }
  318. }
  319.     }
  320. /*******************************************************************************
  321. *
  322. * usbPrnOpen - open a usbPrnDrv serial device.
  323. *
  324. * Increments a counter that holds the number of open paths to device. 
  325. */
  326. LOCAL int usbPrnOpen
  327.     (
  328.     USB_PRN_DEV * pUsbPrnDev,  /* printer device to read from */
  329.     char     * name, /* device name */
  330.     int flags, /* flags */
  331.     int         mode /* mode selected */
  332.     )
  333.     {
  334.     pUsbPrnDev->numOpen++;  /* increment number of open paths */
  335.     
  336.     sioIoctl (pUsbPrnDev->pSioChan, SIO_OPEN, NULL);
  337.     return ((int) pUsbPrnDev);
  338.     }
  339. /*******************************************************************************
  340. *
  341. * usbPrnDrvUnInit - shuts down an I/O USB printer driver
  342. *
  343. *
  344. * This is supplied to for the user, but it should be noted that iosDrvRemove()
  345. * may cause unpredictable results.
  346. *
  347. */
  348. STATUS usbPrnDrvUnInit (void)
  349.     {
  350.     if (!usbPrnDrvNum)
  351. return (OK);
  352.     /* remove the driver */
  353.     if (iosDrvRemove (usbPrnDrvNum, TRUE) != OK)
  354. {
  355. printf("iosDrvRemove () returned ERRORn");
  356. return (ERROR);
  357. }
  358.     /* HELP */
  359.     usbPrnDrvNum = 0;
  360.     /* delete the mutex semaphores */
  361.  
  362.     if (semDelete (usbPrnMutex) == ERROR)
  363. {
  364. printf("semDelete (usbPrnMutex) returned ERRORn");
  365. return (ERROR);
  366. }
  367.     if (semDelete (usbPrnListMutex) == ERROR)
  368. {
  369. printf("semDelete (usbPrnListMutex) returned ERRORn");
  370. return (ERROR);
  371. }
  372.     /* unregister */
  373.  
  374.     if (usbPrinterDynamicAttachUnRegister (usbPrnDrvAttachCallback, 
  375.  NULL) 
  376. != OK)
  377. {
  378. printf("usbPrinterDynamicAttachUnRegister () returned ERRORn");
  379. return (ERROR);
  380. }
  381.  
  382.     /* shutdown */
  383.     if (usbPrinterDevShutdown () != OK)
  384. {
  385. printf("usbPrinterDynamicAttachUnRegister () returned ERRORn");
  386. return (ERROR);
  387. }
  388.     return (OK);
  389.     }
  390. /*******************************************************************************
  391. *
  392. * usbPrnClose - close a usbPrnDrv serial device.
  393. *
  394. * Decrements the counter of open paths to device and alerts the driver 
  395. * with an ioctl call when the count reaches zero. This scheme is used to
  396. * implement the HUPCL(hang up on last close).      
  397. */
  398. LOCAL int usbPrnClose
  399.     (
  400.     USB_PRN_DEV * pUsbPrnDev          /* printer device to read from */
  401.     )
  402.     {
  403.     /* if there are no open channels */
  404.     if (!(--pUsbPrnDev->numOpen))
  405. {
  406. sioIoctl (pUsbPrnDev->pSioChan, SIO_HUP, NULL);
  407. }
  408.     return ((int) pUsbPrnDev);
  409.     }
  410. /*******************************************************************************
  411. *
  412. * usbPrnIoctl - issue device control commands
  413. *
  414. * This routine issues device control commands to an USB printer device.
  415. *
  416. * RETURNS: depends on the function invoked.
  417. */
  418. LOCAL int usbPrnIoctl
  419.     (
  420.     USB_PRN_DEV * pUsbPrnDev, /* printer device to read from */
  421.     int request, /* request code */
  422.     void * arg /* some argument */
  423.     )
  424.     {
  425.     return (sioIoctl (pUsbPrnDev->pSioChan, request, arg));
  426.     }
  427. /*******************************************************************************
  428. *
  429. * usbPrnRead - read from the USB printer
  430. *
  431. * This routines is a no-op for a read from the USB printer.
  432. *
  433. * RETURNS: OK, always.
  434. */
  435. LOCAL int usbPrnRead
  436.     (
  437.     USB_PRN_DEV * pUsbPrnDev          /* printer device to read from */
  438.     )
  439.     {
  440.     int status = OK; /* holder for the return value */
  441.     return (status);
  442.     }
  443. /*******************************************************************************
  444. *
  445. * usbPrnWrite - write to the USB printer
  446. *
  447. * This routine writes <nBytes> bytes of data from the buffer pointed to by
  448. * <buff> to the USB printer described by <pUsbPrnDev>.
  449. *
  450. * RETURNS: number of bytes written or ERROR
  451. */
  452. int usbPrnWrite
  453.     (
  454.     USB_PRN_DEV * pUsbPrnDev,         /* printer device to read from */
  455.     UCHAR * buffer,             /* buffer of data to write  */
  456.     UINT32   nBytes              /* number of bytes in buffer */
  457.     )
  458.     {
  459.     int status = OK; /* holder for the return value */
  460.     /* protect the critical region */
  461.     USB_PRN_MUTEX_TAKE (WAIT_FOREVER);
  462.     /* store buffer information */
  463.     txCallbackBfr = buffer;
  464.     txBytesNum = nBytes;
  465.     pUsbPrnDev->buff = buffer;
  466.     pUsbPrnDev->bufSize = nBytes;
  467.     if ((*(pUsbPrnDev->pSioChan->pDrvFuncs->txStartup)) (pUsbPrnDev->pSioChan) 
  468. != OK)
  469. {
  470. status = ERROR;
  471. }
  472.     /* end of the critical region */
  473.     USB_PRN_MUTEX_GIVE; 
  474.     /* wake up any select-blocked readers */
  475.  
  476.     selWakeupAll (&pUsbPrnDev->selList, SELWRITE);
  477.     status = (int) (nBytes - txBytesNum);
  478.     return (status);
  479.     }
  480. /*************************************************************************
  481. *
  482. * usbPrnTxCallback - feeds characters to USB printer SIO driver
  483. *
  484. * RETURNS: OK
  485. */
  486. LOCAL STATUS usbPrnTxCallback
  487.     (
  488.     void *callbackParam,
  489.     char *txChar
  490.     )
  491.     {
  492.     USB_PRN_DEV * pDev = (USB_PRN_DEV *) callbackParam; /* printer device */
  493.     if (!(pDev->bufSize))
  494. {
  495. return (ERROR);
  496. }
  497.     pDev->bufSize--;
  498.     *txChar = *pDev->buff++;
  499.     return OK;
  500.     }
  501. /*****************************************************************************
  502. *
  503. * usrUsbPrnInit - initialize the USB printer driver
  504. *
  505. * This function initializes the USB printer driver and registers for attach 
  506. * callbacks.  
  507. *
  508. * RETURNS: Nothing 
  509. */
  510. void usrUsbPrnInit (void) 
  511.     {
  512.     /* Check if driver already installed */
  513.     if (usbPrnDrvNum > 0)
  514. {
  515. printf ("Printer already initilaized.n");
  516. }
  517.     /* Initialize USB printer SIO driver */
  518.     if (usbPrinterDevInit () == OK)
  519. {
  520.         printf ("usbPrinterDevInit() returned OKn");
  521. /* Register our device for attach callbacks.  */
  522. if (usbPrinterDynamicAttachRegister (usbPrnDrvAttachCallback, 
  523.    (void *) NULL) 
  524.   != OK)
  525.     {
  526.     printf ("usbPrinterDynamicAttachRegister() returned ERRORn");
  527.     }
  528. }
  529.     else
  530.         printf ("usbPrinterDevInit() returned ERRORn");
  531.     }
  532. /*************************************************************************
  533. *
  534. * usbPrnWrTest - test the USB printer write function
  535. *
  536. * This is given as a sample application to print a file using the i/o 
  537. * system calls to access the printer device.  It has been assumed that the 
  538. * file that it sent to the printer has been "canned" for the particular
  539. * printer being used.  Refer to the USB Developer's Kit manual for further
  540. * details.
  541. *
  542. * RETURNS: OK, or ERROR.
  543. */
  544. STATUS usbPrnWrTest
  545.     (
  546.     char * fileName /* file to print */
  547.     )
  548.     {
  549.     int testFd = 0;
  550.     UCHAR * tempBuff = NULL;
  551.     FILE * testFile;
  552.     UINT32 fsize = 0;
  553.     if ((testFile = fopen (fileName, "rb")) == NULL)
  554. {
  555. printf ("fopen() failed open the input filen");
  556. return (ERROR);
  557. }
  558.     fseek (testFile, 0, SEEK_END);
  559.     fsize = ftell (testFile);
  560.     fseek (testFile, 0, SEEK_SET);
  561.    printf ("usbPrnTxCallback() file size =0x%x n",fsize);
  562.     if ((tempBuff = calloc (1, fsize)) == NULL)
  563. return (ERROR);
  564.     if (fread (tempBuff, 1, fsize, testFile) == 0)
  565. return (ERROR);
  566.     if ((testFd = open ("/usbPr/0", 2,0)) == ERROR)
  567. return (ERROR);
  568.     if (write (testFd, tempBuff, fsize) == ERROR)
  569. return (ERROR);
  570.     return (OK);
  571.     }