hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/sound/firewire/cmp.c
....@@ -1,8 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Connection Management Procedures (IEC 61883-1) helper functions
34 *
45 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5
- * Licensed under the terms of the GNU General Public License, version 2.
66 */
77
88 #include <linux/device.h>
....@@ -185,6 +185,37 @@
185185 }
186186 EXPORT_SYMBOL(cmp_connection_destroy);
187187
188
+int cmp_connection_reserve(struct cmp_connection *c,
189
+ unsigned int max_payload_bytes)
190
+{
191
+ int err;
192
+
193
+ mutex_lock(&c->mutex);
194
+
195
+ if (WARN_ON(c->resources.allocated)) {
196
+ err = -EBUSY;
197
+ goto end;
198
+ }
199
+
200
+ c->speed = min(c->max_speed,
201
+ fw_parent_device(c->resources.unit)->max_speed);
202
+
203
+ err = fw_iso_resources_allocate(&c->resources, max_payload_bytes,
204
+ c->speed);
205
+end:
206
+ mutex_unlock(&c->mutex);
207
+
208
+ return err;
209
+}
210
+EXPORT_SYMBOL(cmp_connection_reserve);
211
+
212
+void cmp_connection_release(struct cmp_connection *c)
213
+{
214
+ mutex_lock(&c->mutex);
215
+ fw_iso_resources_free(&c->resources);
216
+ mutex_unlock(&c->mutex);
217
+}
218
+EXPORT_SYMBOL(cmp_connection_release);
188219
189220 static __be32 ipcr_set_modify(struct cmp_connection *c, __be32 ipcr)
190221 {
....@@ -262,7 +293,6 @@
262293 /**
263294 * cmp_connection_establish - establish a connection to the target
264295 * @c: the connection manager
265
- * @max_payload_bytes: the amount of data (including CIP headers) per packet
266296 *
267297 * This function establishes a point-to-point connection from the local
268298 * computer to the target by allocating isochronous resources (channel and
....@@ -270,25 +300,18 @@
270300 * When this function succeeds, the caller is responsible for starting
271301 * transmitting packets.
272302 */
273
-int cmp_connection_establish(struct cmp_connection *c,
274
- unsigned int max_payload_bytes)
303
+int cmp_connection_establish(struct cmp_connection *c)
275304 {
276305 int err;
277306
278
- if (WARN_ON(c->connected))
279
- return -EISCONN;
280
-
281
- c->speed = min(c->max_speed,
282
- fw_parent_device(c->resources.unit)->max_speed);
283
-
284307 mutex_lock(&c->mutex);
285308
286
-retry_after_bus_reset:
287
- err = fw_iso_resources_allocate(&c->resources,
288
- max_payload_bytes, c->speed);
289
- if (err < 0)
290
- goto err_mutex;
309
+ if (WARN_ON(c->connected)) {
310
+ mutex_unlock(&c->mutex);
311
+ return -EISCONN;
312
+ }
291313
314
+retry_after_bus_reset:
292315 if (c->direction == CMP_OUTPUT)
293316 err = pcr_modify(c, opcr_set_modify, pcr_set_check,
294317 ABORT_ON_BUS_RESET);
....@@ -297,21 +320,13 @@
297320 ABORT_ON_BUS_RESET);
298321
299322 if (err == -EAGAIN) {
300
- fw_iso_resources_free(&c->resources);
301
- goto retry_after_bus_reset;
323
+ err = fw_iso_resources_update(&c->resources);
324
+ if (err >= 0)
325
+ goto retry_after_bus_reset;
302326 }
303
- if (err < 0)
304
- goto err_resources;
327
+ if (err >= 0)
328
+ c->connected = true;
305329
306
- c->connected = true;
307
-
308
- mutex_unlock(&c->mutex);
309
-
310
- return 0;
311
-
312
-err_resources:
313
- fw_iso_resources_free(&c->resources);
314
-err_mutex:
315330 mutex_unlock(&c->mutex);
316331
317332 return err;
....@@ -351,14 +366,12 @@
351366 SUCCEED_ON_BUS_RESET);
352367
353368 if (err < 0)
354
- goto err_resources;
369
+ goto err_unconnect;
355370
356371 mutex_unlock(&c->mutex);
357372
358373 return 0;
359374
360
-err_resources:
361
- fw_iso_resources_free(&c->resources);
362375 err_unconnect:
363376 c->connected = false;
364377 mutex_unlock(&c->mutex);
....@@ -394,8 +407,6 @@
394407 err = pcr_modify(c, pcr_break_modify, NULL, SUCCEED_ON_BUS_RESET);
395408 if (err < 0)
396409 cmp_error(c, "plug is still connected\n");
397
-
398
- fw_iso_resources_free(&c->resources);
399410
400411 c->connected = false;
401412