📄 templateend.c
字号:
/* Bump the statistics counters. */ END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1); /* * Cleanup. If the driver copied the data from the mblks to a different * buffer, then free the mblks now. Otherwise, free the mblk chain * after the device is finished with the TFD. */ if (freeNow) netMblkClChainFree (pMblk); return (OK); }/********************************************************************************* templateIoctl - the driver I/O control routine** Process an ioctl request.** RETURNS: A command specific response, usually OK or ERROR.*/LOCAL int templateIoctl ( END_DEVICE * pDrvCtrl, /* device receiving command */ int cmd, /* ioctl command code */ caddr_t data /* command argument */ ) { int error = 0; long value; switch ((unsigned)cmd) { case EIOCSADDR: /* set MAC address */ if (data == NULL) return (EINVAL); bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end), END_HADDR_LEN(&pDrvCtrl->end)); break; case EIOCGADDR: /* get MAC address */ if (data == NULL) return (EINVAL); bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data, END_HADDR_LEN(&pDrvCtrl->end)); break; case EIOCSFLAGS: /* set (or clear) flags */ value = (long)data; if (value < 0) { value = -value; value--; END_FLAGS_CLR (&pDrvCtrl->end, value); } else { END_FLAGS_SET (&pDrvCtrl->end, value); } templateConfig (pDrvCtrl); break; case EIOCGFLAGS: /* get flags */ *(int *)data = END_FLAGS_GET(&pDrvCtrl->end); break; case EIOCPOLLSTART: /* Begin polled operation */ templatePollStart (pDrvCtrl); break; case EIOCPOLLSTOP: /* End polled operation */ templatePollStop (pDrvCtrl); break; case EIOCGMIB2233: case EIOCGMIB2: /* return MIB information */ if (data == NULL) return (EINVAL); bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data, sizeof(pDrvCtrl->end.mib2Tbl)); break; case EIOCGFBUF: /* return minimum First Buffer for chaining */ if (data == NULL) return (EINVAL); *(int *)data = TEMPLATE_MIN_FBUF; break; case EIOCGHDRLEN: if (data == NULL) return (EINVAL); *(int *)data = EH_SIZE; break; default: /* unknown request */ error = EINVAL; } return (error); }/******************************************************************************** templateConfig - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** RETURNS: N/A.*/LOCAL void templateConfig ( END_DEVICE *pDrvCtrl /* device to be re-configured */ ) { /* Set promiscuous mode if it's asked for. */ if (END_FLAGS_GET(&pDrvCtrl->end) & IFF_PROMISC) { DRV_LOG (DRV_DEBUG_IOCTL, "Setting promiscuous mode on!\n", 1, 2, 3, 4, 5, 6); } else { DRV_LOG (DRV_DEBUG_IOCTL, "Setting promiscuous mode off!\n", 1, 2, 3, 4, 5, 6); } /* Set up address filter for multicasting. */ if (END_MULTI_LST_CNT(&pDrvCtrl->end) > 0) { templateAddrFilterSet (pDrvCtrl); } /* TODO - shutdown device completely */ /* TODO - reset all device counters/pointers, etc. */ /* TODO - initialise the hardware according to flags */ return; }/******************************************************************************** templateAddrFilterSet - 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.*/LOCAL void templateAddrFilterSet ( END_DEVICE *pDrvCtrl /* device to be updated */ ) { ETHER_MULTI* pCurr; pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end); while (pCurr != NULL) { /* TODO - set up the multicast list */ pCurr = END_MULTI_LST_NEXT(pCurr); } /* TODO - update the device filter list */ }/********************************************************************************* templatePollRcv - routine to receive a packet in polled mode.** Polled mode operation takes place without any kernel or other OS* services available. Use extreme care to insure that this code does not* call any kernel services. Polled mode is only for WDB system mode use.* Kernel services, semaphores, tasks, etc, are not available during WDB* system mode.** The WDB agent polls the device constantly looking for new data. Typically* the device has a ring of RFDs to receive incoming packets. This routine* examines the ring for any new data and copies it to the provided mblk.* The concern here is to keep the device supplied with empty buffers at all* time.** RETURNS: OK upon success. EAGAIN is returned when no packet is available.* A return of ERROR indicates a hardware fault or no support for polled mode* at all.*/LOCAL STATUS templatePollRcv ( END_DEVICE * pDrvCtrl, /* device to be polled */ M_BLK_ID pMblk /* ptr to buffer */ ) { u_short stat; char* pPacket; int len = 0; /* TODO - If no packet is available return immediately */ stat = templateStatusRead (pDrvCtrl); if (!(stat & TEMPLATE_RINT)) { return (EAGAIN); } /* Upper layer must provide a valid buffer. */ if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT))) { return (EAGAIN); } /* TODO - Invalidate any inbound RFD DMA buffers */ /* TODO - clear any status bits that may be set. */ /* TODO - Check packet and device for errors */ /* Get packet and length from device buffer/descriptor */ pPacket = NULL; /* DUMMY CODE */ len = 64; /* DUMMY CODE */ /* TODO - Invalidate any inbound data DMA buffers */ /* TODO - Process device packet into net buffer */ bcopy (pPacket, pMblk->m_data, len); pMblk->mBlkHdr.mFlags |= M_PKTHDR; /* set the packet header */ pMblk->mBlkHdr.mLen = len; /* set the data len */ pMblk->mBlkPktHdr.len = len; /* set the total len */ /* * TODO - Done with this packet, clean up device. If needed * setup a new RFD/buffer for incoming packets */ return (OK); }/********************************************************************************* templatePollSend - routine to send a packet in polled mode.** Polled mode operation takes place without any kernel or other OS* services available. Use extreme care to insure that this code does not* call any kernel services. Polled mode is only for WDB system mode use.* Kernel services, semaphores, tasks, etc, are not available during WDB* system mode.** A typical implementation is to set aside a fixed buffer for polled send* operation. Copy the mblk data to the buffer and pass the fixed buffer* to the device. Performance is not a consideration for polled operations.** An alternate implementation is a synchronous one. The routine accepts* user data but does not return until the data has actually been sent. If an* error occurs, the routine returns EAGAIN and the user will retry the request.** If the device returns OK, then the data has been sent and the user may free* the associated mblk. The driver never frees the mblk in polled mode.* The calling routine will free the mblk upon success.** RETURNS: OK upon success. EAGAIN if device is busy or no resources.* A return of ERROR indicates a hardware fault or no support for polled mode* at all.*/LOCAL STATUS templatePollSend ( END_DEVICE* pDrvCtrl, /* device to be polled */ M_BLK_ID pMblk /* packet to send */ ) { int len; u_short stat; static char txBuff [END_BUFSIZ]; /* TODO - test to see if tx is busy */ stat = templateStatusRead (pDrvCtrl); /* dummy code */ if ((stat & TEMPLATE_TINT) == 0) return ((STATUS) EAGAIN); /* TODO - Copy data from mblk */ len = netMblkToBufCopy (pMblk, &txBuff[0], NULL); len = max (ETHERSMALL, len); /* TODO - If necessary get a TFD */ /* TODO - Setup the TFD, with bus physical addresses, Flush it */ /* TODO - Handoff TFD/data to device */ return (OK); }/******************************************************************************* templateMCastAdd - 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 templateMCastAdd ( END_DEVICE *pDrvCtrl, /* device pointer */ char* pAddress /* new address to add */ ) { int error; if ((error = etherMultiAdd (&pDrvCtrl->end.multiList, pAddress)) == ENETRESET) templateConfig (pDrvCtrl); return (OK); }/******************************************************************************* templateMCastDel - 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 templateMCastDel ( END_DEVICE *pDrvCtrl, /* device pointer */ char* pAddress /* address to be deleted */ ) { int error; if ((error = etherMultiDel (&pDrvCtrl->end.multiList, (char *)pAddress)) == ENETRESET) templateConfig (pDrvCtrl); return (OK); }/******************************************************************************* templateMCastGet - 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 templateMCastGet ( END_DEVICE *pDrvCtrl, /* device pointer */ MULTI_TABLE* pTable /* address table to be filled in */ ) { return (etherMultiGet (&pDrvCtrl->end.multiList, pTable)); }/********************************************************************************* templateStop - 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 templateStop ( END_DEVICE *pDrvCtrl /* device to be stopped */ ) { STATUS result = OK; END_FLAGS_CLR (&pDrvCtrl->end, IFF_UP | IFF_RUNNING); /* TODO - stop/disable the device. */ SYS_INT_DISCONNECT (pDrvCtrl, (FUNCPTR)templateInt, (int)pDrvCtrl, &result); if (result == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "Could not disconnect interrupt!\n", 1, 2, 3, 4, 5, 6); } return (result); }/******************************************************************************** templateUnload - 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 templateUnload ( END_DEVICE* pDrvCtrl /* device to be unloaded */ ) { END_OBJECT_UNLOAD (&pDrvCtrl->end); /* TODO - Free any special allocated memory */ /* New: free the END_OBJ structure allocated during templateLoad() */ cfree ((char *)pDrvCtrl); return (OK); }/********************************************************************************* templatePollStart - start polled mode operations** RETURNS: OK or ERROR.*/LOCAL STATUS templatePollStart ( END_DEVICE * pDrvCtrl /* device to be polled */ ) { int oldLevel; oldLevel = intLock (); /* disable ints during update */ /* TODO - turn off interrupts */ pDrvCtrl->flags |= TEMPLATE_POLLING; intUnlock (oldLevel); /* now templateInt won't get confused */ DRV_LOG (DRV_DEBUG_POLL, "STARTED\n", 1, 2, 3, 4, 5, 6); templateConfig (pDrvCtrl); /* reconfigure device */ return (OK); }/********************************************************************************* templatePollStop - stop polled mode operations** This function terminates polled mode operation. The device returns to* interrupt mode.** The device interrupts are enabled, the current mode flag is switched* to indicate interrupt mode and the device is then reconfigured for* interrupt operation.** RETURNS: OK or ERROR.*/LOCAL STATUS templatePollStop ( END_DEVICE * pDrvCtrl /* device to be polled */ ) { int oldLevel; oldLevel = intLock (); /* disable ints during register updates */ /* TODO - re-enable interrupts */ pDrvCtrl->flags &= ~TEMPLATE_POLLING; intUnlock (oldLevel); templateConfig (pDrvCtrl); DRV_LOG (DRV_DEBUG_POLL, "STOPPED\n", 1, 2, 3, 4, 5, 6); return (OK); }/********************************************************************************* templateReset - reset device** RETURNS: N/A.*/LOCAL void templateReset ( END_DEVICE *pDrvCtrl ) { /* TODO - reset the controller */ }/********************************************************************************* templateStatusRead - get current device state/status** RETURNS: status bits.*/LOCAL UINT templateStatusRead ( END_DEVICE *pDrvCtrl ) { /* TODO - read and return status bits/register */ return (0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -