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

📄 firestream.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
				fs_dprintk (FS_DEBUG_IRQ, " %s", irq_bitname[i]);		fs_dprintk (FS_DEBUG_IRQ, "\n");	}  	if (status & ISR_RBRQ0_W) {		fs_dprintk (FS_DEBUG_IRQ, "Iiiin-coming (0)!!!!\n");		process_incoming (dev, &dev->rx_rq[0]);		/* items mentioned on RBRQ0 are from FP 0 or 1. */		top_off_fp (dev, &dev->rx_fp[0], GFP_ATOMIC);		top_off_fp (dev, &dev->rx_fp[1], GFP_ATOMIC);	}	if (status & ISR_RBRQ1_W) {		fs_dprintk (FS_DEBUG_IRQ, "Iiiin-coming (1)!!!!\n");		process_incoming (dev, &dev->rx_rq[1]);		top_off_fp (dev, &dev->rx_fp[2], GFP_ATOMIC);		top_off_fp (dev, &dev->rx_fp[3], GFP_ATOMIC);	}	if (status & ISR_RBRQ2_W) {		fs_dprintk (FS_DEBUG_IRQ, "Iiiin-coming (2)!!!!\n");		process_incoming (dev, &dev->rx_rq[2]);		top_off_fp (dev, &dev->rx_fp[4], GFP_ATOMIC);		top_off_fp (dev, &dev->rx_fp[5], GFP_ATOMIC);	}	if (status & ISR_RBRQ3_W) {		fs_dprintk (FS_DEBUG_IRQ, "Iiiin-coming (3)!!!!\n");		process_incoming (dev, &dev->rx_rq[3]);		top_off_fp (dev, &dev->rx_fp[6], GFP_ATOMIC);		top_off_fp (dev, &dev->rx_fp[7], GFP_ATOMIC);	}	if (status & ISR_CSQ_W) {		fs_dprintk (FS_DEBUG_IRQ, "Command executed ok!\n");		process_return_queue (dev, &dev->st_q);	}	if (status & ISR_TBRQ_W) {		fs_dprintk (FS_DEBUG_IRQ, "Data tramsitted!\n");		process_txdone_queue (dev, &dev->tx_relq);	}	func_exit ();}#ifdef FS_POLL_FREQstatic void fs_poll (unsigned long data){	struct fs_dev *dev = (struct fs_dev *) data;  	fs_irq (0, dev, NULL);	dev->timer.expires = jiffies + FS_POLL_FREQ;	add_timer (&dev->timer);}#endifstatic int __init fs_init (struct fs_dev *dev){	struct pci_dev  *pci_dev;	int isr, to;	int i;	func_enter ();	pci_dev = dev->pci_dev;	printk (KERN_INFO "found a FireStream %d card, base %08lx, irq%d.\n", 		IS_FS50(dev)?50:155,		pci_resource_start(pci_dev, 0), dev->pci_dev->irq);	if (fs_debug & FS_DEBUG_INIT)		my_hd ((unsigned char *) dev, sizeof (*dev));	undocumented_pci_fix (pci_dev);	dev->hw_base = pci_resource_start(pci_dev, 0);	dev->base = (ulong) ioremap(dev->hw_base, 0x1000);	reset_chip (dev);  	write_fs (dev, SARMODE0, 0 		  | (0 * SARMODE0_SHADEN) /* We don't use shadow registers. */		  | (1 * SARMODE0_INTMODE_READCLEAR)		  | (1 * SARMODE0_CWRE)		  | IS_FS50(dev)?SARMODE0_PRPWT_FS50_5: 		                 SARMODE0_PRPWT_FS155_3		  | (1 * SARMODE0_CALSUP_1)		  | IS_FS50 (dev)?(0				   | SARMODE0_RXVCS_32				   | SARMODE0_ABRVCS_32 				   | SARMODE0_TXVCS_32):		                  (0				   | SARMODE0_RXVCS_1k				   | SARMODE0_ABRVCS_1k 				   | SARMODE0_TXVCS_1k));	/* 10ms * 100 is 1 second. That should be enough, as AN3:9 says it takes	   1ms. */	to = 100;	while (--to) {		isr = read_fs (dev, ISR);		/* This bit is documented as "RESERVED" */		if (isr & ISR_INIT_ERR) {			printk (KERN_ERR "Error initializing the FS... \n");			return 1;		}		if (isr & ISR_INIT) {			fs_dprintk (FS_DEBUG_INIT, "Ha! Initialized OK!\n");			break;		}		/* Try again after 10ms. */		current->state = TASK_UNINTERRUPTIBLE;		schedule_timeout ((HZ+99)/100);	}	if (!to) {		printk (KERN_ERR "timeout initializing the FS... \n");		return 1;	}	/* XXX fix for fs155 */	dev->channel_mask = 0x1f; 	dev->channo = 0;	/* AN3: 10 */	write_fs (dev, SARMODE1, 0 		  | (0 * SARMODE1_DEFHEC) /* XXX PHY */		  | ((loopback == 1) * SARMODE1_TSTLP) /* XXX Loopback mode enable... */		  | (1 * SARMODE1_DCRM)		  | (1 * SARMODE1_DCOAM)		  | (0 * SARMODE1_OAMCRC)		  | (0 * SARMODE1_DUMPE)		  | (0 * SARMODE1_GPLEN) 		  | (0 * SARMODE1_GNAM)		  | (0 * SARMODE1_GVAS)		  | (0 * SARMODE1_GPAS)		  | (1 * SARMODE1_GPRI)		  | (0 * SARMODE1_PMS)		  | (0 * SARMODE1_GFCR)		  | (1 * SARMODE1_HECM2)		  | (1 * SARMODE1_HECM1)		  | (1 * SARMODE1_HECM0)		  | (1 << 12) /* That's what hang's driver does. Program to 0 */		  | (0 * 0xff) /* XXX FS155 */);	/* Cal prescale etc */	/* AN3: 11 */	write_fs (dev, TMCONF, 0x0000000f);	write_fs (dev, CALPRESCALE, 0x01010101 * num);	write_fs (dev, 0x80, 0x000F00E4);	/* AN3: 12 */	write_fs (dev, CELLOSCONF, 0		  | (   0 * CELLOSCONF_CEN)		  | (       CELLOSCONF_SC1)		  | (0x80 * CELLOSCONF_COBS)		  | (num  * CELLOSCONF_COPK)  /* Changed from 0xff to 0x5a */		  | (num  * CELLOSCONF_COST));/* after a hint from Hang. 					       * performance jumped 50->70... */	/* Magic value by Hang */	write_fs (dev, CELLOSCONF_COST, 0x0B809191);	if (IS_FS50 (dev)) {		write_fs (dev, RAS0, RAS0_DCD_XHLT);		dev->atm_dev->ci_range.vpi_bits = 12;		dev->atm_dev->ci_range.vci_bits = 16;		dev->nchannels = FS50_NR_CHANNELS;	} else {		write_fs (dev, RAS0, RAS0_DCD_XHLT 			  | (((1 << FS155_VPI_BITS) - 1) * RAS0_VPSEL)			  | (((1 << FS155_VCI_BITS) - 1) * RAS0_VCSEL));		/* We can chose the split arbitarily. We might be able to 		   support more. Whatever. This should do for now. */		dev->atm_dev->ci_range.vpi_bits = FS155_VPI_BITS;		dev->atm_dev->ci_range.vci_bits = FS155_VCI_BITS;    		/* Address bits we can't use should be compared to 0. */		write_fs (dev, RAC, 0);		/* Manual (AN9, page 6) says ASF1=0 means compare Utopia address		 * too.  I can't find ASF1 anywhere. Anyway, we AND with just hte		 * other bits, then compare with 0, which is exactly what we		 * want. */		write_fs (dev, RAM, (1 << (28 - FS155_VPI_BITS - FS155_VCI_BITS)) - 1);		dev->nchannels = FS155_NR_CHANNELS;	}	dev->atm_vccs = kmalloc (dev->nchannels * sizeof (struct atm_vcc *), 				 GFP_KERNEL);	fs_dprintk (FS_DEBUG_ALLOC, "Alloc atmvccs: %p(%d)\n", 		    dev->atm_vccs, dev->nchannels * sizeof (struct atm_vcc *));	if (!dev->atm_vccs) {		printk (KERN_WARNING "Couldn't allocate memory for VCC buffers. Woops!\n");		/* XXX Clean up..... */		return 1;	}	memset (dev->atm_vccs, 0, dev->nchannels * sizeof (struct atm_vcc *));	dev->tx_inuse = kmalloc (dev->nchannels / 8 /* bits/byte */ , GFP_KERNEL);	fs_dprintk (FS_DEBUG_ALLOC, "Alloc tx_inuse: %p(%d)\n", 		    dev->atm_vccs, dev->nchannels / 8);	if (!dev->tx_inuse) {		printk (KERN_WARNING "Couldn't allocate memory for tx_inuse bits!\n");		/* XXX Clean up..... */		return 1;	}	memset (dev->tx_inuse, 0, dev->nchannels / 8);	/* -- RAS1 : FS155 and 50 differ. Default (0) should be OK for both */	/* -- RAS2 : FS50 only: Default is OK. */	/* DMAMODE, default should be OK. -- REW */	write_fs (dev, DMAMR, DMAMR_TX_MODE_FULL);	init_q (dev, &dev->hp_txq, TX_PQ(TXQ_HP), TXQ_NENTRIES, 0);	init_q (dev, &dev->lp_txq, TX_PQ(TXQ_LP), TXQ_NENTRIES, 0);	init_q (dev, &dev->tx_relq, TXB_RQ, TXQ_NENTRIES, 1);	init_q (dev, &dev->st_q, ST_Q, TXQ_NENTRIES, 1);	for (i=0;i < FS_NR_FREE_POOLS;i++) {		init_fp (dev, &dev->rx_fp[i], RXB_FP(i), 			 rx_buf_sizes[i], rx_pool_sizes[i]);		top_off_fp (dev, &dev->rx_fp[i], GFP_KERNEL);	}	for (i=0;i < FS_NR_RX_QUEUES;i++)		init_q (dev, &dev->rx_rq[i], RXB_RQ(i), RXRQ_NENTRIES, 1);	dev->irq = pci_dev->irq;	if (request_irq (dev->irq, fs_irq, SA_SHIRQ, "firestream", dev)) {		printk (KERN_WARNING "couldn't get irq %d for firestream.\n", pci_dev->irq);		/* XXX undo all previous stuff... */		return 1;	}	fs_dprintk (FS_DEBUG_INIT, "Grabbed irq %d for dev at %p.\n", dev->irq, dev);  	/* We want to be notified of most things. Just the statistics count	   overflows are not interesting */	write_fs (dev, IMR, 0		  | ISR_RBRQ0_W 		  | ISR_RBRQ1_W 		  | ISR_RBRQ2_W 		  | ISR_RBRQ3_W 		  | ISR_TBRQ_W		  | ISR_CSQ_W);	write_fs (dev, SARMODE0, 0 		  | (0 * SARMODE0_SHADEN) /* We don't use shadow registers. */		  | (1 * SARMODE0_GINT)		  | (1 * SARMODE0_INTMODE_READCLEAR)		  | (0 * SARMODE0_CWRE)		  | (IS_FS50(dev)?SARMODE0_PRPWT_FS50_5: 		                  SARMODE0_PRPWT_FS155_3)		  | (1 * SARMODE0_CALSUP_1)		  | (IS_FS50 (dev)?(0				    | SARMODE0_RXVCS_32				    | SARMODE0_ABRVCS_32 				    | SARMODE0_TXVCS_32):		                   (0				    | SARMODE0_RXVCS_1k				    | SARMODE0_ABRVCS_1k 				    | SARMODE0_TXVCS_1k))		  | (1 * SARMODE0_RUN));	init_phy (dev, PHY_NTC_INIT);	if (loopback == 2) {		write_phy (dev, 0x39, 0x000e);	}#ifdef FS_POLL_FREQ	init_timer (&dev->timer);	dev->timer.data = (unsigned long) dev;	dev->timer.function = fs_poll;	dev->timer.expires = jiffies + FS_POLL_FREQ;	add_timer (&dev->timer);#endif	dev->atm_dev->dev_data = dev;  	func_exit ();	return 0;}static int __init firestream_init_one (struct pci_dev *pci_dev,				       const struct pci_device_id *ent) {	struct atm_dev *atm_dev;	struct fs_dev *fs_dev;		if (pci_enable_device(pci_dev)) 		goto err_out;	fs_dev = kmalloc (sizeof (struct fs_dev), GFP_KERNEL);	fs_dprintk (FS_DEBUG_ALLOC, "Alloc fs-dev: %p(%d)\n", 		    fs_dev, sizeof (struct fs_dev));	if (!fs_dev)		goto err_out;	memset (fs_dev, 0, sizeof (struct fs_dev));  	atm_dev = atm_dev_register("fs", &ops, -1, NULL);	if (!atm_dev)		goto err_out_free_fs_dev;  	fs_dev->pci_dev = pci_dev;	fs_dev->atm_dev = atm_dev;	fs_dev->flags = ent->driver_data;	if (fs_init(fs_dev))		goto err_out_free_atm_dev;	fs_dev->next = fs_boards;	fs_boards = fs_dev;	return 0; err_out_free_atm_dev:	atm_dev_deregister(atm_dev); err_out_free_fs_dev:	kfree(fs_dev); err_out:	return -ENODEV;}void __devexit firestream_remove_one (struct pci_dev *pdev){	int i;	struct fs_dev *dev, *nxtdev;	struct fs_vcc *vcc;	struct FS_BPENTRY *fp, *nxt;  	func_enter ();#if 0	printk ("hptxq:\n");	for (i=0;i<60;i++) {		printk ("%d: %08x %08x %08x %08x \n", 			i, pq[qp].cmd, pq[qp].p0, pq[qp].p1, pq[qp].p2);		qp++;		if (qp >= 60) qp = 0;	}	printk ("descriptors:\n");	for (i=0;i<60;i++) {		printk ("%d: %p: %08x %08x %p %p\n", 			i, da[qd], dq[qd].flags, dq[qd].bsa, dq[qd].skb, dq[qd].dev);		qd++;		if (qd >= 60) qd = 0;	}#endif	for (dev = fs_boards;dev != NULL;dev=nxtdev) {		fs_dprintk (FS_DEBUG_CLEANUP, "Releasing resources for dev at %p.\n", dev);		/* XXX Hit all the tx channels too! */		for (i=0;i < dev->nchannels;i++) {			if (dev->atm_vccs[i]) {				vcc = FS_VCC (dev->atm_vccs[i]);				submit_command (dev,  &dev->hp_txq,						QE_CMD_TX_PURGE_INH | QE_CMD_IMM_INQ | vcc->channo, 0,0,0);				submit_command (dev,  &dev->hp_txq,						QE_CMD_RX_PURGE_INH | QE_CMD_IMM_INQ | vcc->channo, 0,0,0);			}		}		/* XXX Wait a while for the chip to release all buffers. */		for (i=0;i < FS_NR_FREE_POOLS;i++) {			for (fp=bus_to_virt (read_fs (dev, FP_SA(dev->rx_fp[i].offset)));			     !(fp->flags & FP_FLAGS_EPI);fp = nxt) {				fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p\n", fp->skb);				dev_kfree_skb_any (fp->skb);				nxt = bus_to_virt (fp->next);				fs_dprintk (FS_DEBUG_ALLOC, "Free rec-d: %p\n", fp);				kfree (fp);			}			fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p\n", fp->skb);			dev_kfree_skb_any (fp->skb);			fs_dprintk (FS_DEBUG_ALLOC, "Free rec-d: %p\n", fp);			kfree (fp);		}		/* Hang the chip in "reset", prevent it clobbering memory that is		   no longer ours. */		reset_chip (dev);		fs_dprintk (FS_DEBUG_CLEANUP, "Freeing irq%d.\n", dev->irq);		free_irq (dev->irq, dev);		del_timer (&dev->timer);		atm_dev_deregister(dev->atm_dev);		free_queue (dev, &dev->hp_txq);		free_queue (dev, &dev->lp_txq);		free_queue (dev, &dev->tx_relq);		free_queue (dev, &dev->st_q);		fs_dprintk (FS_DEBUG_ALLOC, "Free atmvccs: %p\n", dev->atm_vccs);		kfree (dev->atm_vccs);		for (i=0;i< FS_NR_FREE_POOLS;i++)			free_freepool (dev, &dev->rx_fp[i]);    		for (i=0;i < FS_NR_RX_QUEUES;i++)			free_queue (dev, &dev->rx_rq[i]);		fs_dprintk (FS_DEBUG_ALLOC, "Free fs-dev: %p\n", dev);		nxtdev = dev->next;		kfree (dev);	}	func_exit ();}#if 0int __init fs_detect(void){	struct pci_dev  *pci_dev;	int devs = 0;	func_enter ();	pci_dev = NULL;	while ((pci_dev = pci_find_device(PCI_VENDOR_ID_FUJITSU_ME,					  PCI_DEVICE_ID_FUJITSU_FS50, 					  pci_dev))) {		if (fs_register_and_init (pci_dev, &fs_pci_tbl[0]))			break;		devs++;	}	while ((pci_dev = pci_find_device(PCI_VENDOR_ID_FUJITSU_ME,					  PCI_DEVICE_ID_FUJITSU_FS155, 					  pci_dev))) {		if (fs_register_and_init (pci_dev, FS_IS155)) 			break;		devs++;	}	func_exit ();	return devs;}#else#if 0int __init init_PCI (void){ /* Begin init_PCI */		int pci_count;	printk ("init_PCI\n");	/*	  memset (&firestream_driver, 0, sizeof (firestream_driver));	  firestream_driver.name = "firestream";	  firestream_driver.id_table = firestream_pci_tbl;	  firestream_driver.probe = fs_register_and_init;	*/	pci_count = pci_register_driver (&firestream_driver);		if (pci_count <= 0) {		pci_unregister_driver (&firestream_driver);		pci_count = 0;	}	return(pci_count);} /* End init_PCI */#endif#endif/*#ifdef MODULE#define firestream_init init_module#endif */const static struct pci_device_id firestream_pci_tbl[] __devinitdata = {	{ PCI_VENDOR_ID_FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS50, 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, FS_IS50},	{ PCI_VENDOR_ID_FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS155, 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, FS_IS155},	{ 0, }};MODULE_DEVICE_TABLE(pci, firestream_pci_tbl);static struct pci_driver firestream_driver = {	name:           "firestream",	id_table:       firestream_pci_tbl,	probe:          firestream_init_one,	remove:         firestream_remove_one,};static int __init firestream_init_module (void){	int error;	func_enter ();	error = pci_module_init(&firestream_driver);	func_exit ();	return error;}static void __exit firestream_cleanup_module(void){	pci_unregister_driver(&firestream_driver);}module_init(firestream_init_module);module_exit(firestream_cleanup_module);

⌨️ 快捷键说明

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