xref: /openbmc/linux/drivers/hid/usbhid/hid-core.c (revision 52d22534)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
26db3dfefSJiri Kosina /*
36db3dfefSJiri Kosina  *  USB HID support for Linux
46db3dfefSJiri Kosina  *
56db3dfefSJiri Kosina  *  Copyright (c) 1999 Andreas Gal
66db3dfefSJiri Kosina  *  Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
76db3dfefSJiri Kosina  *  Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
80361a28dSOliver Neukum  *  Copyright (c) 2007-2008 Oliver Neukum
97d39e849SJiri Kosina  *  Copyright (c) 2006-2010 Jiri Kosina
106db3dfefSJiri Kosina  */
116db3dfefSJiri Kosina 
126db3dfefSJiri Kosina /*
136db3dfefSJiri Kosina  */
146db3dfefSJiri Kosina 
156db3dfefSJiri Kosina #include <linux/module.h>
166db3dfefSJiri Kosina #include <linux/slab.h>
176db3dfefSJiri Kosina #include <linux/init.h>
186db3dfefSJiri Kosina #include <linux/kernel.h>
196db3dfefSJiri Kosina #include <linux/list.h>
206db3dfefSJiri Kosina #include <linux/mm.h>
213d5afd32SJiri Slaby #include <linux/mutex.h>
226db3dfefSJiri Kosina #include <linux/spinlock.h>
236db3dfefSJiri Kosina #include <asm/unaligned.h>
246db3dfefSJiri Kosina #include <asm/byteorder.h>
256db3dfefSJiri Kosina #include <linux/input.h>
266db3dfefSJiri Kosina #include <linux/wait.h>
270361a28dSOliver Neukum #include <linux/workqueue.h>
28dc3c78e4SSimon Haggett #include <linux/string.h>
296db3dfefSJiri Kosina 
306db3dfefSJiri Kosina #include <linux/usb.h>
316db3dfefSJiri Kosina 
326db3dfefSJiri Kosina #include <linux/hid.h>
336db3dfefSJiri Kosina #include <linux/hiddev.h>
346db3dfefSJiri Kosina #include <linux/hid-debug.h>
3586166b7bSJiri Kosina #include <linux/hidraw.h>
366db3dfefSJiri Kosina #include "usbhid.h"
376db3dfefSJiri Kosina 
386db3dfefSJiri Kosina /*
396db3dfefSJiri Kosina  * Version Information
406db3dfefSJiri Kosina  */
416db3dfefSJiri Kosina 
426db3dfefSJiri Kosina #define DRIVER_DESC "USB HID core driver"
436db3dfefSJiri Kosina 
446db3dfefSJiri Kosina /*
456db3dfefSJiri Kosina  * Module parameters.
466db3dfefSJiri Kosina  */
476db3dfefSJiri Kosina 
486db3dfefSJiri Kosina static unsigned int hid_mousepoll_interval;
496db3dfefSJiri Kosina module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
506db3dfefSJiri Kosina MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
516db3dfefSJiri Kosina 
52933bfe4dSTobias Jakobi static unsigned int hid_jspoll_interval;
53933bfe4dSTobias Jakobi module_param_named(jspoll, hid_jspoll_interval, uint, 0644);
54933bfe4dSTobias Jakobi MODULE_PARM_DESC(jspoll, "Polling interval of joysticks");
55933bfe4dSTobias Jakobi 
562ddc8e2dSFilip Alac static unsigned int hid_kbpoll_interval;
572ddc8e2dSFilip Alac module_param_named(kbpoll, hid_kbpoll_interval, uint, 0644);
582ddc8e2dSFilip Alac MODULE_PARM_DESC(kbpoll, "Polling interval of keyboards");
592ddc8e2dSFilip Alac 
600361a28dSOliver Neukum static unsigned int ignoreled;
610361a28dSOliver Neukum module_param_named(ignoreled, ignoreled, uint, 0644);
620361a28dSOliver Neukum MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds");
630361a28dSOliver Neukum 
64876b9276SPaul Walmsley /* Quirks specified at module load time */
6581ba9926SMathias Krause static char *quirks_param[MAX_USBHID_BOOT_QUIRKS];
66876b9276SPaul Walmsley module_param_array_named(quirks, quirks_param, charp, NULL, 0444);
67876b9276SPaul Walmsley MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
68876b9276SPaul Walmsley 		" quirks=vendorID:productID:quirks"
69876b9276SPaul Walmsley 		" where vendorID, productID, and quirks are all in"
70876b9276SPaul Walmsley 		" 0x-prefixed hex");
716db3dfefSJiri Kosina /*
726db3dfefSJiri Kosina  * Input submission and I/O error handler.
736db3dfefSJiri Kosina  */
746db3dfefSJiri Kosina static void hid_io_error(struct hid_device *hid);
750361a28dSOliver Neukum static int hid_submit_out(struct hid_device *hid);
760361a28dSOliver Neukum static int hid_submit_ctrl(struct hid_device *hid);
770361a28dSOliver Neukum static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid);
786db3dfefSJiri Kosina 
796db3dfefSJiri Kosina /* Start up the input URB */
hid_start_in(struct hid_device * hid)806db3dfefSJiri Kosina static int hid_start_in(struct hid_device *hid)
816db3dfefSJiri Kosina {
826db3dfefSJiri Kosina 	unsigned long flags;
836db3dfefSJiri Kosina 	int rc = 0;
846db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
856db3dfefSJiri Kosina 
860361a28dSOliver Neukum 	spin_lock_irqsave(&usbhid->lock, flags);
8728cbc863SDmitry Torokhov 	if (test_bit(HID_IN_POLLING, &usbhid->iofl) &&
8869626f23SOliver Neukum 	    !test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
89f2b5264dSAlan Stern 	    !test_bit(HID_SUSPENDED, &usbhid->iofl) &&
906db3dfefSJiri Kosina 	    !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
916db3dfefSJiri Kosina 		rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
92a8c52b66SOliver Neukum 		if (rc != 0) {
936db3dfefSJiri Kosina 			clear_bit(HID_IN_RUNNING, &usbhid->iofl);
94a8c52b66SOliver Neukum 			if (rc == -ENOSPC)
95a8c52b66SOliver Neukum 				set_bit(HID_NO_BANDWIDTH, &usbhid->iofl);
96a8c52b66SOliver Neukum 		} else {
97a8c52b66SOliver Neukum 			clear_bit(HID_NO_BANDWIDTH, &usbhid->iofl);
98a8c52b66SOliver Neukum 		}
996db3dfefSJiri Kosina 	}
1000361a28dSOliver Neukum 	spin_unlock_irqrestore(&usbhid->lock, flags);
1016db3dfefSJiri Kosina 	return rc;
1026db3dfefSJiri Kosina }
1036db3dfefSJiri Kosina 
1046db3dfefSJiri Kosina /* I/O retry timer routine */
hid_retry_timeout(struct timer_list * t)1050ee32774SKees Cook static void hid_retry_timeout(struct timer_list *t)
1066db3dfefSJiri Kosina {
1070ee32774SKees Cook 	struct usbhid_device *usbhid = from_timer(usbhid, t, io_retry);
1080ee32774SKees Cook 	struct hid_device *hid = usbhid->hid;
1096db3dfefSJiri Kosina 
1106db3dfefSJiri Kosina 	dev_dbg(&usbhid->intf->dev, "retrying intr urb\n");
1116db3dfefSJiri Kosina 	if (hid_start_in(hid))
1126db3dfefSJiri Kosina 		hid_io_error(hid);
1136db3dfefSJiri Kosina }
1146db3dfefSJiri Kosina 
1156db3dfefSJiri Kosina /* Workqueue routine to reset the device or clear a halt */
hid_reset(struct work_struct * work)1166db3dfefSJiri Kosina static void hid_reset(struct work_struct *work)
1176db3dfefSJiri Kosina {
1186db3dfefSJiri Kosina 	struct usbhid_device *usbhid =
1196db3dfefSJiri Kosina 		container_of(work, struct usbhid_device, reset_work);
1206db3dfefSJiri Kosina 	struct hid_device *hid = usbhid->hid;
1218f507ef5SAlan Stern 	int rc;
1226db3dfefSJiri Kosina 
1236db3dfefSJiri Kosina 	if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) {
1246db3dfefSJiri Kosina 		dev_dbg(&usbhid->intf->dev, "clear halt\n");
1256db3dfefSJiri Kosina 		rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe);
1266db3dfefSJiri Kosina 		clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
127011b15dfSAlan Stern 		if (rc == 0) {
1288f507ef5SAlan Stern 			hid_start_in(hid);
1298f507ef5SAlan Stern 		} else {
1308f507ef5SAlan Stern 			dev_dbg(&usbhid->intf->dev,
1318f507ef5SAlan Stern 					"clear-halt failed: %d\n", rc);
1328f507ef5SAlan Stern 			set_bit(HID_RESET_PENDING, &usbhid->iofl);
1336db3dfefSJiri Kosina 		}
1346db3dfefSJiri Kosina 	}
1356db3dfefSJiri Kosina 
1368f507ef5SAlan Stern 	if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) {
1378f507ef5SAlan Stern 		dev_dbg(&usbhid->intf->dev, "resetting device\n");
1388f507ef5SAlan Stern 		usb_queue_reset_device(usbhid->intf);
1396db3dfefSJiri Kosina 	}
1406db3dfefSJiri Kosina }
1416db3dfefSJiri Kosina 
1426db3dfefSJiri Kosina /* Main I/O error handler */
hid_io_error(struct hid_device * hid)1436db3dfefSJiri Kosina static void hid_io_error(struct hid_device *hid)
1446db3dfefSJiri Kosina {
1456db3dfefSJiri Kosina 	unsigned long flags;
1466db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
1476db3dfefSJiri Kosina 
1480361a28dSOliver Neukum 	spin_lock_irqsave(&usbhid->lock, flags);
1496db3dfefSJiri Kosina 
1506db3dfefSJiri Kosina 	/* Stop when disconnected */
15169626f23SOliver Neukum 	if (test_bit(HID_DISCONNECTED, &usbhid->iofl))
1526db3dfefSJiri Kosina 		goto done;
1536db3dfefSJiri Kosina 
1545e2a55f2SAlan Stern 	/* If it has been a while since the last error, we'll assume
1555e2a55f2SAlan Stern 	 * this a brand new error and reset the retry timeout. */
1565e2a55f2SAlan Stern 	if (time_after(jiffies, usbhid->stop_retry + HZ/2))
1575e2a55f2SAlan Stern 		usbhid->retry_delay = 0;
1585e2a55f2SAlan Stern 
1596db3dfefSJiri Kosina 	/* When an error occurs, retry at increasing intervals */
1606db3dfefSJiri Kosina 	if (usbhid->retry_delay == 0) {
1616db3dfefSJiri Kosina 		usbhid->retry_delay = 13;	/* Then 26, 52, 104, 104, ... */
1626db3dfefSJiri Kosina 		usbhid->stop_retry = jiffies + msecs_to_jiffies(1000);
1636db3dfefSJiri Kosina 	} else if (usbhid->retry_delay < 100)
1646db3dfefSJiri Kosina 		usbhid->retry_delay *= 2;
1656db3dfefSJiri Kosina 
1666db3dfefSJiri Kosina 	if (time_after(jiffies, usbhid->stop_retry)) {
1676db3dfefSJiri Kosina 
168a8c52b66SOliver Neukum 		/* Retries failed, so do a port reset unless we lack bandwidth*/
1693af4e5a9SDon Zickus 		if (!test_bit(HID_NO_BANDWIDTH, &usbhid->iofl)
170a8c52b66SOliver Neukum 		     && !test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) {
171a8c52b66SOliver Neukum 
1726db3dfefSJiri Kosina 			schedule_work(&usbhid->reset_work);
1736db3dfefSJiri Kosina 			goto done;
1746db3dfefSJiri Kosina 		}
1756db3dfefSJiri Kosina 	}
1766db3dfefSJiri Kosina 
1776db3dfefSJiri Kosina 	mod_timer(&usbhid->io_retry,
1786db3dfefSJiri Kosina 			jiffies + msecs_to_jiffies(usbhid->retry_delay));
1796db3dfefSJiri Kosina done:
1800361a28dSOliver Neukum 	spin_unlock_irqrestore(&usbhid->lock, flags);
1810361a28dSOliver Neukum }
1820361a28dSOliver Neukum 
usbhid_mark_busy(struct usbhid_device * usbhid)1830361a28dSOliver Neukum static void usbhid_mark_busy(struct usbhid_device *usbhid)
1840361a28dSOliver Neukum {
1850361a28dSOliver Neukum 	struct usb_interface *intf = usbhid->intf;
1860361a28dSOliver Neukum 
1870361a28dSOliver Neukum 	usb_mark_last_busy(interface_to_usbdev(intf));
1880361a28dSOliver Neukum }
1890361a28dSOliver Neukum 
usbhid_restart_out_queue(struct usbhid_device * usbhid)1900361a28dSOliver Neukum static int usbhid_restart_out_queue(struct usbhid_device *usbhid)
1910361a28dSOliver Neukum {
1920361a28dSOliver Neukum 	struct hid_device *hid = usb_get_intfdata(usbhid->intf);
1930361a28dSOliver Neukum 	int kicked;
194f0befcd6SDaniel Kurtz 	int r;
1950361a28dSOliver Neukum 
196d4150c8fSAlan Stern 	if (!hid || test_bit(HID_RESET_PENDING, &usbhid->iofl) ||
197d4150c8fSAlan Stern 			test_bit(HID_SUSPENDED, &usbhid->iofl))
1980361a28dSOliver Neukum 		return 0;
1990361a28dSOliver Neukum 
2000361a28dSOliver Neukum 	if ((kicked = (usbhid->outhead != usbhid->outtail))) {
2016cc203d7SGreg Kroah-Hartman 		hid_dbg(hid, "Kicking head %d tail %d", usbhid->outhead, usbhid->outtail);
202f0befcd6SDaniel Kurtz 
20301a7c984SAlan Stern 		/* Try to wake up from autosuspend... */
204f0befcd6SDaniel Kurtz 		r = usb_autopm_get_interface_async(usbhid->intf);
205f0befcd6SDaniel Kurtz 		if (r < 0)
206f0befcd6SDaniel Kurtz 			return r;
20701a7c984SAlan Stern 
20801a7c984SAlan Stern 		/*
20901a7c984SAlan Stern 		 * If still suspended, don't submit.  Submission will
21001a7c984SAlan Stern 		 * occur if/when resume drains the queue.
21101a7c984SAlan Stern 		 */
212f2b5264dSAlan Stern 		if (test_bit(HID_SUSPENDED, &usbhid->iofl)) {
21301a7c984SAlan Stern 			usb_autopm_put_interface_no_suspend(usbhid->intf);
21401a7c984SAlan Stern 			return r;
21501a7c984SAlan Stern 		}
21601a7c984SAlan Stern 
217f0befcd6SDaniel Kurtz 		/* Asynchronously flush queue. */
218f0befcd6SDaniel Kurtz 		set_bit(HID_OUT_RUNNING, &usbhid->iofl);
2190361a28dSOliver Neukum 		if (hid_submit_out(hid)) {
2200361a28dSOliver Neukum 			clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
221f0befcd6SDaniel Kurtz 			usb_autopm_put_interface_async(usbhid->intf);
2220361a28dSOliver Neukum 		}
223f0befcd6SDaniel Kurtz 		wake_up(&usbhid->wait);
2240361a28dSOliver Neukum 	}
2250361a28dSOliver Neukum 	return kicked;
2260361a28dSOliver Neukum }
2270361a28dSOliver Neukum 
usbhid_restart_ctrl_queue(struct usbhid_device * usbhid)2280361a28dSOliver Neukum static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid)
2290361a28dSOliver Neukum {
2300361a28dSOliver Neukum 	struct hid_device *hid = usb_get_intfdata(usbhid->intf);
2310361a28dSOliver Neukum 	int kicked;
232f0befcd6SDaniel Kurtz 	int r;
2330361a28dSOliver Neukum 
2340361a28dSOliver Neukum 	WARN_ON(hid == NULL);
235d4150c8fSAlan Stern 	if (!hid || test_bit(HID_RESET_PENDING, &usbhid->iofl) ||
236d4150c8fSAlan Stern 			test_bit(HID_SUSPENDED, &usbhid->iofl))
2370361a28dSOliver Neukum 		return 0;
2380361a28dSOliver Neukum 
2390361a28dSOliver Neukum 	if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) {
2406cc203d7SGreg Kroah-Hartman 		hid_dbg(hid, "Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail);
241f0befcd6SDaniel Kurtz 
24201a7c984SAlan Stern 		/* Try to wake up from autosuspend... */
243f0befcd6SDaniel Kurtz 		r = usb_autopm_get_interface_async(usbhid->intf);
244f0befcd6SDaniel Kurtz 		if (r < 0)
245f0befcd6SDaniel Kurtz 			return r;
24601a7c984SAlan Stern 
24701a7c984SAlan Stern 		/*
24801a7c984SAlan Stern 		 * If still suspended, don't submit.  Submission will
24901a7c984SAlan Stern 		 * occur if/when resume drains the queue.
25001a7c984SAlan Stern 		 */
251f2b5264dSAlan Stern 		if (test_bit(HID_SUSPENDED, &usbhid->iofl)) {
25201a7c984SAlan Stern 			usb_autopm_put_interface_no_suspend(usbhid->intf);
25301a7c984SAlan Stern 			return r;
25401a7c984SAlan Stern 		}
25501a7c984SAlan Stern 
256f0befcd6SDaniel Kurtz 		/* Asynchronously flush queue. */
257f0befcd6SDaniel Kurtz 		set_bit(HID_CTRL_RUNNING, &usbhid->iofl);
2580361a28dSOliver Neukum 		if (hid_submit_ctrl(hid)) {
2590361a28dSOliver Neukum 			clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
260f0befcd6SDaniel Kurtz 			usb_autopm_put_interface_async(usbhid->intf);
2610361a28dSOliver Neukum 		}
262f0befcd6SDaniel Kurtz 		wake_up(&usbhid->wait);
2630361a28dSOliver Neukum 	}
2640361a28dSOliver Neukum 	return kicked;
2656db3dfefSJiri Kosina }
2666db3dfefSJiri Kosina 
2676db3dfefSJiri Kosina /*
2686db3dfefSJiri Kosina  * Input interrupt completion handler.
2696db3dfefSJiri Kosina  */
2706db3dfefSJiri Kosina 
hid_irq_in(struct urb * urb)2716db3dfefSJiri Kosina static void hid_irq_in(struct urb *urb)
2726db3dfefSJiri Kosina {
2736db3dfefSJiri Kosina 	struct hid_device	*hid = urb->context;
2746db3dfefSJiri Kosina 	struct usbhid_device	*usbhid = hid->driver_data;
2756db3dfefSJiri Kosina 	int			status;
2766db3dfefSJiri Kosina 
2776db3dfefSJiri Kosina 	switch (urb->status) {
2786db3dfefSJiri Kosina 	case 0:			/* success */
2796db3dfefSJiri Kosina 		usbhid->retry_delay = 0;
28028cbc863SDmitry Torokhov 		if (!test_bit(HID_OPENED, &usbhid->iofl))
2810b750b3bSJohan Hovold 			break;
282cc8a9d79SOliver Neukum 		usbhid_mark_busy(usbhid);
2835b0545dcSJiri Kosina 		if (!test_bit(HID_RESUME_RUNNING, &usbhid->iofl)) {
2846db3dfefSJiri Kosina 			hid_input_report(urb->context, HID_INPUT_REPORT,
2855b0545dcSJiri Kosina 					 urb->transfer_buffer,
2865b0545dcSJiri Kosina 					 urb->actual_length, 1);
2870361a28dSOliver Neukum 			/*
2880361a28dSOliver Neukum 			 * autosuspend refused while keys are pressed
2890361a28dSOliver Neukum 			 * because most keyboards don't wake up when
2900361a28dSOliver Neukum 			 * a key is released
2910361a28dSOliver Neukum 			 */
2920361a28dSOliver Neukum 			if (hid_check_keys_pressed(hid))
2930361a28dSOliver Neukum 				set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
2940361a28dSOliver Neukum 			else
2950361a28dSOliver Neukum 				clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
2965b0545dcSJiri Kosina 		}
2976db3dfefSJiri Kosina 		break;
2986db3dfefSJiri Kosina 	case -EPIPE:		/* stall */
2990361a28dSOliver Neukum 		usbhid_mark_busy(usbhid);
3006db3dfefSJiri Kosina 		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
3016db3dfefSJiri Kosina 		set_bit(HID_CLEAR_HALT, &usbhid->iofl);
3026db3dfefSJiri Kosina 		schedule_work(&usbhid->reset_work);
3036db3dfefSJiri Kosina 		return;
3046db3dfefSJiri Kosina 	case -ECONNRESET:	/* unlink */
3056db3dfefSJiri Kosina 	case -ENOENT:
3066db3dfefSJiri Kosina 	case -ESHUTDOWN:	/* unplug */
3076db3dfefSJiri Kosina 		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
3086db3dfefSJiri Kosina 		return;
3096db3dfefSJiri Kosina 	case -EILSEQ:		/* protocol error or unplug */
3106db3dfefSJiri Kosina 	case -EPROTO:		/* protocol error or unplug */
3116db3dfefSJiri Kosina 	case -ETIME:		/* protocol error or unplug */
3126db3dfefSJiri Kosina 	case -ETIMEDOUT:	/* Should never happen, but... */
3130361a28dSOliver Neukum 		usbhid_mark_busy(usbhid);
3146db3dfefSJiri Kosina 		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
3156db3dfefSJiri Kosina 		hid_io_error(hid);
3166db3dfefSJiri Kosina 		return;
3176db3dfefSJiri Kosina 	default:		/* error */
3184291ee30SJoe Perches 		hid_warn(urb->dev, "input irq status %d received\n",
3194291ee30SJoe Perches 			 urb->status);
3206db3dfefSJiri Kosina 	}
3216db3dfefSJiri Kosina 
3226db3dfefSJiri Kosina 	status = usb_submit_urb(urb, GFP_ATOMIC);
3236db3dfefSJiri Kosina 	if (status) {
3246db3dfefSJiri Kosina 		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
3256db3dfefSJiri Kosina 		if (status != -EPERM) {
3264291ee30SJoe Perches 			hid_err(hid, "can't resubmit intr, %s-%s/input%d, status %d\n",
3276db3dfefSJiri Kosina 				hid_to_usb_dev(hid)->bus->bus_name,
3286db3dfefSJiri Kosina 				hid_to_usb_dev(hid)->devpath,
3296db3dfefSJiri Kosina 				usbhid->ifnum, status);
3306db3dfefSJiri Kosina 			hid_io_error(hid);
3316db3dfefSJiri Kosina 		}
3326db3dfefSJiri Kosina 	}
3336db3dfefSJiri Kosina }
3346db3dfefSJiri Kosina 
hid_submit_out(struct hid_device * hid)3356db3dfefSJiri Kosina static int hid_submit_out(struct hid_device *hid)
3366db3dfefSJiri Kosina {
3376db3dfefSJiri Kosina 	struct hid_report *report;
338f129ea6dSAnssi Hannula 	char *raw_report;
3396db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
34068229689SOliver Neukum 	int r;
3416db3dfefSJiri Kosina 
342f129ea6dSAnssi Hannula 	report = usbhid->out[usbhid->outtail].report;
343f129ea6dSAnssi Hannula 	raw_report = usbhid->out[usbhid->outtail].raw_report;
3446db3dfefSJiri Kosina 
345dabb05c6SMathieu Magnaudet 	usbhid->urbout->transfer_buffer_length = hid_report_len(report);
3466db3dfefSJiri Kosina 	usbhid->urbout->dev = hid_to_usb_dev(hid);
347668160e5SAlan Stern 	if (raw_report) {
348f0befcd6SDaniel Kurtz 		memcpy(usbhid->outbuf, raw_report,
349f0befcd6SDaniel Kurtz 				usbhid->urbout->transfer_buffer_length);
350f129ea6dSAnssi Hannula 		kfree(raw_report);
351668160e5SAlan Stern 		usbhid->out[usbhid->outtail].raw_report = NULL;
352668160e5SAlan Stern 	}
3536db3dfefSJiri Kosina 
35458037eb9SJiri Kosina 	dbg_hid("submitting out urb\n");
3556db3dfefSJiri Kosina 
356f0befcd6SDaniel Kurtz 	r = usb_submit_urb(usbhid->urbout, GFP_ATOMIC);
357f0befcd6SDaniel Kurtz 	if (r < 0) {
358f0befcd6SDaniel Kurtz 		hid_err(hid, "usb_submit_urb(out) failed: %d\n", r);
359f0befcd6SDaniel Kurtz 		return r;
3606db3dfefSJiri Kosina 	}
361858155fbSOliver Neukum 	usbhid->last_out = jiffies;
3626db3dfefSJiri Kosina 	return 0;
3636db3dfefSJiri Kosina }
3646db3dfefSJiri Kosina 
hid_submit_ctrl(struct hid_device * hid)3656db3dfefSJiri Kosina static int hid_submit_ctrl(struct hid_device *hid)
3666db3dfefSJiri Kosina {
3676db3dfefSJiri Kosina 	struct hid_report *report;
3686db3dfefSJiri Kosina 	unsigned char dir;
369f129ea6dSAnssi Hannula 	char *raw_report;
37068229689SOliver Neukum 	int len, r;
3716db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
3726db3dfefSJiri Kosina 
3736db3dfefSJiri Kosina 	report = usbhid->ctrl[usbhid->ctrltail].report;
374f129ea6dSAnssi Hannula 	raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
3756db3dfefSJiri Kosina 	dir = usbhid->ctrl[usbhid->ctrltail].dir;
3766db3dfefSJiri Kosina 
3776be388f4SAnirudh Rayabharam 	len = hid_report_len(report);
3786db3dfefSJiri Kosina 	if (dir == USB_DIR_OUT) {
3796db3dfefSJiri Kosina 		usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
380668160e5SAlan Stern 		if (raw_report) {
381f129ea6dSAnssi Hannula 			memcpy(usbhid->ctrlbuf, raw_report, len);
382f129ea6dSAnssi Hannula 			kfree(raw_report);
383668160e5SAlan Stern 			usbhid->ctrl[usbhid->ctrltail].raw_report = NULL;
384668160e5SAlan Stern 		}
3856db3dfefSJiri Kosina 	} else {
3865049307dSMichal Kubecek 		int maxpacket;
3876db3dfefSJiri Kosina 
3886db3dfefSJiri Kosina 		usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
389f0befcd6SDaniel Kurtz 		maxpacket = usb_maxpacket(hid_to_usb_dev(hid),
390b45cde33SVincent Mailhol 					  usbhid->urbctrl->pipe);
3910a824efdSAlan Stern 		len += (len == 0);	/* Don't allow 0-length reports */
392d2f311ecSAlan Stern 		len = round_up(len, maxpacket);
3935049307dSMichal Kubecek 		if (len > usbhid->bufsize)
3945049307dSMichal Kubecek 			len = usbhid->bufsize;
3956db3dfefSJiri Kosina 	}
3965049307dSMichal Kubecek 	usbhid->urbctrl->transfer_buffer_length = len;
3976db3dfefSJiri Kosina 	usbhid->urbctrl->dev = hid_to_usb_dev(hid);
3986db3dfefSJiri Kosina 
3996db3dfefSJiri Kosina 	usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
400f0befcd6SDaniel Kurtz 	usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT :
401f0befcd6SDaniel Kurtz 						      HID_REQ_GET_REPORT;
402f0befcd6SDaniel Kurtz 	usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) |
403f0befcd6SDaniel Kurtz 					 report->id);
4046db3dfefSJiri Kosina 	usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
4056db3dfefSJiri Kosina 	usbhid->cr->wLength = cpu_to_le16(len);
4066db3dfefSJiri Kosina 
40758037eb9SJiri Kosina 	dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
408f0befcd6SDaniel Kurtz 		usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" :
409f0befcd6SDaniel Kurtz 							     "Get_Report",
4106db3dfefSJiri Kosina 		usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
4116db3dfefSJiri Kosina 
412f0befcd6SDaniel Kurtz 	r = usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC);
413f0befcd6SDaniel Kurtz 	if (r < 0) {
414f0befcd6SDaniel Kurtz 		hid_err(hid, "usb_submit_urb(ctrl) failed: %d\n", r);
415f0befcd6SDaniel Kurtz 		return r;
4166db3dfefSJiri Kosina 	}
417858155fbSOliver Neukum 	usbhid->last_ctrl = jiffies;
4186db3dfefSJiri Kosina 	return 0;
4196db3dfefSJiri Kosina }
4206db3dfefSJiri Kosina 
4216db3dfefSJiri Kosina /*
4226db3dfefSJiri Kosina  * Output interrupt completion handler.
4236db3dfefSJiri Kosina  */
4246db3dfefSJiri Kosina 
hid_irq_out(struct urb * urb)4256db3dfefSJiri Kosina static void hid_irq_out(struct urb *urb)
4266db3dfefSJiri Kosina {
4276db3dfefSJiri Kosina 	struct hid_device *hid = urb->context;
4286db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
4296db3dfefSJiri Kosina 	unsigned long flags;
4306db3dfefSJiri Kosina 	int unplug = 0;
4316db3dfefSJiri Kosina 
4326db3dfefSJiri Kosina 	switch (urb->status) {
4336db3dfefSJiri Kosina 	case 0:			/* success */
4346db3dfefSJiri Kosina 		break;
4356db3dfefSJiri Kosina 	case -ESHUTDOWN:	/* unplug */
4366db3dfefSJiri Kosina 		unplug = 1;
437cae96a5dSGustavo A. R. Silva 		break;
4386db3dfefSJiri Kosina 	case -EILSEQ:		/* protocol error or unplug */
4396db3dfefSJiri Kosina 	case -EPROTO:		/* protocol error or unplug */
4406db3dfefSJiri Kosina 	case -ECONNRESET:	/* unlink */
4416db3dfefSJiri Kosina 	case -ENOENT:
4426db3dfefSJiri Kosina 		break;
4436db3dfefSJiri Kosina 	default:		/* error */
4444291ee30SJoe Perches 		hid_warn(urb->dev, "output irq status %d received\n",
4454291ee30SJoe Perches 			 urb->status);
4466db3dfefSJiri Kosina 	}
4476db3dfefSJiri Kosina 
4480361a28dSOliver Neukum 	spin_lock_irqsave(&usbhid->lock, flags);
4496db3dfefSJiri Kosina 
45093101af3SAlan Stern 	if (unplug) {
4516db3dfefSJiri Kosina 		usbhid->outtail = usbhid->outhead;
45293101af3SAlan Stern 	} else {
4536db3dfefSJiri Kosina 		usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
4546db3dfefSJiri Kosina 
45593101af3SAlan Stern 		if (usbhid->outhead != usbhid->outtail &&
45693101af3SAlan Stern 				hid_submit_out(hid) == 0) {
457f0befcd6SDaniel Kurtz 			/* Successfully submitted next urb in queue */
4580361a28dSOliver Neukum 			spin_unlock_irqrestore(&usbhid->lock, flags);
4596db3dfefSJiri Kosina 			return;
4606db3dfefSJiri Kosina 		}
46193101af3SAlan Stern 	}
4626db3dfefSJiri Kosina 
4636db3dfefSJiri Kosina 	clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
4640361a28dSOliver Neukum 	spin_unlock_irqrestore(&usbhid->lock, flags);
46568229689SOliver Neukum 	usb_autopm_put_interface_async(usbhid->intf);
4661d1bdd20SJiri Slaby 	wake_up(&usbhid->wait);
4676db3dfefSJiri Kosina }
4686db3dfefSJiri Kosina 
4696db3dfefSJiri Kosina /*
4706db3dfefSJiri Kosina  * Control pipe completion handler.
4716db3dfefSJiri Kosina  */
4726db3dfefSJiri Kosina 
hid_ctrl(struct urb * urb)4736db3dfefSJiri Kosina static void hid_ctrl(struct urb *urb)
4746db3dfefSJiri Kosina {
4756db3dfefSJiri Kosina 	struct hid_device *hid = urb->context;
4766db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
477f49255e0SSebastian Andrzej Siewior 	unsigned long flags;
4780361a28dSOliver Neukum 	int unplug = 0, status = urb->status;
4796db3dfefSJiri Kosina 
4800361a28dSOliver Neukum 	switch (status) {
4816db3dfefSJiri Kosina 	case 0:			/* success */
4826db3dfefSJiri Kosina 		if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
483880d29f1SJiri Slaby 			hid_input_report(urb->context,
484880d29f1SJiri Slaby 				usbhid->ctrl[usbhid->ctrltail].report->type,
4856db3dfefSJiri Kosina 				urb->transfer_buffer, urb->actual_length, 0);
4866db3dfefSJiri Kosina 		break;
4876db3dfefSJiri Kosina 	case -ESHUTDOWN:	/* unplug */
4886db3dfefSJiri Kosina 		unplug = 1;
489cae96a5dSGustavo A. R. Silva 		break;
4906db3dfefSJiri Kosina 	case -EILSEQ:		/* protocol error or unplug */
4916db3dfefSJiri Kosina 	case -EPROTO:		/* protocol error or unplug */
4926db3dfefSJiri Kosina 	case -ECONNRESET:	/* unlink */
4936db3dfefSJiri Kosina 	case -ENOENT:
4946db3dfefSJiri Kosina 	case -EPIPE:		/* report not available */
4956db3dfefSJiri Kosina 		break;
4966db3dfefSJiri Kosina 	default:		/* error */
4974291ee30SJoe Perches 		hid_warn(urb->dev, "ctrl urb status %d received\n", status);
4986db3dfefSJiri Kosina 	}
4996db3dfefSJiri Kosina 
500f49255e0SSebastian Andrzej Siewior 	spin_lock_irqsave(&usbhid->lock, flags);
501e470127eSIoan-Adrian Ratiu 
50293101af3SAlan Stern 	if (unplug) {
5036db3dfefSJiri Kosina 		usbhid->ctrltail = usbhid->ctrlhead;
504f7744fa1SAnirudh Rayabharam 	} else if (usbhid->ctrlhead != usbhid->ctrltail) {
5056db3dfefSJiri Kosina 		usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
5066db3dfefSJiri Kosina 
50793101af3SAlan Stern 		if (usbhid->ctrlhead != usbhid->ctrltail &&
50893101af3SAlan Stern 				hid_submit_ctrl(hid) == 0) {
509f0befcd6SDaniel Kurtz 			/* Successfully submitted next urb in queue */
510f49255e0SSebastian Andrzej Siewior 			spin_unlock_irqrestore(&usbhid->lock, flags);
5116db3dfefSJiri Kosina 			return;
5126db3dfefSJiri Kosina 		}
51393101af3SAlan Stern 	}
5146db3dfefSJiri Kosina 
5156db3dfefSJiri Kosina 	clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
516f49255e0SSebastian Andrzej Siewior 	spin_unlock_irqrestore(&usbhid->lock, flags);
51768229689SOliver Neukum 	usb_autopm_put_interface_async(usbhid->intf);
5181d1bdd20SJiri Slaby 	wake_up(&usbhid->wait);
5196db3dfefSJiri Kosina }
5206db3dfefSJiri Kosina 
__usbhid_submit_report(struct hid_device * hid,struct hid_report * report,unsigned char dir)52152cfc61bSH Hartley Sweeten static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report,
52252cfc61bSH Hartley Sweeten 				   unsigned char dir)
5236db3dfefSJiri Kosina {
5246db3dfefSJiri Kosina 	int head;
5256db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
5266db3dfefSJiri Kosina 
52746df9dedSReyad Attiyat 	if (((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) ||
52846df9dedSReyad Attiyat 		test_bit(HID_DISCONNECTED, &usbhid->iofl))
5296db3dfefSJiri Kosina 		return;
5306db3dfefSJiri Kosina 
5316db3dfefSJiri Kosina 	if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
5326db3dfefSJiri Kosina 		if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) {
5334291ee30SJoe Perches 			hid_warn(hid, "output queue full\n");
5346db3dfefSJiri Kosina 			return;
5356db3dfefSJiri Kosina 		}
5366db3dfefSJiri Kosina 
53727ce4050SJiri Kosina 		usbhid->out[usbhid->outhead].raw_report = hid_alloc_report_buf(report, GFP_ATOMIC);
538f129ea6dSAnssi Hannula 		if (!usbhid->out[usbhid->outhead].raw_report) {
5394291ee30SJoe Perches 			hid_warn(hid, "output queueing failed\n");
540f129ea6dSAnssi Hannula 			return;
541f129ea6dSAnssi Hannula 		}
542f129ea6dSAnssi Hannula 		hid_output_report(report, usbhid->out[usbhid->outhead].raw_report);
543f129ea6dSAnssi Hannula 		usbhid->out[usbhid->outhead].report = report;
5446db3dfefSJiri Kosina 		usbhid->outhead = head;
5456db3dfefSJiri Kosina 
54601a7c984SAlan Stern 		/* If the queue isn't running, restart it */
54701a7c984SAlan Stern 		if (!test_bit(HID_OUT_RUNNING, &usbhid->iofl)) {
54801a7c984SAlan Stern 			usbhid_restart_out_queue(usbhid);
54901a7c984SAlan Stern 
55001a7c984SAlan Stern 		/* Otherwise see if an earlier request has timed out */
55101a7c984SAlan Stern 		} else if (time_after(jiffies, usbhid->last_out + HZ * 5)) {
55201a7c984SAlan Stern 
55301a7c984SAlan Stern 			/* Prevent autosuspend following the unlink */
55401a7c984SAlan Stern 			usb_autopm_get_interface_no_resume(usbhid->intf);
555f0befcd6SDaniel Kurtz 
556f0befcd6SDaniel Kurtz 			/*
55701a7c984SAlan Stern 			 * Prevent resubmission in case the URB completes
55801a7c984SAlan Stern 			 * before we can unlink it.  We don't want to cancel
55901a7c984SAlan Stern 			 * the wrong transfer!
560f0befcd6SDaniel Kurtz 			 */
5618815bb09SOliver Neukum 			usb_block_urb(usbhid->urbout);
56201a7c984SAlan Stern 
56301a7c984SAlan Stern 			/* Drop lock to avoid deadlock if the callback runs */
5648815bb09SOliver Neukum 			spin_unlock(&usbhid->lock);
56501a7c984SAlan Stern 
566858155fbSOliver Neukum 			usb_unlink_urb(usbhid->urbout);
5678815bb09SOliver Neukum 			spin_lock(&usbhid->lock);
5688815bb09SOliver Neukum 			usb_unblock_urb(usbhid->urbout);
56901a7c984SAlan Stern 
57001a7c984SAlan Stern 			/* Unlink might have stopped the queue */
5718815bb09SOliver Neukum 			if (!test_bit(HID_OUT_RUNNING, &usbhid->iofl))
57201a7c984SAlan Stern 				usbhid_restart_out_queue(usbhid);
5738815bb09SOliver Neukum 
57401a7c984SAlan Stern 			/* Now we can allow autosuspend again */
57501a7c984SAlan Stern 			usb_autopm_put_interface_async(usbhid->intf);
576858155fbSOliver Neukum 		}
5776db3dfefSJiri Kosina 		return;
5786db3dfefSJiri Kosina 	}
5796db3dfefSJiri Kosina 
5806db3dfefSJiri Kosina 	if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) {
5814291ee30SJoe Perches 		hid_warn(hid, "control queue full\n");
5826db3dfefSJiri Kosina 		return;
5836db3dfefSJiri Kosina 	}
5846db3dfefSJiri Kosina 
585f129ea6dSAnssi Hannula 	if (dir == USB_DIR_OUT) {
58627ce4050SJiri Kosina 		usbhid->ctrl[usbhid->ctrlhead].raw_report = hid_alloc_report_buf(report, GFP_ATOMIC);
587f129ea6dSAnssi Hannula 		if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
5884291ee30SJoe Perches 			hid_warn(hid, "control queueing failed\n");
589f129ea6dSAnssi Hannula 			return;
590f129ea6dSAnssi Hannula 		}
591f129ea6dSAnssi Hannula 		hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report);
592f129ea6dSAnssi Hannula 	}
5936db3dfefSJiri Kosina 	usbhid->ctrl[usbhid->ctrlhead].report = report;
5946db3dfefSJiri Kosina 	usbhid->ctrl[usbhid->ctrlhead].dir = dir;
5956db3dfefSJiri Kosina 	usbhid->ctrlhead = head;
5966db3dfefSJiri Kosina 
59701a7c984SAlan Stern 	/* If the queue isn't running, restart it */
59801a7c984SAlan Stern 	if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl)) {
59901a7c984SAlan Stern 		usbhid_restart_ctrl_queue(usbhid);
60001a7c984SAlan Stern 
60101a7c984SAlan Stern 	/* Otherwise see if an earlier request has timed out */
60201a7c984SAlan Stern 	} else if (time_after(jiffies, usbhid->last_ctrl + HZ * 5)) {
60301a7c984SAlan Stern 
60401a7c984SAlan Stern 		/* Prevent autosuspend following the unlink */
60501a7c984SAlan Stern 		usb_autopm_get_interface_no_resume(usbhid->intf);
606f0befcd6SDaniel Kurtz 
607f0befcd6SDaniel Kurtz 		/*
60801a7c984SAlan Stern 		 * Prevent resubmission in case the URB completes
60901a7c984SAlan Stern 		 * before we can unlink it.  We don't want to cancel
61001a7c984SAlan Stern 		 * the wrong transfer!
611f0befcd6SDaniel Kurtz 		 */
6128815bb09SOliver Neukum 		usb_block_urb(usbhid->urbctrl);
61301a7c984SAlan Stern 
61401a7c984SAlan Stern 		/* Drop lock to avoid deadlock if the callback runs */
6158815bb09SOliver Neukum 		spin_unlock(&usbhid->lock);
61601a7c984SAlan Stern 
617858155fbSOliver Neukum 		usb_unlink_urb(usbhid->urbctrl);
6188815bb09SOliver Neukum 		spin_lock(&usbhid->lock);
6198815bb09SOliver Neukum 		usb_unblock_urb(usbhid->urbctrl);
62001a7c984SAlan Stern 
62101a7c984SAlan Stern 		/* Unlink might have stopped the queue */
6228815bb09SOliver Neukum 		if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
62301a7c984SAlan Stern 			usbhid_restart_ctrl_queue(usbhid);
62401a7c984SAlan Stern 
62501a7c984SAlan Stern 		/* Now we can allow autosuspend again */
62601a7c984SAlan Stern 		usb_autopm_put_interface_async(usbhid->intf);
627858155fbSOliver Neukum 	}
6280361a28dSOliver Neukum }
6296db3dfefSJiri Kosina 
usbhid_submit_report(struct hid_device * hid,struct hid_report * report,unsigned char dir)630d8814272SBenjamin Tissoires static void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
6310361a28dSOliver Neukum {
6320361a28dSOliver Neukum 	struct usbhid_device *usbhid = hid->driver_data;
6330361a28dSOliver Neukum 	unsigned long flags;
6340361a28dSOliver Neukum 
6350361a28dSOliver Neukum 	spin_lock_irqsave(&usbhid->lock, flags);
6360361a28dSOliver Neukum 	__usbhid_submit_report(hid, report, dir);
6370361a28dSOliver Neukum 	spin_unlock_irqrestore(&usbhid->lock, flags);
6386db3dfefSJiri Kosina }
6396db3dfefSJiri Kosina 
usbhid_wait_io(struct hid_device * hid)640b7966a4dSBenjamin Tissoires static int usbhid_wait_io(struct hid_device *hid)
6416db3dfefSJiri Kosina {
6426db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
6436db3dfefSJiri Kosina 
6441d1bdd20SJiri Slaby 	if (!wait_event_timeout(usbhid->wait,
6451d1bdd20SJiri Slaby 				(!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) &&
6466db3dfefSJiri Kosina 				!test_bit(HID_OUT_RUNNING, &usbhid->iofl)),
6476db3dfefSJiri Kosina 					10*HZ)) {
64858037eb9SJiri Kosina 		dbg_hid("timeout waiting for ctrl or out queue to clear\n");
6496db3dfefSJiri Kosina 		return -1;
6506db3dfefSJiri Kosina 	}
6516db3dfefSJiri Kosina 
6526db3dfefSJiri Kosina 	return 0;
6536db3dfefSJiri Kosina }
6546db3dfefSJiri Kosina 
hid_set_idle(struct usb_device * dev,int ifnum,int report,int idle)6556db3dfefSJiri Kosina static int hid_set_idle(struct usb_device *dev, int ifnum, int report, int idle)
6566db3dfefSJiri Kosina {
6576db3dfefSJiri Kosina 	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
6586db3dfefSJiri Kosina 		HID_REQ_SET_IDLE, USB_TYPE_CLASS | USB_RECIP_INTERFACE, (idle << 8) | report,
6596db3dfefSJiri Kosina 		ifnum, NULL, 0, USB_CTRL_SET_TIMEOUT);
6606db3dfefSJiri Kosina }
6616db3dfefSJiri Kosina 
hid_get_class_descriptor(struct usb_device * dev,int ifnum,unsigned char type,void * buf,int size)6626db3dfefSJiri Kosina static int hid_get_class_descriptor(struct usb_device *dev, int ifnum,
6636db3dfefSJiri Kosina 		unsigned char type, void *buf, int size)
6646db3dfefSJiri Kosina {
6656db3dfefSJiri Kosina 	int result, retries = 4;
6666db3dfefSJiri Kosina 
6676db3dfefSJiri Kosina 	memset(buf, 0, size);
6686db3dfefSJiri Kosina 
6696db3dfefSJiri Kosina 	do {
6706db3dfefSJiri Kosina 		result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
6716db3dfefSJiri Kosina 				USB_REQ_GET_DESCRIPTOR, USB_RECIP_INTERFACE | USB_DIR_IN,
6726db3dfefSJiri Kosina 				(type << 8), ifnum, buf, size, USB_CTRL_GET_TIMEOUT);
6736db3dfefSJiri Kosina 		retries--;
6746db3dfefSJiri Kosina 	} while (result < size && retries);
6756db3dfefSJiri Kosina 	return result;
6766db3dfefSJiri Kosina }
6776db3dfefSJiri Kosina 
usbhid_open(struct hid_device * hid)678d36b7d4cSDmitry Torokhov static int usbhid_open(struct hid_device *hid)
6796db3dfefSJiri Kosina {
680933e3187SOliver Neukum 	struct usbhid_device *usbhid = hid->driver_data;
681e399396aSDmitry Torokhov 	int res;
682933e3187SOliver Neukum 
6830ed08fadSAlan Stern 	mutex_lock(&usbhid->mutex);
6840ed08fadSAlan Stern 
685cf601774SDmitry Torokhov 	set_bit(HID_OPENED, &usbhid->iofl);
686cf601774SDmitry Torokhov 
6870ed08fadSAlan Stern 	if (hid->quirks & HID_QUIRK_ALWAYS_POLL) {
6880ed08fadSAlan Stern 		res = 0;
6890ed08fadSAlan Stern 		goto Done;
6900ed08fadSAlan Stern 	}
691e399396aSDmitry Torokhov 
692933e3187SOliver Neukum 	res = usb_autopm_get_interface(usbhid->intf);
69368229689SOliver Neukum 	/* the device must be awake to reliably request remote wakeup */
694cf601774SDmitry Torokhov 	if (res < 0) {
695cf601774SDmitry Torokhov 		clear_bit(HID_OPENED, &usbhid->iofl);
6960ed08fadSAlan Stern 		res = -EIO;
6970ed08fadSAlan Stern 		goto Done;
698cf601774SDmitry Torokhov 	}
699e399396aSDmitry Torokhov 
7000361a28dSOliver Neukum 	usbhid->intf->needs_remote_wakeup = 1;
701e399396aSDmitry Torokhov 
702e399396aSDmitry Torokhov 	set_bit(HID_RESUME_RUNNING, &usbhid->iofl);
70328cbc863SDmitry Torokhov 	set_bit(HID_IN_POLLING, &usbhid->iofl);
704e399396aSDmitry Torokhov 
705a8c52b66SOliver Neukum 	res = hid_start_in(hid);
706a8c52b66SOliver Neukum 	if (res) {
707a8c52b66SOliver Neukum 		if (res != -ENOSPC) {
7086db3dfefSJiri Kosina 			hid_io_error(hid);
709a8c52b66SOliver Neukum 			res = 0;
710a8c52b66SOliver Neukum 		} else {
711a8c52b66SOliver Neukum 			/* no use opening if resources are insufficient */
712a8c52b66SOliver Neukum 			res = -EBUSY;
713e399396aSDmitry Torokhov 			clear_bit(HID_OPENED, &usbhid->iofl);
714e399396aSDmitry Torokhov 			clear_bit(HID_IN_POLLING, &usbhid->iofl);
715a8c52b66SOliver Neukum 			usbhid->intf->needs_remote_wakeup = 0;
716a8c52b66SOliver Neukum 		}
717a8c52b66SOliver Neukum 	}
718e399396aSDmitry Torokhov 
7190361a28dSOliver Neukum 	usb_autopm_put_interface(usbhid->intf);
720b905811aSBenjamin Tissoires 
7215b0545dcSJiri Kosina 	/*
7225b0545dcSJiri Kosina 	 * In case events are generated while nobody was listening,
7235b0545dcSJiri Kosina 	 * some are released when the device is re-opened.
7245b0545dcSJiri Kosina 	 * Wait 50 msec for the queue to empty before allowing events
7255b0545dcSJiri Kosina 	 * to go through hid.
7265b0545dcSJiri Kosina 	 */
7275b0545dcSJiri Kosina 	if (res == 0)
7285b0545dcSJiri Kosina 		msleep(50);
7295b0545dcSJiri Kosina 
7305b0545dcSJiri Kosina 	clear_bit(HID_RESUME_RUNNING, &usbhid->iofl);
7315b0545dcSJiri Kosina 
7320ed08fadSAlan Stern  Done:
7330ed08fadSAlan Stern 	mutex_unlock(&usbhid->mutex);
734a8c52b66SOliver Neukum 	return res;
7356db3dfefSJiri Kosina }
7366db3dfefSJiri Kosina 
usbhid_close(struct hid_device * hid)737d36b7d4cSDmitry Torokhov static void usbhid_close(struct hid_device *hid)
7386db3dfefSJiri Kosina {
7396db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
7406db3dfefSJiri Kosina 
7410ed08fadSAlan Stern 	mutex_lock(&usbhid->mutex);
7420ed08fadSAlan Stern 
743e399396aSDmitry Torokhov 	/*
744e399396aSDmitry Torokhov 	 * Make sure we don't restart data acquisition due to
745e399396aSDmitry Torokhov 	 * a resumption we no longer care about by avoiding racing
746e399396aSDmitry Torokhov 	 * with hid_start_in().
7470361a28dSOliver Neukum 	 */
7480361a28dSOliver Neukum 	spin_lock_irq(&usbhid->lock);
74928cbc863SDmitry Torokhov 	clear_bit(HID_OPENED, &usbhid->iofl);
750cf601774SDmitry Torokhov 	if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL))
751cf601774SDmitry Torokhov 		clear_bit(HID_IN_POLLING, &usbhid->iofl);
7520361a28dSOliver Neukum 	spin_unlock_irq(&usbhid->lock);
753e399396aSDmitry Torokhov 
7540ed08fadSAlan Stern 	if (!(hid->quirks & HID_QUIRK_ALWAYS_POLL)) {
75589092dddSOliver Neukum 		hid_cancel_delayed_stuff(usbhid);
7566db3dfefSJiri Kosina 		usb_kill_urb(usbhid->urbin);
7570361a28dSOliver Neukum 		usbhid->intf->needs_remote_wakeup = 0;
7580b750b3bSJohan Hovold 	}
7596db3dfefSJiri Kosina 
7600ed08fadSAlan Stern 	mutex_unlock(&usbhid->mutex);
7610ed08fadSAlan Stern }
7620ed08fadSAlan Stern 
7636db3dfefSJiri Kosina /*
7646db3dfefSJiri Kosina  * Initialize all reports
7656db3dfefSJiri Kosina  */
7666db3dfefSJiri Kosina 
usbhid_init_reports(struct hid_device * hid)7676db3dfefSJiri Kosina void usbhid_init_reports(struct hid_device *hid)
7686db3dfefSJiri Kosina {
7696db3dfefSJiri Kosina 	struct hid_report *report;
7706db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
771595e9276SBenjamin Tissoires 	struct hid_report_enum *report_enum;
7726db3dfefSJiri Kosina 	int err, ret;
7736db3dfefSJiri Kosina 
774595e9276SBenjamin Tissoires 	report_enum = &hid->report_enum[HID_INPUT_REPORT];
775595e9276SBenjamin Tissoires 	list_for_each_entry(report, &report_enum->report_list, list)
7766db3dfefSJiri Kosina 		usbhid_submit_report(hid, report, USB_DIR_IN);
7776db3dfefSJiri Kosina 
778595e9276SBenjamin Tissoires 	report_enum = &hid->report_enum[HID_FEATURE_REPORT];
779595e9276SBenjamin Tissoires 	list_for_each_entry(report, &report_enum->report_list, list)
7806db3dfefSJiri Kosina 		usbhid_submit_report(hid, report, USB_DIR_IN);
7816db3dfefSJiri Kosina 
7826db3dfefSJiri Kosina 	err = 0;
7836db3dfefSJiri Kosina 	ret = usbhid_wait_io(hid);
7846db3dfefSJiri Kosina 	while (ret) {
7856db3dfefSJiri Kosina 		err |= ret;
7866db3dfefSJiri Kosina 		if (test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
7876db3dfefSJiri Kosina 			usb_kill_urb(usbhid->urbctrl);
7886db3dfefSJiri Kosina 		if (test_bit(HID_OUT_RUNNING, &usbhid->iofl))
7896db3dfefSJiri Kosina 			usb_kill_urb(usbhid->urbout);
7906db3dfefSJiri Kosina 		ret = usbhid_wait_io(hid);
7916db3dfefSJiri Kosina 	}
7926db3dfefSJiri Kosina 
7936db3dfefSJiri Kosina 	if (err)
7944291ee30SJoe Perches 		hid_warn(hid, "timeout initializing reports\n");
7956db3dfefSJiri Kosina }
7966db3dfefSJiri Kosina 
7976db3dfefSJiri Kosina /*
798713c8aadSPete Zaitcev  * Reset LEDs which BIOS might have left on. For now, just NumLock (0x01).
799713c8aadSPete Zaitcev  */
hid_find_field_early(struct hid_device * hid,unsigned int page,unsigned int hid_code,struct hid_field ** pfield)800713c8aadSPete Zaitcev static int hid_find_field_early(struct hid_device *hid, unsigned int page,
801713c8aadSPete Zaitcev     unsigned int hid_code, struct hid_field **pfield)
802713c8aadSPete Zaitcev {
803713c8aadSPete Zaitcev 	struct hid_report *report;
804713c8aadSPete Zaitcev 	struct hid_field *field;
805713c8aadSPete Zaitcev 	struct hid_usage *usage;
806713c8aadSPete Zaitcev 	int i, j;
807713c8aadSPete Zaitcev 
808713c8aadSPete Zaitcev 	list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) {
809713c8aadSPete Zaitcev 		for (i = 0; i < report->maxfield; i++) {
810713c8aadSPete Zaitcev 			field = report->field[i];
811713c8aadSPete Zaitcev 			for (j = 0; j < field->maxusage; j++) {
812713c8aadSPete Zaitcev 				usage = &field->usage[j];
813713c8aadSPete Zaitcev 				if ((usage->hid & HID_USAGE_PAGE) == page &&
814713c8aadSPete Zaitcev 				    (usage->hid & 0xFFFF) == hid_code) {
815713c8aadSPete Zaitcev 					*pfield = field;
816713c8aadSPete Zaitcev 					return j;
817713c8aadSPete Zaitcev 				}
818713c8aadSPete Zaitcev 			}
819713c8aadSPete Zaitcev 		}
820713c8aadSPete Zaitcev 	}
821713c8aadSPete Zaitcev 	return -1;
822713c8aadSPete Zaitcev }
823713c8aadSPete Zaitcev 
usbhid_set_leds(struct hid_device * hid)824ddf64a3cSDavid Herrmann static void usbhid_set_leds(struct hid_device *hid)
825713c8aadSPete Zaitcev {
826713c8aadSPete Zaitcev 	struct hid_field *field;
827713c8aadSPete Zaitcev 	int offset;
828713c8aadSPete Zaitcev 
829713c8aadSPete Zaitcev 	if ((offset = hid_find_field_early(hid, HID_UP_LED, 0x01, &field)) != -1) {
830713c8aadSPete Zaitcev 		hid_set_field(field, offset, 0);
831713c8aadSPete Zaitcev 		usbhid_submit_report(hid, field->report, USB_DIR_OUT);
832713c8aadSPete Zaitcev 	}
833713c8aadSPete Zaitcev }
834713c8aadSPete Zaitcev 
835713c8aadSPete Zaitcev /*
8366db3dfefSJiri Kosina  * Traverse the supplied list of reports and find the longest
8376db3dfefSJiri Kosina  */
hid_find_max_report(struct hid_device * hid,unsigned int type,unsigned int * max)838282bfd4cSJiri Slaby static void hid_find_max_report(struct hid_device *hid, unsigned int type,
839282bfd4cSJiri Slaby 		unsigned int *max)
8406db3dfefSJiri Kosina {
8416db3dfefSJiri Kosina 	struct hid_report *report;
842282bfd4cSJiri Slaby 	unsigned int size;
8436db3dfefSJiri Kosina 
8446db3dfefSJiri Kosina 	list_for_each_entry(report, &hid->report_enum[type].report_list, list) {
845efc7ce18SJiri Kosina 		size = ((report->size - 1) >> 3) + 1 + hid->report_enum[type].numbered;
8466db3dfefSJiri Kosina 		if (*max < size)
8476db3dfefSJiri Kosina 			*max = size;
8486db3dfefSJiri Kosina 	}
8496db3dfefSJiri Kosina }
8506db3dfefSJiri Kosina 
hid_alloc_buffers(struct usb_device * dev,struct hid_device * hid)8516db3dfefSJiri Kosina static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
8526db3dfefSJiri Kosina {
8536db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
8546db3dfefSJiri Kosina 
855997ea58eSDaniel Mack 	usbhid->inbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
856898089d0SJiri Slaby 			&usbhid->inbuf_dma);
857997ea58eSDaniel Mack 	usbhid->outbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
858898089d0SJiri Slaby 			&usbhid->outbuf_dma);
8590ede76fcSAlan Stern 	usbhid->cr = kmalloc(sizeof(*usbhid->cr), GFP_KERNEL);
860997ea58eSDaniel Mack 	usbhid->ctrlbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
861898089d0SJiri Slaby 			&usbhid->ctrlbuf_dma);
862898089d0SJiri Slaby 	if (!usbhid->inbuf || !usbhid->outbuf || !usbhid->cr ||
863898089d0SJiri Slaby 			!usbhid->ctrlbuf)
8646db3dfefSJiri Kosina 		return -1;
8656db3dfefSJiri Kosina 
8666db3dfefSJiri Kosina 	return 0;
8676db3dfefSJiri Kosina }
8686db3dfefSJiri Kosina 
usbhid_get_raw_report(struct hid_device * hid,unsigned char report_number,__u8 * buf,size_t count,unsigned char report_type)869b4dbde9dSAlan Ott static int usbhid_get_raw_report(struct hid_device *hid,
870b4dbde9dSAlan Ott 		unsigned char report_number, __u8 *buf, size_t count,
871b4dbde9dSAlan Ott 		unsigned char report_type)
872b4dbde9dSAlan Ott {
873b4dbde9dSAlan Ott 	struct usbhid_device *usbhid = hid->driver_data;
874b4dbde9dSAlan Ott 	struct usb_device *dev = hid_to_usb_dev(hid);
875b4dbde9dSAlan Ott 	struct usb_interface *intf = usbhid->intf;
876b4dbde9dSAlan Ott 	struct usb_host_interface *interface = intf->cur_altsetting;
877b4dbde9dSAlan Ott 	int skipped_report_id = 0;
878b4dbde9dSAlan Ott 	int ret;
879b4dbde9dSAlan Ott 
880b4dbde9dSAlan Ott 	/* Byte 0 is the report number. Report data starts at byte 1.*/
881b4dbde9dSAlan Ott 	buf[0] = report_number;
882b4dbde9dSAlan Ott 	if (report_number == 0x0) {
883b4dbde9dSAlan Ott 		/* Offset the return buffer by 1, so that the report ID
884b4dbde9dSAlan Ott 		   will remain in byte 0. */
885b4dbde9dSAlan Ott 		buf++;
886b4dbde9dSAlan Ott 		count--;
887b4dbde9dSAlan Ott 		skipped_report_id = 1;
888b4dbde9dSAlan Ott 	}
889b4dbde9dSAlan Ott 	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
890b4dbde9dSAlan Ott 		HID_REQ_GET_REPORT,
891b4dbde9dSAlan Ott 		USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
892b4dbde9dSAlan Ott 		((report_type + 1) << 8) | report_number,
893b4dbde9dSAlan Ott 		interface->desc.bInterfaceNumber, buf, count,
894b4dbde9dSAlan Ott 		USB_CTRL_SET_TIMEOUT);
895b4dbde9dSAlan Ott 
896b4dbde9dSAlan Ott 	/* count also the report id */
897b4dbde9dSAlan Ott 	if (ret > 0 && skipped_report_id)
898b4dbde9dSAlan Ott 		ret++;
899b4dbde9dSAlan Ott 
900b4dbde9dSAlan Ott 	return ret;
901b4dbde9dSAlan Ott }
902b4dbde9dSAlan Ott 
usbhid_set_raw_report(struct hid_device * hid,unsigned int reportnum,__u8 * buf,size_t count,unsigned char rtype)903975a6832SFrank Praznik static int usbhid_set_raw_report(struct hid_device *hid, unsigned int reportnum,
904975a6832SFrank Praznik 				 __u8 *buf, size_t count, unsigned char rtype)
905975a6832SFrank Praznik {
906975a6832SFrank Praznik 	struct usbhid_device *usbhid = hid->driver_data;
907975a6832SFrank Praznik 	struct usb_device *dev = hid_to_usb_dev(hid);
908975a6832SFrank Praznik 	struct usb_interface *intf = usbhid->intf;
909975a6832SFrank Praznik 	struct usb_host_interface *interface = intf->cur_altsetting;
910975a6832SFrank Praznik 	int ret, skipped_report_id = 0;
911975a6832SFrank Praznik 
912975a6832SFrank Praznik 	/* Byte 0 is the report number. Report data starts at byte 1.*/
913e534a935SBenjamin Tissoires 	if ((rtype == HID_OUTPUT_REPORT) &&
914e534a935SBenjamin Tissoires 	    (hid->quirks & HID_QUIRK_SKIP_OUTPUT_REPORT_ID))
915e534a935SBenjamin Tissoires 		buf[0] = 0;
916e534a935SBenjamin Tissoires 	else
917975a6832SFrank Praznik 		buf[0] = reportnum;
918e534a935SBenjamin Tissoires 
919975a6832SFrank Praznik 	if (buf[0] == 0x0) {
920975a6832SFrank Praznik 		/* Don't send the Report ID */
921975a6832SFrank Praznik 		buf++;
922975a6832SFrank Praznik 		count--;
923975a6832SFrank Praznik 		skipped_report_id = 1;
924975a6832SFrank Praznik 	}
925975a6832SFrank Praznik 
926975a6832SFrank Praznik 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
927975a6832SFrank Praznik 			HID_REQ_SET_REPORT,
928975a6832SFrank Praznik 			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
929975a6832SFrank Praznik 			((rtype + 1) << 8) | reportnum,
930975a6832SFrank Praznik 			interface->desc.bInterfaceNumber, buf, count,
931975a6832SFrank Praznik 			USB_CTRL_SET_TIMEOUT);
932975a6832SFrank Praznik 	/* count also the report id, if this was a numbered report. */
933975a6832SFrank Praznik 	if (ret > 0 && skipped_report_id)
934975a6832SFrank Praznik 		ret++;
935975a6832SFrank Praznik 
936975a6832SFrank Praznik 	return ret;
937975a6832SFrank Praznik }
938975a6832SFrank Praznik 
usbhid_output_report(struct hid_device * hid,__u8 * buf,size_t count)939975a6832SFrank Praznik static int usbhid_output_report(struct hid_device *hid, __u8 *buf, size_t count)
940975a6832SFrank Praznik {
941975a6832SFrank Praznik 	struct usbhid_device *usbhid = hid->driver_data;
942975a6832SFrank Praznik 	struct usb_device *dev = hid_to_usb_dev(hid);
943975a6832SFrank Praznik 	int actual_length, skipped_report_id = 0, ret;
944975a6832SFrank Praznik 
945975a6832SFrank Praznik 	if (!usbhid->urbout)
946ddea1af9SBenjamin Tissoires 		return -ENOSYS;
947975a6832SFrank Praznik 
948975a6832SFrank Praznik 	if (buf[0] == 0x0) {
949975a6832SFrank Praznik 		/* Don't send the Report ID */
950975a6832SFrank Praznik 		buf++;
951975a6832SFrank Praznik 		count--;
952975a6832SFrank Praznik 		skipped_report_id = 1;
953975a6832SFrank Praznik 	}
954975a6832SFrank Praznik 
955975a6832SFrank Praznik 	ret = usb_interrupt_msg(dev, usbhid->urbout->pipe,
956975a6832SFrank Praznik 				buf, count, &actual_length,
957975a6832SFrank Praznik 				USB_CTRL_SET_TIMEOUT);
958975a6832SFrank Praznik 	/* return the number of bytes transferred */
959975a6832SFrank Praznik 	if (ret == 0) {
960975a6832SFrank Praznik 		ret = actual_length;
961975a6832SFrank Praznik 		/* count also the report id */
962975a6832SFrank Praznik 		if (skipped_report_id)
963975a6832SFrank Praznik 			ret++;
964975a6832SFrank Praznik 	}
965975a6832SFrank Praznik 
966975a6832SFrank Praznik 	return ret;
967975a6832SFrank Praznik }
968975a6832SFrank Praznik 
hid_free_buffers(struct usb_device * dev,struct hid_device * hid)9696db3dfefSJiri Kosina static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
9706db3dfefSJiri Kosina {
9716db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
9726db3dfefSJiri Kosina 
973997ea58eSDaniel Mack 	usb_free_coherent(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma);
974997ea58eSDaniel Mack 	usb_free_coherent(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma);
9750ede76fcSAlan Stern 	kfree(usbhid->cr);
976997ea58eSDaniel Mack 	usb_free_coherent(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma);
9776db3dfefSJiri Kosina }
9786db3dfefSJiri Kosina 
usbhid_parse(struct hid_device * hid)979c500c971SJiri Slaby static int usbhid_parse(struct hid_device *hid)
980c500c971SJiri Slaby {
981c500c971SJiri Slaby 	struct usb_interface *intf = to_usb_interface(hid->dev.parent);
9826db3dfefSJiri Kosina 	struct usb_host_interface *interface = intf->cur_altsetting;
9836db3dfefSJiri Kosina 	struct usb_device *dev = interface_to_usbdev (intf);
9846db3dfefSJiri Kosina 	struct hid_descriptor *hdesc;
9852eb5dc30SPaul Walmsley 	u32 quirks = 0;
986c500c971SJiri Slaby 	unsigned int rsize = 0;
9876db3dfefSJiri Kosina 	char *rdesc;
988c500c971SJiri Slaby 	int ret, n;
989f043bfc9SJaejoong Kim 	int num_descriptors;
990f043bfc9SJaejoong Kim 	size_t offset = offsetof(struct hid_descriptor, desc);
9916db3dfefSJiri Kosina 
992d5d3e202SBenjamin Tissoires 	quirks = hid_lookup_quirk(hid);
9936db3dfefSJiri Kosina 
9946f4303fbSJiri Kosina 	if (quirks & HID_QUIRK_IGNORE)
9956f4303fbSJiri Kosina 		return -ENODEV;
9966f4303fbSJiri Kosina 
9976db3dfefSJiri Kosina 	/* Many keyboards and mice don't like to be polled for reports,
9986db3dfefSJiri Kosina 	 * so we will always set the HID_QUIRK_NOGET flag for them. */
9996db3dfefSJiri Kosina 	if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
10006db3dfefSJiri Kosina 		if (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_KEYBOARD ||
10016db3dfefSJiri Kosina 			interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE)
10026db3dfefSJiri Kosina 				quirks |= HID_QUIRK_NOGET;
10036db3dfefSJiri Kosina 	}
10046db3dfefSJiri Kosina 
10056db3dfefSJiri Kosina 	if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
10066db3dfefSJiri Kosina 	    (!interface->desc.bNumEndpoints ||
10076db3dfefSJiri Kosina 	     usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
100858037eb9SJiri Kosina 		dbg_hid("class descriptor not present\n");
1009c500c971SJiri Slaby 		return -ENODEV;
10106db3dfefSJiri Kosina 	}
10116db3dfefSJiri Kosina 
1012f043bfc9SJaejoong Kim 	if (hdesc->bLength < sizeof(struct hid_descriptor)) {
1013f043bfc9SJaejoong Kim 		dbg_hid("hid descriptor is too short\n");
1014f043bfc9SJaejoong Kim 		return -EINVAL;
1015f043bfc9SJaejoong Kim 	}
1016f043bfc9SJaejoong Kim 
1017c500c971SJiri Slaby 	hid->version = le16_to_cpu(hdesc->bcdHID);
1018c500c971SJiri Slaby 	hid->country = hdesc->bCountryCode;
1019c500c971SJiri Slaby 
1020f043bfc9SJaejoong Kim 	num_descriptors = min_t(int, hdesc->bNumDescriptors,
1021f043bfc9SJaejoong Kim 	       (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
1022f043bfc9SJaejoong Kim 
1023f043bfc9SJaejoong Kim 	for (n = 0; n < num_descriptors; n++)
10246db3dfefSJiri Kosina 		if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
10256db3dfefSJiri Kosina 			rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
10266db3dfefSJiri Kosina 
10276db3dfefSJiri Kosina 	if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
102858037eb9SJiri Kosina 		dbg_hid("weird size of report descriptor (%u)\n", rsize);
1029c500c971SJiri Slaby 		return -EINVAL;
10306db3dfefSJiri Kosina 	}
10316db3dfefSJiri Kosina 
103252150c78SJoe Perches 	rdesc = kmalloc(rsize, GFP_KERNEL);
103352150c78SJoe Perches 	if (!rdesc)
1034c500c971SJiri Slaby 		return -ENOMEM;
10356db3dfefSJiri Kosina 
10366db3dfefSJiri Kosina 	hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0);
10376db3dfefSJiri Kosina 
1038c500c971SJiri Slaby 	ret = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber,
1039c500c971SJiri Slaby 			HID_DT_REPORT, rdesc, rsize);
1040c500c971SJiri Slaby 	if (ret < 0) {
104158037eb9SJiri Kosina 		dbg_hid("reading report descriptor failed\n");
10426db3dfefSJiri Kosina 		kfree(rdesc);
1043c500c971SJiri Slaby 		goto err;
10446db3dfefSJiri Kosina 	}
10456db3dfefSJiri Kosina 
1046c500c971SJiri Slaby 	ret = hid_parse_report(hid, rdesc, rsize);
104785cdaf52SJiri Slaby 	kfree(rdesc);
1048c500c971SJiri Slaby 	if (ret) {
104958037eb9SJiri Kosina 		dbg_hid("parsing report descriptor failed\n");
1050c500c971SJiri Slaby 		goto err;
10516db3dfefSJiri Kosina 	}
10526db3dfefSJiri Kosina 
1053f5208997SZoltan Karcagi 	hid->quirks |= quirks;
10546db3dfefSJiri Kosina 
1055c500c971SJiri Slaby 	return 0;
1056c500c971SJiri Slaby err:
1057c500c971SJiri Slaby 	return ret;
1058c500c971SJiri Slaby }
1059c500c971SJiri Slaby 
usbhid_start(struct hid_device * hid)1060c500c971SJiri Slaby static int usbhid_start(struct hid_device *hid)
1061c500c971SJiri Slaby {
1062c500c971SJiri Slaby 	struct usb_interface *intf = to_usb_interface(hid->dev.parent);
1063c500c971SJiri Slaby 	struct usb_host_interface *interface = intf->cur_altsetting;
1064c500c971SJiri Slaby 	struct usb_device *dev = interface_to_usbdev(intf);
10653d5afd32SJiri Slaby 	struct usbhid_device *usbhid = hid->driver_data;
1066c500c971SJiri Slaby 	unsigned int n, insize = 0;
1067c500c971SJiri Slaby 	int ret;
1068c500c971SJiri Slaby 
10690ed08fadSAlan Stern 	mutex_lock(&usbhid->mutex);
10700ed08fadSAlan Stern 
1071e3e14de5SJiri Slaby 	clear_bit(HID_DISCONNECTED, &usbhid->iofl);
1072e3e14de5SJiri Slaby 
10736db3dfefSJiri Kosina 	usbhid->bufsize = HID_MIN_BUFFER_SIZE;
10746db3dfefSJiri Kosina 	hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize);
10756db3dfefSJiri Kosina 	hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize);
10766db3dfefSJiri Kosina 	hid_find_max_report(hid, HID_FEATURE_REPORT, &usbhid->bufsize);
10776db3dfefSJiri Kosina 
10786db3dfefSJiri Kosina 	if (usbhid->bufsize > HID_MAX_BUFFER_SIZE)
10796db3dfefSJiri Kosina 		usbhid->bufsize = HID_MAX_BUFFER_SIZE;
10806db3dfefSJiri Kosina 
10816db3dfefSJiri Kosina 	hid_find_max_report(hid, HID_INPUT_REPORT, &insize);
10826db3dfefSJiri Kosina 
10836db3dfefSJiri Kosina 	if (insize > HID_MAX_BUFFER_SIZE)
10846db3dfefSJiri Kosina 		insize = HID_MAX_BUFFER_SIZE;
10856db3dfefSJiri Kosina 
1086c500c971SJiri Slaby 	if (hid_alloc_buffers(dev, hid)) {
1087c500c971SJiri Slaby 		ret = -ENOMEM;
10886db3dfefSJiri Kosina 		goto fail;
1089f345c37cSPekka Sarnila 	}
1090f345c37cSPekka Sarnila 
10916db3dfefSJiri Kosina 	for (n = 0; n < interface->desc.bNumEndpoints; n++) {
10926db3dfefSJiri Kosina 		struct usb_endpoint_descriptor *endpoint;
10936db3dfefSJiri Kosina 		int pipe;
10946db3dfefSJiri Kosina 		int interval;
10956db3dfefSJiri Kosina 
10966db3dfefSJiri Kosina 		endpoint = &interface->endpoint[n].desc;
1097581a2739SJiri Slaby 		if (!usb_endpoint_xfer_int(endpoint))
10986db3dfefSJiri Kosina 			continue;
10996db3dfefSJiri Kosina 
11006db3dfefSJiri Kosina 		interval = endpoint->bInterval;
11016db3dfefSJiri Kosina 
1102f345c37cSPekka Sarnila 		/* Some vendors give fullspeed interval on highspeed devides */
1103c500c971SJiri Slaby 		if (hid->quirks & HID_QUIRK_FULLSPEED_INTERVAL &&
1104f345c37cSPekka Sarnila 		    dev->speed == USB_SPEED_HIGH) {
1105f345c37cSPekka Sarnila 			interval = fls(endpoint->bInterval*8);
110652150c78SJoe Perches 			pr_info("%s: Fixing fullspeed to highspeed interval: %d -> %d\n",
1107f345c37cSPekka Sarnila 				hid->name, endpoint->bInterval, interval);
1108f345c37cSPekka Sarnila 		}
1109f345c37cSPekka Sarnila 
11102ddc8e2dSFilip Alac 		/* Change the polling interval of mice, joysticks
11112ddc8e2dSFilip Alac 		 * and keyboards.
11122ddc8e2dSFilip Alac 		 */
1113933bfe4dSTobias Jakobi 		switch (hid->collection->usage) {
1114933bfe4dSTobias Jakobi 		case HID_GD_MOUSE:
1115933bfe4dSTobias Jakobi 			if (hid_mousepoll_interval > 0)
11166db3dfefSJiri Kosina 				interval = hid_mousepoll_interval;
1117933bfe4dSTobias Jakobi 			break;
1118933bfe4dSTobias Jakobi 		case HID_GD_JOYSTICK:
1119933bfe4dSTobias Jakobi 			if (hid_jspoll_interval > 0)
1120933bfe4dSTobias Jakobi 				interval = hid_jspoll_interval;
1121933bfe4dSTobias Jakobi 			break;
11222ddc8e2dSFilip Alac 		case HID_GD_KEYBOARD:
11232ddc8e2dSFilip Alac 			if (hid_kbpoll_interval > 0)
11242ddc8e2dSFilip Alac 				interval = hid_kbpoll_interval;
11252ddc8e2dSFilip Alac 			break;
1126933bfe4dSTobias Jakobi 		}
11276db3dfefSJiri Kosina 
1128c500c971SJiri Slaby 		ret = -ENOMEM;
11296db3dfefSJiri Kosina 		if (usb_endpoint_dir_in(endpoint)) {
11306db3dfefSJiri Kosina 			if (usbhid->urbin)
11316db3dfefSJiri Kosina 				continue;
11326db3dfefSJiri Kosina 			if (!(usbhid->urbin = usb_alloc_urb(0, GFP_KERNEL)))
11336db3dfefSJiri Kosina 				goto fail;
11346db3dfefSJiri Kosina 			pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
11356db3dfefSJiri Kosina 			usb_fill_int_urb(usbhid->urbin, dev, pipe, usbhid->inbuf, insize,
11366db3dfefSJiri Kosina 					 hid_irq_in, hid, interval);
11376db3dfefSJiri Kosina 			usbhid->urbin->transfer_dma = usbhid->inbuf_dma;
11386db3dfefSJiri Kosina 			usbhid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
11396db3dfefSJiri Kosina 		} else {
11406db3dfefSJiri Kosina 			if (usbhid->urbout)
11416db3dfefSJiri Kosina 				continue;
11426db3dfefSJiri Kosina 			if (!(usbhid->urbout = usb_alloc_urb(0, GFP_KERNEL)))
11436db3dfefSJiri Kosina 				goto fail;
11446db3dfefSJiri Kosina 			pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress);
11456db3dfefSJiri Kosina 			usb_fill_int_urb(usbhid->urbout, dev, pipe, usbhid->outbuf, 0,
11466db3dfefSJiri Kosina 					 hid_irq_out, hid, interval);
11476db3dfefSJiri Kosina 			usbhid->urbout->transfer_dma = usbhid->outbuf_dma;
11486db3dfefSJiri Kosina 			usbhid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
11496db3dfefSJiri Kosina 		}
11506db3dfefSJiri Kosina 	}
11516db3dfefSJiri Kosina 
11526db3dfefSJiri Kosina 	usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
1153c500c971SJiri Slaby 	if (!usbhid->urbctrl) {
1154c500c971SJiri Slaby 		ret = -ENOMEM;
11556db3dfefSJiri Kosina 		goto fail;
1156c500c971SJiri Slaby 	}
11576db3dfefSJiri Kosina 
11586db3dfefSJiri Kosina 	usb_fill_control_urb(usbhid->urbctrl, dev, 0, (void *) usbhid->cr,
11596db3dfefSJiri Kosina 			     usbhid->ctrlbuf, 1, hid_ctrl, hid);
11606db3dfefSJiri Kosina 	usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma;
11610ede76fcSAlan Stern 	usbhid->urbctrl->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1162c500c971SJiri Slaby 
11633d5afd32SJiri Slaby 	set_bit(HID_STARTED, &usbhid->iofl);
11643d5afd32SJiri Slaby 
11650b750b3bSJohan Hovold 	if (hid->quirks & HID_QUIRK_ALWAYS_POLL) {
11660b750b3bSJohan Hovold 		ret = usb_autopm_get_interface(usbhid->intf);
11670b750b3bSJohan Hovold 		if (ret)
11680b750b3bSJohan Hovold 			goto fail;
116928cbc863SDmitry Torokhov 		set_bit(HID_IN_POLLING, &usbhid->iofl);
11700b750b3bSJohan Hovold 		usbhid->intf->needs_remote_wakeup = 1;
11710b750b3bSJohan Hovold 		ret = hid_start_in(hid);
11720b750b3bSJohan Hovold 		if (ret) {
11730b750b3bSJohan Hovold 			dev_err(&hid->dev,
11740b750b3bSJohan Hovold 				"failed to start in urb: %d\n", ret);
11750b750b3bSJohan Hovold 		}
11760b750b3bSJohan Hovold 		usb_autopm_put_interface(usbhid->intf);
11770b750b3bSJohan Hovold 	}
11780b750b3bSJohan Hovold 
117908ef08eeSAlan Stern 	/* Some keyboards don't work until their LEDs have been set.
118008ef08eeSAlan Stern 	 * Since BIOSes do set the LEDs, it must be safe for any device
118108ef08eeSAlan Stern 	 * that supports the keyboard boot protocol.
11823d61510fSAlan Stern 	 * In addition, enable remote wakeup by default for all keyboard
11833d61510fSAlan Stern 	 * devices supporting the boot protocol.
118408ef08eeSAlan Stern 	 */
118508ef08eeSAlan Stern 	if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT &&
118608ef08eeSAlan Stern 			interface->desc.bInterfaceProtocol ==
11873d61510fSAlan Stern 				USB_INTERFACE_PROTOCOL_KEYBOARD) {
118808ef08eeSAlan Stern 		usbhid_set_leds(hid);
11893d61510fSAlan Stern 		device_set_wakeup_enable(&dev->dev, 1);
11903d61510fSAlan Stern 	}
11910ed08fadSAlan Stern 
11920ed08fadSAlan Stern 	mutex_unlock(&usbhid->mutex);
1193c500c971SJiri Slaby 	return 0;
11946db3dfefSJiri Kosina 
11956db3dfefSJiri Kosina fail:
11966db3dfefSJiri Kosina 	usb_free_urb(usbhid->urbin);
11976db3dfefSJiri Kosina 	usb_free_urb(usbhid->urbout);
11986db3dfefSJiri Kosina 	usb_free_urb(usbhid->urbctrl);
1199e3e14de5SJiri Slaby 	usbhid->urbin = NULL;
1200e3e14de5SJiri Slaby 	usbhid->urbout = NULL;
1201e3e14de5SJiri Slaby 	usbhid->urbctrl = NULL;
120222f675f3SJiri Kosina 	hid_free_buffers(dev, hid);
12030ed08fadSAlan Stern 	mutex_unlock(&usbhid->mutex);
1204c500c971SJiri Slaby 	return ret;
12056db3dfefSJiri Kosina }
12066db3dfefSJiri Kosina 
usbhid_stop(struct hid_device * hid)1207c500c971SJiri Slaby static void usbhid_stop(struct hid_device *hid)
12086db3dfefSJiri Kosina {
1209c500c971SJiri Slaby 	struct usbhid_device *usbhid = hid->driver_data;
12106db3dfefSJiri Kosina 
1211c500c971SJiri Slaby 	if (WARN_ON(!usbhid))
12126db3dfefSJiri Kosina 		return;
12136db3dfefSJiri Kosina 
121428cbc863SDmitry Torokhov 	if (hid->quirks & HID_QUIRK_ALWAYS_POLL) {
121528cbc863SDmitry Torokhov 		clear_bit(HID_IN_POLLING, &usbhid->iofl);
12160b750b3bSJohan Hovold 		usbhid->intf->needs_remote_wakeup = 0;
121728cbc863SDmitry Torokhov 	}
12180b750b3bSJohan Hovold 
12190ed08fadSAlan Stern 	mutex_lock(&usbhid->mutex);
12200ed08fadSAlan Stern 
12213d5afd32SJiri Slaby 	clear_bit(HID_STARTED, &usbhid->iofl);
1222f7744fa1SAnirudh Rayabharam 
12234371ea82SDaniel Kurtz 	spin_lock_irq(&usbhid->lock);	/* Sync with error and led handlers */
122469626f23SOliver Neukum 	set_bit(HID_DISCONNECTED, &usbhid->iofl);
1225f7744fa1SAnirudh Rayabharam 	while (usbhid->ctrltail != usbhid->ctrlhead) {
1226f7744fa1SAnirudh Rayabharam 		if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_OUT) {
1227f7744fa1SAnirudh Rayabharam 			kfree(usbhid->ctrl[usbhid->ctrltail].raw_report);
1228f7744fa1SAnirudh Rayabharam 			usbhid->ctrl[usbhid->ctrltail].raw_report = NULL;
1229f7744fa1SAnirudh Rayabharam 		}
1230f7744fa1SAnirudh Rayabharam 
1231f7744fa1SAnirudh Rayabharam 		usbhid->ctrltail = (usbhid->ctrltail + 1) &
1232f7744fa1SAnirudh Rayabharam 			(HID_CONTROL_FIFO_SIZE - 1);
1233f7744fa1SAnirudh Rayabharam 	}
12340361a28dSOliver Neukum 	spin_unlock_irq(&usbhid->lock);
1235f7744fa1SAnirudh Rayabharam 
12366db3dfefSJiri Kosina 	usb_kill_urb(usbhid->urbin);
12376db3dfefSJiri Kosina 	usb_kill_urb(usbhid->urbout);
12386db3dfefSJiri Kosina 	usb_kill_urb(usbhid->urbctrl);
12396db3dfefSJiri Kosina 
12400361a28dSOliver Neukum 	hid_cancel_delayed_stuff(usbhid);
12416db3dfefSJiri Kosina 
1242c500c971SJiri Slaby 	hid->claimed = 0;
1243c500c971SJiri Slaby 
12446db3dfefSJiri Kosina 	usb_free_urb(usbhid->urbin);
12456db3dfefSJiri Kosina 	usb_free_urb(usbhid->urbctrl);
12466db3dfefSJiri Kosina 	usb_free_urb(usbhid->urbout);
1247e3e14de5SJiri Slaby 	usbhid->urbin = NULL; /* don't mess up next start */
1248e3e14de5SJiri Slaby 	usbhid->urbctrl = NULL;
1249e3e14de5SJiri Slaby 	usbhid->urbout = NULL;
12506db3dfefSJiri Kosina 
12516db3dfefSJiri Kosina 	hid_free_buffers(hid_to_usb_dev(hid), hid);
12520ed08fadSAlan Stern 
12530ed08fadSAlan Stern 	mutex_unlock(&usbhid->mutex);
12546db3dfefSJiri Kosina }
12556db3dfefSJiri Kosina 
usbhid_power(struct hid_device * hid,int lvl)12560361a28dSOliver Neukum static int usbhid_power(struct hid_device *hid, int lvl)
12570361a28dSOliver Neukum {
12589a83563fSDmitry Torokhov 	struct usbhid_device *usbhid = hid->driver_data;
12590361a28dSOliver Neukum 	int r = 0;
12600361a28dSOliver Neukum 
12610361a28dSOliver Neukum 	switch (lvl) {
12620361a28dSOliver Neukum 	case PM_HINT_FULLON:
12639a83563fSDmitry Torokhov 		r = usb_autopm_get_interface(usbhid->intf);
12640361a28dSOliver Neukum 		break;
12659a83563fSDmitry Torokhov 
12660361a28dSOliver Neukum 	case PM_HINT_NORMAL:
12679a83563fSDmitry Torokhov 		usb_autopm_put_interface(usbhid->intf);
12680361a28dSOliver Neukum 		break;
12690361a28dSOliver Neukum 	}
12709a83563fSDmitry Torokhov 
12710361a28dSOliver Neukum 	return r;
12720361a28dSOliver Neukum }
12730361a28dSOliver Neukum 
usbhid_request(struct hid_device * hid,struct hid_report * rep,int reqtype)1274e90a6df8SHenrik Rydberg static void usbhid_request(struct hid_device *hid, struct hid_report *rep, int reqtype)
1275e90a6df8SHenrik Rydberg {
1276e90a6df8SHenrik Rydberg 	switch (reqtype) {
1277e90a6df8SHenrik Rydberg 	case HID_REQ_GET_REPORT:
1278e90a6df8SHenrik Rydberg 		usbhid_submit_report(hid, rep, USB_DIR_IN);
1279e90a6df8SHenrik Rydberg 		break;
1280e90a6df8SHenrik Rydberg 	case HID_REQ_SET_REPORT:
1281e90a6df8SHenrik Rydberg 		usbhid_submit_report(hid, rep, USB_DIR_OUT);
1282e90a6df8SHenrik Rydberg 		break;
1283e90a6df8SHenrik Rydberg 	}
1284e90a6df8SHenrik Rydberg }
1285e90a6df8SHenrik Rydberg 
usbhid_raw_request(struct hid_device * hid,unsigned char reportnum,__u8 * buf,size_t len,unsigned char rtype,int reqtype)1286975a6832SFrank Praznik static int usbhid_raw_request(struct hid_device *hid, unsigned char reportnum,
1287975a6832SFrank Praznik 			      __u8 *buf, size_t len, unsigned char rtype,
1288975a6832SFrank Praznik 			      int reqtype)
1289975a6832SFrank Praznik {
1290975a6832SFrank Praznik 	switch (reqtype) {
1291975a6832SFrank Praznik 	case HID_REQ_GET_REPORT:
1292975a6832SFrank Praznik 		return usbhid_get_raw_report(hid, reportnum, buf, len, rtype);
1293975a6832SFrank Praznik 	case HID_REQ_SET_REPORT:
1294975a6832SFrank Praznik 		return usbhid_set_raw_report(hid, reportnum, buf, len, rtype);
1295975a6832SFrank Praznik 	default:
1296975a6832SFrank Praznik 		return -EIO;
1297975a6832SFrank Praznik 	}
1298975a6832SFrank Praznik }
1299975a6832SFrank Praznik 
usbhid_idle(struct hid_device * hid,int report,int idle,int reqtype)13009684819bSBenjamin Tissoires static int usbhid_idle(struct hid_device *hid, int report, int idle,
13019684819bSBenjamin Tissoires 		int reqtype)
13029684819bSBenjamin Tissoires {
13039684819bSBenjamin Tissoires 	struct usb_device *dev = hid_to_usb_dev(hid);
13049684819bSBenjamin Tissoires 	struct usb_interface *intf = to_usb_interface(hid->dev.parent);
13059684819bSBenjamin Tissoires 	struct usb_host_interface *interface = intf->cur_altsetting;
13069684819bSBenjamin Tissoires 	int ifnum = interface->desc.bInterfaceNumber;
13079684819bSBenjamin Tissoires 
13089684819bSBenjamin Tissoires 	if (reqtype != HID_REQ_SET_IDLE)
13099684819bSBenjamin Tissoires 		return -EINVAL;
13109684819bSBenjamin Tissoires 
13119684819bSBenjamin Tissoires 	return hid_set_idle(dev, ifnum, report, idle);
13129684819bSBenjamin Tissoires }
13139684819bSBenjamin Tissoires 
usbhid_may_wakeup(struct hid_device * hid)1314978e786cSHans de Goede static bool usbhid_may_wakeup(struct hid_device *hid)
1315978e786cSHans de Goede {
1316978e786cSHans de Goede 	struct usb_device *dev = hid_to_usb_dev(hid);
1317978e786cSHans de Goede 
1318978e786cSHans de Goede 	return device_may_wakeup(&dev->dev);
1319978e786cSHans de Goede }
1320978e786cSHans de Goede 
1321*52d22534SThomas Weißschuh static const struct hid_ll_driver usb_hid_driver = {
1322c500c971SJiri Slaby 	.parse = usbhid_parse,
1323c500c971SJiri Slaby 	.start = usbhid_start,
1324c500c971SJiri Slaby 	.stop = usbhid_stop,
1325c500c971SJiri Slaby 	.open = usbhid_open,
1326c500c971SJiri Slaby 	.close = usbhid_close,
13270361a28dSOliver Neukum 	.power = usbhid_power,
1328e90a6df8SHenrik Rydberg 	.request = usbhid_request,
13293373443bSHenrik Rydberg 	.wait = usbhid_wait_io,
1330975a6832SFrank Praznik 	.raw_request = usbhid_raw_request,
1331975a6832SFrank Praznik 	.output_report = usbhid_output_report,
13329684819bSBenjamin Tissoires 	.idle = usbhid_idle,
1333978e786cSHans de Goede 	.may_wakeup = usbhid_may_wakeup,
1334c500c971SJiri Slaby };
1335c500c971SJiri Slaby 
hid_is_usb(const struct hid_device * hdev)13368c3e2406SThomas Weißschuh bool hid_is_usb(const struct hid_device *hdev)
13378c3e2406SThomas Weißschuh {
13388c3e2406SThomas Weißschuh 	return hdev->ll_driver == &usb_hid_driver;
13398c3e2406SThomas Weißschuh }
13408c3e2406SThomas Weißschuh EXPORT_SYMBOL_GPL(hid_is_usb);
13418c3e2406SThomas Weißschuh 
usbhid_probe(struct usb_interface * intf,const struct usb_device_id * id)1342c4c259bcSJiri Kosina static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id)
13436db3dfefSJiri Kosina {
1344131d3a7aSJiri Slaby 	struct usb_host_interface *interface = intf->cur_altsetting;
1345c500c971SJiri Slaby 	struct usb_device *dev = interface_to_usbdev(intf);
13463d5afd32SJiri Slaby 	struct usbhid_device *usbhid;
13476db3dfefSJiri Kosina 	struct hid_device *hid;
1348131d3a7aSJiri Slaby 	unsigned int n, has_in = 0;
1349c500c971SJiri Slaby 	size_t len;
1350c500c971SJiri Slaby 	int ret;
13516db3dfefSJiri Kosina 
135258037eb9SJiri Kosina 	dbg_hid("HID probe called for ifnum %d\n",
13536db3dfefSJiri Kosina 			intf->altsetting->desc.bInterfaceNumber);
13546db3dfefSJiri Kosina 
1355131d3a7aSJiri Slaby 	for (n = 0; n < interface->desc.bNumEndpoints; n++)
1356131d3a7aSJiri Slaby 		if (usb_endpoint_is_int_in(&interface->endpoint[n].desc))
1357131d3a7aSJiri Slaby 			has_in++;
1358131d3a7aSJiri Slaby 	if (!has_in) {
13594291ee30SJoe Perches 		hid_err(intf, "couldn't find an input interrupt endpoint\n");
1360131d3a7aSJiri Slaby 		return -ENODEV;
1361131d3a7aSJiri Slaby 	}
1362131d3a7aSJiri Slaby 
1363c500c971SJiri Slaby 	hid = hid_allocate_device();
1364c500c971SJiri Slaby 	if (IS_ERR(hid))
1365c500c971SJiri Slaby 		return PTR_ERR(hid);
13666db3dfefSJiri Kosina 
13676db3dfefSJiri Kosina 	usb_set_intfdata(intf, hid);
1368c500c971SJiri Slaby 	hid->ll_driver = &usb_hid_driver;
136976483cf4SJiri Slaby 	hid->ff_init = hid_pidff_init;
1370c500c971SJiri Slaby #ifdef CONFIG_USB_HIDDEV
137193c10132SJiri Slaby 	hid->hiddev_connect = hiddev_connect;
1372c4c259bcSJiri Kosina 	hid->hiddev_disconnect = hiddev_disconnect;
1373c500c971SJiri Slaby 	hid->hiddev_hid_event = hiddev_hid_event;
1374c500c971SJiri Slaby 	hid->hiddev_report_event = hiddev_report_event;
1375c500c971SJiri Slaby #endif
1376c500c971SJiri Slaby 	hid->dev.parent = &intf->dev;
1377c500c971SJiri Slaby 	hid->bus = BUS_USB;
1378c500c971SJiri Slaby 	hid->vendor = le16_to_cpu(dev->descriptor.idVendor);
1379c500c971SJiri Slaby 	hid->product = le16_to_cpu(dev->descriptor.idProduct);
1380d5158e02SNiels Skou Olsen 	hid->version = le16_to_cpu(dev->descriptor.bcdDevice);
1381c500c971SJiri Slaby 	hid->name[0] = 0;
1382a73a6370SJiri Slaby 	if (intf->cur_altsetting->desc.bInterfaceProtocol ==
1383a73a6370SJiri Slaby 			USB_INTERFACE_PROTOCOL_MOUSE)
1384a73a6370SJiri Slaby 		hid->type = HID_TYPE_USBMOUSE;
13856dc1418eSTomoki Sekiyama 	else if (intf->cur_altsetting->desc.bInterfaceProtocol == 0)
13866dc1418eSTomoki Sekiyama 		hid->type = HID_TYPE_USBNONE;
13876db3dfefSJiri Kosina 
1388c500c971SJiri Slaby 	if (dev->manufacturer)
1389eeeec27dSWolfram Sang 		strscpy(hid->name, dev->manufacturer, sizeof(hid->name));
1390c500c971SJiri Slaby 
1391c500c971SJiri Slaby 	if (dev->product) {
1392c500c971SJiri Slaby 		if (dev->manufacturer)
1393c500c971SJiri Slaby 			strlcat(hid->name, " ", sizeof(hid->name));
1394c500c971SJiri Slaby 		strlcat(hid->name, dev->product, sizeof(hid->name));
13956db3dfefSJiri Kosina 	}
13966db3dfefSJiri Kosina 
1397c500c971SJiri Slaby 	if (!strlen(hid->name))
1398c500c971SJiri Slaby 		snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x",
1399c500c971SJiri Slaby 			 le16_to_cpu(dev->descriptor.idVendor),
1400c500c971SJiri Slaby 			 le16_to_cpu(dev->descriptor.idProduct));
14016db3dfefSJiri Kosina 
1402c500c971SJiri Slaby 	usb_make_path(dev, hid->phys, sizeof(hid->phys));
1403c500c971SJiri Slaby 	strlcat(hid->phys, "/input", sizeof(hid->phys));
1404c500c971SJiri Slaby 	len = strlen(hid->phys);
1405c500c971SJiri Slaby 	if (len < sizeof(hid->phys) - 1)
1406c500c971SJiri Slaby 		snprintf(hid->phys + len, sizeof(hid->phys) - len,
1407c500c971SJiri Slaby 			 "%d", intf->altsetting[0].desc.bInterfaceNumber);
14086db3dfefSJiri Kosina 
1409c500c971SJiri Slaby 	if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
1410c500c971SJiri Slaby 		hid->uniq[0] = 0;
14116db3dfefSJiri Kosina 
14123d5afd32SJiri Slaby 	usbhid = kzalloc(sizeof(*usbhid), GFP_KERNEL);
14133d5afd32SJiri Slaby 	if (usbhid == NULL) {
14143d5afd32SJiri Slaby 		ret = -ENOMEM;
14153d5afd32SJiri Slaby 		goto err;
14163d5afd32SJiri Slaby 	}
14173d5afd32SJiri Slaby 
14183d5afd32SJiri Slaby 	hid->driver_data = usbhid;
14193d5afd32SJiri Slaby 	usbhid->hid = hid;
142057ab12e4SJiri Kosina 	usbhid->intf = intf;
142157ab12e4SJiri Kosina 	usbhid->ifnum = interface->desc.bInterfaceNumber;
14223d5afd32SJiri Slaby 
1423fde4e2f7SAlan Stern 	init_waitqueue_head(&usbhid->wait);
1424fde4e2f7SAlan Stern 	INIT_WORK(&usbhid->reset_work, hid_reset);
14250ee32774SKees Cook 	timer_setup(&usbhid->io_retry, hid_retry_timeout, 0);
1426fde4e2f7SAlan Stern 	spin_lock_init(&usbhid->lock);
14270ed08fadSAlan Stern 	mutex_init(&usbhid->mutex);
1428fde4e2f7SAlan Stern 
142985cdaf52SJiri Slaby 	ret = hid_add_device(hid);
143085cdaf52SJiri Slaby 	if (ret) {
1431d458a9dfSJiri Slaby 		if (ret != -ENODEV)
14324291ee30SJoe Perches 			hid_err(intf, "can't add hid device: %d\n", ret);
14333d5afd32SJiri Slaby 		goto err_free;
143485cdaf52SJiri Slaby 	}
1435c500c971SJiri Slaby 
1436c500c971SJiri Slaby 	return 0;
14373d5afd32SJiri Slaby err_free:
14383d5afd32SJiri Slaby 	kfree(usbhid);
1439c500c971SJiri Slaby err:
1440c500c971SJiri Slaby 	hid_destroy_device(hid);
144185cdaf52SJiri Slaby 	return ret;
14426db3dfefSJiri Kosina }
14436db3dfefSJiri Kosina 
usbhid_disconnect(struct usb_interface * intf)1444c4c259bcSJiri Kosina static void usbhid_disconnect(struct usb_interface *intf)
1445c500c971SJiri Slaby {
1446c500c971SJiri Slaby 	struct hid_device *hid = usb_get_intfdata(intf);
14473d5afd32SJiri Slaby 	struct usbhid_device *usbhid;
1448c500c971SJiri Slaby 
1449c500c971SJiri Slaby 	if (WARN_ON(!hid))
1450c500c971SJiri Slaby 		return;
1451c500c971SJiri Slaby 
14523d5afd32SJiri Slaby 	usbhid = hid->driver_data;
145346df9dedSReyad Attiyat 	spin_lock_irq(&usbhid->lock);	/* Sync with error and led handlers */
145446df9dedSReyad Attiyat 	set_bit(HID_DISCONNECTED, &usbhid->iofl);
145546df9dedSReyad Attiyat 	spin_unlock_irq(&usbhid->lock);
1456c500c971SJiri Slaby 	hid_destroy_device(hid);
14573d5afd32SJiri Slaby 	kfree(usbhid);
1458c500c971SJiri Slaby }
1459c500c971SJiri Slaby 
hid_cancel_delayed_stuff(struct usbhid_device * usbhid)14600361a28dSOliver Neukum static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
14610361a28dSOliver Neukum {
14620361a28dSOliver Neukum 	del_timer_sync(&usbhid->io_retry);
14630361a28dSOliver Neukum 	cancel_work_sync(&usbhid->reset_work);
14640361a28dSOliver Neukum }
14650361a28dSOliver Neukum 
hid_cease_io(struct usbhid_device * usbhid)14660361a28dSOliver Neukum static void hid_cease_io(struct usbhid_device *usbhid)
14670361a28dSOliver Neukum {
1468fad9fbe8SOliver Neukum 	del_timer_sync(&usbhid->io_retry);
14690361a28dSOliver Neukum 	usb_kill_urb(usbhid->urbin);
14700361a28dSOliver Neukum 	usb_kill_urb(usbhid->urbctrl);
14710361a28dSOliver Neukum 	usb_kill_urb(usbhid->urbout);
14720361a28dSOliver Neukum }
14730361a28dSOliver Neukum 
hid_restart_io(struct hid_device * hid)1474972e6a99SAlan Stern static void hid_restart_io(struct hid_device *hid)
1475972e6a99SAlan Stern {
1476972e6a99SAlan Stern 	struct usbhid_device *usbhid = hid->driver_data;
1477972e6a99SAlan Stern 	int clear_halt = test_bit(HID_CLEAR_HALT, &usbhid->iofl);
1478972e6a99SAlan Stern 	int reset_pending = test_bit(HID_RESET_PENDING, &usbhid->iofl);
1479972e6a99SAlan Stern 
1480972e6a99SAlan Stern 	spin_lock_irq(&usbhid->lock);
1481972e6a99SAlan Stern 	clear_bit(HID_SUSPENDED, &usbhid->iofl);
1482972e6a99SAlan Stern 	usbhid_mark_busy(usbhid);
1483972e6a99SAlan Stern 
1484972e6a99SAlan Stern 	if (clear_halt || reset_pending)
1485972e6a99SAlan Stern 		schedule_work(&usbhid->reset_work);
1486972e6a99SAlan Stern 	usbhid->retry_delay = 0;
1487972e6a99SAlan Stern 	spin_unlock_irq(&usbhid->lock);
1488972e6a99SAlan Stern 
1489972e6a99SAlan Stern 	if (reset_pending || !test_bit(HID_STARTED, &usbhid->iofl))
1490972e6a99SAlan Stern 		return;
1491972e6a99SAlan Stern 
1492972e6a99SAlan Stern 	if (!clear_halt) {
1493972e6a99SAlan Stern 		if (hid_start_in(hid) < 0)
1494972e6a99SAlan Stern 			hid_io_error(hid);
1495972e6a99SAlan Stern 	}
1496972e6a99SAlan Stern 
1497972e6a99SAlan Stern 	spin_lock_irq(&usbhid->lock);
1498972e6a99SAlan Stern 	if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl))
1499972e6a99SAlan Stern 		usbhid_restart_out_queue(usbhid);
1500972e6a99SAlan Stern 	if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
1501972e6a99SAlan Stern 		usbhid_restart_ctrl_queue(usbhid);
1502972e6a99SAlan Stern 	spin_unlock_irq(&usbhid->lock);
1503972e6a99SAlan Stern }
1504972e6a99SAlan Stern 
1505ae2f0074SJiri Kosina /* Treat USB reset pretty much the same as suspend/resume */
hid_pre_reset(struct usb_interface * intf)1506ae2f0074SJiri Kosina static int hid_pre_reset(struct usb_interface *intf)
15076db3dfefSJiri Kosina {
15086db3dfefSJiri Kosina 	struct hid_device *hid = usb_get_intfdata(intf);
15096db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
15106db3dfefSJiri Kosina 
1511ae2f0074SJiri Kosina 	spin_lock_irq(&usbhid->lock);
1512ae2f0074SJiri Kosina 	set_bit(HID_RESET_PENDING, &usbhid->iofl);
1513ae2f0074SJiri Kosina 	spin_unlock_irq(&usbhid->lock);
1514ae2f0074SJiri Kosina 	hid_cease_io(usbhid);
15153d5afd32SJiri Slaby 
1516ae2f0074SJiri Kosina 	return 0;
1517ae2f0074SJiri Kosina }
1518ae2f0074SJiri Kosina 
1519ae2f0074SJiri Kosina /* Same routine used for post_reset and reset_resume */
hid_post_reset(struct usb_interface * intf)1520ae2f0074SJiri Kosina static int hid_post_reset(struct usb_interface *intf)
1521ae2f0074SJiri Kosina {
1522ae2f0074SJiri Kosina 	struct usb_device *dev = interface_to_usbdev (intf);
1523ae2f0074SJiri Kosina 	struct hid_device *hid = usb_get_intfdata(intf);
1524ae2f0074SJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
1525dc3c78e4SSimon Haggett 	struct usb_host_interface *interface = intf->cur_altsetting;
1526ae2f0074SJiri Kosina 	int status;
1527dc3c78e4SSimon Haggett 	char *rdesc;
1528dc3c78e4SSimon Haggett 
1529dc3c78e4SSimon Haggett 	/* Fetch and examine the HID report descriptor. If this
1530dc3c78e4SSimon Haggett 	 * has changed, then rebind. Since usbcore's check of the
1531dc3c78e4SSimon Haggett 	 * configuration descriptors passed, we already know that
1532dc3c78e4SSimon Haggett 	 * the size of the HID report descriptor has not changed.
1533dc3c78e4SSimon Haggett 	 */
153486e6b77eSKevin Daughtridge 	rdesc = kmalloc(hid->dev_rsize, GFP_KERNEL);
153552150c78SJoe Perches 	if (!rdesc)
1536c60fa555SPan Bian 		return -ENOMEM;
153752150c78SJoe Perches 
1538dc3c78e4SSimon Haggett 	status = hid_get_class_descriptor(dev,
1539dc3c78e4SSimon Haggett 				interface->desc.bInterfaceNumber,
154086e6b77eSKevin Daughtridge 				HID_DT_REPORT, rdesc, hid->dev_rsize);
1541dc3c78e4SSimon Haggett 	if (status < 0) {
1542dc3c78e4SSimon Haggett 		dbg_hid("reading report descriptor failed (post_reset)\n");
1543dc3c78e4SSimon Haggett 		kfree(rdesc);
1544c60fa555SPan Bian 		return status;
1545dc3c78e4SSimon Haggett 	}
154686e6b77eSKevin Daughtridge 	status = memcmp(rdesc, hid->dev_rdesc, hid->dev_rsize);
1547dc3c78e4SSimon Haggett 	kfree(rdesc);
1548dc3c78e4SSimon Haggett 	if (status != 0) {
1549dc3c78e4SSimon Haggett 		dbg_hid("report descriptor changed\n");
1550c60fa555SPan Bian 		return -EPERM;
1551dc3c78e4SSimon Haggett 	}
1552ae2f0074SJiri Kosina 
1553972e6a99SAlan Stern 	/* No need to do another reset or clear a halted endpoint */
1554ae2f0074SJiri Kosina 	spin_lock_irq(&usbhid->lock);
1555ae2f0074SJiri Kosina 	clear_bit(HID_RESET_PENDING, &usbhid->iofl);
1556972e6a99SAlan Stern 	clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
1557ae2f0074SJiri Kosina 	spin_unlock_irq(&usbhid->lock);
1558ae2f0074SJiri Kosina 	hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
1559972e6a99SAlan Stern 
1560972e6a99SAlan Stern 	hid_restart_io(hid);
1561ae2f0074SJiri Kosina 
1562ae2f0074SJiri Kosina 	return 0;
1563ae2f0074SJiri Kosina }
1564ae2f0074SJiri Kosina 
15650f6f1407SJiri Kosina #ifdef CONFIG_PM
hid_resume_common(struct hid_device * hid,bool driver_suspended)1566eb055fd0SAlan Stern static int hid_resume_common(struct hid_device *hid, bool driver_suspended)
1567eb055fd0SAlan Stern {
1568972e6a99SAlan Stern 	int status = 0;
1569eb055fd0SAlan Stern 
1570972e6a99SAlan Stern 	hid_restart_io(hid);
15719e356208SBenjamin Tissoires 	if (driver_suspended)
15729e356208SBenjamin Tissoires 		status = hid_driver_resume(hid);
1573eb055fd0SAlan Stern 	return status;
1574eb055fd0SAlan Stern }
1575eb055fd0SAlan Stern 
hid_suspend(struct usb_interface * intf,pm_message_t message)15766db3dfefSJiri Kosina static int hid_suspend(struct usb_interface *intf, pm_message_t message)
15776db3dfefSJiri Kosina {
15786db3dfefSJiri Kosina 	struct hid_device *hid = usb_get_intfdata(intf);
15796db3dfefSJiri Kosina 	struct usbhid_device *usbhid = hid->driver_data;
158037093b70SMing Lei 	int status = 0;
1581eb055fd0SAlan Stern 	bool driver_suspended = false;
1582bfde79cbSDavid Herrmann 	unsigned int ledcount;
15836db3dfefSJiri Kosina 
15845b1b0b81SAlan Stern 	if (PMSG_IS_AUTO(message)) {
1585bfde79cbSDavid Herrmann 		ledcount = hidinput_count_leds(hid);
15860361a28dSOliver Neukum 		spin_lock_irq(&usbhid->lock);	/* Sync with error handler */
15870361a28dSOliver Neukum 		if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
15880361a28dSOliver Neukum 		    && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
15890361a28dSOliver Neukum 		    && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)
15900361a28dSOliver Neukum 		    && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl)
15910361a28dSOliver Neukum 		    && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl)
1592bfde79cbSDavid Herrmann 		    && (!ledcount || ignoreled))
15930361a28dSOliver Neukum 		{
1594f2b5264dSAlan Stern 			set_bit(HID_SUSPENDED, &usbhid->iofl);
15950361a28dSOliver Neukum 			spin_unlock_irq(&usbhid->lock);
15969e356208SBenjamin Tissoires 			status = hid_driver_suspend(hid, message);
15976a740aa4SBruno Prémont 			if (status < 0)
1598eb055fd0SAlan Stern 				goto failed;
1599eb055fd0SAlan Stern 			driver_suspended = true;
16000361a28dSOliver Neukum 		} else {
16010361a28dSOliver Neukum 			usbhid_mark_busy(usbhid);
16020361a28dSOliver Neukum 			spin_unlock_irq(&usbhid->lock);
16030361a28dSOliver Neukum 			return -EBUSY;
16040361a28dSOliver Neukum 		}
16056db3dfefSJiri Kosina 
16060361a28dSOliver Neukum 	} else {
160737093b70SMing Lei 		/* TODO: resume() might need to handle suspend failure */
16089e356208SBenjamin Tissoires 		status = hid_driver_suspend(hid, message);
1609eb055fd0SAlan Stern 		driver_suspended = true;
16100361a28dSOliver Neukum 		spin_lock_irq(&usbhid->lock);
1611f2b5264dSAlan Stern 		set_bit(HID_SUSPENDED, &usbhid->iofl);
16120361a28dSOliver Neukum 		spin_unlock_irq(&usbhid->lock);
161337093b70SMing Lei 		if (usbhid_wait_io(hid) < 0)
1614eb055fd0SAlan Stern 			status = -EIO;
16150361a28dSOliver Neukum 	}
16160361a28dSOliver Neukum 
16170361a28dSOliver Neukum 	hid_cancel_delayed_stuff(usbhid);
16180361a28dSOliver Neukum 	hid_cease_io(usbhid);
16190361a28dSOliver Neukum 
16205b1b0b81SAlan Stern 	if (PMSG_IS_AUTO(message) && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
16210361a28dSOliver Neukum 		/* lost race against keypresses */
1622eb055fd0SAlan Stern 		status = -EBUSY;
1623eb055fd0SAlan Stern 		goto failed;
16240361a28dSOliver Neukum 	}
16256db3dfefSJiri Kosina 	dev_dbg(&intf->dev, "suspend\n");
162637093b70SMing Lei 	return status;
1627eb055fd0SAlan Stern 
1628eb055fd0SAlan Stern  failed:
1629eb055fd0SAlan Stern 	hid_resume_common(hid, driver_suspended);
1630eb055fd0SAlan Stern 	return status;
16316db3dfefSJiri Kosina }
16326db3dfefSJiri Kosina 
hid_resume(struct usb_interface * intf)16336db3dfefSJiri Kosina static int hid_resume(struct usb_interface *intf)
16346db3dfefSJiri Kosina {
16356db3dfefSJiri Kosina 	struct hid_device *hid = usb_get_intfdata (intf);
16366db3dfefSJiri Kosina 	int status;
16376db3dfefSJiri Kosina 
1638eb055fd0SAlan Stern 	status = hid_resume_common(hid, true);
16396db3dfefSJiri Kosina 	dev_dbg(&intf->dev, "resume status %d\n", status);
16406db3dfefSJiri Kosina 	return 0;
16416db3dfefSJiri Kosina }
16426db3dfefSJiri Kosina 
hid_reset_resume(struct usb_interface * intf)1643378a0edeSOliver Neukum static int hid_reset_resume(struct usb_interface *intf)
16446db3dfefSJiri Kosina {
1645378a0edeSOliver Neukum 	struct hid_device *hid = usb_get_intfdata(intf);
16466a740aa4SBruno Prémont 	int status;
16476db3dfefSJiri Kosina 
16486a740aa4SBruno Prémont 	status = hid_post_reset(intf);
16499e356208SBenjamin Tissoires 	if (status >= 0) {
16509e356208SBenjamin Tissoires 		int ret = hid_driver_reset_resume(hid);
16516a740aa4SBruno Prémont 		if (ret < 0)
16526a740aa4SBruno Prémont 			status = ret;
16536a740aa4SBruno Prémont 	}
16546a740aa4SBruno Prémont 	return status;
16556db3dfefSJiri Kosina }
16566db3dfefSJiri Kosina 
1657ae2f0074SJiri Kosina #endif /* CONFIG_PM */
16586db3dfefSJiri Kosina 
1659d67dec5bSMárton Németh static const struct usb_device_id hid_usb_ids[] = {
16606db3dfefSJiri Kosina 	{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
16616db3dfefSJiri Kosina 		.bInterfaceClass = USB_INTERFACE_CLASS_HID },
16626db3dfefSJiri Kosina 	{ }						/* Terminating entry */
16636db3dfefSJiri Kosina };
16646db3dfefSJiri Kosina 
16656db3dfefSJiri Kosina MODULE_DEVICE_TABLE (usb, hid_usb_ids);
16666db3dfefSJiri Kosina 
16676db3dfefSJiri Kosina static struct usb_driver hid_driver = {
16686db3dfefSJiri Kosina 	.name =		"usbhid",
1669c4c259bcSJiri Kosina 	.probe =	usbhid_probe,
1670c4c259bcSJiri Kosina 	.disconnect =	usbhid_disconnect,
16710f6f1407SJiri Kosina #ifdef CONFIG_PM
16726db3dfefSJiri Kosina 	.suspend =	hid_suspend,
16736db3dfefSJiri Kosina 	.resume =	hid_resume,
1674378a0edeSOliver Neukum 	.reset_resume =	hid_reset_resume,
16750f6f1407SJiri Kosina #endif
16766db3dfefSJiri Kosina 	.pre_reset =	hid_pre_reset,
16776db3dfefSJiri Kosina 	.post_reset =	hid_post_reset,
16786db3dfefSJiri Kosina 	.id_table =	hid_usb_ids,
1679933e3187SOliver Neukum 	.supports_autosuspend = 1,
16806db3dfefSJiri Kosina };
16816db3dfefSJiri Kosina 
usbhid_find_interface(int minor)16828fe294caSGuillaume Chazarain struct usb_interface *usbhid_find_interface(int minor)
16838fe294caSGuillaume Chazarain {
16848fe294caSGuillaume Chazarain 	return usb_find_interface(&hid_driver, minor);
16858fe294caSGuillaume Chazarain }
16868fe294caSGuillaume Chazarain 
hid_init(void)16876db3dfefSJiri Kosina static int __init hid_init(void)
16886db3dfefSJiri Kosina {
16898e9ddbdeSColin Ian King 	int retval;
16900361a28dSOliver Neukum 
1691d5d3e202SBenjamin Tissoires 	retval = hid_quirks_init(quirks_param, BUS_USB, MAX_USBHID_BOOT_QUIRKS);
1692876b9276SPaul Walmsley 	if (retval)
1693876b9276SPaul Walmsley 		goto usbhid_quirks_init_fail;
16946db3dfefSJiri Kosina 	retval = usb_register(&hid_driver);
16956db3dfefSJiri Kosina 	if (retval)
16966db3dfefSJiri Kosina 		goto usb_register_fail;
169752150c78SJoe Perches 	pr_info(KBUILD_MODNAME ": " DRIVER_DESC "\n");
16986db3dfefSJiri Kosina 
16996db3dfefSJiri Kosina 	return 0;
17006db3dfefSJiri Kosina usb_register_fail:
1701d5d3e202SBenjamin Tissoires 	hid_quirks_exit(BUS_USB);
1702876b9276SPaul Walmsley usbhid_quirks_init_fail:
17036db3dfefSJiri Kosina 	return retval;
17046db3dfefSJiri Kosina }
17056db3dfefSJiri Kosina 
hid_exit(void)17066db3dfefSJiri Kosina static void __exit hid_exit(void)
17076db3dfefSJiri Kosina {
17086db3dfefSJiri Kosina 	usb_deregister(&hid_driver);
1709d5d3e202SBenjamin Tissoires 	hid_quirks_exit(BUS_USB);
17106db3dfefSJiri Kosina }
17116db3dfefSJiri Kosina 
17126db3dfefSJiri Kosina module_init(hid_init);
17136db3dfefSJiri Kosina module_exit(hid_exit);
17146db3dfefSJiri Kosina 
171588adb72bSJiri Kosina MODULE_AUTHOR("Andreas Gal");
171688adb72bSJiri Kosina MODULE_AUTHOR("Vojtech Pavlik");
171788adb72bSJiri Kosina MODULE_AUTHOR("Jiri Kosina");
17186db3dfefSJiri Kosina MODULE_DESCRIPTION(DRIVER_DESC);
17197021b600SGrant Grundler MODULE_LICENSE("GPL");
1720