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

📄 parport_pc.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
static int __devinit parport_ECPEPP_supported(struct parport *pb){	struct parport_pc_private *priv = pb->private_data;	int result;	unsigned char oecr;	if (!priv->ecr) {		return 0;	}	oecr = inb (ECONTROL (pb));	/* Search for SMC style EPP+ECP mode */	ECR_WRITE (pb, 0x80);	outb (0x04, CONTROL (pb));	result = parport_EPP_supported(pb);	ECR_WRITE (pb, oecr);	if (result) {		/* Set up access functions to use ECP+EPP hardware. */		pb->ops->epp_read_data = parport_pc_ecpepp_read_data;		pb->ops->epp_write_data = parport_pc_ecpepp_write_data;		pb->ops->epp_read_addr = parport_pc_ecpepp_read_addr;		pb->ops->epp_write_addr = parport_pc_ecpepp_write_addr;	}	return result;}#else /* No IEEE 1284 support *//* Don't bother probing for modes we know we won't use. */static int __devinit parport_PS2_supported(struct parport *pb) { return 0; }#ifdef CONFIG_PARPORT_PC_FIFOstatic int __devinit parport_ECP_supported(struct parport *pb) { return 0; }#endifstatic int __devinit parport_EPP_supported(struct parport *pb) { return 0; }static int __devinit parport_ECPEPP_supported(struct parport *pb){return 0;}static int __devinit parport_ECPPS2_supported(struct parport *pb){return 0;}#endif /* No IEEE 1284 support *//* --- IRQ detection -------------------------------------- *//* Only if supports ECP mode */static int __devinit programmable_irq_support(struct parport *pb){	int irq, intrLine;	unsigned char oecr = inb (ECONTROL (pb));	static const int lookup[8] = {		PARPORT_IRQ_NONE, 7, 9, 10, 11, 14, 15, 5	};	ECR_WRITE (pb, ECR_CNF << 5); /* Configuration MODE */	intrLine = (inb (CONFIGB (pb)) >> 3) & 0x07;	irq = lookup[intrLine];	ECR_WRITE (pb, oecr);	return irq;}static int __devinit irq_probe_ECP(struct parport *pb){	int i;	unsigned long irqs;	sti();	irqs = probe_irq_on();			ECR_WRITE (pb, ECR_SPP << 5); /* Reset FIFO */	ECR_WRITE (pb, (ECR_TST << 5) | 0x04);	ECR_WRITE (pb, ECR_TST << 5);	/* If Full FIFO sure that writeIntrThreshold is generated */	for (i=0; i < 1024 && !(inb (ECONTROL (pb)) & 0x02) ; i++) 		outb (0xaa, FIFO (pb));			pb->irq = probe_irq_off(irqs);	ECR_WRITE (pb, ECR_SPP << 5);	if (pb->irq <= 0)		pb->irq = PARPORT_IRQ_NONE;	return pb->irq;}/* * This detection seems that only works in National Semiconductors * This doesn't work in SMC, LGS, and Winbond  */static int __devinit irq_probe_EPP(struct parport *pb){#ifndef ADVANCED_DETECT	return PARPORT_IRQ_NONE;#else	int irqs;	unsigned char oecr;	if (pb->modes & PARPORT_MODE_PCECR)		oecr = inb (ECONTROL (pb));	sti();	irqs = probe_irq_on();	if (pb->modes & PARPORT_MODE_PCECR)		frob_econtrol (pb, 0x10, 0x10);		clear_epp_timeout(pb);	parport_pc_frob_control (pb, 0x20, 0x20);	parport_pc_frob_control (pb, 0x10, 0x10);	clear_epp_timeout(pb);	/* Device isn't expecting an EPP read	 * and generates an IRQ.	 */	parport_pc_read_epp(pb);	udelay(20);	pb->irq = probe_irq_off (irqs);	if (pb->modes & PARPORT_MODE_PCECR)		ECR_WRITE (pb, oecr);	parport_pc_write_control(pb, 0xc);	if (pb->irq <= 0)		pb->irq = PARPORT_IRQ_NONE;	return pb->irq;#endif /* Advanced detection */}static int __devinit irq_probe_SPP(struct parport *pb){	/* Don't even try to do this. */	return PARPORT_IRQ_NONE;}/* We will attempt to share interrupt requests since other devices * such as sound cards and network cards seem to like using the * printer IRQs. * * When ECP is available we can autoprobe for IRQs. * NOTE: If we can autoprobe it, we can register the IRQ. */static int __devinit parport_irq_probe(struct parport *pb){	struct parport_pc_private *priv = pb->private_data;	priv->ctr_writable |= 0x10;	if (priv->ecr) {		pb->irq = programmable_irq_support(pb);		if (pb->irq == PARPORT_IRQ_NONE)			pb->irq = irq_probe_ECP(pb);	}	if ((pb->irq == PARPORT_IRQ_NONE) && priv->ecr &&	    (pb->modes & PARPORT_MODE_EPP))		pb->irq = irq_probe_EPP(pb);	clear_epp_timeout(pb);	if (pb->irq == PARPORT_IRQ_NONE && (pb->modes & PARPORT_MODE_EPP))		pb->irq = irq_probe_EPP(pb);	clear_epp_timeout(pb);	if (pb->irq == PARPORT_IRQ_NONE)		pb->irq = irq_probe_SPP(pb);	if (pb->irq == PARPORT_IRQ_NONE)		pb->irq = get_superio_irq(pb);	if (pb->irq == PARPORT_IRQ_NONE)		priv->ctr_writable &= ~0x10;	return pb->irq;}/* --- DMA detection -------------------------------------- *//* Only if chipset conforms to ECP ISA Interface Standard */static int __devinit programmable_dma_support (struct parport *p){	unsigned char oecr = inb (ECONTROL (p));	int dma;	frob_set_mode (p, ECR_CNF);		dma = inb (CONFIGB(p)) & 0x07;	/* 000: Indicates jumpered 8-bit DMA if read-only.	   100: Indicates jumpered 16-bit DMA if read-only. */	if ((dma & 0x03) == 0)		dma = PARPORT_DMA_NONE;	ECR_WRITE (p, oecr);	return dma;}static int __devinit parport_dma_probe (struct parport *p){	const struct parport_pc_private *priv = p->private_data;	if (priv->ecr)		p->dma = programmable_dma_support(p); /* ask ECP chipset first */	if (p->dma == PARPORT_DMA_NONE) {		/* ask known Super-IO chips proper, although these		   claim ECP compatible, some don't report their DMA		   conforming to ECP standards */		p->dma = get_superio_dma(p);	}	return p->dma;}/* --- Initialisation code -------------------------------- */struct parport *parport_pc_probe_port (unsigned long int base,				       unsigned long int base_hi,				       int irq, int dma,				       struct pci_dev *dev){	struct parport_pc_private *priv;	struct parport_operations *ops;	struct parport tmp;	struct parport *p = &tmp;	int probedirq = PARPORT_IRQ_NONE;	if (check_region(base, 3)) return NULL;	priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL);	if (!priv) {		printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base);		return NULL;	}	ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);	if (!ops) {		printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n",			base);		kfree (priv);		return NULL;	}	memcpy (ops, &parport_pc_ops, sizeof (struct parport_operations));	priv->ctr = 0xc;	priv->ctr_writable = ~0x10;	priv->ecr = 0;	priv->fifo_depth = 0;	priv->dma_buf = 0;	priv->dma_handle = 0;	priv->dev = dev;	p->base = base;	p->base_hi = base_hi;	p->irq = irq;	p->dma = dma;	p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT;	p->ops = ops;	p->private_data = priv;	p->physport = p;	if (base_hi && !check_region(base_hi,3))		parport_ECR_present(p);	if (base != 0x3bc) {		if (!check_region(base+0x3, 5)) {			if (!parport_EPP_supported(p))				parport_ECPEPP_supported(p);		}	}	if (!parport_SPP_supported (p)) {		/* No port. */		kfree (priv);		kfree (ops);		return NULL;	}	if (priv->ecr)		parport_ECPPS2_supported(p);	else		parport_PS2_supported (p);	if (!(p = parport_register_port(base, PARPORT_IRQ_NONE,					PARPORT_DMA_NONE, ops))) {		kfree (priv);		kfree (ops);		return NULL;	}	p->base_hi = base_hi;	p->modes = tmp.modes;	p->size = (p->modes & PARPORT_MODE_EPP)?8:3;	p->private_data = priv;	printk(KERN_INFO "%s: PC-style at 0x%lx", p->name, p->base);	if (p->base_hi && priv->ecr)		printk(" (0x%lx)", p->base_hi);	p->irq = irq;	p->dma = dma;	if (p->irq == PARPORT_IRQ_AUTO) {		p->irq = PARPORT_IRQ_NONE;		parport_irq_probe(p);	} else if (p->irq == PARPORT_IRQ_PROBEONLY) {		p->irq = PARPORT_IRQ_NONE;		parport_irq_probe(p);		probedirq = p->irq;		p->irq = PARPORT_IRQ_NONE;	}	if (p->irq != PARPORT_IRQ_NONE) {		printk(", irq %d", p->irq);		if (p->dma == PARPORT_DMA_AUTO) {			p->dma = PARPORT_DMA_NONE;			parport_dma_probe(p);		}	}	if (p->dma == PARPORT_DMA_AUTO) /* To use DMA, giving the irq                                           is mandatory (see above) */		p->dma = PARPORT_DMA_NONE;#ifdef CONFIG_PARPORT_PC_FIFO	if (parport_ECP_supported(p) &&	    p->dma != PARPORT_DMA_NOFIFO &&	    priv->fifo_depth > 0 && p->irq != PARPORT_IRQ_NONE) {		p->modes |= PARPORT_MODE_ECP | PARPORT_MODE_COMPAT;		p->ops->compat_write_data = parport_pc_compat_write_block_pio;#ifdef CONFIG_PARPORT_1284		p->ops->ecp_write_data = parport_pc_ecp_write_block_pio;		/* currently broken, but working on it.. (FB) */		/* p->ops->ecp_read_data = parport_pc_ecp_read_block_pio; */#endif /* IEEE 1284 support */		if (p->dma != PARPORT_DMA_NONE) {			printk(", dma %d", p->dma);			p->modes |= PARPORT_MODE_DMA;		}		else printk(", using FIFO");	}	else		/* We can't use the DMA channel after all. */		p->dma = PARPORT_DMA_NONE;#endif /* Allowed to use FIFO/DMA */	printk(" [");#define printmode(x) {if(p->modes&PARPORT_MODE_##x){printk("%s%s",f?",":"",#x);f++;}}	{		int f = 0;		printmode(PCSPP);		printmode(TRISTATE);		printmode(COMPAT)		printmode(EPP);		printmode(ECP);		printmode(DMA);	}#undef printmode#ifndef CONFIG_PARPORT_1284	printk ("(,...)");#endif /* CONFIG_PARPORT_1284 */	printk("]\n");	if (probedirq != PARPORT_IRQ_NONE) 		printk(KERN_INFO "%s: irq %d detected\n", p->name, probedirq);	parport_proc_register(p);	request_region (p->base, 3, p->name);	if (p->size > 3)		request_region (p->base + 3, p->size - 3, p->name);	if (p->modes & PARPORT_MODE_ECP)		request_region (p->base_hi, 3, p->name);	if (p->irq != PARPORT_IRQ_NONE) {		if (request_irq (p->irq, parport_pc_interrupt,				 0, p->name, p)) {			printk (KERN_WARNING "%s: irq %d in use, "				"resorting to polled operation\n",				p->name, p->irq);			p->irq = PARPORT_IRQ_NONE;			p->dma = PARPORT_DMA_NONE;		}#ifdef CONFIG_PARPORT_PC_FIFO		if (p->dma != PARPORT_DMA_NONE) {			if (request_dma (p->dma, p->name)) {				printk (KERN_WARNING "%s: dma %d in use, "					"resorting to PIO operation\n",					p->name, p->dma);				p->dma = PARPORT_DMA_NONE;			} else {				priv->dma_buf =				  pci_alloc_consistent(priv->dev,						       PAGE_SIZE,						       &priv->dma_handle);				if (! priv->dma_buf) {					printk (KERN_WARNING "%s: "						"cannot get buffer for DMA, "						"resorting to PIO operation\n",						p->name);					free_dma(p->dma);					p->dma = PARPORT_DMA_NONE;				}			}		}#endif /* CONFIG_PARPORT_PC_FIFO */	}	/* Done probing.  Now put the port into a sensible start-up state. */	if (priv->ecr)		/*		 * Put the ECP detected port in PS2 mode.		 * Do this also for ports that have ECR but don't do ECP.		 */		ECR_WRITE (p, 0x34);	parport_pc_write_data(p, 0);	parport_pc_data_forward (p);	/* Now that we've told the sharing engine about the port, and	   found out its characteristics, let the high-level drivers	   know about it. */	parport_announce_port (p);	return p;}void parport_pc_unregister_port (struct parport *p){	struct parport_pc_private *priv = p->private_data;	struct parport_operations *ops = p->ops;	if (p->dma != PARPORT_DMA_NONE)		free_dma(p->dma);	if (p->irq != PARPORT_IRQ_NONE)		free_irq(p->irq, p);	release_region(p->base, 3);	if (p->size > 3)		release_region(p->base + 3, p->size - 3);	if (p->modes & PARPORT_MODE_ECP)		release_region(p->base_hi, 3);	parport_proc_unregister(p);	if (priv->dma_buf)		pci_free_consistent(priv->dev, PAGE_SIZE,				    priv->dma_buf,				    priv->dma_handle);	kfree (p->private_data);	parport_unregister_port(p);	kfree (ops); /* hope no-one cached it */}#ifdef CONFIG_PCI/* ITE support maintained by Rich Liu <richliu@poorman.org> */static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq,					 int autodma){	short inta_addr[6] = { 0x2A0, 0x2C0, 0x220, 0x240, 0x1E0 };	u32 ite8872set;	u32 ite8872_lpt, ite8872_lpthi;	u8 ite8872_irq, type;	int irq;	int i;	DPRINTK (KERN_DEBUG "sio_ite_8872_probe()\n");		// make sure which one chip	for(i = 0; i < 5; i++) {		if (check_region (inta_addr[i], 0x8) >= 0) {			int test;			pci_write_config_dword (pdev, 0x60,						0xe7000000 | inta_addr[i]);			pci_write_config_dword (pdev, 0x78,						0x00000000 | inta_addr[i]);			test = inb (inta_addr[i]);			if (test != 0xff) break;		}	}	if(i >= 5) {		printk (KERN_INFO "parport_pc: cannot find ITE8872 INTA\n");		return 0;	}	type = inb (inta_addr[i] + 0x18);	type &= 0x0f;	switch (type) {	case 0x2:		printk (KERN_INFO "parport_pc: ITE8871 found (1P)\n");		ite8872set = 0x64200000;		break;	case 0xa:		printk (KERN_INFO "parport_pc: ITE8875 found (1P)\n");		ite8872set = 0x64200000;		break;	case 0xe:		printk (KERN_INFO "parport_pc: ITE8872 found (2S1P)\n");		ite8872set = 0x64e00000;		break;	case 0x6:		printk (KERN_INFO "parport_pc: ITE8873 found (1S)\n");		return 0;	case 0x8:		DPRINTK (KERN_DEBUG "parport_pc: ITE8874 found (2S)\n");		return 0;	default:		printk (KERN_INFO "parport_pc: unkn

⌨️ 快捷键说明

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