⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dp.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 2 页
字号:
/***  File:	eth.c	Version 1.00,	Jan. 14, 1997****  Author:	Giovanni Falzoni <gfalzoni@inwind.it>****  This file contains the ethernet device driver main task.**  It has to be integrated with the board specific drivers.**  It is a rewriting of Minix 2.0.0 ethernet driver (dp8390.c)**  to remove bord specific code. It should operate (I hope)**  with any board driver.****  The valid messages and their parameters are:****    m_type       DL_PORT   DL_PROC  DL_COUNT DL_MODE DL_ADDR**  +------------+---------+---------+--------+-------+---------+**  | HARD_INT   |         |         |        |       |         | **  +------------+---------+---------+--------+-------+---------+**  | SYN_ALARM  |         |         |        |       |         | **  +------------+---------+---------+--------+-------+---------+**  | HARD_STOP  |         |         |        |       |         | **  +------------+---------+---------+--------+-------+---------+**  | FKEY_PRESSED         |         |        |       |         | (99)**  +------------+---------+---------+--------+-------+---------+**  | DL_WRITE   | port nr | proc nr | count  | mode  | address | (3)**  +------------+---------+---------+--------+-------+---------+**  | DL_WRITEV  | port nr | proc nr | count  | mode  | address | (4)**  +------------+---------+---------+--------+-------+---------+**  | DL_READ    | port nr | proc nr | count  |       | address | (5)**  +------------+---------+---------+--------+-------+---------+**  | DL_READV   | port nr | proc nr | count  |       | address | (6)**  +------------+---------+---------+--------+-------+---------+**  | DL_INIT    | port nr | proc nr |        | mode  | address | (7)**  +------------+---------+---------+--------+-------+---------+**  | DL_STOP    | port_nr |         |        |       |         | (8)**  +------------+---------+---------+--------+-------+---------+**  | DL_GETSTAT | port nr | proc nr |        |       | address | (9)**  +------------+---------+---------+--------+-------+---------+****  The messages sent are:****    m-type       DL_PORT   DL_PROC  DL_COUNT  DL_STAT   DL_CLCK**  +------------+---------+---------+--------+---------+---------+**  |DL_TASK_REPL| port nr | proc nr |rd-count| err|stat| clock   | (21)**  +------------+---------+---------+--------+---------+---------+****    m_type       m3_i1     m3_i2      m3_ca1**  +------------+---------+---------+---------------+**  |DL_INIT_REPL| port nr |last port| ethernet addr | (20)**  +------------+---------+---------+---------------+****  $Id: dp.c,v 1.11 2005/10/21 17:09:08 philip Exp $*/#include "drivers.h"#include <minix/keymap.h>#include <net/hton.h>#include <net/gen/ether.h>#include <net/gen/eth_io.h>#include "dp.h"/***  Local data*/extern int errno;static dpeth_t de_table[DE_PORT_NR];static char *progname;typedef struct dp_conf {	/* Configuration description structure */  port_t dpc_port;  int dpc_irq;  phys_bytes dpc_mem;  char *dpc_envvar;} dp_conf_t;/* Device default configuration */static dp_conf_t dp_conf[DE_PORT_NR] = {  /* I/O port, IRQ, Buff addr, Env. var, Buf. selector */  {     0x300,   5,   0xC8000,	"DPETH0", },  {     0x280,  10,   0xCC000,	"DPETH1", },};static const char CopyErrMsg[] = "unable to read/write user data";static const char PortErrMsg[] = "illegal port";static const char RecvErrMsg[] = "receive failed";static const char SendErrMsg[] = "send failed";static const char SizeErrMsg[] = "illegal packet size";static const char TypeErrMsg[] = "illegal message type";static const char DevName[] = "eth#?";static void do_getname(message *mp);/***  Name:	void reply(dpeth_t *dep, int err)**  Function:	Fills a DL_TASK_REPLY reply message and sends it.*/static void reply(dpeth_t * dep, int err){  message reply;  int status = FALSE;  if (dep->de_flags & DEF_ACK_SEND) status |= DL_PACK_SEND;  if (dep->de_flags & DEF_ACK_RECV) status |= DL_PACK_RECV;  reply.m_type = DL_TASK_REPLY;  reply.DL_PORT = dep - de_table;  reply.DL_PROC = dep->de_client;  reply.DL_STAT = status /* | ((u32_t) err << 16) */;  reply.DL_COUNT = dep->de_read_s;  getuptime(&reply.DL_CLCK);  DEBUG(printf("\t reply %d (%ld)\n", reply.m_type, reply.DL_STAT));  if ((status = send(dep->de_client, &reply)) == OK) {	dep->de_read_s = 0;	dep->de_flags &= NOT(DEF_ACK_SEND | DEF_ACK_RECV);  } else if (status != ELOCKED || err == OK)	panic(dep->de_name, SendErrMsg, status);  return;}/***  Name:	void dp_confaddr(dpeth_t *dep)**  Function:	Checks environment for a User defined ethernet address.*/static void dp_confaddr(dpeth_t * dep){  static char ea_fmt[] = "x:x:x:x:x:x";  char ea_key[16];  int ix;  long val;  strcpy(ea_key, dp_conf[dep - de_table].dpc_envvar);  strcat(ea_key, "_EA");  for (ix = 0; ix < SA_ADDR_LEN; ix++) {	val = dep->de_address.ea_addr[ix];	if (env_parse(ea_key, ea_fmt, ix, &val, 0x00L, 0xFFL) != EP_SET)		break;	dep->de_address.ea_addr[ix] = val;  }  if (ix != 0 && ix != SA_ADDR_LEN)	/* It's all or nothing, force a panic */	env_parse(ea_key, "?", 0, &val, 0L, 0L);  return;}/***  Name:	void update_conf(dpeth_t *dep, dp_conf_t *dcp)**  Function:	Gets the default settings from 'dp_conf' table and**  		modifies them from the environment.*/static void update_conf(dpeth_t * dep, dp_conf_t * dcp){  static char dpc_fmt[] = "x:d:x";  long val;  dep->de_mode = DEM_SINK;  val = dcp->dpc_port;		/* Get I/O port address */  switch (env_parse(dcp->dpc_envvar, dpc_fmt, 0, &val, 0x000L, 0x3FFL)) {      case EP_OFF:	dep->de_mode = DEM_DISABLED;	break;      case EP_ON:      case EP_SET:	dep->de_mode = DEM_ENABLED;	break;  }  dep->de_base_port = val;  val = dcp->dpc_irq | DEI_DEFAULT;	/* Get Interrupt line (IRQ) */  env_parse(dcp->dpc_envvar, dpc_fmt, 1, &val, 0L, (long) NR_IRQ_VECTORS - 1);  dep->de_irq = val;  val = dcp->dpc_mem;		/* Get shared memory address */  env_parse(dcp->dpc_envvar, dpc_fmt, 2, &val, 0L, LONG_MAX);  dep->de_linmem = val;  return;}/***  Name:	void do_dump(message *mp)**  Function:	Displays statistics on screen (SFx key from console)*/static void do_dump(message *mp){  dpeth_t *dep;  int port;  printf("\n\n");  for (port = 0, dep = de_table; port < DE_PORT_NR; port += 1, dep += 1) {	if (dep->de_mode == DEM_DISABLED) continue;	printf("%s statistics:\t\t", dep->de_name);	/* Network interface status  */	printf("Status: 0x%04x (%d)\n\n", dep->de_flags, dep->de_int_pending);	(*dep->de_dumpstatsf) (dep);	/* Transmitted/received bytes */	printf("Tx bytes:%10ld\t", dep->bytes_Tx);	printf("Rx bytes:%10ld\n", dep->bytes_Rx);	/* Transmitted/received packets */	printf("Tx OK:     %8ld\t", dep->de_stat.ets_packetT);	printf("Rx OK:     %8ld\n", dep->de_stat.ets_packetR);	/* Transmit/receive errors */	printf("Tx Err:    %8ld\t", dep->de_stat.ets_sendErr);	printf("Rx Err:    %8ld\n", dep->de_stat.ets_recvErr);	/* Transmit unnerruns/receive overrruns */	printf("Tx Und:    %8ld\t", dep->de_stat.ets_fifoUnder);	printf("Rx Ovr:    %8ld\n", dep->de_stat.ets_fifoOver);	/* Transmit collisions/receive CRC errors */	printf("Tx Coll:   %8ld\t", dep->de_stat.ets_collision);	printf("Rx CRC:    %8ld\n", dep->de_stat.ets_CRCerr);  }  return;}/***  Name:	void get_userdata(int user_proc, vir_bytes user_addr, int count, void *loc_addr)**  Function:	Copies data from user area.*/static void get_userdata(int user_proc, vir_bytes user_addr, int count, void *loc_addr){  int rc;  vir_bytes len;  len = (count > IOVEC_NR ? IOVEC_NR : count) * sizeof(iovec_t);  if ((rc = sys_datacopy(user_proc, user_addr, SELF, (vir_bytes)loc_addr, len)) != OK)	panic(DevName, CopyErrMsg, rc);  return;}/***  Name:	void do_first_init(dpeth_t *dep, dp_conf_t *dcp);**  Function:	Init action to setup task*/static void do_first_init(dpeth_t *dep, dp_conf_t *dcp){  if (dep->de_linmem != 0) {	dep->de_memsegm = BIOS_SEG;	/* phys2seg(&dep->de_memsegm, &dep->de_memoffs, dep->de_linmem); */  } else	dep->de_linmem = 0xFFFF0000;  /* Make sure statisics are cleared */  memset((void *) &(dep->de_stat), 0, sizeof(eth_stat_t));  /* Device specific initialization */  (*dep->de_initf) (dep);  /* Set the interrupt handler policy. Request interrupts not to be reenabled   * automatically. Return the IRQ line number when an interrupt occurs.   */  dep->de_hook = dep->de_irq;  sys_irqsetpolicy(dep->de_irq, 0 /*IRQ_REENABLE*/, &dep->de_hook);  dep->de_int_pending = FALSE;  sys_irqenable(&dep->de_hook);  return;}/***  Name:	void do_init(message *mp)**  Function:	Checks for hardware presence.**  		Provides initialization of hardware and data structures*/static void do_init(message * mp){  int port;  dpeth_t *dep;  dp_conf_t *dcp;  message reply_mess;  port = mp->DL_PORT;  if (port >= 0 && port < DE_PORT_NR) {	dep = &de_table[port];	dcp = &dp_conf[port];	strcpy(dep->de_name, DevName);	dep->de_name[4] = '0' + port;	if (dep->de_mode == DEM_DISABLED) {		update_conf(dep, dcp);	/* First time thru */		if (dep->de_mode == DEM_ENABLED &&		    !el1_probe(dep) &&	/* Probe for 3c501  */		    !wdeth_probe(dep) &&	/* Probe for WD80x3 */		    !ne_probe(dep) &&	/* Probe for NEx000 */		    !el2_probe(dep) &&	/* Probe for 3c503  */		    !el3_probe(dep)) {	/* Probe for 3c509  */			printf("%s: warning no ethernet card found at 0x%04X\n",			       dep->de_name, dep->de_base_port);			dep->de_mode = DEM_DISABLED;		}	}	/* 'de_mode' may change if probe routines fail, test again */	switch (dep->de_mode) {	    case DEM_DISABLED:		/* Device is configured OFF or hardware probe failed */		port = ENXIO;		break;	    case DEM_ENABLED:		/* Device is present and probed */		if (dep->de_flags == DEF_EMPTY) {			/* These actions only the first time */			do_first_init(dep, dcp);			dep->de_flags |= DEF_ENABLED;		}		dep->de_flags &= NOT(DEF_PROMISC | DEF_MULTI | DEF_BROAD);		if (mp->DL_MODE & DL_PROMISC_REQ)			dep->de_flags |= DEF_PROMISC | DEF_MULTI | DEF_BROAD;		if (mp->DL_MODE & DL_MULTI_REQ) dep->de_flags |= DEF_MULTI;		if (mp->DL_MODE & DL_BROAD_REQ) dep->de_flags |= DEF_BROAD;		(*dep->de_flagsf) (dep);		dep->de_client = mp->m_source;		break;	    case DEM_SINK:		/* Device not present (sink mode) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -