ieee1394 fixed soon...
David S. Miller
davem at redhat.com
Thu Mar 29 17:18:10 EST 2001
Daniel Berlin writes:
> If the patches + removing the bitfields for self-id
> (which it sounds like you already did) give you the ability to
> at least attempt to send packets (IE it runs the dma programs),
> you are in very good shape. I had to get the byteswapping basically
> perfect to even get it to not just laugh at me and do nothing when we told
> ia dma context to run.
What do you mean specifically when you say "removing the bitfields fo
self-id"? I notice in your patches that you don't byte swap
q[0] and q[1] when they arrive for a self-id interrupt. Are these
quadlets supposed to be big-endian in memory? Here is the change I made:
@@ -326,7 +326,7 @@
inline static int handle_selfid(struct ti_ohci *ohci, struct hpsb_host *host,
int phyid, int isroot)
{
- quadlet_t *q = ohci->selfid_buf_cpu;
+ quadlet_t val, *q = ohci->selfid_buf_cpu;
quadlet_t self_id_count=reg_read(ohci, OHCI1394_SelfIDCount);
size_t size;
quadlet_t lsid;
@@ -337,12 +337,13 @@
stage */
/* Check status of self-id reception */
+ val = le32_to_cpu(q[0]);
if ((self_id_count&0x80000000) ||
- ((self_id_count&0x00FF0000) != (q[0]&0x00FF0000))) {
+ ((self_id_count&0x00FF0000) != (val&0x00FF0000))) {
PRINT(KERN_ERR, ohci->id,
"Error in reception of self-id packets"
"Self-id count: %08x q[0]: %08x",
- self_id_count, q[0]);
+ self_id_count, val);
/*
* Tip by James Goodwin <jamesg at Filanet.com>:
@@ -366,18 +367,22 @@
q++;
while (size > 0) {
- if (q[0] == ~q[1]) {
+ quadlet_t q0, q1;
+
+ q0 = le32_to_cpu(q[0]);
+ q1 = le32_to_cpu(q[1]);
+ if (q0 == ~q1) {
PRINT(KERN_INFO, ohci->id, "selfid packet 0x%x rcvd",
- q[0]);
- hpsb_selfid_received(host, cpu_to_be32(q[0]));
- if (((q[0]&0x3f000000)>>24)==phyid) {
- lsid=q[0];
+ q0);
+ hpsb_selfid_received(host, cpu_to_be32(q0));
+ if (((q0&0x3f000000)>>24)==phyid) {
+ lsid=q0;
PRINT(KERN_INFO, ohci->id,
"This node self-id is 0x%08x", lsid);
}
} else {
PRINT(KERN_ERR, ohci->id,
- "inconsistent selfid 0x%x/0x%x", q[0], q[1]);
+ "inconsistent selfid 0x%x/0x%x", q0, q1);
}
q += 2;
size -= 2;
And this seems to work just fine.
There are some problems I have with your patch, and some fixes in mine
that are not in yours (using pci_alloc_consistent more efficiently)
which ought to be integrated.
For one thing, in your stuff, the comments and code near the comment
"Pretty heinous." are totally bogus and wrong:
p->value &= cpu_to_le32(0xfffffff0);
works _PERFECTLY_ fine. As does:
p->value |= cpu_to_le32(0x1);
You don't need to do all the stuff like this:
p->value = cpu_to_le32(le32_to_cpu(p->value) | 0x1);
You only need to do this kind of thing when non-logical operations
(such as addition/subtraction etc.) need to be done on the
byte-swapped value.
It would really be nice if the IEEE1394 developers kept on top of
our patches and merged them to Linus soon.
> I also assumed readl/writel do byteswapping, and thus, there was no need
> to swap the register reads/writes since they would be swapped for us.
Right, readl/writel push little-endian onto little-endian busses like
PCI.
> At the absolute least, it'll give you an idea of what needs to be swapped
> for big endian architectures.
I know what needs to be swapped thats why I did the patches I did :-)
> I have
> patches to do this somewhere, it didn't matter for powerppc, so it was
> only a half hearted attempt.
Please push it to the ieee1394 maintainers, so the work need not
be duplicated by others. Thanks.
Later,
David S. Miller
davem at redhat.com
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-dev
mailing list