ac9a04
Date: Thu, 15 Jan 2009 15:41:16 +0100 (CET)
ac9a04
From: Stefan Richter <stefanr@s5r6.in-berlin.de>
ac9a04
Subject: [PATCH libiec61883] cmp: replace open-coded channel allocation by
ac9a04
	raw1394_channel_modify
ac9a04
To: Dan Dennedy <dan@dennedy.org>
ac9a04
Cc: linux1394-devel@lists.sourceforge.net
ac9a04
ac9a04
On 15 Jan, Dan Dennedy wrote:
ac9a04
> On Thu, Jan 1, 2009 at 5:13 AM, Stefan Richter
ac9a04
> <stefanr@s5r6.in-berlin.de> wrote:
ac9a04
>> input plug register on the local node?  AFAICT neither dvgrab nor kino
ac9a04
>> use raw1394_channel_modify and raw1394_bandwidth_modify, not even
ac9a04
>> through libiec61883.)
ac9a04
> 
ac9a04
> dvgrab indirectly uses channel_modify when you use its -guid option to
ac9a04
> establish a point-to-point connection.
ac9a04
> 
ac9a04
ac9a04
Hmm.
ac9a04
ac9a04
$ dvgrab -guid 0x008088030960484b
ac9a04
libiec61883 error: Failed to get channels available.
ac9a04
Established connection over channel 63
ac9a04
[...proceeds with capture...]
ac9a04
ac9a04
ac9a04
--------------------------------- 8< ---------------------------------
ac9a04
ac9a04
cmp: replace open-coded channel allocation by raw1394_channel_modify
ac9a04
ac9a04
The benefit is that it works on kernel 2.6.30 firewire-core without
ac9a04
write permission to the IRM's device file (provided that libraw1394 is
ac9a04
extended for 2.6.30 ioctls too, otherwise it still needs access to the
ac9a04
IRM's file).
ac9a04
ac9a04
If I read the code correctly, iec61883_cmp_normalize_output doesn't care
ac9a04
whether the channel was already allocated by somebody else; it only
ac9a04
cares that the channel is allocated.  That's what the new code does too.
ac9a04
---
ac9a04
 src/cmp.c |   56 +++++++++---------------------------------------------
ac9a04
 1 file changed, 10 insertions(+), 46 deletions(-)
ac9a04
ac9a04
Index: libiec61883-1.2.0/src/cmp.c
ac9a04
===================================================================
ac9a04
--- libiec61883-1.2.0.orig/src/cmp.c
ac9a04
+++ libiec61883-1.2.0/src/cmp.c
ac9a04
@@ -973,55 +973,19 @@ iec61883_cmp_normalize_output (raw1394ha
ac9a04
 
ac9a04
 	DEBUG ("iec61883_cmp_normalize_output: node %d\n", (int) node & 0x3f);
ac9a04
 
ac9a04
-	// Check for plugs on output
ac9a04
+	/* Check for plugs on output */
ac9a04
 	result = iec61883_get_oMPR (handle, node, &ompr);
ac9a04
 	if (result < 0)
ac9a04
 		return result;
ac9a04
 	
ac9a04
-	// locate an ouput plug that has a connection
ac9a04
-	for (oplug = 0; oplug < ompr.n_plugs; oplug++) {
ac9a04
-		if (iec61883_get_oPCRX (handle, node, &opcr, oplug) == 0) {
ac9a04
-			if (opcr.online && (opcr.n_p2p_connections > 0 || 
ac9a04
-				                opcr.bcast_connection == 1)) {
ac9a04
+	/* Locate an ouptut plug that has a connection,
ac9a04
+	 * make sure the plug's channel is allocated with IRM */
ac9a04
+	for (oplug = 0; oplug < ompr.n_plugs; oplug++)
ac9a04
+		if (iec61883_get_oPCRX (handle, node, &opcr, oplug) == 0
ac9a04
+		    && opcr.online
ac9a04
+		    && (opcr.n_p2p_connections > 0 || opcr.bcast_connection == 1)
ac9a04
+		    && raw1394_channel_modify (handle, opcr.channel, RAW1394_MODIFY_ALLOC) < 0)
ac9a04
+			DEBUG ("Channel %d already allocated, or can't reach IRM", opcr.channel);
ac9a04
 
ac9a04
-				// Make sure the plug's channel is allocated with IRM
ac9a04
-				quadlet_t buffer;
ac9a04
-				nodeaddr_t addr = CSR_REGISTER_BASE;
ac9a04
-				unsigned int c = opcr.channel;
ac9a04
-				quadlet_t compare, swap = 0;
ac9a04
-				quadlet_t new;
ac9a04
-				
ac9a04
-				if (c > 31 && c < 64) {
ac9a04
-					addr += CSR_CHANNELS_AVAILABLE_LO;
ac9a04
-					c -= 32;
ac9a04
-				} else if (c < 64)
ac9a04
-					addr += CSR_CHANNELS_AVAILABLE_HI;
ac9a04
-				else
ac9a04
-					FAIL ("Invalid channel");
ac9a04
-				c = 31 - c;
ac9a04
-
ac9a04
-				result = iec61883_cooked_read (handle, raw1394_get_irm_id (handle), addr, 
ac9a04
-					sizeof (quadlet_t), &buffer);
ac9a04
-				if (result < 0)
ac9a04
-					FAIL ("Failed to get channels available.");
ac9a04
-				
ac9a04
-				buffer = ntohl (buffer);
ac9a04
-				DEBUG ("channels available before: 0x%08x", buffer);
ac9a04
-
ac9a04
-				if ((buffer & (1 << c)) != 0) {
ac9a04
-					swap = htonl (buffer & ~(1 << c));
ac9a04
-					compare = htonl (buffer);
ac9a04
-
ac9a04
-					result = raw1394_lock (handle, raw1394_get_irm_id (handle), addr,
ac9a04
-							   EXTCODE_COMPARE_SWAP, swap, compare, &new;;
ac9a04
-					if ( (result < 0) || (new != compare) ) {
ac9a04
-						FAIL ("Failed to modify channel %d", opcr.channel);
ac9a04
-					}
ac9a04
-					DEBUG ("channels available after: 0x%08x", ntohl (swap));
ac9a04
-				}
ac9a04
-			}
ac9a04
-		}
ac9a04
-	}
ac9a04
-		
ac9a04
-	return result;
ac9a04
+	return 0;
ac9a04
 }
ac9a04
ac9a04
-- 
ac9a04
Stefan Richter
ac9a04
-=====-==--= ---= -====
ac9a04
http://arcgraph.de/sr/