Fix for Bug 2186 - QEMU baseport serial driver doesn't work with multiple UARTs and is unreliable
authorandrew.jordan <>
Sun, 02 May 2010 23:03:18 +0100
changeset 63 84dca1410127
parent 62 99ca724f9829
child 65 6b63d9a6077b
Fix for Bug 2186 - QEMU baseport serial driver doesn't work with multiple UARTs and is unreliable
baseport/syborg/serial/syborg_serial.cpp
baseport/syborg/serial/syborg_serial.h
--- a/baseport/syborg/serial/syborg_serial.cpp	Thu Apr 22 14:59:02 2010 +0100
+++ b/baseport/syborg/serial/syborg_serial.cpp	Sun May 02 23:03:18 2010 +0100
@@ -10,10 +10,10 @@
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
+* NTT DOCOMO, INC. -- Fix bug 2186 - QEMU baseport serial driver doesn't work with multiple UARTs and is unreliable
 *
 * Description: Minimalistic serial driver
 *
-* TODO: Handle multiple Units, hardcoded FIFO Size
 */
 
 #include "syborg_serial.h"
@@ -24,233 +24,287 @@
 #define DPRINT(x)
 #define DPRINT2(x,y)
 
+_LIT(KSerialDfcQName,"SerialDFC");
+const TInt KDfcQuePriority = 27;
 // ---------------------------------------------------------------
 // ---------------------------------------------------------------
 
 DDriverSyborgComm::DDriverSyborgComm()
-{
-  iVersion=TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber);
-}
+	{
+	DPRINT("DDriverSyborgComm::DDriverSyborgComm()");
+	iVersion=TVersion(KCommsMajorVersionNumber, KCommsMinorVersionNumber, KCommsBuildVersionNumber);
+	}
+
+ DDriverSyborgComm::~DDriverSyborgComm()
+	{
+	DPRINT("~DDriverSyborgComm::DDriverSyborgComm()");
+	}
 
 TInt DDriverSyborgComm::Install()
-{
-  DPRINT("DDriverSyborgComm::Install");
-  return SetName(&KPddName);
-}
+	{
+	DPRINT("DDriverSyborgComm::Install");
+	return SetName(&KPddName);
+	}
 
 void DDriverSyborgComm::GetCaps(TDes8 &aDes) const
-{
-  DPRINT("DDriverSyborgComm::GetCaps");
+	{
+	DPRINT("DDriverSyborgComm::GetCaps");
 
-  TCommCaps3 capsBuf;
-  TCommCapsV03 &c=capsBuf();
-  c.iRate=KCapsBps110|KCapsBps150|KCapsBps300|KCapsBps600|KCapsBps1200|KCapsBps2400|KCapsBps4800|KCapsBps9600|KCapsBps19200|KCapsBps38400|KCapsBps57600|KCapsBps115200|KCapsBps230400;
-  c.iDataBits=KCapsData5|KCapsData6|KCapsData7|KCapsData8;
-  c.iStopBits=KCapsStop1|KCapsStop2;
-  c.iParity=KCapsParityNone|KCapsParityEven|KCapsParityOdd;
-  c.iHandshake=KCapsObeyXoffSupported|KCapsSendXoffSupported|KCapsObeyCTSSupported|KCapsFailCTSSupported|KCapsObeyDSRSupported|KCapsFailDSRSupported|KCapsObeyDCDSupported|KCapsFailDCDSupported|KCapsFreeRTSSupported|KCapsFreeDTRSupported;
-  c.iSignals=KCapsSignalCTSSupported|KCapsSignalDSRSupported|KCapsSignalDCDSupported|KCapsSignalRTSSupported|KCapsSignalDTRSupported;
-  c.iSIR=0;
-  c.iNotificationCaps=KNotifyDataAvailableSupported|KNotifySignalsChangeSupported;
-  c.iFifo=KCapsHasFifo;
-  c.iRoleCaps=0;
-  c.iFlowControlCaps=0;
-  c.iBreakSupported=ETrue;
-  aDes.FillZ(aDes.MaxLength());
-  aDes=capsBuf.Left(Min(capsBuf.Length(),aDes.MaxLength()));
-}
+	TCommCaps3 capsBuf;
+	TCommCapsV03 &c=capsBuf();
+	c.iRate=KCapsBps110|KCapsBps150|KCapsBps300|KCapsBps600|KCapsBps1200|KCapsBps2400|KCapsBps4800|KCapsBps9600|KCapsBps19200|KCapsBps38400|KCapsBps57600|KCapsBps115200|KCapsBps230400;
+	c.iDataBits=KCapsData5|KCapsData6|KCapsData7|KCapsData8;
+	c.iStopBits=KCapsStop1|KCapsStop2;
+	c.iParity=KCapsParityNone|KCapsParityEven|KCapsParityOdd;
+	c.iHandshake=KCapsObeyXoffSupported|KCapsSendXoffSupported|KCapsObeyCTSSupported|KCapsFailCTSSupported|KCapsObeyDSRSupported|KCapsFailDSRSupported|KCapsObeyDCDSupported|KCapsFailDCDSupported|KCapsFreeRTSSupported|KCapsFreeDTRSupported;
+	c.iSignals=KCapsSignalCTSSupported|KCapsSignalDSRSupported|KCapsSignalDCDSupported|KCapsSignalRTSSupported|KCapsSignalDTRSupported;
+	c.iSIR=0;
+	c.iNotificationCaps=KNotifyDataAvailableSupported|KNotifySignalsChangeSupported;
+	c.iFifo=KCapsHasFifo;
+	c.iRoleCaps=0;
+	c.iFlowControlCaps=0;
+	c.iBreakSupported=ETrue;
+	aDes.FillZ(aDes.MaxLength());
+	aDes=capsBuf.Left(Min(capsBuf.Length(),aDes.MaxLength()));
+	}
 
 TInt DDriverSyborgComm::Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer)
-{
-  DPRINT("DDriverSyborgComm::Create");
+	{
+	DPRINT("DDriverSyborgComm::Create");
 
-  DCommSyborgSoc* pD=new DCommSyborgSoc;
-  aChannel=pD;
-  TInt r=KErrNoMemory;
-  if (pD)
-	r=pD->DoCreate(aUnit,anInfo);
-  return r;
-}
+	DCommSyborgSoc* pD=new DCommSyborgSoc(this);
+	aChannel=pD;
+	TInt r=KErrNoMemory;
+	if (pD)
+		{
+		r=pD->DoCreate(aUnit,anInfo);
+		}
+	return r;
+	}
 
 TInt DDriverSyborgComm::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer)
-{
-  DPRINT("DDriverSyborgComm::Validate");
-  if ((!Kern::QueryVersionSupported(iVersion,aVer)) || 
+	{
+	DPRINT("DDriverSyborgComm::Validate");
+	if ((!Kern::QueryVersionSupported(iVersion,aVer)) ||
 	  (!Kern::QueryVersionSupported(aVer,TVersion(KMinimumLddMajorVersion,KMinimumLddMinorVersion,KMinimumLddBuild))))
-	return KErrNotSupported;
-  return KErrNone;
-}
+		return KErrNotSupported;
+	return KErrNone;
+	}
+
+/* Reference counted open on Serial Block Drivers DfcQueue */
+TInt DDriverSyborgComm::OpenDfcQueue()
+	{
+	DPRINT("DDriverSyborgComm::OpenDfcQueue()");
+	if (iDfcQRefCount > 0)
+		{
+		iDfcQRefCount++;
+		return KErrNone;
+		}
+		
+	TInt err = Kern::DynamicDfcQCreate(iDfcQueue, KDfcQuePriority, KSerialDfcQName);
+ 
+    if (!err)
+		{
+		iDfcQRefCount++;
+		}
+    return err;
+  }
+
+/*  Reference counted open on Serial Block Drivers DfcQueue */
+void DDriverSyborgComm::CloseDfcQueue()
+	{
+	DPRINT("DDriverSyborgComm::CloseDfcQueue()");
+    iDfcQRefCount--;
+    if (iDfcQRefCount == 0)
+		{
+		iDfcQueue->Destroy();
+		}
+	}
+
+TDfcQue* DDriverSyborgComm::DfcQueue()
+	{
+    return iDfcQueue;
+	}
 
 // ---------------------------------------------------------------
 // ---------------------------------------------------------------
 
-DCommSyborgSoc::DCommSyborgSoc()
-{
-}
+DCommSyborgSoc::DCommSyborgSoc(DDriverSyborgComm* aDriverSyborgComm)
+	:iDriverSyborgComm(aDriverSyborgComm)
+	{
+	}
 
 DCommSyborgSoc::~DCommSyborgSoc()
-{
-  Interrupt::Unbind(iIrq);
-}
-
-TInt DCommSyborgSoc::DoCreate(TInt aUnit, const TDesC8* /*anInfo*/)
-{
-  DPRINT2("DCommSyborgSoc::DoCreate %d",aUnit);
-  switch(aUnit)
 	{
-	case 0:
-	  iPortAddr = KHwBaseUart0;
-	  iIrq = EIntSerial0;
-	  break;
-	case 1:
-	  iPortAddr = KHwBaseUart1;
-	  iIrq = EIntSerial1;
-	  break;
-	case 2:
-	  iPortAddr = KHwBaseUart2;
-	  iIrq = EIntSerial2;
-	  break;
-	case 3:
-	  iPortAddr = KHwBaseUart3;
-	  iIrq = EIntSerial3;
-	  break;
-	default:
-	  iPortAddr = KHwBaseUart0;
-	  iIrq = EIntSerial0;
-	  break;
+	(TInt)Interrupt::Unbind(iIrq);
+	if (iDfcQueueOpened)
+		{
+		iDriverSyborgComm->CloseDfcQueue();
+		}
 	}
 
-  Interrupt::Bind(EIntSerial0,Isr,this);
+TInt DCommSyborgSoc::DoCreate(TInt aUnit, const TDesC8* /*anInfo*/)
+	{
+	DPRINT2("DCommSyborgSoc::DoCreate %d",aUnit);
+	TInt err = KErrNone;
+	switch(aUnit)
+		{
+		case 0:
+			iPortAddr = KHwBaseUart0;
+			iIrq = EIntSerial0;
+			break;
+		case 1:
+			iPortAddr = KHwBaseUart1;
+			iIrq = EIntSerial1;
+			break;
+		case 2:
+			iPortAddr = KHwBaseUart2;
+			iIrq = EIntSerial2;
+			break;
+		case 3:
+			iPortAddr = KHwBaseUart3;
+			iIrq = EIntSerial3;
+			break;
+		default:
+			err = KErrNotSupported;
+		break;
+		}
 
-  return KErrNone;
-
-}
+	if (!err)
+		{
+		err = iDriverSyborgComm->OpenDfcQueue();
+		iDfcQueueOpened = ETrue;
+		}
+	if (!err)
+		{
+		err = Interrupt::Bind(iIrq,Isr,this);
+		}
+	return err;
+	}
 
 TInt DCommSyborgSoc::Start()
-{
-  DPRINT("DCommSyborgSoc::Start");
-  WriteReg(iPortAddr, SERIAL_INT_ENABLE, 0x1);
-  Interrupt::Enable(iIrq);
-  return KErrNone;
-}
+	{
+	DPRINT("DCommSyborgSoc::Start");
+	WriteReg(iPortAddr, SERIAL_INT_ENABLE, 0x1);
+	TInt err = Interrupt::Enable(iIrq);
+	return err;
+	}
 
 void DCommSyborgSoc::Stop(TStopMode aMode)
-{
-  DPRINT("DCommSyborgSoc::Stop");
-  WriteReg(iPortAddr, SERIAL_INT_ENABLE, 0x0);
-  Interrupt::Disable(iIrq);
-}
+	{
+	DPRINT("DCommSyborgSoc::Stop");
+	WriteReg(iPortAddr, SERIAL_INT_ENABLE, 0x0);
+	(TInt)Interrupt::Disable(iIrq);
+	}
 
 void DCommSyborgSoc::Break(TBool aState)
-{
-  DPRINT("DCommSyborgSoc::Break");
-}
+	{
+	DPRINT("DCommSyborgSoc::Break");
+	}
 
 void DCommSyborgSoc::EnableTransmit()
-{
-  DPRINT("DCommSyborgSoc::EnableTransmit");
-  while (Kern::PowerGood())
 	{
-	  TInt r=TransmitIsr();
-	  if (r<0)
-		break;
-	  WriteReg(iPortAddr, SERIAL_DATA, r);
+	DPRINT("DCommSyborgSoc::EnableTransmit");
+	while (Kern::PowerGood())
+		{
+		TInt r=TransmitIsr();
+		if (r<0)
+			{
+			break;
+			}
+		WriteReg(iPortAddr, SERIAL_DATA, r);
+		}
+
+	// Request LDD to check if more data is available in the client buffer.
+	// TransmitISR only copies data from the LDD buffer which is 1k.
+	iLdd->CheckTxBuffer();
 	}
 
-	iLdd->iTxError = KErrNone;
-	iLdd->iTxCompleteDfc.Add();
-
-}
-
 TUint DCommSyborgSoc::Signals() const
-{
-  DPRINT("DCommSyborgSoc::Signals");
-  return(0);
-}
-  
+	{
+	DPRINT("DCommSyborgSoc::Signals");
+	return(0);
+	}
+
 void DCommSyborgSoc::SetSignals(TUint aSetMask, TUint aClearMask)
-{
-  DPRINT("DCommSyborgSoc::SetSignals");
-}
+	{
+	DPRINT("DCommSyborgSoc::SetSignals");
+	}
 
 TInt DCommSyborgSoc::ValidateConfig(const TCommConfigV01 &aConfig) const
-{
-  DPRINT("DCommSyborgSoc::ValidateConfig");
-  return KErrNone;
-}
+	{
+	DPRINT("DCommSyborgSoc::ValidateConfig");
+	return KErrNone;
+	}
 
 void DCommSyborgSoc::Configure(TCommConfigV01 &aConfig)
-{
-  DPRINT("DCommSyborgSoc::Configure");
-}
+	{
+	DPRINT("DCommSyborgSoc::Configure");
+	}
 
 void DCommSyborgSoc::Caps(TDes8 &aCaps) const
-{
-  DPRINT("DCommSyborgSoc::Caps");
-  TCommCaps3 capsBuf;
-  TCommCapsV03 &c=capsBuf();
-  c.iRate=KCapsBps110|KCapsBps150|KCapsBps300|KCapsBps600|KCapsBps1200|KCapsBps2400|KCapsBps4800|KCapsBps9600|KCapsBps19200|KCapsBps38400|KCapsBps57600|KCapsBps115200|KCapsBps230400;
-  c.iDataBits=KCapsData5|KCapsData6|KCapsData7|KCapsData8;
-  c.iStopBits=KCapsStop1|KCapsStop2;
-  c.iParity=KCapsParityNone|KCapsParityEven|KCapsParityOdd;
-  c.iHandshake=KCapsObeyXoffSupported|KCapsSendXoffSupported|KCapsObeyCTSSupported|KCapsFailCTSSupported|KCapsObeyDSRSupported|KCapsFailDSRSupported|KCapsObeyDCDSupported|KCapsFailDCDSupported|KCapsFreeRTSSupported|KCapsFreeDTRSupported;
-  c.iSignals=KCapsSignalCTSSupported|KCapsSignalDSRSupported|KCapsSignalDCDSupported|KCapsSignalRTSSupported|KCapsSignalDTRSupported;
-  c.iSIR=0;
-  c.iNotificationCaps=KNotifyDataAvailableSupported|KNotifySignalsChangeSupported;
-  c.iFifo=KCapsHasFifo;
-  c.iRoleCaps=0;
-  c.iFlowControlCaps=0;
-  c.iBreakSupported=ETrue;
-  aCaps.FillZ(aCaps.MaxLength());
-  aCaps=capsBuf.Left(Min(capsBuf.Length(),aCaps.MaxLength()));
-}
+	{
+	DPRINT("DCommSyborgSoc::Caps");
+	TCommCaps3 capsBuf;
+	TCommCapsV03 &c=capsBuf();
+	c.iRate=KCapsBps110|KCapsBps150|KCapsBps300|KCapsBps600|KCapsBps1200|KCapsBps2400|KCapsBps4800|KCapsBps9600|KCapsBps19200|KCapsBps38400|KCapsBps57600|KCapsBps115200|KCapsBps230400;
+	c.iDataBits=KCapsData5|KCapsData6|KCapsData7|KCapsData8;
+	c.iStopBits=KCapsStop1|KCapsStop2;
+	c.iParity=KCapsParityNone|KCapsParityEven|KCapsParityOdd;
+	c.iHandshake=KCapsObeyXoffSupported|KCapsSendXoffSupported|KCapsObeyCTSSupported|KCapsFailCTSSupported|KCapsObeyDSRSupported|KCapsFailDSRSupported|KCapsObeyDCDSupported|KCapsFailDCDSupported|KCapsFreeRTSSupported|KCapsFreeDTRSupported;
+	c.iSignals=KCapsSignalCTSSupported|KCapsSignalDSRSupported|KCapsSignalDCDSupported|KCapsSignalRTSSupported|KCapsSignalDTRSupported;
+	c.iSIR=0;
+	c.iNotificationCaps=KNotifyDataAvailableSupported|KNotifySignalsChangeSupported;
+	c.iFifo=KCapsHasFifo;
+	c.iRoleCaps=0;
+	c.iFlowControlCaps=0;
+	c.iBreakSupported=ETrue;
+	aCaps.FillZ(aCaps.MaxLength());
+	aCaps=capsBuf.Left(Min(capsBuf.Length(),aCaps.MaxLength()));
+	}
 
 TInt DCommSyborgSoc::DisableIrqs()
-{
-  DPRINT("DCommSyborgSoc::DisableIrqs");
-  return NKern::DisableAllInterrupts();
-}
+	{
+	DPRINT("DCommSyborgSoc::DisableIrqs");
+	return NKern::DisableAllInterrupts();
+	}
 
 void DCommSyborgSoc::RestoreIrqs(TInt aIrq)
-{
-  DPRINT("DCommSyborgSoc::RestoreIrqs");
-  NKern::RestoreInterrupts(aIrq);
-}
+	{
+	DPRINT("DCommSyborgSoc::RestoreIrqs");
+	NKern::RestoreInterrupts(aIrq);
+	}
 
-TDfcQue* DCommSyborgSoc::DfcQ(TInt /*aUnit*/)
-{
-  return Kern::DfcQue0();
-}
+TDfcQue* DCommSyborgSoc::DfcQ(TInt aUnit)
+	{
+	return iDriverSyborgComm->DfcQueue();
+	}
 
 void DCommSyborgSoc::CheckConfig(TCommConfigV01& aConfig)
-{
-  DPRINT("DCommSyborgSoc::CheckConfig");
-}
+	{
+	DPRINT("DCommSyborgSoc::CheckConfig");
+	}
 
 void DCommSyborgSoc::Isr(TAny* aPtr)
-{
-  DCommSyborgSoc& d=*(DCommSyborgSoc*)aPtr;
-  TUint rx[32];
-  TInt rxi=0;
-
-  DPRINT2("DCommSyborgSoc::Isr %x",d.iIrq);
-
-  // Is now auto clear
-  //  WriteReg(d.iPortAddr, SERIAL_CLEAR_INT, 0x0); // clear interrupts
+	{
+	DCommSyborgSoc& d=*(DCommSyborgSoc*)aPtr;
+	TUint rx[32];
+	TInt rxi=0;
 
-  while(ReadReg(d.iPortAddr, SERIAL_FIFO_COUNT)!=0) {
-	TUint ch = ReadReg(d.iPortAddr, SERIAL_DATA);
-	rx[rxi++]=ch;
-  }
-  d.ReceiveIsr(rx,rxi,0);
-}
+	TInt fifo = ReadReg(d.iPortAddr, SERIAL_FIFO_COUNT );
+	while(fifo > 0 && rxi<32)
+		{
+		TUint ch = ReadReg(d.iPortAddr, SERIAL_DATA);
+		rx[rxi++]=ch;
 
-// ---------------------------------------------------------------
-// ---------------------------------------------------------------
+		fifo = ReadReg(d.iPortAddr, SERIAL_FIFO_COUNT );
+		}
+	d.ReceiveIsr(rx,rxi,0);
+	}
 
 DECLARE_STANDARD_PDD()
-{
-  DPRINT("DECLARE_STANDARD_PDD()");
-  return new DDriverSyborgComm;
-}
+	{
+	DPRINT("DECLARE_STANDARD_PDD()");
+	return new DDriverSyborgComm;
+	}
 
--- a/baseport/syborg/serial/syborg_serial.h	Thu Apr 22 14:59:02 2010 +0100
+++ b/baseport/syborg/serial/syborg_serial.h	Sun May 02 23:03:18 2010 +0100
@@ -10,6 +10,7 @@
 * Nokia Corporation - initial contribution.
 *
 * Contributors:
+* NTT DOCOMO, INC. -- Fix bug 2186 - QEMU baseport serial driver doesn't work with multiple UARTs and is unreliable
 *
 * Description: Minimalistic serial driver
 *
@@ -26,52 +27,75 @@
 const TInt KMinimumLddMinorVersion=1;
 const TInt KMinimumLddBuild=1;
 
+/**
+ * Serial Ports Device Driver
+ *
+ *
+ **/
 class DDriverSyborgComm : public DPhysicalDevice
-{
+	{
 public:
   DDriverSyborgComm();
+  ~DDriverSyborgComm();
   virtual TInt Install();
   virtual void GetCaps(TDes8 &aDes) const;
   virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion &aVer);
   virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer);
-};
 
-class DCommSyborgSoc : public DComm
-{
-public:
-  DCommSyborgSoc();
-  ~DCommSyborgSoc();
-  TInt DoCreate(TInt aUnit, const TDesC8* anInfo);
+// interface for single comm port.
 public:
-  virtual TInt Start();
-  virtual void Stop(TStopMode aMode);
-  virtual void Break(TBool aState);
-  virtual void EnableTransmit();
-  virtual TUint Signals() const;
-  virtual void SetSignals(TUint aSetMask, TUint aClearMask);
-  virtual TInt ValidateConfig(const TCommConfigV01 &aConfig) const;
-  virtual void Configure(TCommConfigV01 &aConfig);
-  virtual void Caps(TDes8 &aCaps) const;
-  virtual TInt DisableIrqs();
-  virtual void RestoreIrqs(TInt aIrq);
-  virtual TDfcQue* DfcQ(TInt aUnit);
-  virtual void CheckConfig(TCommConfigV01& aConfig);  
-  static void Isr(TAny* aPtr);
+  TInt OpenDfcQueue();
+  void CloseDfcQueue();
+  TDfcQue* DfcQueue();
+
+private:
+	TDynamicDfcQue* 	iDfcQueue;				// single Dfc queue for all comm ports
+	TUint8  			iDfcQRefCount;			// reference count for dfc queue
+	};
+
+
+
+/**
+ * Driver for a single Comm port
+ **/
+class DCommSyborgSoc : public DComm
+	{
+public:
+	DCommSyborgSoc(DDriverSyborgComm* aDriverSyborgComm);
+	~DCommSyborgSoc();
+	TInt DoCreate(TInt aUnit, const TDesC8* anInfo);
+public:
+	virtual TInt Start();
+	virtual void Stop(TStopMode aMode);
+	virtual void Break(TBool aState);
+	virtual void EnableTransmit();
+	virtual TUint Signals() const;
+	virtual void SetSignals(TUint aSetMask, TUint aClearMask);
+	virtual TInt ValidateConfig(const TCommConfigV01 &aConfig) const;
+	virtual void Configure(TCommConfigV01 &aConfig);
+	virtual void Caps(TDes8 &aCaps) const;
+	virtual TInt DisableIrqs();
+	virtual void RestoreIrqs(TInt aIrq);
+	virtual TDfcQue* DfcQ(TInt aUnit);
+	virtual void CheckConfig(TCommConfigV01& aConfig);
+	static void Isr(TAny* aPtr);
 
 public:
-  TLinAddr iPortAddr;
-  TInt iIrq;
+	DDriverSyborgComm* iDriverSyborgComm;
+	TLinAddr iPortAddr;
+	TInt iIrq;
+	TBool iDfcQueueOpened;
 
-  enum {
-    SERIAL_ID           = 0,
-    SERIAL_DATA         = 1,
-    SERIAL_FIFO_COUNT   = 2,
-    SERIAL_INT_ENABLE   = 3,
-    SERIAL_DMA_TX_ADDR  = 4,
-    SERIAL_DMA_TX_COUNT = 5, /* triggers dma */
-    SERIAL_DMA_RX_ADDR  = 6,
-    SERIAL_DMA_RX_COUNT = 7 /* triggers dma */
-  };
-};
+	enum {
+		SERIAL_ID           = 0,
+		SERIAL_DATA         = 1,
+		SERIAL_FIFO_COUNT   = 2,
+		SERIAL_INT_ENABLE   = 3,
+		SERIAL_DMA_TX_ADDR  = 4,
+		SERIAL_DMA_TX_COUNT = 5, /* triggers dma */
+		SERIAL_DMA_RX_ADDR  = 6,
+		SERIAL_DMA_RX_COUNT = 7 /* triggers dma */
+		};
+	};
 
 #endif