Add ioctl IOCTL_MEI_NOTIFY_SET for enabling and disabling async event notification. Add ioctl IOCTL_MEI_NOTIFY_GET for receiving and acking an event notification.
Unified · Split
| @@ -124,6 +124,8 @@ Code Seq#(hex) Include File Comments · 123 unmodified lines | ||
| 124 | 124 | 'H' 00-7F linux/hiddev.h conflict! |
| 125 | 125 | 'H' 00-0F linux/hidraw.h conflict! |
| 126 | 126 | 'H' 01 linux/mei.h conflict! |
| 127 | +'H' 02 linux/mei.h conflict! | |
| 128 | +'H' 03 linux/mei.h conflict! | |
| 127 | 129 | 'H' 00-0F sound/asound.h conflict! |
| 128 | 130 | 'H' 20-40 sound/asound_fm.h conflict! |
| 129 | 131 | 'H' 80-8F sound/sfnt_info.h conflict! |
| @@ -96,7 +96,7 @@ A code snippet for an application communicating with Intel AMTHI client: · 95 unmodified lines | ||
| 96 | 96 | IOCTL |
| 97 | 97 | ===== |
| 98 | 98 | |
| 99 | −The Intel MEI Driver supports the following IOCTL command: | |
| 99 | +The Intel MEI Driver supports the following IOCTL commands: | |
| 100 | 100 | IOCTL_MEI_CONNECT_CLIENT Connect to firmware Feature (client). |
| 101 | 101 | |
| 102 | 102 | usage: |
| @@ -125,6 +125,49 @@ The Intel MEI Driver supports the following IOCTL command: · 22 unmodified lines | ||
| 125 | 125 | data that can be sent or received. (e.g. if MTU=2K, can send |
| 126 | 126 | requests up to bytes 2k and received responses up to 2k bytes). |
| 127 | 127 | |
| 128 | + IOCTL_MEI_NOTIFY_SET: enable or disable event notifications | |
| 129 | + | |
| 130 | + Usage: | |
| 131 | + uint32_t enable; | |
| 132 | + ioctl(fd, IOCTL_MEI_NOTIFY_SET, &enable); | |
| 133 | + | |
| 134 | + Inputs: | |
| 135 | + uint32_t enable = 1; | |
| 136 | + or | |
| 137 | + uint32_t enable[disable] = 0; | |
| 138 | + | |
| 139 | + Error returns: | |
| 140 | + EINVAL Wrong IOCTL Number | |
| 141 | + ENODEV Device is not initialized or the client not connected | |
| 142 | + ENOMEM Unable to allocate memory to client internal data. | |
| 143 | + EFAULT Fatal Error (e.g. Unable to access user input data) | |
| 144 | + EOPNOTSUPP if the device doesn't support the feature | |
| 145 | + | |
| 146 | + Notes: | |
| 147 | + The client must be connected in order to enable notification events | |
| 148 | + | |
| 149 | + | |
| 150 | + IOCTL_MEI_NOTIFY_GET : retrieve event | |
| 151 | + | |
| 152 | + Usage: | |
| 153 | + uint32_t event; | |
| 154 | + ioctl(fd, IOCTL_MEI_NOTIFY_GET, &event); | |
| 155 | + | |
| 156 | + Outputs: | |
| 157 | + 1 - if an event is pending | |
| 158 | + 0 - if there is no even pending | |
| 159 | + | |
| 160 | + Error returns: | |
| 161 | + EINVAL Wrong IOCTL Number | |
| 162 | + ENODEV Device is not initialized or the client not connected | |
| 163 | + ENOMEM Unable to allocate memory to client internal data. | |
| 164 | + EFAULT Fatal Error (e.g. Unable to access user input data) | |
| 165 | + EOPNOTSUPP if the device doesn't support the feature | |
| 166 | + | |
| 167 | + Notes: | |
| 168 | + The client must be connected and event notification has to be enabled | |
| 169 | + in order to receive an event | |
| 170 | + | |
| 128 | 171 | |
| 129 | 172 | Intel ME Applications |
| 130 | 173 | ===================== |
| @@ -445,6 +445,45 @@ end: · 444 unmodified lines | ||
| 445 | 445 | return rets; |
| 446 | 446 | } |
| 447 | 447 | |
| 448 | +/** | |
| 449 | + * mei_ioctl_client_notify_request - | |
| 450 | + * propagate event notification request to client | |
| 451 | + * | |
| 452 | + * @file: pointer to file structure | |
| 453 | + * @request: 0 - disable, 1 - enable | |
| 454 | + * | |
| 455 | + * Return: 0 on success , <0 on error | |
| 456 | + */ | |
| 457 | +static int mei_ioctl_client_notify_request(struct file *file, u32 request) | |
| 458 | +{ | |
| 459 | + struct mei_cl *cl = file->private_data; | |
| 460 | + | |
| 461 | + return mei_cl_notify_request(cl, file, request); | |
| 462 | +} | |
| 463 | + | |
| 464 | +/** | |
| 465 | + * mei_ioctl_client_notify_get - wait for notification request | |
| 466 | + * | |
| 467 | + * @file: pointer to file structure | |
| 468 | + * @notify_get: 0 - disable, 1 - enable | |
| 469 | + * | |
| 470 | + * Return: 0 on success , <0 on error | |
| 471 | + */ | |
| 472 | +static int mei_ioctl_client_notify_get(struct file *file, u32 *notify_get) | |
| 473 | +{ | |
| 474 | + struct mei_cl *cl = file->private_data; | |
| 475 | + bool notify_ev; | |
| 476 | + bool block = (file->f_flags & O_NONBLOCK) == 0; | |
| 477 | + int rets; | |
| 478 | + | |
| 479 | + rets = mei_cl_notify_get(cl, block, ¬ify_ev); | |
| 480 | + if (rets) | |
| 481 | + return rets; | |
| 482 | + | |
| 483 | + *notify_get = notify_ev ? 1 : 0; | |
| 484 | + return 0; | |
| 485 | +} | |
| 486 | + | |
| 448 | 487 | /** |
| 449 | 488 | * mei_ioctl - the IOCTL function |
| 450 | 489 | * |
| @@ -459,6 +498,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) · 8 unmodified lines | ||
| 459 | 498 | struct mei_device *dev; |
| 460 | 499 | struct mei_cl *cl = file->private_data; |
| 461 | 500 | struct mei_connect_client_data connect_data; |
| 501 | + u32 notify_get, notify_req; | |
| 462 | 502 | int rets; |
| 463 | 503 | |
| 464 | 504 | |
| @@ -499,6 +539,33 @@ static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data) · 34 unmodified lines | ||
| 499 | 539 | |
| 500 | 540 | break; |
| 501 | 541 | |
| 542 | + case IOCTL_MEI_NOTIFY_SET: | |
| 543 | + dev_dbg(dev->dev, ": IOCTL_MEI_NOTIFY_SET.\n"); | |
| 544 | + if (copy_from_user(¬ify_req, | |
| 545 | + (char __user *)data, sizeof(notify_req))) { | |
| 546 | + dev_dbg(dev->dev, "failed to copy data from userland\n"); | |
| 547 | + rets = -EFAULT; | |
| 548 | + goto out; | |
| 549 | + } | |
| 550 | + rets = mei_ioctl_client_notify_request(file, notify_req); | |
| 551 | + break; | |
| 552 | + | |
| 553 | + case IOCTL_MEI_NOTIFY_GET: | |
| 554 | + dev_dbg(dev->dev, ": IOCTL_MEI_NOTIFY_GET.\n"); | |
| 555 | + rets = mei_ioctl_client_notify_get(file, ¬ify_get); | |
| 556 | + if (rets) | |
| 557 | + goto out; | |
| 558 | + | |
| 559 | + dev_dbg(dev->dev, "copy connect data to user\n"); | |
| 560 | + if (copy_to_user((char __user *)data, | |
| 561 | + ¬ify_get, sizeof(notify_get))) { | |
| 562 | + dev_dbg(dev->dev, "failed to copy data to userland\n"); | |
| 563 | + rets = -EFAULT; | |
| 564 | + goto out; | |
| 565 | + | |
| 566 | + } | |
| 567 | + break; | |
| 568 | + | |
| 502 | 569 | default: |
| 503 | 570 | dev_err(dev->dev, ": unsupported ioctl %d.\n", cmd); |
| 504 | 571 | rets = -ENOIOCTLCMD; |
| @@ -107,4 +107,23 @@ struct mei_connect_client_data { · 106 unmodified lines | ||
| 107 | 107 | }; |
| 108 | 108 | }; |
| 109 | 109 | |
| 110 | +/** | |
| 111 | + * DOC: set and unset event notification for a connected client | |
| 112 | + * | |
| 113 | + * The IOCTL argument is 1 for enabling event notification and 0 for | |
| 114 | + * disabling the service | |
| 115 | + * Return: -EOPNOTSUPP if the devices doesn't support the feature | |
| 116 | + */ | |
| 117 | +#define IOCTL_MEI_NOTIFY_SET _IOW('H', 0x02, __u32) | |
| 118 | + | |
| 119 | +/** | |
| 120 | + * DOC: retrieve notification | |
| 121 | + * | |
| 122 | + * The IOCTL output argument is 1 if an event was is pending and 0 otherwise | |
| 123 | + * the ioctl has to be called in order to acknowledge pending event | |
| 124 | + * | |
| 125 | + * Return: -EOPNOTSUPP if the devices doesn't support the feature | |
| 126 | + */ | |
| 127 | +#define IOCTL_MEI_NOTIFY_GET _IOR('H', 0x03, __u32) | |
| 128 | + | |
| 110 | 129 | #endif /* _LINUX_MEI_H */ |