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 retval = gb_connection_bind_protocol(connection);
244 dev_err(&connection->dev, "failed to bind protocol: %d\n",
246 gb_connection_destroy(connection);
250 if (!connection->protocol)
251 dev_warn(&connection->dev,
252 "protocol 0x%02hhx handler not found\n", protocol_id);
259 ida_simple_remove(id_map, hd_cport_id);
264 static int gb_connection_hd_cport_enable(struct gb_connection *connection)
266 struct greybus_host_device *hd = connection->hd;
269 if (!hd->driver->cport_enable)
272 ret = hd->driver->cport_enable(hd, connection->hd_cport_id);
274 dev_err(&connection->dev,
275 "failed to enable host cport: %d\n", ret);
282 static void gb_connection_hd_cport_disable(struct gb_connection *connection)
284 struct greybus_host_device *hd = connection->hd;
286 if (!hd->driver->cport_disable)
289 hd->driver->cport_disable(hd, connection->hd_cport_id);
292 struct gb_connection *gb_connection_create(struct gb_bundle *bundle,
293 u16 cport_id, u8 protocol_id)
295 return gb_connection_create_range(bundle->intf->hd, bundle,
296 &bundle->dev, cport_id, protocol_id,
297 0, bundle->intf->hd->num_cports - 1);
301 * Cancel all active operations on a connection.
303 * Should only be called during connection tear down.
305 static void gb_connection_cancel_operations(struct gb_connection *connection,
308 struct gb_operation *operation;
310 spin_lock_irq(&connection->lock);
311 while (!list_empty(&connection->operations)) {
312 operation = list_last_entry(&connection->operations,
313 struct gb_operation, links);
314 gb_operation_get(operation);
315 spin_unlock_irq(&connection->lock);
317 if (gb_operation_is_incoming(operation))
318 gb_operation_cancel_incoming(operation, errno);
320 gb_operation_cancel(operation, errno);
322 gb_operation_put(operation);
324 spin_lock_irq(&connection->lock);
326 spin_unlock_irq(&connection->lock);
330 * Request the SVC to create a connection from AP's cport to interface's
334 gb_connection_svc_connection_create(struct gb_connection *connection)
336 struct greybus_host_device *hd = connection->hd;
337 struct gb_protocol *protocol = connection->protocol;
338 struct gb_interface *intf;
341 if (protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
344 intf = connection->bundle->intf;
345 ret = gb_svc_connection_create(hd->svc,
346 hd->endo->ap_intf_id,
347 connection->hd_cport_id,
349 connection->intf_cport_id,
350 intf->boot_over_unipro);
352 dev_err(&connection->dev,
353 "failed to create svc connection: %d\n", ret);
361 gb_connection_svc_connection_destroy(struct gb_connection *connection)
363 if (connection->protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
366 gb_svc_connection_destroy(connection->hd->svc,
367 connection->hd->endo->ap_intf_id,
368 connection->hd_cport_id,
369 connection->bundle->intf->interface_id,
370 connection->intf_cport_id);
373 /* Inform Interface about active CPorts */
374 static int gb_connection_control_connected(struct gb_connection *connection)
376 struct gb_protocol *protocol = connection->protocol;
377 struct gb_control *control;
378 u16 cport_id = connection->intf_cport_id;
381 if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_CONNECTED)
384 control = connection->bundle->intf->control;
386 ret = gb_control_connected_operation(control, cport_id);
388 dev_err(&connection->dev,
389 "failed to connect cport: %d\n", ret);
396 /* Inform Interface about inactive CPorts */
398 gb_connection_control_disconnected(struct gb_connection *connection)
400 struct gb_protocol *protocol = connection->protocol;
401 struct gb_control *control;
402 u16 cport_id = connection->intf_cport_id;
405 if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_DISCONNECTED)
408 control = connection->bundle->intf->control;
410 ret = gb_control_disconnected_operation(control, cport_id);
412 dev_warn(&connection->dev,
413 "failed to disconnect cport: %d\n", ret);
418 * Request protocol version supported by the module. We don't need to do
419 * this for SVC as that is initiated by the SVC.
421 static int gb_connection_protocol_get_version(struct gb_connection *connection)
423 struct gb_protocol *protocol = connection->protocol;
426 if (protocol->flags & GB_PROTOCOL_SKIP_VERSION)
429 ret = gb_protocol_get_version(connection);
431 dev_err(&connection->dev,
432 "failed to get protocol version: %d\n", ret);
439 static int gb_connection_init(struct gb_connection *connection)
441 struct gb_protocol *protocol = connection->protocol;
444 ret = gb_connection_hd_cport_enable(connection);
448 ret = gb_connection_svc_connection_create(connection);
450 goto err_hd_cport_disable;
452 ret = gb_connection_control_connected(connection);
454 goto err_svc_destroy;
456 /* Need to enable the connection to initialize it */
457 spin_lock_irq(&connection->lock);
458 connection->state = GB_CONNECTION_STATE_ENABLED;
459 spin_unlock_irq(&connection->lock);
461 ret = gb_connection_protocol_get_version(connection);
465 ret = protocol->connection_init(connection);
472 spin_lock_irq(&connection->lock);
473 connection->state = GB_CONNECTION_STATE_ERROR;
474 spin_unlock_irq(&connection->lock);
476 gb_connection_control_disconnected(connection);
478 gb_connection_svc_connection_destroy(connection);
479 err_hd_cport_disable:
480 gb_connection_hd_cport_disable(connection);
485 static void gb_connection_exit(struct gb_connection *connection)
487 if (!connection->protocol)
490 spin_lock_irq(&connection->lock);
491 if (connection->state != GB_CONNECTION_STATE_ENABLED) {
492 spin_unlock_irq(&connection->lock);
495 connection->state = GB_CONNECTION_STATE_DESTROYING;
496 spin_unlock_irq(&connection->lock);
498 gb_connection_cancel_operations(connection, -ESHUTDOWN);
500 connection->protocol->connection_exit(connection);
501 gb_connection_control_disconnected(connection);
502 gb_connection_svc_connection_destroy(connection);
503 gb_connection_hd_cport_disable(connection);
507 * Tear down a previously set up connection.
509 void gb_connection_destroy(struct gb_connection *connection)
513 if (WARN_ON(!connection))
516 gb_connection_exit(connection);
518 spin_lock_irq(&gb_connections_lock);
519 list_del(&connection->bundle_links);
520 list_del(&connection->hd_links);
521 spin_unlock_irq(&gb_connections_lock);
523 if (connection->protocol)
524 gb_protocol_put(connection->protocol);
525 connection->protocol = NULL;
527 id_map = &connection->hd->cport_id_map;
528 ida_simple_remove(id_map, connection->hd_cport_id);
529 connection->hd_cport_id = CPORT_ID_BAD;
531 device_unregister(&connection->dev);
534 void gb_hd_connections_exit(struct greybus_host_device *hd)
536 struct gb_connection *connection;
538 list_for_each_entry(connection, &hd->connections, hd_links)
539 gb_connection_destroy(connection);
542 int gb_connection_bind_protocol(struct gb_connection *connection)
544 struct gb_protocol *protocol;
547 /* If we already have a protocol bound here, just return */
548 if (connection->protocol)
551 protocol = gb_protocol_get(connection->protocol_id,
556 connection->protocol = protocol;
559 * If we have a valid device_id for the interface block, then we have an
560 * active device, so bring up the connection at the same time.
562 if ((!connection->bundle &&
563 protocol->flags & GB_PROTOCOL_NO_BUNDLE) ||
564 connection->bundle->intf->device_id != GB_DEVICE_ID_BAD) {
565 ret = gb_connection_init(connection);
567 gb_protocol_put(protocol);
568 connection->protocol = NULL;