📄 smend.c
字号:
} pSmEndDev->flags |= S_CPU_ATTACHED; return (result); }#if FALSE /* XXXmas future enhancement *//******************************************************************************** smEndAddrFilterSet - set the address filter for multicast addresses** This routine goes through all of the multicast addresses on the list* of addresses (added with the endAddrAdd() routine) and sets the* device's filter correctly.** RETURNS: N/A.*/void smEndAddrFilterSet ( VOID * pObj /* device to be updated */ ) { SM_END_DEV * pSmEndDev = (SM_END_DEV *)pObj; /* device to be updated */ ETHER_MULTI * pCurr; pCurr = END_MULTI_LST_FIRST (&pSmEndDev->end); while (pCurr != NULL) { /* TODO - set up the multicast list */ pCurr = END_MULTI_LST_NEXT(pCurr); } /* TODO - update the device filter list */ }#endif/******************************************************************************** smEndStart - start the device** This function calls the system functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR if this cpu is configured for polled mode only.*/LOCAL STATUS smEndStart ( VOID * pObj /* device ID */ ) { SM_END_DEV * pSmEndDev = (SM_END_DEV *)pObj; /* device to be started */ STATUS result = OK; /* free all queued tuples */ smEndPollQFree (pSmEndDev); /* * If not already connected, connect sm interrupt. * ++ NOTE: This is necessary until a functional intDisconnect() or * smUtilIntDisconnect() routine becomes available. */ if (!connected[pSmEndDev->intType]) { if ((result = smUtilIntConnect (LOW_PRIORITY, (FUNCPTR)smEndIsr, (int)pSmEndDev, pSmEndDev->intType, pSmEndDev->intArg1, pSmEndDev->intArg2, pSmEndDev->intArg3)) == OK) { connected[pSmEndDev->intType] = TRUE; if ((pSmEndDev->intType == SM_INT_NONE) && (pollTaskId == NONE)) { pollTaskId = taskNameToId (SM_POLL_TASK_NAME); } } } if (result == OK) { SM_LOG (SM_DBG_START, "smEndStart: interrupt connected\n", 0, 0, 0, 0, 0, 0); /* enable interrupt */ smUtilIntEnable (pSmEndDev); SM_LOG (SM_DBG_START, "smEndStart: interrupt enabled\n", 0, 0, 0, 0, 0, 0); /* start the device: enable interrupts */ SM_END_START; } else { SM_LOG (SM_DBG_START, "smEndStart: ERROR: can't connect interrupt!\n", 0, 0, 0, 0, 0, 0); } return (result); }/******************************************************************************** smEndStop - stop the device** This function calls the system functions to disconnect interrupts and stop* the device from operating in interrupt mode.** RETURNS: OK or ERROR.*/LOCAL STATUS smEndStop ( VOID * pObj /* device to be stopped */ ) { SM_END_DEV * pSmEndDev = (SM_END_DEV *)pObj; /* device to be stopped */ STATUS result; /* stop/disable the device. */ SM_END_STOP; smUtilIntDisable (pSmEndDev); /* XXXmas someday will be a real call */ /* * XXXmas someday this will have to be a call to a real functional * smUtilIntDisconnect() routine. */ if ((result = smUtilIntDisconnect (LOW_PRIORITY, (FUNCPTR)smEndIsr, (int)pSmEndDev, pSmEndDev->intType, pSmEndDev->intArg1, pSmEndDev->intArg2, pSmEndDev->intArg3)) == ERROR) { SM_LOG (SM_DBG_STOP, "smEndStop: Can't disconnect interrupt!\n", 0, 0, 0, 0, 0, 0); } else { if (pSmEndDev->intType == SM_INT_BUS) connected[SM_INT_BUS] = FALSE; SM_LOG (SM_DBG_STOP, "smEndStop: interrupt disconnected\n", 0, 0, 0, 0, 0, 0); } return (result); }/******************************************************************************** smEndPollStart - start polled mode operation** This function starts full polled mode operation for both the shared memory* and END interfaces.** RETURNS: OK or ERROR.*/LOCAL STATUS smEndPollStart ( void * pObj ) { SM_END_DEV * pSmEndDev = (SM_END_DEV *)pObj; /* device receiving command */ int oldLevel; STATUS result = ERROR; /* if sm is already in polled mode, just set END polled flag */ if (SM_END_IS_ACTIVE) { if (!SM_END_POLL_SM_RDY) { oldLevel = intLock (); /* disable ints during update */ smUtilIntDisable (pSmEndDev); pSmEndDev->flags |= S_POLLED_SM; intUnlock (oldLevel); /* now smEndInt won't get confused */ smEndConfig (pSmEndDev, SC_INT2POLL); /* reconfigure device */ } pSmEndDev->flags |= S_POLLED_END; result = OK; } else errno = ENODEV; return (result); }/******************************************************************************** smEndPollStop - stop polled mode operation** This function stops polled mode operation for the MUX interface and, if not* locked in polled mode, changes shared memory mode to interrupt.** RETURNS: OK or ERROR.*/LOCAL STATUS smEndPollStop ( void * pObj ) { SM_END_DEV * pSmEndDev = (SM_END_DEV *)pObj; /* device receiving command */ int oldLevel; STATUS result = ERROR; /* if sm is not in polled mode, just clear END polled flag */ if (SM_END_IS_ACTIVE) { if (SM_END_POLL_SM_RDY && !SM_IS_POLLED_LOCKED) { oldLevel = intLock (); /* disable ints during update */ smUtilIntEnable (pSmEndDev); pSmEndDev->flags &= ~S_POLLED_SM; intUnlock (oldLevel); /* now smEndInt won't get confused */ smEndConfig (pSmEndDev, SC_POLL2INT); /* reconfigure device */ } pSmEndDev->flags &= ~S_POLLED_END; result = OK; } else errno = ENODEV; return (result); }/******************************************************************************** smEndIoctl - sm device I/O control routine** This routine is called to perform control operations on the sm device network* interface. The implemented commands are:** Command Data Function* ------------ ---------------- -----------------------------------------* EIOCSADDR char * set sm device address* EIOCGADDR char * get sm device address* EIOCSFLAGS int set sm device flags* EIOCGFLAGS int get sm device flags* EIOCPOLLSTART N/A start polled operation* EIOCPOLLSTOP N/A stop polled operation* EIOCGMIB2 M2_INTERFACETBL * return MIB2 information* EIOCGFBUF int return minimum First Buffer for chaining** RETURNS: A command specific response, usually OK or an error code:* EINVAL (invalid argument) or ENOSUP (unsupported Ioctl command).*/LOCAL int smEndIoctl ( VOID * pObj, /* device receiving command */ int cmd, /* ioctl command code */ caddr_t data /* command argument */ ) { SM_END_DEV * pSmEndDev = (SM_END_DEV *)pObj; /* device receiving command */ int error = OK; long value; switch (cmd) { case EIOCSADDR: /* set sm interface address */ if (data == NULL) return (EINVAL); bcopy ((char *)data, (char *)SM_END_ADDR_GET (&pSmEndDev->end), SM_END_ADDR_LEN_GET (&pSmEndDev->end)); break; case EIOCGADDR: /* get sm interface address */ if (data == NULL) return (EINVAL); bcopy ((char *)SM_END_ADDR_GET (&pSmEndDev->end), (char *)data, SM_END_ADDR_LEN_GET (&pSmEndDev->end)); break; case EIOCSFLAGS: /* set sm END device flags */ value = (long)data; if (value < 0) { value = -(--value); END_FLAGS_CLR (&pSmEndDev->end, value); } else { value &= ~IFF_MULTICAST; /* XXXmas temporary */ END_FLAGS_SET (&pSmEndDev->end, value); } smEndConfig (pSmEndDev, SC_NONE); break; case EIOCGFLAGS: /* get sm END device flags */ *(int *)data = END_FLAGS_GET(&pSmEndDev->end); break; case EIOCGMWIDTH: /* get sm END memory width (#bytes) */ *(int *)data = 0; /* no restrictions on size */ break; case EIOCMULTIGET: /* get multicast list (XXXmas future) */ return (ENOTSUP); break; case EIOCPOLLSTART: /* Begin polled operation */ smEndPollStart (pSmEndDev); break; case EIOCPOLLSTOP: /* End polled operation */ smEndPollStop (pSmEndDev); break; case EIOCGMIB2: /* return MIB information */ if (data == NULL) return (EINVAL); bcopy((char *)&pSmEndDev->end.mib2Tbl, (char *)data, sizeof(pSmEndDev->end.mib2Tbl)); break; case EIOCGFBUF: /* return minimum First Buffer for chaining */ if (data == NULL) return (EINVAL); *(int *)data = SM_END_MIN_FBUF; break; default: SM_LOG (SM_DBG_IOCTL, "smEndIoctl: unsupported command: 0x%x\n", cmd, 0, 0, 0, 0, 0); error = ENOTSUP; } return (error); }/******************************************************************************** smEndHwAddrSet - set hardware address** This routine sets the hardware address associated with the 'sm' device* specified by <pSmEndDev>. It also stores the non-sequential IP address in* the associated CPU descriptor for fast address resolution.** The 'sm' device H/W address consists of six bytes. Depending upon whether* sequential addressing is selected or not, the last three bytes assume* different values:** Sequential addressing: { 0x00, 0x02, 0xE2, ip[2], ip[3], ip[4] }* where ip is the lower three bytes of the IP interface address.** Not sequential addressing: { 0x00, 0x02, 0xE2, 0x00, unit, cpu }** RETURNS: N/A*/LOCAL void smEndHwAddrSet ( SM_END_DEV * pSmEndDev /* device for which to set address */ ) { u_char * pEaddr; /* ethernet address */ u_long addr; /* address */ SM_PKT_MEM_HDR * pSmPktHdr; /* packet header */ FAST SM_CPU_DESC * pCpuDesc; /* sm CPU descriptor */ FAST SM_ANCHOR * pAnchor = pSmEndDev->pAnchor; FAST SM_HDR * pSmHdr; FAST SM_DESC * pSmDesc = &pSmEndDev->smPktDesc.smDesc;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -