diff -urN linux.orig/net/irda/irsysctl.c linux/net/irda/irsysctl.c --- linux.orig/net/irda/irsysctl.c Fri Feb 27 18:28:04 2004 +++ linux/net/irda/irsysctl.c Wed Jan 14 19:36:40 2004 @@ -40,7 +40,8 @@ enum { DISCOVERY=1, DEVNAME, DEBUG, FAST_POLL, DISCOVERY_SLOTS, DISCOVERY_TIMEOUT, SLOT_TIMEOUT, MAX_BAUD_RATE, MIN_TX_TURN_TIME, - MAX_NOREPLY_TIME, WARN_NOREPLY_TIME, LAP_KEEPALIVE_TIME, SPECIFIC_DEV }; + MAX_TX_WINDOW, MAX_NOREPLY_TIME, WARN_NOREPLY_TIME, + LAP_KEEPALIVE_TIME, SPECIFIC_DEV }; extern int sysctl_discovery; extern int sysctl_discovery_slots; @@ -51,6 +52,7 @@ extern char sysctl_devname[]; extern int sysctl_max_baud_rate; extern int sysctl_min_tx_turn_time; +extern int sysctl_max_tx_window; extern int sysctl_max_noreply_time; extern int sysctl_warn_noreply_time; extern int sysctl_lap_keepalive_time; @@ -71,6 +73,8 @@ static int min_max_baud_rate = 2400; static int max_min_tx_turn_time = 10000; /* See qos.c - IrLAP spec */ static int min_min_tx_turn_time = 0; +static int max_max_tx_window=7; +static int min_max_tx_window=1; static int max_max_noreply_time = 40; /* See qos.c - IrLAP spec */ static int min_max_noreply_time = 3; static int max_warn_noreply_time = 3; /* 3s == standard */ @@ -128,6 +132,9 @@ { MIN_TX_TURN_TIME, "min_tx_turn_time", &sysctl_min_tx_turn_time, sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL, &min_min_tx_turn_time, &max_min_tx_turn_time }, + { MAX_TX_WINDOW, "max_tx_window", &sysctl_max_tx_window, + sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, + NULL, &min_max_tx_window, &max_max_tx_window }, { MAX_NOREPLY_TIME, "max_noreply_time", &sysctl_max_noreply_time, sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL, &min_max_noreply_time, &max_max_noreply_time }, diff -urN linux.orig/net/irda/parameters.c linux/net/irda/parameters.c --- linux.orig/net/irda/parameters.c Sat Nov 10 01:22:17 2001 +++ linux/net/irda/parameters.c Wed Jan 14 19:34:23 2004 @@ -204,12 +204,14 @@ { irda_param_t p; int n = 0; + int extract_len; int err; p.pi = pi; /* In case handler needs to know */ p.pl = buf[1]; /* Extract lenght of value */ p.pv.i = 0; /* Clear value */ - + extract_len = p.pl; + /* Check if buffer is long enough for parsing */ if (len < (2+p.pl)) { WARNING(__FUNCTION__ "(), buffer to short for parsing! " @@ -226,12 +228,15 @@ "Expected %d bytes, but value had %d bytes!\n", type & PV_MASK, p.pl); - /* Skip parameter */ + if((p.pl < (type & PV_MASK)) || (type & PV_BIG_ENDIAN)) { return p.pl+2; + } else { + extract_len = type & PV_MASK; + } } - switch (p.pl) { + switch (extract_len) { case 1: n += irda_param_unpack(buf+2, "b", &p.pv.i); break; diff -urN linux.orig/net/irda/qos.c linux/net/irda/qos.c --- linux.orig/net/irda/qos.c Fri Feb 27 18:28:04 2004 +++ linux/net/irda/qos.c Wed Jan 14 18:18:20 2004 @@ -65,6 +65,7 @@ */ unsigned sysctl_min_tx_turn_time = 10; +unsigned sysctl_max_tx_window = 7; /* * Specific device list limits some negotiation parameters at the connection * with listed peer devices. @@ -212,6 +213,9 @@ __u16 msb = 0x8000; int index = 15; /* Current MSB */ + if(!word) + word=0x1; + while (msb) { if (word & msb) break; /* Found it! */ @@ -386,6 +390,9 @@ qos->max_turn_time.value = 500; } + if(qos->window_size.value > sysctl_max_tx_window) + qos->window_size.value = sysctl_max_tx_window; + /* * The data size must be adjusted according to the baud rate and max * turn time