linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: Linux Force Feedback for Saitek Cyborg Evo Force
       [not found] <4B26B824.8010403@physik.uni-muenchen.de>
@ 2009-12-15 13:07 ` Jiri Kosina
  2009-12-17 23:18   ` Johannes Ebke
  0 siblings, 1 reply; 18+ messages in thread
From: Jiri Kosina @ 2009-12-15 13:07 UTC (permalink / raw)
  To: Johannes Ebke, Dmitry Torokhov; +Cc: linux-input

On Mon, 14 Dec 2009, Johannes Ebke wrote:

> I own a Saitek Cyborg Evo Force which works fine with the HID driver on
> Linux. However, i could not find a force feedback driver for it, and
> just adding the USB id and spec to the IForce driver does not work (and
> crashes the kernel)

Hi Johannes,

thanks for your e-mail. I hope you don't mind adding a few relevant CCs.

First, kernel crashing means that we are probably lacking some error 
handling in the iforce driver, which we should add if possible. Could you 
please post the oops message preceeding the crash?

> After that, I have reverse-engineered the protocol using usb snoops from 
> a kvm virtual machine with XP on it. Using libusb, I have verified that 
> I understand the protocol, and it actually looks quite similar to the 
> iforce protocol (no wonder, it just implements the DirectInput interface 
> in hardware)

Good job, thanks a lot for doing this.

> My question: Would it make sense to adapt the iforce modules to include 
> this slightly modified protocol (other initialization strings, other 
> magic bytes) or would it be better to copy & modify?

It really depends how much different the protocols really are. iforce 
driver currently doesn't support any per-device flags which would allow 
for introducing slight differences between individual models.

Maybe it would help if you could just summarize the most important 
differences to iforce protocol, so that we could see what aproach would be 
the best.

Thanks,

-- 
Jiri Kosina
SUSE Labs, Novell Inc.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-15 13:07 ` Linux Force Feedback for Saitek Cyborg Evo Force Jiri Kosina
@ 2009-12-17 23:18   ` Johannes Ebke
  2009-12-18  8:59     ` Johannes Ebke
  2009-12-18 10:52     ` Jiri Kosina
  0 siblings, 2 replies; 18+ messages in thread
From: Johannes Ebke @ 2009-12-17 23:18 UTC (permalink / raw)
  To: Jiri Kosina; +Cc: Dmitry Torokhov, linux-input

[-- Attachment #1: Type: text/plain, Size: 2817 bytes --]

Hi Jiri,

I have looked into the problems some more, and have found that the cause
of the crash was a change I made because I misunderstood the code
(LO(cmd) is the number of bytes in in the message, and is not
transferred on USB - i had removed it from the message...)

First, the changes in the normal input, the joystick axis+buttons message:
* Prefix is 0x06 instead of 0x01 (joystick) or 0x03 (gamepad)
* Throttle is not inverted (data[4] instead of 255-data[4])
* Rudder is present and unsigned (not signed, as in iforce)

I have attached a patch that I think fixes this (it works for me :)
Since saitek uses a different protocol byte, this can be done without
adding per-device flags to the driver.

It also adds a button map btn_saitek_cyborg that switches button 1&2 to
make the button number the same as printed on the device, and
abs_saitek_cyborg for a joystick with rudder but only one hat.

The fftest effects seem to work, but some are feeble and feel strange -
I suspect there are some subtle changes, for example I am quite sure
that the Saitek uses signed (twos complement) numbers for effect
strength (this could perhaps explain the 'strange' behavior for 0x80
byte values in the current code)...

Cheers,
Johannes


Jiri Kosina wrote:
> On Mon, 14 Dec 2009, Johannes Ebke wrote:
> 
>> I own a Saitek Cyborg Evo Force which works fine with the HID driver on
>> Linux. However, i could not find a force feedback driver for it, and
>> just adding the USB id and spec to the IForce driver does not work (and
>> crashes the kernel)
> 
> Hi Johannes,
> 
> thanks for your e-mail. I hope you don't mind adding a few relevant CCs.
> 
> First, kernel crashing means that we are probably lacking some error 
> handling in the iforce driver, which we should add if possible. Could you 
> please post the oops message preceeding the crash?
> 
>> After that, I have reverse-engineered the protocol using usb snoops from 
>> a kvm virtual machine with XP on it. Using libusb, I have verified that 
>> I understand the protocol, and it actually looks quite similar to the 
>> iforce protocol (no wonder, it just implements the DirectInput interface 
>> in hardware)
> 
> Good job, thanks a lot for doing this.
> 
>> My question: Would it make sense to adapt the iforce modules to include 
>> this slightly modified protocol (other initialization strings, other 
>> magic bytes) or would it be better to copy & modify?
> 
> It really depends how much different the protocols really are. iforce 
> driver currently doesn't support any per-device flags which would allow 
> for introducing slight differences between individual models.
> 
> Maybe it would help if you could just summarize the most important 
> differences to iforce protocol, so that we could see what aproach would be 
> the best.
> 
> Thanks,
> 

[-- Attachment #2: saitek.patch --]
[-- Type: text/x-patch, Size: 3618 bytes --]

diff -ru iforce_orig/iforce-main.c iforce/iforce-main.c
--- iforce_orig/iforce-main.c	2009-12-03 04:51:21.000000000 +0100
+++ iforce/iforce-main.c	2009-12-17 23:55:10.000000000 +0100
@@ -35,6 +35,10 @@
 { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
   BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, -1 };
 
+static signed short btn_saitek_cyborg[] =
+{ BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE,
+  BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, -1 };
+
 static signed short btn_avb_pegasus[] =
 { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
   BTN_BASE2, BTN_BASE3, BTN_BASE4, -1 };
@@ -54,6 +58,9 @@
 static signed short abs_joystick[] =
 { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 };
 
+static signed short abs_saitek_cyborg[] =
+{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, -1 };
+
 static signed short abs_avb_pegasus[] =
 { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y,
   ABS_HAT1X, ABS_HAT1Y, -1 };
@@ -79,6 +86,7 @@
 	{ 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel",	btn_wheel, abs_wheel, ff_iforce }, //?
 	{ 0x06f8, 0x0004, "Gullemot Jet Leader 3D",			btn_joystick, abs_joystick, ff_iforce }, //?
 	{ 0x06d6, 0x29bc, "Trust Force Feedback Race Master",		btn_wheel, abs_wheel, ff_iforce },
+	{ 0x06a3, 0xffb5, "Saitek Cyborg Evo Force",			btn_saitek_cyborg, abs_saitek_cyborg, ff_iforce }, //?
 	{ 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]",		btn_joystick, abs_joystick, ff_iforce }
 };
 
diff -ru iforce_orig/iforce-packets.c iforce/iforce-packets.c
--- iforce_orig/iforce-packets.c	2009-12-03 04:51:21.000000000 +0100
+++ iforce/iforce-packets.c	2009-12-18 00:10:08.000000000 +0100
@@ -182,16 +182,24 @@
 
 		case 0x01:	/* joystick position data */
 		case 0x03:	/* wheel position data */
-			if (HI(cmd) == 1) {
-				input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
-				input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
-				input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
-				if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
-					input_report_abs(dev, ABS_RUDDER, (__s8)data[7]);
-			} else {
+		case 0x06:	/* saitek position data */
+			if (HI(cmd) == 3) {
 				input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0]));
 				input_report_abs(dev, ABS_GAS,   255 - data[2]);
 				input_report_abs(dev, ABS_BRAKE, 255 - data[3]);
+			} else {
+				input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
+				input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
+				if (HI(cmd) == 6) {
+					input_report_abs(dev, ABS_THROTTLE, data[4]);
+					if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
+						input_report_abs(dev, ABS_RUDDER, data[7]);
+				} else {
+					input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
+					if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
+						input_report_abs(dev, ABS_RUDDER, (__s8)data[7]);
+				}
+
 			}
 
 			input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x);
diff -ru iforce_orig/iforce-usb.c iforce/iforce-usb.c
--- iforce_orig/iforce-usb.c	2009-12-03 04:51:21.000000000 +0100
+++ iforce/iforce-usb.c	2009-12-15 22:46:11.000000000 +0100
@@ -227,6 +227,7 @@
 	{ USB_DEVICE(0x06f8, 0x0001) },		/* Guillemot Race Leader Force Feedback */
 	{ USB_DEVICE(0x06f8, 0x0004) },		/* Guillemot Force Feedback Racing Wheel */
 	{ USB_DEVICE(0x06f8, 0xa302) },		/* Guillemot Jet Leader 3D */
+	{ USB_DEVICE(0x06a3, 0xffb5) },		/* Saitek Cyborg Evo Force */
 	{ }					/* Terminating entry */
 };
 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-17 23:18   ` Johannes Ebke
@ 2009-12-18  8:59     ` Johannes Ebke
  2009-12-18 10:52     ` Jiri Kosina
  1 sibling, 0 replies; 18+ messages in thread
From: Johannes Ebke @ 2009-12-18  8:59 UTC (permalink / raw)
  To: Jiri Kosina; +Cc: Dmitry Torokhov, linux-input

Hi,

...it worked in the jscalibrator, but in the game I noticed that the
axis ranges (as given by the HID driver, which also works for non-ff
mode) are different to the iforce ones:
x/y is from 0 (top, left, rudder left) to 4096 (bottom right) or 255
(rudder right), and throttle is from 255 (no throttle) to 0 (full)

In iforce the x-range is from -1920 to 1920, so 256 steps less than the
saitek range...
This is a bit more difficult to fit into the driver framework, because
the ranges are set in the initialization routine in iforce-main.c.
I'll put an if() in there for starters.

Cheers,
Johannes


Johannes Ebke wrote:
> Hi Jiri,
> 
> I have looked into the problems some more, and have found that the cause
> of the crash was a change I made because I misunderstood the code
> (LO(cmd) is the number of bytes in in the message, and is not
> transferred on USB - i had removed it from the message...)
> 
> First, the changes in the normal input, the joystick axis+buttons message:
> * Prefix is 0x06 instead of 0x01 (joystick) or 0x03 (gamepad)
> * Throttle is not inverted (data[4] instead of 255-data[4])
> * Rudder is present and unsigned (not signed, as in iforce)
> 
> I have attached a patch that I think fixes this (it works for me :)
> Since saitek uses a different protocol byte, this can be done without
> adding per-device flags to the driver.
> 
> It also adds a button map btn_saitek_cyborg that switches button 1&2 to
> make the button number the same as printed on the device, and
> abs_saitek_cyborg for a joystick with rudder but only one hat.
> 
> The fftest effects seem to work, but some are feeble and feel strange -
> I suspect there are some subtle changes, for example I am quite sure
> that the Saitek uses signed (twos complement) numbers for effect
> strength (this could perhaps explain the 'strange' behavior for 0x80
> byte values in the current code)...
> 
> Cheers,
> Johannes
> 
> 
> Jiri Kosina wrote:
>> On Mon, 14 Dec 2009, Johannes Ebke wrote:
>>
>>> I own a Saitek Cyborg Evo Force which works fine with the HID driver on
>>> Linux. However, i could not find a force feedback driver for it, and
>>> just adding the USB id and spec to the IForce driver does not work (and
>>> crashes the kernel)
>> Hi Johannes,
>>
>> thanks for your e-mail. I hope you don't mind adding a few relevant CCs.
>>
>> First, kernel crashing means that we are probably lacking some error 
>> handling in the iforce driver, which we should add if possible. Could you 
>> please post the oops message preceeding the crash?
>>
>>> After that, I have reverse-engineered the protocol using usb snoops from 
>>> a kvm virtual machine with XP on it. Using libusb, I have verified that 
>>> I understand the protocol, and it actually looks quite similar to the 
>>> iforce protocol (no wonder, it just implements the DirectInput interface 
>>> in hardware)
>> Good job, thanks a lot for doing this.
>>
>>> My question: Would it make sense to adapt the iforce modules to include 
>>> this slightly modified protocol (other initialization strings, other 
>>> magic bytes) or would it be better to copy & modify?
>> It really depends how much different the protocols really are. iforce 
>> driver currently doesn't support any per-device flags which would allow 
>> for introducing slight differences between individual models.
>>
>> Maybe it would help if you could just summarize the most important 
>> differences to iforce protocol, so that we could see what aproach would be 
>> the best.
>>
>> Thanks,
>>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-17 23:18   ` Johannes Ebke
  2009-12-18  8:59     ` Johannes Ebke
@ 2009-12-18 10:52     ` Jiri Kosina
  2009-12-18 17:50       ` Dmitry Torokhov
  1 sibling, 1 reply; 18+ messages in thread
From: Jiri Kosina @ 2009-12-18 10:52 UTC (permalink / raw)
  To: Johannes Ebke, Dmitry Torokhov; +Cc: linux-input

On Fri, 18 Dec 2009, Johannes Ebke wrote:

> I have looked into the problems some more, and have found that the cause 
> of the crash was a change I made because I misunderstood the code 
> (LO(cmd) is the number of bytes in in the message, and is not 
> transferred on USB - i had removed it from the message...)

Ah, good, thanks.

> First, the changes in the normal input, the joystick axis+buttons message:
> * Prefix is 0x06 instead of 0x01 (joystick) or 0x03 (gamepad)
> * Throttle is not inverted (data[4] instead of 255-data[4])
> * Rudder is present and unsigned (not signed, as in iforce)
> 
> I have attached a patch that I think fixes this (it works for me :) 
> Since saitek uses a different protocol byte, this can be done without 
> adding per-device flags to the driver.
> 
> It also adds a button map btn_saitek_cyborg that switches button 1&2 to
> make the button number the same as printed on the device, and
> abs_saitek_cyborg for a joystick with rudder but only one hat.
> 
> The fftest effects seem to work, but some are feeble and feel strange -
> I suspect there are some subtle changes, for example I am quite sure
> that the Saitek uses signed (twos complement) numbers for effect
> strength (this could perhaps explain the 'strange' behavior for 0x80
> byte values in the current code)...

The changes look really minimal to me, so I'd propose just to add a few 
special cases to the iforce driver itself (probably by setting/checking 
some per-device flag where needed), rather than copy/pasting the whole 
iforce driver.

But the ultimate decision is on Dmitry (CCed) here.

Thanks,

-- 
Jiri Kosina
SUSE Labs, Novell Inc.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-18 10:52     ` Jiri Kosina
@ 2009-12-18 17:50       ` Dmitry Torokhov
  2009-12-19 23:36         ` Johannes Ebke
  0 siblings, 1 reply; 18+ messages in thread
From: Dmitry Torokhov @ 2009-12-18 17:50 UTC (permalink / raw)
  To: Jiri Kosina; +Cc: Johannes Ebke, linux-input

On Fri, Dec 18, 2009 at 11:52:32AM +0100, Jiri Kosina wrote:
> On Fri, 18 Dec 2009, Johannes Ebke wrote:
> 
> > I have looked into the problems some more, and have found that the cause 
> > of the crash was a change I made because I misunderstood the code 
> > (LO(cmd) is the number of bytes in in the message, and is not 
> > transferred on USB - i had removed it from the message...)
> 
> Ah, good, thanks.
> 
> > First, the changes in the normal input, the joystick axis+buttons message:
> > * Prefix is 0x06 instead of 0x01 (joystick) or 0x03 (gamepad)
> > * Throttle is not inverted (data[4] instead of 255-data[4])
> > * Rudder is present and unsigned (not signed, as in iforce)
> > 
> > I have attached a patch that I think fixes this (it works for me :) 
> > Since saitek uses a different protocol byte, this can be done without 
> > adding per-device flags to the driver.
> > 
> > It also adds a button map btn_saitek_cyborg that switches button 1&2 to
> > make the button number the same as printed on the device, and
> > abs_saitek_cyborg for a joystick with rudder but only one hat.
> > 
> > The fftest effects seem to work, but some are feeble and feel strange -
> > I suspect there are some subtle changes, for example I am quite sure
> > that the Saitek uses signed (twos complement) numbers for effect
> > strength (this could perhaps explain the 'strange' behavior for 0x80
> > byte values in the current code)...
> 
> The changes look really minimal to me, so I'd propose just to add a few 
> special cases to the iforce driver itself (probably by setting/checking 
> some per-device flag where needed), rather than copy/pasting the whole 
> iforce driver.
> 
> But the ultimate decision is on Dmitry (CCed) here.
> 

Right, so far I have not seen anythig that would warrant creating a
separate driver, adjusting the current one is the way to go.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-18 17:50       ` Dmitry Torokhov
@ 2009-12-19 23:36         ` Johannes Ebke
  2009-12-21  0:22           ` Melchior FRANZ
  2009-12-21  7:44           ` Dmitry Torokhov
  0 siblings, 2 replies; 18+ messages in thread
From: Johannes Ebke @ 2009-12-19 23:36 UTC (permalink / raw)
  To: Jiri Kosina; +Cc: Dmitry Torokhov, linux-input

[-- Attachment #1: Type: text/plain, Size: 3077 bytes --]

Hi,

It seems that the force feedback works well, I have ported the force
feedback for my favorite game to linux now, and it works well.

What does not work is updating effects - there just nothing happens, and
the old event is played. I have circumvented this by
deleting/re-uploading the effect, but this should probably been made to
work. Does it work well with other hardware?

Thirdly, I have re-discovered one kernel oops that occurs if the
joystick is unplugged if some process still has the event device open.
Steps to reproduce:
* plug joystick in
* fftest /dev/input/eventXX
* unplug joystick

(kern.log extract attached)

Sometimes this just gives an oops, sometimes it escalates into a kernel
panic.

Finally, attached is the most recent patch (saitek-v2.patch):
* handling of 0x06 (saitek?) message format for axis/button data
* Saitek Cyborg Evo Force button+axis definitions and table entry
* Changes axis limits if hardware is from Saitek
* Added has_btndead to iforce_device + table entries
* Only add BTN_DEAD if iforce device has_btndead
(since my joystick does not have a physical dead switch)

The patch is against 2.6.32 from kernel.org.

Cheers,
Johannes

Dmitry Torokhov wrote:
> On Fri, Dec 18, 2009 at 11:52:32AM +0100, Jiri Kosina wrote:
>> On Fri, 18 Dec 2009, Johannes Ebke wrote:
>>
>>> I have looked into the problems some more, and have found that the cause 
>>> of the crash was a change I made because I misunderstood the code 
>>> (LO(cmd) is the number of bytes in in the message, and is not 
>>> transferred on USB - i had removed it from the message...)
>> Ah, good, thanks.
>>
>>> First, the changes in the normal input, the joystick axis+buttons message:
>>> * Prefix is 0x06 instead of 0x01 (joystick) or 0x03 (gamepad)
>>> * Throttle is not inverted (data[4] instead of 255-data[4])
>>> * Rudder is present and unsigned (not signed, as in iforce)
>>>
>>> I have attached a patch that I think fixes this (it works for me :) 
>>> Since saitek uses a different protocol byte, this can be done without 
>>> adding per-device flags to the driver.
>>>
>>> It also adds a button map btn_saitek_cyborg that switches button 1&2 to
>>> make the button number the same as printed on the device, and
>>> abs_saitek_cyborg for a joystick with rudder but only one hat.
>>>
>>> The fftest effects seem to work, but some are feeble and feel strange -
>>> I suspect there are some subtle changes, for example I am quite sure
>>> that the Saitek uses signed (twos complement) numbers for effect
>>> strength (this could perhaps explain the 'strange' behavior for 0x80
>>> byte values in the current code)...
>> The changes look really minimal to me, so I'd propose just to add a few 
>> special cases to the iforce driver itself (probably by setting/checking 
>> some per-device flag where needed), rather than copy/pasting the whole 
>> iforce driver.
>>
>> But the ultimate decision is on Dmitry (CCed) here.
>>
> 
> Right, so far I have not seen anythig that would warrant creating a
> separate driver, adjusting the current one is the way to go.
> 

[-- Attachment #2: iforce-oops.txt --]
[-- Type: text/plain, Size: 8788 bytes --]

Dec 19 23:42:17 localhost kernel: [  154.444093] usb 6-1: new full speed USB device using uhci_hcd and address 2
Dec 19 23:42:17 localhost kernel: [  154.600375] usb 6-1: New USB device found, idVendor=06a3, idProduct=ffb5
Dec 19 23:42:17 localhost kernel: [  154.600384] usb 6-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Dec 19 23:42:17 localhost kernel: [  154.600390] usb 6-1: Product: Cyborg Evo Force
Dec 19 23:42:17 localhost kernel: [  154.600394] usb 6-1: Manufacturer: Saitek
Dec 19 23:42:17 localhost kernel: [  154.600737] usb 6-1: configuration #1 chosen from 1 choice
Dec 19 23:42:17 localhost kernel: [  154.714158] drivers/input/joystick/iforce/iforce-packets.c: info cmd = ff01, data = 43 
Dec 19 23:42:17 localhost kernel: [  154.716162] drivers/input/joystick/iforce/iforce-packets.c: info cmd = ff03, data = 45 00 01 
Dec 19 23:42:17 localhost kernel: [  154.718368] drivers/input/joystick/iforce/iforce-packets.c: info cmd = ff01, data = 4f 
Dec 19 23:42:17 localhost kernel: [  154.720155] drivers/input/joystick/iforce/iforce-packets.c: info cmd = ff04, data = 56 02 05 00 
Dec 19 23:42:17 localhost kernel: [  154.721032] input: Saitek Cyborg Evo Force as /devices/pci0000:00/0000:00:1d.0/usb6/6-1/input/input10
Dec 19 23:42:17 localhost kernel: [  154.721642] usbcore: registered new interface driver iforce
Dec 19 23:42:17 localhost kernel: [  154.805812] usbcore: registered new interface driver hiddev
Dec 19 23:42:17 localhost kernel: [  154.805930] usbcore: registered new interface driver usbhid
Dec 19 23:42:17 localhost kernel: [  154.805934] usbhid: v2.6:USB HID core driver
Dec 19 23:42:26 localhost kernel: [  162.928977] drivers/input/joystick/iforce/iforce-packets.c: magnitude:  cmd = 0303, data = 1a 00 20 
Dec 19 23:42:26 localhost kernel: [  162.928993] drivers/input/joystick/iforce/iforce-packets.c: condition cmd = 050a, data = 2a 00 19 19 00 00 00 00 31 31 
Dec 19 23:42:26 localhost kernel: [  162.929009] drivers/input/joystick/iforce/iforce-packets.c: condition cmd = 050a, data = 32 00 19 19 00 00 00 00 31 31 
Dec 19 23:42:26 localhost kernel: [  162.929028] drivers/input/joystick/iforce/iforce-packets.c: condition cmd = 050a, data = 3a 00 19 19 00 00 00 00 31 31 
Dec 19 23:42:26 localhost kernel: [  162.929044] drivers/input/joystick/iforce/iforce-packets.c: condition cmd = 050a, data = 42 00 19 19 00 00 00 00 31 31 
Dec 19 23:42:49 localhost kernel: [  185.954214] usb 6-1: USB disconnect, address 2
Dec 19 23:42:49 localhost kernel: [  185.960338] BUG: unable to handle kernel paging request at 000032002a0000e7
Dec 19 23:42:49 localhost kernel: [  185.960627] IP: [<ffffffff8128949b>] unlink1+0x3b/0x130
Dec 19 23:42:49 localhost kernel: [  185.960810] PGD 0 
Dec 19 23:42:49 localhost kernel: [  185.960973] Oops: 0000 [#1] PREEMPT SMP 
Dec 19 23:42:49 localhost kernel: [  185.961131] last sysfs file: /sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq
Dec 19 23:42:49 localhost kernel: [  185.961131] CPU 1 
Dec 19 23:42:49 localhost kernel: [  185.961131] Modules linked in: usbhid hid iforce fglrx(P) ipv6 openafs(P) cpufreq_stats kvm_intel kvm binfmt_misc uinput fuse radeonfb fb_ddc i2c_algo_bit i2c_core snd_hda_codec_atihdmi snd_hda_codec_analog arc4 snd_hda_intel ide_cs joydev ecb snd_hda_codec iwlagn iwlcore snd_pcm_oss pcmcia snd_mixer_oss uvcvideo yenta_socket psmouse video snd_pcm rsrc_nonstatic mac80211 serio_raw pcspkr wmi pcmcia_core snd_page_alloc output cfg80211 rfkill ext3 jbd mbcache sha256_generic cryptd aes_x86_64 aes_generic sg ricoh_mmc sdhci_pci sdhci led_class uhci_hcd intel_agp [last unloaded: scsi_wait_scan]
Dec 19 23:42:49 localhost kernel: [  185.964097] Pid: 336, comm: khubd Tainted: P           2.6.32-je3 #5 HP EliteBook 8530p
Dec 19 23:42:49 localhost kernel: [  185.964097] RIP: 0010:[<ffffffff8128949b>]  [<ffffffff8128949b>] unlink1+0x3b/0x130
Dec 19 23:42:49 localhost kernel: [  185.964097] RSP: 0018:ffff88007e087b60  EFLAGS: 00010202
Dec 19 23:42:49 localhost kernel: [  185.964097] RAX: 000032002a00007f RBX: 0000000000000286 RCX: ffffffff8117aa43
Dec 19 23:42:49 localhost kernel: [  185.964097] RDX: 00000000fffffffe RSI: ffff880061766000 RDI: ffff88006e10e000
Dec 19 23:42:49 localhost kernel: [  185.964097] RBP: ffff88006e10e000 R08: ffff88000188f0e0 R09: 0000000000000000
Dec 19 23:42:49 localhost kernel: [  185.964097] R10: 8000000000000000 R11: ffffffff81152eb0 R12: 00000000fffffffe
Dec 19 23:42:49 localhost kernel: [  185.964097] R13: ffffffffa00c4408 R14: ffff88006fe57800 R15: 0000000000000000
Dec 19 23:42:49 localhost kernel: [  185.964097] FS:  0000000000000000(0000) GS:ffff880001880000(0000) knlGS:0000000000000000
Dec 19 23:42:49 localhost kernel: [  185.964097] CS:  0010 DS: 0018 ES: 0018 CR0: 000000008005003b
Dec 19 23:42:49 localhost kernel: [  185.964097] CR2: 000032002a0000e7 CR3: 000000005e823000 CR4: 00000000000026e0
Dec 19 23:42:49 localhost kernel: [  185.964097] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
Dec 19 23:42:49 localhost kernel: [  185.964097] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Dec 19 23:42:49 localhost kernel: [  185.964097] Process khubd (pid: 336, threadinfo ffff88007e086000, task ffff88007e1c9ea0)
Dec 19 23:42:49 localhost kernel: [  185.964097] Stack:
Dec 19 23:42:49 localhost kernel: [  185.964097]  0000000000000286 ffff880061766000 00000000fffffffe ffffffffa00c4408
Dec 19 23:42:49 localhost kernel: [  185.964097] <0> ffff88006fe57800 ffffffff812896f9 ffff880061766000 ffff88006e10e000
Dec 19 23:42:49 localhost kernel: [  185.964097] <0> ffff880061766014 ffffffff8128ac2c ffff88005e98d808 ffffffff81179963
Dec 19 23:42:49 localhost kernel: [  185.964097] Call Trace:
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff812896f9>] ? usb_hcd_unlink_urb+0x59/0xa0
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff8128ac2c>] ? usb_kill_urb+0x3c/0xc0
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff81179963>] ? kobject_del+0x23/0x30
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff8120ce3d>] ? device_del+0x17d/0x1d0
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffffa00c35bd>] ? iforce_usb_delete+0xd/0x40 [iforce]
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffffa00c3248>] ? iforce_usb_disconnect+0x48/0x70 [iforce]
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff8128ee54>] ? usb_unbind_interface+0x134/0x180
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff8120f5f2>] ? __device_release_driver+0x72/0xe0
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff8120f745>] ? device_release_driver+0x25/0x40
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff8120eae5>] ? bus_remove_device+0x95/0xd0
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff8120cdea>] ? device_del+0x12a/0x1d0
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff8128b955>] ? usb_disable_device+0x95/0x120
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff8128644b>] ? usb_disconnect+0xbb/0x150
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff81287291>] ? hub_thread+0x371/0x13a0
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff81037d90>] ? select_task_rq_fair+0x4b0/0x760
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff81036d25>] ? set_next_entity+0x35/0x70
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff81280100>] ? mmc_ioctl_dvd_read_struct+0x390/0x5c0
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff8139b849>] ? thread_return+0x243/0x65a
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff81059c80>] ? autoremove_wake_function+0x0/0x30
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff81286f20>] ? hub_thread+0x0/0x13a0
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff81286f20>] ? hub_thread+0x0/0x13a0
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff81059976>] ? kthread+0x96/0xa0
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff8100ce0a>] ? child_rip+0xa/0x20
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff810598e0>] ? kthread+0x0/0xa0
Dec 19 23:42:49 localhost kernel: [  185.964097]  [<ffffffff8100ce00>] ? child_rip+0x0/0x20
Dec 19 23:42:49 localhost kernel: [  185.964097] Code: 24 10 4c 89 6c 24 18 4c 89 74 24 20 48 89 fd 48 8b 46 48 48 89 f3 41 89 d4 48 83 78 38 00 74 30 48 8b 87 f0 00 00 00 48 8b 1c 24 <4c> 8b 58 68 48 8b 6c 24 08 4c 8b 64 24 10 4c 8b 6c 24 18 4c 8b 
Dec 19 23:42:49 localhost kernel: [  185.964097] RIP  [<ffffffff8128949b>] unlink1+0x3b/0x130
Dec 19 23:42:49 localhost kernel: [  185.964097]  RSP <ffff88007e087b60>
Dec 19 23:42:49 localhost kernel: [  185.964097] CR2: 000032002a0000e7
Dec 19 23:42:49 localhost kernel: [  185.977920] ---[ end trace fc8dfb59ff1c03b8 ]---

[-- Attachment #3: saitek-v2.patch --]
[-- Type: text/x-patch, Size: 7512 bytes --]

diff -ru iforce_orig/iforce.h iforce/iforce.h
--- iforce_orig/iforce.h	2009-12-03 04:51:21.000000000 +0100
+++ iforce/iforce.h	2009-12-20 00:18:55.000000000 +0100
@@ -96,6 +96,7 @@
 	signed short *btn;
 	signed short *abs;
 	signed short *ff;
+	bool has_btndead;
 };
 
 struct iforce {
diff -ru iforce_orig/iforce-main.c iforce/iforce-main.c
--- iforce_orig/iforce-main.c	2009-12-03 04:51:21.000000000 +0100
+++ iforce/iforce-main.c	2009-12-20 00:22:36.000000000 +0100
@@ -35,6 +35,10 @@
 { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
   BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, -1 };
 
+static signed short btn_saitek_cyborg[] =
+{ BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE,
+  BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, -1 };
+
 static signed short btn_avb_pegasus[] =
 { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
   BTN_BASE2, BTN_BASE3, BTN_BASE4, -1 };
@@ -54,6 +58,9 @@
 static signed short abs_joystick[] =
 { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 };
 
+static signed short abs_saitek_joystick[] =
+{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, -1 };
+
 static signed short abs_avb_pegasus[] =
 { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y,
   ABS_HAT1X, ABS_HAT1Y, -1 };
@@ -67,19 +74,20 @@
   FF_AUTOCENTER, -1 };
 
 static struct iforce_device iforce_device[] = {
-	{ 0x044f, 0xa01c, "Thrustmaster Motor Sport GT",		btn_wheel, abs_wheel, ff_iforce },
-	{ 0x046d, 0xc281, "Logitech WingMan Force",			btn_joystick, abs_joystick, ff_iforce },
-	{ 0x046d, 0xc291, "Logitech WingMan Formula Force",		btn_wheel, abs_wheel, ff_iforce },
-	{ 0x05ef, 0x020a, "AVB Top Shot Pegasus",			btn_avb_pegasus, abs_avb_pegasus, ff_iforce },
-	{ 0x05ef, 0x8884, "AVB Mag Turbo Force",			btn_avb_wheel, abs_wheel, ff_iforce },
-	{ 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel",	btn_avb_tw, abs_wheel, ff_iforce }, //?
-	{ 0x061c, 0xc0a4, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce }, //?
-	{ 0x061c, 0xc084, "ACT LABS Force RS",				btn_wheel, abs_wheel, ff_iforce },
-	{ 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback",	btn_wheel, abs_wheel, ff_iforce }, //?
-	{ 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel",	btn_wheel, abs_wheel, ff_iforce }, //?
-	{ 0x06f8, 0x0004, "Gullemot Jet Leader 3D",			btn_joystick, abs_joystick, ff_iforce }, //?
-	{ 0x06d6, 0x29bc, "Trust Force Feedback Race Master",		btn_wheel, abs_wheel, ff_iforce },
-	{ 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]",		btn_joystick, abs_joystick, ff_iforce }
+	{ 0x044f, 0xa01c, "Thrustmaster Motor Sport GT",		btn_wheel, abs_wheel, ff_iforce, true },
+	{ 0x046d, 0xc281, "Logitech WingMan Force",			btn_joystick, abs_joystick, ff_iforce, true },
+	{ 0x046d, 0xc291, "Logitech WingMan Formula Force",		btn_wheel, abs_wheel, ff_iforce, true },
+	{ 0x05ef, 0x020a, "AVB Top Shot Pegasus",			btn_avb_pegasus, abs_avb_pegasus, ff_iforce, true },
+	{ 0x05ef, 0x8884, "AVB Mag Turbo Force",			btn_avb_wheel, abs_wheel, ff_iforce, true },
+	{ 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel",	btn_avb_tw, abs_wheel, ff_iforce, true }, //?
+	{ 0x061c, 0xc0a4, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce, true }, //?
+	{ 0x061c, 0xc084, "ACT LABS Force RS",				btn_wheel, abs_wheel, ff_iforce, true },
+	{ 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback",	btn_wheel, abs_wheel, ff_iforce, true }, //?
+	{ 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel",	btn_wheel, abs_wheel, ff_iforce, true }, //?
+	{ 0x06f8, 0x0004, "Gullemot Jet Leader 3D",			btn_joystick, abs_joystick, ff_iforce, true }, //?
+	{ 0x06d6, 0x29bc, "Trust Force Feedback Race Master",		btn_wheel, abs_wheel, ff_iforce, true },
+	{ 0x06a3, 0xffb5, "Saitek Cyborg Evo Force",			btn_saitek_cyborg, abs_saitek_joystick, ff_iforce, false }, //?
+	{ 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]",		btn_joystick, abs_joystick, ff_iforce, true }
 };
 
 static int iforce_playback(struct input_dev *dev, int effect_id, int value)
@@ -396,7 +404,8 @@
 
 	for (i = 0; iforce->type->btn[i] >= 0; i++)
 		set_bit(iforce->type->btn[i], input_dev->keybit);
-	set_bit(BTN_DEAD, input_dev->keybit);
+	if (iforce->type->has_btndead)
+		set_bit(BTN_DEAD, input_dev->keybit);
 
 	for (i = 0; iforce->type->abs[i] >= 0; i++) {
 
@@ -408,7 +417,10 @@
 			case ABS_Y:
 			case ABS_WHEEL:
 
-				input_set_abs_params(input_dev, t, -1920, 1920, 16, 128);
+				if (iforce->type->idvendor == 0x06a3) /* Saitek axis */
+					input_set_abs_params(input_dev, t, 0, 4096, 16, 128);
+				else
+					input_set_abs_params(input_dev, t, -1920, 1920, 16, 128);
 				set_bit(t, input_dev->ffbit);
 				break;
 
@@ -421,7 +433,10 @@
 
 			case ABS_RUDDER:
 
-				input_set_abs_params(input_dev, t, -128, 127, 0, 0);
+				if (iforce->type->idvendor == 0x06a3) /* Saitek axis */
+					input_set_abs_params(input_dev, t, 0, 255, 0, 0);
+				else
+					input_set_abs_params(input_dev, t, -128, 127, 0, 0);
 				break;
 
 			case ABS_HAT0X:
diff -ru iforce_orig/iforce-packets.c iforce/iforce-packets.c
--- iforce_orig/iforce-packets.c	2009-12-03 04:51:21.000000000 +0100
+++ iforce/iforce-packets.c	2009-12-20 00:19:18.000000000 +0100
@@ -182,16 +182,24 @@
 
 		case 0x01:	/* joystick position data */
 		case 0x03:	/* wheel position data */
-			if (HI(cmd) == 1) {
-				input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
-				input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
-				input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
-				if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
-					input_report_abs(dev, ABS_RUDDER, (__s8)data[7]);
-			} else {
+		case 0x06:	/* saitek position data */
+			if (HI(cmd) == 3) {
 				input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0]));
 				input_report_abs(dev, ABS_GAS,   255 - data[2]);
 				input_report_abs(dev, ABS_BRAKE, 255 - data[3]);
+			} else {
+				input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
+				input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
+				if (HI(cmd) == 6) {
+					input_report_abs(dev, ABS_THROTTLE, data[4]);
+					if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
+						input_report_abs(dev, ABS_RUDDER, data[7]);
+				} else {
+					input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
+					if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
+						input_report_abs(dev, ABS_RUDDER, (__s8)data[7]);
+				}
+
 			}
 
 			input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x);
@@ -220,8 +228,10 @@
 			break;
 
 		case 0x02:	/* status report */
-			input_report_key(dev, BTN_DEAD, data[0] & 0x02);
-			input_sync(dev);
+			if (iforce->type->has_btndead) {
+				input_report_key(dev, BTN_DEAD, data[0] & 0x02);
+				input_sync(dev);
+			}
 
 			/* Check if an effect was just started or stopped */
 			i = data[1] & 0x7f;
diff -ru iforce_orig/iforce-usb.c iforce/iforce-usb.c
--- iforce_orig/iforce-usb.c	2009-12-03 04:51:21.000000000 +0100
+++ iforce/iforce-usb.c	2009-12-15 22:46:11.000000000 +0100
@@ -227,6 +227,7 @@
 	{ USB_DEVICE(0x06f8, 0x0001) },		/* Guillemot Race Leader Force Feedback */
 	{ USB_DEVICE(0x06f8, 0x0004) },		/* Guillemot Force Feedback Racing Wheel */
 	{ USB_DEVICE(0x06f8, 0xa302) },		/* Guillemot Jet Leader 3D */
+	{ USB_DEVICE(0x06a3, 0xffb5) },		/* Saitek Cyborg Evo Force */
 	{ }					/* Terminating entry */
 };
 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-19 23:36         ` Johannes Ebke
@ 2009-12-21  0:22           ` Melchior FRANZ
  2009-12-21  7:44           ` Dmitry Torokhov
  1 sibling, 0 replies; 18+ messages in thread
From: Melchior FRANZ @ 2009-12-21  0:22 UTC (permalink / raw)
  To: linux-input

* Johannes Ebke -- Sunday 20 December 2009:
> It seems that the force feedback works well, I have ported the force
> feedback for my favorite game to linux now, and it works well.

How do you handle joystick calibration? Or does your js not need that?
Mine does, and it looks like I can either have a working (= calibrated)
js (/dev/input/js?), *or* ff (/dev/input/event?), which is rather
unfortunate.

m.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-19 23:36         ` Johannes Ebke
  2009-12-21  0:22           ` Melchior FRANZ
@ 2009-12-21  7:44           ` Dmitry Torokhov
  2009-12-21  7:59             ` Dmitry Torokhov
                               ` (2 more replies)
  1 sibling, 3 replies; 18+ messages in thread
From: Dmitry Torokhov @ 2009-12-21  7:44 UTC (permalink / raw)
  To: Johannes Ebke; +Cc: Jiri Kosina, linux-input

On Sun, Dec 20, 2009 at 12:36:23AM +0100, Johannes Ebke wrote:
> Hi,
> 
> It seems that the force feedback works well, I have ported the force
> feedback for my favorite game to linux now, and it works well.
> 
> What does not work is updating effects - there just nothing happens, and
> the old event is played. I have circumvented this by
> deleting/re-uploading the effect, but this should probably been made to
> work. Does it work well with other hardware?
> 
> Thirdly, I have re-discovered one kernel oops that occurs if the
> joystick is unplugged if some process still has the event device open.
> Steps to reproduce:
> * plug joystick in
> * fftest /dev/input/eventXX
> * unplug joystick
> 
> (kern.log extract attached)
> 
> Sometimes this just gives an oops, sometimes it escalates into a kernel
> panic.
> 

Hmm, it looks like iforce unbinding is completely busted:

static void iforce_usb_disconnect(struct usb_interface *intf)
{
        struct iforce *iforce = usb_get_intfdata(intf);
        int open = 0; /* FIXME! iforce->dev.handle->open; */
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        usb_set_intfdata(intf, NULL);
        if (iforce) {
                iforce->usbdev = NULL;
                input_unregister_device(iforce->dev);

                if (!open) {
                        iforce_delete_device(iforce);
                        kfree(iforce);
                }
        }
}


Any chance you could fix that FIXME ;) ?

-- 
Dmitry

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-21  7:44           ` Dmitry Torokhov
@ 2009-12-21  7:59             ` Dmitry Torokhov
  2009-12-21  8:22             ` Dmitry Torokhov
  2009-12-21 11:45             ` [PATCH] " Johannes Ebke
  2 siblings, 0 replies; 18+ messages in thread
From: Dmitry Torokhov @ 2009-12-21  7:59 UTC (permalink / raw)
  To: Johannes Ebke; +Cc: Jiri Kosina, linux-input

On Sun, Dec 20, 2009 at 11:44:19PM -0800, Dmitry Torokhov wrote:
> On Sun, Dec 20, 2009 at 12:36:23AM +0100, Johannes Ebke wrote:
> > Hi,
> > 
> > It seems that the force feedback works well, I have ported the force
> > feedback for my favorite game to linux now, and it works well.
> > 
> > What does not work is updating effects - there just nothing happens, and
> > the old event is played. I have circumvented this by
> > deleting/re-uploading the effect, but this should probably been made to
> > work. Does it work well with other hardware?
> > 
> > Thirdly, I have re-discovered one kernel oops that occurs if the
> > joystick is unplugged if some process still has the event device open.
> > Steps to reproduce:
> > * plug joystick in
> > * fftest /dev/input/eventXX
> > * unplug joystick
> > 
> > (kern.log extract attached)
> > 
> > Sometimes this just gives an oops, sometimes it escalates into a kernel
> > panic.
> > 
> 
> Hmm, it looks like iforce unbinding is completely busted:
> 
> static void iforce_usb_disconnect(struct usb_interface *intf)
> {
>         struct iforce *iforce = usb_get_intfdata(intf);
>         int open = 0; /* FIXME! iforce->dev.handle->open; */
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
>         usb_set_intfdata(intf, NULL);
>         if (iforce) {
>                 iforce->usbdev = NULL;
>                 input_unregister_device(iforce->dev);
> 
>                 if (!open) {
>                         iforce_delete_device(iforce);
>                         kfree(iforce);
>                 }
>         }
> }
> 
> 
> Any chance you could fix that FIXME ;) ?
> 

BTW, could I get you "Signed-off-by: ... " for the Cyborg patch so that
I can apply it to my tree?

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-21  7:44           ` Dmitry Torokhov
  2009-12-21  7:59             ` Dmitry Torokhov
@ 2009-12-21  8:22             ` Dmitry Torokhov
  2009-12-29 12:46               ` Johannes Ebke
  2009-12-21 11:45             ` [PATCH] " Johannes Ebke
  2 siblings, 1 reply; 18+ messages in thread
From: Dmitry Torokhov @ 2009-12-21  8:22 UTC (permalink / raw)
  To: Johannes Ebke; +Cc: Jiri Kosina, linux-input

On Sun, Dec 20, 2009 at 11:44:19PM -0800, Dmitry Torokhov wrote:
> On Sun, Dec 20, 2009 at 12:36:23AM +0100, Johannes Ebke wrote:
> > Hi,
> > 
> > It seems that the force feedback works well, I have ported the force
> > feedback for my favorite game to linux now, and it works well.
> > 
> > What does not work is updating effects - there just nothing happens, and
> > the old event is played. I have circumvented this by
> > deleting/re-uploading the effect, but this should probably been made to
> > work. Does it work well with other hardware?
> > 
> > Thirdly, I have re-discovered one kernel oops that occurs if the
> > joystick is unplugged if some process still has the event device open.
> > Steps to reproduce:
> > * plug joystick in
> > * fftest /dev/input/eventXX
> > * unplug joystick
> > 
> > (kern.log extract attached)
> > 
> > Sometimes this just gives an oops, sometimes it escalates into a kernel
> > panic.
> > 
> 
> Hmm, it looks like iforce unbinding is completely busted:
> 
> static void iforce_usb_disconnect(struct usb_interface *intf)
> {
>         struct iforce *iforce = usb_get_intfdata(intf);
>         int open = 0; /* FIXME! iforce->dev.handle->open; */
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
>         usb_set_intfdata(intf, NULL);
>         if (iforce) {
>                 iforce->usbdev = NULL;
>                 input_unregister_device(iforce->dev);
> 
>                 if (!open) {
>                         iforce_delete_device(iforce);
>                         kfree(iforce);
>                 }
>         }
> }
> 
> 
> Any chance you could fix that FIXME ;) ?
> 

Actually, does the below fixes it for you?

-- 
Dmitry

Input: iforce - fix oops on device disconnect

Reported-by: Johannes Ebke <johannes.ebke@physik.uni-muenchen.de>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---

 drivers/input/joystick/iforce/iforce-main.c |   26 +++++--------------------
 drivers/input/joystick/iforce/iforce-usb.c  |   28 +++++++--------------------
 drivers/input/joystick/iforce/iforce.h      |    2 --
 3 files changed, 12 insertions(+), 44 deletions(-)


diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index 47d8c43..df142df 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -218,7 +218,7 @@ static int iforce_open(struct input_dev *dev)
 	return 0;
 }
 
-static void iforce_release(struct input_dev *dev)
+static void iforce_close(struct input_dev *dev)
 {
 	struct iforce *iforce = input_get_drvdata(dev);
 	int i;
@@ -240,26 +240,10 @@ static void iforce_release(struct input_dev *dev)
 
 	switch (iforce->bus) {
 #ifdef CONFIG_JOYSTICK_IFORCE_USB
-		case IFORCE_USB:
-			usb_kill_urb(iforce->irq);
-
-			/* The device was unplugged before the file
-			 * was released */
-			if (iforce->usbdev == NULL) {
-				iforce_delete_device(iforce);
-				kfree(iforce);
-			}
-		break;
-#endif
-	}
-}
-
-void iforce_delete_device(struct iforce *iforce)
-{
-	switch (iforce->bus) {
-#ifdef CONFIG_JOYSTICK_IFORCE_USB
 	case IFORCE_USB:
-		iforce_usb_delete(iforce);
+		usb_kill_urb(iforce->irq);
+		usb_kill_urb(iforce->out);
+		usb_kill_urb(iforce->ctrl);
 		break;
 #endif
 #ifdef CONFIG_JOYSTICK_IFORCE_232
@@ -311,7 +295,7 @@ int iforce_init_device(struct iforce *iforce)
 
 	input_dev->name = "Unknown I-Force device";
 	input_dev->open = iforce_open;
-	input_dev->close = iforce_release;
+	input_dev->close = iforce_close;
 
 /*
  * On-device memory allocation.
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index ae2e8c6..3fc9f46 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -186,33 +186,19 @@ fail:
 	return err;
 }
 
-/* Called by iforce_delete() */
-void iforce_usb_delete(struct iforce* iforce)
-{
-	usb_kill_urb(iforce->irq);
-	usb_kill_urb(iforce->out);
-	usb_kill_urb(iforce->ctrl);
-
-	usb_free_urb(iforce->irq);
-	usb_free_urb(iforce->out);
-	usb_free_urb(iforce->ctrl);
-}
-
 static void iforce_usb_disconnect(struct usb_interface *intf)
 {
 	struct iforce *iforce = usb_get_intfdata(intf);
-	int open = 0; /* FIXME! iforce->dev.handle->open; */
 
 	usb_set_intfdata(intf, NULL);
-	if (iforce) {
-		iforce->usbdev = NULL;
-		input_unregister_device(iforce->dev);
 
-		if (!open) {
-			iforce_delete_device(iforce);
-			kfree(iforce);
-		}
-	}
+	input_unregister_device(iforce->dev);
+
+	usb_free_urb(iforce->irq);
+	usb_free_urb(iforce->out);
+	usb_free_urb(iforce->ctrl);
+
+	kfree(iforce);
 }
 
 static struct usb_device_id iforce_usb_ids [] = {
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index 1a76ca1..7fa7b5d 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -151,11 +151,9 @@ void iforce_serial_xmit(struct iforce *iforce);
 
 /* iforce-usb.c */
 void iforce_usb_xmit(struct iforce *iforce);
-void iforce_usb_delete(struct iforce *iforce);
 
 /* iforce-main.c */
 int iforce_init_device(struct iforce *iforce);
-void iforce_delete_device(struct iforce *iforce);
 
 /* iforce-packets.c */
 int iforce_control_playback(struct iforce*, u16 id, unsigned int);

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH] Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-21  7:44           ` Dmitry Torokhov
  2009-12-21  7:59             ` Dmitry Torokhov
  2009-12-21  8:22             ` Dmitry Torokhov
@ 2009-12-21 11:45             ` Johannes Ebke
  2 siblings, 0 replies; 18+ messages in thread
From: Johannes Ebke @ 2009-12-21 11:45 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Jiri Kosina, linux-input

[-- Attachment #1: Type: text/plain, Size: 87 bytes --]

Hi,

I am doing this for the first time - I hope I got it correctly.

Cheers,
Johannes

[-- Attachment #2: saitekff.patch --]
[-- Type: text/x-patch, Size: 8101 bytes --]

This patch adds support for the Saitek Cyborg Evo Force Joystick to the iforce driver

From: Johannes Ebke <johannes.ebke@physik.uni-muenchen.de>
Signed-off-by: Johannes Ebke <johannes.ebke@physik.uni-muenchen.de>

diff -ru drivers/input/joystick/iforce_orig/iforce.h drivers/input/joystick/iforce/iforce.h
--- drivers/input/joystick/iforce_orig/iforce.h	2009-12-03 04:51:21.000000000 +0100
+++ drivers/input/joystick/iforce/iforce.h	2009-12-20 00:18:55.000000000 +0100
@@ -96,6 +96,7 @@
 	signed short *btn;
 	signed short *abs;
 	signed short *ff;
+	bool has_btndead;
 };
 
 struct iforce {
diff -ru drivers/input/joystick/iforce_orig/iforce-main.c drivers/input/joystick/iforce/iforce-main.c
--- drivers/input/joystick/iforce_orig/iforce-main.c	2009-12-03 04:51:21.000000000 +0100
+++ drivers/input/joystick/iforce/iforce-main.c	2009-12-20 00:22:36.000000000 +0100
@@ -35,6 +35,10 @@
 { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
   BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, -1 };
 
+static signed short btn_saitek_cyborg[] =
+{ BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE,
+  BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_BASE5, BTN_A, BTN_B, BTN_C, -1 };
+
 static signed short btn_avb_pegasus[] =
 { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE,
   BTN_BASE2, BTN_BASE3, BTN_BASE4, -1 };
@@ -54,6 +58,9 @@
 static signed short abs_joystick[] =
 { ABS_X, ABS_Y, ABS_THROTTLE, ABS_HAT0X, ABS_HAT0Y, -1 };
 
+static signed short abs_saitek_joystick[] =
+{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y, -1 };
+
 static signed short abs_avb_pegasus[] =
 { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, ABS_HAT0X, ABS_HAT0Y,
   ABS_HAT1X, ABS_HAT1Y, -1 };
@@ -67,19 +74,20 @@
   FF_AUTOCENTER, -1 };
 
 static struct iforce_device iforce_device[] = {
-	{ 0x044f, 0xa01c, "Thrustmaster Motor Sport GT",		btn_wheel, abs_wheel, ff_iforce },
-	{ 0x046d, 0xc281, "Logitech WingMan Force",			btn_joystick, abs_joystick, ff_iforce },
-	{ 0x046d, 0xc291, "Logitech WingMan Formula Force",		btn_wheel, abs_wheel, ff_iforce },
-	{ 0x05ef, 0x020a, "AVB Top Shot Pegasus",			btn_avb_pegasus, abs_avb_pegasus, ff_iforce },
-	{ 0x05ef, 0x8884, "AVB Mag Turbo Force",			btn_avb_wheel, abs_wheel, ff_iforce },
-	{ 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel",	btn_avb_tw, abs_wheel, ff_iforce }, //?
-	{ 0x061c, 0xc0a4, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce }, //?
-	{ 0x061c, 0xc084, "ACT LABS Force RS",				btn_wheel, abs_wheel, ff_iforce },
-	{ 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback",	btn_wheel, abs_wheel, ff_iforce }, //?
-	{ 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel",	btn_wheel, abs_wheel, ff_iforce }, //?
-	{ 0x06f8, 0x0004, "Gullemot Jet Leader 3D",			btn_joystick, abs_joystick, ff_iforce }, //?
-	{ 0x06d6, 0x29bc, "Trust Force Feedback Race Master",		btn_wheel, abs_wheel, ff_iforce },
-	{ 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]",		btn_joystick, abs_joystick, ff_iforce }
+	{ 0x044f, 0xa01c, "Thrustmaster Motor Sport GT",		btn_wheel, abs_wheel, ff_iforce, true },
+	{ 0x046d, 0xc281, "Logitech WingMan Force",			btn_joystick, abs_joystick, ff_iforce, true },
+	{ 0x046d, 0xc291, "Logitech WingMan Formula Force",		btn_wheel, abs_wheel, ff_iforce, true },
+	{ 0x05ef, 0x020a, "AVB Top Shot Pegasus",			btn_avb_pegasus, abs_avb_pegasus, ff_iforce, true },
+	{ 0x05ef, 0x8884, "AVB Mag Turbo Force",			btn_avb_wheel, abs_wheel, ff_iforce, true },
+	{ 0x05ef, 0x8888, "AVB Top Shot Force Feedback Racing Wheel",	btn_avb_tw, abs_wheel, ff_iforce, true }, //?
+	{ 0x061c, 0xc0a4, "ACT LABS Force RS",                          btn_wheel, abs_wheel, ff_iforce, true }, //?
+	{ 0x061c, 0xc084, "ACT LABS Force RS",				btn_wheel, abs_wheel, ff_iforce, true },
+	{ 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback",	btn_wheel, abs_wheel, ff_iforce, true }, //?
+	{ 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel",	btn_wheel, abs_wheel, ff_iforce, true }, //?
+	{ 0x06f8, 0x0004, "Gullemot Jet Leader 3D",			btn_joystick, abs_joystick, ff_iforce, true }, //?
+	{ 0x06d6, 0x29bc, "Trust Force Feedback Race Master",		btn_wheel, abs_wheel, ff_iforce, true },
+	{ 0x06a3, 0xffb5, "Saitek Cyborg Evo Force",			btn_saitek_cyborg, abs_saitek_joystick, ff_iforce, false }, //?
+	{ 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]",		btn_joystick, abs_joystick, ff_iforce, true }
 };
 
 static int iforce_playback(struct input_dev *dev, int effect_id, int value)
@@ -396,7 +404,8 @@
 
 	for (i = 0; iforce->type->btn[i] >= 0; i++)
 		set_bit(iforce->type->btn[i], input_dev->keybit);
-	set_bit(BTN_DEAD, input_dev->keybit);
+	if (iforce->type->has_btndead)
+		set_bit(BTN_DEAD, input_dev->keybit);
 
 	for (i = 0; iforce->type->abs[i] >= 0; i++) {
 
@@ -408,7 +417,10 @@
 			case ABS_Y:
 			case ABS_WHEEL:
 
-				input_set_abs_params(input_dev, t, -1920, 1920, 16, 128);
+				if (iforce->type->idvendor == 0x06a3) /* Saitek axis */
+					input_set_abs_params(input_dev, t, 0, 4096, 16, 128);
+				else
+					input_set_abs_params(input_dev, t, -1920, 1920, 16, 128);
 				set_bit(t, input_dev->ffbit);
 				break;
 
@@ -421,7 +433,10 @@
 
 			case ABS_RUDDER:
 
-				input_set_abs_params(input_dev, t, -128, 127, 0, 0);
+				if (iforce->type->idvendor == 0x06a3) /* Saitek axis */
+					input_set_abs_params(input_dev, t, 0, 255, 0, 0);
+				else
+					input_set_abs_params(input_dev, t, -128, 127, 0, 0);
 				break;
 
 			case ABS_HAT0X:
diff -ru drivers/input/joystick/iforce_orig/iforce-packets.c drivers/input/joystick/iforce/iforce-packets.c
--- drivers/input/joystick/iforce_orig/iforce-packets.c	2009-12-03 04:51:21.000000000 +0100
+++ drivers/input/joystick/iforce/iforce-packets.c	2009-12-20 01:11:18.000000000 +0100
@@ -182,16 +182,24 @@
 
 		case 0x01:	/* joystick position data */
 		case 0x03:	/* wheel position data */
-			if (HI(cmd) == 1) {
-				input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
-				input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
-				input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
-				if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
-					input_report_abs(dev, ABS_RUDDER, (__s8)data[7]);
-			} else {
+		case 0x06:	/* saitek position data */
+			if (HI(cmd) == 3) {
 				input_report_abs(dev, ABS_WHEEL, (__s16) (((__s16)data[1] << 8) | data[0]));
 				input_report_abs(dev, ABS_GAS,   255 - data[2]);
 				input_report_abs(dev, ABS_BRAKE, 255 - data[3]);
+			} else {
+				input_report_abs(dev, ABS_X, (__s16) (((__s16)data[1] << 8) | data[0]));
+				input_report_abs(dev, ABS_Y, (__s16) (((__s16)data[3] << 8) | data[2]));
+				if (HI(cmd) == 6) {
+					input_report_abs(dev, ABS_THROTTLE, data[4]);
+					if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
+						input_report_abs(dev, ABS_RUDDER, 255 - data[7]);
+				} else {
+					input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
+					if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
+						input_report_abs(dev, ABS_RUDDER, (__s8)data[7]);
+				}
+
 			}
 
 			input_report_abs(dev, ABS_HAT0X, iforce_hat_to_axis[data[6] >> 4].x);
@@ -220,8 +228,10 @@
 			break;
 
 		case 0x02:	/* status report */
-			input_report_key(dev, BTN_DEAD, data[0] & 0x02);
-			input_sync(dev);
+			if (iforce->type->has_btndead) {
+				input_report_key(dev, BTN_DEAD, data[0] & 0x02);
+				input_sync(dev);
+			}
 
 			/* Check if an effect was just started or stopped */
 			i = data[1] & 0x7f;
diff -ru drivers/input/joystick/iforce_orig/iforce-usb.c drivers/input/joystick/iforce/iforce-usb.c
--- drivers/input/joystick/iforce_orig/iforce-usb.c	2009-12-03 04:51:21.000000000 +0100
+++ drivers/input/joystick/iforce/iforce-usb.c	2009-12-15 22:46:11.000000000 +0100
@@ -227,6 +227,7 @@
 	{ USB_DEVICE(0x06f8, 0x0001) },		/* Guillemot Race Leader Force Feedback */
 	{ USB_DEVICE(0x06f8, 0x0004) },		/* Guillemot Force Feedback Racing Wheel */
 	{ USB_DEVICE(0x06f8, 0xa302) },		/* Guillemot Jet Leader 3D */
+	{ USB_DEVICE(0x06a3, 0xffb5) },		/* Saitek Cyborg Evo Force */
 	{ }					/* Terminating entry */
 };
 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-21  8:22             ` Dmitry Torokhov
@ 2009-12-29 12:46               ` Johannes Ebke
  2009-12-29 22:40                 ` Dmitry Torokhov
  0 siblings, 1 reply; 18+ messages in thread
From: Johannes Ebke @ 2009-12-29 12:46 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Jiri Kosina, linux-input

Dmitry Torokhov wrote:
> On Sun, Dec 20, 2009 at 11:44:19PM -0800, Dmitry Torokhov wrote:
>> On Sun, Dec 20, 2009 at 12:36:23AM +0100, Johannes Ebke wrote:
>>> Hi,
>>>
>>> It seems that the force feedback works well, I have ported the force
>>> feedback for my favorite game to linux now, and it works well.
>>>
>>> What does not work is updating effects - there just nothing happens, and
>>> the old event is played. I have circumvented this by
>>> deleting/re-uploading the effect, but this should probably been made to
>>> work. Does it work well with other hardware?
>>>
>>> Thirdly, I have re-discovered one kernel oops that occurs if the
>>> joystick is unplugged if some process still has the event device open.
>>> Steps to reproduce:
>>> * plug joystick in
>>> * fftest /dev/input/eventXX
>>> * unplug joystick
>>>
>>> (kern.log extract attached)
>>>
>>> Sometimes this just gives an oops, sometimes it escalates into a kernel
>>> panic.
>>>
>> Hmm, it looks like iforce unbinding is completely busted:
>>
>> static void iforce_usb_disconnect(struct usb_interface *intf)
>> {
>>         struct iforce *iforce = usb_get_intfdata(intf);
>>         int open = 0; /* FIXME! iforce->dev.handle->open; */
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>
>>         usb_set_intfdata(intf, NULL);
>>         if (iforce) {
>>                 iforce->usbdev = NULL;
>>                 input_unregister_device(iforce->dev);
>>
>>                 if (!open) {
>>                         iforce_delete_device(iforce);
>>                         kfree(iforce);
>>                 }
>>         }
>> }
>>
>>
>> Any chance you could fix that FIXME ;) ?
>>
>
> Actually, does the below fixes it for you?
>

This fixes the kernel oops - thanks! However it also disables FF, unless
I remove "usb_kill_urb(iforce->out);" from iforce_close.
>From some debug statements I found that iforce_close is called twice if
you just plug in the joystick, so the effect is immediate.

However, when I unplug the joystick while having it open, I get some
input input22: usb_submit_urb failed -19
messages in dmesg (after iforce_disconnect but before iforce_close)
This is probably what should happen, however.

Cheers,
Johannes

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-29 12:46               ` Johannes Ebke
@ 2009-12-29 22:40                 ` Dmitry Torokhov
  2009-12-30  3:23                   ` Dmitry Torokhov
  0 siblings, 1 reply; 18+ messages in thread
From: Dmitry Torokhov @ 2009-12-29 22:40 UTC (permalink / raw)
  To: Johannes Ebke; +Cc: Jiri Kosina, linux-input

  Dec 29, 2009, at 4:46 AM, Johannes Ebke <johannes.ebke@physik.uni-muenchen.de 
 > wrote:

> Dmitry Torokhov wrote:
>> On Sun, Dec 20, 2009 at 11:44:19PM -0800, Dmitry Torokhov wrote:
>>> On Sun, Dec 20, 2009 at 12:36:23AM +0100, Johannes Ebke wrote:
>>>> Hi,
>>>>
>>>> It seems that the force feedback works well, I have ported the  
>>>> force
>>>> feedback for my favorite game to linux now, and it works well.
>>>>
>>>> What does not work is updating effects - there just nothing  
>>>> happens, and
>>>> the old event is played. I have circumvented this by
>>>> deleting/re-uploading the effect, but this should probably been  
>>>> made to
>>>> work. Does it work well with other hardware?
>>>>
>>>> Thirdly, I have re-discovered one kernel oops that occurs if the
>>>> joystick is unplugged if some process still has the event device  
>>>> open.
>>>> Steps to reproduce:
>>>> * plug joystick in
>>>> * fftest /dev/input/eventXX
>>>> * unplug joystick
>>>>
>>>> (kern.log extract attached)
>>>>
>>>> Sometimes this just gives an oops, sometimes it escalates into a  
>>>> kernel
>>>> panic.
>>>>
>>> Hmm, it looks like iforce unbinding is completely busted:
>>>
>>> static void iforce_usb_disconnect(struct usb_interface *intf)
>>> {
>>>        struct iforce *iforce = usb_get_intfdata(intf);
>>>        int open = 0; /* FIXME! iforce->dev.handle->open; */
>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>
>>>        usb_set_intfdata(intf, NULL);
>>>        if (iforce) {
>>>                iforce->usbdev = NULL;
>>>                input_unregister_device(iforce->dev);
>>>
>>>                if (!open) {
>>>                        iforce_delete_device(iforce);
>>>                        kfree(iforce);
>>>                }
>>>        }
>>> }
>>>
>>>
>>> Any chance you could fix that FIXME ;) ?
>>>
>>
>> Actually, does the below fixes it for you?
>>
>
> This fixes the kernel oops - thanks! However it also disables FF,  
> unless
> I remove "usb_kill_urb(iforce->out);" from iforce_close.
> From some debug statements I found that iforce_close is called twice  
> if
> you just plug in the joystick, so the effect is immediate.

I still believe that usb_kill_urb is needed however we need to wait  
for packet disabling FF to complete.

>
> However, when I unplug the joystick while having it open, I get some
> input input22: usb_submit_urb failed -19
> messages in dmesg (after iforce_disconnect but before iforce_close)
> This is probably what should happen, however.
>

This is indeed expected with surprise removals.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-29 22:40                 ` Dmitry Torokhov
@ 2009-12-30  3:23                   ` Dmitry Torokhov
  2009-12-30  9:01                     ` Johannes Ebke
  0 siblings, 1 reply; 18+ messages in thread
From: Dmitry Torokhov @ 2009-12-30  3:23 UTC (permalink / raw)
  To: Johannes Ebke; +Cc: Jiri Kosina, linux-input

On Tue, Dec 29, 2009 at 02:40:21PM -0800, Dmitry Torokhov wrote:
>  Dec 29, 2009, at 4:46 AM, Johannes Ebke
> <johannes.ebke@physik.uni-muenchen.de> wrote:
> 
> >Dmitry Torokhov wrote:
> >>On Sun, Dec 20, 2009 at 11:44:19PM -0800, Dmitry Torokhov wrote:
> >>>On Sun, Dec 20, 2009 at 12:36:23AM +0100, Johannes Ebke wrote:
> >>>>Hi,
> >>>>
> >>>>It seems that the force feedback works well, I have ported
> >>>>the force
> >>>>feedback for my favorite game to linux now, and it works well.
> >>>>
> >>>>What does not work is updating effects - there just nothing
> >>>>happens, and
> >>>>the old event is played. I have circumvented this by
> >>>>deleting/re-uploading the effect, but this should probably
> >>>>been made to
> >>>>work. Does it work well with other hardware?
> >>>>
> >>>>Thirdly, I have re-discovered one kernel oops that occurs if the
> >>>>joystick is unplugged if some process still has the event
> >>>>device open.
> >>>>Steps to reproduce:
> >>>>* plug joystick in
> >>>>* fftest /dev/input/eventXX
> >>>>* unplug joystick
> >>>>
> >>>>(kern.log extract attached)
> >>>>
> >>>>Sometimes this just gives an oops, sometimes it escalates
> >>>>into a kernel
> >>>>panic.
> >>>>
> >>>Hmm, it looks like iforce unbinding is completely busted:
> >>>
> >>>static void iforce_usb_disconnect(struct usb_interface *intf)
> >>>{
> >>>       struct iforce *iforce = usb_get_intfdata(intf);
> >>>       int open = 0; /* FIXME! iforce->dev.handle->open; */
> >>>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >>>
> >>>       usb_set_intfdata(intf, NULL);
> >>>       if (iforce) {
> >>>               iforce->usbdev = NULL;
> >>>               input_unregister_device(iforce->dev);
> >>>
> >>>               if (!open) {
> >>>                       iforce_delete_device(iforce);
> >>>                       kfree(iforce);
> >>>               }
> >>>       }
> >>>}
> >>>
> >>>
> >>>Any chance you could fix that FIXME ;) ?
> >>>
> >>
> >>Actually, does the below fixes it for you?
> >>
> >
> >This fixes the kernel oops - thanks! However it also disables FF,
> >unless
> >I remove "usb_kill_urb(iforce->out);" from iforce_close.
> >From some debug statements I found that iforce_close is called
> >twice if
> >you just plug in the joystick, so the effect is immediate.
> 
> I still believe that usb_kill_urb is needed however we need to wait
> for packet disabling FF to complete.
> 

Does the patch below (on top of the unmodofied previous one) fixes the
issue for you?

Thanks.

-- 
Dmitry


Input: iforce - wait for command completion when closing the device

We need to wait for the command to disable FF effects to complete before
continuing with closing the device.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---

 drivers/input/joystick/iforce/iforce-main.c |    3 +++
 drivers/input/joystick/iforce/iforce-usb.c  |    1 +
 2 files changed, 4 insertions(+), 0 deletions(-)


diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index acc3a9e..b1edd77 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -228,6 +228,9 @@ static void iforce_close(struct input_dev *dev)
 
 		/* Disable force feedback playback */
 		iforce_send_packet(iforce, FF_CMD_ENABLE, "\001");
+		/* Wait for the command to complete */
+		wait_event_interruptible(iforce->wait,
+			!test_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags));
 	}
 
 	switch (iforce->bus) {
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index c0ad883..b41303d 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -109,6 +109,7 @@ static void iforce_usb_out(struct urb *urb)
 	struct iforce *iforce = urb->context;
 
 	if (urb->status) {
+		clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
 		dbg("urb->status %d, exiting", urb->status);
 		return;
 	}


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-30  3:23                   ` Dmitry Torokhov
@ 2009-12-30  9:01                     ` Johannes Ebke
  2009-12-30 10:47                       ` Dmitry Torokhov
  0 siblings, 1 reply; 18+ messages in thread
From: Johannes Ebke @ 2009-12-30  9:01 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Jiri Kosina, linux-input

[-- Attachment #1: Type: text/plain, Size: 3096 bytes --]

Dmitry Torokhov wrote:
> On Tue, Dec 29, 2009 at 02:40:21PM -0800, Dmitry Torokhov wrote:
>>  Dec 29, 2009, at 4:46 AM, Johannes Ebke
>> <johannes.ebke@physik.uni-muenchen.de> wrote:
>>
>>> Dmitry Torokhov wrote:
>>>> On Sun, Dec 20, 2009 at 11:44:19PM -0800, Dmitry Torokhov wrote:
>>>>> On Sun, Dec 20, 2009 at 12:36:23AM +0100, Johannes Ebke wrote:
>>>>>> Hi,
>>>>>>
>>>>>> It seems that the force feedback works well, I have ported
>>>>>> the force
>>>>>> feedback for my favorite game to linux now, and it works well.
>>>>>>
>>>>>> What does not work is updating effects - there just nothing
>>>>>> happens, and
>>>>>> the old event is played. I have circumvented this by
>>>>>> deleting/re-uploading the effect, but this should probably
>>>>>> been made to
>>>>>> work. Does it work well with other hardware?
>>>>>>
>>>>>> Thirdly, I have re-discovered one kernel oops that occurs if the
>>>>>> joystick is unplugged if some process still has the event
>>>>>> device open.
>>>>>> Steps to reproduce:
>>>>>> * plug joystick in
>>>>>> * fftest /dev/input/eventXX
>>>>>> * unplug joystick
>>>>>>
>>>>>> (kern.log extract attached)
>>>>>>
>>>>>> Sometimes this just gives an oops, sometimes it escalates
>>>>>> into a kernel
>>>>>> panic.
>>>>>>
>>>>> Hmm, it looks like iforce unbinding is completely busted:
>>>>>
>>>>> static void iforce_usb_disconnect(struct usb_interface *intf)
>>>>> {
>>>>>       struct iforce *iforce = usb_get_intfdata(intf);
>>>>>       int open = 0; /* FIXME! iforce->dev.handle->open; */
>>>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>>>
>>>>>       usb_set_intfdata(intf, NULL);
>>>>>       if (iforce) {
>>>>>               iforce->usbdev = NULL;
>>>>>               input_unregister_device(iforce->dev);
>>>>>
>>>>>               if (!open) {
>>>>>                       iforce_delete_device(iforce);
>>>>>                       kfree(iforce);
>>>>>               }
>>>>>       }
>>>>> }
>>>>>
>>>>>
>>>>> Any chance you could fix that FIXME ;) ?
>>>>>
>>>> Actually, does the below fixes it for you?
>>>>
>>> This fixes the kernel oops - thanks! However it also disables FF,
>>> unless
>>> I remove "usb_kill_urb(iforce->out);" from iforce_close.
>> >From some debug statements I found that iforce_close is called
>>> twice if
>>> you just plug in the joystick, so the effect is immediate.
>> I still believe that usb_kill_urb is needed however we need to wait
>> for packet disabling FF to complete.
>>
> 
> Does the patch below (on top of the unmodofied previous one) fixes the
> issue for you?
> 
> Thanks.
> 

This fixes it completely, both the FF and the clean shutdown on
unexpected disconnect! Thank you very much!

Finally, for correct orientation of the rudder axis, I have attached one
small change to packets - this makes it work for me if i remove the old
configuration.

One other question: Since the USB HID driver can actually discover the
joystick buttons and axis ranges sucessfully, would it not be easier to
use that for generic input and only add force-feedback in iforce, or is
that just too much overhead? Thanks!

Cheers,
Johannes


[-- Attachment #2: flipRx.patch --]
[-- Type: text/x-patch, Size: 882 bytes --]

Input: iforce - flip initial RUDDER orientation to correct one

Remove the inversion from the data acqisition routine

Signed-off-by: Johannes Ebke <johannes.ebke@physik.uni-muenchen.de>
---

diff -ru drivers/input/joystick/iforce_dmitry/iforce-packets.c drivers/input/joystick/iforce/iforce-packets.c
--- drivers/input/joystick/iforce_dmitry/iforce-packets.c	2009-12-30 09:42:22.000000000 +0100
+++ drivers/input/joystick/iforce/iforce-packets.c	2009-12-30 09:32:34.000000000 +0100
@@ -193,7 +193,7 @@
 				if (HI(cmd) == 6) {
 					input_report_abs(dev, ABS_THROTTLE, data[4]);
 					if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))
-						input_report_abs(dev, ABS_RUDDER, 255 - data[7]);
+						input_report_abs(dev, ABS_RUDDER, data[7]);
 				} else {
 					input_report_abs(dev, ABS_THROTTLE, 255 - data[4]);
 					if (LO(cmd) >= 8 && test_bit(ABS_RUDDER ,dev->absbit))

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-30  9:01                     ` Johannes Ebke
@ 2009-12-30 10:47                       ` Dmitry Torokhov
  2009-12-30 11:32                         ` Johannes Ebke
  0 siblings, 1 reply; 18+ messages in thread
From: Dmitry Torokhov @ 2009-12-30 10:47 UTC (permalink / raw)
  To: Johannes Ebke; +Cc: Jiri Kosina, linux-input

On Wed, Dec 30, 2009 at 10:01:01AM +0100, Johannes Ebke wrote:
> Dmitry Torokhov wrote:
> > On Tue, Dec 29, 2009 at 02:40:21PM -0800, Dmitry Torokhov wrote:
> >>  Dec 29, 2009, at 4:46 AM, Johannes Ebke
> >> <johannes.ebke@physik.uni-muenchen.de> wrote:
> >>
> >>> Dmitry Torokhov wrote:
> >>>> On Sun, Dec 20, 2009 at 11:44:19PM -0800, Dmitry Torokhov wrote:
> >>>>> On Sun, Dec 20, 2009 at 12:36:23AM +0100, Johannes Ebke wrote:
> >>>>>> Hi,
> >>>>>>
> >>>>>> It seems that the force feedback works well, I have ported
> >>>>>> the force
> >>>>>> feedback for my favorite game to linux now, and it works well.
> >>>>>>
> >>>>>> What does not work is updating effects - there just nothing
> >>>>>> happens, and
> >>>>>> the old event is played. I have circumvented this by
> >>>>>> deleting/re-uploading the effect, but this should probably
> >>>>>> been made to
> >>>>>> work. Does it work well with other hardware?
> >>>>>>
> >>>>>> Thirdly, I have re-discovered one kernel oops that occurs if the
> >>>>>> joystick is unplugged if some process still has the event
> >>>>>> device open.
> >>>>>> Steps to reproduce:
> >>>>>> * plug joystick in
> >>>>>> * fftest /dev/input/eventXX
> >>>>>> * unplug joystick
> >>>>>>
> >>>>>> (kern.log extract attached)
> >>>>>>
> >>>>>> Sometimes this just gives an oops, sometimes it escalates
> >>>>>> into a kernel
> >>>>>> panic.
> >>>>>>
> >>>>> Hmm, it looks like iforce unbinding is completely busted:
> >>>>>
> >>>>> static void iforce_usb_disconnect(struct usb_interface *intf)
> >>>>> {
> >>>>>       struct iforce *iforce = usb_get_intfdata(intf);
> >>>>>       int open = 0; /* FIXME! iforce->dev.handle->open; */
> >>>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >>>>>
> >>>>>       usb_set_intfdata(intf, NULL);
> >>>>>       if (iforce) {
> >>>>>               iforce->usbdev = NULL;
> >>>>>               input_unregister_device(iforce->dev);
> >>>>>
> >>>>>               if (!open) {
> >>>>>                       iforce_delete_device(iforce);
> >>>>>                       kfree(iforce);
> >>>>>               }
> >>>>>       }
> >>>>> }
> >>>>>
> >>>>>
> >>>>> Any chance you could fix that FIXME ;) ?
> >>>>>
> >>>> Actually, does the below fixes it for you?
> >>>>
> >>> This fixes the kernel oops - thanks! However it also disables FF,
> >>> unless
> >>> I remove "usb_kill_urb(iforce->out);" from iforce_close.
> >> >From some debug statements I found that iforce_close is called
> >>> twice if
> >>> you just plug in the joystick, so the effect is immediate.
> >> I still believe that usb_kill_urb is needed however we need to wait
> >> for packet disabling FF to complete.
> >>
> > 
> > Does the patch below (on top of the unmodofied previous one) fixes the
> > issue for you?
> > 
> > Thanks.
> > 
> 
> This fixes it completely, both the FF and the clean shutdown on
> unexpected disconnect! Thank you very much!

Ah, great!
 
> Finally, for correct orientation of the rudder axis, I have attached one
> small change to packets - this makes it work for me if i remove the old
> configuration.

Hmm, that might break some other users though (or does it only kick in
for Cyborg?

> 
> One other question: Since the USB HID driver can actually discover the
> joystick buttons and axis ranges sucessfully, would it not be easier to
> use that for generic input and only add force-feedback in iforce, or is
> that just too much overhead?

We do prefer to have HID driver handle the devices and have only
non-HID-compliant devices use specialized drivers. Iforce is an older
driver though, working with both USB devices and devices attached to
serial ports.

Does your joystick works well with HID driver (sans FF)?

-- 
Dmitry

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-30 10:47                       ` Dmitry Torokhov
@ 2009-12-30 11:32                         ` Johannes Ebke
  2011-06-08 18:51                           ` Richie Ward
  0 siblings, 1 reply; 18+ messages in thread
From: Johannes Ebke @ 2009-12-30 11:32 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Jiri Kosina, linux-input

Dmitry Torokhov wrote:
> On Wed, Dec 30, 2009 at 10:01:01AM +0100, Johannes Ebke wrote:
>> Dmitry Torokhov wrote:
>>> On Tue, Dec 29, 2009 at 02:40:21PM -0800, Dmitry Torokhov wrote:
>>>>  Dec 29, 2009, at 4:46 AM, Johannes Ebke
>>>> <johannes.ebke@physik.uni-muenchen.de> wrote:
>>>>
>>>>> Dmitry Torokhov wrote:
>>>>>> On Sun, Dec 20, 2009 at 11:44:19PM -0800, Dmitry Torokhov wrote:
>>>>>>> On Sun, Dec 20, 2009 at 12:36:23AM +0100, Johannes Ebke wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> It seems that the force feedback works well, I have ported
>>>>>>>> the force
>>>>>>>> feedback for my favorite game to linux now, and it works well.
>>>>>>>>
>>>>>>>> What does not work is updating effects - there just nothing
>>>>>>>> happens, and
>>>>>>>> the old event is played. I have circumvented this by
>>>>>>>> deleting/re-uploading the effect, but this should probably
>>>>>>>> been made to
>>>>>>>> work. Does it work well with other hardware?
>>>>>>>>
>>>>>>>> Thirdly, I have re-discovered one kernel oops that occurs if the
>>>>>>>> joystick is unplugged if some process still has the event
>>>>>>>> device open.
>>>>>>>> Steps to reproduce:
>>>>>>>> * plug joystick in
>>>>>>>> * fftest /dev/input/eventXX
>>>>>>>> * unplug joystick
>>>>>>>>
>>>>>>>> (kern.log extract attached)
>>>>>>>>
>>>>>>>> Sometimes this just gives an oops, sometimes it escalates
>>>>>>>> into a kernel
>>>>>>>> panic.
>>>>>>>>
>>>>>>> Hmm, it looks like iforce unbinding is completely busted:
>>>>>>>
>>>>>>> static void iforce_usb_disconnect(struct usb_interface *intf)
>>>>>>> {
>>>>>>>       struct iforce *iforce = usb_get_intfdata(intf);
>>>>>>>       int open = 0; /* FIXME! iforce->dev.handle->open; */
>>>>>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>>>>>
>>>>>>>       usb_set_intfdata(intf, NULL);
>>>>>>>       if (iforce) {
>>>>>>>               iforce->usbdev = NULL;
>>>>>>>               input_unregister_device(iforce->dev);
>>>>>>>
>>>>>>>               if (!open) {
>>>>>>>                       iforce_delete_device(iforce);
>>>>>>>                       kfree(iforce);
>>>>>>>               }
>>>>>>>       }
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> Any chance you could fix that FIXME ;) ?
>>>>>>>
>>>>>> Actually, does the below fixes it for you?
>>>>>>
>>>>> This fixes the kernel oops - thanks! However it also disables FF,
>>>>> unless
>>>>> I remove "usb_kill_urb(iforce->out);" from iforce_close.
>>>> >From some debug statements I found that iforce_close is called
>>>>> twice if
>>>>> you just plug in the joystick, so the effect is immediate.
>>>> I still believe that usb_kill_urb is needed however we need to wait
>>>> for packet disabling FF to complete.
>>>>
>>> Does the patch below (on top of the unmodofied previous one) fixes the
>>> issue for you?
>>>
>>> Thanks.
>>>
>> This fixes it completely, both the FF and the clean shutdown on
>> unexpected disconnect! Thank you very much!
> 
> Ah, great!
>  
>> Finally, for correct orientation of the rudder axis, I have attached one
>> small change to packets - this makes it work for me if i remove the old
>> configuration.
> 
> Hmm, that might break some other users though (or does it only kick in
> for Cyborg?

This is in the part that only kicks in for the Cyborg, or perhaps other
devices as well (if(HI(cmd)==6)..)

> 
>> One other question: Since the USB HID driver can actually discover the
>> joystick buttons and axis ranges sucessfully, would it not be easier to
>> use that for generic input and only add force-feedback in iforce, or is
>> that just too much overhead?
> 
> We do prefer to have HID driver handle the devices and have only
> non-HID-compliant devices use specialized drivers. Iforce is an older
> driver though, working with both USB devices and devices attached to
> serial ports.
> 
> Does your joystick works well with HID driver (sans FF)?
> 

Yes, with one grievance: Since the "dead man switch" is not physically
present on the cyborg but logically present and "always on", some
applications like the flightgear joystick calibration "fgjs" cannot be used.
However, I am not sure how the information "this is a dead man switch"
can be published to userspace most efficiently, and the application
should probably deal with it anyway (stuck key in old joystick, etc...)

Cheers,
Johannes

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Linux Force Feedback for Saitek Cyborg Evo Force
  2009-12-30 11:32                         ` Johannes Ebke
@ 2011-06-08 18:51                           ` Richie Ward
  0 siblings, 0 replies; 18+ messages in thread
From: Richie Ward @ 2011-06-08 18:51 UTC (permalink / raw)
  To: linux-input

Is there any progress on this driver? Johannes seems to of gotten it
working from what I have read.

I own a Cyborg Evo Force but I would like the force feedback driver to
be committed to the mainline so that it can be released with future
Linux distributions.

As of today, I cant see any mention of the Saitek Cyborg Evo Force in
the IForce driver in Linux 3.0 rc2's source. What seems to be the
roadblock to committing it to mainline?

On 30 December 2009 11:32, Johannes Ebke
<johannes.ebke@physik.uni-muenchen.de> wrote:
> Dmitry Torokhov wrote:
>> On Wed, Dec 30, 2009 at 10:01:01AM +0100, Johannes Ebke wrote:
>>> Dmitry Torokhov wrote:
>>>> On Tue, Dec 29, 2009 at 02:40:21PM -0800, Dmitry Torokhov wrote:
>>>>>  Dec 29, 2009, at 4:46 AM, Johannes Ebke
>>>>> <johannes.ebke@physik.uni-muenchen.de> wrote:
>>>>>
>>>>>> Dmitry Torokhov wrote:
>>>>>>> On Sun, Dec 20, 2009 at 11:44:19PM -0800, Dmitry Torokhov wrote:
>>>>>>>> On Sun, Dec 20, 2009 at 12:36:23AM +0100, Johannes Ebke wrote:
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> It seems that the force feedback works well, I have ported
>>>>>>>>> the force
>>>>>>>>> feedback for my favorite game to linux now, and it works well.
>>>>>>>>>
>>>>>>>>> What does not work is updating effects - there just nothing
>>>>>>>>> happens, and
>>>>>>>>> the old event is played. I have circumvented this by
>>>>>>>>> deleting/re-uploading the effect, but this should probably
>>>>>>>>> been made to
>>>>>>>>> work. Does it work well with other hardware?
>>>>>>>>>
>>>>>>>>> Thirdly, I have re-discovered one kernel oops that occurs if the
>>>>>>>>> joystick is unplugged if some process still has the event
>>>>>>>>> device open.
>>>>>>>>> Steps to reproduce:
>>>>>>>>> * plug joystick in
>>>>>>>>> * fftest /dev/input/eventXX
>>>>>>>>> * unplug joystick
>>>>>>>>>
>>>>>>>>> (kern.log extract attached)
>>>>>>>>>
>>>>>>>>> Sometimes this just gives an oops, sometimes it escalates
>>>>>>>>> into a kernel
>>>>>>>>> panic.
>>>>>>>>>
>>>>>>>> Hmm, it looks like iforce unbinding is completely busted:
>>>>>>>>
>>>>>>>> static void iforce_usb_disconnect(struct usb_interface *intf)
>>>>>>>> {
>>>>>>>>       struct iforce *iforce = usb_get_intfdata(intf);
>>>>>>>>       int open = 0; /* FIXME! iforce->dev.handle->open; */
>>>>>>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>>>>>>>
>>>>>>>>       usb_set_intfdata(intf, NULL);
>>>>>>>>       if (iforce) {
>>>>>>>>               iforce->usbdev = NULL;
>>>>>>>>               input_unregister_device(iforce->dev);
>>>>>>>>
>>>>>>>>               if (!open) {
>>>>>>>>                       iforce_delete_device(iforce);
>>>>>>>>                       kfree(iforce);
>>>>>>>>               }
>>>>>>>>       }
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>> Any chance you could fix that FIXME ;) ?
>>>>>>>>
>>>>>>> Actually, does the below fixes it for you?
>>>>>>>
>>>>>> This fixes the kernel oops - thanks! However it also disables FF,
>>>>>> unless
>>>>>> I remove "usb_kill_urb(iforce->out);" from iforce_close.
>>>>> >From some debug statements I found that iforce_close is called
>>>>>> twice if
>>>>>> you just plug in the joystick, so the effect is immediate.
>>>>> I still believe that usb_kill_urb is needed however we need to wait
>>>>> for packet disabling FF to complete.
>>>>>
>>>> Does the patch below (on top of the unmodofied previous one) fixes the
>>>> issue for you?
>>>>
>>>> Thanks.
>>>>
>>> This fixes it completely, both the FF and the clean shutdown on
>>> unexpected disconnect! Thank you very much!
>>
>> Ah, great!
>>
>>> Finally, for correct orientation of the rudder axis, I have attached one
>>> small change to packets - this makes it work for me if i remove the old
>>> configuration.
>>
>> Hmm, that might break some other users though (or does it only kick in
>> for Cyborg?
>
> This is in the part that only kicks in for the Cyborg, or perhaps other
> devices as well (if(HI(cmd)==6)..)
>
>>
>>> One other question: Since the USB HID driver can actually discover the
>>> joystick buttons and axis ranges sucessfully, would it not be easier to
>>> use that for generic input and only add force-feedback in iforce, or is
>>> that just too much overhead?
>>
>> We do prefer to have HID driver handle the devices and have only
>> non-HID-compliant devices use specialized drivers. Iforce is an older
>> driver though, working with both USB devices and devices attached to
>> serial ports.
>>
>> Does your joystick works well with HID driver (sans FF)?
>>
>
> Yes, with one grievance: Since the "dead man switch" is not physically
> present on the cyborg but logically present and "always on", some
> applications like the flightgear joystick calibration "fgjs" cannot be used.
> However, I am not sure how the information "this is a dead man switch"
> can be published to userspace most efficiently, and the application
> should probably deal with it anyway (stuck key in old joystick, etc...)
>
> Cheers,
> Johannes
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Thanks, Richie Ward
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2011-06-08 18:51 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <4B26B824.8010403@physik.uni-muenchen.de>
2009-12-15 13:07 ` Linux Force Feedback for Saitek Cyborg Evo Force Jiri Kosina
2009-12-17 23:18   ` Johannes Ebke
2009-12-18  8:59     ` Johannes Ebke
2009-12-18 10:52     ` Jiri Kosina
2009-12-18 17:50       ` Dmitry Torokhov
2009-12-19 23:36         ` Johannes Ebke
2009-12-21  0:22           ` Melchior FRANZ
2009-12-21  7:44           ` Dmitry Torokhov
2009-12-21  7:59             ` Dmitry Torokhov
2009-12-21  8:22             ` Dmitry Torokhov
2009-12-29 12:46               ` Johannes Ebke
2009-12-29 22:40                 ` Dmitry Torokhov
2009-12-30  3:23                   ` Dmitry Torokhov
2009-12-30  9:01                     ` Johannes Ebke
2009-12-30 10:47                       ` Dmitry Torokhov
2009-12-30 11:32                         ` Johannes Ebke
2011-06-08 18:51                           ` Richie Ward
2009-12-21 11:45             ` [PATCH] " Johannes Ebke

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).