greybus: loopback: drop dependency on internal timestamps
[cascardo/linux.git] / drivers / staging / greybus / connection.c
1 /*
2  * Greybus connections
3  *
4  * Copyright 2014 Google Inc.
5  * Copyright 2014 Linaro Ltd.
6  *
7  * Released under the GPLv2 only.
8  */
9
10 #include <linux/workqueue.h>
11
12 #include "greybus.h"
13
14 #define GB_CONNECTION_TS_KFIFO_ELEMENTS 2
15 #define GB_CONNECTION_TS_KFIFO_LEN \
16         (GB_CONNECTION_TS_KFIFO_ELEMENTS * sizeof(struct timeval))
17
18 static DEFINE_SPINLOCK(gb_connections_lock);
19
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)
23 {
24         struct greybus_host_device *hd = intf->hd;
25         struct gb_connection *connection;
26
27         list_for_each_entry(connection, &hd->connections, hd_links)
28                 if (connection->bundle->intf == intf &&
29                                 connection->intf_cport_id == cport_id)
30                         return connection;
31         return NULL;
32 }
33
34 static struct gb_connection *
35 gb_connection_hd_find(struct greybus_host_device *hd, u16 cport_id)
36 {
37         struct gb_connection *connection;
38         unsigned long flags;
39
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)
43                         goto found;
44         connection = NULL;
45 found:
46         spin_unlock_irqrestore(&gb_connections_lock, flags);
47
48         return connection;
49 }
50
51 /*
52  * Callback from the host driver to let us know that data has been
53  * received on the bundle.
54  */
55 void greybus_data_rcvd(struct greybus_host_device *hd, u16 cport_id,
56                         u8 *data, size_t length)
57 {
58         struct gb_connection *connection;
59
60         connection = gb_connection_hd_find(hd, cport_id);
61         if (!connection) {
62                 dev_err(hd->parent,
63                         "nonexistent connection (%zu bytes dropped)\n", length);
64                 return;
65         }
66         gb_connection_recv(connection, data, length);
67 }
68 EXPORT_SYMBOL_GPL(greybus_data_rcvd);
69
70 static ssize_t state_show(struct device *dev, struct device_attribute *attr,
71                           char *buf)
72 {
73         struct gb_connection *connection = to_gb_connection(dev);
74         enum gb_connection_state state;
75
76         spin_lock_irq(&connection->lock);
77         state = connection->state;
78         spin_unlock_irq(&connection->lock);
79
80         return sprintf(buf, "%d\n", state);
81 }
82 static DEVICE_ATTR_RO(state);
83
84 static ssize_t
85 protocol_id_show(struct device *dev, struct device_attribute *attr, char *buf)
86 {
87         struct gb_connection *connection = to_gb_connection(dev);
88
89         if (connection->protocol)
90                 return sprintf(buf, "%d\n", connection->protocol->id);
91         else
92                 return -EINVAL;
93 }
94 static DEVICE_ATTR_RO(protocol_id);
95
96 static ssize_t
97 ap_cport_id_show(struct device *dev, struct device_attribute *attr, char *buf)
98 {
99         struct gb_connection *connection = to_gb_connection(dev);
100         return sprintf(buf, "%hu\n", connection->hd_cport_id);
101 }
102 static DEVICE_ATTR_RO(ap_cport_id);
103
104 static struct attribute *connection_attrs[] = {
105         &dev_attr_state.attr,
106         &dev_attr_protocol_id.attr,
107         &dev_attr_ap_cport_id.attr,
108         NULL,
109 };
110
111 ATTRIBUTE_GROUPS(connection);
112
113 static void gb_connection_release(struct device *dev)
114 {
115         struct gb_connection *connection = to_gb_connection(dev);
116
117         destroy_workqueue(connection->wq);
118         kfree(connection);
119 }
120
121 struct device_type greybus_connection_type = {
122         .name =         "greybus_connection",
123         .release =      gb_connection_release,
124 };
125
126
127 int svc_update_connection(struct gb_interface *intf,
128                           struct gb_connection *connection)
129 {
130         struct gb_bundle *bundle;
131
132         bundle = gb_bundle_create(intf, GB_SVC_BUNDLE_ID, GREYBUS_CLASS_SVC);
133         if (!bundle)
134                 return -EINVAL;
135
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),
140                      GB_SVC_CPORT_ID);
141
142         WARN_ON(device_add(&connection->dev));
143
144         spin_lock_irq(&gb_connections_lock);
145         list_add(&connection->bundle_links, &bundle->connections);
146         spin_unlock_irq(&gb_connections_lock);
147
148         return 0;
149 }
150
151 /*
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.
155  *
156  * A connection also maintains the state of operations sent over the
157  * connection.
158  *
159  * Returns a pointer to the new connection if successful, or a null
160  * pointer otherwise.
161  */
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,
166                            u32 ida_end)
167 {
168         struct gb_connection *connection;
169         struct ida *id_map = &hd->cport_id_map;
170         int hd_cport_id;
171         int retval;
172         u8 major = 0;
173         u8 minor = 1;
174
175         /*
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.
179          */
180         if (bundle && gb_connection_intf_find(bundle->intf, cport_id)) {
181                 pr_err("duplicate interface cport id 0x%04hx\n", cport_id);
182                 return NULL;
183         }
184
185         hd_cport_id = ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL);
186         if (hd_cport_id < 0)
187                 return NULL;
188
189         connection = kzalloc(sizeof(*connection), GFP_KERNEL);
190         if (!connection)
191                 goto err_remove_ida;
192
193         connection->hd_cport_id = hd_cport_id;
194         connection->intf_cport_id = cport_id;
195         connection->hd = hd;
196
197         connection->protocol_id = protocol_id;
198         connection->major = major;
199         connection->minor = minor;
200
201         connection->bundle = bundle;
202         connection->state = GB_CONNECTION_STATE_DISABLED;
203
204         atomic_set(&connection->op_cycle, 0);
205         spin_lock_init(&connection->lock);
206         INIT_LIST_HEAD(&connection->operations);
207
208         connection->wq = alloc_workqueue("%s:%d", WQ_UNBOUND, 1,
209                                          dev_name(parent), cport_id);
210         if (!connection->wq)
211                 goto err_free_connection;
212
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);
220
221         retval = device_add(&connection->dev);
222         if (retval) {
223                 connection->hd_cport_id = CPORT_ID_BAD;
224                 put_device(&connection->dev);
225
226                 pr_err("failed to add connection device for cport 0x%04hx\n",
227                         cport_id);
228
229                 goto err_remove_ida;
230         }
231
232         spin_lock_irq(&gb_connections_lock);
233         list_add(&connection->hd_links, &hd->connections);
234
235         if (bundle)
236                 list_add(&connection->bundle_links, &bundle->connections);
237         else
238                 INIT_LIST_HEAD(&connection->bundle_links);
239
240         spin_unlock_irq(&gb_connections_lock);
241
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);
246
247         return connection;
248
249 err_free_connection:
250         kfree(connection);
251 err_remove_ida:
252         ida_simple_remove(id_map, hd_cport_id);
253
254         return NULL;
255 }
256
257 static int gb_connection_hd_cport_enable(struct gb_connection *connection)
258 {
259         struct greybus_host_device *hd = connection->hd;
260         int ret;
261
262         if (!hd->driver->cport_enable)
263                 return 0;
264
265         ret = hd->driver->cport_enable(hd, connection->hd_cport_id);
266         if (ret) {
267                 dev_err(&connection->dev,
268                                 "failed to enable host cport: %d\n", ret);
269                 return ret;
270         }
271
272         return 0;
273 }
274
275 static void gb_connection_hd_cport_disable(struct gb_connection *connection)
276 {
277         struct greybus_host_device *hd = connection->hd;
278
279         if (!hd->driver->cport_disable)
280                 return;
281
282         hd->driver->cport_disable(hd, connection->hd_cport_id);
283 }
284
285 struct gb_connection *gb_connection_create(struct gb_bundle *bundle,
286                                 u16 cport_id, u8 protocol_id)
287 {
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);
291 }
292
293 /*
294  * Cancel all active operations on a connection.
295  *
296  * Should only be called during connection tear down.
297  */
298 static void gb_connection_cancel_operations(struct gb_connection *connection,
299                                                 int errno)
300 {
301         struct gb_operation *operation;
302
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);
309
310                 if (gb_operation_is_incoming(operation))
311                         gb_operation_cancel_incoming(operation, errno);
312                 else
313                         gb_operation_cancel(operation, errno);
314
315                 gb_operation_put(operation);
316
317                 spin_lock_irq(&connection->lock);
318         }
319         spin_unlock_irq(&connection->lock);
320 }
321
322 /*
323  * Request the SVC to create a connection from AP's cport to interface's
324  * cport.
325  */
326 static int
327 gb_connection_svc_connection_create(struct gb_connection *connection)
328 {
329         struct greybus_host_device *hd = connection->hd;
330         struct gb_protocol *protocol = connection->protocol;
331         int ret;
332
333         if (protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
334                 return 0;
335
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);
341         if (ret) {
342                 dev_err(&connection->dev,
343                                 "failed to create svc connection: %d\n", ret);
344                 return ret;
345         }
346
347         return 0;
348 }
349
350 static void
351 gb_connection_svc_connection_destroy(struct gb_connection *connection)
352 {
353         if (connection->protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
354                 return;
355
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);
361 }
362
363 /* Inform Interface about active CPorts */
364 static int gb_connection_control_connected(struct gb_connection *connection)
365 {
366         struct gb_protocol *protocol = connection->protocol;
367         struct gb_control *control;
368         u16 cport_id = connection->intf_cport_id;
369         int ret;
370
371         if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_CONNECTED)
372                 return 0;
373
374         control = connection->bundle->intf->control;
375
376         ret = gb_control_connected_operation(control, cport_id);
377         if (ret) {
378                 dev_err(&connection->dev,
379                                 "failed to connect cport: %d\n", ret);
380                 return ret;
381         }
382
383         return 0;
384 }
385
386 /* Inform Interface about inactive CPorts */
387 static void
388 gb_connection_control_disconnected(struct gb_connection *connection)
389 {
390         struct gb_protocol *protocol = connection->protocol;
391         struct gb_control *control;
392         u16 cport_id = connection->intf_cport_id;
393         int ret;
394
395         if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_DISCONNECTED)
396                 return;
397
398         control = connection->bundle->intf->control;
399
400         ret = gb_control_disconnected_operation(control, cport_id);
401         if (ret) {
402                 dev_warn(&connection->dev,
403                                 "failed to disconnect cport: %d\n", ret);
404         }
405 }
406
407 /*
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.
410  */
411 static int gb_connection_protocol_get_version(struct gb_connection *connection)
412 {
413         struct gb_protocol *protocol = connection->protocol;
414         int ret;
415
416         if (protocol->flags & GB_PROTOCOL_SKIP_VERSION)
417                 return 0;
418
419         ret = gb_protocol_get_version(connection);
420         if (ret) {
421                 dev_err(&connection->dev,
422                                 "failed to get protocol version: %d\n", ret);
423                 return ret;
424         }
425
426         return 0;
427 }
428
429 static int gb_connection_init(struct gb_connection *connection)
430 {
431         struct gb_protocol *protocol = connection->protocol;
432         int ret;
433
434         ret = gb_connection_hd_cport_enable(connection);
435         if (ret)
436                 return ret;
437
438         ret = gb_connection_svc_connection_create(connection);
439         if (ret)
440                 goto err_hd_cport_disable;
441
442         ret = gb_connection_control_connected(connection);
443         if (ret)
444                 goto err_svc_destroy;
445
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);
450
451         ret = gb_connection_protocol_get_version(connection);
452         if (ret)
453                 goto err_disconnect;
454
455         ret = protocol->connection_init(connection);
456         if (ret)
457                 goto err_disconnect;
458
459         return 0;
460
461 err_disconnect:
462         spin_lock_irq(&connection->lock);
463         connection->state = GB_CONNECTION_STATE_ERROR;
464         spin_unlock_irq(&connection->lock);
465
466         gb_connection_control_disconnected(connection);
467 err_svc_destroy:
468         gb_connection_svc_connection_destroy(connection);
469 err_hd_cport_disable:
470         gb_connection_hd_cport_disable(connection);
471
472         return ret;
473 }
474
475 static void gb_connection_exit(struct gb_connection *connection)
476 {
477         if (!connection->protocol)
478                 return;
479
480         spin_lock_irq(&connection->lock);
481         if (connection->state != GB_CONNECTION_STATE_ENABLED) {
482                 spin_unlock_irq(&connection->lock);
483                 return;
484         }
485         connection->state = GB_CONNECTION_STATE_DESTROYING;
486         spin_unlock_irq(&connection->lock);
487
488         gb_connection_cancel_operations(connection, -ESHUTDOWN);
489
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);
494 }
495
496 /*
497  * Tear down a previously set up connection.
498  */
499 void gb_connection_destroy(struct gb_connection *connection)
500 {
501         struct ida *id_map;
502
503         if (WARN_ON(!connection))
504                 return;
505
506         gb_connection_exit(connection);
507
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);
512
513         if (connection->protocol)
514                 gb_protocol_put(connection->protocol);
515         connection->protocol = NULL;
516
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;
520
521         device_unregister(&connection->dev);
522 }
523
524 void gb_hd_connections_exit(struct greybus_host_device *hd)
525 {
526         struct gb_connection *connection;
527
528         list_for_each_entry(connection, &hd->connections, hd_links)
529                 gb_connection_destroy(connection);
530 }
531
532 int gb_connection_bind_protocol(struct gb_connection *connection)
533 {
534         struct gb_protocol *protocol;
535         int ret;
536
537         /* If we already have a protocol bound here, just return */
538         if (connection->protocol)
539                 return 0;
540
541         protocol = gb_protocol_get(connection->protocol_id,
542                                    connection->major,
543                                    connection->minor);
544         if (!protocol)
545                 return 0;
546         connection->protocol = protocol;
547
548         /*
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.
551          */
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);
556                 if (ret) {
557                         gb_protocol_put(protocol);
558                         connection->protocol = NULL;
559                         return ret;
560                 }
561         }
562
563         return 0;
564 }