📄 elt3c509end.c
字号:
pDrvCtrl->cacheFuncs = cacheNullFuncs; /* Initialize the memory pool. */ if (netPoolInit (pDrvCtrl->endObj.pNetPool, &pDrvCtrl->endClConfig, &pDrvCtrl->endClDesc, elt3c509ClDescTblNumEnt, NULL) == ERROR) { ENDLOGMSG (("Could not init buffering\n",1,2,3,4,5,6)); return (ERROR); } /* Get Cluster POOL ID here */ pDrvCtrl->pClPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool, ELT3C509_BUFSIZ, FALSE); /* allocate one cluster for the transmit frame */ pDrvCtrl->pTxCluster = (char *)netClusterGet (pDrvCtrl->endObj.pNetPool, pDrvCtrl->pClPoolId); ENDLOGMSG (("Memory setup complete\n",1,2,3,4,5,6)); return OK; }/********************************************************************************* elt3c509Start - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR**/LOCAL STATUS elt3c509Start ( void * pEnd /* device to be started */ ) { STATUS result; ELT3C509_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); SYS_INT_CONNECT (pDrvCtrl, elt3c509Int, (int)pDrvCtrl, &result); if (result == ERROR) return ERROR; ENDLOGMSG (("Interrupt connected.\n", 1, 2, 3, 4, 5, 6)); SYS_INT_ENABLE (pDrvCtrl); ENDLOGMSG (("interrupt enabled.\n", 1, 2, 3, 4, 5, 6)); return (OK); }/********************************************************************************* elt3c509Stop - stop the device** This function calls BSP functions to disconnect interrupts and stop* the device from operating in interrupt mode.** RETURNS: OK or ERROR.*/LOCAL STATUS elt3c509Stop ( void * pEnd /* device to be stopped */ ) { STATUS result = OK; ELT3C509_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); elt3c509Reset(pDrvCtrl); SYS_INT_DISCONNECT (pDrvCtrl, elt3c509Int, (int)pDrvCtrl, &result); if (result == ERROR) { ENDLOGMSG (("Could not diconnect interrupt!\n", 1, 2, 3, 4, 5, 6)); } SYS_INT_DISABLE (pDrvCtrl); END_FLAGS_CLR (&pDrvCtrl->endObj, IFF_UP | IFF_RUNNING); return (result); }/******************************************************************************** elt3c509Unload - unload a driver from the system** This function first brings down the device, and then frees any* stuff that was allocated by the driver in the load function.** RETURNS: OK or ERROR.*/LOCAL STATUS elt3c509Unload ( void * pEnd /* device to be unloaded */ ) { ELT3C509_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); END_OBJECT_UNLOAD (&pDrvCtrl->endObj); if (pDrvCtrl->endClDesc.memArea != NULL) free (pDrvCtrl->endClDesc.memArea); if (pDrvCtrl->endClConfig.memArea != NULL) free ( pDrvCtrl->endClConfig.memArea); if (pDrvCtrl->endObj.pNetPool != NULL) free (pDrvCtrl->endObj.pNetPool); return (OK); }/********************************************************************************* elt3c509Ioctl - the driver I/O control routine** Process an ioctl request.** RETURNS: A command specific response, OK or ERROR or EINVAL.*/LOCAL int elt3c509Ioctl ( void * pEnd, /* device ptr*/ int cmd, /* ioctl command code */ caddr_t data /* command argument */ ) { int error = 0; long value; ELT3C509_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); switch ((UINT)cmd) { case EIOCSADDR: if (data == NULL) return (EINVAL); bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->endObj), END_HADDR_LEN(&pDrvCtrl->endObj)); break; case EIOCGADDR: if (data == NULL) return (EINVAL); bcopy ((char *)END_HADDR(&pDrvCtrl->endObj), (char *)data, END_HADDR_LEN(&pDrvCtrl->endObj)); break; case EIOCSFLAGS: value = (long)data; if (value < 0) { value = -value; value--; END_FLAGS_CLR (&pDrvCtrl->endObj, value); } else { END_FLAGS_SET (&pDrvCtrl->endObj, value); } elt3c509Config (pDrvCtrl); break; case EIOCGFLAGS: *(int *)data = END_FLAGS_GET(&pDrvCtrl->endObj); break; case EIOCPOLLSTART: error = elt3c509PollStart(pDrvCtrl); break; case EIOCPOLLSTOP: error = elt3c509PollStop(pDrvCtrl); break; case EIOCGMIB2: if (data == NULL) return (EINVAL); bcopy((char *)&pDrvCtrl->endObj.mib2Tbl, (char *)data, sizeof(pDrvCtrl->endObj.mib2Tbl)); break; case EIOCGFBUF: return (EINVAL); /* no scatter gather supported for the chip */ break; case EIOCGMWIDTH: if (data == NULL) return (EINVAL); break; case EIOCGHDRLEN: if (data == NULL) return (EINVAL); *(int *)data = EH_SIZE; break; default: error = EINVAL; } return (error); }/********************************************************************************* elt3c509Send - the driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it. This is done by a higher layer.** RETURNS: OK or END_ERR_BLOCK or ERROR.*/LOCAL STATUS elt3c509Send ( void * pEnd, /* device ptr */ M_BLK_ID pMblk /* data to send */ ) { int len; int * pLenMask; char * pBuf; int intLevel; ELT3C509_DEVICE * pDrvCtrl; UINT16 tempData; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); /* change this drv flag set */ if (pDrvCtrl->flags & ELT3C_POLLING) { netMblkClChainFree (pMblk); /* free the given mBlk chain */ errno = EINVAL; return (ERROR); } /* check if transmitter ready */ SYS_IN_WORD (pDrvCtrl, pDrvCtrl->port + TX_FREE_BYTES, tempData); if (tempData >= TX_IDLE_COUNT) { pBuf = pDrvCtrl->pTxCluster; /* pointer to the transmit cluster */ pLenMask = (UINT32 *)pBuf; /* allow space for the preamble the trasmit buffer is 1520 */ pBuf += sizeof(UINT32); len = netMblkToBufCopy (pMblk, pBuf, NULL); /* free the mblk chain */ netMblkClChainFree (pMblk); len = max(len, ETHERSMALL); /* set the packet size */ *pLenMask = len | TX_F_INTERRUPT; /* set the preamble */ len = (len + TX_F_PREAMBLE_SIZE + 3) & TX_F_DWORD_MASK; /* place a transmit request */ SYS_OUT_WORD_STRING (pDrvCtrl, pDrvCtrl->port + DATA_REGISTER, (short *)pLenMask, len / 2); } else { intLevel = intLock(); pDrvCtrl->txBlocked = TRUE; intUnlock (intLevel); ENDLOGMSG(("Error in Send, not enough TxFreeBytes\n",1,2,3,4,5,6)); return (END_ERR_BLOCK); } /* Bump the statistic counter. */ END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1); ENDLOGMSG (("Send complete\n",1,2,3,4,5,6)); return (OK); }/******************************************************************************* elt3c509MCastAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for. It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS elt3c509MCastAdd ( void * pEnd, /* device pointer */ char * pAddress /* new address to add */ ) { int error; ELT3C509_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); if ((error = etherMultiAdd (&pDrvCtrl->endObj.multiList, pAddress)) == ENETRESET) elt3c509Config (pDrvCtrl); return (OK); }/******************************************************************************* elt3c509MCastDel - delete a multicast address for the device** This routine removes a multicast address from whatever the driver* is listening for. It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS elt3c509MCastDel ( void * pEnd, /* device pointer */ char * pAddress /* address to be deleted */ ) { int error; ELT3C509_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); if ((error = etherMultiDel (&pDrvCtrl->endObj.multiList, (char *)pAddress)) == ENETRESET) elt3c509Config (pDrvCtrl); return (OK); }/******************************************************************************* elt3c509MCastGet - get the multicast address list for the device** This routine gets the multicast list of whatever the driver* is already listening for.** RETURNS: OK or ERROR.*/LOCAL STATUS elt3c509MCastGet ( void * pEnd, /* device pointer */ MULTI_TABLE * pTable /* address table to be filled in */ ) { ELT3C509_DEVICE * pDrvCtrl; VOID_TO_DRVCTRL (pEnd, pDrvCtrl); return (etherMultiGet (&pDrvCtrl->endObj.multiList, pTable)); }/********************************************************************************* elt3c509Int - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.** RETURNS: N/A.*/LOCAL void elt3c509Int ( ELT3C509_DEVICE * pDrvCtrl /* interrupting device */ ) { UINT16 status; UINT16 statusDiag; UINT8 statusTx; int port; BOOL needTxStart = FALSE; port = pDrvCtrl->port; ENDLOGMSG (("Got an interrupt!\n", 1, 2, 3, 4, 5, 6));#ifdef ELT_TIMING { int time; SYS_IN_BYTE (pDrvCtrl, pDrvCtrl->port + TIMER, time); if (time> pDrvCtrl->elt3c509Stat.maxIntLatency) pDrvCtrl->elt3c509Stat.maxIntLatency = time; if (pDrvCtrl->interruptTime == -1) pDrvCtrl->interruptTime = time; else if (pDrvCtrl->interruptTime >= 0) pDrvCtrl->interruptTime = -1; }#endif /* ELT_TIMING */ SYS_IN_BYTE (pDrvCtrl, pDrvCtrl->port + ELT3C509_STATUS, status); status &= 0x00ff; if ((status & INTERRUPT_LATCH) == 0) { ++pDrvCtrl->elt3c509Stat.strayint; return; } else ++pDrvCtrl->elt3c509Stat.interrupts;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -