📄 usbpegasusend.c
字号:
while (pegasusOutIrpInUse(pDevCtrl) || pDevCtrl->inIrpInUse) OSS_THREAD_SLEEP (1); for (index=0; index < pDevCtrl->noOfInBfrs; index++) OSS_FREE (pDevCtrl->pInBfrArray[index]); if (pDevCtrl->pInBfrArray !=NULL) OSS_FREE(pDevCtrl->pInBfrArray); if ( pDevCtrl->pEnetIrp != NULL) OSS_FREE(pDevCtrl->pEnetIrp); /* Release structure. */ /* This constitutes a memory leak, however leaving it in * causes failure. if (pDev !=NULL) OSS_FREE (pDev); */ } }/***************************************************************************** usbPegasusEndLoad - initialize the driver and device** This routine initializes the driver and the device to the operational state.* All of the device specific parameters are passed in the initString.* * This function first extracts the vendorId and productId of the device * from the initialization string using the pegasusEndParse() function. It then * passes these parametsrs and its control strcuture to the pegasusDevInit()* function. pegasusDevInit() does most of the device specific initialization* and brings the device to the operational state. Please refer to pegasusLib.c* for more details about usbenetDevInit(). This driver will be attached to MUX* and then the memory initialization of the device is carriedout using* pegasusEndMemInit(). ** This function doesn't do any thing device specific. Instead, it delegates* such initialization to pegasusDevInit(). This routine handles the other part* of the driver initialization as required by MUX.** muxDevLoad calls this function twice. First time this function is called, * initialization string will be NULL . We are required to fill in the device * name ("usb") in the string and return. The next time this function is called* the intilization string will be proper.** <initString> will be in the following format :* "unit:vendorId:productId:noOfInBfrs:noOfIrps"** PARAMETERS** \is* \i <initString>* The device initialization string.* \ie** RETURNS: An END object pointer or NULL on error.** ERRNO: none*/END_OBJ * usbPegasusEndLoad ( char * initString /* initialization string */ ) { PEGASUS_DEVICE * pDrvCtrl; /* driver structure */ UINT16 vendorId; /* vendor information */ UINT16 productId; /* product information */ PEGASUS_LOG (PEGASUS_DBG_LOAD, "Loading usb end...\n", 1, 2, 3, 4, 5, 6); if (initString == NULL) return (NULL); if (initString[0] == EOS) { /* Fill in the device name and return peacefully */ bcopy ((char *)PEGASUS_NAME, (void *)initString, PEGASUS_NAME_LEN); return (0); } /* allocate the device structure */ pDrvCtrl = (PEGASUS_DEVICE *) OSS_CALLOC (sizeof (PEGASUS_DEVICE)); if (pDrvCtrl == NULL) { PEGASUS_LOG (PEGASUS_DBG_LOAD, "No Memory!!...\n", 1, 2, 3, 4, 5, 6); goto errorExit; } /* parse the init string, filling in the device structure */ if (pegasusEndParse (pDrvCtrl, initString, &vendorId, &productId) == ERROR) { PEGASUS_LOG (PEGASUS_DBG_LOAD, "Parse Failed.\n", 1, 2, 3, 4, 5, 6); goto errorExit; } /* Ask the pegasusLib to do the necessary initilization. */ if (pegasusDevInit(pDrvCtrl,vendorId,productId) == ERROR) { PEGASUS_LOG (PEGASUS_DBG_LOAD, "EnetDevInitFailed.\n", 1, 2, 3, 4, 5, 6); goto errorExit; } /* initialize the END and MIB2 parts of the structure */ if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)pDrvCtrl, PEGASUS_NAME, pDrvCtrl->unit, &pegasusEndFuncTable, PEGASUS_DESCRIPTION) == ERROR || END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd, &pDrvCtrl->macAdrs[0], 6, ETHERMTU, PEGASUS_SPEED) == ERROR) { PEGASUS_LOG (PEGASUS_DBG_LOAD, "END MACROS FAILED...\n", 1, 2, 3, 4, 5, 6); goto errorExit; } /* Perform memory allocation/distribution */ if (pegasusEndMemInit (pDrvCtrl) == ERROR) { PEGASUS_LOG (PEGASUS_DBG_LOAD, "endMemInit() Failed...\n", 1, 2, 3, 4, 5, 6); goto errorExit; } /* set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->endObj, IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST); PEGASUS_LOG (PEGASUS_DBG_LOAD, "Done loading usb end..\n", 1, 2, 3, 4, 5, 6); return (&pDrvCtrl->endObj);errorExit: if (pDrvCtrl != NULL) { /* Unlink the structure. */ usbListUnlink (&pDrvCtrl->pDev->devLink); OSS_FREE ((char *)pDrvCtrl); } return NULL; }/***************************************************************************** pegasusEndParse - parse the init string** Parse the input string. Fill in values in the driver control structure.** The muxLib.o module automatically prepends the unit number to the user's* initialization string from the BSP (configNet.h).* * This function parses the input string and fills in the places pointed* to by <pVendorId> and <pProductId>. Unit Number of the string will be* be stored in the device structure pointed to by <pDrvCtrl>.* \is* \i <pDrvCtrl>* Pointer to the device structure.* \i <initString>* Initialization string for the device. It will be of the following format :* "unit:vendorId:productId"* Device unit number, a small integer.* \i <pVendorId>* Pointer to the place holder of the device vendor id.* \i <pProductId>* Pointer to the place holder of the device product id.* \ie** RETURNS: OK or ERROR for invalid arguments.** ERRNO: none** \NOMANUAL*/LOCAL STATUS pegasusEndParse ( PEGASUS_DEVICE * pDrvCtrl, /* device pointer */ char * initString, /* information string */ UINT16 * pVendorId, UINT16 * pProductId ) { char * tok; char * pHolder = NULL; /* Parse the initString */ /* Unit number. (from muxLib.o) */ tok = strtok_r (initString, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->unit = atoi (tok); PEGASUS_LOG (PEGASUS_DBG_LOAD, "Parse: Unit : %d..\n", pDrvCtrl->unit, 2, 3, 4, 5, 6); /* Vendor Id. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; *pVendorId = atoi (tok); PEGASUS_LOG (PEGASUS_DBG_LOAD, "Parse: VendorId : 0x%x..\n", *pVendorId, 2, 3, 4, 5, 6); /* Product Id. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; *pProductId = atoi (tok); PEGASUS_LOG (PEGASUS_DBG_LOAD, "Parse: ProductId : 0x%x..\n", *pProductId, 2, 3, 4, 5, 6); /* we have paresed the inbfrs and outirps here * these vars are to be passed to pegasusEndParse from usbPegasusEndLoad. */ /* no of in buffers */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->noOfInBfrs = atoi (tok); PEGASUS_LOG (PEGASUS_DBG_LOAD, "Parse: NoInBfrs : %d..\n", pDrvCtrl->noOfInBfrs, 2, 3, 4, 5, 6); /* no of out IRPs */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->noOfIrps = atoi (tok); PEGASUS_LOG (PEGASUS_DBG_LOAD, "Parse: NoOutIrps : %d..\n", pDrvCtrl->noOfIrps, 2, 3, 4, 5, 6); /*here ends the extra two parsing blocks */ PEGASUS_LOG (PEGASUS_DBG_LOAD, "Parse: Processed all arugments\n", 1, 2, 3, 4, 5, 6); return OK; }/***************************************************************************** pegasusEndSend - 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 and hand over the * buffer to pegasusSend().The buffer must already have the addressing * information properly installed in it. This is done by a higher layer. * The device requires that the first two bytes of the data sent to it (for * transmission over ethernet) contain the length of the data. So we add this* here. ** During the course of our testing the driver, we found that if we send the * exact length of the data as handed over by MUX, the device is corrupting* some bytes of the packet. This is resulting in packet not being received* by the addresses destination, packet checksum errors etc. The remedy is to* padup few bytes to the data packet. This, we found, solved the problem.** RETURNS: OK or ERROR.** ERRNO: none** \NOMANUAL*/LOCAL STATUS pegasusEndSend ( PEGASUS_DEVICE * pDrvCtrl, /* device ptr */ M_BLK_ID pMblk /* data to send */ ) { UINT8 * pBuf; /* buffer to hold the data */ UINT32 noOfBytes; /* noOfBytes to be transmitted */ STATUS status; PEGASUS_LOG (PEGASUS_DBG_TX, "pegasusEndSend: Entered.\n", 0, 0, 0, 0, 0, 0); if ((pDrvCtrl == NULL) || (pMblk == NULL)) return ERROR; /* Point to the one of the pre-allocated output buffers */ pBuf = pDrvCtrl->pOutBfrArray[pDrvCtrl->txIrpIndex]; if (pBuf == NULL) { PEGASUS_LOG (PEGASUS_DBG_TX," pegasusEndSend : " "Could not allocate memory \n", 0, 0, 0, 0, 0, 0); return ERROR; } /* copy the MBlk chain to a buffer */ noOfBytes = netMblkToBufCopy(pMblk,(char *)pBuf+2,NULL); PEGASUS_LOG (PEGASUS_DBG_LOAD, "pegasusEndSend: %d bytes to be sent.\n", noOfBytes, 0, 0, 0, 0, 0); if (noOfBytes == 0) return ERROR; /* * Padding : how much to pad is decided by trial and error. * Note that we need not add any extra bytes in the buffer. * since we are not using those bytes, they can be any junk * whick is already in the buffer. * We are just interested in the count. */ if (noOfBytes < 60) noOfBytes = 60; /* (Required by the device) Fill in the Length in the first Two Bytes */ *(UINT16 *)pBuf = TO_LITTLEW(noOfBytes); /* Transmit the data */ if ((status = pegasusSend (pDrvCtrl, pBuf, noOfBytes+2)) != OK) { netMblkClChainFree(pMblk); return ERROR; } PEGASUS_LOG (PEGASUS_DBG_TX, "pegasusEndSend: Pkt submitted for tx.\n", 0, 0, 0, 0, 0, 0); /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1); /* * Cleanup. The driver frees the packet now. */ netMblkClChainFree (pMblk); return (OK); }/***************************************************************************** usbPegasusFreeRtn - pegasus Cluster Free Routine** The pegasus driver does not use the netBufLib to free the cluster blocks.* We do nothing when netBufLib is done with them because we allocate the * our buffers as IRP buffers. The USB stack manages these buffers instead* of netBufLib.** RETURNS: N/A.** ERRNO: none** \NOMANUAL*/void usbPegasusFreeRtn (void) { ; /* We do nothing here. */ }/***************************************************************************** pegasusEndRecv - process the next incoming packet** pegasusRecv is called by the pegasusIRPCallBack() 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: OK or ERROR.** ERRNO: none** \NOMANUAL*/LOCAL STATUS pegasusEndRecv ( PEGASUS_DEVICE * pDrvCtrl, /* device structure */ UINT8 * pData, /* pointer to data buffer */ UINT32 len /* length of data */ ) { char * pNewCluster; /* Clusuter 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 */ PEGASUS_LOG (PEGASUS_DBG_RX, "pegasusEndRecv called...Entered len=%d \n", len, 0, 0, 0, 0, 0); /* Add one to our unicast data. */ END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1); pNewCluster = (char *)pData; /* 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 *)pData); PEGASUS_LOG (PEGASUS_DBG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); PEGASUS_LOG (PEGASUS_DBG_RX, "netClBlkGet...Error\n", 0, 0, 0, 0, 0, 0); goto cleanRXD; } /* * Let's get an M_BLK_ID and marry it to the one in the ring. */ if ((pMblk = mBlkGet (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -