From 144670c2ae3f9b452e021a9032b25730d296ba53 Mon Sep 17 00:00:00 2001 From: Fabien Parent Date: Wed, 2 Sep 2015 15:50:35 +0200 Subject: [PATCH] greybus: add num_cports field to greybus hd This commit is doing the preparation work in order to get the number of cports supported from the UniPro IP instead of using a constant defined in a Kconfig file. Greybus host device is now holding the cport count, and all the code will now use this value instead of the constant CPORT_ID_MAX when referring to an AP's CPort ID. Signed-off-by: Fabien Parent [johan: es1 supports 256 cports, minor style changes ] Signed-off-by: Johan Hovold --- drivers/staging/greybus/connection.c | 2 +- drivers/staging/greybus/core.c | 9 ++++++++- drivers/staging/greybus/es1.c | 10 +++++++--- drivers/staging/greybus/es2.c | 13 +++++++------ drivers/staging/greybus/greybus.h | 10 +++++++--- drivers/staging/greybus/interface.c | 2 +- 6 files changed, 31 insertions(+), 15 deletions(-) diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c index 7eb2868..286e7da 100644 --- a/drivers/staging/greybus/connection.c +++ b/drivers/staging/greybus/connection.c @@ -311,7 +311,7 @@ struct gb_connection *gb_connection_create(struct gb_bundle *bundle, { return gb_connection_create_range(bundle->intf->hd, bundle, &bundle->dev, cport_id, protocol_id, - 0, CPORT_ID_MAX); + 0, bundle->intf->hd->num_cports - 1); } /* diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c index af71d02..3ba744b 100644 --- a/drivers/staging/greybus/core.c +++ b/drivers/staging/greybus/core.c @@ -168,7 +168,8 @@ static void free_hd(struct kref *kref) struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver, struct device *parent, - size_t buffer_size_max) + size_t buffer_size_max, + size_t num_cports) { struct greybus_host_device *hd; @@ -186,6 +187,11 @@ struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver return NULL; } + if (num_cports == 0 || num_cports > CPORT_ID_MAX) { + dev_err(parent, "Invalid number of CPorts: %zu\n", num_cports); + return ERR_PTR(-EINVAL); + } + /* * Make sure to never allocate messages larger than what the Greybus * protocol supports. @@ -207,6 +213,7 @@ struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver INIT_LIST_HEAD(&hd->connections); ida_init(&hd->cport_id_map); hd->buffer_size_max = buffer_size_max; + hd->num_cports = num_cports; /* * Initialize AP's SVC protocol connection: diff --git a/drivers/staging/greybus/es1.c b/drivers/staging/greybus/es1.c index ddc26de..fc4297a 100644 --- a/drivers/staging/greybus/es1.c +++ b/drivers/staging/greybus/es1.c @@ -33,6 +33,9 @@ static struct dentry *apb1_log_enable_dentry; static struct task_struct *apb1_log_task; static DEFINE_KFIFO(apb1_log_fifo, char, APB1_LOG_SIZE); +/* Number of CPorts supported by es1 */ +#define CPORT_COUNT 256 + /* * Number of CPort IN urbs in flight at any point in time. * Adjust if we are having stalls in the USB buffer due to not enough urbs in @@ -193,7 +196,7 @@ static int message_send(struct greybus_host_device *hd, u16 cport_id, * of where the data should be sent. Do one last check of * the target CPort id before filling it in. */ - if (!cport_id_valid(cport_id)) { + if (!cport_id_valid(hd, cport_id)) { pr_err("invalid destination cport 0x%02x\n", cport_id); return -EINVAL; } @@ -372,7 +375,7 @@ static void cport_in_callback(struct urb *urb) header = urb->transfer_buffer; cport_id = gb_message_cport_unpack(header); - if (cport_id_valid(cport_id)) + if (cport_id_valid(hd, cport_id)) greybus_data_rcvd(hd, cport_id, urb->transfer_buffer, urb->actual_length); else @@ -560,7 +563,8 @@ static int ap_probe(struct usb_interface *interface, udev = usb_get_dev(interface_to_usbdev(interface)); - hd = greybus_create_hd(&es1_driver, &udev->dev, ES1_GBUF_MSG_SIZE_MAX); + hd = greybus_create_hd(&es1_driver, &udev->dev, ES1_GBUF_MSG_SIZE_MAX, + CPORT_COUNT); if (IS_ERR(hd)) { usb_put_dev(udev); return PTR_ERR(hd); diff --git a/drivers/staging/greybus/es2.c b/drivers/staging/greybus/es2.c index 6808089..4b1f34fe 100644 --- a/drivers/staging/greybus/es2.c +++ b/drivers/staging/greybus/es2.c @@ -128,7 +128,7 @@ static void usb_log_disable(struct es1_ap_dev *es1); static int cport_to_ep(struct es1_ap_dev *es1, u16 cport_id) { - if (cport_id >= CPORT_COUNT) + if (cport_id >= es1->hd->num_cports) return 0; return es1->cport_to_ep[cport_id]; } @@ -139,7 +139,7 @@ static int ep_in_use(struct es1_ap_dev *es1, int bulk_ep_set) { int i; - for (i = 0; i < CPORT_COUNT; i++) { + for (i = 0; i < es1->hd->num_cports; i++) { if (es1->cport_to_ep[i] == bulk_ep_set) return 1; } @@ -154,7 +154,7 @@ int map_cport_to_ep(struct es1_ap_dev *es1, if (bulk_ep_set == 0 || bulk_ep_set >= NUM_BULKS) return -EINVAL; - if (cport_id >= CPORT_COUNT) + if (cport_id >= es1->hd->num_cports) return -EINVAL; if (bulk_ep_set && ep_in_use(es1, bulk_ep_set)) return -EINVAL; @@ -287,7 +287,7 @@ static int message_send(struct greybus_host_device *hd, u16 cport_id, * of where the data should be sent. Do one last check of * the target CPort id before filling it in. */ - if (!cport_id_valid(cport_id)) { + if (!cport_id_valid(hd, cport_id)) { pr_err("invalid destination cport 0x%02x\n", cport_id); return -EINVAL; } @@ -472,7 +472,7 @@ static void cport_in_callback(struct urb *urb) header = urb->transfer_buffer; cport_id = gb_message_cport_unpack(header); - if (cport_id_valid(cport_id)) + if (cport_id_valid(hd, cport_id)) greybus_data_rcvd(hd, cport_id, urb->transfer_buffer, urb->actual_length); else @@ -660,7 +660,8 @@ static int ap_probe(struct usb_interface *interface, udev = usb_get_dev(interface_to_usbdev(interface)); - hd = greybus_create_hd(&es1_driver, &udev->dev, ES1_GBUF_MSG_SIZE_MAX); + hd = greybus_create_hd(&es1_driver, &udev->dev, ES1_GBUF_MSG_SIZE_MAX, + CPORT_COUNT); if (IS_ERR(hd)) { usb_put_dev(udev); return PTR_ERR(hd); diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h index 5726555..27a7724 100644 --- a/drivers/staging/greybus/greybus.h +++ b/drivers/staging/greybus/greybus.h @@ -96,6 +96,9 @@ struct greybus_host_device { struct ida cport_id_map; u8 device_id; + /* Number of CPorts supported by the UniPro IP */ + size_t num_cports; + /* Host device buffer constraints */ size_t buffer_size_max; @@ -109,7 +112,8 @@ struct greybus_host_device { struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *hd, struct device *parent, - size_t buffer_size_max); + size_t buffer_size_max, + size_t num_cports); int greybus_endo_setup(struct greybus_host_device *hd, u16 endo_id, u8 ap_intf_id); void greybus_remove_hd(struct greybus_host_device *hd); @@ -191,9 +195,9 @@ static inline int is_gb_connection(const struct device *dev) return dev->type == &greybus_connection_type; } -static inline bool cport_id_valid(u16 cport_id) +static inline bool cport_id_valid(struct greybus_host_device *hd, u16 cport_id) { - return cport_id != CPORT_ID_BAD && cport_id <= CPORT_ID_MAX; + return cport_id != CPORT_ID_BAD && cport_id < hd->num_cports; } #endif /* __KERNEL__ */ diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c index 0c3613e..c38fb8b 100644 --- a/drivers/staging/greybus/interface.c +++ b/drivers/staging/greybus/interface.c @@ -84,7 +84,7 @@ int gb_create_bundle_connection(struct gb_interface *intf, u8 class) bundle_id = GB_CONTROL_BUNDLE_ID; cport_id = GB_CONTROL_CPORT_ID; ida_start = 0; - ida_end = CPORT_ID_MAX; + ida_end = intf->hd->num_cports - 1; } else if (class == GREYBUS_CLASS_SVC) { protocol_id = GREYBUS_PROTOCOL_SVC; bundle_id = GB_SVC_BUNDLE_ID; -- 2.7.4