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 dev_err(parent, "cport 0x%04hx already connected\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 dev_err(parent, "failed to register connection to cport %04hx: %d\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 retval = gb_connection_bind_protocol(connection);
244 dev_err(&connection->dev, "failed to bind protocol: %d\n",
246 gb_connection_destroy(connection);
255 ida_simple_remove(id_map, hd_cport_id);
260 static int gb_connection_hd_cport_enable(struct gb_connection *connection)
262 struct greybus_host_device *hd = connection->hd;
265 if (!hd->driver->cport_enable)
268 ret = hd->driver->cport_enable(hd, connection->hd_cport_id);
270 dev_err(&connection->dev,
271 "failed to enable host cport: %d\n", ret);
278 static void gb_connection_hd_cport_disable(struct gb_connection *connection)
280 struct greybus_host_device *hd = connection->hd;
282 if (!hd->driver->cport_disable)
285 hd->driver->cport_disable(hd, connection->hd_cport_id);
288 struct gb_connection *gb_connection_create(struct gb_bundle *bundle,
289 u16 cport_id, u8 protocol_id)
291 return gb_connection_create_range(bundle->intf->hd, bundle,
292 &bundle->dev, cport_id, protocol_id,
293 0, bundle->intf->hd->num_cports - 1);
297 * Cancel all active operations on a connection.
299 * Should only be called during connection tear down.
301 static void gb_connection_cancel_operations(struct gb_connection *connection,
304 struct gb_operation *operation;
306 spin_lock_irq(&connection->lock);
307 while (!list_empty(&connection->operations)) {
308 operation = list_last_entry(&connection->operations,
309 struct gb_operation, links);
310 gb_operation_get(operation);
311 spin_unlock_irq(&connection->lock);
313 if (gb_operation_is_incoming(operation))
314 gb_operation_cancel_incoming(operation, errno);
316 gb_operation_cancel(operation, errno);
318 gb_operation_put(operation);
320 spin_lock_irq(&connection->lock);
322 spin_unlock_irq(&connection->lock);
326 * Request the SVC to create a connection from AP's cport to interface's
330 gb_connection_svc_connection_create(struct gb_connection *connection)
332 struct greybus_host_device *hd = connection->hd;
333 struct gb_protocol *protocol = connection->protocol;
334 struct gb_interface *intf;
337 if (protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
340 intf = connection->bundle->intf;
341 ret = gb_svc_connection_create(hd->svc,
342 hd->endo->ap_intf_id,
343 connection->hd_cport_id,
345 connection->intf_cport_id,
346 intf->boot_over_unipro);
348 dev_err(&connection->dev,
349 "failed to create svc connection: %d\n", ret);
357 gb_connection_svc_connection_destroy(struct gb_connection *connection)
359 if (connection->protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
362 gb_svc_connection_destroy(connection->hd->svc,
363 connection->hd->endo->ap_intf_id,
364 connection->hd_cport_id,
365 connection->bundle->intf->interface_id,
366 connection->intf_cport_id);
369 /* Inform Interface about active CPorts */
370 static int gb_connection_control_connected(struct gb_connection *connection)
372 struct gb_protocol *protocol = connection->protocol;
373 struct gb_control *control;
374 u16 cport_id = connection->intf_cport_id;
377 if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_CONNECTED)
380 control = connection->bundle->intf->control;
382 ret = gb_control_connected_operation(control, cport_id);
384 dev_err(&connection->dev,
385 "failed to connect cport: %d\n", ret);
392 /* Inform Interface about inactive CPorts */
394 gb_connection_control_disconnected(struct gb_connection *connection)
396 struct gb_protocol *protocol = connection->protocol;
397 struct gb_control *control;
398 u16 cport_id = connection->intf_cport_id;
401 if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_DISCONNECTED)
404 control = connection->bundle->intf->control;
406 ret = gb_control_disconnected_operation(control, cport_id);
408 dev_warn(&connection->dev,
409 "failed to disconnect cport: %d\n", ret);
414 * Request protocol version supported by the module. We don't need to do
415 * this for SVC as that is initiated by the SVC.
417 static int gb_connection_protocol_get_version(struct gb_connection *connection)
419 struct gb_protocol *protocol = connection->protocol;
422 if (protocol->flags & GB_PROTOCOL_SKIP_VERSION)
425 ret = gb_protocol_get_version(connection);
427 dev_err(&connection->dev,
428 "failed to get protocol version: %d\n", ret);
435 static int gb_connection_init(struct gb_connection *connection)
437 struct gb_protocol *protocol = connection->protocol;
440 ret = gb_connection_hd_cport_enable(connection);
444 ret = gb_connection_svc_connection_create(connection);
446 goto err_hd_cport_disable;
448 ret = gb_connection_control_connected(connection);
450 goto err_svc_destroy;
452 /* Need to enable the connection to initialize it */
453 spin_lock_irq(&connection->lock);
454 connection->state = GB_CONNECTION_STATE_ENABLED;
455 spin_unlock_irq(&connection->lock);
457 ret = gb_connection_protocol_get_version(connection);
461 ret = protocol->connection_init(connection);
468 spin_lock_irq(&connection->lock);
469 connection->state = GB_CONNECTION_STATE_ERROR;
470 spin_unlock_irq(&connection->lock);
472 gb_connection_control_disconnected(connection);
474 gb_connection_svc_connection_destroy(connection);
475 err_hd_cport_disable:
476 gb_connection_hd_cport_disable(connection);
481 static void gb_connection_exit(struct gb_connection *connection)
483 if (!connection->protocol)
486 spin_lock_irq(&connection->lock);
487 if (connection->state != GB_CONNECTION_STATE_ENABLED) {
488 spin_unlock_irq(&connection->lock);
491 connection->state = GB_CONNECTION_STATE_DESTROYING;
492 spin_unlock_irq(&connection->lock);
494 gb_connection_cancel_operations(connection, -ESHUTDOWN);
496 connection->protocol->connection_exit(connection);
497 gb_connection_control_disconnected(connection);
498 gb_connection_svc_connection_destroy(connection);
499 gb_connection_hd_cport_disable(connection);
503 * Tear down a previously set up connection.
505 void gb_connection_destroy(struct gb_connection *connection)
509 if (WARN_ON(!connection))
512 gb_connection_exit(connection);
514 spin_lock_irq(&gb_connections_lock);
515 list_del(&connection->bundle_links);
516 list_del(&connection->hd_links);
517 spin_unlock_irq(&gb_connections_lock);
519 if (connection->protocol)
520 gb_protocol_put(connection->protocol);
521 connection->protocol = NULL;
523 id_map = &connection->hd->cport_id_map;
524 ida_simple_remove(id_map, connection->hd_cport_id);
525 connection->hd_cport_id = CPORT_ID_BAD;
527 device_unregister(&connection->dev);
530 void gb_connection_latency_tag_enable(struct gb_connection *connection)
532 struct greybus_host_device *hd = connection->hd;
535 if (!hd->driver->latency_tag_enable)
538 ret = hd->driver->latency_tag_enable(hd, connection->hd_cport_id);
540 dev_err(&connection->dev,
541 "failed to enable latency tag: %d\n", ret);
544 EXPORT_SYMBOL_GPL(gb_connection_latency_tag_enable);
546 void gb_connection_latency_tag_disable(struct gb_connection *connection)
548 struct greybus_host_device *hd = connection->hd;
551 if (!hd->driver->latency_tag_disable)
554 ret = hd->driver->latency_tag_disable(hd, connection->hd_cport_id);
556 dev_err(&connection->dev,
557 "failed to disable latency tag: %d\n", ret);
560 EXPORT_SYMBOL_GPL(gb_connection_latency_tag_disable);
562 void gb_hd_connections_exit(struct greybus_host_device *hd)
564 struct gb_connection *connection;
566 list_for_each_entry(connection, &hd->connections, hd_links)
567 gb_connection_destroy(connection);
570 int gb_connection_bind_protocol(struct gb_connection *connection)
572 struct gb_protocol *protocol;
575 /* If we already have a protocol bound here, just return */
576 if (connection->protocol)
579 protocol = gb_protocol_get(connection->protocol_id,
583 dev_warn(&connection->dev,
584 "protocol 0x%02hhx version %hhu.%hhu not found\n",
585 connection->protocol_id,
586 connection->major, connection->minor);
589 connection->protocol = protocol;
592 * If we have a valid device_id for the interface block, then we have an
593 * active device, so bring up the connection at the same time.
595 if ((!connection->bundle &&
596 protocol->flags & GB_PROTOCOL_NO_BUNDLE) ||
597 connection->bundle->intf->device_id != GB_DEVICE_ID_BAD) {
598 ret = gb_connection_init(connection);
600 gb_protocol_put(protocol);
601 connection->protocol = NULL;