Re: [PATCH? v2] powerpc: Hard wire PT_SOFTE value to 1 in gpr_get() too

2020-06-11 Thread Jan Kratochvil
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, , 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, , NULL);
# else
  l = ptrace (PTRACE_GETREGS, child, NULL, );
# 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, , NULL);
# else
  l = ptrace (PTRACE_SETREGS, child, NULL, );
# endif
  assert (l == 0);

  /* Peek into U2.  */
# ifdef __sparc__
  l = ptrace (PTRACE_GETREGS, child, , NULL);
# else
  l = ptrace (PTRACE_GETREGS, child, NULL, );
# endif
  assert (l == 0);

  /* Verify it matches.  */
  if (memcmp (, , sizeof u.byte) != 0)
{
  for (start = 0; start + REGALIGN <= sizeof u.byte; start += REGALIGN)
if (*(unsigned long *) (u.byte + 

Re: perf report: fix off-by-one for non-activation frames

2017-06-17 Thread Jan Kratochvil
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

2017-06-17 Thread Jan Kratochvil
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

2017-06-16 Thread Jan Kratochvil
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

2017-06-16 Thread Jan Kratochvil
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

2017-06-16 Thread Jan Kratochvil
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: perf report: fix off-by-one for non-activation frames

2017-06-16 Thread Jan Kratochvil
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

2017-06-15 Thread Jan Kratochvil
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 1/2] perf report: ensure the perf DSO mapping matches what libdw sees

2017-06-15 Thread Jan Kratochvil
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

2017-06-15 Thread Jan Kratochvil
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 2/2] perf report: report module before querying isactivation in dwfl unwind

2017-06-15 Thread Jan Kratochvil
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

2016-06-20 Thread Jan Kratochvil
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] x86/ptrace: Remove questionable TS_COMPAT usage in ptrace

2016-06-20 Thread Jan Kratochvil
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

2013-11-19 Thread Jan Kratochvil
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

2013-11-19 Thread Jan Kratochvil
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

2013-11-18 Thread Jan Kratochvil
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] perf top: Make -g refer to callchains

2013-11-18 Thread Jan Kratochvil
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.

2013-06-19 Thread Jan Kratochvil
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] ptrace: make PTRACE_DETACH work on non-stopped tracees.

2013-06-19 Thread Jan Kratochvil
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()

2013-04-16 Thread Jan Kratochvil
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()

2013-04-16 Thread Jan Kratochvil
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()

2013-04-14 Thread Jan Kratochvil
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: [PATCH 0/2] ptrace/x86: simplify ptrace_write_dr7()

2013-04-14 Thread Jan Kratochvil
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)

2012-12-05 Thread Jan Kratochvil
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: PTRACE_SYSCALL vsyscall (Was: arch_check_bp_in_kernelspace: fix the range check)

2012-12-05 Thread Jan Kratochvil
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

2007-07-30 Thread Jan Kratochvil
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: [BUG] i386 relocable kernel breakes /proc/kcore debugging

2007-07-30 Thread Jan Kratochvil
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.

2007-06-03 Thread Jan Kratochvil

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] = 0x00;
+  

Re: [PATCH] Support for controlling leds on xbox 360 pad.

2007-06-03 Thread Jan Kratochvil

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(>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(>odata_mutex);
+   xpad->odata[0] = 0x01;
+   xpad->odata[1] = 0x03;
+   xpad->odata[2] = command;
+   usb_submit_urb(xpad->irq_out, GFP_KERNEL);
+   mutex_unlock(>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, _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 = xpad;
+
+   list_add_tail(_led->node, _led->node);
+
+   if (led_classdev_

Re: [PATCH] Support for controlling leds on xbox 360 pad.

2007-06-03 Thread Jan Kratochvil

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 linux/leds.h

+
+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 = xpad;
+
+   list_add_tail(new_led-node, pos_led-node);
+
+   if (led_classdev_register(xpad-udev-dev, new_led-cdev))
+   goto fail3;
+
+   xpad_send_command( (i % 4) + 2, xpad

Re: [PATCH] Support for controlling leds on xbox 360 pad.

2007-06-03 Thread Jan Kratochvil

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] = 0x00;
+   xpad-odata[7] = 0x00;
+   usb_submit_urb(xpad-irq_out, GFP_KERNEL);
+   }
+
+   return 0;
+}
+
+static int xpad_init_ff(struct usb_xpad *xpad

Re: [PATCH] Support for controlling leds on xbox 360 pad.

2007-05-31 Thread Jan Kratochvil

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.

2007-05-31 Thread Jan Kratochvil

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.

2007-05-30 Thread Jan Kratochvil

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.

2007-05-30 Thread Jan Kratochvil

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.

2007-05-29 Thread Jan Kratochvil

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.

2007-05-29 Thread Jan Kratochvil

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(>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(>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, >odata_dma );
-   if (!xpad->idata)
+   if (!xpad->odata)
goto fail1;
+ 
+	mutex_init(>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 = >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 for interrupt out report */
+   unsigned ch

[PATCH] Support for controlling leds on xbox 360 pad.

2007-05-29 Thread Jan Kratochvil

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 linux/smp_lock.h
 #include linux/usb/input.h

+#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 linux/usb/input.h
+
+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;
+   struct mutex odata_mutex;
+#endif

Re: [PATCH] Support for controlling leds on xbox 360 pad.

2007-05-29 Thread Jan Kratochvil

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/


Re: [PATCH][RESEND] PIE randomization

2007-05-17 Thread Jan Kratochvil

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(>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(>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(>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 long total_size;
int ret

Re: [PATCH][RESEND] PIE randomization

2007-05-17 Thread Jan Kratochvil

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(current-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(current-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(current-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 long total_size;
int retval, i, size;

/* First of all, some simple consistency

[PATCH][RESEND] PIE randomization

2007-05-11 Thread Jan Kratochvil

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(>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(>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(>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)
 

[PATCH][RESEND] PIE randomization

2007-05-11 Thread Jan Kratochvil

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(current-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(current-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(current-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

[PATCH] PIE randomization

2007-05-06 Thread Jan Kratochvil

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(>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(>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(>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 = 0;
unsigned lon

[PATCH] PIE randomization

2007-05-06 Thread Jan Kratochvil

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(current-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(current-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(current-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 = 0;
unsigned long last_bss = 0, elf_bss = 0;
unsigned long error = ~0UL

Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-03 Thread Jan Kratochvil

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, >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.

2007-05-03 Thread Jan Kratochvil

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, >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 = >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 (xpad->xtype == XTYPE_XBOX

Re: [PATCH 2/3] xpad.c: Initial support for xbox360 gamepad.

2007-05-03 Thread Jan Kratochvil

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 },
-   { 0x, 0x, &

Re: [PATCH 1/3] xpad.c: Added flags into xpad_device structure and removed dpad_mapping.

2007-05-03 Thread Jan Kratochvil

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/


Re: [PATCH 1/3] xpad.c: Added flags into xpad_device structure and removed dpad_mapping.

2007-05-03 Thread Jan Kratochvil

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/


Re: [PATCH 2/3] xpad.c: Initial support for xbox360 gamepad.

2007-05-03 Thread Jan Kratochvil

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 },
-   { 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), MAP_DPAD_TO_AXES, 
XTYPE_XBOX },
+   { 0x045e, 0x0289, Microsoft X-Box pad v2 (US), MAP_DPAD_TO_AXES, 
XTYPE_XBOX },
+   { 0x045e, 0x0285, Microsoft X-Box pad (Japan), MAP_DPAD_TO_AXES, 
XTYPE_XBOX },
+   { 0x045e, 0x0287, Microsoft Xbox

Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-03 Thread Jan Kratochvil

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 (xpad-xtype == XTYPE_XBOX360) {
+   usb_free_urb(xpad-irq_out);
+   usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN,
+   xpad-odata, xpad-odata_dma);
+   }
+}
+#else
+static int xpad_init_ff(struct usb_interface *intf

Re: [PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-03 Thread Jan Kratochvil

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;i16;++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/


[PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-02 Thread Jan Kratochvil
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, >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 = >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_interface *intf, struct usb_xpad *x

[PATCH 2/3] xpad.c: Initial support for xbox360 gamepad.

2007-05-02 Thread Jan Kratochvil
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);
+   }
+
+   /* start/back buttons */

[PATCH 1/3] xpad.c: Added flags into xpad_device structure and removed dpad_mapping.

2007-05-02 Thread Jan Kratochvil
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_TO_AXES },
+   

[PATCH] [RFC] Added USB_DEVICE_INTERFACE_PROTOCOL

2007-05-02 Thread Jan Kratochvil
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/


[PATCH 1/3] xpad.c: Added flags into xpad_device structure and removed dpad_mapping.

2007-05-02 Thread Jan Kratochvil
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_TO_AXES },
+   { 0x05fd, 0x1007, Mad Catz Controller (unverified), 
XPAD_FLAGS_DPAD_TO_AXES },
+   { 0x05fd, 0x107a, InterAct 'PowerPad Pro' X-Box pad (Germany), 
XPAD_FLAGS_DPAD_TO_AXES },
+   { 0x0738, 0x4516, Mad Catz Control Pad, XPAD_FLAGS_DPAD_TO_AXES },
+   { 0x0738, 0x4522, Mad Catz LumiCON, XPAD_FLAGS_DPAD_TO_AXES },
+   { 0x0738, 0x4526, Mad Catz Control Pad Pro, XPAD_FLAGS_DPAD_TO_AXES },
+   { 0x0738, 0x4536, Mad Catz MicroCON, XPAD_FLAGS_DPAD_TO_AXES },
+   { 0x0738, 0x4540, Mad Catz Beat Pad

[PATCH] [RFC] Added USB_DEVICE_INTERFACE_PROTOCOL

2007-05-02 Thread Jan Kratochvil
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/


[PATCH 2/3] xpad.c: Initial support for xbox360 gamepad.

2007-05-02 Thread Jan Kratochvil
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);
+   }
+
+   /* start/back buttons */
+   input_report_key(dev, BTN_START,  (data[2]  0x10)  4);
+   input_report_key(dev, BTN_BACK,   (data[2]  0x20)  5);
+
+   /* stick press left/right */
+   input_report_key(dev, BTN_THUMBL, data[2]  0x40);
+   input_report_key(dev, BTN_THUMBR

[PATCH 3/3] xpad.c: Added Xbox360 gamepad rumble support.

2007-05-02 Thread Jan Kratochvil
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_interface *intf, struct usb_xpad *xpad)
+{
+   if (xpad-flags  XPAD_FLAGS_XBOX360) {
+   usb_kill_urb(xpad-irq_out);
+   usb_free_urb(xpad-irq_out);
+   usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN,
+   xpad