From 408f22e81ea2fcf96c80e85ee12d20ef5148bf7c Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Sat, 16 Jun 2007 14:03:45 -0400 Subject: SCTP: update sctp_getsockopt helpers to allow oversized buffers I noted the other day while looking at a bug that was ostensibly in some perl networking library, that we strictly avoid allowing getsockopt operations to complete if we pass in oversized buffers. This seems to make libraries like Perl::NET malfunction since it seems to allocate oversized buffers for use in several operations. It also seems to be out of line with the way udp, tcp and ip getsockopt routines handle buffer input (since the *optlen pointer in both an input and an output and gets set to the length of the data that we copy into the buffer). This patch brings our getsockopt helpers into line with other protocols, and allows us to accept oversized buffers for our getsockopt operations. Tested by me with good results. Signed-off-by: Neil Horman Acked-by: Sridhar Samudrala Signed-off-by: Vlad Yasevich --- net/sctp/socket.c | 108 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 34 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6edaaa009d62..c1f239ac12b9 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -3375,12 +3375,13 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, sctp_assoc_t associd; int retval = 0; - if (len != sizeof(status)) { + if (len < sizeof(status)) { retval = -EINVAL; goto out; } - if (copy_from_user(&status, optval, sizeof(status))) { + len = sizeof(status); + if (copy_from_user(&status, optval, len)) { retval = -EFAULT; goto out; } @@ -3452,12 +3453,13 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len, struct sctp_transport *transport; int retval = 0; - if (len != sizeof(pinfo)) { + if (len < sizeof(pinfo)) { retval = -EINVAL; goto out; } - if (copy_from_user(&pinfo, optval, sizeof(pinfo))) { + len = sizeof(pinfo); + if (copy_from_user(&pinfo, optval, len)) { retval = -EFAULT; goto out; } @@ -3523,8 +3525,11 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len, static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval, int __user *optlen) { - if (len != sizeof(struct sctp_event_subscribe)) + if (len < sizeof(struct sctp_event_subscribe)) return -EINVAL; + len = sizeof(struct sctp_event_subscribe); + if (put_user(len, optlen)) + return -EFAULT; if (copy_to_user(optval, &sctp_sk(sk)->subscribe, len)) return -EFAULT; return 0; @@ -3546,9 +3551,12 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv /* Applicable to UDP-style socket only */ if (sctp_style(sk, TCP)) return -EOPNOTSUPP; - if (len != sizeof(int)) + if (len < sizeof(int)) return -EINVAL; - if (copy_to_user(optval, &sctp_sk(sk)->autoclose, len)) + len = sizeof(int); + if (put_user(len, optlen)) + return -EFAULT; + if (copy_to_user(optval, &sctp_sk(sk)->autoclose, sizeof(int))) return -EFAULT; return 0; } @@ -3599,8 +3607,9 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval int retval = 0; struct sctp_association *asoc; - if (len != sizeof(sctp_peeloff_arg_t)) + if (len < sizeof(sctp_peeloff_arg_t)) return -EINVAL; + len = sizeof(sctp_peeloff_arg_t); if (copy_from_user(&peeloff, optval, len)) return -EFAULT; @@ -3628,6 +3637,8 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval /* Return the fd mapped to the new socket. */ peeloff.sd = retval; + if (put_user(len, optlen)) + return -EFAULT; if (copy_to_user(optval, &peeloff, len)) retval = -EFAULT; @@ -3736,9 +3747,9 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len, struct sctp_association *asoc = NULL; struct sctp_sock *sp = sctp_sk(sk); - if (len != sizeof(struct sctp_paddrparams)) + if (len < sizeof(struct sctp_paddrparams)) return -EINVAL; - + len = sizeof(struct sctp_paddrparams); if (copy_from_user(¶ms, optval, len)) return -EFAULT; @@ -3837,9 +3848,11 @@ static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len, struct sctp_association *asoc = NULL; struct sctp_sock *sp = sctp_sk(sk); - if (len != sizeof(struct sctp_assoc_value)) + if (len < sizeof(struct sctp_assoc_value)) return - EINVAL; + len = sizeof(struct sctp_assoc_value); + if (copy_from_user(¶ms, optval, len)) return -EFAULT; @@ -3888,8 +3901,11 @@ static int sctp_getsockopt_delayed_ack_time(struct sock *sk, int len, */ static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval, int __user *optlen) { - if (len != sizeof(struct sctp_initmsg)) + if (len < sizeof(struct sctp_initmsg)) return -EINVAL; + len = sizeof(struct sctp_initmsg); + if (put_user(len, optlen)) + return -EFAULT; if (copy_to_user(optval, &sctp_sk(sk)->initmsg, len)) return -EFAULT; return 0; @@ -3904,7 +3920,7 @@ static int sctp_getsockopt_peer_addrs_num_old(struct sock *sk, int len, struct list_head *pos; int cnt = 0; - if (len != sizeof(sctp_assoc_t)) + if (len < sizeof(sctp_assoc_t)) return -EINVAL; if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) @@ -3940,10 +3956,12 @@ static int sctp_getsockopt_peer_addrs_old(struct sock *sk, int len, struct sctp_sock *sp = sctp_sk(sk); int addrlen; - if (len != sizeof(struct sctp_getaddrs_old)) + if (len < sizeof(struct sctp_getaddrs_old)) return -EINVAL; - if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs_old))) + len = sizeof(struct sctp_getaddrs_old); + + if (copy_from_user(&getaddrs, optval, len)) return -EFAULT; if (getaddrs.addr_num <= 0) return -EINVAL; @@ -3966,7 +3984,9 @@ static int sctp_getsockopt_peer_addrs_old(struct sock *sk, int len, if (cnt >= getaddrs.addr_num) break; } getaddrs.addr_num = cnt; - if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old))) + if (put_user(len, optlen)) + return -EFAULT; + if (copy_to_user(optval, &getaddrs, len)) return -EFAULT; return 0; @@ -4037,7 +4057,7 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len, rwlock_t *addr_lock; int cnt = 0; - if (len != sizeof(sctp_assoc_t)) + if (len < sizeof(sctp_assoc_t)) return -EINVAL; if (copy_from_user(&id, optval, sizeof(sctp_assoc_t))) @@ -4179,10 +4199,11 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len, void *buf; int bytes_copied = 0; - if (len != sizeof(struct sctp_getaddrs_old)) + if (len < sizeof(struct sctp_getaddrs_old)) return -EINVAL; - if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs_old))) + len = sizeof(struct sctp_getaddrs_old); + if (copy_from_user(&getaddrs, optval, len)) return -EFAULT; if (getaddrs.addr_num <= 0) return -EINVAL; @@ -4254,7 +4275,7 @@ copy_getaddrs: /* copy the leading structure back to user */ getaddrs.addr_num = cnt; - if (copy_to_user(optval, &getaddrs, sizeof(struct sctp_getaddrs_old))) + if (copy_to_user(optval, &getaddrs, len)) err = -EFAULT; error: @@ -4282,7 +4303,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, void *addrs; void *buf; - if (len <= sizeof(struct sctp_getaddrs)) + if (len < sizeof(struct sctp_getaddrs)) return -EINVAL; if (copy_from_user(&getaddrs, optval, sizeof(struct sctp_getaddrs))) @@ -4379,10 +4400,12 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len, struct sctp_association *asoc; struct sctp_sock *sp = sctp_sk(sk); - if (len != sizeof(struct sctp_prim)) + if (len < sizeof(struct sctp_prim)) return -EINVAL; - if (copy_from_user(&prim, optval, sizeof(struct sctp_prim))) + len = sizeof(struct sctp_prim); + + if (copy_from_user(&prim, optval, len)) return -EFAULT; asoc = sctp_id2assoc(sk, prim.ssp_assoc_id); @@ -4398,7 +4421,9 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len, sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, (union sctp_addr *)&prim.ssp_addr); - if (copy_to_user(optval, &prim, sizeof(struct sctp_prim))) + if (put_user(len, optlen)) + return -EFAULT; + if (copy_to_user(optval, &prim, len)) return -EFAULT; return 0; @@ -4415,10 +4440,15 @@ static int sctp_getsockopt_adaptation_layer(struct sock *sk, int len, { struct sctp_setadaptation adaptation; - if (len != sizeof(struct sctp_setadaptation)) + if (len < sizeof(struct sctp_setadaptation)) return -EINVAL; + len = sizeof(struct sctp_setadaptation); + adaptation.ssb_adaptation_ind = sctp_sk(sk)->adaptation_ind; + + if (put_user(len, optlen)) + return -EFAULT; if (copy_to_user(optval, &adaptation, len)) return -EFAULT; @@ -4452,9 +4482,12 @@ static int sctp_getsockopt_default_send_param(struct sock *sk, struct sctp_association *asoc; struct sctp_sock *sp = sctp_sk(sk); - if (len != sizeof(struct sctp_sndrcvinfo)) + if (len < sizeof(struct sctp_sndrcvinfo)) return -EINVAL; - if (copy_from_user(&info, optval, sizeof(struct sctp_sndrcvinfo))) + + len = sizeof(struct sctp_sndrcvinfo); + + if (copy_from_user(&info, optval, len)) return -EFAULT; asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); @@ -4475,7 +4508,9 @@ static int sctp_getsockopt_default_send_param(struct sock *sk, info.sinfo_timetolive = sp->default_timetolive; } - if (copy_to_user(optval, &info, sizeof(struct sctp_sndrcvinfo))) + if (put_user(len, optlen)) + return -EFAULT; + if (copy_to_user(optval, &info, len)) return -EFAULT; return 0; @@ -4526,10 +4561,12 @@ static int sctp_getsockopt_rtoinfo(struct sock *sk, int len, struct sctp_rtoinfo rtoinfo; struct sctp_association *asoc; - if (len != sizeof (struct sctp_rtoinfo)) + if (len < sizeof (struct sctp_rtoinfo)) return -EINVAL; - if (copy_from_user(&rtoinfo, optval, sizeof (struct sctp_rtoinfo))) + len = sizeof(struct sctp_rtoinfo); + + if (copy_from_user(&rtoinfo, optval, len)) return -EFAULT; asoc = sctp_id2assoc(sk, rtoinfo.srto_assoc_id); @@ -4581,11 +4618,12 @@ static int sctp_getsockopt_associnfo(struct sock *sk, int len, struct list_head *pos; int cnt = 0; - if (len != sizeof (struct sctp_assocparams)) + if (len < sizeof (struct sctp_assocparams)) return -EINVAL; - if (copy_from_user(&assocparams, optval, - sizeof (struct sctp_assocparams))) + len = sizeof(struct sctp_assocparams); + + if (copy_from_user(&assocparams, optval, len)) return -EFAULT; asoc = sctp_id2assoc(sk, assocparams.sasoc_assoc_id); @@ -4671,9 +4709,11 @@ static int sctp_getsockopt_context(struct sock *sk, int len, struct sctp_sock *sp; struct sctp_association *asoc; - if (len != sizeof(struct sctp_assoc_value)) + if (len < sizeof(struct sctp_assoc_value)) return -EINVAL; + len = sizeof(struct sctp_assoc_value); + if (copy_from_user(¶ms, optval, len)) return -EFAULT; -- cgit v1.2.3 From 186e234358ba29a4094d0c8c0d3ea00f84d32a3e Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 18 Jun 2007 19:59:16 -0400 Subject: SCTP: Fix sctp_getsockopt_get_peer_addrs This is the split out of the patch that we agreed I should split out from my last patch. It changes space_left to be computed in the same way the to variable is. I know we talked about changing space_left to an int, but I think size_t is more appropriate, since we should never have negative space in our buffer, and computing using offsetof means space_left should now never drop below zero. Signed-off-by: Neil Horman Acked-by: Sridhar Samudrala Signed-off-by: Vlad Yasevich --- net/sctp/socket.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index c1f239ac12b9..2fc036699d48 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4019,8 +4019,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, return -EINVAL; to = optval + offsetof(struct sctp_getaddrs,addrs); - space_left = len - sizeof(struct sctp_getaddrs) - - offsetof(struct sctp_getaddrs,addrs); + space_left = len - offsetof(struct sctp_getaddrs,addrs); list_for_each(pos, &asoc->peer.transport_addr_list) { from = list_entry(pos, struct sctp_transport, transports); @@ -4327,8 +4326,8 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, } to = optval + offsetof(struct sctp_getaddrs,addrs); - space_left = len - sizeof(struct sctp_getaddrs) - - offsetof(struct sctp_getaddrs,addrs); + space_left = len - offsetof(struct sctp_getaddrs,addrs); + addrs = kmalloc(space_left, GFP_KERNEL); if (!addrs) return -ENOMEM; -- cgit v1.2.3 From de3025f4e2bc063c274f561f9daf2b696910ad3b Mon Sep 17 00:00:00 2001 From: Jie Zhang Date: Mon, 25 Jun 2007 18:04:12 +0800 Subject: Blackfin arch: Add proper -mcpu option according to the cpu and silicon revision configuration Add silicon revision "any" and "none". Add proper -mcpu option according to the cpu and silicon revision configuration. Need update to use latest Blackfin cross compile toolchain. Signed-off-by: Jie Zhang Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/Kconfig | 6 ++++++ arch/blackfin/Makefile | 21 +++++++++++++++++++++ arch/blackfin/kernel/setup.c | 18 ++++++++++++++---- include/asm-blackfin/processor.h | 4 ++++ 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig index 1fad8560c7af..d98bafcaca59 100644 --- a/arch/blackfin/Kconfig +++ b/arch/blackfin/Kconfig @@ -142,6 +142,12 @@ config BF_REV_0_5 bool "0.5" depends on (BF561 || BF533 || BF532 || BF531) +config BF_REV_ANY + bool "any" + +config BF_REV_NONE + bool "none" + endchoice config BFIN_DUAL_CORE diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile index 75e89c324756..6971a4418dfe 100644 --- a/arch/blackfin/Makefile +++ b/arch/blackfin/Makefile @@ -28,6 +28,27 @@ machine-$(CONFIG_BF561) := bf561 MACHINE := $(machine-y) export MACHINE +cpu-$(CONFIG_BF531) := bf531 +cpu-$(CONFIG_BF532) := bf532 +cpu-$(CONFIG_BF533) := bf533 +cpu-$(CONFIG_BF534) := bf534 +cpu-$(CONFIG_BF536) := bf536 +cpu-$(CONFIG_BF537) := bf537 +cpu-$(CONFIG_BF548) := bf548 +cpu-$(CONFIG_BF549) := bf549 +cpu-$(CONFIG_BF561) := bf561 + +rev-$(CONFIG_BF_REV_0_0) := 0.0 +rev-$(CONFIG_BF_REV_0_1) := 0.1 +rev-$(CONFIG_BF_REV_0_2) := 0.2 +rev-$(CONFIG_BF_REV_0_3) := 0.3 +rev-$(CONFIG_BF_REV_0_4) := 0.4 +rev-$(CONFIG_BF_REV_0_5) := 0.5 +rev-$(CONFIG_BF_REV_NONE) := none +rev-$(CONFIG_BF_REV_ANY) := any + +CFLAGS += -mcpu=$(cpu-y)-$(rev-y) +AFLAGS += -mcpu=$(cpu-y)-$(rev-y) head-y := arch/$(ARCH)/mach-$(MACHINE)/head.o arch/$(ARCH)/kernel/init_task.o diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 5b9b434c1ed9..83060f98d15d 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -307,10 +307,20 @@ void __init setup_arch(char **cmdline_p) init_leds(); printk(KERN_INFO "Blackfin support (C) 2004-2007 Analog Devices, Inc.\n"); - printk(KERN_INFO "Compiled for ADSP-%s Rev 0.%d\n", CPU, bfin_compiled_revid()); - if (bfin_revid() != bfin_compiled_revid()) - printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n", - bfin_compiled_revid(), bfin_revid()); + if (bfin_compiled_revid() == 0xffff) + printk(KERN_INFO "Compiled for ADSP-%s Rev any\n", CPU); + else if (bfin_compiled_revid() == -1) + printk(KERN_INFO "Compiled for ADSP-%s Rev none\n", CPU); + else + printk(KERN_INFO "Compiled for ADSP-%s Rev 0.%d\n", CPU, bfin_compiled_revid()); + if (bfin_revid() != bfin_compiled_revid()) { + if (bfin_compiled_revid() == -1) + printk(KERN_ERR "Warning: Compiled for Rev none, but running on Rev %d\n", + bfin_revid()); + else if (bfin_compiled_revid() != 0xffff) + printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n", + bfin_compiled_revid(), bfin_revid()); + } if (bfin_revid() < SUPPORTED_REVID) printk(KERN_ERR "Warning: Unsupported Chip Revision ADSP-%s Rev 0.%d detected\n", CPU, bfin_revid()); diff --git a/include/asm-blackfin/processor.h b/include/asm-blackfin/processor.h index aba2b30a8ed8..6bb3e0d4705d 100644 --- a/include/asm-blackfin/processor.h +++ b/include/asm-blackfin/processor.h @@ -124,6 +124,10 @@ static inline __attribute_pure__ uint32_t bfin_compiled_revid(void) return 4; #elif defined(CONFIG_BF_REV_0_5) return 5; +#elif defined(CONFIG_BF_REV_ANY) + return 0xffff; +#else + return -1; #endif } -- cgit v1.2.3 From da1f95b4c41e09ef96869552db587452e0da46d6 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Mon, 25 Jun 2007 18:05:53 +0800 Subject: Blackfin arch: Fix up remaining printks with proper log levels Signed-off-by: Robin Getz Signed-off-by: Bryan Wu --- arch/blackfin/kernel/traps.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index aa660f32d8c8..56058b0b6d4a 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -545,7 +545,8 @@ void dump_bfin_regs(struct pt_regs *fp, void *retaddr) if (current->mm) { printk(KERN_EMERG "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" - "BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n", + KERN_EMERG "BSS = 0x%p-0x%p USER-STACK = 0x%p\n" + KERN_EMERG "\n", (void*)current->mm->start_code, (void*)current->mm->end_code, (void*)current->mm->start_data, -- cgit v1.2.3 From 701271dfd220d214e26ef90c48a2dae3a2042687 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2007 00:11:56 -0700 Subject: [SPARC64]: Add irqs to mdesc_node. Will be used to store translated LDC rx-ino and tx-ino. Signed-off-by: David S. Miller --- include/asm-sparc64/mdesc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-sparc64/mdesc.h b/include/asm-sparc64/mdesc.h index 124eb8ca2378..c6383982b53d 100644 --- a/include/asm-sparc64/mdesc.h +++ b/include/asm-sparc64/mdesc.h @@ -15,6 +15,7 @@ struct mdesc_node { u64 node; unsigned int unique_id; unsigned int num_arcs; + unsigned int irqs[2]; struct property *properties; struct mdesc_node *hash_next; struct mdesc_node *allnodes_next; -- cgit v1.2.3 From 1245088400c0e5f93b979356e578c9a8825b953a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2007 00:13:09 -0700 Subject: [SPARC64]: Fix VIRQ enabling. We were doing the wrong call to turn them on, and also when enabling we need to forcefully set the state to IDLE. Signed-off-by: David S. Miller --- arch/sparc64/kernel/irq.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index e60d283f60bc..a862d13fc857 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -400,6 +400,12 @@ static void sun4v_virq_enable(unsigned int virt_irq) "err(%d)\n", dev_handle, dev_ino, cpuid, err); err = sun4v_vintr_set_state(dev_handle, dev_ino, + HV_INTR_STATE_IDLE); + if (err != HV_EOK) + printk("sun4v_vintr_set_state(%lx,%lx," + "HV_INTR_STATE_IDLE): err(%d)\n", + dev_handle, dev_ino, err); + err = sun4v_vintr_set_valid(dev_handle, dev_ino, HV_INTR_ENABLED); if (err != HV_EOK) printk("sun4v_vintr_set_state(%lx,%lx," @@ -420,7 +426,7 @@ static void sun4v_virq_disable(unsigned int virt_irq) dev_handle = ino & IMAP_IGN; dev_ino = ino & IMAP_INO; - err = sun4v_vintr_set_state(dev_handle, dev_ino, + err = sun4v_vintr_set_valid(dev_handle, dev_ino, HV_INTR_DISABLED); if (err != HV_EOK) printk("sun4v_vintr_set_state(%lx,%lx," -- cgit v1.2.3 From a357b8f42e7b85e2522c3ad2b29b685bc28743b4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 26 Jun 2007 00:13:31 -0700 Subject: [SPARC64]: Need to set state to IDLE during sun4v IRQ enable. This fixes hypervisor console interrupts on LDOM guests. Signed-off-by: David S. Miller --- arch/sparc64/kernel/irq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index a862d13fc857..6b6165d36fd8 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -329,6 +329,10 @@ static void sun4v_irq_enable(unsigned int virt_irq) if (err != HV_EOK) printk("sun4v_intr_settarget(%x,%lu): err(%d)\n", ino, cpuid, err); + err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE); + if (err != HV_EOK) + printk("sun4v_intr_setstate(%x): " + "err(%d)\n", ino, err); err = sun4v_intr_setenabled(ino, HV_INTR_ENABLED); if (err != HV_EOK) printk("sun4v_intr_setenabled(%x): err(%d)\n", -- cgit v1.2.3 From 5131a184a3458d9ac47d9eba032cf4c4d3295afd Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Fri, 22 Jun 2007 15:14:46 -0700 Subject: SCTP: lock_sock_nested in sctp_sock_migrate sctp_sock_migrate() grabs the socket lock on a newly allocated socket while holding the socket lock on an old socket. lockdep worries that this might be a recursive lock attempt. task/3026 is trying to acquire lock: (sk_lock-AF_INET){--..}, at: [] sctp_sock_migrate+0x2e3/0x327 [sctp] but task is already holding lock: (sk_lock-AF_INET){--..}, at: [] sctp_accept+0xdf/0x1e3 [sctp] This patch tells lockdep that this locking is safe by using lock_sock_nested(). Signed-off-by: Zach Brown Signed-off-by: Vlad Yasevich --- net/sctp/socket.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 2fc036699d48..67861a8f00cb 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -6123,8 +6123,11 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, * queued to the backlog. This prevents a potential race between * backlog processing on the old socket and new-packet processing * on the new socket. + * + * The caller has just allocated newsk so we can guarantee that other + * paths won't try to lock it and then oldsk. */ - sctp_lock_sock(newsk); + lock_sock_nested(newsk, SINGLE_DEPTH_NESTING); sctp_assoc_migrate(assoc, newsk); /* If the association on the newsk is already closed before accept() -- cgit v1.2.3 From 0db3dc73f7a3a73b0dc725b6a991253f5652c905 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 27 Jun 2007 00:39:42 -0700 Subject: [NETPOLL]: tx lock deadlock fix If sky2 device poll routine is called from netpoll_send_skb, it would deadlock. The netpoll_send_skb held the netif_tx_lock, and the poll routine could acquire it to clean up skb's. Other drivers might use same locking model. The driver is correct, netpoll should not introduce more locking problems than it causes already. So change the code to drop lock before calling poll handler. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/core/netpoll.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 758dafe284c0..f8e74e511ce6 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -250,22 +250,23 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) unsigned long flags; local_irq_save(flags); - if (netif_tx_trylock(dev)) { - /* try until next clock tick */ - for (tries = jiffies_to_usecs(1)/USEC_PER_POLL; - tries > 0; --tries) { + /* try until next clock tick */ + for (tries = jiffies_to_usecs(1)/USEC_PER_POLL; + tries > 0; --tries) { + if (netif_tx_trylock(dev)) { if (!netif_queue_stopped(dev)) status = dev->hard_start_xmit(skb, dev); + netif_tx_unlock(dev); if (status == NETDEV_TX_OK) break; - /* tickle device maybe there is some cleanup */ - netpoll_poll(np); - - udelay(USEC_PER_POLL); } - netif_tx_unlock(dev); + + /* tickle device maybe there is some cleanup */ + netpoll_poll(np); + + udelay(USEC_PER_POLL); } local_irq_restore(flags); } -- cgit v1.2.3 From b59bb616636f58ea650d2800a1dfc41c114f5ef8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 18 Jun 2007 11:50:43 -0400 Subject: [PATCH] libertas: style fixes Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 623ab4b16973..cf2d71943865 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -181,7 +181,8 @@ u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] = * @brief Get function for sysfs attribute anycast_mask */ static ssize_t libertas_anycast_get(struct device * dev, - struct device_attribute *attr, char * buf) { + struct device_attribute *attr, char * buf) +{ struct cmd_ds_mesh_access mesh_access; memset(&mesh_access, 0, sizeof(mesh_access)); @@ -197,7 +198,8 @@ static ssize_t libertas_anycast_get(struct device * dev, * @brief Set function for sysfs attribute anycast_mask */ static ssize_t libertas_anycast_set(struct device * dev, - struct device_attribute *attr, const char * buf, size_t count) { + struct device_attribute *attr, const char * buf, size_t count) +{ struct cmd_ds_mesh_access mesh_access; uint32_t datum; -- cgit v1.2.3 From f8f551089b0ca571b8f95465b6c3e1dd7bcea28e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 30 May 2007 10:12:55 -0400 Subject: [PATCH] libertas: kill wlan_scan_process_results Fold into wlan_scan_networks() and protect with debug defines. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/scan.c | 51 ++++++++++-------------------------- 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 606af50fa09b..c3043dcb541e 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -214,38 +214,6 @@ done: return matched; } -/** - * @brief Post process the scan table after a new scan command has completed - * - * Inspect each entry of the scan table and try to find an entry that - * matches our current associated/joined network from the scan. If - * one is found, update the stored copy of the bssdescriptor for our - * current network. - * - * Debug dump the current scan table contents if compiled accordingly. - * - * @param priv A pointer to wlan_private structure - * - * @return void - */ -static void wlan_scan_process_results(wlan_private * priv) -{ - wlan_adapter *adapter = priv->adapter; - struct bss_descriptor * iter_bss; - int i = 0; - - if (adapter->connect_status == libertas_connected) - return; - - mutex_lock(&adapter->lock); - list_for_each_entry (iter_bss, &adapter->network_list, list) { - lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n", - i++, MAC_ARG(iter_bss->bssid), (s32) iter_bss->rssi, - escape_essid(iter_bss->ssid, iter_bss->ssid_len)); - } - mutex_unlock(&adapter->lock); -} - /** * @brief Create a channel list for the driver to scan based on region info * @@ -791,6 +759,10 @@ int wlan_scan_networks(wlan_private * priv, u8 scancurrentchanonly; int maxchanperscan; int ret; +#ifdef CONFIG_LIBERTAS_DEBUG + struct bss_descriptor * iter_bss; + int i = 0; +#endif lbs_deb_enter(LBS_DEB_ASSOC); @@ -832,11 +804,16 @@ int wlan_scan_networks(wlan_private * priv, puserscanin, full_scan); - /* Process the resulting scan table: - * - Remove any bad ssids - * - Update our current BSS information from scan data - */ - wlan_scan_process_results(priv); +#ifdef CONFIG_LIBERTAS_DEBUG + /* Dump the scan table */ + mutex_lock(&adapter->lock); + list_for_each_entry (iter_bss, &adapter->network_list, list) { + lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n", + i++, MAC_ARG(iter_bss->bssid), (s32) iter_bss->rssi, + escape_essid(iter_bss->ssid, iter_bss->ssid_len)); + } + mutex_unlock(&adapter->lock); +#endif if (priv->adapter->connect_status == libertas_connected) { netif_carrier_on(priv->dev); -- cgit v1.2.3 From 18c96c3497aa871608d57ca5e08de3558159a6c9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 18 Jun 2007 12:01:12 -0400 Subject: [PATCH] libertas: fix WPA associations by handling ENABLE_RSN correctly Don't clobber the firmware's internal state machine by setting ENABLE_RSN more than once during the 4-way handshake. Check what the ENABLE_RSN status is and only set if it should be changed. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/assoc.c | 28 ++++++++++++++++++++++++++-- drivers/net/wireless/libertas/cmd.c | 12 +++++++----- drivers/net/wireless/libertas/cmdresp.c | 21 +++++++++++++++++++++ drivers/net/wireless/libertas/hostcmd.h | 2 +- 4 files changed, 55 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index f67efa0815fe..afd5617dd92b 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -323,6 +323,8 @@ static int assoc_helper_secinfo(wlan_private *priv, { wlan_adapter *adapter = priv->adapter; int ret = 0; + u32 do_wpa; + u32 rsn = 0; lbs_deb_enter(LBS_DEB_ASSOC); @@ -333,12 +335,34 @@ static int assoc_helper_secinfo(wlan_private *priv, if (ret) goto out; - /* enable/disable RSN */ + /* If RSN is already enabled, don't try to enable it again, since + * ENABLE_RSN resets internal state machines and will clobber the + * 4-way WPA handshake. + */ + + /* Get RSN enabled/disabled */ ret = libertas_prepare_and_send_command(priv, cmd_802_11_enable_rsn, cmd_act_set, cmd_option_waitforrsp, - 0, assoc_req); + 0, &rsn); + if (ret) { + lbs_deb_assoc("Failed to get RSN status: %d", ret); + goto out; + } + + /* Don't re-enable RSN if it's already enabled */ + do_wpa = (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled); + if (do_wpa == rsn) + goto out; + + /* Set RSN enabled/disabled */ + rsn = do_wpa; + ret = libertas_prepare_and_send_command(priv, + cmd_802_11_enable_rsn, + cmd_act_set, + cmd_option_waitforrsp, + 0, &rsn); out: lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 124e029f1bf4..13f6528abb00 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -228,17 +228,19 @@ static int wlan_cmd_802_11_enable_rsn(wlan_private * priv, void * pdata_buf) { struct cmd_ds_802_11_enable_rsn *penableRSN = &cmd->params.enbrsn; - struct assoc_request * assoc_req = pdata_buf; + u32 * enable = pdata_buf; lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(cmd_802_11_enable_rsn); cmd->size = cpu_to_le16(sizeof(*penableRSN) + S_DS_GEN); penableRSN->action = cpu_to_le16(cmd_action); - if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { - penableRSN->enable = cpu_to_le16(cmd_enable_rsn); - } else { - penableRSN->enable = cpu_to_le16(cmd_disable_rsn); + + if (cmd_action == cmd_act_set) { + if (*enable) + penableRSN->enable = cpu_to_le16(cmd_enable_rsn); + else + penableRSN->enable = cpu_to_le16(cmd_enable_rsn); } lbs_deb_leave(LBS_DEB_CMD); diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 0c3b9a583d83..6ac0d4752fa4 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -537,6 +537,24 @@ static int wlan_ret_get_log(wlan_private * priv, return 0; } +static int libertas_ret_802_11_enable_rsn(wlan_private * priv, + struct cmd_ds_command *resp) +{ + struct cmd_ds_802_11_enable_rsn *enable_rsn = &resp->params.enbrsn; + wlan_adapter *adapter = priv->adapter; + u32 * pdata_buf = adapter->cur_cmd->pdata_buf; + + lbs_deb_enter(LBS_DEB_CMD); + + if (enable_rsn->action == cpu_to_le16(cmd_act_get)) { + if (pdata_buf) + *pdata_buf = (u32) le16_to_cpu(enable_rsn->enable); + } + + lbs_deb_enter(LBS_DEB_CMD); + return 0; +} + static inline int handle_cmd_response(u16 respcmd, struct cmd_ds_command *resp, wlan_private *priv) @@ -610,7 +628,10 @@ static inline int handle_cmd_response(u16 respcmd, case cmd_ret_802_11_authenticate: case cmd_ret_802_11_radio_control: case cmd_ret_802_11_beacon_stop: + break; + case cmd_ret_802_11_enable_rsn: + ret = libertas_ret_802_11_enable_rsn(priv, resp); break; case cmd_ret_802_11_data_rate: diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index 3acf93988125..09b898f6719c 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h @@ -503,7 +503,7 @@ struct cmd_ds_802_11_ad_hoc_join { struct cmd_ds_802_11_enable_rsn { __le16 action; __le16 enable; -}; +} __attribute__ ((packed)); struct MrvlIEtype_keyParamSet { /* type ID */ -- cgit v1.2.3 From 7dcf5284d12d7b59359a503d35797295f085f327 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 18 Jun 2007 12:10:33 -0400 Subject: [PATCH] libertas: remove private ioctls Signed-off-by: Christoph Hellwig Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/Makefile | 2 +- drivers/net/wireless/libertas/README | 275 -------- drivers/net/wireless/libertas/ioctl.c | 1081 -------------------------------- drivers/net/wireless/libertas/main.c | 2 - drivers/net/wireless/libertas/wext.c | 152 ----- drivers/net/wireless/libertas/wext.h | 45 +- 6 files changed, 6 insertions(+), 1551 deletions(-) delete mode 100644 drivers/net/wireless/libertas/ioctl.c diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile index a1097f59fd46..32ed4136b0d4 100644 --- a/drivers/net/wireless/libertas/Makefile +++ b/drivers/net/wireless/libertas/Makefile @@ -2,7 +2,7 @@ libertas-objs := main.o fw.o wext.o \ rx.o tx.o cmd.o \ cmdresp.o scan.o \ join.o 11d.o \ - ioctl.o debugfs.o \ + debugfs.o \ ethtool.o assoc.o usb8xxx-objs += if_bootcmd.o diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README index 1f92f50b643c..0b133ce63805 100644 --- a/drivers/net/wireless/libertas/README +++ b/drivers/net/wireless/libertas/README @@ -28,281 +28,6 @@ DRIVER LOADING insmod usb8388.ko [fw_name=usb8388.bin] -===================== -IWPRIV COMMAND -===================== - -NAME - This manual describes the usage of private commands used in Marvell WLAN - Linux Driver. All the commands available in Wlanconfig will not be available - in the iwpriv. - -SYNOPSIS - iwpriv [sub-command] ... - - iwpriv ethX setregioncode - iwpriv ethX getregioncode - -Version 5 Command: - iwpriv ethX ledgpio - -BT Commands: - The blinding table (BT) contains a list of mac addresses that will be, - by default, ignored by the firmware. It is also possible to invert this - behavior so that we will ignore all traffic except for the portion - coming from mac addresess in the list. It is primarily used for - debugging and testing networks. It can be edited and inspected with - the following commands: - - iwpriv ethX bt_reset - iwpriv ethX bt_add - iwpriv ethX bt_del - iwpriv ethX bt_list - iwpriv ethX bt_get_invert - iwpriv ethX bt_set_invert - -FWT Commands: - The forwarding table (FWT) is a feature used to manage mesh network - routing in the firmware. The FWT is essentially a routing table that - associates a destination mac address (da) with a next hop receiver - address (ra). The FWT can be inspected and edited with the following - iwpriv commands, which are described in greater detail below. - Eventually, the table will be automatically maintained by a custom - routing protocol. - - NOTE: FWT commands replace the previous DFT commands. What were the DFT - commands?, you might ask. They were an earlier API to the firmware that - implemented a simple MAC-layer forwarding mechanism. In the unlikely - event that you were using these commands, you must migrate to the new - FWT commands which can be used to achieve the same functionality. - - iwpriv ethX fwt_add [parameters] - iwpriv ethX fwt_del [parameters] - iwpriv ethX fwt_lookup [parameters] - iwpriv ethX fwt_list [parameters] - iwpriv ethX fwt_list_route [parameters] - iwpriv ethX fwt_list_neigh [parameters] - iwpriv ethX fwt_reset [parameters] - iwpriv ethX fwt_cleanup - iwpriv ethX fwt_time - -MESH Commands: - - The MESH commands are used to configure various features of the mesh - routing protocol. The following commands are supported: - - iwpriv ethX mesh_get_ttl - iwpriv ethX mesh_set_ttl ttl - -DESCRIPTION - Those commands are used to send additional commands to the Marvell WLAN - card via the Linux device driver. - - The ethX parameter specifies the network device that is to be used to - perform this command on. it could be eth0, eth1 etc. - -setregioncode - This command is used to set the region code in the station. - where value is 'region code' for various regions like - USA FCC, Canada IC, Spain, France, Europe ETSI, Japan ... - - Usage: - iwpriv ethX setregioncode 0x10: set region code to USA (0x10). - -getregioncode - This command is used to get the region code information set in the - station. - -ledgpio - This command is used to set/get LEDs. - - iwpriv ethX ledgpio - will set the corresponding LED for the GPIO Line. - - iwpriv ethX ledgpio - will give u which LEDs are Enabled. - - Usage: - iwpriv eth1 ledgpio 1 0 2 1 3 4 - will enable - LED 1 -> GPIO 0 - LED 2 -> GPIO 1 - LED 3 -> GPIO 4 - - iwpriv eth1 ledgpio - shows LED information in the format as mentioned above. - - Note: LED0 is invalid - Note: Maximum Number of LEDs are 16. - -fwt_add - This command is used to insert an entry into the FWT table. The list of - parameters must follow the following structure: - - iwpriv ethX fwt_add da ra [metric dir rate ssn dsn hopcount ttl expiration sleepmode snr] - - The parameters between brackets are optional, but they must appear in - the order specified. For example, if you want to specify the metric, - you must also specify the dir, ssn, and dsn but you need not specify the - hopcount, expiration, sleepmode, or snr. Any unspecified parameters - will be assigned the defaults specified below. - - The different parameters are:- - da -- DA MAC address in the form 00:11:22:33:44:55 - ra -- RA MAC address in the form 00:11:22:33:44:55 - metric -- route metric (cost: smaller-metric routes are - preferred, default is 0) - dir -- direction (1 for direct, 0 for reverse, - default is 1) - rate -- data rate used for transmission to the RA, - as specified for the rateadapt command, - default is 3 (11Mbps) - ssn -- Source Sequence Number (time at the RA for - reverse routes. Default is 0) - dsn -- Destination Sequence Number (time at the DA - for direct routes. Default is 0) - hopcount -- hop count (currently unused, default is 0) - ttl -- TTL (Only used in reverse entries) - expiration -- entry expiration (in ticks, where a tick is - 1024us, or ~ 1ms. Use 0 for an indefinite - entry, default is 0) - sleepmode -- RA's sleep mode (currently unused, default is - 0) - snr -- SNR in the link to RA (currently unused, - default is 0) - - The command does not return anything. - -fwt_del - This command is used to remove an entry to the FWT table. The list of - parameters must follow the following structure: - - iwpriv ethX fwt_del da ra [dir] - - where the different parameters are:- - da -- DA MAC address (in the form "00:11:22:33:44:55") - ra -- RA MAC address (in the form "00:11:22:33:44:55") - dir -- direction (1 for direct, 0 for reverse, - default is 1) - - The command does not return anything. - -fwt_lookup - This command is used to get the best route in the FWT table to a given - host. The only parameter is the MAC address of the host that is being - looked for. - - iwpriv ethX fwt_lookup da - - where:- - da -- DA MAC address (in the form "00:11:22:33:44:55") - - The command returns an output string identical to the one returned by - fwt_list described below. - - -fwt_list - This command is used to list a route from the FWT table. The only - parameter is the index into the table. If you want to list all the - routes in a table, start with index=0, and keep listing until you get a - "(null)" string. Note that the indicies may change as the fwt is - updated. It is expected that most users will not use fwt_list directly, - but that a utility similar to the traditional route command will be used - to invoke fwt_list over and over. - - iwpriv ethX fwt_list index - - The output is a string of the following form: - - da ra valid metric dir rate ssn dsn hopcount ttl expiration - sleepmode snr precursor - - where the different fields are:- - da -- DA MAC address (in the form "00:11:22:33:44:55") - ra -- RA MAC address (in the form "00:11:22:33:44:55") - valid -- whether the route is valid (0 if not valid) - metric -- route metric (cost: smaller-metric routes are preferred) - dir -- direction (1 for direct, 0 for reverse) - rate -- data rate used for transmission to the RA, - as specified for the rateadapt command - ssn -- Source Sequence Number (time at the RA for reverse routes) - dsn -- Destination Sequence Number (time at the DA for direct routes) - hopcount -- hop count (currently unused) - ttl -- TTL (only used in reverse entries) - expiration -- entry expiration (in ticks, where a tick is 1024us, or ~ 1ms. Use 0 for an indefinite entry) - sleepmode -- RA's sleep mode (currently unused) - snr -- SNR in the link to RA (currently unused) - precursor -- predecessor in direct routes - -fwt_list_route - This command is equivalent to fwt_list. - -fwt_list_neigh - This command is used to list a neighbor from the FWT table. The only - parameter is the neighbor ID. If you want to list all the neighbors in a - table, start with nid=0, and keep incrementing nid until you get a - "(null)" string. Note that the nid from a fwt_list_route command can be - used as an input to this command. Also note that this command is meant - mostly for debugging. It is expected that users will use fwt_lookup. - One important reason for this is that the neighbor id may change as the - neighbor table is altered. - - iwpriv ethX fwt_list_neigh nid - - The output is a string of the following form: - - ra sleepmode snr references - - where the different fields are:- - ra -- RA MAC address (in the form "00:11:22:33:44:55") - sleepmode -- RA's sleep mode (currently unused) - snr -- SNR in the link to RA (currently unused) - references -- RA's reference counter - -fwt_reset - This command is used to reset the FWT table, getting rid of all the - entries. There are no input parameters. - - iwpriv ethX fwt_reset - - The command does not return anything. - -fwt_cleanup - This command is used to perform user-based garbage recollection. The - FWT table is checked, and all the entries that are expired or invalid - are cleaned. Note that this is exported to the driver for debugging - purposes, as garbage collection is also fired by the firmware when in - space problems. There are no input parameters. - - iwpriv ethX fwt_cleanup - - The command does returns the number of invalid/expired routes deleted. - -fwt_time - This command returns a card's internal time representation. It is this - time that is used to represent the expiration times of FWT entries. The - number is not consistent from card to card; it is simply a timer count. - The fwt_time command is used to inspect the timer so that expiration - times reported by fwt_list can be properly interpreted. - - iwpriv ethX fwt_time - -mesh_get_ttl - - The mesh ttl is the number of hops a mesh packet can traverse before it - is dropped. This parameter is used to prevent infinite loops in the - mesh network. The value returned by this function is the ttl assigned - to all mesh packets. Currently there is no way to control the ttl on a - per packet or per socket basis. - - iwpriv ethX mesh_get_ttl - -mesh_set_ttl ttl - - Set the ttl. The argument must be between 0 and 255. - - iwpriv ethX mesh_set_ttl - ========================= ETHTOOL ========================= diff --git a/drivers/net/wireless/libertas/ioctl.c b/drivers/net/wireless/libertas/ioctl.c deleted file mode 100644 index f41081585564..000000000000 --- a/drivers/net/wireless/libertas/ioctl.c +++ /dev/null @@ -1,1081 +0,0 @@ -/** - * This file contains ioctl functions - */ - -#include -#include -#include -#include -#include - -#include -#include - -#include "host.h" -#include "radiotap.h" -#include "decl.h" -#include "defs.h" -#include "dev.h" -#include "join.h" -#include "wext.h" - -#define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN + \ - IW_ESSID_MAX_SIZE + \ - IW_EV_UINT_LEN + IW_EV_FREQ_LEN + \ - IW_EV_QUAL_LEN + IW_ESSID_MAX_SIZE + \ - IW_EV_PARAM_LEN + 40) /* 40 for WPAIE */ - -#define WAIT_FOR_SCAN_RRESULT_MAX_TIME (10 * HZ) - -static int wlan_set_region(wlan_private * priv, u16 region_code) -{ - int i; - int ret = 0; - - for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { - // use the region code to search for the index - if (region_code == libertas_region_code_to_index[i]) { - priv->adapter->regiontableindex = (u16) i; - priv->adapter->regioncode = region_code; - break; - } - } - - // if it's unidentified region code - if (i >= MRVDRV_MAX_REGION_CODE) { - lbs_deb_ioctl("region Code not identified\n"); - ret = -1; - goto done; - } - - if (libertas_set_regiontable(priv, priv->adapter->regioncode, 0)) { - ret = -EINVAL; - } - -done: - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); - return ret; -} - -static inline int hex2int(char c) -{ - if (c >= '0' && c <= '9') - return (c - '0'); - if (c >= 'a' && c <= 'f') - return (c - 'a' + 10); - if (c >= 'A' && c <= 'F') - return (c - 'A' + 10); - return -1; -} - -/* Convert a string representation of a MAC address ("xx:xx:xx:xx:xx:xx") - into binary format (6 bytes). - - This function expects that each byte is represented with 2 characters - (e.g., 11:2:11:11:11:11 is invalid) - - */ -static char *eth_str2addr(char *ethstr, u8 * addr) -{ - int i, val, val2; - char *pos = ethstr; - - /* get rid of initial blanks */ - while (*pos == ' ' || *pos == '\t') - ++pos; - - for (i = 0; i < 6; i++) { - val = hex2int(*pos++); - if (val < 0) - return NULL; - val2 = hex2int(*pos++); - if (val2 < 0) - return NULL; - addr[i] = (val * 16 + val2) & 0xff; - - if (i < 5 && *pos++ != ':') - return NULL; - } - return pos; -} - -/* this writes xx:xx:xx:xx:xx:xx into ethstr - (ethstr must have space for 18 chars) */ -static int eth_addr2str(u8 * addr, char *ethstr) -{ - int i; - char *pos = ethstr; - - for (i = 0; i < 6; i++) { - sprintf(pos, "%02x", addr[i] & 0xff); - pos += 2; - if (i < 5) - *pos++ = ':'; - } - return 17; -} - -/** - * @brief Add an entry to the BT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_bt_add_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char ethaddrs_str[18]; - char *pos; - u8 ethaddr[ETH_ALEN]; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(ethaddrs_str, wrq->u.data.pointer, - sizeof(ethaddrs_str))) - return -EFAULT; - - if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) { - lbs_pr_info("BT_ADD: Invalid MAC address\n"); - return -EINVAL; - } - - lbs_deb_ioctl("BT: adding %s\n", ethaddrs_str); - ret = libertas_prepare_and_send_command(priv, cmd_bt_access, - cmd_act_bt_access_add, - cmd_option_waitforrsp, 0, ethaddr); - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); - return ret; -} - -/** - * @brief Delete an entry from the BT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_bt_del_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char ethaddrs_str[18]; - u8 ethaddr[ETH_ALEN]; - char *pos; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(ethaddrs_str, wrq->u.data.pointer, - sizeof(ethaddrs_str))) - return -EFAULT; - - if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) { - lbs_pr_info("Invalid MAC address\n"); - return -EINVAL; - } - - lbs_deb_ioctl("BT: deleting %s\n", ethaddrs_str); - - return (libertas_prepare_and_send_command(priv, - cmd_bt_access, - cmd_act_bt_access_del, - cmd_option_waitforrsp, 0, ethaddr)); - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Reset all entries from the BT table - * @param priv A pointer to wlan_private structure - * @return 0 --success, otherwise fail - */ -static int wlan_bt_reset_ioctl(wlan_private * priv) -{ - lbs_deb_enter(LBS_DEB_IOCTL); - - lbs_pr_alert( "BT: resetting\n"); - - return (libertas_prepare_and_send_command(priv, - cmd_bt_access, - cmd_act_bt_access_reset, - cmd_option_waitforrsp, 0, NULL)); - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief List an entry from the BT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_bt_list_ioctl(wlan_private * priv, struct ifreq *req) -{ - int pos; - char *addr1; - struct iwreq *wrq = (struct iwreq *)req; - /* used to pass id and store the bt entry returned by the FW */ - union { - u32 id; - char addr1addr2[2 * ETH_ALEN]; - } param; - static char outstr[64]; - char *pbuf = outstr; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(outstr, wrq->u.data.pointer, sizeof(outstr))) { - lbs_deb_ioctl("Copy from user failed\n"); - return -1; - } - param.id = simple_strtoul(outstr, NULL, 10); - pos = sprintf(pbuf, "%d: ", param.id); - pbuf += pos; - - ret = libertas_prepare_and_send_command(priv, cmd_bt_access, - cmd_act_bt_access_list, - cmd_option_waitforrsp, 0, - (char *)¶m); - - if (ret == 0) { - addr1 = param.addr1addr2; - - pos = sprintf(pbuf, "BT includes node "); - pbuf += pos; - pos = eth_addr2str(addr1, pbuf); - pbuf += pos; - } else { - sprintf(pbuf, "(null)"); - pbuf += pos; - } - - wrq->u.data.length = strlen(outstr); - if (copy_to_user(wrq->u.data.pointer, (char *)outstr, - wrq->u.data.length)) { - lbs_deb_ioctl("BT_LIST: Copy to user failed!\n"); - return -EFAULT; - } - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0 ; -} - -/** - * @brief Sets inverted state of blacklist (non-zero if inverted) - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_bt_set_invert_ioctl(wlan_private * priv, struct ifreq *req) -{ - int ret; - struct iwreq *wrq = (struct iwreq *)req; - union { - u32 id; - char addr1addr2[2 * ETH_ALEN]; - } param; - - lbs_deb_enter(LBS_DEB_IOCTL); - - param.id = SUBCMD_DATA(wrq) ; - ret = libertas_prepare_and_send_command(priv, cmd_bt_access, - cmd_act_bt_access_set_invert, - cmd_option_waitforrsp, 0, - (char *)¶m); - if (ret != 0) - return -EFAULT; - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Gets inverted state of blacklist (non-zero if inverted) - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_bt_get_invert_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - int ret; - union { - u32 id; - char addr1addr2[2 * ETH_ALEN]; - } param; - - lbs_deb_enter(LBS_DEB_IOCTL); - - ret = libertas_prepare_and_send_command(priv, cmd_bt_access, - cmd_act_bt_access_get_invert, - cmd_option_waitforrsp, 0, - (char *)¶m); - - if (ret == 0) - wrq->u.param.value = le32_to_cpu(param.id); - else - return -EFAULT; - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Find the next parameter in an input string - * @param ptr A pointer to the input parameter string - * @return A pointer to the next parameter, or 0 if no parameters left. - */ -static char * next_param(char * ptr) -{ - if (!ptr) return NULL; - while (*ptr == ' ' || *ptr == '\t') ++ptr; - return (*ptr == '\0') ? NULL : ptr; -} - -/** - * @brief Add an entry to the FWT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char in_str[128]; - static struct cmd_ds_fwt_access fwt_access; - char *ptr; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) - return -EFAULT; - - if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) { - lbs_pr_alert( "FWT_ADD: Invalid MAC address 1\n"); - return -EINVAL; - } - - if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) { - lbs_pr_alert( "FWT_ADD: Invalid MAC address 2\n"); - return -EINVAL; - } - - if ((ptr = next_param(ptr))) - fwt_access.metric = - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - else - fwt_access.metric = cpu_to_le32(FWT_DEFAULT_METRIC); - - if ((ptr = next_param(ptr))) - fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10); - else - fwt_access.dir = FWT_DEFAULT_DIR; - - if ((ptr = next_param(ptr))) - fwt_access.rate = (u8) simple_strtoul(ptr, &ptr, 10); - else - fwt_access.rate = FWT_DEFAULT_RATE; - - if ((ptr = next_param(ptr))) - fwt_access.ssn = - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - else - fwt_access.ssn = cpu_to_le32(FWT_DEFAULT_SSN); - - if ((ptr = next_param(ptr))) - fwt_access.dsn = - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - else - fwt_access.dsn = cpu_to_le32(FWT_DEFAULT_DSN); - - if ((ptr = next_param(ptr))) - fwt_access.hopcount = simple_strtoul(ptr, &ptr, 10); - else - fwt_access.hopcount = FWT_DEFAULT_HOPCOUNT; - - if ((ptr = next_param(ptr))) - fwt_access.ttl = simple_strtoul(ptr, &ptr, 10); - else - fwt_access.ttl = FWT_DEFAULT_TTL; - - if ((ptr = next_param(ptr))) - fwt_access.expiration = - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - else - fwt_access.expiration = cpu_to_le32(FWT_DEFAULT_EXPIRATION); - - if ((ptr = next_param(ptr))) - fwt_access.sleepmode = (u8)simple_strtoul(ptr, &ptr, 10); - else - fwt_access.sleepmode = FWT_DEFAULT_SLEEPMODE; - - if ((ptr = next_param(ptr))) - fwt_access.snr = - cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - else - fwt_access.snr = cpu_to_le32(FWT_DEFAULT_SNR); - -#ifdef DEBUG - { - char ethaddr1_str[18], ethaddr2_str[18]; - eth_addr2str(fwt_access.da, ethaddr1_str); - eth_addr2str(fwt_access.ra, ethaddr2_str); - lbs_deb_ioctl("FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str, - fwt_access.dir, ethaddr2_str); - lbs_deb_ioctl("FWT_ADD: ssn:%u dsn:%u met:%u hop:%u ttl:%u exp:%u slp:%u snr:%u\n", - fwt_access.ssn, fwt_access.dsn, fwt_access.metric, - fwt_access.hopcount, fwt_access.ttl, fwt_access.expiration, - fwt_access.sleepmode, fwt_access.snr); - } -#endif - - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, - cmd_act_fwt_access_add, - cmd_option_waitforrsp, 0, - (void *)&fwt_access); - - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); - return ret; -} - -/** - * @brief Delete an entry from the FWT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_del_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char in_str[64]; - static struct cmd_ds_fwt_access fwt_access; - char *ptr; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) - return -EFAULT; - - if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) { - lbs_pr_alert( "FWT_DEL: Invalid MAC address 1\n"); - return -EINVAL; - } - - if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) { - lbs_pr_alert( "FWT_DEL: Invalid MAC address 2\n"); - return -EINVAL; - } - - if ((ptr = next_param(ptr))) - fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10); - else - fwt_access.dir = FWT_DEFAULT_DIR; - -#ifdef DEBUG - { - char ethaddr1_str[18], ethaddr2_str[18]; - lbs_deb_ioctl("FWT_DEL: line is %s\n", in_str); - eth_addr2str(fwt_access.da, ethaddr1_str); - eth_addr2str(fwt_access.ra, ethaddr2_str); - lbs_deb_ioctl("FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str, - ethaddr2_str, fwt_access.dir); - } -#endif - - ret = libertas_prepare_and_send_command(priv, - cmd_fwt_access, - cmd_act_fwt_access_del, - cmd_option_waitforrsp, 0, - (void *)&fwt_access); - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); - return ret; -} - - -/** - * @brief Print route parameters - * @param fwt_access struct cmd_ds_fwt_access with route info - * @param buf destination buffer for route info - */ -static void print_route(struct cmd_ds_fwt_access fwt_access, char *buf) -{ - buf += sprintf(buf, " "); - buf += eth_addr2str(fwt_access.da, buf); - buf += sprintf(buf, " "); - buf += eth_addr2str(fwt_access.ra, buf); - buf += sprintf(buf, " %u", fwt_access.valid); - buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.metric)); - buf += sprintf(buf, " %u", fwt_access.dir); - buf += sprintf(buf, " %u", fwt_access.rate); - buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.ssn)); - buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.dsn)); - buf += sprintf(buf, " %u", fwt_access.hopcount); - buf += sprintf(buf, " %u", fwt_access.ttl); - buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.expiration)); - buf += sprintf(buf, " %u", fwt_access.sleepmode); - buf += sprintf(buf, " %u ", le32_to_cpu(fwt_access.snr)); - buf += eth_addr2str(fwt_access.prec, buf); -} - -/** - * @brief Lookup an entry in the FWT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char in_str[64]; - char *ptr; - static struct cmd_ds_fwt_access fwt_access; - static char out_str[128]; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) - return -EFAULT; - - if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) { - lbs_pr_alert( "FWT_LOOKUP: Invalid MAC address\n"); - return -EINVAL; - } - -#ifdef DEBUG - { - char ethaddr1_str[18]; - lbs_deb_ioctl("FWT_LOOKUP: line is %s\n", in_str); - eth_addr2str(fwt_access.da, ethaddr1_str); - lbs_deb_ioctl("FWT_LOOKUP: looking for (da:%s)\n", ethaddr1_str); - } -#endif - - ret = libertas_prepare_and_send_command(priv, - cmd_fwt_access, - cmd_act_fwt_access_lookup, - cmd_option_waitforrsp, 0, - (void *)&fwt_access); - - if (ret == 0) - print_route(fwt_access, out_str); - else - sprintf(out_str, "(null)"); - - wrq->u.data.length = strlen(out_str); - if (copy_to_user(wrq->u.data.pointer, (char *)out_str, - wrq->u.data.length)) { - lbs_deb_ioctl("FWT_LOOKUP: Copy to user failed!\n"); - return -EFAULT; - } - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Reset all entries from the FWT table - * @param priv A pointer to wlan_private structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_reset_ioctl(wlan_private * priv) -{ - lbs_deb_ioctl("FWT: resetting\n"); - - return (libertas_prepare_and_send_command(priv, - cmd_fwt_access, - cmd_act_fwt_access_reset, - cmd_option_waitforrsp, 0, NULL)); -} - -/** - * @brief List an entry from the FWT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_list_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char in_str[8]; - static struct cmd_ds_fwt_access fwt_access; - char *ptr = in_str; - static char out_str[128]; - char *pbuf = out_str; - int ret = 0; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) { - ret = -EFAULT; - goto out; - } - - fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - -#ifdef DEBUG - { - lbs_deb_ioctl("FWT_LIST: line is %s\n", in_str); - lbs_deb_ioctl("FWT_LIST: listing id:%i\n", le32_to_cpu(fwt_access.id)); - } -#endif - - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, - cmd_act_fwt_access_list, - cmd_option_waitforrsp, 0, (void *)&fwt_access); - - if (ret == 0) - print_route(fwt_access, pbuf); - else - pbuf += sprintf(pbuf, " (null)"); - - wrq->u.data.length = strlen(out_str); - if (copy_to_user(wrq->u.data.pointer, (char *)out_str, - wrq->u.data.length)) { - lbs_deb_ioctl("FWT_LIST: Copy to user failed!\n"); - ret = -EFAULT; - goto out; - } - - ret = 0; - -out: - lbs_deb_leave(LBS_DEB_IOCTL); - return ret; -} - -/** - * @brief List an entry from the FRT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_list_route_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char in_str[64]; - static struct cmd_ds_fwt_access fwt_access; - char *ptr = in_str; - static char out_str[128]; - char *pbuf = out_str; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) - return -EFAULT; - - fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - -#ifdef DEBUG - { - lbs_deb_ioctl("FWT_LIST_ROUTE: line is %s\n", in_str); - lbs_deb_ioctl("FWT_LIST_ROUTE: listing id:%i\n", le32_to_cpu(fwt_access.id)); - } -#endif - - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, - cmd_act_fwt_access_list_route, - cmd_option_waitforrsp, 0, (void *)&fwt_access); - - if (ret == 0) { - print_route(fwt_access, pbuf); - } else - pbuf += sprintf(pbuf, " (null)"); - - wrq->u.data.length = strlen(out_str); - if (copy_to_user(wrq->u.data.pointer, (char *)out_str, - wrq->u.data.length)) { - lbs_deb_ioctl("FWT_LIST_ROUTE: Copy to user failed!\n"); - return -EFAULT; - } - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief List an entry from the FNT table - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - char in_str[8]; - static struct cmd_ds_fwt_access fwt_access; - char *ptr = in_str; - static char out_str[128]; - char *pbuf = out_str; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) - return -EFAULT; - - memset(&fwt_access, 0, sizeof(fwt_access)); - fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); - -#ifdef DEBUG - { - lbs_deb_ioctl("FWT_LIST_NEIGHBOR: line is %s\n", in_str); - lbs_deb_ioctl("FWT_LIST_NEIGHBOR: listing id:%i\n", le32_to_cpu(fwt_access.id)); - } -#endif - - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, - cmd_act_fwt_access_list_neighbor, - cmd_option_waitforrsp, 0, - (void *)&fwt_access); - - if (ret == 0) { - pbuf += sprintf(pbuf, " ra "); - pbuf += eth_addr2str(fwt_access.ra, pbuf); - pbuf += sprintf(pbuf, " slp %u", fwt_access.sleepmode); - pbuf += sprintf(pbuf, " snr %u", le32_to_cpu(fwt_access.snr)); - pbuf += sprintf(pbuf, " ref %u", le32_to_cpu(fwt_access.references)); - } else - pbuf += sprintf(pbuf, " (null)"); - - wrq->u.data.length = strlen(out_str); - if (copy_to_user(wrq->u.data.pointer, (char *)out_str, - wrq->u.data.length)) { - lbs_deb_ioctl("FWT_LIST_NEIGHBOR: Copy to user failed!\n"); - return -EFAULT; - } - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Cleans up the route (FRT) and neighbor (FNT) tables - * (Garbage Collection) - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - static struct cmd_ds_fwt_access fwt_access; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - lbs_deb_ioctl("FWT: cleaning up\n"); - - memset(&fwt_access, 0, sizeof(fwt_access)); - - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, - cmd_act_fwt_access_cleanup, - cmd_option_waitforrsp, 0, - (void *)&fwt_access); - - if (ret == 0) - wrq->u.param.value = le32_to_cpu(fwt_access.references); - else - return -EFAULT; - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Gets firmware internal time (debug purposes) - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - static struct cmd_ds_fwt_access fwt_access; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - lbs_deb_ioctl("FWT: getting time\n"); - - memset(&fwt_access, 0, sizeof(fwt_access)); - - ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, - cmd_act_fwt_access_time, - cmd_option_waitforrsp, 0, - (void *)&fwt_access); - - if (ret == 0) - wrq->u.param.value = le32_to_cpu(fwt_access.references); - else - return -EFAULT; - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Gets mesh ttl from firmware - * @param priv A pointer to wlan_private structure - * @param req A pointer to ifreq structure - * @return 0 --success, otherwise fail - */ -static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req) -{ - struct iwreq *wrq = (struct iwreq *)req; - struct cmd_ds_mesh_access mesh_access; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - memset(&mesh_access, 0, sizeof(mesh_access)); - - ret = libertas_prepare_and_send_command(priv, cmd_mesh_access, - cmd_act_mesh_get_ttl, - cmd_option_waitforrsp, 0, - (void *)&mesh_access); - - if (ret == 0) - wrq->u.param.value = le32_to_cpu(mesh_access.data[0]); - else - return -EFAULT; - - lbs_deb_leave(LBS_DEB_IOCTL); - return 0; -} - -/** - * @brief Gets mesh ttl from firmware - * @param priv A pointer to wlan_private structure - * @param ttl New ttl value - * @return 0 --success, otherwise fail - */ -static int wlan_mesh_set_ttl_ioctl(wlan_private * priv, int ttl) -{ - struct cmd_ds_mesh_access mesh_access; - int ret; - - lbs_deb_enter(LBS_DEB_IOCTL); - - if( (ttl > 0xff) || (ttl < 0) ) - return -EINVAL; - - memset(&mesh_access, 0, sizeof(mesh_access)); - mesh_access.data[0] = cpu_to_le32(ttl); - - ret = libertas_prepare_and_send_command(priv, cmd_mesh_access, - cmd_act_mesh_set_ttl, - cmd_option_waitforrsp, 0, - (void *)&mesh_access); - - if (ret != 0) - ret = -EFAULT; - - lbs_deb_leave(LBS_DEB_IOCTL); - return ret; -} - -/** - * @brief ioctl function - entry point - * - * @param dev A pointer to net_device structure - * @param req A pointer to ifreq structure - * @param cmd command - * @return 0--success, otherwise fail - */ -int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) -{ - int subcmd = 0; - int idata = 0; - int *pdata; - int ret = 0; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; - struct iwreq *wrq = (struct iwreq *)req; - - lbs_deb_enter(LBS_DEB_IOCTL); - - lbs_deb_ioctl("libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd); - switch (cmd) { - case WLAN_SETNONE_GETNONE: /* set WPA mode on/off ioctl #20 */ - switch (wrq->u.data.flags) { - case WLAN_SUBCMD_BT_RESET: /* bt_reset */ - wlan_bt_reset_ioctl(priv); - break; - case WLAN_SUBCMD_FWT_RESET: /* fwt_reset */ - wlan_fwt_reset_ioctl(priv); - break; - } /* End of switch */ - break; - - case WLAN_SETONEINT_GETNONE: - /* The first 4 bytes of req->ifr_data is sub-ioctl number - * after 4 bytes sits the payload. - */ - subcmd = wrq->u.data.flags; - if (!subcmd) - subcmd = (int)wrq->u.param.value; - - switch (subcmd) { - case WLANSETREGION: - idata = SUBCMD_DATA(wrq); - ret = wlan_set_region(priv, (u16) idata); - break; - case WLAN_SUBCMD_MESH_SET_TTL: - idata = SUBCMD_DATA(wrq); - ret = wlan_mesh_set_ttl_ioctl(priv, idata); - break; - - case WLAN_SUBCMD_BT_SET_INVERT: - ret = wlan_bt_set_invert_ioctl(priv, req); - break ; - - default: - ret = -EOPNOTSUPP; - break; - } - - break; - - case WLAN_SET128CHAR_GET128CHAR: - switch ((int)wrq->u.data.flags) { - case WLAN_SUBCMD_BT_ADD: - ret = wlan_bt_add_ioctl(priv, req); - break; - case WLAN_SUBCMD_BT_DEL: - ret = wlan_bt_del_ioctl(priv, req); - break; - case WLAN_SUBCMD_BT_LIST: - ret = wlan_bt_list_ioctl(priv, req); - break; - case WLAN_SUBCMD_FWT_ADD: - ret = wlan_fwt_add_ioctl(priv, req); - break; - case WLAN_SUBCMD_FWT_DEL: - ret = wlan_fwt_del_ioctl(priv, req); - break; - case WLAN_SUBCMD_FWT_LOOKUP: - ret = wlan_fwt_lookup_ioctl(priv, req); - break; - case WLAN_SUBCMD_FWT_LIST_NEIGHBOR: - ret = wlan_fwt_list_neighbor_ioctl(priv, req); - break; - case WLAN_SUBCMD_FWT_LIST: - ret = wlan_fwt_list_ioctl(priv, req); - break; - case WLAN_SUBCMD_FWT_LIST_ROUTE: - ret = wlan_fwt_list_route_ioctl(priv, req); - break; - } - break; - - case WLAN_SETNONE_GETONEINT: - switch (wrq->u.param.value) { - case WLANGETREGION: - pdata = (int *)wrq->u.name; - *pdata = (int)adapter->regioncode; - break; - case WLAN_SUBCMD_FWT_CLEANUP: /* fwt_cleanup */ - ret = wlan_fwt_cleanup_ioctl(priv, req); - break; - - case WLAN_SUBCMD_FWT_TIME: /* fwt_time */ - ret = wlan_fwt_time_ioctl(priv, req); - break; - - case WLAN_SUBCMD_MESH_GET_TTL: - ret = wlan_mesh_get_ttl_ioctl(priv, req); - break; - - case WLAN_SUBCMD_BT_GET_INVERT: - ret = wlan_bt_get_invert_ioctl(priv, req); - break ; - - default: - ret = -EOPNOTSUPP; - - } - - break; - - case WLAN_SET_GET_SIXTEEN_INT: - switch ((int)wrq->u.data.flags) { - case WLAN_LED_GPIO_CTRL: - { - int i; - int data[16]; - - struct cmd_ds_802_11_led_ctrl ctrl; - struct mrvlietypes_ledgpio *gpio = - (struct mrvlietypes_ledgpio *) ctrl.data; - - memset(&ctrl, 0, sizeof(ctrl)); - if (wrq->u.data.length > MAX_LEDS * 2) - return -ENOTSUPP; - if ((wrq->u.data.length % 2) != 0) - return -ENOTSUPP; - if (wrq->u.data.length == 0) { - ctrl.action = - cpu_to_le16 - (cmd_act_get); - } else { - if (copy_from_user - (data, wrq->u.data.pointer, - sizeof(int) * - wrq->u.data.length)) { - lbs_deb_ioctl( - "Copy from user failed\n"); - return -EFAULT; - } - - ctrl.action = - cpu_to_le16 - (cmd_act_set); - ctrl.numled = cpu_to_le16(0); - gpio->header.type = - cpu_to_le16(TLV_TYPE_LED_GPIO); - gpio->header.len = wrq->u.data.length; - for (i = 0; i < wrq->u.data.length; - i += 2) { - gpio->ledpin[i / 2].led = - data[i]; - gpio->ledpin[i / 2].pin = - data[i + 1]; - } - } - ret = - libertas_prepare_and_send_command(priv, - cmd_802_11_led_gpio_ctrl, - 0, - cmd_option_waitforrsp, - 0, (void *)&ctrl); - for (i = 0; i < gpio->header.len; i += 2) { - data[i] = gpio->ledpin[i / 2].led; - data[i + 1] = gpio->ledpin[i / 2].pin; - } - if (copy_to_user(wrq->u.data.pointer, data, - sizeof(int) * - gpio->header.len)) { - lbs_deb_ioctl("Copy to user failed\n"); - return -EFAULT; - } - - wrq->u.data.length = gpio->header.len; - } - break; - } - break; - - default: - ret = -EINVAL; - break; - } - - lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); - return ret; -} - - diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index cf2d71943865..4a59306a3f05 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -801,7 +801,6 @@ wlan_private *libertas_add_card(void *card, struct device *dmdev) dev->open = wlan_open; dev->hard_start_xmit = wlan_pre_start_xmit; dev->stop = wlan_close; - dev->do_ioctl = libertas_do_ioctl; dev->set_mac_address = wlan_set_mac_address; dev->tx_timeout = wlan_tx_timeout; dev->get_stats = wlan_get_stats; @@ -920,7 +919,6 @@ int libertas_add_mesh(wlan_private *priv, struct device *dev) mesh_dev->open = mesh_open; mesh_dev->hard_start_xmit = mesh_pre_start_xmit; mesh_dev->stop = mesh_close; - mesh_dev->do_ioctl = libertas_do_ioctl; mesh_dev->get_stats = wlan_get_stats; mesh_dev->set_mac_address = wlan_set_mac_address; mesh_dev->ethtool_ops = &libertas_ethtool_ops; diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index 8939251a2f4c..f42b796b5e47 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -913,148 +913,6 @@ out: return 0; } -/* - * iwpriv settable callbacks - */ - -static const iw_handler wlan_private_handler[] = { - NULL, /* SIOCIWFIRSTPRIV */ -}; - -static const struct iw_priv_args wlan_private_args[] = { - /* - * { cmd, set_args, get_args, name } - */ - /* Using iwpriv sub-command feature */ - { - WLAN_SETONEINT_GETNONE, /* IOCTL: 24 */ - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - ""}, - { - WLANSETREGION, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "setregioncode"}, - { - WLAN_SUBCMD_MESH_SET_TTL, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "mesh_set_ttl"}, - { - WLAN_SETNONE_GETONEINT, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - ""}, - { - WLANGETREGION, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "getregioncode"}, - { - WLAN_SUBCMD_FWT_CLEANUP, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "fwt_cleanup"}, - { - WLAN_SUBCMD_FWT_TIME, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "fwt_time"}, - { - WLAN_SUBCMD_MESH_GET_TTL, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "mesh_get_ttl"}, - { - WLAN_SETNONE_GETNONE, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_NONE, - ""}, - { - WLAN_SUBCMD_FWT_RESET, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_NONE, - "fwt_reset"}, - { - WLAN_SUBCMD_BT_RESET, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_NONE, - "bt_reset"}, - { - WLAN_SET128CHAR_GET128CHAR, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - ""}, - /* BT Management */ - { - WLAN_SUBCMD_BT_ADD, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "bt_add"}, - { - WLAN_SUBCMD_BT_DEL, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "bt_del"}, - { - WLAN_SUBCMD_BT_LIST, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "bt_list"}, - { - WLAN_SUBCMD_BT_SET_INVERT, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_NONE, - "bt_set_invert"}, - { - WLAN_SUBCMD_BT_GET_INVERT, - IW_PRIV_TYPE_NONE, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - "bt_get_invert"}, - /* FWT Management */ - { - WLAN_SUBCMD_FWT_ADD, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "fwt_add"}, - { - WLAN_SUBCMD_FWT_DEL, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "fwt_del"}, - { - WLAN_SUBCMD_FWT_LOOKUP, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "fwt_lookup"}, - { - WLAN_SUBCMD_FWT_LIST_NEIGHBOR, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "fwt_list_neigh"}, - { - WLAN_SUBCMD_FWT_LIST, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "fwt_list"}, - { - WLAN_SUBCMD_FWT_LIST_ROUTE, - IW_PRIV_TYPE_CHAR | 128, - IW_PRIV_TYPE_CHAR | 128, - "fwt_list_route"}, - { - WLAN_SET_GET_SIXTEEN_INT, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - ""}, - { - WLAN_LED_GPIO_CTRL, - IW_PRIV_TYPE_INT | 16, - IW_PRIV_TYPE_INT | 16, - "ledgpio"}, -}; - static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) { enum { @@ -2444,22 +2302,12 @@ static const iw_handler mesh_wlan_handler[] = { }; struct iw_handler_def libertas_handler_def = { .num_standard = sizeof(wlan_handler) / sizeof(iw_handler), - .num_private = sizeof(wlan_private_handler) / sizeof(iw_handler), - .num_private_args = sizeof(wlan_private_args) / - sizeof(struct iw_priv_args), .standard = (iw_handler *) wlan_handler, - .private = (iw_handler *) wlan_private_handler, - .private_args = (struct iw_priv_args *)wlan_private_args, .get_wireless_stats = wlan_get_wireless_stats, }; struct iw_handler_def mesh_handler_def = { .num_standard = sizeof(mesh_wlan_handler) / sizeof(iw_handler), - .num_private = sizeof(wlan_private_handler) / sizeof(iw_handler), - .num_private_args = sizeof(wlan_private_args) / - sizeof(struct iw_priv_args), .standard = (iw_handler *) mesh_wlan_handler, - .private = (iw_handler *) wlan_private_handler, - .private_args = (struct iw_priv_args *)wlan_private_args, .get_wireless_stats = wlan_get_wireless_stats, }; diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h index d555056b25b7..3d5196c9553a 100644 --- a/drivers/net/wireless/libertas/wext.h +++ b/drivers/net/wireless/libertas/wext.h @@ -7,45 +7,6 @@ #define SUBCMD_OFFSET 4 #define SUBCMD_DATA(x) *((int *)(x->u.name + SUBCMD_OFFSET)) -/** PRIVATE CMD ID */ -#define WLANIOCTL SIOCIWFIRSTPRIV - -#define WLAN_SETNONE_GETNONE (WLANIOCTL + 8) -#define WLAN_SUBCMD_BT_RESET 13 -#define WLAN_SUBCMD_FWT_RESET 14 - -#define WLAN_SETNONE_GETONEINT (WLANIOCTL + 15) -#define WLANGETREGION 1 - -#define WLAN_SUBCMD_FWT_CLEANUP 15 -#define WLAN_SUBCMD_FWT_TIME 16 -#define WLAN_SUBCMD_MESH_GET_TTL 17 -#define WLAN_SUBCMD_BT_GET_INVERT 18 - -#define WLAN_SETONEINT_GETNONE (WLANIOCTL + 24) -#define WLANSETREGION 8 -#define WLAN_SUBCMD_MESH_SET_TTL 18 -#define WLAN_SUBCMD_BT_SET_INVERT 19 - -#define WLAN_SET128CHAR_GET128CHAR (WLANIOCTL + 25) -#define WLAN_SUBCMD_BT_ADD 18 -#define WLAN_SUBCMD_BT_DEL 19 -#define WLAN_SUBCMD_BT_LIST 20 -#define WLAN_SUBCMD_FWT_ADD 21 -#define WLAN_SUBCMD_FWT_DEL 22 -#define WLAN_SUBCMD_FWT_LOOKUP 23 -#define WLAN_SUBCMD_FWT_LIST_NEIGHBOR 24 -#define WLAN_SUBCMD_FWT_LIST 25 -#define WLAN_SUBCMD_FWT_LIST_ROUTE 26 - -#define WLAN_SET_GET_SIXTEEN_INT (WLANIOCTL + 29) -#define WLAN_LED_GPIO_CTRL 5 - -#define WLAN_LINKMODE_802_3 0 -#define WLAN_LINKMODE_802_11 2 -#define WLAN_RADIOMODE_NONE 0 -#define WLAN_RADIOMODE_RADIOTAP 2 - /** wlan_ioctl_regrdwr */ struct wlan_ioctl_regrdwr { /** Which register to access */ @@ -57,9 +18,13 @@ struct wlan_ioctl_regrdwr { u32 value; }; +#define WLAN_LINKMODE_802_3 0 +#define WLAN_LINKMODE_802_11 2 +#define WLAN_RADIOMODE_NONE 0 +#define WLAN_RADIOMODE_RADIOTAP 2 + extern struct iw_handler_def libertas_handler_def; extern struct iw_handler_def mesh_handler_def; -int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int i); int wlan_radio_ioctl(wlan_private * priv, u8 option); #endif /* _WLAN_WEXT_H_ */ -- cgit v1.2.3 From 5f708dd91d15876e26d7a57f97a255cedffca463 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 28 Jun 2007 13:26:06 -0500 Subject: phy: Fix phy_id for Vitesse 824x PHY The phy_id specified for the Vitesse 824x PHY would never match because it was expecting bits to be set that would be masked by the phy_id_mask. Fix the phy_id so it will match properly, and changed the mdio_bus_match to mask both the driver and devices phy_id with the mask so we dont have this issue in the future. Signed-off-by: Kumar Gala --- drivers/net/phy/mdio_bus.c | 3 ++- drivers/net/phy/vitesse.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index fc4aee96cdfd..fc2f0e695a13 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -131,7 +131,8 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv) struct phy_device *phydev = to_phy_device(dev); struct phy_driver *phydrv = to_phy_driver(drv); - return (phydrv->phy_id == (phydev->phy_id & phydrv->phy_id_mask)); + return ((phydrv->phy_id & phydrv->phy_id_mask) == + (phydev->phy_id & phydrv->phy_id_mask)); } /* Suspend and resume. Copied from platform_suspend and diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index 792716beb052..596222b260d6 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -84,7 +84,7 @@ static int vsc824x_config_intr(struct phy_device *phydev) /* Vitesse 824x */ static struct phy_driver vsc8244_driver = { - .phy_id = 0x000fc6c2, + .phy_id = 0x000fc6c0, .name = "Vitesse VSC8244", .phy_id_mask = 0x000fffc0, .features = PHY_GBIT_FEATURES, -- cgit v1.2.3 From 240e2df5c740d73fc08cac9989872212deb2d20e Mon Sep 17 00:00:00 2001 From: Michael Halcrow Date: Wed, 27 Jun 2007 14:09:44 -0700 Subject: eCryptfs: fix write zeros behavior This patch fixes the processes involved in wiping regions of the data during truncate and write events, fixing a kernel hang in 2.6.22-rc4 while assuring that zero values are written out to the appropriate locations during events in which the i_size will change. The range passed to ecryptfs_truncate() from ecryptfs_prepare_write() includes the page that is the object of ecryptfs_prepare_write(). This leads to a kernel hang as read_cache_page() is executed on the same page in the ecryptfs_truncate() execution path. This patch remedies this by limiting the range passed to ecryptfs_truncate() so as to exclude the page that is the object of ecryptfs_prepare_write(); it also adds code to ecryptfs_prepare_write() to zero out the region of its own page when writing past the i_size position. This patch also modifies ecryptfs_truncate() so that when a file is truncated to a smaller size, eCryptfs will zero out the contents of the new last page from the new size through to the end of the last page. Signed-off-by: Michael Halcrow Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ecryptfs/ecryptfs_kernel.h | 2 ++ fs/ecryptfs/inode.c | 19 ++++++++++++++++ fs/ecryptfs/mmap.c | 53 +++++++++++++++++++++++-------------------- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 403e3bad1455..1b9dd9a96f19 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -580,5 +580,7 @@ void ecryptfs_write_header_metadata(char *virt, struct ecryptfs_crypt_stat *crypt_stat, size_t *written); +int ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, + int num_zeros); #endif /* #ifndef ECRYPTFS_KERNEL_H */ diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 1548be26b5e6..0981ae35ea16 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -800,6 +800,25 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) goto out_fput; } } else { /* new_length < i_size_read(inode) */ + pgoff_t index = 0; + int end_pos_in_page = -1; + + if (new_length != 0) { + index = ((new_length - 1) >> PAGE_CACHE_SHIFT); + end_pos_in_page = ((new_length - 1) & ~PAGE_CACHE_MASK); + } + if (end_pos_in_page != (PAGE_CACHE_SIZE - 1)) { + if ((rc = ecryptfs_write_zeros(&fake_ecryptfs_file, + index, + (end_pos_in_page + 1), + ((PAGE_CACHE_SIZE - 1) + - end_pos_in_page)))) { + printk(KERN_ERR "Error attempting to zero out " + "the remainder of the end page on " + "reducing truncate; rc = [%d]\n", rc); + goto out_fput; + } + } vmtruncate(inode, new_length); rc = ecryptfs_write_inode_size_to_metadata( lower_file, lower_dentry->d_inode, inode, dentry, diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 55cec98a84e7..6df410c77264 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -56,9 +56,6 @@ static struct page *ecryptfs_get1page(struct file *file, int index) return read_mapping_page(mapping, index, (void *)file); } -static -int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros); - /** * ecryptfs_fill_zeros * @file: The ecryptfs file @@ -101,10 +98,13 @@ int ecryptfs_fill_zeros(struct file *file, loff_t new_length) if (old_end_page_index == new_end_page_index) { /* Start and end are in the same page; we just need to * set a portion of the existing page to zero's */ - rc = write_zeros(file, index, (old_end_pos_in_page + 1), - (new_end_pos_in_page - old_end_pos_in_page)); + rc = ecryptfs_write_zeros(file, index, + (old_end_pos_in_page + 1), + (new_end_pos_in_page + - old_end_pos_in_page)); if (rc) - ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], " + ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(" + "file=[%p], " "index=[0x%.16x], " "old_end_pos_in_page=[d], " "(PAGE_CACHE_SIZE - new_end_pos_in_page" @@ -117,10 +117,10 @@ int ecryptfs_fill_zeros(struct file *file, loff_t new_length) goto out; } /* Fill the remainder of the previous last page with zeros */ - rc = write_zeros(file, index, (old_end_pos_in_page + 1), + rc = ecryptfs_write_zeros(file, index, (old_end_pos_in_page + 1), ((PAGE_CACHE_SIZE - 1) - old_end_pos_in_page)); if (rc) { - ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], " + ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(file=[%p], " "index=[0x%.16x], old_end_pos_in_page=[d], " "(PAGE_CACHE_SIZE - old_end_pos_in_page)=[d]) " "returned [%d]\n", file, index, @@ -131,9 +131,10 @@ int ecryptfs_fill_zeros(struct file *file, loff_t new_length) index++; while (index < new_end_page_index) { /* Fill all intermediate pages with zeros */ - rc = write_zeros(file, index, 0, PAGE_CACHE_SIZE); + rc = ecryptfs_write_zeros(file, index, 0, PAGE_CACHE_SIZE); if (rc) { - ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], " + ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(" + "file=[%p], " "index=[0x%.16x], " "old_end_pos_in_page=[d], " "(PAGE_CACHE_SIZE - new_end_pos_in_page" @@ -149,9 +150,9 @@ int ecryptfs_fill_zeros(struct file *file, loff_t new_length) } /* Fill the portion at the beginning of the last new page with * zero's */ - rc = write_zeros(file, index, 0, (new_end_pos_in_page + 1)); + rc = ecryptfs_write_zeros(file, index, 0, (new_end_pos_in_page + 1)); if (rc) { - ecryptfs_printk(KERN_ERR, "write_zeros(file=" + ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(file=" "[%p], index=[0x%.16x], 0, " "new_end_pos_in_page=[%d]" "returned [%d]\n", file, index, @@ -400,7 +401,6 @@ out: static int ecryptfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { - loff_t pos; int rc = 0; if (from == 0 && to == PAGE_CACHE_SIZE) @@ -408,14 +408,19 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, up to date. */ if (!PageUptodate(page)) rc = ecryptfs_do_readpage(file, page, page->index); - pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; - if (pos > i_size_read(page->mapping->host)) { - rc = ecryptfs_truncate(file->f_path.dentry, pos); - if (rc) { - printk(KERN_ERR "Error on attempt to " - "truncate to (higher) offset [%lld];" - " rc = [%d]\n", pos, rc); - goto out; + if (page->index != 0) { + loff_t end_of_prev_pg_pos = + (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1); + + if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) { + rc = ecryptfs_truncate(file->f_path.dentry, + end_of_prev_pg_pos); + if (rc) { + printk(KERN_ERR "Error on attempt to " + "truncate to (higher) offset [%lld];" + " rc = [%d]\n", end_of_prev_pg_pos, rc); + goto out; + } } } out: @@ -753,7 +758,7 @@ out: } /** - * write_zeros + * ecryptfs_write_zeros * @file: The ecryptfs file * @index: The index in which we are writing * @start: The position after the last block of data @@ -763,8 +768,8 @@ out: * * (start + num_zeros) must be less than or equal to PAGE_CACHE_SIZE */ -static -int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) +int +ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) { int rc = 0; struct page *tmp_page; -- cgit v1.2.3 From e10f281bca03f45bdec91e67645c394eaec2f8f6 Mon Sep 17 00:00:00 2001 From: Michael Halcrow Date: Wed, 27 Jun 2007 14:09:44 -0700 Subject: eCryptfs: initialize crypt_stat in setattr Recent changes in eCryptfs have made it possible to get to ecryptfs_setattr() with an uninitialized crypt_stat struct. This results in a wide and colorful variety of unpleasantries. This patch properly initializes the crypt_stat structure in ecryptfs_setattr() when it is necessary to do so. Signed-off-by: Michael Halcrow Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ecryptfs/inode.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 0981ae35ea16..83e94fedd4e9 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -894,9 +894,54 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) struct ecryptfs_crypt_stat *crypt_stat; crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; - lower_dentry = ecryptfs_dentry_to_lower(dentry); + if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)) + ecryptfs_init_crypt_stat(crypt_stat); inode = dentry->d_inode; lower_inode = ecryptfs_inode_to_lower(inode); + lower_dentry = ecryptfs_dentry_to_lower(dentry); + mutex_lock(&crypt_stat->cs_mutex); + if (S_ISDIR(dentry->d_inode->i_mode)) + crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); + else if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) + || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { + struct vfsmount *lower_mnt; + struct file *lower_file = NULL; + struct ecryptfs_mount_crypt_stat *mount_crypt_stat; + int lower_flags; + + lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); + lower_flags = O_RDONLY; + if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, + lower_mnt, lower_flags))) { + printk(KERN_ERR + "Error opening lower file; rc = [%d]\n", rc); + mutex_unlock(&crypt_stat->cs_mutex); + goto out; + } + mount_crypt_stat = &ecryptfs_superblock_to_private( + dentry->d_sb)->mount_crypt_stat; + if ((rc = ecryptfs_read_metadata(dentry, lower_file))) { + if (!(mount_crypt_stat->flags + & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { + rc = -EIO; + printk(KERN_WARNING "Attempt to read file that " + "is not in a valid eCryptfs format, " + "and plaintext passthrough mode is not " + "enabled; returning -EIO\n"); + + mutex_unlock(&crypt_stat->cs_mutex); + fput(lower_file); + goto out; + } + rc = 0; + crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); + mutex_unlock(&crypt_stat->cs_mutex); + fput(lower_file); + goto out; + } + fput(lower_file); + } + mutex_unlock(&crypt_stat->cs_mutex); if (ia->ia_valid & ATTR_SIZE) { ecryptfs_printk(KERN_DEBUG, "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n", -- cgit v1.2.3 From d4c5cdb3e099da7cc64df622b02ff7659babe16e Mon Sep 17 00:00:00 2001 From: Michael Halcrow Date: Wed, 27 Jun 2007 14:09:45 -0700 Subject: zero out last page for llseek/write When one llseek's past the end of the file and then writes, every page past the previous end of the file should be cleared. Trevor found that the code, as is, does not assure that the very last page is always cleared. This patch takes care of that. Signed-off-by: Michael Halcrow Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ecryptfs/mmap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 6df410c77264..7d5a43cb0d5c 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c @@ -422,6 +422,8 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, goto out; } } + if (end_of_prev_pg_pos + 1 > i_size_read(page->mapping->host)) + zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); } out: return rc; -- cgit v1.2.3 From c0887eedb4498e20e7895508b7af8e419e397405 Mon Sep 17 00:00:00 2001 From: Ville Syrjala Date: Wed, 27 Jun 2007 14:09:46 -0700 Subject: atyfb: Fix XCLK frequency on Apple iBook1 Fix a regression on Apple iBook1. Changes in the clock init code caused an incorrect XCLK frequency to be used leading to a corrupted display. Signed-off-by: Ville Syrjala Cc: Olaf Hering Cc: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/aty/atyfb_base.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 8d3455da663a..2fbff6317433 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -2290,15 +2290,6 @@ static int __devinit aty_init(struct fb_info *info) init_waitqueue_head(&par->vblank.wait); spin_lock_init(&par->int_lock); -#ifdef CONFIG_PPC_PMAC - /* The Apple iBook1 uses non-standard memory frequencies. We detect it - * and set the frequency manually. */ - if (machine_is_compatible("PowerBook2,1")) { - par->pll_limits.mclk = 70; - par->pll_limits.xclk = 53; - } -#endif - #ifdef CONFIG_FB_ATY_GX if (!M64_HAS(INTEGRATED)) { u32 stat0; @@ -2383,6 +2374,14 @@ static int __devinit aty_init(struct fb_info *info) par->pll_limits.xclk = (par->pll_limits.xclk + 1) >> 1; } #endif +#ifdef CONFIG_PPC_PMAC + /* The Apple iBook1 uses non-standard memory frequencies. We detect it + * and set the frequency manually. */ + if (machine_is_compatible("PowerBook2,1")) { + par->pll_limits.mclk = 70; + par->pll_limits.xclk = 53; + } +#endif /* Allow command line to override clocks. */ if (pll) -- cgit v1.2.3 From d2fd89962cd5de6b1fb9c1c789b56bc16f58f121 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 27 Jun 2007 14:09:48 -0700 Subject: eventfd: clean compile when CONFIG_EVENTFD=n Fix gcc warning and add parameter checking when CONFIG_EVENTFD=n: fs/aio.c: In function 'aio_complete': fs/aio.c:955: warning: statement with no effect Signed-off-by: Randy Dunlap Cc: Davide Libenzi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/eventfd.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h index 0d6ecc60b94d..b489fc6d0b62 100644 --- a/include/linux/eventfd.h +++ b/include/linux/eventfd.h @@ -19,7 +19,8 @@ int eventfd_signal(struct file *file, int n); #else /* CONFIG_EVENTFD */ #define eventfd_fget(fd) ERR_PTR(-ENOSYS) -#define eventfd_signal(f, n) 0 +static inline int eventfd_signal(struct file *file, int n) +{ return 0; } #endif /* CONFIG_EVENTFD */ -- cgit v1.2.3 From 80581c43d02f66afb2cafa44bef710a2549a1748 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 27 Jun 2007 14:09:49 -0700 Subject: mtrr/cyrix: fix sections main.c::mtrr_add() or mtrr_del() [exported] calls main.c::mtrr_add_page() or mtrr_del_page() or mtrr_restore() [resume] calls main.c::set_mtrr() calls main.c::ipi_handler() calls main.c::mtrr_if->set_all() == which can be cyrix_set_all WARNING: arch/i386/kernel/built-in.o(.text+0x8657): Section mismatch: reference to .init.data: (between 'cyrix_set_all' and 'centaur_get_free_region') WARNING: arch/i386/kernel/built-in.o(.text+0x866b): Section mismatch: reference to .init.data: (between 'cyrix_set_all' and 'centaur_get_free_region') WARNING: arch/i386/kernel/built-in.o(.text+0x867e): Section mismatch: reference to .init.data: (between 'cyrix_set_all' and 'centaur_get_free_region') WARNING: arch/i386/kernel/built-in.o(.text+0x8684): Section mismatch: reference to .init.data: (between 'cyrix_set_all' and 'centaur_get_free_region') WARNING: arch/i386/kernel/built-in.o(.text+0x868a): Section mismatch: reference to .init.data: (between 'cyrix_set_all' and 'centaur_get_free_region') Signed-off-by: Randy Dunlap Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/mtrr/cyrix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/i386/kernel/cpu/mtrr/cyrix.c b/arch/i386/kernel/cpu/mtrr/cyrix.c index 9edf5625584f..1001f1e0fe6d 100644 --- a/arch/i386/kernel/cpu/mtrr/cyrix.c +++ b/arch/i386/kernel/cpu/mtrr/cyrix.c @@ -233,12 +233,12 @@ typedef struct { mtrr_type type; } arr_state_t; -static arr_state_t arr_state[8] __devinitdata = { +static arr_state_t arr_state[8] = { {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL} }; -static unsigned char ccr_state[7] __devinitdata = { 0, 0, 0, 0, 0, 0, 0 }; +static unsigned char ccr_state[7] = { 0, 0, 0, 0, 0, 0, 0 }; static void cyrix_set_all(void) { -- cgit v1.2.3 From 7c31d2f59c14191c3251f18ad1782fe6692f0c33 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 27 Jun 2007 14:09:50 -0700 Subject: smsc-ircc2: skip preconfiguration for PNP devices If we rely on the device resources from PNPBIOS, we also have to rely on the BIOS to configure any bridges on the way to the device. Using the PNPBIOS resources but changing the configuration of a bridge behind the back of the firmware is likely to make things inconsistent. This patch addresses part of the 2.6.22 regression: "no irda0 interface (2.6.21 was OK), smsc does not find chip" It fixes smsc-ircc2 PNP device detection on HP nx5000 laptops. Other laptops, including HP nc6000, HP nc8000, HP nw8000, and Toshiba Portege 4000, still need PNP quirks to make this work. With "smsc-ircc2.nopnp", we do the legacy device probe, including manual bridge preconfiguration, as before. Signed-off-by: Bjorn Helgaas Cc: Samuel Ortiz Acked-by: "Linus Walleij (LD/EAB)" Cc: Andrey Borzenkov Cc: Michal Piotrowski Cc: "David S. Miller" Cc: Adam Belay Cc: Andrew Morton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/irda/smsc-ircc2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 9043bf4aa49e..2803b370ba01 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -416,6 +416,13 @@ static int __init smsc_ircc_legacy_probe(void) { int ret = 0; +#ifdef CONFIG_PCI + if (smsc_ircc_preconfigure_subsystems(ircc_cfg, ircc_fir, ircc_sir, ircc_dma, ircc_irq) < 0) { + /* Ignore errors from preconfiguration */ + IRDA_ERROR("%s, Preconfiguration failed !\n", driver_name); + } +#endif + if (ircc_fir > 0 && ircc_sir > 0) { IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); @@ -459,13 +466,6 @@ static int __init smsc_ircc_init(void) return ret; } -#ifdef CONFIG_PCI - if (smsc_ircc_preconfigure_subsystems(ircc_cfg, ircc_fir, ircc_sir, ircc_dma, ircc_irq) < 0) { - /* Ignore errors from preconfiguration */ - IRDA_ERROR("%s, Preconfiguration failed !\n", driver_name); - } -#endif - dev_count = 0; if (smsc_nopnp || !pnp_platform_devices || -- cgit v1.2.3 From 172d0496cd22c98ee2e4238821fa309c01685f3a Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 27 Jun 2007 14:09:52 -0700 Subject: PNP SMCf010 quirk: auto-config device if BIOS left it broken Some HP firmware leaves the SMCf010 IRDA device incompletely configured, or reports the wrong resources in _CRS. As a workaround, when we find such a device, try to auto-configure the device. This ignores the _CRS data, picks a config from _PRS, and runs _SRS to configure the device. This makes smsc-ircc2 work correctly with PNP resources (with no preconfiguration!) on all the machines I tested. I think Windows does something like this by default for all devices, so we should consider doing the same thing in Linux. This patch addresses part of the 2.6.22 regression: "no irda0 interface (2.6.21 was OK), smsc does not find chip" It fixes smsc-ircc2 PNP device detection on HP nc6000, nc6220, nw8000, nw8240, and possibly other machines. Signed-off-by: Bjorn Helgaas Cc: Samuel Ortiz Cc: "Linus Walleij (LD/EAB)" Cc: Andrey Borzenkov Cc: Michal Piotrowski Cc: Adam Belay Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pnp/quirks.c | 66 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 277df50c89ae..967a8e22b2da 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -107,31 +107,61 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev) return; } -static void quirk_smc_enable(struct pnp_dev *dev) +static int quirk_smc_fir_enabled(struct pnp_dev *dev) { - unsigned int firbase; + unsigned long firbase; + u8 bank, high, low, chip; + + if (!pnp_port_valid(dev, 1)) + return 0; + + firbase = pnp_port_start(dev, 1); + + /* Select register bank 3 */ + bank = inb(firbase + 7); + bank &= 0xf0; + bank |= 3; + outb(bank, firbase + 7); + + high = inb(firbase + 0); + low = inb(firbase + 1); + chip = inb(firbase + 2); + + /* This corresponds to the check in smsc_ircc_present() */ + if (high == 0x10 && low == 0xb8 && (chip == 0xf1 || chip == 0xf2)) + return 1; + + return 0; +} - if (!dev->active || !pnp_port_valid(dev, 1)) +static void quirk_smc_enable(struct pnp_dev *dev) +{ + /* + * If the BIOS left the device disabled, or it is enabled and + * responding correctly, we're in good shape. + */ + if (!dev->active || quirk_smc_fir_enabled(dev)) return; /* - * On the HP/Compaq nw8240 (and probably other similar machines), - * there is an SMCF010 device with two I/O port regions: - * - * 0x3e8-0x3ef SIR - * 0x100-0x10f FIR + * Sometimes the BIOS claims the device is enabled, but it reports + * the wrong FIR resources or doesn't properly configure ISA or LPC + * bridges on the way to the device. * - * _STA reports the device is enabled, but in fact, the BIOS - * neglects to enable the FIR range. Fortunately, it does fully - * enable the device if we call _SRS. + * HP nc6000 and nc8000/nw8000 laptops have known problems like + * this. Fortunately, they do fix things up if we auto-configure + * the device using its _PRS and _SRS methods. */ - firbase = pnp_port_start(dev, 1); - if (inb(firbase + 0x7 /* IRCC_MASTER */) == 0xff) { - pnp_err("%s (%s) enabled but not responding, disabling and " - "re-enabling", dev->dev.bus_id, pnp_dev_name(dev)); - pnp_disable_dev(dev); - pnp_activate_dev(dev); - } + dev_err(&dev->dev, "%s device not responding, auto-configuring " + "resources\n", dev->id->id); + + pnp_disable_dev(dev); + pnp_init_resource_table(&dev->res); + pnp_auto_config_dev(dev); + pnp_activate_dev(dev); + + if (!quirk_smc_fir_enabled(dev)) + dev_err(&dev->dev, "giving up; try \"smsc-ircc2.nopnp\"\n"); } -- cgit v1.2.3 From 30acbabae38793c9c9acace4de5b1c1889570768 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Wed, 27 Jun 2007 14:09:53 -0700 Subject: mm: kill validate_anon_vma to avoid mapcount BUG validate_anon_vma gave a useful check on the integrity of the anon_vma list when Andrea was developing obj rmap; but it was not enabled in SLES9 itself, nor in mainline, until Nick changed commented-out RMAP_DEBUG to configurable CONFIG_DEBUG_VM in 2.6.17. Now Petr Vandrovec reports that its BUG_ON(mapcount > 100000) can easily crash a CONFIG_DEBUG_VM=y system. That limit was just an arbitrary number to protect against an infinite loop. We could raise it to something enormous (depending on sizeof struct vma and size of memory?); but I rather think validate_anon_vma has outlived its usefulness, and is better just removed - which gives a magnificent performance boost to anything like Petr's test program ;) Of course, a very long anon_vma list is bad news for preemption latency, and I believe there has been one recent report of such: let's not forget that, but validate_anon_vma only makes it worse not better. Signed-off-by: Hugh Dickins Cc: Petr Vandrovec Acked-by: Nick Piggin Cc: Andrea Arcangeli Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/rmap.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/mm/rmap.c b/mm/rmap.c index 850165d32b7a..61e492597a0b 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -53,24 +53,6 @@ struct kmem_cache *anon_vma_cachep; -static inline void validate_anon_vma(struct vm_area_struct *find_vma) -{ -#ifdef CONFIG_DEBUG_VM - struct anon_vma *anon_vma = find_vma->anon_vma; - struct vm_area_struct *vma; - unsigned int mapcount = 0; - int found = 0; - - list_for_each_entry(vma, &anon_vma->head, anon_vma_node) { - mapcount++; - BUG_ON(mapcount > 100000); - if (vma == find_vma) - found = 1; - } - BUG_ON(!found); -#endif -} - /* This must be called under the mmap_sem. */ int anon_vma_prepare(struct vm_area_struct *vma) { @@ -121,10 +103,8 @@ void __anon_vma_link(struct vm_area_struct *vma) { struct anon_vma *anon_vma = vma->anon_vma; - if (anon_vma) { + if (anon_vma) list_add_tail(&vma->anon_vma_node, &anon_vma->head); - validate_anon_vma(vma); - } } void anon_vma_link(struct vm_area_struct *vma) @@ -134,7 +114,6 @@ void anon_vma_link(struct vm_area_struct *vma) if (anon_vma) { spin_lock(&anon_vma->lock); list_add_tail(&vma->anon_vma_node, &anon_vma->head); - validate_anon_vma(vma); spin_unlock(&anon_vma->lock); } } @@ -148,7 +127,6 @@ void anon_vma_unlink(struct vm_area_struct *vma) return; spin_lock(&anon_vma->lock); - validate_anon_vma(vma); list_del(&vma->anon_vma_node); /* We must garbage collect the anon_vma if it's empty */ -- cgit v1.2.3 From 59faba1b316a7798a33752b3889193333f8af1a0 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Wed, 27 Jun 2007 14:09:54 -0700 Subject: Fix Kconfig dependency problems wrt boolean menuconfigs If one has a dependency chain (tristate)FOO depends on (bool)BAR depends on (tristate)BAZ, build problems will result. If BAZ=m, then BAR can be set y, which allows FOO=y. It's possible to have FOO=y && BAZ=m, which wouldn't be allowed if FOO depended directly on BAZ. In effect, the bool promotes the tristate from m to y. This ends up causing a problem with several menuconfigs that look like: menuconfig BAR bool depends on BAZ [tristate] if BAR config FOO tristate endif The solution used here is to add the dependencies of BAR to the if statement, so that items in the if block will gain a direct non-bool-promoted dependency on BAZ. This is how it would work if a menu was used instead of an if block. Signed-off-by: Trent Piepho Acked-by: Mauro Carvalho Chehab Cc: "David S. Miller" Acked-by: Jeff Garzik Cc: Dominik Brodowski Cc: Chas Williams Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/atm/Kconfig | 2 +- drivers/media/dvb/Kconfig | 2 +- drivers/media/radio/Kconfig | 2 +- drivers/media/video/Kconfig | 6 +++--- drivers/net/pcmcia/Kconfig | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig index f5a47a48c3b4..5b4fab24155f 100644 --- a/drivers/atm/Kconfig +++ b/drivers/atm/Kconfig @@ -7,7 +7,7 @@ menuconfig ATM_DRIVERS depends on NETDEVICES && ATM default y -if ATM_DRIVERS +if ATM_DRIVERS && NETDEVICES && ATM config ATM_DUMMY tristate "Dummy ATM driver" diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig index efd2b7468158..03ef88acd9b8 100644 --- a/drivers/media/dvb/Kconfig +++ b/drivers/media/dvb/Kconfig @@ -11,7 +11,7 @@ menuconfig DVB_CAPTURE_DRIVERS ---help--- Say Y to select Digital TV adapters -if DVB_CAPTURE_DRIVERS +if DVB_CAPTURE_DRIVERS && DVB_CORE comment "Supported SAA7146 based PCI Adapters" depends on DVB_CORE && PCI && I2C diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index a6ac82a609d4..194b102140ef 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -9,7 +9,7 @@ menuconfig RADIO_ADAPTERS ---help--- Say Y here to enable selecting AM/FM radio adapters. -if RADIO_ADAPTERS +if RADIO_ADAPTERS && VIDEO_DEV config RADIO_CADET tristate "ADS Cadet AM/FM Tuner" diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 4cca55170e21..4d45a40016de 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -11,7 +11,7 @@ menuconfig VIDEO_CAPTURE_DRIVERS webcams, analog TV, and hybrid analog/digital TV. Some of those devices also supports FM radio. -if VIDEO_CAPTURE_DRIVERS +if VIDEO_CAPTURE_DRIVERS && VIDEO_DEV config VIDEO_ADV_DEBUG bool "Enable advanced debug functionality" @@ -347,7 +347,7 @@ endmenu # encoder / decoder chips config VIDEO_VIVI tristate "Virtual Video Driver" - depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI && VIDEO_DEV + depends on VIDEO_V4L2 && !SPARC32 && !SPARC64 && PCI select VIDEO_BUF default n ---help--- @@ -691,7 +691,7 @@ menuconfig V4L_USB_DRIVERS depends on USB default y -if V4L_USB_DRIVERS +if V4L_USB_DRIVERS && USB source "drivers/media/video/pvrusb2/Kconfig" diff --git a/drivers/net/pcmcia/Kconfig b/drivers/net/pcmcia/Kconfig index 5d658bc9791c..e8f55d8ed7a9 100644 --- a/drivers/net/pcmcia/Kconfig +++ b/drivers/net/pcmcia/Kconfig @@ -19,7 +19,7 @@ menuconfig NET_PCMCIA If unsure, say N. -if NET_PCMCIA +if NET_PCMCIA && PCMCIA config PCMCIA_3C589 tristate "3Com 3c589 PCMCIA support" -- cgit v1.2.3 From 92504f79a7c57b853dfb59595fd2860282f6ba1e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 27 Jun 2007 14:09:56 -0700 Subject: IOATDMA: fix section mismatches Rename struct pci_driver data so that false section mismatch warnings won't be produced. Sam, ISTM that depending on variable names is the weakest & worst part of modpost section checking. Should __init_refok work here? I got build errors when I tried to use it, probably because the struct pci_driver probe and remove methods are not marked "__init_refok". WARNING: drivers/dma/ioatdma.o(.data+0x10): Section mismatch: reference to .init.text: (between 'ioat_pci_drv' and 'ioat_pci_tbl') WARNING: drivers/dma/ioatdma.o(.data+0x14): Section mismatch: reference to .exit.text: (between 'ioat_pci_drv' and 'ioat_pci_tbl') Signed-off-by: Randy Dunlap Acked-by: Chris Leech Cc: Sam Ravnborg Cc: Andrew Morton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/dma/ioatdma.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c index 8e8726104619..850014139556 100644 --- a/drivers/dma/ioatdma.c +++ b/drivers/dma/ioatdma.c @@ -556,7 +556,7 @@ static struct pci_device_id ioat_pci_tbl[] = { { 0, } }; -static struct pci_driver ioat_pci_drv = { +static struct pci_driver ioat_pci_driver = { .name = "ioatdma", .id_table = ioat_pci_tbl, .probe = ioat_probe, @@ -699,7 +699,7 @@ static int __devinit ioat_probe(struct pci_dev *pdev, if (err) goto err_set_dma_mask; - err = pci_request_regions(pdev, ioat_pci_drv.name); + err = pci_request_regions(pdev, ioat_pci_driver.name); if (err) goto err_request_regions; @@ -828,14 +828,14 @@ static int __init ioat_init_module(void) /* if forced, worst case is that rmmod hangs */ __unsafe(THIS_MODULE); - return pci_register_driver(&ioat_pci_drv); + return pci_register_driver(&ioat_pci_driver); } module_init(ioat_init_module); static void __exit ioat_exit_module(void) { - pci_unregister_driver(&ioat_pci_drv); + pci_unregister_driver(&ioat_pci_driver); } module_exit(ioat_exit_module); -- cgit v1.2.3 From 53f3bed0a46c786b17f040005b1bd7a78ddd0770 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 27 Jun 2007 14:09:57 -0700 Subject: ALSA: fix ice1712 section mismatch Cannot mix const and __initdata: sound/pci/ice1712/prodigy192.c:708: error: ak4114_controls causes a section type conflict Signed-off-by: Randy Dunlap Cc: Jaroslav Kysela Cc: Takashi Iwai Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- sound/pci/ice1712/prodigy192.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index f03c02c07743..4bae7305a79b 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c @@ -705,7 +705,7 @@ static int ak4114_input_sw_put(struct snd_kcontrol *kcontrol, } -static const struct snd_kcontrol_new ak4114_controls[] __devinitdata = { +static struct snd_kcontrol_new ak4114_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "MIODIO IEC958 Capture Input", -- cgit v1.2.3 From 58e78475ec706f93e0cc049449ffd11fbfdadb3e Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Wed, 27 Jun 2007 14:09:58 -0700 Subject: saa7134: fix thread shutdown handling This patch changes the test for the thread pid from >= 0 to > 0. When the saa8134 driver initialization fails after a certain point, it goes through the complete shutdown process for the driver. Part of shutting it down includes tearing down the thread for tv audio. The test for tearing down the thread tests for >= 0. Since the dev structure is kzalloc'd, the test will always be true if we haven't tried to start the thread yet. We end up waiting on pid 0 to complete, which will never happen, so we lock up. This bug was observed in Novell Bugzilla 284718, when request_irq() failed. Signed-off-by: Jeff Mahoney Acked-by: Mauro Carvalho Chehab Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/saa7134/saa7134-tvaudio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index 7b56041186dc..30395d6b5f14 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -1005,7 +1005,7 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev) int saa7134_tvaudio_fini(struct saa7134_dev *dev) { /* shutdown tvaudio thread */ - if (dev->thread.pid >= 0) { + if (dev->thread.pid > 0) { dev->thread.shutdown = 1; wake_up_interruptible(&dev->thread.wq); wait_for_completion(&dev->thread.exit); -- cgit v1.2.3 From f8738c5c5298d55ccfc26383f9f45af082a9be57 Mon Sep 17 00:00:00 2001 From: Davide Libenzi Date: Wed, 27 Jun 2007 14:09:59 -0700 Subject: avoid spurious POLLIN returns in signalfd The new code in kernel/signal.c does not allow fetching private signals from another task. This patch avoid spurious POLLIN returns from a signalfd poll(2) operation. Signed-off-by: Davide Libenzi Cc: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/signalfd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/signalfd.c b/fs/signalfd.c index f1da89203a9a..3b07f26d984d 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c @@ -133,7 +133,8 @@ static unsigned int signalfd_poll(struct file *file, poll_table *wait) * the peer disconnects. */ if (signalfd_lock(ctx, &lk)) { - if (next_signal(&lk.tsk->pending, &ctx->sigmask) > 0 || + if ((lk.tsk == current && + next_signal(&lk.tsk->pending, &ctx->sigmask) > 0) || next_signal(&lk.tsk->signal->shared_pending, &ctx->sigmask) > 0) events |= POLLIN; -- cgit v1.2.3 From 74bfe034d62ae71ad896932748de3ec8d1340809 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Wed, 27 Jun 2007 14:10:00 -0700 Subject: fix section mismatch in chipsfb WARNING: drivers/built-in.o(.text+0x8742a): Section mismatch: reference to .init.data:chipsfb_fix (between 'chipsfb_pci_init' and 'chipsfb_set_par') WARNING: drivers/built-in.o(.text+0x87432): Section mismatch: reference to .init.data:chipsfb_fix (between 'chipsfb_pci_init' and 'chipsfb_set_par') WARNING: drivers/built-in.o(.text+0x87442): Section mismatch: reference to .init.data:chipsfb_var (between 'chipsfb_pci_init' and 'chipsfb_set_par') WARNING: drivers/built-in.o(.text+0x8744a): Section mismatch: reference to .init.data:chipsfb_var (between 'chipsfb_pci_init' and 'chipsfb_set_par') init_chips is only called from chipsfb_pci_init chipsfb_fix and chipsfb_var are only referenced from init_chips Signed-off-by: Olaf Hering Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/chipsfb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c index af313bf1a2da..f48e8c534c87 100644 --- a/drivers/video/chipsfb.c +++ b/drivers/video/chipsfb.c @@ -292,7 +292,7 @@ static void __init chips_hw_init(void) write_fr(chips_init_fr[i].addr, chips_init_fr[i].data); } -static struct fb_fix_screeninfo chipsfb_fix __initdata = { +static struct fb_fix_screeninfo chipsfb_fix __devinitdata = { .id = "C&T 65550", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_PSEUDOCOLOR, @@ -309,7 +309,7 @@ static struct fb_fix_screeninfo chipsfb_fix __initdata = { .smem_len = 0x100000, /* 1MB */ }; -static struct fb_var_screeninfo chipsfb_var __initdata = { +static struct fb_var_screeninfo chipsfb_var __devinitdata = { .xres = 800, .yres = 600, .xres_virtual = 800, @@ -330,7 +330,7 @@ static struct fb_var_screeninfo chipsfb_var __initdata = { .vsync_len = 8, }; -static void __init init_chips(struct fb_info *p, unsigned long addr) +static void __devinit init_chips(struct fb_info *p, unsigned long addr) { memset(p->screen_base, 0, 0x100000); -- cgit v1.2.3 From 8a465c3239d5b3a5a7361c38fc499ad8082a0685 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Wed, 27 Jun 2007 14:10:01 -0700 Subject: Documentation/HOWTO: update URLs of git trees Also, remove outdated 1394 tree and mention MAINTAINERS as pointer to development trees. Signed-off-by: Stefan Richter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/HOWTO | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/Documentation/HOWTO b/Documentation/HOWTO index ced9207bedcf..98e2701c746f 100644 --- a/Documentation/HOWTO +++ b/Documentation/HOWTO @@ -322,39 +322,34 @@ kernel releases as described above. Here is a list of some of the different kernel trees available: git trees: - Kbuild development tree, Sam Ravnborg - kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git + git.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git - ACPI development tree, Len Brown - kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git + git.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git - Block development tree, Jens Axboe - kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git + git.kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git - DRM development tree, Dave Airlie - kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git + git.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git - ia64 development tree, Tony Luck - kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git - - - ieee1394 development tree, Jody McIntyre - kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git + git.kernel.org:/pub/scm/linux/kernel/git/aegl/linux-2.6.git - infiniband, Roland Dreier - kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git + git.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git - libata, Jeff Garzik - kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git + git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git - network drivers, Jeff Garzik - kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git + git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git - pcmcia, Dominik Brodowski - kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git + git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git - SCSI, James Bottomley - kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git - - Other git kernel trees can be found listed at http://kernel.org/git + git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git quilt trees: - USB, PCI, Driver Core, and I2C, Greg Kroah-Hartman @@ -362,6 +357,9 @@ Here is a list of some of the different kernel trees available: - x86-64, partly i386, Andi Kleen ftp.firstfloor.org:/pub/ak/x86_64/quilt/ + Other kernel trees can be found listed at http://git.kernel.org/ and in + the MAINTAINERS file. + Bug Reporting ------------- -- cgit v1.2.3 From ea7fc3336b1d657c65daf55614d4aaadd8c1c244 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 27 Jun 2007 14:10:02 -0700 Subject: ALSA: use __devexit_p Change __devexit to __devexit_p: sound/isa/opl3sa2.c:956: error: expected expression before '__attribute__' Signed-off-by: Randy Dunlap Cc: Jaroslav Kysela Cc: Takashi Iwai Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- sound/isa/opl3sa2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 61a323cc0e49..4f6800b43b0e 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -953,7 +953,7 @@ static int snd_opl3sa2_isa_resume(struct device *dev, unsigned int n) static struct isa_driver snd_opl3sa2_isa_driver = { .match = snd_opl3sa2_isa_match, .probe = snd_opl3sa2_isa_probe, - .remove = __devexit( snd_opl3sa2_isa_remove), + .remove = __devexit_p(snd_opl3sa2_isa_remove), #ifdef CONFIG_PM .suspend = snd_opl3sa2_isa_suspend, .resume = snd_opl3sa2_isa_resume, -- cgit v1.2.3 From 8d62fdebdaf9b866c7e236a8f5cfe90e6dba5773 Mon Sep 17 00:00:00 2001 From: David Wilder Date: Wed, 27 Jun 2007 14:10:03 -0700 Subject: relay file read: start-pos fix Fix a bug in the relay read interface causing the number of consumed bytes to be set incorrectly. Signed-off-by: Tom Zanussi Signed-off-by: David Wilder Cc: Masami Hiramatsu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/relay.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/relay.c b/kernel/relay.c index 4311101b0ca7..e61156ea4e25 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -899,7 +899,10 @@ static size_t relay_file_read_start_pos(size_t read_pos, size_t read_subbuf, padding, padding_start, padding_end; size_t subbuf_size = buf->chan->subbuf_size; size_t n_subbufs = buf->chan->n_subbufs; + size_t consumed = buf->subbufs_consumed % n_subbufs; + if (!read_pos) + read_pos = consumed * subbuf_size + buf->bytes_consumed; read_subbuf = read_pos / subbuf_size; padding = buf->padding[read_subbuf]; padding_start = (read_subbuf + 1) * subbuf_size - padding; -- cgit v1.2.3 From a66e356c04ece4a96f44b942b68234c3de8ec3f5 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 27 Jun 2007 14:10:04 -0700 Subject: relayfs: fix overwrites When I use relayfs with "overwrite" mode, read() still sets incorrect number of consumed bytes. Signed-off-by: Masami Hiramatsu Acked-by: Tom Zanussi Acked-by: David Wilder Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/relay.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/relay.c b/kernel/relay.c index e61156ea4e25..95db8c79fe8f 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -812,7 +812,10 @@ static void relay_file_read_consume(struct rchan_buf *buf, } buf->bytes_consumed += bytes_consumed; - read_subbuf = read_pos / buf->chan->subbuf_size; + if (!read_pos) + read_subbuf = buf->subbufs_consumed % n_subbufs; + else + read_subbuf = read_pos / buf->chan->subbuf_size; if (buf->bytes_consumed + buf->padding[read_subbuf] == subbuf_size) { if ((read_subbuf == buf->subbufs_produced % n_subbufs) && (buf->offset == subbuf_size)) @@ -841,8 +844,9 @@ static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos) } if (unlikely(produced - consumed >= n_subbufs)) { - consumed = (produced / n_subbufs) * n_subbufs; + consumed = produced - n_subbufs + 1; buf->subbufs_consumed = consumed; + buf->bytes_consumed = 0; } produced = (produced % n_subbufs) * subbuf_size + buf->offset; -- cgit v1.2.3 From 33e44b158821cc703f99d43d87579a2fe819ce7b Mon Sep 17 00:00:00 2001 From: Evgeniy Polyakov Date: Wed, 27 Jun 2007 14:10:04 -0700 Subject: w1_therm_read_bin: don't call flush_signals() This can disrupt userspace signal management. Signed-off-by: Evgeniy Polyakov Cc: Roland McGrath Cc: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/w1/slaves/w1_therm.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 732db4780042..1a6937dc190b 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -191,11 +191,7 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si w1_write_8(dev, W1_CONVERT_TEMP); - while (tm) { - tm = msleep_interruptible(tm); - if (signal_pending(current)) - flush_signals(current); - } + msleep(tm); if (!w1_reset_select_slave(sl)) { -- cgit v1.2.3 From 5da44ad504662de8120063bdca46897a15f3f1e5 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 27 Jun 2007 14:10:06 -0700 Subject: mips-jazz: correct flags for timer io resource arch/mips/jazz/setup.c:55:4: error: Initializer entry defined twice Signed-off-by: Alexey Dobriyan Acked-by: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/jazz/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c index d848f1a07786..81ec559a1c26 100644 --- a/arch/mips/jazz/setup.c +++ b/arch/mips/jazz/setup.c @@ -54,7 +54,7 @@ static struct resource jazz_io_resources[] = { .start = 0x40, .end = 0x5f, .name = "timer", - .end = IORESOURCE_BUSY + .flags = IORESOURCE_BUSY }, { .start = 0x80, .end = 0x8f, -- cgit v1.2.3 From ddc80bd781590ef6eb8ce30a0f3ac88c5599e41c Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 27 Jun 2007 14:10:08 -0700 Subject: ext2: fix return of uninitialised variable gcc correctly says fs/ext2/super.c: In function 'ext2_remount': fs/ext2/super.c:1055: warning: 'err' may be used uninitialized in this function Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ext2/super.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ext2/super.c b/fs/ext2/super.c index c9fd8cf6eaa9..5de5061eb331 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -1043,6 +1043,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) if ((ext2_use_xip(sb)) && (sb->s_blocksize != PAGE_SIZE)) { printk("XIP: Unsupported blocksize\n"); + err = -EINVAL; goto restore_opts; } -- cgit v1.2.3 From 2f4d4da8f82c2598b8713f4a01f360f3751d90be Mon Sep 17 00:00:00 2001 From: Jay Lubomirski Date: Wed, 27 Jun 2007 14:10:09 -0700 Subject: serial: clear proper MPSC interrupt cause bits The interrupt clearing code in mpsc_sdma_intr_ack() mistakenly clears the interrupt for both controllers instead of just the one its supposed to. This can result in the other controller appearing to hang because its interrupt was effectively lost. So, don't clear the interrupt cause bits for both MPSC controllers when clearing the interrupt for one of them. Just clear the one that is supposed to be cleared. Signed-off-by: Jay Lubomirski Acked-by: Mark A. Greer Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/mpsc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index d09f2097d5b0..00924feaf621 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c @@ -503,7 +503,8 @@ mpsc_sdma_intr_ack(struct mpsc_port_info *pi) if (pi->mirror_regs) pi->shared_regs->SDMA_INTR_CAUSE_m = 0; - writel(0, pi->shared_regs->sdma_intr_base + SDMA_INTR_CAUSE); + writeb(0x00, pi->shared_regs->sdma_intr_base + SDMA_INTR_CAUSE + + pi->port.line); return; } -- cgit v1.2.3 From edd5cd4a9424f22b0fa08bef5e299d41befd5622 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 27 Jun 2007 14:10:09 -0700 Subject: Introduce fixed sys_sync_file_range2() syscall, implement on PowerPC and ARM Not all the world is an i386. Many architectures need 64-bit arguments to be aligned in suitable pairs of registers, and the original sys_sync_file_range(int, loff_t, loff_t, int) was therefore wasting an argument register for padding after the first integer. Since we don't normally have more than 6 arguments for system calls, that left no room for the final argument on some architectures. Fix this by introducing sys_sync_file_range2(int, int, loff_t, loff_t) which all fits nicely. In fact, ARM already had that, but called it sys_arm_sync_file_range. Move it to fs/sync.c and rename it, then implement the needed compatibility routine. And stop the missing syscall check from bitching about the absence of sys_sync_file_range() if we've implemented sys_sync_file_range2() instead. Tested on PPC32 and with 32-bit and 64-bit userspace on PPC64. Signed-off-by: David Woodhouse Acked-by: Russell King Cc: Arnd Bergmann Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/kernel/calls.S | 2 +- arch/arm/kernel/sys_arm.c | 13 ------------- arch/powerpc/kernel/sys_ppc32.c | 9 +++++++++ fs/sync.c | 8 ++++++++ include/asm-arm/unistd.h | 1 + include/asm-powerpc/systbl.h | 1 + include/asm-powerpc/unistd.h | 3 ++- include/linux/syscalls.h | 2 ++ scripts/checksyscalls.sh | 5 +++++ 9 files changed, 29 insertions(+), 15 deletions(-) diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 19326d7cdeb3..a98d0c933db0 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -350,7 +350,7 @@ CALL(sys_set_robust_list) CALL(sys_get_robust_list) /* 340 */ CALL(sys_splice) - CALL(sys_arm_sync_file_range) + CALL(sys_sync_file_range2) CALL(sys_tee) CALL(sys_vmsplice) CALL(sys_move_pages) diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index 1ca2d5174fcb..4d25e49a14f7 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c @@ -328,16 +328,3 @@ asmlinkage long sys_arm_fadvise64_64(int fd, int advice, { return sys_fadvise64_64(fd, offset, len, advice); } - -/* - * Yet more syscall fsckage - we can't fit sys_sync_file_range's - * arguments into the available registers with EABI. So, let's - * create an ARM specific syscall for this which has _sane_ - * arguments. (This incidentally also has an ABI-independent - * argument layout.) - */ -asmlinkage long sys_arm_sync_file_range(int fd, unsigned int flags, - loff_t offset, loff_t nbytes) -{ - return sys_sync_file_range(fd, offset, nbytes, flags); -} diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 047246ad4f65..b42cbf1e2d7d 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -810,3 +810,12 @@ asmlinkage long compat_sys_request_key(const char __user *_type, return sys_request_key(_type, _description, _callout_info, destringid); } +asmlinkage long compat_sys_sync_file_range2(int fd, unsigned int flags, + unsigned offset_hi, unsigned offset_lo, + unsigned nbytes_hi, unsigned nbytes_lo) +{ + loff_t offset = ((loff_t)offset_hi << 32) | offset_lo; + loff_t nbytes = ((loff_t)nbytes_hi << 32) | nbytes_lo; + + return sys_sync_file_range(fd, offset, nbytes, flags); +} diff --git a/fs/sync.c b/fs/sync.c index 2f97576355b8..7cd005ea7639 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -236,6 +236,14 @@ out: return ret; } +/* It would be nice if people remember that not all the world's an i386 + when they introduce new system calls */ +asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, + loff_t offset, loff_t nbytes) +{ + return sys_sync_file_range(fd, offset, nbytes, flags); +} + /* * `endbyte' is inclusive */ diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h index 250d7f145aca..bfdbebebdc1b 100644 --- a/include/asm-arm/unistd.h +++ b/include/asm-arm/unistd.h @@ -367,6 +367,7 @@ #define __NR_get_robust_list (__NR_SYSCALL_BASE+339) #define __NR_splice (__NR_SYSCALL_BASE+340) #define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341) +#define __NR_sync_file_range2 __NR_arm_sync_file_range #define __NR_tee (__NR_SYSCALL_BASE+342) #define __NR_vmsplice (__NR_SYSCALL_BASE+343) #define __NR_move_pages (__NR_SYSCALL_BASE+344) diff --git a/include/asm-powerpc/systbl.h b/include/asm-powerpc/systbl.h index 700ca5928741..1cc3f9cb6f4e 100644 --- a/include/asm-powerpc/systbl.h +++ b/include/asm-powerpc/systbl.h @@ -311,3 +311,4 @@ COMPAT_SYS_SPU(utimensat) COMPAT_SYS_SPU(signalfd) COMPAT_SYS_SPU(timerfd) SYSCALL_SPU(eventfd) +COMPAT_SYS_SPU(sync_file_range2) diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h index e3c28dc31abf..f71c6061f1ec 100644 --- a/include/asm-powerpc/unistd.h +++ b/include/asm-powerpc/unistd.h @@ -330,10 +330,11 @@ #define __NR_signalfd 305 #define __NR_timerfd 306 #define __NR_eventfd 307 +#define __NR_sync_file_range2 308 #ifdef __KERNEL__ -#define __NR_syscalls 308 +#define __NR_syscalls 309 #define __NR__exit __NR_exit #define NR_syscalls __NR_syscalls diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index b02070eac422..83d0ec11235e 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -598,6 +598,8 @@ asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags); asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, unsigned int flags); +asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, + loff_t offset, loff_t nbytes); asmlinkage long sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr, size_t __user *len_ptr); diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index f98171f5a3df..0dcc01ce45a6 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh @@ -99,6 +99,11 @@ cat << EOF #define __IGNORE_setfsuid32 #define __IGNORE_setfsgid32 +/* sync_file_range had a stupid ABI. Allow sync_file_range2 instead */ +#ifdef __NR_sync_file_range2 +#define __IGNORE_sync_file_range +#endif + /* Unmerged syscalls for AFS, STREAMS, etc. */ #define __IGNORE_afs_syscall #define __IGNORE_getpmsg -- cgit v1.2.3 From 9f462a1a5de06503fd247186b91d4205ac1cf1ba Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 28 Jun 2007 21:25:31 -0700 Subject: [SPARC64]: Add linux/pagemap.h to asm/tlb.h As seen on sparc64-allnoconfig: CC arch/sparc64/mm/tlb.o In file included from arch/sparc64/mm/tlb.c:19: include/asm/tlb.h: In function 'tlb_flush_mmu': include/asm/tlb.h:60: warning: implicit declaration of function 'release_pages' include/asm/tlb.h: In function 'tlb_remove_page': include/asm/tlb.h:92: warning: implicit declaration of function 'page_cache_release' Signed-off-by: Alexey Dobriyan Signed-off-by: David S. Miller --- include/asm-sparc64/tlb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-sparc64/tlb.h b/include/asm-sparc64/tlb.h index 7af1e1109c49..349d1d3e9c27 100644 --- a/include/asm-sparc64/tlb.h +++ b/include/asm-sparc64/tlb.h @@ -2,6 +2,7 @@ #define _SPARC64_TLB_H #include +#include #include #include #include -- cgit v1.2.3 From 17200811cf539b9107a99a39bf71ba3567966285 Mon Sep 17 00:00:00 2001 From: Jarek Poplawski Date: Thu, 28 Jun 2007 22:11:47 -0700 Subject: [NETPOLL] netconsole: fix soft lockup when removing module #1 Until kernel ver. 2.6.21 (including) cancel_rearming_delayed_work() required a work function should always (unconditionally) rearm with delay > 0 - otherwise it would endlessly loop. This patch replaces this function with cancel_delayed_work(). Later kernel versions don't require this, so here it's only for uniformity. #2 After deleting a timer in cancel_[rearming_]delayed_work() there could stay a last skb queued in npinfo->txq causing a memory leak after kfree(npinfo). Initial patch & testing by: Jason Wessel Signed-off-by: Jarek Poplawski Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- net/core/netpoll.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/net/core/netpoll.c b/net/core/netpoll.c index f8e74e511ce6..cf40ff91ac01 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -72,7 +72,8 @@ static void queue_process(struct work_struct *work) netif_tx_unlock(dev); local_irq_restore(flags); - schedule_delayed_work(&npinfo->tx_work, HZ/10); + if (atomic_read(&npinfo->refcnt)) + schedule_delayed_work(&npinfo->tx_work, HZ/10); return; } netif_tx_unlock(dev); @@ -785,9 +786,15 @@ void netpoll_cleanup(struct netpoll *np) if (atomic_dec_and_test(&npinfo->refcnt)) { skb_queue_purge(&npinfo->arp_tx); skb_queue_purge(&npinfo->txq); - cancel_rearming_delayed_work(&npinfo->tx_work); + cancel_delayed_work(&npinfo->tx_work); flush_scheduled_work(); + /* clean after last, unfinished work */ + if (!skb_queue_empty(&npinfo->txq)) { + struct sk_buff *skb; + skb = __skb_dequeue(&npinfo->txq); + kfree_skb(skb); + } kfree(npinfo); } } -- cgit v1.2.3 From 8da32de5c845b711a500f89342baf10c662e2ecb Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 29 Jun 2007 00:12:04 -0500 Subject: gianfar: Fix typo bug introduced by move to udp_hdr() In commit 4bedb45203eab92a87b4c863fe2d0cded633427f both the udp and tcp cases where changed to use udp_hdr() instead of leaving the tcp case alone and fixing with tcp_hdr(). This ended up causing random behavior with TCP connections because of looking for tcp_hdr()->check in the wrong place. Signed-off-by: Kumar Gala --- drivers/net/gianfar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 6822bf14267b..1b854bf07b09 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -944,7 +944,7 @@ static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb) flags |= TXFCB_UDP; fcb->phcs = udp_hdr(skb)->check; } else - fcb->phcs = udp_hdr(skb)->check; + fcb->phcs = tcp_hdr(skb)->check; /* l3os is the distance between the start of the * frame (skb->data) and the start of the IP hdr. -- cgit v1.2.3 From 5f0212174db33828f8bddcff501b73d2bc734f72 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 28 Jun 2007 22:40:23 -0700 Subject: [IRDA]: fix printk format Fix printk format warning: drivers/net/irda/irport.c:512: warning: format '%d' expects type 'int', but argument 5 has type 'long int' Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/irda/irport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c index 3098960dc2a1..3078c419cb02 100644 --- a/drivers/net/irda/irport.c +++ b/drivers/net/irda/irport.c @@ -509,7 +509,7 @@ static void irport_timeout(struct net_device *dev) IRDA_DEBUG(0, "%s(), iir=%02x, lsr=%02x, iobase=%#x\n", __FUNCTION__, iir, lsr, iobase); - IRDA_DEBUG(0, "%s(), transmitting=%d, remain=%d, done=%d\n", + IRDA_DEBUG(0, "%s(), transmitting=%d, remain=%d, done=%td\n", __FUNCTION__, self->transmitting, self->tx_buff.len, self->tx_buff.data - self->tx_buff.head); -- cgit v1.2.3 From 0a9972baa7454c747fd5f67ce864420dff99d383 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 23 Jun 2007 20:28:17 +0200 Subject: firewire: fix async reception on big endian machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit descriptor.data_address is little endian Tested-by: Olaf Hering Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-ohci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index b72a5c1f9e69..96c8ac5b86cc 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -373,8 +373,8 @@ static void ar_context_tasklet(unsigned long data) offset = offsetof(struct ar_buffer, data); dma_unmap_single(ohci->card.device, - ab->descriptor.data_address - offset, - PAGE_SIZE, DMA_BIDIRECTIONAL); + le32_to_cpu(ab->descriptor.data_address) - offset, + PAGE_SIZE, DMA_BIDIRECTIONAL); buffer = ab; ab = ab->next; @@ -427,7 +427,7 @@ static void ar_context_run(struct ar_context *ctx) size_t offset; offset = offsetof(struct ar_buffer, data); - ab_bus = ab->descriptor.data_address - offset; + ab_bus = le32_to_cpu(ab->descriptor.data_address) - offset; reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ab_bus | 1); reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN); -- cgit v1.2.3 From fe77d4f283e840879f0e23b86a5d6a486823fdef Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 25 Jun 2007 22:18:40 +0200 Subject: firewire: add Kconfig help on building both stacks Alas that won't work so good, because nobody reads help texts. I thought about adding some crude multiple choice selection (build the old stack, build the new stack, build both stacks). It's possible, but it would introduce awkward dummy config variables. Signed-off-by: Stefan Richter --- drivers/firewire/Kconfig | 65 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig index 396dade731f9..d011a76f8e7a 100644 --- a/drivers/firewire/Kconfig +++ b/drivers/firewire/Kconfig @@ -4,27 +4,44 @@ comment "An alternative FireWire stack is available with EXPERIMENTAL=y" depends on EXPERIMENTAL=n config FIREWIRE - tristate "IEEE 1394 (FireWire) support (JUJU alternative stack, experimental)" + tristate "IEEE 1394 (FireWire) support - alternative stack, EXPERIMENTAL" depends on EXPERIMENTAL select CRC_ITU_T help - IEEE 1394 describes a high performance serial bus, which is also - known as FireWire(tm) or i.Link(tm) and is used for connecting all - sorts of devices (most notably digital video cameras) to your - computer. - - If you have FireWire hardware and want to use it, say Y here. This - is the core support only, you will also need to select a driver for - your IEEE 1394 adapter. - - To compile this driver as a module, say M here: the module will be - called firewire-core. - - This is the "JUJU" FireWire stack, an alternative implementation + This is the "Juju" FireWire stack, a new alternative implementation designed for robustness and simplicity. You can build either this stack, or the classic stack (the ieee1394 driver, ohci1394 etc.) or both. + To compile this driver as a module, say M here: the module will be + called firewire-core. It functionally replaces ieee1394, raw1394, + and video1394. + + NOTE: + + You should only build ONE of the stacks, unless you REALLY know what + you are doing. If you install both, you should configure them only as + modules rather than link them statically, and you should blacklist one + of the concurrent low-level drivers in /etc/modprobe.conf. Add either + + blacklist firewire-ohci + or + blacklist ohci1394 + + there depending on which driver you DON'T want to have auto-loaded. + You can optionally do the same with the other IEEE 1394/ FireWire + drivers. + + If you have an old modprobe which doesn't implement the blacklist + directive, use either + + install firewire-ohci /bin/true + or + install ohci1394 /bin/true + + and so on, depending on which modules you DON't want to have + auto-loaded. + config FIREWIRE_OHCI tristate "Support for OHCI FireWire host controllers" depends on PCI && FIREWIRE @@ -34,11 +51,13 @@ config FIREWIRE_OHCI is the only chipset in use, so say Y here. To compile this driver as a module, say M here: The module will be - called firewire-ohci. + called firewire-ohci. It replaces ohci1394 of the classic IEEE 1394 + stack. + + NOTE: - If you also build ohci1394 of the classic IEEE 1394 driver stack, - blacklist either ohci1394 or firewire-ohci to let hotplug load the - desired driver. + If you also build ohci1394 of the classic stack, blacklist either + ohci1394 or firewire-ohci to let hotplug load only the desired driver. config FIREWIRE_SBP2 tristate "Support for storage devices (SBP-2 protocol driver)" @@ -50,12 +69,14 @@ config FIREWIRE_SBP2 like scanners. To compile this driver as a module, say M here: The module will be - called firewire-sbp2. + called firewire-sbp2. It replaces sbp2 of the classic IEEE 1394 + stack. You should also enable support for disks, CD-ROMs, etc. in the SCSI configuration section. - If you also build sbp2 of the classic IEEE 1394 driver stack, - blacklist either sbp2 or firewire-sbp2 to let hotplug load the - desired driver. + NOTE: + + If you also build sbp2 of the classic stack, blacklist either sbp2 + or firewire-sbp2 to let hotplug load only the desired driver. -- cgit v1.2.3 From fde937d826e43c9fe7fecc98b6f3da7188e76930 Mon Sep 17 00:00:00 2001 From: Will Schmidt Date: Fri, 29 Jun 2007 15:49:50 -0500 Subject: Fix VDSO gettimeofday() when called with NULL struct timeval. The vdso64 portion of patch 74609f4536f2b8fd6a48381bbbe3cd37da20a527 for fixing problems with NULL gettimeofday input mistakenly checks for a null tz field twice, when it should be checking for null tz once, and null tv once; by way of a r10/r11 typo. Any application calling gettimeofday(&tv,NULL) will "fail". This corrects that typo, and makes my G5 happy. Tested on G5. Signed-off-by: Will Schmidt Cc: Tony Breeds Forwarded-by: Ben Herrenschmidt [ Ben says: "I checked the 32 bits part of the change is correct. You can probably blame me for originally writing the 2 versions with inversed usage of r10 and r11, thus confusing Tony :-)" Ben duly blamed. - Linus ] Signed-off-by: Linus Torvalds --- arch/powerpc/kernel/vdso64/gettimeofday.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index 2d7a5104c666..c6401f9e37f1 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S @@ -31,7 +31,7 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday) mr r11,r3 /* r11 holds tv */ mr r10,r4 /* r10 holds tz */ bl V_LOCAL_FUNC(__get_datapage) /* get data page */ - cmpldi r10,0 /* check if tv is NULL */ + cmpldi r11,0 /* check if tv is NULL */ beq 2f bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ -- cgit v1.2.3 From 4710bcce8e02257c8a423b7a62ea81d0207582c8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 1 Jul 2007 10:56:11 -0700 Subject: i386: remove bogus mtrr range check Commit 9215da33209b861b01c51382254b178a3fe92a30 "fixed" the MTRR range check to not allow any MTRR's under the 1MB mark (since that's where the fixed MTRR's are active). However, that was totally bogus, since it's normal (and almost required) to have a large variable MTRR that starts at 0, and covers some large percentage of the whole RAM, and then using the fixed MTRR's to override that large MTRR to handle the special ISA hole in the 640k-1M region. The old check was bogus too (checking that no variable MTRR is used that is entirely under the 1MB range), but at least it wasn't actively detrimental, because no sane situation would ever trigger such MTRR usage in the first place. That said, the whole notion of not allowing variable MTRR's in the low 1MB is just stupid, so rather than revert the commit, this just removes the whole sad and unnecessary check entirely. Cc: Jan Beulich Cc: Andi Kleen Cc: Andrew Morton Tested-by: Luca Palermo Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/mtrr/generic.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c index 6d5937891b46..5a551fb7ea7b 100644 --- a/arch/i386/kernel/cpu/mtrr/generic.c +++ b/arch/i386/kernel/cpu/mtrr/generic.c @@ -469,11 +469,6 @@ int generic_validate_add_page(unsigned long base, unsigned long size, unsigned i } } - if (base < 0x100) { - printk(KERN_WARNING "mtrr: cannot set region below 1 MiB (0x%lx000,0x%lx000)\n", - base, size); - return -EINVAL; - } /* Check upper bits of base and last are equal and lower bits are 0 for base and 1 for last */ last = base + size - 1; -- cgit v1.2.3 From 0f4915b9c5d7a35da11bfcff80ae6466cb7b9fc4 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sun, 1 Jul 2007 12:50:35 -0400 Subject: blink driver power saving The blink driver wakes up every jiffies which wastes power unnecessarily. Using a notifier gives same effect. Also add ability to unload module. Signed-off-by: Stephen Hemminger [ We should really just delete the whole thing. The blink driver is broken in many other ways too -Linus ] Signed-off-by: Linus Torvalds --- drivers/misc/blink.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/misc/blink.c b/drivers/misc/blink.c index 634431ce1184..97f7253ce2d3 100644 --- a/drivers/misc/blink.c +++ b/drivers/misc/blink.c @@ -16,12 +16,30 @@ static void do_blink(unsigned long data) add_timer(&blink_timer); } -static int blink_init(void) +static int blink_panic_event(struct notifier_block *blk, + unsigned long event, void *arg) { - printk(KERN_INFO "Enabling keyboard blinking\n"); do_blink(0); return 0; } +static struct notifier_block blink_notify = { + .notifier_call = blink_panic_event, +}; + +static __init int blink_init(void) +{ + printk(KERN_INFO "Enabling keyboard blinking\n"); + atomic_notifier_chain_register(&panic_notifier_list, &blink_notify); + return 0; +} + +static __exit void blink_remove(void) +{ + del_timer_sync(&blink_timer); + atomic_notifier_chain_unregister(&panic_notifier_list, &blink_notify); +} + module_init(blink_init); +module_exit(blink_remove); -- cgit v1.2.3 From 17022220dd70378b2f17fa9b0248f15067d88c58 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Sun, 1 Jul 2007 12:06:35 -0700 Subject: SLAB: remove WARN_ON_ONCE for zero sized objects for 2.6.22 release We agreed to remove the WARN_ON_ONCE before 2.6.22 is released. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mm/slab.c b/mm/slab.c index 6d65cf4e4b2e..a9c4472e9204 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -774,7 +774,6 @@ static inline struct kmem_cache *__find_general_cachep(size_t size, */ BUG_ON(malloc_sizes[INDEX_AC].cs_cachep == NULL); #endif - WARN_ON_ONCE(size == 0); while (size > csizep->cs_size) csizep++; -- cgit v1.2.3 From 95203aec21fcdff1f1fa5480a597d02416aa0a63 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sun, 1 Jul 2007 12:06:36 -0700 Subject: frv: fix fallout from "remove sched.h from mm.h" patch /home/rpjday/AMD/k/topics/0_hi/hi1.c:15: error: dereferencing pointer to incomplete type /home/rpjday/AMD/k/topics/0_hi/hi1.c:16: error: dereferencing pointer to incomplete type Signed-off-by: Alexey Dobriyan Cc: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-frv/pgtable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-frv/pgtable.h b/include/asm-frv/pgtable.h index 2687c7715120..114aefae2701 100644 --- a/include/asm-frv/pgtable.h +++ b/include/asm-frv/pgtable.h @@ -25,7 +25,7 @@ #include #include #include -struct mm_struct; +#include struct vm_area_struct; #endif -- cgit v1.2.3 From 10c86be57724adf44c266300964182fd2966d108 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 1 Jul 2007 12:06:37 -0700 Subject: ALSA: more section mismatches Fix section mismatch warnings: WARNING: sound/built-in.o(.exit.text+0x3ad): Section mismatch: reference to .init.text: (between 'sb_exit' and 'unload_uart6850') WARNING: sound/built-in.o(.exit.text+0x753): Section mismatch: reference to .init.text: (between 'snd_mts64_module_exit' and 'snd_portman_module_exit') Signed-off-by: Randy Dunlap Cc: Jaroslav Kysela Cc: Takashi Iwai Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- sound/drivers/mts64.c | 2 +- sound/oss/sb_card.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c index ebb1bdac7237..2025db5947ae 100644 --- a/sound/drivers/mts64.c +++ b/sound/drivers/mts64.c @@ -1048,7 +1048,7 @@ static struct platform_driver snd_mts64_driver = { /********************************************************************* * module init stuff *********************************************************************/ -static void __init_or_module snd_mts64_unregister_all(void) +static void snd_mts64_unregister_all(void) { int i; diff --git a/sound/oss/sb_card.c b/sound/oss/sb_card.c index 27acd6f29b98..7de18b58f2cd 100644 --- a/sound/oss/sb_card.c +++ b/sound/oss/sb_card.c @@ -290,7 +290,7 @@ static struct pnp_card_driver sb_pnp_driver = { MODULE_DEVICE_TABLE(pnp_card, sb_pnp_card_table); #endif /* CONFIG_PNP */ -static void __init_or_module sb_unregister_all(void) +static void sb_unregister_all(void) { #ifdef CONFIG_PNP if (pnp_registered) -- cgit v1.2.3 From d80d02173360562625c10a526132fb87be4de2a4 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 1 Jul 2007 12:06:37 -0700 Subject: pci.h stubs (for EDD build error) Provide stubs for more PCI bus/slot functions when CONFIG_PCI=n. Signed-off-by: Randy Dunlap Cc: Matt Domsch Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pci.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/linux/pci.h b/include/linux/pci.h index fbf3766dac1e..086a0e5a6318 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -748,6 +748,17 @@ static inline void pci_release_regions(struct pci_dev *dev) { } static inline void pci_block_user_cfg_access(struct pci_dev *dev) { } static inline void pci_unblock_user_cfg_access(struct pci_dev *dev) { } +static inline struct pci_bus *pci_find_next_bus(const struct pci_bus *from) +{ return NULL; } + +static inline struct pci_dev *pci_get_slot(struct pci_bus *bus, + unsigned int devfn) +{ return NULL; } + +static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus, + unsigned int devfn) +{ return NULL; } + #endif /* CONFIG_PCI */ /* Include architecture-dependent settings and functions */ -- cgit v1.2.3 From 5ebffd7c05391693b71d3326c8c78ff82f728ed0 Mon Sep 17 00:00:00 2001 From: Maxime Austruy Date: Sun, 1 Jul 2007 12:06:38 -0700 Subject: asus_acpi: fix oops on non-asus machines If asus_acpi_init doesn't find any device it knows about, it mistakenly returns a "success" error code even though it cleans up after itself. Later when trying to rmmod asus_acpi, the module_exit routine would try to clean up one more time and we would end up calling acpi_bus_unregister_driver(&asus_hotk_driver) twice. This patch addresses this first problem by returning -ENODEV when no appropriate device is found. Then there was also another bug with the code handling the return value of backlight_device_register. If this function ever failed, the driver would cleanup by calling the module_exit routine from module_init, but it would still return "success". So any attempt to rmmod this module would result in asus_acpi_exit being called twice but it's not ready to handle it (I haven't hit this bug, just found it by code inspection). This patch fixes that by inserting a return -ENODEV; at the end of this error handling path. Signed-off-by: Maxime Austruy Cc: Len Brown Cc: Richard Purdie Cc: Jan Engelhardt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/acpi/asus_acpi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index 6d7d4157e049..3cd79caad70c 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -1398,7 +1398,7 @@ static int __init asus_acpi_init(void) if (!asus_hotk_found) { acpi_bus_unregister_driver(&asus_hotk_driver); remove_proc_entry(PROC_ASUS, acpi_root_dir); - return result; + return -ENODEV; } asus_backlight_device = backlight_device_register("asus",NULL,NULL, @@ -1407,6 +1407,7 @@ static int __init asus_acpi_init(void) printk(KERN_ERR "Could not register asus backlight device\n"); asus_backlight_device = NULL; asus_acpi_exit(); + return -ENODEV; } asus_backlight_device->props.max_brightness = 15; -- cgit v1.2.3 From 84288ad89e9736c7478e138f247397b9ab7a9d28 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 1 Jul 2007 12:06:48 -0700 Subject: i386: mtrr crash fix Commit 3ebad5905609476a4ff1151a66b21d9794009961 ("[PATCH] x86: Save and restore the fixed-range MTRRs of the BSP when suspending") added mtrr operations without verifying that the CPU has MTRRs. Crashes transmeta CPUs. Cc: "H. Peter Anvin" Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/mtrr/generic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c index 5a551fb7ea7b..f6e46943e6ef 100644 --- a/arch/i386/kernel/cpu/mtrr/generic.c +++ b/arch/i386/kernel/cpu/mtrr/generic.c @@ -65,7 +65,8 @@ get_fixed_ranges(mtrr_type * frs) void mtrr_save_fixed_ranges(void *info) { - get_fixed_ranges(mtrr_state.fixed_ranges); + if (cpu_has_mtrr) + get_fixed_ranges(mtrr_state.fixed_ranges); } static void print_fixed(unsigned base, unsigned step, const mtrr_type*types) -- cgit v1.2.3 From cbcdd772ff43de58cc0d9de76ae9d05e2dd98bc0 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Sun, 1 Jul 2007 12:06:49 -0700 Subject: smsc-ircc2: bypass PNP detection until we get the quirks worked out Don't use PNP detection by default yet. We have some PNP and BIOS issues to work out first. Sample problem on a Toshiba Portege 4000: the SMCf010 device is handed off disabled. We assign I/O ports originally assigned to the SMCf010 to a PCMCIA device instead. We enable the SMCf010, configuring it to use disjoint ports, but _SRS doesn't work correctly, so the device doesn't work. Signed-off-by: Bjorn Helgaas Cc: Andrey Borzenkov Cc: Adam Belay Cc: Michal Piotrowski Cc: Samuel Ortiz Cc: "David S. Miller" Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/irda/smsc-ircc2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 2803b370ba01..36ab98386be0 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -79,7 +79,7 @@ MODULE_AUTHOR("Daniele Peri "); MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver"); MODULE_LICENSE("GPL"); -static int smsc_nopnp; +static int smsc_nopnp = 1; module_param_named(nopnp, smsc_nopnp, bool, 0); MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings"); -- cgit v1.2.3 From 2391dae3e36c19fe668c71eac2eb8344dbaaf46d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 1 Jul 2007 12:07:33 -0700 Subject: PM: introduce set_target method in pm_ops Commit 52ade9b3b97fd3bea42842a056fe0786c28d0555 changed the suspend code ordering to execute pm_ops->prepare() after the device model per-device .suspend() calls in order to fix some ACPI-related issues. Unfortunately, it broke the at91 platform which assumed that pm_ops->prepare() would be called before suspending devices. at91 used pm_ops->prepare() to get notified of the target system sleep state, so that it could use this information while suspending devices. However, with the current suspend code ordering pm_ops->prepare() is called too late for this purpose. Thus, at91 needs an additional method in 'struct pm_ops' that will be used for notifying the platform of the target system sleep state. Moreover, in the future such a method will also be needed by ACPI. This patch adds the .set_target() method to 'struct pm_ops' and makes the suspend code call it, if implemented, before executing the device model per-device .suspend() calls. It also modifies the at91 code to use pm_ops->set_target() instead of pm_ops->prepare(). Signed-off-by: Rafael J. Wysocki Acked-by: David Brownell Cc: Pavel Machek Cc: Johannes Berg Cc: Len Brown Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/mach-at91/pm.c | 4 ++-- include/linux/pm.h | 62 +++++++++++++++++++++++++++++++++++++------------ kernel/power/main.c | 6 ++++- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 47ff676aca5f..ddf9184d561d 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -53,7 +53,7 @@ static suspend_state_t target_state; /* * Called after processes are frozen, but before we shutdown devices. */ -static int at91_pm_prepare(suspend_state_t state) +static int at91_pm_set_target(suspend_state_t state) { target_state = state; return 0; @@ -201,7 +201,7 @@ error: static struct pm_ops at91_pm_ops ={ .valid = at91_pm_valid_state, - .prepare = at91_pm_prepare, + .set_target = at91_pm_set_target, .enter = at91_pm_enter, }; diff --git a/include/linux/pm.h b/include/linux/pm.h index 87545e0f0b58..b2c4fde4e994 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -110,37 +110,67 @@ typedef int __bitwise suspend_state_t; #define PM_SUSPEND_MAX ((__force suspend_state_t) 4) /** - * struct pm_ops - Callbacks for managing platform dependent suspend states. - * @valid: Callback to determine whether the given state can be entered. - * Valid states are advertised in /sys/power/state but can still - * be rejected by prepare or enter if the conditions aren't right. - * There is a %pm_valid_only_mem function available that can be assigned - * to this if you only implement mem sleep. + * struct pm_ops - Callbacks for managing platform dependent system sleep + * states. * - * @prepare: Prepare the platform for the given suspend state. Can return a - * negative error code if necessary. + * @valid: Callback to determine if given system sleep state is supported by + * the platform. + * Valid (ie. supported) states are advertised in /sys/power/state. Note + * that it still may be impossible to enter given system sleep state if the + * conditions aren't right. + * There is the %pm_valid_only_mem function available that can be assigned + * to this if the platform only supports mem sleep. * - * @enter: Enter the given suspend state, must be assigned. Can return a - * negative error code if necessary. + * @set_target: Tell the platform which system sleep state is going to be + * entered. + * @set_target() is executed right prior to suspending devices. The + * information conveyed to the platform code by @set_target() should be + * disregarded by the platform as soon as @finish() is executed and if + * @prepare() fails. If @set_target() fails (ie. returns nonzero), + * @prepare(), @enter() and @finish() will not be called by the PM core. + * This callback is optional. However, if it is implemented, the argument + * passed to @prepare(), @enter() and @finish() is meaningless and should + * be ignored. * - * @finish: Called when the system has left the given state and all devices - * are resumed. The return value is ignored. + * @prepare: Prepare the platform for entering the system sleep state indicated + * by @set_target() or represented by the argument if @set_target() is not + * implemented. + * @prepare() is called right after devices have been suspended (ie. the + * appropriate .suspend() method has been executed for each device) and + * before the nonboot CPUs are disabled (it is executed with IRQs enabled). + * This callback is optional. It returns 0 on success or a negative + * error code otherwise, in which case the system cannot enter the desired + * sleep state (@enter() and @finish() will not be called in that case). + * + * @enter: Enter the system sleep state indicated by @set_target() or + * represented by the argument if @set_target() is not implemented. + * This callback is mandatory. It returns 0 on success or a negative + * error code otherwise, in which case the system cannot enter the desired + * sleep state. + * + * @finish: Called when the system has just left a sleep state, right after + * the nonboot CPUs have been enabled and before devices are resumed (it is + * executed with IRQs enabled). If @set_target() is not implemented, the + * argument represents the sleep state being left. + * This callback is optional, but should be implemented by the platforms + * that implement @prepare(). If implemented, it is always called after + * @enter() (even if @enter() fails). */ struct pm_ops { int (*valid)(suspend_state_t state); + int (*set_target)(suspend_state_t state); int (*prepare)(suspend_state_t state); int (*enter)(suspend_state_t state); int (*finish)(suspend_state_t state); }; +extern struct pm_ops *pm_ops; + /** * pm_set_ops - set platform dependent power management ops * @pm_ops: The new power management operations to set. */ extern void pm_set_ops(struct pm_ops *pm_ops); -extern struct pm_ops *pm_ops; -extern int pm_suspend(suspend_state_t state); - extern int pm_valid_only_mem(suspend_state_t state); /** @@ -161,6 +191,8 @@ extern void arch_suspend_disable_irqs(void); */ extern void arch_suspend_enable_irqs(void); +extern int pm_suspend(suspend_state_t state); + /* * Device power management */ diff --git a/kernel/power/main.c b/kernel/power/main.c index 8812985f3029..fc45ed22620f 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -97,6 +96,11 @@ static int suspend_prepare(suspend_state_t state) } } + if (pm_ops->set_target) { + error = pm_ops->set_target(state); + if (error) + goto Thaw; + } suspend_console(); error = device_suspend(PMSG_SUSPEND); if (error) { -- cgit v1.2.3 From a38d6181ff27824c79fc7df825164a212eff6a3f Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 1 Jul 2007 12:54:24 -0700 Subject: Linux 2.6.22-rc7 Last -rc? That's the plan.. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8a3c2717e388..c6f7b71eae81 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 22 -EXTRAVERSION = -rc6 +EXTRAVERSION = -rc7 NAME = Holy Dancing Manatees, Batman! # *DOCUMENTATION* -- cgit v1.2.3 From 4a3207a3339955047aab1fd5d808f8050d50dd85 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 2 Jul 2007 13:49:15 +0800 Subject: Blackfin arch: update board defconfig files Signed-off-by: Mike Frysinger Signed-off-by: Bryan Wu --- arch/blackfin/configs/BF533-EZKIT_defconfig | 12 +++++++++++- arch/blackfin/configs/BF533-STAMP_defconfig | 26 ++++++++++++++++++++++---- arch/blackfin/configs/BF537-STAMP_defconfig | 26 ++++++++++++++++++++++---- arch/blackfin/configs/BF561-EZKIT_defconfig | 12 ++++++++++-- arch/blackfin/configs/PNAV-10_defconfig | 13 +++++++++++-- 5 files changed, 76 insertions(+), 13 deletions(-) diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig index 90d58aabe693..1cf1ab28dc66 100644 --- a/arch/blackfin/configs/BF533-EZKIT_defconfig +++ b/arch/blackfin/configs/BF533-EZKIT_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21.3 +# Linux kernel version: 2.6.21.5 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -115,17 +115,26 @@ CONFIG_BF533=y # CONFIG_BF534 is not set # CONFIG_BF536 is not set # CONFIG_BF537 is not set +# CONFIG_BF542 is not set +# CONFIG_BF544 is not set +# CONFIG_BF548 is not set +# CONFIG_BF549 is not set # CONFIG_BF561 is not set +# CONFIG_BF_REV_0_0 is not set # CONFIG_BF_REV_0_2 is not set CONFIG_BF_REV_0_3=y # CONFIG_BF_REV_0_4 is not set # CONFIG_BF_REV_0_5 is not set +# CONFIG_BF_REV_ANY is not set +# CONFIG_BF_REV_NONE is not set +CONFIG_BF53x=y CONFIG_BFIN_SINGLE_CORE=y CONFIG_BFIN533_EZKIT=y # CONFIG_BFIN533_STAMP is not set # CONFIG_BFIN537_STAMP is not set # CONFIG_BFIN533_BLUETECHNIX_CM is not set # CONFIG_BFIN537_BLUETECHNIX_CM is not set +# CONFIG_BFIN548_EZKIT is not set # CONFIG_BFIN561_BLUETECHNIX_CM is not set # CONFIG_BFIN561_EZKIT is not set # CONFIG_BFIN561_TEPLA is not set @@ -634,6 +643,7 @@ CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y +# CONFIG_SMSC911X is not set # # Ethernet (1000 Mbit) diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig index fee918957392..64b7f1b3b2af 100644 --- a/arch/blackfin/configs/BF533-STAMP_defconfig +++ b/arch/blackfin/configs/BF533-STAMP_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21.3 +# Linux kernel version: 2.6.21.5 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -115,17 +115,26 @@ CONFIG_BF533=y # CONFIG_BF534 is not set # CONFIG_BF536 is not set # CONFIG_BF537 is not set +# CONFIG_BF542 is not set +# CONFIG_BF544 is not set +# CONFIG_BF548 is not set +# CONFIG_BF549 is not set # CONFIG_BF561 is not set +# CONFIG_BF_REV_0_0 is not set # CONFIG_BF_REV_0_2 is not set CONFIG_BF_REV_0_3=y # CONFIG_BF_REV_0_4 is not set # CONFIG_BF_REV_0_5 is not set +# CONFIG_BF_REV_ANY is not set +# CONFIG_BF_REV_NONE is not set +CONFIG_BF53x=y CONFIG_BFIN_SINGLE_CORE=y # CONFIG_BFIN533_EZKIT is not set CONFIG_BFIN533_STAMP=y # CONFIG_BFIN537_STAMP is not set # CONFIG_BFIN533_BLUETECHNIX_CM is not set # CONFIG_BFIN537_BLUETECHNIX_CM is not set +# CONFIG_BFIN548_EZKIT is not set # CONFIG_BFIN561_BLUETECHNIX_CM is not set # CONFIG_BFIN561_EZKIT is not set # CONFIG_BFIN561_TEPLA is not set @@ -646,6 +655,7 @@ CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y +# CONFIG_SMSC911X is not set # # Ethernet (1000 Mbit) @@ -986,9 +996,17 @@ CONFIG_SND_VERBOSE_PROCFS=y # # ALSA Blackfin devices # -# CONFIG_SND_BLACKFIN_AD1836 is not set -# CONFIG_SND_BLACKFIN_AD1981B is not set -# CONFIG_SND_BFIN_AD73311 is not set +CONFIG_SND_BLACKFIN_AD1836=m +CONFIG_SND_BLACKFIN_AD1836_TDM=y +# CONFIG_SND_BLACKFIN_AD1836_I2S is not set +CONFIG_SND_BLACKFIN_AD1836_MULSUB=y +# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set +CONFIG_SND_BLACKFIN_AD1981B=m +CONFIG_SND_BLACKFIN_SPORT=0 +CONFIG_SND_BLACKFIN_SPI_PFBIT=4 +CONFIG_SND_BFIN_AD73311=m +CONFIG_SND_BFIN_SPORT=0 +CONFIG_SND_BFIN_AD73311_SE=4 # # SoC audio support diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig index 37688bb55b9a..ccf09dc09a18 100644 --- a/arch/blackfin/configs/BF537-STAMP_defconfig +++ b/arch/blackfin/configs/BF537-STAMP_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21.3 +# Linux kernel version: 2.6.21.5 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -115,17 +115,26 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_BF534 is not set # CONFIG_BF536 is not set CONFIG_BF537=y +# CONFIG_BF542 is not set +# CONFIG_BF544 is not set +# CONFIG_BF548 is not set +# CONFIG_BF549 is not set # CONFIG_BF561 is not set +# CONFIG_BF_REV_0_0 is not set CONFIG_BF_REV_0_2=y # CONFIG_BF_REV_0_3 is not set # CONFIG_BF_REV_0_4 is not set # CONFIG_BF_REV_0_5 is not set +# CONFIG_BF_REV_ANY is not set +# CONFIG_BF_REV_NONE is not set +CONFIG_BF53x=y CONFIG_BFIN_SINGLE_CORE=y # CONFIG_BFIN533_EZKIT is not set # CONFIG_BFIN533_STAMP is not set CONFIG_BFIN537_STAMP=y # CONFIG_BFIN533_BLUETECHNIX_CM is not set # CONFIG_BFIN537_BLUETECHNIX_CM is not set +# CONFIG_BFIN548_EZKIT is not set # CONFIG_BFIN561_BLUETECHNIX_CM is not set # CONFIG_BFIN561_EZKIT is not set # CONFIG_BFIN561_TEPLA is not set @@ -664,6 +673,7 @@ CONFIG_BFIN_MAC_USE_L1=y CONFIG_BFIN_TX_DESC_NUM=10 CONFIG_BFIN_RX_DESC_NUM=20 # CONFIG_BFIN_MAC_RMII is not set +# CONFIG_SMSC911X is not set # # Ethernet (1000 Mbit) @@ -1020,9 +1030,17 @@ CONFIG_SND_VERBOSE_PROCFS=y # # ALSA Blackfin devices # -# CONFIG_SND_BLACKFIN_AD1836 is not set -# CONFIG_SND_BLACKFIN_AD1981B is not set -# CONFIG_SND_BFIN_AD73311 is not set +CONFIG_SND_BLACKFIN_AD1836=m +CONFIG_SND_BLACKFIN_AD1836_TDM=y +# CONFIG_SND_BLACKFIN_AD1836_I2S is not set +CONFIG_SND_BLACKFIN_AD1836_MULSUB=y +# CONFIG_SND_BLACKFIN_AD1836_5P1 is not set +CONFIG_SND_BLACKFIN_AD1981B=m +CONFIG_SND_BLACKFIN_SPORT=0 +CONFIG_SND_BLACKFIN_SPI_PFBIT=4 +CONFIG_SND_BFIN_AD73311=m +CONFIG_SND_BFIN_SPORT=0 +CONFIG_SND_BFIN_AD73311_SE=4 # # SoC audio support diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig index fe4e67debaca..51c0b6f97798 100644 --- a/arch/blackfin/configs/BF561-EZKIT_defconfig +++ b/arch/blackfin/configs/BF561-EZKIT_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21.3 +# Linux kernel version: 2.6.21.5 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -115,17 +115,25 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_BF534 is not set # CONFIG_BF536 is not set # CONFIG_BF537 is not set +# CONFIG_BF542 is not set +# CONFIG_BF544 is not set +# CONFIG_BF548 is not set +# CONFIG_BF549 is not set CONFIG_BF561=y +# CONFIG_BF_REV_0_0 is not set # CONFIG_BF_REV_0_2 is not set CONFIG_BF_REV_0_3=y # CONFIG_BF_REV_0_4 is not set # CONFIG_BF_REV_0_5 is not set +# CONFIG_BF_REV_ANY is not set +# CONFIG_BF_REV_NONE is not set CONFIG_BFIN_DUAL_CORE=y # CONFIG_BFIN533_EZKIT is not set # CONFIG_BFIN533_STAMP is not set # CONFIG_BFIN537_STAMP is not set # CONFIG_BFIN533_BLUETECHNIX_CM is not set # CONFIG_BFIN537_BLUETECHNIX_CM is not set +# CONFIG_BFIN548_EZKIT is not set # CONFIG_BFIN561_BLUETECHNIX_CM is not set CONFIG_BFIN561_EZKIT=y # CONFIG_BFIN561_TEPLA is not set @@ -673,6 +681,7 @@ CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_MII=y CONFIG_SMC91X=y +# CONFIG_SMSC911X is not set # # Ethernet (1000 Mbit) @@ -801,7 +810,6 @@ CONFIG_WATCHDOG=y CONFIG_BFIN_WDT=y CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set -# CONFIG_BLACKFIN_DPMC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set diff --git a/arch/blackfin/configs/PNAV-10_defconfig b/arch/blackfin/configs/PNAV-10_defconfig index a783ff69ace1..983ed181c896 100644 --- a/arch/blackfin/configs/PNAV-10_defconfig +++ b/arch/blackfin/configs/PNAV-10_defconfig @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21.3 +# Linux kernel version: 2.6.21.5 # # CONFIG_MMU is not set # CONFIG_FPU is not set @@ -114,17 +114,26 @@ CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_BF534 is not set # CONFIG_BF536 is not set CONFIG_BF537=y +# CONFIG_BF542 is not set +# CONFIG_BF544 is not set +# CONFIG_BF548 is not set +# CONFIG_BF549 is not set # CONFIG_BF561 is not set +# CONFIG_BF_REV_0_0 is not set CONFIG_BF_REV_0_2=y # CONFIG_BF_REV_0_3 is not set # CONFIG_BF_REV_0_4 is not set # CONFIG_BF_REV_0_5 is not set +# CONFIG_BF_REV_ANY is not set +# CONFIG_BF_REV_NONE is not set +CONFIG_BF53x=y CONFIG_BFIN_SINGLE_CORE=y # CONFIG_BFIN533_EZKIT is not set # CONFIG_BFIN533_STAMP is not set # CONFIG_BFIN537_STAMP is not set # CONFIG_BFIN533_BLUETECHNIX_CM is not set # CONFIG_BFIN537_BLUETECHNIX_CM is not set +# CONFIG_BFIN548_EZKIT is not set # CONFIG_BFIN561_BLUETECHNIX_CM is not set # CONFIG_BFIN561_EZKIT is not set # CONFIG_BFIN561_TEPLA is not set @@ -598,6 +607,7 @@ CONFIG_BFIN_MAC=y CONFIG_BFIN_TX_DESC_NUM=100 CONFIG_BFIN_RX_DESC_NUM=100 CONFIG_BFIN_MAC_RMII=y +# CONFIG_SMSC911X is not set # # Ethernet (1000 Mbit) @@ -746,7 +756,6 @@ CONFIG_CAN_BLACKFIN=m # CONFIG_WATCHDOG is not set CONFIG_HW_RANDOM=y # CONFIG_GEN_RTC is not set -CONFIG_BLACKFIN_DPMC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set -- cgit v1.2.3 From b245fb675bf03d716b84dcb40885aeb50041dcca Mon Sep 17 00:00:00 2001 From: Maik Hampel Date: Thu, 28 Jun 2007 17:07:26 +0200 Subject: myri10ge: SET_NETDEV_DEV() SET_NETDEV_DEV() in myri10ge to create the "/sys/class/net//device" symlink. Signed-off-by: Maik Hampel Signed-off-by: Jeff Garzik --- drivers/net/myri10ge/myri10ge.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 0f9904fe3a5a..d0cc122fa3f0 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -2854,6 +2854,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return -ENOMEM; } + SET_NETDEV_DEV(netdev, &pdev->dev); + mgp = netdev_priv(netdev); memset(mgp, 0, sizeof(*mgp)); mgp->dev = netdev; -- cgit v1.2.3 From 983b7dc07f083d7d78f408a6f841b399b954767d Mon Sep 17 00:00:00 2001 From: maximilian attems Date: Sun, 24 Jun 2007 23:36:45 +0200 Subject: starfire list alpha as 64 bit arch instead of: "This driver has not been ported to this 64-bit architecture yet." the driver is said to work on alpha, see http://bugs.debian.org/305330 Signed-off-by: maximilian attems Signed-off-by: Jeff Garzik --- drivers/net/starfire.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 9d6e454a8f98..786d4b9c07ec 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -152,7 +152,7 @@ static int full_duplex[MAX_UNITS] = {0, }; * This SUCKS. * We need a much better method to determine if dma_addr_t is 64-bit. */ -#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) +#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) /* 64-bit dma_addr_t */ #define ADDR_64BITS /* This chip uses 64 bit addresses. */ #define netdrv_addr_t u64 -- cgit v1.2.3 From 23de559b8d3537f972f325e7e015c18aa2e4d987 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Wed, 27 Jun 2007 08:14:50 +0200 Subject: dm9601: HW header size shouldn't be included in packet length The dm9601 driver was including the 2 byte hardware header in the packet length, causing the HW to send 2 extra bytes of garbage on tx. Signed-off-by: Peter Korsgaard Signed-off-by: Jeff Garzik --- drivers/net/usb/dm9601.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index a67638601477..ac200b0f6a92 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -489,6 +489,8 @@ static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb, b3..n: packet data */ + len = skb->len; + if (skb_headroom(skb) < DM_TX_OVERHEAD) { struct sk_buff *skb2; @@ -501,10 +503,9 @@ static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb, __skb_push(skb, DM_TX_OVERHEAD); - len = skb->len; /* usbnet adds padding if length is a multiple of packet size if so, adjust length value in header */ - if ((len % dev->maxpacket) == 0) + if ((skb->len % dev->maxpacket) == 0) len++; skb->data[0] = len; -- cgit v1.2.3 From 3e323f3e86196eec18d6959585aa3188d060c43b Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Wed, 27 Jun 2007 08:48:15 +0200 Subject: usbnet: Zero padding byte if there is tail room in skb Usbnet adds a padding byte if a 0 byte USB packet would be sent. Zero padding byte if there is tail room in skb. Signed-of-by: Peter Korsgaard Acked-by: David Brownell Signed-off-by: Jeff Garzik --- drivers/net/usb/usbnet.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 5b16d9a1269a..a12f576391cf 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -953,11 +953,14 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) /* don't assume the hardware handles USB_ZERO_PACKET * NOTE: strictly conforming cdc-ether devices should expect * the ZLP here, but ignore the one-byte packet. - * - * FIXME zero that byte, if it doesn't require a new skb. */ - if ((length % dev->maxpacket) == 0) + if ((length % dev->maxpacket) == 0) { urb->transfer_buffer_length++; + if (skb_tailroom(skb)) { + skb->data[skb->len] = 0; + __skb_put(skb, 1); + } + } spin_lock_irqsave (&dev->txq.lock, flags); -- cgit v1.2.3 From 043600a62a45b2d5cac262fca9012fc24db19964 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Wed, 27 Jun 2007 21:18:18 +0200 Subject: Update MAINTAINERS for USB network devices >>>>> "Greg" == Greg KH writes: Greg> Yeah, this is the cdc_acm driver that is still in the USB drivers/ Greg> directory tree as it is a USB class driver that shows up as a tty device Greg> to userspace. It should not be moved to the networking list unless no Greg> one minds that I never see any queries about it :) Ok, here's an updated patch: Questions regarding the USB network drivers should now go to netdev. Signed-off-by: Peter Korsgaard Acked-by: David Brownell Signed-off-by: Jeff Garzik --- MAINTAINERS | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 4ce895a4b5ba..23a04f431283 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3618,7 +3618,7 @@ W: http://www.kroah.com/linux-usb/ USB DAVICOM DM9601 DRIVER P: Peter Korsgaard M: jacmet@sunsite.dk -L: linux-usb-devel@lists.sourceforge.net +L: netdev@vger.kernel.org W: http://www.linux-usb.org/usbnet S: Maintained @@ -3702,8 +3702,8 @@ S: Maintained USB PEGASUS DRIVER P: Petko Manolov M: petkan@users.sourceforge.net -L: linux-usb-users@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net +L: netdev@vger.kernel.org W: http://pegasus2.sourceforge.net/ S: Maintained @@ -3717,8 +3717,8 @@ S: Maintained USB RTL8150 DRIVER P: Petko Manolov M: petkan@users.sourceforge.net -L: linux-usb-users@lists.sourceforge.net L: linux-usb-devel@lists.sourceforge.net +L: netdev@vger.kernel.org W: http://pegasus2.sourceforge.net/ S: Maintained @@ -3829,7 +3829,7 @@ S: Maintained USB "USBNET" DRIVER FRAMEWORK P: David Brownell M: dbrownell@users.sourceforge.net -L: linux-usb-devel@lists.sourceforge.net +L: netdev@vger.kernel.org W: http://www.linux-usb.org/usbnet S: Maintained -- cgit v1.2.3 From b8f59586cecdb612cd31f4d9e7904f46277ddd64 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Sat, 30 Jun 2007 23:07:42 +0200 Subject: dm9601: Return 0 from bind() on success Fixup dm9601_bind() so it returns 0 on success rather than just a positive number, as otherwise usbnet doesn't init the status handler. Signed-off-by: Peter Korsgaard Signed-off-by: Jeff Garzik --- drivers/net/usb/dm9601.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index ac200b0f6a92..16c7a0e87850 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -414,18 +414,16 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) dev->mii.reg_num_mask = 0x1f; /* reset */ - ret = dm_write_reg(dev, DM_NET_CTRL, 1); + dm_write_reg(dev, DM_NET_CTRL, 1); udelay(20); /* read MAC */ - ret = dm_read(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr); - if (ret < 0) { + if (dm_read(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr) < 0) { printk(KERN_ERR "Error reading MAC address\n"); ret = -ENODEV; goto out; } - /* power up phy */ dm_write_reg(dev, DM_GPR_CTRL, 1); dm_write_reg(dev, DM_GPR_DATA, 0); -- cgit v1.2.3 From 644caeefb3bbf539e74b7098648ff0bfc9e52bb3 Mon Sep 17 00:00:00 2001 From: "dhananjay.phadke@gmail.com" Date: Mon, 2 Jul 2007 00:25:59 +0530 Subject: RESEND [PATCH 1/3] NetXen: Fix issue of MSI not working correctly NetXen driver uses PCI function 0 to provide the functionality of MSI. The patch makes driver check the bus master bit for function 0 and enable it after the card initialization. Signed-off-by: Dhananjay Phadke Signed-off-by: Milan Bag Signed-off-by: Wen Xiong Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic_main.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 6167b58d2731..663bc47c1f63 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -336,11 +336,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; - if (pci_enable_msi(pdev)) { + if (pci_enable_msi(pdev)) adapter->flags &= ~NETXEN_NIC_MSI_ENABLED; - printk(KERN_WARNING "%s: unable to allocate MSI interrupt" - " error\n", netxen_nic_driver_name); - } else + else adapter->flags |= NETXEN_NIC_MSI_ENABLED; netdev->irq = pdev->irq; @@ -355,13 +353,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* initialize the adapter */ netxen_initialize_adapter_hw(adapter); -#ifdef CONFIG_PPC - if ((adapter->ahw.boardcfg.board_type == - NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) && - (pci_func_id == 2)) - goto err_out_free_adapter; -#endif /* CONFIG_PPC */ - /* * Adapter in our case is quad port so initialize it before * initializing the ports @@ -509,16 +500,22 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) NETXEN_CAM_RAM(0x1fc))); if (val == 0x55555555) { /* This is the first boot after power up */ + netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); + if (!(val & 0x4)) { + val |= 0x4; + netxen_nic_write_w0(adapter, NETXEN_PCIE_REG(0x4), val); + netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); + } val = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_SW_RESET)); printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val); if (val != 0x80000f) { /* clear the register for future unloads/loads */ - writel(0, NETXEN_CRB_NORMALIZE(adapter, - NETXEN_CAM_RAM(0x1fc))); - printk(KERN_ERR "ERROR in NetXen HW init sequence.\n"); - err = -ENODEV; - goto err_out_free_dev; + writel(0, NETXEN_CRB_NORMALIZE(adapter, + NETXEN_CAM_RAM(0x1fc))); + printk(KERN_ERR "ERROR in NetXen HW init sequence.\n"); + err = -ENODEV; + goto err_out_free_dev; } /* clear the register for future unloads/loads */ -- cgit v1.2.3 From 2d1a3bbdf21d05e16703c8d608628ae4676eb3ac Mon Sep 17 00:00:00 2001 From: "dhananjay.phadke@gmail.com" Date: Mon, 2 Jul 2007 00:26:00 +0530 Subject: RESEND [PATCH 2/3] NetXen: Support per PCI-function interrupt mask registers This patch updates the various access routines to access different control and status settings present in different register locations. This will fix problems related to working of different ports in multi Port card. Signed-off by: Dhananjay Phadke Signed-off by: Milan Bag Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 102 ++++++++++++++++++++++++++----- drivers/net/netxen/netxen_nic_hw.c | 6 +- drivers/net/netxen/netxen_nic_init.c | 2 + drivers/net/netxen/netxen_nic_main.c | 30 +++++---- drivers/net/netxen/netxen_nic_phan_reg.h | 14 +++++ 5 files changed, 124 insertions(+), 30 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 91f25e0a638e..6ce93fcbed32 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -937,6 +937,7 @@ struct netxen_adapter { struct netxen_ring_ctx *ctx_desc; struct pci_dev *ctx_desc_pdev; dma_addr_t ctx_desc_phys_addr; + int intr_scheme; int (*enable_phy_interrupts) (struct netxen_adapter *); int (*disable_phy_interrupts) (struct netxen_adapter *); void (*handle_phy_intr) (struct netxen_adapter *); @@ -1080,37 +1081,106 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); static inline void netxen_nic_disable_int(struct netxen_adapter *adapter) { - /* - * ISR_INT_MASK: Can be read from window 0 or 1. - */ - writel(0x7ff, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); + uint32_t mask = 0x7ff; + int retries = 32; + + DPRINTK(1, INFO, "Entered ISR Disable \n"); + + switch (adapter->portnum) { + case 0: + writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); + break; + case 1: + writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); + break; + case 2: + writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); + break; + case 3: + writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); + break; + } + + if (adapter->intr_scheme != -1 && + adapter->intr_scheme != INTR_SCHEME_PERPORT) { + writel(mask, + (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK))); + } + + /* Window = 0 or 1 */ + if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { + do { + writel(0xffffffff, (void *) + (PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS))); + mask = readl((void *) + (pci_base_offset(adapter, ISR_INT_VECTOR))); + if (!(mask & 0x80)) + break; + udelay(10); + } while (--retries); + + if (!retries) { + printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n", + netxen_nic_driver_name); + } + } + + DPRINTK(1, INFO, "Done with Disable Int\n"); + return; } static inline void netxen_nic_enable_int(struct netxen_adapter *adapter) { u32 mask; - switch (adapter->ahw.board_type) { - case NETXEN_NIC_GBE: - mask = 0x77b; + DPRINTK(1, INFO, "Entered ISR Enable \n"); + + if (adapter->intr_scheme != -1 && + adapter->intr_scheme != INTR_SCHEME_PERPORT) { + switch (adapter->ahw.board_type) { + case NETXEN_NIC_GBE: + mask = 0x77b; + break; + case NETXEN_NIC_XGBE: + mask = 0x77f; + break; + default: + mask = 0x7ff; + break; + } + + writel(mask, + (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK))); + } + switch (adapter->portnum) { + case 0: + writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); break; - case NETXEN_NIC_XGBE: - mask = 0x77f; + case 1: + writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); break; - default: - mask = 0x7ff; + case 2: + writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); + break; + case 3: + writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); break; } - writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); - if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { mask = 0xbff; - writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); - writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, - ISR_INT_TARGET_MASK)); + if (adapter->intr_scheme != -1 && + adapter->intr_scheme != INTR_SCHEME_PERPORT) { + writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); + } + writel(mask, + (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK))); } + + DPRINTK(1, INFO, "Done with enable Int\n"); + + return; } /* diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index c012764d1145..2b40a5a19c47 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -392,7 +392,11 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) return err; } } - DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n"); + adapter->intr_scheme = readl( + NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); + printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netdev->name, + adapter->intr_scheme); + DPRINTK(INFO, "Receive Peg ready too. starting stuff\n"); addr = netxen_alloc(adapter->ahw.pdev, sizeof(struct netxen_ring_ctx) + diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index bb23f4c360db..15f6dc5a1cf7 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -139,6 +139,8 @@ int netxen_init_firmware(struct netxen_adapter *adapter) return err; } /* Window 1 call */ + writel(INTR_SCHEME_PERPORT, + NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_HOST)); writel(MPORT_MULTI_FUNCTION_MODE, NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE)); writel(PHAN_INITIALIZE_ACK, diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 663bc47c1f63..dba8e6b29ff3 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -308,7 +308,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->netdev = netdev; adapter->pdev = pdev; + + /* this will be read from FW later */ + adapter->intr_scheme = -1; + + /* This will be reset for mezz cards */ adapter->portnum = pci_func_id; + adapter->status &= ~NETXEN_NETDEV_STATUS; netdev->open = netxen_nic_open; netdev->stop = netxen_nic_close; @@ -1100,28 +1106,26 @@ static int netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) { u32 ret = 0; + u32 our_int = 0; DPRINTK(INFO, "Entered handle ISR\n"); adapter->stats.ints++; if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { - int count = 0; - u32 mask; - u32 our_int = 0; our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); /* not our interrupt */ if ((our_int & (0x80 << adapter->portnum)) == 0) return ret; - netxen_nic_disable_int(adapter); - /* Window = 0 or 1 */ - do { - writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter, - ISR_INT_TARGET_STATUS)); - mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR)); - } while (((mask & 0x80) != 0) && (++count < 32)); - if ((mask & 0x80) != 0) - printk("Could not disable interrupt completely\n"); + } + netxen_nic_disable_int(adapter); + + if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { + /* claim interrupt */ + if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { + writel(our_int & ~((u32)(0x80 << adapter->portnum)), + NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); + } } if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) { @@ -1133,7 +1137,7 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) } else { static unsigned int intcount = 0; if ((++intcount & 0xfff) == 0xfff) - printk(KERN_ERR + DPRINTK(KERN_ERR "%s: %s interrupt %d while in poll\n", netxen_nic_driver_name, netdev->name, intcount); diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index 9457fc7249c8..10fe6fafa6f6 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h @@ -114,6 +114,20 @@ #define CRB_V2P_3 NETXEN_NIC_REG(0x29c) #define CRB_V2P(port) (CRB_V2P_0+((port)*4)) #define CRB_DRIVER_VERSION NETXEN_NIC_REG(0x2a0) +/* sw int status/mask registers */ +#define CRB_SW_INT_MASK_0 NETXEN_NIC_REG(0x1d8) +#define CRB_SW_INT_MASK_1 NETXEN_NIC_REG(0x1e0) +#define CRB_SW_INT_MASK_2 NETXEN_NIC_REG(0x1e4) +#define CRB_SW_INT_MASK_3 NETXEN_NIC_REG(0x1e8) + +/* + * capabilities register, can be used to selectively enable/disable features + * for backward compability + */ +#define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8) +#define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc) + +#define INTR_SCHEME_PERPORT 0x1 /* used for ethtool tests */ #define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280) -- cgit v1.2.3 From afaee82c0aef7c2b30acff129c723031343e10c2 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 1 Jul 2007 11:47:59 -0700 Subject: net/usb/cdc_ether minor sparse cleanup Remove an "sparse" warning about a shadowed variable name. Signed-off-by: David Brownell Signed-off-by: Jeff Garzik --- drivers/net/usb/cdc_ether.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 675ac99a79c6..a42acc3cc609 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -144,14 +144,14 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) * modem interface from an RNDIS non-modem. */ if (rndis) { - struct usb_cdc_acm_descriptor *d; + struct usb_cdc_acm_descriptor *acm; - d = (void *) buf; - if (d->bmCapabilities) { + acm = (void *) buf; + if (acm->bmCapabilities) { dev_dbg(&intf->dev, "ACM capabilities %02x, " "not really RNDIS?\n", - d->bmCapabilities); + acm->bmCapabilities); goto bad_desc; } } -- cgit v1.2.3 From d14e37e12087e98b63907518dff83a90297605d6 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 1 Jul 2007 22:21:10 +0200 Subject: drivers/net/ns83820.c: fix a check-after-use This patch fixes a check-after-use spotted by the Coverity checker. Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/net/ns83820.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 717d8e9b9833..104aab3c957f 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -1831,11 +1831,13 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ ndev = alloc_etherdev(sizeof(struct ns83820)); dev = PRIV(ndev); - dev->ndev = ndev; + err = -ENOMEM; if (!dev) goto out; + dev->ndev = ndev; + spin_lock_init(&dev->rx_info.lock); spin_lock_init(&dev->tx_lock); spin_lock_init(&dev->misc_lock); -- cgit v1.2.3 From 96acb6eb8effe7c2549909e2ee49f4130f2c167d Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Mon, 2 Jul 2007 09:37:57 +0530 Subject: RESEND [PATCH 3/3] NetXen: Graceful teardown of interface and hardware upon module unload Resending patch 3/3 only. These changes allow driver close routine to be called during module unload, to clean-up buffers and other software resources, flush queues etc. Also, hardware is reset to pristine state. Signed-off-by: Dhananjay Phadke Signed-off-by: Milan Bag Signed-off-by: Wen Xiong Signed-off-by: Jeff Garzik --- drivers/net/netxen/netxen_nic.h | 78 ++++++++++++++++++++- drivers/net/netxen/netxen_nic_hdr.h | 2 + drivers/net/netxen/netxen_nic_hw.c | 29 +++++--- drivers/net/netxen/netxen_nic_init.c | 49 ++++++++------ drivers/net/netxen/netxen_nic_main.c | 128 +++++++++++++++++++++++------------ 5 files changed, 210 insertions(+), 76 deletions(-) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 6ce93fcbed32..619503742b7d 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -952,6 +952,24 @@ struct netxen_adapter { int (*stop_port) (struct netxen_adapter *); }; /* netxen_adapter structure */ +/* + * NetXen dma watchdog control structure + * + * Bit 0 : enabled => R/O: 1 watchdog active, 0 inactive + * Bit 1 : disable_request => 1 req disable dma watchdog + * Bit 2 : enable_request => 1 req enable dma watchdog + * Bit 3-31 : unused + */ + +#define netxen_set_dma_watchdog_disable_req(config_word) \ + _netxen_set_bits(config_word, 1, 1, 1) +#define netxen_set_dma_watchdog_enable_req(config_word) \ + _netxen_set_bits(config_word, 2, 1, 1) +#define netxen_get_dma_watchdog_enabled(config_word) \ + ((config_word) & 0x1) +#define netxen_get_dma_watchdog_disabled(config_word) \ + (((config_word) >> 1) & 0x1) + /* Max number of xmit producer threads that can run simultaneously */ #define MAX_XMIT_PRODUCERS 16 @@ -1031,8 +1049,8 @@ int netxen_nic_erase_pxe(struct netxen_adapter *adapter); /* Functions from netxen_nic_init.c */ void netxen_free_adapter_offload(struct netxen_adapter *adapter); int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); -void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); -void netxen_load_firmware(struct netxen_adapter *adapter); +int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); +int netxen_load_firmware(struct netxen_adapter *adapter); int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, @@ -1234,6 +1252,62 @@ static inline void get_brd_name_by_type(u32 type, char *name) name = "Unknown"; } +static inline int +dma_watchdog_shutdown_request(struct netxen_adapter *adapter) +{ + u32 ctrl; + + /* check if already inactive */ + if (netxen_nic_hw_read_wx(adapter, + NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) + printk(KERN_ERR "failed to read dma watchdog status\n"); + + if (netxen_get_dma_watchdog_enabled(ctrl) == 0) + return 1; + + /* Send the disable request */ + netxen_set_dma_watchdog_disable_req(ctrl); + netxen_crb_writelit_adapter(adapter, + NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl); + + return 0; +} + +static inline int +dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter) +{ + u32 ctrl; + + if (netxen_nic_hw_read_wx(adapter, + NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) + printk(KERN_ERR "failed to read dma watchdog status\n"); + + return ((netxen_get_dma_watchdog_enabled(ctrl) == 0) && + (netxen_get_dma_watchdog_disabled(ctrl) == 0)); +} + +static inline int +dma_watchdog_wakeup(struct netxen_adapter *adapter) +{ + u32 ctrl; + + if (netxen_nic_hw_read_wx(adapter, + NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) + printk(KERN_ERR "failed to read dma watchdog status\n"); + + if (netxen_get_dma_watchdog_enabled(ctrl)) + return 1; + + /* send the wakeup request */ + netxen_set_dma_watchdog_enable_req(ctrl); + + netxen_crb_writelit_adapter(adapter, + NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl); + + return 0; +} + + int netxen_is_flash_supported(struct netxen_adapter *adapter); int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]); extern void netxen_change_ringparam(struct netxen_adapter *adapter); diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 608e37b349b4..3276866b17e2 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h @@ -687,4 +687,6 @@ enum { #define PCIE_MAX_MASTER_SPLIT (0x14048) +#define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14) + #endif /* __NETXEN_NIC_HDR_H_ */ diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 2b40a5a19c47..aac15421bd1e 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -377,7 +377,7 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) recv_crb_registers[ctx]. crb_rcvpeg_state)); while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) { - udelay(100); + msleep(1); /* Window 1 call */ state = readl(NETXEN_CRB_NORMALIZE(adapter, recv_crb_registers @@ -394,7 +394,7 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) } adapter->intr_scheme = readl( NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); - printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netdev->name, + printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name, adapter->intr_scheme); DPRINTK(INFO, "Receive Peg ready too. starting stuff\n"); @@ -701,7 +701,7 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) adapter->curr_window = 0; } -void netxen_load_firmware(struct netxen_adapter *adapter) +int netxen_load_firmware(struct netxen_adapter *adapter) { int i; u32 data, size = 0; @@ -713,15 +713,24 @@ void netxen_load_firmware(struct netxen_adapter *adapter) writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); for (i = 0; i < size; i++) { - if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) { - DPRINTK(ERR, - "Error in netxen_rom_fast_read(). Will skip" - "loading flash image\n"); - return; - } + int retries = 10; + if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) + return -EIO; + off = netxen_nic_pci_set_window(adapter, memaddr); addr = pci_base_offset(adapter, off); writel(data, addr); + do { + if (readl(addr) == data) + break; + msleep(100); + writel(data, addr); + } while (--retries); + if (!retries) { + printk(KERN_ERR "%s: firmware load aborted, write failed at 0x%x\n", + netxen_nic_driver_name, memaddr); + return -EIO; + } flashaddr += 4; memaddr += 4; } @@ -731,7 +740,7 @@ void netxen_load_firmware(struct netxen_adapter *adapter) NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL)); writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); - udelay(100); + return 0; } int diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 15f6dc5a1cf7..1811bcb8c380 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -407,10 +407,7 @@ static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr, static inline int do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) { - if (jiffies > (last_schedule_time + (8 * HZ))) { - last_schedule_time = jiffies; - schedule(); - } + cond_resched(); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); @@ -856,10 +853,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) netxen_nic_pci_change_crbwindow(adapter, 1); } if (init_delay == 1) { - ssleep(1); + msleep(2000); init_delay = 0; } - msleep(1); + msleep(20); } kfree(buf); @@ -935,10 +932,6 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) void netxen_free_adapter_offload(struct netxen_adapter *adapter) { if (adapter->dummy_dma.addr) { - writel(0, NETXEN_CRB_NORMALIZE(adapter, - CRB_HOST_DUMMY_BUF_ADDR_HI)); - writel(0, NETXEN_CRB_NORMALIZE(adapter, - CRB_HOST_DUMMY_BUF_ADDR_LO)); pci_free_consistent(adapter->ahw.pdev, NETXEN_HOST_DUMMY_DMA_SIZE, adapter->dummy_dma.addr, @@ -947,25 +940,32 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter) } } -void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) +int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) { u32 val = 0; - int loops = 0; + int retries = 30; if (!pegtune_val) { - val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); - while (val != PHAN_INITIALIZE_COMPLETE && - val != PHAN_INITIALIZE_ACK && loops < 200000) { - udelay(100); - schedule(); - val = - readl(NETXEN_CRB_NORMALIZE + do { + val = readl(NETXEN_CRB_NORMALIZE (adapter, CRB_CMDPEG_STATE)); - loops++; + pegtune_val = readl(NETXEN_CRB_NORMALIZE + (adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); + + if (val == PHAN_INITIALIZE_COMPLETE || + val == PHAN_INITIALIZE_ACK) + return 0; + + msleep(1000); + } while (--retries); + if (!retries) { + printk(KERN_WARNING "netxen_phantom_init: init failed, " + "pegtune_val=%x\n", pegtune_val); + return -1; } - if (val != PHAN_INITIALIZE_COMPLETE) - printk("WARNING: Initial boot wait loop failed...\n"); } + + return 0; } int netxen_nic_rx_has_work(struct netxen_adapter *adapter) @@ -1122,6 +1122,7 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, adapter->stats.csummed++; skb->ip_summed = CHECKSUM_UNNECESSARY; } + skb->dev = netdev; if (desc_ctx == RCV_DESC_LRO_CTXID) { /* True length was only available on the last pkt */ skb_put(skb, buffer->lro_length); @@ -1226,6 +1227,7 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) NETXEN_CRB_NORMALIZE(adapter, recv_crb_registers[adapter->portnum]. crb_rcv_status_consumer)); + wmb(); } return count; @@ -1278,11 +1280,13 @@ int netxen_process_cmd_ring(unsigned long data) if (skb && (cmpxchg(&buffer->skb, skb, 0) == skb)) { pci_unmap_single(pdev, frag->dma, frag->length, PCI_DMA_TODEVICE); + frag->dma = 0ULL; for (i = 1; i < buffer->frag_count; i++) { DPRINTK(INFO, "getting fragment no %d\n", i); frag++; /* Get the next frag */ pci_unmap_page(pdev, frag->dma, frag->length, PCI_DMA_TODEVICE); + frag->dma = 0ULL; } adapter->stats.skbfreed++; @@ -1448,6 +1452,7 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) writel(msg, DB_NORMALIZE(adapter, NETXEN_RCV_PRODUCER_OFFSET)); + wmb(); } } } diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index dba8e6b29ff3..a66ff58366cf 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -507,11 +507,14 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (val == 0x55555555) { /* This is the first boot after power up */ netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); - if (!(val & 0x4)) { - val |= 0x4; - netxen_nic_write_w0(adapter, NETXEN_PCIE_REG(0x4), val); - netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); - } + if (!(val & 0x4)) { + val |= 0x4; + netxen_nic_write_w0(adapter, NETXEN_PCIE_REG(0x4), val); + netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); + if (!(val & 0x4)) + printk(KERN_ERR "%s: failed to set MSI bit in PCI-e reg\n", + netxen_nic_driver_name); + } val = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_SW_RESET)); printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val); @@ -523,11 +526,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = -ENODEV; goto err_out_free_dev; } - - /* clear the register for future unloads/loads */ - writel(0, NETXEN_CRB_NORMALIZE(adapter, - NETXEN_CAM_RAM(0x1fc))); } + + /* clear the register for future unloads/loads */ + writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); printk(KERN_INFO "State: 0x%0x\n", readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); @@ -545,13 +547,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); /* Handshake with the card before we register the devices. */ netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); - - /* leave the hw in the same state as reboot */ - writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); - netxen_pinit_from_rom(adapter, 0); - udelay(500); - netxen_load_firmware(adapter); - netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); } /* @@ -642,8 +637,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) struct netxen_rx_buffer *buffer; struct netxen_recv_context *recv_ctx; struct netxen_rcv_desc_ctx *rcv_desc; - int i; - int ctxid, ring; + int i, ctxid, ring; + static int init_firmware_done = 0; adapter = pci_get_drvdata(pdev); if (adapter == NULL) @@ -651,30 +646,20 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) netdev = adapter->netdev; - netxen_nic_disable_int(adapter); - if (adapter->irq) - free_irq(adapter->irq, adapter); - + unregister_netdev(netdev); + if (adapter->stop_port) adapter->stop_port(adapter); - if ((adapter->flags & NETXEN_NIC_MSI_ENABLED)) - pci_disable_msi(pdev); - - if (adapter->portnum == 0) - netxen_free_adapter_offload(adapter); + netxen_nic_disable_int(adapter); - if(adapter->portnum == 0) { - /* leave the hw in the same state as reboot */ - writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); - netxen_pinit_from_rom(adapter, 0); - udelay(500); - netxen_load_firmware(adapter); - netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); - } + if (adapter->irq) + free_irq(adapter->irq, adapter); - if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) + if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { + init_firmware_done++; netxen_free_hw_resources(adapter); + } for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { recv_ctx = &adapter->recv_ctx[ctxid]; @@ -694,17 +679,73 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) } } - unregister_netdev(netdev); + if (adapter->flags & NETXEN_NIC_MSI_ENABLED) + pci_disable_msi(pdev); vfree(adapter->cmd_buf_arr); + pci_disable_device(pdev); + + if (adapter->portnum == 0) { + if (init_firmware_done) { + dma_watchdog_shutdown_request(adapter); + msleep(100); + i = 100; + while ((dma_watchdog_shutdown_poll_result(adapter) != 1) && i) { + printk(KERN_INFO "dma_watchdog_shutdown_poll still in progress\n"); + msleep(100); + i--; + } + + if (i == 0) { + printk(KERN_ERR "dma_watchdog_shutdown_request failed\n"); + return; + } + + /* clear the register for future unloads/loads */ + writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); + printk(KERN_INFO "State: 0x%0x\n", + readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); + + /* leave the hw in the same state as reboot */ + writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); + if (netxen_pinit_from_rom(adapter, 0)) + return; + msleep(1); + if (netxen_load_firmware(adapter)) + return; + netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); + } + + /* clear the register for future unloads/loads */ + writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); + printk(KERN_INFO "State: 0x%0x\n", + readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); + + dma_watchdog_shutdown_request(adapter); + msleep(100); + i = 100; + while ((dma_watchdog_shutdown_poll_result(adapter) != 1) && i) { + printk(KERN_INFO "dma_watchdog_shutdown_poll still in progress\n"); + msleep(100); + i--; + } + + if (i) { + netxen_free_adapter_offload(adapter); + } else { + printk(KERN_ERR "failed to dma shutdown\n"); + return; + } + + } + iounmap(adapter->ahw.db_base); iounmap(adapter->ahw.pci_base0); iounmap(adapter->ahw.pci_base1); iounmap(adapter->ahw.pci_base2); pci_release_regions(pdev); - pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); free_netdev(netdev); @@ -801,7 +842,7 @@ static int netxen_nic_close(struct net_device *netdev) if (buffrag->dma) { pci_unmap_single(adapter->pdev, buffrag->dma, buffrag->length, PCI_DMA_TODEVICE); - buffrag->dma = (u64) NULL; + buffrag->dma = 0ULL; } for (j = 0; j < cmd_buff->frag_count; j++) { buffrag++; @@ -809,7 +850,7 @@ static int netxen_nic_close(struct net_device *netdev) pci_unmap_page(adapter->pdev, buffrag->dma, buffrag->length, PCI_DMA_TODEVICE); - buffrag->dma = (u64) NULL; + buffrag->dma = 0ULL; } } /* Free the skb we received in netxen_nic_xmit_frame */ @@ -819,8 +860,10 @@ static int netxen_nic_close(struct net_device *netdev) } cmd_buff++; } - FLUSH_SCHEDULED_WORK(); - del_timer_sync(&adapter->watchdog_timer); + if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { + FLUSH_SCHEDULED_WORK(); + del_timer_sync(&adapter->watchdog_timer); + } return 0; } @@ -1259,6 +1302,7 @@ static void __exit netxen_exit_module(void) /* * Wait for some time to allow the dma to drain, if any. */ + msleep(100); pci_unregister_driver(&netxen_driver); destroy_workqueue(netxen_workq); } -- cgit v1.2.3 From abcdceb9d0bf39da7c7ff8bcdff6eb4d9dfec56f Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 11 Jun 2007 11:59:34 -0700 Subject: scsi disk help file is not complete On Mon, 11 Jun 2007 20:28:16 +0200 api wrote: > Good day, > When doing make menuconfig one comes across CONFIG_BLK_DEV_SD. > The help file states that this is for scsi disks.NO MENTION IS MADE THAT > IT IS NEEDE FOR SATA DISKS AS WELL! > Would have saved me a lot of time if the help was up to date. > I hope this can be changed so others can make a kernel for sata systems > quicker. From: Randy Dunlap Add help info for BLK_DEV_SD referring to its use in SATA or PATA driver configurations. Add help text for "ATA" indicating that it probably needs some SCSI config symbols enabled in order to be useful. Signed-off-by: Randy Dunlap Signed-off-by: Jeff Garzik --- drivers/ata/Kconfig | 5 +++++ drivers/scsi/Kconfig | 1 + 2 files changed, 6 insertions(+) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index b4a8d6030e48..4ad8675f5a16 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -16,6 +16,11 @@ menuconfig ATA that "speaks" the ATA protocol, also called ATA controller), because you will be asked for it. + NOTE: ATA enables basic SCSI support; *however*, + 'SCSI disk support', 'SCSI tape support', or + 'SCSI CDROM support' may also be needed, + depending on your hardware configuration. + if ATA config ATA_NONSTANDARD diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 2b2f5c12019b..eb46cb0e3cb7 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -60,6 +60,7 @@ config BLK_DEV_SD depends on SCSI ---help--- If you want to use SCSI hard disks, Fibre Channel disks, + Serial ATA (SATA) or Parallel ATA (PATA) hard disks, USB storage or the SCSI or parallel port version of the IOMEGA ZIP drive, say Y and read the SCSI-HOWTO, the Disk-HOWTO and the Multi-Disk-HOWTO, available from -- cgit v1.2.3 From 8c781bf77a339748839bfd5eedfe2ad3e0e05c4a Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Tue, 26 Jun 2007 13:43:15 +0800 Subject: libata: pata_pdc2027x PLL input clock fix Recently the PLL input clock of pata_pdc2027x is sometimes detected higer than expected (e.g. 20.027 MHz compared to 16.714 MHz). It seems sometimes the mdelay() function is not as precise as it used to be. Per Alan's advice, HT or power management might affect the precision of mdelay(). This patch calls gettimeofday() to mesure the time elapsed and calculate the PLL input clock accordingly. Signed-off-by: Albert Lee Cc: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_pdc2027x.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 0d2cc49fde4b..69a5aa4949f5 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -689,10 +689,12 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR]; u32 scr; long start_count, end_count; - long pll_clock; + struct timeval start_time, end_time; + long pll_clock, usec_elapsed; /* Read current counter value */ start_count = pdc_read_counter(host); + do_gettimeofday(&start_time); /* Start the test mode */ scr = readl(mmio_base + PDC_SYS_CTL); @@ -705,6 +707,7 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) /* Read the counter values again */ end_count = pdc_read_counter(host); + do_gettimeofday(&end_time); /* Stop the test mode */ scr = readl(mmio_base + PDC_SYS_CTL); @@ -713,7 +716,11 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) readl(mmio_base + PDC_SYS_CTL); /* flush */ /* calculate the input clock in Hz */ - pll_clock = (start_count - end_count) * 10; + usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 + + (end_time.tv_usec - start_time.tv_usec); + + pll_clock = (start_count - end_count) / 100 * + (100000000 / usec_elapsed); PDPRINTK("start[%ld] end[%ld] \n", start_count, end_count); PDPRINTK("PLL input clock[%ld]Hz\n", pll_clock); -- cgit v1.2.3 From 74cdbba42dd515887ef3fc0ab498e70bd086c075 Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Thu, 28 Jun 2007 10:05:31 +0800 Subject: libata: remove reading alt_status from ata_hsm_qc_complete() In ata_hsm_qc_complete(): Calling ata_altstatus() after the qc is completed might race with next qc. Remove it. Signed-off-by: Albert Lee Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index bfc59a104728..95671d6a0ce5 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4781,8 +4781,6 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq) } else ata_qc_complete(qc); } - - ata_altstatus(ap); /* flush */ } /** -- cgit v1.2.3 From 90c937853d792ea997d7fdec72dbbea4f92e12c4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 29 Jun 2007 11:33:08 +0900 Subject: sata_inic162x: disable LBA48 devices sata_inic162x can't do LBA48 properly yet and is likely to corrupt data on drives larger than LBA28 limit. Disable LBA48 devices during device configuration. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/sata_inic162x.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 2d80c9d95e95..dc3bbce04676 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c @@ -496,6 +496,13 @@ static void inic_dev_config(struct ata_device *dev) /* inic can only handle upto LBA28 max sectors */ if (dev->max_sectors > ATA_MAX_SECTORS) dev->max_sectors = ATA_MAX_SECTORS; + + if (dev->n_sectors >= 1 << 28) { + ata_dev_printk(dev, KERN_ERR, + "ERROR: This driver doesn't support LBA48 yet and may cause\n" + " data corruption on such devices. Disabling.\n"); + ata_dev_disable(dev); + } } static void init_port(struct ata_port *ap) -- cgit v1.2.3 From 1e0b5ab81e2abb8bbf7446f4a17f43a1e34944fe Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Thu, 28 Jun 2007 18:52:24 -0600 Subject: sata_nv: allow changing queue depth The sata_nv driver was missing the change_queue_depth hook in the SCSI host template which the other NCQ-capable libata drivers had. This made it impossible to change the queue depth by user request. Add this in. Signed-off-by: Robert Hancock Signed-off-by: Jeff Garzik --- drivers/ata/sata_nv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index adfa693db53d..d53cb8c47f39 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -307,6 +307,7 @@ static struct scsi_host_template nv_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .change_queue_depth = ata_scsi_change_queue_depth, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, @@ -325,6 +326,7 @@ static struct scsi_host_template nv_adma_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, + .change_queue_depth = ata_scsi_change_queue_depth, .can_queue = NV_ADMA_MAX_CPBS, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN, -- cgit v1.2.3 From e14cbfa630cd3ab2631ee21b718b290928f47868 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Jun 2007 11:28:59 +0900 Subject: libata: add HTS541616J9SA00 to NCQ blacklist Another member of HTS5416* family doing spurious NCQ completion. Signed-off-by: Tejun Heo Cc: Enrico Sardi Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 95671d6a0ce5..2407f8482948 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3798,6 +3798,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { /* Drives which do spurious command completion */ { "HTS541680J9SA00", "SB2IC7EP", ATA_HORKAGE_NONCQ, }, { "HTS541612J9SA00", "SBDIC7JP", ATA_HORKAGE_NONCQ, }, + { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, }, { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, }, /* Devices with NCQ limits */ -- cgit v1.2.3 From a3cabb271ea66739704497102536fb01bb72fe37 Mon Sep 17 00:00:00 2001 From: Uwe Koziolek Date: Thu, 14 Jun 2007 23:40:43 +0200 Subject: libata: PATA-mode fixes for sis_sata Changed PATA handler for PATA-ports used by sata_sis. This patch was originally submitted by Jeff Garzik. Added PCI-ID 1180 for SiS966 Controller in pata_sis. The 1180 mode is fully compatible to other SiS PATA-controller. The PCI-ID 1183 is SATA in PATA-emulation, but not fully compatible to SiS5513/5518. sata_sis.c is forwarding this ID to pata_sis. 1183 is not working if simply added to pata_sis. This handling fixes issues with SiS968. Signed-off-by: Uwe Koziolek Signed-off-by: Jeff Garzik --- drivers/ata/pata_sis.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- drivers/ata/sata_sis.c | 39 +++++++++++++++++++-------------------- drivers/ata/sis.h | 2 +- 3 files changed, 64 insertions(+), 23 deletions(-) diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index ec3ae9375015..cfe4ec6eb3d5 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -560,6 +560,40 @@ static const struct ata_port_operations sis_133_ops = { .port_start = ata_port_start, }; +static const struct ata_port_operations sis_133_for_sata_ops = { + .port_disable = ata_port_disable, + .set_piomode = sis_133_set_piomode, + .set_dmamode = sis_133_set_dmamode, + .mode_filter = ata_pci_default_filter, + + .tf_load = ata_tf_load, + .tf_read = ata_tf_read, + .check_status = ata_check_status, + .exec_command = ata_exec_command, + .dev_select = ata_std_dev_select, + + .freeze = ata_bmdma_freeze, + .thaw = ata_bmdma_thaw, + .error_handler = ata_bmdma_error_handler, + .post_internal_cmd = ata_bmdma_post_internal_cmd, + .cable_detect = sis_133_cable_detect, + + .bmdma_setup = ata_bmdma_setup, + .bmdma_start = ata_bmdma_start, + .bmdma_stop = ata_bmdma_stop, + .bmdma_status = ata_bmdma_status, + .qc_prep = ata_qc_prep, + .qc_issue = ata_qc_issue_prot, + .data_xfer = ata_data_xfer, + + .irq_handler = ata_interrupt, + .irq_clear = ata_bmdma_irq_clear, + .irq_on = ata_irq_on, + .irq_ack = ata_irq_ack, + + .port_start = ata_port_start, +}; + static const struct ata_port_operations sis_133_early_ops = { .port_disable = ata_port_disable, .set_piomode = sis_100_set_piomode, @@ -733,13 +767,20 @@ static const struct ata_port_info sis_info100_early = { .pio_mask = 0x1f, /* pio0-4 */ .port_ops = &sis_66_ops, }; -const struct ata_port_info sis_info133 = { +static const struct ata_port_info sis_info133 = { .sht = &sis_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = ATA_UDMA6, .port_ops = &sis_133_ops, }; +const struct ata_port_info sis_info133_for_sata = { + .sht = &sis_sht, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, + .pio_mask = 0x1f, /* pio0-4 */ + .udma_mask = ATA_UDMA6, + .port_ops = &sis_133_for_sata_ops, +}; static const struct ata_port_info sis_info133_early = { .sht = &sis_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, @@ -749,7 +790,7 @@ static const struct ata_port_info sis_info133_early = { }; /* Privately shared with the SiS180 SATA driver, not for use elsewhere */ -EXPORT_SYMBOL_GPL(sis_info133); +EXPORT_SYMBOL_GPL(sis_info133_for_sata); static void sis_fixup(struct pci_dev *pdev, struct sis_chipset *sis) { @@ -975,6 +1016,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) static const struct pci_device_id sis_pci_tbl[] = { { PCI_VDEVICE(SI, 0x5513), }, /* SiS 5513 */ { PCI_VDEVICE(SI, 0x5518), }, /* SiS 5518 */ + { PCI_VDEVICE(SI, 0x1180), }, /* SiS 1180 */ { } }; diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 221099d1d08f..f111c984a359 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -72,8 +72,8 @@ static const struct pci_device_id sis_pci_tbl[] = { { PCI_VDEVICE(SI, 0x0181), sis_180 }, /* SiS 964/180 */ { PCI_VDEVICE(SI, 0x0182), sis_180 }, /* SiS 965/965L */ { PCI_VDEVICE(SI, 0x0183), sis_180 }, /* SiS 965/965L */ - { PCI_VDEVICE(SI, 0x1182), sis_180 }, /* SiS 966/966L */ - { PCI_VDEVICE(SI, 0x1183), sis_180 }, /* SiS 966/966L */ + { PCI_VDEVICE(SI, 0x1182), sis_180 }, /* SiS 966/680 */ + { PCI_VDEVICE(SI, 0x1183), sis_180 }, /* SiS 966/966L/968/680 */ { } /* terminate list */ }; @@ -161,7 +161,6 @@ static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg) case 0x0182: case 0x0183: case 0x1182: - case 0x1183: addr += SIS182_SATA1_OFS; break; } @@ -183,8 +182,8 @@ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg) pci_read_config_dword(pdev, cfg_addr, &val); - if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) || - (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED)) + if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || + (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) pci_read_config_dword(pdev, cfg_addr+0x10, &val2); return (val|val2) & 0xfffffffb; /* avoid problems with powerdowned ports */ @@ -203,8 +202,8 @@ static void sis_scr_cfg_write (struct ata_port *ap, unsigned int sc_reg, u32 val pci_write_config_dword(pdev, cfg_addr, val); - if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) || - (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED)) + if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || + (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) pci_write_config_dword(pdev, cfg_addr+0x10, val); } @@ -224,8 +223,8 @@ static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg) val = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4)); - if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) || - (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED)) + if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || + (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) val2 = ioread32(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10); return (val | val2) & 0xfffffffb; @@ -245,8 +244,8 @@ static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) sis_scr_cfg_write(ap, sc_reg, val); else { iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)); - if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || (pdev->device == 0x1182) || - (pdev->device == 0x1183) || (pmr & SIS_PMR_COMBINED)) + if ((pdev->device == 0x0182) || (pdev->device == 0x0183) || + (pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED)) iowrite32(val, ap->ioaddr.scr_addr + (sc_reg * 4)+0x10); } } @@ -293,11 +292,11 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) /* The PATA-handling is provided by pata_sis */ switch (pmr & 0x30) { case 0x10: - ppi[1] = &sis_info133; + ppi[1] = &sis_info133_for_sata; break; case 0x30: - ppi[0] = &sis_info133; + ppi[0] = &sis_info133_for_sata; break; } if ((pmr & SIS_PMR_COMBINED) == 0) { @@ -324,14 +323,14 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) break; case 0x1182: + dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 1182/966/680 SATA controller\n"); + pi.flags |= ATA_FLAG_SLAVE_POSS; + break; + case 0x1183: - pci_read_config_dword(pdev, 0x64, &val); - if (val & 0x10000000) { - dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 1182/1183/966L SATA controller\n"); - } else { - dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 1182/1183/966 SATA controller\n"); - pi.flags |= ATA_FLAG_SLAVE_POSS; - } + dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 1183/966/966L/968/680 controller in PATA mode\n"); + ppi[0] = &sis_info133_for_sata; + ppi[1] = &sis_info133_for_sata; break; } diff --git a/drivers/ata/sis.h b/drivers/ata/sis.h index 0f2208d8d5ef..f7f3eebe666c 100644 --- a/drivers/ata/sis.h +++ b/drivers/ata/sis.h @@ -2,4 +2,4 @@ struct ata_port_info; /* pata_sis.c */ -extern const struct ata_port_info sis_info133; +extern const struct ata_port_info sis_info133_for_sata; -- cgit v1.2.3 From 63ac9b915924d1237d2135fcb4de724e6127ca5e Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 2 Jul 2007 16:08:28 +0200 Subject: 3c589_cs: fix local_bh_enable warning Russell King wrote: > Having upgraded from 2.6.16 to 2.6.22-rc6, I'm now seeing the following. > > Looks like netfilter is calling local_bh_enable() with IRQs disabled, > which would appear to be illegal. Thankfully, this is a warn-once > warning. > > WARNING: at /home/rmk/git/linux-2.6-rmk/kernel/softirq.c:138 local_bh_enable() > [...] > [] (nf_conntrack_destroy+0x0/0x2c) from [] (__kfree_skb+0xd0/0x100) > [] (__kfree_skb+0x0/0x100) from [] (kfree_skb+0x4c/0x50) > r5:c12a3800 r4:00000300 > [] (kfree_skb+0x0/0x50) from [] (el3_start_xmit+0xb8/0xd0 [3c589_cs]) > [] (el3_start_xmit+0x0/0xd0 [3c589_cs]) from [] (dev_hard_start_xmit+0x1a8/0x244) > r7:c12a3800 r6:c1a9aa00 r5:c1a9aa00 r4:c12a3800 > [] (dev_hard_start_xmit+0x0/0x244) from [] (__qdisc_run+0xb0/0x198) Thats a bug in the 3c589_cs driver. Patch attached. Signed-off-by: Patrick McHardy Signed-off-by: Jeff Garzik --- drivers/net/pcmcia/3c589_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 143ae2ff309e..503f2685fb73 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -629,9 +629,9 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) outw(SetTxThreshold + 1536, ioaddr + EL3_CMD); } - dev_kfree_skb(skb); pop_tx_status(dev); spin_unlock_irqrestore(&priv->lock, flags); + dev_kfree_skb(skb); return 0; } -- cgit v1.2.3 From 531e3a61f55261bf466d0415c48999511334933c Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 2 Jul 2007 18:12:19 -0400 Subject: [libata] sata_nv: undo merge error Only the ADMA entry was supposed to be able to change queue depth. Signed-off-by: Jeff Garzik --- drivers/ata/sata_nv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index d53cb8c47f39..b2656867c647 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -307,7 +307,6 @@ static struct scsi_host_template nv_sht = { .name = DRV_NAME, .ioctl = ata_scsi_ioctl, .queuecommand = ata_scsi_queuecmd, - .change_queue_depth = ata_scsi_change_queue_depth, .can_queue = ATA_DEF_QUEUE, .this_id = ATA_SHT_THIS_ID, .sg_tablesize = LIBATA_MAX_PRD, -- cgit v1.2.3 From 7718457dc8fd98a9f61a5e42653161bac3904a65 Mon Sep 17 00:00:00 2001 From: Marco Roeland Date: Tue, 3 Jul 2007 08:25:50 +0800 Subject: Blackfin arch: remove zero-sized include/asm-blackfin/macros.h This file accidentally got truncated instead of deleted in commit df30b11. Signed-off-by: Marco Roeland Cc: Robert P. J. Day Cc: Jeff Garzik Cc: Jesper Juhl Cc: Alex Riesen Cc: Robin Getz Acked-by: Bryan Wu --- include/asm-blackfin/macros.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 include/asm-blackfin/macros.h diff --git a/include/asm-blackfin/macros.h b/include/asm-blackfin/macros.h deleted file mode 100644 index e69de29bb2d1..000000000000 -- cgit v1.2.3 From 786f238e4f2f0d962831ee3228f2327133eb082a Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Mon, 2 Jul 2007 17:36:18 +0300 Subject: mlx4_core: Add new Mellanox device IDs Add new IDs for PCIe gen2 devices. Signed-off-by: Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/net/mlx4/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 41eafebf5823..c3da2a2f5431 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -911,6 +911,8 @@ static struct pci_device_id mlx4_pci_table[] = { { PCI_VDEVICE(MELLANOX, 0x6340) }, /* MT25408 "Hermon" SDR */ { PCI_VDEVICE(MELLANOX, 0x634a) }, /* MT25408 "Hermon" DDR */ { PCI_VDEVICE(MELLANOX, 0x6354) }, /* MT25408 "Hermon" QDR */ + { PCI_VDEVICE(MELLANOX, 0x6732) }, /* MT25408 "Hermon" DDR PCIe gen2 */ + { PCI_VDEVICE(MELLANOX, 0x673c) }, /* MT25408 "Hermon" QDR PCIe gen2 */ { 0, } }; -- cgit v1.2.3 From 841adfca9c5fc0fec6b1f0b2e5eb7a3b239a7730 Mon Sep 17 00:00:00 2001 From: Ralph Campbell Date: Fri, 29 Jun 2007 11:37:56 -0700 Subject: IPoIB/cm: Partial error clean up unmaps wrong address If a page can't be allocated for the frag list of a skb, the code to unmap the partially allocated list is off by one. For exaple, if 'frags' equals one, i == 0, and the alloc_page() fails, then the old loop would have unmapped mapping[1] which is uninitialized. The same would happen if the call to ib_dma_map_page() failed. Signed-off-by: Ralph Campbell Acked-by: Michael S. Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 5ffc464c99aa..ea74d1eaf004 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -148,8 +148,8 @@ partial_error: ib_dma_unmap_single(priv->ca, mapping[0], IPOIB_CM_HEAD_SIZE, DMA_FROM_DEVICE); - for (; i >= 0; --i) - ib_dma_unmap_single(priv->ca, mapping[i + 1], PAGE_SIZE, DMA_FROM_DEVICE); + for (; i > 0; --i) + ib_dma_unmap_single(priv->ca, mapping[i], PAGE_SIZE, DMA_FROM_DEVICE); dev_kfree_skb_any(skb); return NULL; -- cgit v1.2.3 From aa2e09da2a332e748532aa2a71b090e7e7c3203d Mon Sep 17 00:00:00 2001 From: Len Brown Date: Mon, 2 Jul 2007 23:57:45 -0400 Subject: ACPI: fix acpi_osi=!Linux Need to check for special case "acpi_osi=!Linux" before handling the general case "acpi_osi=!*", or it will have no effect. Signed-off-by: Len Brown Signed-off-by: Linus Torvalds --- drivers/acpi/osl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 58ceb18ec997..2e7ba615d760 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -999,11 +999,11 @@ static int __init acpi_osi_setup(char *str) if (str == NULL || *str == '\0') { printk(KERN_INFO PREFIX "_OSI method disabled\n"); acpi_gbl_create_osi_method = FALSE; + } else if (!strcmp("!Linux", str)) { + enable_osi_linux(0); } else if (*str == '!') { if (acpi_osi_invalidate(++str) == AE_OK) printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); - } else if (!strcmp("!Linux", str)) { - enable_osi_linux(0); } else if (!strcmp("Linux", str)) { enable_osi_linux(1); } else if (*osi_additional_string == '\0') { -- cgit v1.2.3 From 4031826b3ca40982880f6b9f2282c7d7fad60d77 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 3 Jul 2007 01:38:47 +0900 Subject: libata: fix assigned IRQ reporting host->irq and host->irq2 should be set before ata_host_register() for IRQ reporting to work. Move up host->irq assignment in ata_host_activate() and add it to ata_pci_init_one() native path and pata_cs5520. The port info printing in ata_host_register() doesn't fit all the different controllers. It should probably be moved out to LLDs with some helpers in the future. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 6 +++--- drivers/ata/libata-sff.c | 5 +++-- drivers/ata/pata_cs5520.c | 5 +++++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2407f8482948..981b397cb46b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6423,14 +6423,14 @@ int ata_host_activate(struct ata_host *host, int irq, if (rc) return rc; + /* Used to print device info at probe */ + host->irq = irq; + rc = ata_host_register(host, sht); /* if failed, just free the IRQ and leave ports alone */ if (rc) devm_free_irq(host->dev, irq, host); - /* Used to print device info at probe */ - host->irq = irq; - return rc; } diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index ce84805ba5f1..fa1c22c7b38f 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1065,10 +1065,11 @@ int ata_pci_init_one(struct pci_dev *pdev, if (rc) goto err_out; - if (!legacy_mode) + if (!legacy_mode) { rc = devm_request_irq(dev, pdev->irq, pi->port_ops->irq_handler, IRQF_SHARED, DRV_NAME, host); - else { + host->irq = pdev->irq; + } else { irq_handler_t handler[2] = { host->ops->irq_handler, host->ops->irq_handler }; unsigned int irq_flags[2] = { IRQF_SHARED, IRQF_SHARED }; diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 1aabe15ad9d3..00cf0134079c 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c @@ -284,6 +284,11 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi ata_interrupt, 0, DRV_NAME, host); if (rc) return rc; + + if (i == 0) + host->irq = irq[0]; + else + host->irq2 = irq[1]; } return ata_host_register(host, &cs5520_sht); -- cgit v1.2.3 From d9f9c6bc91c14f53ffa782ffcd42259ecae1d38c Mon Sep 17 00:00:00 2001 From: Florian Attenberger Date: Mon, 2 Jul 2007 17:09:29 +0200 Subject: sata_mv: PCI-ID for Adaptec 1430SA SATA Controller Signed-off-by: Florian Attenberger Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index c957e6e54ba1..590f2f92b4e0 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -582,6 +582,9 @@ static const struct pci_device_id mv_pci_tbl[] = { { PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x }, + /* Adaptec 1430SA */ + { PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 }, + { PCI_VDEVICE(TTI, 0x2310), chip_7042 }, /* add Marvell 7042 support */ -- cgit v1.2.3 From ee5815023527dd579ada340786e329ff6c5c0eea Mon Sep 17 00:00:00 2001 From: Chuck Ebbert Date: Mon, 25 Jun 2007 19:13:32 -0400 Subject: pata_ali: fix UDMA settings This patch was found to fix some of the problems with the pata_ali driver. https://bugzilla.redhat.com/bugzilla/attachment.cgi?id=156482 Signed-off-by: Jeff Garzik --- drivers/ata/pata_ali.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c index 3c55a5ff74c7..75e95bdbe02f 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -550,22 +550,22 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = 0x1f, .port_ops = &ali_c2_port_ops }; - /* Revision 0xC3 is UDMA100 */ + /* Revision 0xC3 is UDMA66 for now */ static const struct ata_port_info info_c3 = { .sht = &ali_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x3f, + .udma_mask = 0x1f, .port_ops = &ali_c2_port_ops }; - /* Revision 0xC4 is UDMA133 */ + /* Revision 0xC4 is UDMA100 */ static const struct ata_port_info info_c4 = { .sht = &ali_sht, .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48, .pio_mask = 0x1f, .mwdma_mask = 0x07, - .udma_mask = 0x7f, + .udma_mask = 0x3f, .port_ops = &ali_c2_port_ops }; /* Revision 0xC5 is UDMA133 with LBA48 DMA */ -- cgit v1.2.3 From d6f4d5eafdd0bbdaa166a0650d27045c26ca63dd Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 3 Jul 2007 15:11:30 +0100 Subject: ata_generic: Check the right register for the DMA enabled flags Mirrors change in IT821X Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/ata_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c index 7565f022bd69..4c6e95c95e4a 100644 --- a/drivers/ata/ata_generic.c +++ b/drivers/ata/ata_generic.c @@ -50,7 +50,7 @@ static int generic_set_mode(struct ata_port *ap, struct ata_device **unused) /* Bits 5 and 6 indicate if DMA is active on master/slave */ if (ap->ioaddr.bmdma_addr) - dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD); + dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS); for (i = 0; i < ATA_MAX_DEVICES; i++) { struct ata_device *dev = &ap->device[i]; -- cgit v1.2.3 From a0ac38f16045f90dbbcd265b638cd7254c53aa65 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 3 Jul 2007 15:15:13 +0100 Subject: pata_pdc202xx_old: Correct cable detect logic We got it backwards and now the other detects are fixed it shows up Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_pdc202xx_old.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index edbaf9d653b8..d277246b7337 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -31,8 +31,8 @@ static int pdc2026x_cable_detect(struct ata_port *ap) pci_read_config_word(pdev, 0x50, &cis); if (cis & (1 << (10 + ap->port_no))) - return ATA_CBL_PATA80; - return ATA_CBL_PATA40; + return ATA_CBL_PATA40; + return ATA_CBL_PATA80; } /** -- cgit v1.2.3 From 872aad45d6174570dd2e1defc3efee50f2cfcc72 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 3 Jul 2007 15:14:05 +0100 Subject: pata_pcmcia: Switch to ata_sff_port_start PCMCIA doesn't use DMA and as this driver is used on many platforms we don't want it to fail on those that define the DMA alloc API as a NULL return Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_pcmcia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 4d44c7555db1..a56257c98fe5 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c @@ -129,7 +129,7 @@ static struct ata_port_operations pcmcia_port_ops = { .irq_on = ata_irq_on, .irq_ack = ata_irq_ack, - .port_start = ata_port_start, + .port_start = ata_sff_port_start, }; #define CS_CHECK(fn, ret) \ -- cgit v1.2.3 From 333408f21590d50397f3004e3f87070fa8f52c51 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Tue, 3 Jul 2007 15:08:10 -0300 Subject: V4L/DVB (5808): Bttv: fix v4l1 breaking the driver If one uses a V4L *one* application, such as vlc or mplayer's v4l driver, as the first user after the driver is loaded, the driver wedges itself and will never capture properly. Even if one uses a V4L2 application later, it still won't work. If one uses a V4L *two* application first, such as tvtime or mplayer's v4l2 driver, then the driver will be ok. One can then run a V4L1 application, and it will work. It turns out the problem is with norm changing and the crop support that was added in 2.6.21. The driver defaults to PAL, and keeps the last norm it was set too across opens. If one changes the norm via V4L1, the cropping parameters are not reset like they should be, and they'll remain broken across device opens. This patch removes the direct setting of btv->tvnorm in the V4L1 ioctl VIDIOCSCHAN handler. The norm is set via the existing call to set_input(), which calls set_tvnorm(), which will reset the cropping values now that it is able to detect the norm change. Signed-off-by: Trent Piepho Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-driver.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 1c38723d3169..b1fedb0f6431 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -1331,7 +1331,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm) /* Call with btv->lock down. */ static void -set_input(struct bttv *btv, unsigned int input) +set_input(struct bttv *btv, unsigned int input, unsigned int norm) { unsigned long flags; @@ -1350,7 +1350,7 @@ set_input(struct bttv *btv, unsigned int input) } audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ? TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN)); - set_tvnorm(btv,btv->tvnorm); + set_tvnorm(btv, norm); i2c_vidiocschan(btv); } @@ -1441,7 +1441,7 @@ static void bttv_reinit_bt848(struct bttv *btv) init_bt848(btv); btv->pll.pll_current = -1; - set_input(btv,btv->input); + set_input(btv, btv->input, btv->tvnorm); } static int get_control(struct bttv *btv, struct v4l2_control *c) @@ -2011,8 +2011,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) return 0; } - btv->tvnorm = v->norm; - set_input(btv,v->channel); + set_input(btv, v->channel, v->norm); mutex_unlock(&btv->lock); return 0; } @@ -2148,7 +2147,7 @@ static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) if (*i > bttv_tvcards[btv->c.type].video_inputs) return -EINVAL; mutex_lock(&btv->lock); - set_input(btv,*i); + set_input(btv, *i, btv->tvnorm); mutex_unlock(&btv->lock); return 0; } @@ -4780,7 +4779,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, bt848_hue(btv,32768); bt848_sat(btv,32768); audio_mute(btv, 1); - set_input(btv,0); + set_input(btv, 0, btv->tvnorm); bttv_crop_reset(&btv->crop[0], btv->tvnorm); btv->crop[1] = btv->crop[0]; /* current = default */ disclaim_vbi_lines(btv); -- cgit v1.2.3 From f057131fb6eb2c45f6023e3da41ccd6e4e71aee9 Mon Sep 17 00:00:00 2001 From: Jelle Foks Date: Mon, 21 May 2007 14:56:17 -0300 Subject: V4L/DVB (5816): Cx88-blackbird: fix vidioc_g_tuner never ending list of tuners v4l-info and other programs would loop indefinitely while querying the tuners for cx88-blackbird cards. The cause was that vidioc_g_tuner didn't return an error value for qctrl->id != 0, making the application think there is a never ending list of tuners... This patch adds the same index check as done in vidioc_g_tuner() in cx88-video. Signed-off-by: Jelle Foks Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/cx88-blackbird.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index b0466b88f52c..a80b1cb1abe8 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -1034,6 +1034,8 @@ static int vidioc_g_tuner (struct file *file, void *priv, if (unlikely(UNSET == core->tuner_type)) return -EINVAL; + if (0 != t->index) + return -EINVAL; strcpy(t->name, "Television"); t->type = V4L2_TUNER_ANALOG_TV; -- cgit v1.2.3 From 1e4597e8f0049dccedb0e011934007309fa2aeab Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Mon, 2 Jul 2007 12:26:20 -0300 Subject: V4L/DVB (5818): CinergyT2: fix flush_workqueue() vs work->func() deadlock Spotted and tested by Thomas Sattler . cinergyT2.c does cancel_delayed_work() + flush_scheduled_work() while holding cinergyt2->sem. This leads to deadlock because work->func() needs the same mutex to complete. Another bug is that this code in fact can't reliably stop the re-arming delayed_work. Convert this code to use cancel_rearming_delayed_work() and move it out of ->sem. Another mutex, ->wq_sem, was added to protect against the concurrent open/resume. This patch is a horrible hack to fix the lockup which happens in practice. As Dmitry Torokhov pointed out this driver has other problems and needs further changes. Signed-off-by: Oleg Nesterov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/cinergyT2/cinergyT2.c | 66 ++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 6aba5b39ed14..b40af48a2edb 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -118,6 +118,7 @@ struct cinergyt2 { struct dvb_demux demux; struct usb_device *udev; struct mutex sem; + struct mutex wq_sem; struct dvb_adapter adapter; struct dvb_device *fedev; struct dmxdev dmxdev; @@ -482,14 +483,14 @@ static int cinergyt2_open (struct inode *inode, struct file *file) struct cinergyt2 *cinergyt2 = dvbdev->priv; int err = -ERESTARTSYS; - if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) - return -ERESTARTSYS; + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem)) + goto out; - if ((err = dvb_generic_open(inode, file))) { - mutex_unlock(&cinergyt2->sem); - return err; - } + if (mutex_lock_interruptible(&cinergyt2->sem)) + goto out_unlock1; + if ((err = dvb_generic_open(inode, file))) + goto out_unlock2; if ((file->f_flags & O_ACCMODE) != O_RDONLY) { cinergyt2_sleep(cinergyt2, 0); @@ -498,8 +499,12 @@ static int cinergyt2_open (struct inode *inode, struct file *file) atomic_inc(&cinergyt2->inuse); +out_unlock2: mutex_unlock(&cinergyt2->sem); - return 0; +out_unlock1: + mutex_unlock(&cinergyt2->wq_sem); +out: + return err; } static void cinergyt2_unregister(struct cinergyt2 *cinergyt2) @@ -519,15 +524,17 @@ static int cinergyt2_release (struct inode *inode, struct file *file) struct dvb_device *dvbdev = file->private_data; struct cinergyt2 *cinergyt2 = dvbdev->priv; - mutex_lock(&cinergyt2->sem); + mutex_lock(&cinergyt2->wq_sem); if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) { - cancel_delayed_work(&cinergyt2->query_work); - flush_scheduled_work(); + cancel_rearming_delayed_work(&cinergyt2->query_work); + + mutex_lock(&cinergyt2->sem); cinergyt2_sleep(cinergyt2, 1); + mutex_unlock(&cinergyt2->sem); } - mutex_unlock(&cinergyt2->sem); + mutex_unlock(&cinergyt2->wq_sem); if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) { warn("delayed unregister in release"); @@ -838,13 +845,13 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) { - cancel_delayed_work(&cinergyt2->rc_query_work); + cancel_rearming_delayed_work(&cinergyt2->rc_query_work); input_unregister_device(cinergyt2->rc_input_dev); } static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) { - cancel_delayed_work(&cinergyt2->rc_query_work); + cancel_rearming_delayed_work(&cinergyt2->rc_query_work); } static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) @@ -907,6 +914,7 @@ static int cinergyt2_probe (struct usb_interface *intf, usb_set_intfdata (intf, (void *) cinergyt2); mutex_init(&cinergyt2->sem); + mutex_init(&cinergyt2->wq_sem); init_waitqueue_head (&cinergyt2->poll_wq); INIT_DELAYED_WORK(&cinergyt2->query_work, cinergyt2_query); @@ -974,11 +982,8 @@ static void cinergyt2_disconnect (struct usb_interface *intf) { struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); - flush_scheduled_work(); - cinergyt2_unregister_rc(cinergyt2); - - cancel_delayed_work(&cinergyt2->query_work); + cancel_rearming_delayed_work(&cinergyt2->query_work); wake_up_interruptible(&cinergyt2->poll_wq); cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx); @@ -992,21 +997,21 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) { struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); - if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem)) return -ERESTARTSYS; if (1) { - struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); - cinergyt2_suspend_rc(cinergyt2); - cancel_delayed_work(&cinergyt2->query_work); + cancel_rearming_delayed_work(&cinergyt2->query_work); + + mutex_lock(&cinergyt2->sem); if (cinergyt2->streaming) cinergyt2_stop_stream_xfer(cinergyt2); - flush_scheduled_work(); cinergyt2_sleep(cinergyt2, 1); + mutex_unlock(&cinergyt2->sem); } - mutex_unlock(&cinergyt2->sem); + mutex_unlock(&cinergyt2->wq_sem); return 0; } @@ -1014,9 +1019,15 @@ static int cinergyt2_resume (struct usb_interface *intf) { struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); struct dvbt_set_parameters_msg *param = &cinergyt2->param; + int err = -ERESTARTSYS; - if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) - return -ERESTARTSYS; + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem)) + goto out; + + if (mutex_lock_interruptible(&cinergyt2->sem)) + goto out_unlock1; + + err = 0; if (!cinergyt2->sleeping) { cinergyt2_sleep(cinergyt2, 0); @@ -1029,7 +1040,10 @@ static int cinergyt2_resume (struct usb_interface *intf) cinergyt2_resume_rc(cinergyt2); mutex_unlock(&cinergyt2->sem); - return 0; +out_unlock1: + mutex_unlock(&cinergyt2->wq_sem); +out: + return err; } static const struct usb_device_id cinergyt2_table [] __devinitdata = { -- cgit v1.2.3 From 1fb4a17f6e47d86b25bfc4fd9df4301bca09c999 Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Mon, 2 Jul 2007 13:39:41 -0300 Subject: V4L/DVB (5822): Fix the return value in ttpci_budget_init() if the call to budget_register() fails in ttpci_budget_int(), ttpci_budget_init() returns success. The attached patch will fix this problem. Signed-off-by: Hartmut Birr Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c index 2557ac9620d0..b611f2b1f8bc 100644 --- a/drivers/media/dvb/ttpci/budget-core.c +++ b/drivers/media/dvb/ttpci/budget-core.c @@ -529,7 +529,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, if (bi->type != BUDGET_FS_ACTIVY) saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); - if (budget_register(budget) == 0) + if ((ret = budget_register(budget)) == 0) return 0; /* Everything OK */ /* An error occurred, cleanup resources */ -- cgit v1.2.3 From b42fa133110fa952299fa76cbe91226c14838261 Mon Sep 17 00:00:00 2001 From: Masatake YAMATO Date: Tue, 3 Jul 2007 22:28:34 +0200 Subject: ide: never called printk statement in ide-taskfile.c::wait_drive_not_busy Look at wait_drive_not_busy in drivers/ide/ide-taskfile.c: static u8 wait_drive_not_busy(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); int retries = 100; u8 stat; /* * Last sector was transfered, wait until drive is ready. * This can take up to 10 usec, but we will wait max 1 ms * (drive_cmd_intr() waits that long). */ while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--) udelay(10); if (!retries) printk(KERN_ERR "%s: drive still BUSY!\n", drive->name); return stat; } `printk' is never called because `retries' never holds zero at the outside of `while' loop: when `retries' holds zero at the while's loop condition, `retries' will hold -1 at the if condition. Signed-off-by: Masatake YAMATO Cc: Chuck Ebbert Cc: joe@perches.com Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-taskfile.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 30175c7688e8..aa06dafb74ac 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -238,7 +238,7 @@ EXPORT_SYMBOL(task_no_data_intr); static u8 wait_drive_not_busy(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); - int retries = 100; + int retries; u8 stat; /* @@ -246,10 +246,14 @@ static u8 wait_drive_not_busy(ide_drive_t *drive) * This can take up to 10 usec, but we will wait max 1 ms * (drive_cmd_intr() waits that long). */ - while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--) - udelay(10); + for (retries = 0; retries < 100; retries++) { + if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) + udelay(10); + else + break; + } - if (!retries) + if (stat & BUSY_STAT) printk(KERN_ERR "%s: drive still BUSY!\n", drive->name); return stat; -- cgit v1.2.3 From 785955752fde4c555a1d9f74ddfe1f7aca3e0c7f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 3 Jul 2007 22:28:35 +0200 Subject: ide: Fix a theoretical Ooops case Found by a static analyser. It is in theory possible we dereference dev->id when it has become invalid. Re-order to avoid this. Not needed for new-ide as we no longer support the crazy exabyte nest stuff Signed-off-by: Alan Cox Cc: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 41bfa4d21ab6..f5ce22c38f82 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -574,11 +574,11 @@ static inline u8 probe_for_drive (ide_drive_t *drive) /* look for ATAPI device */ (void) do_probe(drive, WIN_PIDENTIFY); } - if (strstr(drive->id->model, "E X A B Y T E N E S T")) - enable_nest(drive); if (!drive->present) /* drive not found */ return 0; + if (strstr(drive->id->model, "E X A B Y T E N E S T")) + enable_nest(drive); /* identification failed? */ if (!drive->id_read) { -- cgit v1.2.3 From 783353b1d3d1ed3ae4a0bd4ea4557bd4d77aa04e Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 3 Jul 2007 22:28:35 +0200 Subject: hpt366: blacklist MAXTOR STM3320620A for UltraDMA/66 Add the MAXTOR STM3320620A drive into the UltraDMA/66 mode blacklist for the HPT36x chips. Signed-off-by: Sergei Shtylyov Acked-by: Linas Vepstas Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/hpt366.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index ce8a5449a574..4f8017ac9900 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/hpt366.c Version 1.04 Jun 4, 2007 + * linux/drivers/ide/pci/hpt366.c Version 1.05 Jun 26, 2007 * * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. @@ -182,6 +182,7 @@ static const char *bad_ata66_4[] = { "IC35L040AVER07-0", "IC35L060AVER07-0", "WDC AC310200R", + "MAXTOR STM3320620A", NULL }; -- cgit v1.2.3 From 96dcc08b0c6b730474469b10ed5eeda06e617deb Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 3 Jul 2007 22:28:35 +0200 Subject: hpt366: use correct enablebits for HPT36x The HPT36x chips finally turned out to have the channel enable bits -- however, badly implemented. Make use of them despite it's probably only going to burden the driver's code -- assuming both channels are always enabled by the HighPoint BIOS anyway... Signed-off-by: Sergei Shtylyov Acked-by: Linas Vepstas Cc: michal.kepien@poczta.onet.pl Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/hpt366.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 4f8017ac9900..c33d0b0f11c9 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/hpt366.c Version 1.05 Jun 26, 2007 + * linux/drivers/ide/pci/hpt366.c Version 1.06 Jun 27, 2007 * * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. @@ -1514,18 +1514,28 @@ static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d) goto init_single; /* - * HPT36x chips are single channel and - * do not seem to have the channel enable bit... + * HPT36x chips have one channel per function and have + * both channel enable bits located differently and visible + * to both functions -- really stupid design decision... :-( + * Bit 4 is for the primary channel, bit 5 for the secondary. */ d->channels = 1; - d->enablebits[0].reg = 0; + d->enablebits[0].mask = d->enablebits[0].val = 0x10; if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) { - u8 pin1 = 0, pin2 = 0; + u8 mcr1 = 0, pin1 = 0, pin2 = 0; int ret; pci_set_drvdata(dev2, info[rev]); + /* + * Now we'll have to force both channels enabled if + * at least one of them has been enabled by BIOS... + */ + pci_read_config_byte(dev, 0x50, &mcr1); + if (mcr1 & 0x30) + pci_write_config_byte(dev, 0x50, mcr1 | 0x30); + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1); pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2); if (pin1 != pin2 && dev->irq == dev2->irq) { -- cgit v1.2.3 From 603a0e2c0a160ad8c2d00d71a700bb95482be5de Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 3 Jul 2007 22:28:35 +0200 Subject: amd74xx: resume fix * Driver can't skip programming transfer mode on the device in amd_set_drive() (similar fix has been applied to via82cxxx driver ages ago). * While at it remove redundant warning (ide_config_drive_speed() already produces more valuable one). * Bump driver version. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/amd74xx.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 9db1be826e80..a2be65fcf89c 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -1,5 +1,5 @@ /* - * Version 2.15 + * Version 2.16 * * AMD 755/756/766/8111 and nVidia nForce/2/2s/3/3s/CK804/MCP04 * IDE driver for Linux. @@ -244,10 +244,8 @@ static int amd_set_drive(ide_drive_t *drive, u8 speed) struct ide_timing t, p; int T, UT; - if (speed != XFER_PIO_SLOW && speed != drive->current_speed) - if (ide_config_drive_speed(drive, speed)) - printk(KERN_WARNING "ide%d: Drive %d didn't accept speed setting. Oh, well.\n", - drive->dn >> 1, drive->dn & 1); + if (speed != XFER_PIO_SLOW) + ide_config_drive_speed(drive, speed); T = 1000000000 / amd_clock; UT = T / min_t(int, max_t(int, amd_config->flags & AMD_UDMA, 1), 2); -- cgit v1.2.3 From 52374f890c1d0d64148d55a20d995a0b3e0ae987 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 3 Jul 2007 22:28:35 +0200 Subject: it821x: fix incorrect SWDMA mask SWDMA modes are unsupported by it821x. Attempts to tune SWDMA modes always fail (due to sanity check in ->speedproc) and result in PIO being tuned. * Fix incorrect SWDMA mask so core code won't try these modes and will just tune PIO if no other DMA modes are available. * Bump driver version. Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Sergei Shtylyov --- drivers/ide/pci/it821x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 4bd4bf02e917..3aeb7f1b7916 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c @@ -1,6 +1,6 @@ /* - * linux/drivers/ide/pci/it821x.c Version 0.15 Jun 2 2007 + * linux/drivers/ide/pci/it821x.c Version 0.16 Jul 3 2007 * * Copyright (C) 2004 Red Hat * Copyright (C) 2007 Bartlomiej Zolnierkiewicz @@ -660,7 +660,6 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) hwif->ultra_mask = 0x7f; hwif->mwdma_mask = 0x07; - hwif->swdma_mask = 0x07; hwif->ide_dma_check = &it821x_config_drive_for_dma; if (!(hwif->udma_four)) -- cgit v1.2.3 From 8006bf56e360a4db71d304df778870a371a9e930 Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Tue, 3 Jul 2007 22:28:36 +0200 Subject: ide: pdc202xx_new PLL input clock fix Recently the PLL input clock of Promise 2027x is sometimes detected higher than expected (e.g. 20.027 MHz compared to 16.714 MHz). It seems sometimes the mdelay() function is not as precise as it used to be. Per Alan's advice, HT or power management might affect the precision of mdelay(). This patch calls gettimeofday() to measure the time elapsed and calculate the PLL input clock accordingly. Signed-off-by: Albert Lee Cc: Alan Cox Cc: Bahadir Balban Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/pdc202xx_new.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index cc0bfdcf1f19..0765dce6948e 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -306,11 +306,13 @@ static long __devinit read_counter(u32 dma_base) */ static long __devinit detect_pll_input_clock(unsigned long dma_base) { + struct timeval start_time, end_time; long start_count, end_count; - long pll_input; + long pll_input, usec_elapsed; u8 scr1; start_count = read_counter(dma_base); + do_gettimeofday(&start_time); /* Start the test mode */ outb(0x01, dma_base + 0x01); @@ -322,6 +324,7 @@ static long __devinit detect_pll_input_clock(unsigned long dma_base) mdelay(10); end_count = read_counter(dma_base); + do_gettimeofday(&end_time); /* Stop the test mode */ outb(0x01, dma_base + 0x01); @@ -333,7 +336,10 @@ static long __devinit detect_pll_input_clock(unsigned long dma_base) * Calculate the input clock in Hz * (the clock counter is 30 bit wide and counts down) */ - pll_input = ((start_count - end_count) & 0x3ffffff) * 100; + usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 + + (end_time.tv_usec - start_time.tv_usec); + pll_input = ((start_count - end_count) & 0x3ffffff) / 10 * + (10000000 / usec_elapsed); DBG("start[%ld] end[%ld]\n", start_count, end_count); -- cgit v1.2.3 From d61bcce9c1aa2c9f8a768d73c4c517f81d226725 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 3 Jul 2007 22:28:36 +0200 Subject: ide: ide_scan_pcibus(): check __pci_register_driver return value drivers/ide/setup-pci.c: In function 'ide_scan_pcibus': drivers/ide/setup-pci.c:879: warning: ignoring return value of '__pci_register_driver', declared with attribute warn_unused_result Signed-off-by: Andrew Morton Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/setup-pci.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 67035ba4bf5e..c88d33225cf9 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -872,11 +872,15 @@ void __init ide_scan_pcibus (int scan_direction) * are post init. */ - list_for_each_safe(l, n, &ide_pci_drivers) - { + list_for_each_safe(l, n, &ide_pci_drivers) { list_del(l); d = list_entry(l, struct pci_driver, node); - __pci_register_driver(d, d->driver.owner, d->driver.mod_name); + if (__pci_register_driver(d, d->driver.owner, + d->driver.mod_name)) { + printk(KERN_ERR "%s: failed to register driver " + "for %s\n", __FUNCTION__, + d->driver.mod_name); + } } } #endif -- cgit v1.2.3 From 746976a301ac9c9aa10d7d42454f8d6cdad8ff2b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 3 Jul 2007 20:05:20 +0200 Subject: NTP: remove clock_was_set() call to prevent deadlock The clock_was_set() call in seconds_overflow() which happens only when leap seconds are inserted / deleted is wrong in two aspects: 1. it results in a call to on_each_cpu() with interrupts disabled 2. it is potential deadlock source vs. call_lock in smp_call_function() The only possible side effect of the removal might be, that an absolute CLOCK_REALTIME timer fires 1 second too late, in the rare case of leap second deletion and an absolute CLOCK_REALTIME timer which expires in the affected time frame. It will never fire too early. This was probably observed by the reporter of a June 30th -> July 1st hang: http://lkml.org/lkml/2007/7/3/103 A similar problem was observed by Dave Jones, who provided a screen shot with a lockdep back trace, which allowed to analyse the problem. Signed-off-by: Thomas Gleixner Acked-by: Ingo Molnar Signed-off-by: Linus Torvalds --- kernel/time/ntp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index 87aa5ff931e0..cf53bb5814cb 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -122,7 +122,6 @@ void second_overflow(void) */ time_interpolator_update(-NSEC_PER_SEC); time_state = TIME_OOP; - clock_was_set(); printk(KERN_NOTICE "Clock: inserting leap second " "23:59:60 UTC\n"); } @@ -137,7 +136,6 @@ void second_overflow(void) */ time_interpolator_update(NSEC_PER_SEC); time_state = TIME_WAIT; - clock_was_set(); printk(KERN_NOTICE "Clock: deleting leap second " "23:59:59 UTC\n"); } -- cgit v1.2.3 From dbc55faa64c12f4c9fab6e2bd131d771bc026ed1 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Tue, 3 Jul 2007 09:31:04 -0700 Subject: SLUB: Make lockdep happy by not calling add_partial with interrupts enabled during bootstrap If we move the local_irq_enable() to the end of the function then add_partial() in early_kmem_cache_node_alloc() will be called with interrupts disabled like during regular operations. This makes lockdep happy. Signed-off-by: Christoph Lameter Tested-by: Andre Noll Acked-by: Ingo Molnar Signed-off-by: Linus Torvalds --- mm/slub.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 202049a45764..0437f2f09986 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -1798,8 +1798,6 @@ static struct kmem_cache_node * __init early_kmem_cache_node_alloc(gfp_t gfpflag BUG_ON(kmalloc_caches->size < sizeof(struct kmem_cache_node)); page = new_slab(kmalloc_caches, gfpflags | GFP_THISNODE, node); - /* new_slab() disables interupts */ - local_irq_enable(); BUG_ON(!page); n = page->freelist; @@ -1811,6 +1809,12 @@ static struct kmem_cache_node * __init early_kmem_cache_node_alloc(gfp_t gfpflag init_kmem_cache_node(n); atomic_long_inc(&n->nr_slabs); add_partial(n, page); + + /* + * new_slab() disables interupts. If we do not reenable interrupts here + * then bootup would continue with interrupts disabled. + */ + local_irq_enable(); return n; } -- cgit v1.2.3 From 0f8dc2f06560e2ca126d1670a24126ba08357d38 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 29 Jun 2007 16:16:36 +0200 Subject: Revert HPET resource reservation Matthias Lenk reports that the PCI subsystem would move the HPET on SB400/SB600-based systems, where the HPET is in BAR1 of the SMbus controller. The reason? The ACPI layer registered the PCI MMIO range as being busy too early, before PCI enumeration had happened, causing the PCI layer to decide that it should relocate the resources somewhere else. Firmware resources should be marked busy _after_ the PCI enumeration and probing has happened, not before. Remove the too-early reservation, we'll fix it up to do it properly later. In the meantime, this solves the regression. Tested-by: Matthias Lenk Cc: Aaron Durbin Cc: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/acpi/boot.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 280898b045b2..3e497fd028e4 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -636,29 +636,10 @@ static int __init acpi_parse_hpet(struct acpi_table_header *table) return -1; } -#define HPET_RESOURCE_NAME_SIZE 9 - hpet_res = alloc_bootmem(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE); - if (hpet_res) { - memset(hpet_res, 0, sizeof(*hpet_res)); - hpet_res->name = (void *)&hpet_res[1]; - hpet_res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE, - "HPET %u", hpet_tbl->sequence); - hpet_res->end = (1 * 1024) - 1; - } - hpet_address = hpet_tbl->address.address; printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", hpet_tbl->id, hpet_address); - res_start = hpet_address; - - if (hpet_res) { - hpet_res->start = res_start; - hpet_res->end += res_start; - insert_resource(&iomem_resource, hpet_res); - } - return 0; } #else -- cgit v1.2.3 From 5dcccd8d7eae870d85c3f175fd0823d3da07d0e3 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 4 Jul 2007 01:38:13 +0200 Subject: Revert perfctr reservation to 2.6.21 state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this change it works again when the nmi watchdog is disabled. Signed-off-by: Andi Kleen Cc: Björn Steinbrink Cc: Stephane Eranian Cc: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/perfctr-watchdog.c | 35 +++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/arch/i386/kernel/cpu/perfctr-watchdog.c b/arch/i386/kernel/cpu/perfctr-watchdog.c index f0b67630b90d..4d26d514c56f 100644 --- a/arch/i386/kernel/cpu/perfctr-watchdog.c +++ b/arch/i386/kernel/cpu/perfctr-watchdog.c @@ -55,14 +55,45 @@ static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk); /* converts an msr to an appropriate reservation bit */ static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) { - return wd_ops ? msr - wd_ops->perfctr : 0; + /* returns the bit offset of the performance counter register */ + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + return (msr - MSR_K7_PERFCTR0); + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + return (msr - MSR_ARCH_PERFMON_PERFCTR0); + + switch (boot_cpu_data.x86) { + case 6: + return (msr - MSR_P6_PERFCTR0); + case 15: + return (msr - MSR_P4_BPU_PERFCTR0); + } + } + return 0; } /* converts an msr to an appropriate reservation bit */ /* returns the bit offset of the event selection register */ static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) { - return wd_ops ? msr - wd_ops->evntsel : 0; + /* returns the bit offset of the event selection register */ + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + return (msr - MSR_K7_EVNTSEL0); + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) + return (msr - MSR_ARCH_PERFMON_EVENTSEL0); + + switch (boot_cpu_data.x86) { + case 6: + return (msr - MSR_P6_EVNTSEL0); + case 15: + return (msr - MSR_P4_BSU_ESCR0); + } + } + return 0; + } /* checks for a bit availability (hack for oprofile) */ -- cgit v1.2.3 From fcb82f8835c1d71b4fe5de1d9894f45370f80dab Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Tue, 3 Jul 2007 15:28:55 -0700 Subject: dio: remove bogus refcounting BUG_ON Badari Pulavarty reported a case of this BUG_ON is triggering during testing. It's completely bogus and should be removed. It's trying to notice if we left references to the dio hanging around in the sync case. They should have been dropped as IO completed while this path was in dio_await_completion(). This condition will also be checked, via some twisty logic, by the BUG_ON(ret != -EIOCBQUEUED) a few lines lower. So to start this BUG_ON() is redundant. More fatally, it's dereferencing dio-> after having dropped its reference. It's only safe to dereference the dio after releasing the lock if the final reference was just dropped. Another CPU might free the dio in bio completion and reuse the memory after this path drops the dio lock but before the BUG_ON() is evaluated. This patch passed aio+dio regression unit tests and aio-stress on ext3. Signed-off-by: Zach Brown Cc: Badari Pulavarty Cc: Andrew Morton Signed-off-by: Linus Torvalds --- fs/direct-io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index 8593f3dfd299..52bb2638f7ab 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1106,7 +1106,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, spin_lock_irqsave(&dio->bio_lock, flags); ret2 = --dio->refcount; spin_unlock_irqrestore(&dio->bio_lock, flags); - BUG_ON(!dio->is_async && ret2 != 0); + if (ret2 == 0) { ret = dio_complete(dio, offset, ret); kfree(dio); -- cgit v1.2.3 From ba609a9d97ba231c3d94443c50579ceb5fc33867 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 3 Jul 2007 18:27:53 -0700 Subject: Remove some unused variables When Andi reverted the HPET resource reservation (in commit 0f8dc2f06560e2ca126d1670a24126ba08357d38), he didn't remove the now unused variables, which just causes gcc to be noisy. Signed-off-by: Linus Torvalds --- arch/i386/kernel/acpi/boot.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 3e497fd028e4..a574cd2c8b61 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -621,8 +621,6 @@ static int __init acpi_parse_sbf(struct acpi_table_header *table) static int __init acpi_parse_hpet(struct acpi_table_header *table) { struct acpi_table_hpet *hpet_tbl; - struct resource *hpet_res; - resource_size_t res_start; hpet_tbl = (struct acpi_table_hpet *)table; if (!hpet_tbl) { -- cgit v1.2.3 From e2baf4ed168589af8224d51f0ac50e65bcdee3f6 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 3 Jul 2007 16:51:19 -0400 Subject: [JFFS2] Fix readinode failure when read_dnode() detects CRC failure. We should have stopped returning 1 from read_dnode() to indicate failure. We can just mark the damn thing obsolete immediately. But I missed a case where we don't. Signed-off-by: David Woodhouse --- fs/jffs2/readinode.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 12e83f67eee4..7b363786c2d2 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -210,8 +210,7 @@ static void jffs2_kill_tn(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info * * offset, and the one with the smallest length will come first in the * ordering. * - * Returns 0 if the node was inserted - * 1 if the node is obsolete (because we can't mark it so yet) + * Returns 0 if the node was handled (including marking it obsolete) * < 0 an if error occurred */ static int jffs2_add_tn_to_tree(struct jffs2_sb_info *c, @@ -572,8 +571,7 @@ static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_r * Helper function for jffs2_get_inode_nodes(). * It is called every time an directory entry node is found. * - * Returns: 0 on succes; - * 1 if the node should be marked obsolete; + * Returns: 0 on success; * negative error code on failure. */ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, @@ -680,8 +678,7 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r * Helper function for jffs2_get_inode_nodes(). * It is called every time an inode node is found. * - * Returns: 0 on success; - * 1 if the node should be marked obsolete; + * Returns: 0 on success (possibly after marking a bad node obsolete); * negative error code on failure. */ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, @@ -690,7 +687,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref { struct jffs2_tmp_dnode_info *tn; uint32_t len, csize; - int ret = 1; + int ret = 0; uint32_t crc; /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ @@ -719,8 +716,9 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref /* Sanity checks */ if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) { - JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref)); - jffs2_dbg_dump_node(c, ref_offset(ref)); + JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref)); + jffs2_dbg_dump_node(c, ref_offset(ref)); + jffs2_mark_node_obsolete(c, ref); goto free_out; } @@ -775,6 +773,7 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref if (len >= csize && unlikely(tn->partial_crc != je32_to_cpu(rd->data_crc))) { JFFS2_NOTICE("wrong data CRC in data node at 0x%08x: read %#08x, calculated %#08x.\n", ref_offset(ref), tn->partial_crc, je32_to_cpu(rd->data_crc)); + jffs2_mark_node_obsolete(c, ref); goto free_out; } @@ -854,7 +853,6 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref * It is called every time an unknown node is found. * * Returns: 0 on success; - * 1 if the node should be marked obsolete; * negative error code on failure. */ static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un) @@ -1088,10 +1086,7 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf } err = read_unknown(c, ref, &node->u); - if (err == 1) { - jffs2_mark_node_obsolete(c, ref); - break; - } else if (unlikely(err)) + if (unlikely(err)) goto free_out; } -- cgit v1.2.3 From ab012ebf9ebb5f3392e74c1666e7473b8567aeb0 Mon Sep 17 00:00:00 2001 From: Kumba Date: Fri, 25 May 2007 02:26:47 -0400 Subject: [MIPS] Fix include wrapper symbol definitions in IP32 code. Some IP35 defines snuck into some IP32-specific code during the DMA re-write. Signed-off-by: Joshua Kinard Signed-off-by: Ralf Baechle --- include/asm-mips/mach-ip32/dma-coherence.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/asm-mips/mach-ip32/dma-coherence.h b/include/asm-mips/mach-ip32/dma-coherence.h index c3f9a6a20eb0..a5511ebb2d53 100644 --- a/include/asm-mips/mach-ip32/dma-coherence.h +++ b/include/asm-mips/mach-ip32/dma-coherence.h @@ -6,8 +6,8 @@ * Copyright (C) 2006 Ralf Baechle * */ -#ifndef __ASM_MACH_IP35_DMA_COHERENCE_H -#define __ASM_MACH_IP35_DMA_COHERENCE_H +#ifndef __ASM_MACH_IP32_DMA_COHERENCE_H +#define __ASM_MACH_IP32_DMA_COHERENCE_H #include @@ -69,4 +69,4 @@ static inline int plat_device_is_coherent(struct device *dev) return 0; /* IP32 is non-cohernet */ } -#endif /* __ASM_MACH_IP35_DMA_COHERENCE_H */ +#endif /* __ASM_MACH_IP32_DMA_COHERENCE_H */ -- cgit v1.2.3 From eaf2b8dca47cc1d4ca7fd83f37604e0f5478b33a Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Tue, 29 May 2007 15:03:56 +0100 Subject: [MIPS] die(): Properly declare as non-returning This marks the declaration of die() correctly, removing "control reaches end of non-void function" warnings from non-void functions that die() at the end. Signed-off-by: Maciej W. Rozycki Signed-off-by: Ralf Baechle --- include/asm-mips/ptrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h index 1906938285c0..85b44366343a 100644 --- a/include/asm-mips/ptrace.h +++ b/include/asm-mips/ptrace.h @@ -86,7 +86,7 @@ struct pt_regs { extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit); -extern NORET_TYPE void die(const char *, struct pt_regs *); +extern NORET_TYPE void die(const char *, struct pt_regs *) ATTRIB_NORET; static inline void die_if_kernel(const char *str, struct pt_regs *regs) { -- cgit v1.2.3 From 83d0f2332edb3001617e6a292c4412ae5f2bf659 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 29 May 2007 23:30:04 +0900 Subject: [MIPS] Add whitelists for checksyscalls.sh Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- include/asm-mips/unistd.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 59d6fec8fbff..ed16de0a6398 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -977,6 +977,22 @@ # define __ARCH_WANT_COMPAT_SYS_TIME # endif +/* whitelists for checksyscalls */ +#define __IGNORE_select +#define __IGNORE_vfork +#define __IGNORE_time +#define __IGNORE_uselib +#define __IGNORE_fadvise64_64 +#define __IGNORE_getdents64 +#if _MIPS_SIM == _MIPS_SIM_NABI32 +#define __IGNORE_truncate64 +#define __IGNORE_ftruncate64 +#define __IGNORE_stat64 +#define __IGNORE_lstat64 +#define __IGNORE_fstat64 +#define __IGNORE_fstatat64 +#endif + #endif /* !__ASSEMBLY__ */ /* -- cgit v1.2.3 From 8c976e34516c9e134488babbb95af182340370c8 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 3 Jul 2007 18:25:58 +0200 Subject: [MIPS] VSMP: Fix initialization ordering bug. Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp-mt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index b8fa7ddd78f6..19b30d6f1727 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -236,8 +236,6 @@ void __init plat_smp_setup(void) dvpe(); dmt(); - mips_mt_set_cpuoptions(); - /* Put MVPE's into 'configuration state' */ set_c0_mvpcontrol(MVPCONTROL_VPC); @@ -263,6 +261,8 @@ void __init plat_smp_setup(void) void __init plat_prepare_cpus(unsigned int max_cpus) { + mips_mt_set_cpuoptions(); + /* set up ipi interrupts */ if (cpu_has_vint) { set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); -- cgit v1.2.3