<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
From: Jean Tourrilhes &lt;jt@bougret.hpl.hp.com&gt;

o [CORRECT] Speed change fixes in via-ircc driver
o [FEATURE] Add new dongle ID in via-ircc driver
o [FEATURE] Various code cleanups in via-ircc driver

Signed-off-by: Jean Tourrilhes &lt;jt@hpl.hp.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@osdl.org&gt;
---

 /dev/null                           |    0 
 25-akpm/drivers/net/irda/via-ircc.c |  515 +++++++++++++++++++-----------------
 25-akpm/drivers/net/irda/via-ircc.h |   19 -
 3 files changed, 282 insertions(+), 252 deletions(-)

diff -puN drivers/net/irda/via-ircc.c~irda-via-ircc-driver-speed-fixes drivers/net/irda/via-ircc.c
--- 25/drivers/net/irda/via-ircc.c~irda-via-ircc-driver-speed-fixes	Wed Oct 20 15:51:31 2004
+++ 25-akpm/drivers/net/irda/via-ircc.c	Wed Oct 20 15:51:31 2004
@@ -26,6 +26,16 @@ F02 Oct/28/02: Add SB device ID for 3147
        jul/09/2002 : only implement two kind of dongle currently.
        Oct/02/2002 : work on VT8231 and VT8233 .
        Aug/06/2003 : change driver format to pci driver .
+
+2004-02-16: &lt;sda@bdit.de&gt;
+- Removed unneeded 'legacy' pci stuff.
+- Make sure SIR mode is set (hw_init()) before calling mode-dependant stuff.
+- On speed change from core, don't send SIR frame with new speed.
+  Use current speed and change speeds later.
+- Make module-param dongle_id actually work.
+- New dongle_id 17 (0x11): TDFS4500. Single-ended SIR only.
+  Tested with home-grown PCB on EPIA boards.
+- Code cleanup.
        
  ********************************************************************/
 #include &lt;linux/module.h&gt;
@@ -53,26 +63,16 @@ F02 Oct/28/02: Add SB device ID for 3147
 
 #include "via-ircc.h"
 
-//#define DBG_IO	1
-//#define   DBGMSG 1
-//#define   DBGMSG_96 1
-//#define   DBGMSG_76 1
-//static int debug=0;
-
-
-#define DBG(x) {if (debug) x;}
+#define VIA_MODULE_NAME "via-ircc"
+#define CHIP_IO_EXTENT 0x40
 
-#define   VIA_MODULE_NAME "via-ircc"
-#define CHIP_IO_EXTENT 8
-#define BROKEN_DONGLE_ID
-
-static char *driver_name = "via-ircc";
+static char *driver_name = VIA_MODULE_NAME;
 
 /* Module parameters */
 static int qos_mtt_bits = 0x07;	/* 1 ms or more */
-static int dongle_id = 9;	//defalut IBM type
+static int dongle_id = 0;	/* default: probe */
 
-/* Resource is allocate by BIOS user only need to supply dongle_id*/
+/* We can't guess the type of connected dongle, user *must* supply it. */
 MODULE_PARM(dongle_id, "i");
 
 /* Max 4 instances for now */
@@ -81,7 +81,6 @@ static struct via_ircc_cb *dev_self[] = 
 /* Some prototypes */
 static int via_ircc_open(int i, chipio_t * info, unsigned int id);
 static int __exit via_ircc_close(struct via_ircc_cb *self);
-static int via_ircc_setup(chipio_t * info, unsigned int id);
 static int via_ircc_dma_receive(struct via_ircc_cb *self);
 static int via_ircc_dma_receive_complete(struct via_ircc_cb *self,
 					 int iobase);
@@ -89,6 +88,7 @@ static int via_ircc_hard_xmit_sir(struct
 				  struct net_device *dev);
 static int via_ircc_hard_xmit_fir(struct sk_buff *skb,
 				  struct net_device *dev);
+static void via_hw_init(struct via_ircc_cb *self);
 static void via_ircc_change_speed(struct via_ircc_cb *self, __u32 baud);
 static irqreturn_t via_ircc_interrupt(int irq, void *dev_id,
 				      struct pt_regs *regs);
@@ -110,7 +110,7 @@ static int upload_rxdata(struct via_ircc
 static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_device_id *id);
 static void __exit via_remove_one (struct pci_dev *pdev);
 
-/* Should use udelay() instead, even if we are x86 only - Jean II */
+/* FIXME : Should use udelay() instead, even if we are x86 only - Jean II */
 static void iodelay(int udelay)
 {
 	u8 data;
@@ -122,11 +122,11 @@ static void iodelay(int udelay)
 }
 
 static struct pci_device_id via_pci_tbl[] = {
-	{ PCI_VENDOR_ID_VIA, DeviceID1, PCI_ANY_ID, PCI_ANY_ID,0,0,0 },
-	{ PCI_VENDOR_ID_VIA, DeviceID2, PCI_ANY_ID, PCI_ANY_ID,0,0,1 },
-	{ PCI_VENDOR_ID_VIA, DeviceID3, PCI_ANY_ID, PCI_ANY_ID,0,0,2 },
-	{ PCI_VENDOR_ID_VIA, DeviceID4, PCI_ANY_ID, PCI_ANY_ID,0,0,3 },
-	{ PCI_VENDOR_ID_VIA, DeviceID5, PCI_ANY_ID, PCI_ANY_ID,0,0,4 },
+	{ PCI_VENDOR_ID_VIA, 0x8231, PCI_ANY_ID, PCI_ANY_ID,0,0,0 },
+	{ PCI_VENDOR_ID_VIA, 0x3109, PCI_ANY_ID, PCI_ANY_ID,0,0,1 },
+	{ PCI_VENDOR_ID_VIA, 0x3074, PCI_ANY_ID, PCI_ANY_ID,0,0,2 },
+	{ PCI_VENDOR_ID_VIA, 0x3147, PCI_ANY_ID, PCI_ANY_ID,0,0,3 },
+	{ PCI_VENDOR_ID_VIA, 0x3177, PCI_ANY_ID, PCI_ANY_ID,0,0,4 },
 	{ 0, }
 };
 
@@ -150,13 +150,16 @@ static int __init via_ircc_init(void)
 {
 	int rc;
 
-#ifdef	HEADMSG
-        DBG(printk(KERN_INFO "via_ircc_init ......\n"));
-#endif
-	rc = pci_register_driver (&amp;via_driver);
-#ifdef	HEADMSG
-        DBG(printk(KERN_INFO "via_ircc_init :rc = %d......\n",rc));
-#endif
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
+
+	rc = pci_register_driver(&amp;via_driver);
+	if (rc &lt; 1) {
+		IRDA_DEBUG(0, "%s(): error rc = %d, returning  -ENODEV...\n",
+			   __FUNCTION__, rc);
+		if (rc == 0)
+			pci_unregister_driver (&amp;via_driver);
+		return -ENODEV;
+	}
 	return rc;
 }
 
@@ -166,33 +169,24 @@ static int __devinit via_init_one (struc
         u8 temp,oldPCI_40,oldPCI_44,bTmp,bTmp1;
 	u16 Chipset,FirDRQ1,FirDRQ0,FirIRQ,FirIOBase;
 	chipio_t info;
-	
-#ifdef	HEADMSG
-        DBG(printk(KERN_INFO "via_init_one : Device ID=(0X%X)\n",id-&gt;device));
-#endif
-	if(id-&gt;device != DeviceID1 &amp;&amp; id-&gt;device != DeviceID2 &amp;&amp;
-	   id-&gt;device != DeviceID3 &amp;&amp; id-&gt;device != DeviceID4 &amp;&amp;
-	   id-&gt;device != DeviceID5  ){
-#ifdef	HEADMSG
-		DBG(printk(KERN_INFO "via_init_one : Device ID(0X%X) not Supported\n",id-&gt;device));
-#endif
-	      return -ENODEV; //South not exist !!!!!
-	}
+
+	IRDA_DEBUG(2, "%s(): Device ID=(0X%X)\n", __FUNCTION__, id-&gt;device);
+
 	rc = pci_enable_device (pcidev);
-#ifdef	HEADMSG
-	DBG(printk(KERN_INFO "via_init_one : rc=%d\n",rc));
-#endif
-	if (rc)
-		return -ENODEV; 
-        //South Bridge exist
+	if (rc) {
+		IRDA_DEBUG(0, "%s(): error rc = %d\n", __FUNCTION__, rc);
+		return -ENODEV;
+	}
+
+	// South Bridge exist
         if ( ReadLPCReg(0x20) != 0x3C )
 		Chipset=0x3096;
 	else
 		Chipset=0x3076;
+
 	if (Chipset==0x3076) {
-#ifdef	HEADMSG
-		DBG(printk(KERN_INFO "via_init_one : 3076 ......\n"));
-#endif
+		IRDA_DEBUG(2, "%s(): Chipset = 3076\n", __FUNCTION__);
+
 		WriteLPCReg(7,0x0c );
 		temp=ReadLPCReg(0x30);//check if BIOS Enable Fir
 		if((temp&amp;0x01)==1) {   // BIOS close or no FIR
@@ -228,9 +222,8 @@ static int __devinit via_init_one (struc
 		} else
 			rc = -ENODEV; //IR not turn on	 
 	} else { //Not VT1211
-#ifdef	HEADMSG
-		DBG(printk(KERN_INFO "via_init_one : 3096 ......\n"));
-#endif
+		IRDA_DEBUG(2, "%s(): Chipset = 3096\n", __FUNCTION__);
+
 		pci_read_config_byte(pcidev,0x67,&amp;bTmp);//check if BIOS Enable Fir
 		if((bTmp&amp;0x01)==1) {  // BIOS enable FIR
 			//Enable Double DMA clock
@@ -268,9 +261,8 @@ static int __devinit via_init_one (struc
 		} else
 			rc = -ENODEV; //IR not turn on !!!!!
 	}//Not VT1211
-#ifdef	HEADMSG
-	DBG(printk(KERN_INFO "via_init_one End : rc=%d\n",rc));
-#endif
+
+	IRDA_DEBUG(2, "%s(): End - rc = %d\n", __FUNCTION__, rc);
 	return rc;
 }
 
@@ -284,9 +276,8 @@ static void __exit via_ircc_clean(void)
 {
 	int i;
 
-#ifdef	HEADMSG
-	DBG(printk(KERN_INFO "via_ircc_clean\n"));
-#endif
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
+
 	for (i=0; i &lt; 4; i++) {
 		if (dev_self[i])
 			via_ircc_close(dev_self[i]);
@@ -295,19 +286,16 @@ static void __exit via_ircc_clean(void)
 
 static void __exit via_remove_one (struct pci_dev *pdev)
 {
-#ifdef	HEADMSG
-        DBG(printk(KERN_INFO "via_remove_one :  ......\n"));
-#endif
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
+
 	via_ircc_clean();
 
 }
 
 static void __exit via_ircc_cleanup(void)
 {
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
-#ifdef	HEADMSG
-	DBG(printk(KERN_INFO "via_ircc_cleanup ......\n"));
-#endif
 	via_ircc_clean();
 	pci_unregister_driver (&amp;via_driver); 
 }
@@ -324,8 +312,7 @@ static __devinit int via_ircc_open(int i
 	struct via_ircc_cb *self;
 	int err;
 
-	if ((via_ircc_setup(info, id)) == -1)
-		return -1;
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	/* Allocate new instance of the driver */
 	dev = alloc_irdadev(sizeof(struct via_ircc_cb));
@@ -353,19 +340,40 @@ static __devinit int via_ircc_open(int i
 
 	/* Reserve the ioports that we need */
 	if (!request_region(self-&gt;io.fir_base, self-&gt;io.fir_ext, driver_name)) {
-//              WARNING("%s(), can't get iobase of 0x%03x\n", __FUNCTION__, self-&gt;io.fir_base);
+		IRDA_DEBUG(0, "%s(), can't get iobase of 0x%03x\n",
+			   __FUNCTION__, self-&gt;io.fir_base);
 		err = -ENODEV;
 		goto err_out1;
 	}
 	
 	/* Initialize QoS for this device */
 	irda_init_max_qos_capabilies(&amp;self-&gt;qos);
+
+	/* Check if user has supplied the dongle id or not */
+	if (!dongle_id)
+		dongle_id = via_ircc_read_dongle_id(self-&gt;io.fir_base);
+	self-&gt;io.dongle_id = dongle_id;
+
 	/* The only value we must override it the baudrate */
-//      self-&gt;qos.baud_rate.bits = IR_9600;// May use this for testing
+	/* Maximum speeds and capabilities are dongle-dependant. */
+	switch( self-&gt;io.dongle_id ){
+	case 0x0d:
+		self-&gt;qos.baud_rate.bits =
+		    IR_9600 | IR_19200 | IR_38400 | IR_57600 | IR_115200 |
+		    IR_576000 | IR_1152000 | (IR_4000000 &lt;&lt; 8);
+		break;
+	default:
+		self-&gt;qos.baud_rate.bits =
+		    IR_9600 | IR_19200 | IR_38400 | IR_57600 | IR_115200;
+		break;
+	}
 
-	self-&gt;qos.baud_rate.bits =
-	    IR_9600 | IR_19200 | IR_38400 | IR_57600 | IR_115200 |
-	    IR_576000 | IR_1152000 | (IR_4000000 &lt;&lt; 8);
+	/* Following was used for testing:
+	 *
+	 *   self-&gt;qos.baud_rate.bits = IR_9600;
+	 *
+	 * Is is no good, as it prohibits (error-prone) speed-changes.
+	 */
 
 	self-&gt;qos.min_turn_time.bits = qos_mtt_bits;
 	irda_qos_bits_to_value(&amp;self-&gt;qos);
@@ -416,15 +424,12 @@ static __devinit int via_ircc_open(int i
 	if (err)
 		goto err_out4;
 
-	MESSAGE("IrDA: Registered device %s\n", dev-&gt;name);
-
-	/* Check if user has supplied the dongle id or not */
-	if (!dongle_id)
-		dongle_id = via_ircc_read_dongle_id(self-&gt;io.fir_base);
-	self-&gt;io.dongle_id = dongle_id;
-	via_ircc_change_dongle_speed(self-&gt;io.fir_base, 9600,
-				     self-&gt;io.dongle_id);
+	MESSAGE("IrDA: Registered device %s (via-ircc)\n", dev-&gt;name);
 
+	/* Initialise the hardware..
+	*/
+	self-&gt;io.speed = 9600;
+	via_hw_init(self);
 	return 0;
  err_out4:
 	dma_free_coherent(NULL, self-&gt;tx_buff.truesize,
@@ -450,7 +455,7 @@ static int __exit via_ircc_close(struct 
 {
 	int iobase;
 
-	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	ASSERT(self != NULL, return -1;);
 
@@ -461,7 +466,7 @@ static int __exit via_ircc_close(struct 
 	unregister_netdev(self-&gt;netdev);
 
 	/* Release the PORT that this driver is using */
-	IRDA_DEBUG(4, "%s(), Releasing Region %03x\n",
+	IRDA_DEBUG(2, "%s(), Releasing Region %03x\n",
 		   __FUNCTION__, self-&gt;io.fir_base);
 	release_region(self-&gt;io.fir_base, self-&gt;io.fir_ext);
 	if (self-&gt;tx_buff.head)
@@ -478,14 +483,17 @@ static int __exit via_ircc_close(struct 
 }
 
 /*
- * Function via_ircc_setup (info)
+ * Function via_hw_init(self)
  *
  *    Returns non-negative on success.
  *
+ * Formerly via_ircc_setup
  */
-static int via_ircc_setup(chipio_t * info, unsigned int chip_id)
+static void via_hw_init(struct via_ircc_cb *self)
 {
-	int iobase = info-&gt;fir_base;
+	int iobase = self-&gt;io.fir_base;
+
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	SetMaxRxPacketSize(iobase, 0x0fff);	//set to max:4095
 	// FIFO Init
@@ -496,22 +504,40 @@ static int via_ircc_setup(chipio_t * inf
 	EnTXFIFOReadyInt(iobase, OFF);
 	InvertTX(iobase, OFF);
 	InvertRX(iobase, OFF);
+
 	if (ReadLPCReg(0x20) == 0x3c)
 		WriteLPCReg(0xF0, 0);	// for VT1211
-	if (IsSIROn(iobase)) {
-		SIRFilter(iobase, ON);
-		SIRRecvAny(iobase, ON);
-	} else {
-		SIRFilter(iobase, OFF);
-		SIRRecvAny(iobase, OFF);
-	}
-	//Int Init
+	/* Int Init */
 	EnRXSpecInt(iobase, ON);
-	//DMA Init Later....
-	WriteReg(iobase, I_ST_CT_0, 0x80);
-	EnableDMA(iobase, ON);
 
-	return 0;
+	/* The following is basically hwreset */
+	/* If this is the case, why not just call hwreset() ? Jean II */
+	ResetChip(iobase, 5);
+	EnableDMA(iobase, OFF);
+	EnableTX(iobase, OFF);
+	EnableRX(iobase, OFF);
+	EnRXDMA(iobase, OFF);
+	EnTXDMA(iobase, OFF);
+	RXStart(iobase, OFF);
+	TXStart(iobase, OFF);
+	InitCard(iobase);
+	CommonInit(iobase);
+	SIRFilter(iobase, ON);
+	SetSIR(iobase, ON);
+	CRC16(iobase, ON);
+	EnTXCRC(iobase, 0);
+	WriteReg(iobase, I_ST_CT_0, 0x00);
+	SetBaudRate(iobase, 9600);
+	SetPulseWidth(iobase, 12);
+	SetSendPreambleCount(iobase, 0);
+
+	self-&gt;io.speed = 9600;
+	self-&gt;st_fifo.len = 0;
+
+	via_ircc_change_dongle_speed(iobase, self-&gt;io.speed,
+				     self-&gt;io.dongle_id);
+
+	WriteReg(iobase, I_ST_CT_0, 0x80);
 }
 
 /*
@@ -520,8 +546,9 @@ static int via_ircc_setup(chipio_t * inf
  */
 static int via_ircc_read_dongle_id(int iobase)
 {
-	int dongle_id = 9;
+	int dongle_id = 9;	/* Default to IBM */
 
+	ERROR("via-ircc: dongle probing not supported, please specify dongle_id module parameter.\n");
 	return dongle_id;
 }
 
@@ -535,22 +562,16 @@ static void via_ircc_change_dongle_speed
 {
 	u8 mode = 0;
 
-	WriteReg(iobase, I_ST_CT_0, 0x0);
-	switch (dongle_id) {	//HP1100
-	case 0x00:		/* same as */
-	case 0x01:		/* Differential serial interface */
-		break;
-	case 0x02:		/* same as */
-	case 0x03:		/* Reserved */
-		break;
-	case 0x04:		/* Sharp RY5HD01 */
-		break;
-	case 0x05:		/* Reserved, but this is what the Thinkpad reports */
-		break;
-	case 0x06:		/* Single-ended serial interface */
-		break;
-	case 0x07:		/* Consumer-IR only */
-		break;
+	/* speed is unused, as we use IsSIROn()/IsMIROn() */
+	speed = speed;
+
+	IRDA_DEBUG(1, "%s(): change_dongle_speed to %d for 0x%x, %d\n",
+		   __FUNCTION__, speed, iobase, dongle_id);
+
+	switch (dongle_id) {
+
+		/* Note: The dongle_id's listed here are derived from
+		 * nsc-ircc.c */
 
 	case 0x08:		/* HP HSDL-2300, HP HSDL-3600/HSDL-3610 */
 		UseOneRX(iobase, ON);	// use one RX pin   RX1,RX2
@@ -579,10 +600,12 @@ static void via_ircc_change_dongle_speed
 			}
 		}
 		break;
+
 	case 0x09:		/* IBM31T1100 or Temic TFDS6000/TFDS6500 */
 		UseOneRX(iobase, ON);	//use ONE RX....RX1
 		InvertTX(iobase, OFF);
 		InvertRX(iobase, OFF);	// invert RX pin
+
 		EnRX2(iobase, ON);
 		EnGPIOtoRX2(iobase, OFF);
 		if (IsSIROn(iobase)) {	//sir
@@ -613,6 +636,7 @@ static void via_ircc_change_dongle_speed
 			}
 		}
 		break;
+
 	case 0x0d:
 		UseOneRX(iobase, OFF);	// use two RX pin   RX1,RX2
 		InvertTX(iobase, OFF);
@@ -628,6 +652,31 @@ static void via_ircc_change_dongle_speed
 			EnRX2(iobase, OFF);	//fir to rx
 		}
 		break;
+
+	case 0x11:		/* Temic TFDS4500 */
+
+		IRDA_DEBUG(2, "%s: Temic TFDS4500: One RX pin, TX normal, RX inverted.\n", __FUNCTION__);
+
+		UseOneRX(iobase, ON);	//use ONE RX....RX1
+		InvertTX(iobase, OFF);
+		InvertRX(iobase, ON);	// invert RX pin
+
+		EnRX2(iobase, ON);	//sir to rx2
+		EnGPIOtoRX2(iobase, OFF);
+
+		if( IsSIROn(iobase) ){	//sir
+
+			// Mode select On
+			SlowIRRXLowActive(iobase, ON);
+			udelay(20);
+			// Mode select Off
+			SlowIRRXLowActive(iobase, OFF);
+
+		} else{
+			IRDA_DEBUG(0, "%s: Warning: TFDS4500 not running in SIR mode !\n", __FUNCTION__);
+		}
+		break;
+
 	case 0x0ff:		/* Vishay */
 		if (IsSIROn(iobase))
 			mode = 0;
@@ -638,9 +687,12 @@ static void via_ircc_change_dongle_speed
 		else if (IsVFIROn(iobase))
 			mode = 5;	//VFIR-16
 		SI_SetMode(iobase, mode);
-	}
-	WriteReg(iobase, I_ST_CT_0, 0x80);
+		break;
 
+	default:
+		ERROR("%s: Error: dongle_id %d unsupported !\n",
+		      __FUNCTION__, dongle_id);
+	}
 }
 
 /*
@@ -658,46 +710,25 @@ static void via_ircc_change_speed(struct
 	iobase = self-&gt;io.fir_base;
 	/* Update accounting for new speed */
 	self-&gt;io.speed = speed;
-#ifdef	DBGMSG
-	DBG(printk(KERN_INFO "change_speed =%x......\n", speed));
-#endif
-
-#ifdef	DBG_IO
-	if (self-&gt;io.speed &gt; 0x2580)
-		outb(0xaa, 0x90);
-	else
-		outb(0xbb, 0x90);
-#endif
+	IRDA_DEBUG(1, "%s: change_speed to %d bps.\n", __FUNCTION__, speed);
 
+	WriteReg(iobase, I_ST_CT_0, 0x0);
 
 	/* Controller mode sellection */
 	switch (speed) {
+	case 2400:
 	case 9600:
-		value = 11;
-		SetSIR(iobase, ON);
-		CRC16(iobase, ON);
-		break;
 	case 19200:
-		value = 5;
-		SetSIR(iobase, ON);
-		CRC16(iobase, ON);
-		break;
 	case 38400:
-		value = 2;
-		SetSIR(iobase, ON);
-		CRC16(iobase, ON);
-		break;
 	case 57600:
-		value = 1;
-		SetSIR(iobase, ON);
-		CRC16(iobase, ON);
-		break;
 	case 115200:
-		value = 0;
+		value = (115200/speed)-1;
 		SetSIR(iobase, ON);
 		CRC16(iobase, ON);
 		break;
 	case 576000:
+		/* FIXME: this can't be right, as it's the same as 115200,
+		 * and 576000 is MIR, not SIR. */
 		value = 0;
 		SetSIR(iobase, ON);
 		CRC16(iobase, ON);
@@ -705,6 +736,7 @@ static void via_ircc_change_speed(struct
 	case 1152000:
 		value = 0;
 		SetMIR(iobase, ON);
+		/* FIXME: CRC ??? */
 		break;
 	case 4000000:
 		value = 0;
@@ -717,19 +749,29 @@ static void via_ircc_change_speed(struct
 	case 16000000:
 		value = 0;
 		SetVFIR(iobase, ON);
+		/* FIXME: CRC ??? */
 		break;
 	default:
 		value = 0;
 		break;
 	}
+
 	/* Set baudrate to 0x19[2..7] */
 	bTmp = (ReadReg(iobase, I_CF_H_1) &amp; 0x03);
-	bTmp = bTmp | (value &lt;&lt; 2);
+	bTmp |= value &lt;&lt; 2;
 	WriteReg(iobase, I_CF_H_1, bTmp);
+
+	/* Some dongles may need to be informed about speed changes. */
 	via_ircc_change_dongle_speed(iobase, speed, self-&gt;io.dongle_id);
-// EnTXFIFOHalfLevelInt(iobase,ON);
+
 	/* Set FIFO size to 64 */
 	SetFIFO(iobase, 64);
+
+	/* Enable IR */
+	WriteReg(iobase, I_ST_CT_0, 0x80);
+
+	// EnTXFIFOHalfLevelInt(iobase,ON);
+
 	/* Enable some interrupts so we can receive frames */
 	//EnAllInt(iobase,ON);
 
@@ -740,6 +782,7 @@ static void via_ircc_change_speed(struct
 		SIRFilter(iobase, OFF);
 		SIRRecvAny(iobase, OFF);
 	}
+
 	if (speed &gt; 115200) {
 		/* Install FIR xmit handler */
 		dev-&gt;hard_start_xmit = via_ircc_hard_xmit_fir;
@@ -797,7 +840,8 @@ static int via_ircc_hard_xmit_sir(struct
 			   self-&gt;tx_buff.truesize);
 
 	self-&gt;stats.tx_bytes += self-&gt;tx_buff.len;
-	SetBaudRate(iobase, speed);
+	/* Send this frame with old speed */
+	SetBaudRate(iobase, self-&gt;io.speed);
 	SetPulseWidth(iobase, 12);
 	SetSendPreambleCount(iobase, 0);
 	WriteReg(iobase, I_ST_CT_0, 0x80);
@@ -879,9 +923,6 @@ static int via_ircc_hard_xmit_fir(struct
 
 static int via_ircc_dma_xmit(struct via_ircc_cb *self, u16 iobase)
 {
-//      int i;
-//      u8 *ch;
-
 	EnTXDMA(iobase, OFF);
 	self-&gt;io.direction = IO_XMIT;
 	EnPhys(iobase, ON);
@@ -899,18 +940,10 @@ static int via_ircc_dma_xmit(struct via_
 		       ((u8 *)self-&gt;tx_fifo.queue[self-&gt;tx_fifo.ptr].start -
 			self-&gt;tx_buff.head) + self-&gt;tx_buff_dma,
 		       self-&gt;tx_fifo.queue[self-&gt;tx_fifo.ptr].len, DMA_TX_MODE);
-#ifdef	DBGMSG
-	DBG(printk
-	    (KERN_INFO "dma_xmit:tx_fifo.ptr=%x,len=%x,tx_fifo.len=%x..\n",
-	     self-&gt;tx_fifo.ptr, self-&gt;tx_fifo.queue[self-&gt;tx_fifo.ptr].len,
-	     self-&gt;tx_fifo.len));
-/*   
-	ch = self-&gt;tx_fifo.queue[self-&gt;tx_fifo.ptr].start;
-	for(i=0 ; i &lt; self-&gt;tx_fifo.queue[self-&gt;tx_fifo.ptr].len ; i++) {
-	    DBG(printk(KERN_INFO "%x..\n",ch[i]));
-	}
-*/
-#endif
+	IRDA_DEBUG(1, "%s: tx_fifo.ptr=%x,len=%x,tx_fifo.len=%x..\n",
+		   __FUNCTION__, self-&gt;tx_fifo.ptr,
+		   self-&gt;tx_fifo.queue[self-&gt;tx_fifo.ptr].len,
+		   self-&gt;tx_fifo.len);
 
 	SetSendByte(iobase, self-&gt;tx_fifo.queue[self-&gt;tx_fifo.ptr].len);
 	RXStart(iobase, OFF);
@@ -932,7 +965,8 @@ static int via_ircc_dma_xmit_complete(st
 	int ret = TRUE;
 	u8 Tx_status;
 
-	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
+
 	iobase = self-&gt;io.fir_base;
 	/* Disable DMA */
 //      DisableDmaChannel(self-&gt;io.dma);
@@ -962,12 +996,10 @@ static int via_ircc_dma_xmit_complete(st
 			self-&gt;tx_fifo.ptr++;
 		}
 	}
-#ifdef	DBGMSG
-	DBG(printk
-	    (KERN_INFO
-	     "via_ircc_dma_xmit_complete:tx_fifo.len=%x ,tx_fifo.ptr=%x,tx_fifo.free=%x...\n",
-	     self-&gt;tx_fifo.len, self-&gt;tx_fifo.ptr, self-&gt;tx_fifo.free));
-#endif
+	IRDA_DEBUG(1,
+		   "%s: tx_fifo.len=%x ,tx_fifo.ptr=%x,tx_fifo.free=%x...\n",
+		   __FUNCTION__,
+		   self-&gt;tx_fifo.len, self-&gt;tx_fifo.ptr, self-&gt;tx_fifo.free);
 /* F01_S
 	// Any frames to be sent back-to-back? 
 	if (self-&gt;tx_fifo.len) {
@@ -1002,6 +1034,8 @@ static int via_ircc_dma_receive(struct v
 
 	iobase = self-&gt;io.fir_base;
 
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
+
 	self-&gt;tx_fifo.len = self-&gt;tx_fifo.ptr = self-&gt;tx_fifo.free = 0;
 	self-&gt;tx_fifo.tail = self-&gt;tx_buff.head;
 	self-&gt;RxDataReady = 0;
@@ -1009,6 +1043,7 @@ static int via_ircc_dma_receive(struct v
 	self-&gt;rx_buff.data = self-&gt;rx_buff.head;
 	self-&gt;st_fifo.len = self-&gt;st_fifo.pending_bytes = 0;
 	self-&gt;st_fifo.tail = self-&gt;st_fifo.head = 0;
+
 	EnPhys(iobase, ON);
 	EnableTX(iobase, OFF);
 	EnableRX(iobase, ON);
@@ -1082,22 +1117,16 @@ static int via_ircc_dma_receive_complete
 		if (len == 0)
 			return TRUE;	//interrupt only, data maybe move by RxT  
 		if (((len - 4) &lt; 2) || ((len - 4) &gt; 2048)) {
-#ifdef	DBGMSG
-			DBG(printk
-			    (KERN_INFO
-			     "receive_comple:Trouble:len=%x,CurCount=%x,LastCount=%x..\n",
-			     len, RxCurCount(iobase, self),
-			     self-&gt;RxLastCount));
-#endif
+			IRDA_DEBUG(1, "%s(): Trouble:len=%x,CurCount=%x,LastCount=%x..\n",
+				   __FUNCTION__, len, RxCurCount(iobase, self),
+				   self-&gt;RxLastCount);
 			hwreset(self);
 			return FALSE;
 		}
-#ifdef	DBGMSG
-		DBG(printk
-		    (KERN_INFO
-		     "recv_comple:fifo.len=%x,len=%x,CurCount=%x..\n",
-		     st_fifo-&gt;len, len - 4, RxCurCount(iobase, self)));
-#endif
+		IRDA_DEBUG(2, "%s(): fifo.len=%x,len=%x,CurCount=%x..\n",
+			   __FUNCTION__,
+			   st_fifo-&gt;len, len - 4, RxCurCount(iobase, self));
+
 		st_fifo-&gt;entries[st_fifo-&gt;tail].status = status;
 		st_fifo-&gt;entries[st_fifo-&gt;tail].len = len;
 		st_fifo-&gt;pending_bytes += len;
@@ -1140,16 +1169,11 @@ F01_E */
 		}
 		skb_reserve(skb, 1);
 		skb_put(skb, len - 4);
+
 		memcpy(skb-&gt;data, self-&gt;rx_buff.data, len - 4);
-#ifdef	DBGMSG
-		DBG(printk
-		    (KERN_INFO "RxT:len=%x.rx_buff=%x\n", len - 4,
-		     self-&gt;rx_buff.data));
-/*		for(i=0 ; i &lt; (len-4) ; i++) {
-		    DBG(printk(KERN_INFO "%x..\n",self-&gt;rx_buff.data[i]));
-		}
-*/
-#endif
+		IRDA_DEBUG(2, "%s(): len=%x.rx_buff=%p\n", __FUNCTION__,
+			   len - 4, self-&gt;rx_buff.data);
+
 		// Move to next frame 
 		self-&gt;rx_buff.data += len;
 		self-&gt;stats.rx_bytes += len;
@@ -1177,9 +1201,8 @@ static int upload_rxdata(struct via_ircc
 
 	len = GetRecvByte(iobase, self);
 
-#ifdef	DBGMSG
-	DBG(printk(KERN_INFO "upload_rxdata: len=%x\n", len));
-#endif
+	IRDA_DEBUG(2, "%s(): len=%x\n", __FUNCTION__, len);
+
 	skb = dev_alloc_skb(len + 1);
 	if ((skb == NULL) || ((len - 4) &lt; 2)) {
 		self-&gt;stats.rx_dropped++;
@@ -1257,11 +1280,10 @@ static int RxTimerHandler(struct via_irc
 			skb_reserve(skb, 1);
 			skb_put(skb, len - 4);
 			memcpy(skb-&gt;data, self-&gt;rx_buff.data, len - 4);
-#ifdef	DBGMSG
-			DBG(printk
-			    (KERN_INFO "RxT:len=%x.head=%x\n", len - 4,
-			     st_fifo-&gt;head));
-#endif
+
+			IRDA_DEBUG(2, "%s(): len=%x.head=%x\n", __FUNCTION__,
+				   len - 4, st_fifo-&gt;head);
+
 			// Move to next frame 
 			self-&gt;rx_buff.data += len;
 			self-&gt;stats.rx_bytes += len;
@@ -1272,12 +1294,12 @@ static int RxTimerHandler(struct via_irc
 			netif_rx(skb);
 		}		//while
 		self-&gt;RetryCount = 0;
-#ifdef	DBGMSG
-		DBG(printk
-		    (KERN_INFO
-		     "RxT:End of upload HostStatus=%x,RxStatus=%x\n",
-		     GetHostStatus(iobase), GetRXStatus(iobase)));
-#endif
+
+		IRDA_DEBUG(2,
+			   "%s(): End of upload HostStatus=%x,RxStatus=%x\n",
+			   __FUNCTION__,
+			   GetHostStatus(iobase), GetRXStatus(iobase));
+
 		/*
 		 * if frame is receive complete at this routine ,then upload
 		 * frame.
@@ -1320,6 +1342,14 @@ static irqreturn_t via_ircc_interrupt(in
 	iobase = self-&gt;io.fir_base;
 	spin_lock(&amp;self-&gt;lock);
 	iHostIntType = GetHostStatus(iobase);
+
+	IRDA_DEBUG(4, "%s(): iHostIntType %02x:  %s %s %s  %02x\n",
+		   __FUNCTION__, iHostIntType,
+		   (iHostIntType &amp; 0x40) ? "Timer" : "",
+		   (iHostIntType &amp; 0x20) ? "Tx" : "",
+		   (iHostIntType &amp; 0x10) ? "Rx" : "",
+		   (iHostIntType &amp; 0x0e) &gt;&gt; 1);
+
 	if ((iHostIntType &amp; 0x40) != 0) {	//Timer Event
 		self-&gt;EventFlag.TimeOut++;
 		ClearTimerInt(iobase, 1);
@@ -1332,8 +1362,7 @@ static irqreturn_t via_ircc_interrupt(in
 			 */
 			if (self-&gt;RxDataReady &gt; 30) {
 				hwreset(self);
-				if (irda_device_txqueue_empty
-				    (self-&gt;netdev)) {
+				if (irda_device_txqueue_empty(self-&gt;netdev)) {
 					via_ircc_dma_receive(self);
 				}
 			} else {	// call this to upload frame.
@@ -1343,6 +1372,14 @@ static irqreturn_t via_ircc_interrupt(in
 	}			//Timer Event
 	if ((iHostIntType &amp; 0x20) != 0) {	//Tx Event
 		iTxIntType = GetTXStatus(iobase);
+
+		IRDA_DEBUG(4, "%s(): iTxIntType %02x:  %s %s %s %s\n",
+			   __FUNCTION__, iTxIntType,
+			   (iTxIntType &amp; 0x08) ? "FIFO underr." : "",
+			   (iTxIntType &amp; 0x04) ? "EOM" : "",
+			   (iTxIntType &amp; 0x02) ? "FIFO ready" : "",
+			   (iTxIntType &amp; 0x01) ? "Early EOM" : "");
+
 		if (iTxIntType &amp; 0x4) {
 			self-&gt;EventFlag.EOMessage++;	// read and will auto clean
 			if (via_ircc_dma_xmit_complete(self)) {
@@ -1359,10 +1396,19 @@ static irqreturn_t via_ircc_interrupt(in
 	if ((iHostIntType &amp; 0x10) != 0) {	//Rx Event
 		/* Check if DMA has finished */
 		iRxIntType = GetRXStatus(iobase);
-#ifdef	DBGMSG
+
+		IRDA_DEBUG(4, "%s(): iRxIntType %02x:  %s %s %s %s %s %s %s\n",
+			   __FUNCTION__, iRxIntType,
+			   (iRxIntType &amp; 0x80) ? "PHY err."	: "",
+			   (iRxIntType &amp; 0x40) ? "CRC err"	: "",
+			   (iRxIntType &amp; 0x20) ? "FIFO overr."	: "",
+			   (iRxIntType &amp; 0x10) ? "EOF"		: "",
+			   (iRxIntType &amp; 0x08) ? "RxData"	: "",
+			   (iRxIntType &amp; 0x02) ? "RxMaxLen"	: "",
+			   (iRxIntType &amp; 0x01) ? "SIR bad"	: "");
 		if (!iRxIntType)
-			DBG(printk(KERN_INFO " RxIRQ =0\n"));
-#endif
+			IRDA_DEBUG(3, "%s(): RxIRQ =0\n", __FUNCTION__);
+
 		if (iRxIntType &amp; 0x10) {
 			if (via_ircc_dma_receive_complete(self, iobase)) {
 //F01       if(!(IsFIROn(iobase)))  via_ircc_dma_receive(self);
@@ -1370,14 +1416,11 @@ static irqreturn_t via_ircc_interrupt(in
 			}
 		}		// No ERR     
 		else {		//ERR
-#ifdef	DBGMSG
-			DBG(printk
-			    (KERN_INFO
-			     " RxIRQ ERR:iRxIntType=%x,HostIntType=%x,CurCount=%x,RxLastCount=%x_____\n",
-			     iRxIntType, iHostIntType, RxCurCount(iobase,
-								  self),
-			     self-&gt;RxLastCount));
-#endif
+			IRDA_DEBUG(4, "%s(): RxIRQ ERR:iRxIntType=%x,HostIntType=%x,CurCount=%x,RxLastCount=%x_____\n",
+				   __FUNCTION__, iRxIntType, iHostIntType,
+				   RxCurCount(iobase, self),
+				   self-&gt;RxLastCount);
+
 			if (iRxIntType &amp; 0x20) {	//FIFO OverRun ERR
 				ResetChip(iobase, 0);
 				ResetChip(iobase, 1);
@@ -1398,9 +1441,9 @@ static void hwreset(struct via_ircc_cb *
 {
 	int iobase;
 	iobase = self-&gt;io.fir_base;
-#ifdef	DBGMSG
-	DBG(printk(KERN_INFO "hwreset  ....\n"));
-#endif
+
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
+
 	ResetChip(iobase, 5);
 	EnableDMA(iobase, OFF);
 	EnableTX(iobase, OFF);
@@ -1420,7 +1463,10 @@ static void hwreset(struct via_ircc_cb *
 	SetPulseWidth(iobase, 12);
 	SetSendPreambleCount(iobase, 0);
 	WriteReg(iobase, I_ST_CT_0, 0x80);
+
+	/* Restore speed. */
 	via_ircc_change_speed(self, self-&gt;io.speed);
+
 	self-&gt;st_fifo.len = 0;
 }
 
@@ -1440,9 +1486,9 @@ static int via_ircc_is_receiving(struct 
 	iobase = self-&gt;io.fir_base;
 	if (CkRxRecv(iobase, self))
 		status = TRUE;
-#ifdef	DBGMSG
-	DBG(printk(KERN_INFO "is_receiving  status=%x....\n", status));
-#endif
+
+	IRDA_DEBUG(2, "%s(): status=%x....\n", __FUNCTION__, status);
+
 	return status;
 }
 
@@ -1459,15 +1505,14 @@ static int via_ircc_net_open(struct net_
 	int iobase;
 	char hwname[32];
 
-	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	ASSERT(dev != NULL, return -1;);
 	self = (struct via_ircc_cb *) dev-&gt;priv;
 	self-&gt;stats.rx_packets = 0;
 	ASSERT(self != NULL, return 0;);
 	iobase = self-&gt;io.fir_base;
-	if (request_irq
-	    (self-&gt;io.irq, via_ircc_interrupt, 0, dev-&gt;name, dev)) {
+	if (request_irq(self-&gt;io.irq, via_ircc_interrupt, 0, dev-&gt;name, dev)) {
 		WARNING("%s, unable to allocate irq=%d\n", driver_name,
 			self-&gt;io.irq);
 		return -EAGAIN;
@@ -1496,6 +1541,10 @@ static int via_ircc_net_open(struct net_
 	EnAllInt(iobase, ON);
 	EnInternalLoop(iobase, OFF);
 	EnExternalLoop(iobase, OFF);
+
+	/* */
+	via_ircc_dma_receive(self);
+
 	/* Ready to play! */
 	netif_start_queue(dev);
 
@@ -1503,12 +1552,8 @@ static int via_ircc_net_open(struct net_
 	 * Open new IrLAP layer instance, now that everything should be
 	 * initialized properly 
 	 */
-	sprintf(hwname, "VIA");
-	/*
-	 * for different kernel ,irlap_open have different parameter.
-	 */
+	sprintf(hwname, "VIA @ 0x%x", iobase);
 	self-&gt;irlap = irlap_open(dev, &amp;self-&gt;qos, hwname);
-//      self-&gt;irlap = irlap_open(dev, &amp;self-&gt;qos);
 
 	self-&gt;RxLastCount = 0;
 
@@ -1526,16 +1571,12 @@ static int via_ircc_net_close(struct net
 	struct via_ircc_cb *self;
 	int iobase;
 
-	IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
+	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
 
 	ASSERT(dev != NULL, return -1;);
 	self = (struct via_ircc_cb *) dev-&gt;priv;
 	ASSERT(self != NULL, return 0;);
 
-#ifdef	DBG_IO
-	outb(0xff, 0x90);
-	outb(0xff, 0x94);
-#endif
 	/* Stop device */
 	netif_stop_queue(dev);
 	/* Stop and remove instance of IrLAP */
@@ -1572,7 +1613,7 @@ static int via_ircc_net_ioctl(struct net
 	ASSERT(dev != NULL, return -1;);
 	self = dev-&gt;priv;
 	ASSERT(self != NULL, return -1;);
-	IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev-&gt;name,
+	IRDA_DEBUG(1, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev-&gt;name,
 		   cmd);
 	/* Disable interrupts &amp; save flags */
 	spin_lock_irqsave(&amp;self-&gt;lock, flags);
diff -L drivers/net/irda/via-ircc.d0.c -puN /dev/null /dev/null
diff -L drivers/net/irda/via-ircc.d0.h -puN /dev/null /dev/null
diff -puN drivers/net/irda/via-ircc.h~irda-via-ircc-driver-speed-fixes drivers/net/irda/via-ircc.h
--- 25/drivers/net/irda/via-ircc.h~irda-via-ircc-driver-speed-fixes	Wed Oct 20 15:51:31 2004
+++ 25-akpm/drivers/net/irda/via-ircc.h	Wed Oct 20 15:51:31 2004
@@ -170,17 +170,6 @@ struct via_ircc_cb {
 			// Sets bit to 1
 #define ResetBit(val,bit) val= (unsigned char ) (val &amp; ~(0x1 &lt;&lt; bit))
 			// Sets bit to 0
-#define PCI_CONFIG_ADDRESS 0xcf8
-#define PCI_CONFIG_DATA    0xcfc
-
-#define VenderID    0x1106
-#define DeviceID1   0x8231
-#define DeviceID2   0x3109
-#define DeviceID3   0x3074
-//F01_S
-#define DeviceID4   0x3147
-#define DeviceID5   0x3177
-//F01_E
 
 #define OFF   0
 #define ON   1
@@ -794,7 +783,7 @@ static void SetBaudRate(__u16 iobase, __
 		value = 0;	// will automatically be fixed in 4M
 	}
 	temp = (ReadReg(iobase, I_CF_H_1) &amp; 0x03);
-	temp = temp | (value &lt;&lt; 2);
+	temp |= value &lt;&lt; 2;
 	WriteReg(iobase, I_CF_H_1, temp);
 }
 
@@ -805,9 +794,9 @@ static void SetPulseWidth(__u16 iobase, 
 	temp = (ReadReg(iobase, I_CF_L_1) &amp; 0x1f);
 	temp1 = (ReadReg(iobase, I_CF_H_1) &amp; 0xfc);
 	temp2 = (width &amp; 0x07) &lt;&lt; 5;
-	temp = temp | temp2;
+	temp |= temp2;
 	temp2 = (width &amp; 0x18) &gt;&gt; 3;
-	temp1 = temp1 | temp2;
+	temp1 |= temp2;
 	WriteReg(iobase, I_CF_L_1, temp);
 	WriteReg(iobase, I_CF_H_1, temp1);
 }
@@ -817,7 +806,7 @@ static void SetSendPreambleCount(__u16 i
 	__u8 temp;
 
 	temp = ReadReg(iobase, I_CF_L_1) &amp; 0xe0;
-	temp = temp | count;
+	temp |= count;
 	WriteReg(iobase, I_CF_L_1, temp);
 
 }
_
</pre></body></html>