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