3 * Intel Management Engine Interface (Intel MEI) Linux driver
4 * Copyright (c) 2003-2012, Intel Corporation.
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.
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
17 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/types.h>
21 #include <linux/fcntl.h>
22 #include <linux/ioctl.h>
23 #include <linux/cdev.h>
24 #include <linux/list.h>
25 #include <linux/delay.h>
26 #include <linux/sched.h>
27 #include <linux/uuid.h>
28 #include <linux/jiffies.h>
29 #include <linux/uaccess.h>
30 #include <linux/slab.h>
32 #include <linux/mei.h>
38 const uuid_le mei_amthif_guid = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d,
39 0xac, 0xa8, 0x46, 0xe0,
40 0xff, 0x65, 0x81, 0x4c);
43 * mei_amthif_reset_params - initializes mei device iamthif
45 * @dev: the device structure
47 void mei_amthif_reset_params(struct mei_device *dev)
49 /* reset iamthif parameters. */
50 dev->iamthif_canceled = false;
51 dev->iamthif_state = MEI_IAMTHIF_IDLE;
52 dev->iamthif_stall_timer = 0;
53 dev->iamthif_open_count = 0;
57 * mei_amthif_host_init - mei initialization amthif client.
59 * @dev: the device structure
62 * Return: 0 on success, <0 on failure.
64 int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl)
66 struct mei_cl *cl = &dev->iamthif_cl;
69 mutex_lock(&dev->device_lock);
71 if (mei_cl_is_connected(cl)) {
76 dev->iamthif_state = MEI_IAMTHIF_IDLE;
80 ret = mei_cl_link(cl);
82 dev_err(dev->dev, "amthif: failed cl_link %d\n", ret);
86 ret = mei_cl_connect(cl, me_cl, NULL);
89 mutex_unlock(&dev->device_lock);
94 * mei_amthif_read_start - queue message for sending read credential
97 * @fp: file pointer of message recipient
99 * Return: 0 on success, <0 on failure.
101 static int mei_amthif_read_start(struct mei_cl *cl, const struct file *fp)
103 struct mei_device *dev = cl->dev;
104 struct mei_cl_cb *cb;
106 cb = mei_cl_enqueue_ctrl_wr_cb(cl, mei_cl_mtu(cl), MEI_FOP_READ, fp);
110 cl->rx_flow_ctrl_creds++;
112 dev->iamthif_state = MEI_IAMTHIF_READING;
119 * mei_amthif_run_next_cmd - send next amt command from queue
121 * @dev: the device structure
123 * Return: 0 on success, <0 on failure.
125 int mei_amthif_run_next_cmd(struct mei_device *dev)
127 struct mei_cl *cl = &dev->iamthif_cl;
128 struct mei_cl_cb *cb;
131 dev->iamthif_canceled = false;
133 dev_dbg(dev->dev, "complete amthif cmd_list cb.\n");
135 cb = list_first_entry_or_null(&dev->amthif_cmd_list.list,
138 dev->iamthif_state = MEI_IAMTHIF_IDLE;
143 list_del_init(&cb->list);
144 dev->iamthif_state = MEI_IAMTHIF_WRITING;
147 ret = mei_cl_write(cl, cb, false);
152 cb->status = mei_amthif_read_start(cl, cb->fp);
158 * mei_amthif_write - write amthif data to amthif client
161 * @cb: mei call back struct
163 * Return: 0 on success, <0 on failure.
165 int mei_amthif_write(struct mei_cl *cl, struct mei_cl_cb *cb)
168 struct mei_device *dev = cl->dev;
170 list_add_tail(&cb->list, &dev->amthif_cmd_list.list);
173 * The previous request is still in processing, queue this one.
175 if (dev->iamthif_state != MEI_IAMTHIF_IDLE)
178 return mei_amthif_run_next_cmd(dev);
182 * mei_amthif_poll - the amthif poll function
184 * @file: pointer to file structure
185 * @wait: pointer to poll_table structure
189 * Locking: called under "dev->device_lock" lock
191 unsigned int mei_amthif_poll(struct file *file, poll_table *wait)
193 struct mei_cl *cl = file->private_data;
194 struct mei_cl_cb *cb = mei_cl_read_cb(cl, file);
195 unsigned int mask = 0;
197 poll_wait(file, &cl->rx_wait, wait);
199 mask |= POLLIN | POLLRDNORM;
205 * mei_amthif_irq_write - write iamthif command in irq thread context.
207 * @cl: private data of the file object.
208 * @cb: callback block.
209 * @cmpl_list: complete list.
211 * Return: 0, OK; otherwise, error.
213 int mei_amthif_irq_write(struct mei_cl *cl, struct mei_cl_cb *cb,
214 struct mei_cl_cb *cmpl_list)
218 ret = mei_cl_irq_write(cl, cb, cmpl_list);
223 cb->status = mei_amthif_read_start(cl, cb->fp);
229 * mei_amthif_irq_read_msg - read routine after ISR to
230 * handle the read amthif message
233 * @mei_hdr: header of amthif message
234 * @cmpl_list: completed callbacks list
236 * Return: -ENODEV if cb is NULL 0 otherwise; error message is in cb->status
238 int mei_amthif_irq_read_msg(struct mei_cl *cl,
239 struct mei_msg_hdr *mei_hdr,
240 struct mei_cl_cb *cmpl_list)
242 struct mei_device *dev;
247 if (dev->iamthif_state != MEI_IAMTHIF_READING) {
248 mei_irq_discard_msg(dev, mei_hdr);
252 ret = mei_cl_irq_read_msg(cl, mei_hdr, cmpl_list);
256 if (!mei_hdr->msg_complete)
259 dev_dbg(dev->dev, "completed amthif read.\n ");
260 dev->iamthif_stall_timer = 0;
266 * mei_amthif_complete - complete amthif callback.
269 * @cb: callback block.
271 void mei_amthif_complete(struct mei_cl *cl, struct mei_cl_cb *cb)
273 struct mei_device *dev = cl->dev;
275 dev_dbg(dev->dev, "completing amthif call back.\n");
276 switch (cb->fop_type) {
279 dev->iamthif_stall_timer = MEI_IAMTHIF_STALL_TIMER;
280 mei_schedule_stall_timer(dev);
284 dev->iamthif_state = MEI_IAMTHIF_IDLE;
286 if (!dev->iamthif_canceled) {
288 * in case of error enqueue the write cb to complete
289 * read list so it can be propagated to the reader
291 list_add_tail(&cb->list, &cl->rd_completed);
292 wake_up_interruptible(&cl->rx_wait);
298 if (!dev->iamthif_canceled) {
299 list_add_tail(&cb->list, &cl->rd_completed);
300 dev_dbg(dev->dev, "amthif read completed\n");
301 wake_up_interruptible(&cl->rx_wait);
306 dev->iamthif_stall_timer = 0;
307 mei_amthif_run_next_cmd(dev);
315 * mei_clear_list - removes all callbacks associated with file
318 * @file: file structure
319 * @mei_cb_list: callbacks list
321 * mei_clear_list is called to clear resources associated with file
322 * when application calls close function or Ctrl-C was pressed
324 static void mei_clear_list(const struct file *file,
325 struct list_head *mei_cb_list)
327 struct mei_cl_cb *cb, *next;
329 list_for_each_entry_safe(cb, next, mei_cb_list, list)
335 * mei_amthif_release - the release function
337 * @dev: device structure
338 * @file: pointer to file structure
340 * Return: 0 on success, <0 on error
342 int mei_amthif_release(struct mei_device *dev, struct file *file)
344 struct mei_cl *cl = file->private_data;
346 if (dev->iamthif_open_count > 0)
347 dev->iamthif_open_count--;
349 if (cl->fp == file && dev->iamthif_state != MEI_IAMTHIF_IDLE) {
351 dev_dbg(dev->dev, "amthif canceled iamthif state %d\n",
353 dev->iamthif_canceled = true;
356 mei_clear_list(file, &dev->amthif_cmd_list.list);
357 mei_clear_list(file, &cl->rd_completed);
358 mei_clear_list(file, &dev->ctrl_rd_list.list);