Re: [PATCH? v2] powerpc: Hard wire PT_SOFTE value to 1 in gpr_get() too
On Thu, 11 Jun 2020 12:58:31 +0200, Oleg Nesterov wrote: > On 06/11, Madhavan Srinivasan wrote: > > On 6/10/20 8:37 PM, Oleg Nesterov wrote: > > > > This is not consistent and this breaks > > > > http://sourceware.org/systemtap/wiki/utrace/tests/user-regs-peekpoke > > this is 404. Attaching the testcase, the CVS web interface no longer works on sourceware.org. Jan /* Test case for PTRACE_SETREGS modifying the requested ragisters. x86* counterpart of the s390* testcase `user-area-access.c'. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely. */ /* FIXME: EFLAGS should be tested restricted on the appropriate bits. */ #define _GNU_SOURCE 1 #if defined __powerpc__ || defined __sparc__ # define user_regs_struct pt_regs #endif #ifdef __ia64__ #define ia64_fpreg ia64_fpreg_DISABLE #define pt_all_user_regs pt_all_user_regs_DISABLE #endif /* __ia64__ */ #include #ifdef __ia64__ #undef ia64_fpreg #undef pt_all_user_regs #endif /* __ia64__ */ #include #include #include #if defined __i386__ || defined __x86_64__ #include #endif #include #include #include #include #include #include #include #include #include #include #include #include /* ia64 has PTRACE_SETREGS but it has no USER_REGS_STRUCT. */ #if !defined PTRACE_SETREGS || defined __ia64__ int main (void) { return 77; } #else /* PTRACE_SETREGS */ /* The minimal alignment we use for the random access ranges. */ #define REGALIGN (sizeof (long)) static pid_t child; static void cleanup (void) { if (child > 0) kill (child, SIGKILL); child = 0; } static void handler_fail (int signo) { cleanup (); signal (SIGABRT, SIG_DFL); abort (); } int main (void) { long l; int status, i; pid_t pid; union { struct user_regs_struct user; unsigned char byte[sizeof (struct user_regs_struct)]; } u, u2; int start; setbuf (stdout, NULL); atexit (cleanup); signal (SIGABRT, handler_fail); signal (SIGALRM, handler_fail); signal (SIGINT, handler_fail); i = alarm (10); assert (i == 0); child = fork (); switch (child) { case -1: assert_perror (errno); assert (0); case 0: l = ptrace (PTRACE_TRACEME, 0, NULL, NULL); assert (l == 0); // Prevent rt_sigprocmask() call called by glibc after raise(). syscall (__NR_tkill, getpid (), SIGSTOP); assert (0); default: break; } pid = waitpid (child, &status, 0); assert (pid == child); assert (WIFSTOPPED (status)); assert (WSTOPSIG (status) == SIGSTOP); /* Fetch U2 from the inferior. */ errno = 0; # ifdef __sparc__ l = ptrace (PTRACE_GETREGS, child, &u2.user, NULL); # else l = ptrace (PTRACE_GETREGS, child, NULL, &u2.user); # endif assert_perror (errno); assert (l == 0); /* Initialize U with a pattern. */ for (i = 0; i < sizeof u.byte; i++) u.byte[i] = i; #ifdef __x86_64__ /* non-EFLAGS modifications fail with EIO, EFLAGS gets back different. */ u.user.eflags = u2.user.eflags; u.user.cs = u2.user.cs; u.user.ds = u2.user.ds; u.user.es = u2.user.es; u.user.fs = u2.user.fs; u.user.gs = u2.user.gs; u.user.ss = u2.user.ss; u.user.fs_base = u2.user.fs_base; u.user.gs_base = u2.user.gs_base; /* RHEL-4 refuses to set too high (and invalid) PC values. */ u.user.rip = (unsigned long) handler_fail; /* 2.6.25 always truncates and sign-extends orig_rax. */ u.user.orig_rax = (int) u.user.orig_rax; #endif /* __x86_64__ */ #ifdef __i386__ /* These values get back different. */ u.user.xds = u2.user.xds; u.user.xes = u2.user.xes; u.user.xfs = u2.user.xfs; u.user.xgs = u2.user.xgs; u.user.xcs = u2.user.xcs; u.user.eflags = u2.user.eflags; u.user.xss = u2.user.xss; /* RHEL-4 refuses to set too high (and invalid) PC values. */ u.user.eip = (unsigned long) handler_fail; #endif /* __i386__ */ #ifdef __powerpc__ /* These fields are constrained. */ u.user.msr = u2.user.msr; # ifdef __powerpc64__ u.user.softe = u2.user.softe; # else u.user.mq = u2.user.mq; # endif /* __powerpc64__ */ u.user.trap = u2.user.trap; u.user.dar = u2.user.dar; u.user.dsisr = u2.user.dsisr; u.user.result = u2.user.result; #endif /* __powerpc__ */ /* Poke U. */ # ifdef __sparc__ l = ptrace (PTRACE_SETREGS, child, &u.user, NULL); # else l = ptrace (PTRACE_SETREGS, child, NULL, &u.user); # endif assert (l == 0); /* Peek into U2. */ # ifdef __sparc__ l = ptrace (PTRACE_GETREGS, child, &u2.user, NULL); # else l = ptrace (PTRACE_GETREGS, child, NULL, &u2.user); # endif assert (l == 0); /* Verify it matches. */ if (memcmp (&u.user, &u2.user, sizeof u.byte) != 0) { for (start = 0; start + REGALIGN <= sizeof u.byte
Re: perf report: fix off-by-one for non-activation frames
On Sat, 17 Jun 2017 09:56:57 +0200, Namhyung Kim wrote: > Not sure whether it needs be fixed or not. If we fix it, srcline and > address would not match so it can give its own confusion to users. > Ideally it should display an addressof the instruction before the > address IMHO. One can figure million ways how it can behave and each one has its pros and cons. I was just describing the current behavior of GDB and LLDB which people are used to already. Jan
Re: perf report: fix off-by-one for non-activation frames
On Fri, 16 Jun 2017 13:51:37 +0200, Milian Wolff wrote: > > perf-4.12.0-0.rc5.git0.1.fc27.x86_64 > > 39e32e gdb_main (/usr/libexec/gdb) > > 10b6fa main (/usr/libexec/gdb) > >0x5565f6f6 <+54>:callq 0x558f17a0 > > >0x5565f6fb <+59>:mov0x18(%rsp),%rcx [...] > Excuse me, but I'm having trouble following you. The non-GDB backtraces you > are pasting do not show srcline information. So what exactly is broken? There is broken that perf now reports address 10b6fa (corresponding to relocated address 0x5565f6fa) but there is no instruction on address 0x5565f6fa. If you 'objdump -d' it you cannot find any instruction on adress 0x5565f6fa (or on address 0x10b6fa). There is instruction on address 0x5565f6fb. > Maybe paste the perf output you get now and highlight what you'd expect > instead? Actual: 39e32e gdb_main (/usr/libexec/gdb) 10b6fa main (/usr/libexec/gdb) Expected: 39e32f gdb_main (/usr/libexec/gdb) 10b6fb main (/usr/libexec/gdb) I agree perf needs to calculate with 39e32e and 10b6fa. But it should display to user 39e32f and 10b6fb. Jan
Re: perf report: fix off-by-one for non-activation frames
On Mon, 15 May 2017 17:04:44 +0200, Milian Wolff wrote: commit 1982ad48fc82c284a5cc55697a012d3357e84d01 Author: Milian Wolff Date: Wed May 24 15:21:25 2017 +0900 > --- a/tools/perf/util/unwind-libdw.c > +++ b/tools/perf/util/unwind-libdw.c > @@ -168,12 +168,16 @@ frame_callback(Dwfl_Frame *state, void *arg) ... > + if (!isactivation) > + --pc; > + FYI I find it as a regression a bit: perf-4.11.4-200.fc25.x86_64 30c563 gdb_main (/usr/libexec/gdb) fae48 main (/usr/libexec/gdb) 0x5564ee43 <+51>:callq 0x5585f340 0x5564ee48 <+56>:mov0x18(%rsp),%rcx perf-4.12.0-0.rc5.git0.1.fc27.x86_64 39e32e gdb_main (/usr/libexec/gdb) 10b6fa main (/usr/libexec/gdb) 0x5565f6f6 <+54>:callq 0x558f17a0 0x5565f6fb <+59>:mov0x18(%rsp),%rcx In backtraces it is correct to show the source line of the calling line - as perf does now after your fix - but one still should report PC address of the start of the next instruction. At least this is what debuggers are used to do: #9 gdb_main (args=0x7fffe2e0) at ../../gdb/main.c:1257 #10 0x5565f6fb in main (argc=, argv=) at ../../gdb/gdb.c:40 0x5565f6f6 <+54>:callq 0x558f17a0 => 0x5565f6fb <+59>:mov0x18(%rsp),%rcx Line 40 of "../../gdb/gdb.c" starts at address 0x5565f6f6 and ends at 0x5565f6fb . Line 41 of "../../gdb/gdb.c" starts at address 0x5565f6fb and ends at 0x5565f715. You see "gdb.c:40" and 0x5565f6fb in the backtrace despite 0x5565f6fb is already line 41. This is also why elfutils reports separately PC and 'isactivation' flag. Instead of just reporting decreased PC. Jan
Re: [PATCH 1/2] perf report: ensure the perf DSO mapping matches what libdw sees
On Mon, 05 Jun 2017 12:41:30 +0200, Jiri Olsa wrote: > On Fri, Jun 02, 2017 at 04:37:52PM +0200, Milian Wolff wrote: > > Debug output showed me that libdw found a module for the last frame > > address, but it thinks it belongs to /usr/lib/ld-2.25.so. I find your patch as a correct workaround of an elfutils bug. I have filed it as: dwfl_addrmodule reports bogus modules for unmapped areas https://sourceware.org/bugzilla/show_bug.cgi?id=21602 Thanks, Jan
Re: [PATCH 2/2] perf report: report module before querying isactivation in dwfl unwind
On Mon, 05 Jun 2017 12:47:20 +0200, Jiri Olsa wrote: > On Fri, Jun 02, 2017 at 12:25:08PM -0300, Arnaldo Carvalho de Melo wrote: > > Em Fri, Jun 02, 2017 at 04:37:53PM +0200, Milian Wolff escreveu: > > > The PC returned by dwfl_frame_pc may map into a not-yet-reported > > > module. We have to report it before we continue unwinding. But when > > > we query for the isactivation flag in dwfl_frame_pc, libdw will > > > actually do one more unwinding step internally which can then break > > > and lead to missed frames or broken stacks. > > > > > > With libunwind we get e.g.: > > sounds like a libdw design issue.. Jan is there a specific way > to handle the case that Milian described? I agree with the patch. Just be aware for performance then the __report_module() call in entry() is no longer useful as the '--pc' adjustment should never cross a module boundary. Although for perf unwinding performance there is still a wide gap there (such as caching the loaded modules for multiple backtraces.) Thanks, Jan
Re: [PATCH] x86/ptrace: Remove questionable TS_COMPAT usage in ptrace
On Mon, 20 Jun 2016 12:07:56 +0200, Pedro Alves wrote: > On 06/18/2016 06:02 PM, Andy Lutomirski wrote: > > Yuck. I should have dug in to the history. Why not just > > unconditionally sign-extend eax when set by a 32-bit tracer? > > No idea. Roland McGrath knows why he wrote it that way, Cced. What if eax contains an address in 2GB..4GB range? I guess currently the orig_eax check tries to verify %eax cannot contain an address. Jan
Re: [PATCH] perf top: Make -g refer to callchains
On Tue, 19 Nov 2013 10:26:42 +0100, Jean Pihet wrote: > Do you know about the support of AARCH64, both in 64-bit and 32-bit > (compat) mode? > I would be glad to give it a try. Please move this topic to: https://lists.fedorahosted.org/mailman/listinfo/elfutils-devel aarch64 elfutils port is now posted by Petr Machata. The elfutils unwinder part for aarch64 (or arm) has not been written yet. Jan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] perf top: Make -g refer to callchains
On Mon, 18 Nov 2013 18:49:45 +0100, Jiri Olsa wrote: > I think it's an option.. but it'll simpler to try the libdw > interface first and see if it's good/fast enough.. The elfutils libdw unwinder is being upstreamed these weeks, the x86* unwinder itself is already upstream now. > also I recall discussing the speed with libdw developer My tests with perf using elfutils unwinder were 10x faster than libunwind; this is by some simple caching of ELF files. Sure a similar cache could be implemented also for libunwind. But the cache is a wrong solution. The problem is that currently perf loads the ELF files again and again for every process as the ELF file always gets automatically relocated for the address where it was loaded. The right way is to load the ELF file only once and access always the same copy with process-specific displacement only. I did not investigate how much feasible it is with libunwind. For elfutils there is pmachata/sharing unfinished branch from 2008 to implement that. I have not checked it more before the unwinder gets fully upstreamed. Jan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] ptrace: make PTRACE_DETACH work on non-stopped tracees.
On Wed, 19 Jun 2013 17:15:36 +0200, Denys Vlasenko wrote: > CCing Jan to hear his comments from gdb side. GDB never calls PTRACE_DETACH without having the inferior already stopped. Jan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 0/2] ptrace/x86: simplify ptrace_write_dr7()
On Tue, 16 Apr 2013 15:25:45 +0200, Oleg Nesterov wrote: > On 04/16, Frederic Weisbecker wrote: > > On Sun, Apr 14, 2013 at 09:12:05PM +0200, Oleg Nesterov wrote: > > Looking at the bug report, it seems they only reproduced with a homemade > > test. No real app has reported that issue? > > iirc (Jan can correct me) gdb hit this problem, but it was already > changed to change DR0 first. Both old GDB and recent GDB handle it correctly (DR0 first, then DR7). I do not remember how but I have hit this issue, probably during development of the GDB watchpoint code, there were many variants of it in the past. So it was not found just by an artificial testing. My concern was not so much about GDB but rather about possible other existing debugging/tracing software using DR. Jan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 0/2] ptrace/x86: simplify ptrace_write_dr7()
On Sun, 14 Apr 2013 21:12:05 +0200, Oleg Nesterov wrote: > Jan, Frederic, et all. What do you think we should do? > > 1. Change ptrace_write_dr7() to do register_user_hw_breakpoint() > if necessary. > > This is what I was going to do, but I am no longer sure > we want this. For what? Unlikely it is very useful to use > the "default" addr == 0 for debugging. I do not understand how these functions map to the PTRACE_* syscall. But this was a regression from the application point of view as some application did/do: * waitpid - get the process to: t (tracing stop) * PTRACE_POKEUSER DR7, enableDR0 * PTRACE_POKEUSER DR0, address * PTRACE_CONT This was perfectly valid before, there is no "default" addr == 0 used for any debugging. Just the applications did not care about PTRACE_POKEUSER ordering. This is also how the bug was found. Thanks, Jan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: PTRACE_SYSCALL && vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)
On Sun, 02 Dec 2012 20:30:58 +0100, Oleg Nesterov wrote: > Yes, that is why I said this needs the new option. I do not mind new options although personally I do not find them meaningful for an already deprecated ABI compatibility-only issue. > If the tracer does PTRACE_SYSCALL the tracee reports syscall exit > _after_ gettimeofday/etc. The tracer can look at regs->orig_ax == -1 > and detect that this is not syscall but vsyscall, it can look at > regs->ip then (not with the patch below). I believe applications just call PTRACE_SYSCALL twice, without checking orig_eax. At least strace and its TCB_INSYSCALL looks so. On Mon, 03 Dec 2012 00:54:58 +0100, u3...@miso.sublimeip.com wrote: > The beauty of using the x86 debug-registers, x86 debug registers are already very scarce. Besides that userland applications know they have 4 of them available so it would also break them. Regards, Jan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [BUG] i386 relocable kernel breakes /proc/kcore debugging
On Mon, 30 Jul 2007 10:03:03 +0200, Vivek Goyal wrote: > On Sat, Jul 28, 2007 at 04:43:43AM +0300, Maxim Levitsky wrote: ... > > gdb 'thinks' that all kernel symbols are below 0x8000 , while they are > > at > > 0xC000 > > > > Turning CONFIG_RELOCATABLE off fixes that, so I assume that is the reason > > for > > that. > > This is a gdb issue. I had raised it in gdb mailing list some time back. > > http://sourceware.org/ml/gdb/2006-08/msg00137.html There was the patch post: http://sources.redhat.com/ml/gdb/2006-08/msg00182.html > What version of gdb you are using? I know it got fixed for gdb shipped > with RHEL5. I am not sure about what upstream version of gdb it got fixed > in. It did not make it to the upstream as the patch above is an imperfect one. It is fixed in RH gdb-6.5-5 upwards, therefore Fedora 6 + RHEL-5. http://cvs.fedora.redhat.com/viewcvs/*checkout*/devel/gdb/gdb-6.5-bz203661-emit-relocs.patch?root=core Regards, Jan - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Support for controlling leds on xbox 360 pad.
Hi, the previous patch made led support dependent on force feedback. Which doesn't make sense from user point of view. So this patch removes this odd dependency. I made it in separate patch to make my changes easier to review. Led support of xbox 360 now doesn't depend on force feedback. Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]> --- drivers/input/joystick/Kconfig |2 +- drivers/input/joystick/xpad.c | 87 ++-- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index 2098ab6..e6c7560 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig @@ -276,7 +276,7 @@ config JOYSTICK_XPAD_FF config JOYSTICK_XPAD_LEDS bool "LED Support for Xbox360 controller 'BigX' LED" - depends on LEDS_CLASS && JOYSTICK_XPAD_FF + depends on LEDS_CLASS && JOYSTICK_XPAD ---help--- This option enables support for the LED which surrounds the Big X on XBox 360 controller. diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 4a51d6f..b51229f 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -194,7 +194,7 @@ struct usb_xpad { unsigned char *idata; /* input data */ dma_addr_t idata_dma; -#ifdef CONFIG_JOYSTICK_XPAD_FF +#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) struct urb *irq_out;/* urb for interrupt out report */ unsigned char *odata; /* output data */ dma_addr_t odata_dma; @@ -358,7 +358,7 @@ exit: __FUNCTION__, retval); } -#ifdef CONFIG_JOYSTICK_XPAD_FF +#if defined(CONFIG_JOYSTICK_XPAD_FF) || defined(CONFIG_JOYSTICK_XPAD_LEDS) static void xpad_irq_out(struct urb *urb) { int retval; @@ -385,28 +385,7 @@ exit: __FUNCTION__, retval); } -int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) -{ - struct usb_xpad *xpad = input_get_drvdata(dev); - - if (effect->type == FF_RUMBLE) { - __u16 strong = effect->u.rumble.strong_magnitude; - __u16 weak = effect->u.rumble.weak_magnitude; - xpad->odata[0] = 0x00; - xpad->odata[1] = 0x08; - xpad->odata[2] = 0x00; - xpad->odata[3] = strong / 256; - xpad->odata[4] = weak / 256; - xpad->odata[5] = 0x00; - xpad->odata[6] = 0x00; - xpad->odata[7] = 0x00; - usb_submit_urb(xpad->irq_out, GFP_KERNEL); - } - - return 0; -} - -static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) +static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { struct usb_endpoint_descriptor *ep_irq_out; int error = -ENOMEM; @@ -433,25 +412,19 @@ static int xpad_init_ff(struct usb_inter xpad->irq_out->transfer_dma = xpad->odata_dma; xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - input_set_capability(xpad->dev, EV_FF, FF_RUMBLE); - - error = input_ff_create_memless(xpad->dev, NULL, xpad_play_effect); - if (error) - goto fail2; - return 0; fail2:usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); fail1:return error; } -static void xpad_stop_ff(struct usb_xpad *xpad) +static void xpad_stop_output(struct usb_xpad *xpad) { if (xpad->xtype == XTYPE_XBOX360) usb_kill_urb(xpad->irq_out); } -static void xpad_deinit_ff(struct usb_xpad *xpad) +static void xpad_deinit_output(struct usb_xpad *xpad) { if (xpad->xtype == XTYPE_XBOX360) { usb_free_urb(xpad->irq_out); @@ -459,11 +432,43 @@ static void xpad_deinit_ff(struct usb_xp xpad->odata, xpad->odata_dma); } } +#else +static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad) { return 0; } +static void xpad_deinit_output(struct usb_xpad *xpad) {} +static void xpad_stop_output(struct usb_xpad *xpad) {} +#endif + +#ifdef CONFIG_JOYSTICK_XPAD_FF +int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) +{ + struct usb_xpad *xpad = input_get_drvdata(dev); + + if (effect->type == FF_RUMBLE) { + __u16 strong = effect->u.rumble.strong_magnitude; + __u16 weak = effect->u.rumble.weak_magnitude; + xpad->odata[0] = 0x00; + xpad->odata[1] = 0x08; + xpad->odata[2] = 0x00; + xpad->odata[3] = strong / 256; + xpad->odata[4] = weak / 256; + xpad->odata[5] = 0x00; + xpad->odata[6]
Re: [PATCH] Support for controlling leds on xbox 360 pad.
On Wed, 30 May 2007, Jan Kratochvil wrote: Hi, In ideal world having the code in drivers/leds would be preferred but if you want to add the LED code directly to the input driver in this case I have no objection and it probably makes sense. The LED code is already spread about a bit anyway... I wasn't happy about having this splited in two subsystems either. So I'll rewrite it to use led functionality directly from drivers/input/joystick/xpad.c. Hello, so I integrated this patch into xpad.c itself. Xbox360 pad has four leds, which forms a circle. Unfortunately the leds itself are not independent, and we can't control them directle, but rather through sending commands which have predefined meaning (like turn first on, others off) This patch allows us to send these commands via leds subsystem. Commands itself are described here: http://www.free60.org/wiki/Gamepad. Led subsystem allows us to set brightness, but there is nothing like brightness on this device. So brightness is actually interpreted as the command (only values between 0 and 14 are accepted). So this patch uses led subystem in such way that it makes led in /sys/class/leds/xpad[0-9][0-9]/ for each attached xbox 360 pad. Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]> --- drivers/input/joystick/Kconfig |7 ++ drivers/input/joystick/xpad.c | 134 ++- 2 files changed, 137 insertions(+), 4 deletions(-) diff --git a/drivers/input/joystick/Kconfig b/drivers/input/joystick/Kconfig index a15a923..2098ab6 100644 --- a/drivers/input/joystick/Kconfig +++ b/drivers/input/joystick/Kconfig @@ -274,4 +274,11 @@ config JOYSTICK_XPAD_FF ---help--- Say Y here if you want to take advantage of xbox 360 rumble features. +config JOYSTICK_XPAD_LEDS + bool "LED Support for Xbox360 controller 'BigX' LED" + depends on LEDS_CLASS && JOYSTICK_XPAD_FF + ---help--- + This option enables support for the LED which surrounds the Big X on + XBox 360 controller. + endif diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index f3f2ade..4a51d6f 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -198,6 +198,7 @@ struct usb_xpad { struct urb *irq_out;/* urb for interrupt out report */ unsigned char *odata; /* output data */ dma_addr_t odata_dma; + struct mutex odata_mutex; #endif char phys[65]; /* physical device path */ @@ -418,6 +419,8 @@ static int xpad_init_ff(struct usb_inter if (!xpad->odata) goto fail1; + mutex_init(&xpad->odata_mutex); + xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_out) goto fail2; @@ -463,6 +466,123 @@ static void xpad_stop_ff(struct usb_xpad static void xpad_deinit_ff(struct usb_xpad *xpad) { } #endif +#if defined(CONFIG_JOYSTICK_XPAD_LEDS) +#include + +struct xpad_led { + struct led_classdev cdev; + + unsigned intid; + struct usb_xpad * xpad; + struct list_headnode; +}; + +static LIST_HEAD(xpad_led_list); + +static void xpad_send_command(int command, struct usb_xpad *xpad) +{ + if (command >= 0 && command < 14) { + mutex_lock(&xpad->odata_mutex); + xpad->odata[0] = 0x01; + xpad->odata[1] = 0x03; + xpad->odata[2] = command; + usb_submit_urb(xpad->irq_out, GFP_KERNEL); + mutex_unlock(&xpad->odata_mutex); + } +} + +static void xpad_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct xpad_led *led_dev = + container_of(led_cdev, struct xpad_led, cdev); + + xpad_send_command(value, led_dev->xpad); +} + +int xpad_led_probe(struct usb_xpad *xpad) +{ + int i = 0; + struct xpad_led *pos_led; + struct xpad_led *new_led; + int error = -ENOMEM; + char *name; + + if (xpad->xtype != XTYPE_XBOX360) + return 0; + + list_for_each_entry(pos_led, &xpad_led_list, node) { + if (pos_led->id == i) + i++; + else + break; + } + + if (i > 99) + goto fail1; + + new_led = kzalloc(sizeof(struct xpad_led), GFP_KERNEL); + if (!new_led) + goto fail1; + + new_led->id = i; + + name = kzalloc(sizeof(char)*7, GFP_KERNEL); + if (!name) + goto fail2; + + strcpy(name, "xpad"); + name[4] = '0' + i / 10; + name[5] = '0' + i % 10; + name[6] = 0; + + new_led->cdev.name = name; + new_led->cdev.brightness_set = xpad_led_set; + new_led->xpad
Re: [PATCH] Support for controlling leds on xbox 360 pad.
Hi, On Thu, 31 May 2007, Pavel Machek wrote: Led subsystem allows us to set brightness, but there is nothing like brightness on this device. So brightness is actually interpreted as the command (only values between 0 and 14 are accepted). Ugh, no, I do not think we want to do that. finally! I was surprised that it took so long before someone made objection to this. I agree that interpreting brightness as command isn't nice. But what other options do I have? a) Do not use led subystem, and do everything on my own b) Do not allow user to change state of leds on this device c) Extend led subsystem to have something like command. But it is in contradiction with desired simplicity of led sybsystem. d) Control leds via force feedback effect e) Make 4 leds available and use brightness 0 for off and 255 for on. But only one of them can be active at one time. And I'll give up some flashing effects. Well actually I don't like this options. Any suggestions? Thanks! Jan - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Support for controlling leds on xbox 360 pad.
Hi, On Wed, 30 May 2007, Richard Purdie wrote: On Wed, 2007-05-30 at 10:56 -0400, Dmitry Torokhov wrote: Do you think it makes sense to split the driver (and Kconfig options) between input and leds directories as Jan had done? I know that I prefer to keep anything input related in input directory because it makes my life as maintainer easier and I bet you prefer the same but it does not always work well for multifunction devices or devices using several subsystems... In ideal world having the code in drivers/leds would be preferred but if you want to add the LED code directly to the input driver in this case I have no objection and it probably makes sense. The LED code is already spread about a bit anyway... I wasn't happy about having this splited in two subsystems either. So I'll rewrite it to use led functionality directly from drivers/input/joystick/xpad.c. Thanks for comments Jan - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] Support for controlling leds on xbox 360 pad.
Hello, I have question, probably for Richard. Why is /sys/class/leds/whatsoever/brightness mode set to 0644? Is it really necessary? I feel like I'll be happy to allow anybody to change the state of this led. (Ok this maybe doesn't apply to other leds) So this patch uses led subystem in such way that it makes led in /sys/class/leds/xpad:[0-9][0-9]/ for each attached xbox 360 pad. I have the impression that the led subsystem doesn't actually count with possibility to have more then one device of one type, right? In my case there can by lots of pads, so I made it on my own, using counter. Is it ok? Thanks Jan Kratochvil - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] Support for controlling leds on xbox 360 pad.
Hello, this patch is against current input tree. Xbox360 pad has four leds, which forms a circle. Unfortunately the leds itself are not independent, and we can't control them directle, but rather through sending commands which have predefined meaning (like turn first on, others off) This patch allows us to send these commands via leds subsystem. Commands itself are described here: http://www.free60.org/wiki/Gamepad. Led subsystem allows us to set brightness, but there is nothing like brightness on this device. So brightness is actually interpreted as the command (only values between 0 and 14 are accepted). So this patch uses led subystem in such way that it makes led in /sys/class/leds/xpad:[0-9][0-9]/ for each attached xbox 360 pad. Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]> --- drivers/input/joystick/xpad.c | 34 --- drivers/input/joystick/xpad.h | 35 drivers/leds/Kconfig |7 ++ drivers/leds/Makefile |1 + drivers/leds/leds-xpad.c | 123 + 5 files changed, 179 insertions(+), 21 deletions(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 664c765..4322ec9 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -79,6 +79,8 @@ #include #include +#include "xpad.h" + #define DRIVER_VERSION "v0.0.6" #define DRIVER_AUTHOR "Marko Friedemann <[EMAIL PROTECTED]>" #define DRIVER_DESC "X-Box pad driver" @@ -184,26 +186,6 @@ static struct usb_device_id xpad_table [ MODULE_DEVICE_TABLE (usb, xpad_table); -struct usb_xpad { - struct input_dev *dev; /* input device interface */ - struct usb_device *udev;/* usb device */ - - struct urb *irq_in; /* urb for interrupt in report */ - unsigned char *idata; /* input data */ - dma_addr_t idata_dma; - -#ifdef CONFIG_JOYSTICK_XPAD_FF - struct urb *irq_out;/* urb for interrupt out report */ - unsigned char *odata; /* output data */ - dma_addr_t odata_dma; -#endif - - char phys[65]; /* physical device path */ - - int dpad_mapping; /* map d-pad to buttons or to axes */ - int xtype; /* type of xbox device */ -}; - /* * xpad_process_packet * @@ -384,6 +366,7 @@ int xpad_play_effect(struct input_dev *d if (effect->type == FF_RUMBLE) { __u16 strong = effect->u.rumble.strong_magnitude; __u16 weak = effect->u.rumble.weak_magnitude; + mutex_lock(&xpad->odata_mutex); xpad->odata[0] = 0x00; xpad->odata[1] = 0x08; xpad->odata[2] = 0x00; @@ -393,6 +376,7 @@ int xpad_play_effect(struct input_dev *d xpad->odata[6] = 0x00; xpad->odata[7] = 0x00; usb_submit_urb(xpad->irq_out, GFP_KERNEL); + mutex_unlock(&xpad->odata_mutex); } return 0; @@ -408,8 +392,10 @@ static int xpad_init_ff(struct usb_inter xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, GFP_ATOMIC, &xpad->odata_dma ); - if (!xpad->idata) + if (!xpad->odata) goto fail1; + + mutex_init(&xpad->odata_mutex); xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); if (!xpad->irq_out) @@ -568,6 +554,9 @@ static int xpad_probe(struct usb_interfa if (error) goto fail2; + if (xpad->xtype == XTYPE_XBOX360) + xpad_led_probe(xpad); + ep_irq_in = &intf->cur_altsetting->endpoint[0].desc; usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), @@ -597,6 +586,9 @@ static void xpad_disconnect(struct usb_i usb_set_intfdata(intf, NULL); if (xpad) { + if (xpad->xtype == XTYPE_XBOX360) + xpad_led_disconnect(xpad); + input_unregister_device(xpad->dev); xpad_deinit_ff(xpad); usb_free_urb(xpad->irq_in); diff --git a/drivers/input/joystick/xpad.h b/drivers/input/joystick/xpad.h new file mode 100644 index 000..487a129 --- /dev/null +++ b/drivers/input/joystick/xpad.h @@ -0,0 +1,35 @@ +#ifndef __INPUT_XPAD_H_INCLUDED +#define __INPUT_XPAD_H_INCLUDED + +#include + +struct usb_xpad { + struct input_dev *dev; /* input device interface */ + struct usb_device *udev;/* usb device */ + + struct urb *irq_in; /* urb for interrupt in report */ + unsigned char *idata; /* input data */ + dma_addr_t idata_dma; + +#ifdef CONFIG_JOYSTICK_XPAD_FF + struct urb *irq_out;/* urb
Re: [PATCH][RESEND] PIE randomization
Hi, sorry for insufficient description in my earlier post. I hope it is better this time. Jiri: Thanks for help, I applied your change on my previous patch. This patch is using mmap()'s randomization functionality in such a way that it maps the main executable of (specially compiled/linked -pie/-fpie) ET_DYN binaries onto a random address (in cases in which mmap() is allowed to perform a randomization). Origin of this patch is in exec-shield (http://people.redhat.com/mingo/exec-shield/) Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]> --- fs/binfmt_elf.c | 99 ++ 1 files changed, 77 insertions(+), 22 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index fa8ea33..8406f9a 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -45,7 +45,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); static int load_elf_library(struct file *); -static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); +static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int, unsigned long); /* * If we don't support core dumping, then supply a NULL so we @@ -80,7 +80,7 @@ static struct linux_binfmt elf_format = .hasvdso= 1 }; -#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) +#define BAD_ADDR(x) ((unsigned long)(x) >= PAGE_MASK) static int set_brk(unsigned long start, unsigned long end) { @@ -285,33 +285,70 @@ create_elf_tables(struct linux_binprm *b #ifndef elf_map static unsigned long elf_map(struct file *filep, unsigned long addr, - struct elf_phdr *eppnt, int prot, int type) + struct elf_phdr *eppnt, int prot, int type, + unsigned long total_size) { unsigned long map_addr; - unsigned long pageoffset = ELF_PAGEOFFSET(eppnt->p_vaddr); + unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr); + unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr); + addr = ELF_PAGESTART(addr); + size = ELF_PAGEALIGN(size); - down_write(¤t->mm->mmap_sem); /* mmap() will return -EINVAL if given a zero size, but a * segment with zero filesize is perfectly valid */ - if (eppnt->p_filesz + pageoffset) - map_addr = do_mmap(filep, ELF_PAGESTART(addr), - eppnt->p_filesz + pageoffset, prot, type, - eppnt->p_offset - pageoffset); - else - map_addr = ELF_PAGESTART(addr); + if (!size) + return addr; + + down_write(¤t->mm->mmap_sem); + /* + * total_size is the size of the ELF (interpreter) image. + * The _first_ mmap needs to know the full size, otherwise + * randomization might put this image into an overlapping + * position with the ELF binary image. (since size < total_size) + * So we first map the 'big' image - and unmap the remainder at + * the end. (which unmap is needed for ELF images with holes.) + */ + if (total_size) { + total_size = ELF_PAGEALIGN(total_size); + map_addr = do_mmap(filep, addr, total_size, prot, type, off); + if (!BAD_ADDR(map_addr)) + do_munmap(current->mm, map_addr+size, total_size-size); + } else + map_addr = do_mmap(filep, addr, size, prot, type, off); + up_write(¤t->mm->mmap_sem); return(map_addr); } #endif /* !elf_map */ +static inline unsigned long total_mapping_size(struct elf_phdr *cmds, int nr) +{ + int i, first_idx = -1, last_idx = -1; + + for (i = 0; i < nr; i++) + if (cmds[i].p_type == PT_LOAD) { + last_idx = i; + if (first_idx == -1) + first_idx = i; + } + + if (first_idx == -1) + return 0; + + return cmds[last_idx].p_vaddr + cmds[last_idx].p_memsz - + ELF_PAGESTART(cmds[first_idx].p_vaddr); +} + + /* This is much more generalized than the library routine read function, so we keep this separate. Technically the library read function is only provided so that we can read a.out libraries that have an ELF header */ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, - struct file *interpreter, unsigned long *interp_load_addr) + struct file *interpreter, unsigned long *interp_map_addr, + unsigned long no_base) { struct elf_phdr *elf_phdata; struct elf_phdr *eppnt; @@ -319,6 +356,7 @@ static unsigned long load_elf_interp(str int load_addr_set = 0; unsigned long last_bss = 0, elf_bss = 0; unsigned long error = ~0UL; + unsigned
[PATCH][RESEND] PIE randomization
Hello, I sent this patch 5 days ago, nobody replied. So I am giving it second attempt. Andrew, is it possible to test this in -mm branch? Original mail follows: Hi, this is something like reaction to this thread: http://lkml.org/lkml/2007/1/6/124. I hope I was able to separate the PIE randomization part correctly. There is platform specific (__i386__ only) part in exec shield, I am not pretty sure why is it there, but wasn't brave enough to touch it. Can someone comment the #ifdef out and test it on some other platform? It will be nice to follow with brk randomization, but in exec-shield it is afaik i386 only. Right? Randomizes -pie compiled binaries. The implementation is part of Redhat's exec-shield (http://people.redhat.com/mingo/exec-shield/). Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]> --- fs/binfmt_elf.c | 96 ++ 1 files changed, 74 insertions(+), 22 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 9cc4f0a..1156f41 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -45,7 +45,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); static int load_elf_library(struct file *); -static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); +static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int, unsigned long); /* * If we don't support core dumping, then supply a NULL so we @@ -80,7 +80,7 @@ static struct linux_binfmt elf_format = .hasvdso= 1 }; -#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) +#define BAD_ADDR(x) ((unsigned long)(x) >= PAGE_MASK) static int set_brk(unsigned long start, unsigned long end) { @@ -285,33 +285,70 @@ create_elf_tables(struct linux_binprm *b #ifndef elf_map static unsigned long elf_map(struct file *filep, unsigned long addr, - struct elf_phdr *eppnt, int prot, int type) + struct elf_phdr *eppnt, int prot, int type, + unsigned long total_size) { unsigned long map_addr; - unsigned long pageoffset = ELF_PAGEOFFSET(eppnt->p_vaddr); + unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr); + unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr); + addr = ELF_PAGESTART(addr); + size = ELF_PAGEALIGN(size); - down_write(¤t->mm->mmap_sem); /* mmap() will return -EINVAL if given a zero size, but a * segment with zero filesize is perfectly valid */ - if (eppnt->p_filesz + pageoffset) - map_addr = do_mmap(filep, ELF_PAGESTART(addr), - eppnt->p_filesz + pageoffset, prot, type, - eppnt->p_offset - pageoffset); - else - map_addr = ELF_PAGESTART(addr); + if (!size) + return addr; + + down_write(¤t->mm->mmap_sem); + /* + * total_size is the size of the ELF (interpreter) image. + * The _first_ mmap needs to know the full size, otherwise + * randomization might put this image into an overlapping + * position with the ELF binary image. (since size < total_size) + * So we first map the 'big' image - and unmap the remainder at + * the end. (which unmap is needed for ELF images with holes.) + */ + if (total_size) { + total_size = ELF_PAGEALIGN(total_size); + map_addr = do_mmap(filep, addr, total_size, prot, type, off); + if (!BAD_ADDR(map_addr)) + do_munmap(current->mm, map_addr+size, total_size-size); + } else + map_addr = do_mmap(filep, addr, size, prot, type, off); + up_write(¤t->mm->mmap_sem); return(map_addr); } #endif /* !elf_map */ +static inline unsigned long total_mapping_size(struct elf_phdr *cmds, int nr) +{ + int i, first_idx = -1, last_idx = -1; + + for (i = 0; i < nr; i++) + if (cmds[i].p_type == PT_LOAD) { + last_idx = i; + if (first_idx == -1) + first_idx = i; + } + + if (first_idx == -1) + return 0; + + return cmds[last_idx].p_vaddr + cmds[last_idx].p_memsz - + ELF_PAGESTART(cmds[first_idx].p_vaddr); +} + + /* This is much more generalized than the library routine read function, so we keep this separate. Technically the library read function is only provided so that we can read a.out libraries that have an ELF header */ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, - struct file *interpreter, unsigned long *interp_load_addr) + struct file *interpreter, unsigned long *interp_load_addr, +
[PATCH] PIE randomization
Hi, this is something like reaction to this thread: http://lkml.org/lkml/2007/1/6/124. I hope I was able to separate the PIE randomization part correctly. There is platform specific (__i386__ only) part in exec shield, I am not pretty sure why is it there, but wasn't brave enough to touch it. Can someone comment the #ifdef out and test it on some other platform? It will be nice to follow with brk randomization, but in exec-shield it is afaik i386 only. Right? Randomizes -pie compiled binaries. The implementation is part of Redhat's exec-shield (http://people.redhat.com/mingo/exec-shield/). Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]> --- fs/binfmt_elf.c | 96 ++ 1 files changed, 74 insertions(+), 22 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 9cc4f0a..1156f41 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -45,7 +45,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); static int load_elf_library(struct file *); -static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); +static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int, unsigned long); /* * If we don't support core dumping, then supply a NULL so we @@ -80,7 +80,7 @@ static struct linux_binfmt elf_format = .hasvdso= 1 }; -#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) +#define BAD_ADDR(x) ((unsigned long)(x) >= PAGE_MASK) static int set_brk(unsigned long start, unsigned long end) { @@ -285,33 +285,70 @@ create_elf_tables(struct linux_binprm *b #ifndef elf_map static unsigned long elf_map(struct file *filep, unsigned long addr, - struct elf_phdr *eppnt, int prot, int type) + struct elf_phdr *eppnt, int prot, int type, + unsigned long total_size) { unsigned long map_addr; - unsigned long pageoffset = ELF_PAGEOFFSET(eppnt->p_vaddr); + unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr); + unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr); + addr = ELF_PAGESTART(addr); + size = ELF_PAGEALIGN(size); - down_write(¤t->mm->mmap_sem); /* mmap() will return -EINVAL if given a zero size, but a * segment with zero filesize is perfectly valid */ - if (eppnt->p_filesz + pageoffset) - map_addr = do_mmap(filep, ELF_PAGESTART(addr), - eppnt->p_filesz + pageoffset, prot, type, - eppnt->p_offset - pageoffset); - else - map_addr = ELF_PAGESTART(addr); + if (!size) + return addr; + + down_write(¤t->mm->mmap_sem); + /* + * total_size is the size of the ELF (interpreter) image. + * The _first_ mmap needs to know the full size, otherwise + * randomization might put this image into an overlapping + * position with the ELF binary image. (since size < total_size) + * So we first map the 'big' image - and unmap the remainder at + * the end. (which unmap is needed for ELF images with holes.) + */ + if (total_size) { + total_size = ELF_PAGEALIGN(total_size); + map_addr = do_mmap(filep, addr, total_size, prot, type, off); + if (!BAD_ADDR(map_addr)) + do_munmap(current->mm, map_addr+size, total_size-size); + } else + map_addr = do_mmap(filep, addr, size, prot, type, off); + up_write(¤t->mm->mmap_sem); return(map_addr); } #endif /* !elf_map */ +static inline unsigned long total_mapping_size(struct elf_phdr *cmds, int nr) +{ + int i, first_idx = -1, last_idx = -1; + + for (i = 0; i < nr; i++) + if (cmds[i].p_type == PT_LOAD) { + last_idx = i; + if (first_idx == -1) + first_idx = i; + } + + if (first_idx == -1) + return 0; + + return cmds[last_idx].p_vaddr + cmds[last_idx].p_memsz - + ELF_PAGESTART(cmds[first_idx].p_vaddr); +} + + /* This is much more generalized than the library routine read function, so we keep this separate. Technically the library read function is only provided so that we can read a.out libraries that have an ELF header */ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, - struct file *interpreter, unsigned long *interp_load_addr) + struct file *interpreter, unsigned long *interp_load_addr, + unsigned long no_base) { struct elf_phdr *elf_phdata; struct elf_phdr *eppnt; @@ -319,6 +356,7 @@ static unsigned long load_elf_interp(str int load_addr_set
Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.
Hi again, what do you think about this? (This patch will work only against last gamepad rumble support patch) Thanks for your time Jan Kratochvil BigX button on xbox360 gamepad is surrounded by 4 green leds. This patch adds support to control them. This device understand to 14 messages (described at http://www.free60.org/wiki/Gamepad#LED_Control). Control is done through event interface, message type EV_LED. EV_LED isn't perfect match because you are actualy not turning some led on or off but more likely you are telling the gamepad what "flash effect" it should play. Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]> --- drivers/usb/input/xpad.c | 31 --- 1 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index d117e71..8b38990 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -397,13 +397,33 @@ int xpad_play_effect(struct input_dev *d return 0; } +int xpad_input_event(struct input_dev *dev, unsigned int type, +unsigned int code, int value) +{ + switch (type) { + case EV_FF: + return input_ff_event(dev,type,code,value); + case EV_LED: { + struct usb_xpad *xpad = dev->private; + change_bit(code,dev->led); + xpad->odata[0] = 0x01; + xpad->odata[1] = 0x03; + xpad->odata[2] = code; + usb_submit_urb(xpad->irq_out, GFP_KERNEL); + return 0; + } + default: + return -EINVAL; + } +} + static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) { if (xpad->xtype == TYPE_XBOX360) { struct usb_endpoint_descriptor *ep_irq_out; - int rv; + int i; - xpad->dev->evbit[0] |= BIT(EV_FF); + xpad->dev->evbit[0] |= BIT(EV_FF) | BIT(EV_LED); xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, GFP_ATOMIC, &xpad->odata_dma ); @@ -422,11 +442,16 @@ static int xpad_init_ff(struct usb_inter xpad->irq_out->transfer_dma = xpad->odata_dma; xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - set_bit( FF_RUMBLE, xpad->dev->ffbit ); + set_bit(FF_RUMBLE, xpad->dev->ffbit); + for (i=0;i<16;++i) + set_bit(i, xpad->dev->ledbit); + if (input_ff_create_memless(xpad->dev, NULL, xpad_play_effect)) { goto fail2; } + xpad->dev->event = xpad_input_event; + return 0; fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); -- 1.4.3.4 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.
Hi Dmitry, thanks for feedback. Improved version of this patch follows: It is enabled only if CONFIG_XPAD_FF is set to y. Implementation is using force feedback support for memoryless devices. Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]> --- drivers/usb/input/Kconfig |7 +++ drivers/usb/input/xpad.c | 116 - 2 files changed, 122 insertions(+), 1 deletions(-) diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index a792e42..8963522 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig @@ -149,6 +149,13 @@ config USB_XPAD To compile this driver as a module, choose M here: the module will be called xpad. +config XPAD_FF + bool "X-Box gamepad rumble support" + depends on USB_XPAD && INPUT + select INPUT_FF_MEMLESS + ---help--- + Say Y here if you want to take advantage of xbox 360 rumble features. + config USB_ATI_REMOTE tristate "ATI / X10 USB RF remote control" depends on USB && INPUT diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index 75d1a62..d117e71 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -192,6 +192,12 @@ struct usb_xpad { unsigned char *idata; /* input data */ dma_addr_t idata_dma; +#ifdef CONFIG_XPAD_FF + struct urb *irq_out;/* urb for interrupt out report */ + unsigned char *odata; /* output data */ + dma_addr_t odata_dma; +#endif + char phys[65]; /* physical device path */ int dpad_mapping; /* map d-pad to buttons or to axes */ @@ -344,6 +350,106 @@ exit: __FUNCTION__, retval); } +#ifdef CONFIG_XPAD_FF +static void xpad_irq_out(struct urb *urb) +{ + int retval; + + switch (urb->status) { + case 0: + /* success */ + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); + return; + default: + dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); + goto exit; + } + +exit: + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) + err("%s - usb_submit_urb failed with result %d", + __FUNCTION__, retval); +} + +int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) +{ + struct usb_xpad *xpad = dev->private; + if (effect->type == FF_RUMBLE) { + __u16 strong = effect->u.rumble.strong_magnitude; + __u16 weak = effect->u.rumble.weak_magnitude; + xpad->odata[0] = 0x00; + xpad->odata[1] = 0x08; + xpad->odata[2] = 0x00; + xpad->odata[3] = strong / 256; + xpad->odata[4] = weak / 256; + xpad->odata[5] = 0x00; + xpad->odata[6] = 0x00; + xpad->odata[7] = 0x00; + usb_submit_urb(xpad->irq_out, GFP_KERNEL); + } + + return 0; +} + +static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) +{ + if (xpad->xtype == XTYPE_XBOX360) { + struct usb_endpoint_descriptor *ep_irq_out; + int rv; + + xpad->dev->evbit[0] |= BIT(EV_FF); + + xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, + GFP_ATOMIC, &xpad->odata_dma ); + if (!xpad->idata) + goto fail1; + + xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); + if (!xpad->irq_out) + goto fail2; + + ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; + usb_fill_int_urb(xpad->irq_out, xpad->udev, +usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress), +xpad->odata, XPAD_PKT_LEN, +xpad_irq_out, xpad, ep_irq_out->bInterval); + xpad->irq_out->transfer_dma = xpad->odata_dma; + xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + set_bit( FF_RUMBLE, xpad->dev->ffbit ); + if (input_ff_create_memless(xpad->dev, NULL, xpad_play_effect)) { + goto fail2; + } + + return 0; + +fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); +fail1: + return -ENOMEM; + } + return 0; +} + +static void xpad_deinit_ff(struct usb_interface *intf, struct usb_xpad *xpad) +{ + if
Re: [PATCH 2/3] xpad.c: Initial support for xbox360 gamepad.
Hi, now this patch doesn't need flags but rather adds new member xtype. Xbox 360 gamepad is slightly different then the previous model so it has its own version of process_packet method. Detection of this new device relies on USB_DEVICE_INTERFACE_PROTOCOL macro. This device got vendor specific subclass so it can't be matched with USB_INTERFACE_INFO and we need only one interface protocol from four availaible. It means USB_DEVICE can't be used either. Added xpad360_btn structure with additional buttons for x360 gamepad. Added xtype into xpad_device structure to distinguish between different types of xbox devices. Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]> --- drivers/usb/input/xpad.c | 151 +++-- 1 files changed, 117 insertions(+), 34 deletions(-) diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index e4bc76e..75d1a62 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -8,6 +8,7 @@ *Ivan Hawkes <[EMAIL PROTECTED]> * 2005 Dominic Cerquetti <[EMAIL PROTECTED]> * 2006 Adam Buchbinder <[EMAIL PROTECTED]> + * 2007 Jan Kratochvil <[EMAIL PROTECTED]> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -28,6 +29,7 @@ * - information from http://euc.jp/periphs/xbox-controller.ja.html * - the iForce driverdrivers/char/joystick/iforce.c * - the skeleton-driver drivers/usb/usb-skeleton.c + * - Xbox 360 information http://www.free60.org/wiki/Gamepad * * Thanks to: * - ITO Takayuki for providing essential xpad information on his website @@ -89,6 +91,9 @@ #define MAP_DPAD_TO_AXES 1 #define MAP_DPAD_UNKNOWN -1 +#define XTYPE_XBOX0 +#define XTYPE_XBOX360 1 + static int dpad_to_buttons; module_param(dpad_to_buttons, bool, S_IRUGO); MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads"); @@ -98,40 +103,42 @@ static const struct xpad_device { u16 idProduct; char *name; u8 dpad_mapping; + u8 xtype; } xpad_device[] = { - { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS }, - { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES }, - { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES }, - { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES }, - { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES }, - { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS }, - { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS }, - { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES }, - { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES }, - { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES}, - { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES }, - { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES }, - { 0x0f30, 0x, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES }, - { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES }, - { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS }, - { 0x1430, 0x, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS }, -
Re: [PATCH 1/3] xpad.c: Added flags into xpad_device structure and removed dpad_mapping.
Hi Dmitry, On Wed, 2 May 2007, Dmitry Torokhov wrote: Hi Jan, On Wednesday 02 May 2007 11:01, Jan Kratochvil wrote: This changes are expected to simplify further improves of this driver, We will need to add information if the driver is xbox360 device or not. Second option was to simply add u8 is_360, but what if we'll need to know if device is a wheel? Or if the device can have keyboard (or headset) attached. ... -#define MAP_DPAD_TO_BUTTONS0 -#define MAP_DPAD_TO_AXES 1 -#define MAP_DPAD_UNKNOWN -1 +#define XPAD_FLAGS_DPAD_TO_BUTTONS(1 << 0) +#define XPAD_FLAGS_DPAD_TO_AXES (1 << 1) +#define XPAD_FLAGS_DPAD_UNKNOWN (1 << 2) Turning this into bitmaps suggests that all of these could be set which is not the case. Since there are 3 spare bytes in xpad_device structure to use for additional flags/bitmaps I'd leave dpad_mapping alone. Ok. Lets ignore this patch. -- Dmitry Jan Kratochvil - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.
It is enabled only if CONFIG_XPAD_FF is set to y. Implementation is using force feedback support for memoryless devices. Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]> --- drivers/usb/input/Kconfig |8 +++ drivers/usb/input/xpad.c | 116 + 2 files changed, 124 insertions(+), 0 deletions(-) diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index a792e42..2066200 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig @@ -149,6 +149,14 @@ config USB_XPAD To compile this driver as a module, choose M here: the module will be called xpad. +config XPAD_FF + default n + bool "X-Box gamepad rumble support" + depends on USB_XPAD && INPUT + select INPUT_FF_MEMLESS + ---help--- + Say Y here if you want to take advantage of xbox 360 rumble features. + config USB_ATI_REMOTE tristate "ATI / X10 USB RF remote control" depends on USB && INPUT diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index bac9ec2..2dabde5 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -189,6 +189,12 @@ struct usb_xpad { unsigned char *idata; /* input data */ dma_addr_t idata_dma; +#ifdef CONFIG_XPAD_FF + struct urb *irq_out;/* urb for interrupt out report */ + unsigned char *odata; /* output data */ + dma_addr_t odata_dma; +#endif + char phys[65]; /* physical device path */ u8 flags; /* combination of XPAD_FLAGS_* */ @@ -340,6 +346,103 @@ exit: __FUNCTION__, retval); } +#ifdef CONFIG_XPAD_FF +/** + * xpad_irq_out + */ +static void xpad_irq_out(struct urb *urb) +{ + int retval; + + switch (urb->status) { + case 0: + /* success */ + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); + return; + default: + dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); + goto exit; + } + +exit: + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) + err("%s - usb_submit_urb failed with result %d", + __FUNCTION__, retval); +} + +int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) +{ + struct usb_xpad *xpad = dev->private; + if (effect->type == FF_RUMBLE) { + __u16 strong = effect->u.rumble.strong_magnitude; + __u16 weak = effect->u.rumble.weak_magnitude; + xpad->odata[0] = 0x00; + xpad->odata[1] = 0x08; + xpad->odata[2] = 0x00; + xpad->odata[3] = strong / 256; + xpad->odata[4] = weak / 256; + xpad->odata[5] = 0x00; + xpad->odata[6] = 0x00; + xpad->odata[7] = 0x00; + usb_submit_urb(xpad->irq_out, GFP_KERNEL); + } + + return 0; +} + +static int xpad_init_ff(struct usb_interface *intf, struct usb_xpad *xpad) +{ + if (xpad->flags & XPAD_FLAGS_XBOX360) { + struct usb_endpoint_descriptor *ep_irq_out; + int rv; + + xpad->odata = usb_buffer_alloc(xpad->udev, XPAD_PKT_LEN, + GFP_ATOMIC, &xpad->odata_dma ); + if (!xpad->idata) + goto fail1; + + xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL); + if (!xpad->irq_out) + goto fail2; + + + ep_irq_out = &intf->cur_altsetting->endpoint[1].desc; + usb_fill_int_urb(xpad->irq_out, xpad->udev, +usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress), +xpad->odata, XPAD_PKT_LEN, +xpad_irq_out, xpad, ep_irq_out->bInterval); + xpad->irq_out->transfer_dma = xpad->odata_dma; + xpad->irq_out->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + set_bit( FF_RUMBLE, xpad->dev->ffbit ); + rv = input_ff_create_memless(xpad->dev, NULL, xpad_play_effect); + + return 0; + +fail2: usb_buffer_free(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma); +fail1: + return -ENOMEM; + } + return 0; +} + +static void xpad_deinit_ff(struct usb_in
[PATCH 2/3] xpad.c: Initial support for xbox360 gamepad.
Xbox 360 gamepad is slightly different then the previous model so it has its own version of process_packet method. Detection of this new device relies on USB_DEVICE_INTERFACE_PROTOCOL macro. This device got vendor specific subclass so it can't be matched with USB_INTERFACE_INFO and we need only one interface protocol from four availaible. It means USB_DEVICE can't be used either. Added xpad360_btn structure with additional buttons for x360 gamepad. Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]> --- drivers/usb/input/xpad.c | 80 +- 1 files changed, 79 insertions(+), 1 deletions(-) diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index 2a20aa2..bac9ec2 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -8,6 +8,7 @@ *Ivan Hawkes <[EMAIL PROTECTED]> * 2005 Dominic Cerquetti <[EMAIL PROTECTED]> * 2006 Adam Buchbinder <[EMAIL PROTECTED]> + * 2007 Jan Kratochvil <[EMAIL PROTECTED]> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -28,6 +29,7 @@ * - information from http://euc.jp/periphs/xbox-controller.ja.html * - the iForce driverdrivers/char/joystick/iforce.c * - the skeleton-driver drivers/usb/usb-skeleton.c + * - Xbox 360 information http://www.free60.org/wiki/Gamepad * * Thanks to: * - ITO Takayuki for providing essential xpad information on his website @@ -88,6 +90,7 @@ #define XPAD_FLAGS_DPAD_TO_BUTTONS(1 << 0) #define XPAD_FLAGS_DPAD_TO_AXES (1 << 1) #define XPAD_FLAGS_DPAD_UNKNOWN (1 << 2) +#define XPAD_FLAGS_XBOX360(1 << 3) static int dpad_to_buttons; module_param(dpad_to_buttons, bool, S_IRUGO); @@ -130,6 +133,7 @@ static const struct xpad_device { { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", XPAD_FLAGS_DPAD_TO_AXES }, { 0x12ab, 0x8809, "Xbox DDR dancepad", XPAD_FLAGS_DPAD_TO_BUTTONS }, { 0x1430, 0x, "TX6500+ Dance Pad (first generation)", XPAD_FLAGS_DPAD_TO_BUTTONS }, + { 0x045e, 0x028e, "Microsoft X-Box 360 pad", XPAD_FLAGS_DPAD_TO_AXES | XPAD_FLAGS_XBOX360 }, { 0x, 0x, "Chinese-made Xbox Controller", XPAD_FLAGS_DPAD_TO_AXES }, { 0x, 0x, "Generic X-Box pad", XPAD_FLAGS_DPAD_UNKNOWN } }; @@ -140,6 +144,12 @@ static const signed short xpad_btn[] = { -1 /* terminating entry */ }; +static const signed short xpad360_btn[] = { /* buttons for x360 controller */ + BTN_TL, BTN_TR, /* Button LB/RB */ + BTN_MODE, /* The big X button */ + -1 +}; + /* only used if XPAD_FLAGS_DPAD_TO_BUTTONS */ static const signed short xpad_btn_pad[] = { BTN_LEFT, BTN_RIGHT,/* d-pad left, right */ @@ -160,8 +170,12 @@ static const signed short xpad_abs_pad[] = { -1 /* terminating entry */ }; +/* Xbox 360 has a vendor-specific (sub)class, so we cannot match it with only + * USB_INTERFACE_INFO, more to that this device has 4 InterfaceProtocols, + * but we need only one of them. */ static struct usb_device_id xpad_table [] = { { USB_INTERFACE_INFO('X', 'B', 0) },/* X-Box USB-IF not approved class */ + { USB_DEVICE_INTERFACE_PROTOCOL(0x045e, 0x028e, 1) }, /* X-Box 360 controller */ { } }; @@ -236,6 +250,64 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d input_sync(dev); } +/* + * xpad360_process_packet + * + * Completes a request by converting the data into events for the + * input subsystem. It is version for xbox 360 controller + * + * The used report descriptor was taken from: + * http://www.free60.org/wiki/Gamepad + */ + +static void xpad360_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data) +{ + struct input_dev *dev = xpad->dev; + + /* digital pad */ + if (xpad->flags & XPAD_FLAGS_DPAD_TO_AXES) { + input_report_abs(dev, ABS_HAT0X, !!(data[2] & 0x01) - !!((data[2] & 0x08) >> 3)); + input_report_abs(dev, ABS_HAT0Y, !!((data[2] & 0x02) >> 1) - !!((data[2] & 0x04) >> 2)); + } else if ( xpad->flags & XPAD_FLAGS_DPAD_TO_BUTTONS ) { + /* dpad as buttons (right, left, down, up) */ + input_report_key(dev, BTN_RIGHT, (data[2] & 0x01)); + input_report_key(dev, BTN_LEFT, (data[2] & 0x08) >> 3); + input_report_key(dev, BTN_0, (data[2] & 0x02) >> 1); + input_report_key(dev, BTN_1, (data[2] & 0x04) >> 2); + } + +
[PATCH 1/3] xpad.c: Added flags into xpad_device structure and removed dpad_mapping.
This changes are expected to simplify further improves of this driver, We will need to add information if the driver is xbox360 device or not. Second option was to simply add u8 is_360, but what if we'll need to know if device is a wheel? Or if the device can have keyboard (or headset) attached. Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]> --- drivers/usb/input/xpad.c | 102 - 1 files changed, 54 insertions(+), 48 deletions(-) diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c index e4bc76e..2a20aa2 100644 --- a/drivers/usb/input/xpad.c +++ b/drivers/usb/input/xpad.c @@ -85,9 +85,9 @@ /* xbox d-pads should map to buttons, as is required for DDR pads but we map them to axes when possible to simplify things */ -#define MAP_DPAD_TO_BUTTONS0 -#define MAP_DPAD_TO_AXES 1 -#define MAP_DPAD_UNKNOWN -1 +#define XPAD_FLAGS_DPAD_TO_BUTTONS(1 << 0) +#define XPAD_FLAGS_DPAD_TO_AXES (1 << 1) +#define XPAD_FLAGS_DPAD_UNKNOWN (1 << 2) static int dpad_to_buttons; module_param(dpad_to_buttons, bool, S_IRUGO); @@ -97,41 +97,41 @@ static const struct xpad_device { u16 idVendor; u16 idProduct; char *name; - u8 dpad_mapping; + u8 flags; } xpad_device[] = { - { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", MAP_DPAD_TO_AXES }, - { 0x045e, 0x0287, "Microsoft Xbox Controller S", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", MAP_DPAD_TO_BUTTONS }, - { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", MAP_DPAD_TO_AXES }, - { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", MAP_DPAD_TO_AXES }, - { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", MAP_DPAD_TO_AXES }, - { 0x05fd, 0x1007, "Mad Catz Controller (unverified)", MAP_DPAD_TO_AXES }, - { 0x05fd, 0x107a, "InterAct 'PowerPad Pro' X-Box pad (Germany)", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4516, "Mad Catz Control Pad", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4522, "Mad Catz LumiCON", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4526, "Mad Catz Control Pad Pro", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4536, "Mad Catz MicroCON", MAP_DPAD_TO_AXES }, - { 0x0738, 0x4540, "Mad Catz Beat Pad", MAP_DPAD_TO_BUTTONS }, - { 0x0738, 0x4556, "Mad Catz Lynx Wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS }, - { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES }, - { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES }, - { 0x0e4c, 0x2390, "Radica Games Jtech Controller", MAP_DPAD_TO_AXES}, - { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e6f, 0x0005, "Eclipse wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e6f, 0x0006, "Edge wireless Controller", MAP_DPAD_TO_AXES }, - { 0x0e8f, 0x0201, "SmartJoy Frag Xpad/PS2 adaptor", MAP_DPAD_TO_AXES }, - { 0x0f30, 0x0202, "Joytech Advanced Controller", MAP_DPAD_TO_AXES }, - { 0x0f30, 0x, "BigBen XBMiniPad Controller", MAP_DPAD_TO_AXES }, - { 0x102c, 0xff0c, "Joytech Wireless Advanced Controller", MAP_DPAD_TO_AXES }, - { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS }, - { 0x1430, 0x, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS }, - { 0x, 0x, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES }, - { 0x, 0x, "Generic X-Box pad", MAP_DPAD_UNKNOWN } + { 0x045e, 0x0202, "Microsoft X-Box pad v1 (US)", XPAD_FLAGS_DPAD_TO_AXES }, + { 0x045e, 0x0289, "Microsoft X-Box pad v2 (US)", XPAD_FLAGS_DPAD_TO_AXES }, + { 0x045e, 0x0285, "Microsoft X-Box pad (Japan)", XPAD_FLAGS_DPAD_TO_AXES }, + { 0x045e, 0x0287, "Microsoft Xbox Controller S", XPAD_FLAGS_DPAD_TO_AXES }, + { 0x0c12, 0x8809, "RedOctane Xbox Dance Pad", XPAD_FLAGS_DPAD_TO_BUTTONS }, + { 0x044f, 0x0f07, "Thrustmaster, Inc. Controller", XPAD_FLAGS_DPAD_TO_AXES }, + { 0x046d, 0xca84, "Logitech Xbox Cordless Controller", XPAD_FLAGS_DPAD_TO_AXES }, + { 0x046d, 0xca88, "Logitech Compact Controller for Xbox", XPAD_FLAGS_DPAD_
[PATCH] [RFC] Added USB_DEVICE_INTERFACE_PROTOCOL
The USB_DEVICE_INTERFACE_PROTOCOL will allow to match one interface protocol of vendor specific device. This macro is used in patch adding support for xbox360 to xpad.c Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]> --- include/linux/usb.h | 15 +++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/include/linux/usb.h b/include/linux/usb.h index cfbd2bb..84e2330 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -729,6 +729,21 @@ static inline int usb_endpoint_is_isoc_out(const struct usb_endpoint_descriptor .bcdDevice_lo = (lo), .bcdDevice_hi = (hi) /** + * USB_DEVICE_INTERFACE_PROTOCOL - macro used to describe a usb + * device with a specific interface protocol + * @vend: the 16 bit USB Vendor ID + * @prod: the 16 bit USB Product ID + * @pr: bInterfaceProtocol value + * + * This macro is used to create a struct usb_device_id that matches a + * specific interface protocol of devices. + */ +#define USB_DEVICE_INTERFACE_PROTOCOL(vend,prod,pr) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_PROTOCOL, \ + .idVendor = (vend), \ + .idProduct = (prod), \ + .bInterfaceProtocol = (pr) +/** * USB_DEVICE_INFO - macro used to describe a class of usb devices * @cl: bDeviceClass value * @sc: bDeviceSubClass value -- 1.5.0.6 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/