📄 usbpegasusend.c
字号:
* what we do here is that we start listening on the * BULK input pipe..for any ethernet packet coming in. * This is just simulating "connecting the interrupt" in End Model. */ pDevCtrl->communicateOk = TRUE; if (pegasusListenForInput (pDevCtrl) != OK) { pDevCtrl->communicateOk = FALSE; PEGASUS_LOG (PEGASUS_DBG_START, "pegasusEndStart:..Unable to listen " "for input.\n",0, 0, 0, 0, 0, 0); return ERROR; } /* * The above will effectively preempt any possibility of packet reception, * before the pegasusEndStart is called. * for preempting such possiblity for transmission, we use the * communicateOk flag. Ideally we should use a semaphore here but * i thought flag will suffice. */ return OK; }/***************************************************************************** pegasusEndStop - Disables communication over Ethernet via usb (device)* * The pipes will be aborted. If there are any pending transfers on these* Pipes, usbd will see to it that theu are also cancelled. The IRPs for* these transfers will be returned a S_usbHcdLib_IRP_CANCELED error code.* It waits for the IRPs to be informed of their Cancelled Status and then* the function returns.* * RETURNS: OK or ERROR*/STATUS pegasusEndStop ( PEGASUS_DEVICE * pDevCtrl /* Device to be Stopped */ ) { pATTACH_REQUEST pRequest; PEGASUS_LOG (PEGASUS_DBG_STOP, "pegasusEndStop:..entered.\n", 0, 0, 0, 0, 0, 0); /* * We will Abort the transfers the input and output Pipes.. * once we issue such requests, usbd will take care of aborting the * outstanding transfers, if any, associated with the Pipes. */ pDevCtrl->communicateOk = FALSE; /* Dispose of any outstanding notification requests */#if TRUE while ((pRequest = usbListFirst (&reqList)) != NULL) { usbListUnlink (&pRequest->reqLink); OSS_FREE (pRequest); }#endif pegasusDestroyDevice(pDevCtrl); taskDelay(sysClkRateGet()*5); return OK; }/***************************************************************************** pegasusListenForInput - Listens for data on the ethernet (Bulk In Pipe) ** Input IRP will be initialized to listen on the BULK input pipe and will* be submitted to the usbd.** RETURNS : OK if successful or ERROR on failure.** NOMANUAL*/ LOCAL STATUS pegasusListenForInput ( PEGASUS_DEVICE * pDevCtrl /* device to receive from */ ) { pUSB_IRP pIrp = &pDevCtrl->inIrp; if (pDevCtrl == NULL) return ERROR; /* Initialize IRP */ memset (pIrp, 0, sizeof (*pIrp)); pIrp->userPtr = pDevCtrl; pIrp->irpLen = sizeof (*pIrp); pIrp->userCallback = pegasusRxCallback; pIrp->timeout = USB_TIMEOUT_NONE; pIrp->transferLen = pDevCtrl->inBfrLen; pIrp->flags = USB_FLAG_SHORT_OK; pIrp->bfrCount = 1; pIrp->bfrList[0].pid = USB_PID_IN; pIrp->bfrList[0].bfrLen = pDevCtrl->inBfrLen; pIrp->bfrList[0].pBfr = (pUINT8)pDevCtrl->pInBfrArray[pDevCtrl->rxIndex]; /* Submit IRP */ if (usbdTransfer (pegasusHandle, pDevCtrl->inPipeHandle, pIrp) != OK) return ERROR; pDevCtrl->inIrpInUse = TRUE; return OK; }/***************************************************************************** pegasusSend - initiates data transmission to the device** this function initiates transmission on the ethernet.** RETURNS: OK, or ERROR if unable to initiate transmission*/STATUS pegasusSend ( PEGASUS_DEVICE * pDevCtrl, /* device to send to */ UINT8 * pBfr, /* data to send */ UINT32 size /* data size */ ) { pUSB_IRP pIrp; /* = &pDevCtrl->outIrp; */ PEGASUS_ENET_IRP* pIrpBfr; PEGASUS_LOG (PEGASUS_DBG_TX, "pegasusSend:..entered. %d bytes\n", size, 0, 0, 0, 0, 0); if ((pDevCtrl == NULL) || (pBfr == NULL)) { return ERROR; } if (size == 0) return ERROR; pIrpBfr = pDevCtrl->pEnetIrp + pDevCtrl->txIrpIndex; pIrp = &pIrpBfr -> outIrp; pIrpBfr->outIrpInUse = TRUE; PEGASUS_LOG (PEGASUS_DBG_TX, "pegasusSend: %d Irp put to use\n", pDevCtrl->txIrpIndex, 0, 0, 0, 0, 0); pDevCtrl->txIrpIndex++; pDevCtrl->txIrpIndex %= pDevCtrl->noOfIrps; /* Initialize IRP */ memset (pIrp, 0, sizeof (*pIrp)); pIrp->userPtr = pDevCtrl; pIrp->irpLen = sizeof (*pIrp); pIrp->userCallback = pegasusTxCallback; pIrp->timeout = USB_TIMEOUT_NONE; pIrp->transferLen = size; pIrp->bfrCount = 1; pIrp->bfrList [0].pid = USB_PID_OUT; pIrp->bfrList [0].pBfr = pBfr; pIrp->bfrList [0].bfrLen = size; /* Submit IRP */ if (usbdTransfer (pegasusHandle, pDevCtrl->outPipeHandle, pIrp) != OK) return ERROR; return OK; }/***************************************************************************** pegasusTxCallback - Invoked upon Transmit IRP completion/cancellation** NOMANUAL*/LOCAL VOID pegasusTxCallback ( pVOID p /* completed IRP */ ) { pUSB_IRP pIrp = (pUSB_IRP) p; int index = 0; PEGASUS_ENET_IRP* pIrpBfr; PEGASUS_DEVICE * pDevCtrl = pIrp->userPtr; /* Output IRP completed */ for (index = 0; index < pDevCtrl->noOfIrps; index++) { pIrpBfr = pDevCtrl->pEnetIrp + index; if (pIrp == &pIrpBfr->outIrp) { break; } } if (index == pDevCtrl->noOfIrps) return; PEGASUS_LOG (PEGASUS_DBG_TX, "Tx Callback for %d IRP.\n", index, 0, 0, 0, 0, 0); pIrpBfr = pDevCtrl->pEnetIrp + index; pIrpBfr->outIrpInUse = FALSE; free (pIrp->bfrList [0].pBfr); if (pIrp->result != OK) { PEGASUS_LOG (PEGASUS_DBG_TX, "Tx error %x.\n", pIrp->result, 0, 0, 0, 0, 0); if (pIrp->result == S_usbHcdLib_STALLED) { if (usbdFeatureClear (pegasusHandle, pDevCtrl->pDev->nodeId, USB_RT_STANDARD | USB_RT_ENDPOINT, 0, 1) == ERROR) { PEGASUS_LOG (PEGASUS_DBG_TX, "Could not clear STALL.\n", pIrp->result, 0, 0, 0, 0, 0); } } pDevCtrl->outErrors++; /* Should also Update MIB */ } else { PEGASUS_LOG (PEGASUS_DBG_TX, "Tx finished.\n", 0, 0, 0, 0, 0, 0); } }/***************************************************************************** pegasusRxCallback - Invoked when a Packet is received.** NOMANUAL*/LOCAL VOID pegasusRxCallback ( pVOID p /* completed IRP */ ) { pUSB_IRP pIrp = (pUSB_IRP) p; PEGASUS_DEVICE * pDevCtrl = pIrp->userPtr; /* Input IRP completed */ pDevCtrl->inIrpInUse = FALSE; /* * If the IRP was successful then pass the data back to the client. * Note that the netJobAdd() is not necessary here as the function * is not getting executed in isr context. */ if (pIrp->result != OK) { pDevCtrl->inErrors++; /* Should also update MIB */ if(pIrp->result == S_usbHcdLib_STALLED) { usbdFeatureClear (pegasusHandle,pDevCtrl->pDev->nodeId, USB_RT_STANDARD | USB_RT_ENDPOINT, 0, 0); } } else { if( pIrp->bfrList [0].actLen >= 2) { pegasusEndRecv (pDevCtrl,pIrp->bfrList [0].pBfr, pIrp->bfrList [0].actLen); pDevCtrl->rxIndex++; pDevCtrl->rxIndex %= pDevCtrl->noOfInBfrs; } } /* * Unless the IRP was cancelled - implying the channel is being * torn down, re-initiate the "in" IRP to listen for more data from * the printer. */ if (pIrp->result != S_usbHcdLib_IRP_CANCELED) pegasusListenForInput (pDevCtrl); }/***************************************************************************** pegasusMCastFilterSet - Sets a Multicast Address Filter for the device** Even if the host wishes to change a single multicast filter in the device,* it must reprogram the entire list of filters using this function. * <pAddress> shall contain a pointer to this list of multicast addresses* and <noOfFilters> shall hold the number of multicast address filters* being programmed to the device.** RETURNS : OK or ERROR if <noOfFilters> is BIG or if the device NAKs*/STATUS pegasusMCastFilterSet ( PEGASUS_DEVICE * pDevCtrl, /* device to add the mcast filters */ UINT8 * pAddress, /* Mcast address filters list */ UINT32 noOfFilters /* no. of filters to add */ ) { UINT16 actLen; PEGASUS_LOG (PEGASUS_DBG_MCAST, "pegasusMCastFilterSet:..entered.\n", 0, 0, 0, 0, 0, 0); if (pDevCtrl == NULL) return ERROR; /* Check if this many number of Filters are supported by the device */ if ((noOfFilters < 0) || (noOfFilters > (pDevCtrl->mCastFilters.noMCastFilters))) return ERROR; if (((noOfFilters == 0) && (pAddress != NULL)) || ((noOfFilters > 0) && (pAddress == NULL))) return ERROR; /* Set the Filters */ if (usbdVendorSpecific (pegasusHandle, pDevCtrl->pDev->nodeId, USB_PEGASUS_SET_BMREQ, USB_PEGASUS_SET_BREQ, 0, 0x08, noOfFilters*6, pAddress, &actLen) != OK) { PEGASUS_LOG (PEGASUS_DBG_LOAD, "Error Setting Registers\n", 0, 0, 0, 0, 0, 0); return ERROR; } return OK; }/***************************************************************************** pegasusFindDevice - Searches for a usb enet device for indicated <nodeId>** RETURNS: pointer to matching dev struct or NULL if not found* NOMANUAL*/USB_PEGASUS_DEV * pegasusFindDevice ( USBD_NODE_ID nodeId /* Node Id to find */ ) { USB_PEGASUS_DEV * pDev = usbListFirst (&pegasusDevList); while (pDev != NULL) { if (pDev->nodeId == nodeId) break; pDev = usbListNext (&pDev->devLink); } return pDev; }/***************************************************************************** pegasusEndFindDevice - Searches for a usb enet device for a given <productId>* and <vendorId>.** RETURNS: pointer to matching dev struct or NULL if not found* NOMANUAL*/USB_PEGASUS_DEV * pegasusEndFindDevice ( UINT16 vendorId, /* Vendor Id to search for */ UINT16 productId /* Product Id to search for */ ) { USB_PEGASUS_DEV * pDev = usbListFirst (&pegasusDevList); while (pDev != NULL) { if ((pDev->vendorId == vendorId) && (pDev->productId == productId)) break; pDev = usbListNext (&pDev->devLink); } return pDev; } /***************************************************************************** pegasusShutdown - shuts down USB EnetLib** <errCode> should be OK or S_pegasusLib_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 pegasusShutdown ( int errCode ) { PEGASUS_DEVICE * pDev; /* Dispose of any open connections. */ while ((pDev = usbListFirst (&pegasusDevList)) != NULL) pegasusDestroyDevice (pDev); /* * Release our connection to the USBD. The USBD automatically * releases any outstanding dynamic attach requests when a client * unregisters. */ if (pegasusHandle != NULL) { usbdClientUnregister (pegasusHandle); pegasusHandle = NULL; } /* Release resources. */ if (pegasusMutex != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -