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

📄 ibmtr.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	dev->base_addr = PIOaddr;	/* set the value for device */	dev->mem_start = ti->sram_base << 12;	dev->mem_end = dev->mem_start + (ti->mapped_ram_size << 9) - 1;	trdev_init(dev);	return 0;   /* Return 0 to indicate we have found a Token Ring card. */}				/*ibmtr_probe1() *//*****************************************************************************//* query the adapter for the size of shared RAM  *//* the function returns the RAM size in units of 512 bytes */static unsigned char __devinit get_sram_size(struct tok_info *adapt_info){	unsigned char avail_sram_code;	static unsigned char size_code[] = { 0, 16, 32, 64, 127, 128 };	/* Adapter gives	   'F' -- use RRR bits 3,2	   'E' -- 8kb   'D' -- 16kb	   'C' -- 32kb  'A' -- 64KB	   'B' - 64KB less 512 bytes at top	   (WARNING ... must zero top bytes in INIT */	avail_sram_code = 0xf - readb(adapt_info->mmio + AIPAVAILSHRAM);	if (avail_sram_code) return size_code[avail_sram_code];	else		/* for code 'F', must compute size from RRR(3,2) bits */		return 1 <<		 ((readb(adapt_info->mmio+ACA_OFFSET+ACA_RW+RRR_ODD)>>2&3)+4);}/*****************************************************************************/static int __devinit trdev_init(struct net_device *dev){	struct tok_info *ti = (struct tok_info *) dev->priv;	SET_PAGE(ti->srb_page);        ti->open_failure = NO    ;	dev->open = tok_open;	dev->stop = tok_close;	dev->hard_start_xmit = tok_send_packet;	dev->get_stats = tok_get_stats;	dev->set_multicast_list = tok_set_multicast_list;	dev->change_mtu = ibmtr_change_mtu;	return 0;}/*****************************************************************************/static int tok_init_card(struct net_device *dev){	struct tok_info *ti;	short PIOaddr;	unsigned long i;	PIOaddr = dev->base_addr;	ti = (struct tok_info *) dev->priv;	/* Special processing for first interrupt after reset */	ti->do_tok_int = FIRST_INT;	/* Reset adapter */	writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);	outb(0, PIOaddr + ADAPTRESET);	schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */	outb(0, PIOaddr + ADAPTRESETREL);#ifdef ENABLE_PAGING	if (ti->page_mask)		writeb(SRPR_ENABLE_PAGING,ti->mmio+ACA_OFFSET+ACA_RW+SRPR_EVEN);#endif	writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);	i = sleep_on_timeout(&ti->wait_for_reset, 4 * HZ);	return i? 0 : -EAGAIN;}/*****************************************************************************/static int tok_open(struct net_device *dev){	struct tok_info *ti = (struct tok_info *) dev->priv;	int i;	/*the case we were left in a failure state during a previous open */	if (ti->open_failure == YES) {		DPRINTK("Last time you were disconnected, how about now?\n");		printk("You can't insert with an ICS connector half-cocked.\n");	}	ti->open_status  = CLOSED; /* CLOSED or OPEN      */	ti->sap_status   = CLOSED; /* CLOSED or OPEN      */	ti->open_failure =     NO; /* NO     or YES       */	ti->open_mode    = MANUAL; /* MANUAL or AUTOMATIC */	ti->sram_phys &= ~1; /* to reverse what we do in tok_close */	/* init the spinlock */	spin_lock_init(&ti->lock);	init_timer(&ti->tr_timer);		i = tok_init_card(dev);	if (i) return i;	while (1){		tok_open_adapter((unsigned long) dev);		i= interruptible_sleep_on_timeout(&ti->wait_for_reset, 25 * HZ);		/* sig catch: estimate opening adapter takes more than .5 sec*/		if (i>(245*HZ)/10) break; /* fancier than if (i==25*HZ) */		if (i==0) break;		if (ti->open_status == OPEN && ti->sap_status==OPEN) {			netif_start_queue(dev);			DPRINTK("Adapter is up and running\n");			return 0;		}		i=schedule_timeout_interruptible(TR_RETRY_INTERVAL);							/* wait 30 seconds */		if(i!=0) break; /*prob. a signal, like the i>24*HZ case above */	}	outb(0, dev->base_addr + ADAPTRESET);/* kill pending interrupts*/	DPRINTK("TERMINATED via signal\n");	/*BMS useful */	return -EAGAIN;}/*****************************************************************************/#define COMMAND_OFST             0#define OPEN_OPTIONS_OFST        8#define NUM_RCV_BUF_OFST        24#define RCV_BUF_LEN_OFST        26#define DHB_LENGTH_OFST         28#define NUM_DHB_OFST            30#define DLC_MAX_SAP_OFST        32#define DLC_MAX_STA_OFST        33static void tok_open_adapter(unsigned long dev_addr){	struct net_device *dev = (struct net_device *) dev_addr;	struct tok_info *ti;	int i;	ti = (struct tok_info *) dev->priv;	SET_PAGE(ti->init_srb_page); 	writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);	for (i = 0; i < sizeof(struct dir_open_adapter); i++)		writeb(0, ti->init_srb + i);	writeb(DIR_OPEN_ADAPTER, ti->init_srb + COMMAND_OFST);	writew(htons(OPEN_PASS_BCON_MAC), ti->init_srb + OPEN_OPTIONS_OFST);	if (ti->ring_speed == 16) {		writew(htons(ti->dhb_size16mb), ti->init_srb + DHB_LENGTH_OFST);		writew(htons(ti->rbuf_cnt16), ti->init_srb + NUM_RCV_BUF_OFST);		writew(htons(ti->rbuf_len16), ti->init_srb + RCV_BUF_LEN_OFST);	} else {		writew(htons(ti->dhb_size4mb), ti->init_srb + DHB_LENGTH_OFST);		writew(htons(ti->rbuf_cnt4), ti->init_srb + NUM_RCV_BUF_OFST);		writew(htons(ti->rbuf_len4), ti->init_srb + RCV_BUF_LEN_OFST);	}	writeb(NUM_DHB,		/* always 2 */ ti->init_srb + NUM_DHB_OFST);	writeb(DLC_MAX_SAP, ti->init_srb + DLC_MAX_SAP_OFST);	writeb(DLC_MAX_STA, ti->init_srb + DLC_MAX_STA_OFST);	ti->srb = ti->init_srb;	/* We use this one in the interrupt handler */	ti->srb_page = ti->init_srb_page;	DPRINTK("Opening adapter: Xmit bfrs: %d X %d, Rcv bfrs: %d X %d\n",		readb(ti->init_srb + NUM_DHB_OFST),		ntohs(readw(ti->init_srb + DHB_LENGTH_OFST)),		ntohs(readw(ti->init_srb + NUM_RCV_BUF_OFST)),		ntohs(readw(ti->init_srb + RCV_BUF_LEN_OFST)));	writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);}/*****************************************************************************/static void open_sap(unsigned char type, struct net_device *dev){	int i;	struct tok_info *ti = (struct tok_info *) dev->priv;	SET_PAGE(ti->srb_page);	for (i = 0; i < sizeof(struct dlc_open_sap); i++)		writeb(0, ti->srb + i);#define MAX_I_FIELD_OFST        14#define SAP_VALUE_OFST          16#define SAP_OPTIONS_OFST        17#define STATION_COUNT_OFST      18	writeb(DLC_OPEN_SAP, ti->srb + COMMAND_OFST);	writew(htons(MAX_I_FIELD), ti->srb + MAX_I_FIELD_OFST);	writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY, ti->srb+ SAP_OPTIONS_OFST);	writeb(SAP_OPEN_STATION_CNT, ti->srb + STATION_COUNT_OFST);	writeb(type, ti->srb + SAP_VALUE_OFST);	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);}/*****************************************************************************/static void tok_set_multicast_list(struct net_device *dev){	struct tok_info *ti = (struct tok_info *) dev->priv;	struct dev_mc_list *mclist;	unsigned char address[4];	int i;	/*BMS the next line is CRUCIAL or you may be sad when you */	/*BMS ifconfig tr down or hot unplug a PCMCIA card ??hownowbrowncow*/	if (/*BMSHELPdev->start == 0 ||*/ ti->open_status != OPEN) return;	address[0] = address[1] = address[2] = address[3] = 0;	mclist = dev->mc_list;	for (i = 0; i < dev->mc_count; i++) {		address[0] |= mclist->dmi_addr[2];		address[1] |= mclist->dmi_addr[3];		address[2] |= mclist->dmi_addr[4];		address[3] |= mclist->dmi_addr[5];		mclist = mclist->next;	}	SET_PAGE(ti->srb_page);	for (i = 0; i < sizeof(struct srb_set_funct_addr); i++)		writeb(0, ti->srb + i);#define FUNCT_ADDRESS_OFST 6	writeb(DIR_SET_FUNC_ADDR, ti->srb + COMMAND_OFST);	for (i = 0; i < 4; i++) 		writeb(address[i], ti->srb + FUNCT_ADDRESS_OFST + i);	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);#if TR_VERBOSE	DPRINTK("Setting functional address: ");	for (i=0;i<4;i++)  printk("%02X ", address[i]);	printk("\n");#endif}/*****************************************************************************/#define STATION_ID_OFST 4static int tok_send_packet(struct sk_buff *skb, struct net_device *dev){	struct tok_info *ti;	unsigned long flags;	ti = (struct tok_info *) dev->priv;        netif_stop_queue(dev);	/* lock against other CPUs */	spin_lock_irqsave(&(ti->lock), flags);	/* Save skb; we'll need it when the adapter asks for the data */	ti->current_skb = skb;	SET_PAGE(ti->srb_page);	writeb(XMIT_UI_FRAME, ti->srb + COMMAND_OFST);	writew(ti->exsap_station_id, ti->srb + STATION_ID_OFST);	writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);	spin_unlock_irqrestore(&(ti->lock), flags);	dev->trans_start = jiffies;	return 0;}/*****************************************************************************/static int tok_close(struct net_device *dev){	struct tok_info *ti = (struct tok_info *) dev->priv;	/* Important for PCMCIA hot unplug, otherwise, we'll pull the card, */	/* unloading the module from memory, and then if a timer pops, ouch */	del_timer_sync(&ti->tr_timer);	outb(0, dev->base_addr + ADAPTRESET);	ti->sram_phys |= 1;	ti->open_status = CLOSED;	netif_stop_queue(dev);	DPRINTK("Adapter is closed.\n");	return 0;}/*****************************************************************************/#define RETCODE_OFST		2#define OPEN_ERROR_CODE_OFST	6#define ASB_ADDRESS_OFST        8#define SRB_ADDRESS_OFST        10#define ARB_ADDRESS_OFST        12#define SSB_ADDRESS_OFST        14static char *printphase[]= {"Lobe media test","Physical insertion",	      "Address verification","Roll call poll","Request Parameters"};static char *printerror[]={"Function failure","Signal loss","Reserved",		"Frequency error","Timeout","Ring failure","Ring beaconing",		"Duplicate node address",		"Parameter request-retry count exceeded","Remove received",		"IMPL force received","Duplicate modifier",		"No monitor detected","Monitor contention failed for RPL"};static void __iomem *map_address(struct tok_info *ti, unsigned index, __u8 *page){	if (ti->page_mask) {		*page = (index >> 8) & ti->page_mask;		index &= ~(ti->page_mask << 8);	}	return ti->sram_virt + index;}static void dir_open_adapter (struct net_device *dev){        struct tok_info *ti = (struct tok_info *) dev->priv;        unsigned char ret_code;        __u16 err;        ti->srb = map_address(ti,		ntohs(readw(ti->init_srb + SRB_ADDRESS_OFST)),		&ti->srb_page);        ti->ssb = map_address(ti,		ntohs(readw(ti->init_srb + SSB_ADDRESS_OFST)),		&ti->ssb_page);        ti->arb = map_address(ti,		ntohs(readw(ti->init_srb + ARB_ADDRESS_OFST)),		&ti->arb_page);        ti->asb = map_address(ti,		ntohs(readw(ti->init_srb + ASB_ADDRESS_OFST)),		&ti->asb_page);        ti->current_skb = NULL;        ret_code = readb(ti->init_srb + RETCODE_OFST);        err = ntohs(readw(ti->init_srb + OPEN_ERROR_CODE_OFST));        if (!ret_code) {		ti->open_status = OPEN; /* TR adapter is now available */                if (ti->open_mode == AUTOMATIC) {			DPRINTK("Adapter reopened.\n");                }                writeb(~SRB_RESP_INT, ti->mmio+ACA_OFFSET+ACA_RESET+ISRP_ODD);                open_sap(EXTENDED_SAP, dev);		return;	}	ti->open_failure = YES;	if (ret_code == 7){               if (err == 0x24) {			if (!ti->auto_speedsave) {				DPRINTK("Open failed: Adapter speed must match "                                 "ring speed if Automatic Ring Speed Save is "				 "disabled.\n");				ti->open_action = FAIL;			}else				DPRINTK("Retrying open to adjust to "					"ring speed, ");                } else if (err == 0x2d) {			DPRINTK("Physical Insertion: No Monitor Detected, ");			printk("retrying after %ds delay...\n",					TR_RETRY_INTERVAL/HZ);                } else if (err == 0x11) {			DPRINTK("Lobe Media Function Failure (0x11), ");			printk(" retrying after %ds delay...\n",					TR_RETRY_INTERVAL/HZ);                } else {			char **prphase = printphase;			char **prerror = printerror;			DPRINTK("TR Adapter misc open failure, error code = ");			printk("0x%x, Phase: %s, Error: %s\n",				err, prphase[err/16 -1], prerror[err%16 -1]);			printk(" retrying after %ds delay...\n",					TR_RETRY_INTERVAL/HZ);                }        } else DPRINTK("open failed: ret_code = %02X..., ", ret_code);	if (ti->open_action != FAIL) {		if (ti->open_mode==AUTOMATIC){			ti->open_action = REOPEN;			ibmtr_reset_timer(&(ti->tr_timer), dev);			return;		}		wake_up(&ti->wait_for_reset);		return;	}	DPRINTK("FAILURE, CAPUT\n");}/******************************************************************************/static irqreturn_t tok_interrupt(int irq, void *dev_id, struct pt_regs *regs){	unsigned char status;	/*  unsigned char status_even ; */	struct tok_info *ti;	struct net_device *dev;#ifdef ENABLE_PAGING	unsigned char save_srpr;#endif	dev = dev_id;#if TR_VERBOSE	DPRINTK("Int from tok_driver, dev : %p irq%d regs=%p\n", dev,irq,regs);#endif	ti = (struct tok_info *) dev->priv;	if (ti->sram_phys & 1)		return IRQ_NONE;         /* PCMCIA card extraction flag */	spin_lock(&(ti->lock));#ifdef ENABLE_PAGING	save_srpr = readb(ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);

⌨️ 快捷键说明

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