1 /* 2 * 3 * Intel Management Engine Interface (Intel MEI) Linux driver 4 * Copyright (c) 2003-2012, 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 17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18 19 #include <linux/module.h> 20 #include <linux/moduleparam.h> 21 #include <linux/kernel.h> 22 #include <linux/device.h> 23 #include <linux/fs.h> 24 #include <linux/errno.h> 25 #include <linux/types.h> 26 #include <linux/fcntl.h> 27 #include <linux/aio.h> 28 #include <linux/pci.h> 29 #include <linux/poll.h> 30 #include <linux/init.h> 31 #include <linux/ioctl.h> 32 #include <linux/cdev.h> 33 #include <linux/sched.h> 34 #include <linux/uuid.h> 35 #include <linux/compat.h> 36 #include <linux/jiffies.h> 37 #include <linux/interrupt.h> 38 #include <linux/miscdevice.h> 39 40 #include <linux/mei.h> 41 42 #include "mei_dev.h" 43 #include "hw-me.h" 44 #include "client.h" 45 46 /** 47 * mei_open - the open function 48 * 49 * @inode: pointer to inode structure 50 * @file: pointer to file structure 51 * 52 * returns 0 on success, <0 on error 53 */ 54 static int mei_open(struct inode *inode, struct file *file) 55 { 56 struct miscdevice *misc = file->private_data; 57 struct pci_dev *pdev; 58 struct mei_cl *cl; 59 struct mei_device *dev; 60 61 int err; 62 63 err = -ENODEV; 64 if (!misc->parent) 65 goto out; 66 67 pdev = container_of(misc->parent, struct pci_dev, dev); 68 69 dev = pci_get_drvdata(pdev); 70 if (!dev) 71 goto out; 72 73 mutex_lock(&dev->device_lock); 74 err = -ENOMEM; 75 cl = mei_cl_allocate(dev); 76 if (!cl) 77 goto out_unlock; 78 79 err = -ENODEV; 80 if (dev->dev_state != MEI_DEV_ENABLED) { 81 dev_dbg(&dev->pdev->dev, "dev_state != MEI_ENABLED dev_state = %s\n", 82 mei_dev_state_str(dev->dev_state)); 83 goto out_unlock; 84 } 85 err = -EMFILE; 86 if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT) { 87 dev_err(&dev->pdev->dev, "open_handle_count exceded %d", 88 MEI_MAX_OPEN_HANDLE_COUNT); 89 goto out_unlock; 90 } 91 92 err = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY); 93 if (err) 94 goto out_unlock; 95 96 file->private_data = cl; 97 mutex_unlock(&dev->device_lock); 98 99 return nonseekable_open(inode, file); 100 101 out_unlock: 102 mutex_unlock(&dev->device_lock); 103 kfree(cl); 104 out: 105 return err; 106 } 107 108 /** 109 * mei_release - the release function 110 * 111 * @inode: pointer to inode structure 112 * @file: pointer to file structure 113 * 114 * returns 0 on success, <0 on error 115 */ 116 static int mei_release(struct inode *inode, struct file *file) 117 { 118 struct mei_cl *cl = file->private_data; 119 struct mei_cl_cb *cb; 120 struct mei_device *dev; 121 int rets = 0; 122 123 if (WARN_ON(!cl || !cl->dev)) 124 return -ENODEV; 125 126 dev = cl->dev; 127 128 mutex_lock(&dev->device_lock); 129 if (cl == &dev->iamthif_cl) { 130 rets = mei_amthif_release(dev, file); 131 goto out; 132 } 133 if (cl->state == MEI_FILE_CONNECTED) { 134 cl->state = MEI_FILE_DISCONNECTING; 135 dev_dbg(&dev->pdev->dev, 136 "disconnecting client host client = %d, " 137 "ME client = %d\n", 138 cl->host_client_id, 139 cl->me_client_id); 140 rets = mei_cl_disconnect(cl); 141 } 142 mei_cl_flush_queues(cl); 143 dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n", 144 cl->host_client_id, 145 cl->me_client_id); 146 147 if (dev->open_handle_count > 0) { 148 clear_bit(cl->host_client_id, dev->host_clients_map); 149 dev->open_handle_count--; 150 } 151 mei_cl_unlink(cl); 152 153 154 /* free read cb */ 155 cb = NULL; 156 if (cl->read_cb) { 157 cb = mei_cl_find_read_cb(cl); 158 /* Remove entry from read list */ 159 if (cb) 160 list_del(&cb->list); 161 162 cb = cl->read_cb; 163 cl->read_cb = NULL; 164 } 165 166 file->private_data = NULL; 167 168 if (cb) { 169 mei_io_cb_free(cb); 170 cb = NULL; 171 } 172 173 kfree(cl); 174 out: 175 mutex_unlock(&dev->device_lock); 176 return rets; 177 } 178 179 180 /** 181 * mei_read - the read function. 182 * 183 * @file: pointer to file structure 184 * @ubuf: pointer to user buffer 185 * @length: buffer length 186 * @offset: data offset in buffer 187 * 188 * returns >=0 data length on success , <0 on error 189 */ 190 static ssize_t mei_read(struct file *file, char __user *ubuf, 191 size_t length, loff_t *offset) 192 { 193 struct mei_cl *cl = file->private_data; 194 struct mei_cl_cb *cb_pos = NULL; 195 struct mei_cl_cb *cb = NULL; 196 struct mei_device *dev; 197 int i; 198 int rets; 199 int err; 200 201 202 if (WARN_ON(!cl || !cl->dev)) 203 return -ENODEV; 204 205 dev = cl->dev; 206 207 mutex_lock(&dev->device_lock); 208 if (dev->dev_state != MEI_DEV_ENABLED) { 209 rets = -ENODEV; 210 goto out; 211 } 212 213 if ((cl->sm_state & MEI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) { 214 /* Do not allow to read watchdog client */ 215 i = mei_me_cl_by_uuid(dev, &mei_wd_guid); 216 if (i >= 0) { 217 struct mei_me_client *me_client = &dev->me_clients[i]; 218 if (cl->me_client_id == me_client->client_id) { 219 rets = -EBADF; 220 goto out; 221 } 222 } 223 } else { 224 cl->sm_state &= ~MEI_WD_STATE_INDEPENDENCE_MSG_SENT; 225 } 226 227 if (cl == &dev->iamthif_cl) { 228 rets = mei_amthif_read(dev, file, ubuf, length, offset); 229 goto out; 230 } 231 232 if (cl->read_cb && cl->read_cb->buf_idx > *offset) { 233 cb = cl->read_cb; 234 goto copy_buffer; 235 } else if (cl->read_cb && cl->read_cb->buf_idx > 0 && 236 cl->read_cb->buf_idx <= *offset) { 237 cb = cl->read_cb; 238 rets = 0; 239 goto free; 240 } else if ((!cl->read_cb || !cl->read_cb->buf_idx) && *offset > 0) { 241 /*Offset needs to be cleaned for contiguous reads*/ 242 *offset = 0; 243 rets = 0; 244 goto out; 245 } 246 247 err = mei_cl_read_start(cl); 248 if (err && err != -EBUSY) { 249 dev_dbg(&dev->pdev->dev, 250 "mei start read failure with status = %d\n", err); 251 rets = err; 252 goto out; 253 } 254 255 if (MEI_READ_COMPLETE != cl->reading_state && 256 !waitqueue_active(&cl->rx_wait)) { 257 if (file->f_flags & O_NONBLOCK) { 258 rets = -EAGAIN; 259 goto out; 260 } 261 262 mutex_unlock(&dev->device_lock); 263 264 if (wait_event_interruptible(cl->rx_wait, 265 (MEI_READ_COMPLETE == cl->reading_state || 266 MEI_FILE_INITIALIZING == cl->state || 267 MEI_FILE_DISCONNECTED == cl->state || 268 MEI_FILE_DISCONNECTING == cl->state))) { 269 if (signal_pending(current)) 270 return -EINTR; 271 return -ERESTARTSYS; 272 } 273 274 mutex_lock(&dev->device_lock); 275 if (MEI_FILE_INITIALIZING == cl->state || 276 MEI_FILE_DISCONNECTED == cl->state || 277 MEI_FILE_DISCONNECTING == cl->state) { 278 rets = -EBUSY; 279 goto out; 280 } 281 } 282 283 cb = cl->read_cb; 284 285 if (!cb) { 286 rets = -ENODEV; 287 goto out; 288 } 289 if (cl->reading_state != MEI_READ_COMPLETE) { 290 rets = 0; 291 goto out; 292 } 293 /* now copy the data to user space */ 294 copy_buffer: 295 dev_dbg(&dev->pdev->dev, "cb->response_buffer size - %d\n", 296 cb->response_buffer.size); 297 dev_dbg(&dev->pdev->dev, "cb->buf_idx - %lu\n", cb->buf_idx); 298 if (length == 0 || ubuf == NULL || *offset > cb->buf_idx) { 299 rets = -EMSGSIZE; 300 goto free; 301 } 302 303 /* length is being truncated to PAGE_SIZE, 304 * however buf_idx may point beyond that */ 305 length = min_t(size_t, length, cb->buf_idx - *offset); 306 307 if (copy_to_user(ubuf, cb->response_buffer.data + *offset, length)) { 308 rets = -EFAULT; 309 goto free; 310 } 311 312 rets = length; 313 *offset += length; 314 if ((unsigned long)*offset < cb->buf_idx) 315 goto out; 316 317 free: 318 cb_pos = mei_cl_find_read_cb(cl); 319 /* Remove entry from read list */ 320 if (cb_pos) 321 list_del(&cb_pos->list); 322 mei_io_cb_free(cb); 323 cl->reading_state = MEI_IDLE; 324 cl->read_cb = NULL; 325 out: 326 dev_dbg(&dev->pdev->dev, "end mei read rets= %d\n", rets); 327 mutex_unlock(&dev->device_lock); 328 return rets; 329 } 330 /** 331 * mei_write - the write function. 332 * 333 * @file: pointer to file structure 334 * @ubuf: pointer to user buffer 335 * @length: buffer length 336 * @offset: data offset in buffer 337 * 338 * returns >=0 data length on success , <0 on error 339 */ 340 static ssize_t mei_write(struct file *file, const char __user *ubuf, 341 size_t length, loff_t *offset) 342 { 343 struct mei_cl *cl = file->private_data; 344 struct mei_cl_cb *write_cb = NULL; 345 struct mei_msg_hdr mei_hdr; 346 struct mei_device *dev; 347 unsigned long timeout = 0; 348 int rets; 349 int i; 350 351 if (WARN_ON(!cl || !cl->dev)) 352 return -ENODEV; 353 354 dev = cl->dev; 355 356 mutex_lock(&dev->device_lock); 357 358 if (dev->dev_state != MEI_DEV_ENABLED) { 359 rets = -ENODEV; 360 goto err; 361 } 362 363 i = mei_me_cl_by_id(dev, cl->me_client_id); 364 if (i < 0) { 365 rets = -ENODEV; 366 goto err; 367 } 368 if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { 369 rets = -EMSGSIZE; 370 goto err; 371 } 372 373 if (cl->state != MEI_FILE_CONNECTED) { 374 rets = -ENODEV; 375 dev_err(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d", 376 cl->host_client_id, cl->me_client_id); 377 goto err; 378 } 379 if (cl == &dev->iamthif_cl) { 380 write_cb = mei_amthif_find_read_list_entry(dev, file); 381 382 if (write_cb) { 383 timeout = write_cb->read_time + 384 mei_secs_to_jiffies(MEI_IAMTHIF_READ_TIMER); 385 386 if (time_after(jiffies, timeout) || 387 cl->reading_state == MEI_READ_COMPLETE) { 388 *offset = 0; 389 list_del(&write_cb->list); 390 mei_io_cb_free(write_cb); 391 write_cb = NULL; 392 } 393 } 394 } 395 396 /* free entry used in read */ 397 if (cl->reading_state == MEI_READ_COMPLETE) { 398 *offset = 0; 399 write_cb = mei_cl_find_read_cb(cl); 400 if (write_cb) { 401 list_del(&write_cb->list); 402 mei_io_cb_free(write_cb); 403 write_cb = NULL; 404 cl->reading_state = MEI_IDLE; 405 cl->read_cb = NULL; 406 } 407 } else if (cl->reading_state == MEI_IDLE) 408 *offset = 0; 409 410 411 write_cb = mei_io_cb_init(cl, file); 412 if (!write_cb) { 413 dev_err(&dev->pdev->dev, "write cb allocation failed\n"); 414 rets = -ENOMEM; 415 goto err; 416 } 417 rets = mei_io_cb_alloc_req_buf(write_cb, length); 418 if (rets) 419 goto err; 420 421 dev_dbg(&dev->pdev->dev, "cb request size = %zd\n", length); 422 423 rets = copy_from_user(write_cb->request_buffer.data, ubuf, length); 424 if (rets) 425 goto err; 426 427 cl->sm_state = 0; 428 if (length == 4 && 429 ((memcmp(mei_wd_state_independence_msg[0], 430 write_cb->request_buffer.data, 4) == 0) || 431 (memcmp(mei_wd_state_independence_msg[1], 432 write_cb->request_buffer.data, 4) == 0) || 433 (memcmp(mei_wd_state_independence_msg[2], 434 write_cb->request_buffer.data, 4) == 0))) 435 cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT; 436 437 if (cl == &dev->iamthif_cl) { 438 rets = mei_amthif_write(dev, write_cb); 439 440 if (rets) { 441 dev_err(&dev->pdev->dev, 442 "amthif write failed with status = %d\n", rets); 443 goto err; 444 } 445 mutex_unlock(&dev->device_lock); 446 return length; 447 } 448 449 write_cb->fop_type = MEI_FOP_WRITE; 450 451 dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", 452 cl->host_client_id, cl->me_client_id); 453 rets = mei_cl_flow_ctrl_creds(cl); 454 if (rets < 0) 455 goto err; 456 457 if (rets == 0 || !dev->hbuf_is_ready) { 458 write_cb->buf_idx = 0; 459 mei_hdr.msg_complete = 0; 460 cl->writing_state = MEI_WRITING; 461 goto out; 462 } 463 464 dev->hbuf_is_ready = false; 465 if (length > mei_hbuf_max_len(dev)) { 466 mei_hdr.length = mei_hbuf_max_len(dev); 467 mei_hdr.msg_complete = 0; 468 } else { 469 mei_hdr.length = length; 470 mei_hdr.msg_complete = 1; 471 } 472 mei_hdr.host_addr = cl->host_client_id; 473 mei_hdr.me_addr = cl->me_client_id; 474 mei_hdr.reserved = 0; 475 476 dev_dbg(&dev->pdev->dev, "write " MEI_HDR_FMT "\n", 477 MEI_HDR_PRM(&mei_hdr)); 478 if (mei_write_message(dev, &mei_hdr, write_cb->request_buffer.data)) { 479 rets = -ENODEV; 480 goto err; 481 } 482 cl->writing_state = MEI_WRITING; 483 write_cb->buf_idx = mei_hdr.length; 484 485 out: 486 if (mei_hdr.msg_complete) { 487 if (mei_cl_flow_ctrl_reduce(cl)) { 488 rets = -ENODEV; 489 goto err; 490 } 491 list_add_tail(&write_cb->list, &dev->write_waiting_list.list); 492 } else { 493 list_add_tail(&write_cb->list, &dev->write_list.list); 494 } 495 496 mutex_unlock(&dev->device_lock); 497 return length; 498 499 err: 500 mutex_unlock(&dev->device_lock); 501 mei_io_cb_free(write_cb); 502 return rets; 503 } 504 505 /** 506 * mei_ioctl_connect_client - the connect to fw client IOCTL function 507 * 508 * @dev: the device structure 509 * @data: IOCTL connect data, input and output parameters 510 * @file: private data of the file object 511 * 512 * Locking: called under "dev->device_lock" lock 513 * 514 * returns 0 on success, <0 on failure. 515 */ 516 static int mei_ioctl_connect_client(struct file *file, 517 struct mei_connect_client_data *data) 518 { 519 struct mei_device *dev; 520 struct mei_client *client; 521 struct mei_cl *cl; 522 int i; 523 int rets; 524 525 cl = file->private_data; 526 if (WARN_ON(!cl || !cl->dev)) 527 return -ENODEV; 528 529 dev = cl->dev; 530 531 if (dev->dev_state != MEI_DEV_ENABLED) { 532 rets = -ENODEV; 533 goto end; 534 } 535 536 if (cl->state != MEI_FILE_INITIALIZING && 537 cl->state != MEI_FILE_DISCONNECTED) { 538 rets = -EBUSY; 539 goto end; 540 } 541 542 /* find ME client we're trying to connect to */ 543 i = mei_me_cl_by_uuid(dev, &data->in_client_uuid); 544 if (i >= 0 && !dev->me_clients[i].props.fixed_address) { 545 cl->me_client_id = dev->me_clients[i].client_id; 546 cl->state = MEI_FILE_CONNECTING; 547 } 548 549 dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n", 550 cl->me_client_id); 551 dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n", 552 dev->me_clients[i].props.protocol_version); 553 dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n", 554 dev->me_clients[i].props.max_msg_length); 555 556 /* if we're connecting to amthif client then we will use the 557 * existing connection 558 */ 559 if (uuid_le_cmp(data->in_client_uuid, mei_amthif_guid) == 0) { 560 dev_dbg(&dev->pdev->dev, "FW Client is amthi\n"); 561 if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { 562 rets = -ENODEV; 563 goto end; 564 } 565 clear_bit(cl->host_client_id, dev->host_clients_map); 566 mei_cl_unlink(cl); 567 568 kfree(cl); 569 cl = NULL; 570 file->private_data = &dev->iamthif_cl; 571 572 client = &data->out_client_properties; 573 client->max_msg_length = 574 dev->me_clients[i].props.max_msg_length; 575 client->protocol_version = 576 dev->me_clients[i].props.protocol_version; 577 rets = dev->iamthif_cl.status; 578 579 goto end; 580 } 581 582 if (cl->state != MEI_FILE_CONNECTING) { 583 rets = -ENODEV; 584 goto end; 585 } 586 587 588 /* prepare the output buffer */ 589 client = &data->out_client_properties; 590 client->max_msg_length = dev->me_clients[i].props.max_msg_length; 591 client->protocol_version = dev->me_clients[i].props.protocol_version; 592 dev_dbg(&dev->pdev->dev, "Can connect?\n"); 593 594 595 rets = mei_cl_connect(cl, file); 596 597 end: 598 dev_dbg(&dev->pdev->dev, "free connect cb memory."); 599 return rets; 600 } 601 602 603 /** 604 * mei_ioctl - the IOCTL function 605 * 606 * @file: pointer to file structure 607 * @cmd: ioctl command 608 * @data: pointer to mei message structure 609 * 610 * returns 0 on success , <0 on error 611 */ 612 static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) 613 { 614 struct mei_device *dev; 615 struct mei_cl *cl = file->private_data; 616 struct mei_connect_client_data *connect_data = NULL; 617 int rets; 618 619 if (cmd != IOCTL_MEI_CONNECT_CLIENT) 620 return -EINVAL; 621 622 if (WARN_ON(!cl || !cl->dev)) 623 return -ENODEV; 624 625 dev = cl->dev; 626 627 dev_dbg(&dev->pdev->dev, "IOCTL cmd = 0x%x", cmd); 628 629 mutex_lock(&dev->device_lock); 630 if (dev->dev_state != MEI_DEV_ENABLED) { 631 rets = -ENODEV; 632 goto out; 633 } 634 635 dev_dbg(&dev->pdev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n"); 636 637 connect_data = kzalloc(sizeof(struct mei_connect_client_data), 638 GFP_KERNEL); 639 if (!connect_data) { 640 rets = -ENOMEM; 641 goto out; 642 } 643 dev_dbg(&dev->pdev->dev, "copy connect data from user\n"); 644 if (copy_from_user(connect_data, (char __user *)data, 645 sizeof(struct mei_connect_client_data))) { 646 dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n"); 647 rets = -EFAULT; 648 goto out; 649 } 650 651 rets = mei_ioctl_connect_client(file, connect_data); 652 653 /* if all is ok, copying the data back to user. */ 654 if (rets) 655 goto out; 656 657 dev_dbg(&dev->pdev->dev, "copy connect data to user\n"); 658 if (copy_to_user((char __user *)data, connect_data, 659 sizeof(struct mei_connect_client_data))) { 660 dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n"); 661 rets = -EFAULT; 662 goto out; 663 } 664 665 out: 666 kfree(connect_data); 667 mutex_unlock(&dev->device_lock); 668 return rets; 669 } 670 671 /** 672 * mei_compat_ioctl - the compat IOCTL function 673 * 674 * @file: pointer to file structure 675 * @cmd: ioctl command 676 * @data: pointer to mei message structure 677 * 678 * returns 0 on success , <0 on error 679 */ 680 #ifdef CONFIG_COMPAT 681 static long mei_compat_ioctl(struct file *file, 682 unsigned int cmd, unsigned long data) 683 { 684 return mei_ioctl(file, cmd, (unsigned long)compat_ptr(data)); 685 } 686 #endif 687 688 689 /** 690 * mei_poll - the poll function 691 * 692 * @file: pointer to file structure 693 * @wait: pointer to poll_table structure 694 * 695 * returns poll mask 696 */ 697 static unsigned int mei_poll(struct file *file, poll_table *wait) 698 { 699 struct mei_cl *cl = file->private_data; 700 struct mei_device *dev; 701 unsigned int mask = 0; 702 703 if (WARN_ON(!cl || !cl->dev)) 704 return mask; 705 706 dev = cl->dev; 707 708 mutex_lock(&dev->device_lock); 709 710 if (dev->dev_state != MEI_DEV_ENABLED) 711 goto out; 712 713 714 if (cl == &dev->iamthif_cl) { 715 mask = mei_amthif_poll(dev, file, wait); 716 goto out; 717 } 718 719 mutex_unlock(&dev->device_lock); 720 poll_wait(file, &cl->tx_wait, wait); 721 mutex_lock(&dev->device_lock); 722 if (MEI_WRITE_COMPLETE == cl->writing_state) 723 mask |= (POLLIN | POLLRDNORM); 724 725 out: 726 mutex_unlock(&dev->device_lock); 727 return mask; 728 } 729 730 /* 731 * file operations structure will be used for mei char device. 732 */ 733 static const struct file_operations mei_fops = { 734 .owner = THIS_MODULE, 735 .read = mei_read, 736 .unlocked_ioctl = mei_ioctl, 737 #ifdef CONFIG_COMPAT 738 .compat_ioctl = mei_compat_ioctl, 739 #endif 740 .open = mei_open, 741 .release = mei_release, 742 .write = mei_write, 743 .poll = mei_poll, 744 .llseek = no_llseek 745 }; 746 747 /* 748 * Misc Device Struct 749 */ 750 static struct miscdevice mei_misc_device = { 751 .name = "mei", 752 .fops = &mei_fops, 753 .minor = MISC_DYNAMIC_MINOR, 754 }; 755 756 int mei_register(struct device *dev) 757 { 758 mei_misc_device.parent = dev; 759 return misc_register(&mei_misc_device); 760 } 761 762 void mei_deregister(void) 763 { 764 misc_deregister(&mei_misc_device); 765 mei_misc_device.parent = NULL; 766 } 767 768 MODULE_LICENSE("GPL v2"); 769 770