mei: always initialize the callback with the intended operation type
We set the operation type at initialization time as each cb is used only for a single type of operation As a byproduct we add a convenient wrapper for allocating cb with the data buffer. Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
5db7514d93
commit
bca67d681c
@ -254,7 +254,7 @@ static int mei_amthif_read_start(struct mei_cl *cl, struct file *file)
|
||||
size_t length = dev->iamthif_mtu;
|
||||
int rets;
|
||||
|
||||
cb = mei_io_cb_init(cl, file);
|
||||
cb = mei_io_cb_init(cl, MEI_FOP_READ, file);
|
||||
if (!cb) {
|
||||
rets = -ENOMEM;
|
||||
goto err;
|
||||
@ -264,7 +264,6 @@ static int mei_amthif_read_start(struct mei_cl *cl, struct file *file)
|
||||
if (rets)
|
||||
goto err;
|
||||
|
||||
cb->fop_type = MEI_FOP_READ;
|
||||
list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
|
||||
|
||||
dev->iamthif_state = MEI_IAMTHIF_READING;
|
||||
@ -359,7 +358,6 @@ int mei_amthif_write(struct mei_cl *cl, struct mei_cl_cb *cb)
|
||||
|
||||
dev = cl->dev;
|
||||
|
||||
cb->fop_type = MEI_FOP_WRITE;
|
||||
list_add_tail(&cb->list, &dev->amthif_cmd_list.list);
|
||||
return mei_amthif_run_next_cmd(dev);
|
||||
}
|
||||
|
@ -255,16 +255,12 @@ static ssize_t ___mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length,
|
||||
goto out;
|
||||
}
|
||||
|
||||
cb = mei_io_cb_init(cl, NULL);
|
||||
cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, NULL);
|
||||
if (!cb) {
|
||||
rets = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rets = mei_io_cb_alloc_buf(cb, length);
|
||||
if (rets < 0)
|
||||
goto out;
|
||||
|
||||
memcpy(cb->buf.data, buf, length);
|
||||
|
||||
rets = mei_cl_write(cl, cb, blocking);
|
||||
@ -293,7 +289,7 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
|
||||
mutex_lock(&dev->device_lock);
|
||||
|
||||
if (!cl->read_cb) {
|
||||
rets = mei_cl_read_start(cl, length);
|
||||
rets = mei_cl_read_start(cl, length, NULL);
|
||||
if (rets < 0)
|
||||
goto out;
|
||||
}
|
||||
@ -392,7 +388,7 @@ static void mei_bus_event_work(struct work_struct *work)
|
||||
device->events = 0;
|
||||
|
||||
/* Prepare for the next read */
|
||||
mei_cl_read_start(device->cl, 0);
|
||||
mei_cl_read_start(device->cl, 0, NULL);
|
||||
}
|
||||
|
||||
int mei_cl_register_event_cb(struct mei_cl_device *device,
|
||||
@ -406,7 +402,7 @@ int mei_cl_register_event_cb(struct mei_cl_device *device,
|
||||
device->event_context = context;
|
||||
INIT_WORK(&device->event_work, mei_bus_event_work);
|
||||
|
||||
mei_cl_read_start(device->cl, 0);
|
||||
mei_cl_read_start(device->cl, 0, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -448,7 +444,7 @@ int mei_cl_enable_device(struct mei_cl_device *device)
|
||||
mutex_unlock(&dev->device_lock);
|
||||
|
||||
if (device->event_cb && !cl->read_cb)
|
||||
mei_cl_read_start(device->cl, 0);
|
||||
mei_cl_read_start(device->cl, 0, NULL);
|
||||
|
||||
if (!device->ops || !device->ops->enable)
|
||||
return 0;
|
||||
|
@ -384,11 +384,13 @@ void mei_io_cb_free(struct mei_cl_cb *cb)
|
||||
* mei_io_cb_init - allocate and initialize io callback
|
||||
*
|
||||
* @cl: mei client
|
||||
* @type: operation type
|
||||
* @fp: pointer to file structure
|
||||
*
|
||||
* Return: mei_cl_cb pointer or NULL;
|
||||
*/
|
||||
struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp)
|
||||
struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type,
|
||||
struct file *fp)
|
||||
{
|
||||
struct mei_cl_cb *cb;
|
||||
|
||||
@ -401,6 +403,7 @@ struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp)
|
||||
cb->file_object = fp;
|
||||
cb->cl = cl;
|
||||
cb->buf_idx = 0;
|
||||
cb->fop_type = type;
|
||||
return cb;
|
||||
}
|
||||
|
||||
@ -429,6 +432,33 @@ int mei_io_cb_alloc_buf(struct mei_cl_cb *cb, size_t length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_cl_alloc_cb - a convenient wrapper for allocating read cb
|
||||
*
|
||||
* @cl: host client
|
||||
* @length: size of the buffer
|
||||
* @type: operation type
|
||||
* @fp: associated file pointer (might be NULL)
|
||||
*
|
||||
* Return: cb on success and NULL on failure
|
||||
*/
|
||||
struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length,
|
||||
enum mei_cb_file_ops type, struct file *fp)
|
||||
{
|
||||
struct mei_cl_cb *cb;
|
||||
|
||||
cb = mei_io_cb_init(cl, type, fp);
|
||||
if (!cb)
|
||||
return NULL;
|
||||
|
||||
if (mei_io_cb_alloc_buf(cb, length)) {
|
||||
mei_io_cb_free(cb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* mei_cl_flush_queues - flushes queue lists belonging to cl.
|
||||
*
|
||||
@ -688,13 +718,10 @@ int mei_cl_disconnect(struct mei_cl *cl)
|
||||
return rets;
|
||||
}
|
||||
|
||||
cb = mei_io_cb_init(cl, NULL);
|
||||
if (!cb) {
|
||||
rets = -ENOMEM;
|
||||
cb = mei_io_cb_init(cl, MEI_FOP_DISCONNECT, NULL);
|
||||
rets = cb ? 0 : -ENOMEM;
|
||||
if (rets)
|
||||
goto free;
|
||||
}
|
||||
|
||||
cb->fop_type = MEI_FOP_DISCONNECT;
|
||||
|
||||
if (mei_hbuf_acquire(dev)) {
|
||||
if (mei_hbm_cl_disconnect_req(dev, cl)) {
|
||||
@ -795,13 +822,10 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
|
||||
return rets;
|
||||
}
|
||||
|
||||
cb = mei_io_cb_init(cl, file);
|
||||
if (!cb) {
|
||||
rets = -ENOMEM;
|
||||
cb = mei_io_cb_init(cl, MEI_FOP_CONNECT, file);
|
||||
rets = cb ? 0 : -ENOMEM;
|
||||
if (rets)
|
||||
goto out;
|
||||
}
|
||||
|
||||
cb->fop_type = MEI_FOP_CONNECT;
|
||||
|
||||
/* run hbuf acquire last so we don't have to undo */
|
||||
if (!mei_cl_is_other_connecting(cl) && mei_hbuf_acquire(dev)) {
|
||||
@ -934,10 +958,11 @@ int mei_cl_flow_ctrl_reduce(struct mei_cl *cl)
|
||||
*
|
||||
* @cl: host client
|
||||
* @length: number of bytes to read
|
||||
* @fp: pointer to file structure
|
||||
*
|
||||
* Return: 0 on success, <0 on failure.
|
||||
*/
|
||||
int mei_cl_read_start(struct mei_cl *cl, size_t length)
|
||||
int mei_cl_read_start(struct mei_cl *cl, size_t length, struct file *fp)
|
||||
{
|
||||
struct mei_device *dev;
|
||||
struct mei_cl_cb *cb;
|
||||
@ -972,17 +997,11 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length)
|
||||
return rets;
|
||||
}
|
||||
|
||||
cb = mei_io_cb_init(cl, NULL);
|
||||
if (!cb) {
|
||||
rets = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rets = mei_io_cb_alloc_buf(cb, length);
|
||||
cb = mei_cl_alloc_cb(cl, length, MEI_FOP_READ, fp);
|
||||
rets = cb ? 0 : -ENOMEM;
|
||||
if (rets)
|
||||
goto out;
|
||||
|
||||
cb->fop_type = MEI_FOP_READ;
|
||||
if (mei_hbuf_acquire(dev)) {
|
||||
rets = mei_hbm_cl_flow_control_req(dev, cl);
|
||||
if (rets < 0)
|
||||
@ -1128,7 +1147,6 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking)
|
||||
return rets;
|
||||
}
|
||||
|
||||
cb->fop_type = MEI_FOP_WRITE;
|
||||
cb->buf_idx = 0;
|
||||
cl->writing_state = MEI_IDLE;
|
||||
|
||||
|
@ -47,7 +47,8 @@ void mei_me_cl_rm_all(struct mei_device *dev);
|
||||
/*
|
||||
* MEI IO Functions
|
||||
*/
|
||||
struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, struct file *fp);
|
||||
struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, enum mei_cb_file_ops type,
|
||||
struct file *fp);
|
||||
void mei_io_cb_free(struct mei_cl_cb *priv_cb);
|
||||
int mei_io_cb_alloc_buf(struct mei_cl_cb *cb, size_t length);
|
||||
|
||||
@ -77,6 +78,8 @@ int mei_cl_unlink(struct mei_cl *cl);
|
||||
int mei_cl_flush_queues(struct mei_cl *cl);
|
||||
struct mei_cl_cb *mei_cl_find_read_cb(struct mei_cl *cl);
|
||||
|
||||
struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length,
|
||||
enum mei_cb_file_ops type, struct file *fp);
|
||||
|
||||
int mei_cl_flow_ctrl_creds(struct mei_cl *cl);
|
||||
|
||||
@ -100,7 +103,7 @@ static inline bool mei_cl_is_transitioning(struct mei_cl *cl)
|
||||
bool mei_cl_is_other_connecting(struct mei_cl *cl);
|
||||
int mei_cl_disconnect(struct mei_cl *cl);
|
||||
int mei_cl_connect(struct mei_cl *cl, struct file *file);
|
||||
int mei_cl_read_start(struct mei_cl *cl, size_t length);
|
||||
int mei_cl_read_start(struct mei_cl *cl, size_t length, struct file *fp);
|
||||
int mei_cl_irq_read_msg(struct mei_cl *cl, struct mei_msg_hdr *hdr,
|
||||
struct mei_cl_cb *cmpl_list);
|
||||
int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking);
|
||||
|
@ -684,10 +684,9 @@ static int mei_hbm_fw_disconnect_req(struct mei_device *dev,
|
||||
cl->state = MEI_FILE_DISCONNECTED;
|
||||
cl->timer_count = 0;
|
||||
|
||||
cb = mei_io_cb_init(cl, NULL);
|
||||
cb = mei_io_cb_init(cl, MEI_FOP_DISCONNECT_RSP, NULL);
|
||||
if (!cb)
|
||||
return -ENOMEM;
|
||||
cb->fop_type = MEI_FOP_DISCONNECT_RSP;
|
||||
cl_dbg(dev, cl, "add disconnect response as first\n");
|
||||
list_add(&cb->list, &dev->ctrl_wr_list.list);
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
|
||||
*offset = 0;
|
||||
}
|
||||
|
||||
err = mei_cl_read_start(cl, length);
|
||||
err = mei_cl_read_start(cl, length, file);
|
||||
if (err && err != -EBUSY) {
|
||||
dev_dbg(dev->dev,
|
||||
"mei start read failure with status = %d\n", err);
|
||||
@ -383,15 +383,11 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf,
|
||||
} else if (cl->reading_state == MEI_IDLE)
|
||||
*offset = 0;
|
||||
|
||||
|
||||
write_cb = mei_io_cb_init(cl, file);
|
||||
write_cb = mei_cl_alloc_cb(cl, length, MEI_FOP_WRITE, file);
|
||||
if (!write_cb) {
|
||||
rets = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
rets = mei_io_cb_alloc_buf(write_cb, length);
|
||||
if (rets)
|
||||
goto out;
|
||||
|
||||
rets = copy_from_user(write_cb->buf.data, ubuf, length);
|
||||
if (rets) {
|
||||
|
Loading…
Reference in New Issue
Block a user