Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input fixes from Dmitry Torokhov:

- fixes for two long standing issues (lock up and a crash) in force
feedback handling in uinput driver

- tweak to firmware update timing in Elan I2C touchpad driver.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: elan_i2c - extend Flash-Write delay
Input: uinput - avoid crash when sending FF request to device going away
Input: uinput - avoid FF flush when destroying device

+51 -22
+10 -3
drivers/input/ff-core.c
··· 237 237 EXPORT_SYMBOL_GPL(input_ff_erase); 238 238 239 239 /* 240 - * flush_effects - erase all effects owned by a file handle 240 + * input_ff_flush - erase all effects owned by a file handle 241 + * @dev: input device to erase effect from 242 + * @file: purported owner of the effects 243 + * 244 + * This function erases all force-feedback effects associated with 245 + * the given owner from specified device. Note that @file may be %NULL, 246 + * in which case all effects will be erased. 241 247 */ 242 - static int flush_effects(struct input_dev *dev, struct file *file) 248 + int input_ff_flush(struct input_dev *dev, struct file *file) 243 249 { 244 250 struct ff_device *ff = dev->ff; 245 251 int i; ··· 261 255 262 256 return 0; 263 257 } 258 + EXPORT_SYMBOL_GPL(input_ff_flush); 264 259 265 260 /** 266 261 * input_ff_event() - generic handler for force-feedback events ··· 350 343 mutex_init(&ff->mutex); 351 344 352 345 dev->ff = ff; 353 - dev->flush = flush_effects; 346 + dev->flush = input_ff_flush; 354 347 dev->event = input_ff_event; 355 348 __set_bit(EV_FF, dev->evbit); 356 349
+39 -18
drivers/input/misc/uinput.c
··· 98 98 uinput_request_alloc_id(udev, request)); 99 99 } 100 100 101 - static void uinput_request_done(struct uinput_device *udev, 102 - struct uinput_request *request) 101 + static void uinput_request_release_slot(struct uinput_device *udev, 102 + unsigned int id) 103 103 { 104 104 /* Mark slot as available */ 105 - udev->requests[request->id] = NULL; 106 - wake_up(&udev->requests_waitq); 105 + spin_lock(&udev->requests_lock); 106 + udev->requests[id] = NULL; 107 + spin_unlock(&udev->requests_lock); 107 108 108 - complete(&request->done); 109 + wake_up(&udev->requests_waitq); 109 110 } 110 111 111 112 static int uinput_request_send(struct uinput_device *udev, ··· 139 138 static int uinput_request_submit(struct uinput_device *udev, 140 139 struct uinput_request *request) 141 140 { 142 - int error; 141 + int retval; 143 142 144 - error = uinput_request_reserve_slot(udev, request); 145 - if (error) 146 - return error; 143 + retval = uinput_request_reserve_slot(udev, request); 144 + if (retval) 145 + return retval; 147 146 148 - error = uinput_request_send(udev, request); 149 - if (error) { 150 - uinput_request_done(udev, request); 151 - return error; 152 - } 147 + retval = uinput_request_send(udev, request); 148 + if (retval) 149 + goto out; 153 150 154 151 wait_for_completion(&request->done); 155 - return request->retval; 152 + retval = request->retval; 153 + 154 + out: 155 + uinput_request_release_slot(udev, request->id); 156 + return retval; 156 157 } 157 158 158 159 /* ··· 172 169 request = udev->requests[i]; 173 170 if (request) { 174 171 request->retval = -ENODEV; 175 - uinput_request_done(udev, request); 172 + complete(&request->done); 176 173 } 177 174 } 178 175 ··· 231 228 request.u.effect_id = effect_id; 232 229 233 230 return uinput_request_submit(udev, &request); 231 + } 232 + 233 + static int uinput_dev_flush(struct input_dev *dev, struct file *file) 234 + { 235 + /* 236 + * If we are called with file == NULL that means we are tearing 237 + * down the device, and therefore we can not handle FF erase 238 + * requests: either we are handling UI_DEV_DESTROY (and holding 239 + * the udev->mutex), or the file descriptor is closed and there is 240 + * nobody on the other side anymore. 241 + */ 242 + return file ? input_ff_flush(dev, file) : 0; 234 243 } 235 244 236 245 static void uinput_destroy_device(struct uinput_device *udev) ··· 312 297 dev->ff->playback = uinput_dev_playback; 313 298 dev->ff->set_gain = uinput_dev_set_gain; 314 299 dev->ff->set_autocenter = uinput_dev_set_autocenter; 300 + /* 301 + * The standard input_ff_flush() implementation does 302 + * not quite work for uinput as we can't reasonably 303 + * handle FF requests during device teardown. 304 + */ 305 + dev->flush = uinput_dev_flush; 315 306 } 316 307 317 308 error = input_register_device(udev->dev); ··· 960 939 } 961 940 962 941 req->retval = ff_up.retval; 963 - uinput_request_done(udev, req); 942 + complete(&req->done); 964 943 goto out; 965 944 966 945 case UI_END_FF_ERASE: ··· 976 955 } 977 956 978 957 req->retval = ff_erase.retval; 979 - uinput_request_done(udev, req); 958 + complete(&req->done); 980 959 goto out; 981 960 } 982 961
+1 -1
drivers/input/mouse/elan_i2c_i2c.c
··· 598 598 } 599 599 600 600 /* Wait for F/W to update one page ROM data. */ 601 - msleep(20); 601 + msleep(35); 602 602 603 603 error = elan_i2c_read_cmd(client, ETP_I2C_IAP_CTRL_CMD, val); 604 604 if (error) {
+1
include/linux/input.h
··· 529 529 530 530 int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, struct file *file); 531 531 int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file); 532 + int input_ff_flush(struct input_dev *dev, struct file *file); 532 533 533 534 int input_ff_create_memless(struct input_dev *dev, void *data, 534 535 int (*play_effect)(struct input_dev *, void *, struct ff_effect *));