From: Greg Kroah-Hartman Date: Tue, 10 Oct 2006 06:09:43 +0000 (-0700) Subject: 2.6.18 patches added X-Git-Tag: v2.6.17.14~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bfa38b300ec7494e9910161b719eb54829b610ee;p=thirdparty%2Fkernel%2Fstable-queue.git 2.6.18 patches added --- diff --git a/queue-2.6.18/net_sched-fix-fallout-from-dev-qdisc-rcu-change.patch b/queue-2.6.18/net_sched-fix-fallout-from-dev-qdisc-rcu-change.patch new file mode 100644 index 00000000000..cf57f039ec0 --- /dev/null +++ b/queue-2.6.18/net_sched-fix-fallout-from-dev-qdisc-rcu-change.patch @@ -0,0 +1,273 @@ +From stable-bounces@linux.kernel.org Mon Oct 9 21:17:18 2006 +Date: Mon, 09 Oct 2006 21:16:11 -0700 (PDT) +Message-Id: <20061009.211611.118971931.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Subject: NET_SCHED: Fix fallout from dev->qdisc RCU change + +From: Patrick McHardy + +The move of qdisc destruction to a rcu callback broke locking in the +entire qdisc layer by invalidating previously valid assumptions about +the context in which changes to the qdisc tree occur. + +The two assumptions were: + +- since changes only happen in process context, read_lock doesn't need + bottem half protection. Now invalid since destruction of inner qdiscs, + classifiers, actions and estimators happens in the RCU callback unless + they're manually deleted, resulting in dead-locks when read_lock in + process context is interrupted by write_lock_bh in bottem half context. + +- since changes only happen under the RTNL, no additional locking is + necessary for data not used during packet processing (f.e. u32_list). + Again, since destruction now happens in the RCU callback, this assumption + is not valid anymore, causing races while using this data, which can + result in corruption or use-after-free. + +Instead of "fixing" this by disabling bottem halfs everywhere and adding +new locks/refcounting, this patch makes these assumptions valid again by +moving destruction back to process context. Since only the dev->qdisc +pointer is protected by RCU, but ->enqueue and the qdisc tree are still +protected by dev->qdisc_lock, destruction of the tree can be performed +immediately and only the final free needs to happen in the rcu callback +to make sure dev_queue_xmit doesn't access already freed memory. + +Signed-off-by: Patrick McHardy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/core/dev.c | 14 +++++----- + net/sched/cls_api.c | 4 +- + net/sched/sch_api.c | 16 +++++------ + net/sched/sch_generic.c | 66 +++++++++++++++--------------------------------- + 4 files changed, 39 insertions(+), 61 deletions(-) + +--- linux-2.6.18.orig/net/core/dev.c ++++ linux-2.6.18/net/core/dev.c +@@ -1478,14 +1478,16 @@ gso: + if (q->enqueue) { + /* Grab device queue */ + spin_lock(&dev->queue_lock); ++ q = dev->qdisc; ++ if (q->enqueue) { ++ rc = q->enqueue(skb, q); ++ qdisc_run(dev); ++ spin_unlock(&dev->queue_lock); + +- rc = q->enqueue(skb, q); +- +- qdisc_run(dev); +- ++ rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc; ++ goto out; ++ } + spin_unlock(&dev->queue_lock); +- rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc; +- goto out; + } + + /* The device has no queue. Common case for software devices: +--- linux-2.6.18.orig/net/sched/cls_api.c ++++ linux-2.6.18/net/sched/cls_api.c +@@ -401,7 +401,7 @@ static int tc_dump_tfilter(struct sk_buf + if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL) + return skb->len; + +- read_lock_bh(&qdisc_tree_lock); ++ read_lock(&qdisc_tree_lock); + if (!tcm->tcm_parent) + q = dev->qdisc_sleeping; + else +@@ -458,7 +458,7 @@ errout: + if (cl) + cops->put(q, cl); + out: +- read_unlock_bh(&qdisc_tree_lock); ++ read_unlock(&qdisc_tree_lock); + dev_put(dev); + return skb->len; + } +--- linux-2.6.18.orig/net/sched/sch_api.c ++++ linux-2.6.18/net/sched/sch_api.c +@@ -195,14 +195,14 @@ struct Qdisc *qdisc_lookup(struct net_de + { + struct Qdisc *q; + +- read_lock_bh(&qdisc_tree_lock); ++ read_lock(&qdisc_tree_lock); + list_for_each_entry(q, &dev->qdisc_list, list) { + if (q->handle == handle) { +- read_unlock_bh(&qdisc_tree_lock); ++ read_unlock(&qdisc_tree_lock); + return q; + } + } +- read_unlock_bh(&qdisc_tree_lock); ++ read_unlock(&qdisc_tree_lock); + return NULL; + } + +@@ -837,7 +837,7 @@ static int tc_dump_qdisc(struct sk_buff + continue; + if (idx > s_idx) + s_q_idx = 0; +- read_lock_bh(&qdisc_tree_lock); ++ read_lock(&qdisc_tree_lock); + q_idx = 0; + list_for_each_entry(q, &dev->qdisc_list, list) { + if (q_idx < s_q_idx) { +@@ -846,12 +846,12 @@ static int tc_dump_qdisc(struct sk_buff + } + if (tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) { +- read_unlock_bh(&qdisc_tree_lock); ++ read_unlock(&qdisc_tree_lock); + goto done; + } + q_idx++; + } +- read_unlock_bh(&qdisc_tree_lock); ++ read_unlock(&qdisc_tree_lock); + } + + done: +@@ -1074,7 +1074,7 @@ static int tc_dump_tclass(struct sk_buff + s_t = cb->args[0]; + t = 0; + +- read_lock_bh(&qdisc_tree_lock); ++ read_lock(&qdisc_tree_lock); + list_for_each_entry(q, &dev->qdisc_list, list) { + if (t < s_t || !q->ops->cl_ops || + (tcm->tcm_parent && +@@ -1096,7 +1096,7 @@ static int tc_dump_tclass(struct sk_buff + break; + t++; + } +- read_unlock_bh(&qdisc_tree_lock); ++ read_unlock(&qdisc_tree_lock); + + cb->args[0] = t; + +--- linux-2.6.18.orig/net/sched/sch_generic.c ++++ linux-2.6.18/net/sched/sch_generic.c +@@ -45,11 +45,10 @@ + The idea is the following: + - enqueue, dequeue are serialized via top level device + spinlock dev->queue_lock. +- - tree walking is protected by read_lock_bh(qdisc_tree_lock) ++ - tree walking is protected by read_lock(qdisc_tree_lock) + and this lock is used only in process context. +- - updates to tree are made under rtnl semaphore or +- from softirq context (__qdisc_destroy rcu-callback) +- hence this lock needs local bh disabling. ++ - updates to tree are made only under rtnl semaphore, ++ hence this lock may be made without local bh disabling. + + qdisc_tree_lock must be grabbed BEFORE dev->queue_lock! + */ +@@ -57,14 +56,14 @@ DEFINE_RWLOCK(qdisc_tree_lock); + + void qdisc_lock_tree(struct net_device *dev) + { +- write_lock_bh(&qdisc_tree_lock); ++ write_lock(&qdisc_tree_lock); + spin_lock_bh(&dev->queue_lock); + } + + void qdisc_unlock_tree(struct net_device *dev) + { + spin_unlock_bh(&dev->queue_lock); +- write_unlock_bh(&qdisc_tree_lock); ++ write_unlock(&qdisc_tree_lock); + } + + /* +@@ -483,20 +482,6 @@ void qdisc_reset(struct Qdisc *qdisc) + static void __qdisc_destroy(struct rcu_head *head) + { + struct Qdisc *qdisc = container_of(head, struct Qdisc, q_rcu); +- struct Qdisc_ops *ops = qdisc->ops; +- +-#ifdef CONFIG_NET_ESTIMATOR +- gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est); +-#endif +- write_lock(&qdisc_tree_lock); +- if (ops->reset) +- ops->reset(qdisc); +- if (ops->destroy) +- ops->destroy(qdisc); +- write_unlock(&qdisc_tree_lock); +- module_put(ops->owner); +- +- dev_put(qdisc->dev); + kfree((char *) qdisc - qdisc->padded); + } + +@@ -504,32 +489,23 @@ static void __qdisc_destroy(struct rcu_h + + void qdisc_destroy(struct Qdisc *qdisc) + { +- struct list_head cql = LIST_HEAD_INIT(cql); +- struct Qdisc *cq, *q, *n; ++ struct Qdisc_ops *ops = qdisc->ops; + + if (qdisc->flags & TCQ_F_BUILTIN || +- !atomic_dec_and_test(&qdisc->refcnt)) ++ !atomic_dec_and_test(&qdisc->refcnt)) + return; + +- if (!list_empty(&qdisc->list)) { +- if (qdisc->ops->cl_ops == NULL) +- list_del(&qdisc->list); +- else +- list_move(&qdisc->list, &cql); +- } +- +- /* unlink inner qdiscs from dev->qdisc_list immediately */ +- list_for_each_entry(cq, &cql, list) +- list_for_each_entry_safe(q, n, &qdisc->dev->qdisc_list, list) +- if (TC_H_MAJ(q->parent) == TC_H_MAJ(cq->handle)) { +- if (q->ops->cl_ops == NULL) +- list_del_init(&q->list); +- else +- list_move_tail(&q->list, &cql); +- } +- list_for_each_entry_safe(cq, n, &cql, list) +- list_del_init(&cq->list); ++ list_del(&qdisc->list); ++#ifdef CONFIG_NET_ESTIMATOR ++ gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est); ++#endif ++ if (ops->reset) ++ ops->reset(qdisc); ++ if (ops->destroy) ++ ops->destroy(qdisc); + ++ module_put(ops->owner); ++ dev_put(qdisc->dev); + call_rcu(&qdisc->q_rcu, __qdisc_destroy); + } + +@@ -549,15 +525,15 @@ void dev_activate(struct net_device *dev + printk(KERN_INFO "%s: activation failed\n", dev->name); + return; + } +- write_lock_bh(&qdisc_tree_lock); ++ write_lock(&qdisc_tree_lock); + list_add_tail(&qdisc->list, &dev->qdisc_list); +- write_unlock_bh(&qdisc_tree_lock); ++ write_unlock(&qdisc_tree_lock); + } else { + qdisc = &noqueue_qdisc; + } +- write_lock_bh(&qdisc_tree_lock); ++ write_lock(&qdisc_tree_lock); + dev->qdisc_sleeping = qdisc; +- write_unlock_bh(&qdisc_tree_lock); ++ write_unlock(&qdisc_tree_lock); + } + + if (!netif_carrier_ok(dev)) diff --git a/queue-2.6.18/series b/queue-2.6.18/series new file mode 100644 index 00000000000..e39b176fd70 --- /dev/null +++ b/queue-2.6.18/series @@ -0,0 +1,11 @@ +net_sched-fix-fallout-from-dev-qdisc-rcu-change.patch +uml-allow-using-again-x86-x86_64-crypto-code.patch +uml-use-defconfig_list-to-avoid-reading-host-s-config.patch +uml-fix-uml-build-failure.patch +video-fix-msp343xg-handling-regression.patch +video-cx24123-fix-pll-divisor-setup.patch +video-pvrusb2-solve-mutex-deadlock.patch +video-pvrusb2-improve-24xxx-config-option-description.patch +video-pvrusb2-suppress-compiler-warning.patch +video-pvrusb2-limit-hor-res-for-24xxx-devices.patch +zd1211rw-zd1211b-asic-fwt-not-jointly-decoder.patch diff --git a/queue-2.6.18/uml-allow-using-again-x86-x86_64-crypto-code.patch b/queue-2.6.18/uml-allow-using-again-x86-x86_64-crypto-code.patch new file mode 100644 index 00000000000..9bfcc7bb124 --- /dev/null +++ b/queue-2.6.18/uml-allow-using-again-x86-x86_64-crypto-code.patch @@ -0,0 +1,65 @@ +From stable-bounces@linux.kernel.org Thu Oct 5 14:10:24 2006 +From: "Paolo 'Blaisorblade' Giarrusso" +To: stable@kernel.org +Date: Thu, 5 Oct 2006 21:34:28 +0200 +Message-Id: <11600768683307-git-send-email-blaisorblade@yahoo.it> +Cc: Jeff Dike , + "Paolo 'Blaisorblade' Giarrusso" , + +Subject: uml: allow using again x86/x86_64 crypto code + +From: Paolo 'Blaisorblade' Giarrusso + +Enable compilation of x86_64 crypto code;, and add the needed constant +to make the code compile again (that macro was added to i386 asm-offsets +between 2.6.17 and 2.6.18, in 6c2bb98bc33ae33c7a33a133a4cd5a06395fece5). + +Signed-off-by: Paolo 'Blaisorblade' Giarrusso +Acked-by: Jeff Dike +Signed-off-by: Greg Kroah-Hartman + +--- + arch/um/Makefile-x86_64 | 2 +- + arch/um/include/common-offsets.h | 1 + + arch/um/include/sysdep-i386/kernel-offsets.h | 1 + + arch/um/include/sysdep-x86_64/kernel-offsets.h | 1 + + 4 files changed, 4 insertions(+), 1 deletion(-) + +--- linux-2.6.18.orig/arch/um/Makefile-x86_64 ++++ linux-2.6.18/arch/um/Makefile-x86_64 +@@ -1,7 +1,7 @@ + # Copyright 2003 - 2004 Pathscale, Inc + # Released under the GPL + +-core-y += arch/um/sys-x86_64/ ++core-y += arch/um/sys-x86_64/ arch/x86_64/crypto/ + START := 0x60000000 + + #We #undef __x86_64__ for kernelspace, not for userspace where +--- linux-2.6.18.orig/arch/um/include/common-offsets.h ++++ linux-2.6.18/arch/um/include/common-offsets.h +@@ -15,3 +15,4 @@ DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG); + DEFINE(UM_ELF_CLASS, ELF_CLASS); + DEFINE(UM_ELFCLASS32, ELFCLASS32); + DEFINE(UM_ELFCLASS64, ELFCLASS64); ++DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); +--- linux-2.6.18.orig/arch/um/include/sysdep-i386/kernel-offsets.h ++++ linux-2.6.18/arch/um/include/sysdep-i386/kernel-offsets.h +@@ -1,6 +1,7 @@ + #include + #include + #include ++#include + #include + + #define DEFINE(sym, val) \ +--- linux-2.6.18.orig/arch/um/include/sysdep-x86_64/kernel-offsets.h ++++ linux-2.6.18/arch/um/include/sysdep-x86_64/kernel-offsets.h +@@ -2,6 +2,7 @@ + #include + #include + #include ++#include + #include + #include + diff --git a/queue-2.6.18/uml-fix-uml-build-failure.patch b/queue-2.6.18/uml-fix-uml-build-failure.patch new file mode 100644 index 00000000000..040424dce6c --- /dev/null +++ b/queue-2.6.18/uml-fix-uml-build-failure.patch @@ -0,0 +1,96 @@ +From stable-bounces@linux.kernel.org Thu Oct 5 11:28:24 2006 +Date: Thu, 5 Oct 2006 20:27:32 +0200 +From: Mattia Dongili +To: stable@kernel.org +Message-ID: <20061005182732.GB17561@inferi.kami.home> +Content-Disposition: inline +Cc: Jeff Dike , Paolo Giarrusso +Subject: UML: Fix UML build failure + +From: Jeff Dike + +don't know if the following is already queued, it fixes an ARCH=um build +failure, evidence here: +http://marc.theaimsgroup.com/?l=linux-kernel&m=115875912525137&w=2 +and following thread. +Cc-ing uml maintainers and I hope I didn't follow too many +Submitting-patches rules... + +The patch is taken from: +http://user-mode-linux.sourceforge.net/work/current/2.6/2.6.18/patches/no-syscallx + +Since the syscallx macros seem to be under threat, this patch stops +using them, using syscall instead. + +Acked-by: Jeff Dike +Signed-off-by: Greg Kroah-Hartman + + +--- + arch/um/os-Linux/process.c | 4 +--- + arch/um/os-Linux/sys-i386/tls.c | 4 +--- + arch/um/os-Linux/tls.c | 7 ++----- + 3 files changed, 4 insertions(+), 11 deletions(-) + +--- linux-2.6.18.orig/arch/um/os-Linux/process.c ++++ linux-2.6.18/arch/um/os-Linux/process.c +@@ -141,11 +141,9 @@ void os_usr1_process(int pid) + * syscalls, and also breaks with clone(), which does not unshare the TLS. + */ + +-inline _syscall0(pid_t, getpid) +- + int os_getpid(void) + { +- return(getpid()); ++ return syscall(__NR_getpid); + } + + int os_getpgrp(void) +--- linux-2.6.18.orig/arch/um/os-Linux/sys-i386/tls.c ++++ linux-2.6.18/arch/um/os-Linux/sys-i386/tls.c +@@ -3,8 +3,6 @@ + #include "sysdep/tls.h" + #include "user_util.h" + +-static _syscall1(int, get_thread_area, user_desc_t *, u_info); +- + /* Checks whether host supports TLS, and sets *tls_min according to the value + * valid on the host. + * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */ +@@ -17,7 +15,7 @@ void check_host_supports_tls(int *suppor + user_desc_t info; + info.entry_number = val[i]; + +- if (get_thread_area(&info) == 0) { ++ if(syscall(__NR_get_thread_area, &info) == 0){ + *tls_min = val[i]; + *supports_tls = 1; + return; +--- linux-2.6.18.orig/arch/um/os-Linux/tls.c ++++ linux-2.6.18/arch/um/os-Linux/tls.c +@@ -48,14 +48,11 @@ int os_get_thread_area(user_desc_t *info + #ifdef UML_CONFIG_MODE_TT + #include "linux/unistd.h" + +-static _syscall1(int, get_thread_area, user_desc_t *, u_info); +-static _syscall1(int, set_thread_area, user_desc_t *, u_info); +- + int do_set_thread_area_tt(user_desc_t *info) + { + int ret; + +- ret = set_thread_area(info); ++ ret = syscall(__NR_set_thread_area, info); + if (ret < 0) { + ret = -errno; + } +@@ -66,7 +63,7 @@ int do_get_thread_area_tt(user_desc_t *i + { + int ret; + +- ret = get_thread_area(info); ++ ret = syscall(__NR_get_thread_area, info); + if (ret < 0) { + ret = -errno; + } diff --git a/queue-2.6.18/uml-use-defconfig_list-to-avoid-reading-host-s-config.patch b/queue-2.6.18/uml-use-defconfig_list-to-avoid-reading-host-s-config.patch new file mode 100644 index 00000000000..616c826c8e3 --- /dev/null +++ b/queue-2.6.18/uml-use-defconfig_list-to-avoid-reading-host-s-config.patch @@ -0,0 +1,53 @@ +From stable-bounces@linux.kernel.org Thu Oct 5 14:10:16 2006 +From: "Paolo 'Blaisorblade' Giarrusso" +To: stable@kernel.org +Date: Thu, 5 Oct 2006 22:01:47 +0200 +Message-Id: <11600785071661-git-send-email-blaisorblade@yahoo.it> +Cc: Jeff Dike , + "Paolo 'Blaisorblade' Giarrusso" , + +Subject: uml: use DEFCONFIG_LIST to avoid reading host's config + +From: Paolo 'Blaisorblade' Giarrusso + +This should make sure that, for UML, host's configuration files are not +considered, which avoids various pains to the user. Our dependency are such that +the obtained Kconfig will be valid and will lead to successful compilation - +however they cannot prevent an user from disabling any boot device, and if an +option is not set in the read .config (say /boot/config-XXX), with make +menuconfig ARCH=um, it is not set. This always disables UBD and all console I/O +channels, which leads to non-working UML kernels, so this bothers users - +especially now, since it will happen on almost every machine +(/boot/config-`uname -r` exists almost on every machine). It can be workarounded +with make defconfig ARCH=um, but it is non-obvious and can be avoided, so please +_do_ merge this patch. + +Signed-off-by: Paolo 'Blaisorblade' Giarrusso +Acked-by: Jeff Dike +Signed-off-by: Greg Kroah-Hartman + +--- + arch/um/Kconfig | 5 +++++ + init/Kconfig | 1 + + 2 files changed, 6 insertions(+) + +--- linux-2.6.18.orig/arch/um/Kconfig ++++ linux-2.6.18/arch/um/Kconfig +@@ -1,3 +1,8 @@ ++config DEFCONFIG_LIST ++ string ++ option defconfig_list ++ default "arch/$ARCH/defconfig" ++ + # UML uses the generic IRQ sugsystem + config GENERIC_HARDIRQS + bool +--- linux-2.6.18.orig/init/Kconfig ++++ linux-2.6.18/init/Kconfig +@@ -1,5 +1,6 @@ + config DEFCONFIG_LIST + string ++ depends on !UML + option defconfig_list + default "/lib/modules/$UNAME_RELEASE/.config" + default "/etc/kernel-config" diff --git a/queue-2.6.18/video-cx24123-fix-pll-divisor-setup.patch b/queue-2.6.18/video-cx24123-fix-pll-divisor-setup.patch new file mode 100644 index 00000000000..a8f5fbf9ee9 --- /dev/null +++ b/queue-2.6.18/video-cx24123-fix-pll-divisor-setup.patch @@ -0,0 +1,41 @@ +From stable-bounces@linux.kernel.org Sun Oct 8 11:43:11 2006 +Message-ID: <45294667.9030503@linuxtv.org> +Date: Sun, 08 Oct 2006 14:41:43 -0400 +From: Michael Krufky +To: stable@kernel.org +Cc: v4l-dvb maintainer list , + Yeasah Pell , linux-kernel@vger.kernel.org, + Steven Toth +Subject: Video: cx24123: fix PLL divisor setup + +From: Yeasah Pell + +The cx24109 datasheet says: "NOTE: if A=0, then N=N+1" + +The current code is the result of a misinterpretation of the datasheet to +mean exactly the opposite of the requirement -- The actual value of N is 1 +greater than the value written when A is 0, so 1 needs to be *subtracted* +from it to compensate. + +Signed-off-by: Yeasah Pell +Signed-off-by: Steven Toth +Signed-off-by: Michael Krufky +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/dvb/frontends/cx24123.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- linux-2.6.18.orig/drivers/media/dvb/frontends/cx24123.c ++++ linux-2.6.18/drivers/media/dvb/frontends/cx24123.c +@@ -549,8 +549,8 @@ static int cx24123_pll_calculate(struct + ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff; + adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f; + +- if (adiv == 0) +- ndiv++; ++ if (adiv == 0 && ndiv > 0) ++ ndiv--; + + /* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */ + state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv; diff --git a/queue-2.6.18/video-fix-msp343xg-handling-regression.patch b/queue-2.6.18/video-fix-msp343xg-handling-regression.patch new file mode 100644 index 00000000000..ac14b863881 --- /dev/null +++ b/queue-2.6.18/video-fix-msp343xg-handling-regression.patch @@ -0,0 +1,66 @@ +From stable-bounces@linux.kernel.org Sun Oct 8 11:42:36 2006 +Message-ID: <45294666.3040204@linuxtv.org> +Date: Sun, 08 Oct 2006 14:41:42 -0400 +From: Michael Krufky +To: stable@kernel.org +Cc: v4l-dvb maintainer list , + Hans Verkuil , + Linux and Kernel Video , + linux-kernel@vger.kernel.org +Subject: Video: Fix msp343xG handling regression + +From: Hans Verkuil + +The msp3430G and msp3435G models cannot do Automatic Standard Detection, +so these should be forced to BTSC. These chips are early production +versions for the msp34xxG series and are quite rare. + +The workaround for kernel 2.6.18 is to use 'standard=32' as msp3400 module +option. + +Signed-off-by: Hans Verkuil +Signed-off-by: Michael Krufky +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/video/msp3400-driver.c | 2 ++ + drivers/media/video/msp3400-driver.h | 1 + + drivers/media/video/msp3400-kthreads.c | 5 +++-- + 3 files changed, 6 insertions(+), 2 deletions(-) + +--- linux-2.6.18.orig/drivers/media/video/msp3400-driver.c ++++ linux-2.6.18/drivers/media/video/msp3400-driver.c +@@ -904,6 +904,8 @@ static int msp_attach(struct i2c_adapter + state->has_virtual_dolby_surround = msp_revision == 'G' && msp_prod_lo == 1; + /* Has Virtual Dolby Surround & Dolby Pro Logic: only in msp34x2 */ + state->has_dolby_pro_logic = msp_revision == 'G' && msp_prod_lo == 2; ++ /* The msp343xG supports BTSC only and cannot do Automatic Standard Detection. */ ++ state->force_btsc = msp_family == 3 && msp_revision == 'G' && msp_prod_hi == 3; + + state->opmode = opmode; + if (state->opmode == OPMODE_AUTO) { +--- linux-2.6.18.orig/drivers/media/video/msp3400-driver.h ++++ linux-2.6.18/drivers/media/video/msp3400-driver.h +@@ -64,6 +64,7 @@ struct msp_state { + u8 has_sound_processing; + u8 has_virtual_dolby_surround; + u8 has_dolby_pro_logic; ++ u8 force_btsc; + + int radio; + int opmode; +--- linux-2.6.18.orig/drivers/media/video/msp3400-kthreads.c ++++ linux-2.6.18/drivers/media/video/msp3400-kthreads.c +@@ -960,9 +960,10 @@ int msp34xxg_thread(void *data) + + /* setup the chip*/ + msp34xxg_reset(client); +- state->std = state->radio ? 0x40 : msp_standard; +- /* start autodetect */ ++ state->std = state->radio ? 0x40 : ++ (state->force_btsc && msp_standard == 1) ? 32 : msp_standard; + msp_write_dem(client, 0x20, state->std); ++ /* start autodetect */ + if (state->std != 1) + goto unmute; + diff --git a/queue-2.6.18/video-pvrusb2-improve-24xxx-config-option-description.patch b/queue-2.6.18/video-pvrusb2-improve-24xxx-config-option-description.patch new file mode 100644 index 00000000000..f2d49bb19d2 --- /dev/null +++ b/queue-2.6.18/video-pvrusb2-improve-24xxx-config-option-description.patch @@ -0,0 +1,41 @@ +From stable-bounces@linux.kernel.org Sun Oct 8 11:43:20 2006 +Message-ID: <45294683.8040508@linuxtv.org> +Date: Sun, 08 Oct 2006 14:42:11 -0400 +From: Michael Krufky +To: stable@kernel.org +Cc: v4l-dvb maintainer list , + Mike Isely , linux-kernel@vger.kernel.org +Subject: Video: pvrusb2: improve 24XXX config option description + +From: Mike Isely + +The CONFIG_VIDEO_PVRUSB2_24XXX is not nearly as "experimental" as the +description suggests. So refine the description to better match reality. + +Signed-off-by: Mike Isely +Signed-off-by: Michael Krufky +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/video/pvrusb2/Kconfig | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +--- linux-2.6.18.orig/drivers/media/video/pvrusb2/Kconfig ++++ linux-2.6.18/drivers/media/video/pvrusb2/Kconfig +@@ -25,14 +25,9 @@ config VIDEO_PVRUSB2_24XXX + form "24xxx" (leading prefix of "24" followed by 3 digits). + To see if you may need this option, examine the white + sticker on the underside of your device. Enabling this +- option will not harm support for older devices, however it +- is a separate option because of the experimental nature of +- this new feature. ++ option will not harm support for older devices. + +- If you are in doubt, say N. +- +- Note: This feature is _very_ experimental. You have been +- warned. ++ If you are in doubt, say Y. + + config VIDEO_PVRUSB2_SYSFS + bool "pvrusb2 sysfs support (EXPERIMENTAL)" diff --git a/queue-2.6.18/video-pvrusb2-limit-hor-res-for-24xxx-devices.patch b/queue-2.6.18/video-pvrusb2-limit-hor-res-for-24xxx-devices.patch new file mode 100644 index 00000000000..476d1ee9470 --- /dev/null +++ b/queue-2.6.18/video-pvrusb2-limit-hor-res-for-24xxx-devices.patch @@ -0,0 +1,189 @@ +From stable-bounces@linux.kernel.org Sun Oct 8 12:11:06 2006 +Message-ID: <45294689.80706@linuxtv.org> +Date: Sun, 08 Oct 2006 14:42:17 -0400 +From: Michael Krufky +To: stable@kernel.org +Cc: v4l-dvb maintainer list , + Mike Isely , linux-kernel@vger.kernel.org +Subject: Video: pvrusb2: Limit hor res for 24xxx devices + +From: Mike Isely + +Currently it is not understood how to properly control the horizontal +capture resolution on 24xxx devices. The pvrusb2 driver is doing +everything it should (pass resolution paramter(s) to cx2341x and +cx25840 modules) but for some reason the result is corrupted video if +any resolution other than 720 is used. This patch causes the driver +to only permit a horizontal resolution of 720 to be used on 24xxx +devices. Even if the app requests something else, the driver will +force the resolution back to 720. This patch still allows full +control of the resolution for 29xxx devices. + +Signed-off-by: Mike Isely +Signed-off-by: Michael Krufky +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/video/pvrusb2/pvrusb2-ctrl.c | 21 +++++++++--- + drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | 2 + + drivers/media/video/pvrusb2/pvrusb2-hdw.c | 30 ++++++++++++++++++ + drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 34 +++++++++++---------- + 4 files changed, 65 insertions(+), 22 deletions(-) + +--- linux-2.6.18.orig/drivers/media/video/pvrusb2/pvrusb2-ctrl.c ++++ linux-2.6.18/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +@@ -43,12 +43,17 @@ int pvr2_ctrl_set_mask_value(struct pvr2 + if (cptr->info->type == pvr2_ctl_bitmask) { + mask &= cptr->info->def.type_bitmask.valid_bits; + } else if (cptr->info->type == pvr2_ctl_int) { +- if (val < cptr->info->def.type_int.min_value) { +- break; ++ int lim; ++ lim = cptr->info->def.type_int.min_value; ++ if (cptr->info->get_min_value) { ++ cptr->info->get_min_value(cptr,&lim); + } +- if (val > cptr->info->def.type_int.max_value) { +- break; ++ if (val < lim) break; ++ lim = cptr->info->def.type_int.max_value; ++ if (cptr->info->get_max_value) { ++ cptr->info->get_max_value(cptr,&lim); + } ++ if (val > lim) break; + } else if (cptr->info->type == pvr2_ctl_enum) { + if (val >= cptr->info->def.type_enum.count) { + break; +@@ -91,7 +96,9 @@ int pvr2_ctrl_get_max(struct pvr2_ctrl * + int ret = 0; + if (!cptr) return 0; + LOCK_TAKE(cptr->hdw->big_lock); do { +- if (cptr->info->type == pvr2_ctl_int) { ++ if (cptr->info->get_max_value) { ++ cptr->info->get_max_value(cptr,&ret); ++ } else if (cptr->info->type == pvr2_ctl_int) { + ret = cptr->info->def.type_int.max_value; + } + } while(0); LOCK_GIVE(cptr->hdw->big_lock); +@@ -105,7 +112,9 @@ int pvr2_ctrl_get_min(struct pvr2_ctrl * + int ret = 0; + if (!cptr) return 0; + LOCK_TAKE(cptr->hdw->big_lock); do { +- if (cptr->info->type == pvr2_ctl_int) { ++ if (cptr->info->get_min_value) { ++ cptr->info->get_min_value(cptr,&ret); ++ } else if (cptr->info->type == pvr2_ctl_int) { + ret = cptr->info->def.type_int.min_value; + } + } while(0); LOCK_GIVE(cptr->hdw->big_lock); +--- linux-2.6.18.orig/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h ++++ linux-2.6.18/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +@@ -107,6 +107,8 @@ struct pvr2_ctl_info { + + /* Control's implementation */ + pvr2_ctlf_get_value get_value; /* Get its value */ ++ pvr2_ctlf_get_value get_min_value; /* Get minimum allowed value */ ++ pvr2_ctlf_get_value get_max_value; /* Get maximum allowed value */ + pvr2_ctlf_set_value set_value; /* Set its value */ + pvr2_ctlf_val_to_sym val_to_sym; /* Custom convert value->symbol */ + pvr2_ctlf_sym_to_val sym_to_val; /* Custom convert symbol->value */ +--- linux-2.6.18.orig/drivers/media/video/pvrusb2/pvrusb2-hdw.c ++++ linux-2.6.18/drivers/media/video/pvrusb2/pvrusb2-hdw.c +@@ -362,6 +362,30 @@ static int ctrl_freq_set(struct pvr2_ctr + return 0; + } + ++#ifdef CONFIG_VIDEO_PVRUSB2_24XXX ++static int ctrl_hres_max_get(struct pvr2_ctrl *cptr,int *vp) ++{ ++ /* If we're dealing with a 24xxx device, force the horizontal ++ maximum to be 720 no matter what, since we can't get the device ++ to work properly with any other value. Otherwise just return ++ the normal value. */ ++ *vp = cptr->info->def.type_int.max_value; ++ if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720; ++ return 0; ++} ++ ++static int ctrl_hres_min_get(struct pvr2_ctrl *cptr,int *vp) ++{ ++ /* If we're dealing with a 24xxx device, force the horizontal ++ minimum to be 720 no matter what, since we can't get the device ++ to work properly with any other value. Otherwise just return ++ the normal value. */ ++ *vp = cptr->info->def.type_int.min_value; ++ if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720; ++ return 0; ++} ++#endif ++ + static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr) + { + return cptr->hdw->enc_stale != 0; +@@ -720,6 +744,12 @@ static const struct pvr2_ctl_info contro + .default_value = 720, + DEFREF(res_hor), + DEFINT(320,720), ++#ifdef CONFIG_VIDEO_PVRUSB2_24XXX ++ /* Hook in check for clamp on horizontal resolution in ++ order to avoid unsolved problem involving cx25840. */ ++ .get_max_value = ctrl_hres_max_get, ++ .get_min_value = ctrl_hres_min_get, ++#endif + },{ + .desc = "Vertical capture resolution", + .name = "resolution_ver", +--- linux-2.6.18.orig/drivers/media/video/pvrusb2/pvrusb2-v4l2.c ++++ linux-2.6.18/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +@@ -456,18 +456,26 @@ static int pvr2_v4l2_do_ioctl(struct ino + ret = 0; + switch(vf->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { ++ int lmin,lmax; ++ struct pvr2_ctrl *hcp,*vcp; + int h = vf->fmt.pix.height; + int w = vf->fmt.pix.width; ++ hcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES); ++ vcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES); + +- if (h < 200) { +- h = 200; +- } else if (h > 625) { +- h = 625; ++ lmin = pvr2_ctrl_get_min(hcp); ++ lmax = pvr2_ctrl_get_max(hcp); ++ if (w < lmin) { ++ w = lmin; ++ } else if (w > lmax) { ++ w = lmax; + } +- if (w < 320) { +- w = 320; +- } else if (w > 720) { +- w = 720; ++ lmin = pvr2_ctrl_get_min(vcp); ++ lmax = pvr2_ctrl_get_max(vcp); ++ if (h < lmin) { ++ h = lmin; ++ } else if (h > lmax) { ++ h = lmax; + } + + memcpy(vf, &pvr_format[PVR_FORMAT_PIX], +@@ -476,14 +484,8 @@ static int pvr2_v4l2_do_ioctl(struct ino + vf->fmt.pix.height = h; + + if (cmd == VIDIOC_S_FMT) { +- pvr2_ctrl_set_value( +- pvr2_hdw_get_ctrl_by_id(hdw, +- PVR2_CID_HRES), +- vf->fmt.pix.width); +- pvr2_ctrl_set_value( +- pvr2_hdw_get_ctrl_by_id(hdw, +- PVR2_CID_VRES), +- vf->fmt.pix.height); ++ pvr2_ctrl_set_value(hcp,vf->fmt.pix.width); ++ pvr2_ctrl_set_value(vcp,vf->fmt.pix.height); + } + } break; + case V4L2_BUF_TYPE_VBI_CAPTURE: diff --git a/queue-2.6.18/video-pvrusb2-solve-mutex-deadlock.patch b/queue-2.6.18/video-pvrusb2-solve-mutex-deadlock.patch new file mode 100644 index 00000000000..ee7441a7352 --- /dev/null +++ b/queue-2.6.18/video-pvrusb2-solve-mutex-deadlock.patch @@ -0,0 +1,148 @@ +From stable-bounces@linux.kernel.org Sun Oct 8 11:43:20 2006 +Message-ID: <45294680.5010205@linuxtv.org> +Date: Sun, 08 Oct 2006 14:42:08 -0400 +From: Michael Krufky +To: stable@kernel.org +Cc: v4l-dvb maintainer list , + Mike Isely , linux-kernel@vger.kernel.org +Subject: Video: pvrusb2: Solve mutex deadlock + +From: Mike Isely + +There is a mutex ordering problem between the pvrusb2 driver and the +v4l core. Two different pathways take mutexes in opposing orders and +this (under rare circumstances) can cause a deadlock. The two mutexes +in question are videodev_lock in the v4l core and device_lock inside +the pvrusb2 driver. The device_lock instance in the driver protects a +private global array of context pointers which had been implemented in +advance of v4l core changes which eliminate the video_set_drvdata() +and video_get_drvdata() functions. + +This patch restores the use of video_get_drvdata() and +video_set_drvdata(), eliminating the need for the array and the mutex. +(This is actually a patch to restore the previous implementation.) We +can do this for 2.6.18 since those functions are in fact still +present. A better (and larger) solution will be done for later +kernels. + +Signed-off-by: Mike Isely +Signed-off-by: Michael Krufky +Signed-off-by: Greg Kroah-Hartman + +--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c ++++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +@@ -22,6 +22,7 @@ + + #include + #include ++#include + #include "pvrusb2-context.h" + #include "pvrusb2-hdw.h" + #include "pvrusb2.h" +@@ -35,21 +36,11 @@ struct pvr2_v4l2_dev; + struct pvr2_v4l2_fh; + struct pvr2_v4l2; + +-/* V4L no longer provide the ability to set / get a private context pointer +- (i.e. video_get_drvdata / video_set_drvdata), which means we have to +- concoct our own context locating mechanism. Supposedly this is intended +- to simplify driver implementation. It's not clear to me how that can +- possibly be true. Our solution here is to maintain a lookup table of +- our context instances, indexed by the minor device number of the V4L +- device. See pvr2_v4l2_open() for some implications of this approach. */ +-static struct pvr2_v4l2_dev *devices[256]; +-static DEFINE_MUTEX(device_lock); + + struct pvr2_v4l2_dev { + struct pvr2_v4l2 *v4lp; + struct video_device *vdev; + struct pvr2_context_stream *stream; +- int ctxt_idx; + enum pvr2_config config; + }; + +@@ -703,12 +694,6 @@ static void pvr2_v4l2_dev_destroy(struct + { + printk(KERN_INFO "pvrusb2: unregistering device video%d [%s]\n", + dip->vdev->minor,pvr2_config_get_name(dip->config)); +- if (dip->ctxt_idx >= 0) { +- mutex_lock(&device_lock); +- devices[dip->ctxt_idx] = NULL; +- dip->ctxt_idx = -1; +- mutex_unlock(&device_lock); +- } + video_unregister_device(dip->vdev); + } + +@@ -800,33 +785,10 @@ static int pvr2_v4l2_open(struct inode * + struct pvr2_v4l2 *vp; + struct pvr2_hdw *hdw; + +- mutex_lock(&device_lock); +- /* MCI 7-Jun-2006 Even though we're just doing what amounts to an +- atomic read of the device mapping array here, we still need the +- mutex. The problem is that there is a tiny race possible when +- we register the device. We can't update the device mapping +- array until after the device has been registered, owing to the +- fact that we can't know the minor device number until after the +- registration succeeds. And if another thread tries to open the +- device in the window of time after registration but before the +- map is updated, then it will get back an erroneous null pointer +- and the open will result in a spurious failure. The only way to +- prevent that is to (a) be inside the mutex here before we access +- the array, and (b) cover the entire registration process later +- on with this same mutex. Thus if we get inside the mutex here, +- then we can be assured that the registration process actually +- completed correctly. This is an unhappy complication from the +- use of global data in a driver that lives in a preemptible +- environment. It sure would be nice if the video device itself +- had a means for storing and retrieving a local context pointer. +- Oh wait. It did. But now it's gone. Silly me. */ + { +- unsigned int midx = iminor(file->f_dentry->d_inode); +- if (midx < sizeof(devices)/sizeof(devices[0])) { +- dip = devices[midx]; +- } ++ struct video_device *vdev = video_devdata(file); ++ dip = (struct pvr2_v4l2_dev *)video_get_drvdata(vdev); + } +- mutex_unlock(&device_lock); + + if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */ + +@@ -1066,7 +1028,7 @@ static void pvr2_v4l2_dev_init(struct pv + + memcpy(dip->vdev,&vdev_template,sizeof(vdev_template)); + dip->vdev->release = video_device_release; +- mutex_lock(&device_lock); ++ video_set_drvdata(dip->vdev,dip); + + mindevnum = -1; + unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw); +@@ -1081,12 +1043,6 @@ static void pvr2_v4l2_dev_init(struct pv + dip->vdev->minor,pvr2_config_get_name(dip->config)); + } + +- if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) && +- (devices[dip->vdev->minor] == NULL)) { +- dip->ctxt_idx = dip->vdev->minor; +- devices[dip->ctxt_idx] = dip; +- } +- mutex_unlock(&device_lock); + + pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw, + dip->vdev->minor); +@@ -1100,7 +1056,6 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struc + vp = kmalloc(sizeof(*vp),GFP_KERNEL); + if (!vp) return vp; + memset(vp,0,sizeof(*vp)); +- vp->video_dev.ctxt_idx = -1; + pvr2_channel_init(&vp->channel,mnp); + pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp); + + +_______________________________________________ +stable mailing list +stable@linux.kernel.org +http://linux.kernel.org/mailman/listinfo/stable + diff --git a/queue-2.6.18/video-pvrusb2-suppress-compiler-warning.patch b/queue-2.6.18/video-pvrusb2-suppress-compiler-warning.patch new file mode 100644 index 00000000000..693553bec11 --- /dev/null +++ b/queue-2.6.18/video-pvrusb2-suppress-compiler-warning.patch @@ -0,0 +1,47 @@ +From stable-bounces@linux.kernel.org Sun Oct 8 11:43:20 2006 +Message-ID: <45294686.6050003@linuxtv.org> +Date: Sun, 08 Oct 2006 14:42:14 -0400 +From: Michael Krufky +To: stable@kernel.org +Cc: v4l-dvb maintainer list , + Mike Isely , linux-kernel@vger.kernel.org +Subject: Video: pvrusb2: Suppress compiler warning + +From: Mike Isely + +The pvrusb2 driver needs to call video_devdata() in order to correctly +transform a file pointer into a video_device pointer. Unfortunately +the prototype for this function has been marked V4L1-only and there's +no official substitute that I can find for V4L2. Adding to the +mystery is that the implementation for this function exists whether or +not V4L1 compatibility has been selected. The upshot of all this is +that we get a compilation warning here about a missing prototype but +the code links OK. This fix solves the warning by copying the +prototype into the source file that is using it. Yes this is a hack, +but it's a safe one for 2.6.18 (any alternative would be much more +intrusive). A better solution should be forthcoming for the next +kernel. + +Signed-off-by: Mike Isely +Signed-off-by: Michael Krufky +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- linux-2.6.18.orig/drivers/media/video/pvrusb2/pvrusb2-v4l2.c ++++ linux-2.6.18/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +@@ -32,6 +32,12 @@ + #include + #include + ++/* Mike Isely 23-Sep-2006 - This function is prototyped ++ * only for V4L1 but is implemented regardless of the V4L1 compatibility ++ * option state. V4L2 has no replacement for this and we need it. For now ++ * copy the prototype here so we can avoid the compiler warning. */ ++extern struct video_device* video_devdata(struct file*); ++ + struct pvr2_v4l2_dev; + struct pvr2_v4l2_fh; + struct pvr2_v4l2; diff --git a/queue-2.6.18/zd1211rw-zd1211b-asic-fwt-not-jointly-decoder.patch b/queue-2.6.18/zd1211rw-zd1211b-asic-fwt-not-jointly-decoder.patch new file mode 100644 index 00000000000..304fd5340a2 --- /dev/null +++ b/queue-2.6.18/zd1211rw-zd1211b-asic-fwt-not-jointly-decoder.patch @@ -0,0 +1,31 @@ +From stable-bounces@linux.kernel.org Mon Oct 9 08:06:59 2006 +From: Daniel Drake +To: stable@kernel.org +Message-Id: <20061009150616.878027B40A0@zog.reactivated.net> +Date: Mon, 9 Oct 2006 16:06:16 +0100 (BST) +Subject: zd1211rw: ZD1211B ASIC/FWT, not jointly decoder + +From: Daniel Drake + +The vendor driver chooses this value based on an ifndef ASIC, +and ASIC is never defined. + +Signed-off-by: Daniel Drake +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/zd1211rw/zd_chip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.18.orig/drivers/net/wireless/zd1211rw/zd_chip.c ++++ linux-2.6.18/drivers/net/wireless/zd1211rw/zd_chip.c +@@ -717,7 +717,7 @@ static int zd1211b_hw_reset_phy(struct z + { CR21, 0x0e }, { CR22, 0x23 }, { CR23, 0x90 }, + { CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 }, + { CR27, 0x10 }, { CR28, 0x7f }, { CR29, 0x80 }, +- { CR30, 0x49 }, /* jointly decoder, no ASIC */ ++ { CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */ + { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 }, + { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 }, + { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },