Commit e420721b authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

greybus: operation: allow atomic operation allocations

Add gfp mask argument to gb_operation_create to allow operations to be
allocated in atomic context.
Signed-off-by: default avatarJohan Hovold <johan@hovoldconsulting.com>
Reviewed-by: default avatarBryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 3e136cc9
...@@ -128,7 +128,8 @@ static int gb_hid_set_report(struct gb_hid *ghid, u8 report_type, u8 report_id, ...@@ -128,7 +128,8 @@ static int gb_hid_set_report(struct gb_hid *ghid, u8 report_type, u8 report_id,
int ret, size = sizeof(*request) + len - 1; int ret, size = sizeof(*request) + len - 1;
operation = gb_operation_create(ghid->connection, operation = gb_operation_create(ghid->connection,
GB_HID_TYPE_SET_REPORT, size, 0); GB_HID_TYPE_SET_REPORT, size, 0,
GFP_KERNEL);
if (!operation) if (!operation)
return -ENOMEM; return -ENOMEM;
......
...@@ -146,7 +146,7 @@ gb_i2c_operation_create(struct gb_connection *connection, ...@@ -146,7 +146,7 @@ gb_i2c_operation_create(struct gb_connection *connection,
/* Response consists only of incoming data */ /* Response consists only of incoming data */
operation = gb_operation_create(connection, GB_I2C_TYPE_TRANSFER, operation = gb_operation_create(connection, GB_I2C_TYPE_TRANSFER,
request_size, data_in_size); request_size, data_in_size, GFP_KERNEL);
if (!operation) if (!operation)
return NULL; return NULL;
......
...@@ -409,22 +409,13 @@ EXPORT_SYMBOL_GPL(gb_operation_response_alloc); ...@@ -409,22 +409,13 @@ EXPORT_SYMBOL_GPL(gb_operation_response_alloc);
*/ */
static struct gb_operation * static struct gb_operation *
gb_operation_create_common(struct gb_connection *connection, u8 type, gb_operation_create_common(struct gb_connection *connection, u8 type,
size_t request_size, size_t response_size) size_t request_size, size_t response_size,
gfp_t gfp_flags)
{ {
struct greybus_host_device *hd = connection->hd; struct greybus_host_device *hd = connection->hd;
struct gb_operation *operation; struct gb_operation *operation;
unsigned long flags; unsigned long flags;
gfp_t gfp_flags;
/*
* An incoming request will pass an invalid operation type,
* because the header will get overwritten anyway. These
* occur in interrupt context, so we must use GFP_ATOMIC.
*/
if (type == GB_OPERATION_TYPE_INVALID)
gfp_flags = GFP_ATOMIC;
else
gfp_flags = GFP_KERNEL;
operation = kmem_cache_zalloc(gb_operation_cache, gfp_flags); operation = kmem_cache_zalloc(gb_operation_cache, gfp_flags);
if (!operation) if (!operation)
return NULL; return NULL;
...@@ -472,7 +463,8 @@ gb_operation_create_common(struct gb_connection *connection, u8 type, ...@@ -472,7 +463,8 @@ gb_operation_create_common(struct gb_connection *connection, u8 type,
*/ */
struct gb_operation *gb_operation_create(struct gb_connection *connection, struct gb_operation *gb_operation_create(struct gb_connection *connection,
u8 type, size_t request_size, u8 type, size_t request_size,
size_t response_size) size_t response_size,
gfp_t gfp)
{ {
if (WARN_ON_ONCE(type == GB_OPERATION_TYPE_INVALID)) if (WARN_ON_ONCE(type == GB_OPERATION_TYPE_INVALID))
return NULL; return NULL;
...@@ -480,7 +472,7 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection, ...@@ -480,7 +472,7 @@ struct gb_operation *gb_operation_create(struct gb_connection *connection,
type &= ~GB_MESSAGE_TYPE_RESPONSE; type &= ~GB_MESSAGE_TYPE_RESPONSE;
return gb_operation_create_common(connection, type, return gb_operation_create_common(connection, type,
request_size, response_size); request_size, response_size, gfp);
} }
EXPORT_SYMBOL_GPL(gb_operation_create); EXPORT_SYMBOL_GPL(gb_operation_create);
...@@ -504,7 +496,7 @@ gb_operation_create_incoming(struct gb_connection *connection, u16 id, ...@@ -504,7 +496,7 @@ gb_operation_create_incoming(struct gb_connection *connection, u16 id,
operation = gb_operation_create_common(connection, operation = gb_operation_create_common(connection,
GB_OPERATION_TYPE_INVALID, GB_OPERATION_TYPE_INVALID,
request_size, 0); request_size, 0, GFP_ATOMIC);
if (operation) { if (operation) {
operation->id = id; operation->id = id;
operation->type = type; operation->type = type;
...@@ -888,7 +880,8 @@ int gb_operation_sync(struct gb_connection *connection, int type, ...@@ -888,7 +880,8 @@ int gb_operation_sync(struct gb_connection *connection, int type,
return -EINVAL; return -EINVAL;
operation = gb_operation_create(connection, type, operation = gb_operation_create(connection, type,
request_size, response_size); request_size, response_size,
GFP_KERNEL);
if (!operation) if (!operation)
return -ENOMEM; return -ENOMEM;
......
...@@ -134,7 +134,8 @@ int gb_operation_result(struct gb_operation *operation); ...@@ -134,7 +134,8 @@ int gb_operation_result(struct gb_operation *operation);
size_t gb_operation_get_payload_size_max(struct gb_connection *connection); size_t gb_operation_get_payload_size_max(struct gb_connection *connection);
struct gb_operation *gb_operation_create(struct gb_connection *connection, struct gb_operation *gb_operation_create(struct gb_connection *connection,
u8 type, size_t request_size, u8 type, size_t request_size,
size_t response_size); size_t response_size,
gfp_t gfp);
void gb_operation_get(struct gb_operation *operation); void gb_operation_get(struct gb_operation *operation);
void gb_operation_put(struct gb_operation *operation); void gb_operation_put(struct gb_operation *operation);
static inline void gb_operation_destroy(struct gb_operation *operation) static inline void gb_operation_destroy(struct gb_operation *operation)
......
...@@ -90,7 +90,7 @@ gb_spi_operation_create(struct gb_connection *connection, ...@@ -90,7 +90,7 @@ gb_spi_operation_create(struct gb_connection *connection,
/* Response consists only of incoming data */ /* Response consists only of incoming data */
operation = gb_operation_create(connection, GB_SPI_TYPE_TRANSFER, operation = gb_operation_create(connection, GB_SPI_TYPE_TRANSFER,
request_size, rx_size); request_size, rx_size, GFP_KERNEL);
if (!operation) if (!operation)
return NULL; return NULL;
......
...@@ -131,7 +131,8 @@ static int urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) ...@@ -131,7 +131,8 @@ static int urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
operation = gb_operation_create(dev->connection, operation = gb_operation_create(dev->connection,
GB_USB_TYPE_URB_ENQUEUE, GB_USB_TYPE_URB_ENQUEUE,
sizeof(*request) + sizeof(*request) +
urb->transfer_buffer_length, 0); urb->transfer_buffer_length, 0,
GFP_KERNEL);
if (!operation) if (!operation)
return -ENODEV; return -ENODEV;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment