aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/main.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 16:57:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-21 16:57:13 -0500
commit7ed214ac2095f561a94335ca672b6c42a1ea40ff (patch)
treeda41901bff1d0d8d61170bf362384fdc61deb3ab /drivers/misc/mei/main.c
parent21eaab6d19ed43e82ed39c8deb7f192134fb4a0e (diff)
parent29e5507ae4ab34397f538f06b7070c81a4e4a2bf (diff)
Merge tag 'char-misc-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver patches from Greg Kroah-Hartman: "Here's the big char/misc driver patches for 3.9-rc1. Nothing major here, just lots of different driver updates (mei, hyperv, ipack, extcon, vmci, etc.). All of these have been in the linux-next tree for a while." * tag 'char-misc-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (209 commits) w1: w1_therm: Add force-pullup option for "broken" sensors w1: ds2482: Added 1-Wire pull-up support to the driver vme: add missing put_device() after device_register() fails extcon: max8997: Use workqueue to check cable state after completing boot of platform extcon: max8997: Set default UART/USB path on probe extcon: max8997: Consolidate duplicate code for checking ADC/CHG cable type extcon: max8997: Set default of ADC debounce time during initialization extcon: max8997: Remove duplicate code related to set H/W line path extcon: max8997: Move defined constant to header file extcon: max77693: Make max77693_extcon_cable static extcon: max8997: Remove unreachable code extcon: max8997: Make max8997_extcon_cable static extcon: max77693: Remove unnecessary goto statement to improve readability extcon: max77693: Convert to devm_input_allocate_device() extcon: gpio: Rename filename of extcon-gpio.c according to kernel naming style CREDITS: update email and address of Harald Hoyer extcon: arizona: Use MICDET for final microphone identification extcon: arizona: Always take the first HPDET reading as the final one extcon: arizona: Clear _trig_sts bits after jack detection extcon: arizona: Don't HPDET magic when headphones are enabled ...
Diffstat (limited to 'drivers/misc/mei/main.c')
-rw-r--r--drivers/misc/mei/main.c536
1 files changed, 135 insertions, 401 deletions
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index 43fb52ff98ad..903f809b21f7 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -37,79 +37,11 @@
37#include <linux/interrupt.h> 37#include <linux/interrupt.h>
38#include <linux/miscdevice.h> 38#include <linux/miscdevice.h>
39 39
40#include "mei_dev.h"
41#include <linux/mei.h> 40#include <linux/mei.h>
42#include "interface.h"
43
44/* AMT device is a singleton on the platform */
45static struct pci_dev *mei_pdev;
46
47/* mei_pci_tbl - PCI Device ID Table */
48static DEFINE_PCI_DEVICE_TABLE(mei_pci_tbl) = {
49 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)},
50 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G35)},
51 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82Q965)},
52 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G965)},
53 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GM965)},
54 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GME965)},
55 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q35)},
56 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82G33)},
57 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q33)},
58 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82X38)},
59 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_3200)},
60 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_6)},
61 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_7)},
62 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_8)},
63 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_9)},
64 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_10)},
65 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_1)},
66 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_2)},
67 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_3)},
68 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_4)},
69 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_1)},
70 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_2)},
71 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_3)},
72 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_4)},
73 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_1)},
74 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_2)},
75 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_CPT_1)},
76 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PBG_1)},
77 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_1)},
78 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)},
79 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)},
80 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT)},
81 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)},
82
83 /* required last entry */
84 {0, }
85};
86
87MODULE_DEVICE_TABLE(pci, mei_pci_tbl);
88 41
89static DEFINE_MUTEX(mei_mutex); 42#include "mei_dev.h"
90 43#include "hw-me.h"
91 44#include "client.h"
92/**
93 * find_read_list_entry - find read list entry
94 *
95 * @dev: device structure
96 * @file: pointer to file structure
97 *
98 * returns cb on success, NULL on error
99 */
100static struct mei_cl_cb *find_read_list_entry(
101 struct mei_device *dev,
102 struct mei_cl *cl)
103{
104 struct mei_cl_cb *pos = NULL;
105 struct mei_cl_cb *next = NULL;
106
107 dev_dbg(&dev->pdev->dev, "remove read_list CB\n");
108 list_for_each_entry_safe(pos, next, &dev->read_list.list, list)
109 if (mei_cl_cmp_id(cl, pos->cl))
110 return pos;
111 return NULL;
112}
113 45
114/** 46/**
115 * mei_open - the open function 47 * mei_open - the open function
@@ -121,16 +53,20 @@ static struct mei_cl_cb *find_read_list_entry(
121 */ 53 */
122static int mei_open(struct inode *inode, struct file *file) 54static int mei_open(struct inode *inode, struct file *file)
123{ 55{
56 struct miscdevice *misc = file->private_data;
57 struct pci_dev *pdev;
124 struct mei_cl *cl; 58 struct mei_cl *cl;
125 struct mei_device *dev; 59 struct mei_device *dev;
126 unsigned long cl_id; 60
127 int err; 61 int err;
128 62
129 err = -ENODEV; 63 err = -ENODEV;
130 if (!mei_pdev) 64 if (!misc->parent)
131 goto out; 65 goto out;
132 66
133 dev = pci_get_drvdata(mei_pdev); 67 pdev = container_of(misc->parent, struct pci_dev, dev);
68
69 dev = pci_get_drvdata(pdev);
134 if (!dev) 70 if (!dev)
135 goto out; 71 goto out;
136 72
@@ -153,24 +89,9 @@ static int mei_open(struct inode *inode, struct file *file)
153 goto out_unlock; 89 goto out_unlock;
154 } 90 }
155 91
156 cl_id = find_first_zero_bit(dev->host_clients_map, MEI_CLIENTS_MAX); 92 err = mei_cl_link(cl, MEI_HOST_CLIENT_ID_ANY);
157 if (cl_id >= MEI_CLIENTS_MAX) { 93 if (err)
158 dev_err(&dev->pdev->dev, "client_id exceded %d",
159 MEI_CLIENTS_MAX) ;
160 goto out_unlock; 94 goto out_unlock;
161 }
162
163 cl->host_client_id = cl_id;
164
165 dev_dbg(&dev->pdev->dev, "client_id = %d\n", cl->host_client_id);
166
167 dev->open_handle_count++;
168
169 list_add_tail(&cl->link, &dev->file_list);
170
171 set_bit(cl->host_client_id, dev->host_clients_map);
172 cl->state = MEI_FILE_INITIALIZING;
173 cl->sm_state = 0;
174 95
175 file->private_data = cl; 96 file->private_data = cl;
176 mutex_unlock(&dev->device_lock); 97 mutex_unlock(&dev->device_lock);
@@ -216,7 +137,7 @@ static int mei_release(struct inode *inode, struct file *file)
216 "ME client = %d\n", 137 "ME client = %d\n",
217 cl->host_client_id, 138 cl->host_client_id,
218 cl->me_client_id); 139 cl->me_client_id);
219 rets = mei_disconnect_host_client(dev, cl); 140 rets = mei_cl_disconnect(cl);
220 } 141 }
221 mei_cl_flush_queues(cl); 142 mei_cl_flush_queues(cl);
222 dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n", 143 dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n",
@@ -227,12 +148,13 @@ static int mei_release(struct inode *inode, struct file *file)
227 clear_bit(cl->host_client_id, dev->host_clients_map); 148 clear_bit(cl->host_client_id, dev->host_clients_map);
228 dev->open_handle_count--; 149 dev->open_handle_count--;
229 } 150 }
230 mei_me_cl_unlink(dev, cl); 151 mei_cl_unlink(cl);
152
231 153
232 /* free read cb */ 154 /* free read cb */
233 cb = NULL; 155 cb = NULL;
234 if (cl->read_cb) { 156 if (cl->read_cb) {
235 cb = find_read_list_entry(dev, cl); 157 cb = mei_cl_find_read_cb(cl);
236 /* Remove entry from read list */ 158 /* Remove entry from read list */
237 if (cb) 159 if (cb)
238 list_del(&cb->list); 160 list_del(&cb->list);
@@ -322,7 +244,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
322 goto out; 244 goto out;
323 } 245 }
324 246
325 err = mei_start_read(dev, cl); 247 err = mei_cl_read_start(cl);
326 if (err && err != -EBUSY) { 248 if (err && err != -EBUSY) {
327 dev_dbg(&dev->pdev->dev, 249 dev_dbg(&dev->pdev->dev,
328 "mei start read failure with status = %d\n", err); 250 "mei start read failure with status = %d\n", err);
@@ -393,14 +315,13 @@ copy_buffer:
393 goto out; 315 goto out;
394 316
395free: 317free:
396 cb_pos = find_read_list_entry(dev, cl); 318 cb_pos = mei_cl_find_read_cb(cl);
397 /* Remove entry from read list */ 319 /* Remove entry from read list */
398 if (cb_pos) 320 if (cb_pos)
399 list_del(&cb_pos->list); 321 list_del(&cb_pos->list);
400 mei_io_cb_free(cb); 322 mei_io_cb_free(cb);
401 cl->reading_state = MEI_IDLE; 323 cl->reading_state = MEI_IDLE;
402 cl->read_cb = NULL; 324 cl->read_cb = NULL;
403 cl->read_pending = 0;
404out: 325out:
405 dev_dbg(&dev->pdev->dev, "end mei read rets= %d\n", rets); 326 dev_dbg(&dev->pdev->dev, "end mei read rets= %d\n", rets);
406 mutex_unlock(&dev->device_lock); 327 mutex_unlock(&dev->device_lock);
@@ -475,16 +396,15 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
475 /* free entry used in read */ 396 /* free entry used in read */
476 if (cl->reading_state == MEI_READ_COMPLETE) { 397 if (cl->reading_state == MEI_READ_COMPLETE) {
477 *offset = 0; 398 *offset = 0;
478 write_cb = find_read_list_entry(dev, cl); 399 write_cb = mei_cl_find_read_cb(cl);
479 if (write_cb) { 400 if (write_cb) {
480 list_del(&write_cb->list); 401 list_del(&write_cb->list);
481 mei_io_cb_free(write_cb); 402 mei_io_cb_free(write_cb);
482 write_cb = NULL; 403 write_cb = NULL;
483 cl->reading_state = MEI_IDLE; 404 cl->reading_state = MEI_IDLE;
484 cl->read_cb = NULL; 405 cl->read_cb = NULL;
485 cl->read_pending = 0;
486 } 406 }
487 } else if (cl->reading_state == MEI_IDLE && !cl->read_pending) 407 } else if (cl->reading_state == MEI_IDLE)
488 *offset = 0; 408 *offset = 0;
489 409
490 410
@@ -519,7 +439,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
519 439
520 if (rets) { 440 if (rets) {
521 dev_err(&dev->pdev->dev, 441 dev_err(&dev->pdev->dev,
522 "amthi write failed with status = %d\n", rets); 442 "amthif write failed with status = %d\n", rets);
523 goto err; 443 goto err;
524 } 444 }
525 mutex_unlock(&dev->device_lock); 445 mutex_unlock(&dev->device_lock);
@@ -530,20 +450,20 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
530 450
531 dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", 451 dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n",
532 cl->host_client_id, cl->me_client_id); 452 cl->host_client_id, cl->me_client_id);
533 rets = mei_flow_ctrl_creds(dev, cl); 453 rets = mei_cl_flow_ctrl_creds(cl);
534 if (rets < 0) 454 if (rets < 0)
535 goto err; 455 goto err;
536 456
537 if (rets == 0 || dev->mei_host_buffer_is_empty == false) { 457 if (rets == 0 || !dev->hbuf_is_ready) {
538 write_cb->buf_idx = 0; 458 write_cb->buf_idx = 0;
539 mei_hdr.msg_complete = 0; 459 mei_hdr.msg_complete = 0;
540 cl->writing_state = MEI_WRITING; 460 cl->writing_state = MEI_WRITING;
541 goto out; 461 goto out;
542 } 462 }
543 463
544 dev->mei_host_buffer_is_empty = false; 464 dev->hbuf_is_ready = false;
545 if (length > mei_hbuf_max_data(dev)) { 465 if (length > mei_hbuf_max_len(dev)) {
546 mei_hdr.length = mei_hbuf_max_data(dev); 466 mei_hdr.length = mei_hbuf_max_len(dev);
547 mei_hdr.msg_complete = 0; 467 mei_hdr.msg_complete = 0;
548 } else { 468 } else {
549 mei_hdr.length = length; 469 mei_hdr.length = length;
@@ -552,10 +472,10 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
552 mei_hdr.host_addr = cl->host_client_id; 472 mei_hdr.host_addr = cl->host_client_id;
553 mei_hdr.me_addr = cl->me_client_id; 473 mei_hdr.me_addr = cl->me_client_id;
554 mei_hdr.reserved = 0; 474 mei_hdr.reserved = 0;
555 dev_dbg(&dev->pdev->dev, "call mei_write_message header=%08x.\n", 475
556 *((u32 *) &mei_hdr)); 476 dev_dbg(&dev->pdev->dev, "write " MEI_HDR_FMT "\n",
557 if (mei_write_message(dev, &mei_hdr, 477 MEI_HDR_PRM(&mei_hdr));
558 write_cb->request_buffer.data, mei_hdr.length)) { 478 if (mei_write_message(dev, &mei_hdr, write_cb->request_buffer.data)) {
559 rets = -ENODEV; 479 rets = -ENODEV;
560 goto err; 480 goto err;
561 } 481 }
@@ -564,7 +484,7 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
564 484
565out: 485out:
566 if (mei_hdr.msg_complete) { 486 if (mei_hdr.msg_complete) {
567 if (mei_flow_ctrl_reduce(dev, cl)) { 487 if (mei_cl_flow_ctrl_reduce(cl)) {
568 rets = -ENODEV; 488 rets = -ENODEV;
569 goto err; 489 goto err;
570 } 490 }
@@ -582,6 +502,103 @@ err:
582 return rets; 502 return rets;
583} 503}
584 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 */
516static 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
597end:
598 dev_dbg(&dev->pdev->dev, "free connect cb memory.");
599 return rets;
600}
601
585 602
586/** 603/**
587 * mei_ioctl - the IOCTL function 604 * mei_ioctl - the IOCTL function
@@ -630,6 +647,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
630 rets = -EFAULT; 647 rets = -EFAULT;
631 goto out; 648 goto out;
632 } 649 }
650
633 rets = mei_ioctl_connect_client(file, connect_data); 651 rets = mei_ioctl_connect_client(file, connect_data);
634 652
635 /* if all is ok, copying the data back to user. */ 653 /* if all is ok, copying the data back to user. */
@@ -726,7 +744,6 @@ static const struct file_operations mei_fops = {
726 .llseek = no_llseek 744 .llseek = no_llseek
727}; 745};
728 746
729
730/* 747/*
731 * Misc Device Struct 748 * Misc Device Struct
732 */ 749 */
@@ -736,300 +753,17 @@ static struct miscdevice mei_misc_device = {
736 .minor = MISC_DYNAMIC_MINOR, 753 .minor = MISC_DYNAMIC_MINOR,
737}; 754};
738 755
739/** 756int mei_register(struct device *dev)
740 * mei_quirk_probe - probe for devices that doesn't valid ME interface
741 * @pdev: PCI device structure
742 * @ent: entry into pci_device_table
743 *
744 * returns true if ME Interface is valid, false otherwise
745 */
746static bool mei_quirk_probe(struct pci_dev *pdev,
747 const struct pci_device_id *ent)
748{ 757{
749 u32 reg; 758 mei_misc_device.parent = dev;
750 if (ent->device == MEI_DEV_ID_PBG_1) { 759 return misc_register(&mei_misc_device);
751 pci_read_config_dword(pdev, 0x48, &reg);
752 /* make sure that bit 9 is up and bit 10 is down */
753 if ((reg & 0x600) == 0x200) {
754 dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
755 return false;
756 }
757 }
758 return true;
759}
760/**
761 * mei_probe - Device Initialization Routine
762 *
763 * @pdev: PCI device structure
764 * @ent: entry in kcs_pci_tbl
765 *
766 * returns 0 on success, <0 on failure.
767 */
768static int mei_probe(struct pci_dev *pdev,
769 const struct pci_device_id *ent)
770{
771 struct mei_device *dev;
772 int err;
773
774 mutex_lock(&mei_mutex);
775
776 if (!mei_quirk_probe(pdev, ent)) {
777 err = -ENODEV;
778 goto end;
779 }
780
781 if (mei_pdev) {
782 err = -EEXIST;
783 goto end;
784 }
785 /* enable pci dev */
786 err = pci_enable_device(pdev);
787 if (err) {
788 dev_err(&pdev->dev, "failed to enable pci device.\n");
789 goto end;
790 }
791 /* set PCI host mastering */
792 pci_set_master(pdev);
793 /* pci request regions for mei driver */
794 err = pci_request_regions(pdev, KBUILD_MODNAME);
795 if (err) {
796 dev_err(&pdev->dev, "failed to get pci regions.\n");
797 goto disable_device;
798 }
799 /* allocates and initializes the mei dev structure */
800 dev = mei_device_init(pdev);
801 if (!dev) {
802 err = -ENOMEM;
803 goto release_regions;
804 }
805 /* mapping IO device memory */
806 dev->mem_addr = pci_iomap(pdev, 0, 0);
807 if (!dev->mem_addr) {
808 dev_err(&pdev->dev, "mapping I/O device memory failure.\n");
809 err = -ENOMEM;
810 goto free_device;
811 }
812 pci_enable_msi(pdev);
813
814 /* request and enable interrupt */
815 if (pci_dev_msi_enabled(pdev))
816 err = request_threaded_irq(pdev->irq,
817 NULL,
818 mei_interrupt_thread_handler,
819 IRQF_ONESHOT, KBUILD_MODNAME, dev);
820 else
821 err = request_threaded_irq(pdev->irq,
822 mei_interrupt_quick_handler,
823 mei_interrupt_thread_handler,
824 IRQF_SHARED, KBUILD_MODNAME, dev);
825
826 if (err) {
827 dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n",
828 pdev->irq);
829 goto disable_msi;
830 }
831 INIT_DELAYED_WORK(&dev->timer_work, mei_timer);
832 INIT_WORK(&dev->init_work, mei_host_client_init);
833
834 if (mei_hw_init(dev)) {
835 dev_err(&pdev->dev, "init hw failure.\n");
836 err = -ENODEV;
837 goto release_irq;
838 }
839
840 err = misc_register(&mei_misc_device);
841 if (err)
842 goto release_irq;
843
844 mei_pdev = pdev;
845 pci_set_drvdata(pdev, dev);
846
847
848 schedule_delayed_work(&dev->timer_work, HZ);
849
850 mutex_unlock(&mei_mutex);
851
852 pr_debug("initialization successful.\n");
853
854 return 0;
855
856release_irq:
857 /* disable interrupts */
858 dev->host_hw_state = mei_hcsr_read(dev);
859 mei_disable_interrupts(dev);
860 flush_scheduled_work();
861 free_irq(pdev->irq, dev);
862disable_msi:
863 pci_disable_msi(pdev);
864 pci_iounmap(pdev, dev->mem_addr);
865free_device:
866 kfree(dev);
867release_regions:
868 pci_release_regions(pdev);
869disable_device:
870 pci_disable_device(pdev);
871end:
872 mutex_unlock(&mei_mutex);
873 dev_err(&pdev->dev, "initialization failed.\n");
874 return err;
875} 760}
876 761
877/** 762void mei_deregister(void)
878 * mei_remove - Device Removal Routine
879 *
880 * @pdev: PCI device structure
881 *
882 * mei_remove is called by the PCI subsystem to alert the driver
883 * that it should release a PCI device.
884 */
885static void mei_remove(struct pci_dev *pdev)
886{ 763{
887 struct mei_device *dev;
888
889 if (mei_pdev != pdev)
890 return;
891
892 dev = pci_get_drvdata(pdev);
893 if (!dev)
894 return;
895
896 mutex_lock(&dev->device_lock);
897
898 cancel_delayed_work(&dev->timer_work);
899
900 mei_wd_stop(dev);
901
902 mei_pdev = NULL;
903
904 if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) {
905 dev->iamthif_cl.state = MEI_FILE_DISCONNECTING;
906 mei_disconnect_host_client(dev, &dev->iamthif_cl);
907 }
908 if (dev->wd_cl.state == MEI_FILE_CONNECTED) {
909 dev->wd_cl.state = MEI_FILE_DISCONNECTING;
910 mei_disconnect_host_client(dev, &dev->wd_cl);
911 }
912
913 /* Unregistering watchdog device */
914 mei_watchdog_unregister(dev);
915
916 /* remove entry if already in list */
917 dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");
918 mei_me_cl_unlink(dev, &dev->wd_cl);
919 mei_me_cl_unlink(dev, &dev->iamthif_cl);
920
921 dev->iamthif_current_cb = NULL;
922 dev->me_clients_num = 0;
923
924 mutex_unlock(&dev->device_lock);
925
926 flush_scheduled_work();
927
928 /* disable interrupts */
929 mei_disable_interrupts(dev);
930
931 free_irq(pdev->irq, dev);
932 pci_disable_msi(pdev);
933 pci_set_drvdata(pdev, NULL);
934
935 if (dev->mem_addr)
936 pci_iounmap(pdev, dev->mem_addr);
937
938 kfree(dev);
939
940 pci_release_regions(pdev);
941 pci_disable_device(pdev);
942
943 misc_deregister(&mei_misc_device); 764 misc_deregister(&mei_misc_device);
944} 765 mei_misc_device.parent = NULL;
945#ifdef CONFIG_PM
946static int mei_pci_suspend(struct device *device)
947{
948 struct pci_dev *pdev = to_pci_dev(device);
949 struct mei_device *dev = pci_get_drvdata(pdev);
950 int err;
951
952 if (!dev)
953 return -ENODEV;
954 mutex_lock(&dev->device_lock);
955
956 cancel_delayed_work(&dev->timer_work);
957
958 /* Stop watchdog if exists */
959 err = mei_wd_stop(dev);
960 /* Set new mei state */
961 if (dev->dev_state == MEI_DEV_ENABLED ||
962 dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
963 dev->dev_state = MEI_DEV_POWER_DOWN;
964 mei_reset(dev, 0);
965 }
966 mutex_unlock(&dev->device_lock);
967
968 free_irq(pdev->irq, dev);
969 pci_disable_msi(pdev);
970
971 return err;
972} 766}
973 767
974static int mei_pci_resume(struct device *device)
975{
976 struct pci_dev *pdev = to_pci_dev(device);
977 struct mei_device *dev;
978 int err;
979
980 dev = pci_get_drvdata(pdev);
981 if (!dev)
982 return -ENODEV;
983
984 pci_enable_msi(pdev);
985
986 /* request and enable interrupt */
987 if (pci_dev_msi_enabled(pdev))
988 err = request_threaded_irq(pdev->irq,
989 NULL,
990 mei_interrupt_thread_handler,
991 IRQF_ONESHOT, KBUILD_MODNAME, dev);
992 else
993 err = request_threaded_irq(pdev->irq,
994 mei_interrupt_quick_handler,
995 mei_interrupt_thread_handler,
996 IRQF_SHARED, KBUILD_MODNAME, dev);
997
998 if (err) {
999 dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n",
1000 pdev->irq);
1001 return err;
1002 }
1003
1004 mutex_lock(&dev->device_lock);
1005 dev->dev_state = MEI_DEV_POWER_UP;
1006 mei_reset(dev, 1);
1007 mutex_unlock(&dev->device_lock);
1008
1009 /* Start timer if stopped in suspend */
1010 schedule_delayed_work(&dev->timer_work, HZ);
1011
1012 return err;
1013}
1014static SIMPLE_DEV_PM_OPS(mei_pm_ops, mei_pci_suspend, mei_pci_resume);
1015#define MEI_PM_OPS (&mei_pm_ops)
1016#else
1017#define MEI_PM_OPS NULL
1018#endif /* CONFIG_PM */
1019/*
1020 * PCI driver structure
1021 */
1022static struct pci_driver mei_driver = {
1023 .name = KBUILD_MODNAME,
1024 .id_table = mei_pci_tbl,
1025 .probe = mei_probe,
1026 .remove = mei_remove,
1027 .shutdown = mei_remove,
1028 .driver.pm = MEI_PM_OPS,
1029};
1030
1031module_pci_driver(mei_driver);
1032
1033MODULE_AUTHOR("Intel Corporation");
1034MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
1035MODULE_LICENSE("GPL v2"); 768MODULE_LICENSE("GPL v2");
769