1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * ISHTP client driver for HID (ISH)
4 *
5 * Copyright (c) 2014-2016, Intel Corporation.
6 */
7
8#include <linux/module.h>
9#include <linux/hid.h>
10#include <linux/intel-ish-client-if.h>
11#include <linux/sched.h>
12#include "ishtp-hid.h"
13
14/* Rx ring buffer pool size */
15#define HID_CL_RX_RING_SIZE	32
16#define HID_CL_TX_RING_SIZE	16
17
18#define cl_data_to_dev(client_data) ishtp_device(client_data->cl_device)
19
20/**
21 * report_bad_packets() - Report bad packets
22 * @hid_ishtp_cl:	Client instance to get stats
23 * @recv_buf:		Raw received host interface message
24 * @cur_pos:		Current position index in payload
25 * @payload_len:	Length of payload expected
26 *
27 * Dumps error in case bad packet is received
28 */
29static void report_bad_packet(struct ishtp_cl *hid_ishtp_cl, void *recv_buf,
30			      size_t cur_pos,  size_t payload_len)
31{
32	struct hostif_msg *recv_msg = recv_buf;
33	struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
34
35	dev_err(cl_data_to_dev(client_data), "[hid-ish]: BAD packet %02X\n"
36		"total_bad=%u cur_pos=%u\n"
37		"[%02X %02X %02X %02X]\n"
38		"payload_len=%u\n"
39		"multi_packet_cnt=%u\n"
40		"is_response=%02X\n",
41		recv_msg->hdr.command, client_data->bad_recv_cnt,
42		(unsigned int)cur_pos,
43		((unsigned char *)recv_msg)[0], ((unsigned char *)recv_msg)[1],
44		((unsigned char *)recv_msg)[2], ((unsigned char *)recv_msg)[3],
45		(unsigned int)payload_len, client_data->multi_packet_cnt,
46		recv_msg->hdr.command & ~CMD_MASK);
47}
48
49/**
50 * process_recv() - Received and parse incoming packet
51 * @hid_ishtp_cl:	Client instance to get stats
52 * @recv_buf:		Raw received host interface message
53 * @data_len:		length of the message
54 *
55 * Parse the incoming packet. If it is a response packet then it will update
56 * per instance flags and wake up the caller waiting to for the response.
57 */
58static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf,
59			 size_t data_len)
60{
61	struct hostif_msg *recv_msg;
62	unsigned char *payload;
63	struct device_info *dev_info;
64	int i, j;
65	size_t	payload_len, total_len, cur_pos, raw_len;
66	int report_type;
67	struct report_list *reports_list;
68	char *reports;
69	size_t report_len;
70	struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
71	int curr_hid_dev = client_data->cur_hid_dev;
72	struct ishtp_hid_data *hid_data = NULL;
73	struct hid_device *hid = NULL;
74
75	payload = recv_buf + sizeof(struct hostif_msg_hdr);
76	total_len = data_len;
77	cur_pos = 0;
78
79	do {
80		if (cur_pos + sizeof(struct hostif_msg) > total_len) {
81			dev_err(cl_data_to_dev(client_data),
82				"[hid-ish]: error, received %u which is less than data header %u\n",
83				(unsigned int)data_len,
84				(unsigned int)sizeof(struct hostif_msg_hdr));
85			++client_data->bad_recv_cnt;
86			ish_hw_reset(ishtp_get_ishtp_device(hid_ishtp_cl));
87			break;
88		}
89
90		recv_msg = (struct hostif_msg *)(recv_buf + cur_pos);
91		payload_len = recv_msg->hdr.size;
92
93		/* Sanity checks */
94		if (cur_pos + payload_len + sizeof(struct hostif_msg) >
95				total_len) {
96			++client_data->bad_recv_cnt;
97			report_bad_packet(hid_ishtp_cl, recv_msg, cur_pos,
98					  payload_len);
99			ish_hw_reset(ishtp_get_ishtp_device(hid_ishtp_cl));
100			break;
101		}
102
103		hid_ishtp_trace(client_data,  "%s %d\n",
104				__func__, recv_msg->hdr.command & CMD_MASK);
105
106		switch (recv_msg->hdr.command & CMD_MASK) {
107		case HOSTIF_DM_ENUM_DEVICES:
108			if ((!(recv_msg->hdr.command & ~CMD_MASK) ||
109					client_data->init_done)) {
110				++client_data->bad_recv_cnt;
111				report_bad_packet(hid_ishtp_cl, recv_msg,
112						  cur_pos,
113						  payload_len);
114				ish_hw_reset(ishtp_get_ishtp_device(hid_ishtp_cl));
115				break;
116			}
117			client_data->hid_dev_count = (unsigned int)*payload;
118			if (!client_data->hid_devices)
119				client_data->hid_devices = devm_kcalloc(
120						cl_data_to_dev(client_data),
121						client_data->hid_dev_count,
122						sizeof(struct device_info),
123						GFP_KERNEL);
124			if (!client_data->hid_devices) {
125				dev_err(cl_data_to_dev(client_data),
126				"Mem alloc failed for hid device info\n");
127				wake_up_interruptible(&client_data->init_wait);
128				break;
129			}
130			for (i = 0; i < client_data->hid_dev_count; ++i) {
131				if (1 + sizeof(struct device_info) * i >=
132						payload_len) {
133					dev_err(cl_data_to_dev(client_data),
134						"[hid-ish]: [ENUM_DEVICES]: content size %zu is bigger than payload_len %zu\n",
135						1 + sizeof(struct device_info)
136						* i, payload_len);
137				}
138
139				if (1 + sizeof(struct device_info) * i >=
140						data_len)
141					break;
142
143				dev_info = (struct device_info *)(payload + 1 +
144					sizeof(struct device_info) * i);
145				if (client_data->hid_devices)
146					memcpy(client_data->hid_devices + i,
147					       dev_info,
148					       sizeof(struct device_info));
149			}
150
151			client_data->enum_devices_done = true;
152			wake_up_interruptible(&client_data->init_wait);
153
154			break;
155
156		case HOSTIF_GET_HID_DESCRIPTOR:
157			if ((!(recv_msg->hdr.command & ~CMD_MASK) ||
158					client_data->init_done)) {
159				++client_data->bad_recv_cnt;
160				report_bad_packet(hid_ishtp_cl, recv_msg,
161						  cur_pos,
162						  payload_len);
163				ish_hw_reset(ishtp_get_ishtp_device(hid_ishtp_cl));
164				break;
165			}
166			if (!client_data->hid_descr[curr_hid_dev])
167				client_data->hid_descr[curr_hid_dev] =
168				devm_kmalloc(cl_data_to_dev(client_data),
169					     payload_len, GFP_KERNEL);
170			if (client_data->hid_descr[curr_hid_dev]) {
171				memcpy(client_data->hid_descr[curr_hid_dev],
172				       payload, payload_len);
173				client_data->hid_descr_size[curr_hid_dev] =
174					payload_len;
175				client_data->hid_descr_done = true;
176			}
177			wake_up_interruptible(&client_data->init_wait);
178
179			break;
180
181		case HOSTIF_GET_REPORT_DESCRIPTOR:
182			if ((!(recv_msg->hdr.command & ~CMD_MASK) ||
183					client_data->init_done)) {
184				++client_data->bad_recv_cnt;
185				report_bad_packet(hid_ishtp_cl, recv_msg,
186						  cur_pos,
187						  payload_len);
188				ish_hw_reset(ishtp_get_ishtp_device(hid_ishtp_cl));
189				break;
190			}
191			if (!client_data->report_descr[curr_hid_dev])
192				client_data->report_descr[curr_hid_dev] =
193				devm_kmalloc(cl_data_to_dev(client_data),
194					     payload_len, GFP_KERNEL);
195			if (client_data->report_descr[curr_hid_dev])  {
196				memcpy(client_data->report_descr[curr_hid_dev],
197				       payload,
198				       payload_len);
199				client_data->report_descr_size[curr_hid_dev] =
200					payload_len;
201				client_data->report_descr_done = true;
202			}
203			wake_up_interruptible(&client_data->init_wait);
204
205			break;
206
207		case HOSTIF_GET_FEATURE_REPORT:
208			report_type = HID_FEATURE_REPORT;
209			goto	do_get_report;
210
211		case HOSTIF_GET_INPUT_REPORT:
212			report_type = HID_INPUT_REPORT;
213do_get_report:
214			/* Get index of device that matches this id */
215			for (i = 0; i < client_data->num_hid_devices; ++i) {
216				if (recv_msg->hdr.device_id ==
217					  client_data->hid_devices[i].dev_id) {
218					hid = client_data->hid_sensor_hubs[i];
219					if (!hid)
220						break;
221
222					hid_data = hid->driver_data;
223					if (hid_data->raw_get_req) {
224						raw_len =
225						  (hid_data->raw_buf_size <
226								payload_len) ?
227						  hid_data->raw_buf_size :
228						  payload_len;
229
230						memcpy(hid_data->raw_buf,
231						       payload, raw_len);
232					} else {
233						hid_input_report
234							(hid, report_type,
235							 payload, payload_len,
236							 0);
237					}
238
239					ishtp_hid_wakeup(hid);
240					break;
241				}
242			}
243			break;
244
245		case HOSTIF_SET_FEATURE_REPORT:
246			/* Get index of device that matches this id */
247			for (i = 0; i < client_data->num_hid_devices; ++i) {
248				if (recv_msg->hdr.device_id ==
249					client_data->hid_devices[i].dev_id)
250					if (client_data->hid_sensor_hubs[i]) {
251						ishtp_hid_wakeup(
252						client_data->hid_sensor_hubs[
253							i]);
254						break;
255					}
256			}
257			break;
258
259		case HOSTIF_PUBLISH_INPUT_REPORT:
260			report_type = HID_INPUT_REPORT;
261			for (i = 0; i < client_data->num_hid_devices; ++i)
262				if (recv_msg->hdr.device_id ==
263					client_data->hid_devices[i].dev_id)
264					if (client_data->hid_sensor_hubs[i])
265						hid_input_report(
266						client_data->hid_sensor_hubs[
267									i],
268						report_type, payload,
269						payload_len, 0);
270			break;
271
272		case HOSTIF_PUBLISH_INPUT_REPORT_LIST:
273			report_type = HID_INPUT_REPORT;
274			reports_list = (struct report_list *)payload;
275			reports = (char *)reports_list->reports;
276
277			for (j = 0; j < reports_list->num_of_reports; j++) {
278				recv_msg = (struct hostif_msg *)(reports +
279					sizeof(uint16_t));
280				report_len = *(uint16_t *)reports;
281				payload = reports + sizeof(uint16_t) +
282					sizeof(struct hostif_msg_hdr);
283				payload_len = report_len -
284					sizeof(struct hostif_msg_hdr);
285
286				for (i = 0; i < client_data->num_hid_devices;
287				     ++i)
288					if (recv_msg->hdr.device_id ==
289					client_data->hid_devices[i].dev_id &&
290					client_data->hid_sensor_hubs[i]) {
291						hid_input_report(
292						client_data->hid_sensor_hubs[
293									i],
294						report_type,
295						payload, payload_len,
296						0);
297					}
298
299				reports += sizeof(uint16_t) + report_len;
300			}
301			break;
302		default:
303			++client_data->bad_recv_cnt;
304			report_bad_packet(hid_ishtp_cl, recv_msg, cur_pos,
305					  payload_len);
306			ish_hw_reset(ishtp_get_ishtp_device(hid_ishtp_cl));
307			break;
308
309		}
310
311		if (!cur_pos && cur_pos + payload_len +
312				sizeof(struct hostif_msg) < total_len)
313			++client_data->multi_packet_cnt;
314
315		cur_pos += payload_len + sizeof(struct hostif_msg);
316		payload += payload_len + sizeof(struct hostif_msg);
317
318	} while (cur_pos < total_len);
319}
320
321/**
322 * ish_cl_event_cb() - bus driver callback for incoming message/packet
323 * @device:	Pointer to the the ishtp client device for which this message
324 *		is targeted
325 *
326 * Remove the packet from the list and process the message by calling
327 * process_recv
328 */
329static void ish_cl_event_cb(struct ishtp_cl_device *device)
330{
331	struct ishtp_cl	*hid_ishtp_cl = ishtp_get_drvdata(device);
332	struct ishtp_cl_rb *rb_in_proc;
333	size_t r_length;
334
335	if (!hid_ishtp_cl)
336		return;
337
338	while ((rb_in_proc = ishtp_cl_rx_get_rb(hid_ishtp_cl)) != NULL) {
339		if (!rb_in_proc->buffer.data)
340			return;
341
342		r_length = rb_in_proc->buf_idx;
343
344		/* decide what to do with received data */
345		process_recv(hid_ishtp_cl, rb_in_proc->buffer.data, r_length);
346
347		ishtp_cl_io_rb_recycle(rb_in_proc);
348	}
349}
350
351/**
352 * hid_ishtp_set_feature() - send request to ISH FW to set a feature request
353 * @hid:	hid device instance for this request
354 * @buf:	feature buffer
355 * @len:	Length of feature buffer
356 * @report_id:	Report id for the feature set request
357 *
358 * This is called from hid core .request() callback. This function doesn't wait
359 * for response.
360 */
361void hid_ishtp_set_feature(struct hid_device *hid, char *buf, unsigned int len,
362			   int report_id)
363{
364	struct ishtp_hid_data *hid_data =  hid->driver_data;
365	struct ishtp_cl_data *client_data = hid_data->client_data;
366	struct hostif_msg *msg = (struct hostif_msg *)buf;
367	int	rv;
368	int	i;
369
370	hid_ishtp_trace(client_data,  "%s hid %p\n", __func__, hid);
371
372	rv = ishtp_hid_link_ready_wait(client_data);
373	if (rv) {
374		hid_ishtp_trace(client_data,  "%s hid %p link not ready\n",
375				__func__, hid);
376		return;
377	}
378
379	memset(msg, 0, sizeof(struct hostif_msg));
380	msg->hdr.command = HOSTIF_SET_FEATURE_REPORT;
381	for (i = 0; i < client_data->num_hid_devices; ++i) {
382		if (hid == client_data->hid_sensor_hubs[i]) {
383			msg->hdr.device_id =
384				client_data->hid_devices[i].dev_id;
385			break;
386		}
387	}
388
389	if (i == client_data->num_hid_devices)
390		return;
391
392	rv = ishtp_cl_send(client_data->hid_ishtp_cl, buf, len);
393	if (rv)
394		hid_ishtp_trace(client_data,  "%s hid %p send failed\n",
395				__func__, hid);
396}
397
398/**
399 * hid_ishtp_get_report() - request to get feature/input report
400 * @hid:	hid device instance for this request
401 * @report_id:	Report id for the get request
402 * @report_type:	Report type for the this request
403 *
404 * This is called from hid core .request() callback. This function will send
405 * request to FW and return without waiting for response.
406 */
407void hid_ishtp_get_report(struct hid_device *hid, int report_id,
408			  int report_type)
409{
410	struct ishtp_hid_data *hid_data =  hid->driver_data;
411	struct ishtp_cl_data *client_data = hid_data->client_data;
412	struct hostif_msg_to_sensor msg = {};
413	int	rv;
414	int	i;
415
416	hid_ishtp_trace(client_data,  "%s hid %p\n", __func__, hid);
417	rv = ishtp_hid_link_ready_wait(client_data);
418	if (rv) {
419		hid_ishtp_trace(client_data,  "%s hid %p link not ready\n",
420				__func__, hid);
421		return;
422	}
423
424	msg.hdr.command = (report_type == HID_FEATURE_REPORT) ?
425		HOSTIF_GET_FEATURE_REPORT : HOSTIF_GET_INPUT_REPORT;
426	for (i = 0; i < client_data->num_hid_devices; ++i) {
427		if (hid == client_data->hid_sensor_hubs[i]) {
428			msg.hdr.device_id =
429				client_data->hid_devices[i].dev_id;
430			break;
431		}
432	}
433
434	if (i == client_data->num_hid_devices)
435		return;
436
437	msg.report_id = report_id;
438	rv = ishtp_cl_send(client_data->hid_ishtp_cl, (uint8_t *)&msg,
439			    sizeof(msg));
440	if (rv)
441		hid_ishtp_trace(client_data,  "%s hid %p send failed\n",
442				__func__, hid);
443}
444
445/**
446 * ishtp_hid_link_ready_wait() - Wait for link ready
447 * @client_data:	client data instance
448 *
449 * If the transport link started suspend process, then wait, till either
450 * resumed or timeout
451 *
452 * Return: 0 on success, non zero on error
453 */
454int ishtp_hid_link_ready_wait(struct ishtp_cl_data *client_data)
455{
456	int rc;
457
458	if (client_data->suspended) {
459		hid_ishtp_trace(client_data,  "wait for link ready\n");
460		rc = wait_event_interruptible_timeout(
461					client_data->ishtp_resume_wait,
462					!client_data->suspended,
463					5 * HZ);
464
465		if (rc == 0) {
466			hid_ishtp_trace(client_data,  "link not ready\n");
467			return -EIO;
468		}
469		hid_ishtp_trace(client_data,  "link ready\n");
470	}
471
472	return 0;
473}
474
475/**
476 * ishtp_enum_enum_devices() - Enumerate hid devices
477 * @hid_ishtp_cl:	client instance
478 *
479 * Helper function to send request to firmware to enumerate HID devices
480 *
481 * Return: 0 on success, non zero on error
482 */
483static int ishtp_enum_enum_devices(struct ishtp_cl *hid_ishtp_cl)
484{
485	struct hostif_msg msg;
486	struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
487	int retry_count;
488	int rv;
489
490	/* Send HOSTIF_DM_ENUM_DEVICES */
491	memset(&msg, 0, sizeof(struct hostif_msg));
492	msg.hdr.command = HOSTIF_DM_ENUM_DEVICES;
493	rv = ishtp_cl_send(hid_ishtp_cl, (unsigned char *)&msg,
494			   sizeof(struct hostif_msg));
495	if (rv)
496		return rv;
497
498	retry_count = 0;
499	while (!client_data->enum_devices_done &&
500	       retry_count < 10) {
501		wait_event_interruptible_timeout(client_data->init_wait,
502					 client_data->enum_devices_done,
503					 3 * HZ);
504		++retry_count;
505		if (!client_data->enum_devices_done)
506			/* Send HOSTIF_DM_ENUM_DEVICES */
507			rv = ishtp_cl_send(hid_ishtp_cl,
508					   (unsigned char *) &msg,
509					   sizeof(struct hostif_msg));
510	}
511	if (!client_data->enum_devices_done) {
512		dev_err(cl_data_to_dev(client_data),
513			"[hid-ish]: timed out waiting for enum_devices\n");
514		return -ETIMEDOUT;
515	}
516	if (!client_data->hid_devices) {
517		dev_err(cl_data_to_dev(client_data),
518			"[hid-ish]: failed to allocate HID dev structures\n");
519		return -ENOMEM;
520	}
521
522	client_data->num_hid_devices = client_data->hid_dev_count;
523	dev_info(ishtp_device(client_data->cl_device),
524		"[hid-ish]: enum_devices_done OK, num_hid_devices=%d\n",
525		client_data->num_hid_devices);
526
527	return	0;
528}
529
530/**
531 * ishtp_get_hid_descriptor() - Get hid descriptor
532 * @hid_ishtp_cl:	client instance
533 * @index:		Index into the hid_descr array
534 *
535 * Helper function to send request to firmware get HID descriptor of a device
536 *
537 * Return: 0 on success, non zero on error
538 */
539static int ishtp_get_hid_descriptor(struct ishtp_cl *hid_ishtp_cl, int index)
540{
541	struct hostif_msg msg;
542	struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
543	int rv;
544
545	/* Get HID descriptor */
546	client_data->hid_descr_done = false;
547	memset(&msg, 0, sizeof(struct hostif_msg));
548	msg.hdr.command = HOSTIF_GET_HID_DESCRIPTOR;
549	msg.hdr.device_id = client_data->hid_devices[index].dev_id;
550	rv = ishtp_cl_send(hid_ishtp_cl, (unsigned char *) &msg,
551			   sizeof(struct hostif_msg));
552	if (rv)
553		return rv;
554
555	if (!client_data->hid_descr_done) {
556		wait_event_interruptible_timeout(client_data->init_wait,
557						 client_data->hid_descr_done,
558						 3 * HZ);
559		if (!client_data->hid_descr_done) {
560			dev_err(cl_data_to_dev(client_data),
561				"[hid-ish]: timed out for hid_descr_done\n");
562			return -EIO;
563		}
564
565		if (!client_data->hid_descr[index]) {
566			dev_err(cl_data_to_dev(client_data),
567				"[hid-ish]: allocation HID desc fail\n");
568			return -ENOMEM;
569		}
570	}
571
572	return 0;
573}
574
575/**
576 * ishtp_get_report_descriptor() - Get report descriptor
577 * @hid_ishtp_cl:	client instance
578 * @index:		Index into the hid_descr array
579 *
580 * Helper function to send request to firmware get HID report descriptor of
581 * a device
582 *
583 * Return: 0 on success, non zero on error
584 */
585static int ishtp_get_report_descriptor(struct ishtp_cl *hid_ishtp_cl,
586				       int index)
587{
588	struct hostif_msg msg;
589	struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
590	int rv;
591
592	/* Get report descriptor */
593	client_data->report_descr_done = false;
594	memset(&msg, 0, sizeof(struct hostif_msg));
595	msg.hdr.command = HOSTIF_GET_REPORT_DESCRIPTOR;
596	msg.hdr.device_id = client_data->hid_devices[index].dev_id;
597	rv = ishtp_cl_send(hid_ishtp_cl, (unsigned char *) &msg,
598			   sizeof(struct hostif_msg));
599	if (rv)
600		return rv;
601
602	if (!client_data->report_descr_done)
603		wait_event_interruptible_timeout(client_data->init_wait,
604					 client_data->report_descr_done,
605					 3 * HZ);
606	if (!client_data->report_descr_done) {
607		dev_err(cl_data_to_dev(client_data),
608				"[hid-ish]: timed out for report descr\n");
609		return -EIO;
610	}
611	if (!client_data->report_descr[index]) {
612		dev_err(cl_data_to_dev(client_data),
613			"[hid-ish]: failed to alloc report descr\n");
614		return -ENOMEM;
615	}
616
617	return 0;
618}
619
620/**
621 * hid_ishtp_cl_init() - Init function for ISHTP client
622 * @hid_ishtp_cl:	ISHTP client instance
623 * @reset:		true if called for init after reset
624 *
625 * This function complete the initializtion of the client. The summary of
626 * processing:
627 * - Send request to enumerate the hid clients
628 *	Get the HID descriptor for each enumearated device
629 *	Get report description of each device
630 *	Register each device wik hid core by calling ishtp_hid_probe
631 *
632 * Return: 0 on success, non zero on error
633 */
634static int hid_ishtp_cl_init(struct ishtp_cl *hid_ishtp_cl, int reset)
635{
636	struct ishtp_device *dev;
637	struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
638	struct ishtp_fw_client *fw_client;
639	int i;
640	int rv;
641
642	dev_dbg(cl_data_to_dev(client_data), "%s\n", __func__);
643	hid_ishtp_trace(client_data,  "%s reset flag: %d\n", __func__, reset);
644
645	rv = ishtp_cl_link(hid_ishtp_cl);
646	if (rv) {
647		dev_err(cl_data_to_dev(client_data),
648			"ishtp_cl_link failed\n");
649		return	-ENOMEM;
650	}
651
652	client_data->init_done = 0;
653
654	dev = ishtp_get_ishtp_device(hid_ishtp_cl);
655
656	/* Connect to FW client */
657	ishtp_set_tx_ring_size(hid_ishtp_cl, HID_CL_TX_RING_SIZE);
658	ishtp_set_rx_ring_size(hid_ishtp_cl, HID_CL_RX_RING_SIZE);
659
660	fw_client = ishtp_fw_cl_get_client(dev, &hid_ishtp_guid);
661	if (!fw_client) {
662		dev_err(cl_data_to_dev(client_data),
663			"ish client uuid not found\n");
664		return -ENOENT;
665	}
666	ishtp_cl_set_fw_client_id(hid_ishtp_cl,
667				  ishtp_get_fw_client_id(fw_client));
668	ishtp_set_connection_state(hid_ishtp_cl, ISHTP_CL_CONNECTING);
669
670	rv = ishtp_cl_connect(hid_ishtp_cl);
671	if (rv) {
672		dev_err(cl_data_to_dev(client_data),
673			"client connect fail\n");
674		goto err_cl_unlink;
675	}
676
677	hid_ishtp_trace(client_data,  "%s client connected\n", __func__);
678
679	/* Register read callback */
680	ishtp_register_event_cb(client_data->cl_device, ish_cl_event_cb);
681
682	rv = ishtp_enum_enum_devices(hid_ishtp_cl);
683	if (rv)
684		goto err_cl_disconnect;
685
686	hid_ishtp_trace(client_data,  "%s enumerated device count %d\n",
687			__func__, client_data->num_hid_devices);
688
689	for (i = 0; i < client_data->num_hid_devices; ++i) {
690		client_data->cur_hid_dev = i;
691
692		rv = ishtp_get_hid_descriptor(hid_ishtp_cl, i);
693		if (rv)
694			goto err_cl_disconnect;
695
696		rv = ishtp_get_report_descriptor(hid_ishtp_cl, i);
697		if (rv)
698			goto err_cl_disconnect;
699
700		if (!reset) {
701			rv = ishtp_hid_probe(i, client_data);
702			if (rv) {
703				dev_err(cl_data_to_dev(client_data),
704				"[hid-ish]: HID probe for #%u failed: %d\n",
705				i, rv);
706				goto err_cl_disconnect;
707			}
708		}
709	} /* for() on all hid devices */
710
711	client_data->init_done = 1;
712	client_data->suspended = false;
713	wake_up_interruptible(&client_data->ishtp_resume_wait);
714	hid_ishtp_trace(client_data,  "%s successful init\n", __func__);
715	return 0;
716
717err_cl_disconnect:
718	ishtp_set_connection_state(hid_ishtp_cl, ISHTP_CL_DISCONNECTING);
719	ishtp_cl_disconnect(hid_ishtp_cl);
720err_cl_unlink:
721	ishtp_cl_unlink(hid_ishtp_cl);
722	return rv;
723}
724
725/**
726 * hid_ishtp_cl_deinit() - Deinit function for ISHTP client
727 * @hid_ishtp_cl:	ISHTP client instance
728 *
729 * Unlink and free hid client
730 */
731static void hid_ishtp_cl_deinit(struct ishtp_cl *hid_ishtp_cl)
732{
733	ishtp_cl_unlink(hid_ishtp_cl);
734	ishtp_cl_flush_queues(hid_ishtp_cl);
735
736	/* disband and free all Tx and Rx client-level rings */
737	ishtp_cl_free(hid_ishtp_cl);
738}
739
740static void hid_ishtp_cl_reset_handler(struct work_struct *work)
741{
742	struct ishtp_cl_data *client_data;
743	struct ishtp_cl *hid_ishtp_cl;
744	struct ishtp_cl_device *cl_device;
745	int retry;
746	int rv;
747
748	client_data = container_of(work, struct ishtp_cl_data, work);
749
750	hid_ishtp_cl = client_data->hid_ishtp_cl;
751	cl_device = client_data->cl_device;
752
753	hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
754			hid_ishtp_cl);
755	dev_dbg(ishtp_device(client_data->cl_device), "%s\n", __func__);
756
757	hid_ishtp_cl_deinit(hid_ishtp_cl);
758
759	hid_ishtp_cl = ishtp_cl_allocate(cl_device);
760	if (!hid_ishtp_cl)
761		return;
762
763	ishtp_set_drvdata(cl_device, hid_ishtp_cl);
764	ishtp_set_client_data(hid_ishtp_cl, client_data);
765	client_data->hid_ishtp_cl = hid_ishtp_cl;
766
767	client_data->num_hid_devices = 0;
768
769	for (retry = 0; retry < 3; ++retry) {
770		rv = hid_ishtp_cl_init(hid_ishtp_cl, 1);
771		if (!rv)
772			break;
773		dev_err(cl_data_to_dev(client_data), "Retry reset init\n");
774	}
775	if (rv) {
776		dev_err(cl_data_to_dev(client_data), "Reset Failed\n");
777		hid_ishtp_trace(client_data, "%s Failed hid_ishtp_cl %p\n",
778				__func__, hid_ishtp_cl);
779	}
780}
781
782void (*hid_print_trace)(void *unused, const char *format, ...);
783
784/**
785 * hid_ishtp_cl_probe() - ISHTP client driver probe
786 * @cl_device:		ISHTP client device instance
787 *
788 * This function gets called on device create on ISHTP bus
789 *
790 * Return: 0 on success, non zero on error
791 */
792static int hid_ishtp_cl_probe(struct ishtp_cl_device *cl_device)
793{
794	struct ishtp_cl *hid_ishtp_cl;
795	struct ishtp_cl_data *client_data;
796	int rv;
797
798	if (!cl_device)
799		return	-ENODEV;
800
801	client_data = devm_kzalloc(ishtp_device(cl_device),
802				   sizeof(*client_data),
803				   GFP_KERNEL);
804	if (!client_data)
805		return -ENOMEM;
806
807	hid_ishtp_cl = ishtp_cl_allocate(cl_device);
808	if (!hid_ishtp_cl)
809		return -ENOMEM;
810
811	ishtp_set_drvdata(cl_device, hid_ishtp_cl);
812	ishtp_set_client_data(hid_ishtp_cl, client_data);
813	client_data->hid_ishtp_cl = hid_ishtp_cl;
814	client_data->cl_device = cl_device;
815
816	init_waitqueue_head(&client_data->init_wait);
817	init_waitqueue_head(&client_data->ishtp_resume_wait);
818
819	INIT_WORK(&client_data->work, hid_ishtp_cl_reset_handler);
820
821	hid_print_trace = ishtp_trace_callback(cl_device);
822
823	rv = hid_ishtp_cl_init(hid_ishtp_cl, 0);
824	if (rv) {
825		ishtp_cl_free(hid_ishtp_cl);
826		return rv;
827	}
828	ishtp_get_device(cl_device);
829
830	return 0;
831}
832
833/**
834 * hid_ishtp_cl_remove() - ISHTP client driver remove
835 * @cl_device:		ISHTP client device instance
836 *
837 * This function gets called on device remove on ISHTP bus
838 *
839 * Return: 0
840 */
841static int hid_ishtp_cl_remove(struct ishtp_cl_device *cl_device)
842{
843	struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
844	struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
845
846	hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
847			hid_ishtp_cl);
848
849	dev_dbg(ishtp_device(cl_device), "%s\n", __func__);
850	ishtp_set_connection_state(hid_ishtp_cl, ISHTP_CL_DISCONNECTING);
851	ishtp_cl_disconnect(hid_ishtp_cl);
852	ishtp_put_device(cl_device);
853	ishtp_hid_remove(client_data);
854	hid_ishtp_cl_deinit(hid_ishtp_cl);
855
856	hid_ishtp_cl = NULL;
857
858	client_data->num_hid_devices = 0;
859
860	return 0;
861}
862
863/**
864 * hid_ishtp_cl_reset() - ISHTP client driver reset
865 * @cl_device:		ISHTP client device instance
866 *
867 * This function gets called on device reset on ISHTP bus
868 *
869 * Return: 0
870 */
871static int hid_ishtp_cl_reset(struct ishtp_cl_device *cl_device)
872{
873	struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
874	struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
875
876	hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
877			hid_ishtp_cl);
878
879	schedule_work(&client_data->work);
880
881	return 0;
882}
883
884/**
885 * hid_ishtp_cl_suspend() - ISHTP client driver suspend
886 * @device:	device instance
887 *
888 * This function gets called on system suspend
889 *
890 * Return: 0
891 */
892static int hid_ishtp_cl_suspend(struct device *device)
893{
894	struct ishtp_cl_device *cl_device = ishtp_dev_to_cl_device(device);
895	struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
896	struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
897
898	hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
899			hid_ishtp_cl);
900	client_data->suspended = true;
901
902	return 0;
903}
904
905/**
906 * hid_ishtp_cl_resume() - ISHTP client driver resume
907 * @device:	device instance
908 *
909 * This function gets called on system resume
910 *
911 * Return: 0
912 */
913static int hid_ishtp_cl_resume(struct device *device)
914{
915	struct ishtp_cl_device *cl_device = ishtp_dev_to_cl_device(device);
916	struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
917	struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
918
919	hid_ishtp_trace(client_data, "%s hid_ishtp_cl %p\n", __func__,
920			hid_ishtp_cl);
921	client_data->suspended = false;
922	return 0;
923}
924
925static const struct dev_pm_ops hid_ishtp_pm_ops = {
926	.suspend = hid_ishtp_cl_suspend,
927	.resume = hid_ishtp_cl_resume,
928};
929
930static struct ishtp_cl_driver	hid_ishtp_cl_driver = {
931	.name = "ish-hid",
932	.guid = &hid_ishtp_guid,
933	.probe = hid_ishtp_cl_probe,
934	.remove = hid_ishtp_cl_remove,
935	.reset = hid_ishtp_cl_reset,
936	.driver.pm = &hid_ishtp_pm_ops,
937};
938
939static int __init ish_hid_init(void)
940{
941	int	rv;
942
943	/* Register ISHTP client device driver with ISHTP Bus */
944	rv = ishtp_cl_driver_register(&hid_ishtp_cl_driver, THIS_MODULE);
945
946	return rv;
947
948}
949
950static void __exit ish_hid_exit(void)
951{
952	ishtp_cl_driver_unregister(&hid_ishtp_cl_driver);
953}
954
955late_initcall(ish_hid_init);
956module_exit(ish_hid_exit);
957
958MODULE_DESCRIPTION("ISH ISHTP HID client driver");
959/* Primary author */
960MODULE_AUTHOR("Daniel Drubin <daniel.drubin@intel.com>");
961/*
962 * Several modification for multi instance support
963 * suspend/resume and clean up
964 */
965MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
966
967MODULE_LICENSE("GPL");
968MODULE_ALIAS("ishtp:*");
969