📄 usbnc1080end.c
字号:
/* * Unless the IRP was cancelled - implying the channel is being * torn down, re-initiate the "in" IRP to listen for more data from * the device. */ if (pIrp->result != S_usbHcdLib_IRP_CANCELED) usbNC1080ListenForInput (pDrvCtrl); }/**************************************************************************** usbNC1080Recv - process the incoming packet** usbNC1080Recv is called by the usbNC1080RxCallBack() upon successful execution* of an input IRP. This means we got some proper data. This function will be* called with the pointer to be buffer and the length of data.* What we do here is to construct an MBlk strcuture with the data received* and pass it onto the upper layer.** RETURNS: N/A.* NOMANUAL*/LOCAL STATUS usbNC1080Recv ( NC1080_END_DEV * pDrvCtrl, /* device structure */ UINT8 * pBuf, /* pointer to data buffer */ UINT16 len /* length of data */ ) { char * pNewCluster; /* Clsuter to store the data */ CL_BLK_ID pClBlk; /* Control block to "control" the cluster */ M_BLK_ID pMblk; /* and an MBlk to complete a MBlk contruct */ NC_HEADER * pHeader; /* usbNC1080 Protocol */ /* Add one to our unicast data. */ END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1); /* NC1080 Protocol verifications */ pHeader = (NC_HEADER *) pBuf; if (pHeader->hdr_len < NETCHIP_MIN_HEADER) { DRV_LOG (DRV_DBG_RX, "Rx : Header Length mismatch! Actual : %d \n", pHeader->hdr_len, 2, 3, 4, 5, 6); return ERROR; } if (pHeader->hdr_len != sizeof (NC_HEADER)) { DRV_LOG (DRV_DBG_RX, "Rx : Out of Band Header : %d bytes\n", pHeader->hdr_len, 2, 3, 4, 5, 6); } /* All protocol checks complete */ pNewCluster = netClusterGet (pDrvCtrl->endObj.pNetPool, pDrvCtrl->pClPoolId); if (pNewCluster == NULL) { DRV_LOG (DRV_DBG_RX, "Recv: Cannot loan!\n", 1, 2, 3, 4, 5, 6); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); goto cleanRXD; } memcpy( pNewCluster, pBuf + pHeader->hdr_len, pHeader->packet_len); /* pNewCluster = pBuf + pHeader->hdr_len; */ /* Grab a cluster block to marry to the cluster we received. */ if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL) { netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pNewCluster); DRV_LOG (DRV_DBG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); goto cleanRXD; } /* * Let's get an M_BLK_ID and marry it to the one in the ring. */ if ((pMblk = mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA)) == NULL) { netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk); netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *)pNewCluster); DRV_LOG (DRV_DBG_RX, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); goto cleanRXD; } END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1); /* Join the cluster to the MBlock */ netClBlkJoin (pClBlk, pNewCluster, pHeader->packet_len, NULL, 0, 0, 0); netMblkClJoin (pMblk, pClBlk); pMblk->mBlkHdr.mLen = pHeader->packet_len; pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkPktHdr.len = pHeader->packet_len; /* Call the upper layer's receive routine. */ END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk); cleanRXD: return OK; }/**************************************************************************** usbNC1080Send - the driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID. We copy* the data contained in the MBlks to a character buffer, forms an IRP and* transmits the data.* We put the usbNC1080 turboconnect protocol information in the buffer here.* The data copied from MBlks, must already have the addressing information* properly installed in it. This is done by a higher layer.*** RETURNS: OK or ERROR.*/LOCAL STATUS usbNC1080Send ( NC1080_END_DEV * pDrvCtrl, /* device ptr */ M_BLK_ID pMblk /* data to send */ ) { UINT8 * pBuf; /* buffer to hold the data */ UINT32 noOfBytes; /* noOfBytes to be transmitted */ NC_HEADER * pHeader; /* protcol header */ NC_FOOTER * pFooter; /* protocol footer */ int len; /* length of packet */ pUSB_IRP pIrp = &pDrvCtrl->outIrp; if ((pDrvCtrl == NULL) || (pMblk == NULL)) return ERROR; OSS_MUTEX_TAKE (usbNC1080TxMutex, OSS_BLOCK); DRV_LOG (DRV_DBG_TX, "usbNC1080Send: Entered.\n", 0, 0, 0, 0, 0, 0); pBuf = pDrvCtrl->pOutBfrArray[pDrvCtrl->txBufIndex]; pDrvCtrl->txBufIndex++; pDrvCtrl->txBufIndex %= NETCHIP_NUM_OUT_BFRS; /* copy the MBlk chain to a buffer */ noOfBytes = netMblkToBufCopy (pMblk, (char *)pBuf + sizeof(NC_HEADER),NULL); if (noOfBytes == 0) return ERROR; DRV_LOG (DRV_DBG_TX, "usbNC1080Send: %d bytes to be sent.\n", noOfBytes, 0, 0, 0, 0, 0); /* Set the netchip protocol header/footer */ pHeader = (NC_HEADER *)pBuf; pHeader->hdr_len = sizeof (NC_HEADER); pHeader->packet_len = noOfBytes; pHeader->packet_id = ++(pDrvCtrl->txPkts); /* Maintain odd length. Pad a byte if necessary */ len = noOfBytes + sizeof (NC_HEADER)+ sizeof (NC_FOOTER); if (!(len & 0x01)) { *(pBuf + noOfBytes + sizeof (NC_HEADER)) = NETCHIP_PAD_BYTE; pFooter = (NC_FOOTER *)(pBuf + noOfBytes + sizeof (NC_HEADER) + 1); len ++; } else { pFooter = (NC_FOOTER *)(pBuf + noOfBytes + sizeof (NC_HEADER)); } pFooter->packet_id = pDrvCtrl->txPkts; PKT_PRINT(PKT_DBG_TX,pBuf,len); /* Transmit data */ pDrvCtrl->outIrpInUse = TRUE; /* Initialize IRP */ memset (pIrp, 0, sizeof (*pIrp)); pIrp->userPtr = pDrvCtrl; pIrp->irpLen = sizeof (*pIrp); pIrp->userCallback = usbNC1080TxCallback; pIrp->timeout = 2000; pIrp->transferLen = len; pIrp->bfrCount = 1; pIrp->bfrList [0].pid = USB_PID_OUT; pIrp->bfrList [0].pBfr = pBuf; pIrp->bfrList [0].bfrLen = len; /* Submit IRP */ if (usbdTransfer (usbNC1080Handle, pDrvCtrl->outPipeHandle, pIrp) != OK) return ERROR; DRV_LOG (DRV_DBG_TX, "usbNC1080Send: Pkt submitted for tx.\n", 0, 0, 0, 0, 0, 0); /* Wait for IRP to complete or cancel by timeout */ if (OSS_SEM_TAKE (usbNC1080IrpSem, 2000 + 1000) == ERROR ) { DRV_LOG (DRV_DBG_TX, "usbNC1080Send: Fatal error. " "pId : %x len : %x \n", pHeader->packet_id, len, 0, 0, 0, 0); OSS_SEM_GIVE (usbNC1080IrpSem); } else { DRV_LOG (DRV_DBG_TX, "usbNC1080Send: Tx Successful!!. " "pId : %x len : %d \n", pHeader->packet_id, len, 0, 0, 0, 0); } OSS_MUTEX_RELEASE (usbNC1080TxMutex); /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1); /* Cleanup. The driver frees the packet now. */ netMblkClChainFree (pMblk); return (OK); }/**************************************************************************** usbNC1080TxCallback - Invoked upon Transmit IRP completion/cancellation** NOMANUAL*/LOCAL VOID usbNC1080TxCallback ( pVOID p /* completed IRP */ ) { pUSB_IRP pIrp = (pUSB_IRP) p; NC1080_END_DEV * pDrvCtrl = pIrp->userPtr; /* Output IRP completed */ pDrvCtrl->outIrpInUse = FALSE; DRV_LOG (DRV_DBG_TX, "Tx Callback \n", 0, 0, 0, 0, 0, 0); if (pIrp->result != OK) { DRV_LOG (DRV_DBG_TX, "Tx error %x.\n",pIrp->result, 0, 0, 0, 0, 0); if (pIrp->result == S_usbHcdLib_STALLED) { if (usbdFeatureClear (usbNC1080Handle, pDrvCtrl->pDev->nodeId, USB_RT_STANDARD | USB_RT_ENDPOINT, 0, 1) == ERROR) { DRV_LOG (DRV_DBG_TX, "Could not clear STALL.\n", pIrp->result, 0, 0, 0, 0, 0); } } pDrvCtrl->outErrors++; /* Should also Update MIB */ } /* Release the sync semaphore */ OSS_SEM_GIVE (usbNC1080IrpSem); }/**************************************************************************** usbNC1080MCastAdd - add a multicast address for the device** This function is not supported.* RETURNS: ERROR */LOCAL STATUS usbNC1080MCastAdd ( NC1080_END_DEV * pDrvCtrl, /* device pointer */ char* pAddress /* new address to add */ ) { return (ERROR); }/**************************************************************************** usbNC1080MCastDel - delete a multicast address for the device** This function is not supported.* RETURNS: ERROR.*/LOCAL STATUS usbNC1080MCastDel ( NC1080_END_DEV * pDrvCtrl, /* device pointer */ char* pAddress /* new address to add */ ) { return (ERROR); }/**************************************************************************** usbNC1080MCastGet - get the multicast address list for the device** This routine is not supported.* RETURNS: ERROR.*/LOCAL STATUS usbNC1080MCastGet ( NC1080_END_DEV * pDrvCtrl, /* device pointer */ MULTI_TABLE * pTable /* address table to be filled in */ ) { return (ERROR); }/**************************************************************************** usbNC1080Ioctl - the driver I/O control routine** Process an ioctl request.** RETURNS: A command specific response, usually OK or ERROR.*/LOCAL int usbNC1080Ioctl ( NC1080_END_DEV * pDrvCtrl, /* device receiving command */ int cmd, /* ioctl command code */ caddr_t data /* command argument */ ) { int error = 0; long value; switch (cmd) { case EIOCSADDR : /* Set Device Address */ return ERROR; case EIOCGADDR : /* Get Device Address */ if (data == NULL) return (EINVAL); bcopy ((char *)NETCHIP_HADDR (&pDrvCtrl->endObj), (char *)data, NETCHIP_HADDR_LEN (&pDrvCtrl->endObj)); break; case EIOCSFLAGS : /* Set Device Flags */ value = (long)data; if (value < 0) { value = -(--value); END_FLAGS_CLR (&pDrvCtrl->endObj, value); } else { END_FLAGS_SET (&pDrvCtrl->endObj, value); } break; case EIOCGFLAGS: /* Get Device Flags */ *(int *)data = END_FLAGS_GET(&pDrvCtrl->endObj); break; case EIOCPOLLSTART : /* Begin polled operation */ return EINVAL; /* Not supported */ case EIOCPOLLSTOP : /* End polled operation */ return EINVAL; /* Not supported */ case EIOCGMIB2 : /* return MIB information */ if (data == NULL) return (EINVAL); bcopy ((char *)&pDrvCtrl->endObj.mib2Tbl, (char *)data, sizeof(pDrvCtrl->endObj.mib2Tbl)); break; case EIOCGFBUF : /* return minimum First Buffer for chaining */ if (data == NULL) return (EINVAL); *(int *)data = NETCHIP_MIN_FBUF; break; case EIOCMULTIADD : /* Add a Multicast Address */ return EINVAL; /* Not supported */ case EIOCMULTIDEL : /* Delete a Multicast Address */ return EINVAL; /* Not supported */ break; case EIOCMULTIGET : /* Get the Multicast List */ return EINVAL; /* Not supported */ break; default: error = EINVAL; } return (error); }/**************************************************************************** usbNC1080PollRcv - routine to receive a packet in polled mode.** This routine is NOT supported** RETURNS: ERROR Always*/LOCAL STATUS usbNC1080PollRcv ( NC1080_END_DEV * pDrvCtrl, /* device to be polled */ M_BLK_ID pMblk /* ptr to buffer */ ) { return (ERROR); }/**************************************************************************** usbNC1080PollSend - routine to send a packet in polled mode.** This rout
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -