aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/bus.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2013-04-08 14:56:37 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-08 19:55:57 -0400
commit4234a6deb5ab04e50cfd6d72761345727bd2de21 (patch)
tree6da543ec16e78959e5a05055d4b6cee393d2ad47 /drivers/misc/mei/bus.c
parent606f34ad124faeeb77830d7fdfc513084566d2ba (diff)
mei: add mei_cl_write function
consolidate write code to a specific me client in mei_cl_write function the function is called from mei device write handler and from mei_cl bus send function Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei/bus.c')
-rw-r--r--drivers/misc/mei/bus.c103
1 files changed, 19 insertions, 84 deletions
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
index 8dbcb1516dc6..6badfa1110e9 100644
--- a/drivers/misc/mei/bus.c
+++ b/drivers/misc/mei/bus.c
@@ -226,112 +226,47 @@ static int ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
226 bool blocking) 226 bool blocking)
227{ 227{
228 struct mei_device *dev; 228 struct mei_device *dev;
229 struct mei_msg_hdr mei_hdr;
230 struct mei_cl_cb *cb; 229 struct mei_cl_cb *cb;
231 int me_cl_id, err; 230 int id;
231 int rets;
232 232
233 if (WARN_ON(!cl || !cl->dev)) 233 if (WARN_ON(!cl || !cl->dev))
234 return -ENODEV; 234 return -ENODEV;
235 235
236 dev = cl->dev;
237
236 if (cl->state != MEI_FILE_CONNECTED) 238 if (cl->state != MEI_FILE_CONNECTED)
237 return -ENODEV; 239 return -ENODEV;
238 240
241 /* Check if we have an ME client device */
242 id = mei_me_cl_by_id(dev, cl->me_client_id);
243 if (id < 0)
244 return -ENODEV;
245
246 if (length > dev->me_clients[id].props.max_msg_length)
247 return -EINVAL;
248
239 cb = mei_io_cb_init(cl, NULL); 249 cb = mei_io_cb_init(cl, NULL);
240 if (!cb) 250 if (!cb)
241 return -ENOMEM; 251 return -ENOMEM;
242 252
243 err = mei_io_cb_alloc_req_buf(cb, length); 253 rets = mei_io_cb_alloc_req_buf(cb, length);
244 if (err < 0) { 254 if (rets < 0) {
245 mei_io_cb_free(cb); 255 mei_io_cb_free(cb);
246 return err; 256 return rets;
247 } 257 }
248 258
249 memcpy(cb->request_buffer.data, buf, length); 259 memcpy(cb->request_buffer.data, buf, length);
250 cb->fop_type = MEI_FOP_WRITE;
251
252 dev = cl->dev;
253 260
254 mutex_lock(&dev->device_lock); 261 mutex_lock(&dev->device_lock);
255 262
256 /* Check if we have an ME client device */ 263 rets = mei_cl_write(cl, cb, blocking);
257 me_cl_id = mei_me_cl_by_id(dev, cl->me_client_id);
258 if (me_cl_id == dev->me_clients_num) {
259 err = -ENODEV;
260 goto out_err;
261 }
262
263 if (length > dev->me_clients[me_cl_id].props.max_msg_length) {
264 err = -EINVAL;
265 goto out_err;
266 }
267
268 err = mei_cl_flow_ctrl_creds(cl);
269 if (err < 0)
270 goto out_err;
271
272 /* Host buffer is not ready, we queue the request */
273 if (err == 0 || !dev->hbuf_is_ready) {
274 cb->buf_idx = 0;
275 mei_hdr.msg_complete = 0;
276 cl->writing_state = MEI_WRITING;
277
278 goto out;
279 }
280
281 dev->hbuf_is_ready = false;
282
283 /* Check for a maximum length */
284 if (length > mei_hbuf_max_len(dev)) {
285 mei_hdr.length = mei_hbuf_max_len(dev);
286 mei_hdr.msg_complete = 0;
287 } else {
288 mei_hdr.length = length;
289 mei_hdr.msg_complete = 1;
290 }
291
292 mei_hdr.host_addr = cl->host_client_id;
293 mei_hdr.me_addr = cl->me_client_id;
294 mei_hdr.reserved = 0;
295
296 if (mei_write_message(dev, &mei_hdr, buf)) {
297 err = -EIO;
298 goto out_err;
299 }
300
301 cl->writing_state = MEI_WRITING;
302 cb->buf_idx = mei_hdr.length;
303
304out:
305 if (mei_hdr.msg_complete) {
306 if (mei_cl_flow_ctrl_reduce(cl)) {
307 err = -ENODEV;
308 goto out_err;
309 }
310 list_add_tail(&cb->list, &dev->write_waiting_list.list);
311 } else {
312 list_add_tail(&cb->list, &dev->write_list.list);
313 }
314 264
315 mutex_unlock(&dev->device_lock); 265 mutex_unlock(&dev->device_lock);
266 if (rets < 0)
267 mei_io_cb_free(cb);
316 268
317 if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) { 269 return rets;
318 if (wait_event_interruptible(cl->tx_wait,
319 cl->writing_state == MEI_WRITE_COMPLETE)) {
320 if (signal_pending(current))
321 err = -EINTR;
322 err = -ERESTARTSYS;
323 mutex_lock(&dev->device_lock);
324 goto out_err;
325 }
326 }
327
328 return mei_hdr.length;
329
330out_err:
331 mutex_unlock(&dev->device_lock);
332 mei_io_cb_free(cb);
333
334 return err;
335} 270}
336 271
337int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length) 272int __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)