Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Greybus connections
  4 *
  5 * Copyright 2014 Google Inc.
  6 * Copyright 2014 Linaro Ltd.
  7 */
  8
  9#include <linux/workqueue.h>
 10#include <linux/greybus.h>
 11
 12#include "greybus_trace.h"
 13
 14#define GB_CONNECTION_CPORT_QUIESCE_TIMEOUT	1000
 15
 16static void gb_connection_kref_release(struct kref *kref);
 17
 18static DEFINE_SPINLOCK(gb_connections_lock);
 19static DEFINE_MUTEX(gb_connection_mutex);
 20
 21/* Caller holds gb_connection_mutex. */
 22static bool gb_connection_cport_in_use(struct gb_interface *intf, u16 cport_id)
 23{
 24	struct gb_host_device *hd = intf->hd;
 25	struct gb_connection *connection;
 26
 27	list_for_each_entry(connection, &hd->connections, hd_links) {
 28		if (connection->intf == intf &&
 29		    connection->intf_cport_id == cport_id)
 30			return true;
 31	}
 32
 33	return false;
 34}
 35
 36static void gb_connection_get(struct gb_connection *connection)
 37{
 38	kref_get(&connection->kref);
 39
 40	trace_gb_connection_get(connection);
 41}
 42
 43static void gb_connection_put(struct gb_connection *connection)
 44{
 45	trace_gb_connection_put(connection);
 46
 47	kref_put(&connection->kref, gb_connection_kref_release);
 48}
 49
 50/*
 51 * Returns a reference-counted pointer to the connection if found.
 52 */
 53static struct gb_connection *
 54gb_connection_hd_find(struct gb_host_device *hd, u16 cport_id)
 55{
 56	struct gb_connection *connection;
 57	unsigned long flags;
 58
 59	spin_lock_irqsave(&gb_connections_lock, flags);
 60	list_for_each_entry(connection, &hd->connections, hd_links)
 61		if (connection->hd_cport_id == cport_id) {
 62			gb_connection_get(connection);
 63			goto found;
 64		}
 65	connection = NULL;
 66found:
 67	spin_unlock_irqrestore(&gb_connections_lock, flags);
 68
 69	return connection;
 70}
 71
 72/*
 73 * Callback from the host driver to let us know that data has been
 74 * received on the bundle.
 75 */
 76void greybus_data_rcvd(struct gb_host_device *hd, u16 cport_id,
 77		       u8 *data, size_t length)
 78{
 79	struct gb_connection *connection;
 80
 81	trace_gb_hd_in(hd);
 82
 83	connection = gb_connection_hd_find(hd, cport_id);
 84	if (!connection) {
 85		dev_err(&hd->dev,
 86			"nonexistent connection (%zu bytes dropped)\n", length);
 87		return;
 88	}
 89	gb_connection_recv(connection, data, length);
 90	gb_connection_put(connection);
 91}
 92EXPORT_SYMBOL_GPL(greybus_data_rcvd);
 93
 94static void gb_connection_kref_release(struct kref *kref)
 95{
 96	struct gb_connection *connection;
 97
 98	connection = container_of(kref, struct gb_connection, kref);
 99
100	trace_gb_connection_release(connection);
101
102	kfree(connection);
103}
104
105static void gb_connection_init_name(struct gb_connection *connection)
106{
107	u16 hd_cport_id = connection->hd_cport_id;
108	u16 cport_id = 0;
109	u8 intf_id = 0;
110
111	if (connection->intf) {
112		intf_id = connection->intf->interface_id;
113		cport_id = connection->intf_cport_id;
114	}
115
116	snprintf(connection->name, sizeof(connection->name),
117		 "%u/%u:%u", hd_cport_id, intf_id, cport_id);
118}
119
120/*
121 * _gb_connection_create() - create a Greybus connection
122 * @hd:			host device of the connection
123 * @hd_cport_id:	host-device cport id, or -1 for dynamic allocation
124 * @intf:		remote interface, or NULL for static connections
125 * @bundle:		remote-interface bundle (may be NULL)
126 * @cport_id:		remote-interface cport id, or 0 for static connections
127 * @handler:		request handler (may be NULL)
128 * @flags:		connection flags
129 *
130 * Create a Greybus connection, representing the bidirectional link
131 * between a CPort on a (local) Greybus host device and a CPort on
132 * another Greybus interface.
133 *
134 * A connection also maintains the state of operations sent over the
135 * connection.
136 *
137 * Serialised against concurrent create and destroy using the
138 * gb_connection_mutex.
139 *
140 * Return: A pointer to the new connection if successful, or an ERR_PTR
141 * otherwise.
142 */
143static struct gb_connection *
144_gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
145		      struct gb_interface *intf,
146		      struct gb_bundle *bundle, int cport_id,
147		      gb_request_handler_t handler,
148		      unsigned long flags)
149{
150	struct gb_connection *connection;
151	int ret;
152
153	mutex_lock(&gb_connection_mutex);
154
155	if (intf && gb_connection_cport_in_use(intf, cport_id)) {
156		dev_err(&intf->dev, "cport %u already in use\n", cport_id);
157		ret = -EBUSY;
158		goto err_unlock;
159	}
160
161	ret = gb_hd_cport_allocate(hd, hd_cport_id, flags);
162	if (ret < 0) {
163		dev_err(&hd->dev, "failed to allocate cport: %d\n", ret);
164		goto err_unlock;
165	}
166	hd_cport_id = ret;
167
168	connection = kzalloc(sizeof(*connection), GFP_KERNEL);
169	if (!connection) {
170		ret = -ENOMEM;
171		goto err_hd_cport_release;
172	}
173
174	connection->hd_cport_id = hd_cport_id;
175	connection->intf_cport_id = cport_id;
176	connection->hd = hd;
177	connection->intf = intf;
178	connection->bundle = bundle;
179	connection->handler = handler;
180	connection->flags = flags;
181	if (intf && (intf->quirks & GB_INTERFACE_QUIRK_NO_CPORT_FEATURES))
182		connection->flags |= GB_CONNECTION_FLAG_NO_FLOWCTRL;
183	connection->state = GB_CONNECTION_STATE_DISABLED;
184
185	atomic_set(&connection->op_cycle, 0);
186	mutex_init(&connection->mutex);
187	spin_lock_init(&connection->lock);
188	INIT_LIST_HEAD(&connection->operations);
189
190	connection->wq = alloc_workqueue("%s:%d", WQ_UNBOUND, 1,
191					 dev_name(&hd->dev), hd_cport_id);
192	if (!connection->wq) {
193		ret = -ENOMEM;
194		goto err_free_connection;
195	}
196
197	kref_init(&connection->kref);
198
199	gb_connection_init_name(connection);
200
201	spin_lock_irq(&gb_connections_lock);
202	list_add(&connection->hd_links, &hd->connections);
203
204	if (bundle)
205		list_add(&connection->bundle_links, &bundle->connections);
206	else
207		INIT_LIST_HEAD(&connection->bundle_links);
208
209	spin_unlock_irq(&gb_connections_lock);
210
211	mutex_unlock(&gb_connection_mutex);
212
213	trace_gb_connection_create(connection);
214
215	return connection;
216
217err_free_connection:
218	kfree(connection);
219err_hd_cport_release:
220	gb_hd_cport_release(hd, hd_cport_id);
221err_unlock:
222	mutex_unlock(&gb_connection_mutex);
223
224	return ERR_PTR(ret);
225}
226
227struct gb_connection *
228gb_connection_create_static(struct gb_host_device *hd, u16 hd_cport_id,
229			    gb_request_handler_t handler)
230{
231	return _gb_connection_create(hd, hd_cport_id, NULL, NULL, 0, handler,
232				     GB_CONNECTION_FLAG_HIGH_PRIO);
233}
234
235struct gb_connection *
236gb_connection_create_control(struct gb_interface *intf)
237{
238	return _gb_connection_create(intf->hd, -1, intf, NULL, 0, NULL,
239				     GB_CONNECTION_FLAG_CONTROL |
240				     GB_CONNECTION_FLAG_HIGH_PRIO);
241}
242
243struct gb_connection *
244gb_connection_create(struct gb_bundle *bundle, u16 cport_id,
245		     gb_request_handler_t handler)
246{
247	struct gb_interface *intf = bundle->intf;
248
249	return _gb_connection_create(intf->hd, -1, intf, bundle, cport_id,
250				     handler, 0);
251}
252EXPORT_SYMBOL_GPL(gb_connection_create);
253
254struct gb_connection *
255gb_connection_create_flags(struct gb_bundle *bundle, u16 cport_id,
256			   gb_request_handler_t handler,
257			   unsigned long flags)
258{
259	struct gb_interface *intf = bundle->intf;
260
261	if (WARN_ON_ONCE(flags & GB_CONNECTION_FLAG_CORE_MASK))
262		flags &= ~GB_CONNECTION_FLAG_CORE_MASK;
263
264	return _gb_connection_create(intf->hd, -1, intf, bundle, cport_id,
265				     handler, flags);
266}
267EXPORT_SYMBOL_GPL(gb_connection_create_flags);
268
269struct gb_connection *
270gb_connection_create_offloaded(struct gb_bundle *bundle, u16 cport_id,
271			       unsigned long flags)
272{
273	flags |= GB_CONNECTION_FLAG_OFFLOADED;
274
275	return gb_connection_create_flags(bundle, cport_id, NULL, flags);
276}
277EXPORT_SYMBOL_GPL(gb_connection_create_offloaded);
278
279static int gb_connection_hd_cport_enable(struct gb_connection *connection)
280{
281	struct gb_host_device *hd = connection->hd;
282	int ret;
283
284	if (!hd->driver->cport_enable)
285		return 0;
286
287	ret = hd->driver->cport_enable(hd, connection->hd_cport_id,
288				       connection->flags);
289	if (ret) {
290		dev_err(&hd->dev, "%s: failed to enable host cport: %d\n",
291			connection->name, ret);
292		return ret;
293	}
294
295	return 0;
296}
297
298static void gb_connection_hd_cport_disable(struct gb_connection *connection)
299{
300	struct gb_host_device *hd = connection->hd;
301	int ret;
302
303	if (!hd->driver->cport_disable)
304		return;
305
306	ret = hd->driver->cport_disable(hd, connection->hd_cport_id);
307	if (ret) {
308		dev_err(&hd->dev, "%s: failed to disable host cport: %d\n",
309			connection->name, ret);
310	}
311}
312
313static int gb_connection_hd_cport_connected(struct gb_connection *connection)
314{
315	struct gb_host_device *hd = connection->hd;
316	int ret;
317
318	if (!hd->driver->cport_connected)
319		return 0;
320
321	ret = hd->driver->cport_connected(hd, connection->hd_cport_id);
322	if (ret) {
323		dev_err(&hd->dev, "%s: failed to set connected state: %d\n",
324			connection->name, ret);
325		return ret;
326	}
327
328	return 0;
329}
330
331static int gb_connection_hd_cport_flush(struct gb_connection *connection)
332{
333	struct gb_host_device *hd = connection->hd;
334	int ret;
335
336	if (!hd->driver->cport_flush)
337		return 0;
338
339	ret = hd->driver->cport_flush(hd, connection->hd_cport_id);
340	if (ret) {
341		dev_err(&hd->dev, "%s: failed to flush host cport: %d\n",
342			connection->name, ret);
343		return ret;
344	}
345
346	return 0;
347}
348
349static int gb_connection_hd_cport_quiesce(struct gb_connection *connection)
350{
351	struct gb_host_device *hd = connection->hd;
352	size_t peer_space;
353	int ret;
354
355	if (!hd->driver->cport_quiesce)
356		return 0;
357
358	peer_space = sizeof(struct gb_operation_msg_hdr) +
359			sizeof(struct gb_cport_shutdown_request);
360
361	if (connection->mode_switch)
362		peer_space += sizeof(struct gb_operation_msg_hdr);
363
364	if (!hd->driver->cport_quiesce)
365		return 0;
366
367	ret = hd->driver->cport_quiesce(hd, connection->hd_cport_id,
368					peer_space,
369					GB_CONNECTION_CPORT_QUIESCE_TIMEOUT);
370	if (ret) {
371		dev_err(&hd->dev, "%s: failed to quiesce host cport: %d\n",
372			connection->name, ret);
373		return ret;
374	}
375
376	return 0;
377}
378
379static int gb_connection_hd_cport_clear(struct gb_connection *connection)
380{
381	struct gb_host_device *hd = connection->hd;
382	int ret;
383
384	if (!hd->driver->cport_clear)
385		return 0;
386
387	ret = hd->driver->cport_clear(hd, connection->hd_cport_id);
388	if (ret) {
389		dev_err(&hd->dev, "%s: failed to clear host cport: %d\n",
390			connection->name, ret);
391		return ret;
392	}
393
394	return 0;
395}
396
397/*
398 * Request the SVC to create a connection from AP's cport to interface's
399 * cport.
400 */
401static int
402gb_connection_svc_connection_create(struct gb_connection *connection)
403{
404	struct gb_host_device *hd = connection->hd;
405	struct gb_interface *intf;
406	u8 cport_flags;
407	int ret;
408
409	if (gb_connection_is_static(connection))
410		return 0;
411
412	intf = connection->intf;
413
414	/*
415	 * Enable either E2EFC or CSD, unless no flow control is requested.
416	 */
417	cport_flags = GB_SVC_CPORT_FLAG_CSV_N;
418	if (gb_connection_flow_control_disabled(connection)) {
419		cport_flags |= GB_SVC_CPORT_FLAG_CSD_N;
420	} else if (gb_connection_e2efc_enabled(connection)) {
421		cport_flags |= GB_SVC_CPORT_FLAG_CSD_N |
422				GB_SVC_CPORT_FLAG_E2EFC;
423	}
424
425	ret = gb_svc_connection_create(hd->svc,
426				       hd->svc->ap_intf_id,
427				       connection->hd_cport_id,
428				       intf->interface_id,
429				       connection->intf_cport_id,
430				       cport_flags);
431	if (ret) {
432		dev_err(&connection->hd->dev,
433			"%s: failed to create svc connection: %d\n",
434			connection->name, ret);
435		return ret;
436	}
437
438	return 0;
439}
440
441static void
442gb_connection_svc_connection_destroy(struct gb_connection *connection)
443{
444	if (gb_connection_is_static(connection))
445		return;
446
447	gb_svc_connection_destroy(connection->hd->svc,
448				  connection->hd->svc->ap_intf_id,
449				  connection->hd_cport_id,
450				  connection->intf->interface_id,
451				  connection->intf_cport_id);
452}
453
454/* Inform Interface about active CPorts */
455static int gb_connection_control_connected(struct gb_connection *connection)
456{
457	struct gb_control *control;
458	u16 cport_id = connection->intf_cport_id;
459	int ret;
460
461	if (gb_connection_is_static(connection))
462		return 0;
463
464	if (gb_connection_is_control(connection))
465		return 0;
466
467	control = connection->intf->control;
468
469	ret = gb_control_connected_operation(control, cport_id);
470	if (ret) {
471		dev_err(&connection->bundle->dev,
472			"failed to connect cport: %d\n", ret);
473		return ret;
474	}
475
476	return 0;
477}
478
479static void
480gb_connection_control_disconnecting(struct gb_connection *connection)
481{
482	struct gb_control *control;
483	u16 cport_id = connection->intf_cport_id;
484	int ret;
485
486	if (gb_connection_is_static(connection))
487		return;
488
489	control = connection->intf->control;
490
491	ret = gb_control_disconnecting_operation(control, cport_id);
492	if (ret) {
493		dev_err(&connection->hd->dev,
494			"%s: failed to send disconnecting: %d\n",
495			connection->name, ret);
496	}
497}
498
499static void
500gb_connection_control_disconnected(struct gb_connection *connection)
501{
502	struct gb_control *control;
503	u16 cport_id = connection->intf_cport_id;
504	int ret;
505
506	if (gb_connection_is_static(connection))
507		return;
508
509	control = connection->intf->control;
510
511	if (gb_connection_is_control(connection)) {
512		if (connection->mode_switch) {
513			ret = gb_control_mode_switch_operation(control);
514			if (ret) {
515				/*
516				 * Allow mode switch to time out waiting for
517				 * mailbox event.
518				 */
519				return;
520			}
521		}
522
523		return;
524	}
525
526	ret = gb_control_disconnected_operation(control, cport_id);
527	if (ret) {
528		dev_warn(&connection->bundle->dev,
529			 "failed to disconnect cport: %d\n", ret);
530	}
531}
532
533static int gb_connection_shutdown_operation(struct gb_connection *connection,
534					    u8 phase)
535{
536	struct gb_cport_shutdown_request *req;
537	struct gb_operation *operation;
538	int ret;
539
540	operation = gb_operation_create_core(connection,
541					     GB_REQUEST_TYPE_CPORT_SHUTDOWN,
542					     sizeof(*req), 0, 0,
543					     GFP_KERNEL);
544	if (!operation)
545		return -ENOMEM;
546
547	req = operation->request->payload;
548	req->phase = phase;
549
550	ret = gb_operation_request_send_sync(operation);
551
552	gb_operation_put(operation);
553
554	return ret;
555}
556
557static int gb_connection_cport_shutdown(struct gb_connection *connection,
558					u8 phase)
559{
560	struct gb_host_device *hd = connection->hd;
561	const struct gb_hd_driver *drv = hd->driver;
562	int ret;
563
564	if (gb_connection_is_static(connection))
565		return 0;
566
567	if (gb_connection_is_offloaded(connection)) {
568		if (!drv->cport_shutdown)
569			return 0;
570
571		ret = drv->cport_shutdown(hd, connection->hd_cport_id, phase,
572					  GB_OPERATION_TIMEOUT_DEFAULT);
573	} else {
574		ret = gb_connection_shutdown_operation(connection, phase);
575	}
576
577	if (ret) {
578		dev_err(&hd->dev, "%s: failed to send cport shutdown (phase %d): %d\n",
579			connection->name, phase, ret);
580		return ret;
581	}
582
583	return 0;
584}
585
586static int
587gb_connection_cport_shutdown_phase_1(struct gb_connection *connection)
588{
589	return gb_connection_cport_shutdown(connection, 1);
590}
591
592static int
593gb_connection_cport_shutdown_phase_2(struct gb_connection *connection)
594{
595	return gb_connection_cport_shutdown(connection, 2);
596}
597
598/*
599 * Cancel all active operations on a connection.
600 *
601 * Locking: Called with connection lock held and state set to DISABLED or
602 * DISCONNECTING.
603 */
604static void gb_connection_cancel_operations(struct gb_connection *connection,
605					    int errno)
606	__must_hold(&connection->lock)
607{
608	struct gb_operation *operation;
609
610	while (!list_empty(&connection->operations)) {
611		operation = list_last_entry(&connection->operations,
612					    struct gb_operation, links);
613		gb_operation_get(operation);
614		spin_unlock_irq(&connection->lock);
615
616		if (gb_operation_is_incoming(operation))
617			gb_operation_cancel_incoming(operation, errno);
618		else
619			gb_operation_cancel(operation, errno);
620
621		gb_operation_put(operation);
622
623		spin_lock_irq(&connection->lock);
624	}
625}
626
627/*
628 * Cancel all active incoming operations on a connection.
629 *
630 * Locking: Called with connection lock held and state set to ENABLED_TX.
631 */
632static void
633gb_connection_flush_incoming_operations(struct gb_connection *connection,
634					int errno)
635	__must_hold(&connection->lock)
636{
637	struct gb_operation *operation;
638	bool incoming;
639
640	while (!list_empty(&connection->operations)) {
641		incoming = false;
642		list_for_each_entry(operation, &connection->operations,
643				    links) {
644			if (gb_operation_is_incoming(operation)) {
645				gb_operation_get(operation);
646				incoming = true;
647				break;
648			}
649		}
650
651		if (!incoming)
652			break;
653
654		spin_unlock_irq(&connection->lock);
655
656		/* FIXME: flush, not cancel? */
657		gb_operation_cancel_incoming(operation, errno);
658		gb_operation_put(operation);
659
660		spin_lock_irq(&connection->lock);
661	}
662}
663
664/*
665 * _gb_connection_enable() - enable a connection
666 * @connection:		connection to enable
667 * @rx:			whether to enable incoming requests
668 *
669 * Connection-enable helper for DISABLED->ENABLED, DISABLED->ENABLED_TX, and
670 * ENABLED_TX->ENABLED state transitions.
671 *
672 * Locking: Caller holds connection->mutex.
673 */
674static int _gb_connection_enable(struct gb_connection *connection, bool rx)
675{
676	int ret;
677
678	/* Handle ENABLED_TX -> ENABLED transitions. */
679	if (connection->state == GB_CONNECTION_STATE_ENABLED_TX) {
680		if (!(connection->handler && rx))
681			return 0;
682
683		spin_lock_irq(&connection->lock);
684		connection->state = GB_CONNECTION_STATE_ENABLED;
685		spin_unlock_irq(&connection->lock);
686
687		return 0;
688	}
689
690	ret = gb_connection_hd_cport_enable(connection);
691	if (ret)
692		return ret;
693
694	ret = gb_connection_svc_connection_create(connection);
695	if (ret)
696		goto err_hd_cport_clear;
697
698	ret = gb_connection_hd_cport_connected(connection);
699	if (ret)
700		goto err_svc_connection_destroy;
701
702	spin_lock_irq(&connection->lock);
703	if (connection->handler && rx)
704		connection->state = GB_CONNECTION_STATE_ENABLED;
705	else
706		connection->state = GB_CONNECTION_STATE_ENABLED_TX;
707	spin_unlock_irq(&connection->lock);
708
709	ret = gb_connection_control_connected(connection);
710	if (ret)
711		goto err_control_disconnecting;
712
713	return 0;
714
715err_control_disconnecting:
716	spin_lock_irq(&connection->lock);
717	connection->state = GB_CONNECTION_STATE_DISCONNECTING;
718	gb_connection_cancel_operations(connection, -ESHUTDOWN);
719	spin_unlock_irq(&connection->lock);
720
721	/* Transmit queue should already be empty. */
722	gb_connection_hd_cport_flush(connection);
723
724	gb_connection_control_disconnecting(connection);
725	gb_connection_cport_shutdown_phase_1(connection);
726	gb_connection_hd_cport_quiesce(connection);
727	gb_connection_cport_shutdown_phase_2(connection);
728	gb_connection_control_disconnected(connection);
729	connection->state = GB_CONNECTION_STATE_DISABLED;
730err_svc_connection_destroy:
731	gb_connection_svc_connection_destroy(connection);
732err_hd_cport_clear:
733	gb_connection_hd_cport_clear(connection);
734
735	gb_connection_hd_cport_disable(connection);
736
737	return ret;
738}
739
740int gb_connection_enable(struct gb_connection *connection)
741{
742	int ret = 0;
743
744	mutex_lock(&connection->mutex);
745
746	if (connection->state == GB_CONNECTION_STATE_ENABLED)
747		goto out_unlock;
748
749	ret = _gb_connection_enable(connection, true);
750	if (!ret)
751		trace_gb_connection_enable(connection);
752
753out_unlock:
754	mutex_unlock(&connection->mutex);
755
756	return ret;
757}
758EXPORT_SYMBOL_GPL(gb_connection_enable);
759
760int gb_connection_enable_tx(struct gb_connection *connection)
761{
762	int ret = 0;
763
764	mutex_lock(&connection->mutex);
765
766	if (connection->state == GB_CONNECTION_STATE_ENABLED) {
767		ret = -EINVAL;
768		goto out_unlock;
769	}
770
771	if (connection->state == GB_CONNECTION_STATE_ENABLED_TX)
772		goto out_unlock;
773
774	ret = _gb_connection_enable(connection, false);
775	if (!ret)
776		trace_gb_connection_enable(connection);
777
778out_unlock:
779	mutex_unlock(&connection->mutex);
780
781	return ret;
782}
783EXPORT_SYMBOL_GPL(gb_connection_enable_tx);
784
785void gb_connection_disable_rx(struct gb_connection *connection)
786{
787	mutex_lock(&connection->mutex);
788
789	spin_lock_irq(&connection->lock);
790	if (connection->state != GB_CONNECTION_STATE_ENABLED) {
791		spin_unlock_irq(&connection->lock);
792		goto out_unlock;
793	}
794	connection->state = GB_CONNECTION_STATE_ENABLED_TX;
795	gb_connection_flush_incoming_operations(connection, -ESHUTDOWN);
796	spin_unlock_irq(&connection->lock);
797
798	trace_gb_connection_disable(connection);
799
800out_unlock:
801	mutex_unlock(&connection->mutex);
802}
803EXPORT_SYMBOL_GPL(gb_connection_disable_rx);
804
805void gb_connection_mode_switch_prepare(struct gb_connection *connection)
806{
807	connection->mode_switch = true;
808}
809
810void gb_connection_mode_switch_complete(struct gb_connection *connection)
811{
812	gb_connection_svc_connection_destroy(connection);
813	gb_connection_hd_cport_clear(connection);
814
815	gb_connection_hd_cport_disable(connection);
816
817	connection->mode_switch = false;
818}
819
820void gb_connection_disable(struct gb_connection *connection)
821{
822	mutex_lock(&connection->mutex);
823
824	if (connection->state == GB_CONNECTION_STATE_DISABLED)
825		goto out_unlock;
826
827	trace_gb_connection_disable(connection);
828
829	spin_lock_irq(&connection->lock);
830	connection->state = GB_CONNECTION_STATE_DISCONNECTING;
831	gb_connection_cancel_operations(connection, -ESHUTDOWN);
832	spin_unlock_irq(&connection->lock);
833
834	gb_connection_hd_cport_flush(connection);
835
836	gb_connection_control_disconnecting(connection);
837	gb_connection_cport_shutdown_phase_1(connection);
838	gb_connection_hd_cport_quiesce(connection);
839	gb_connection_cport_shutdown_phase_2(connection);
840	gb_connection_control_disconnected(connection);
841
842	connection->state = GB_CONNECTION_STATE_DISABLED;
843
844	/* control-connection tear down is deferred when mode switching */
845	if (!connection->mode_switch) {
846		gb_connection_svc_connection_destroy(connection);
847		gb_connection_hd_cport_clear(connection);
848
849		gb_connection_hd_cport_disable(connection);
850	}
851
852out_unlock:
853	mutex_unlock(&connection->mutex);
854}
855EXPORT_SYMBOL_GPL(gb_connection_disable);
856
857/* Disable a connection without communicating with the remote end. */
858void gb_connection_disable_forced(struct gb_connection *connection)
859{
860	mutex_lock(&connection->mutex);
861
862	if (connection->state == GB_CONNECTION_STATE_DISABLED)
863		goto out_unlock;
864
865	trace_gb_connection_disable(connection);
866
867	spin_lock_irq(&connection->lock);
868	connection->state = GB_CONNECTION_STATE_DISABLED;
869	gb_connection_cancel_operations(connection, -ESHUTDOWN);
870	spin_unlock_irq(&connection->lock);
871
872	gb_connection_hd_cport_flush(connection);
873
874	gb_connection_svc_connection_destroy(connection);
875	gb_connection_hd_cport_clear(connection);
876
877	gb_connection_hd_cport_disable(connection);
878out_unlock:
879	mutex_unlock(&connection->mutex);
880}
881EXPORT_SYMBOL_GPL(gb_connection_disable_forced);
882
883/* Caller must have disabled the connection before destroying it. */
884void gb_connection_destroy(struct gb_connection *connection)
885{
886	if (!connection)
887		return;
888
889	if (WARN_ON(connection->state != GB_CONNECTION_STATE_DISABLED))
890		gb_connection_disable(connection);
891
892	mutex_lock(&gb_connection_mutex);
893
894	spin_lock_irq(&gb_connections_lock);
895	list_del(&connection->bundle_links);
896	list_del(&connection->hd_links);
897	spin_unlock_irq(&gb_connections_lock);
898
899	destroy_workqueue(connection->wq);
900
901	gb_hd_cport_release(connection->hd, connection->hd_cport_id);
902	connection->hd_cport_id = CPORT_ID_BAD;
903
904	mutex_unlock(&gb_connection_mutex);
905
906	gb_connection_put(connection);
907}
908EXPORT_SYMBOL_GPL(gb_connection_destroy);
909
910void gb_connection_latency_tag_enable(struct gb_connection *connection)
911{
912	struct gb_host_device *hd = connection->hd;
913	int ret;
914
915	if (!hd->driver->latency_tag_enable)
916		return;
917
918	ret = hd->driver->latency_tag_enable(hd, connection->hd_cport_id);
919	if (ret) {
920		dev_err(&connection->hd->dev,
921			"%s: failed to enable latency tag: %d\n",
922			connection->name, ret);
923	}
924}
925EXPORT_SYMBOL_GPL(gb_connection_latency_tag_enable);
926
927void gb_connection_latency_tag_disable(struct gb_connection *connection)
928{
929	struct gb_host_device *hd = connection->hd;
930	int ret;
931
932	if (!hd->driver->latency_tag_disable)
933		return;
934
935	ret = hd->driver->latency_tag_disable(hd, connection->hd_cport_id);
936	if (ret) {
937		dev_err(&connection->hd->dev,
938			"%s: failed to disable latency tag: %d\n",
939			connection->name, ret);
940	}
941}
942EXPORT_SYMBOL_GPL(gb_connection_latency_tag_disable);