From: Paul B. <peb...@gm...> - 2010-12-30 19:04:12
|
I have been attempting to figure out why lirc_atiusb does not work with kernel 2.6.36. So far, what I have found is that when lirc_dev attempts to read the fifo it reads 0 bytes even though the fifo contains 4 bytes and the reported fifo length is 4 bytes and the requested number of bytes to read is 4 bytes. Since 0 bytes were read, the fifo still contains 4 bytes. As a result, lirc_dev attempts to read the fifo again. Therefore, once a key is pressed, lirc_dev attempts to read the fifo forever. However, since it is not reading anything from the fifo, the result is all zeros so lircd does not output anything. If I upgrade the kfifo implementation in 2.6.36.2 to the one in 2.6.37-rc8, then I get the same result. However, if I downgrade the kfifo implementation in 2.6.36.2 to the one in 2.6.35.10, then lirc_atiusb works again. As a result, it would appear the problem is a result of the interaction of lirc_atiusb and/or lirc_dev with the new kfifo implementation introduced in 2.6.36. However, the new kfifo implementation appears to have arrived in Linus' git tree in one shot and I cannot find the git tree where it was incrementally developed. Therefore, I see no easy what to bisect the problem. I am not sure where to go from here. I can (and will) look at the code differences between the two kfifo implementations to see whether or not there is something obvious. I am assuming the problem is either an initialization or locking issue (but I could be wrong), so I will be looking at the code differences with that in mind. However, I was hoping someone might have a more directed approach that they could suggest. By the way, the reason I have not switched away from lirc_atiusb is it is the only driver that has support for the Xbox remote. As some MiniMyth users (I maintain MiniMyth) have an Xbox remote, I switching away from lirc_atiusb is not a particularly attractive option. |
From: Jarod W. <ja...@wi...> - 2010-12-31 23:39:57
|
On Thu, Dec 30, 2010 at 2:03 PM, Paul Bender <peb...@gm...> wrote: > I have been attempting to figure out why lirc_atiusb does not work with > kernel 2.6.36. So far, what I have found is that when lirc_dev attempts > to read the fifo it reads 0 bytes even though the fifo contains 4 bytes > and the reported fifo length is 4 bytes and the requested number of > bytes to read is 4 bytes. Since 0 bytes were read, the fifo still > contains 4 bytes. As a result, lirc_dev attempts to read the fifo again. > Therefore, once a key is pressed, lirc_dev attempts to read the fifo > forever. However, since it is not reading anything from the fifo, the > result is all zeros so lircd does not output anything. Thanks for looking at this, its been on my own TODO list for a while as well. I've dealt with a few kfifo issues w/other drivers, but never really bothered with looking at lirc_atiusb. I'll try to give it some attention soon though. I suspect its just a usage issue that needs to be sorted out somewhere in lirc_atiusb though, since several other drivers all work perfectly fine with the new kfifo bits. > By the way, the reason I have not switched away from lirc_atiusb is it > is the only driver that has support for the Xbox remote. As some > MiniMyth users (I maintain MiniMyth) have an Xbox remote, I switching > away from lirc_atiusb is not a particularly attractive option. Well, really, we should add support for the xbox remote upstream in the ati_remote driver, I think. But fixing lirc_atiusb also doesn't hurt. Doesn't the xbox remote work with the atilibusb userspace driver too though? (I thought all that didn't support was the remote wonder II, but I could be mistaken). -- Jarod Wilson ja...@wi... |
From: Vassilis V. <va...@ii...> - 2011-01-01 10:05:06
|
Hi everybody and a happy new year. On 01/01/2011 01:16 πμ, Jarod Wilson wrote: > Well, really, we should add support for the xbox remote upstream in > the ati_remote driver, I think. But fixing lirc_atiusb also doesn't > hurt. Doesn't the xbox remote work with the atilibusb userspace driver > too though? (I thought all that didn't support was the remote wonder > II, but I could be mistaken). > I am the one that adapted and merged xbox remote support patch after getting permission of the original author (Michael Wojciechowski). My xbox is currently broken due to post 2.6.16 upgrade (incompatible udev) and my time is severely limited. I am not familiar with the new ati driver but I am reposting the xbox specific bits in case somebody wants to do a direct port. Here is the original mail I sent in lirc-dev back in 2006 ---------------------------------------------------------- Hi, I am a happy owner of a xbox and I thought to try to merge this to upstream so it would be easier for me to keep lirc/lirc-modules up to date. The original author of the patch is Michael Wojciechowski. The patch was utilizing #ifdef XBOX_SUPPORT and the resulting lirc_atiusb had to be compiled twice. In this version I get rid of conditional compilation with the risk that I have screwed up the ati, ati2 remotes. I tried to keep the patch minimal so that's why we have the macro magic redefinition. I am open to suggestions and bug reports from ati/ati2 owners since I would really like this to be merged in? .bill lirc_atiusb-xbox.diff --- ../../lirc-modules.orig/lirc/drivers/lirc_atiusb/lirc_atiusb.c 2006-09-18 16:39:16.000000000 +0300 +++ drivers/lirc_atiusb/lirc_atiusb.c 2006-12-16 20:46:04.000000000 +0200 @@ -11,6 +11,10 @@ * "USB StreamZap remote driver" (LIRC) * Artur Lipowski <ali...@kk...>'s 2002 * "lirc_dev" and "lirc_gpio" LIRC modules + * Michael Wojciechowski + * initial xbox support + * Vassilis Virvilis <va...@ii...> 2006 + * reworked the patch for lirc submission * * $Id: lirc_atiusb.c,v 1.53 2006/03/04 22:36:38 lirc Exp $ */ @@ -64,9 +68,9 @@ #define DRIVER_DESC "USB remote driver for LIRC" #define DRIVER_NAME "lirc_atiusb" -#define CODE_LENGTH 5 -#define CODE_LENGTH_ATI2 3 -#define CODE_MIN_LENGTH 3 +#define CODE_LENGTH code_length[ir->remote_type] +#define CODE_MIN_LENGTH code_min_length[ir->remote_type] +#define DECODE_LENGTH decode_length[ir->remote_type] #define RW2_MODENAV_KEYCODE 0x3F #define RW2_NULL_MODE 0xFF @@ -89,6 +93,14 @@ if(debug) printk(KERN_DEBUG fmt, ## args); \ }while(0) +// ATI, ATI2, XBOX +static const int code_length[] = {5, 3, 6}; +static const int code_min_length[] = {3, 3, 6}; +static const int decode_length[] = {5, 3, 1}; +// USB_BUFF_LEN must be the maximum value of the code_length array. +// It is used for static arrays. +#define USB_BUFF_LEN 6 + static int mask = 0xFFFF; // channel acceptance bit mask static int unique = 0; // enable channel-specific codes static int repeat = 10; // repeat time in 1/100 sec @@ -120,6 +132,8 @@ #define VENDOR_ATI1 0x0bc7 #define VENDOR_ATI2 0x0471 +#define VENDOR_MS1 0x040b +#define VENDOR_MS2 0x045e static struct usb_device_id usb_remote_table [] = { { USB_DEVICE(VENDOR_ATI1, 0x0002) }, /* X10 USB Firecracker Interface */ @@ -140,6 +154,8 @@ { USB_DEVICE(VENDOR_ATI2, 0x0602) }, /* ATI Remote Wonder 2: Input Device */ { USB_DEVICE(VENDOR_ATI2, 0x0603) }, /* ATI Remote Wonder 2: Controller (???) */ + { USB_DEVICE(VENDOR_MS1, 0x6521) }, /* Gamester Xbox DVD Movie Playback Kit IR */ + { USB_DEVICE(VENDOR_MS2, 0x0284) }, /* Microsoft Xbox DVD Movie Playback Kit IR */ { } /* Terminating entry */ }; @@ -168,7 +184,7 @@ #endif /* handle repeats */ - unsigned char old[CODE_LENGTH]; + unsigned char old[USB_BUFF_LEN]; unsigned long old_jiffies; }; @@ -206,7 +222,8 @@ /* remote type based on usb_device_id tables */ enum { ATI1_COMPATIBLE, - ATI2_COMPATIBLE + ATI2_COMPATIBLE, + XBOX_COMPATIBLE } remote_type; /* rw2 current mode (mirror's remote's state) */ @@ -369,13 +386,14 @@ static void print_data(struct in_endpt *iep, char *buf, int len) { - char codes[CODE_LENGTH*3 + 1]; + const int clen = code_length[iep->ir->remote_type]; + char codes[clen * 3 + 1]; int i; if (len <= 0) return; - for (i = 0; i < len && i < CODE_LENGTH; i++) { + for (i = 0; i < len && i < clen; i++) { snprintf(codes+i*3, 4, "%02x ", buf[i] & 0xFF); } printk(DRIVER_NAME "[%d]: data received %s (ep=0x%x length=%d)\n", @@ -506,7 +524,7 @@ int mode, i; char *buf = iep->buf; - if (len != CODE_LENGTH_ATI2) { + if (len != CODE_LENGTH) { dprintk(DRIVER_NAME "[%d]: Huh? Abnormal length (%d) buffer recieved.\n", ir->devnum, len); @@ -598,6 +616,37 @@ return SUCCESS; } +static int code_check_xbox(struct in_endpt *iep, int len) +{ + struct irctl *ir = iep->ir; + const int clen = CODE_LENGTH; + + if (len != clen) + { + dprintk(DRIVER_NAME ": We got %d instead of %d bytes from xbox ir.. ?\n", len, clen); + return -1; + } + + /* check for repeats */ + if (memcmp(iep->old, iep->buf, len) == 0) + { + if (iep->old_jiffies + repeat_jiffies > jiffies) + { + return -1; + } + } + else + { + // the third byte of xbox ir packet seems to contain key info + // the last two bytes are.. some kind of clock? + iep->buf[0] = iep->buf[2]; + memset(iep->buf + 1, 0, len - 1); + memcpy(iep->old, iep->buf, len); + } + iep->old_jiffies = jiffies; + + return SUCCESS; +} #ifdef KERNEL_2_5 static void usb_remote_recv(struct urb *urb, struct pt_regs *regs) @@ -606,7 +655,7 @@ #endif { struct in_endpt *iep; - int len, result; + int len, result = -1; if (!urb) return; @@ -630,6 +679,9 @@ case SUCCESS: switch (iep->ir->remote_type) { + case XBOX_COMPATIBLE: + result = code_check_xbox(iep, len); + break; case ATI2_COMPATIBLE: result = code_check_ati2(iep, len); break; @@ -946,6 +998,10 @@ case VENDOR_ATI2: type = ATI2_COMPATIBLE; break; + case VENDOR_MS1: + case VENDOR_MS2: + type = XBOX_COMPATIBLE; + break; default: dprintk(DRIVER_NAME "[%d]: unknown type\n", devnum); return NULL; @@ -957,6 +1013,8 @@ if ( !(ir = kmalloc(sizeof(*ir), GFP_KERNEL)) ) { mem_failure = 1; } else { + // at this stage we cannot use the macro [DE]CODE_LENGTH: ir is not yet setup + const int dclen = decode_length[type]; memset(ir, 0, sizeof(*ir)); /* add this infrared remote struct to remote_list, keeping track of * the number of drivers registered. */ @@ -968,13 +1026,13 @@ mem_failure = 2; } else if (!(rbuf = kmalloc(sizeof(*rbuf), GFP_KERNEL))) { mem_failure = 3; - } else if (lirc_buffer_init(rbuf, CODE_LENGTH, 1)) { + } else if (lirc_buffer_init(rbuf, dclen, 1)) { mem_failure = 4; } else { memset(plugin, 0, sizeof(*plugin)); strcpy(plugin->name, DRIVER_NAME " "); plugin->minor = -1; - plugin->code_length = CODE_LENGTH*8; + plugin->code_length = dclen * 8; plugin->features = LIRC_CAN_REC_LIRCCODE; plugin->data = ir; plugin->rbuf = rbuf; |