📄 usbpegasusend.c
字号:
{ OSS_MUTEX_DESTROY (pegasusMutex); pegasusMutex = NULL; } if (pegasusTxMutex != NULL) { OSS_MUTEX_DESTROY (pegasusTxMutex); pegasusTxMutex = NULL; } if (pegasusRxMutex != NULL) { OSS_MUTEX_DESTROY (pegasusRxMutex); pegasusRxMutex = NULL; } usbdShutdown(); return ossStatus (errCode); }/***************************************************************************** pegasusDestroyDevice - disposes of a PEGASUS_DEVICE structure** Unlinks the indicated PEGASUS_DEVICE structure and de-allocates* resources associated with the channel.** RETURNS: N/A*/void pegasusDestroyDevice ( PEGASUS_DEVICE * pDevCtrl ) { USB_PEGASUS_DEV * pDev; if (pDevCtrl != NULL) { pDev = pDevCtrl->pDev; /* Unlink the structure. */ usbListUnlink (&pDev->devLink); /* Release pipes and wait for IRPs to be cancelled if necessary. */ if (pDevCtrl->outPipeHandle != NULL) usbdPipeDestroy (pegasusHandle, pDevCtrl->outPipeHandle); if (pDevCtrl->inPipeHandle != NULL) usbdPipeDestroy (pegasusHandle, pDevCtrl->inPipeHandle); while (pDevCtrl->pEnetIrp->outIrpInUse || pDevCtrl->inIrpInUse) OSS_THREAD_SLEEP (1); if ( pDevCtrl->pInBfrArray !=NULL) { OSS_FREE(pDevCtrl->pInBfrArray); taskDelay(sysClkRateGet()*1); } if ( pDevCtrl->pEnetIrp != NULL) { OSS_FREE(pDevCtrl->pEnetIrp); taskDelay(sysClkRateGet()*1); } /* Release structure. */ 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**.IP <initString>*The device initialization string.** RETURNS: An END object pointer or NULL on error.*/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] == NULL) { /* 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 *)calloc (sizeof (PEGASUS_DEVICE), 1); 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, "usb", pDrvCtrl->unit, &pegasusEndFuncTable, PEGASUS_NAME) == ERROR || END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd, &pDrvCtrl->macAdrs[0], 6, PEGASUS_BUFSIZ, 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) 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>.** .IP <pDrvCtrl>* Pointer to the device structure.* .IP <initString>* Initialization string for the device. It will be of the following format :* "unit:vendorId:productId"* Device unit number, a small integer.* .IP <pVendorId>* Pointer to the place holder of the device vendor id.* .IP <pProductId>* Pointer to the place holder of the device product id.** RETURNS: OK or ERROR for invalid arguments.* NOMANUAL*/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.*/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 */ PEGASUS_LOG (PEGASUS_DBG_TX, "pegasusEndSend: Entered.\n", 0, 0, 0, 0, 0, 0); if ((pDrvCtrl == NULL) || (pMblk == NULL)) return ERROR; pBuf = (UINT8 *) malloc(1550); 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 = noOfBytes; /* Transmit the data */ if (pegasusSend (pDrvCtrl, pBuf, noOfBytes+2) == ERROR) 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); }/***************************************************************************** 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: N/A.* NOMANUAL*/STATUS pegasusEndRecv ( PEGASUS_DEVICE * pDrvCtrl, /* device structure */ UINT8 * pData, /* pointer to data buffer */ UINT32 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 */ 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 *)pNewCluster);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -