c3207c828a450ce1acf4ce4b38da712e59e54299
[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
15 static int gb_connection_bind_protocol(struct gb_connection *connection);
16 static void gb_connection_unbind_protocol(struct gb_connection *connection);
17
18
19 static DEFINE_SPINLOCK(gb_connections_lock);
20
21 /* This is only used at initialization time; no locking is required. */
22 static struct gb_connection *
23 gb_connection_intf_find(struct gb_interface *intf, u16 cport_id)
24 {
25         struct gb_host_device *hd = intf->hd;
26         struct gb_connection *connection;
27
28         list_for_each_entry(connection, &hd->connections, hd_links) {
29                 if (connection->intf == intf &&
30                                 connection->intf_cport_id == cport_id)
31                         return connection;
32         }
33
34         return NULL;
35 }
36
37 static struct gb_connection *
38 gb_connection_hd_find(struct gb_host_device *hd, u16 cport_id)
39 {
40         struct gb_connection *connection;
41         unsigned long flags;
42
43         spin_lock_irqsave(&gb_connections_lock, flags);
44         list_for_each_entry(connection, &hd->connections, hd_links)
45                 if (connection->hd_cport_id == cport_id)
46                         goto found;
47         connection = NULL;
48 found:
49         spin_unlock_irqrestore(&gb_connections_lock, flags);
50
51         return connection;
52 }
53
54 /*
55  * Callback from the host driver to let us know that data has been
56  * received on the bundle.
57  */
58 void greybus_data_rcvd(struct gb_host_device *hd, u16 cport_id,
59                         u8 *data, size_t length)
60 {
61         struct gb_connection *connection;
62
63         connection = gb_connection_hd_find(hd, cport_id);
64         if (!connection) {
65                 dev_err(&hd->dev,
66                         "nonexistent connection (%zu bytes dropped)\n", length);
67                 return;
68         }
69         gb_connection_recv(connection, data, length);
70 }
71 EXPORT_SYMBOL_GPL(greybus_data_rcvd);
72
73 static DEFINE_MUTEX(connection_mutex);
74
75 static void gb_connection_kref_release(struct kref *kref)
76 {
77         struct gb_connection *connection;
78
79         connection = container_of(kref, struct gb_connection, kref);
80         destroy_workqueue(connection->wq);
81         kfree(connection);
82         mutex_unlock(&connection_mutex);
83 }
84
85 static void gb_connection_init_name(struct gb_connection *connection)
86 {
87         u16 hd_cport_id = connection->hd_cport_id;
88         u16 cport_id = 0;
89         u8 intf_id = 0;
90
91         if (connection->intf) {
92                 intf_id = connection->intf->interface_id;
93                 cport_id = connection->intf_cport_id;
94         }
95
96         snprintf(connection->name, sizeof(connection->name),
97                         "%u/%u:%u", hd_cport_id, intf_id, cport_id);
98 }
99
100 /*
101  * gb_connection_create() - create a Greybus connection
102  * @hd:                 host device of the connection
103  * @hd_cport_id:        host-device cport id, or -1 for dynamic allocation
104  * @intf:               remote interface, or NULL for static connections
105  * @bundle:             remote-interface bundle (may be NULL)
106  * @cport_id:           remote-interface cport id, or 0 for static connections
107  * @protocol_id:        protocol id
108  *
109  * Create a Greybus connection, representing the bidirectional link
110  * between a CPort on a (local) Greybus host device and a CPort on
111  * another Greybus interface.
112  *
113  * A connection also maintains the state of operations sent over the
114  * connection.
115  *
116  * Return: A pointer to the new connection if successful, or NULL otherwise.
117  */
118 static struct gb_connection *
119 gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
120                                 struct gb_interface *intf,
121                                 struct gb_bundle *bundle, int cport_id,
122                                 u8 protocol_id)
123 {
124         struct gb_connection *connection;
125         struct ida *id_map = &hd->cport_id_map;
126         int ida_start, ida_end;
127         u8 major = 0;
128         u8 minor = 1;
129
130         /*
131          * If a manifest tries to reuse a cport, reject it.  We
132          * initialize connections serially so we don't need to worry
133          * about holding the connection lock.
134          */
135         if (bundle && gb_connection_intf_find(bundle->intf, cport_id)) {
136                 dev_err(&bundle->dev, "cport %u already connected\n",
137                                 cport_id);
138                 return NULL;
139         }
140
141         if (hd_cport_id < 0) {
142                 ida_start = 0;
143                 ida_end = hd->num_cports;
144         } else if (hd_cport_id < hd->num_cports) {
145                 ida_start = hd_cport_id;
146                 ida_end = hd_cport_id + 1;
147         } else {
148                 dev_err(&hd->dev, "cport %d not available\n", hd_cport_id);
149                 return NULL;
150         }
151
152         hd_cport_id = ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL);
153         if (hd_cport_id < 0)
154                 return NULL;
155
156         connection = kzalloc(sizeof(*connection), GFP_KERNEL);
157         if (!connection)
158                 goto err_remove_ida;
159
160         connection->hd_cport_id = hd_cport_id;
161         connection->intf_cport_id = cport_id;
162         connection->hd = hd;
163         connection->intf = intf;
164
165         connection->protocol_id = protocol_id;
166         connection->major = major;
167         connection->minor = minor;
168
169         connection->bundle = bundle;
170         connection->state = GB_CONNECTION_STATE_DISABLED;
171
172         atomic_set(&connection->op_cycle, 0);
173         mutex_init(&connection->mutex);
174         spin_lock_init(&connection->lock);
175         INIT_LIST_HEAD(&connection->operations);
176
177         connection->wq = alloc_workqueue("%s:%d", WQ_UNBOUND, 1,
178                                          dev_name(&hd->dev), hd_cport_id);
179         if (!connection->wq)
180                 goto err_free_connection;
181
182         kref_init(&connection->kref);
183
184         gb_connection_init_name(connection);
185
186         spin_lock_irq(&gb_connections_lock);
187         list_add(&connection->hd_links, &hd->connections);
188
189         if (bundle)
190                 list_add(&connection->bundle_links, &bundle->connections);
191         else
192                 INIT_LIST_HEAD(&connection->bundle_links);
193
194         spin_unlock_irq(&gb_connections_lock);
195
196         return connection;
197
198 err_free_connection:
199         kfree(connection);
200 err_remove_ida:
201         ida_simple_remove(id_map, hd_cport_id);
202
203         return NULL;
204 }
205
206 struct gb_connection *
207 gb_connection_create_static(struct gb_host_device *hd,
208                                         u16 hd_cport_id, u8 protocol_id)
209 {
210         return gb_connection_create(hd, hd_cport_id, NULL, NULL, 0,
211                                                                 protocol_id);
212 }
213
214 struct gb_connection *
215 gb_connection_create_dynamic(struct gb_interface *intf,
216                                         struct gb_bundle *bundle,
217                                         u16 cport_id, u8 protocol_id)
218 {
219         return gb_connection_create(intf->hd, -1, intf, bundle, cport_id,
220                                                                 protocol_id);
221 }
222
223 static int gb_connection_hd_cport_enable(struct gb_connection *connection)
224 {
225         struct gb_host_device *hd = connection->hd;
226         int ret;
227
228         if (!hd->driver->cport_enable)
229                 return 0;
230
231         ret = hd->driver->cport_enable(hd, connection->hd_cport_id);
232         if (ret) {
233                 dev_err(&hd->dev,
234                         "failed to enable host cport: %d\n", ret);
235                 return ret;
236         }
237
238         return 0;
239 }
240
241 static void gb_connection_hd_cport_disable(struct gb_connection *connection)
242 {
243         struct gb_host_device *hd = connection->hd;
244
245         if (!hd->driver->cport_disable)
246                 return;
247
248         hd->driver->cport_disable(hd, connection->hd_cport_id);
249 }
250
251 /*
252  * Request the SVC to create a connection from AP's cport to interface's
253  * cport.
254  */
255 static int
256 gb_connection_svc_connection_create(struct gb_connection *connection)
257 {
258         struct gb_host_device *hd = connection->hd;
259         struct gb_interface *intf;
260         int ret;
261
262         if (gb_connection_is_static(connection))
263                 return 0;
264
265         intf = connection->intf;
266         ret = gb_svc_connection_create(hd->svc,
267                         hd->svc->ap_intf_id,
268                         connection->hd_cport_id,
269                         intf->interface_id,
270                         connection->intf_cport_id,
271                         intf->boot_over_unipro);
272         if (ret) {
273                 dev_err(&connection->hd->dev,
274                         "%s: failed to create svc connection: %d\n",
275                         connection->name, ret);
276                 return ret;
277         }
278
279         return 0;
280 }
281
282 static void
283 gb_connection_svc_connection_destroy(struct gb_connection *connection)
284 {
285         if (gb_connection_is_static(connection))
286                 return;
287
288         gb_svc_connection_destroy(connection->hd->svc,
289                                   connection->hd->svc->ap_intf_id,
290                                   connection->hd_cport_id,
291                                   connection->intf->interface_id,
292                                   connection->intf_cport_id);
293 }
294
295 /* Inform Interface about active CPorts */
296 static int gb_connection_control_connected(struct gb_connection *connection)
297 {
298         struct gb_protocol *protocol = connection->protocol;
299         struct gb_control *control;
300         u16 cport_id = connection->intf_cport_id;
301         int ret;
302
303         if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_CONNECTED)
304                 return 0;
305
306         control = connection->bundle->intf->control;
307
308         ret = gb_control_connected_operation(control, cport_id);
309         if (ret) {
310                 dev_err(&connection->bundle->dev,
311                         "failed to connect cport: %d\n", ret);
312                 return ret;
313         }
314
315         return 0;
316 }
317
318 /* Inform Interface about inactive CPorts */
319 static void
320 gb_connection_control_disconnected(struct gb_connection *connection)
321 {
322         struct gb_protocol *protocol = connection->protocol;
323         struct gb_control *control;
324         u16 cport_id = connection->intf_cport_id;
325         int ret;
326
327         if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_DISCONNECTED)
328                 return;
329
330         control = connection->bundle->intf->control;
331
332         ret = gb_control_disconnected_operation(control, cport_id);
333         if (ret) {
334                 dev_warn(&connection->bundle->dev,
335                          "failed to disconnect cport: %d\n", ret);
336         }
337 }
338
339 /*
340  * Request protocol version supported by the module. We don't need to do
341  * this for SVC as that is initiated by the SVC.
342  */
343 static int gb_connection_protocol_get_version(struct gb_connection *connection)
344 {
345         struct gb_protocol *protocol = connection->protocol;
346         int ret;
347
348         if (protocol->flags & GB_PROTOCOL_SKIP_VERSION)
349                 return 0;
350
351         ret = gb_protocol_get_version(connection);
352         if (ret) {
353                 dev_err(&connection->hd->dev,
354                         "%s: failed to get protocol version: %d\n",
355                         connection->name, ret);
356                 return ret;
357         }
358
359         return 0;
360 }
361
362 /*
363  * Cancel all active operations on a connection.
364  *
365  * Locking: Called with connection lock held and state set to DISABLED.
366  */
367 static void gb_connection_cancel_operations(struct gb_connection *connection,
368                                                 int errno)
369 {
370         struct gb_operation *operation;
371
372         while (!list_empty(&connection->operations)) {
373                 operation = list_last_entry(&connection->operations,
374                                                 struct gb_operation, links);
375                 gb_operation_get(operation);
376                 spin_unlock_irq(&connection->lock);
377
378                 if (gb_operation_is_incoming(operation))
379                         gb_operation_cancel_incoming(operation, errno);
380                 else
381                         gb_operation_cancel(operation, errno);
382
383                 gb_operation_put(operation);
384
385                 spin_lock_irq(&connection->lock);
386         }
387 }
388
389 /*
390  * Cancel all active incoming operations on a connection.
391  *
392  * Locking: Called with connection lock held and state set to ENABLED_TX.
393  */
394 static void
395 gb_connection_flush_incoming_operations(struct gb_connection *connection,
396                                                 int errno)
397 {
398         struct gb_operation *operation;
399         bool incoming;
400
401         while (!list_empty(&connection->operations)) {
402                 incoming = false;
403                 list_for_each_entry(operation, &connection->operations,
404                                                                 links) {
405                         if (gb_operation_is_incoming(operation)) {
406                                 gb_operation_get(operation);
407                                 incoming = true;
408                                 break;
409                         }
410                 }
411
412                 if (!incoming)
413                         break;
414
415                 spin_unlock_irq(&connection->lock);
416
417                 /* FIXME: flush, not cancel? */
418                 gb_operation_cancel_incoming(operation, errno);
419                 gb_operation_put(operation);
420
421                 spin_lock_irq(&connection->lock);
422         }
423 }
424
425 int gb_connection_enable(struct gb_connection *connection,
426                                 gb_request_handler_t handler)
427 {
428         int ret;
429
430         mutex_lock(&connection->mutex);
431
432         if (connection->state == GB_CONNECTION_STATE_ENABLED)
433                 goto out_unlock;
434
435         if (connection->state == GB_CONNECTION_STATE_ENABLED_TX) {
436                 if (!handler)
437                         goto out_unlock;
438
439                 spin_lock_irq(&connection->lock);
440                 connection->handler = handler;
441                 connection->state = GB_CONNECTION_STATE_ENABLED;
442                 spin_unlock_irq(&connection->lock);
443
444                 goto out_unlock;
445         }
446
447         ret = gb_connection_hd_cport_enable(connection);
448         if (ret)
449                 goto err_unlock;
450
451         ret = gb_connection_svc_connection_create(connection);
452         if (ret)
453                 goto err_hd_cport_disable;
454
455         spin_lock_irq(&connection->lock);
456         connection->handler = handler;
457         if (handler)
458                 connection->state = GB_CONNECTION_STATE_ENABLED;
459         else
460                 connection->state = GB_CONNECTION_STATE_ENABLED_TX;
461         spin_unlock_irq(&connection->lock);
462
463         ret = gb_connection_control_connected(connection);
464         if (ret)
465                 goto err_svc_destroy;
466
467 out_unlock:
468         mutex_unlock(&connection->mutex);
469
470         return 0;
471
472 err_svc_destroy:
473         spin_lock_irq(&connection->lock);
474         connection->state = GB_CONNECTION_STATE_DISABLED;
475         gb_connection_cancel_operations(connection, -ESHUTDOWN);
476         connection->handler = NULL;
477         spin_unlock_irq(&connection->lock);
478
479         gb_connection_svc_connection_destroy(connection);
480 err_hd_cport_disable:
481         gb_connection_hd_cport_disable(connection);
482 err_unlock:
483         mutex_unlock(&connection->mutex);
484
485         return ret;
486 }
487 EXPORT_SYMBOL_GPL(gb_connection_enable);
488
489 void gb_connection_disable_rx(struct gb_connection *connection)
490 {
491         mutex_lock(&connection->mutex);
492
493         spin_lock_irq(&connection->lock);
494         if (connection->state != GB_CONNECTION_STATE_ENABLED) {
495                 spin_unlock_irq(&connection->lock);
496                 goto out_unlock;
497         }
498         connection->state = GB_CONNECTION_STATE_ENABLED_TX;
499         gb_connection_flush_incoming_operations(connection, -ESHUTDOWN);
500         connection->handler = NULL;
501         spin_unlock_irq(&connection->lock);
502
503 out_unlock:
504         mutex_unlock(&connection->mutex);
505 }
506
507 void gb_connection_disable(struct gb_connection *connection)
508 {
509         mutex_lock(&connection->mutex);
510
511         if (connection->state == GB_CONNECTION_STATE_DISABLED)
512                 goto out_unlock;
513
514         gb_connection_control_disconnected(connection);
515
516         spin_lock_irq(&connection->lock);
517         connection->state = GB_CONNECTION_STATE_DISABLED;
518         gb_connection_cancel_operations(connection, -ESHUTDOWN);
519         connection->handler = NULL;
520         spin_unlock_irq(&connection->lock);
521
522         gb_connection_svc_connection_destroy(connection);
523         gb_connection_hd_cport_disable(connection);
524
525 out_unlock:
526         mutex_unlock(&connection->mutex);
527 }
528 EXPORT_SYMBOL_GPL(gb_connection_disable);
529
530 static int gb_legacy_request_handler(struct gb_operation *operation)
531 {
532         struct gb_protocol *protocol = operation->connection->protocol;
533
534         return protocol->request_recv(operation->type, operation);
535 }
536
537 int gb_connection_legacy_init(struct gb_connection *connection)
538 {
539         gb_request_handler_t handler;
540         int ret;
541
542         ret = gb_connection_bind_protocol(connection);
543         if (ret)
544                 return ret;
545
546         if (connection->protocol->request_recv)
547                 handler = gb_legacy_request_handler;
548         else
549                 handler = NULL;
550
551         ret = gb_connection_enable(connection, handler);
552         if (ret)
553                 goto err_unbind_protocol;
554
555         ret = gb_connection_protocol_get_version(connection);
556         if (ret)
557                 goto err_disable;
558
559         ret = connection->protocol->connection_init(connection);
560         if (ret)
561                 goto err_disable;
562
563         return 0;
564
565 err_disable:
566         gb_connection_disable(connection);
567 err_unbind_protocol:
568         gb_connection_unbind_protocol(connection);
569
570         return ret;
571 }
572 EXPORT_SYMBOL_GPL(gb_connection_legacy_init);
573
574 void gb_connection_legacy_exit(struct gb_connection *connection)
575 {
576         if (connection->state == GB_CONNECTION_STATE_DISABLED)
577                 return;
578
579         gb_connection_disable(connection);
580
581         connection->protocol->connection_exit(connection);
582
583         gb_connection_unbind_protocol(connection);
584 }
585 EXPORT_SYMBOL_GPL(gb_connection_legacy_exit);
586
587 /*
588  * Tear down a previously set up connection.
589  */
590 void gb_connection_destroy(struct gb_connection *connection)
591 {
592         struct ida *id_map;
593
594         if (WARN_ON(!connection))
595                 return;
596
597         spin_lock_irq(&gb_connections_lock);
598         list_del(&connection->bundle_links);
599         list_del(&connection->hd_links);
600         spin_unlock_irq(&gb_connections_lock);
601
602         id_map = &connection->hd->cport_id_map;
603         ida_simple_remove(id_map, connection->hd_cport_id);
604         connection->hd_cport_id = CPORT_ID_BAD;
605
606         kref_put_mutex(&connection->kref, gb_connection_kref_release,
607                        &connection_mutex);
608 }
609
610 void gb_connection_latency_tag_enable(struct gb_connection *connection)
611 {
612         struct gb_host_device *hd = connection->hd;
613         int ret;
614
615         if (!hd->driver->latency_tag_enable)
616                 return;
617
618         ret = hd->driver->latency_tag_enable(hd, connection->hd_cport_id);
619         if (ret) {
620                 dev_err(&connection->hd->dev,
621                         "%s: failed to enable latency tag: %d\n",
622                         connection->name, ret);
623         }
624 }
625 EXPORT_SYMBOL_GPL(gb_connection_latency_tag_enable);
626
627 void gb_connection_latency_tag_disable(struct gb_connection *connection)
628 {
629         struct gb_host_device *hd = connection->hd;
630         int ret;
631
632         if (!hd->driver->latency_tag_disable)
633                 return;
634
635         ret = hd->driver->latency_tag_disable(hd, connection->hd_cport_id);
636         if (ret) {
637                 dev_err(&connection->hd->dev,
638                         "%s: failed to disable latency tag: %d\n",
639                         connection->name, ret);
640         }
641 }
642 EXPORT_SYMBOL_GPL(gb_connection_latency_tag_disable);
643
644 static int gb_connection_bind_protocol(struct gb_connection *connection)
645 {
646         struct gb_protocol *protocol;
647
648         protocol = gb_protocol_get(connection->protocol_id,
649                                    connection->major,
650                                    connection->minor);
651         if (!protocol) {
652                 dev_err(&connection->hd->dev,
653                                 "protocol 0x%02x version %u.%u not found\n",
654                                 connection->protocol_id,
655                                 connection->major, connection->minor);
656                 return -EPROTONOSUPPORT;
657         }
658         connection->protocol = protocol;
659
660         return 0;
661 }
662
663 static void gb_connection_unbind_protocol(struct gb_connection *connection)
664 {
665         struct gb_protocol *protocol = connection->protocol;
666
667         gb_protocol_put(protocol);
668
669         connection->protocol = NULL;
670 }