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