greybus: connection: destroy connection on failing to bind it
[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         retval = gb_connection_bind_protocol(connection);
243         if (retval) {
244                 dev_err(&connection->dev, "failed to bind protocol: %d\n",
245                         retval);
246                 gb_connection_destroy(connection);
247                 return NULL;
248         }
249
250         if (!connection->protocol)
251                 dev_warn(&connection->dev,
252                          "protocol 0x%02hhx handler not found\n", protocol_id);
253
254         return connection;
255
256 err_free_connection:
257         kfree(connection);
258 err_remove_ida:
259         ida_simple_remove(id_map, hd_cport_id);
260
261         return NULL;
262 }
263
264 static int gb_connection_hd_cport_enable(struct gb_connection *connection)
265 {
266         struct greybus_host_device *hd = connection->hd;
267         int ret;
268
269         if (!hd->driver->cport_enable)
270                 return 0;
271
272         ret = hd->driver->cport_enable(hd, connection->hd_cport_id);
273         if (ret) {
274                 dev_err(&connection->dev,
275                                 "failed to enable host cport: %d\n", ret);
276                 return ret;
277         }
278
279         return 0;
280 }
281
282 static void gb_connection_hd_cport_disable(struct gb_connection *connection)
283 {
284         struct greybus_host_device *hd = connection->hd;
285
286         if (!hd->driver->cport_disable)
287                 return;
288
289         hd->driver->cport_disable(hd, connection->hd_cport_id);
290 }
291
292 struct gb_connection *gb_connection_create(struct gb_bundle *bundle,
293                                 u16 cport_id, u8 protocol_id)
294 {
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);
298 }
299
300 /*
301  * Cancel all active operations on a connection.
302  *
303  * Should only be called during connection tear down.
304  */
305 static void gb_connection_cancel_operations(struct gb_connection *connection,
306                                                 int errno)
307 {
308         struct gb_operation *operation;
309
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);
316
317                 if (gb_operation_is_incoming(operation))
318                         gb_operation_cancel_incoming(operation, errno);
319                 else
320                         gb_operation_cancel(operation, errno);
321
322                 gb_operation_put(operation);
323
324                 spin_lock_irq(&connection->lock);
325         }
326         spin_unlock_irq(&connection->lock);
327 }
328
329 /*
330  * Request the SVC to create a connection from AP's cport to interface's
331  * cport.
332  */
333 static int
334 gb_connection_svc_connection_create(struct gb_connection *connection)
335 {
336         struct greybus_host_device *hd = connection->hd;
337         struct gb_protocol *protocol = connection->protocol;
338         struct gb_interface *intf;
339         int ret;
340
341         if (protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
342                 return 0;
343
344         intf = connection->bundle->intf;
345         ret = gb_svc_connection_create(hd->svc,
346                         hd->endo->ap_intf_id,
347                         connection->hd_cport_id,
348                         intf->interface_id,
349                         connection->intf_cport_id,
350                         intf->boot_over_unipro);
351         if (ret) {
352                 dev_err(&connection->dev,
353                                 "failed to create svc connection: %d\n", ret);
354                 return ret;
355         }
356
357         return 0;
358 }
359
360 static void
361 gb_connection_svc_connection_destroy(struct gb_connection *connection)
362 {
363         if (connection->protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
364                 return;
365
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);
371 }
372
373 /* Inform Interface about active CPorts */
374 static int gb_connection_control_connected(struct gb_connection *connection)
375 {
376         struct gb_protocol *protocol = connection->protocol;
377         struct gb_control *control;
378         u16 cport_id = connection->intf_cport_id;
379         int ret;
380
381         if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_CONNECTED)
382                 return 0;
383
384         control = connection->bundle->intf->control;
385
386         ret = gb_control_connected_operation(control, cport_id);
387         if (ret) {
388                 dev_err(&connection->dev,
389                                 "failed to connect cport: %d\n", ret);
390                 return ret;
391         }
392
393         return 0;
394 }
395
396 /* Inform Interface about inactive CPorts */
397 static void
398 gb_connection_control_disconnected(struct gb_connection *connection)
399 {
400         struct gb_protocol *protocol = connection->protocol;
401         struct gb_control *control;
402         u16 cport_id = connection->intf_cport_id;
403         int ret;
404
405         if (protocol->flags & GB_PROTOCOL_SKIP_CONTROL_DISCONNECTED)
406                 return;
407
408         control = connection->bundle->intf->control;
409
410         ret = gb_control_disconnected_operation(control, cport_id);
411         if (ret) {
412                 dev_warn(&connection->dev,
413                                 "failed to disconnect cport: %d\n", ret);
414         }
415 }
416
417 /*
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.
420  */
421 static int gb_connection_protocol_get_version(struct gb_connection *connection)
422 {
423         struct gb_protocol *protocol = connection->protocol;
424         int ret;
425
426         if (protocol->flags & GB_PROTOCOL_SKIP_VERSION)
427                 return 0;
428
429         ret = gb_protocol_get_version(connection);
430         if (ret) {
431                 dev_err(&connection->dev,
432                                 "failed to get protocol version: %d\n", ret);
433                 return ret;
434         }
435
436         return 0;
437 }
438
439 static int gb_connection_init(struct gb_connection *connection)
440 {
441         struct gb_protocol *protocol = connection->protocol;
442         int ret;
443
444         ret = gb_connection_hd_cport_enable(connection);
445         if (ret)
446                 return ret;
447
448         ret = gb_connection_svc_connection_create(connection);
449         if (ret)
450                 goto err_hd_cport_disable;
451
452         ret = gb_connection_control_connected(connection);
453         if (ret)
454                 goto err_svc_destroy;
455
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);
460
461         ret = gb_connection_protocol_get_version(connection);
462         if (ret)
463                 goto err_disconnect;
464
465         ret = protocol->connection_init(connection);
466         if (ret)
467                 goto err_disconnect;
468
469         return 0;
470
471 err_disconnect:
472         spin_lock_irq(&connection->lock);
473         connection->state = GB_CONNECTION_STATE_ERROR;
474         spin_unlock_irq(&connection->lock);
475
476         gb_connection_control_disconnected(connection);
477 err_svc_destroy:
478         gb_connection_svc_connection_destroy(connection);
479 err_hd_cport_disable:
480         gb_connection_hd_cport_disable(connection);
481
482         return ret;
483 }
484
485 static void gb_connection_exit(struct gb_connection *connection)
486 {
487         if (!connection->protocol)
488                 return;
489
490         spin_lock_irq(&connection->lock);
491         if (connection->state != GB_CONNECTION_STATE_ENABLED) {
492                 spin_unlock_irq(&connection->lock);
493                 return;
494         }
495         connection->state = GB_CONNECTION_STATE_DESTROYING;
496         spin_unlock_irq(&connection->lock);
497
498         gb_connection_cancel_operations(connection, -ESHUTDOWN);
499
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);
504 }
505
506 /*
507  * Tear down a previously set up connection.
508  */
509 void gb_connection_destroy(struct gb_connection *connection)
510 {
511         struct ida *id_map;
512
513         if (WARN_ON(!connection))
514                 return;
515
516         gb_connection_exit(connection);
517
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);
522
523         if (connection->protocol)
524                 gb_protocol_put(connection->protocol);
525         connection->protocol = NULL;
526
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;
530
531         device_unregister(&connection->dev);
532 }
533
534 void gb_hd_connections_exit(struct greybus_host_device *hd)
535 {
536         struct gb_connection *connection;
537
538         list_for_each_entry(connection, &hd->connections, hd_links)
539                 gb_connection_destroy(connection);
540 }
541
542 int gb_connection_bind_protocol(struct gb_connection *connection)
543 {
544         struct gb_protocol *protocol;
545         int ret;
546
547         /* If we already have a protocol bound here, just return */
548         if (connection->protocol)
549                 return 0;
550
551         protocol = gb_protocol_get(connection->protocol_id,
552                                    connection->major,
553                                    connection->minor);
554         if (!protocol)
555                 return 0;
556         connection->protocol = protocol;
557
558         /*
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.
561          */
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);
566                 if (ret) {
567                         gb_protocol_put(protocol);
568                         connection->protocol = NULL;
569                         return ret;
570                 }
571         }
572
573         return 0;
574 }