}
struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver,
- struct device *parent)
+ struct device *parent,
+ size_t buffer_size_max)
{
struct greybus_host_device *hd;
return NULL;
}
+ /*
+ * Make sure to never allocate messages larger than what the Greybus
+ * protocol supports.
+ */
+ if (buffer_size_max > GB_OPERATION_MESSAGE_SIZE_MAX) {
+ dev_warn(parent, "limiting buffer size to %u\n",
+ GB_OPERATION_MESSAGE_SIZE_MAX);
+ buffer_size_max = GB_OPERATION_MESSAGE_SIZE_MAX;
+ }
+
hd = kzalloc(sizeof(*hd) + driver->hd_priv_size, GFP_KERNEL);
if (!hd)
return NULL;
INIT_LIST_HEAD(&hd->interfaces);
INIT_LIST_HEAD(&hd->connections);
ida_init(&hd->cport_id_map);
+ hd->buffer_size_max = buffer_size_max;
hd->endo = gb_endo_create(hd);
if (!hd->endo) {
static void usb_log_enable(struct es1_ap_dev *es1);
static void usb_log_disable(struct es1_ap_dev *es1);
-/*
- * Buffer constraints for the host driver.
- *
- * A "buffer" is used to hold data to be transferred for Greybus by
- * the host driver. A buffer is represented by a "buffer pointer",
- * which defines a region of memory used by the host driver for
- * transferring the data. When Greybus allocates a buffer, it must
- * do so subject to the constraints associated with the host driver.
- *
- * size_max: The maximum size of a buffer
- */
-static void hd_buffer_constraints(struct greybus_host_device *hd)
-{
- hd->buffer_size_max = ES1_GBUF_MSG_SIZE_MAX;
-}
-
#define ES1_TIMEOUT 500 /* 500 ms for the SVC to do something */
static int submit_svc(struct svc_msg *svc_msg, struct greybus_host_device *hd)
{
udev = usb_get_dev(interface_to_usbdev(interface));
- hd = greybus_create_hd(&es1_driver, &udev->dev);
+ hd = greybus_create_hd(&es1_driver, &udev->dev, ES1_GBUF_MSG_SIZE_MAX);
if (!hd) {
usb_put_dev(udev);
return -ENOMEM;
}
- /* Fill in the buffer allocation constraints */
- hd_buffer_constraints(hd);
-
es1 = hd_to_es1(hd);
es1->hd = hd;
es1->usb_intf = interface;
static void usb_log_enable(struct es1_ap_dev *es1);
static void usb_log_disable(struct es1_ap_dev *es1);
-/*
- * Buffer constraints for the host driver.
- *
- * A "buffer" is used to hold data to be transferred for Greybus by
- * the host driver. A buffer is represented by a "buffer pointer",
- * which defines a region of memory used by the host driver for
- * transferring the data. When Greybus allocates a buffer, it must
- * do so subject to the constraints associated with the host driver.
- *
- * size_max: The maximum size of a buffer
- */
-static void hd_buffer_constraints(struct greybus_host_device *hd)
-{
- hd->buffer_size_max = ES1_GBUF_MSG_SIZE_MAX;
-}
-
#define ES1_TIMEOUT 500 /* 500 ms for the SVC to do something */
static int submit_svc(struct svc_msg *svc_msg, struct greybus_host_device *hd)
{
udev = usb_get_dev(interface_to_usbdev(interface));
- hd = greybus_create_hd(&es1_driver, &udev->dev);
+ hd = greybus_create_hd(&es1_driver, &udev->dev, ES1_GBUF_MSG_SIZE_MAX);
if (!hd) {
usb_put_dev(udev);
return -ENOMEM;
}
- /* Fill in the buffer allocation constraints */
- hd_buffer_constraints(hd);
-
es1 = hd_to_es1(hd);
es1->hd = hd;
es1->usb_intf = interface;
};
struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *hd,
- struct device *parent);
+ struct device *parent,
+ size_t buffer_size_max);
void greybus_remove_hd(struct greybus_host_device *hd);
struct greybus_driver {
/* The default amount of time a request is given to complete */
#define OPERATION_TIMEOUT_DEFAULT 1000 /* milliseconds */
-/*
- * XXX This needs to be coordinated with host driver parameters
- * XXX May need to reduce to allow for message header within a page
- */
-#define GB_OPERATION_MESSAGE_SIZE_MAX 4096
-
static struct kmem_cache *gb_operation_cache;
static struct kmem_cache *gb_message_cache;
struct gb_operation_msg_hdr *header;
size_t message_size = payload_size + sizeof(*header);
- if (hd->buffer_size_max > GB_OPERATION_MESSAGE_SIZE_MAX) {
- pr_warn("limiting buffer size to %u\n",
- GB_OPERATION_MESSAGE_SIZE_MAX);
- hd->buffer_size_max = GB_OPERATION_MESSAGE_SIZE_MAX;
- }
-
if (message_size > hd->buffer_size_max) {
pr_warn("requested message size too big (%zu > %zu)\n",
message_size, hd->buffer_size_max);
int gb_operation_init(void)
{
- BUILD_BUG_ON(GB_OPERATION_MESSAGE_SIZE_MAX >
- U16_MAX - sizeof(struct gb_operation_msg_hdr));
-
gb_message_cache = kmem_cache_create("gb_message_cache",
sizeof(struct gb_message), 0, 0, NULL);
if (!gb_message_cache)
__u8 pad[2]; /* must be zero (ignore when read) */
} __aligned(sizeof(u64));
+#define GB_OPERATION_MESSAGE_SIZE_MAX 4096
+
/*
* Protocol code should only examine the payload and payload_size
* fields. All other fields are intended to be private to the