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

📄 hisax_fcpcipnp.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	 */	bcs->ctrl.sr.xml = 0;	bcs->ctrl.sr.cmd |= HDLC_CMD_XRS;	adapter->write_ctrl(bcs, 1);	bcs->ctrl.sr.cmd &= ~HDLC_CMD_XRS;	adapter->write_ctrl(bcs, 1);	if (!bcs->tx_skb) {		DBG(0x10, "XDU without skb");		return;	}	skb_push(bcs->tx_skb, bcs->tx_cnt);	bcs->tx_cnt = 0;}static inline void hdlc_xpr_irq(struct fritz_bcs *bcs){	struct sk_buff *skb;	skb = bcs->tx_skb;	if (!skb)		return;	if (skb->len) {		hdlc_fill_fifo(bcs);		return;	}	bcs->tx_cnt = 0;	bcs->tx_skb = NULL;	B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize);	dev_kfree_skb_irq(skb);}static void hdlc_irq_one(struct fritz_bcs *bcs, u32 stat){	DBG(0x10, "ch%d stat %#x", bcs->channel, stat);	if (stat & HDLC_INT_RPR) {		DBG(0x10, "RPR");		hdlc_rpr_irq(bcs, stat);	}	if (stat & HDLC_INT_XDU) {		DBG(0x10, "XDU");		hdlc_xdu_irq(bcs);	}	if (stat & HDLC_INT_XPR) {		DBG(0x10, "XPR");		hdlc_xpr_irq(bcs);	}}static inline void hdlc_irq(struct fritz_adapter *adapter){	int nr;	u32 stat;	for (nr = 0; nr < 2; nr++) {		stat = adapter->read_hdlc_status(adapter, nr);		DBG(0x10, "HDLC %c stat %#x", 'A' + nr, stat);		if (stat & HDLC_INT_MASK)			hdlc_irq_one(&adapter->bcs[nr], stat);	}}static void modehdlc(struct fritz_bcs *bcs, int mode){	struct fritz_adapter *adapter = bcs->adapter;		DBG(0x40, "hdlc %c mode %d --> %d",	    'A' + bcs->channel, bcs->mode, mode);	if (bcs->mode == mode)		return;	bcs->ctrl.ctrl = 0;	bcs->ctrl.sr.cmd  = HDLC_CMD_XRS | HDLC_CMD_RRS;	switch (mode) {	case L1_MODE_NULL:		bcs->ctrl.sr.mode = HDLC_MODE_TRANS;		adapter->write_ctrl(bcs, 5);		break;	case L1_MODE_TRANS:	case L1_MODE_HDLC:		bcs->rcvidx = 0;		bcs->tx_cnt = 0;		bcs->tx_skb = NULL;		if (mode == L1_MODE_TRANS)			bcs->ctrl.sr.mode = HDLC_MODE_TRANS;		else			bcs->ctrl.sr.mode = HDLC_MODE_ITF_FLG;		adapter->write_ctrl(bcs, 5);		bcs->ctrl.sr.cmd = HDLC_CMD_XRS;		adapter->write_ctrl(bcs, 1);		bcs->ctrl.sr.cmd = 0;		break;	}	bcs->mode = mode;}static void fritz_b_l2l1(struct hisax_if *ifc, int pr, void *arg){	struct fritz_bcs *bcs = ifc->priv;	struct sk_buff *skb = arg;	int mode;	DBG(0x10, "pr %#x", pr);	switch (pr) {	case PH_DATA | REQUEST:		if (bcs->tx_skb)			BUG();				bcs->tx_skb = skb;		DBG_SKB(1, skb);		hdlc_fill_fifo(bcs);		break;	case PH_ACTIVATE | REQUEST:		mode = (int) arg;		DBG(4,"B%d,PH_ACTIVATE_REQUEST %d", bcs->channel + 1, mode);		modehdlc(bcs, mode);		B_L1L2(bcs, PH_ACTIVATE | INDICATION, NULL);		break;	case PH_DEACTIVATE | REQUEST:		DBG(4,"B%d,PH_DEACTIVATE_REQUEST", bcs->channel + 1);		modehdlc(bcs, L1_MODE_NULL);		B_L1L2(bcs, PH_DEACTIVATE | INDICATION, NULL);		break;	}}// ----------------------------------------------------------------------static void fcpci2_irq(int intno, void *dev, struct pt_regs *regs){	struct fritz_adapter *adapter = dev;	unsigned char val;	val = inb(adapter->io + AVM_STATUS0);	if (!(val & AVM_STATUS0_IRQ_MASK))		/* hopefully a shared  IRQ reqest */		return;	DBG(2, "STATUS0 %#x", val);	if (val & AVM_STATUS0_IRQ_ISAC)		isacsx_irq(&adapter->isac);	if (val & AVM_STATUS0_IRQ_HDLC)		hdlc_irq(adapter);}static void fcpci_irq(int intno, void *dev, struct pt_regs *regs){	struct fritz_adapter *adapter = dev;	unsigned char sval;	sval = inb(adapter->io + 2);	if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK)		/* possibly a shared  IRQ reqest */		return;	DBG(2, "sval %#x", sval);	if (!(sval & AVM_STATUS0_IRQ_ISAC))		isac_irq(&adapter->isac);	if (!(sval & AVM_STATUS0_IRQ_HDLC))		hdlc_irq(adapter);}// ----------------------------------------------------------------------static inline void fcpci2_init(struct fritz_adapter *adapter){	outb(AVM_STATUS0_RES_TIMER, adapter->io + AVM_STATUS0);	outb(AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);}static inline void fcpci_init(struct fritz_adapter *adapter){	outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | 	     AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);	outb(AVM_STATUS1_ENA_IOM | adapter->irq, 	     adapter->io + AVM_STATUS1);	set_current_state(TASK_UNINTERRUPTIBLE);	schedule_timeout(50*HZ / 1000); /* Timeout 50ms */}// ----------------------------------------------------------------------static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter){	u32 val = 0;	int retval;	DBG(1,"");	isac_init(&adapter->isac); // FIXME is this okay now	retval = -EBUSY;	if (!request_region(adapter->io, 32, "fcpcipnp"))		goto err;	switch (adapter->type) {	case AVM_FRITZ_PCIV2:		retval = request_irq(adapter->irq, fcpci2_irq, SA_SHIRQ, 				     "fcpcipnp", adapter);		break;	case AVM_FRITZ_PCI:		retval = request_irq(adapter->irq, fcpci_irq, SA_SHIRQ,				     "fcpcipnp", adapter);		break;	case AVM_FRITZ_PNP:		retval = request_irq(adapter->irq, fcpci_irq, 0,				     "fcpcipnp", adapter);		break;	}	if (retval)		goto err_region;	switch (adapter->type) {	case AVM_FRITZ_PCIV2:	case AVM_FRITZ_PCI:		val = inl(adapter->io);		break;	case AVM_FRITZ_PNP:		val = inb(adapter->io);		val |= inb(adapter->io + 1) << 8;		break;	}	DBG(1, "stat %#x Class %X Rev %d",	    val, val & 0xff, (val>>8) & 0xff);	spin_lock_init(&adapter->hw_lock);	adapter->isac.priv = adapter;	switch (adapter->type) {	case AVM_FRITZ_PCIV2:		adapter->isac.read_isac       = &fcpci2_read_isac;;		adapter->isac.write_isac      = &fcpci2_write_isac;		adapter->isac.read_isac_fifo  = &fcpci2_read_isac_fifo;		adapter->isac.write_isac_fifo = &fcpci2_write_isac_fifo;		adapter->read_hdlc_status     = &fcpci2_read_hdlc_status;		adapter->write_ctrl           = &fcpci2_write_ctrl;		break;	case AVM_FRITZ_PCI:		adapter->isac.read_isac       = &fcpci_read_isac;;		adapter->isac.write_isac      = &fcpci_write_isac;		adapter->isac.read_isac_fifo  = &fcpci_read_isac_fifo;		adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;		adapter->read_hdlc_status     = &fcpci_read_hdlc_status;		adapter->write_ctrl           = &fcpci_write_ctrl;		break;	case AVM_FRITZ_PNP:		adapter->isac.read_isac       = &fcpci_read_isac;;		adapter->isac.write_isac      = &fcpci_write_isac;		adapter->isac.read_isac_fifo  = &fcpci_read_isac_fifo;		adapter->isac.write_isac_fifo = &fcpci_write_isac_fifo;		adapter->read_hdlc_status     = &fcpnp_read_hdlc_status;		adapter->write_ctrl           = &fcpnp_write_ctrl;		break;	}	// Reset	outb(0, adapter->io + AVM_STATUS0);	set_current_state(TASK_UNINTERRUPTIBLE);	schedule_timeout(50 * HZ / 1000); // 50 msec	outb(AVM_STATUS0_RESET, adapter->io + AVM_STATUS0);	set_current_state(TASK_UNINTERRUPTIBLE);	schedule_timeout(50 * HZ / 1000); // 50 msec	outb(0, adapter->io + AVM_STATUS0);	set_current_state(TASK_UNINTERRUPTIBLE);	schedule_timeout(10 * HZ / 1000); // 10 msec	switch (adapter->type) {	case AVM_FRITZ_PCIV2:		fcpci2_init(adapter);		isacsx_setup(&adapter->isac);		break;	case AVM_FRITZ_PCI:	case AVM_FRITZ_PNP:		fcpci_init(adapter);		isac_setup(&adapter->isac);		break;	}	val = adapter->read_hdlc_status(adapter, 0);	DBG(0x20, "HDLC A STA %x", val);	val = adapter->read_hdlc_status(adapter, 1);	DBG(0x20, "HDLC B STA %x", val);	adapter->bcs[0].mode = -1;	adapter->bcs[1].mode = -1;	modehdlc(&adapter->bcs[0], L1_MODE_NULL);	modehdlc(&adapter->bcs[1], L1_MODE_NULL);	return 0; err_region:	release_region(adapter->io, 32); err:	return retval;}static void __devexit fcpcipnp_release(struct fritz_adapter *adapter){	DBG(1,"");	outb(0, adapter->io + AVM_STATUS0);	free_irq(adapter->irq, adapter);	release_region(adapter->io, 32);}// ----------------------------------------------------------------------static struct fritz_adapter * __devinit new_adapter(struct pci_dev *pdev){	struct fritz_adapter *adapter;	struct hisax_b_if *b_if[2];	int i;	adapter = kmalloc(sizeof(struct fritz_adapter), GFP_KERNEL);	if (!adapter)		return NULL;	memset(adapter, 0, sizeof(struct fritz_adapter));	SET_MODULE_OWNER(&adapter->isac.hisax_d_if);	adapter->isac.hisax_d_if.ifc.priv = &adapter->isac;	adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1;		for (i = 0; i < 2; i++) {		adapter->bcs[i].adapter = adapter;		adapter->bcs[i].channel = i;		adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i];		adapter->bcs[i].b_if.ifc.l2l1 = fritz_b_l2l1;	}	pci_set_drvdata(pdev, adapter);	for (i = 0; i < 2; i++)		b_if[i] = &adapter->bcs[i].b_if;	hisax_register(&adapter->isac.hisax_d_if, b_if, "fcpcipnp", protocol);	return adapter;}static void delete_adapter(struct fritz_adapter *adapter){	hisax_unregister(&adapter->isac.hisax_d_if);	kfree(adapter);}static int __devinit fcpci_probe(struct pci_dev *pdev,				 const struct pci_device_id *ent){	struct fritz_adapter *adapter;	int retval;	retval = -ENOMEM;	adapter = new_adapter(pdev);	if (!adapter)		goto err;	if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2) 		adapter->type = AVM_FRITZ_PCIV2;	else		adapter->type = AVM_FRITZ_PCI;	retval = pci_enable_device(pdev);	if (retval)		goto err_free;	adapter->io = pci_resource_start(pdev, 1);	adapter->irq = pdev->irq;	printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at %s\n",	       (char *) ent->driver_data, pdev->slot_name);	retval = fcpcipnp_setup(adapter);	if (retval)		goto err_free;	return 0;	 err_free:	delete_adapter(adapter); err:	return retval;}static int __devinit fcpnp_probe(struct pci_dev *pdev,				 const struct isapnp_device_id *ent){	struct fritz_adapter *adapter;	int retval;	retval = -ENOMEM;	adapter = new_adapter(pdev);	if (!adapter)		goto err;	adapter->type = AVM_FRITZ_PNP;	pdev->prepare(pdev);	pdev->deactivate(pdev); // why?	pdev->activate(pdev);	adapter->io = pdev->resource[0].start;	adapter->irq = pdev->irq_resource[0].start;	printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at IO %#x irq %d\n",	       (char *) ent->driver_data, adapter->io, adapter->irq);	retval = fcpcipnp_setup(adapter);	if (retval)		goto err_free;	return 0;	 err_free:	delete_adapter(adapter); err:	return retval;}static void __devexit fcpci_remove(struct pci_dev *pdev){	struct fritz_adapter *adapter = pci_get_drvdata(pdev);	fcpcipnp_release(adapter);	pci_disable_device(pdev);	delete_adapter(adapter);}static void __devexit fcpnp_remove(struct pci_dev *pdev){	struct fritz_adapter *adapter = pci_get_drvdata(pdev);	fcpcipnp_release(adapter);	pdev->deactivate(pdev);	delete_adapter(adapter);}static struct pci_driver fcpci_driver = {	name:     "fcpci",	probe:    fcpci_probe,	remove:   __devexit_p(fcpci_remove),	id_table: fcpci_ids,};static struct isapnp_driver fcpnp_driver = {	name:     "fcpnp",	probe:    fcpnp_probe,	remove:   __devexit_p(fcpnp_remove),	id_table: fcpnp_ids,};static int __init hisax_fcpcipnp_init(void){	int retval, pci_nr_found;	printk(KERN_INFO "hisax_fcpcipnp: Fritz!Card PCI/PCIv2/PnP ISDN driver v0.0.1\n");	retval = pci_register_driver(&fcpci_driver);	if (retval < 0)		goto out;	pci_nr_found = retval;	retval = isapnp_register_driver(&fcpnp_driver);	if (retval < 0)		goto out_unregister_pci;#if !defined(CONFIG_HOTPLUG) || defined(MODULE)	if (pci_nr_found + retval == 0) {		retval = -ENODEV;		goto out_unregister_isapnp;	}#endif	return 0;#if !defined(CONFIG_HOTPLUG) || defined(MODULE) out_unregister_isapnp:	isapnp_unregister_driver(&fcpnp_driver);#endif out_unregister_pci:	pci_unregister_driver(&fcpci_driver); out:	return retval;}static void __exit hisax_fcpcipnp_exit(void){	isapnp_unregister_driver(&fcpnp_driver);	pci_unregister_driver(&fcpci_driver);}module_init(hisax_fcpcipnp_init);module_exit(hisax_fcpcipnp_exit);

⌨️ 快捷键说明

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