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

mei: add a reference from the host client to the me client

Keep a pointer to associated me client in the host client object to
eliminate me client searches. Check if the me client is active in the
firmware by checking if its is linked on the me clients list
Add accessors for the me client properties from host client.

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Alexander Usyskin and committed by
Greg Kroah-Hartman
d49ed64a 0c53357c

+228 -182
+4 -15
drivers/misc/mei/amthif.c
··· 59 59 * mei_amthif_host_init - mei initialization amthif client. 60 60 * 61 61 * @dev: the device structure 62 + * @me_cl: me client 62 63 * 63 64 * Return: 0 on success, <0 on failure. 64 65 */ 65 - int mei_amthif_host_init(struct mei_device *dev) 66 + int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl) 66 67 { 67 68 struct mei_cl *cl = &dev->iamthif_cl; 68 - struct mei_me_client *me_cl; 69 69 int ret; 70 70 71 71 dev->iamthif_state = MEI_IAMTHIF_IDLE; 72 72 73 73 mei_cl_init(cl, dev); 74 - 75 - me_cl = mei_me_cl_by_uuid(dev, &mei_amthif_guid); 76 - if (!me_cl) { 77 - dev_info(dev->dev, "amthif: failed to find the client"); 78 - return -ENOTTY; 79 - } 80 - 81 - cl->me_client_id = me_cl->client_id; 82 - cl->cl_uuid = me_cl->props.protocol_name; 83 74 84 75 /* Assign iamthif_mtu to the value received from ME */ 85 76 ··· 81 90 ret = mei_cl_link(cl, MEI_IAMTHIF_HOST_CLIENT_ID); 82 91 if (ret < 0) { 83 92 dev_err(dev->dev, "amthif: failed cl_link %d\n", ret); 84 - goto out; 93 + return ret; 85 94 } 86 95 87 - ret = mei_cl_connect(cl, NULL); 96 + ret = mei_cl_connect(cl, me_cl, NULL); 88 97 89 98 dev->iamthif_state = MEI_IAMTHIF_IDLE; 90 99 91 - out: 92 - mei_me_cl_put(me_cl); 93 100 return ret; 94 101 } 95 102
+23 -15
drivers/misc/mei/bus.c
··· 133 133 134 134 static void mei_cl_dev_release(struct device *dev) 135 135 { 136 - kfree(to_mei_cl_device(dev)); 136 + struct mei_cl_device *device = to_mei_cl_device(dev); 137 + 138 + if (!device) 139 + return; 140 + 141 + mei_me_cl_put(device->me_cl); 142 + kfree(device); 137 143 } 138 144 139 145 static struct device_type mei_cl_device_type = { ··· 147 141 }; 148 142 149 143 struct mei_cl *mei_cl_bus_find_cl_by_uuid(struct mei_device *dev, 150 - uuid_le uuid) 144 + uuid_le uuid) 151 145 { 152 146 struct mei_cl *cl; 153 147 154 148 list_for_each_entry(cl, &dev->device_list, device_link) { 155 - if (!uuid_le_cmp(uuid, cl->cl_uuid)) 149 + if (cl->device && cl->device->me_cl && 150 + !uuid_le_cmp(uuid, *mei_me_cl_uuid(cl->device->me_cl))) 156 151 return cl; 157 152 } 158 153 159 154 return NULL; 160 155 } 156 + 161 157 struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, 162 - uuid_le uuid, char *name, 158 + struct mei_me_client *me_cl, 159 + struct mei_cl *cl, 160 + char *name, 163 161 struct mei_cl_ops *ops) 164 162 { 165 163 struct mei_cl_device *device; 166 - struct mei_cl *cl; 167 164 int status; 168 - 169 - cl = mei_cl_bus_find_cl_by_uuid(dev, uuid); 170 - if (cl == NULL) 171 - return NULL; 172 165 173 166 device = kzalloc(sizeof(struct mei_cl_device), GFP_KERNEL); 174 167 if (!device) 175 168 return NULL; 176 169 170 + device->me_cl = mei_me_cl_get(me_cl); 171 + if (!device->me_cl) { 172 + kfree(device); 173 + return NULL; 174 + } 177 175 device->cl = cl; 178 176 device->ops = ops; 179 177 ··· 190 180 status = device_register(&device->dev); 191 181 if (status) { 192 182 dev_err(dev->dev, "Failed to register MEI device\n"); 183 + mei_me_cl_put(device->me_cl); 193 184 kfree(device); 194 185 return NULL; 195 186 } ··· 239 228 bool blocking) 240 229 { 241 230 struct mei_device *dev; 242 - struct mei_me_client *me_cl = NULL; 243 231 struct mei_cl_cb *cb = NULL; 244 232 ssize_t rets; 245 233 ··· 254 244 } 255 245 256 246 /* Check if we have an ME client device */ 257 - me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id); 258 - if (!me_cl) { 247 + if (!mei_me_cl_is_active(cl->me_cl)) { 259 248 rets = -ENOTTY; 260 249 goto out; 261 250 } 262 251 263 - if (length > me_cl->props.max_msg_length) { 252 + if (length > mei_cl_mtu(cl)) { 264 253 rets = -EFBIG; 265 254 goto out; 266 255 } ··· 275 266 rets = mei_cl_write(cl, cb, blocking); 276 267 277 268 out: 278 - mei_me_cl_put(me_cl); 279 269 mutex_unlock(&dev->device_lock); 280 270 if (rets < 0) 281 271 mei_io_cb_free(cb); ··· 450 442 return -EBUSY; 451 443 } 452 444 453 - err = mei_cl_connect(cl, NULL); 445 + err = mei_cl_connect(cl, device->me_cl, NULL); 454 446 if (err < 0) { 455 447 mutex_unlock(&dev->device_lock); 456 448 dev_err(dev->dev, "Could not connect to the ME client");
+52 -66
drivers/misc/mei/client.c
··· 83 83 } 84 84 85 85 /** 86 - * __mei_me_cl_del - delete me client form the list and decrease 86 + * __mei_me_cl_del - delete me client from the list and decrease 87 87 * reference counter 88 88 * 89 89 * @dev: mei device ··· 96 96 if (!me_cl) 97 97 return; 98 98 99 - list_del(&me_cl->list); 99 + list_del_init(&me_cl->list); 100 100 mei_me_cl_put(me_cl); 101 + } 102 + 103 + /** 104 + * mei_me_cl_del - delete me client from the list and decrease 105 + * reference counter 106 + * 107 + * @dev: mei device 108 + * @me_cl: me client 109 + */ 110 + void mei_me_cl_del(struct mei_device *dev, struct mei_me_client *me_cl) 111 + { 112 + down_write(&dev->me_clients_rwsem); 113 + __mei_me_cl_del(dev, me_cl); 114 + up_write(&dev->me_clients_rwsem); 101 115 } 102 116 103 117 /** ··· 331 317 { 332 318 return cl1 && cl2 && 333 319 (cl1->host_client_id == cl2->host_client_id) && 334 - (cl1->me_client_id == cl2->me_client_id); 320 + (mei_cl_me_id(cl1) == mei_cl_me_id(cl2)); 335 321 } 336 322 337 323 /** ··· 634 620 } 635 621 636 622 /** 637 - * mei_cl_unlink - remove me_cl from the list 623 + * mei_cl_unlink - remove host client from the list 638 624 * 639 625 * @cl: host client 640 626 * ··· 682 668 683 669 me_cl = mei_me_cl_by_uuid(dev, &mei_amthif_guid); 684 670 if (me_cl) 685 - mei_amthif_host_init(dev); 671 + mei_amthif_host_init(dev, me_cl); 686 672 mei_me_cl_put(me_cl); 687 673 688 674 me_cl = mei_me_cl_by_uuid(dev, &mei_wd_guid); 689 675 if (me_cl) 690 - mei_wd_host_init(dev); 676 + mei_wd_host_init(dev, me_cl); 691 677 mei_me_cl_put(me_cl); 692 678 693 679 me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_guid); 694 680 if (me_cl) 695 - mei_nfc_host_init(dev); 681 + mei_nfc_host_init(dev, me_cl); 696 682 mei_me_cl_put(me_cl); 697 683 698 684 ··· 748 734 mei_io_list_flush(&dev->ctrl_wr_list, cl); 749 735 cl->mei_flow_ctrl_creds = 0; 750 736 cl->timer_count = 0; 737 + 738 + mei_me_cl_put(cl->me_cl); 739 + cl->me_cl = NULL; 751 740 } 752 741 753 742 /* ··· 907 890 908 891 list_for_each_entry(cb, &dev->ctrl_rd_list.list, list) { 909 892 if (cb->fop_type == MEI_FOP_CONNECT && 910 - cl->me_client_id == cb->cl->me_client_id) 893 + mei_cl_me_id(cl) == mei_cl_me_id(cb->cl)) 911 894 return true; 912 895 } 913 896 ··· 978 961 * mei_cl_connect - connect host client to the me one 979 962 * 980 963 * @cl: host client 964 + * @me_cl: me client 981 965 * @file: pointer to file structure 982 966 * 983 967 * Locking: called under "dev->device_lock" lock 984 968 * 985 969 * Return: 0 on success, <0 on failure. 986 970 */ 987 - int mei_cl_connect(struct mei_cl *cl, struct file *file) 971 + int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, 972 + struct file *file) 988 973 { 989 974 struct mei_device *dev; 990 975 struct mei_cl_cb *cb; ··· 1008 989 rets = cb ? 0 : -ENOMEM; 1009 990 if (rets) 1010 991 goto out; 992 + 993 + cl->me_cl = mei_me_cl_get(me_cl); 994 + if (!cl->me_cl) { 995 + rets = -ENODEV; 996 + goto out; 997 + } 1011 998 1012 999 cl->state = MEI_FILE_CONNECTING; 1013 1000 list_add_tail(&cb->list, &dev->ctrl_wr_list.list); ··· 1089 1064 * @cl: private data of the file object 1090 1065 * 1091 1066 * Return: 1 if mei_flow_ctrl_creds >0, 0 - otherwise. 1092 - * -ENOENT if mei_cl is not present 1093 - * -EINVAL if single_recv_buf == 0 1094 1067 */ 1095 1068 int mei_cl_flow_ctrl_creds(struct mei_cl *cl) 1096 1069 { 1097 - struct mei_device *dev; 1098 - struct mei_me_client *me_cl; 1099 - int rets = 0; 1100 - 1101 - if (WARN_ON(!cl || !cl->dev)) 1070 + if (WARN_ON(!cl || !cl->me_cl)) 1102 1071 return -EINVAL; 1103 - 1104 - dev = cl->dev; 1105 1072 1106 1073 if (cl->mei_flow_ctrl_creds > 0) 1107 1074 return 1; 1108 1075 1109 - me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id); 1110 - if (!me_cl) { 1111 - cl_err(dev, cl, "no such me client %d\n", cl->me_client_id); 1112 - return -ENOENT; 1076 + if (mei_cl_is_single_recv_buf(cl)) { 1077 + if (cl->me_cl->mei_flow_ctrl_creds > 0) 1078 + return 1; 1113 1079 } 1114 - 1115 - if (me_cl->mei_flow_ctrl_creds > 0) { 1116 - rets = 1; 1117 - if (WARN_ON(me_cl->props.single_recv_buf == 0)) 1118 - rets = -EINVAL; 1119 - } 1120 - mei_me_cl_put(me_cl); 1121 - return rets; 1080 + return 0; 1122 1081 } 1123 1082 1124 1083 /** ··· 1112 1103 * 1113 1104 * Return: 1114 1105 * 0 on success 1115 - * -ENOENT when me client is not found 1116 1106 * -EINVAL when ctrl credits are <= 0 1117 1107 */ 1118 1108 int mei_cl_flow_ctrl_reduce(struct mei_cl *cl) 1119 1109 { 1120 - struct mei_device *dev; 1121 - struct mei_me_client *me_cl; 1122 - int rets; 1123 - 1124 - if (WARN_ON(!cl || !cl->dev)) 1110 + if (WARN_ON(!cl || !cl->me_cl)) 1125 1111 return -EINVAL; 1126 1112 1127 - dev = cl->dev; 1128 - 1129 - me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id); 1130 - if (!me_cl) { 1131 - cl_err(dev, cl, "no such me client %d\n", cl->me_client_id); 1132 - return -ENOENT; 1133 - } 1134 - 1135 - if (me_cl->props.single_recv_buf) { 1136 - if (WARN_ON(me_cl->mei_flow_ctrl_creds <= 0)) { 1137 - rets = -EINVAL; 1138 - goto out; 1139 - } 1140 - me_cl->mei_flow_ctrl_creds--; 1113 + if (mei_cl_is_single_recv_buf(cl)) { 1114 + if (WARN_ON(cl->me_cl->mei_flow_ctrl_creds <= 0)) 1115 + return -EINVAL; 1116 + cl->me_cl->mei_flow_ctrl_creds--; 1141 1117 } else { 1142 - if (WARN_ON(cl->mei_flow_ctrl_creds <= 0)) { 1143 - rets = -EINVAL; 1144 - goto out; 1145 - } 1118 + if (WARN_ON(cl->mei_flow_ctrl_creds <= 0)) 1119 + return -EINVAL; 1146 1120 cl->mei_flow_ctrl_creds--; 1147 1121 } 1148 - rets = 0; 1149 - out: 1150 - mei_me_cl_put(me_cl); 1151 - return rets; 1122 + return 0; 1152 1123 } 1153 1124 1154 1125 /** ··· 1144 1155 { 1145 1156 struct mei_device *dev; 1146 1157 struct mei_cl_cb *cb; 1147 - struct mei_me_client *me_cl; 1148 1158 int rets; 1149 1159 1150 1160 if (WARN_ON(!cl || !cl->dev)) ··· 1158 1170 if (!list_empty(&cl->rd_pending)) 1159 1171 return -EBUSY; 1160 1172 1161 - me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id); 1162 - if (!me_cl) { 1163 - cl_err(dev, cl, "no such me client %d\n", cl->me_client_id); 1173 + if (!mei_me_cl_is_active(cl->me_cl)) { 1174 + cl_err(dev, cl, "no such me client\n"); 1164 1175 return -ENOTTY; 1165 1176 } 1166 1177 /* always allocate at least client max message */ 1167 - length = max_t(size_t, length, me_cl->props.max_msg_length); 1168 - mei_me_cl_put(me_cl); 1178 + length = max_t(size_t, length, mei_cl_mtu(cl)); 1169 1179 1170 1180 rets = pm_runtime_get(dev->dev); 1171 1181 if (rets < 0 && rets != -EINPROGRESS) { ··· 1240 1254 msg_slots = mei_data2slots(len); 1241 1255 1242 1256 mei_hdr.host_addr = cl->host_client_id; 1243 - mei_hdr.me_addr = cl->me_client_id; 1257 + mei_hdr.me_addr = mei_cl_me_id(cl); 1244 1258 mei_hdr.reserved = 0; 1245 1259 mei_hdr.internal = cb->internal; 1246 1260 ··· 1324 1338 cl->writing_state = MEI_IDLE; 1325 1339 1326 1340 mei_hdr.host_addr = cl->host_client_id; 1327 - mei_hdr.me_addr = cl->me_client_id; 1341 + mei_hdr.me_addr = mei_cl_me_id(cl); 1328 1342 mei_hdr.reserved = 0; 1329 1343 mei_hdr.msg_complete = 0; 1330 1344 mei_hdr.internal = cb->internal;
+90 -6
drivers/misc/mei/client.h
··· 44 44 const uuid_le *uuid, u8 id); 45 45 void mei_me_cl_rm_all(struct mei_device *dev); 46 46 47 + /** 48 + * mei_me_cl_is_active - check whether me client is active in the fw 49 + * 50 + * @me_cl: me client 51 + * 52 + * Return: true if the me client is active in the firmware 53 + */ 54 + static inline bool mei_me_cl_is_active(const struct mei_me_client *me_cl) 55 + { 56 + return !list_empty_careful(&me_cl->list); 57 + } 58 + 59 + /** 60 + * mei_me_cl_uuid - return me client protocol name (uuid) 61 + * 62 + * @me_cl: me client 63 + * 64 + * Return: me client protocol name 65 + */ 66 + static inline const uuid_le *mei_me_cl_uuid(const struct mei_me_client *me_cl) 67 + { 68 + return &me_cl->props.protocol_name; 69 + } 70 + 47 71 /* 48 72 * MEI IO Functions 49 73 */ ··· 118 94 /** 119 95 * mei_cl_is_connected - host client is connected 120 96 * 121 - * @cl: host clinet 97 + * @cl: host client 122 98 * 123 - * Return: true if the host clinet is connected 99 + * Return: true if the host client is connected 124 100 */ 125 101 static inline bool mei_cl_is_connected(struct mei_cl *cl) 126 102 { 127 103 return cl->state == MEI_FILE_CONNECTED; 128 104 } 129 105 106 + /** 107 + * mei_cl_me_id - me client id 108 + * 109 + * @cl: host client 110 + * 111 + * Return: me client id or 0 if client is not connected 112 + */ 113 + static inline u8 mei_cl_me_id(const struct mei_cl *cl) 114 + { 115 + return cl->me_cl ? cl->me_cl->client_id : 0; 116 + } 117 + 118 + /** 119 + * mei_cl_mtu - maximal message that client can send and receive 120 + * 121 + * @cl: host client 122 + * 123 + * Return: mtu 124 + */ 125 + static inline size_t mei_cl_mtu(const struct mei_cl *cl) 126 + { 127 + return cl->me_cl->props.max_msg_length; 128 + } 129 + 130 + /** 131 + * mei_cl_is_fixed_address - check whether the me client uses fixed address 132 + * 133 + * @cl: host client 134 + * 135 + * Return: true if the client is connected and it has fixed me address 136 + */ 137 + static inline bool mei_cl_is_fixed_address(const struct mei_cl *cl) 138 + { 139 + return cl->me_cl && cl->me_cl->props.fixed_address; 140 + } 141 + 142 + /** 143 + * mei_cl_is_single_recv_buf- check whether the me client 144 + * uses single receiving buffer 145 + * 146 + * @cl: host client 147 + * 148 + * Return: true if single_recv_buf == 1; 0 otherwise 149 + */ 150 + static inline bool mei_cl_is_single_recv_buf(const struct mei_cl *cl) 151 + { 152 + return cl->me_cl->props.single_recv_buf; 153 + } 154 + 155 + /** 156 + * mei_cl_uuid - client's uuid 157 + * 158 + * @cl: host client 159 + * 160 + * Return: return uuid of connected me client 161 + */ 162 + static inline const uuid_le *mei_cl_uuid(const struct mei_cl *cl) 163 + { 164 + return mei_me_cl_uuid(cl->me_cl); 165 + } 166 + 130 167 int mei_cl_disconnect(struct mei_cl *cl); 131 168 void mei_cl_set_disconnected(struct mei_cl *cl); 132 169 int mei_cl_irq_disconnect(struct mei_cl *cl, struct mei_cl_cb *cb, 133 170 struct mei_cl_cb *cmpl_list); 134 - int mei_cl_connect(struct mei_cl *cl, struct file *file); 171 + int mei_cl_connect(struct mei_cl *cl, struct mei_me_client *me_cl, 172 + struct file *file); 135 173 int mei_cl_irq_connect(struct mei_cl *cl, struct mei_cl_cb *cb, 136 174 struct mei_cl_cb *cmpl_list); 137 175 int mei_cl_read_start(struct mei_cl *cl, size_t length, struct file *fp); ··· 207 121 208 122 void mei_host_client_init(struct work_struct *work); 209 123 210 - 211 - 212 124 void mei_cl_all_disconnect(struct mei_device *dev); 213 125 void mei_cl_all_wakeup(struct mei_device *dev); 214 126 void mei_cl_all_write_clear(struct mei_device *dev); 215 127 216 128 #define MEI_CL_FMT "cl:host=%02d me=%02d " 217 - #define MEI_CL_PRM(cl) (cl)->host_client_id, (cl)->me_client_id 129 + #define MEI_CL_PRM(cl) (cl)->host_client_id, mei_cl_me_id(cl) 218 130 219 131 #define cl_dbg(dev, cl, format, arg...) \ 220 132 dev_dbg((dev)->dev, MEI_CL_FMT format, MEI_CL_PRM(cl), ##arg)
+1 -1
drivers/misc/mei/debugfs.c
··· 116 116 117 117 pos += scnprintf(buf + pos, bufsz - pos, 118 118 "%2d|%2d|%4d|%5d|%2d|%2d|\n", 119 - i, cl->me_client_id, cl->host_client_id, cl->state, 119 + i, mei_cl_me_id(cl), cl->host_client_id, cl->state, 120 120 !list_empty(&cl->rd_completed), cl->writing_state); 121 121 i++; 122 122 }
+2 -2
drivers/misc/mei/hbm.c
··· 151 151 152 152 cmd->hbm_cmd = hbm_cmd; 153 153 cmd->host_addr = cl->host_client_id; 154 - cmd->me_addr = cl->me_client_id; 154 + cmd->me_addr = mei_cl_me_id(cl); 155 155 } 156 156 157 157 /** ··· 189 189 bool mei_hbm_cl_addr_equal(struct mei_cl *cl, struct mei_hbm_cl_cmd *cmd) 190 190 { 191 191 return cl->host_client_id == cmd->host_addr && 192 - cl->me_client_id == cmd->me_addr; 192 + mei_cl_me_id(cl) == cmd->me_addr; 193 193 } 194 194 195 195 /**
+3 -1
drivers/misc/mei/interrupt.c
··· 66 66 struct mei_msg_hdr *mei_hdr) 67 67 { 68 68 return cl->host_client_id == mei_hdr->host_addr && 69 - cl->me_client_id == mei_hdr->me_addr; 69 + mei_cl_me_id(cl) == mei_hdr->me_addr; 70 70 } 71 71 72 72 /** ··· 182 182 ret = mei_hbm_cl_disconnect_rsp(dev, cl); 183 183 mei_cl_set_disconnected(cl); 184 184 mei_io_cb_free(cb); 185 + mei_me_cl_put(cl->me_cl); 186 + cl->me_cl = NULL; 185 187 186 188 return ret; 187 189 }
+16 -21
drivers/misc/mei/main.c
··· 271 271 size_t length, loff_t *offset) 272 272 { 273 273 struct mei_cl *cl = file->private_data; 274 - struct mei_me_client *me_cl = NULL; 275 274 struct mei_cl_cb *write_cb = NULL; 276 275 struct mei_device *dev; 277 276 unsigned long timeout = 0; ··· 288 289 goto out; 289 290 } 290 291 291 - me_cl = mei_me_cl_by_uuid_id(dev, &cl->cl_uuid, cl->me_client_id); 292 - if (!me_cl) { 292 + if (!mei_cl_is_connected(cl)) { 293 + cl_err(dev, cl, "is not connected"); 294 + rets = -ENODEV; 295 + goto out; 296 + } 297 + 298 + if (!mei_me_cl_is_active(cl->me_cl)) { 293 299 rets = -ENOTTY; 300 + goto out; 301 + } 302 + 303 + if (length > mei_cl_mtu(cl)) { 304 + rets = -EFBIG; 294 305 goto out; 295 306 } 296 307 ··· 309 300 goto out; 310 301 } 311 302 312 - if (length > me_cl->props.max_msg_length) { 313 - rets = -EFBIG; 314 - goto out; 315 - } 316 - 317 - if (!mei_cl_is_connected(cl)) { 318 - cl_err(dev, cl, "is not connected"); 319 - rets = -ENODEV; 320 - goto out; 321 - } 322 303 if (cl == &dev->iamthif_cl) { 323 304 write_cb = mei_amthif_find_read_list_entry(dev, file); 324 305 ··· 346 347 "amthif write failed with status = %d\n", rets); 347 348 goto out; 348 349 } 349 - mei_me_cl_put(me_cl); 350 350 mutex_unlock(&dev->device_lock); 351 351 return length; 352 352 } 353 353 354 354 rets = mei_cl_write(cl, write_cb, false); 355 355 out: 356 - mei_me_cl_put(me_cl); 357 356 mutex_unlock(&dev->device_lock); 358 357 if (rets < 0) 359 358 mei_io_cb_free(write_cb); ··· 391 394 me_cl = mei_me_cl_by_uuid(dev, &data->in_client_uuid); 392 395 if (!me_cl || me_cl->props.fixed_address) { 393 396 dev_dbg(dev->dev, "Cannot connect to FW Client UUID = %pUl\n", 394 - &data->in_client_uuid); 397 + &data->in_client_uuid); 398 + mei_me_cl_put(me_cl); 395 399 return -ENOTTY; 396 400 } 397 401 398 - cl->me_client_id = me_cl->client_id; 399 - cl->cl_uuid = me_cl->props.protocol_name; 400 - 401 402 dev_dbg(dev->dev, "Connect to FW Client ID = %d\n", 402 - cl->me_client_id); 403 + me_cl->client_id); 403 404 dev_dbg(dev->dev, "FW Client - Protocol Version = %d\n", 404 405 me_cl->props.protocol_version); 405 406 dev_dbg(dev->dev, "FW Client - Max Msg Len = %d\n", ··· 433 438 client->protocol_version = me_cl->props.protocol_version; 434 439 dev_dbg(dev->dev, "Can connect?\n"); 435 440 436 - rets = mei_cl_connect(cl, file); 441 + rets = mei_cl_connect(cl, me_cl, file); 437 442 438 443 end: 439 444 mei_me_cl_put(me_cl);
+12 -8
drivers/misc/mei/mei_dev.h
··· 227 227 * @rx_wait: wait queue for rx completion 228 228 * @wait: wait queue for management operation 229 229 * @status: connection status 230 - * @cl_uuid: client uuid name 230 + * @me_cl: fw client connected 231 231 * @host_client_id: host id 232 - * @me_client_id: me/fw id 233 232 * @mei_flow_ctrl_creds: transmit flow credentials 234 233 * @timer_count: watchdog timer for operation completion 234 + * @reserved: reserved for alignment 235 235 * @writing_state: state of the tx 236 236 * @rd_pending: pending read credits 237 237 * @rd_completed: completed read ··· 247 247 wait_queue_head_t rx_wait; 248 248 wait_queue_head_t wait; 249 249 int status; 250 - uuid_le cl_uuid; 250 + struct mei_me_client *me_cl; 251 251 u8 host_client_id; 252 - u8 me_client_id; 253 252 u8 mei_flow_ctrl_creds; 254 253 u8 timer_count; 254 + u8 reserved; 255 255 enum mei_file_transaction_states writing_state; 256 256 struct list_head rd_pending; 257 257 struct list_head rd_completed; ··· 346 346 }; 347 347 348 348 struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, 349 - uuid_le uuid, char *name, 349 + struct mei_me_client *me_cl, 350 + struct mei_cl *cl, 351 + char *name, 350 352 struct mei_cl_ops *ops); 351 353 void mei_cl_remove_device(struct mei_cl_device *device); 352 354 ··· 370 368 * when being probed and shall use it for doing ME bus I/O. 371 369 * 372 370 * @dev: linux driver model device pointer 371 + * @me_cl: me client 373 372 * @cl: mei client 374 373 * @ops: ME transport ops 375 374 * @event_work: async work to execute event callback ··· 383 380 struct mei_cl_device { 384 381 struct device dev; 385 382 383 + struct mei_me_client *me_cl; 386 384 struct mei_cl *cl; 387 385 388 386 const struct mei_cl_ops *ops; ··· 657 653 */ 658 654 void mei_amthif_reset_params(struct mei_device *dev); 659 655 660 - int mei_amthif_host_init(struct mei_device *dev); 656 + int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl); 661 657 662 658 int mei_amthif_read(struct mei_device *dev, struct file *file, 663 659 char __user *ubuf, size_t length, loff_t *offset); ··· 684 680 /* 685 681 * NFC functions 686 682 */ 687 - int mei_nfc_host_init(struct mei_device *dev); 683 + int mei_nfc_host_init(struct mei_device *dev, struct mei_me_client *me_cl); 688 684 void mei_nfc_host_exit(struct mei_device *dev); 689 685 690 686 /* ··· 694 690 695 691 int mei_wd_send(struct mei_device *dev); 696 692 int mei_wd_stop(struct mei_device *dev); 697 - int mei_wd_host_init(struct mei_device *dev); 693 + int mei_wd_host_init(struct mei_device *dev, struct mei_me_client *me_cl); 698 694 /* 699 695 * mei_watchdog_register - Registering watchdog interface 700 696 * once we got connection to the WD Client
+21 -29
drivers/misc/mei/nfc.c
··· 91 91 /** 92 92 * struct mei_nfc_dev - NFC mei device 93 93 * 94 + * @me_cl: NFC me client 94 95 * @cl: NFC host client 95 96 * @cl_info: NFC info host client 96 97 * @init_work: perform connection to the info client ··· 105 104 * @recv_req_id: reception message counter 106 105 */ 107 106 struct mei_nfc_dev { 107 + struct mei_me_client *me_cl; 108 108 struct mei_cl *cl; 109 109 struct mei_cl *cl_info; 110 110 struct work_struct init_work; ··· 153 151 kfree(ndev->cl_info); 154 152 } 155 153 154 + mei_me_cl_put(ndev->me_cl); 156 155 kfree(ndev); 157 156 } 158 157 ··· 420 417 struct mei_cl_device *cldev; 421 418 struct mei_nfc_dev *ndev; 422 419 struct mei_cl *cl_info; 420 + struct mei_me_client *me_cl_info; 423 421 424 422 ndev = container_of(work, struct mei_nfc_dev, init_work); 425 423 ··· 429 425 430 426 mutex_lock(&dev->device_lock); 431 427 432 - if (mei_cl_connect(cl_info, NULL) < 0) { 428 + /* check for valid client id */ 429 + me_cl_info = mei_me_cl_by_uuid(dev, &mei_nfc_info_guid); 430 + if (!me_cl_info) { 431 + mutex_unlock(&dev->device_lock); 432 + dev_info(dev->dev, "nfc: failed to find the info client\n"); 433 + goto err; 434 + } 435 + 436 + if (mei_cl_connect(cl_info, me_cl_info, NULL) < 0) { 437 + mei_me_cl_put(me_cl_info); 433 438 mutex_unlock(&dev->device_lock); 434 439 dev_err(dev->dev, "Could not connect to the NFC INFO ME client"); 435 440 436 441 goto err; 437 442 } 438 - 443 + mei_me_cl_put(me_cl_info); 439 444 mutex_unlock(&dev->device_lock); 440 445 441 446 if (mei_nfc_if_version(ndev) < 0) { ··· 472 459 return; 473 460 } 474 461 475 - cldev = mei_cl_add_device(dev, mei_nfc_guid, ndev->bus_name, &nfc_ops); 462 + cldev = mei_cl_add_device(dev, ndev->me_cl, ndev->cl, 463 + ndev->bus_name, &nfc_ops); 476 464 if (!cldev) { 477 465 dev_err(dev->dev, "Could not add the NFC device to the MEI bus\n"); 478 466 ··· 493 479 } 494 480 495 481 496 - int mei_nfc_host_init(struct mei_device *dev) 482 + int mei_nfc_host_init(struct mei_device *dev, struct mei_me_client *me_cl) 497 483 { 498 484 struct mei_nfc_dev *ndev; 499 485 struct mei_cl *cl_info, *cl; 500 - struct mei_me_client *me_cl = NULL; 501 486 int ret; 502 487 503 488 ··· 513 500 goto err; 514 501 } 515 502 516 - /* check for valid client id */ 517 - me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_info_guid); 518 - if (!me_cl) { 519 - dev_info(dev->dev, "nfc: failed to find the client\n"); 520 - ret = -ENOTTY; 503 + ndev->me_cl = mei_me_cl_get(me_cl); 504 + if (!ndev->me_cl) { 505 + ret = -ENODEV; 521 506 goto err; 522 507 } 523 508 ··· 525 514 goto err; 526 515 } 527 516 528 - cl_info->me_client_id = me_cl->client_id; 529 - cl_info->cl_uuid = me_cl->props.protocol_name; 530 - mei_me_cl_put(me_cl); 531 - me_cl = NULL; 532 - 533 517 list_add_tail(&cl_info->device_link, &dev->device_list); 534 518 535 519 ndev->cl_info = cl_info; 536 - 537 - /* check for valid client id */ 538 - me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_guid); 539 - if (!me_cl) { 540 - dev_info(dev->dev, "nfc: failed to find the client\n"); 541 - ret = -ENOTTY; 542 - goto err; 543 - } 544 520 545 521 cl = mei_cl_alloc_linked(dev, MEI_HOST_CLIENT_ID_ANY); 546 522 if (IS_ERR(cl)) { 547 523 ret = PTR_ERR(cl); 548 524 goto err; 549 525 } 550 - 551 - cl->me_client_id = me_cl->client_id; 552 - cl->cl_uuid = me_cl->props.protocol_name; 553 - mei_me_cl_put(me_cl); 554 - me_cl = NULL; 555 526 556 527 list_add_tail(&cl->device_link, &dev->device_list); 557 528 ··· 548 555 return 0; 549 556 550 557 err: 551 - mei_me_cl_put(me_cl); 552 558 mei_nfc_free(ndev); 553 559 554 560 return ret;
+4 -18
drivers/misc/mei/wd.c
··· 50 50 * mei_wd_host_init - connect to the watchdog client 51 51 * 52 52 * @dev: the device structure 53 + * @me_cl: me client 53 54 * 54 55 * Return: -ENOTTY if wd client cannot be found 55 56 * -EIO if write has failed 56 57 * 0 on success 57 58 */ 58 - int mei_wd_host_init(struct mei_device *dev) 59 + int mei_wd_host_init(struct mei_device *dev, struct mei_me_client *me_cl) 59 60 { 60 61 struct mei_cl *cl = &dev->wd_cl; 61 - struct mei_me_client *me_cl; 62 62 int ret; 63 63 64 64 mei_cl_init(cl, dev); ··· 66 66 dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT; 67 67 dev->wd_state = MEI_WD_IDLE; 68 68 69 - 70 - /* check for valid client id */ 71 - me_cl = mei_me_cl_by_uuid(dev, &mei_wd_guid); 72 - if (!me_cl) { 73 - dev_info(dev->dev, "wd: failed to find the client\n"); 74 - return -ENOTTY; 75 - } 76 - 77 - cl->me_client_id = me_cl->client_id; 78 - cl->cl_uuid = me_cl->props.protocol_name; 79 - mei_me_cl_put(me_cl); 80 - 81 69 ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID); 82 - 83 70 if (ret < 0) { 84 71 dev_info(dev->dev, "wd: failed link client\n"); 85 72 return ret; 86 73 } 87 74 88 - ret = mei_cl_connect(cl, NULL); 89 - 75 + ret = mei_cl_connect(cl, me_cl, NULL); 90 76 if (ret) { 91 77 dev_err(dev->dev, "wd: failed to connect = %d\n", ret); 92 78 mei_cl_unlink(cl); ··· 104 118 int ret; 105 119 106 120 hdr.host_addr = cl->host_client_id; 107 - hdr.me_addr = cl->me_client_id; 121 + hdr.me_addr = mei_cl_me_id(cl); 108 122 hdr.msg_complete = 1; 109 123 hdr.reserved = 0; 110 124 hdr.internal = 0;