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

📄 parport_pc.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
			"%s: BUSY timeout (%d) in ecp_write_block_pio\n",			port->name, r);	port->physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE;	return written;}size_t parport_pc_ecp_read_block_pio (struct parport *port,				      void *buf, size_t length, int flags){	size_t left = length;	size_t fifofull;	int r;	const int fifo = FIFO(port);	const struct parport_pc_private *priv = port->physport->private_data;	const int fifo_depth = priv->fifo_depth;	char *bufp = buf;	port = port->physport;DPRINTK (KERN_DEBUG "parport_pc: parport_pc_ecp_read_block_pio\n");dump_parport_state ("enter fcn", port);	/* Special case: a timeout of zero means we cannot call schedule(). */	if (!port->cad->timeout)		return parport_ieee1284_ecp_read_data (port, buf,						       length, flags);	if (port->ieee1284.mode == IEEE1284_MODE_ECPRLE) {		/* If the peripheral is allowed to send RLE compressed		 * data, it is possible for a byte to expand to 128		 * bytes in the FIFO. */		fifofull = 128;	} else {		fifofull = fifo_depth;	}	/* If the caller wants less than a full FIFO's worth of data,	 * go through software emulation.  Otherwise we may have to throw	 * away data. */	if (length < fifofull)		return parport_ieee1284_ecp_read_data (port, buf,						       length, flags);	if (port->ieee1284.phase != IEEE1284_PH_REV_IDLE) {		/* change to reverse-idle phase (must be in forward-idle) */		/* Event 38: Set nAutoFd low (also make sure nStrobe is high) */		parport_frob_control (port,				      PARPORT_CONTROL_AUTOFD				      | PARPORT_CONTROL_STROBE,				      PARPORT_CONTROL_AUTOFD);		parport_pc_data_reverse (port); /* Must be in PS2 mode */		udelay (5);		/* Event 39: Set nInit low to initiate bus reversal */		parport_frob_control (port,				      PARPORT_CONTROL_INIT,				      0);		/* Event 40: Wait for  nAckReverse (PError) to go low */		r = parport_wait_peripheral (port, PARPORT_STATUS_PAPEROUT, 0);                if (r) {                        printk (KERN_DEBUG "%s: PE timeout Event 40 (%d) "				"in ecp_read_block_pio\n", port->name, r);			return 0;		}	}	/* Set up ECP FIFO mode.*//*	parport_pc_frob_control (port,				 PARPORT_CONTROL_STROBE |				 PARPORT_CONTROL_AUTOFD,				 PARPORT_CONTROL_AUTOFD); */	r = change_mode (port, ECR_ECP); /* ECP FIFO */	if (r) printk (KERN_DEBUG "%s: Warning change_mode ECR_ECP failed\n", port->name);	port->ieee1284.phase = IEEE1284_PH_REV_DATA;	/* the first byte must be collected manually */dump_parport_state ("pre 43", port);	/* Event 43: Wait for nAck to go low */	r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, 0);	if (r) {		/* timed out while reading -- no data */		printk (KERN_DEBUG "PIO read timed out (initial byte)\n");		goto out_no_data;	}	/* read byte */	*bufp++ = inb (DATA (port));	left--;dump_parport_state ("43-44", port);	/* Event 44: nAutoFd (HostAck) goes high to acknowledge */	parport_pc_frob_control (port,				 PARPORT_CONTROL_AUTOFD,				 0);dump_parport_state ("pre 45", port);	/* Event 45: Wait for nAck to go high *//*	r = parport_wait_peripheral (port, PARPORT_STATUS_ACK, PARPORT_STATUS_ACK); */dump_parport_state ("post 45", port);r = 0;	if (r) {		/* timed out while waiting for peripheral to respond to ack */		printk (KERN_DEBUG "ECP PIO read timed out (waiting for nAck)\n");		/* keep hold of the byte we've got already */		goto out_no_data;	}	/* Event 46: nAutoFd (HostAck) goes low to accept more data */	parport_pc_frob_control (port,				 PARPORT_CONTROL_AUTOFD,				 PARPORT_CONTROL_AUTOFD);dump_parport_state ("rev idle", port);	/* Do the transfer. */	while (left > fifofull) {		int ret;		long int expire = jiffies + port->cad->timeout;		unsigned char ecrval = inb (ECONTROL (port));		if (current->need_resched && time_before (jiffies, expire))			/* Can't yield the port. */			schedule ();		/* At this point, the FIFO may already be full. In                 * that case ECP is already holding back the                 * peripheral (assuming proper design) with a delayed                 * handshake.  Work fast to avoid a peripheral                 * timeout.  */		if (ecrval & 0x01) {			/* FIFO is empty. Wait for interrupt. */dump_parport_state ("FIFO empty", port);			/* Anyone else waiting for the port? */			if (port->waithead) {				printk (KERN_DEBUG "Somebody wants the port\n");				break;			}			/* Clear serviceIntr */			ECR_WRITE (port, ecrval & ~(1<<2));		false_alarm:dump_parport_state ("waiting", port);			ret = parport_wait_event (port, HZ);DPRINTK (KERN_DEBUG "parport_wait_event returned %d\n", ret);			if (ret < 0)				break;			ret = 0;			if (!time_before (jiffies, expire)) {				/* Timed out. */dump_parport_state ("timeout", port);				printk (KERN_DEBUG "PIO read timed out\n");				break;			}			ecrval = inb (ECONTROL (port));			if (!(ecrval & (1<<2))) {				if (current->need_resched &&				    time_before (jiffies, expire)) {					schedule ();				}				goto false_alarm;			}			/* Depending on how the FIFO threshold was                         * set, how long interrupt service took, and                         * how fast the peripheral is, we might be                         * lucky and have a just filled FIFO. */			continue;		}		if (ecrval & 0x02) {			/* FIFO is full. */dump_parport_state ("FIFO full", port);			insb (fifo, bufp, fifo_depth);			bufp += fifo_depth;			left -= fifo_depth;			continue;		}DPRINTK (KERN_DEBUG "*** ecp_read_block_pio: reading one byte from the FIFO\n");		/* FIFO not filled.  We will cycle this loop for a while                 * and either the peripheral will fill it faster,                 * tripping a fast empty with insb, or we empty it. */		*bufp++ = inb (fifo);		left--;	}	/* scoop up anything left in the FIFO */	while (left && !(inb (ECONTROL (port) & 0x01))) {		*bufp++ = inb (fifo);		left--;	}	port->ieee1284.phase = IEEE1284_PH_REV_IDLE;dump_parport_state ("rev idle2", port);out_no_data:	/* Go to forward idle mode to shut the peripheral up (event 47). */	parport_frob_control (port, PARPORT_CONTROL_INIT, PARPORT_CONTROL_INIT);	/* event 49: PError goes high */	r = parport_wait_peripheral (port,				     PARPORT_STATUS_PAPEROUT,				     PARPORT_STATUS_PAPEROUT);	if (r) {		printk (KERN_DEBUG			"%s: PE timeout FWDIDLE (%d) in ecp_read_block_pio\n",			port->name, r);	}	port->ieee1284.phase = IEEE1284_PH_FWD_IDLE;	/* Finish up. */	{		int lost = get_fifo_residue (port);		if (lost)			/* Shouldn't happen with compliant peripherals. */			printk (KERN_DEBUG "%s: DATA LOSS (%d bytes)!\n",				port->name, lost);	}dump_parport_state ("fwd idle", port);	return length - left;}#endif /* IEEE 1284 support */#endif /* Allowed to use FIFO/DMA *//* *	****************************************** *	INITIALISATION AND MODULE STUFF BELOW HERE *	****************************************** */void parport_pc_inc_use_count(void){#ifdef MODULE	MOD_INC_USE_COUNT;#endif}void parport_pc_dec_use_count(void){#ifdef MODULE	MOD_DEC_USE_COUNT;#endif}struct parport_operations parport_pc_ops = {	parport_pc_write_data,	parport_pc_read_data,	parport_pc_write_control,	parport_pc_read_control,	parport_pc_frob_control,	parport_pc_read_status,	parport_pc_enable_irq,	parport_pc_disable_irq,	parport_pc_data_forward,	parport_pc_data_reverse,	parport_pc_init_state,	parport_pc_save_state,	parport_pc_restore_state,	parport_pc_inc_use_count,	parport_pc_dec_use_count,	parport_ieee1284_epp_write_data,	parport_ieee1284_epp_read_data,	parport_ieee1284_epp_write_addr,	parport_ieee1284_epp_read_addr,	parport_ieee1284_ecp_write_data,	parport_ieee1284_ecp_read_data,	parport_ieee1284_ecp_write_addr,	parport_ieee1284_write_compat,	parport_ieee1284_read_nibble,	parport_ieee1284_read_byte,};#ifdef CONFIG_PARPORT_PC_SUPERIO/* Super-IO chipset detection, Winbond, SMSC */static void __devinit show_parconfig_smsc37c669(int io, int key){	int cr1,cr4,cra,cr23,cr26,cr27,i=0;	static const char *modes[]={ "SPP and Bidirectional (PS/2)",					     "EPP and SPP",				     "ECP",				     "ECP and EPP" };	outb(key,io);	outb(key,io);	outb(1,io);	cr1=inb(io+1);	outb(4,io);	cr4=inb(io+1);	outb(0x0a,io);	cra=inb(io+1);	outb(0x23,io);	cr23=inb(io+1);	outb(0x26,io);	cr26=inb(io+1);	outb(0x27,io);	cr27=inb(io+1);	outb(0xaa,io);	if (verbose_probing) {		printk (KERN_INFO "SMSC 37c669 LPT Config: cr_1=0x%02x, 4=0x%02x, "			"A=0x%2x, 23=0x%02x, 26=0x%02x, 27=0x%02x\n",			cr1,cr4,cra,cr23,cr26,cr27);				/* The documentation calls DMA and IRQ-Lines by letters, so		   the board maker can/will wire them		   appropriately/randomly...  G=reserved H=IDE-irq, */		printk (KERN_INFO "SMSC LPT Config: io=0x%04x, irq=%c, dma=%c, "			"fifo threshold=%d\n", cr23*4,			(cr27 &0x0f) ? 'A'-1+(cr27 &0x0f): '-',			(cr26 &0x0f) ? 'A'-1+(cr26 &0x0f): '-', cra & 0x0f);		printk(KERN_INFO "SMSC LPT Config: enabled=%s power=%s\n",		       (cr23*4 >=0x100) ?"yes":"no", (cr1 & 4) ? "yes" : "no");		printk(KERN_INFO "SMSC LPT Config: Port mode=%s, EPP version =%s\n",		       (cr1 & 0x08 ) ? "Standard mode only (SPP)" : modes[cr4 & 0x03], 		       (cr4 & 0x40) ? "1.7" : "1.9");	}			/* Heuristics !  BIOS setup for this mainboard device limits	   the choices to standard settings, i.e. io-address and IRQ	   are related, however DMA can be 1 or 3, assume DMA_A=DMA1,	   DMA_C=DMA3 (this is true e.g. for TYAN 1564D Tomcat IV) */	if(cr23*4 >=0x100) { /* if active */		while((superios[i].io!= 0) && (i<NR_SUPERIOS))			i++;		if(i==NR_SUPERIOS)			printk(KERN_INFO "Super-IO: too many chips!\n");		else {			int d;			switch (cr23*4) {				case 0x3bc:					superios[i].io = 0x3bc;					superios[i].irq = 7;					break;				case 0x378:					superios[i].io = 0x378;					superios[i].irq = 7;					break;				case 0x278:					superios[i].io = 0x278;					superios[i].irq = 5;			}			d=(cr26 &0x0f);			if((d==1) || (d==3)) 				superios[i].dma= d;			else				superios[i].dma= PARPORT_DMA_NONE;		} 	}}static void __devinit show_parconfig_winbond(int io, int key){	int cr30,cr60,cr61,cr70,cr74,crf0,i=0;	static const char *modes[] = {		"Standard (SPP) and Bidirectional(PS/2)", /* 0 */		"EPP-1.9 and SPP",		"ECP",		"ECP and EPP-1.9",		"Standard (SPP)",		"EPP-1.7 and SPP",		/* 5 */		"undefined!",		"ECP and EPP-1.7" };	static char *irqtypes[] = { "pulsed low, high-Z", "follows nACK" };			/* The registers are called compatible-PnP because the           register layout is modelled after ISA-PnP, the access           method is just another ... */	outb(key,io);	outb(key,io);	outb(0x07,io);   /* Register 7: Select Logical Device */	outb(0x01,io+1); /* LD1 is Parallel Port */	outb(0x30,io);	cr30=inb(io+1);	outb(0x60,io);	cr60=inb(io+1);	outb(0x61,io);	cr61=inb(io+1);	outb(0x70,io);	cr70=inb(io+1);	outb(0x74,io);	cr74=inb(io+1);	outb(0xf0,io);	crf0=inb(io+1);	outb(0xaa,io);	if (verbose_probing) {		printk(KERN_INFO "Winbond LPT Config: cr_30=%02x 60,61=%02x%02x "		       "70=%02x 74=%02x, f0=%02x\n", cr30,cr60,cr61,cr70,cr74,crf0);		printk(KERN_INFO "Winbond LPT Config: active=%s, io=0x%02x%02x irq=%d, ", 		       (cr30 & 0x01) ? "yes":"no", cr60,cr61,cr70&0x0f );		if ((cr74 & 0x07) > 3)			printk("dma=none\n");		else			printk("dma=%d\n",cr74 & 0x07);		printk(KERN_INFO "Winbond LPT Config: irqtype=%s, ECP fifo threshold=%d\n",		       irqtypes[crf0>>7], (crf0>>3)&0x0f);		printk(KERN_INFO "Winbond LPT Config: Port mode=%s\n", modes[crf0 & 0x07]);	}	if(cr30 & 0x01) { /* the settings can be interrogated later ... */		while((superios[i].io!= 0) && (i<NR_SUPERIOS))			i++;		if(i==NR_SUPERIOS) 			printk(KERN_INFO "Super-IO: too many chips!\n");		else {			superios[i].io = (cr60<<8)|cr61;			superios[i].irq = cr70&0x0f;			superios[i].dma = (((cr74 & 0x07) > 3) ?					   PARPORT_DMA_NONE : (cr74 & 0x07));		}	}}static void __devinit decode_winbond(int efer, int key, int devid, int devrev, int oldid){	const char *type = "unknown";	int id,progif=2;	if (devid == devrev)		/* simple heuristics, we happened to read some                   non-winbond register */		return;	id=(devid<<8) | devrev;	/* Values are from public data sheets pdf files, I can just           confirm 83977TF is correct :-) */	if      (id == 0x9771) type="83977F/AF";	else if (id == 0x9773) type="83977TF / SMSC 97w33x/97w34x";	else if (id == 0x9774) type="83977ATF";	else if ((id & ~0x0f) == 0x5270) type="83977CTF / SMSC 97w36x";	else if ((id & ~0x0f) == 0x52f0) type="83977EF / SMSC 97w35x";	else if ((id & ~0x0f) == 0x5210) type="83627";	else if ((id & ~0x0f) == 0x6010) type="83697HF";	else if ((oldid &0x0f ) == 0x0a) { type="83877F"; progif=1;}	else if ((oldid &0x0f ) == 0x0b) { type="83877AF"; progif=1;}	else if ((oldid &0x0f ) == 0x0c) { type="83877TF"; progif=1;}	else if ((oldid &0x0f ) == 0x0d) { type="83877ATF"; progif=1;}	else progif=0;	if (verbose_probing)		printk(KERN_INFO "Winbond chip at EFER=0x%x key=0x%02x "		       "devid=%02x devrev=%02x oldid=%02x type=%s\n", 		       efer, key, devid, devrev, oldid, type);	if (progif == 2)		show_parconfig_winbond(efer,key);}static void __devinit decode_smsc(int efer, int key, int devid, int devrev){        const char *type = "unknown";	void (*func)(int io, int key);        int id;        if (devid == devrev)		/* simple heuristics, we happened to read some                   non-smsc register */		return;	func=NULL;        id=(devid<<8) | devrev;	if	(id==0x0302) {type="37c669"; func=show_parconfig_smsc37c669;}	else if	(id==0x6582) type="37c665IR";	else if	(devid==0x65) type="37c665GT";	else if	(devid==0x66) type="37c666GT";	if (verbose_probing)		printk(KERN_INFO "SMSC chip at EFER=0x%x "		       "key=0x%02x devid=%02x devrev=%02x type=%s\n",		       efer, key, devid, devrev, type);	if (func)		func(efer,key);}static void __devinit winbond_check(int io, int key)

⌨️ 快捷键说明

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