1/* ---------------------------------------------------------------------------- 2 * Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved. 3 * Description: LiteOS USB Driver HID Protocol 4 * Author: wanghongxu 5 * Create: 2019-10-24 6 * Redistribution and use in source and binary forms, with or without modification, 7 * are permitted provided that the following conditions are met: 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 * of conditions and the following disclaimer in the documentation and/or other materials 12 * provided with the distribution. 13 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 14 * to endorse or promote products derived from this software without specific prior written 15 * permission. 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * --------------------------------------------------------------------------- */ 28/* ---------------------------------------------------------------------------- 29 * Notice of Export Control Law 30 * =============================================== 31 * Huawei LiteOS may be subject to applicable export control laws and regulations, which might 32 * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. 33 * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such 34 * applicable export control laws and regulations. 35 * --------------------------------------------------------------------------- */ 36 37#include "gadget/f_hid.h" 38#include "gadget/usbd_hid.h" 39#include "core/usbhid.h" 40#include "implementation/global_implementation.h" 41#ifdef LOSCFG_DRIVERS_USB2_DEVICE_CONTROLLER 42#include "controller/usb_device/dwc_otg_pcd.h" 43#endif 44 45#ifdef __cplusplus 46#if __cplusplus 47extern "C" { 48#endif /* __cplusplus */ 49#endif /* __cplusplus */ 50 51int usbdev_hid_initialize(struct module *mod, int n, void *arg); 52 53/* device driver structure definition */ 54 55static const driver_t g_fhid_driver = 56{ 57 .name = "fhid", 58 .methods = NULL, 59 .size = sizeof(struct hid_softc) 60}; 61 62/* private device class information */ 63 64static devclass_t g_fhid_devclass; 65DRIVER_MODULE(fhid, simple, g_fhid_driver, g_fhid_devclass, usbdev_hid_initialize, 0); 66 67static int usbclass_hid_bind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev); 68static int usbclass_hid_unbind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev); 69static int usbclass_hid_setup(struct usbdevclass_driver_s *driver, struct usbdev_s *dev, 70 const struct usb_device_request *ctrl, uint8_t *dataout, size_t outlen); 71static void usbclass_hid_disconnect(struct usbdevclass_driver_s *driver, struct usbdev_s *dev); 72 73/* USB driver operations */ 74 75static const struct usbdevclass_driverops_s g_hid_driverops = 76{ 77 usbclass_hid_bind, 78 usbclass_hid_unbind, 79 usbclass_hid_setup, 80 usbclass_hid_disconnect, 81 NULL, 82 NULL 83}; 84 85static struct dev_report_desc g_fhid_report_desc; 86 87#define HID_STRING_HEAD_LEN 2 88#define HID_STRING_DESC_NUM 3 89#define HID_STRING_LEN_MAX 0xFF 90 91#define HID_STR_LANG 4 92static const char g_fhid_str_lang[HID_STR_LANG] = 93{ 94 HID_STR_LANG, 95 UDESC_STRING, 96 0x09, 0x04 97}; 98 99#define HID_STR_IDX_INTERFACE 28 100static const char g_fhid_str_interface[HID_STR_IDX_INTERFACE] = 101{ 102 HID_STR_IDX_INTERFACE, 103 UDESC_STRING, 104 'H', 0, 'I', 0, 'D', 0, ' ', 0, 'I', 0, 'n', 0, 't', 0, 105 'e', 0, 'r', 0, 'f', 0, 'a', 0, 'c', 0, 'e', 0 106}; 107 108struct usbd_string g_fhid_device_strings[6] = 109{ 110 { 0, g_fhid_str_lang }, 111 { 1, NULL }, 112 { 2, NULL }, 113 { 3, NULL }, 114 { 4, g_fhid_str_interface }, 115 USBD_DEVICE_STRINGS_END 116}; 117 118static struct usb_device_descriptor g_fhid_device_desc = 119{ 120 .bLength = sizeof(struct usb_device_descriptor), 121 .bDescriptorType = UDESC_DEVICE, /* Constant for device descriptor */ 122 HSETW(.bcdUSB, UD_BCD_USB), /* USB version required: 2.0 */ 123 .bDeviceClass = 0x00, /* Miscellaneous Device Class */ 124 .bDeviceSubClass = 0x00, /* Common Class */ 125 .bDeviceProtocol = 0x00, /* Interface Association Descriptor */ 126 .bMaxPacketSize = UD_USB_MPS, /* Control Endpoint packet size */ 127 HSETW(.bcdDevice, 0x0100), /* Device release code */ 128 .iManufacturer = 1, /* Manufacturer name, string index */ 129 .iProduct = 2, /* Product name, string index */ 130 .iSerialNumber = 3, /* Used */ 131 .bNumConfigurations = 1 /* One Configuration */ 132}; 133 134static struct usb_config_descriptor g_fhid_config_desc = 135{ 136 .bLength = sizeof(struct usb_config_descriptor), 137 .bDescriptorType = UDESC_CONFIG, 138 HSETW(.wTotalLength, 0x0029), /* Size of all descriptors, set later */ 139 .bNumInterface = 0x1, /* Number of Interfaces */ 140 .bConfigurationValue = 0x1, /* ID of this configuration */ 141 .iConfiguration = 0x0, /* Index of string descriptor */ 142 .bmAttributes = 0xc0, /* Self-powered */ 143 .bMaxPower = 0x32 /* Maximum power consumption from the bus */ 144}; 145 146static const struct usb_interface_descriptor g_fhid_intf_desc = 147{ 148 .bLength = sizeof(struct usb_interface_descriptor), 149 .bDescriptorType = UDESC_INTERFACE, 150 .bInterfaceNumber = 0, /* index number of this interface */ 151 .bAlternateSetting = 0, /* index of this settings */ 152 .bNumEndpoints = 2, /* Number of endpoint */ 153 .bInterfaceClass = 0x03, /* bInterfaceClass: HID */ 154 .bInterfaceSubClass = 0, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ 155 .bInterfaceProtocol = 0, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ 156 .iInterface = 4 /* index of string descriptor */ 157}; 158 159static struct usb_hid_descriptor g_fhid_desc = 160{ 161 .bLength = sizeof(struct usb_hid_descriptor), 162 .bDescriptorType = UDESC_HID, /* HID type is 0x21 */ 163 HSETW(.bcdHID, 0x0110), /* bcdHID: HID Class Spec release number HID 1.1 */ 164 .bCountryCode = 0x00, /* bCountryCode: Hardware target country */ 165 .bNumDescriptors = 0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ 166 { 167 { 168 .bDescriptorType = 0x22, /* bDescriptorType */ 169 } 170 } 171}; 172 173static const struct hid_endpoint_descriptor g_fhid_in_ep_desc = 174{ 175 .bLength = sizeof(struct hid_endpoint_descriptor), 176 .bDescriptorType = UDESC_ENDPOINT, 177 .bEndpointAddress = UE_DIR_IN | 0x01, 178 .bmAttributes = 0x03, /* bmAttributes = 00000011b */ 179 HSETW(.wMaxPacketSize, HID_IN_DATA_SIZE), /* wMaxPacketSize = 64 */ 180 .bInterval = 0x04 /* bInterval = 4ms */ 181}; 182 183static const struct hid_endpoint_descriptor g_fhid_out_ep_desc = 184{ 185 .bLength = sizeof(struct hid_endpoint_descriptor), 186 .bDescriptorType = UDESC_ENDPOINT, 187 .bEndpointAddress = UE_DIR_OUT | 0x01, 188 .bmAttributes = 0x03, 189 HSETW(.wMaxPacketSize, HID_OUT_DATA_SIZE), 190 .bInterval = 0x04 191}; 192 193const uint8_t *g_fhid_desc_array[] = 194{ 195 (const uint8_t *)&g_fhid_config_desc, 196 (const uint8_t *)&g_fhid_intf_desc, 197 (const uint8_t *)&g_fhid_desc, 198 (const uint8_t *)&g_fhid_in_ep_desc, 199 (const uint8_t *)&g_fhid_out_ep_desc, 200 NULL, 201}; 202 203void hid_deviceid_info(uint16_t vendorid, uint16_t productid) 204{ 205 USETW(g_fhid_device_desc.idVendor, vendorid); 206 207 USETW(g_fhid_device_desc.idProduct, productid); 208} 209 210int hid_device_string_info(const struct dev_string_desc *str_manufacturer, 211 const struct dev_string_desc *str_product, 212 const struct dev_string_desc *str_serial_number) 213{ 214 char *buf[HID_STRING_DESC_NUM] = {NULL}; 215 const struct dev_string_desc *str_desc[HID_STRING_DESC_NUM]; 216 int i; 217 uint32_t len; 218 219 if (str_manufacturer == NULL || str_product == NULL || str_serial_number == NULL) 220 { 221 usb_err("%s failed, invalid param!\n", __FUNCTION__); 222 return -1; 223 } 224 225 if (str_manufacturer->str == NULL || str_manufacturer->len == 0 || 226 str_serial_number->str == NULL || str_serial_number->len == 0 || 227 str_product->str == NULL || str_product->len == 0) 228 { 229 usb_err("%s failed, str is NULL or len is 0\n", __FUNCTION__); 230 return -1; 231 } 232 233 if (str_manufacturer->len > (HID_STRING_LEN_MAX - HID_STRING_HEAD_LEN) || 234 str_serial_number->len > (HID_STRING_LEN_MAX - HID_STRING_HEAD_LEN) || 235 str_product->len > (HID_STRING_LEN_MAX - HID_STRING_HEAD_LEN)) 236 { 237 usb_err("%s failed, len exceeds maximum limit! str_manufacturer->len = %u" 238 "str_serial_number->len = %u str_product->len = %u\n", __FUNCTION__, 239 str_manufacturer->len, str_serial_number->len, str_product->len); 240 return -1; 241 } 242 243 str_desc[0] = str_manufacturer; 244 str_desc[1] = str_product; 245 str_desc[2] = str_serial_number; 246 247 for (i = 0; i < HID_STRING_DESC_NUM; i++) 248 { 249 len = str_desc[i]->len + HID_STRING_HEAD_LEN; 250 buf[i] = (char *)malloc(len); 251 if (buf[i] == NULL) 252 { 253 usb_err("%s malloc failed\n", __FUNCTION__); 254 goto errout; 255 } 256 g_fhid_device_strings[i + 1].s = buf[i]; 257 258 *buf[i] = (char)len; 259 *(buf[i] + 1) = UDESC_STRING; 260 261 /* len represents the size of the string */ 262 263 (void)memcpy_s(buf[i] + HID_STRING_HEAD_LEN, (size_t)str_desc[i]->len, 264 str_desc[i]->str, (size_t)str_desc[i]->len); 265 } 266 267 return 0; 268 269errout: 270 for (i = 0; i < HID_STRING_DESC_NUM; i++) 271 { 272 if (buf[i] != NULL) 273 { 274 free(buf[i]); 275 } 276 } 277 return -1; 278} 279 280int hid_report_descriptor_info(const void *buf, size_t len) 281{ 282 uint8_t *report_desc; 283 284 if (buf == NULL || len == 0) 285 { 286 usb_err("%s failed, buf is NULL or len is 0\n", __FUNCTION__); 287 return -1; 288 } 289 290 report_desc = (uint8_t *)malloc(len); 291 if (report_desc == NULL) 292 { 293 usb_err("%s malloc failed\n", __FUNCTION__); 294 return -1; 295 } 296 297 g_fhid_report_desc.report_size = len; 298 g_fhid_report_desc.report_desc = report_desc; 299 300 /* len represents the size of the report */ 301 302 (void)memcpy_s(report_desc, len, buf, len); 303 304 return 0; 305} 306 307static void usbdev_hid_free(void) 308{ 309 int i; 310 311 if (g_fhid_report_desc.report_desc != NULL) 312 { 313 free(g_fhid_report_desc.report_desc); 314 g_fhid_report_desc.report_desc = NULL; 315 } 316 317 for (i = 1; i <= HID_STRING_DESC_NUM; i++) 318 { 319 if (g_fhid_device_strings[i].s != NULL) 320 { 321 free((void *)g_fhid_device_strings[i].s); 322 g_fhid_device_strings[i].s = NULL; 323 } 324 } 325} 326 327static void fhid_output_request_complete(struct usbdev_ep_s *ep, struct usbdev_req_s *req) 328{ 329 struct hid_dev_s *hid; 330 errno_t ret; 331 uint32_t ret_event; 332 333 if (ep == NULL || ep->priv == NULL || req == NULL) 334 { 335 usb_err("Illegal request or ep!\n"); 336 return; 337 } 338 339 if (req->result != 0) 340 { 341 return; 342 } 343 344 hid = (struct hid_dev_s *)ep->priv; 345 spin_lock(&hid->hid_lock); 346 347 /* Save private data of read request */ 348 349 hid->read_len = req->xfrd; 350 ret = memcpy_s(hid->read_buf, HID_OUT_DATA_SIZE, req->buf, req->xfrd); 351 if (ret != EOK) 352 { 353 spin_unlock(&hid->hid_lock); 354 usb_err("memcpy fail!\n"); 355 return; 356 } 357 spin_unlock(&hid->hid_lock); 358 359 ret_event = LOS_EventWrite(&hid->read_event, USB_HID_READ_EVENT); 360 if (ret_event != LOS_OK) 361 { 362 usb_err("write event failed!\r\n"); 363 } 364 365 (void)EP_SUBMIT(hid->out_ep, req); 366} 367 368static void fhid_input_req_complete(struct usbdev_ep_s *ep, struct usbdev_req_s *req) 369{ 370 struct hid_dev_s *hid = (struct hid_dev_s *)ep->priv; 371 struct hid_queue_node *node_temp; 372 373 spin_lock(&hid->hid_lock); 374 atomic_set(&hid->busy_flag, 0); 375 376 if (req->result != 0) 377 { 378 hid_queue_free(hid); 379 spin_unlock(&hid->hid_lock); 380 return; 381 } 382 383 if (hid->cur_node != NULL) 384 { 385 node_temp = hid->cur_node; 386 if (node_temp->buf_len == 0) 387 { 388 hid_queue_node_free(node_temp); 389 hid->cur_node = NULL; 390 } 391 else 392 { 393 hid_send_data_sub(hid); 394 spin_unlock(&hid->hid_lock); 395 return; 396 } 397 } 398 399 if (!list_empty(&hid->hid_queue)) 400 { 401 node_temp = list_first_entry(&hid->hid_queue, struct hid_queue_node, irqqueue); 402 hid->cur_node = node_temp; 403 list_del_init(&node_temp->irqqueue); 404 hid->hid_queue_len--; 405 hid_send_data_sub(hid); 406 } 407 spin_unlock(&hid->hid_lock); 408} 409 410static void fhid_source_free(struct hid_dev_s *hid, struct usbdev_s *dev) 411{ 412 if (hid != NULL) 413 { 414 DEV_FREEEP(dev, hid->out_ep); 415 DEV_FREEEP(dev, hid->in_ep); 416 } 417} 418 419static int usbclass_hid_bind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev) 420{ 421 struct usbdev_ep_s *ep; 422 struct hid_driver_s *drvr; 423 struct composite_dev_s *cdev; 424 struct hid_dev_s *hid; 425 struct composite_devobj_s *devobj; 426 struct usbdev_devinfo_s *devinfo; 427 int ret; 428 429 if (driver == NULL || dev == NULL) 430 { 431 return -1; 432 } 433 434 cdev = dev->ep0->priv; 435 drvr = (struct hid_driver_s *)driver; 436 hid = drvr->dev; 437 if (hid == NULL) 438 { 439 return -1; 440 } 441 442 INIT_LIST_HEAD(&hid->hid_queue); 443 hid->busy_flag = 0; 444 hid->hid_queue_len = 0; 445 hid->cur_node = NULL; 446 447 devobj = usbclass_devobj_get(cdev, DEV_HID); 448 if (devobj == NULL) 449 { 450 return -1; 451 } 452 devinfo = &devobj->compdesc.devinfo; 453 454 /* Initialize the interrupt output endpoint */ 455 456 ep = DEV_ALLOCEP(dev, g_fhid_out_ep_desc.bEndpointAddress, (struct usb_endpoint_descriptor *)&g_fhid_out_ep_desc); 457 if (ep == NULL) 458 { 459 return -1; 460 } 461 462 (void)memset_s(&(hid->outputreq), sizeof(struct usbdev_req_s), 0, sizeof(struct usbdev_req_s)); 463 hid->outputreq.callback = fhid_output_request_complete; 464 hid->outputreq.priv = (void *)hid; 465 hid->outputreq.buf = NULL; 466 ep->priv = (void *)hid; 467 ep->handle_req = &hid->outputreq; 468 hid->out_ep = ep; 469 devinfo->epno[0] = ep->eplog; 470 471 (VOID)LOS_EventInit(&hid->read_event); 472 spin_lock_init(&hid->hid_lock); 473 hid->read_len = 0; 474 hid->read_buf = memalign(USB_CACHE_ALIGN_SIZE, HID_OUT_DATA_SIZE); 475 if (hid->read_buf == NULL) 476 { 477 usb_err("Malloc failed!\n"); 478 goto errout; 479 } 480 481 /* Initialize the interrupt input endpoint */ 482 483 ep = DEV_ALLOCEP(dev, g_fhid_in_ep_desc.bEndpointAddress, (struct usb_endpoint_descriptor *)&g_fhid_in_ep_desc); 484 if (ep == NULL) 485 { 486 goto errout; 487 } 488 489 (void)memset_s(&hid->inputreq, sizeof(struct usbdev_req_s), 0, sizeof(struct usbdev_req_s)); 490 hid->inputreq.callback = fhid_input_req_complete; 491 hid->inputreq.priv = (void *)hid; 492 hid->inputreq.buf = NULL; 493 ep->priv = (void *)hid; 494 ep->handle_req = &hid->inputreq; 495 hid->in_ep = ep; 496 devinfo->epno[1] = ep->eplog; 497 498 /* Registered character device */ 499 500 ret = hid_fops_init(hid); 501 if (ret != LOS_OK) 502 { 503 goto errout; 504 } 505 506 return 0; 507errout: 508 (void)usbclass_hid_unbind(driver, dev); 509 return -1; 510} 511 512static int usbclass_hid_unbind(struct usbdevclass_driver_s *driver, struct usbdev_s *dev) 513{ 514 struct composite_dev_s *cdev; 515 struct composite_devobj_s *devobj; 516 struct usbdev_devinfo_s *devinfo; 517 struct hid_driver_s *drvr; 518 struct hid_dev_s *hid; 519 520 if (driver == NULL || dev == NULL) 521 { 522 return -1; 523 } 524 525 drvr = (struct hid_driver_s *)driver; 526 hid = drvr->dev; 527 528 if (atomic_read(&hid->open_flag)) 529 { 530 usb_err("HID device is busy!\n"); 531 return -1; 532 } 533 534 (void)hid_fops_deinit(hid); 535 536 usbclass_hid_disconnect(driver, dev); 537 538 /* Destroy read event */ 539 540 (VOID)LOS_EventDestroy(&hid->read_event); 541 if (hid->read_buf != NULL) 542 { 543 free(hid->read_buf); 544 hid->read_buf = NULL; 545 } 546 547 fhid_source_free(hid, dev); 548 549 cdev = dev->ep0->priv; 550 devobj = usbclass_devobj_get(cdev, DEV_HID); 551 if (devobj == NULL) 552 { 553 return -1; 554 } 555 devinfo = &devobj->compdesc.devinfo; 556 (void)memset_s(devinfo, sizeof(struct usbdev_devinfo_s), 0, sizeof(struct usbdev_devinfo_s)); 557 558 return 0; 559} 560 561static void usbclass_hid_set_endpoint(struct usbdevclass_driver_s *driver, struct usbdev_s *dev) 562{ 563 struct usbdev_req_s *req; 564 struct hid_driver_s *drvr; 565 struct hid_dev_s *hid; 566 int ret; 567 568 drvr = (struct hid_driver_s *)driver; 569 hid = drvr->dev; 570 571 hid->busy_flag = 0; 572 if (hid->in_ep_enabled == true) 573 { 574 (void)EP_DISABLE(hid->in_ep); 575 hid->in_ep_enabled = false; 576 } 577 578 ret = EP_CONFIGURE(hid->in_ep, (const usb_endpoint_descriptor_t *)&g_fhid_in_ep_desc, 0); 579 if (ret < 0) 580 { 581 usb_err("Config interrupt in_ep failed!\n"); 582 goto errout; 583 } 584 hid->in_ep_enabled = true; 585 586 if (hid->out_ep_enabled == true) 587 { 588 (void)EP_DISABLE(hid->out_ep); 589 hid->out_ep_enabled = false; 590 } 591 592 ret = EP_CONFIGURE(hid->out_ep, (const usb_endpoint_descriptor_t *)&g_fhid_out_ep_desc, 0); 593 if (ret < 0) 594 { 595 usb_err("Config interrupt out_ep failed!\n"); 596 goto errout; 597 } 598 hid->out_ep_enabled = true; 599 600 req = hid->out_ep->handle_req; 601 req->buf = (uint8_t *)hid->read_buf; 602 req->len = HID_OUT_DATA_SIZE; 603 ret = EP_SUBMIT(hid->out_ep, req); 604 if (ret != OK) 605 { 606 usb_err("out_ep submit failed!\n"); 607 goto errout; 608 } 609 610 return; 611 612errout: 613 usbclass_hid_disconnect(driver, dev); 614} 615 616static void usbclass_hid_get_report(struct usbdev_s *dev, uint32_t len) 617{ 618 struct usbdev_req_s *req = dev->ep0->handle_req; 619 errno_t ret; 620 621 ret = memcpy_s(req->buf, USB_COMP_EP0_BUFSIZ, 622 g_fhid_report_desc.report_desc, g_fhid_report_desc.report_size); 623 if (ret != EOK) 624 { 625 usb_err("memcpy fail\n"); 626 return; 627 } 628 629 req->len = MIN(len, g_fhid_report_desc.report_size); 630} 631 632static int usbclass_hid_setup(struct usbdevclass_driver_s *driver, struct usbdev_s *dev, 633 const struct usb_device_request *ctrl, uint8_t *dataout, size_t outlen) 634{ 635 uint8_t req_type; 636 uint16_t w_value; 637 struct hid_dev_s *hid; 638 struct hid_driver_s *drvr; 639 struct usbdev_req_s *req; 640 int ret; 641 int new_req = 0; 642 643 (void)dataout; (void)outlen; 644 645 if (dev == NULL || driver == NULL || ctrl == NULL) 646 { 647 return -1; 648 } 649 650 drvr = (struct hid_driver_s *)driver; 651 hid = drvr->dev; 652 if (hid == NULL) 653 { 654 return -1; 655 } 656 657 w_value = UGETW(ctrl->wValue); 658 req = dev->ep0->handle_req; 659 req_type = ctrl->bmRequestType; 660 req->priv = hid; 661 662 if (UT_GET_TYPE(req_type) == UT_STANDARD) 663 { 664 switch (ctrl->bRequest) 665 { 666 case USB_REQ_SET_CONFIGURATION: 667 case USB_REQ_SET_INTERFACE: 668 usbclass_hid_set_endpoint(driver, dev); 669 break; 670 671 case UR_GET_HID_DESCRIPTOR: 672 { 673 if ((w_value >> 8) == UDESC_REPORT) 674 { 675 usbclass_hid_get_report(dev, UGETW(ctrl->wLength)); 676 new_req = 1; 677 } 678 } 679 break; 680 681 default: 682 break; 683 } 684 } 685 else 686 { 687 switch (ctrl->bRequest) 688 { 689 case UR_SET_IDLE: 690 { 691 req->len = 0; 692 new_req = 1; 693 } 694 break; 695 696 case UR_SET_REPORT: 697 { 698 req->len = MIN(UGETW(ctrl->wLength), HID_IN_DATA_SIZE); 699 ret = memset_s(req->buf, req->len, 0, req->len); 700 if (ret != EOK) 701 { 702 usb_err("memset fail!\n"); 703 return -1; 704 } 705 new_req = 1; 706 } 707 break; 708 709 case UR_GET_IDLE: 710 { 711 req->len = 0; 712 new_req = 1; 713 } 714 break; 715 716 case UR_GET_REPORT: 717 { 718 req->len = MIN(UGETW(ctrl->wLength), HID_IN_DATA_SIZE); 719 ret = memset_s(req->buf, req->len, 0, req->len); 720 if (ret != EOK) 721 { 722 usb_err("memset fail!\n"); 723 return -1; 724 } 725 new_req = 1; 726 } 727 break; 728 729 default: 730 break; 731 } 732 } 733 734 if (new_req) 735 { 736 ret = EP_SUBMIT(dev->ep0, req); 737 if (ret != OK) 738 { 739 usb_err("Endpoint send fail!\n"); 740 req->result = 0; 741 return -1; 742 } 743 } 744 return 0; 745} 746 747static void usbclass_hid_disconnect(struct usbdevclass_driver_s *driver, struct usbdev_s *dev) 748{ 749 struct hid_driver_s *hid_drvr; 750 struct hid_dev_s *hid_dev; 751 752 (void)dev; 753 754 hid_drvr = (struct hid_driver_s *)driver; 755 hid_dev = hid_drvr->dev; 756 if (hid_dev == NULL) 757 { 758 return; 759 } 760 761 if (hid_dev->in_ep_enabled == true) 762 { 763 (void)EP_DISABLE(hid_dev->in_ep); 764 hid_dev->in_ep_enabled = false; 765 } 766 767 if (hid_dev->out_ep_enabled == true) 768 { 769 (void)EP_DISABLE(hid_dev->out_ep); 770 hid_dev->out_ep_enabled = false; 771 } 772} 773 774static uint8_t *linkg_fhid_descriptors(const uint8_t *prefer, uint16_t ps, uint16_t *total_size) 775{ 776 int i; 777 uint8_t *des; 778 uint8_t *pdes; 779 uint16_t ds = 0; 780 errno_t ret; 781 782 (void)prefer; 783 (void)ps; 784 785 /* Add the length of descriptors one by one */ 786 787 for (i = 0; g_fhid_desc_array[i] != NULL; ++i) 788 { 789 ds += (uint16_t)(*g_fhid_desc_array[i]); 790 } 791 792 if (total_size != NULL) 793 { 794 *total_size = ds; 795 } 796 797 des = memalign(64, SKB_DATA_ALIGN(ds)); 798 if (des == NULL) 799 { 800 usb_err("System out of memory! Descriptors length: %u\n", ds); 801 return NULL; 802 } 803 (void)memset_s((void *)des, SKB_DATA_ALIGN(ds), 0, SKB_DATA_ALIGN(ds)); 804 805 pdes = des; 806 807 /* configuration descriptor needs to have the full length of rest of descriptors */ 808 809 USETW(g_fhid_config_desc.wTotalLength, ds); 810 811 for (i = 0; g_fhid_desc_array[i] != NULL; ++i) 812 { 813 const uint8_t *des_src = g_fhid_desc_array[i]; 814 uint8_t des_len = *des_src; 815 ret = memcpy_s(pdes, SKB_DATA_ALIGN(ds), des_src, des_len); 816 if (ret != EOK) 817 { 818 usb_err("memcpy fail!\n"); 819 free(des); 820 return NULL; 821 } 822 pdes += des_len; 823 } 824 825 return des; 826} 827 828static void hid_mkdevdesc(uint8_t *buf) 829{ 830 errno_t ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, &g_fhid_device_desc, sizeof(g_fhid_device_desc)); 831 if (ret != EOK) 832 { 833 usb_err("memcpy_s fail!, ret:%d\n", ret); 834 return; 835 } 836} 837 838static int16_t hid_mkcfgdesc(uint8_t *buf, struct usbdev_devinfo_s *devinfo) 839{ 840 uint16_t total_len; 841 uint8_t *des; 842 errno_t ret; 843 844 (void)devinfo; 845 846 USETW(g_fhid_desc.descrs[0].wDescriptorLength, g_fhid_report_desc.report_size); 847 848 des = linkg_fhid_descriptors(NULL, 0, &total_len); 849 if (des != NULL) 850 { 851 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, des, total_len); 852 if (ret != EOK) 853 { 854 usb_err("memcpy_s fail!, ret:%d\n", ret); 855 free(des); 856 return 0; 857 } 858 free(des); 859 } 860 861 return (int16_t)total_len; 862} 863 864static int hid_mkstrdesc(uint8_t id, uint8_t *buf) 865{ 866 errno_t ret; 867 const char *str; 868 int i; 869 870 for (i = 0; g_fhid_device_strings[i].s != NULL; i++) 871 { 872 str = g_fhid_device_strings[i].s; 873 if (g_fhid_device_strings[i].id == id) 874 { 875 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, (const void *)str, (uint32_t)str[0]); 876 if (ret != EOK) 877 { 878 usb_err("memcpy_s failed, ret = %d\n", ret); 879 return -1; 880 } 881 return str[0]; 882 } 883 } 884 885 usb_err("Can not find the id = %u of string\n", id); 886 return -1; 887} 888 889#define HID_NCONFIGS 1 890#define HID_CONFIGID 0 891#define HID_NINTERFACES 1 892#define HID_NSTRIDS 5 893#define HID_NUM_EPS 2 894static void hid_get_composite_devdesc(struct composite_devdesc_s *dev) 895{ 896 (void)memset_s(dev, sizeof(struct composite_devdesc_s), 0, sizeof(struct composite_devdesc_s)); 897 898 dev->mkdevdesc = hid_mkdevdesc; 899 dev->mkconfdesc = hid_mkcfgdesc; 900 dev->mkstrdesc = hid_mkstrdesc; 901 902 dev->nconfigs = HID_NCONFIGS; /* Number of configurations supported */ 903 dev->configid = HID_CONFIGID; /* The only supported configuration ID */ 904 905 /* Interfaces. 906 * 907 * ifnobase must be provided by board-specific logic 908 */ 909 910 dev->devinfo.ninterfaces = HID_NINTERFACES; /* Number of interfaces in the configuration */ 911 912 /* Strings. 913 * 914 * strbase must be provided by board-specific logic 915 */ 916 917 dev->devinfo.nstrings = HID_NSTRIDS; /* Number of Strings */ 918 919 /* Endpoints. 920 * 921 * Endpoint numbers must be provided by board-specific logic. 922 */ 923 924 dev->devinfo.nendpoints = HID_NUM_EPS; 925} 926 927static int hid_classobject(int minor, struct usbdev_devinfo_s *devinfo, 928 struct usbdevclass_driver_s **classdev) 929{ 930 struct hid_softc *hid_s; 931 struct hid_dev_s *priv; 932 struct hid_driver_s *drvr; 933 934 (void)minor; 935 (void)devinfo; 936 937 /* Allocate the structures needed */ 938 939 hid_s = (struct hid_softc *)malloc(sizeof(struct hid_softc)); 940 if (hid_s == NULL) 941 { 942 return -1; 943 } 944 945 /* Convenience pointers into the allocated blob */ 946 947 priv = &hid_s->dev; 948 drvr = &hid_s->drvr; 949 950 /* Initialize the USB serial driver structure */ 951 952 (void)memset_s(priv, sizeof(struct hid_dev_s), 0, sizeof(struct hid_dev_s)); 953 954 /* Initialize the USB class driver structure */ 955 956 drvr->drvr.speed = USB_SPEED_HIGH; 957 drvr->drvr.ops = &g_hid_driverops; 958 drvr->dev = priv; 959 960 *classdev = &drvr->drvr; 961 return 0; 962} 963 964static void hid_uninitialize(struct usbdevclass_driver_s *classdev) 965{ 966 struct hid_driver_s *hid_drvr = (struct hid_driver_s *)classdev; 967 struct hid_dev_s *priv; 968 struct hid_softc *hid_s; 969 970 usbdev_hid_free(); 971 972 if (hid_drvr == NULL) 973 { 974 return; 975 } 976 977 priv = hid_drvr->dev; 978 if (priv == NULL) 979 { 980 return; 981 } 982 983 hid_s = container_of(hid_drvr, struct hid_softc, drvr); 984 if (hid_s != NULL) 985 { 986 free(hid_s); 987 } 988} 989 990static void usbdev_hid_initialize_sub(struct composite_devdesc_s *dev, int ifnobase, int minor) 991{ 992 /* Ask the HID driver to fill in the constants we didn't 993 * know here. 994 */ 995 996 hid_get_composite_devdesc(dev); 997 998 /* Overwrite and correct some values. */ 999 1000 /* The callback functions for the HID class */ 1001 1002 dev->classobject = hid_classobject; 1003 dev->uninitialize = hid_uninitialize; 1004 1005 /* Interfaces */ 1006 1007 dev->devinfo.ifnobase = ifnobase; /* Offset to Interface-IDs */ 1008 dev->minor = minor; /* The minor interface number */ 1009 1010 /* Strings */ 1011 1012 dev->devinfo.strbase = 0; /* Offset to String Numbers */ 1013} 1014 1015int usbdev_hid_initialize(struct module *mod, int n, void *arg) 1016{ 1017 struct composite_softc *com_s = (struct composite_softc *)arg; 1018 struct composite_devdesc_s dev; 1019 int ret; 1020 1021 (void)mod; 1022 (void)n; 1023 if (com_s == NULL) 1024 { 1025 return -1; 1026 } 1027 1028 usbdev_hid_initialize_sub(&dev, 0, DEV_HID); 1029 1030 ret = composite_initialize(com_s, 1, &dev); 1031 if (ret < 0) 1032 { 1033 return -1; 1034 } 1035 1036 PRINTK(" ** hid device initialized successfully! **\n"); 1037 return 0; 1038} 1039 1040#ifdef __cplusplus 1041#if __cplusplus 1042} 1043#endif /* __cplusplus */ 1044#endif /* __cplusplus */