r3672 - branches/src/target/kernel/2.6.24.x/patches

laforge at sita.openmoko.org laforge at sita.openmoko.org
Tue Dec 18 10:49:39 CET 2007


Author: laforge
Date: 2007-12-18 10:49:36 +0100 (Tue, 18 Dec 2007)
New Revision: 3672

Added:
   branches/src/target/kernel/2.6.24.x/patches/s3c2410_ts-gta01.patch
   branches/src/target/kernel/2.6.24.x/patches/s3c_mci-gta01.patch
Removed:
   branches/src/target/kernel/2.6.24.x/patches/ts0710.patch
Modified:
   branches/src/target/kernel/2.6.24.x/patches/gta01-core.patch
   branches/src/target/kernel/2.6.24.x/patches/gta01-pcf50606.patch
   branches/src/target/kernel/2.6.24.x/patches/series
Log:
* reorder patches to reflect proposed kernel merge schedule
* remove defunct old ts0710 skeleton
* pcf50606: implement per-second irq disable/re-enable in case of time adjustment
* gta01-core: separate out non-mainline-compatible touchscreen and sd/mmc bits


Modified: branches/src/target/kernel/2.6.24.x/patches/gta01-core.patch
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/gta01-core.patch	2007-12-18 04:11:54 UTC (rev 3671)
+++ branches/src/target/kernel/2.6.24.x/patches/gta01-core.patch	2007-12-18 09:49:36 UTC (rev 3672)
@@ -7,7 +7,7 @@
 ===================================================================
 --- linux-2.6.orig/arch/arm/mach-s3c2410/Kconfig
 +++ linux-2.6/arch/arm/mach-s3c2410/Kconfig
-@@ -116,5 +116,13 @@
+@@ -110,5 +110,13 @@
  	help
  	   Say Y here if you are using the Armzone QT2410
  
@@ -25,7 +25,7 @@
 ===================================================================
 --- linux-2.6.orig/arch/arm/mach-s3c2410/Makefile
 +++ linux-2.6/arch/arm/mach-s3c2410/Makefile
-@@ -30,3 +30,4 @@
+@@ -29,3 +29,4 @@
  obj-$(CONFIG_BAST_PC104_IRQ)	+= bast-irq.o
  obj-$(CONFIG_MACH_VR1000)	+= mach-vr1000.o usb-simtec.o
  obj-$(CONFIG_MACH_QT2410)	+= mach-qt2410.o
@@ -34,7 +34,7 @@
 ===================================================================
 --- /dev/null
 +++ linux-2.6/arch/arm/mach-s3c2410/mach-gta01.c
-@@ -0,0 +1,740 @@
+@@ -0,0 +1,657 @@
 +/*
 + * linux/arch/arm/mach-s3c2410/mach-gta01.c
 + *
@@ -80,6 +80,8 @@
 +#include <linux/mtd/nand_ecc.h>
 +#include <linux/mtd/partitions.h>
 +
++#include <linux/mmc/host.h>
++
 +#include <linux/pcf50606.h>
 +
 +#include <asm/mach/arch.h>
@@ -93,8 +95,6 @@
 +
 +#include <asm/arch/regs-gpio.h>
 +#include <asm/arch/fb.h>
-+#include <asm/arch/mci.h>
-+#include <asm/arch/ts.h>
 +#include <asm/arch/spi.h>
 +#include <asm/arch/spi-gpio.h>
 +#include <asm/arch/usb-control.h>
@@ -399,7 +399,6 @@
 +	&s3c_device_sdi,
 +	&s3c_device_usbgadget,
 +	&s3c_device_nand,
-+	&s3c_device_ts,
 +};
 +
 +static struct s3c2410_nand_set gta01_nand_sets[] = {
@@ -417,79 +416,6 @@
 +	.sets		= gta01_nand_sets,
 +};
 +
-+static unsigned int mmc_millivolts[] = {
-+	[MMC_VDD_145_150]	= 1500,
-+	[MMC_VDD_150_155]	= 1500,
-+	[MMC_VDD_155_160]	= 1600,
-+	[MMC_VDD_160_165]	= 1600,
-+	[MMC_VDD_165_170]	= 1700,
-+	[MMC_VDD_17_18]		= 1800,
-+	[MMC_VDD_18_19]		= 1900,
-+	[MMC_VDD_19_20]		= 2000,
-+	[MMC_VDD_20_21]		= 2100,
-+	[MMC_VDD_21_22]		= 2200,
-+	[MMC_VDD_22_23]		= 2300,
-+	[MMC_VDD_23_24]		= 2400,
-+	[MMC_VDD_24_25]		= 2500,
-+	[MMC_VDD_25_26]		= 2600,
-+	[MMC_VDD_26_27]		= 2700,
-+	[MMC_VDD_27_28]		= 2800,
-+	[MMC_VDD_28_29]		= 2900,
-+	[MMC_VDD_29_30]		= 3000,
-+	[MMC_VDD_30_31]		= 3100,
-+	[MMC_VDD_31_32]		= 3200,
-+	[MMC_VDD_32_33]		= 3300,
-+};
-+
-+static void gta01_mmc_set_power(unsigned char power_mode, unsigned short vdd)
-+{
-+	printk(KERN_DEBUG "mmc_set_power(power_mode=%u, vdd=%u\n",
-+	       power_mode, vdd);
-+
-+	switch (system_rev) {
-+	case GTA01v3_SYSTEM_REV:
-+		switch (power_mode) {
-+		case MMC_POWER_OFF:
-+			pcf50606_onoff_set(pcf50606_global,
-+					   PCF50606_REGULATOR_D2REG, 0);
-+			break;
-+		case MMC_POWER_ON:
-+			pcf50606_voltage_set(pcf50606_global,
-+					     PCF50606_REGULATOR_D2REG,
-+					     mmc_millivolts[vdd]);
-+			pcf50606_onoff_set(pcf50606_global,
-+					   PCF50606_REGULATOR_D2REG, 1);
-+			break;
-+		}
-+		break;
-+	case GTA01v4_SYSTEM_REV:
-+	case GTA01Bv2_SYSTEM_REV:
-+	case GTA01Bv3_SYSTEM_REV:
-+	case GTA01Bv4_SYSTEM_REV:
-+		switch (power_mode) {
-+		case MMC_POWER_OFF:
-+			s3c2410_gpio_setpin(GTA01_GPIO_SDMMC_ON, 1);
-+			break;
-+		case MMC_POWER_ON:
-+			s3c2410_gpio_setpin(GTA01_GPIO_SDMMC_ON, 0);
-+			break;
-+		}
-+		break;
-+	}
-+}
-+
-+static struct s3c24xx_mci_pdata gta01_mmc_cfg = {
-+	.gpio_detect	= GTA01_GPIO_nSD_DETECT,
-+	.set_power	= &gta01_mmc_set_power,
-+	.ocr_avail	= MMC_VDD_145_150|MMC_VDD_150_155|MMC_VDD_155_160|
-+			  MMC_VDD_160_165| MMC_VDD_165_170|MMC_VDD_17_18|
-+			  MMC_VDD_18_19|MMC_VDD_19_20|MMC_VDD_20_21|
-+			  MMC_VDD_21_22|MMC_VDD_22_23|MMC_VDD_23_24|
-+			  MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27|
-+			  MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
-+			  MMC_VDD_30_31|MMC_VDD_31_32|MMC_VDD_32_33,
-+};
-+
 +static void gta01_udc_command(enum s3c2410_udc_cmd_e cmd)
 +{
 +	printk(KERN_DEBUG "%s(%d)\n", __func__, cmd);
@@ -544,12 +470,6 @@
 +	.vbus_draw	= gta01_udc_vbus_draw,
 +};
 +
-+static struct s3c2410_ts_mach_info gta01_ts_cfg = {
-+	.delay = 10000,
-+	.presc = 65,
-+	.oversampling_shift = 5,
-+};
-+
 +/* SPI */
 +
 +static struct spi_board_info gta01_spi_board_info[] __initdata = {
@@ -706,18 +626,15 @@
 +	    system_rev == GTA01Bv3_SYSTEM_REV ||
 +	    system_rev == GTA01Bv4_SYSTEM_REV) {
 +		gta01_udc_cfg.udc_command = gta01_udc_command;
-+		gta01_mmc_cfg.ocr_avail = MMC_VDD_32_33;
 +	}
 +
 +	s3c_device_usb.dev.platform_data = &gta01_usb_info;
 +	s3c_device_nand.dev.platform_data = &gta01_nand_info;
-+	s3c_device_sdi.dev.platform_data = &gta01_mmc_cfg;
 +
 +	s3c24xx_fb_set_platdata(&gta01_lcd_cfg);
 +
 +	INIT_WORK(&gta01_udc_vbus_drawer.work, __gta01_udc_vbus_draw);
 +	s3c24xx_udc_set_platdata(&gta01_udc_cfg);
-+	set_s3c2410ts_info(&gta01_ts_cfg);
 +
 +	/* Set LCD_RESET / XRES to high */
 +	s3c2410_gpio_cfgpin(S3C2410_GPC6, S3C2410_GPIO_OUTPUT);

Modified: branches/src/target/kernel/2.6.24.x/patches/gta01-pcf50606.patch
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/gta01-pcf50606.patch	2007-12-18 04:11:54 UTC (rev 3671)
+++ branches/src/target/kernel/2.6.24.x/patches/gta01-pcf50606.patch	2007-12-18 09:49:36 UTC (rev 3672)
@@ -8,7 +8,7 @@
 ===================================================================
 --- /dev/null
 +++ linux-2.6/drivers/i2c/chips/pcf50606.c
-@@ -0,0 +1,1935 @@
+@@ -0,0 +1,1943 @@
 +/* Philips/NXP PCF50606 Power Management Unit (PMU) driver
 + *
 + * (C) 2006-2007 by OpenMoko, Inc.
@@ -1189,6 +1189,7 @@
 +	struct i2c_client *client = to_i2c_client(dev);
 +	struct pcf50606_data *pcf = i2c_get_clientdata(client);
 +	struct pcf50606_time pcf_tm;
++	u_int8_t int1m;
 +
 +	dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n",
 +		tm->tm_mday, tm->tm_mon, tm->tm_year,
@@ -1199,7 +1200,11 @@
 +		pcf_tm.hour, pcf_tm.min, pcf_tm.sec);
 +
 +	mutex_lock(&pcf->lock);
-+	/* FIXME: disable second interrupt */
++
++	/* disable SECOND interrupt */
++	int1m = __reg_read(pcf, PCF50606_REG_INT1M);
++	__reg_write(pcf, PCF50606_REG_INT1M, int1m | PCF50606_INT1_SECOND);
++
 +	__reg_write(pcf, PCF50606_REG_RTCSC, pcf_tm.sec);
 +	__reg_write(pcf, PCF50606_REG_RTCMN, pcf_tm.min);
 +	__reg_write(pcf, PCF50606_REG_RTCHR, pcf_tm.hour);
@@ -1207,7 +1212,10 @@
 +	__reg_write(pcf, PCF50606_REG_RTCDT, pcf_tm.day);
 +	__reg_write(pcf, PCF50606_REG_RTCMT, pcf_tm.month);
 +	__reg_write(pcf, PCF50606_REG_RTCYR, pcf_tm.year);
-+	/* FIXME: re-enable second interrupt */
++
++	/* restore INT1M, potentially re-enable SECOND interrupt */
++	__reg_write(pcf, PCF50606_REG_INT1M, int1m);
++
 +	mutex_unlock(&pcf->lock);
 +
 +	return 0;

Added: branches/src/target/kernel/2.6.24.x/patches/s3c2410_ts-gta01.patch
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/s3c2410_ts-gta01.patch	2007-12-18 04:11:54 UTC (rev 3671)
+++ branches/src/target/kernel/2.6.24.x/patches/s3c2410_ts-gta01.patch	2007-12-18 09:49:36 UTC (rev 3672)
@@ -0,0 +1,41 @@
+Index: linux-2.6/arch/arm/mach-s3c2410/mach-gta01.c
+===================================================================
+--- linux-2.6.orig/arch/arm/mach-s3c2410/mach-gta01.c
++++ linux-2.6/arch/arm/mach-s3c2410/mach-gta01.c
+@@ -33,6 +33,7 @@
+ #include <linux/workqueue.h>
+ #include <linux/platform_device.h>
+ #include <linux/serial_core.h>
++#include <asm/arch/ts.h>
+ #include <linux/spi/spi.h>
+ #include <linux/spi/spi_bitbang.h>
+ #include <linux/mmc/mmc.h>
+@@ -362,6 +363,7 @@
+ 	&s3c_device_sdi,
+ 	&s3c_device_usbgadget,
+ 	&s3c_device_nand,
++	&s3c_device_ts,
+ };
+ 
+ static struct s3c2410_nand_set gta01_nand_sets[] = {
+@@ -433,6 +435,12 @@
+ 	.vbus_draw	= gta01_udc_vbus_draw,
+ };
+ 
++static struct s3c2410_ts_mach_info gta01_ts_cfg = {
++	.delay = 10000,
++	.presc = 65,
++	.oversampling_shift = 5,
++};
++
+ /* SPI */
+ 
+ static struct spi_board_info gta01_spi_board_info[] __initdata = {
+@@ -598,6 +606,7 @@
+ 
+ 	INIT_WORK(&gta01_udc_vbus_drawer.work, __gta01_udc_vbus_draw);
+ 	s3c24xx_udc_set_platdata(&gta01_udc_cfg);
++	set_s3c2410ts_info(&gta01_ts_cfg);
+ 
+ 	/* Set LCD_RESET / XRES to high */
+ 	s3c2410_gpio_cfgpin(S3C2410_GPC6, S3C2410_GPIO_OUTPUT);

Added: branches/src/target/kernel/2.6.24.x/patches/s3c_mci-gta01.patch
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/s3c_mci-gta01.patch	2007-12-18 04:11:54 UTC (rev 3671)
+++ branches/src/target/kernel/2.6.24.x/patches/s3c_mci-gta01.patch	2007-12-18 09:49:36 UTC (rev 3672)
@@ -0,0 +1,96 @@
+Index: linux-2.6/arch/arm/mach-s3c2410/mach-gta01.c
+===================================================================
+--- linux-2.6.orig/arch/arm/mach-s3c2410/mach-gta01.c
++++ linux-2.6/arch/arm/mach-s3c2410/mach-gta01.c
+@@ -59,6 +59,7 @@
+ 
+ #include <asm/arch/regs-gpio.h>
+ #include <asm/arch/fb.h>
++#include <asm/arch/mci.h>
+ #include <asm/arch/spi.h>
+ #include <asm/arch/spi-gpio.h>
+ #include <asm/arch/usb-control.h>
+@@ -381,6 +382,70 @@
+ 	.sets		= gta01_nand_sets,
+ };
+ 
++static unsigned int mmc_millivolts[] = {
++	[MMC_VDD_165_195]	= 1700,
++	[MMC_VDD_20_21]		= 2100,
++	[MMC_VDD_21_22]		= 2200,
++	[MMC_VDD_22_23]		= 2300,
++	[MMC_VDD_23_24]		= 2400,
++	[MMC_VDD_24_25]		= 2500,
++	[MMC_VDD_25_26]		= 2600,
++	[MMC_VDD_26_27]		= 2700,
++	[MMC_VDD_27_28]		= 2800,
++	[MMC_VDD_28_29]		= 2900,
++	[MMC_VDD_29_30]		= 3000,
++	[MMC_VDD_30_31]		= 3100,
++	[MMC_VDD_31_32]		= 3200,
++	[MMC_VDD_32_33]		= 3300,
++};
++
++static void gta01_mmc_set_power(unsigned char power_mode, unsigned short vdd)
++{
++	printk(KERN_DEBUG "mmc_set_power(power_mode=%u, vdd=%u\n",
++	       power_mode, vdd);
++
++	switch (system_rev) {
++	case GTA01v3_SYSTEM_REV:
++		switch (power_mode) {
++		case MMC_POWER_OFF:
++			pcf50606_onoff_set(pcf50606_global,
++					   PCF50606_REGULATOR_D2REG, 0);
++			break;
++		case MMC_POWER_ON:
++			pcf50606_voltage_set(pcf50606_global,
++					     PCF50606_REGULATOR_D2REG,
++					     mmc_millivolts[vdd]);
++			pcf50606_onoff_set(pcf50606_global,
++					   PCF50606_REGULATOR_D2REG, 1);
++			break;
++		}
++		break;
++	case GTA01v4_SYSTEM_REV:
++	case GTA01Bv2_SYSTEM_REV:
++	case GTA01Bv3_SYSTEM_REV:
++	case GTA01Bv4_SYSTEM_REV:
++		switch (power_mode) {
++		case MMC_POWER_OFF:
++			s3c2410_gpio_setpin(GTA01_GPIO_SDMMC_ON, 1);
++			break;
++		case MMC_POWER_ON:
++			s3c2410_gpio_setpin(GTA01_GPIO_SDMMC_ON, 0);
++			break;
++		}
++		break;
++	}
++}
++
++static struct s3c24xx_mci_pdata gta01_mmc_cfg = {
++	.gpio_detect	= GTA01_GPIO_nSD_DETECT,
++	.set_power	= &gta01_mmc_set_power,
++	.ocr_avail	= MMC_VDD_165_195|MMC_VDD_20_21|
++			  MMC_VDD_21_22|MMC_VDD_22_23|MMC_VDD_23_24|
++			  MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27|
++			  MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
++			  MMC_VDD_30_31|MMC_VDD_31_32|MMC_VDD_32_33,
++};
++
+ static void gta01_udc_command(enum s3c2410_udc_cmd_e cmd)
+ {
+ 	printk(KERN_DEBUG "%s(%d)\n", __func__, cmd);
+@@ -597,10 +662,12 @@
+ 	    system_rev == GTA01Bv3_SYSTEM_REV ||
+ 	    system_rev == GTA01Bv4_SYSTEM_REV) {
+ 		gta01_udc_cfg.udc_command = gta01_udc_command;
++		gta01_mmc_cfg.ocr_avail = MMC_VDD_32_33;
+ 	}
+ 
+ 	s3c_device_usb.dev.platform_data = &gta01_usb_info;
+ 	s3c_device_nand.dev.platform_data = &gta01_nand_info;
++	s3c_device_sdi.dev.platform_data = &gta01_mmc_cfg;
+ 
+ 	s3c24xx_fb_set_platdata(&gta01_lcd_cfg);
+ 

Modified: branches/src/target/kernel/2.6.24.x/patches/series
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/series	2007-12-18 04:11:54 UTC (rev 3671)
+++ branches/src/target/kernel/2.6.24.x/patches/series	2007-12-18 09:49:36 UTC (rev 3672)
@@ -1,51 +1,69 @@
+# fixes that should already be upstream
+explicitly-link-notes-section.patch
+s3c2410_fb-line_length.patch
+gta01-no_nand_partitions.patch
+neo1973-soc-include-fix.patch
 asoc-neo1973_wm8753-power.patch
-asoc-s3c24xx-iis-suspend_resume.patch
 asoc-core-suspend_resume.patch
-missing_defs.patch
-openmoko-logo.patch
-yaffs2-20070905.patch
+
+# GTA01 core feature set
+s3c2410-bbt.patch
+gta01-pcf50606.patch
+gta01-core.patch
+gta01-jbt6k74.patch
+gta01-inputdevice.patch
+gta01-power_control.patch
+s3c2410-pwm.patch
+gta01-vibrator.patch
+gta01-backlight.patch
+
+# Touchscreen for S3C24xx
+s3c2410_touchscreen.patch
+s3c2410_ts-gta01.patch
+
+# pending review/
 i2c-permit_invalid_addrs.patch
-pm-debug_less_verbose.patch
 g_ether-highpower.patch
 g_ether-vendor_product.patch
-s3c2410_serial-nodebug.patch
-#s3c2410_udc_from_upstream.p (merged upstream)
-s3c2410_udc-2440_dual_packet-workaround.patch
-s3c2410_touchscreen.patch
-s3c2410-bbt.patch
+
+# SD/MMC for S3C24xx
 s3c_mci.patch
 s3cmci_dbg.patch
 s3cmci-dma-free.patch
 s3cmci-stop-fix.patch
 s3cmci-unfinished-write-fix.patch
 s3c_mci_platform.patch
-s3c2410-pwm.patch
-qt2410-cs8900.patch
+s3c_mci-gta01.patch
 qt2410-s3c_mci-pdata.patch
-gta01-no_nand_partitions.patch
-gta01-pcf50606.patch
-gta01-core.patch
-gta01-jbt6k74.patch
-gta01-backlight.patch
-gta01-vibrator.patch
-gta01-inputdevice.patch
-gta01-power_control.patch
-input-nots-mousedev.patch
-ts0710.patch
-s3c2410-qt2410-buttons.patch
-config-nr-tty-devices.patch
+
+# hxd8 required pre-patches
+s3c24xx-nand-largepage.patch
+s3c2410_udc-2440_dual_packet-workaround.patch
+
+# hxd8 feature set
 hxd8-core.patch
-# s3c2410_fb-truecolor.patch evaluate
-s3c2410_fb-line_length.patch
-s3c2440-nand-disable-hwecc.patch
 hxd8-tsl256x.patch
+
+# gta02 required pre-patches
+s3c2442b-cpuid.patch
+
+# gta02 feature set
 pcf50633.patch
 smedia-glamo.patch
-s3c24xx-nand-largepage.patch
-s3c2442b-cpuid.patch
 gta02-core.patch
 gta02-sound.patch
-neo1973-soc-include-fix.patch
-explicitly-link-notes-section.patch
 lis302dl.patch
 gta02-leds.patch
+
+# additional local stuff
+yaffs2-20070905.patch
+openmoko-logo.patch
+config-nr-tty-devices.patch
+pm-debug_less_verbose.patch
+s3c2410_serial-nodebug.patch
+input-nots-mousedev.patch
+s3c2440-nand-disable-hwecc.patch
+
+# qt2410 local hacks
+qt2410-cs8900.patch
+s3c2410-qt2410-buttons.patch

Deleted: branches/src/target/kernel/2.6.24.x/patches/ts0710.patch
===================================================================
--- branches/src/target/kernel/2.6.24.x/patches/ts0710.patch	2007-12-18 04:11:54 UTC (rev 3671)
+++ branches/src/target/kernel/2.6.24.x/patches/ts0710.patch	2007-12-18 09:49:36 UTC (rev 3672)
@@ -1,5717 +0,0 @@
-Index: linux-2.6.17.14-fic2/drivers/char/Kconfig
-===================================================================
---- linux-2.6.17.14-fic2.orig/drivers/char/Kconfig	2006-12-02 11:20:42.000000000 +0100
-+++ linux-2.6.17.14-fic2/drivers/char/Kconfig	2006-12-02 11:23:49.000000000 +0100
-@@ -1034,5 +1034,17 @@
- 	  sysfs directory, /sys/devices/platform/telco_clock, with a number of
- 	  files for controlling the behavior of this hardware.
- 
-+config TS0710_MUX
-+	tristate "GSM TS 07.10 Multiplex driver"
-+	help
-+	  This implements the GSM 07.10 multiplex protocol.
-+
-+config TS0710_MUX_USB_MOTO
-+	tristate "Motorola USB support for TS 07.10 Multiplex driver"
-+	depends on TS0710_MUX && USB
-+	help
-+	  This addrs support for the TS07.10 over USB, as found in Motorola
-+	  Smartphones.
-+
- endmenu
- 
-Index: linux-2.6.17.14-fic2/drivers/char/Makefile
-===================================================================
---- linux-2.6.17.14-fic2.orig/drivers/char/Makefile	2006-12-02 11:20:46.000000000 +0100
-+++ linux-2.6.17.14-fic2/drivers/char/Makefile	2006-12-02 11:24:55.000000000 +0100
-@@ -97,6 +97,9 @@
- obj-$(CONFIG_HANGCHECK_TIMER)	+= hangcheck-timer.o
- obj-$(CONFIG_TCG_TPM)		+= tpm/
- 
-+obj-$(CONFIG_TS0710_MUX)	+= ts0710_mux.o
-+obj-$(CONFIG_TS0710_MUX_USB)	+= ts0710_mux_usb.o
-+
- # Files generated that shall be removed upon make clean
- clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c
- 
-Index: linux-2.6.17.14-fic2/drivers/char/ts0710.h
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17.14-fic2/drivers/char/ts0710.h	2006-12-02 11:21:56.000000000 +0100
-@@ -0,0 +1,368 @@
-+/*
-+ * File: ts0710.h
-+ *
-+ * Portions derived from rfcomm.c, original header as follows:
-+ *
-+ * Copyright (C) 2000, 2001  Axis Communications AB
-+ *
-+ * Author: Mats Friden <mats.friden at axis.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version 2
-+ * of the License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-+ *
-+ * Exceptionally, Axis Communications AB grants discretionary and
-+ * conditional permissions for additional use of the text contained
-+ * in the company's release of the AXIS OpenBT Stack under the
-+ * provisions set forth hereunder.
-+ *
-+ * Provided that, if you use the AXIS OpenBT Stack with other files,
-+ * that do not implement functionality as specified in the Bluetooth
-+ * System specification, to produce an executable, this does not by
-+ * itself cause the resulting executable to be covered by the GNU
-+ * General Public License. Your use of that executable is in no way
-+ * restricted on account of using the AXIS OpenBT Stack code with it.
-+ *
-+ * This exception does not however invalidate any other reasons why
-+ * the executable file might be covered by the provisions of the GNU
-+ * General Public License.
-+ *
-+ */
-+/*
-+ * Copyright (C) 2002  Motorola
-+ *
-+ *  07/28/2002  Initial version based on rfcomm.c
-+ *  11/18/2002  Modified
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/fcntl.h>
-+#include <linux/string.h>
-+#include <linux/major.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/devfs_fs_kernel.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+
-+#include <asm/byteorder.h>
-+#include <asm/types.h>
-+
-+#define TS0710_MAX_CHN 14
-+
-+#define SET_PF(ctr) ((ctr) | (1 << 4))
-+#define CLR_PF(ctr) ((ctr) & 0xef)
-+#define GET_PF(ctr) (((ctr) >> 4) & 0x1)
-+
-+#define GET_PN_MSG_FRAME_SIZE(pn) ( ((pn)->frame_sizeh << 8) | ((pn)->frame_sizel))
-+#define SET_PN_MSG_FRAME_SIZE(pn, size) ({ (pn)->frame_sizel = (size) & 0xff; \
-+                                           (pn)->frame_sizeh = (size) >> 8; })
-+
-+#define GET_LONG_LENGTH(a) ( ((a).h_len << 7) | ((a).l_len) )
-+#define SET_LONG_LENGTH(a, length) ({ (a).ea = 0; \
-+                                      (a).l_len = length & 0x7F; \
-+                                      (a).h_len = (length >> 7) & 0xFF; })
-+
-+#define SHORT_CRC_CHECK 3
-+#define LONG_CRC_CHECK 4
-+
-+/* FIXME: Should thsi one be define here? */
-+#define SHORT_PAYLOAD_SIZE 127
-+
-+#define EA 1
-+#define FCS_SIZE 1
-+#define FLAG_SIZE 2
-+
-+#define TS0710_MAX_HDR_SIZE 5
-+#define DEF_TS0710_MTU 256
-+
-+#define TS0710_BASIC_FLAG 0xF9
-+/* the control field */
-+#define SABM 0x2f
-+#define SABM_SIZE 4
-+#define UA 0x63
-+#define UA_SIZE 4
-+#define DM 0x0f
-+#define DISC 0x43
-+#define UIH 0xef
-+
-+/* the type field in a multiplexer command packet */
-+#define TEST 0x8
-+#define FCON 0x28
-+#define FCOFF 0x18
-+#define MSC 0x38
-+#define RPN 0x24
-+#define RLS 0x14
-+#define PN 0x20
-+#define NSC 0x4
-+
-+/* V.24 modem control signals */
-+#define FC 0x2
-+#define RTC 0x4
-+#define RTR 0x8
-+#define IC 0x40
-+#define DV 0x80
-+
-+#define CTRL_CHAN 0		/* The control channel is defined as DLCI 0 */
-+#define MCC_CMD 1		/* Multiplexer command cr */
-+#define MCC_RSP 0		/* Multiplexer response cr */
-+
-+#ifdef __LITTLE_ENDIAN_BITFIELD
-+
-+typedef struct {
-+	__u8 ea:1;
-+	__u8 cr:1;
-+	__u8 d:1;
-+	__u8 server_chn:5;
-+} __attribute__ ((packed)) address_field;
-+
-+typedef struct {
-+	__u8 ea:1;
-+	__u8 len:7;
-+} __attribute__ ((packed)) short_length;
-+
-+typedef struct {
-+	__u8 ea:1;
-+	__u8 l_len:7;
-+	__u8 h_len;
-+} __attribute__ ((packed)) long_length;
-+
-+typedef struct {
-+	address_field addr;
-+	__u8 control;
-+	short_length length;
-+} __attribute__ ((packed)) short_frame_head;
-+
-+typedef struct {
-+	short_frame_head h;
-+	__u8 data[0];
-+} __attribute__ ((packed)) short_frame;
-+
-+typedef struct {
-+	address_field addr;
-+	__u8 control;
-+	long_length length;
-+	__u8 data[0];
-+} __attribute__ ((packed)) long_frame_head;
-+
-+typedef struct {
-+	long_frame_head h;
-+	__u8 data[0];
-+} __attribute__ ((packed)) long_frame;
-+
-+/* Typedefinitions for structures used for the multiplexer commands */
-+typedef struct {
-+	__u8 ea:1;
-+	__u8 cr:1;
-+	__u8 type:6;
-+} __attribute__ ((packed)) mcc_type;
-+
-+typedef struct {
-+	mcc_type type;
-+	short_length length;
-+	__u8 value[0];
-+} __attribute__ ((packed)) mcc_short_frame_head;
-+
-+typedef struct {
-+	mcc_short_frame_head h;
-+	__u8 value[0];
-+} __attribute__ ((packed)) mcc_short_frame;
-+
-+typedef struct {
-+	mcc_type type;
-+	long_length length;
-+	__u8 value[0];
-+} __attribute__ ((packed)) mcc_long_frame_head;
-+
-+typedef struct {
-+	mcc_long_frame_head h;
-+	__u8 value[0];
-+} __attribute__ ((packed)) mcc_long_frame;
-+
-+/* MSC-command */
-+typedef struct {
-+	__u8 ea:1;
-+	__u8 fc:1;
-+	__u8 rtc:1;
-+	__u8 rtr:1;
-+	__u8 reserved:2;
-+	__u8 ic:1;
-+	__u8 dv:1;
-+} __attribute__ ((packed)) v24_sigs;
-+
-+typedef struct {
-+	__u8 ea:1;
-+	__u8 b1:1;
-+	__u8 b2:1;
-+	__u8 b3:1;
-+	__u8 len:4;
-+} __attribute__ ((packed)) brk_sigs;
-+
-+typedef struct {
-+	short_frame_head s_head;
-+	mcc_short_frame_head mcc_s_head;
-+	address_field dlci;
-+	__u8 v24_sigs;
-+	//brk_sigs break_signals;
-+	__u8 fcs;
-+} __attribute__ ((packed)) msc_msg;
-+
-+#if 0
-+/* conflict with termios.h */
-+/* RPN command */
-+#define B2400 0
-+#define B4800 1
-+#define B7200 2
-+#define B9600 3
-+#define B19200 4
-+#define B38400 5
-+#define B57600 6
-+#define B115200 7
-+#define D230400 8
-+#endif
-+
-+/*
-+typedef struct{
-+  __u8 bit_rate:1;
-+  __u8 data_bits:1;
-+  __u8 stop_bit:1;
-+  __u8 parity:1;
-+  __u8 parity_type:1;
-+  __u8 xon_u8:1;
-+  __u8 xoff_u8:1;
-+  __u8 res1:1;
-+  __u8 xon_input:1;
-+  __u8 xon_output:1;
-+  __u8 rtr_input:1;
-+  __u8 rtr_output:1;
-+  __u8 rtc_input:1;
-+  __u8 rtc_output:1;
-+  __u8 res2:2;
-+} __attribute__((packed)) parameter_mask;
-+
-+typedef struct{
-+  __u8 bit_rate;
-+  __u8 data_bits:2;
-+  __u8 stop_bit:1;
-+  __u8 parity:1;
-+  __u8 parity_type:2;
-+  __u8 res1:2;
-+  __u8 xon_input:1;
-+  __u8 xon_output:1;
-+  __u8 rtr_input:1;
-+  __u8 rtr_output:1;
-+  __u8 rtc_input:1;
-+  __u8 rtc_output:1;
-+  __u8 res2:2;
-+  __u8 xon_u8;
-+  __u8 xoff_u8;
-+  parameter_mask pm;
-+} __attribute__((packed)) rpn_values;
-+
-+typedef struct{
-+  short_frame_head s_head;
-+  mcc_short_frame_head mcc_s_head;
-+  address_field dlci;
-+  rpn_values rpn_val;
-+  __u8 fcs;
-+} __attribute__((packed)) rpn_msg;
-+*/
-+
-+/* RLS-command */
-+/*
-+typedef struct{
-+  short_frame_head s_head;
-+  mcc_short_frame_head mcc_s_head;
-+  address_field dlci;
-+  __u8 error:4;
-+  __u8 res:4;
-+  __u8 fcs;
-+} __attribute__((packed)) rls_msg;
-+*/
-+
-+/* PN-command */
-+typedef struct {
-+	short_frame_head s_head;
-+	mcc_short_frame_head mcc_s_head;
-+	__u8 dlci:6;
-+	__u8 res1:2;
-+	__u8 frame_type:4;
-+	__u8 credit_flow:4;
-+	__u8 prior:6;
-+	__u8 res2:2;
-+	__u8 ack_timer;
-+	__u8 frame_sizel;
-+	__u8 frame_sizeh;
-+	__u8 max_nbrof_retrans;
-+	__u8 credits;
-+	__u8 fcs;
-+} __attribute__ ((packed)) pn_msg;
-+
-+/* NSC-command */
-+typedef struct {
-+	short_frame_head s_head;
-+	mcc_short_frame_head mcc_s_head;
-+	mcc_type command_type;
-+	__u8 fcs;
-+} __attribute__ ((packed)) nsc_msg;
-+
-+#else
-+#error Only littel-endianess supported now!
-+#endif
-+
-+enum {
-+	REJECTED = 0,
-+	DISCONNECTED,
-+	CONNECTING,
-+	NEGOTIATING,
-+	CONNECTED,
-+	DISCONNECTING,
-+	FLOW_STOPPED
-+};
-+
-+enum ts0710_events {
-+	CONNECT_IND,
-+	CONNECT_CFM,
-+	DISCONN_CFM
-+};
-+
-+typedef struct {
-+	volatile __u8 state;
-+	volatile __u8 flow_control;
-+	volatile __u8 initiated;
-+	volatile __u8 initiator;
-+	volatile __u16 mtu;
-+	wait_queue_head_t open_wait;
-+	wait_queue_head_t close_wait;
-+} dlci_struct;
-+
-+/* user space interfaces */
-+typedef struct {
-+	volatile __u8 initiator;
-+	volatile __u8 c_dlci;
-+	volatile __u16 mtu;
-+	volatile __u8 be_testing;
-+	volatile __u32 test_errs;
-+	wait_queue_head_t test_wait;
-+
-+	dlci_struct dlci[TS0710_MAX_CHN];
-+} ts0710_con;
-Index: linux-2.6.17.14-fic2/drivers/char/ts0710_mux.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17.14-fic2/drivers/char/ts0710_mux.c	2006-12-03 09:20:01.000000000 +0100
-@@ -0,0 +1,3978 @@
-+/*
-+ * File: mux_driver.c
-+ *
-+ * Portions derived from rfcomm.c, original header as follows:
-+ *
-+ * Copyright (C) 2000, 2001  Axis Communications AB
-+ *
-+ * Author: Mats Friden <mats.friden at axis.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version 2
-+ * of the License, or (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-+ *
-+ * Exceptionally, Axis Communications AB grants discretionary and
-+ * conditional permissions for additional use of the text contained
-+ * in the company's release of the AXIS OpenBT Stack under the
-+ * provisions set forth hereunder.
-+ *
-+ * Provided that, if you use the AXIS OpenBT Stack with other files,
-+ * that do not implement functionality as specified in the Bluetooth
-+ * System specification, to produce an executable, this does not by
-+ * itself cause the resulting executable to be covered by the GNU
-+ * General Public License. Your use of that executable is in no way
-+ * restricted on account of using the AXIS OpenBT Stack code with it.
-+ *
-+ * This exception does not however invalidate any other reasons why
-+ * the executable file might be covered by the provisions of the GNU
-+ * General Public License.
-+ *
-+ */
-+
-+/*
-+ * Copyright (C) 2002-2004  Motorola
-+ * Copyright (C) 2006 Harald Welte <laforge at openezx.org>
-+ *
-+ *  07/28/2002  Initial version
-+ *  11/18/2002  Second version
-+ *  04/21/2004  Add GPRS PROC
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+
-+#include <linux/kernel.h>
-+
-+#include <linux/errno.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/fcntl.h>
-+#include <linux/string.h>
-+#include <linux/major.h>
-+#include <linux/init.h>
-+
-+
-+#if 0
-+#include <linux/proc_fs.h>
-+
-+#define USB_FOR_MUX
-+
-+#ifndef USB_FOR_MUX
-+#include <linux/serial.h>
-+#endif
-+
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/devfs_fs_kernel.h>
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+
-+#endif
-+
-+#ifdef USB_FOR_MUX
-+//#include <linux/usb.h>
-+#include "ts0710_mux_usb.h"
-+#endif
-+
-+#include "ts0710.h"
-+#include "ts0710_mux.h"
-+
-+#define TS0710MUX_GPRS_SESSION_MAX 2
-+#define TS0710MUX_MAJOR 250
-+#define TS0710MUX_MINOR_START 0
-+#define NR_MUXS 16
-+
-+				  /*#define TS0710MUX_TIME_OUT 30 *//* 300ms  */
-+#define TS0710MUX_TIME_OUT 250	/* 2500ms, for BP UART hardware flow control AP UART  */
-+
-+#define TS0710MUX_IO_DLCI_FC_ON 0x54F2
-+#define TS0710MUX_IO_DLCI_FC_OFF 0x54F3
-+#define TS0710MUX_IO_FC_ON 0x54F4
-+#define TS0710MUX_IO_FC_OFF 0x54F5
-+
-+#define TS0710MUX_MAX_BUF_SIZE 2048
-+
-+#define TS0710MUX_SEND_BUF_OFFSET 10
-+#define TS0710MUX_SEND_BUF_SIZE (DEF_TS0710_MTU + TS0710MUX_SEND_BUF_OFFSET + 34)
-+#define TS0710MUX_RECV_BUF_SIZE TS0710MUX_SEND_BUF_SIZE
-+
-+/*For BP UART problem Begin*/
-+#ifdef TS0710SEQ2
-+#define ACK_SPACE 66		/* 6 * 11(ACK frame size)  */
-+#else
-+#define ACK_SPACE 42		/* 6 * 7(ACK frame size)  */
-+#endif
-+/*For BP UART problem End*/
-+
-+									     /*#define TS0710MUX_SERIAL_BUF_SIZE (DEF_TS0710_MTU + TS0710_MAX_HDR_SIZE)*//* For BP UART problem  */
-+#define TS0710MUX_SERIAL_BUF_SIZE (DEF_TS0710_MTU + TS0710_MAX_HDR_SIZE + ACK_SPACE)	/* For BP UART problem: ACK_SPACE  */
-+
-+#define TS0710MUX_MAX_TOTAL_FRAME_SIZE (DEF_TS0710_MTU + TS0710_MAX_HDR_SIZE + FLAG_SIZE)
-+#define TS0710MUX_MAX_CHARS_IN_BUF 65535
-+#define TS0710MUX_THROTTLE_THRESHOLD DEF_TS0710_MTU
-+
-+#define TEST_PATTERN_SIZE 250
-+
-+#define CMDTAG 0x55
-+#define DATATAG 0xAA
-+
-+#define ACK 0x4F		/*For BP UART problem */
-+
-+/*For BP UART problem Begin*/
-+#ifdef TS0710SEQ2
-+#define FIRST_BP_SEQ_OFFSET 1	/*offset from start flag */
-+#define SECOND_BP_SEQ_OFFSET 2	/*offset from start flag */
-+#define FIRST_AP_SEQ_OFFSET 3	/*offset from start flag */
-+#define SECOND_AP_SEQ_OFFSET 4	/*offset from start flag */
-+#define SLIDE_BP_SEQ_OFFSET 5	/*offset from start flag */
-+#define SEQ_FIELD_SIZE 5
-+#else
-+#define SLIDE_BP_SEQ_OFFSET 1	/*offset from start flag */
-+#define SEQ_FIELD_SIZE 1
-+#endif
-+
-+#define ADDRESS_FIELD_OFFSET (1 + SEQ_FIELD_SIZE)	/*offset from start flag */
-+/*For BP UART problem End*/
-+
-+#ifndef UNUSED_PARAM
-+#define UNUSED_PARAM(v) (void)(v)
-+#endif
-+
-+#define TS0710MUX_GPRS1_DLCI 7
-+#define TS0710MUX_GPRS2_DLCI 8
-+
-+#define TS0710MUX_GPRS1_RECV_COUNT_IDX 0
-+#define TS0710MUX_GPRS1_SEND_COUNT_IDX 1
-+#define TS0710MUX_GPRS2_RECV_COUNT_IDX 2
-+#define TS0710MUX_GPRS2_SEND_COUNT_IDX 3
-+#define TS0710MUX_COUNT_MAX_IDX        3
-+#define TS0710MUX_COUNT_IDX_NUM (TS0710MUX_COUNT_MAX_IDX + 1)
-+
-+#if 0
-+static volatile int mux_data_count[TS0710MUX_COUNT_IDX_NUM] = { 0, 0, 0, 0 };
-+static volatile int mux_data_count2[TS0710MUX_COUNT_IDX_NUM] = { 0, 0, 0, 0 };
-+static struct semaphore mux_data_count_mutex[TS0710MUX_COUNT_IDX_NUM];
-+static volatile __u8 post_recv_count_flag = 0;
-+
-+/*PROC file*/
-+struct proc_dir_entry *gprs_proc_file = NULL;
-+ssize_t file_proc_read(struct file *file, char *buf, size_t size,
-+		       loff_t * ppos);
-+ssize_t file_proc_write(struct file *file, const char *buf, size_t count,
-+			loff_t * ppos);
-+struct file_operations file_proc_operations = {
-+      read:file_proc_read,
-+      write:file_proc_write,
-+};
-+typedef struct {
-+	int recvBytes;
-+	int sentBytes;
-+} gprs_bytes;
-+
-+static __u8 tty2dlci[NR_MUXS] =
-+    { 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8, 9, 10, 11, 12, 13 };
-+static __u8 iscmdtty[NR_MUXS] =
-+    { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
-+typedef struct {
-+	__u8 cmdtty;
-+	__u8 datatty;
-+} dlci_tty;
-+static dlci_tty dlci2tty[] = { {0, 0},	/* DLCI 0 */
-+{0, 0},				/* DLCI 1 */
-+{1, 1},				/* DLCI 2 */
-+{2, 2},				/* DLCI 3 */
-+{3, 3},				/* DLCI 4 */
-+{4, 4},				/* DLCI 5 */
-+{5, 8},				/* DLCI 6 */
-+{6, 9},				/* DLCI 7 */
-+{7, 10},			/* DLCI 8 */
-+{11, 11},			/* DLCI 9 */
-+{12, 12},			/* DLCI 10 */
-+{13, 13},			/* DLCI 11 */
-+{14, 14},			/* DLCI 12 */
-+{15, 15}
-+};				/* DLCI 13 */
-+
-+typedef struct {
-+	volatile __u8 buf[TS0710MUX_SEND_BUF_SIZE];
-+	volatile __u8 *frame;
-+	unsigned long flags;
-+	volatile __u16 length;
-+	volatile __u8 filled;
-+	volatile __u8 dummy;	/* Allignment to 4*n bytes */
-+} mux_send_struct;
-+
-+/* Bit number in flags of mux_send_struct */
-+#define BUF_BUSY 0
-+
-+struct mux_recv_packet_tag {
-+	__u8 *data;
-+	__u32 length;
-+	struct mux_recv_packet_tag *next;
-+};
-+typedef struct mux_recv_packet_tag mux_recv_packet;
-+
-+struct mux_recv_struct_tag {
-+	__u8 data[TS0710MUX_RECV_BUF_SIZE];
-+	__u32 length;
-+	__u32 total;
-+	mux_recv_packet *mux_packet;
-+	struct mux_recv_struct_tag *next;
-+	int no_tty;
-+	volatile __u8 post_unthrottle;
-+};
-+typedef struct mux_recv_struct_tag mux_recv_struct;
-+
-+#define RECV_RUNNING 0
-+static unsigned long mux_recv_flags = 0;
-+
-+static mux_send_struct *mux_send_info[NR_MUXS];
-+static volatile __u8 mux_send_info_flags[NR_MUXS];
-+static volatile __u8 mux_send_info_idx = NR_MUXS;
-+
-+static mux_recv_struct *mux_recv_info[NR_MUXS];
-+static volatile __u8 mux_recv_info_flags[NR_MUXS];
-+static mux_recv_struct *mux_recv_queue = NULL;
-+
-+static struct tty_driver mux_driver;
-+
-+#ifdef USB_FOR_MUX
-+#define COMM_FOR_MUX_DRIVER usb_for_mux_driver
-+#define COMM_FOR_MUX_TTY usb_for_mux_tty
-+#define COMM_MUX_DISPATCHER usb_mux_dispatcher
-+#define COMM_MUX_SENDER usb_mux_sender
-+#else
-+#define COMM_FOR_MUX_DRIVER serial_for_mux_driver
-+#define COMM_FOR_MUX_TTY serial_for_mux_tty
-+#define COMM_MUX_DISPATCHER serial_mux_dispatcher
-+#define COMM_MUX_SENDER serial_mux_sender
-+
-+extern struct list_head *tq_serial_for_mux;
-+#endif
-+
-+extern struct tty_driver *COMM_FOR_MUX_DRIVER;
-+extern struct tty_struct *COMM_FOR_MUX_TTY;
-+extern void (*COMM_MUX_DISPATCHER) (struct tty_struct * tty);
-+extern void (*COMM_MUX_SENDER) (void);
-+
-+static struct work_struct send_tqueue;
-+static struct work_struct receive_tqueue;
-+static struct work_struct post_recv_tqueue;
-+
-+static struct tty_struct *mux_table[NR_MUXS];
-+static struct termios *mux_termios[NR_MUXS];
-+static struct termios *mux_termios_locked[NR_MUXS];
-+static volatile short int mux_tty[NR_MUXS];
-+
-+#ifdef min
-+#undef min
-+#define min(a,b)    ( (a)<(b) ? (a):(b) )
-+#endif
-+
-+static int get_count(__u8 idx);
-+static int set_count(__u8 idx, int count);
-+static int add_count(__u8 idx, int count);
-+
-+static int send_ua(ts0710_con * ts0710, __u8 dlci);
-+static int send_dm(ts0710_con * ts0710, __u8 dlci);
-+static int send_sabm(ts0710_con * ts0710, __u8 dlci);
-+static int send_disc(ts0710_con * ts0710, __u8 dlci);
-+static void queue_uih(mux_send_struct * send_info, __u16 len,
-+		      ts0710_con * ts0710, __u8 dlci);
-+static int send_pn_msg(ts0710_con * ts0710, __u8 prior, __u32 frame_size,
-+		       __u8 credit_flow, __u8 credits, __u8 dlci, __u8 cr);
-+static int send_nsc_msg(ts0710_con * ts0710, mcc_type cmd, __u8 cr);
-+static void set_uih_hdr(short_frame * uih_pkt, __u8 dlci, __u32 len, __u8 cr);
-+
-+static __u32 crc_check(__u8 * data, __u32 length, __u8 check_sum);
-+static __u8 crc_calc(__u8 * data, __u32 length);
-+static void create_crctable(__u8 table[]);
-+
-+static void mux_sched_send(void);
-+
-+static __u8 crctable[256];
-+
-+static ts0710_con ts0710_connection;
-+/*
-+static rpn_values rpn_val;
-+*/
-+
-+static int valid_dlci(__u8 dlci)
-+{
-+	if ((dlci < TS0710_MAX_CHN) && (dlci > 0))
-+		return 1;
-+	else
-+		return 0;
-+}
-+
-+#ifdef TS0710DEBUG
-+
-+#ifdef PRINT_OUTPUT_PRINTK
-+#define TS0710_DEBUG(fmt, arg...) printk(KERN_INFO "MUX " __FUNCTION__ ": " fmt "\n" , ## arg)
-+#else
-+#include "ezxlog.h"
-+static __u8 strDebug[256];
-+#define TS0710_DEBUG(fmt, arg...) ({ snprintf(strDebug, sizeof(strDebug), "MUX " __FUNCTION__ ": " fmt "\n" , ## arg); \
-+                                     /*printk("%s", strDebug)*/ezxlogk("MX", strDebug, strlen(strDebug)); })
-+#endif				/* End #ifdef PRINT_OUTPUT_PRINTK */
-+
-+#else
-+#define TS0710_DEBUG(fmt...)
-+#endif				/* End #ifdef TS0710DEBUG */
-+
-+#ifdef TS0710LOG
-+static unsigned char g_tbuf[TS0710MUX_MAX_BUF_SIZE];
-+#ifdef PRINT_OUTPUT_PRINTK
-+#define TS0710_LOG(fmt, arg...) printk(fmt, ## arg)
-+#define TS0710_PRINTK(fmt, arg...) printk(fmt, ## arg)
-+#else
-+#include "ezxlog.h"
-+static __u8 strLog[256];
-+#define TS0710_LOG(fmt, arg...) ({ snprintf(strLog, sizeof(strLog), fmt, ## arg); \
-+                                     /*printk("%s", strLog)*/ezxlogk("MX", strLog, strlen(strLog)); })
-+#define TS0710_PRINTK(fmt, arg...) ({ printk(fmt, ## arg); \
-+                                      TS0710_LOG(fmt, ## arg); })
-+#endif				/* End #ifdef PRINT_OUTPUT_PRINTK */
-+
-+#else
-+#define TS0710_LOG(fmt...)
-+#define TS0710_PRINTK(fmt, arg...) printk(fmt, ## arg)
-+#endif				/* End #ifdef TS0710LOG */
-+
-+#ifdef TS0710DEBUG
-+static void TS0710_DEBUGHEX(__u8 * buf, int len)
-+{
-+	static unsigned char tbuf[TS0710MUX_MAX_BUF_SIZE];
-+
-+	int i;
-+	int c;
-+
-+	if (len <= 0) {
-+		return;
-+	}
-+
-+	c = 0;
-+	for (i = 0; (i < len) && (c < (TS0710MUX_MAX_BUF_SIZE - 3)); i++) {
-+		sprintf(&tbuf[c], "%02x ", buf[i]);
-+		c += 3;
-+	}
-+	tbuf[c] = 0;
-+
-+#ifdef PRINT_OUTPUT_PRINTK
-+	TS0710_DEBUG("%s", tbuf);
-+#else
-+	/*printk("%s\n", tbuf) */ ezxlogk("MX", tbuf, c);
-+#endif
-+}
-+static void TS0710_DEBUGSTR(__u8 * buf, int len)
-+{
-+	static unsigned char tbuf[TS0710MUX_MAX_BUF_SIZE];
-+
-+	if (len <= 0) {
-+		return;
-+	}
-+
-+	if (len > (TS0710MUX_MAX_BUF_SIZE - 1)) {
-+		len = (TS0710MUX_MAX_BUF_SIZE - 1);
-+	}
-+
-+	memcpy(tbuf, buf, len);
-+	tbuf[len] = 0;
-+
-+#ifdef PRINT_OUTPUT_PRINTK
-+	/* 0x00 byte in the string pointed by tbuf may truncate the print result */
-+	TS0710_DEBUG("%s", tbuf);
-+#else
-+	/*printk("%s\n", tbuf) */ ezxlogk("MX", tbuf, len);
-+#endif
-+}
-+#else
-+#define TS0710_DEBUGHEX(buf, len)
-+#define TS0710_DEBUGSTR(buf, len)
-+#endif				/* End #ifdef TS0710DEBUG */
-+
-+#ifdef TS0710LOG
-+static void TS0710_LOGSTR_FRAME(__u8 send, __u8 * data, int len)
-+{
-+	short_frame *short_pkt;
-+	long_frame *long_pkt;
-+	__u8 *uih_data_start;
-+	__u32 uih_len;
-+	__u8 dlci;
-+	int pos;
-+
-+	if (len <= 0) {
-+		return;
-+	}
-+
-+	pos = 0;
-+	if (send) {
-+		pos += sprintf(&g_tbuf[pos], "<");
-+		short_pkt = (short_frame *) (data + 1);	/*For BP UART problem */
-+	} else {
-+		/*For BP UART problem */
-+		/*pos += sprintf(&g_tbuf[pos], ">"); */
-+		pos += sprintf(&g_tbuf[pos], ">%d ", *(data + SLIDE_BP_SEQ_OFFSET));	/*For BP UART problem */
-+
-+#ifdef TS0710SEQ2
-+		pos += sprintf(&g_tbuf[pos], "%02x %02x %02x %02x ", *(data + FIRST_BP_SEQ_OFFSET), *(data + SECOND_BP_SEQ_OFFSET), *(data + FIRST_AP_SEQ_OFFSET), *(data + SECOND_AP_SEQ_OFFSET));	/*For BP UART problem */
-+#endif
-+
-+		short_pkt = (short_frame *) (data + ADDRESS_FIELD_OFFSET);	/*For BP UART problem */
-+	}
-+
-+	/*For BP UART problem */
-+	/*short_pkt = (short_frame *)(data + 1); */
-+
-+	dlci = short_pkt->h.addr.server_chn << 1 | short_pkt->h.addr.d;
-+	switch (CLR_PF(short_pkt->h.control)) {
-+	case SABM:
-+		pos += sprintf(&g_tbuf[pos], "C SABM %d ::", dlci);
-+		break;
-+	case UA:
-+		pos += sprintf(&g_tbuf[pos], "C UA %d ::", dlci);
-+		break;
-+	case DM:
-+		pos += sprintf(&g_tbuf[pos], "C DM %d ::", dlci);
-+		break;
-+	case DISC:
-+		pos += sprintf(&g_tbuf[pos], "C DISC %d ::", dlci);
-+		break;
-+
-+		/*For BP UART problem Begin */
-+	case ACK:
-+		pos += sprintf(&g_tbuf[pos], "C ACK %d ", short_pkt->data[0]);
-+
-+#ifdef TS0710SEQ2
-+		pos += sprintf(&g_tbuf[pos], "%02x %02x %02x %02x ", short_pkt->data[1], short_pkt->data[2], short_pkt->data[3], short_pkt->data[4]);	/*For BP UART problem */
-+#endif
-+
-+		pos += sprintf(&g_tbuf[pos], "::");
-+		break;
-+		/*For BP UART problem End */
-+
-+	case UIH:
-+		if (!dlci) {
-+			pos += sprintf(&g_tbuf[pos], "C MCC %d ::", dlci);
-+		} else {
-+
-+			if ((short_pkt->h.length.ea) == 0) {
-+				long_pkt = (long_frame *) short_pkt;
-+				uih_len = GET_LONG_LENGTH(long_pkt->h.length);
-+				uih_data_start = long_pkt->h.data;
-+			} else {
-+				uih_len = short_pkt->h.length.len;
-+				uih_data_start = short_pkt->data;
-+			}
-+			switch (*uih_data_start) {
-+			case CMDTAG:
-+				pos +=
-+				    sprintf(&g_tbuf[pos], "I %d A %d ::", dlci,
-+					    uih_len);
-+				break;
-+			case DATATAG:
-+			default:
-+				pos +=
-+				    sprintf(&g_tbuf[pos], "I %d D %d ::", dlci,
-+					    uih_len);
-+				break;
-+			}
-+
-+		}
-+		break;
-+	default:
-+		pos += sprintf(&g_tbuf[pos], "N!!! %d ::", dlci);
-+		break;
-+	}
-+
-+	if (len > (sizeof(g_tbuf) - pos - 1)) {
-+		len = (sizeof(g_tbuf) - pos - 1);
-+	}
-+
-+	memcpy(&g_tbuf[pos], data, len);
-+	pos += len;
-+	g_tbuf[pos] = 0;
-+
-+#ifdef PRINT_OUTPUT_PRINTK
-+	/* 0x00 byte in the string pointed by g_tbuf may truncate the print result */
-+	TS0710_LOG("%s\n", g_tbuf);
-+#else
-+	/*printk("%s\n", g_tbuf) */ ezxlogk("MX", g_tbuf, pos);
-+#endif
-+}
-+#else
-+#define TS0710_LOGSTR_FRAME(send, data, len)
-+#endif
-+
-+#ifdef TS0710SIG
-+#define my_for_each_task(p) \
-+        for ((p) = current; ((p) = (p)->next_task) != current; )
-+
-+static void TS0710_SIG2APLOGD(void)
-+{
-+	struct task_struct *p;
-+	static __u8 sig = 0;
-+
-+	if (sig) {
-+		return;
-+	}
-+
-+	read_lock(&tasklist_lock);
-+	my_for_each_task(p) {
-+		if (strncmp(p->comm, "aplogd", 6) == 0) {
-+			sig = 1;
-+			if (send_sig(SIGUSR2, p, 1) == 0) {
-+				TS0710_PRINTK
-+				    ("MUX: success to send SIGUSR2 to aplogd!\n");
-+			} else {
-+				TS0710_PRINTK
-+				    ("MUX: failure to send SIGUSR2 to aplogd!\n");
-+			}
-+			break;
-+		}
-+	}
-+	read_unlock(&tasklist_lock);
-+
-+	if (!sig) {
-+		TS0710_PRINTK("MUX: not found aplogd!\n");
-+	}
-+}
-+#else
-+#define TS0710_SIG2APLOGD()
-+#endif
-+
-+static int basic_write(ts0710_con * ts0710, __u8 * buf, int len)
-+{
-+	int res;
-+
-+	UNUSED_PARAM(ts0710);
-+
-+	buf[0] = TS0710_BASIC_FLAG;
-+	buf[len + 1] = TS0710_BASIC_FLAG;
-+
-+	if ((COMM_FOR_MUX_DRIVER == 0) || (COMM_FOR_MUX_TTY == 0)) {
-+		TS0710_PRINTK
-+		    ("MUX basic_write: (COMM_FOR_MUX_DRIVER == 0) || (COMM_FOR_MUX_TTY == 0)\n");
-+
-+#ifndef USB_FOR_MUX
-+		TS0710_PRINTK
-+		    ("MUX basic_write: tapisrv might be down!!! (serial_for_mux_driver == 0) || (serial_for_mux_tty == 0)\n");
-+		TS0710_SIG2APLOGD();
-+#endif
-+
-+		return -1;
-+	}
-+
-+	TS0710_LOGSTR_FRAME(1, buf, len + 2);
-+	TS0710_DEBUGHEX(buf, len + 2);
-+
-+	res = COMM_FOR_MUX_DRIVER->write(COMM_FOR_MUX_TTY, buf, len + 2);
-+
-+	if (res != len + 2) {
-+		TS0710_PRINTK("MUX basic_write: Write Error!\n");
-+		return -1;
-+	}
-+
-+	return len + 2;
-+}
-+
-+/* Functions for the crc-check and calculation */
-+
-+#define CRC_VALID 0xcf
-+
-+static __u32 crc_check(__u8 * data, __u32 length, __u8 check_sum)
-+{
-+	__u8 fcs = 0xff;
-+
-+	while (length--) {
-+		fcs = crctable[fcs ^ *data++];
-+	}
-+	fcs = crctable[fcs ^ check_sum];
-+	TS0710_DEBUG("fcs : %d\n", fcs);
-+	if (fcs == (uint) 0xcf) {	/*CRC_VALID) */
-+		TS0710_DEBUG("crc_check: CRC check OK\n");
-+		return 0;
-+	} else {
-+		TS0710_PRINTK("MUX crc_check: CRC check failed\n");
-+		return 1;
-+	}
-+}
-+
-+/* Calculates the checksum according to the ts0710 specification */
-+
-+static __u8 crc_calc(__u8 * data, __u32 length)
-+{
-+	__u8 fcs = 0xff;
-+
-+	while (length--) {
-+		fcs = crctable[fcs ^ *data++];
-+	}
-+
-+	return 0xff - fcs;
-+}
-+
-+/* Calulates a reversed CRC table for the FCS check */
-+
-+static void create_crctable(__u8 table[])
-+{
-+	int i, j;
-+
-+	__u8 data;
-+	__u8 code_word = (__u8) 0xe0;
-+	__u8 sr = (__u8) 0;
-+
-+	for (j = 0; j < 256; j++) {
-+		data = (__u8) j;
-+
-+		for (i = 0; i < 8; i++) {
-+			if ((data & 0x1) ^ (sr & 0x1)) {
-+				sr >>= 1;
-+				sr ^= code_word;
-+			} else {
-+				sr >>= 1;
-+			}
-+
-+			data >>= 1;
-+			sr &= 0xff;
-+		}
-+
-+		table[j] = sr;
-+		sr = 0;
-+	}
-+}
-+
-+static void ts0710_reset_dlci(__u8 j)
-+{
-+	if (j >= TS0710_MAX_CHN)
-+		return;
-+
-+	ts0710_connection.dlci[j].state = DISCONNECTED;
-+	ts0710_connection.dlci[j].flow_control = 0;
-+	ts0710_connection.dlci[j].mtu = DEF_TS0710_MTU;
-+	ts0710_connection.dlci[j].initiated = 0;
-+	ts0710_connection.dlci[j].initiator = 0;
-+	init_waitqueue_head(&ts0710_connection.dlci[j].open_wait);
-+	init_waitqueue_head(&ts0710_connection.dlci[j].close_wait);
-+}
-+
-+static void ts0710_reset_con(void)
-+{
-+	__u8 j;
-+
-+	ts0710_connection.initiator = 0;
-+	ts0710_connection.mtu = DEF_TS0710_MTU + TS0710_MAX_HDR_SIZE;
-+	ts0710_connection.be_testing = 0;
-+	ts0710_connection.test_errs = 0;
-+	init_waitqueue_head(&ts0710_connection.test_wait);
-+
-+	for (j = 0; j < TS0710_MAX_CHN; j++) {
-+		ts0710_reset_dlci(j);
-+	}
-+}
-+
-+static void ts0710_init(void)
-+{
-+	create_crctable(crctable);
-+
-+	ts0710_reset_con();
-+
-+	/* Set the values in the rpn octets */
-+/*
-+  rpn_val.bit_rate  = 7;
-+  rpn_val.data_bits = 3;
-+  rpn_val.stop_bit  = 0;
-+  rpn_val.parity    = 0;
-+  rpn_val.parity_type = 0;
-+  rpn_val.res1    = 0;
-+  rpn_val.xon_input = 0;
-+  rpn_val.xon_output  = 0;
-+  rpn_val.rtr_input = 0;
-+  rpn_val.rtr_output  = 0;
-+  rpn_val.rtc_input = 0;
-+  rpn_val.rtc_output  = 0;
-+  rpn_val.res2    = 0;
-+  rpn_val.xon_u8  = 0x11;
-+  rpn_val.xoff_u8 = 0x13;
-+	  memset(&rpn_val.pm, 0 , 2); *//* Set the mask to zero */
-+}
-+
-+static void ts0710_upon_disconnect(void)
-+{
-+	ts0710_con *ts0710 = &ts0710_connection;
-+	__u8 j;
-+
-+	for (j = 0; j < TS0710_MAX_CHN; j++) {
-+		ts0710->dlci[j].state = DISCONNECTED;
-+		wake_up_interruptible(&ts0710->dlci[j].open_wait);
-+		wake_up_interruptible(&ts0710->dlci[j].close_wait);
-+	}
-+	ts0710->be_testing = 0;
-+	wake_up_interruptible(&ts0710->test_wait);
-+	ts0710_reset_con();
-+}
-+
-+/* Sending packet functions */
-+
-+/* Creates a UA packet and puts it at the beginning of the pkt pointer */
-+
-+static int send_ua(ts0710_con * ts0710, __u8 dlci)
-+{
-+	__u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE];
-+	short_frame *ua;
-+
-+	TS0710_DEBUG("send_ua: Creating UA packet to DLCI %d\n", dlci);
-+
-+	ua = (short_frame *) (buf + 1);
-+	ua->h.addr.ea = 1;
-+	ua->h.addr.cr = ((~(ts0710->initiator)) & 0x1);
-+	ua->h.addr.d = (dlci) & 0x1;
-+	ua->h.addr.server_chn = (dlci) >> 0x1;
-+	ua->h.control = SET_PF(UA);
-+	ua->h.length.ea = 1;
-+	ua->h.length.len = 0;
-+	ua->data[0] = crc_calc((__u8 *) ua, SHORT_CRC_CHECK);
-+
-+	return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE);
-+}
-+
-+/* Creates a DM packet and puts it at the beginning of the pkt pointer */
-+
-+static int send_dm(ts0710_con * ts0710, __u8 dlci)
-+{
-+	__u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE];
-+	short_frame *dm;
-+
-+	TS0710_DEBUG("send_dm: Creating DM packet to DLCI %d\n", dlci);
-+
-+	dm = (short_frame *) (buf + 1);
-+	dm->h.addr.ea = 1;
-+	dm->h.addr.cr = ((~(ts0710->initiator)) & 0x1);
-+	dm->h.addr.d = dlci & 0x1;
-+	dm->h.addr.server_chn = dlci >> 0x1;
-+	dm->h.control = SET_PF(DM);
-+	dm->h.length.ea = 1;
-+	dm->h.length.len = 0;
-+	dm->data[0] = crc_calc((__u8 *) dm, SHORT_CRC_CHECK);
-+
-+	return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE);
-+}
-+
-+static int send_sabm(ts0710_con * ts0710, __u8 dlci)
-+{
-+	__u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE];
-+	short_frame *sabm;
-+
-+	TS0710_DEBUG("send_sabm: Creating SABM packet to DLCI %d\n", dlci);
-+
-+	sabm = (short_frame *) (buf + 1);
-+	sabm->h.addr.ea = 1;
-+	sabm->h.addr.cr = ((ts0710->initiator) & 0x1);
-+	sabm->h.addr.d = dlci & 0x1;
-+	sabm->h.addr.server_chn = dlci >> 0x1;
-+	sabm->h.control = SET_PF(SABM);
-+	sabm->h.length.ea = 1;
-+	sabm->h.length.len = 0;
-+	sabm->data[0] = crc_calc((__u8 *) sabm, SHORT_CRC_CHECK);
-+
-+	return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE);
-+}
-+
-+static int send_disc(ts0710_con * ts0710, __u8 dlci)
-+{
-+	__u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE];
-+	short_frame *disc;
-+
-+	TS0710_DEBUG("send_disc: Creating DISC packet to DLCI %d\n", dlci);
-+
-+	disc = (short_frame *) (buf + 1);
-+	disc->h.addr.ea = 1;
-+	disc->h.addr.cr = ((ts0710->initiator) & 0x1);
-+	disc->h.addr.d = dlci & 0x1;
-+	disc->h.addr.server_chn = dlci >> 0x1;
-+	disc->h.control = SET_PF(DISC);
-+	disc->h.length.ea = 1;
-+	disc->h.length.len = 0;
-+	disc->data[0] = crc_calc((__u8 *) disc, SHORT_CRC_CHECK);
-+
-+	return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE);
-+}
-+
-+static void queue_uih(mux_send_struct * send_info, __u16 len,
-+		      ts0710_con * ts0710, __u8 dlci)
-+{
-+	__u32 size;
-+
-+	TS0710_DEBUG
-+	    ("queue_uih: Creating UIH packet with %d bytes data to DLCI %d\n",
-+	     len, dlci);
-+
-+	if (len > SHORT_PAYLOAD_SIZE) {
-+		long_frame *l_pkt;
-+
-+		size = sizeof(long_frame) + len + FCS_SIZE;
-+		l_pkt = (long_frame *) (send_info->frame - sizeof(long_frame));
-+		set_uih_hdr((void *)l_pkt, dlci, len, ts0710->initiator);
-+		l_pkt->data[len] = crc_calc((__u8 *) l_pkt, LONG_CRC_CHECK);
-+		send_info->frame = ((__u8 *) l_pkt) - 1;
-+	} else {
-+		short_frame *s_pkt;
-+
-+		size = sizeof(short_frame) + len + FCS_SIZE;
-+		s_pkt =
-+		    (short_frame *) (send_info->frame - sizeof(short_frame));
-+		set_uih_hdr((void *)s_pkt, dlci, len, ts0710->initiator);
-+		s_pkt->data[len] = crc_calc((__u8 *) s_pkt, SHORT_CRC_CHECK);
-+		send_info->frame = ((__u8 *) s_pkt) - 1;
-+	}
-+	send_info->length = size;
-+}
-+
-+/* Multiplexer command packets functions */
-+
-+/* Turns on the ts0710 flow control */
-+
-+static int ts0710_fcon_msg(ts0710_con * ts0710, __u8 cr)
-+{
-+	__u8 buf[30];
-+	mcc_short_frame *mcc_pkt;
-+	short_frame *uih_pkt;
-+	__u32 size;
-+
-+	size = sizeof(short_frame) + sizeof(mcc_short_frame) + FCS_SIZE;
-+	uih_pkt = (short_frame *) (buf + 1);
-+	set_uih_hdr(uih_pkt, CTRL_CHAN, sizeof(mcc_short_frame),
-+		    ts0710->initiator);
-+	uih_pkt->data[sizeof(mcc_short_frame)] =
-+	    crc_calc((__u8 *) uih_pkt, SHORT_CRC_CHECK);
-+	mcc_pkt = (mcc_short_frame *) (uih_pkt->data);
-+
-+	mcc_pkt->h.type.ea = EA;
-+	mcc_pkt->h.type.cr = cr;
-+	mcc_pkt->h.type.type = FCON;
-+	mcc_pkt->h.length.ea = EA;
-+	mcc_pkt->h.length.len = 0;
-+
-+	return basic_write(ts0710, buf, size);
-+}
-+
-+/* Turns off the ts0710 flow control */
-+
-+static int ts0710_fcoff_msg(ts0710_con * ts0710, __u8 cr)
-+{
-+	__u8 buf[30];
-+	mcc_short_frame *mcc_pkt;
-+	short_frame *uih_pkt;
-+	__u32 size;
-+
-+	size = (sizeof(short_frame) + sizeof(mcc_short_frame) + FCS_SIZE);
-+	uih_pkt = (short_frame *) (buf + 1);
-+	set_uih_hdr(uih_pkt, CTRL_CHAN, sizeof(mcc_short_frame),
-+		    ts0710->initiator);
-+	uih_pkt->data[sizeof(mcc_short_frame)] =
-+	    crc_calc((__u8 *) uih_pkt, SHORT_CRC_CHECK);
-+	mcc_pkt = (mcc_short_frame *) (uih_pkt->data);
-+
-+	mcc_pkt->h.type.ea = 1;
-+	mcc_pkt->h.type.cr = cr;
-+	mcc_pkt->h.type.type = FCOFF;
-+	mcc_pkt->h.length.ea = 1;
-+	mcc_pkt->h.length.len = 0;
-+
-+	return basic_write(ts0710, buf, size);
-+}
-+
-+/*
-+static int ts0710_rpn_msg(ts0710_con *ts0710, __u8 cr, __u8 dlci, __u8 req)
-+{
-+  char buf[100];
-+  rpn_msg* rpn_pkt;
-+  __u32 fsize;
-+  __u32 psize;
-+
-+  fsize = sizeof(rpn_msg);
-+
-+  if (req) {
-+    fsize -= sizeof(rpn_values);
-+  }
-+
-+  psize = (fsize - sizeof(short_frame) - FCS_SIZE);
-+
-+  rpn_pkt = (rpn_msg *) buf;
-+
-+  set_uih_hdr((short_frame *) rpn_pkt, CTRL_CHAN, psize, ts0710->initiator);
-+
-+  rpn_pkt->fcs = crc_calc((__u8*) rpn_pkt, SHORT_CRC_CHECK);
-+
-+  rpn_pkt->mcc_s_head.type.ea = EA;
-+  rpn_pkt->mcc_s_head.type.cr = cr;
-+  rpn_pkt->mcc_s_head.type.type = RPN;
-+  rpn_pkt->mcc_s_head.length.ea = EA;
-+
-+  rpn_pkt->dlci.ea = EA;
-+  rpn_pkt->dlci.cr = 1;
-+  rpn_pkt->dlci.d = dlci & 1;
-+  rpn_pkt->dlci.server_chn = (dlci >> 1);
-+
-+  if (req) {
-+    rpn_pkt->mcc_s_head.length.len = 1;
-+    rpn_pkt->rpn_val.bit_rate = rpn_pkt->fcs;
-+  } else {
-+    rpn_pkt->mcc_s_head.length.len = 8;
-+    memcpy(&(rpn_pkt->rpn_val), &rpn_val, sizeof(rpn_values));
-+  }
-+  return basic_write(ts0710, buf, fsize);
-+}
-+*/
-+/*
-+static int ts0710_rls_msg(ts0710_con *ts0710, __u8 cr, __u8 dlci, __u8 err_code)
-+{
-+  char buf[100];
-+  rls_msg *rls_pkt;
-+  __u32 fsize;
-+  __u32 psize;
-+
-+  fsize = sizeof(rls_msg);
-+  psize = fsize - sizeof(short_frame) - FCS_SIZE;
-+  rls_pkt = (rls_msg *) buf;
-+
-+  set_uih_hdr((short_frame *) rls_pkt, CTRL_CHAN, psize, ts0710->initiator);
-+  rls_pkt->fcs = crc_calc((__u8*) rls_pkt, SHORT_CRC_CHECK);
-+
-+  rls_pkt->mcc_s_head.type.ea = EA;
-+  rls_pkt->mcc_s_head.type.cr = cr;
-+  rls_pkt->mcc_s_head.type.type = RLS;
-+  rls_pkt->mcc_s_head.length.ea = EA;
-+  rls_pkt->mcc_s_head.length.len = 2;
-+
-+  rls_pkt->dlci.ea = EA;
-+  rls_pkt->dlci.cr = 1;
-+  rls_pkt->dlci.d = dlci & 1;
-+  rls_pkt->dlci.server_chn = dlci >> 1;
-+  rls_pkt->error = err_code;
-+  rls_pkt->res = 0;
-+
-+  return basic_write(ts0710, buf, fsize);
-+}
-+*/
-+
-+/* Sends an PN-messages and sets the not negotiable parameters to their
-+   default values in ts0710 */
-+
-+static int send_pn_msg(ts0710_con * ts0710, __u8 prior, __u32 frame_size,
-+		       __u8 credit_flow, __u8 credits, __u8 dlci, __u8 cr)
-+{
-+	__u8 buf[30];
-+	pn_msg *pn_pkt;
-+	__u32 size;
-+	TS0710_DEBUG
-+	    ("send_pn_msg: DLCI 0x%02x, prior:0x%02x, frame_size:%d, credit_flow:%x, credits:%d, cr:%x\n",
-+	     dlci, prior, frame_size, credit_flow, credits, cr);
-+
-+	size = sizeof(pn_msg);
-+	pn_pkt = (pn_msg *) (buf + 1);
-+
-+	set_uih_hdr((void *)pn_pkt, CTRL_CHAN,
-+		    size - (sizeof(short_frame) + FCS_SIZE), ts0710->initiator);
-+	pn_pkt->fcs = crc_calc((__u8 *) pn_pkt, SHORT_CRC_CHECK);
-+
-+	pn_pkt->mcc_s_head.type.ea = 1;
-+	pn_pkt->mcc_s_head.type.cr = cr;
-+	pn_pkt->mcc_s_head.type.type = PN;
-+	pn_pkt->mcc_s_head.length.ea = 1;
-+	pn_pkt->mcc_s_head.length.len = 8;
-+
-+	pn_pkt->res1 = 0;
-+	pn_pkt->res2 = 0;
-+	pn_pkt->dlci = dlci;
-+	pn_pkt->frame_type = 0;
-+	pn_pkt->credit_flow = credit_flow;
-+	pn_pkt->prior = prior;
-+	pn_pkt->ack_timer = 0;
-+	SET_PN_MSG_FRAME_SIZE(pn_pkt, frame_size);
-+	pn_pkt->credits = credits;
-+	pn_pkt->max_nbrof_retrans = 0;
-+
-+	return basic_write(ts0710, buf, size);
-+}
-+
-+/* Send a Not supported command - command, which needs 3 bytes */
-+
-+static int send_nsc_msg(ts0710_con * ts0710, mcc_type cmd, __u8 cr)
-+{
-+	__u8 buf[30];
-+	nsc_msg *nsc_pkt;
-+	__u32 size;
-+
-+	size = sizeof(nsc_msg);
-+	nsc_pkt = (nsc_msg *) (buf + 1);
-+
-+	set_uih_hdr((void *)nsc_pkt, CTRL_CHAN,
-+		    sizeof(nsc_msg) - sizeof(short_frame) - FCS_SIZE,
-+		    ts0710->initiator);
-+
-+	nsc_pkt->fcs = crc_calc((__u8 *) nsc_pkt, SHORT_CRC_CHECK);
-+
-+	nsc_pkt->mcc_s_head.type.ea = 1;
-+	nsc_pkt->mcc_s_head.type.cr = cr;
-+	nsc_pkt->mcc_s_head.type.type = NSC;
-+	nsc_pkt->mcc_s_head.length.ea = 1;
-+	nsc_pkt->mcc_s_head.length.len = 1;
-+
-+	nsc_pkt->command_type.ea = 1;
-+	nsc_pkt->command_type.cr = cmd.cr;
-+	nsc_pkt->command_type.type = cmd.type;
-+
-+	return basic_write(ts0710, buf, size);
-+}
-+
-+static int ts0710_msc_msg(ts0710_con * ts0710, __u8 value, __u8 cr, __u8 dlci)
-+{
-+	__u8 buf[30];
-+	msc_msg *msc_pkt;
-+	__u32 size;
-+
-+	size = sizeof(msc_msg);
-+	msc_pkt = (msc_msg *) (buf + 1);
-+
-+	set_uih_hdr((void *)msc_pkt, CTRL_CHAN,
-+		    sizeof(msc_msg) - sizeof(short_frame) - FCS_SIZE,
-+		    ts0710->initiator);
-+
-+	msc_pkt->fcs = crc_calc((__u8 *) msc_pkt, SHORT_CRC_CHECK);
-+
-+	msc_pkt->mcc_s_head.type.ea = 1;
-+	msc_pkt->mcc_s_head.type.cr = cr;
-+	msc_pkt->mcc_s_head.type.type = MSC;
-+	msc_pkt->mcc_s_head.length.ea = 1;
-+	msc_pkt->mcc_s_head.length.len = 2;
-+
-+	msc_pkt->dlci.ea = 1;
-+	msc_pkt->dlci.cr = 1;
-+	msc_pkt->dlci.d = dlci & 1;
-+	msc_pkt->dlci.server_chn = (dlci >> 1) & 0x1f;
-+
-+	msc_pkt->v24_sigs = value;
-+
-+	return basic_write(ts0710, buf, size);
-+}
-+
-+static int ts0710_test_msg(ts0710_con * ts0710, __u8 * test_pattern, __u32 len,
-+			   __u8 cr, __u8 * f_buf /*Frame buf */ )
-+{
-+	__u32 size;
-+
-+	if (len > SHORT_PAYLOAD_SIZE) {
-+		long_frame *uih_pkt;
-+		mcc_long_frame *mcc_pkt;
-+
-+		size =
-+		    (sizeof(long_frame) + sizeof(mcc_long_frame) + len +
-+		     FCS_SIZE);
-+		uih_pkt = (long_frame *) (f_buf + 1);
-+
-+		set_uih_hdr((short_frame *) uih_pkt, CTRL_CHAN, len +
-+			    sizeof(mcc_long_frame), ts0710->initiator);
-+		uih_pkt->data[GET_LONG_LENGTH(uih_pkt->h.length)] =
-+		    crc_calc((__u8 *) uih_pkt, LONG_CRC_CHECK);
-+		mcc_pkt = (mcc_long_frame *) uih_pkt->data;
-+
-+		mcc_pkt->h.type.ea = EA;
-+		/* cr tells whether it is a commmand (1) or a response (0) */
-+		mcc_pkt->h.type.cr = cr;
-+		mcc_pkt->h.type.type = TEST;
-+		SET_LONG_LENGTH(mcc_pkt->h.length, len);
-+		memcpy(mcc_pkt->value, test_pattern, len);
-+	} else if (len > (SHORT_PAYLOAD_SIZE - sizeof(mcc_short_frame))) {
-+		long_frame *uih_pkt;
-+		mcc_short_frame *mcc_pkt;
-+
-+		/* Create long uih packet and short mcc packet */
-+		size =
-+		    (sizeof(long_frame) + sizeof(mcc_short_frame) + len +
-+		     FCS_SIZE);
-+		uih_pkt = (long_frame *) (f_buf + 1);
-+
-+		set_uih_hdr((short_frame *) uih_pkt, CTRL_CHAN,
-+			    len + sizeof(mcc_short_frame), ts0710->initiator);
-+		uih_pkt->data[GET_LONG_LENGTH(uih_pkt->h.length)] =
-+		    crc_calc((__u8 *) uih_pkt, LONG_CRC_CHECK);
-+		mcc_pkt = (mcc_short_frame *) uih_pkt->data;
-+
-+		mcc_pkt->h.type.ea = EA;
-+		mcc_pkt->h.type.cr = cr;
-+		mcc_pkt->h.type.type = TEST;
-+		mcc_pkt->h.length.ea = EA;
-+		mcc_pkt->h.length.len = len;
-+		memcpy(mcc_pkt->value, test_pattern, len);
-+	} else {
-+		short_frame *uih_pkt;
-+		mcc_short_frame *mcc_pkt;
-+
-+		size =
-+		    (sizeof(short_frame) + sizeof(mcc_short_frame) + len +
-+		     FCS_SIZE);
-+		uih_pkt = (short_frame *) (f_buf + 1);
-+
-+		set_uih_hdr((void *)uih_pkt, CTRL_CHAN, len
-+			    + sizeof(mcc_short_frame), ts0710->initiator);
-+		uih_pkt->data[uih_pkt->h.length.len] =
-+		    crc_calc((__u8 *) uih_pkt, SHORT_CRC_CHECK);
-+		mcc_pkt = (mcc_short_frame *) uih_pkt->data;
-+
-+		mcc_pkt->h.type.ea = EA;
-+		mcc_pkt->h.type.cr = cr;
-+		mcc_pkt->h.type.type = TEST;
-+		mcc_pkt->h.length.ea = EA;
-+		mcc_pkt->h.length.len = len;
-+		memcpy(mcc_pkt->value, test_pattern, len);
-+
-+	}
-+	return basic_write(ts0710, f_buf, size);
-+}
-+
-+static void set_uih_hdr(short_frame * uih_pkt, __u8 dlci, __u32 len, __u8 cr)
-+{
-+	uih_pkt->h.addr.ea = 1;
-+	uih_pkt->h.addr.cr = cr;
-+	uih_pkt->h.addr.d = dlci & 0x1;
-+	uih_pkt->h.addr.server_chn = dlci >> 1;
-+	uih_pkt->h.control = CLR_PF(UIH);
-+
-+	if (len > SHORT_PAYLOAD_SIZE) {
-+		SET_LONG_LENGTH(((long_frame *) uih_pkt)->h.length, len);
-+	} else {
-+		uih_pkt->h.length.ea = 1;
-+		uih_pkt->h.length.len = len;
-+	}
-+}
-+
-+/* Parses a multiplexer control channel packet */
-+
-+void process_mcc(__u8 * data, __u32 len, ts0710_con * ts0710, int longpkt)
-+{
-+	__u8 *tbuf = NULL;
-+	mcc_short_frame *mcc_short_pkt;
-+	int j;
-+
-+	if (longpkt) {
-+		mcc_short_pkt =
-+		    (mcc_short_frame *) (((long_frame *) data)->data);
-+	} else {
-+		mcc_short_pkt =
-+		    (mcc_short_frame *) (((short_frame *) data)->data);
-+	}
-+
-+	switch (mcc_short_pkt->h.type.type) {
-+	case TEST:
-+		if (mcc_short_pkt->h.type.cr == MCC_RSP) {
-+			TS0710_DEBUG("Received test command response\n");
-+
-+			if (ts0710->be_testing) {
-+				if ((mcc_short_pkt->h.length.ea) == 0) {
-+					mcc_long_frame *mcc_long_pkt;
-+					mcc_long_pkt =
-+					    (mcc_long_frame *) mcc_short_pkt;
-+					if (GET_LONG_LENGTH
-+					    (mcc_long_pkt->h.length) !=
-+					    TEST_PATTERN_SIZE) {
-+						ts0710->test_errs =
-+						    TEST_PATTERN_SIZE;
-+						TS0710_DEBUG
-+						    ("Err: received test pattern is %d bytes long, not expected %d\n",
-+						     GET_LONG_LENGTH
-+						     (mcc_long_pkt->h.length),
-+						     TEST_PATTERN_SIZE);
-+					} else {
-+						ts0710->test_errs = 0;
-+						for (j = 0;
-+						     j < TEST_PATTERN_SIZE;
-+						     j++) {
-+							if (mcc_long_pkt->
-+							    value[j] !=
-+							    (j & 0xFF)) {
-+								(ts0710->
-+								 test_errs)++;
-+							}
-+						}
-+					}
-+
-+				} else {
-+
-+#if TEST_PATTERN_SIZE < 128
-+					if (mcc_short_pkt->h.length.len !=
-+					    TEST_PATTERN_SIZE) {
-+#endif
-+
-+						ts0710->test_errs =
-+						    TEST_PATTERN_SIZE;
-+						TS0710_DEBUG
-+						    ("Err: received test pattern is %d bytes long, not expected %d\n",
-+						     mcc_short_pkt->h.length.
-+						     len, TEST_PATTERN_SIZE);
-+
-+#if TEST_PATTERN_SIZE < 128
-+					} else {
-+						ts0710->test_errs = 0;
-+						for (j = 0;
-+						     j < TEST_PATTERN_SIZE;
-+						     j++) {
-+							if (mcc_short_pkt->
-+							    value[j] !=
-+							    (j & 0xFF)) {
-+								(ts0710->
-+								 test_errs)++;
-+							}
-+						}
-+					}
-+#endif
-+
-+				}
-+
-+				ts0710->be_testing = 0;	/* Clear the flag */
-+				wake_up_interruptible(&ts0710->test_wait);
-+			} else {
-+				TS0710_DEBUG
-+				    ("Err: shouldn't or late to get test cmd response\n");
-+			}
-+		} else {
-+			tbuf = (__u8 *) kmalloc(len + 32, GFP_ATOMIC);
-+			if (!tbuf) {
-+				break;
-+			}
-+
-+			if ((mcc_short_pkt->h.length.ea) == 0) {
-+				mcc_long_frame *mcc_long_pkt;
-+				mcc_long_pkt = (mcc_long_frame *) mcc_short_pkt;
-+				ts0710_test_msg(ts0710, mcc_long_pkt->value,
-+						GET_LONG_LENGTH(mcc_long_pkt->h.
-+								length),
-+						MCC_RSP, tbuf);
-+			} else {
-+				ts0710_test_msg(ts0710, mcc_short_pkt->value,
-+						mcc_short_pkt->h.length.len,
-+						MCC_RSP, tbuf);
-+			}
-+
-+			kfree(tbuf);
-+		}
-+		break;
-+
-+	case FCON:		/*Flow control on command */
-+		TS0710_PRINTK
-+		    ("MUX Received Flow control(all channels) on command\n");
-+		if (mcc_short_pkt->h.type.cr == MCC_CMD) {
-+			ts0710->dlci[0].state = CONNECTED;
-+			ts0710_fcon_msg(ts0710, MCC_RSP);
-+			mux_sched_send();
-+		}
-+		break;
-+
-+	case FCOFF:		/*Flow control off command */
-+		TS0710_PRINTK
-+		    ("MUX Received Flow control(all channels) off command\n");
-+		if (mcc_short_pkt->h.type.cr == MCC_CMD) {
-+			for (j = 0; j < TS0710_MAX_CHN; j++) {
-+				ts0710->dlci[j].state = FLOW_STOPPED;
-+			}
-+			ts0710_fcoff_msg(ts0710, MCC_RSP);
-+		}
-+		break;
-+
-+	case MSC:		/*Modem status command */
-+		{
-+			__u8 dlci;
-+			__u8 v24_sigs;
-+
-+			dlci = (mcc_short_pkt->value[0]) >> 2;
-+			v24_sigs = mcc_short_pkt->value[1];
-+
-+			if ((ts0710->dlci[dlci].state != CONNECTED)
-+			    && (ts0710->dlci[dlci].state != FLOW_STOPPED)) {
-+				send_dm(ts0710, dlci);
-+				break;
-+			}
-+			if (mcc_short_pkt->h.type.cr == MCC_CMD) {
-+				TS0710_DEBUG("Received Modem status command\n");
-+				if (v24_sigs & 2) {
-+					if (ts0710->dlci[dlci].state ==
-+					    CONNECTED) {
-+						TS0710_LOG
-+						    ("MUX Received Flow off on dlci %d\n",
-+						     dlci);
-+						ts0710->dlci[dlci].state =
-+						    FLOW_STOPPED;
-+					}
-+				} else {
-+					if (ts0710->dlci[dlci].state ==
-+					    FLOW_STOPPED) {
-+						ts0710->dlci[dlci].state =
-+						    CONNECTED;
-+						TS0710_LOG
-+						    ("MUX Received Flow on on dlci %d\n",
-+						     dlci);
-+						mux_sched_send();
-+					}
-+				}
-+
-+				ts0710_msc_msg(ts0710, v24_sigs, MCC_RSP, dlci);
-+/*
-+          if (!(ts0710->dlci[dlci].initiated) && !(ts0710->dlci[dlci].initiator)) {
-+            ts0710_msc_msg(ts0710, EA | RTR | RTC | DV, MCC_CMD, dlci);
-+            ts0710->dlci[dlci].initiated = 1;
-+          }
-+*/
-+			} else {
-+				TS0710_DEBUG
-+				    ("Received Modem status response\n");
-+
-+				if (v24_sigs & 2) {
-+					TS0710_DEBUG("Flow stop accepted\n");
-+				}
-+			}
-+			break;
-+		}
-+
-+		/*    case RPN:  *//*Remote port negotiation command */
-+
-+/*      {
-+        __u8 dlci;
-+
-+        dlci = (mcc_short_pkt->value[0]) >> 2;
-+
-+        if (mcc_short_pkt->h.type.cr == MCC_CMD) {
-+          if (mcc_short_pkt->h.length.len == 1) {
-+            TS0710_DEBUG("Received Remote port negotiation command\n");
-+            ts0710_rpn_msg(ts0710, MCC_RSP, dlci, 0);
-+          } else {
-+*/
-+		/* Accept the other sides settings (accept all for now) */
-+/*            TS0710_DEBUG("Received Remote port negotiation respons\n");
-+            memcpy(&rpn_val, &mcc_short_pkt->value[1], 8);
-+            ts0710_rpn_msg(ts0710, MCC_RSP, dlci, 0);
-+*/
-+		/* Zero the parametermask after response */
-+/*            memset(&rpn_val.pm, 0, 2);
-+          }
-+        }
-+        break;
-+      }
-+*/
-+/*
-+		    case RLS: *//*Remote line status */
-+/*      {
-+        __u8 dlci;
-+        __u8 err_code;
-+
-+        TS0710_DEBUG("Received Remote line status\n");
-+        if (mcc_short_pkt->h.type.cr == MCC_CMD) {
-+          dlci = mcc_short_pkt->value[0] >> 2;
-+          err_code = mcc_short_pkt->value[1];
-+
-+          ts0710_rls_msg(ts0710, MCC_RSP, dlci, err_code);
-+        }
-+        break;
-+      }
-+*/
-+	case PN:		/*DLC parameter negotiation */
-+		{
-+			__u8 dlci;
-+			__u16 frame_size;
-+			pn_msg *pn_pkt;
-+
-+			pn_pkt = (pn_msg *) data;
-+			dlci = pn_pkt->dlci;
-+			frame_size = GET_PN_MSG_FRAME_SIZE(pn_pkt);
-+			TS0710_DEBUG
-+			    ("Received DLC parameter negotiation, PN\n");
-+			if (pn_pkt->mcc_s_head.type.cr == MCC_CMD) {
-+				TS0710_DEBUG("received PN command with:\n");
-+				TS0710_DEBUG("Frame size:%d\n", frame_size);
-+
-+				frame_size =
-+				    min(frame_size, ts0710->dlci[dlci].mtu);
-+				send_pn_msg(ts0710, pn_pkt->prior, frame_size,
-+					    0, 0, dlci, MCC_RSP);
-+				ts0710->dlci[dlci].mtu = frame_size;
-+				TS0710_DEBUG("process_mcc : mtu set to %d\n",
-+					     ts0710->dlci[dlci].mtu);
-+			} else {
-+				TS0710_DEBUG("received PN response with:\n");
-+				TS0710_DEBUG("Frame size:%d\n", frame_size);
-+
-+				frame_size =
-+				    min(frame_size, ts0710->dlci[dlci].mtu);
-+				ts0710->dlci[dlci].mtu = frame_size;
-+
-+				TS0710_DEBUG
-+				    ("process_mcc : mtu set on dlci:%d to %d\n",
-+				     dlci, ts0710->dlci[dlci].mtu);
-+
-+				if (ts0710->dlci[dlci].state == NEGOTIATING) {
-+					ts0710->dlci[dlci].state = CONNECTING;
-+					wake_up_interruptible(&ts0710->
-+							      dlci[dlci].
-+							      open_wait);
-+				}
-+			}
-+			break;
-+		}
-+
-+	case NSC:		/*Non supported command resonse */
-+		TS0710_LOG("MUX Received Non supported command response\n");
-+		break;
-+
-+	default:		/*Non supported command received */
-+		TS0710_LOG("MUX Received a non supported command\n");
-+		send_nsc_msg(ts0710, mcc_short_pkt->h.type, MCC_RSP);
-+		break;
-+	}
-+}
-+
-+static mux_recv_packet *get_mux_recv_packet(__u32 size)
-+{
-+	mux_recv_packet *recv_packet;
-+
-+	TS0710_DEBUG("Enter into get_mux_recv_packet");
-+
-+	recv_packet =
-+	    (mux_recv_packet *) kmalloc(sizeof(mux_recv_packet), GFP_ATOMIC);
-+	if (!recv_packet) {
-+		return 0;
-+	}
-+
-+	recv_packet->data = (__u8 *) kmalloc(size, GFP_ATOMIC);
-+	if (!(recv_packet->data)) {
-+		kfree(recv_packet);
-+		return 0;
-+	}
-+	recv_packet->length = 0;
-+	recv_packet->next = 0;
-+	return recv_packet;
-+}
-+
-+static void free_mux_recv_packet(mux_recv_packet * recv_packet)
-+{
-+	TS0710_DEBUG("Enter into free_mux_recv_packet");
-+
-+	if (!recv_packet) {
-+		return;
-+	}
-+
-+	if (recv_packet->data) {
-+		kfree(recv_packet->data);
-+	}
-+	kfree(recv_packet);
-+}
-+
-+static void free_mux_recv_struct(mux_recv_struct * recv_info)
-+{
-+	mux_recv_packet *recv_packet1, *recv_packet2;
-+
-+	if (!recv_info) {
-+		return;
-+	}
-+
-+	recv_packet1 = recv_info->mux_packet;
-+	while (recv_packet1) {
-+		recv_packet2 = recv_packet1->next;
-+		free_mux_recv_packet(recv_packet1);
-+		recv_packet1 = recv_packet2;
-+	}
-+
-+	kfree(recv_info);
-+}
-+
-+static inline void add_post_recv_queue(mux_recv_struct ** head,
-+				       mux_recv_struct * new_item)
-+{
-+	new_item->next = *head;
-+	*head = new_item;
-+}
-+
-+static void ts0710_flow_on(__u8 dlci, ts0710_con * ts0710)
-+{
-+	int i;
-+	__u8 cmdtty;
-+	__u8 datatty;
-+	struct tty_struct *tty;
-+	mux_recv_struct *recv_info;
-+
-+	if ((ts0710->dlci[0].state != CONNECTED)
-+	    && (ts0710->dlci[0].state != FLOW_STOPPED)) {
-+		return;
-+	} else if ((ts0710->dlci[dlci].state != CONNECTED)
-+		   && (ts0710->dlci[dlci].state != FLOW_STOPPED)) {
-+		return;
-+	}
-+
-+	if (!(ts0710->dlci[dlci].flow_control)) {
-+		return;
-+	}
-+
-+	cmdtty = dlci2tty[dlci].cmdtty;
-+	datatty = dlci2tty[dlci].datatty;
-+
-+	if (cmdtty != datatty) {
-+		/* Check AT cmd tty */
-+		tty = mux_table[cmdtty];
-+		if (mux_tty[cmdtty] && tty) {
-+			if (test_bit(TTY_THROTTLED, &tty->flags)) {
-+				return;
-+			}
-+		}
-+		recv_info = mux_recv_info[cmdtty];
-+		if (mux_recv_info_flags[cmdtty] && recv_info) {
-+			if (recv_info->total) {
-+				return;
-+			}
-+		}
-+
-+		/* Check data tty */
-+		tty = mux_table[datatty];
-+		if (mux_tty[datatty] && tty) {
-+			if (test_bit(TTY_THROTTLED, &tty->flags)) {
-+				return;
-+			}
-+		}
-+		recv_info = mux_recv_info[datatty];
-+		if (mux_recv_info_flags[datatty] && recv_info) {
-+			if (recv_info->total) {
-+				return;
-+			}
-+		}
-+	}
-+
-+	for (i = 0; i < 3; i++) {
-+		if (ts0710_msc_msg(ts0710, EA | RTC | RTR | DV, MCC_CMD, dlci) <
-+		    0) {
-+			continue;
-+		} else {
-+			TS0710_LOG("MUX send Flow on on dlci %d\n", dlci);
-+			ts0710->dlci[dlci].flow_control = 0;
-+			break;
-+		}
-+	}
-+}
-+
-+static void ts0710_flow_off(struct tty_struct *tty, __u8 dlci,
-+			    ts0710_con * ts0710)
-+{
-+	int i;
-+
-+	if (test_and_set_bit(TTY_THROTTLED, &tty->flags)) {
-+		return;
-+	}
-+
-+	if ((ts0710->dlci[0].state != CONNECTED)
-+	    && (ts0710->dlci[0].state != FLOW_STOPPED)) {
-+		return;
-+	} else if ((ts0710->dlci[dlci].state != CONNECTED)
-+		   && (ts0710->dlci[dlci].state != FLOW_STOPPED)) {
-+		return;
-+	}
-+
-+	if (ts0710->dlci[dlci].flow_control) {
-+		return;
-+	}
-+
-+	for (i = 0; i < 3; i++) {
-+		if (ts0710_msc_msg
-+		    (ts0710, EA | FC | RTC | RTR | DV, MCC_CMD, dlci) < 0) {
-+			continue;
-+		} else {
-+			TS0710_LOG("MUX send Flow off on dlci %d\n", dlci);
-+			ts0710->dlci[dlci].flow_control = 1;
-+			break;
-+		}
-+	}
-+}
-+
-+int ts0710_recv_data(ts0710_con * ts0710, char *data, int len)
-+{
-+	short_frame *short_pkt;
-+	long_frame *long_pkt;
-+	__u8 *uih_data_start;
-+	__u32 uih_len;
-+	__u8 dlci;
-+	__u8 be_connecting;
-+#ifdef TS0710DEBUG
-+	unsigned long t;
-+#endif
-+
-+	short_pkt = (short_frame *) data;
-+
-+	dlci = short_pkt->h.addr.server_chn << 1 | short_pkt->h.addr.d;
-+	switch (CLR_PF(short_pkt->h.control)) {
-+	case SABM:
-+		TS0710_DEBUG("SABM-packet received\n");
-+
-+/*For BP UART problem
-+      if( crc_check((__u8*) short_pkt, SHORT_CRC_CHECK, short_pkt->data[0]) )
-+        break;
-+*/
-+
-+		if (!dlci) {
-+			TS0710_DEBUG("server channel == 0\n");
-+			ts0710->dlci[0].state = CONNECTED;
-+
-+			TS0710_DEBUG("sending back UA - control channel\n");
-+			send_ua(ts0710, dlci);
-+			wake_up_interruptible(&ts0710->dlci[0].open_wait);
-+
-+		} else if (valid_dlci(dlci)) {
-+
-+			TS0710_DEBUG("Incomming connect on channel %d\n", dlci);
-+
-+			TS0710_DEBUG("sending UA, dlci %d\n", dlci);
-+			send_ua(ts0710, dlci);
-+
-+			ts0710->dlci[dlci].state = CONNECTED;
-+			wake_up_interruptible(&ts0710->dlci[dlci].open_wait);
-+
-+		} else {
-+			TS0710_DEBUG("invalid dlci %d, sending DM\n", dlci);
-+			send_dm(ts0710, dlci);
-+		}
-+
-+		break;
-+
-+	case UA:
-+		TS0710_DEBUG("UA packet received\n");
-+
-+/*For BP UART problem
-+      if( crc_check((__u8*) short_pkt, SHORT_CRC_CHECK, short_pkt->data[0]) )
-+        break;
-+*/
-+
-+		if (!dlci) {
-+			TS0710_DEBUG("server channel == 0\n");
-+
-+			if (ts0710->dlci[0].state == CONNECTING) {
-+				ts0710->dlci[0].state = CONNECTED;
-+				wake_up_interruptible(&ts0710->dlci[0].
-+						      open_wait);
-+			} else if (ts0710->dlci[0].state == DISCONNECTING) {
-+				ts0710_upon_disconnect();
-+			} else {
-+				TS0710_DEBUG
-+				    (" Something wrong receiving UA packet\n");
-+			}
-+		} else if (valid_dlci(dlci)) {
-+			TS0710_DEBUG("Incomming UA on channel %d\n", dlci);
-+
-+			if (ts0710->dlci[dlci].state == CONNECTING) {
-+				ts0710->dlci[dlci].state = CONNECTED;
-+				wake_up_interruptible(&ts0710->dlci[dlci].
-+						      open_wait);
-+			} else if (ts0710->dlci[dlci].state == DISCONNECTING) {
-+				ts0710->dlci[dlci].state = DISCONNECTED;
-+				wake_up_interruptible(&ts0710->dlci[dlci].
-+						      open_wait);
-+				wake_up_interruptible(&ts0710->dlci[dlci].
-+						      close_wait);
-+				ts0710_reset_dlci(dlci);
-+			} else {
-+				TS0710_DEBUG
-+				    (" Something wrong receiving UA packet\n");
-+			}
-+		} else {
-+			TS0710_DEBUG("invalid dlci %d\n", dlci);
-+		}
-+
-+		break;
-+
-+	case DM:
-+		TS0710_DEBUG("DM packet received\n");
-+
-+/*For BP UART problem
-+      if( crc_check((__u8*) short_pkt, SHORT_CRC_CHECK, short_pkt->data[0]) )
-+        break;
-+*/
-+
-+		if (!dlci) {
-+			TS0710_DEBUG("server channel == 0\n");
-+
-+			if (ts0710->dlci[0].state == CONNECTING) {
-+				be_connecting = 1;
-+			} else {
-+				be_connecting = 0;
-+			}
-+			ts0710_upon_disconnect();
-+			if (be_connecting) {
-+				ts0710->dlci[0].state = REJECTED;
-+			}
-+		} else if (valid_dlci(dlci)) {
-+			TS0710_DEBUG("Incomming DM on channel %d\n", dlci);
-+
-+			if (ts0710->dlci[dlci].state == CONNECTING) {
-+				ts0710->dlci[dlci].state = REJECTED;
-+			} else {
-+				ts0710->dlci[dlci].state = DISCONNECTED;
-+			}
-+			wake_up_interruptible(&ts0710->dlci[dlci].open_wait);
-+			wake_up_interruptible(&ts0710->dlci[dlci].close_wait);
-+			ts0710_reset_dlci(dlci);
-+		} else {
-+			TS0710_DEBUG("invalid dlci %d\n", dlci);
-+		}
-+
-+		break;
-+
-+	case DISC:
-+		TS0710_DEBUG("DISC packet received\n");
-+
-+/*For BP UART problem
-+      if( crc_check((__u8*) short_pkt, SHORT_CRC_CHECK, short_pkt->data[0]) )
-+        break;
-+*/
-+
-+		if (!dlci) {
-+			TS0710_DEBUG("server channel == 0\n");
-+
-+			send_ua(ts0710, dlci);
-+			TS0710_DEBUG("DISC, sending back UA\n");
-+
-+			ts0710_upon_disconnect();
-+		} else if (valid_dlci(dlci)) {
-+			TS0710_DEBUG("Incomming DISC on channel %d\n", dlci);
-+
-+			send_ua(ts0710, dlci);
-+			TS0710_DEBUG("DISC, sending back UA\n");
-+
-+			ts0710->dlci[dlci].state = DISCONNECTED;
-+			wake_up_interruptible(&ts0710->dlci[dlci].open_wait);
-+			wake_up_interruptible(&ts0710->dlci[dlci].close_wait);
-+			ts0710_reset_dlci(dlci);
-+		} else {
-+			TS0710_DEBUG("invalid dlci %d\n", dlci);
-+		}
-+
-+		break;
-+
-+	case UIH:
-+		TS0710_DEBUG("UIH packet received\n");
-+
-+		if ((dlci >= TS0710_MAX_CHN)) {
-+			TS0710_DEBUG("invalid dlci %d\n", dlci);
-+			send_dm(ts0710, dlci);
-+			break;
-+		}
-+
-+		if (GET_PF(short_pkt->h.control)) {
-+			TS0710_LOG
-+			    ("MUX Error %s: UIH packet with P/F set, discard it!\n",
-+			     __FUNCTION__);
-+			break;
-+		}
-+
-+		if ((ts0710->dlci[dlci].state != CONNECTED)
-+		    && (ts0710->dlci[dlci].state != FLOW_STOPPED)) {
-+			TS0710_LOG
-+			    ("MUX Error %s: DLCI %d not connected, discard it!\n",
-+			     __FUNCTION__, dlci);
-+			send_dm(ts0710, dlci);
-+			break;
-+		}
-+
-+		if ((short_pkt->h.length.ea) == 0) {
-+			TS0710_DEBUG("Long UIH packet received\n");
-+			long_pkt = (long_frame *) data;
-+			uih_len = GET_LONG_LENGTH(long_pkt->h.length);
-+			uih_data_start = long_pkt->h.data;
-+			TS0710_DEBUG("long packet length %d\n", uih_len);
-+
-+/*For BP UART problem
-+        if (crc_check(data, LONG_CRC_CHECK, *(uih_data_start + uih_len)))
-+          break;
-+*/
-+		} else {
-+			TS0710_DEBUG("Short UIH pkt received\n");
-+			uih_len = short_pkt->h.length.len;
-+			uih_data_start = short_pkt->data;
-+
-+/*For BP UART problem
-+        if (crc_check(data, SHORT_CRC_CHECK, *(uih_data_start + uih_len)))
-+          break;
-+*/
-+		}
-+
-+		if (dlci == 0) {
-+			TS0710_DEBUG("UIH on serv_channel 0\n");
-+			process_mcc(data, len, ts0710,
-+				    !(short_pkt->h.length.ea));
-+		} else if (valid_dlci(dlci)) {
-+			/* do tty dispatch */
-+			__u8 tag;
-+			__u8 tty_idx;
-+			struct tty_struct *tty;
-+			__u8 queue_data;
-+			__u8 post_recv;
-+			__u8 flow_control;
-+			mux_recv_struct *recv_info;
-+			int recv_room;
-+			mux_recv_packet *recv_packet, *recv_packet2;
-+
-+			TS0710_DEBUG("UIH on channel %d\n", dlci);
-+
-+			if (uih_len > ts0710->dlci[dlci].mtu) {
-+				TS0710_PRINTK
-+				    ("MUX Error:  DLCI:%d, uih_len:%d is bigger than mtu:%d, discard data!\n",
-+				     dlci, uih_len, ts0710->dlci[dlci].mtu);
-+				break;
-+			}
-+
-+			tag = *uih_data_start;
-+			uih_data_start++;
-+			uih_len--;
-+
-+			if (!uih_len) {
-+				break;
-+			}
-+
-+			switch (tag) {
-+			case CMDTAG:
-+				tty_idx = dlci2tty[dlci].cmdtty;
-+				TS0710_DEBUG("CMDTAG on DLCI:%d, /dev/mux%d\n",
-+					     dlci, tty_idx);
-+				TS0710_DEBUGSTR(uih_data_start, uih_len);
-+				if (!(iscmdtty[tty_idx])) {
-+					TS0710_PRINTK
-+					    ("MUX Error: %s: Wrong CMDTAG on DLCI:%d, /dev/mux%d\n",
-+					     __FUNCTION__, dlci, tty_idx);
-+				}
-+				break;
-+			case DATATAG:
-+			default:
-+				tty_idx = dlci2tty[dlci].datatty;
-+				TS0710_DEBUG
-+				    ("NON-CMDTAG on DLCI:%d, /dev/mux%d\n",
-+				     dlci, tty_idx);
-+				if (iscmdtty[tty_idx]) {
-+					TS0710_PRINTK
-+					    ("MUX Error: %s: Wrong NON-CMDTAG on DLCI:%d, /dev/mux%d\n",
-+					     __FUNCTION__, dlci, tty_idx);
-+				}
-+				break;
-+			}
-+			tty = mux_table[tty_idx];
-+			if ((!mux_tty[tty_idx]) || (!tty)) {
-+				TS0710_PRINTK
-+				    ("MUX: No application waiting for, discard it! /dev/mux%d\n",
-+				     tty_idx);
-+			} else {	/* Begin processing received data */
-+				if ((!mux_recv_info_flags[tty_idx])
-+				    || (!mux_recv_info[tty_idx])) {
-+					TS0710_PRINTK
-+					    ("MUX Error: No mux_recv_info, discard it! /dev/mux%d\n",
-+					     tty_idx);
-+					break;
-+				}
-+
-+				recv_info = mux_recv_info[tty_idx];
-+				if (recv_info->total > 8192) {
-+					TS0710_PRINTK
-+					    ("MUX : discard data for tty_idx:%d, recv_info->total > 8192 \n",
-+					     tty_idx);
-+					break;
-+				}
-+
-+				queue_data = 0;
-+				post_recv = 0;
-+				flow_control = 0;
-+				recv_room = 65535;
-+				if (tty->receive_room)
-+					recv_room = tty->receive_room;
-+
-+				if (test_bit(TTY_THROTTLED, &tty->flags)) {
-+					queue_data = 1;
-+				} else {
-+					if (test_bit
-+					    (TTY_DONT_FLIP, &tty->flags)) {
-+						queue_data = 1;
-+						post_recv = 1;
-+					} else if (recv_info->total) {
-+						queue_data = 1;
-+						post_recv = 1;
-+					} else if (recv_room < uih_len) {
-+						queue_data = 1;
-+						flow_control = 1;
-+					}
-+
-+					if ((recv_room -
-+					     (uih_len + recv_info->total)) <
-+					    ts0710->dlci[dlci].mtu) {
-+						flow_control = 1;
-+					}
-+				}
-+
-+				if (!queue_data) {
-+					/* Put received data into read buffer of tty */
-+					TS0710_DEBUG
-+					    ("Put received data into read buffer of /dev/mux%d",
-+					     tty_idx);
-+
-+#ifdef TS0710DEBUG
-+					t = jiffies;
-+#endif
-+
-+					(tty->ldisc.receive_buf) (tty,
-+								  uih_data_start,
-+								  NULL,
-+								  uih_len);
-+
-+#ifdef TS0710DEBUG
-+					TS0710_DEBUG
-+					    ("tty->ldisc.receive_buf take ticks: %lu",
-+					     (jiffies - t));
-+#endif
-+
-+				} else {	/* Queue data */
-+
-+					TS0710_DEBUG
-+					    ("Put received data into recv queue of /dev/mux%d",
-+					     tty_idx);
-+					if (recv_info->total) {
-+						/* recv_info is already linked into mux_recv_queue */
-+
-+						recv_packet =
-+						    get_mux_recv_packet
-+						    (uih_len);
-+						if (!recv_packet) {
-+							TS0710_PRINTK
-+							    ("MUX %s: no memory\n",
-+							     __FUNCTION__);
-+							break;
-+						}
-+
-+						memcpy(recv_packet->data,
-+						       uih_data_start, uih_len);
-+						recv_packet->length = uih_len;
-+						recv_info->total += uih_len;
-+						recv_packet->next = NULL;
-+
-+						if (!(recv_info->mux_packet)) {
-+							recv_info->mux_packet =
-+							    recv_packet;
-+						} else {
-+							recv_packet2 =
-+							    recv_info->
-+							    mux_packet;
-+							while (recv_packet2->
-+							       next) {
-+								recv_packet2 =
-+								    recv_packet2->
-+								    next;
-+							}
-+							recv_packet2->next =
-+							    recv_packet;
-+						}	/* End if( !(recv_info->mux_packet) ) */
-+					} else {	/* recv_info->total == 0 */
-+						if (uih_len >
-+						    TS0710MUX_RECV_BUF_SIZE) {
-+							TS0710_PRINTK
-+							    ("MUX Error:  tty_idx:%d, uih_len == %d is too big\n",
-+							     tty_idx, uih_len);
-+							uih_len =
-+							    TS0710MUX_RECV_BUF_SIZE;
-+						}
-+						memcpy(recv_info->data,
-+						       uih_data_start, uih_len);
-+						recv_info->length = uih_len;
-+						recv_info->total = uih_len;
-+
-+						add_post_recv_queue
-+						    (&mux_recv_queue,
-+						     recv_info);
-+					}	/* End recv_info->total == 0 */
-+				}	/* End Queue data */
-+
-+				if (flow_control) {
-+					/* Do something for flow control */
-+					ts0710_flow_off(tty, dlci, ts0710);
-+				}
-+
-+				if (tty_idx ==
-+				    dlci2tty[TS0710MUX_GPRS1_DLCI].datatty) {
-+					if (add_count
-+					    (TS0710MUX_GPRS1_RECV_COUNT_IDX,
-+					     uih_len) < 0) {
-+						post_recv_count_flag = 1;
-+						post_recv = 1;
-+						mux_data_count2
-+						    [TS0710MUX_GPRS1_RECV_COUNT_IDX]
-+						    += uih_len;
-+					}
-+				} else if (tty_idx ==
-+					   dlci2tty[TS0710MUX_GPRS2_DLCI].
-+					   datatty) {
-+					if (add_count
-+					    (TS0710MUX_GPRS2_RECV_COUNT_IDX,
-+					     uih_len) < 0) {
-+						post_recv_count_flag = 1;
-+						post_recv = 1;
-+						mux_data_count2
-+						    [TS0710MUX_GPRS2_RECV_COUNT_IDX]
-+						    += uih_len;
-+					}
-+				}
-+
-+				if (post_recv) 
-+					schedule_work(&post_recv_tqueue);
-+			}	/* End processing received data */
-+		} else {
-+			TS0710_DEBUG("invalid dlci %d\n", dlci);
-+		}
-+
-+		break;
-+
-+	default:
-+		TS0710_DEBUG("illegal packet\n");
-+		break;
-+	}
-+	return 0;
-+}
-+
-+/*
-+int ts0710_send_data(ts0710_con *ts0710, __u8 dlci, __u8 *data, __u32 count)
-+{
-+  __u32 c, total = 0;
-+  __u8 tag, first;
-+
-+  if( ts0710->dlci[0].state == FLOW_STOPPED ){
-+    TS0710_DEBUG("Flow stopped on all channels, returning zero\n");
-+*/
-+/*
-+    return -EFLOWSTOPPED;
-+  } else if( ts0710->dlci[dlci].state == FLOW_STOPPED ){
-+    TS0710_DEBUG("Flow stopped, returning zero\n");
-+*/
-+/*
-+    return -EFLOWSTOPPED;
-+  } else if( ts0710->dlci[dlci].state == CONNECTED ){
-+
-+    TS0710_DEBUG("trying to send %d bytes\n", count);
-+    tag = *data;
-+    first = 1;
-+*/
-+    /* The first byte is always a Cmd/Data tag */
-+/*
-+    while( count > 1 ){
-+
-+      c = min(count, ts0710->dlci[dlci].mtu);
-+      if( queue_uih(data, c, ts0710, dlci) <= 0 ) {
-+        break;
-+      }
-+
-+      total += (c - 1);
-+      data += (c - 1);
-+      *data = tag;
-+      count -= (c - 1);
-+
-+      if( first ) {
-+        first = 0;
-+	total++;
-+      }
-+    }
-+    TS0710_DEBUG("sent %d bytes\n", total);
-+    return total;
-+  } else {
-+    TS0710_DEBUG("DLCI %d not connected\n", dlci);
-+    return -EDISCONNECTED;
-+  }
-+}
-+*/
-+
-+/* Close ts0710 channel */
-+static void ts0710_close_channel(__u8 dlci)
-+{
-+	ts0710_con *ts0710 = &ts0710_connection;
-+	int try;
-+	unsigned long t;
-+
-+	TS0710_DEBUG("ts0710_disc_command on channel %d\n", dlci);
-+
-+	if ((ts0710->dlci[dlci].state == DISCONNECTED)
-+	    || (ts0710->dlci[dlci].state == REJECTED)) {
-+		return;
-+	} else if (ts0710->dlci[dlci].state == DISCONNECTING) {
-+		/* Reentry */
-+		return;
-+	} else {
-+		ts0710->dlci[dlci].state = DISCONNECTING;
-+		try = 3;
-+		while (try--) {
-+			t = jiffies;
-+			send_disc(ts0710, dlci);
-+			interruptible_sleep_on_timeout(&ts0710->dlci[dlci].
-+						       close_wait,
-+						       TS0710MUX_TIME_OUT);
-+			if (ts0710->dlci[dlci].state == DISCONNECTED) {
-+				break;
-+			} else if (signal_pending(current)) {
-+				TS0710_PRINTK
-+				    ("MUX DLCI %d Send DISC got signal!\n",
-+				     dlci);
-+				break;
-+			} else if ((jiffies - t) >= TS0710MUX_TIME_OUT) {
-+				TS0710_PRINTK
-+				    ("MUX DLCI %d Send DISC timeout!\n", dlci);
-+				continue;
-+			}
-+		}
-+
-+		if (ts0710->dlci[dlci].state != DISCONNECTED) {
-+			if (dlci == 0) {	/* Control Channel */
-+				ts0710_upon_disconnect();
-+			} else {	/* Other Channel */
-+				ts0710->dlci[dlci].state = DISCONNECTED;
-+				wake_up_interruptible(&ts0710->dlci[dlci].
-+						      close_wait);
-+				ts0710_reset_dlci(dlci);
-+			}
-+		}
-+	}
-+}
-+
-+int ts0710_open_channel(__u8 dlci)
-+{
-+	ts0710_con *ts0710 = &ts0710_connection;
-+	int try;
-+	int retval;
-+	unsigned long t;
-+
-+	retval = -ENODEV;
-+	if (dlci == 0) {	// control channel
-+		if ((ts0710->dlci[0].state == CONNECTED)
-+		    || (ts0710->dlci[0].state == FLOW_STOPPED)) {
-+			return 0;
-+		} else if (ts0710->dlci[0].state == CONNECTING) {
-+			/* Reentry */
-+			TS0710_PRINTK
-+			    ("MUX DLCI: 0, reentry to open DLCI 0, pid: %d, %s !\n",
-+			     current->pid, current->comm);
-+			try = 11;
-+			while (try--) {
-+				t = jiffies;
-+				interruptible_sleep_on_timeout(&ts0710->dlci[0].
-+							       open_wait,
-+							       TS0710MUX_TIME_OUT);
-+				if ((ts0710->dlci[0].state == CONNECTED)
-+				    || (ts0710->dlci[0].state ==
-+					FLOW_STOPPED)) {
-+					retval = 0;
-+					break;
-+				} else if (ts0710->dlci[0].state == REJECTED) {
-+					retval = -EREJECTED;
-+					break;
-+				} else if (ts0710->dlci[0].state ==
-+					   DISCONNECTED) {
-+					break;
-+				} else if (signal_pending(current)) {
-+					TS0710_PRINTK
-+					    ("MUX DLCI:%d Wait for connecting got signal!\n",
-+					     dlci);
-+					retval = -EAGAIN;
-+					break;
-+				} else if ((jiffies - t) >= TS0710MUX_TIME_OUT) {
-+					TS0710_PRINTK
-+					    ("MUX DLCI:%d Wait for connecting timeout!\n",
-+					     dlci);
-+					continue;
-+				} else if (ts0710->dlci[0].state == CONNECTING) {
-+					continue;
-+				}
-+			}
-+
-+			if (ts0710->dlci[0].state == CONNECTING) {
-+				ts0710->dlci[0].state = DISCONNECTED;
-+			}
-+		} else if ((ts0710->dlci[0].state != DISCONNECTED)
-+			   && (ts0710->dlci[0].state != REJECTED)) {
-+			TS0710_PRINTK("MUX DLCI:%d state is invalid!\n", dlci);
-+			return retval;
-+		} else {
-+			ts0710->initiator = 1;
-+			ts0710->dlci[0].state = CONNECTING;
-+			ts0710->dlci[0].initiator = 1;
-+			try = 10;
-+			while (try--) {
-+				t = jiffies;
-+				send_sabm(ts0710, 0);
-+				interruptible_sleep_on_timeout(&ts0710->dlci[0].
-+							       open_wait,
-+							       TS0710MUX_TIME_OUT);
-+				if ((ts0710->dlci[0].state == CONNECTED)
-+				    || (ts0710->dlci[0].state ==
-+					FLOW_STOPPED)) {
-+					retval = 0;
-+					break;
-+				} else if (ts0710->dlci[0].state == REJECTED) {
-+					TS0710_PRINTK
-+					    ("MUX DLCI:%d Send SABM got rejected!\n",
-+					     dlci);
-+					retval = -EREJECTED;
-+					break;
-+				} else if (signal_pending(current)) {
-+					TS0710_PRINTK
-+					    ("MUX DLCI:%d Send SABM got signal!\n",
-+					     dlci);
-+					retval = -EAGAIN;
-+					break;
-+				} else if ((jiffies - t) >= TS0710MUX_TIME_OUT) {
-+					TS0710_PRINTK
-+					    ("MUX DLCI:%d Send SABM timeout!\n",
-+					     dlci);
-+					continue;
-+				}
-+			}
-+
-+			if (ts0710->dlci[0].state == CONNECTING) {
-+				ts0710->dlci[0].state = DISCONNECTED;
-+			}
-+			wake_up_interruptible(&ts0710->dlci[0].open_wait);
-+		}
-+	} else {		// other channel
-+		if ((ts0710->dlci[0].state != CONNECTED)
-+		    && (ts0710->dlci[0].state != FLOW_STOPPED)) {
-+			return retval;
-+		} else if ((ts0710->dlci[dlci].state == CONNECTED)
-+			   || (ts0710->dlci[dlci].state == FLOW_STOPPED)) {
-+			return 0;
-+		} else if ((ts0710->dlci[dlci].state == NEGOTIATING)
-+			   || (ts0710->dlci[dlci].state == CONNECTING)) {
-+			/* Reentry */
-+			try = 8;
-+			while (try--) {
-+				t = jiffies;
-+				interruptible_sleep_on_timeout(&ts0710->
-+							       dlci[dlci].
-+							       open_wait,
-+							       TS0710MUX_TIME_OUT);
-+				if ((ts0710->dlci[dlci].state == CONNECTED)
-+				    || (ts0710->dlci[dlci].state ==
-+					FLOW_STOPPED)) {
-+					retval = 0;
-+					break;
-+				} else if (ts0710->dlci[dlci].state == REJECTED) {
-+					retval = -EREJECTED;
-+					break;
-+				} else if (ts0710->dlci[dlci].state ==
-+					   DISCONNECTED) {
-+					break;
-+				} else if (signal_pending(current)) {
-+					TS0710_PRINTK
-+					    ("MUX DLCI:%d Wait for connecting got signal!\n",
-+					     dlci);
-+					retval = -EAGAIN;
-+					break;
-+				} else if ((jiffies - t) >= TS0710MUX_TIME_OUT) {
-+					TS0710_PRINTK
-+					    ("MUX DLCI:%d Wait for connecting timeout!\n",
-+					     dlci);
-+					continue;
-+				} else
-+				    if ((ts0710->dlci[dlci].state ==
-+					 NEGOTIATING)
-+					|| (ts0710->dlci[dlci].state ==
-+					    CONNECTING)) {
-+					continue;
-+				}
-+			}
-+
-+			if ((ts0710->dlci[dlci].state == NEGOTIATING)
-+			    || (ts0710->dlci[dlci].state == CONNECTING)) {
-+				ts0710->dlci[dlci].state = DISCONNECTED;
-+			}
-+		} else if ((ts0710->dlci[dlci].state != DISCONNECTED)
-+			   && (ts0710->dlci[dlci].state != REJECTED)) {
-+			TS0710_PRINTK("MUX DLCI:%d state is invalid!\n", dlci);
-+			return retval;
-+		} else {
-+			ts0710->dlci[dlci].state = NEGOTIATING;
-+			ts0710->dlci[dlci].initiator = 1;
-+			try = 3;
-+			while (try--) {
-+				t = jiffies;
-+				send_pn_msg(ts0710, 7, ts0710->dlci[dlci].mtu,
-+					    0, 0, dlci, 1);
-+				interruptible_sleep_on_timeout(&ts0710->
-+							       dlci[dlci].
-+							       open_wait,
-+							       TS0710MUX_TIME_OUT);
-+				if (ts0710->dlci[dlci].state == CONNECTING) {
-+					break;
-+				} else if (signal_pending(current)) {
-+					TS0710_PRINTK
-+					    ("MUX DLCI:%d Send pn_msg got signal!\n",
-+					     dlci);
-+					retval = -EAGAIN;
-+					break;
-+				} else if ((jiffies - t) >= TS0710MUX_TIME_OUT) {
-+					TS0710_PRINTK
-+					    ("MUX DLCI:%d Send pn_msg timeout!\n",
-+					     dlci);
-+					continue;
-+				}
-+			}
-+
-+			if (ts0710->dlci[dlci].state == CONNECTING) {
-+				try = 3;
-+				while (try--) {
-+					t = jiffies;
-+					send_sabm(ts0710, dlci);
-+					interruptible_sleep_on_timeout(&ts0710->
-+								       dlci
-+								       [dlci].
-+								       open_wait,
-+								       TS0710MUX_TIME_OUT);
-+					if ((ts0710->dlci[dlci].state ==
-+					     CONNECTED)
-+					    || (ts0710->dlci[dlci].state ==
-+						FLOW_STOPPED)) {
-+						retval = 0;
-+						break;
-+					} else if (ts0710->dlci[dlci].state ==
-+						   REJECTED) {
-+						TS0710_PRINTK
-+						    ("MUX DLCI:%d Send SABM got rejected!\n",
-+						     dlci);
-+						retval = -EREJECTED;
-+						break;
-+					} else if (signal_pending(current)) {
-+						TS0710_PRINTK
-+						    ("MUX DLCI:%d Send SABM got signal!\n",
-+						     dlci);
-+						retval = -EAGAIN;
-+						break;
-+					} else if ((jiffies - t) >=
-+						   TS0710MUX_TIME_OUT) {
-+						TS0710_PRINTK
-+						    ("MUX DLCI:%d Send SABM timeout!\n",
-+						     dlci);
-+						continue;
-+					}
-+				}
-+			}
-+
-+			if ((ts0710->dlci[dlci].state == NEGOTIATING)
-+			    || (ts0710->dlci[dlci].state == CONNECTING)) {
-+				ts0710->dlci[dlci].state = DISCONNECTED;
-+			}
-+			wake_up_interruptible(&ts0710->dlci[dlci].open_wait);
-+		}
-+	}
-+	return retval;
-+}
-+
-+static int ts0710_exec_test_cmd(void)
-+{
-+	ts0710_con *ts0710 = &ts0710_connection;
-+	__u8 *f_buf;		/* Frame buffer */
-+	__u8 *d_buf;		/* Data buffer */
-+	int retval = -EFAULT;
-+	int j;
-+	unsigned long t;
-+
-+	if (ts0710->be_testing) {
-+		/* Reentry */
-+		t = jiffies;
-+		interruptible_sleep_on_timeout(&ts0710->test_wait,
-+					       3 * TS0710MUX_TIME_OUT);
-+		if (ts0710->be_testing == 0) {
-+			if (ts0710->test_errs == 0) {
-+				retval = 0;
-+			} else {
-+				retval = -EFAULT;
-+			}
-+		} else if (signal_pending(current)) {
-+			TS0710_DEBUG
-+			    ("Wait for Test_cmd response got signal!\n");
-+			retval = -EAGAIN;
-+		} else if ((jiffies - t) >= 3 * TS0710MUX_TIME_OUT) {
-+			TS0710_DEBUG("Wait for Test_cmd response timeout!\n");
-+			retval = -EFAULT;
-+		}
-+	} else {
-+		ts0710->be_testing = 1;	/* Set the flag */
-+
-+		f_buf = (__u8 *) kmalloc(TEST_PATTERN_SIZE + 32, GFP_KERNEL);
-+		d_buf = (__u8 *) kmalloc(TEST_PATTERN_SIZE + 32, GFP_KERNEL);
-+		if ((!f_buf) || (!d_buf)) {
-+			if (f_buf) {
-+				kfree(f_buf);
-+			}
-+			if (d_buf) {
-+				kfree(d_buf);
-+			}
-+
-+			ts0710->be_testing = 0;	/* Clear the flag */
-+			ts0710->test_errs = TEST_PATTERN_SIZE;
-+			wake_up_interruptible(&ts0710->test_wait);
-+			return -ENOMEM;
-+		}
-+
-+		for (j = 0; j < TEST_PATTERN_SIZE; j++) {
-+			d_buf[j] = j & 0xFF;
-+		}
-+
-+		t = jiffies;
-+		ts0710_test_msg(ts0710, d_buf, TEST_PATTERN_SIZE, MCC_CMD,
-+				f_buf);
-+		interruptible_sleep_on_timeout(&ts0710->test_wait,
-+					       2 * TS0710MUX_TIME_OUT);
-+		if (ts0710->be_testing == 0) {
-+			if (ts0710->test_errs == 0) {
-+				retval = 0;
-+			} else {
-+				retval = -EFAULT;
-+			}
-+		} else if (signal_pending(current)) {
-+			TS0710_DEBUG("Send Test_cmd got signal!\n");
-+			retval = -EAGAIN;
-+		} else if ((jiffies - t) >= 2 * TS0710MUX_TIME_OUT) {
-+			TS0710_DEBUG("Send Test_cmd timeout!\n");
-+			ts0710->test_errs = TEST_PATTERN_SIZE;
-+			retval = -EFAULT;
-+		}
-+
-+		ts0710->be_testing = 0;	/* Clear the flag */
-+		wake_up_interruptible(&ts0710->test_wait);
-+
-+		/* Release buffer */
-+		if (f_buf) {
-+			kfree(f_buf);
-+		}
-+		if (d_buf) {
-+			kfree(d_buf);
-+		}
-+	}
-+
-+	return retval;
-+}
-+
-+static void mux_sched_send(void)
-+{
-+
-+#ifdef USB_FOR_MUX
-+	schedule_work(&send_tqueue);
-+#else
-+	if (!tq_serial_for_mux) {
-+		TS0710_PRINTK("MUX Error: %s: tq_serial_for_mux == 0\n",
-+			      __FUNCTION__);
-+		return;
-+	}
-+	schedule_work(&send_tqueue);
-+	mark_bh(SERIAL_BH);
-+#endif
-+
-+}
-+
-+/****************************
-+ * TTY driver routines
-+*****************************/
-+
-+static void mux_close(struct tty_struct *tty, struct file *filp)
-+{
-+	ts0710_con *ts0710 = &ts0710_connection;
-+	int line;
-+	__u8 dlci;
-+	__u8 cmdtty;
-+	__u8 datatty;
-+
-+	UNUSED_PARAM(filp);
-+
-+	if (!tty) {
-+		return;
-+	}
-+	line = tty->index;
-+	if ((line < 0) || (line >= NR_MUXS)) {
-+		return;
-+	}
-+	if (mux_tty[line] > 0)
-+		mux_tty[line]--;
-+
-+	dlci = tty2dlci[line];
-+	cmdtty = dlci2tty[dlci].cmdtty;
-+	datatty = dlci2tty[dlci].datatty;
-+	if ((mux_tty[cmdtty] == 0) && (mux_tty[datatty] == 0)) {
-+		if (dlci == 1) {
-+			ts0710_close_channel(0);
-+			TS0710_PRINTK
-+			    ("MUX mux_close: tapisrv might be down!!! Close DLCI 1\n");
-+			TS0710_SIG2APLOGD();
-+		}
-+		ts0710_close_channel(dlci);
-+	}
-+
-+	if (mux_tty[line] == 0) {
-+		if ((mux_send_info_flags[line])
-+		    && (mux_send_info[line])
-+		    /*&& (mux_send_info[line]->filled == 0) */
-+		    ) {
-+			mux_send_info_flags[line] = 0;
-+			kfree(mux_send_info[line]);
-+			mux_send_info[line] = 0;
-+			TS0710_DEBUG("Free mux_send_info for /dev/mux%d", line);
-+		}
-+
-+		if ((mux_recv_info_flags[line])
-+		    && (mux_recv_info[line])
-+		    && (mux_recv_info[line]->total == 0)) {
-+			mux_recv_info_flags[line] = 0;
-+			free_mux_recv_struct(mux_recv_info[line]);
-+			mux_recv_info[line] = 0;
-+			TS0710_DEBUG("Free mux_recv_info for /dev/mux%d", line);
-+		}
-+
-+		ts0710_flow_on(dlci, ts0710);
-+		schedule_work(&post_recv_tqueue);
-+
-+		wake_up_interruptible(&tty->read_wait);
-+		wake_up_interruptible(&tty->write_wait);
-+		tty->packet = 0;
-+	}
-+}
-+
-+static void mux_throttle(struct tty_struct *tty)
-+{
-+	ts0710_con *ts0710 = &ts0710_connection;
-+	int line;
-+	int i;
-+	__u8 dlci;
-+
-+	if (!tty) {
-+		return;
-+	}
-+
-+	line = tty->index;
-+	if ((line < 0) || (line >= NR_MUXS)) {
-+		return;
-+	}
-+
-+	TS0710_DEBUG("Enter into %s, minor number is: %d\n", __FUNCTION__,
-+		     line);
-+
-+	dlci = tty2dlci[line];
-+	if ((ts0710->dlci[0].state != CONNECTED)
-+	    && (ts0710->dlci[0].state != FLOW_STOPPED)) {
-+		return;
-+	} else if ((ts0710->dlci[dlci].state != CONNECTED)
-+		   && (ts0710->dlci[dlci].state != FLOW_STOPPED)) {
-+		return;
-+	}
-+
-+	if (ts0710->dlci[dlci].flow_control) {
-+		return;
-+	}
-+
-+	for (i = 0; i < 3; i++) {
-+		if (ts0710_msc_msg
-+		    (ts0710, EA | FC | RTC | RTR | DV, MCC_CMD, dlci) < 0) {
-+			continue;
-+		} else {
-+			TS0710_LOG("MUX Send Flow off on dlci %d\n", dlci);
-+			ts0710->dlci[dlci].flow_control = 1;
-+			break;
-+		}
-+	}
-+}
-+
-+static void mux_unthrottle(struct tty_struct *tty)
-+{
-+	ts0710_con *ts0710 = &ts0710_connection;
-+	int line;
-+	__u8 dlci;
-+	mux_recv_struct *recv_info;
-+
-+	if (!tty) {
-+		return;
-+	}
-+	line = tty->index;
-+	if ((line < 0) || (line >= NR_MUXS)) {
-+		return;
-+	}
-+
-+	if ((!mux_recv_info_flags[line]) || (!mux_recv_info[line])) {
-+		return;
-+	}
-+
-+	TS0710_DEBUG("Enter into %s, minor number is: %d\n", __FUNCTION__,
-+		     line);
-+
-+	recv_info = mux_recv_info[line];
-+	dlci = tty2dlci[line];
-+
-+	if (recv_info->total) {
-+		recv_info->post_unthrottle = 1;
-+		schedule_work(&post_recv_tqueue);
-+	} else {
-+		ts0710_flow_on(dlci, ts0710);
-+	}
-+}
-+
-+static int mux_chars_in_buffer(struct tty_struct *tty)
-+{
-+	ts0710_con *ts0710 = &ts0710_connection;
-+	int retval;
-+	int line;
-+	__u8 dlci;
-+	mux_send_struct *send_info;
-+
-+	retval = TS0710MUX_MAX_CHARS_IN_BUF;
-+	if (!tty) {
-+		goto out;
-+	}
-+	line = tty->index;
-+	if ((line < 0) || (line >= NR_MUXS)) {
-+		goto out;
-+	}
-+
-+	dlci = tty2dlci[line];
-+	if (ts0710->dlci[0].state == FLOW_STOPPED) {
-+		TS0710_DEBUG
-+		    ("Flow stopped on all channels, returning MAX chars in buffer\n");
-+		goto out;
-+	} else if (ts0710->dlci[dlci].state == FLOW_STOPPED) {
-+		TS0710_DEBUG("Flow stopped, returning MAX chars in buffer\n");
-+		goto out;
-+	} else if (ts0710->dlci[dlci].state != CONNECTED) {
-+		TS0710_DEBUG("DLCI %d not connected\n", dlci);
-+		goto out;
-+	}
-+
-+	if (!(mux_send_info_flags[line])) {
-+		goto out;
-+	}
-+	send_info = mux_send_info[line];
-+	if (!send_info) {
-+		goto out;
-+	}
-+	if (send_info->filled) {
-+		goto out;
-+	}
-+
-+	retval = 0;
-+
-+      out:
-+	return retval;
-+}
-+
-+static int mux_chars_in_serial_buffer(struct tty_struct *tty)
-+{
-+	UNUSED_PARAM(tty);
-+
-+	if ((COMM_FOR_MUX_DRIVER == 0) || (COMM_FOR_MUX_TTY == 0)) {
-+		TS0710_PRINTK
-+		    ("MUX %s: (COMM_FOR_MUX_DRIVER == 0) || (COMM_FOR_MUX_TTY == 0)\n",
-+		     __FUNCTION__);
-+
-+#ifndef USB_FOR_MUX
-+		TS0710_PRINTK
-+		    ("MUX %s: tapisrv might be down!!! (serial_for_mux_driver == 0) || (serial_for_mux_tty == 0)\n",
-+		     __FUNCTION__);
-+		TS0710_SIG2APLOGD();
-+#endif
-+
-+		return 0;
-+	}
-+	return COMM_FOR_MUX_DRIVER->chars_in_buffer(COMM_FOR_MUX_TTY);
-+}
-+
-+static int mux_write(struct tty_struct *tty,
-+		     const unsigned char *buf, int count)
-+{
-+	ts0710_con *ts0710 = &ts0710_connection;
-+	int line;
-+	__u8 dlci;
-+	mux_send_struct *send_info;
-+	__u8 *d_buf;
-+	__u16 c;
-+	__u8 post_recv;
-+
-+	if (count <= 0) {
-+		return 0;
-+	}
-+
-+	if (!tty) {
-+		return 0;
-+	}
-+
-+	line = tty->index;
-+	if ((line < 0) || (line >= NR_MUXS))
-+		return -ENODEV;
-+
-+	dlci = tty2dlci[line];
-+	if (ts0710->dlci[0].state == FLOW_STOPPED) {
-+		TS0710_DEBUG
-+		    ("Flow stopped on all channels, returning zero /dev/mux%d\n",
-+		     line);
-+		return 0;
-+	} else if (ts0710->dlci[dlci].state == FLOW_STOPPED) {
-+		TS0710_DEBUG("Flow stopped, returning zero /dev/mux%d\n", line);
-+		return 0;
-+	} else if (ts0710->dlci[dlci].state == CONNECTED) {
-+
-+		if (!(mux_send_info_flags[line])) {
-+			TS0710_PRINTK
-+			    ("MUX Error: mux_write: mux_send_info_flags[%d] == 0\n",
-+			     line);
-+			return -ENODEV;
-+		}
-+		send_info = mux_send_info[line];
-+		if (!send_info) {
-+			TS0710_PRINTK
-+			    ("MUX Error: mux_write: mux_send_info[%d] == 0\n",
-+			     line);
-+			return -ENODEV;
-+		}
-+
-+		c = min(count, (ts0710->dlci[dlci].mtu - 1));
-+		if (c <= 0) {
-+			return 0;
-+		}
-+
-+		if (test_and_set_bit(BUF_BUSY, &send_info->flags))
-+			return 0;
-+
-+		if (send_info->filled) {
-+			clear_bit(BUF_BUSY, &send_info->flags);
-+			return 0;
-+		}
-+
-+		d_buf = ((__u8 *) send_info->buf) + TS0710MUX_SEND_BUF_OFFSET;
-+		memcpy(&d_buf[1], buf, c);
-+
-+		TS0710_DEBUG("Prepare to send %d bytes from /dev/mux%d", c,
-+			     line);
-+		if (iscmdtty[line]) {
-+			TS0710_DEBUGSTR(&d_buf[1], c);
-+			TS0710_DEBUG("CMDTAG");
-+			d_buf[0] = CMDTAG;
-+		} else {
-+			TS0710_DEBUG("DATATAG");
-+			d_buf[0] = DATATAG;
-+		}
-+
-+		TS0710_DEBUGHEX(d_buf, c + 1);
-+
-+		send_info->frame = d_buf;
-+		queue_uih(send_info, c + 1, ts0710, dlci);
-+		send_info->filled = 1;
-+		clear_bit(BUF_BUSY, &send_info->flags);
-+
-+		post_recv = 0;
-+		if (dlci == TS0710MUX_GPRS1_DLCI) {
-+			if (add_count
-+			    (TS0710MUX_GPRS1_SEND_COUNT_IDX, c) < 0) {
-+				post_recv_count_flag = 1;
-+				post_recv = 1;
-+				mux_data_count2[TS0710MUX_GPRS1_SEND_COUNT_IDX]
-+				    += c;
-+			}
-+		} else if (dlci == TS0710MUX_GPRS2_DLCI) {
-+			if (add_count
-+			    (TS0710MUX_GPRS2_SEND_COUNT_IDX, c) < 0) {
-+				post_recv_count_flag = 1;
-+				post_recv = 1;
-+				mux_data_count2[TS0710MUX_GPRS2_SEND_COUNT_IDX]
-+				    += c;
-+			}
-+		}
-+
-+		if (post_recv)
-+			schedule_work(&post_recv_tqueue);
-+
-+		if (mux_chars_in_serial_buffer(COMM_FOR_MUX_TTY) == 0) {
-+			/* Sending bottom half should be
-+			   run after return from this function */
-+			mux_sched_send();
-+		}
-+		return c;
-+	} else {
-+		TS0710_PRINTK("MUX mux_write: DLCI %d not connected\n", dlci);
-+		return -EDISCONNECTED;
-+	}
-+}
-+
-+static int mux_write_room(struct tty_struct *tty)
-+{
-+	ts0710_con *ts0710 = &ts0710_connection;
-+	int retval;
-+	int line;
-+	__u8 dlci;
-+	mux_send_struct *send_info;
-+
-+	retval = 0;
-+	if (!tty) {
-+		goto out;
-+	}
-+	line = tty->index;
-+	if ((line < 0) || (line >= NR_MUXS)) {
-+		goto out;
-+	}
-+
-+	dlci = tty2dlci[line];
-+	if (ts0710->dlci[0].state == FLOW_STOPPED) {
-+		TS0710_DEBUG("Flow stopped on all channels, returning ZERO\n");
-+		goto out;
-+	} else if (ts0710->dlci[dlci].state == FLOW_STOPPED) {
-+		TS0710_DEBUG("Flow stopped, returning ZERO\n");
-+		goto out;
-+	} else if (ts0710->dlci[dlci].state != CONNECTED) {
-+		TS0710_DEBUG("DLCI %d not connected\n", dlci);
-+		goto out;
-+	}
-+
-+	if (!(mux_send_info_flags[line])) {
-+		goto out;
-+	}
-+	send_info = mux_send_info[line];
-+	if (!send_info) {
-+		goto out;
-+	}
-+	if (send_info->filled) {
-+		goto out;
-+	}
-+
-+	retval = ts0710->dlci[dlci].mtu - 1;
-+
-+      out:
-+	return retval;
-+}
-+
-+static int mux_ioctl(struct tty_struct *tty, struct file *file,
-+		     unsigned int cmd, unsigned long arg)
-+{
-+	ts0710_con *ts0710 = &ts0710_connection;
-+	int line;
-+	__u8 dlci;
-+
-+	UNUSED_PARAM(file);
-+	UNUSED_PARAM(arg);
-+
-+	if (!tty) {
-+		return -EIO;
-+	}
-+	line = tty->index;
-+	if ((line < 0) || (line >= NR_MUXS)) {
-+		return -ENODEV;
-+	}
-+
-+	dlci = tty2dlci[line];
-+	switch (cmd) {
-+	case TS0710MUX_IO_MSC_HANGUP:
-+		if (ts0710_msc_msg(ts0710, EA | RTR | DV, MCC_CMD, dlci) < 0) {
-+			return -EAGAIN;
-+		} else {
-+			return 0;
-+		}
-+
-+	case TS0710MUX_IO_TEST_CMD:
-+		return ts0710_exec_test_cmd();
-+/*
-+    case TS0710MUX_IO_DLCI_FC_ON:
-+      if( line == 0 ) {
-+        break;
-+      }
-+      if( ts0710_msc_msg(ts0710, EA | RTC | RTR | DV, MCC_CMD, (__u8)line) < 0) {
-+        return -EAGAIN;
-+      } else {
-+        return 0;
-+      }
-+
-+    case TS0710MUX_IO_DLCI_FC_OFF:
-+      if( line == 0 ) {
-+        break;
-+      }
-+      if( ts0710_msc_msg(ts0710, EA | FC | RTC | RTR | DV, MCC_CMD, (__u8)line) < 0) {
-+        return -EAGAIN;
-+      } else {
-+        return 0;
-+      }
-+
-+    case TS0710MUX_IO_FC_ON:
-+      if( line != 0 ) {
-+        break;
-+      }
-+      if( ts0710_fcon_msg(ts0710, MCC_CMD) < 0) {
-+        return -EAGAIN;
-+      } else {
-+        return 0;
-+      }
-+
-+    case TS0710MUX_IO_FC_OFF:
-+      if( line != 0 ) {
-+        break;
-+      }
-+      if( ts0710_fcoff_msg(ts0710, MCC_CMD) < 0) {
-+        return -EAGAIN;
-+      } else {
-+        return 0;
-+      }
-+*/
-+	default:
-+		break;
-+	}
-+	return -ENOIOCTLCMD;
-+}
-+
-+static void mux_flush_buffer(struct tty_struct *tty)
-+{
-+	int line;
-+
-+	if (!tty) {
-+		return;
-+	}
-+
-+	line = tty->index;
-+	if ((line < 0) || (line >= NR_MUXS)) {
-+		return;
-+	}
-+
-+	TS0710_PRINTK("MUX %s: line is:%d\n", __FUNCTION__, line);
-+
-+	if ((mux_send_info_flags[line])
-+	    && (mux_send_info[line])
-+	    && (mux_send_info[line]->filled)) {
-+
-+		mux_send_info[line]->filled = 0;
-+	}
-+
-+	wake_up_interruptible(&tty->write_wait);
-+#ifdef SERIAL_HAVE_POLL_WAIT
-+	wake_up_interruptible(&tty->poll_wait);
-+#endif
-+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-+	    tty->ldisc.write_wakeup) {
-+		(tty->ldisc.write_wakeup) (tty);
-+	}
-+
-+/*
-+  if( (COMM_FOR_MUX_DRIVER == 0) || (COMM_FOR_MUX_TTY == 0) ) {
-+    TS0710_PRINTK("MUX %s: (COMM_FOR_MUX_DRIVER == 0) || (COMM_FOR_MUX_TTY == 0)\n", __FUNCTION__);
-+
-+#ifndef USB_FOR_MUX
-+    TS0710_PRINTK("MUX %s: tapisrv might be down!!! (serial_for_mux_driver == 0) || (serial_for_mux_tty == 0)\n", __FUNCTION__);
-+    TS0710_SIG2APLOGD();
-+#endif
-+
-+    return;
-+  }
-+  return COMM_FOR_MUX_DRIVER->flush_buffer(COMM_FOR_MUX_TTY);
-+*/
-+}
-+
-+static int mux_open(struct tty_struct *tty, struct file *filp)
-+{
-+	int retval;
-+	int line;
-+	__u8 dlci;
-+	__u8 cmdtty;
-+	__u8 datatty;
-+	mux_send_struct *send_info;
-+	mux_recv_struct *recv_info;
-+
-+	UNUSED_PARAM(filp);
-+
-+	retval = -ENODEV;
-+	if ((COMM_FOR_MUX_DRIVER == NULL) || (COMM_FOR_MUX_TTY == NULL)) {
-+
-+#ifdef USB_FOR_MUX
-+		TS0710_PRINTK("MUX: please install and open IPC-USB first\n");
-+#else
-+		TS0710_PRINTK("MUX: please install and open ttyS0 first\n");
-+#endif
-+
-+		goto out;
-+	}
-+
-+	if (!tty) {
-+		goto out;
-+	}
-+	line = tty->index;
-+	if ((line < 0) || (line >= NR_MUXS)) {
-+		goto out;
-+	}
-+#ifdef TS0710SERVER
-+	/* do nothing as a server */
-+	mux_tty[line]++;
-+	retval = 0;
-+#else
-+	mux_tty[line]++;
-+	dlci = tty2dlci[line];
-+
-+/*  if( dlci == 1 ) { */
-+	/* Open server channel 0 first */
-+	if ((retval = ts0710_open_channel(0)) != 0) {
-+		TS0710_PRINTK("MUX: Can't connect server channel 0!\n");
-+		ts0710_init();
-+
-+		mux_tty[line]--;
-+		goto out;
-+	}
-+/*  } */
-+
-+	/* Allocate memory first. As soon as connection has been established, MUX may receive */
-+	if (mux_send_info_flags[line] == 0) {
-+		send_info =
-+		    (mux_send_struct *) kmalloc(sizeof(mux_send_struct),
-+						GFP_KERNEL);
-+		if (!send_info) {
-+			retval = -ENOMEM;
-+
-+			mux_tty[line]--;
-+			goto out;
-+		}
-+		send_info->length = 0;
-+		send_info->flags = 0;
-+		send_info->filled = 0;
-+		mux_send_info[line] = send_info;
-+		mux_send_info_flags[line] = 1;
-+		TS0710_DEBUG("Allocate mux_send_info for /dev/mux%d", line);
-+	}
-+
-+	if (mux_recv_info_flags[line] == 0) {
-+		recv_info =
-+		    (mux_recv_struct *) kmalloc(sizeof(mux_recv_struct),
-+						GFP_KERNEL);
-+		if (!recv_info) {
-+			mux_send_info_flags[line] = 0;
-+			kfree(mux_send_info[line]);
-+			mux_send_info[line] = 0;
-+			TS0710_DEBUG("Free mux_send_info for /dev/mux%d", line);
-+			retval = -ENOMEM;
-+
-+			mux_tty[line]--;
-+			goto out;
-+		}
-+		recv_info->length = 0;
-+		recv_info->total = 0;
-+		recv_info->mux_packet = 0;
-+		recv_info->next = 0;
-+		recv_info->no_tty = line;
-+		recv_info->post_unthrottle = 0;
-+		mux_recv_info[line] = recv_info;
-+		mux_recv_info_flags[line] = 1;
-+		TS0710_DEBUG("Allocate mux_recv_info for /dev/mux%d", line);
-+	}
-+
-+	/* Now establish DLCI connection */
-+	cmdtty = dlci2tty[dlci].cmdtty;
-+	datatty = dlci2tty[dlci].datatty;
-+	if ((mux_tty[cmdtty] > 0) || (mux_tty[datatty] > 0)) {
-+		if ((retval = ts0710_open_channel(dlci)) != 0) {
-+			TS0710_PRINTK("MUX: Can't connected channel %d!\n",
-+				      dlci);
-+			ts0710_reset_dlci(dlci);
-+
-+			mux_send_info_flags[line] = 0;
-+			kfree(mux_send_info[line]);
-+			mux_send_info[line] = 0;
-+			TS0710_DEBUG("Free mux_send_info for /dev/mux%d", line);
-+
-+			mux_recv_info_flags[line] = 0;
-+			free_mux_recv_struct(mux_recv_info[line]);
-+			mux_recv_info[line] = 0;
-+			TS0710_DEBUG("Free mux_recv_info for /dev/mux%d", line);
-+
-+			mux_tty[line]--;
-+			goto out;
-+		}
-+	}
-+
-+	retval = 0;
-+#endif
-+      out:
-+	return retval;
-+}
-+
-+/* mux dispatcher, call from serial.c receiver_chars() */
-+void mux_dispatcher(struct tty_struct *tty)
-+{
-+	UNUSED_PARAM(tty);
-+
-+	schedule_work(&receive_tqueue);
-+}
-+
-+/*For BP UART problem Begin*/
-+#ifdef TS0710SEQ2
-+static int send_ack(ts0710_con * ts0710, __u8 seq_num, __u8 bp_seq1,
-+		    __u8 bp_seq2)
-+#else
-+static int send_ack(ts0710_con * ts0710, __u8 seq_num)
-+#endif
-+{
-+	__u8 buf[20];
-+	short_frame *ack;
-+
-+#ifdef TS0710SEQ2
-+	static __u16 ack_seq = 0;
-+#endif
-+
-+	ack = (short_frame *) (buf + 1);
-+	ack->h.addr.ea = 1;
-+	ack->h.addr.cr = ((ts0710->initiator) & 0x1);
-+	ack->h.addr.d = 0;
-+	ack->h.addr.server_chn = 0;
-+	ack->h.control = ACK;
-+	ack->h.length.ea = 1;
-+
-+#ifdef TS0710SEQ2
-+	ack->h.length.len = 5;
-+	ack->data[0] = seq_num;
-+	ack->data[1] = bp_seq1;
-+	ack->data[2] = bp_seq2;
-+	ack->data[3] = (ack_seq & 0xFF);
-+	ack->data[4] = (ack_seq >> 8) & 0xFF;
-+	ack_seq++;
-+	ack->data[5] = crc_calc((__u8 *) ack, SHORT_CRC_CHECK);
-+#else
-+	ack->h.length.len = 1;
-+	ack->data[0] = seq_num;
-+	ack->data[1] = crc_calc((__u8 *) ack, SHORT_CRC_CHECK);
-+#endif
-+
-+	return basic_write(ts0710, buf,
-+			   (sizeof(short_frame) + FCS_SIZE +
-+			    ack->h.length.len));
-+}
-+
-+/*For BP UART problem End*/
-+
-+static void receive_worker(void *private_)
-+{
-+	struct tty_struct *tty = COMM_FOR_MUX_TTY;
-+	int i, count;
-+	static unsigned char tbuf[TS0710MUX_MAX_BUF_SIZE];
-+	static unsigned char *tbuf_ptr = &tbuf[0];
-+	static unsigned char *start_flag = 0;
-+	unsigned char *search, *to, *from;
-+	short_frame *short_pkt;
-+	long_frame *long_pkt;
-+	static int framelen = -1;
-+
-+	/*For BP UART problem Begin */
-+	static __u8 expect_seq = 0;
-+	__u32 crc_error;
-+	__u8 *uih_data_start;
-+	__u32 uih_len;
-+	/*For BP UART problem End */
-+
-+	UNUSED_PARAM(private_);
-+
-+	if (!tty)
-+		return;
-+
-+#ifdef USB_FOR_MUX
-+	TS0710_DEBUG("Receive following bytes from IPC-USB");
-+#else
-+	TS0710_DEBUG("Receive following bytes from UART");
-+#endif
-+
-+	TS0710_DEBUGHEX(cp, count);
-+
-+	if (count > (TS0710MUX_MAX_BUF_SIZE - (tbuf_ptr - tbuf))) {
-+		TS0710_PRINTK
-+		    ("MUX receive_worker: !!!!! Exceed buffer boundary !!!!!\n");
-+		count = (TS0710MUX_MAX_BUF_SIZE - (tbuf_ptr - tbuf));
-+	}
-+
-+	count = tty_buffer_request_room(tty, count);
-+
-+	for (i = 0; i < count; i++)
-+		tty_insert_flip_char(tty, tbuf_ptr[i], TTY_NORMAL);
-+
-+	tbuf_ptr += count;
-+	search = &tbuf[0];
-+
-+	if (test_and_set_bit(RECV_RUNNING, &mux_recv_flags)) {
-+		schedule_work(&receive_tqueue);
-+		return;
-+	}
-+
-+	if ((start_flag != 0) && (framelen != -1)) {
-+		if ((tbuf_ptr - start_flag) < framelen) {
-+			clear_bit(RECV_RUNNING, &mux_recv_flags);
-+			return;
-+		}
-+	}
-+
-+	while (1) {
-+		if (start_flag == 0) {	/* Frame Start Flag not found */
-+			framelen = -1;
-+			while (search < tbuf_ptr) {
-+				if (*search == TS0710_BASIC_FLAG) {
-+					start_flag = search;
-+					break;
-+				}
-+#ifdef TS0710LOG
-+				else {
-+					TS0710_LOG(">S %02x %c\n", *search,
-+						   *search);
-+				}
-+#endif
-+
-+				search++;
-+			}
-+
-+			if (start_flag == 0) {
-+				tbuf_ptr = &tbuf[0];
-+				break;
-+			}
-+		} else {	/* Frame Start Flag found */
-+			/* 1 start flag + 1 address + 1 control + 1 or 2 length + lengths data + 1 FCS + 1 end flag */
-+			/* For BP UART problem 1 start flag + 1 seq_num + 1 address + ...... */
-+			/*if( (framelen == -1) && ((tbuf_ptr - start_flag) > TS0710_MAX_HDR_SIZE) ) */
-+			if ((framelen == -1) && ((tbuf_ptr - start_flag) > (TS0710_MAX_HDR_SIZE + SEQ_FIELD_SIZE))) {	/*For BP UART problem */
-+				/*short_pkt = (short_frame *) (start_flag + 1); */
-+				short_pkt = (short_frame *) (start_flag + ADDRESS_FIELD_OFFSET);	/*For BP UART problem */
-+				if (short_pkt->h.length.ea == 1) {	/* short frame */
-+					/*framelen = TS0710_MAX_HDR_SIZE + short_pkt->h.length.len + 1; */
-+					framelen = TS0710_MAX_HDR_SIZE + short_pkt->h.length.len + 1 + SEQ_FIELD_SIZE;	/*For BP UART problem */
-+				} else {	/* long frame */
-+					/*long_pkt = (long_frame *) (start_flag + 1); */
-+					long_pkt = (long_frame *) (start_flag + ADDRESS_FIELD_OFFSET);	/*For BP UART problem */
-+					/*framelen = TS0710_MAX_HDR_SIZE + GET_LONG_LENGTH( long_pkt->h.length ) + 2; */
-+					framelen = TS0710_MAX_HDR_SIZE + GET_LONG_LENGTH(long_pkt->h.length) + 2 + SEQ_FIELD_SIZE;	/*For BP UART problem */
-+				}
-+
-+				/*if( framelen > TS0710MUX_MAX_TOTAL_FRAME_SIZE ) { */
-+				if (framelen > (TS0710MUX_MAX_TOTAL_FRAME_SIZE + SEQ_FIELD_SIZE)) {	/*For BP UART problem */
-+					TS0710_LOGSTR_FRAME(0, start_flag,
-+							    (tbuf_ptr -
-+							     start_flag));
-+					TS0710_PRINTK
-+					    ("MUX Error: %s: frame length:%d is bigger than Max total frame size:%d\n",
-+		 /*__FUNCTION__, framelen, TS0710MUX_MAX_TOTAL_FRAME_SIZE);*/
-+					     __FUNCTION__, framelen, (TS0710MUX_MAX_TOTAL_FRAME_SIZE + SEQ_FIELD_SIZE));	/*For BP UART problem */
-+					search = start_flag + 1;
-+					start_flag = 0;
-+					framelen = -1;
-+					continue;
-+				}
-+			}
-+
-+			if ((framelen != -1)
-+			    && ((tbuf_ptr - start_flag) >= framelen)) {
-+				if (*(start_flag + framelen - 1) == TS0710_BASIC_FLAG) {	/* OK, We got one frame */
-+
-+					/*For BP UART problem Begin */
-+					TS0710_LOGSTR_FRAME(0, start_flag,
-+							    framelen);
-+					TS0710_DEBUGHEX(start_flag, framelen);
-+
-+					short_pkt =
-+					    (short_frame *) (start_flag +
-+							     ADDRESS_FIELD_OFFSET);
-+					if ((short_pkt->h.length.ea) == 0) {
-+						long_pkt =
-+						    (long_frame *) (start_flag +
-+								    ADDRESS_FIELD_OFFSET);
-+						uih_len =
-+						    GET_LONG_LENGTH(long_pkt->h.
-+								    length);
-+						uih_data_start =
-+						    long_pkt->h.data;
-+
-+						crc_error =
-+						    crc_check((__u8
-+							       *) (start_flag +
-+								   SLIDE_BP_SEQ_OFFSET),
-+							      LONG_CRC_CHECK +
-+							      1,
-+							      *(uih_data_start +
-+								uih_len));
-+					} else {
-+						uih_len =
-+						    short_pkt->h.length.len;
-+						uih_data_start =
-+						    short_pkt->data;
-+
-+						crc_error =
-+						    crc_check((__u8
-+							       *) (start_flag +
-+								   SLIDE_BP_SEQ_OFFSET),
-+							      SHORT_CRC_CHECK +
-+							      1,
-+							      *(uih_data_start +
-+								uih_len));
-+					}
-+
-+					if (!crc_error) {
-+						if (expect_seq ==
-+						    *(start_flag +
-+						      SLIDE_BP_SEQ_OFFSET)) {
-+							expect_seq++;
-+							if (expect_seq >= 4) {
-+								expect_seq = 0;
-+							}
-+#ifdef TS0710SEQ2
-+							send_ack
-+							    (&ts0710_connection,
-+							     expect_seq,
-+							     *(start_flag +
-+							       FIRST_BP_SEQ_OFFSET),
-+							     *(start_flag +
-+							       SECOND_BP_SEQ_OFFSET));
-+#else
-+							send_ack
-+							    (&ts0710_connection,
-+							     expect_seq);
-+#endif
-+
-+							ts0710_recv_data
-+							    (&ts0710_connection,
-+							     start_flag +
-+							     ADDRESS_FIELD_OFFSET,
-+							     framelen - 2 -
-+							     SEQ_FIELD_SIZE);
-+						} else {
-+
-+#ifdef TS0710DEBUG
-+							if (*
-+							    (start_flag +
-+							     SLIDE_BP_SEQ_OFFSET)
-+							    != 0x9F) {
-+#endif
-+
-+								TS0710_LOG
-+								    ("MUX sequence number %d is not expected %d, discard data!\n",
-+								     *
-+								     (start_flag
-+								      +
-+								      SLIDE_BP_SEQ_OFFSET),
-+								     expect_seq);
-+
-+#ifdef TS0710SEQ2
-+								send_ack
-+								    (&ts0710_connection,
-+								     expect_seq,
-+								     *
-+								     (start_flag
-+								      +
-+								      FIRST_BP_SEQ_OFFSET),
-+								     *
-+								     (start_flag
-+								      +
-+								      SECOND_BP_SEQ_OFFSET));
-+#else
-+								send_ack
-+								    (&ts0710_connection,
-+								     expect_seq);
-+#endif
-+
-+#ifdef TS0710DEBUG
-+							} else {
-+								*(uih_data_start
-+								  + uih_len) =
-+						     0;
-+								TS0710_PRINTK
-+								    ("MUX bp log: %s\n",
-+								     uih_data_start);
-+							}
-+#endif
-+
-+						}
-+					} else {	/* crc_error */
-+						search = start_flag + 1;
-+						start_flag = 0;
-+						framelen = -1;
-+						continue;
-+					}	/*End if(!crc_error) */
-+
-+					/*For BP UART problem End */
-+
-+/*For BP UART problem
-+          TS0710_LOGSTR_FRAME(0, start_flag, framelen);
-+          TS0710_DEBUGHEX(start_flag, framelen);
-+	  ts0710_recv_data(&ts0710_connection, start_flag + 1, framelen - 2);
-+*/
-+					search = start_flag + framelen;
-+				} else {
-+					TS0710_LOGSTR_FRAME(0, start_flag,
-+							    framelen);
-+					TS0710_DEBUGHEX(start_flag, framelen);
-+					TS0710_PRINTK
-+					    ("MUX: Lost synchronization!\n");
-+					search = start_flag + 1;
-+				}
-+
-+				start_flag = 0;
-+				framelen = -1;
-+				continue;
-+			}
-+
-+			if (start_flag != &tbuf[0]) {
-+				to = tbuf;
-+				from = start_flag;
-+				count = tbuf_ptr - start_flag;
-+				while (count--) {
-+					*to++ = *from++;
-+				}
-+
-+				tbuf_ptr -= (start_flag - tbuf);
-+				start_flag = tbuf;
-+			}
-+			break;
-+		}		/* End Frame Start Flag found */
-+	}			/* End while(1) */
-+
-+	clear_bit(RECV_RUNNING, &mux_recv_flags);
-+}
-+
-+static void post_recv_worker(void *private_)
-+{
-+	ts0710_con *ts0710 = &ts0710_connection;
-+	int tty_idx;
-+	struct tty_struct *tty;
-+	__u8 post_recv;
-+	__u8 flow_control;
-+	__u8 dlci;
-+	mux_recv_struct *recv_info, *recv_info2, *post_recv_q;
-+	int recv_room;
-+	mux_recv_packet *recv_packet, *recv_packet2;
-+	__u8 j;
-+
-+	UNUSED_PARAM(private_);
-+
-+	if (test_and_set_bit(RECV_RUNNING, &mux_recv_flags)) {
-+		schedule_work(&post_recv_tqueue);
-+		return;
-+	}
-+
-+	TS0710_DEBUG("Enter into post_recv_worker");
-+
-+	post_recv = 0;
-+	if (!mux_recv_queue) {
-+		goto out;
-+	}
-+
-+	post_recv_q = NULL;
-+	recv_info2 = mux_recv_queue;
-+	while ((recv_info = recv_info2)) {
-+		recv_info2 = recv_info->next;
-+
-+		if (!(recv_info->total)) {
-+			TS0710_PRINTK
-+			    ("MUX Error: %s: Should not get here, recv_info->total == 0 \n",
-+			     __FUNCTION__);
-+			continue;
-+		}
-+
-+		tty_idx = recv_info->no_tty;
-+		dlci = tty2dlci[tty_idx];
-+		tty = mux_table[tty_idx];
-+		if ((!mux_tty[tty_idx]) || (!tty)) {
-+			TS0710_PRINTK
-+			    ("MUX: No application waiting for, free recv_info! tty_idx:%d\n",
-+			     tty_idx);
-+			mux_recv_info_flags[tty_idx] = 0;
-+			free_mux_recv_struct(mux_recv_info[tty_idx]);
-+			mux_recv_info[tty_idx] = 0;
-+			ts0710_flow_on(dlci, ts0710);
-+			continue;
-+		}
-+
-+		TS0710_DEBUG("/dev/mux%d recv_info->total is: %d", tty_idx,
-+			     recv_info->total);
-+
-+		if (test_bit(TTY_THROTTLED, &tty->flags)) {
-+			add_post_recv_queue(&post_recv_q, recv_info);
-+			continue;
-+		} else if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
-+			post_recv = 1;
-+			add_post_recv_queue(&post_recv_q, recv_info);
-+			continue;
-+		}
-+
-+		flow_control = 0;
-+		recv_packet2 = recv_info->mux_packet;
-+		while (recv_info->total) {
-+			recv_room = 65535;
-+			if (tty->receive_room)
-+				recv_room = tty->receive_room;
-+
-+			if (recv_info->length) {
-+				if (recv_room < recv_info->length) {
-+					flow_control = 1;
-+					break;
-+				}
-+
-+				/* Put queued data into read buffer of tty */
-+				TS0710_DEBUG
-+				    ("Put queued recv data into read buffer of /dev/mux%d",
-+				     tty_idx);
-+				TS0710_DEBUGHEX(recv_info->data,
-+						recv_info->length);
-+				(tty->ldisc.receive_buf) (tty, recv_info->data,
-+							  NULL,
-+							  recv_info->length);
-+				recv_info->total -= recv_info->length;
-+				recv_info->length = 0;
-+			} else {	/* recv_info->length == 0 */
-+				if ((recv_packet = recv_packet2)) {
-+					recv_packet2 = recv_packet->next;
-+
-+					if (recv_room < recv_packet->length) {
-+						flow_control = 1;
-+						recv_info->mux_packet =
-+						    recv_packet;
-+						break;
-+					}
-+
-+					/* Put queued data into read buffer of tty */
-+					TS0710_DEBUG
-+					    ("Put queued recv data into read buffer of /dev/mux%d",
-+					     tty_idx);
-+					TS0710_DEBUGHEX(recv_packet->data,
-+							recv_packet->length);
-+					(tty->ldisc.receive_buf) (tty,
-+								  recv_packet->
-+								  data, NULL,
-+								  recv_packet->
-+								  length);
-+					recv_info->total -= recv_packet->length;
-+					free_mux_recv_packet(recv_packet);
-+				} else {
-+					TS0710_PRINTK
-+					    ("MUX Error: %s: Should not get here, recv_info->total is:%u \n",
-+					     __FUNCTION__, recv_info->total);
-+				}
-+			}	/* End recv_info->length == 0 */
-+		}		/* End while( recv_info->total ) */
-+
-+		if (!(recv_info->total)) {
-+			/* Important clear */
-+			recv_info->mux_packet = 0;
-+
-+			if (recv_info->post_unthrottle) {
-+				/* Do something for post_unthrottle */
-+				ts0710_flow_on(dlci, ts0710);
-+				recv_info->post_unthrottle = 0;
-+			}
-+		} else {
-+			add_post_recv_queue(&post_recv_q, recv_info);
-+
-+			if (flow_control) {
-+				/* Do something for flow control */
-+				if (recv_info->post_unthrottle) {
-+					set_bit(TTY_THROTTLED, &tty->flags);
-+					recv_info->post_unthrottle = 0;
-+				} else {
-+					ts0710_flow_off(tty, dlci, ts0710);
-+				}
-+			}	/* End if( flow_control ) */
-+		}
-+	}			/* End while( (recv_info = recv_info2) ) */
-+
-+	mux_recv_queue = post_recv_q;
-+
-+      out:
-+	if (post_recv_count_flag) {
-+		post_recv_count_flag = 0;
-+		for (j = 0; j < TS0710MUX_COUNT_IDX_NUM; j++) {
-+			if (mux_data_count2[j] > 0) {
-+				if (add_count(j, mux_data_count2[j]) == 0) {
-+					mux_data_count2[j] = 0;
-+				} else {
-+					post_recv_count_flag = 1;
-+					post_recv = 1;
-+				}
-+			}
-+		}		/* End for (j = 0; j < TS0710MUX_COUNT_IDX_NUM; j++) */
-+	}
-+	/* End if( post_recv_count_flag ) */
-+	if (post_recv)
-+		schedule_work(&post_recv_tqueue);
-+	clear_bit(RECV_RUNNING, &mux_recv_flags);
-+}
-+
-+/* mux sender, call from serial.c transmit_chars() */
-+void mux_sender(void)
-+{
-+	mux_send_struct *send_info;
-+	int chars;
-+	__u8 idx;
-+
-+	chars = mux_chars_in_serial_buffer(COMM_FOR_MUX_TTY);
-+	if (!chars) {
-+		/* chars == 0 */
-+		TS0710_LOG("<[]\n");
-+		mux_sched_send();
-+		return;
-+	}
-+
-+	idx = mux_send_info_idx;
-+	if ((idx < NR_MUXS) && (mux_send_info_flags[idx])) {
-+		send_info = mux_send_info[idx];
-+		if ((send_info)
-+		    && (send_info->filled)
-+		    && (send_info->length <=
-+			(TS0710MUX_SERIAL_BUF_SIZE - chars))) {
-+
-+			mux_sched_send();
-+		}
-+	}
-+}
-+
-+static void send_worker(void *private_)
-+{
-+	ts0710_con *ts0710 = &ts0710_connection;
-+	__u8 j;
-+	mux_send_struct *send_info;
-+	int chars;
-+	struct tty_struct *tty;
-+	__u8 dlci;
-+
-+	UNUSED_PARAM(private_);
-+
-+	TS0710_DEBUG("Enter into send_worker");
-+
-+	mux_send_info_idx = NR_MUXS;
-+
-+	if (ts0710->dlci[0].state == FLOW_STOPPED) {
-+		TS0710_DEBUG("Flow stopped on all channels\n");
-+		return;
-+	}
-+
-+	for (j = 0; j < NR_MUXS; j++) {
-+
-+		if (!(mux_send_info_flags[j])) {
-+			continue;
-+		}
-+
-+		send_info = mux_send_info[j];
-+		if (!send_info) {
-+			continue;
-+		}
-+
-+		if (!(send_info->filled)) {
-+			continue;
-+		}
-+
-+		dlci = tty2dlci[j];
-+		if (ts0710->dlci[dlci].state == FLOW_STOPPED) {
-+			TS0710_DEBUG("Flow stopped on channel DLCI: %d\n",
-+				     dlci);
-+			continue;
-+		} else if (ts0710->dlci[dlci].state != CONNECTED) {
-+			TS0710_DEBUG("DLCI %d not connected\n", dlci);
-+			send_info->filled = 0;
-+			continue;
-+		}
-+
-+		chars = mux_chars_in_serial_buffer(COMM_FOR_MUX_TTY);
-+		if (send_info->length <= (TS0710MUX_SERIAL_BUF_SIZE - chars)) {
-+			TS0710_DEBUG("Send queued UIH for /dev/mux%d", j);
-+			basic_write(ts0710, (__u8 *) send_info->frame,
-+				    send_info->length);
-+			send_info->length = 0;
-+			send_info->filled = 0;
-+		} else {
-+			mux_send_info_idx = j;
-+			break;
-+		}
-+	}			/* End for() loop */
-+
-+	/* Queue UIH data to be transmitted */
-+	for (j = 0; j < NR_MUXS; j++) {
-+
-+		if (!(mux_send_info_flags[j])) {
-+			continue;
-+		}
-+
-+		send_info = mux_send_info[j];
-+		if (!send_info) {
-+			continue;
-+		}
-+
-+		if (send_info->filled) {
-+			continue;
-+		}
-+
-+		/* Now queue UIH data to send_info->buf */
-+
-+		if (!mux_tty[j]) {
-+			continue;
-+		}
-+
-+		tty = mux_table[j];
-+		if (!tty) {
-+			continue;
-+		}
-+
-+		dlci = tty2dlci[j];
-+		if (ts0710->dlci[dlci].state == FLOW_STOPPED) {
-+			TS0710_DEBUG("Flow stopped on channel DLCI: %d\n",
-+				     dlci);
-+			continue;
-+		} else if (ts0710->dlci[dlci].state != CONNECTED) {
-+			TS0710_DEBUG("DLCI %d not connected\n", dlci);
-+			continue;
-+		}
-+
-+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
-+		    && tty->ldisc.write_wakeup) {
-+			(tty->ldisc.write_wakeup) (tty);
-+		}
-+		wake_up_interruptible(&tty->write_wait);
-+
-+#ifdef SERIAL_HAVE_POLL_WAIT
-+		wake_up_interruptible(&tty->poll_wait);
-+#endif
-+
-+		if (send_info->filled) {
-+			if (j < mux_send_info_idx) {
-+				mux_send_info_idx = j;
-+			}
-+		}
-+	}			/* End for() loop */
-+}
-+
-+static int get_count(__u8 idx)
-+{
-+	int ret;
-+
-+	if (idx > TS0710MUX_COUNT_MAX_IDX) {
-+		TS0710_PRINTK("MUX get_count: invalid idx: %d!\n", idx);
-+		return -1;
-+	}
-+
-+	down(&mux_data_count_mutex[idx]);
-+	ret = mux_data_count[idx];
-+	up(&mux_data_count_mutex[idx]);
-+
-+	return ret;
-+}
-+
-+static int set_count(__u8 idx, int count)
-+{
-+	if (idx > TS0710MUX_COUNT_MAX_IDX) {
-+		TS0710_PRINTK("MUX set_count: invalid idx: %d!\n", idx);
-+		return -1;
-+	}
-+	if (count < 0) {
-+		TS0710_PRINTK("MUX set_count: invalid count: %d!\n", count);
-+		return -1;
-+	}
-+
-+	down(&mux_data_count_mutex[idx]);
-+	mux_data_count[idx] = count;
-+	up(&mux_data_count_mutex[idx]);
-+
-+	return 0;
-+}
-+
-+static int add_count(__u8 idx, int count)
-+{
-+	if (idx > TS0710MUX_COUNT_MAX_IDX) {
-+		TS0710_PRINTK("MUX add_count: invalid idx: %d!\n", idx);
-+		return -1;
-+	}
-+	if (count <= 0) {
-+		TS0710_PRINTK("MUX add_count: invalid count: %d!\n", count);
-+		return -1;
-+	}
-+
-+	if (down_trylock(&mux_data_count_mutex[idx]))
-+		return -1;
-+	mux_data_count[idx] += count;
-+	up(&mux_data_count_mutex[idx]);
-+
-+	return 0;
-+}
-+
-+ssize_t file_proc_read(struct file * file, char *buf, size_t size,
-+		       loff_t * ppos)
-+{
-+	gprs_bytes gprsData[TS0710MUX_GPRS_SESSION_MAX];
-+	int bufLen = sizeof(gprs_bytes) * TS0710MUX_GPRS_SESSION_MAX;
-+
-+	UNUSED_PARAM(file);
-+	UNUSED_PARAM(size);
-+	UNUSED_PARAM(ppos);
-+
-+	gprsData[0].recvBytes = get_count(TS0710MUX_GPRS1_RECV_COUNT_IDX);
-+	gprsData[0].sentBytes = get_count(TS0710MUX_GPRS1_SEND_COUNT_IDX);
-+	gprsData[TS0710MUX_GPRS_SESSION_MAX - 1].recvBytes =
-+	    get_count(TS0710MUX_GPRS2_RECV_COUNT_IDX);
-+	gprsData[TS0710MUX_GPRS_SESSION_MAX - 1].sentBytes =
-+	    get_count(TS0710MUX_GPRS2_SEND_COUNT_IDX);
-+
-+	copy_to_user(buf, gprsData, bufLen);
-+
-+	return bufLen;
-+}
-+
-+ssize_t file_proc_write(struct file * file, const char *buf, size_t count,
-+			loff_t * ppos)
-+{
-+	gprs_bytes gprsData[TS0710MUX_GPRS_SESSION_MAX];
-+	int bufLen = sizeof(gprs_bytes) * TS0710MUX_GPRS_SESSION_MAX;
-+
-+	UNUSED_PARAM(file);
-+	UNUSED_PARAM(count);
-+	UNUSED_PARAM(ppos);
-+
-+	memset(gprsData, 0, bufLen);
-+
-+	copy_from_user(gprsData, buf, bufLen);
-+
-+	set_count(TS0710MUX_GPRS1_RECV_COUNT_IDX, gprsData[0].recvBytes);
-+	set_count(TS0710MUX_GPRS1_SEND_COUNT_IDX, gprsData[0].sentBytes);
-+	set_count(TS0710MUX_GPRS2_RECV_COUNT_IDX,
-+		  gprsData[TS0710MUX_GPRS_SESSION_MAX - 1].recvBytes);
-+	set_count(TS0710MUX_GPRS2_SEND_COUNT_IDX,
-+		  gprsData[TS0710MUX_GPRS_SESSION_MAX - 1].sentBytes);
-+
-+	return bufLen;
-+}
-+
-+static void gprs_proc_init(void)
-+{
-+	gprs_proc_file =
-+	    create_proc_entry("gprsbytes", S_IRUSR | S_IWUSR, NULL);
-+	gprs_proc_file->proc_fops = &file_proc_operations;
-+}
-+
-+static void gprs_proc_exit(void)
-+{
-+	remove_proc_entry("gprsbytes", gprs_proc_file);
-+}
-+#endif
-+
-+static int __init mux_init(void)
-+{
-+	unsigned int j;
-+
-+	ts0710_init();
-+#if 0
-+	if (COMM_FOR_MUX_DRIVER == NULL) {
-+
-+#ifdef USB_FOR_MUX
-+		panic("please install IPC-USB first\n");
-+#else
-+		panic("please install ttyS0 first\n");
-+#endif
-+
-+	}
-+
-+	for (j = 0; j < NR_MUXS; j++) {
-+		mux_send_info_flags[j] = 0;
-+		mux_send_info[j] = 0;
-+		mux_recv_info_flags[j] = 0;
-+		mux_recv_info[j] = 0;
-+	}
-+	mux_send_info_idx = NR_MUXS;
-+	mux_recv_queue = NULL;
-+	mux_recv_flags = 0;
-+
-+	for (j = 0; j < TS0710MUX_COUNT_IDX_NUM; j++) {
-+		mux_data_count[j] = 0;
-+		mux_data_count2[j] = 0;
-+		init_MUTEX(&mux_data_count_mutex[j]);
-+	}
-+	post_recv_count_flag = 0;
-+
-+	INIT_WORK(&send_tqueue, send_worker, NULL);
-+	INIT_WORK(&receive_tqueue, receive_worker, NULL);
-+	INIT_WORK(&post_recv_tqueue, post_recv_worker, NULL);
-+#endif
-+
-+	memset(&mux_driver, 0, sizeof(struct tty_driver));
-+	memset(&mux_tty, 0, sizeof(mux_tty));
-+	mux_driver.magic = TTY_DRIVER_MAGIC;
-+	mux_driver.driver_name = "ts0710mux";
-+	mux_driver.name = "ts0710mux";
-+	mux_driver.major = TS0710MUX_MAJOR;
-+	mux_driver.minor_start = TS0710MUX_MINOR_START;
-+	mux_driver.num = NR_MUXS;
-+	mux_driver.type = TTY_DRIVER_TYPE_SERIAL;
-+	mux_driver.subtype = SERIAL_TYPE_NORMAL;
-+	mux_driver.init_termios = tty_std_termios;
-+	mux_driver.init_termios.c_iflag = 0;
-+	mux_driver.init_termios.c_oflag = 0;
-+	mux_driver.init_termios.c_cflag = B38400 | CS8 | CREAD;
-+	mux_driver.init_termios.c_lflag = 0;
-+	mux_driver.flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW;
-+
-+	mux_driver.ttys = mux_table;
-+	mux_driver.termios = mux_termios;
-+	mux_driver.termios_locked = mux_termios_locked;
-+//  mux_driver.driver_state = mux_state;
-+	mux_driver.other = NULL;
-+
-+	mux_driver.open = mux_open;
-+	mux_driver.close = mux_close;
-+	mux_driver.write = mux_write;
-+	mux_driver.write_room = mux_write_room;
-+	mux_driver.flush_buffer = mux_flush_buffer;
-+	mux_driver.chars_in_buffer = mux_chars_in_buffer;
-+	mux_driver.throttle = mux_throttle;
-+	mux_driver.unthrottle = mux_unthrottle;
-+	mux_driver.ioctl = mux_ioctl;
-+	mux_driver.owner = THIS_MODULE;
-+
-+	if (tty_register_driver(&mux_driver))
-+		panic("Couldn't register mux driver");
-+
-+#if 0
-+	COMM_MUX_DISPATCHER = mux_dispatcher;
-+	COMM_MUX_SENDER = mux_sender;
-+
-+	gprs_proc_init();
-+#endif
-+
-+	return 0;
-+}
-+
-+static void __exit mux_exit(void)
-+{
-+	int j;
-+
-+#if 0
-+	COMM_MUX_DISPATCHER = NULL;
-+	COMM_MUX_SENDER = NULL;
-+
-+	gprs_proc_exit();
-+
-+	mux_send_info_idx = NR_MUXS;
-+	mux_recv_queue = NULL;
-+	for (j = 0; j < NR_MUXS; j++) {
-+		if ((mux_send_info_flags[j]) && (mux_send_info[j])) {
-+			kfree(mux_send_info[j]);
-+		}
-+		mux_send_info_flags[j] = 0;
-+		mux_send_info[j] = 0;
-+
-+		if ((mux_recv_info_flags[j]) && (mux_recv_info[j])) {
-+			free_mux_recv_struct(mux_recv_info[j]);
-+		}
-+		mux_recv_info_flags[j] = 0;
-+		mux_recv_info[j] = 0;
-+	}
-+#endif
-+
-+	if (tty_unregister_driver(&mux_driver))
-+		panic("Couldn't unregister mux driver");
-+}
-+
-+module_init(mux_init);
-+module_exit(mux_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Harald Welte <laforge at openezx.org>");
-+MODULE_DESCRIPTION("GSM TS 07.10 Multiplexer");
-Index: linux-2.6.17.14-fic2/drivers/char/ts0710_mux.h
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17.14-fic2/drivers/char/ts0710_mux.h	2006-12-02 11:21:56.000000000 +0100
-@@ -0,0 +1,103 @@
-+/*
-+ * mux_macro.h
-+ *
-+ * Copyright (C) 2002 2005 Motorola
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ *
-+ *
-+ *  11/18/2002  (Motorola) - Initial version
-+ *
-+ */
-+
-+/*
-+* This header file should be included by both MUX and other applications
-+* which access MUX device files. It gives the additional macro definitions
-+* shared between MUX and applications.
-+*/
-+
-+/* MUX DLCI(Data Link Connection Identifier) Configuration */
-+/*
-+*  DLCI     Service
-+*   0    Control Channel
-+*   1    Voice Call & Network-related
-+*   2    SMS MO
-+*   3    SMS MT
-+*   4    Phonebook & related
-+*   5    MISC
-+*   6    CSD/FAX
-+*   7    GPRS1
-+*   8    GPRS2
-+*   9    Logger CMD
-+*   10   Logger Data
-+*   11   Test CMD
-+*   12   AGPS
-+*   13   Net Monitor
-+*/
-+
-+/* Mapping between DLCI and MUX device files */
-+/*
-+*   File Name   Minor  DLCI  AT Command/Data
-+*   /dev/mux0     0     1     AT Command
-+*   /dev/mux1     1     2     AT Command
-+*   /dev/mux2     2     3     AT Command
-+*   /dev/mux3     3     4     AT Command
-+*   /dev/mux4     4     5     AT Command
-+*   /dev/mux5     5     6     AT Command
-+*   /dev/mux6     6     7     AT Command
-+*   /dev/mux7     7     8     AT Command
-+*   /dev/mux8     8     6     Data
-+*   /dev/mux9     9     7     Data
-+*   /dev/mux10    10    8     Data
-+*   /dev/mux11    11    9     Data
-+*   /dev/mux12    12    10    Data
-+*   /dev/mux13    13    11    Data
-+*   /dev/mux14    14    12    Data
-+*   /dev/mux15    15    13    Data
-+*/
-+
-+#define MUX_CMD_FILE_VOICE_CALL   "/dev/mux0"
-+#define MUX_CMD_FILE_SMS_MO       "/dev/mux1"
-+#define MUX_CMD_FILE_SMS_MT       "/dev/mux2"
-+#define MUX_CMD_FILE_PHONEBOOK    "/dev/mux3"
-+#define MUX_CMD_FILE_MISC         "/dev/mux4"
-+#define MUX_CMD_FILE_CSD          "/dev/mux5"
-+#define MUX_CMD_FILE_GPRS1        "/dev/mux6"
-+#define MUX_CMD_FILE_GPRS2        "/dev/mux7"
-+
-+#define MUX_DATA_FILE_CSD         "/dev/mux8"
-+#define MUX_DATA_FILE_GPRS1       "/dev/mux9"
-+#define MUX_DATA_FILE_GPRS2       "/dev/mux10"
-+#define MUX_DATA_FILE_LOGGER_CMD  "/dev/mux11"
-+#define MUX_DATA_FILE_LOGGER_DATA "/dev/mux12"
-+#define MUX_DATA_FILE_TEST_CMD    "/dev/mux13"
-+#define MUX_DATA_FILE_AGPS        "/dev/mux14"
-+#define MUX_DATA_FILE_NET_MONITOR "/dev/mux15"
-+
-+#define NUM_MUX_CMD_FILES 8
-+#define NUM_MUX_DATA_FILES 8
-+#define NUM_MUX_FILES ( NUM_MUX_CMD_FILES  +  NUM_MUX_DATA_FILES )
-+
-+/* Special ioctl() upon a MUX device file for hanging up a call */
-+#define TS0710MUX_IO_MSC_HANGUP 0x54F0
-+
-+/* Special ioctl() upon a MUX device file for MUX loopback test */
-+#define TS0710MUX_IO_TEST_CMD 0x54F1
-+
-+/* Special Error code might be return from write() to a MUX device file  */
-+#define EDISCONNECTED 900	/* Logical data link is disconnected */
-+
-+/* Special Error code might be return from open() to a MUX device file  */
-+#define EREJECTED 901		/* Logical data link connection request is rejected */
-Index: linux-2.6.17.14-fic2/drivers/char/ts0710_mux_usb.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17.14-fic2/drivers/char/ts0710_mux_usb.c	2006-12-02 11:21:56.000000000 +0100
-@@ -0,0 +1,868 @@
-+/*
-+ * linux/drivers/usb/ipcusb.c
-+ *
-+ * Implementation of a ipc driver based Intel's Bulverde USB Host 
-+ * Controller.
-+ *
-+ * Copyright (C) 2003-2005 Motorola
-+ * Copyright (C) 2006 Harald Welte <laforge at openezx.org>
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *                                                                                               
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ * 
-+ *  2003-Nov-03 - (Motorola) created
-+ *  2004-Feb-20 - (Motorola) Add Power Manager codes
-+ *  2004-Apr-14 - (Motorola) Update Suspend/Resume codes
-+ *  2004-May-10 - (Motorola) Add unlink_urbs codes and do some updates of send
-+ *			     out urb sequence
-+ *  2006-Jun-22 - (Harald Welte) port to Linux 2.6.x
-+ *  
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/list.h>
-+#include <linux/errno.h>
-+#include <asm/uaccess.h>
-+#include <asm/hardware.h>
-+#include <asm/arch/hardware.h>
-+#include <asm/arch-pxa/pxa-regs.h>
-+#include <asm/arch-pxa/ezx.h>
-+#include <linux/slab.h>
-+#include <linux/miscdevice.h>
-+#include <linux/init.h>
-+#include <linux/timer.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/tty.h>
-+#include <linux/tty_driver.h>
-+#include <linux/tty_flip.h>
-+#include <linux/circ_buf.h>
-+#include <linux/usb.h>
-+
-+#include "ts0710_mux_usb.h"
-+
-+/*Macro defined for this driver*/
-+#define DRIVER_VERSION "1.0alpha1"
-+#define DRIVER_AUTHOR "Motorola / Harald Welte <laforge at openezx.org>"
-+#define DRIVER_DESC "USB IPC Driver (TS07.10 lowlevel)"
-+#define MOTO_IPC_VID		0x22b8
-+#define MOTO_IPC_PID		0x3006
-+#define IBUF_SIZE 		32		/*urb size*/	
-+#define IPC_USB_XMIT_SIZE	1024
-+#define IPC_URB_SIZE		32	
-+#define IPC_USB_WRITE_INIT 	0
-+#define IPC_USB_WRITE_XMIT	1
-+#define IPC_USB_PROBE_READY	3
-+#define IPC_USB_PROBE_NOT_READY	4
-+#define DBG_MAX_BUF_SIZE	1024
-+#define ICL_EVENT_INTERVAL	(HZ) 
-+#undef BVD_DEBUG		
-+
-+#define IS_EP_BULK(ep)  ((ep).bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0)
-+#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
-+#define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
-+/*End defined macro*/
-+
-+/*global values defined*/
-+static struct usb_driver 		usb_ipc_driver;
-+static struct timer_list 		ipcusb_timer;
-+static struct timer_list 		suspend_timer;
-+static struct timer_list 		wakeup_timer;
-+static struct tty_struct		ipcusb_tty;		/* the coresponding tty struct, we just use flip buffer here. */
-+static struct tty_driver		ipcusb_tty_driver;	/* the coresponding tty driver, we just use write and chars in buff here*/
-+struct tty_driver *usb_for_mux_driver = NULL;
-+struct tty_struct *usb_for_mux_tty = NULL;
-+void (*usb_mux_dispatcher)(struct tty_struct *tty) = NULL;
-+void (*usb_mux_sender)(void) = NULL;
-+void (*ipcusb_ap_to_bp)(unsigned char*, int) = NULL;
-+void (*ipcusb_bp_to_ap)(unsigned char*, int) = NULL;
-+EXPORT_SYMBOL(usb_for_mux_driver);	
-+EXPORT_SYMBOL(usb_for_mux_tty);	
-+EXPORT_SYMBOL(usb_mux_dispatcher);	
-+EXPORT_SYMBOL(usb_mux_sender);
-+EXPORT_SYMBOL(ipcusb_ap_to_bp);
-+EXPORT_SYMBOL(ipcusb_bp_to_ap);
-+static int sumbit_times = 0; 	
-+static int callback_times = 0; 
-+//static unsigned long last_jiff = 0;
-+extern int usbh_finished_resume;
-+/*end global values defined*/
-+
-+MODULE_AUTHOR(DRIVER_AUTHOR);
-+MODULE_DESCRIPTION(DRIVER_DESC);
-+MODULE_LICENSE("GPL");
-+
-+#ifdef BVD_DEBUG
-+#define bvd_dbg(format, arg...) printk(__FILE__ ": " format "\n" , ## arg)
-+#else
-+#define bvd_dbg(format, arg...) do {} while (0)
-+#endif
-+
-+/* USB device context */
-+typedef struct {
-+	struct list_head list;
-+	int size;
-+	char *body; 
-+} buf_list_t;
-+
-+struct ipc_usb_data {
-+	u_int8_t 		write_finished_flag;
-+	u_int8_t		write_flag,
-+				ipc_flag,
-+				suspend_flag;
-+	struct usb_device 	*ipc_dev;
-+	struct urb 		readurb_mux,
-+				writeurb_mux,
-+				writeurb_dsplog;
-+	char 			*obuf, *ibuf;
-+	int			writesize;	/* max packet size for the
-+						   output bulk endpoint *
-+						   transfer buffers */
-+
-+	struct circ_buf		xmit;		/* write cric bufffer */
-+  	struct list_head 	in_buf_list;
-+	char 			bulk_in_ep_mux, 
-+				bulk_out_ep_mux, 
-+				bulk_in_ep_dsplog;
-+	unsigned int 		ifnum;
-+
-+	struct tasklet_struct	bh,
-+				bh_bp;
-+
-+	spinlock_t		lock;
-+}; 
-+
-+struct ipc_usb_data *bvd_ipc;
-+
-+#ifdef BVD_DEBUG
-+static void bvd_dbg_hex(__u8 *buf, int len)
-+{
-+	static unsigned char tbuf[DBG_MAX_BUF_SIZE];
-+	int i, c;
-+
-+	if (len <= 0)
-+		return;
-+
-+	c = 0;  
-+	for (i=0; (i < len) && (c < (DBG_MAX_BUF_SIZE - 3)); i++) {
-+		sprintf(&tbuf[c], "%02x ",buf[i]);
-+		c += 3;
-+	}
-+	tbuf[c] = 0;
-+
-+	printk("%s: %s\n", __FUNCTION__, tbuf);
-+}
-+#else
-+#define bvd_dbg_hex(buf, len)
-+#endif
-+
-+static int unlink_urbs(struct urb *urb)
-+{	
-+	unsigned long flags;
-+	int retval;
-+
-+	spin_lock_irqsave(&bvd_ipc->lock, flags);
-+	
-+	retval = usb_unlink_urb(urb);
-+	if (retval != -EINPROGRESS && retval != 0)
-+		printk("unlink urb err, %d", retval);
-+	
-+	spin_unlock_irqrestore(&bvd_ipc->lock, flags);
-+	return retval;
-+}
-+
-+static void append_to_inbuf_list(struct urb *urb)
-+{
-+	buf_list_t *inbuf;
-+	int count = urb->actual_length;
-+	
-+	inbuf = kmalloc(sizeof(buf_list_t), GFP_KERNEL);
-+	if (!inbuf) {
-+		printk("append_to_inbuf_list: (%d) out of memory!\n",
-+			sizeof(buf_list_t));
-+		return;
-+	}
-+	
-+	inbuf->size = count;
-+	inbuf->body = kmalloc(sizeof(char)*count, GFP_KERNEL);
-+	if (!inbuf->body) {
-+		kfree(inbuf);
-+		printk("append_to_inbuf_list: (%d) out of memory!\n",
-+			sizeof(char)*count);
-+		return;
-+	}
-+	memcpy(inbuf->body, (unsigned char*)urb->transfer_buffer, count);
-+	list_add_tail(&inbuf->list, &bvd_ipc->in_buf_list);
-+}
-+
-+static void ipcusb_timeout(unsigned long data)
-+{
-+	struct tty_struct *tty = &ipcusb_tty;	
-+	struct urb *urb = (struct urb *)data;
-+	
-+	bvd_dbg("ipcusb_timeout***");
-+
-+	while (!(list_empty(&bvd_ipc->in_buf_list))) {
-+		int count;
-+		buf_list_t *inbuf;
-+		struct list_head *ptr = NULL;			
-+		
-+		ptr = bvd_ipc->in_buf_list.next;
-+		inbuf = list_entry (ptr, buf_list_t, list);			
-+		count = inbuf->size;
-+		if (tty_insert_flip_string(tty, inbuf->body, count) >= count) {
-+			list_del(ptr);
-+			kfree(inbuf->body);
-+			inbuf->body = NULL;
-+			kfree(inbuf);				
-+		} else {
-+			bvd_dbg("ipcusb_timeout: bvd_ipc->in_buf_list empty!");
-+			break;
-+		}
-+	}
-+
-+	if (usb_mux_dispatcher)
-+		usb_mux_dispatcher(tty);	/**call Liu changhui's func.**/	
-+	
-+	if (list_empty(&bvd_ipc->in_buf_list)) {
-+		urb->actual_length = 0;
-+		urb->dev = bvd_ipc->ipc_dev;
-+		if (usb_submit_urb(urb, GFP_ATOMIC))
-+			bvd_dbg("ipcusb_timeout: failed resubmitting read urb");
-+		bvd_dbg("ipcusb_timeout: resubmited read urb");
-+	} else {
-+		ipcusb_timer.data = (unsigned long)urb;
-+		mod_timer(&ipcusb_timer, jiffies+(10*HZ/1000));
-+	}
-+}
-+
-+static void usb_ipc_read_bulk(struct urb *urb, struct pt_regs *regs)
-+{	
-+	buf_list_t *inbuf;
-+	int count = urb->actual_length;
-+	struct tty_struct *tty = &ipcusb_tty;	
-+	
-+ 	bvd_dbg("usb_ipc_read_bulk: begining!");
-+	if (urb->status)
-+		printk("nonzero read bulk status received: %d\n", urb->status);
-+	
-+ 	bvd_dbg("usb_ipc_read_bulk: urb->actual_length=%d", urb->actual_length);
-+ 	bvd_dbg("usb_ipc_read_bulk: urb->transfer_buffer:");	
-+
-+	bvd_dbg_hex((unsigned char*)urb->transfer_buffer, urb->actual_length);
-+
-+	if (count > 0 && ((*ipcusb_bp_to_ap) != NULL))
-+		(*ipcusb_bp_to_ap)(urb->transfer_buffer, urb->actual_length);
-+ 
-+ 	if (!(list_empty(&bvd_ipc->in_buf_list))) {
-+		int need_mux = 0;
-+
-+ 		bvd_dbg("usb_ipc_read_bulk: some urbs in_buf_list");	
-+		if (count > 0) {
-+			bvd_ipc->suspend_flag = 1;
-+			append_to_inbuf_list(urb); /* append the current received urb */
-+#if 0		
-+			if(jiffies - last_jiff > ICL_EVENT_INTERVAL) 
-+			{
-+				last_jiff = jiffies;
-+				queue_apm_event(KRNL_ICL, NULL);
-+			}	
-+#endif
-+		}
-+		
-+		while (!(list_empty(&bvd_ipc->in_buf_list))) {
-+			struct list_head* ptr = NULL;	
-+			ptr = bvd_ipc->in_buf_list.next;
-+			inbuf = list_entry(ptr, buf_list_t, list);			
-+			count = inbuf->size;
-+			need_mux = 1;
-+
-+			tty_insert_flip_string(tty, inbuf->body, count);
-+
-+			list_del(ptr);
-+			kfree(inbuf->body);
-+			inbuf->body = NULL;
-+			kfree(inbuf);				
-+		}	
-+
-+		if (usb_mux_dispatcher && need_mux) 
-+			usb_mux_dispatcher(tty); /* call Liu changhui's func. */
-+
-+		if (list_empty(&bvd_ipc->in_buf_list)) {
-+			urb->actual_length = 0;
-+			urb->dev = bvd_ipc->ipc_dev;
-+			if (usb_submit_urb(urb, GFP_ATOMIC))
-+				bvd_dbg("usb_ipc_read_bulk: "
-+					"failed resubmitting read urb");
-+			bvd_dbg("usb_ipc_read_bulk: resubmited read urb");
-+		} else {
-+			ipcusb_timer.data = (unsigned long)urb;
-+			mod_timer(&ipcusb_timer, jiffies+(10*HZ/1000));
-+		}
-+	} else if (count > 0) {
-+ 		bvd_dbg("usb_ipc_read_bulk: no urbs in_buf_list");	
-+		bvd_ipc->suspend_flag = 1;
-+
-+		if (tty_insert_flip_string(tty, urb->transfer_buffer, 
-+					   count) < count) {
-+			bvd_ipc->suspend_flag = 1;
-+			append_to_inbuf_list(urb);
-+			ipcusb_timer.data = (unsigned long)urb;
-+			mod_timer(&ipcusb_timer, jiffies+(10*HZ/1000));
-+#if 0			
-+			if(jiffies - last_jiff > ICL_EVENT_INTERVAL) 
-+			{
-+				last_jiff = jiffies;
-+				queue_apm_event(KRNL_ICL, NULL);
-+			}
-+#endif	
-+		}
-+
-+		if (usb_mux_dispatcher)
-+			usb_mux_dispatcher(tty); /* call Liu changhui's func. */
-+
-+		urb->actual_length = 0;
-+		urb->dev = bvd_ipc->ipc_dev;
-+		if (usb_submit_urb(urb, GFP_ATOMIC))
-+			bvd_dbg("failed resubmitting read urb");
-+#if 0
-+		if(jiffies - last_jiff > ICL_EVENT_INTERVAL) 
-+		{
-+			last_jiff = jiffies;
-+			queue_apm_event(KRNL_ICL, NULL);
-+		}
-+#endif	
-+		bvd_dbg("usb_ipc_read_bulk: resubmited read urb");
-+	}
-+
-+	bvd_dbg("usb_ipc_read_bulk: completed!!!");		
-+}
-+
-+static void usb_ipc_write_bulk(struct urb *urb, struct pt_regs *regs)
-+{
-+	callback_times++;
-+	bvd_ipc->write_finished_flag = 1;
-+	
-+	bvd_dbg("usb_ipc_write_bulk: begining!");
-+	//printk("%s: write_finished_flag=%d\n", __FUNCTION__, bvd_ipc->write_finished_flag);
-+	
-+	if (urb->status)
-+		printk("nonzero write bulk status received: %d\n", urb->status);
-+
-+	if (usb_mux_sender)
-+		usb_mux_sender();		/**call Liu changhui's func**/
-+
-+	//printk("usb_ipc_write_bulk: mark ipcusb_softint!\n");
-+	tasklet_schedule(&bvd_ipc->bh);
-+
-+	bvd_dbg("usb_ipc_write_bulk: finished!");
-+}
-+
-+static void wakeup_timeout(unsigned long data)
-+{
-+	GPSR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW);
-+	bvd_dbg("wakup_timeout: send GPIO_MCU_INT_SW signal!");	
-+}
-+
-+static void suspend_timeout(unsigned long data)
-+{
-+	if (bvd_ipc->suspend_flag == 1) {
-+		bvd_ipc->suspend_flag = 0;
-+		mod_timer(&suspend_timer, jiffies+(5000*HZ/1000));
-+		bvd_dbg("suspend_timeout: add the suspend timer again");	
-+	} else {
-+		unlink_urbs(&bvd_ipc->readurb_mux);
-+		UHCRHPS3 = 0x4;
-+		mdelay(40);
-+		bvd_dbg("suspend_timeout: send SUSPEND signal! UHCRHPS3=0x%x",
-+			UHCRHPS3);
-+	}
-+}
-+
-+static void ipcusb_xmit_data(void)
-+{	
-+	int c, count = IPC_URB_SIZE;
-+	int result = 0;
-+	int buf_flag = 0;
-+	int buf_num = 0;
-+
-+	//printk("%s: sumbit_times=%d, callback_times=%d\n", __FUNCTION__, sumbit_times, callback_times);
-+	if (bvd_ipc->write_finished_flag == 0)
-+		return;
-+ 
-+	while (1) {
-+		c = CIRC_CNT_TO_END(bvd_ipc->xmit.head, bvd_ipc->xmit.tail, 
-+				    IPC_USB_XMIT_SIZE);
-+		if (count < c)
-+			c = count;
-+		if (c <= 0)
-+			break;
-+
-+		memcpy(bvd_ipc->obuf+buf_num, 
-+		       bvd_ipc->xmit.buf + bvd_ipc->xmit.tail, c);
-+		buf_flag = 1;	
-+		bvd_ipc->xmit.tail = ((bvd_ipc->xmit.tail + c) 
-+						& (IPC_USB_XMIT_SIZE-1));
-+		count -= c;
-+		buf_num += c;
-+	}    
-+
-+	if (buf_num == 0) {
-+		bvd_dbg("ipcusb_xmit_data: buf_num=%d, add suspend_timer",
-+			buf_num);
-+		bvd_ipc->suspend_flag = 0;
-+		mod_timer(&suspend_timer, jiffies+(5000*HZ/1000));
-+	}
-+
-+	bvd_dbg("ipcusb_xmit_data: buf_num=%d", buf_num);
-+	bvd_dbg("ipcusb_xmit_data: bvd_ipc->obuf: ");
-+
-+	bvd_dbg_hex((bvd_ipc->obuf)-buf_num, buf_num);
-+
-+	if (buf_flag) {
-+		bvd_ipc->writeurb_mux.transfer_buffer_length = buf_num;
-+		bvd_dbg("ipcusb_xmit_data: copy data to write urb finished! ");
-+		
-+		if ((UHCRHPS3 & 0x4) == 0x4) {
-+			static int ret;
-+			int time = 0;	
-+
-+			/* if BP sleep, wake up BP first */
-+			pxa_gpio_mode(GPIO_IN | 41);
-+			if (GPIO_is_high(41)) {
-+				if (GPIO_is_high(GPIO_MCU_INT_SW))
-+					GPCR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW);
-+				else
-+					GPSR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW);
-+
-+				time = jiffies;
-+				while (GPIO_is_high(41) && (jiffies < (time+HZ)));
-+
-+				if (GPIO_is_high(41)) {
-+					printk("%s: Wakeup BP timeout! BP state is %d\n",
-+						__FUNCTION__, GPIO_is_high(41));
-+				}
-+				if (GPIO_is_high(GPIO_MCU_INT_SW))
-+					GPCR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW);
-+				else
-+					GPSR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW);
-+			}
-+
-+			/* Resume BP */ 
-+			UHCRHPS3 = 0x8;
-+			mdelay(40);
-+			bvd_dbg("ipcusb_xmit_data: Send RESUME signal! UHCRHPS3=0x%x",
-+				 UHCRHPS3);
-+			/*send IN token*/
-+			bvd_ipc->readurb_mux.actual_length = 0;
-+			bvd_ipc->readurb_mux.dev = bvd_ipc->ipc_dev;
-+			if (ret = usb_submit_urb(&bvd_ipc->readurb_mux, GFP_ATOMIC))
-+				printk("ipcusb_xmit_data: usb_submit_urb(read mux bulk)"
-+					"failed! status=%d\n", ret);
-+			bvd_dbg("ipcusb_xmit_data: Send a IN token successfully!");
-+		}
-+
-+		sumbit_times++;
-+		bvd_ipc->write_finished_flag = 0;
-+		//printk("%s: clear write_finished_flag:%d\n", __FUNCTION__, bvd_ipc->write_finished_flag);
-+		bvd_ipc->writeurb_mux.dev = bvd_ipc->ipc_dev;
-+		if (result = usb_submit_urb(&bvd_ipc->writeurb_mux, GFP_ATOMIC))
-+			warn("ipcusb_xmit_data: funky result! result=%d\n", result);
-+
-+		bvd_dbg("ipcusb_xmit_data: usb_submit_urb finished! result:%d", result);
-+	
-+	}		
-+}
-+
-+static void usbipc_bh_func(unsigned long param)
-+{
-+	ipcusb_xmit_data();
-+}
-+
-+extern void get_halted_bit(void);
-+
-+static void usbipc_bh_bp_func(unsigned long param)
-+{
-+	if ((UHCRHPS3 & 0x4) == 0x4) {
-+		UHCRHPS3 = 0x8;
-+		mdelay(40);
-+		bvd_dbg("ipcusb_softint_send_readurb: Send RESUME signal! "
-+			"UHCRHPS3=0x%x", UHCRHPS3);
-+	}
-+	if (bvd_ipc->ipc_flag == IPC_USB_PROBE_READY) { 
-+		get_halted_bit();
-+
-+		/*send a IN token*/
-+		bvd_ipc->readurb_mux.dev = bvd_ipc->ipc_dev;
-+		if (usb_submit_urb(&bvd_ipc->readurb_mux, GFP_ATOMIC)) {
-+			bvd_dbg("ipcusb_softint_send_readurb: "
-+				"usb_submit_urb(read mux bulk) failed!");
-+		}
-+		bvd_dbg("ipcusb_softint_send_readurb: Send a IN token successfully!");
-+		bvd_ipc->suspend_flag = 0;
-+		bvd_dbg("ipcusb_softint_send_readurb: add suspend_timer");
-+		mod_timer(&suspend_timer, jiffies+(5000*HZ/1000));		
-+	}
-+}
-+
-+static int usb_ipc_write(struct tty_struct *tty, 
-+			 const unsigned char *buf, int count)
-+{	
-+	int c, ret = 0;
-+
-+	bvd_dbg("usb_ipc_write: count=%d, buf: ", count);
-+	bvd_dbg_hex(buf, count);
-+
-+	if (count <= 0)
-+		return 0;
-+
-+	if (*ipcusb_ap_to_bp != NULL)
-+		(*ipcusb_ap_to_bp)(buf, count);
-+
-+	bvd_ipc->suspend_flag = 1;
-+	
-+	if ((bvd_ipc->ipc_flag == IPC_USB_PROBE_READY) && 
-+	    (bvd_ipc->xmit.head == bvd_ipc->xmit.tail)) {
-+		bvd_dbg("usb_ipc_write: set write_flag");
-+		bvd_ipc->write_flag = IPC_USB_WRITE_XMIT;
-+	}
-+		
-+	while (1) {
-+		c = CIRC_SPACE_TO_END(bvd_ipc->xmit.head, 
-+				      bvd_ipc->xmit.tail, IPC_USB_XMIT_SIZE);
-+		if (count < c)
-+			c = count;
-+		if (c <= 0)
-+			break;
-+
-+		memcpy(bvd_ipc->xmit.buf + bvd_ipc->xmit.head, buf, c);
-+		bvd_ipc->xmit.head = ((bvd_ipc->xmit.head + c) 
-+						& (IPC_USB_XMIT_SIZE-1));
-+		buf += c;
-+		count -= c;
-+		ret += c;
-+	}
-+	bvd_dbg("usb_ipc_write: ret=%d, bvd_ipc->xmit.buf: ", ret);
-+
-+	bvd_dbg_hex(bvd_ipc->xmit.buf, ret);
-+
-+	if (bvd_ipc->write_flag == IPC_USB_WRITE_XMIT) {
-+		bvd_ipc->write_flag = IPC_USB_WRITE_INIT;
-+		bvd_dbg("usb_ipc_write: mark ipcusb_softint");
-+		tasklet_schedule(&bvd_ipc->bh);
-+	}
-+
-+	bvd_dbg("usb_ipc_write: ret=%d\n", ret);
-+	return ret;
-+}
-+
-+static int usb_ipc_chars_in_buffer(struct tty_struct *tty)
-+{		
-+	return CIRC_CNT(bvd_ipc->xmit.head, bvd_ipc->xmit.tail, IPC_USB_XMIT_SIZE);
-+}
-+
-+void usb_send_readurb(void)
-+{
-+	//printk("usb_send_readurb: begining!UHCRHPS3=0x%x, usbh_finished_resume=%d\n", UHCRHPS3, usbh_finished_resume);
-+	
-+	if (usbh_finished_resume == 0)
-+		return;
-+
-+	tasklet_schedule(&bvd_ipc->bh_bp);
-+}
-+
-+static int usb_ipc_probe(struct usb_interface *intf,
-+			 const struct usb_device_id *id)
-+{	
-+	struct usb_device *usbdev = interface_to_usbdev(intf);
-+	struct usb_config_descriptor *ipccfg;
-+	struct usb_interface_descriptor *interface;
-+	struct usb_endpoint_descriptor *endpoint;		
-+	int ep_cnt, readsize, writesize;
-+	char have_bulk_in_mux, have_bulk_out_mux;
-+
-+	bvd_dbg("usb_ipc_probe: vendor id 0x%x, device id 0x%x",
-+		usbdev->descriptor.idVendor, usbdev->descriptor.idProduct);
-+
-+	if ((usbdev->descriptor.idVendor != MOTO_IPC_VID) ||
-+	    (usbdev->descriptor.idProduct != MOTO_IPC_PID))
-+ 		return -ENODEV;
-+
-+	/* a2590c : dsplog interface is not supported by this driver */
-+	if (intf->minor == 2)	/* dsplog interface number is 2 */
-+		return -1;
-+
-+	bvd_dbg("usb_ipc_probe: USB dev address:%p", usbdev);
-+	bvd_dbg("usb_ipc_probe: ifnum:%u", intf->minor);
-+	
-+	ipccfg = &usbdev->actconfig->desc;
-+	bvd_dbg("usb_ipc_prob: config%d", ipccfg->bConfigurationValue);
-+	bvd_dbg("usb_ipc_prob: bNumInterfaces = %d", ipccfg->bNumInterfaces);
-+
-+	/* After this point we can be a little noisy about what we are trying
-+	 * to configure, hehe.  */
-+	if (usbdev->descriptor.bNumConfigurations != 1) {
-+		info("usb_ipc_probe: Only one device configuration "
-+		     "is supported.");
-+		return -1;
-+	}
-+
-+	if (usbdev->config[0].desc.bNumInterfaces != 3) {
-+		info("usb_ipc_probe: Only three device interfaces are "
-+		     "supported.");
-+		return -1;
-+	}
-+	
-+	interface = &intf->cur_altsetting->desc;
-+	endpoint = &intf->cur_altsetting->endpoint[0].desc;
-+	/* Start checking for two bulk endpoints or ... FIXME: This is a future
-+	 * enhancement...*/
-+	bvd_dbg("usb_ipc_probe: Number of Endpoints:%d", 
-+		(int) interface->bNumEndpoints);
-+	if (interface->bNumEndpoints != 2) {
-+		info("usb_ipc_probe: Only two endpoints supported.");
-+		return -1;
-+	}
-+
-+	ep_cnt = have_bulk_in_mux = have_bulk_out_mux = 0;	
-+
-+	bvd_dbg("usb_ipc_probe: endpoint[0] is:%x",
-+		(&endpoint[0])->bEndpointAddress);
-+	bvd_dbg("usb_ipc_probe: endpoint[1] is:%x ",
-+		(&endpoint[1])->bEndpointAddress);
-+	
-+	while (ep_cnt < interface->bNumEndpoints) {
-+
-+		if (!have_bulk_in_mux && IS_EP_BULK_IN(endpoint[ep_cnt])) {
-+			bvd_dbg("usb_ipc_probe: bEndpointAddress(IN) is:%x ", 
-+				(&endpoint[ep_cnt])->bEndpointAddress);
-+			have_bulk_in_mux = 
-+					(&endpoint[ep_cnt])->bEndpointAddress;
-+			readsize = (&endpoint[ep_cnt])->wMaxPacketSize;	
-+			bvd_dbg("usb_ipc_probe: readsize=%d", readsize);			
-+			ep_cnt++;
-+			continue;
-+		}
-+
-+		if (!have_bulk_out_mux && IS_EP_BULK_OUT(endpoint[ep_cnt])) {
-+			bvd_dbg("usb_ipc_probe: bEndpointAddress(OUT) is:%x ",
-+				(&endpoint[ep_cnt])->bEndpointAddress);
-+			have_bulk_out_mux =
-+				(&endpoint[ep_cnt])->bEndpointAddress;
-+			writesize = (&endpoint[ep_cnt])->wMaxPacketSize;
-+			bvd_dbg("usb_ipc_probe: writesize=%d", writesize);			
-+			ep_cnt++;
-+			continue;
-+		}
-+		
-+		info("usb_ipc_probe: Undetected endpoint ^_^ ");
-+		/* Shouldn't ever get here unless we have something weird */
-+		return -1;
-+	}
-+
-+	/* Perform a quick check to make sure that everything worked as it
-+	 * should have.  */
-+
-+	switch (interface->bNumEndpoints) {
-+	case 2:
-+		if (!have_bulk_in_mux || !have_bulk_out_mux) {
-+			info("usb_ipc_probe: Two bulk endpoints required.");
-+			return -1;
-+		}
-+		break;	
-+	default:
-+		info("usb_ipc_probe: Endpoint determination failed ^_^ ");
-+		return -1;
-+	}	
-+
-+	/* Ok, now initialize all the relevant values */
-+	if (!(bvd_ipc->obuf = (char *)kmalloc(writesize, GFP_KERNEL))) {
-+		err("usb_ipc_probe: Not enough memory for the output buffer.");
-+		kfree(bvd_ipc);		
-+		return -1;
-+	}
-+	bvd_dbg("usb_ipc_probe: obuf address:%p", bvd_ipc->obuf);
-+
-+	if (!(bvd_ipc->ibuf = (char *)kmalloc(readsize, GFP_KERNEL))) {
-+		err("usb_ipc_probe: Not enough memory for the input buffer.");
-+		kfree(bvd_ipc->obuf);
-+		kfree(bvd_ipc);		
-+		return -1;
-+	}
-+	bvd_dbg("usb_ipc_probe: ibuf address:%p", bvd_ipc->ibuf);
-+
-+	bvd_ipc->ipc_flag = IPC_USB_PROBE_READY;	
-+	bvd_ipc->write_finished_flag = 1;
-+	bvd_ipc->suspend_flag = 1;
-+	bvd_ipc->bulk_in_ep_mux= have_bulk_in_mux;
-+	bvd_ipc->bulk_out_ep_mux= have_bulk_out_mux;		
-+	bvd_ipc->ipc_dev = usbdev;	
-+	bvd_ipc->writesize = writesize;	
-+	INIT_LIST_HEAD (&bvd_ipc->in_buf_list);
-+
-+	bvd_ipc->bh.func = usbipc_bh_func;
-+	bvd_ipc->bh.data = (unsigned long) bvd_ipc;
-+
-+	bvd_ipc->bh_bp.func = usbipc_bh_bp_func;
-+	bvd_ipc->bh_bp.data = (unsigned long) bvd_ipc;
-+	
-+	/*Build a write urb*/
-+	usb_fill_bulk_urb(&bvd_ipc->writeurb_mux, usbdev, 
-+			  usb_sndbulkpipe(bvd_ipc->ipc_dev, 
-+			  		  bvd_ipc->bulk_out_ep_mux), 
-+			  bvd_ipc->obuf, writesize, usb_ipc_write_bulk,
-+			  bvd_ipc);
-+	//bvd_ipc->writeurb_mux.transfer_flags |= USB_ASYNC_UNLINK;
-+
-+	/*Build a read urb and send a IN token first time*/
-+	usb_fill_bulk_urb(&bvd_ipc->readurb_mux, usbdev,
-+			  usb_rcvbulkpipe(usbdev, bvd_ipc->bulk_in_ep_mux),
-+			  bvd_ipc->ibuf, readsize, usb_ipc_read_bulk, bvd_ipc);
-+	//bvd_ipc->readurb_mux.transfer_flags |= USB_ASYNC_UNLINK;	
-+	
-+	usb_driver_claim_interface(&usb_ipc_driver, intf, bvd_ipc);
-+	//usb_driver_claim_interface(&usb_ipc_driver, &ipccfg->interface[1], bvd_ipc);
-+	
-+        // a2590c: dsplog is not supported by this driver
-+	//	usb_driver_claim_interface(&usb_ipc_driver, 
-+	//				   &ipccfg->interface[2], bvd_ipc);
-+	/*send a IN token first time*/
-+	bvd_ipc->readurb_mux.dev = bvd_ipc->ipc_dev;
-+	if (usb_submit_urb(&bvd_ipc->readurb_mux, GFP_ATOMIC))
-+		printk("usb_ipc_prob: usb_submit_urb(read mux bulk) failed!\n");
-+
-+	bvd_dbg("usb_ipc_prob: Send a IN token successfully!");
-+	
-+	if (bvd_ipc->xmit.head != bvd_ipc->xmit.tail) {
-+		printk("usb_ipc_probe: mark ipcusb_softint!\n");
-+		tasklet_schedule(&bvd_ipc->bh);
-+	}
-+
-+	printk("usb_ipc_probe: completed probe!");
-+	usb_set_intfdata(intf, &bvd_ipc);
-+	return 0;
-+}
-+
-+static void usb_ipc_disconnect(struct usb_interface *intf)
-+{
-+	//struct usb_device *usbdev = interface_to_usbdev(intf);
-+	struct ipc_usb_data *bvd_ipc_disconnect = usb_get_intfdata(intf);
-+		
-+	printk("usb_ipc_disconnect:*** \n");
-+
-+	if ((UHCRHPS3 & 0x4) == 0)
-+		usb_unlink_urb(&bvd_ipc_disconnect->readurb_mux);
-+
-+	usb_unlink_urb(&bvd_ipc_disconnect->writeurb_mux);
-+        
-+	bvd_ipc_disconnect->ipc_flag = IPC_USB_PROBE_NOT_READY;
-+	kfree(bvd_ipc_disconnect->ibuf);
-+	kfree(bvd_ipc_disconnect->obuf);
-+	
-+	usb_driver_release_interface(&usb_ipc_driver, 
-+			bvd_ipc_disconnect->ipc_dev->actconfig->interface[0]);
-+        usb_driver_release_interface(&usb_ipc_driver, 
-+			bvd_ipc_disconnect->ipc_dev->actconfig->interface[1]);
-+        
-+	//a2590c: dsplog interface is not supported by this driver
-+	//usb_driver_release_interface(&usb_ipc_driver, &bvd_ipc_disconnect->ipc_dev->actconfig->interface[2]);
-+
-+	bvd_ipc_disconnect->ipc_dev = NULL;
-+
-+	usb_set_intfdata(intf, NULL);
-+
-+	printk("usb_ipc_disconnect completed!\n");
-+}
-+
-+static struct usb_device_id usb_ipc_id_table[] = {
-+	{ USB_DEVICE(MOTO_IPC_VID, MOTO_IPC_PID) },
-+	{ }						/* Terminating entry */
-+};
-+
-+static struct usb_driver usb_ipc_driver = {
-+	.name		= "usb ipc",
-+	.probe		= usb_ipc_probe,
-+	.disconnect	= usb_ipc_disconnect,
-+	.id_table	= usb_ipc_id_table,
-+};
-+
-+static int __init usb_ipc_init(void)
-+{
-+	int result;
-+
-+	bvd_dbg("init usb_ipc");
-+	/* register driver at the USB subsystem */
-+	result = usb_register(&usb_ipc_driver);
-+	if (result < 0) {
-+		err ("usb ipc driver could not be registered");
-+		return result;
-+	}
-+
-+	/*init the related mux interface*/
-+	if (!(bvd_ipc = kzalloc(sizeof(struct ipc_usb_data), GFP_KERNEL))) {
-+		err("usb_ipc_init: Out of memory.");		
-+		usb_deregister(&usb_ipc_driver);
-+		return -ENOMEM;
-+	}
-+	bvd_dbg("usb_ipc_init: Address of bvd_ipc:%p", bvd_ipc);
-+
-+	if (!(bvd_ipc->xmit.buf = kmalloc(IPC_USB_XMIT_SIZE, GFP_KERNEL))) {
-+		err("usb_ipc_init: Not enough memory for the input buffer.");
-+		kfree(bvd_ipc);
-+		usb_deregister(&usb_ipc_driver);
-+		return -ENOMEM;
-+	}
-+	bvd_dbg("usb_ipc_init: bvd_ipc->xmit.buf address:%p",
-+		bvd_ipc->xmit.buf);
-+	bvd_ipc->ipc_dev = NULL;
-+	bvd_ipc->xmit.head = bvd_ipc->xmit.tail = 0;
-+	bvd_ipc->write_flag = IPC_USB_WRITE_INIT;
-+
-+	ipcusb_tty_driver.write = usb_ipc_write;
-+	ipcusb_tty_driver.chars_in_buffer = usb_ipc_chars_in_buffer;
-+
-+	usb_for_mux_driver = &ipcusb_tty_driver;
-+	usb_for_mux_tty = &ipcusb_tty;
-+	
-+	/* init timers for ipcusb read process and usb suspend */
-+	init_timer(&ipcusb_timer);
-+	ipcusb_timer.function = ipcusb_timeout;
-+
-+	init_timer(&suspend_timer);
-+	suspend_timer.function = suspend_timeout;
-+
-+	init_timer(&wakeup_timer);
-+	wakeup_timer.function = wakeup_timeout;
-+	
-+	info("USB Host(Bulverde) IPC driver registered.");
-+	info(DRIVER_VERSION ":" DRIVER_DESC);
-+
-+	return 0;
-+}
-+
-+static void __exit usb_ipc_exit(void)
-+{
-+	bvd_dbg("cleanup bvd_ipc");
-+
-+	kfree(bvd_ipc->xmit.buf);
-+	kfree(bvd_ipc);
-+	usb_deregister(&usb_ipc_driver);
-+
-+	info("USB Host(Bulverde) IPC driver deregistered.");
-+}
-+
-+module_init(usb_ipc_init);
-+module_exit(usb_ipc_exit);
-+EXPORT_SYMBOL(usb_send_readurb);
-Index: linux-2.6.17.14-fic2/drivers/char/ts0710_mux_usb.h
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17.14-fic2/drivers/char/ts0710_mux_usb.h	2006-12-02 11:21:56.000000000 +0100
-@@ -0,0 +1,29 @@
-+/*
-+ * linux/drivers/usb/ipcusb.h
-+ *
-+ * Implementation of a ipc driver based Intel's Bulverde USB Host 
-+ * Controller.
-+ *
-+ * Copyright (C) 2003-2005 Motorola
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *                                                                                               
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ * 
-+ *  2003-Nov-18 - (Motorola) created
-+ * 
-+ */
-+extern struct tty_driver *usb_for_mux_driver;
-+extern struct tty_struct *usb_for_mux_tty;
-+extern void (*usb_mux_dispatcher)(struct tty_struct *tty);
-+extern void (*usb_mux_sender)(void);
-Index: linux-2.6.17.14-fic2/drivers/char/gsmmux/gsmmux_ldisc.c
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.17.14-fic2/drivers/char/gsmmux/gsmmux_ldisc.c	2006-12-04 16:50:05.000000000 +0100
-@@ -0,0 +1,291 @@
-+/* Linux kernel GSM multiplex implementation
-+ *
-+ * (C) 2006 by Harald Welte <hwelte at gnumonks.org>
-+ *
-+ *  This program is free software; you can redistribute it and/or modify
-+ *  it under the terms of the GNU General Public License as published by 
-+ *  the Free Software Foundation; either version 2 of the License, or
-+ *  (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/poll.h>
-+#include <linux/ioctl.h>
-+#include <linux/list.h>
-+#include <linux/tty.h>
-+#include <linux/string.h>
-+#include <linux/tty_ldisc.h>
-+
-+/* this structure resembles a (de)multiplexer implementation */
-+struct gsm_muxer {
-+	struct list_head list;
-+	char *name;
-+	struct module *owner;
-+	int (input)(struct gsmmux_instance *mi, const unsigned char *buf,
-+		    char *flags, int count);
-+};
-+
-+/* one instance of gsm_muxer */
-+struct gsmmux_instance {
-+	struct gsm_muxer *muxer;
-+}
-+
-+
-+/* muxer core */
-+
-+static list_head gsm_muxers;
-+spinlock_t gsm_muxers_lock;
-+
-+int gsmmux_register(struct gsm_muxer *muxer)
-+{
-+	spin_lock(&gsm_muxers_lock);
-+	list_add(&muxer->list, &gsm_muxers);
-+	spin_unlock(&gsm_muxers_lock);
-+}
-+EXPORT_SYMBOL_GPL(gsmmux_register);
-+
-+void gsmmux_unregister(struct gsm_muxer *muxer)
-+{
-+	spin_lock(&gsm_muxers_lock);
-+	list_del(&muxer->list);
-+	spin_unlock(&gsm_muxers_lock);
-+}
-+EXPORT_SYMBOL_GPL(gsmmux_unregister);
-+
-+/* called by lower layer (e.g. ldisc) if new data arrives */
-+int gsmmmux_input(struct gsmmux_instance *mi, const unsigned char *buf,
-+		  char *flags, int count)
-+{
-+	return mi->muxer->input(mi, buf, flags, count);
-+}
-+EXPORT_SYMBOL_GPL(gsmmux_input);
-+
-+/* UART ops */
-+
-+static void gsmmux_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
-+{
-+}
-+
-+static void gsmmux_uart_break_ctl(struct uart_port *port, int break_state)
-+{
-+
-+}
-+
-+static void gsmmux_uart_shutdown(struct uart_port *)
-+{
-+
-+}
-+
-+static int gsmmux_uart_startup(struct uart_port *port)
-+{
-+	int ret = 0;
-+
-+	dbg("gsmmux_uart_startup: port=%s\n", port);
-+
-+	return ret;
-+}
-+
-+static void gsmmux_uart_pm(struct uart_port *port, unsigned int level,
-+			   unsigned int old)
-+{
-+	switch (level) {
-+	case 3:
-+		break;
-+	case 0:
-+		break;
-+	default:
-+	}
-+}
-+
-+static const char *gsmmux_uart_type(struct uart_port *port)
-+{
-+	return "gsmmux";
-+}
-+
-+static void gsmmux_uart_release_port(struct uart_port *port)
-+{
-+}
-+
-+static int gsmmux_uart_request_port(struct uart_port *port)
-+{
-+	return 0;
-+}
-+
-+static void gsmmux_uart_config_port(struct uart_port *port, int flags)
-+{
-+}
-+
-+static int gsmmux_uart_verify_port(struct uart_port *port, 
-+				   struct serial_struct *ser)
-+{
-+	return 0;
-+}
-+
-+static struct uart_ops gsmmux_uart_ops = {
-+	.pm		= gsmmux_uart_pm,
-+	.tx_empty	= gsmmux_uart_tx_empty,
-+	.get_mctrl	= gsmmux_uart_get_mctrl,
-+	.set_mctrl	= gsmmux_uart_set_mctrl,
-+	.stop_tx	= gsmmux_uart_stop_tx,
-+	.enable_ms	= gsmmux_uart_enable_ms,
-+	.break_ctl	= gsmmux_uart_break_ctl,
-+	.startup	= gsmmux_uart_startup,
-+	.shutdown	= gsmmux_uart_shutdown,
-+	.set_termios	= gsmmux_uart_set_termios,
-+	.type		= gsmmux_uart_type,
-+	.release_port	= gsmmux_uart_release_port,
-+	.request_port	= gsmmux_uart_request_port,
-+	.config_port	= gsmmux_uart_config_port,
-+	.verify_port	= gsmmux_uart_verify_port,
-+};
-+
-+static struct uart_driver gsmmux_uart_drv = {
-+	.owner			= THIS_MODULE,
-+	.driver_name		= "ttyGSM",
-+	.devfs_name		= "gsm/",
-+	.dev_name		= "gsmmux_serial",
-+	.major			= 240, /* local/unassigned range */
-+	.nr			= NUM_MUX,
-+};
-+
-+static struct uart_port gsmmux_uart_ports[NUM_MUX] = {
-+	{
-+		.type		= PORT_GSMMUX,
-+	},
-+};
-+
-+
-+/* This is the gsmmux ldisc instance-specific data structure */
-+struct gsm_ldisc {
-+	struct gsmmux_instance mux;
-+	spinlock_t recv_lock;
-+};
-+
-+#define tty2gsm_ldisc(tty)	((struct gsm_ldisc *) ((tty)->disc_data))
-+#define gsm_ldisc2tty(gsm_ldisc)	((gsm_ldisc)->tty)
-+
-+static ssize_t gsm_ldisc_read(struct tty_struct *tty, struct file *file,
-+			   __u8 __user *buf, size_t nr)
-+{
-+	/* reading by the userspace process on the 'master' tty is generally
-+	 * not supported while this line discipline is in presence */
-+	return -EAGAIN;
-+}
-+
-+static ssize_t gsm_ldisc_write(struct tty_struct *tty, struct file *file,
-+			    const unsigned char *buf, size_t nr)
-+{
-+	/* writing by the userspace process on the 'master' tty is generally
-+	 * not supported while this line discipline is in presence */
-+	return -EAGAIN;
-+}
-+
-+static int gsm_ldisc_ioctl(struct tty_struct *tty, struct file *file,
-+			    unsigned int cmd, unsigned long arg)
-+{
-+	struct gsm_ldisc *gsm_ldisc = tty2gsm_ldisc(tty);
-+	int err;
-+
-+	if (gsm_ldisc == NULL)
-+		return -ENXIO;
-+	err = -EFAULT;
-+
-+	switch (cmd) {
-+	default:
-+		err = -ENOIOCTLCMD;
-+	}
-+
-+	return err;
-+}
-+
-+static unsigned int gsm_ldisc_poll(struct tty_struct *tty, struct file *filp,
-+				    poll_table *wait)
-+{
-+	return 0;
-+}
-+
-+static int gsm_ldisc_open(struct tty_struct *tty)
-+{
-+	struct gsm_ldisc *gsm_ldisc = tty2gsm_ldisc(tty);
-+
-+	/* Attach the line discipline ... */
-+}
-+
-+static void gsm_ldisc_close(struct tty_struct *tty)
-+{
-+	struct gsm_ldisc *gsm_ldisc = tty2gsm_ldisc(tty);
-+
-+	/* Disconnect the line discipline */
-+}
-+
-+/* this is called by the lower level (serial) driver when received data is
-+ * available */
-+
-+static void gsm_ldisc_recv_buf(struct tty_struct *tty, const __u8 *data,
-+			       char *flags, int count)
-+{
-+	struct gsm_ldisc *gsm_ldisc = tty2gsm_ldisc(tty);
-+	unsigned long flags;
-+
-+	if (!gsm_ldisc)
-+		return;
-+
-+	spin_lock_irqsave(&gsm_ldisc->recv_lock, flags);
-+	gsmmux_input(gsm_ldisc->mux, buf, cflags, count);
-+	spin_unlock_irqrestore(&gsm_ldisc->recv_lock, flags);
-+
-+}
-+
-+/* this gets called by the lower level (serial) driver when it wants
-+ * us to send some [more] data */
-+static void gsm_ldisc_write_wakeup(struct tty_struct *tty)
-+{
-+	struct gsm_ldisc *gsm_ldisc = tty2gsm_ldisc(tty);
-+
-+	clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-+	if (!gsm_ldisc)
-+		return;
-+}
-+
-+static struct tty_ldisc gsmmux_ldisc = {
-+	.owner		= THIS_MODULE,
-+	.magic		= TTY_LDISC_MAGIC,
-+	.name		= "gsmmux",
-+	.open		= gsm_ldisc_open,
-+	.close		= gsm_ldisc_close,
-+	.read		= gsm_ldisc_read,
-+	.write		= gsm_ldics_write,
-+	.ioctl		= gsm_ldisc_ioctl,
-+	.poll		= gsm_ldisc_poll,
-+	.receive_buf	= gsm_ldisc_recv_buf,
-+	.write_wakeup	= gsm_ldisc_write_wakeup,
-+};
-+
-+static int __init gsm_ldisc_init(void)
-+{
-+	return tty_register_ldisc(N_GSMMUX, &gsmmux_ldisc);
-+}
-+
-+static void __exit gsm_ldisc_exit(void)
-+{
-+	tty_unregister_ldisc(N_GSMMUX);
-+}
-+
-+module_init(gsm_ldisc_init);
-+module_exit(gsm_ldisc_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Harald Welte <laforge at gnumonks.org>");
-+MODULE_ALIAS_LDISC(N_GSMMUX);
-Index: linux-2.6.17.14-fic2/include/linux/serial_core.h
-===================================================================
---- linux-2.6.17.14-fic2.orig/include/linux/serial_core.h	2006-12-03 18:21:27.000000000 +0100
-+++ linux-2.6.17.14-fic2/include/linux/serial_core.h	2006-12-03 18:23:55.000000000 +0100
-@@ -130,6 +130,9 @@
- /* SUN4V Hypervisor Console */
- #define PORT_SUNHV	72
- 
-+/* GSM Multiplexer Virtual Port */
-+#define PORT_GSMMUX	73
-+
- #ifdef __KERNEL__
- 
- #include <linux/config.h>





More information about the commitlog mailing list