4 * Copyright 2014 Google Inc.
5 * Copyright 2014 Linaro Ltd.
7 * Released under the GPLv2 only.
10 #include <linux/workqueue.h>
14 #define GB_CONNECTION_TS_KFIFO_ELEMENTS 2
15 #define GB_CONNECTION_TS_KFIFO_LEN \
16 (GB_CONNECTION_TS_KFIFO_ELEMENTS * sizeof(struct timeval))
18 static DEFINE_SPINLOCK(gb_connections_lock);
20 /* This is only used at initialization time; no locking is required. */
21 static struct gb_connection *
22 gb_connection_intf_find(struct gb_interface *intf, u16 cport_id)
24 struct greybus_host_device *hd = intf->hd;
25 struct gb_connection *connection;
27 list_for_each_entry(connection, &hd->connections, hd_links)
28 if (connection->bundle->intf == intf &&
29 connection->intf_cport_id == cport_id)
34 static struct gb_connection *
35 gb_connection_hd_find(struct greybus_host_device *hd, u16 cport_id)
37 struct gb_connection *connection;
40 spin_lock_irqsave(&gb_connections_lock, flags);
41 list_for_each_entry(connection, &hd->connections, hd_links)
42 if (connection->hd_cport_id == cport_id)
46 spin_unlock_irqrestore(&gb_connections_lock, flags);
52 * Callback from the host driver to let us know that data has been
53 * received on the bundle.
55 void greybus_data_rcvd(struct greybus_host_device *hd, u16 cport_id,
56 u8 *data, size_t length)
58 struct gb_connection *connection;
60 connection = gb_connection_hd_find(hd, cport_id);
63 "nonexistent connection (%zu bytes dropped)\n", length);
66 gb_connection_recv(connection, data, length);
68 EXPORT_SYMBOL_GPL(greybus_data_rcvd);
70 static ssize_t state_show(struct device *dev, struct device_attribute *attr,
73 struct gb_connection *connection = to_gb_connection(dev);
74 enum gb_connection_state state;
76 spin_lock_irq(&connection->lock);
77 state = connection->state;
78 spin_unlock_irq(&connection->lock);
80 return sprintf(buf, "%d\n", state);
82 static DEVICE_ATTR_RO(state);
85 protocol_id_show(struct device *dev, struct device_attribute *attr, char *buf)
87 struct gb_connection *connection = to_gb_connection(dev);
89 if (connection->protocol)
90 return sprintf(buf, "%d\n", connection->protocol->id);
94 static DEVICE_ATTR_RO(protocol_id);
97 ap_cport_id_show(struct device *dev, struct device_attribute *attr, char *buf)
99 struct gb_connection *connection = to_gb_connection(dev);
100 return sprintf(buf, "%hu\n", connection->hd_cport_id);
102 static DEVICE_ATTR_RO(ap_cport_id);
104 static struct attribute *connection_attrs[] = {
105 &dev_attr_state.attr,
106 &dev_attr_protocol_id.attr,
107 &dev_attr_ap_cport_id.attr,
111 ATTRIBUTE_GROUPS(connection);
113 static void gb_connection_release(struct device *dev)
115 struct gb_connection *connection = to_gb_connection(dev);
117 destroy_workqueue(connection->wq);
121 struct device_type greybus_connection_type = {
122 .name = "greybus_connection",
123 .release = gb_connection_release,
127 int svc_update_connection(struct gb_interface *intf,
128 struct gb_connection *connection)
130 struct gb_bundle *bundle;
132 bundle = gb_bundle_create(intf, GB_SVC_BUNDLE_ID, GREYBUS_CLASS_SVC);
136 device_del(&connection->dev);
137 connection->bundle = bundle;
138 connection->dev.parent = &bundle->dev;
139 dev_set_name(&connection->dev, "%s:%d", dev_name(&bundle->dev),
142 WARN_ON(device_add(&connection->dev));
144 spin_lock_irq(&gb_connections_lock);
145 list_add(&connection->bundle_links, &bundle->connections);
146 spin_unlock_irq(&gb_connections_lock);
152 * Set up a Greybus connection, representing the bidirectional link
153 * between a CPort on a (local) Greybus host device and a CPort on
154 * another Greybus module.
156 * A connection also maintains the state of operations sent over the
159 * Returns a pointer to the new connection if successful, or a null
162 struct gb_connection *
163 gb_connection_create_range(struct greybus_host_device *hd,
164 struct gb_bundle *bundle, struct device *parent,
165 u16 cport_id, u8 protocol_id, u32 ida_start,
168 struct gb_connection *connection;
169 struct ida *id_map = &hd->cport_id_map;
176 * If a manifest tries to reuse a cport, reject it. We
177 * initialize connections serially so we don't need to worry
178 * about holding the connection lock.
180 if (bundle && gb_connection_intf_find(bundle->intf, cport_id)) {
181 pr_err("duplicate interface cport id 0x%04hx\n", cport_id);
185 hd_cport_id = ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL);
189 connection = kzalloc(sizeof(*connection), GFP_KERNEL);
193 connection->hd_cport_id = hd_cport_id;
194 connection->intf_cport_id = cport_id;
197 connection->protocol_id = protocol_id;
198 connection->major = major;
199 connection->minor = minor;
201 connection->bundle = bundle;
202 connection->state = GB_CONNECTION_STATE_DISABLED;
204 atomic_set(&connection->op_cycle, 0);
205 spin_lock_init(&connection->lock);
206 INIT_LIST_HEAD(&connection->operations);
208 connection->wq = alloc_workqueue("%s:%d", WQ_UNBOUND, 1,
209 dev_name(parent), cport_id);
211 goto err_free_connection;
213 connection->dev.parent = parent;
214 connection->dev.bus = &greybus_bus_type;
215 connection->dev.type = &greybus_connection_type;
216 connection->dev.groups = connection_groups;
217 device_initialize(&connection->dev);
218 dev_set_name(&connection->dev, "%s:%d",
219 dev_name(parent), cport_id);
221 retval = device_add(&connection->dev);
223 connection->hd_cport_id = CPORT_ID_BAD;
224 put_device(&connection->dev);
226 pr_err("failed to add connection device for cport 0x%04hx\n",
232 spin_lock_irq(&gb_connections_lock);
233 list_add(&connection->hd_links, &hd->connections);
236 list_add(&connection->bundle_links, &bundle->connections);
238 INIT_LIST_HEAD(&connection->bundle_links);
240 spin_unlock_irq(&gb_connections_lock);
242 gb_connection_bind_protocol(connection);
243 if (!connection->protocol)
244 dev_warn(&connection->dev,
245 "protocol 0x%02hhx handler not found\n", protocol_id);
252 ida_simple_remove(id_map, hd_cport_id);
257 static int gb_connection_hd_cport_enable(struct gb_connection *connection)
259 struct greybus_host_device *hd = connection->hd;
262 if (!hd->driver->cport_enable)
265 ret = hd->driver->cport_enable(hd, connection->hd_cport_id);
267 dev_err(&connection->dev,
268 "failed to enable host cport: %d\n", ret);
275 static void gb_connection_hd_cport_disable(struct gb_connection *connection)
277 struct greybus_host_device *hd = connection->hd;
279 if (!hd->driver->cport_disable)
282 hd->driver->cport_disable(hd, connection->hd_cport_id);
285 struct gb_connection *gb_connection_create(struct gb_bundle *bundle,
286 u16 cport_id, u8 protocol_id)
288 return gb_connection_create_range(bundle->intf->hd, bundle,
289 &bundle->dev, cport_id, protocol_id,
290 0, bundle->intf->hd->num_cports - 1);
294 * Cancel all active operations on a connection.
296 * Should only be called during connection tear down.
298 static void gb_connection_cancel_operations(struct gb_connection *connection,
301 struct gb_operation *operation;
303 spin_lock_irq(&connection->lock);
304 while (!list_empty(&connection->operations)) {
305 operation = list_last_entry(&connection->operations,
306 struct gb_operation, links);
307 gb_operation_get(operation);
308 spin_unlock_irq(&connection->lock);
310 if (gb_operation_is_incoming(operation))
311 gb_operation_cancel_incoming(operation, errno);
313 gb_operation_cancel(operation, errno);
315 gb_operation_put(operation);
317 spin_lock_irq(&connection->lock);
319 spin_unlock_irq(&connection->lock);
323 * Request the SVC to create a connection from AP's cport to interface's
327 gb_connection_svc_connection_create(struct gb_connection *connection)
329 struct greybus_host_device *hd = connection->hd;
330 struct gb_protocol *protocol = connection->protocol;
333 if (protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
336 ret = gb_svc_connection_create(hd->svc,
337 hd->endo->ap_intf_id,
338 connection->hd_cport_id,
339 connection->bundle->intf->interface_id,
340 connection->intf_cport_id);
342 dev_err(&connection->dev,
343 "failed to create svc connection: %d\n", ret);
351 gb_connection_svc_connection_destroy(struct gb_connection *connection)
353 if (connection->protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
356 gb_svc_connection_destroy(connection->hd->svc,
357 connection->hd->endo->ap_intf_id,
358 connection->hd_cport_id,
359 connection->bundle->intf->interface_id,
360 connection->intf_cport_id);
363 /* Inform Interface about active CPorts */
364 static int gb_connection_control_connected(struct gb_connection *connection)
366 struct gb_protocol *protocol = connection->protocol;
367 struct gb_control *control;
368 u16 cport_id = connection->intf_cport_id;
371 if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_CONNECTED)
374 control = connection->bundle->intf->control;
376 ret = gb_control_connected_operation(control, cport_id);
378 dev_err(&connection->dev,
379 "failed to connect cport: %d\n", ret);
386 /* Inform Interface about inactive CPorts */
388 gb_connection_control_disconnected(struct gb_connection *connection)
390 struct gb_protocol *protocol = connection->protocol;
391 struct gb_control *control;
392 u16 cport_id = connection->intf_cport_id;
395 if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_DISCONNECTED)
398 control = connection->bundle->intf->control;
400 ret = gb_control_disconnected_operation(control, cport_id);
402 dev_warn(&connection->dev,
403 "failed to disconnect cport: %d\n", ret);
408 * Request protocol version supported by the module. We don't need to do
409 * this for SVC as that is initiated by the SVC.
411 static int gb_connection_protocol_get_version(struct gb_connection *connection)
413 struct gb_protocol *protocol = connection->protocol;
416 if (protocol->flags & GB_PROTOCOL_SKIP_VERSION)
419 ret = gb_protocol_get_version(connection);
421 dev_err(&connection->dev,
422 "failed to get protocol version: %d\n", ret);
429 static int gb_connection_init(struct gb_connection *connection)
431 struct gb_protocol *protocol = connection->protocol;
434 ret = gb_connection_hd_cport_enable(connection);
438 ret = gb_connection_svc_connection_create(connection);
440 goto err_hd_cport_disable;
442 ret = gb_connection_control_connected(connection);
444 goto err_svc_destroy;
446 /* Need to enable the connection to initialize it */
447 spin_lock_irq(&connection->lock);
448 connection->state = GB_CONNECTION_STATE_ENABLED;
449 spin_unlock_irq(&connection->lock);
451 ret = gb_connection_protocol_get_version(connection);
455 ret = protocol->connection_init(connection);
462 spin_lock_irq(&connection->lock);
463 connection->state = GB_CONNECTION_STATE_ERROR;
464 spin_unlock_irq(&connection->lock);
466 gb_connection_control_disconnected(connection);
468 gb_connection_svc_connection_destroy(connection);
469 err_hd_cport_disable:
470 gb_connection_hd_cport_disable(connection);
475 static void gb_connection_exit(struct gb_connection *connection)
477 if (!connection->protocol)
480 spin_lock_irq(&connection->lock);
481 if (connection->state != GB_CONNECTION_STATE_ENABLED) {
482 spin_unlock_irq(&connection->lock);
485 connection->state = GB_CONNECTION_STATE_DESTROYING;
486 spin_unlock_irq(&connection->lock);
488 gb_connection_cancel_operations(connection, -ESHUTDOWN);
490 connection->protocol->connection_exit(connection);
491 gb_connection_control_disconnected(connection);
492 gb_connection_svc_connection_destroy(connection);
493 gb_connection_hd_cport_disable(connection);
497 * Tear down a previously set up connection.
499 void gb_connection_destroy(struct gb_connection *connection)
503 if (WARN_ON(!connection))
506 gb_connection_exit(connection);
508 spin_lock_irq(&gb_connections_lock);
509 list_del(&connection->bundle_links);
510 list_del(&connection->hd_links);
511 spin_unlock_irq(&gb_connections_lock);
513 if (connection->protocol)
514 gb_protocol_put(connection->protocol);
515 connection->protocol = NULL;
517 id_map = &connection->hd->cport_id_map;
518 ida_simple_remove(id_map, connection->hd_cport_id);
519 connection->hd_cport_id = CPORT_ID_BAD;
521 device_unregister(&connection->dev);
524 void gb_hd_connections_exit(struct greybus_host_device *hd)
526 struct gb_connection *connection;
528 list_for_each_entry(connection, &hd->connections, hd_links)
529 gb_connection_destroy(connection);
532 int gb_connection_bind_protocol(struct gb_connection *connection)
534 struct gb_protocol *protocol;
537 /* If we already have a protocol bound here, just return */
538 if (connection->protocol)
541 protocol = gb_protocol_get(connection->protocol_id,
546 connection->protocol = protocol;
549 * If we have a valid device_id for the interface block, then we have an
550 * active device, so bring up the connection at the same time.
552 if ((!connection->bundle &&
553 protocol->flags & GB_PROTOCOL_NO_BUNDLE) ||
554 connection->bundle->intf->device_id != GB_DEVICE_ID_BAD) {
555 ret = gb_connection_init(connection);
557 gb_protocol_put(protocol);
558 connection->protocol = NULL;