Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mei: bus: add vtag support

Add API to support vtag in communication on mei bus.

Add mei_cldev_send_vtag, mei_cldev_recv_vtag and
mei_cldev_recv_nonblock_vtag functions to allow sending a message
with vtag set and to receive vtag of an incoming message.

Cc: Sean Z Huang <sean.z.huang@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Link: https://lore.kernel.org/r/20201116125612.1660971-1-tomas.winkler@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Alexander Usyskin and committed by
Greg Kroah-Hartman
85261c1f 6e559fe1

+113 -35
+8 -5
drivers/misc/mei/bus-fixup.c
··· 148 148 os_ver = (struct mei_os_ver *)fwcaps->data; 149 149 os_ver->os_type = OSTYPE_LINUX; 150 150 151 - return __mei_cl_send(cldev->cl, buf, size, mode); 151 + return __mei_cl_send(cldev->cl, buf, size, 0, mode); 152 152 } 153 153 154 154 #define MKHI_FWVER_BUF_LEN (sizeof(struct mkhi_msg_hdr) + \ ··· 169 169 req.hdr.group_id = MKHI_GEN_GROUP_ID; 170 170 req.hdr.command = MKHI_GEN_GET_FW_VERSION_CMD; 171 171 172 - ret = __mei_cl_send(cldev->cl, (u8 *)&req, sizeof(req), 172 + ret = __mei_cl_send(cldev->cl, (u8 *)&req, sizeof(req), 0, 173 173 MEI_CL_IO_TX_BLOCKING); 174 174 if (ret < 0) { 175 175 dev_err(&cldev->dev, "Could not send ReqFWVersion cmd\n"); ··· 177 177 } 178 178 179 179 ret = 0; 180 - bytes_recv = __mei_cl_recv(cldev->cl, buf, sizeof(buf), 0, 180 + bytes_recv = __mei_cl_recv(cldev->cl, buf, sizeof(buf), NULL, 0, 181 181 MKHI_RCV_TIMEOUT); 182 182 if (bytes_recv < 0 || (size_t)bytes_recv < MKHI_FWVER_LEN(1)) { 183 183 /* ··· 324 324 }; 325 325 struct mei_nfc_reply *reply = NULL; 326 326 size_t if_version_length; 327 + u8 vtag; 327 328 int bytes_recv, ret; 328 329 329 330 bus = cl->dev; 330 331 331 332 WARN_ON(mutex_is_locked(&bus->device_lock)); 332 333 333 - ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(cmd), MEI_CL_IO_TX_BLOCKING); 334 + ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(cmd), 0, 335 + MEI_CL_IO_TX_BLOCKING); 334 336 if (ret < 0) { 335 337 dev_err(bus->dev, "Could not send IF version cmd\n"); 336 338 return ret; ··· 346 344 return -ENOMEM; 347 345 348 346 ret = 0; 349 - bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, 0, 0); 347 + bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, &vtag, 348 + 0, 0); 350 349 if (bytes_recv < 0 || (size_t)bytes_recv < if_version_length) { 351 350 dev_err(bus->dev, "Could not read IF version\n"); 352 351 ret = -EIO;
+93 -26
drivers/misc/mei/bus.c
··· 26 26 * @cl: host client 27 27 * @buf: buffer to send 28 28 * @length: buffer length 29 + * @vtag: virtual tag 29 30 * @mode: sending mode 30 31 * 31 32 * Return: written size bytes or < 0 on error 32 33 */ 33 - ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, 34 + ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, u8 vtag, 34 35 unsigned int mode) 35 36 { 36 37 struct mei_device *bus; ··· 87 86 rets = -ENOMEM; 88 87 goto out; 89 88 } 89 + cb->vtag = vtag; 90 90 91 91 cb->internal = !!(mode & MEI_CL_IO_TX_INTERNAL); 92 92 cb->blocking = !!(mode & MEI_CL_IO_TX_BLOCKING); ··· 108 106 * @buf: buffer to receive 109 107 * @length: buffer length 110 108 * @mode: io mode 109 + * @vtag: virtual tag 111 110 * @timeout: recv timeout, 0 for infinite timeout 112 111 * 113 112 * Return: read size in bytes of < 0 on error 114 113 */ 115 - ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, 114 + ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, u8 *vtag, 116 115 unsigned int mode, unsigned long timeout) 117 116 { 118 117 struct mei_device *bus; ··· 199 196 r_length = min_t(size_t, length, cb->buf_idx); 200 197 memcpy(buf, cb->buf.data, r_length); 201 198 rets = r_length; 199 + if (vtag) 200 + *vtag = cb->vtag; 202 201 203 202 free: 204 203 mei_cl_del_rd_completed(cl, cb); ··· 211 206 } 212 207 213 208 /** 209 + * mei_cldev_send_vtag - me device send with vtag (write) 210 + * 211 + * @cldev: me client device 212 + * @buf: buffer to send 213 + * @length: buffer length 214 + * @vtag: virtual tag 215 + * 216 + * Return: 217 + * * written size in bytes 218 + * * < 0 on error 219 + */ 220 + 221 + ssize_t mei_cldev_send_vtag(struct mei_cl_device *cldev, u8 *buf, size_t length, 222 + u8 vtag) 223 + { 224 + struct mei_cl *cl = cldev->cl; 225 + 226 + return __mei_cl_send(cl, buf, length, vtag, MEI_CL_IO_TX_BLOCKING); 227 + } 228 + EXPORT_SYMBOL_GPL(mei_cldev_send_vtag); 229 + 230 + /** 231 + * mei_cldev_recv_vtag - client receive with vtag (read) 232 + * 233 + * @cldev: me client device 234 + * @buf: buffer to receive 235 + * @length: buffer length 236 + * @vtag: virtual tag 237 + * 238 + * Return: 239 + * * read size in bytes 240 + * * < 0 on error 241 + */ 242 + 243 + ssize_t mei_cldev_recv_vtag(struct mei_cl_device *cldev, u8 *buf, size_t length, 244 + u8 *vtag) 245 + { 246 + struct mei_cl *cl = cldev->cl; 247 + 248 + return __mei_cl_recv(cl, buf, length, vtag, 0, 0); 249 + } 250 + EXPORT_SYMBOL_GPL(mei_cldev_recv_vtag); 251 + 252 + /** 253 + * mei_cldev_recv_nonblock_vtag - non block client receive with vtag (read) 254 + * 255 + * @cldev: me client device 256 + * @buf: buffer to receive 257 + * @length: buffer length 258 + * @vtag: virtual tag 259 + * 260 + * Return: 261 + * * read size in bytes 262 + * * -EAGAIN if function will block. 263 + * * < 0 on other error 264 + */ 265 + ssize_t mei_cldev_recv_nonblock_vtag(struct mei_cl_device *cldev, u8 *buf, 266 + size_t length, u8 *vtag) 267 + { 268 + struct mei_cl *cl = cldev->cl; 269 + 270 + return __mei_cl_recv(cl, buf, length, vtag, MEI_CL_IO_RX_NONBLOCK, 0); 271 + } 272 + EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock_vtag); 273 + 274 + /** 214 275 * mei_cldev_send - me device send (write) 215 276 * 216 277 * @cldev: me client device 217 278 * @buf: buffer to send 218 279 * @length: buffer length 219 280 * 220 - * Return: written size in bytes or < 0 on error 281 + * Return: 282 + * * written size in bytes 283 + * * < 0 on error 221 284 */ 222 285 ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length) 223 286 { 224 - struct mei_cl *cl = cldev->cl; 225 - 226 - return __mei_cl_send(cl, buf, length, MEI_CL_IO_TX_BLOCKING); 287 + return mei_cldev_send_vtag(cldev, buf, length, 0); 227 288 } 228 289 EXPORT_SYMBOL_GPL(mei_cldev_send); 290 + 291 + /** 292 + * mei_cldev_recv - client receive (read) 293 + * 294 + * @cldev: me client device 295 + * @buf: buffer to receive 296 + * @length: buffer length 297 + * 298 + * Return: read size in bytes of < 0 on error 299 + */ 300 + ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length) 301 + { 302 + return mei_cldev_recv_vtag(cldev, buf, length, NULL); 303 + } 304 + EXPORT_SYMBOL_GPL(mei_cldev_recv); 229 305 230 306 /** 231 307 * mei_cldev_recv_nonblock - non block client receive (read) ··· 321 235 ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf, 322 236 size_t length) 323 237 { 324 - struct mei_cl *cl = cldev->cl; 325 - 326 - return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK, 0); 238 + return mei_cldev_recv_nonblock_vtag(cldev, buf, length, NULL); 327 239 } 328 240 EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock); 329 - 330 - /** 331 - * mei_cldev_recv - client receive (read) 332 - * 333 - * @cldev: me client device 334 - * @buf: buffer to receive 335 - * @length: buffer length 336 - * 337 - * Return: read size in bytes of < 0 on error 338 - */ 339 - ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length) 340 - { 341 - struct mei_cl *cl = cldev->cl; 342 - 343 - return __mei_cl_recv(cl, buf, length, 0, 0); 344 - } 345 - EXPORT_SYMBOL_GPL(mei_cldev_recv); 346 241 347 242 /** 348 243 * mei_cl_bus_rx_work - dispatch rx event for a bus device
+4 -2
drivers/misc/mei/client.c
··· 1306 1306 * mei_cl_fp_by_vtag - obtain the file pointer by vtag 1307 1307 * 1308 1308 * @cl: host client 1309 - * @vtag: vm tag 1309 + * @vtag: virtual tag 1310 1310 * 1311 1311 * Return: 1312 1312 * * A file pointer - on success ··· 1317 1317 struct mei_cl_vtag *vtag_l; 1318 1318 1319 1319 list_for_each_entry(vtag_l, &cl->vtag_map, list) 1320 - if (vtag_l->vtag == vtag) 1320 + /* The client on bus has one fixed fp */ 1321 + if ((cl->cldev && mei_cldev_enabled(cl->cldev)) || 1322 + vtag_l->vtag == vtag) 1321 1323 return vtag_l->fp; 1322 1324 1323 1325 return ERR_PTR(-ENOENT);
+2 -2
drivers/misc/mei/mei_dev.h
··· 340 340 /* MEI bus API*/ 341 341 void mei_cl_bus_rescan_work(struct work_struct *work); 342 342 void mei_cl_bus_dev_fixup(struct mei_cl_device *dev); 343 - ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, 343 + ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, u8 vtag, 344 344 unsigned int mode); 345 - ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, 345 + ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, u8 *vtag, 346 346 unsigned int mode, unsigned long timeout); 347 347 bool mei_cl_bus_rx_event(struct mei_cl *cl); 348 348 bool mei_cl_bus_notify_event(struct mei_cl *cl);
+6
include/linux/mei_cl_bus.h
··· 95 95 ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length); 96 96 ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf, 97 97 size_t length); 98 + ssize_t mei_cldev_send_vtag(struct mei_cl_device *cldev, u8 *buf, size_t length, 99 + u8 vtag); 100 + ssize_t mei_cldev_recv_vtag(struct mei_cl_device *cldev, u8 *buf, size_t length, 101 + u8 *vtag); 102 + ssize_t mei_cldev_recv_nonblock_vtag(struct mei_cl_device *cldev, u8 *buf, 103 + size_t length, u8 *vtag); 98 104 99 105 int mei_cldev_register_rx_cb(struct mei_cl_device *cldev, mei_cldev_cb_t rx_cb); 100 106 int mei_cldev_register_notif_cb(struct mei_cl_device *cldev,