📄 usbprinterlib.c
字号:
{ if (usbdVendorSpecific (usbdHandle, pSioChan->nodeId, USB_RT_HOST_TO_DEV | USB_RT_CLASS | USB_RT_OTHER, USB_REQ_PRN_SOFT_RESET, 0, pSioChan->interface, 0, NULL, NULL) != OK) { return ERROR; } return OK; }/***************************************************************************** usbPrinterIoctl - special device control** usbPrinterLib supports the following IOCTLs:** SIO_MODE_GET - returns current SIO driver mode (always SIO_MODE_INT).* SIO_MODE_SET - sets current SIO driver mode (must be SIO_MODE_INT).* SIO_AVAIL_MODES_GET - returns available SIO driver modes (SIO_MODE_INT).* SIO_OPEN - always returns OK.* SIO_USB_PRN_DEVICE_ID_GET - returns USB printer device ID* SIO_USB_PRN_PROTOCOL_GET - returns USB printer protocol (uni- or bi-dir)* SIO_USB_PRN_STATUS_GET - returns USB printer status* SIO_USB_PRN_SOFT_RESET - issues soft reset to printer** For SIO_USB_PRN_DEVICE_ID_GET, <someArg> must be a pointer a buffer of* at least USB_PRN_MAX_DEVICE_ID_LEN bytes in length in which the device* ID string for the device will be stored.** For SIO_USB_PRN_PROTOCOL_GET, <someArg> must be a pointer to a UINT8* variable in which the device's "protocol" byte will be stored. The * device generally reports its protocol as USB_PROTOCOL_PRINTER_UNIDIR or* USB_PROTOCOL_PRINTER_BIDIR. If the device reports that it is bi-* directional, then usbPrinterLib will allow input to be read from the * device.** For SIO_USB_PRN_STATUS_GET, <someArg> must be a pointer to a * USB_PRINTER_PORT_STATUS structure in which the device's current status * will be stored. The format of the status structure is defined in * usbPrinter.h.** SIO_USB_PRN_SOFT_RESET does not take an argument in <someArg>.** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed* request.*/LOCAL int usbPrinterIoctl ( SIO_CHAN *pChan, /* device to control */ int request, /* request code */ void *someArg /* some argument */ ) { pUSB_PRN_SIO_CHAN pSioChan = (pUSB_PRN_SIO_CHAN) pChan; int arg = (int) someArg; switch (request) { case SIO_MODE_SET: /* Set driver operating mode: interrupt or polled. * * NOTE: This driver supports only SIO_MODE_INT. */ if (arg != SIO_MODE_INT) return EIO; pSioChan->mode = arg; return OK; case SIO_MODE_GET: /* Return current driver operating mode for channel */ *((int *) arg) = pSioChan->mode; return OK; case SIO_AVAIL_MODES_GET: /* Return modes supported by driver. */ *((int *) arg) = SIO_MODE_INT; return OK; case SIO_OPEN: /* Channel is always open. */ return OK; case SIO_USB_PRN_DEVICE_ID_GET: if (usbPrnDeviceIdGet (pSioChan, (pUSB_PRINTER_CAPABILITIES) arg) != OK) return EIO; return OK; case SIO_USB_PRN_PROTOCOL_GET: /* return protocol byte reported by printer. */ *((pUINT8) arg) = pSioChan->protocol; return OK; case SIO_USB_PRN_STATUS_GET: if (usbPrnPortStatusGet (pSioChan, (pUSB_PRINTER_PORT_STATUS) arg) != OK) return EIO; return OK; case SIO_USB_PRN_SOFT_RESET: if (usbPrnSoftReset (pSioChan) != OK) return EIO; return OK; case SIO_BAUD_SET: /* set baud rate */ case SIO_BAUD_GET: /* get baud rate */ case SIO_HW_OPTS_SET: /* optional, not supported */ case SIO_HW_OPTS_GET: /* optional, not supported */ case SIO_HUP: /* hang up is not supported */ default: /* unknown/unsupported command. */ return ENOSYS; } }/***************************************************************************** usbPrinterTxStartup - start the interrupt transmitter** This function will be called when characters are available for transmission* to the printer. ** RETURNS: OK, or EIO if unable to start transmission to printer*/LOCAL int usbPrinterTxStartup ( SIO_CHAN *pChan /* channel to start */ ) { pUSB_PRN_SIO_CHAN pSioChan = (pUSB_PRN_SIO_CHAN) pChan; int status = OK; OSS_MUTEX_TAKE (prnMutex, OSS_BLOCK); if (initiateOutput (pSioChan) != OK) status = EIO; OSS_MUTEX_RELEASE (prnMutex); return status; }/***************************************************************************** usbPrinterCallbackInstall - install ISR callbacks to get/put chars** This driver allows interrupt callbacks for transmitting characters* and receiving characters.=** RETURNS: OK on success, or ENOSYS for an unsupported callback type.*/ LOCAL int usbPrinterCallbackInstall ( SIO_CHAN *pChan, /* channel */ int callbackType, /* type of callback */ STATUS (*callback) (), /* callback */ void *callbackArg /* parameter to callback */ ) { pUSB_PRN_SIO_CHAN pSioChan = (pUSB_PRN_SIO_CHAN) pChan; switch (callbackType) { case SIO_CALLBACK_GET_TX_CHAR: pSioChan->getTxCharCallback = callback; pSioChan->getTxCharArg = callbackArg; return OK; case SIO_CALLBACK_PUT_RCV_CHAR: pSioChan->putRxCharCallback = callback; pSioChan->putRxCharArg = callbackArg; return OK; default: return ENOSYS; } }/***************************************************************************** usbPrinterPollOutput - output a character in polled mode** The USB printer driver supports only interrupt-mode operation. Therefore,* this function always returns the error ENOSYS.** RETURNS: ENOSYS*/LOCAL int usbPrinterPollOutput ( SIO_CHAN *pChan, char outChar ) { return ENOSYS; }/***************************************************************************** usbPrinterPollInput - poll the device for input** The USB printer driver supports only interrupt-mode operation. Therefore,* this function always returns the error ENOSYS.** RETURNS: ENOSYS*/LOCAL int usbPrinterPollInput ( SIO_CHAN *pChan, char *thisChar ) { return ENOSYS; }/***************************************************************************** usbPrinterDevInit - initialize USB printer SIO driver** Initializes the USB printer SIO driver. The USB printer SIO driver* maintains an initialization count, so calls to this function may be* nested.** RETURNS: OK, or ERROR if unable to initialize.** ERRNO:** S_usbPrinterLib_OUT_OF_RESOURCES* S_usbPrinterLib_USBD_FAULT*/STATUS usbPrinterDevInit (void) { /* If not already initialized, then initialize internal structures * and connection to USBD. */ if (initCount == 0) { /* Initialize lists, structures, resources. */ memset (&sioList, 0, sizeof (sioList)); memset (&reqList, 0, sizeof (reqList)); prnMutex = NULL; usbdHandle = NULL; if (OSS_MUTEX_CREATE (&prnMutex) != OK) return doShutdown (S_usbPrinterLib_OUT_OF_RESOURCES); /* Establish connection to USBD */ if (usbdClientRegister (PRN_CLIENT_NAME, &usbdHandle) != OK || usbdDynamicAttachRegister (usbdHandle, USB_CLASS_PRINTER, USB_SUBCLASS_PRINTER, USBD_NOTIFY_ALL, usbPrinterAttachCallback) != OK) { return doShutdown (S_usbPrinterLib_USBD_FAULT); } } initCount++; return OK; }/***************************************************************************** usbPrinterDevShutdown - shuts down printer SIO driver** RETURNS: OK, or ERROR if unable to shutdown.** ERRNO:* S_usbPrinterLib_NOT_INITIALIZED*/STATUS usbPrinterDevShutdown (void) { /* Shut down the USB printer SIO driver if the initCount goes to 0. */ if (initCount == 0) return ossStatus (S_usbPrinterLib_NOT_INITIALIZED); if (--initCount == 0) return doShutdown (OK); return OK; }/***************************************************************************** usbPrinterDynamicAttachRegister - Register printer attach callback** <callback> is a caller-supplied function of the form:** .CS* typedef (*USB_PRN_ATTACH_CALLBACK) * (* pVOID arg,* SIO_CHAN *pSioChan,* UINT16 attachCode* );* .CE** usbPrinterLib will invoke <callback> each time a USB printer* is attached to or removed from the system. <arg> is a caller-defined* parameter which will be passed to the <callback> each time it is* invoked. The <callback> will also be passed a pointer to the * SIO_CHAN structure for the channel being created/destroyed and* an attach code of USB_PRN_ATTACH or USB_PRN_REMOVE.** RETURNS: OK, or ERROR if unable to register callback** ERRNO:* S_usbPrinterLib_BAD_PARAM* S_usbPrinterLib_OUT_OF_MEMORY*/STATUS usbPrinterDynamicAttachRegister ( USB_PRN_ATTACH_CALLBACK callback, /* new callback to be registered */ pVOID arg /* user-defined arg to callback */ ) { pATTACH_REQUEST pRequest; pUSB_PRN_SIO_CHAN pSioChan; int status = OK; /* Validate parameters */ if (callback == NULL) return ossStatus (S_usbPrinterLib_BAD_PARAM); OSS_MUTEX_TAKE (prnMutex, OSS_BLOCK); /* Create a new request structure to track this callback request. */ if ((pRequest = OSS_CALLOC (sizeof (*pRequest))) == NULL) status = S_usbPrinterLib_OUT_OF_MEMORY; else { pRequest->callback = callback; pRequest->callbackArg = arg; usbListLink (&reqList, pRequest, &pRequest->reqLink, LINK_TAIL); /* Perform an initial notification of all currrently attached * printer devices. */ pSioChan = usbListFirst (&sioList); while (pSioChan != NULL) { if (pSioChan->connected) (*callback) (arg, (SIO_CHAN *) pSioChan, USB_PRN_ATTACH); pSioChan = usbListNext (&pSioChan->sioLink); } } OSS_MUTEX_RELEASE (prnMutex); return ossStatus (status); }/***************************************************************************** usbPrinterDynamicAttachUnregister - Unregisters printer attach callback** This function cancels a previous request to be dynamically notified for* printer attachment and removal. The <callback> and <arg> paramters must* exactly match those passed in a previous call to * usbPrinterDynamicAttachRegister().** RETURNS: OK, or ERROR if unable to unregister callback** ERRNO:* S_usbPrinterLib_NOT_REGISTERED*/STATUS usbPrinterDynamicAttachUnRegister ( USB_PRN_ATTACH_CALLBACK callback, /* callback to be unregistered */ pVOID arg /* user-defined arg to callback */ ) { pATTACH_REQUEST pRequest; int status = S_usbPrinterLib_NOT_REGISTERED; OSS_MUTEX_TAKE (prnMutex, OSS_BLOCK); pRequest = usbListFirst (&reqList); while (pRequest != NULL) { if (callback == pRequest->callback && arg == pRequest->callbackArg) { /* We found a matching notification request. */ destroyAttachRequest (pRequest); status = OK; break; } pRequest = usbListNext (&pRequest->reqLink); } OSS_MUTEX_RELEASE (prnMutex); return ossStatus (status); }/***************************************************************************** usbPrinterSioChanLock - Marks SIO_CHAN structure as in use** A caller uses usbPrinterSioChanLock() to notify usbPrinterLib that* it is using the indicated SIO_CHAN structure. usbPrinterLib maintains* a count of callers using a particular SIO_CHAN structure so that it * knows when it is safe to dispose of a structure when the underlying* USB printer is removed from the system. So long as the "lock count"* is greater than zero, usbPrinterLib will not dispose of an SIO_CHAN* structure.** RETURNS: OK, or ERROR if unable to mark SIO_CHAN structure in use.*/STATUS usbPrinterSioChanLock ( SIO_CHAN *pChan /* SIO_CHAN to be marked as in use */ ) { pUSB_PRN_SIO_CHAN pSioChan = (pUSB_PRN_SIO_CHAN) pChan; pSioChan->lockCount++; return OK; }/***************************************************************************** usbPrinterSioChanUnlock - Marks SIO_CHAN structure as unused** This function releases a lock placed on an SIO_CHAN structure. When a* caller no longer needs an SIO_CHAN structure for which it has previously* called usbPrinterSioChanLock(), then it should call this function to* release the lock.** NOTE: If the underlying USB printer device has already been removed* from the system, then this function will automatically dispose of the* SIO_CHAN structure if this call removes the last lock on the structure.* Therefore, a caller must not reference the SIO_CHAN again structure after* making this call.** RETURNS: OK, or ERROR if unable to mark SIO_CHAN structure unused** ERRNO:* S_usbPrinterLib_NOT_LOCKED*/STATUS usbPrinterSioChanUnlock ( SIO_CHAN *pChan /* SIO_CHAN to be marked as unused */ ) { pUSB_PRN_SIO_CHAN pSioChan = (pUSB_PRN_SIO_CHAN) pChan; int status = OK; OSS_MUTEX_TAKE (prnMutex, OSS_BLOCK); if (pSioChan->lockCount == 0) status = S_usbPrinterLib_NOT_LOCKED; else { /* If this is the last lock and the underlying USB printer is * no longer connected, then dispose of the printer. */ if (--pSioChan->lockCount == 0 && !pSioChan->connected) destroySioChan (pSioChan); } OSS_MUTEX_RELEASE (prnMutex); return ossStatus (status); }/* end of file. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -