📄 usbpegasusend.c
字号:
/* * Now we decifer the descriptors provided by the device .. * we try finding out what end point is what.. * that doesn't mean we won't assume any thing, we assume certain * things though..like there are no any alternate settings for interfaces * etc.. */ /* To start with, get the configuration descriptor ..*/ if (usbdDescriptorGet (pegasusHandle, pNewDev->nodeId, USB_RT_STANDARD | USB_RT_DEVICE, USB_DESCR_CONFIGURATION, 0, 0, USB_MAX_DESCR_LEN, pBfr, &actLen) != OK) { PEGASUS_LOG (PEGASUS_DBG_INIT, "Could not GET Desc...\n", 0, 0, 0, 0, 0, 0); goto errorExit; } if ((pCfgDescr = usbDescrParse (pBfr, actLen, USB_DESCR_CONFIGURATION)) == NULL) { PEGASUS_LOG (PEGASUS_DBG_INIT, "Could not find Config. Desc...\n", 0, 0, 0, 0, 0, 0); goto errorExit; } /* * Since we registered for NOTIFY_ALL for attachment of devices, * the configuration no and interface number as reported by the * call back function doesn't have any meanning. * we refer to the PEGASUS document and it says, it has only one * interface with number 0. So the first (only) interface we find * is the interface we want. * If there are more interfaces and one of them meet our requirement * (as reported by callback funtction), then we need to parse * until we find our one.. */ /* * usbDescrParseSkip() modifies the value of the pointer it recieves * so we pass it a copy of our buffer pointer */ pScratchBfr = pBfr; if ((pIfDescr = usbDescrParseSkip (&pScratchBfr, &actLen, USB_DESCR_INTERFACE)) == NULL) { PEGASUS_LOG (PEGASUS_DBG_INIT, "Could not find Intrface Desc.\n", 0, 0, 0, 0, 0, 0); goto errorExit; } /* Find out the output and input end points ..*/ if ((pOutEp = findEndpoint (pScratchBfr, actLen, USB_ENDPOINT_OUT)) == NULL) { PEGASUS_LOG (PEGASUS_DBG_INIT, "No Output End Point \n", 0, 0, 0, 0, 0, 0); goto errorExit; } if ((pInEp = findEndpoint (pScratchBfr, actLen, USB_ENDPOINT_IN)) == NULL) { PEGASUS_LOG (PEGASUS_DBG_INIT, "No Input End Point \n", 0, 0, 0, 0, 0, 0); goto errorExit; } pDevCtrl->maxPower = pCfgDescr->maxPower; /* * Now, set the configuration. */ if (usbdConfigurationSet (pegasusHandle, pNewDev->nodeId, pCfgDescr->configurationValue, pCfgDescr->maxPower * USB_POWER_MA_PER_UNIT) != OK) { 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 */ if (usbPegasusInit (pNewDev->nodeId, (UINT8 *) pBfr) != OK) { PEGASUS_LOG (PEGASUS_DBG_INIT, "Could not initialize \n", 0, 0, 0, 0, 0, 0); goto errorExit; } 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); if (pDevCtrl->pEnetIrp != NULL) OSS_FREE (pDevCtrl->pEnetIrp); 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** ERRNO: NONE**\NOMANUAL*/LOCAL 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; PEGASUS_LOG (PEGASUS_DBG_START, "pegasusListenForInput:..entered.\n", 0, 0, 0, 0, 0, 0); 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** ERRNO: none** \NOMANUAL*/LOCAL 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.** ERRNO: none** \NOMANUAL*/ LOCAL STATUS pegasusListenForInput ( PEGASUS_DEVICE * pDevCtrl /* device to receive from */ ) { pUSB_IRP pIrp = NULL; if (pDevCtrl == NULL) return ERROR; pIrp = &pDevCtrl->inIrp; /* 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** ERRNO: none** \NOMANUAL*/LOCAL 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; int index; 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; END_TX_SEM_TAKE(&pDevCtrl->endObj,WAIT_FOREVER); pIrpBfr = pDevCtrl->pEnetIrp + pDevCtrl->txIrpIndex; if (pIrpBfr->outIrpInUse) { pDevCtrl->txStall = TRUE; PEGASUS_LOG (PEGASUS_DBG_TX_STALL, "pegasusSend: No TX IRP's available\n", 0, 0, 0, 0, 0, 0); END_TX_SEM_GIVE(&pDevCtrl->endObj); return(END_ERR_BLOCK); } 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); index = pDevCtrl->txIrpIndex; pDevCtrl->txIrpIndex++; pDevCtrl->txIrpIndex %= pDevCtrl->noOfIrps; /* Initialize IRP */ if ((size % 64) == 0) size++; 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 (!pDevCtrl->txActive) { PEGASUS_LOG (PEGASUS_DBG_TX_STALL, "pegasusSend: Submitting 1st IRP %d %x %d\n", index, (int)pIrp, size, 0, 0, 0); if (usbdTransfer (pegasusHandle, pDevCtrl->outPipeHandle, pIrp) != OK) { END_TX_SEM_GIVE(&pDevCtrl->endObj); return ERROR; } pDevCtrl->txActive = TRUE; } else { PEGASUS_LOG (PEGASUS_DBG_TX_STALL, "pegasusSend: Queueing IRP %d\n", index, 0, 0, 0, 0, 0); } END_TX_SEM_GIVE(&pDevCtrl->endObj); return OK; }/******************************************************************************** pegasusMuxTxRestart - place muxTxRestart on netJobRing** This function places the muxTxRestart on netJobRing** RETURNS: N/A** ERRNO: none*/void pegasusMuxTxRestart ( END_OBJ * pEndObj /* pointer to DRV_CTRL structure */ ) { muxTxRestart(pEndObj); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -