From owner-freebsd-drivers@FreeBSD.ORG Sat Apr 5 18:01:29 2008 Return-Path: Delivered-To: freebsd-drivers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3D6C01065670 for ; Sat, 5 Apr 2008 18:01:29 +0000 (UTC) (envelope-from nslay@comcast.net) Received: from QMTA09.westchester.pa.mail.comcast.net (qmta09.westchester.pa.mail.comcast.net [76.96.62.96]) by mx1.freebsd.org (Postfix) with ESMTP id B977F8FC14 for ; Sat, 5 Apr 2008 18:01:28 +0000 (UTC) (envelope-from nslay@comcast.net) Received: from OMTA05.westchester.pa.mail.comcast.net ([76.96.62.43]) by QMTA09.westchester.pa.mail.comcast.net with comcast id 9q671Z0010vyq2s590Du00; Sat, 05 Apr 2008 17:49:44 +0000 Received: from LIGHTBULB.LOCAL ([68.35.224.189]) by OMTA05.westchester.pa.mail.comcast.net with comcast id 9trS1Z00145o48c3R00000; Sat, 05 Apr 2008 17:51:27 +0000 X-Authority-Analysis: v=1.0 c=1 a=26M6HwpVVxEA:10 a=Je3QHf6rl_8A:10 a=Pns_BpMpAAAA:8 a=-QR5d-TvvEGG3OSV27cA:9 a=yxarzY3HIW-QFjH_s4eL19tqRo8A:4 a=b8hG5vVbyAkA:10 a=evZnwLbNcu5r3UvcFI0A:9 a=06_lVmeu3BXuJjE2KHUA:7 a=XLNY7HUqgvRvkkNHdCs0L81itRUA:4 a=PxHhwJ9AYXMA:10 a=cKoO-q72gq7WG9RTfGwA:9 a=yqTZqZtdOy0rkPp7D3r2GU42H14A:4 a=Hh7NdPsCZosA:10 Message-ID: <47F7BC0D.1090907@comcast.net> Date: Sat, 05 Apr 2008 13:51:09 -0400 From: Nathan Lay User-Agent: Thunderbird 2.0.0.12 (X11/20080313) MIME-Version: 1.0 To: freebsd-drivers@freebsd.org, freebsd-x11@freebsd.org Content-Type: multipart/mixed; boundary="------------090803010606010008020202" Cc: Subject: Xbox controller S causes SIGFPE in Xorg X-BeenThere: freebsd-drivers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Writing device drivers for FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 05 Apr 2008 18:01:29 -0000 This is a multi-part message in MIME format. --------------090803010606010008020202 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Hey everybody, I have a bunch of these Xbox Controller S gamepads lying around and got a break-away <-> USB adapter. I plugged it in and at first, uhid did not recognize the controller so I googled and found some information about it here: http://euc.jp/periphs/xbox-controller.ja.html I grabbed the report descriptor there and made it into a C struct (attached) much like the xbox360 gamepad has. I added the following #defines in usb.h #define UICLASS_XBOXS 0x58 #define UISUBCLASS_XBOXS_CONTROLLER 0x42 #define UIPROTO_XBOXS_GAMEPAD 0x00 I added a few lines of code uhid.c's match and attach functions (similar to the 360 case) and voila, it attached as uhid. So I setup an InputDevice section in xorg.conf for the joystick and added the SendCoreEvents line to ServerLayout as noted in joystick(4x). Everytime I launch Xorg, as soon as I touch the controller, Xorg dies due to a SIGFPE. To make sure everything works, I wrote a simple C program to read from uhid (attached) and everything seems to work correctly. Where might I look to find the SIGFPE problem? Best Regards, Nathan Lay --------------090803010606010008020202 Content-Type: text/plain; name="uxbgp_rdesc.h" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="uxbgp_rdesc.h" static const uByte uhid_xbgp_report_descr[] = { 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x05, /* Usage (Game Pad) */ 0xA1, 0x01, /* Collection (Application) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x3A, /* Usage (Counted Buffer) ;XXX */ 0xA1, 0x02, /* Collection (Logical) */ /* ; padding */ 0x75, 0x08, /* Report Size (8) */ 0x95, 0x01, /* Report Count (1) */ 0x81, 0x01, /* Input (Constant) */ /* ; byte count */ 0x75, 0x08, /* Report Size (8) */ 0x95, 0x01, /* Report Count (1) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x3B, /* Usage (Byte Count) ;XXX */ 0x81, 0x01, /* Input (Constant) */ /* ; D-pad */ 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x01, /* Usage (Pointer) */ 0xA1, 0x00, /* Collection (Physical) */ 0x75, 0x01, /* Report Size (1) */ 0x15, 0x00, /* Logical Minimum (0) */ 0x25, 0x01, /* Logical Maximum (1) */ 0x35, 0x00, /* Physical Minimum (0) */ 0x45, 0x01, /* Physical Maximum (1) */ 0x95, 0x04, /* Report Count (4) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x90, /* Usage (D-pad Up) */ 0x09, 0x91, /* Usage (D-pad Down) */ 0x09, 0x93, /* Usage (D-pad Left) */ 0x09, 0x92, /* Usage (D-pad Right) */ 0x81, 0x02, /* Input (Data,Variable,Absolute) */ 0xC0, /* End Collection */ /* ; start, back, stick press */ 0x75, 0x01, /* Report Size (1) */ 0x15, 0x00, /* Logical Minimum (0) */ 0x25, 0x01, /* Logical Maximum (1) */ 0x35, 0x00, /* Physical Minimum (0) */ 0x45, 0x01, /* Physical Maximum (1) */ 0x95, 0x04, /* Report Count (4) */ 0x05, 0x09, /* Usage Page (Button) */ 0x19, 0x07, /* Usage Minimum (Button 7) */ 0x29, 0x0A, /* Usage Maximum (Button 10) */ 0x81, 0x02, /* Input (Data,Variable,Absolute) */ /* ; reserved */ 0x75, 0x01, /* Report Size (1) */ 0x95, 0x08, /* Report Count (8) */ 0x81, 0x01, /* Input (Constant) */ /* ; analog buttons */ 0x75, 0x08, /* Report Size (8) */ 0x15, 0x00, /* Logical Minimum (0) */ 0x26, 0xFF, 0x00, /* Logical Maximum (255) */ 0x35, 0x00, /* Physical Minimum (0) */ 0x46, 0xFF, 0x00, /* Physical Maximum (255) */ 0x95, 0x06, /* Report Count (6) */ 0x05, 0x09, /* Usage Page (Button) */ 0x19, 0x01, /* Usage Minimum (Button 1) */ 0x29, 0x06, /* Usage Minimum (Button 6) */ 0x81, 0x02, /* Input (Data,Variable,Absolute) */ /* ; triggers */ 0x75, 0x08, /* Report Size (8) */ 0x15, 0x00, /* Logical Minimum (0) */ 0x26, 0xFF, 0x00, /* Logical Maximum (255) */ 0x35, 0x00, /* Physical Minimum (0) */ 0x46, 0xFF, 0x00, /* Physical Maximum (255) */ 0x95, 0x02, /* Report Count (2) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x32, /* Usage (Z) */ 0x09, 0x35, /* Usage (Rz) */ 0x81, 0x02, /* Input (Data,Variable,Absolute) */ /* ; sticks */ 0x75, 0x10, /* Report Size (16) */ 0x16, 0x00, 0x80, /* Logical Minimum (-32768) */ 0x26, 0xFF, 0x7F, /* Logical Maximum (32767) */ 0x36, 0x00, 0x80, /* Physical Minimum (-32768) */ 0x46, 0xFF, 0x7F, /* Physical Maximum (32767) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x01, /* Usage (Pointer) */ 0xA1, 0x00, /* Collection (Physical) */ 0x95, 0x02, /* Report Count (2) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x30, /* Usage (X) */ 0x09, 0x31, /* Usage (Y) ;north positive */ 0x81, 0x02, /* Input (Data,Variable,Absolute) */ 0xC0, /* End Collection */ 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x01, /* Usage (Pointer) */ 0xA1, 0x00, /* Collection (Physical) */ 0x95, 0x02, /* Report Count (2) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x33, /* Usage (Rx) */ 0x09, 0x34, /* Usage (Ry) ;north positive */ 0x81, 0x02, /* Input (Data,Variable,Absolute) */ 0xC0, /* End Collection */ 0xC0, /* End Collection */ 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x3A, /* Usage (Counted Buffer) ;XXX */ 0xA1, 0x02, /* Collection (Logical) */ /* ; padding */ 0x75, 0x08, /* Report Size (8) */ 0x95, 0x01, /* Report Count (1) */ 0x91, 0x01, /* Output (Constant) */ /* ; byte count */ 0x75, 0x08, /* Report Size (8) */ 0x95, 0x01, /* Report Count (1) */ 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x3B, /* Usage (Byte Count) ;XXX */ 0x91, 0x01, /* Output (Constant) */ /* ; padding */ 0x75, 0x08, /* Report Size (8) */ 0x95, 0x01, /* Report Count (1) */ 0x91, 0x01, /* Output (Constant) */ /* ; left actuator */ 0x75, 0x08, /* Report Size (8) */ 0x15, 0x00, /* Logical Minimum (0) */ 0x26, 0xFF, 0x00, /* Logical Maximum (255) */ 0x35, 0x00, /* Physical Minimum (0) */ 0x46, 0xFF, 0x00, /* Physical Maximum (255) */ 0x95, 0x01, /* Report Count (1) */ 0x06, 0x00, 0xFF, /* Usage Page (vendor-defined) */ 0x09, 0x01, /* Usage (1) */ 0x91, 0x02, /* Output (Data,Variable,Absolute) */ /* ; padding */ 0x75, 0x08, /* Report Size (8) */ 0x95, 0x01, /* Report Count (1) */ 0x91, 0x01, /* Output (Constant) */ /* ; right actuator */ 0x75, 0x08, /* Report Size (8) */ 0x15, 0x00, /* Logical Minimum (0) */ 0x26, 0xFF, 0x00, /* Logical Maximum (255) */ 0x35, 0x00, /* Physical Minimum (0) */ 0x46, 0xFF, 0x00, /* Physical Maximum (255) */ 0x95, 0x01, /* Report Count (1) */ 0x06, 0x00, 0xFF, /* Usage Page (vendor-defined) */ 0x09, 0x02, /* Usage (2) */ 0x91, 0x02, /* Output (Data,Variable,Absolute) */ 0xC0, /* End Collection */ 0xC0 /* End Collection */ }; --------------090803010606010008020202 Content-Type: text/plain; name="xbox.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="xbox.c" #include #include #define ARROWUP 0x01 #define ARROWDOWN 0x02 #define ARROWLEFT 0x04 #define ARROWRIGHT 0x08 #define START 0x10 #define BACK 0x20 #define LEFTJOY 0x40 #define RIGHTJOY 0x80 #define ABUTTON 4 #define BBUTTON 5 #define XBUTTON 6 #define YBUTTON 7 #define BLACKBUTTON 8 #define WHITEBUTTON 9 #define LEFTTRIGGER 10 #define RIGHTTRIGGER 11 #define LEFTJOYX 12 #define RIGHTJOYX 16 #define DEBUG int main( int argc, char **argv ) { unsigned long i; uint8_t buf[20]; FILE *file = fopen( "/dev/uhid0", "r" ); if ( file == NULL ) { perror( "fopen" ); return -1; } while ( !feof( file ) ) { fread( buf, 1, sizeof(buf), file ); #ifdef DEBUG for ( i = 0; i < sizeof(buf); ++i ) printf( "0x%02x ", buf[i] ); printf( "\n" ); #else if ( buf[2] & ARROWUP ) printf( "UP is pressed.\n" ); if ( buf[2] & ARROWDOWN ) printf( "DOWN is pressed.\n" ); if ( buf[2] & ARROWLEFT ) printf( "LEFT is pressed.\n" ); if ( buf[2] & ARROWRIGHT ) printf( "RIGHT is pressed.\n" ); if ( buf[2] & START ) printf( "START is pressed.\n" ); if ( buf[2] & BACK ) printf( "BACK is pressed.\n" ); if ( buf[2] & LEFTJOY ) printf( "LEFTJOY is pressed.\n" ); if ( buf[2] & RIGHTJOY ) printf( "RIGHTJOY is pressed.\n" ); if ( buf[ABUTTON] ) printf( "ABUTTON is pressed with force %d.\n", buf[ABUTTON] ); if ( buf[BBUTTON] ) printf( "BBUTTON is pressed with force %d.\n", buf[BBUTTON] ); if ( buf[XBUTTON] ) printf( "XBUTTON is pressed with force %d.\n", buf[XBUTTON] ); if ( buf[YBUTTON] ) printf( "YBUTTON is pressed with force %d.\n", buf[YBUTTON] ); if ( buf[BLACKBUTTON] ) printf( "BLACKBUTTON is pressed with force %d.\n", buf[BLACKBUTTON] ); if ( buf[WHITEBUTTON] ) printf( "WHITEBUTTON is pressed with force %d.\n", buf[WHITEBUTTON] ); if ( buf[LEFTTRIGGER] ) printf( "LEFTTRIGGER is pressed with force %d.\n", buf[LEFTTRIGGER] ); if ( buf[RIGHTTRIGGER] ) printf( "RIGHTTRIGGER is pressed with force %d.\n", buf[RIGHTTRIGGER] ); printf( "LEFTJOY X = %d\tY = %d\n", *(int16_t *)(buf+LEFTJOYX), *(int16_t *)(buf+LEFTJOYX+2) ); printf( "RIGHTJOY X = %d\tY = %d\n", *(int16_t *)(buf+RIGHTJOYX), *(int16_t *)(buf+RIGHTJOYX+2) ); #endif } return 0; } --------------090803010606010008020202--