Quadlet read/write bug
Hidetoshi Shimokawa
simokawa at sat.t.u-tokyo.ac.jp
Thu May 27 07:39:01 PDT 2004
As you know, userland interface, fwdev.c is broken and annoying in
many respects. I suppose it was designed just for debugging and it's
inefficient for real use. Some of those interfaces were broken
originally and I broke some more interfaces when I changed packet
format in struct fw_xfer :-(.
You are right that there is a problem in handling of payload length.
Your change and Doug's change committed to -current seem to be a
enough workaround. Though I have also an incomplete/untested patch, I
should explain why the payload for read request response is 4. As you
mentioned, actual IEEE1394 packet length is 16 bytes which includes 4
bytes read data and payload length should be 0. But I intentionally
copy the 4 bytes data to xfer->recv.payload in the following code in
fw_rcv_copy().
/* special handling for RRESQ */
if (pkt->mode.hdr.tcode == FWTCODE_RRESQ &&
p != NULL && res >= sizeof(u_int32_t)) {
*(u_int32_t *)p = pkt->mode.rresq.data;
rb->xfer->recv.pay_len = sizeof(u_int32_t);
return;
}
This is mainly for the fwmem_read_quad() interface. In my opinion, it
is useful that we have such uniform interface for quad and block read
that the caller pass a pointer of the buffer and the data is copied to
the buffer by callee.
Gotanda-san reported me that FW_SBINDADDR ioctl is also broken. The
lower kernel interface fw_bindadd() is well tested by
sbp(4)/sbp_targ(4). So it just a problem of fwdev.c.
We need someone to rewrite userland interface. Compatibility for Linux
may be useful but I'm sure how hard it is.
I hope this helps you.
/\ Hidetoshi Shimokawa
\/ simokawa at sat.t.u-tokyo.ac.jp
PGP public key: http://www.sat.t.u-tokyo.ac.jp/~simokawa/pgp.html
At Wed, 26 May 2004 13:59:16 -0700 (PDT),
Buzz Slye wrote:
>
> A temporary fix to the asyncronous read and write cases of fw_ioctl
> for a req.len = 16 is (fwdev.c line 595):
> int tc;
> .....
> /* copy response */
> tc = xfer->recv.hdr.mode.hdr.tcode;
> tinfo = &sc->fc->tcode[tc];
> if (tc == FWTCODE_RRESQ || tc == FWTCODE_WRES)
> asyreq->req.len = xfer->recv.pay_len;
> else if (asyreq->req.len >= xfer->recv.pay_len + tinfo->hdr_len)
> asyreq->req.len = xfer->recv.pay_len;
> else
> err = EINVAL;
>
> The above will work for rreqq and wreqq, but I didn't look at the other cases.
> Note that for the read request response, the payload length is 4, but the
> header length is 16. This adds up to 20 which doesn't work for req.len=16.
> The response header should be 12 maybe, if the payload is 4 ?
> For the write request response, the payload length is 4096, but there really
> isn't any payload returned. Returning req.len=4096 isn't good, but if the
> application doesn't check it, it certainly beats returning EINVAL.
>
> R. E. Slye
> NASA/Ames
>
> _______________________________________________
> freebsd-firewire at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-firewire
> To unsubscribe, send any mail to "freebsd-firewire-unsubscribe at freebsd.org"
>
More information about the freebsd-firewire
mailing list