On Tue, Dec 29, 2009 at 02:40:21PM -0800, Dmitry Torokhov wrote: > Dec 29, 2009, at 4:46 AM, Johannes Ebke > <johannes.ebke@xxxxxxxxxxxxxxxxxxxxxx> 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@xxxxxxx> --- 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; } -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html