2006-11-29 00:59:03

by Robert Crocombe

[permalink] [raw]
Subject: isochronous receives?

Keith, et. al,

I am having problems with isochronous receives, and remembered just as
I was getting ready to dig into the source that there was a message
about this stuff. Lo and behold your message to linux1394-user from
September 7:

> I'm trying to receive isochronous streams (using libraw1394 1.2.0), and
> I've noticed that if data is transmitted on channel 63, then my app tends
> to work fine. If the stream is on a different channel, then I don't see
> any isochronous packets at all. I'm using 2.4.29, I've also tried 2.6.15
> with similar results, can't seem to receive channels < 63.

Did you ultimately have any success getting this going? Funnily
enough, when I tested isochronous stuff in July, I just did iso
transmit since I figured receives *must* be working since everyone has
camcorders and whatnot. My currently my iso xmit stuff does appear to
be working, but iso receives are not.

I have a Firespy and no reason not to trust it, so I can see the junk
I'm spewing out. I've tried transmitting on channels 4 and 63 (per
your advice), but neither works for me. I suppose it could my
stuff... nah.

--
Robert Crocombe
[email protected]


2006-11-30 01:57:26

by Keith Curtis

[permalink] [raw]
Subject: RE: isochronous receives?

Hi Robert,

I never resolved the problem. I turned on the excessive debugging output, but it
didn't print out info about receiving packets or interrupts. My test
app claimed there were no packets received although the bus analyzer
showed lots of packets going by.

If I can help out, let me know, but I'm not sure where to start at this point.

Keith


-----Original Message-----
From: Robert Crocombe [mailto:[email protected]]
Sent: Tuesday, November 28, 2006 4:59 PM
To: Keith Curtis; linux1394-devel; linux-kernel
Subject: isochronous receives?


Keith, et. al,

I am having problems with isochronous receives, and remembered just as
I was getting ready to dig into the source that there was a message
about this stuff. Lo and behold your message to linux1394-user from
September 7:

> I'm trying to receive isochronous streams (using libraw1394 1.2.0), and
> I've noticed that if data is transmitted on channel 63, then my app tends
> to work fine. If the stream is on a different channel, then I don't see
> any isochronous packets at all. I'm using 2.4.29, I've also tried 2.6.15
> with similar results, can't seem to receive channels < 63.

Did you ultimately have any success getting this going? Funnily
enough, when I tested isochronous stuff in July, I just did iso
transmit since I figured receives *must* be working since everyone has
camcorders and whatnot. My currently my iso xmit stuff does appear to
be working, but iso receives are not.

I have a Firespy and no reason not to trust it, so I can see the junk
I'm spewing out. I've tried transmitting on channels 4 and 63 (per
your advice), but neither works for me. I suppose it could my
stuff... nah.

--
Robert Crocombe
[email protected]

2006-12-01 10:30:56

by Stefan Richter

[permalink] [raw]
Subject: Re: isochronous receives?

Keith Curtis wrote:
> I never resolved the problem. I turned on the excessive debugging output, but it
> didn't print out info about receiving packets or interrupts. My test
> app claimed there were no packets received although the bus analyzer
> showed lots of packets going by.
>
> If I can help out, let me know, but I'm not sure where to start at this point.
...
> -----Original Message-----
> From: Robert Crocombe [mailto:[email protected]]
> Sent: Tuesday, November 28, 2006 4:59 PM
...
> Did you ultimately have any success getting this going? Funnily
> enough, when I tested isochronous stuff in July, I just did iso
> transmit since I figured receives *must* be working since everyone has
> camcorders and whatnot. My currently my iso xmit stuff does appear to
> be working, but iso receives are not.
>
> I have a Firespy and no reason not to trust it, so I can see the junk
> I'm spewing out. I've tried transmitting on channels 4 and 63 (per
> your advice), but neither works for me. I suppose it could my
> stuff... nah.

I don't know much about the mechanisms, but I suppose there could be one
of the following causes:
- The IR DMA context was never set up for the respective channel in the
first place.
- The context was set up but the interrupt event masks weren't switched
on, i.e. IntMask as per OHCI clause 6.2 and isoRecvIntMask as per
clause 6.3.2.
- The context and masks were set up, but then one or both of the masks
were switched off again, similar to the bus reset bug which Robert
reported: http://bugzilla.kernel.org/show_bug.cgi?id=7569
--
Stefan Richter
-=====-=-==- ==-- ----=
http://arcgraph.de/sr/

2006-12-13 14:30:15

by Robert Crocombe

[permalink] [raw]
Subject: Re: isochronous receives?

On 11/29/06, Keith Curtis <[email protected]> wrote:
> I never resolved the problem. I turned on the excessive debugging output, but it
> didn't print out info about receiving packets or interrupts. My test
> app claimed there were no packets received although the bus analyzer
> showed lots of packets going by.

Well, I figured it out, finally. Thankfully (in a way...), it was my
code: I was setting the tag to -1 in a certain spot (which indicates
that you want to see all packets, regardless of their tag), but
unhelpfully changing it to 0 before calling raw1394_iso_recv_start...

...dangit, though. Looking at the data stream, the tag *is* zero.

Stefan, isn't the line:

/* match on specified tags */
contextMatch = tag_mask << 28;

in ohci_iso_recv_start() wrong? The register looks to work like this.
The tag field is two bits.

if you want to match on 11b, then set bit tag3 (bit 31)
if you want to match on 10b, then set bit tag2 (bit 30)
if you want to match on 01b, then set bit tag1 (bit 29)
if you want to match on 00b, then set bit tag0 (bit 28)

Which makes the shift obviously wrong. Passing in '3' to match on tag
11b will have you instead set bits 29 and 28, and you will match on
01b and 00b. Passing in '0' will completely bone you: no bits will be
turned on. Passing in '-1' to match all bits does work, though.
You'd have to know to pass in 0x8 to match for tag 11b, which is a
skosh counterintuitive and probably not what was intended.

Here's my crap patch. It appears to Work For Me(tm).

--- ohci1394.c 2006-12-04 16:52:10.916044780 -0700
+++ modified_ohci1394.c 2006-12-13 07:22:07.613917511 -0700
@@ -1491,7 +1491,18 @@
reg_write(recv->ohci, recv->ContextControlSet, command);

/* match on specified tags */
- contextMatch = tag_mask << 28;
+ switch (tag_mask)
+ {
+ case -1: contextMatch = tag_mask << 28; break;
+ case 0: contextMatch = (1 << 28); break;
+ case 1: contextMatch = (1 << 29); break;
+ case 2: contextMatch = (1 << 30); break;
+ case 3: contextMatch = (1 << 31); break;
+ default:
+ DBGMSG("Invalid tag_mask %0x, matching all tags",tag_mask);
+ contextMatch = tag_mask << 28;
+ break;
+ }

if (iso->channel == -1) {
/* enable multichannel reception */


So nevermind. I'm totally vindicated and my code is, as always,
flawless. Cough.

--
Robert Crocombe
[email protected]

2006-12-13 18:46:09

by Stefan Richter

[permalink] [raw]
Subject: Re: isochronous receives?

Robert Crocombe wrote:
> I was setting the tag to -1 in a certain spot (which indicates
> that you want to see all packets, regardless of their tag), but
> unhelpfully changing it to 0 before calling raw1394_iso_recv_start...
>
> ...dangit, though. Looking at the data stream, the tag *is* zero.
>
> Stefan, isn't the line:
>
> /* match on specified tags */
> contextMatch = tag_mask << 28;
>
> in ohci_iso_recv_start() wrong? The register looks to work like this.
> The tag field is two bits.
>
> if you want to match on 11b, then set bit tag3 (bit 31)
> if you want to match on 10b, then set bit tag2 (bit 30)
> if you want to match on 01b, then set bit tag1 (bit 29)
> if you want to match on 00b, then set bit tag0 (bit 28)
>
> Which makes the shift obviously wrong. Passing in '3' to match on tag
> 11b will have you instead set bits 29 and 28, and you will match on
> 01b and 00b. Passing in '0' will completely bone you: no bits will be
> turned on. Passing in '-1' to match all bits does work, though.

The question is, what is tag_mask in libraw1394's
int raw1394_iso_recv_start(raw1394handle_t handle,
int start_on_cycle,
int tag_mask,
int sync);
supposed to mean in the first place? It is not entirely documented, at
least not in the currently online documentation.

However, as it works now, tag_mask is obviously nothing else than the
highest 4 bits of the OHCI-1394 1.1 iso receive contextMatch register,
which is...

> You'd have to know to pass in 0x8 to match for tag 11b, which is a
> skosh counterintuitive

...counterintuitive and apparently undocumented.

> and probably not what was intended.

How can we tell? The author of libraw1394's rawiso API should confirm
or deny that. :-)

> Here's my crap patch. It appears to Work For Me(tm).
>
> --- ohci1394.c 2006-12-04 16:52:10.916044780 -0700
> +++ modified_ohci1394.c 2006-12-13 07:22:07.613917511 -0700
> @@ -1491,7 +1491,18 @@
> reg_write(recv->ohci, recv->ContextControlSet, command);
>
> /* match on specified tags */
> - contextMatch = tag_mask << 28;
> + switch (tag_mask)
> + {
> + case -1: contextMatch = tag_mask << 28; break;
> + case 0: contextMatch = (1 << 28); break;
> + case 1: contextMatch = (1 << 29); break;
> + case 2: contextMatch = (1 << 30); break;
> + case 3: contextMatch = (1 << 31); break;
> + default:
> + DBGMSG("Invalid tag_mask %0x, matching all tags",tag_mask);
> + contextMatch = tag_mask << 28;
> + break;
> + }
>
> if (iso->channel == -1) {
> /* enable multichannel reception */
>
>
> So nevermind. I'm totally vindicated and my code is, as always,
> flawless. Cough.

We could do this, but this would have two disadvantages:
- We change the kernel's userspace ABI. This is only done if serious
bugs of an ABI need to be fixed.
- We loose the ability to match two or three tags out of four, FWIW.
The proposed patch can match only one or all four tags.

How about leaving ohci1394 as it is but document tag_mask better in
libraw1394's inline doxygen(?) comments, and maybe add an enum or macros
to be used as values of raw1394_iso_recv_start's tag_mask argument?

/* can be ORed together */
#define RAW1394_IR_MATCH_TAG_0 1
#define RAW1394_IR_MATCH_TAG_1 2
#define RAW1394_IR_MATCH_TAG_2 4
#define RAW1394_IR_MATCH_TAG_3 8
#define RAW1394_IR_MATCH_ALL_TAGS -1

or

/* can be used for tag = 0...3 and ORed together for multiple tags */
#define RAW1394_IR_MATCH_TAG(tag) (1<<((tag)&3))
#define RAW1394_IR_MATCH_ALL_TAGS -1

--
Stefan Richter
-=====-=-==- ==-- -==-=
http://arcgraph.de/sr/

2006-12-13 23:31:05

by Stefan Richter

[permalink] [raw]
Subject: Re: isochronous receives?

I wrote:
> /* can be used for tag = 0...3 and ORed together for multiple tags */
> #define RAW1394_IR_MATCH_TAG(tag) (1<<((tag)&3))

PS: or ((tag)>>2 ? 0 : 1<<(tag)) or just (1<<(tag))

> #define RAW1394_IR_MATCH_ALL_TAGS -1

--
Stefan Richter
-=====-=-==- ==-- -===-
http://arcgraph.de/sr/

2006-12-14 18:23:13

by Robert Crocombe

[permalink] [raw]
Subject: Re: isochronous receives?

On 12/13/06, Stefan Richter <[email protected]> wrote:
> How about leaving ohci1394 as it is but document tag_mask better in
> libraw1394's inline doxygen(?) comments, and maybe add an enum or macros
> to be used as values of raw1394_iso_recv_start's tag_mask argument?
>
> /* can be ORed together */
> #define RAW1394_IR_MATCH_TAG_0 1
> #define RAW1394_IR_MATCH_TAG_1 2
> #define RAW1394_IR_MATCH_TAG_2 4
> #define RAW1394_IR_MATCH_TAG_3 8
> #define RAW1394_IR_MATCH_ALL_TAGS -1

Yeah, that's definitely much better. I guess this would go in
libraw1394's raw1394.h? Similar to:

--- raw1394.h 2006-11-29 11:54:56.000000000 -0700
+++ raw1394_modified.h 2006-12-14 11:20:57.000000000 -0700
@@ -40,6 +40,14 @@
#define RAW1394_RCODE_TYPE_ERROR 0x6
#define RAW1394_RCODE_ADDRESS_ERROR 0x7

+/* can be ORed together */
+#define RAW1394_IR_MATCH_TAG_0 0x1
+#define RAW1394_IR_MATCH_TAG_1 0x2
+#define RAW1394_IR_MATCH_TAG_2 0x4
+#define RAW1394_IR_MATCH_TAG_3 0x8
+#define RAW1394_IR_MATCH_ALL_TAGS -1
+#define RAW1394_IR_MATCH_TAG(tag) (1 << (tag))
+
typedef u_int8_t byte_t;
typedef u_int32_t quadlet_t;
typedef u_int64_t octlet_t;
@@ -273,7 +281,9 @@
* @handle: libraw1394 handle
* @start_on_cycle: isochronous cycle number on which to start
* (-1 if you don't care)
- * @tag_mask: mask of tag fields to match (-1 to receive all packets)
+ * @tag_mask: mask of tag fields to match. Use the RAW1394_IR_MATCH_*
+ * values for this rather than the literal tag bits: the values are not
+ * equivalent.
* @sync: not used, reserved for future implementation
*
* Returns: 0 on success or -1 on failure (sets errno)

??

--
Robert Crocombe
[email protected]