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