📄 usbprinterlib.c
字号:
* of device** RETURNS: N/A** ERRNO: none** \NOMANUAL*/LOCAL VOID notifyAttach ( pUSB_PRN_SIO_CHAN pSioChan, UINT16 attachCode ) { pATTACH_REQUEST pRequest = usbListFirst (&reqList); while (pRequest != NULL) { (*pRequest->callback) (pRequest->callbackArg, (SIO_CHAN *) pSioChan, attachCode); pRequest = usbListNext (&pRequest->reqLink); } }/***************************************************************************** usbPrinterAttachCallback - called by USBD when printer attached/removed** The USBD will invoke this callback when a USB printer is attached to or* removed from the system. <nodeId> is the USBD_NODE_ID of the node being* attached or removed. <attachAction> is USBD_DYNA_ATTACH or USBD_DYNA_REMOVE.* printers generally report their class information at the interface level,* so <configuration> and <interface> will indicate the configuratin/interface* that reports itself as a printer. <deviceClass> and <deviceSubClass> * will match the class/subclass for which we registered. <deviceProtocol>* will tell us if this is a uni- or bi-directional device.** NOTE: The USBD will invoke this function once for each configuration/* interface which reports itself as a printer. So, it is possible that* a single device insertion/removal may trigger multiple callbacks. We* ignore all callbacks except the first for a given device.** RETURNS: N/A** ERRNO: none** \NOMANUAL*/LOCAL VOID usbPrinterAttachCallback ( USBD_NODE_ID nodeId, UINT16 attachAction, UINT16 configuration, UINT16 interface, UINT16 deviceClass, UINT16 deviceSubClass, UINT16 deviceProtocol ) { pUSB_PRN_SIO_CHAN pSioChan; OSS_MUTEX_TAKE (prnMutex, OSS_BLOCK); /* Depending on the attach code, add a new printer or disable one * that's already been created. */ switch (attachAction) { case USBD_DYNA_ATTACH: /* A new device is being attached. Check if we already * have a structure for this device. */ if (findSioChan (nodeId) != NULL) break; /* Create a new structure to manage this device. If there's * an error, there's nothing we can do about it, so skip the * device and return immediately. */ if ((pSioChan = createSioChan (nodeId, configuration, interface, deviceProtocol)) == NULL) break; /* Notify registered callers that a new printer has been * added and a new channel created. */ notifyAttach (pSioChan, USB_PRN_ATTACH); break; case USBD_DYNA_REMOVE: /* A device is being detached. Check if we have any * structures to manage this device. */ if ((pSioChan = findSioChan (nodeId)) == NULL) break; /* The device has been disconnected. */ pSioChan->connected = FALSE; /* Notify registered callers that the printer has been * removed and the channel disabled. * * NOTE: We temporarily increment the channel's lock count * to prevent usbPrinterSioChanUnlock() from destroying the * structure while we're still using it. */ pSioChan->lockCount++; notifyAttach (pSioChan, USB_PRN_REMOVE); pSioChan->lockCount--; /* If no callers have the channel structure locked, destroy * it now. If it is locked, it will be destroyed later during * a call to usbPrinterUnlock(). */ if (pSioChan->lockCount == 0) destroySioChan (pSioChan); break; } OSS_MUTEX_RELEASE (prnMutex); }/***************************************************************************** doShutdown - shuts down USB printer SIO driver** <errCode> should be OK or S_usbPrinterLib_xxxx. This value will be* passed to ossStatus() and the return value from ossStatus() is the* return value of this function.** RETURNS: OK, or ERROR per value of <errCode> passed by caller** ERRNO: appropiate errorcode** \NOMANUAL*/LOCAL STATUS doShutdown ( int errCode ) { pATTACH_REQUEST pRequest; pUSB_PRN_SIO_CHAN pSioChan; /* Dispose of any outstanding notification requests */ while ((pRequest = usbListFirst (&reqList)) != NULL) destroyAttachRequest (pRequest); /* Dispose of any open printer connections. */ while ((pSioChan = usbListFirst (&sioList)) != NULL) destroySioChan (pSioChan); /* Release our connection to the USBD. The USBD automatically * releases any outstanding dynamic attach requests when a client * unregisters. */ if (usbdHandle != NULL) { usbdClientUnregister (usbdHandle); usbdHandle = NULL; } /* Release resources. */ if (prnMutex != NULL) { OSS_MUTEX_DESTROY (prnMutex); prnMutex = NULL; } return ossStatus (errCode); }/***************************************************************************** usbPrnDeviceIdGet - Reads USB printer device ID** This function reads the USB printer device ID** RETURNS: OK, or ERROR if unable to read device ID.** ERRNO: none** \NOMANUAL*/LOCAL STATUS usbPrnDeviceIdGet ( pUSB_PRN_SIO_CHAN pSioChan, pUSB_PRINTER_CAPABILITIES pBfr ) { UINT16 actLen; if (usbdVendorSpecific (usbdHandle, pSioChan->nodeId, USB_RT_DEV_TO_HOST | USB_RT_CLASS | USB_RT_INTERFACE, USB_REQ_PRN_GET_DEVICE_ID, pSioChan->configuration, (pSioChan->interface << 8) | pSioChan->alternateSetting, USB_PRN_MAX_DEVICE_ID_LEN, (pUINT8) pBfr, &actLen) != OK || actLen < sizeof (UINT16) /* size of 1284 device ID length prefix */) { return ERROR; } return OK; }/***************************************************************************** usbPrnPortStatusGet - Reads USB printer status** This function reads the printer status.** RETURNS: OK, or ERROR if unable to read printer status.** ERRNO: none** \NOMANUAL*/LOCAL STATUS usbPrnPortStatusGet ( pUSB_PRN_SIO_CHAN pSioChan, pUSB_PRINTER_PORT_STATUS pBfr ) { UINT16 actLen; if (usbdVendorSpecific (usbdHandle, pSioChan->nodeId, USB_RT_DEV_TO_HOST | USB_RT_CLASS | USB_RT_INTERFACE, USB_REQ_PRN_GET_PORT_STATUS, 0, pSioChan->interface, sizeof (*pBfr), (pUINT8) pBfr, &actLen) != OK || actLen < sizeof (*pBfr)) { return ERROR; } return OK; }/***************************************************************************** usbPrnSoftReset - Issues soft reset to printer device** This function issues a soft reset to the printer device as a vendor specific* request** RETURNS: OK, or ERROR if unable to issue soft reset.** ERRNO: none** \NOMANUAL*/LOCAL STATUS usbPrnSoftReset ( pUSB_PRN_SIO_CHAN pSioChan ) { 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.** ERRNO: none** \NOMANUAL*/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; int status = 0; OSS_MUTEX_TAKE (prnMutex, OSS_BLOCK); 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) status = EIO; else { pSioChan->mode = arg; status = OK; } break; case SIO_MODE_GET: /* Return current driver operating mode for channel */ *((int *) arg) = pSioChan->mode; status = OK; break; case SIO_AVAIL_MODES_GET: /* Return modes supported by driver. */ *((int *) arg) = SIO_MODE_INT; status = OK; break; case SIO_OPEN: /* Channel is always open. */ status = OK; break; case SIO_USB_PRN_DEVICE_ID_GET: if (usbPrnDeviceIdGet (pSioChan, (pUSB_PRINTER_CAPABILITIES) arg) != OK) status = EIO; else status = OK; break; case SIO_USB_PRN_PROTOCOL_GET: /* return protocol byte reported by printer. */ *((pUINT8) arg) = pSioChan->protocol; status = OK; break; case SIO_USB_PRN_STATUS_GET: if (usbPrnPortStatusGet (pSioChan, (pUSB_PRINTER_PORT_STATUS) arg) != OK) status = EIO; else status = OK; break; case SIO_USB_PRN_SOFT_RESET: if (usbPrnSoftReset (pSioChan) != OK) status = EIO; else status = OK; break; case SIO_USB_PRN_CANCEL: if ( usbPrnCancelPrint (pSioChan) != OK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -