⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbprinterlib.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* Retrieve the endpoint descriptor(s) following the identified interface     * descriptor.     */    if ((pOutEp = findEndpoint (pScratchBfr, actLen, USB_ENDPOINT_OUT)) == NULL)        {        OSS_FREE (pBfr);        return ERROR;        }    if (IS_BIDIR (pSioChan->protocol))	if ((pInEp = findEndpoint (pScratchBfr, actLen, USB_ENDPOINT_IN)) == NULL)            {            OSS_FREE (pBfr);            return ERROR;            }    /* Select the configuration. */    if (usbdConfigurationSet (usbdHandle, 			      pSioChan->nodeId,			      pCfgDescr->configurationValue, 			      pCfgDescr->maxPower * USB_POWER_MA_PER_UNIT) 			   != OK)        {        OSS_FREE (pBfr);        return ERROR;        }    /* Select interface      *      * NOTE: Some devices may reject this command, and this does not represent     * a fatal error.  Therefore, we ignore the return status.     */    pSioChan->alternateSetting = pIfDescr->alternateSetting;    usbdInterfaceSet (usbdHandle, pSioChan->nodeId,    pSioChan->interface, pIfDescr->alternateSetting);    /* Create a pipe for output to the printer. */    maxPacketSizeOut = *((pUINT8) &pOutEp->maxPacketSize) |			(*(((pUINT8) &pOutEp->maxPacketSize) + 1) << 8);    if (usbdPipeCreate (usbdHandle, 			pSioChan->nodeId, 			pOutEp->endpointAddress, 			pCfgDescr->configurationValue,			pSioChan->interface, 			USB_XFRTYPE_BULK, 			USB_DIR_OUT,			maxPacketSizeOut, 			0, 			0, 			&pSioChan->outPipeHandle) 		      != OK)        {        OSS_FREE (pBfr);        return ERROR;        }    /* If the device is bi-direction, create a pipe to listen for input from     * the device and submit an IRP to listen for input.     */    if (IS_BIDIR (pSioChan->protocol))	{	maxPacketSizeIn = *((pUINT8) &pInEp->maxPacketSize) |			    (*(((pUINT8) &pInEp->maxPacketSize) + 1) << 8);	if (usbdPipeCreate (usbdHandle, 			    pSioChan->nodeId, 			    pInEp->endpointAddress, 			    pCfgDescr->configurationValue,			    pSioChan->interface, 			    USB_XFRTYPE_BULK, 			    USB_DIR_IN,			    maxPacketSizeIn, 			    0, 			    0, 			    &pSioChan->inPipeHandle) 			  != OK)	    {            OSS_FREE (pBfr);            return ERROR;            }	if (listenForInput (pSioChan) != OK)            {            OSS_FREE (pBfr);            return ERROR;            }	}    OSS_FREE (pBfr);    return OK;    }/***************************************************************************** destroyAttachRequest - disposes of an ATTACH_REQUEST structure** RETURNS: N/A*/LOCAL VOID destroyAttachRequest    (    pATTACH_REQUEST pRequest    )    {    /* Unlink request */    usbListUnlink (&pRequest->reqLink);    /* Dispose of structure */    OSS_FREE (pRequest);    }/***************************************************************************** destroySioChan - disposes of a USB_PRN_SIO_CHAN structure** Unlinks the indicated USB_PRN_SIO_CHAN structure and de-allocates* resources associated with the channel.** RETURNS: N/A*/LOCAL VOID destroySioChan    (    pUSB_PRN_SIO_CHAN pSioChan    )    {    if (pSioChan != NULL)	{	/* Unlink the structure. */	usbListUnlink (&pSioChan->sioLink);	/* Release pipes and wait for IRPs to be cancelled if necessary. */	if (pSioChan->outPipeHandle != NULL)	    usbdPipeDestroy (usbdHandle, pSioChan->outPipeHandle);	if (pSioChan->inPipeHandle != NULL)	    usbdPipeDestroy (usbdHandle, pSioChan->inPipeHandle);	while (pSioChan->outIrpInUse || pSioChan->inIrpInUse)	    OSS_THREAD_SLEEP (1);	/* release buffers */	if (pSioChan->outBfr != NULL)	    OSS_FREE (pSioChan->outBfr);	if (pSioChan->inBfr != NULL)	    OSS_FREE (pSioChan->inBfr);	/* Release structure. */	OSS_FREE (pSioChan);	}    }/***************************************************************************** createSioChan - creates a new USB_PRN_SIO_CHAN structure** Creates a new USB_PRN_SIO_CHAN structure for the indicated <nodeId>.* If successful, the new structure is linked into the sioList upon * return.** <configuration> and <interface> identify the configuration/interface* that first reported itself as a printer for this device.** RETURNS: pointer to newly created structure, or NULL if failure*/LOCAL pUSB_PRN_SIO_CHAN createSioChan    (    USBD_NODE_ID nodeId,    UINT16 configuration,    UINT16 interface,    UINT16 deviceProtocol    )    {    pUSB_PRN_SIO_CHAN pSioChan;    /* Try to allocate space for a new printer struct */    if ((pSioChan = OSS_CALLOC (sizeof (*pSioChan))) == NULL ||	(pSioChan->outBfr = OSS_MALLOC (PRN_OUT_BFR_SIZE)) == NULL)	{	destroySioChan (pSioChan);	return NULL;	}    if (IS_BIDIR (deviceProtocol))	if ((pSioChan->inBfr = OSS_MALLOC (PRN_IN_BFR_SIZE)) == NULL)	    {	    destroySioChan (pSioChan);	    return NULL;	    }    pSioChan->outBfrLen = PRN_OUT_BFR_SIZE;    pSioChan->inBfrLen = PRN_IN_BFR_SIZE;    pSioChan->sioChan.pDrvFuncs = &usbPrinterSioDrvFuncs;    pSioChan->nodeId = nodeId;    pSioChan->connected = TRUE;    pSioChan->mode = SIO_MODE_INT;    pSioChan->configuration = configuration;    pSioChan->interface = interface;    pSioChan->protocol = deviceProtocol;    /* Try to configure the printer. */    if (configureSioChan (pSioChan) != OK)	{	destroySioChan (pSioChan);	return NULL;	}    /* Link the newly created structure. */    usbListLink (&sioList, pSioChan, &pSioChan->sioLink, LINK_TAIL);    return pSioChan;    }/***************************************************************************** findSioChan - Searches for a USB_PRN_SIO_CHAN for indicated node ID** RETURNS: pointer to matching USB_PRN_SIO_CHAN or NULL if not found*/LOCAL pUSB_PRN_SIO_CHAN findSioChan    (    USBD_NODE_ID nodeId    )    {    pUSB_PRN_SIO_CHAN pSioChan = usbListFirst (&sioList);    while (pSioChan != NULL)	{	if (pSioChan->nodeId == nodeId)	    break;	pSioChan = usbListNext (&pSioChan->sioLink);	}    return pSioChan;    }/***************************************************************************** notifyAttach - Notifies registered callers of attachment/removal** RETURNS: N/A*/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*/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*/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** RETURNS: OK, or ERROR if unable to read device ID.*/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** RETURNS: OK, or ERROR if unable to read printer status.*/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** RETURNS: OK, or ERROR if unable to issue soft reset.*/LOCAL STATUS usbPrnSoftReset    (    pUSB_PRN_SIO_CHAN pSioChan    )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -