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

📄 zatm.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
		u32 data,*addr;		EVENT("MBX: host 0x%lx, nic 0x%x\n",pos,x);		addr = (u32 *) pos;		data = *addr;		chan = (data & uPD98401_TXI_CONN) >> uPD98401_TXI_CONN_SHIFT;		EVENT("addr = 0x%lx, data = 0x%08x,",(unsigned long) addr,		    data);		EVENT("chan = %d\n",chan,0);#elseNO !		chan = (zatm_dev->mbx_start[mbx][pos >> 2] & uPD98401_TXI_CONN)		>> uPD98401_TXI_CONN_SHIFT;#endif		if (chan < zatm_dev->chans && zatm_dev->tx_map[chan])			dequeue_tx(zatm_dev->tx_map[chan]);		else {			printk(KERN_CRIT DEV_LABEL "(itf %d): TX indication "			    "for non-existing channel %d\n",dev->number,chan);			event_dump();		}		if (((pos += 4) & 0xffff) == zatm_dev->mbx_end[mbx])			pos = zatm_dev->mbx_start[mbx];	}	zout(pos & 0xffff,MTA(mbx));}/* * BUG BUG BUG: Doesn't handle "new-style" rate specification yet. */static int alloc_shaper(struct atm_dev *dev,int *pcr,int min,int max,int ubr){	struct zatm_dev *zatm_dev;	unsigned long flags;	unsigned long i,m,c;	int shaper;	DPRINTK("alloc_shaper (min = %d, max = %d)\n",min,max);	zatm_dev = ZATM_DEV(dev);	if (!zatm_dev->free_shapers) return -EAGAIN;	for (shaper = 0; !((zatm_dev->free_shapers >> shaper) & 1); shaper++);	zatm_dev->free_shapers &= ~1 << shaper;	if (ubr) {		c = 5;		i = m = 1;		zatm_dev->ubr_ref_cnt++;		zatm_dev->ubr = shaper;	}	else {		if (min) {			if (min <= 255) {				i = min;				m = ATM_OC3_PCR;			}			else {				i = 255;				m = ATM_OC3_PCR*255/min;			}		}		else {			if (max > zatm_dev->tx_bw) max = zatm_dev->tx_bw;			if (max <= 255) {				i = max;				m = ATM_OC3_PCR;			}			else {				i = 255;				m = (ATM_OC3_PCR*255+max-1)/max;			}		}		if (i > m) {			printk(KERN_CRIT DEV_LABEL "shaper algorithm botched "			    "[%d,%d] -> i=%ld,m=%ld\n",min,max,i,m);			m = i;		}		*pcr = i*ATM_OC3_PCR/m;		c = 20; /* @@@ should use max_cdv ! */		if ((min && *pcr < min) || (max && *pcr > max)) return -EINVAL;		if (zatm_dev->tx_bw < *pcr) return -EAGAIN;		zatm_dev->tx_bw -= *pcr;	}	save_flags(flags);	cli();	DPRINTK("i = %d, m = %d, PCR = %d\n",i,m,*pcr);	zpokel(zatm_dev,(i << uPD98401_IM_I_SHIFT) | m,uPD98401_IM(shaper));	zpokel(zatm_dev,c << uPD98401_PC_C_SHIFT,uPD98401_PC(shaper));	zpokel(zatm_dev,0,uPD98401_X(shaper));	zpokel(zatm_dev,0,uPD98401_Y(shaper));	zpokel(zatm_dev,uPD98401_PS_E,uPD98401_PS(shaper));	restore_flags(flags);	return shaper;}static void dealloc_shaper(struct atm_dev *dev,int shaper){	struct zatm_dev *zatm_dev;	unsigned long flags;	zatm_dev = ZATM_DEV(dev);	if (shaper == zatm_dev->ubr) {		if (--zatm_dev->ubr_ref_cnt) return;		zatm_dev->ubr = -1;	}	save_flags(flags);	cli();	zpokel(zatm_dev,zpeekl(zatm_dev,uPD98401_PS(shaper)) & ~uPD98401_PS_E,	    uPD98401_PS(shaper));	restore_flags(flags);	zatm_dev->free_shapers |= 1 << shaper;}static void close_tx(struct atm_vcc *vcc){	struct zatm_dev *zatm_dev;	struct zatm_vcc *zatm_vcc;	unsigned long flags;	int chan;struct sk_buff *skb;int once = 1;	zatm_vcc = ZATM_VCC(vcc);	zatm_dev = ZATM_DEV(vcc->dev);	chan = zatm_vcc->tx_chan;	if (!chan) return;	DPRINTK("close_tx\n");	save_flags(flags);	cli();	while (skb_peek(&zatm_vcc->backlog)) {if (once) {printk("waiting for backlog to drain ...\n");event_dump();once = 0;}		sleep_on(&zatm_vcc->tx_wait);	}once = 1;	while ((skb = skb_peek(&zatm_vcc->tx_queue))) {if (once) {printk("waiting for TX queue to drain ... %p\n",skb);event_dump();once = 0;}		DPRINTK("waiting for TX queue to drain ... %p\n",skb);		sleep_on(&zatm_vcc->tx_wait);	}#if 0	zwait;	zout(uPD98401_DEACT_CHAN | (chan << uPD98401_CHAN_ADDR_SHIFT),CMR);#endif	zwait;	zout(uPD98401_CLOSE_CHAN | (chan << uPD98401_CHAN_ADDR_SHIFT),CMR);	zwait;	if (!(zin(CMR) & uPD98401_CHAN_ADDR))		printk(KERN_CRIT DEV_LABEL "(itf %d): can't close TX channel "		    "%d\n",vcc->dev->number,chan);	restore_flags(flags);	zatm_vcc->tx_chan = 0;	zatm_dev->tx_map[chan] = NULL;	if (zatm_vcc->shaper != zatm_dev->ubr) {		zatm_dev->tx_bw += vcc->qos.txtp.min_pcr;		dealloc_shaper(vcc->dev,zatm_vcc->shaper);	}	if (zatm_vcc->ring) kfree(zatm_vcc->ring);}static int open_tx_first(struct atm_vcc *vcc){	struct zatm_dev *zatm_dev;	struct zatm_vcc *zatm_vcc;	unsigned long flags;	u32 *loop;	unsigned short chan;	int pcr,unlimited;	DPRINTK("open_tx_first\n");	zatm_dev = ZATM_DEV(vcc->dev);	zatm_vcc = ZATM_VCC(vcc);	zatm_vcc->tx_chan = 0;	if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0;	save_flags(flags);	cli();	zwait;	zout(uPD98401_OPEN_CHAN,CMR);	zwait;	DPRINTK("0x%x 0x%x\n",zin(CMR),zin(CER));	chan = (zin(CMR) & uPD98401_CHAN_ADDR) >> uPD98401_CHAN_ADDR_SHIFT;	restore_flags(flags);	DPRINTK("chan is %d\n",chan);	if (!chan) return -EAGAIN;	unlimited = vcc->qos.txtp.traffic_class == ATM_UBR &&	    (!vcc->qos.txtp.max_pcr || vcc->qos.txtp.max_pcr == ATM_MAX_PCR ||	    vcc->qos.txtp.max_pcr >= ATM_OC3_PCR);	if (unlimited && zatm_dev->ubr != -1) zatm_vcc->shaper = zatm_dev->ubr;	else {		if (unlimited) vcc->qos.txtp.max_sdu = ATM_MAX_AAL5_PDU;		if ((zatm_vcc->shaper = alloc_shaper(vcc->dev,&pcr,		    vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,unlimited))		    < 0) {			close_tx(vcc);			return zatm_vcc->shaper;		}		if (pcr > ATM_OC3_PCR) pcr = ATM_OC3_PCR;		vcc->qos.txtp.min_pcr = vcc->qos.txtp.max_pcr = pcr;	}	zatm_vcc->tx_chan = chan;	skb_queue_head_init(&zatm_vcc->tx_queue);	init_waitqueue_head(&zatm_vcc->tx_wait);	/* initialize ring */	zatm_vcc->ring = kmalloc(RING_SIZE,GFP_KERNEL);	if (!zatm_vcc->ring) return -ENOMEM;	memset(zatm_vcc->ring,0,RING_SIZE);	loop = zatm_vcc->ring+RING_ENTRIES*RING_WORDS;	loop[0] = uPD98401_TXPD_V;	loop[1] = loop[2] = 0;	loop[3] = virt_to_bus(zatm_vcc->ring);	zatm_vcc->ring_curr = 0;	zatm_vcc->txing = 0;	skb_queue_head_init(&zatm_vcc->backlog);	zpokel(zatm_dev,virt_to_bus(zatm_vcc->ring),	    chan*VC_SIZE/4+uPD98401_TXVC_QRP);	return 0;}static int open_tx_second(struct atm_vcc *vcc){	struct zatm_dev *zatm_dev;	struct zatm_vcc *zatm_vcc;	unsigned long flags;	DPRINTK("open_tx_second\n");	zatm_dev = ZATM_DEV(vcc->dev);	zatm_vcc = ZATM_VCC(vcc);	if (!zatm_vcc->tx_chan) return 0;	save_flags(flags);	/* set up VC descriptor */	cli();	zpokel(zatm_dev,0,zatm_vcc->tx_chan*VC_SIZE/4);	zpokel(zatm_dev,uPD98401_TXVC_L | (zatm_vcc->shaper <<	    uPD98401_TXVC_SHP_SHIFT) | (vcc->vpi << uPD98401_TXVC_VPI_SHIFT) |	    vcc->vci,zatm_vcc->tx_chan*VC_SIZE/4+1);	zpokel(zatm_dev,0,zatm_vcc->tx_chan*VC_SIZE/4+2);	restore_flags(flags);	zatm_dev->tx_map[zatm_vcc->tx_chan] = vcc;	return 0;}static int start_tx(struct atm_dev *dev){	struct zatm_dev *zatm_dev;	int i;	DPRINTK("start_tx\n");	zatm_dev = ZATM_DEV(dev);	zatm_dev->tx_map = (struct atm_vcc **) kmalloc(sizeof(struct atm_vcc *)*	    zatm_dev->chans,GFP_KERNEL);	if (!zatm_dev->tx_map) return -ENOMEM;	zatm_dev->tx_bw = ATM_OC3_PCR;	zatm_dev->free_shapers = (1 << NR_SHAPERS)-1;	zatm_dev->ubr = -1;	zatm_dev->ubr_ref_cnt = 0;	/* initialize shapers */	for (i = 0; i < NR_SHAPERS; i++) zpokel(zatm_dev,0,uPD98401_PS(i));	return 0;}/*------------------------------- interrupts --------------------------------*/static void zatm_int(int irq,void *dev_id,struct pt_regs *regs){	struct atm_dev *dev;	struct zatm_dev *zatm_dev;	u32 reason;	dev = dev_id;	zatm_dev = ZATM_DEV(dev);	while ((reason = zin(GSR))) {		EVENT("reason 0x%x\n",reason,0);		if (reason & uPD98401_INT_PI) {			EVENT("PHY int\n",0,0);			dev->phy->interrupt(dev);		}		if (reason & uPD98401_INT_RQA) {			unsigned long pools;			int i;			pools = zin(RQA);			EVENT("RQA (0x%08x)\n",pools,0);			for (i = 0; pools; i++) {				if (pools & 1) {					refill_pool(dev,i);					zatm_dev->pool_info[i].rqa_count++;				}				pools >>= 1;			}		}		if (reason & uPD98401_INT_RQU) {			unsigned long pools;			int i;			pools = zin(RQU);			printk(KERN_WARNING DEV_LABEL "(itf %d): RQU 0x%08lx\n",			    dev->number,pools);			event_dump();			for (i = 0; pools; i++) {				if (pools & 1) {					refill_pool(dev,i);					zatm_dev->pool_info[i].rqu_count++;				}				pools >>= 1;			}		}		/* don't handle RD */		if (reason & uPD98401_INT_SPE)			printk(KERN_ALERT DEV_LABEL "(itf %d): system parity "			    "error at 0x%08x\n",dev->number,zin(ADDR));		if (reason & uPD98401_INT_CPE)			printk(KERN_ALERT DEV_LABEL "(itf %d): control memory "			    "parity error at 0x%08x\n",dev->number,zin(ADDR));		if (reason & uPD98401_INT_SBE) {			printk(KERN_ALERT DEV_LABEL "(itf %d): system bus "			    "error at 0x%08x\n",dev->number,zin(ADDR));			event_dump();		}		/* don't handle IND */		if (reason & uPD98401_INT_MF) {			printk(KERN_CRIT DEV_LABEL "(itf %d): mailbox full "			    "(0x%x)\n",dev->number,(reason & uPD98401_INT_MF)			    >> uPD98401_INT_MF_SHIFT);			event_dump();			    /* @@@ should try to recover */		}		if (reason & uPD98401_INT_MM) {			if (reason & 1) poll_rx(dev,0);			if (reason & 2) poll_rx(dev,1);			if (reason & 4) poll_tx(dev,2);			if (reason & 8) poll_tx(dev,3);		}		/* @@@ handle RCRn */	}}/*----------------------------- (E)EPROM access -----------------------------*/static void __init eprom_set(struct zatm_dev *zatm_dev,unsigned long value,    unsigned short cmd){	int error;	if ((error = pci_write_config_dword(zatm_dev->pci_dev,cmd,value)))		printk(KERN_ERR DEV_LABEL ": PCI write failed (0x%02x)\n",		    error);}static unsigned long __init eprom_get(struct zatm_dev *zatm_dev,    unsigned short cmd){	unsigned int value;	int error;	if ((error = pci_read_config_dword(zatm_dev->pci_dev,cmd,&value)))		printk(KERN_ERR DEV_LABEL ": PCI read failed (0x%02x)\n",		    error);	return value;}static void __init eprom_put_bits(struct zatm_dev *zatm_dev,    unsigned long data,int bits,unsigned short cmd){	unsigned long value;	int i;	for (i = bits-1; i >= 0; i--) {		value = ZEPROM_CS | (((data >> i) & 1) ? ZEPROM_DI : 0);		eprom_set(zatm_dev,value,cmd);		eprom_set(zatm_dev,value | ZEPROM_SK,cmd);		eprom_set(zatm_dev,value,cmd);	}}static void __init eprom_get_byte(struct zatm_dev *zatm_dev,    unsigned char *byte,unsigned short cmd){	int i;	*byte = 0;	for (i = 8; i; i--) {		eprom_set(zatm_dev,ZEPROM_CS,cmd);		eprom_set(zatm_dev,ZEPROM_CS | ZEPROM_SK,cmd);		*byte <<= 1;		if (eprom_get(zatm_dev,cmd) & ZEPROM_DO) *byte |= 1;		eprom_set(zatm_dev,ZEPROM_CS,cmd);	}}static unsigned char __init eprom_try_esi(struct atm_dev *dev,    unsigned short cmd,int offset,int swap){	unsigned char buf[ZEPROM_SIZE];	struct zatm_dev *zatm_dev;	int i;	zatm_dev = ZATM_DEV(dev);	for (i = 0; i < ZEPROM_SIZE; i += 2) {		eprom_set(zatm_dev,ZEPROM_CS,cmd); /* select EPROM */		eprom_put_bits(zatm_dev,ZEPROM_CMD_READ,ZEPROM_CMD_LEN,cmd);		eprom_put_bits(zatm_dev,i >> 1,ZEPROM_ADDR_LEN,cmd);		eprom_get_byte(zatm_dev,buf+i+swap,cmd);		eprom_get_byte(zatm_dev,buf+i+1-swap,cmd);		eprom_set(zatm_dev,0,cmd); /* deselect EPROM */	}	memcpy(dev->esi,buf+offset,ESI_LEN);	return memcmp(dev->esi,"\0\0\0\0\0",ESI_LEN); /* assumes ESI_LEN == 6 */}static void __init eprom_get_esi(struct atm_dev *dev){	if (eprom_try_esi(dev,ZEPROM_V1_REG,ZEPROM_V1_ESI_OFF,1)) return;	(void) eprom_try_esi(dev,ZEPROM_V2_REG,ZEPROM_V2_ESI_OFF,0);}/*--------------------------------- entries ---------------------------------*/static int __init zatm_init(struct atm_dev *dev){	struct zatm_dev *zatm_dev;	struct pci_dev *pci_dev;	unsigned short command;	unsigned char revision;	int error,i,last;	unsigned long t0,t1,t2;	DPRINTK(">zatm_init\n");	zatm_dev = ZATM_DEV(dev);	pci_dev = zatm_dev->pci_dev;	zatm_dev->base = pci_resource_start(pci_dev, 0);	zatm_dev->irq = pci_dev->irq;	if ((error = pci_read_config_word(pci_dev,PCI_COMMAND,&command)) ||	    (error = pci_read_config_byte(pci_dev,PCI_REVISION_ID,&revision))) {		printk(KERN_ERR DEV_LABEL "(itf %d): init error 0x%02x\n",		    dev->number,error);		return -EINVAL;	}	if ((error = pci_write_config_word(pci_dev,PCI_COMMAND,	    command | PCI_COMMAND_IO | PCI_COMMAND_MASTER))) {		printk(KERN_ERR DEV_LABEL "(itf %d): can't enable IO (0x%02x)"		    "\n",dev->number,error);		return -EIO;	}	eprom_get_esi(dev);	printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%x,irq=%d,",	    dev->number,revision,zatm_dev->base,zatm_dev->irq);	/* reset uPD98401 */	zout(0,SWR);

⌨️ 快捷键说明

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