📄 usbpegasusend.c
字号:
{ PEGASUS_LOG (PEGASUS_DBG_INIT, "Could not set configutation. \n", 0, 0, 0, 0, 0, 0); goto errorExit; } /* Now go off and initialize the chip and read the mac address */ usbPegasusInit (pNewDev->nodeId, (UINT8 *) pBfr); pDevCtrl->macAdrs[0] = *pBfr; pDevCtrl->macAdrs[1] = *(pBfr + 1); pDevCtrl->macAdrs[2] = *(pBfr + 2); pDevCtrl->macAdrs[3] = *(pBfr + 3); pDevCtrl->macAdrs[4] = *(pBfr + 4); pDevCtrl->macAdrs[5] = *(pBfr + 5); PEGASUS_LOG (PEGASUS_DBG_INIT, "EthernetID %02x %02x %02x " "%02x %02x %02x\n", *pBfr, *(pBfr + 1), *(pBfr + 2), *(pBfr + 3), *(pBfr + 4), *(pBfr + 5)); /* Now, Create the Pipes.. */ if (usbdPipeCreate (pegasusHandle, pNewDev->nodeId, pOutEp->endpointAddress, pCfgDescr->configurationValue, pNewDev->interface, USB_XFRTYPE_BULK, USB_DIR_OUT, FROM_LITTLEW (pOutEp->maxPacketSize), 0, 0, &pDevCtrl->outPipeHandle) != OK) { PEGASUS_LOG (PEGASUS_DBG_INIT, "Pipe O/P coud not be created \n", 0, 0, 0, 0, 0, 0); goto errorExit; } if (usbdPipeCreate (pegasusHandle, pNewDev->nodeId, pInEp->endpointAddress, pCfgDescr->configurationValue, pNewDev->interface, USB_XFRTYPE_BULK, USB_DIR_IN, FROM_LITTLEW (pInEp->maxPacketSize), 0, 0, &pDevCtrl->inPipeHandle) != OK) { PEGASUS_LOG (PEGASUS_DBG_INIT, "Pipe I/P coud not be created \n", 0, 0, 0, 0, 0, 0); goto errorExit; } pDevCtrl->inIrpInUse = FALSE; OSS_FREE (pBfr); return OK;errorExit: OSS_FREE (pBfr); OSS_FREE (pIrpBfrs); for (index=0; index<pDevCtrl->noOfInBfrs; index++) OSS_FREE (pInBfr[index]); OSS_FREE (pInBfr); return ERROR; }/***************************************************************************** pegasusEndStart - Starts communications over Ethernet via usb (device)** Since we don't have any interrupt, we have to prevent the device from * communicating, in some other way. Here, since the reception is based * on polling, and we do the pegasusListenForInput() for such polling,* we can delay listening to any packet coming in, by having* this function called in pegasusEndStart()... This way, we try to mimic the* traditional "interrupt enabling". This is for packet reception.** For packet transmission, we use the communicateOk flag. We transmit data * only if this flag is true. This flag will be set to TRUE in pegasusEndStart().* and will be reset to FALSE in pegasusEndStop().** RETURNS : OK or ERROR*/STATUS pegasusEndStart ( PEGASUS_DEVICE * pDevCtrl /* Device to be started */ ) { PEGASUS_LOG (PEGASUS_DBG_START, "pegasusEndStart:..entered.\n", 0, 0, 0, 0, 0, 0); /* * 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); /* mark the interface as down */ END_FLAGS_CLR (&pDevCtrl->endObj, (IFF_UP | IFF_RUNNING)); /* * 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 */ while ((pRequest = usbListFirst (&reqList)) != NULL) { usbListUnlink (&pRequest->reqLink); OSS_FREE (pRequest); } 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; 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; OSS_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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -