diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 905e40a..a608ee6 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1546,9 +1546,8 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) return -ENODEV; } - if ((hdev->claimed & HID_CLAIMED_INPUT) && - (connect_mask & HID_CONNECT_FF) && hdev->ff_init) - hdev->ff_init(hdev); + /* Removed ff_init() call from here. It does device I/O but this is blocked + * because driver_input_lock is currently locked. */ len = 0; if (hdev->claimed & HID_CLAIMED_INPUT) @@ -2029,6 +2028,13 @@ static int hid_device_probe(struct device *dev) unlock: if (!hdev->io_started) up(&hdev->driver_input_lock); + + if ((hdev->claimed & HID_CLAIMED_INPUT) && hdev->ff_init) { + /* Late init of PID force-feedback drivers moved to after + * unlock of driver_input_lock */ + hdev->ff_init(hdev); + } + unlock_driver_lock: up(&hdev->driver_lock); return ret; diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 029965e..5d34dd7 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -505,7 +505,12 @@ static void hid_ctrl(struct urb *urb) case -EPROTO: /* protocol error or unplug */ case -ECONNRESET: /* unlink */ case -ENOENT: + break; case -EPIPE: /* report not available */ + usbhid_mark_busy(usbhid); + clear_bit(HID_IN_RUNNING, &usbhid->iofl); + set_bit(HID_CLEAR_HALT, &usbhid->iofl); + schedule_work(&usbhid->reset_work); break; default: /* error */ hid_warn(urb->dev, "ctrl urb status %d received\n", status); diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index 10b6167..3f8ea63 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c @@ -568,6 +568,13 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect, int type_id; int error; + pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0; + + if (old && effect) { + pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = + pidff->pid_id[effect->id]; + } + switch (effect->type) { case FF_CONSTANT: if (!old) { @@ -701,10 +708,14 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect, return -EINVAL; } - if (!old) + if (!old) { pidff->pid_id[effect->id] = pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]; + hid_dbg(pidff->hid, "Created new effect of type 0x%02x with h/w ID %d, driver ID %d\n", + effect->type, pidff->pid_id[effect->id], effect->id); + } + hid_dbg(pidff->hid, "uploaded\n"); return 0;