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