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 | 'H' 00-7F linux/hiddev.h conflict! | 124 | 'H' 00-7F linux/hiddev.h conflict! |
| 125 | 'H' 00-0F linux/hidraw.h conflict! | 125 | 'H' 00-0F linux/hidraw.h conflict! |
| 126 | 'H' 01 linux/mei.h conflict! | 126 | 'H' 01 linux/mei.h conflict! |
| 127 | 'H' 02 linux/mei.h conflict! | ||
| 128 | 'H' 03 linux/mei.h conflict! | ||
| 127 | 'H' 00-0F sound/asound.h conflict! | 129 | 'H' 00-0F sound/asound.h conflict! |
| 128 | 'H' 20-40 sound/asound_fm.h conflict! | 130 | 'H' 20-40 sound/asound_fm.h conflict! |
| 129 | 'H' 80-8F sound/sfnt_info.h conflict! | 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 | IOCTL | 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 | IOCTL_MEI_CONNECT_CLIENT Connect to firmware Feature (client). | 100 | IOCTL_MEI_CONNECT_CLIENT Connect to firmware Feature (client). |
| 101 | 101 | ||
| 102 | usage: | 102 | usage: |
| @@ -125,6 +125,49 @@ The Intel MEI Driver supports the following IOCTL command: · 22 unmodified lines | |||
| 125 | data that can be sent or received. (e.g. if MTU=2K, can send | 125 | data that can be sent or received. (e.g. if MTU=2K, can send |
| 126 | requests up to bytes 2k and received responses up to 2k bytes). | 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 | Intel ME Applications | 172 | Intel ME Applications |
| 130 | ===================== | 173 | ===================== |
| @@ -445,6 +445,45 @@ end: · 444 unmodified lines | |||
| 445 | return rets; | 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 | * mei_ioctl - the IOCTL function | 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 | struct mei_device *dev; | 498 | struct mei_device *dev; |
| 460 | struct mei_cl *cl = file->private_data; | 499 | struct mei_cl *cl = file->private_data; |
| 461 | struct mei_connect_client_data connect_data; | 500 | struct mei_connect_client_data connect_data; |
| 501 | u32 notify_get, notify_req; | ||
| 462 | int rets; | 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 | break; | 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 | default: | 569 | default: |
| 503 | dev_err(dev->dev, ": unsupported ioctl %d.\n", cmd); | 570 | dev_err(dev->dev, ": unsupported ioctl %d.\n", cmd); |
| 504 | rets = -ENOIOCTLCMD; | 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 | #endif /* _LINUX_MEI_H */ | 129 | #endif /* _LINUX_MEI_H */ |