tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: USB async read question
2009/9/27 Dmitry Cherkassov <4da.darkstar%gmail.com@localhost>:
> Hi, just another newbie question.
>
> In my driver for samsung usb wimax driver I register an async read callback:
>
> <code>
> usbd_status
> wimax_async_read(struct wimax_softc *sc)
> {
> usbd_xfer_handle xfer;
> usbd_status err;
> int total_len = 0, s;
>
> s = splnet();
>
> xfer = usbd_alloc_xfer(sc->wimax_udev);
>
> usbd_setup_xfer(xfer, sc->rx_pipe, 0, sc->recv_buff, sc->bulk_in_len,
>
> USBD_SHORT_XFER_OK, 5000, recv_callback);
>
> err = usbd_transfer(xfer);
>
> splx(s);
> }
> </code>
>
> The callback function itself:
>
> <code>
> void recv_callback(usbd_xfer_handle xh, usbd_private_handle priv,
> usbd_status stat)
> {
> char *buf;
> char count;
> printf("in callback!\n");
> usbd_get_xfer_status(xh, 0, 0, &count, 0);
> printf("data transferred: %d\nstatus = %s", count, usbd_errstr(stat));
> }
> </code>
>
> Than I send requests to my device using that:
>
> <code>
> usbd_status
> wimax_usb_write(struct wimax_softc *sc, u_int16_t length, u_int8_t *data)
> {
> usbd_xfer_handle xfer;
> usbd_status err;
> int total_len = 0, s;
>
> s = splnet();
>
> xfer = usbd_alloc_xfer(sc->wimax_udev);
>
> usbd_setup_xfer(xfer, sc->tx_pipe, 0, data, length,
>
> USBD_SHORT_XFER_OK, 1000, NULL);
>
> err = usbd_sync_transfer(xfer);
>
> usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
>
> printf("%s: transfered 0x%x bytes out\n",
> USBDEVNAME(sc->wimax_dev), total_len);
>
> usbd_free_xfer(xfer);
>
> splx(s);
> return(err);
> }
> </code>
>
> The problem is:
>
> When my callback gets called the status it gets as argument is IOERROR.
>
> Also when
>
> usbd_get_xfer_status(xh, 0, 0, &count, 0)
> in callback function is called.
> I get:
> trap type 6 code eip ***** cs * eflags **** cr2 * ilevel *
>
> and my machine reboots in a split-second.
>
> Could someone point what am I doing wrong?
>
> Thank you!
>
I have noticed that I have forgotten to specify the buffer in:
>usbd_get_xfer_status(xh, 0, 0, &count, 0);
I replaced it with:
usbd_get_xfer_status(xh, 0, &buf, &count, 0);
BTW that's from freebsd usbdi (9) man page:
The function usbd_get_xfer_status() retrieves various information from a
transfer. If the priv parameter is not NULL then the callback
argument is stored in *priv. If buffer is not NULL then the
buffer pointer is stored in *buffer. The actual number of bytes
is stored in *count if count is not NULL. Finally, the trans-
status is stored in *status if status is not NULL.
As I presume, 0 instead of buffer shouldn't be a problem. Or it may be
FreeBSD-specific?
Here is that callback method again:
<code>
void recv_callback(usbd_xfer_handle xh, usbd_private_handle priv,
usbd_status stat)
{
char *buf;
char count;
printf("in callback!\n");
usbd_get_xfer_status(xh, 0, &buf, &count, 0);
printf("data transferred: %d\nstatus = %s\nbuf=%s\n", count,
usbd_errstr(stat), ether_sprintf(buf));
}
</code>
The system doesn't crash anymore, but I still get that IOERROR.
May be this error is device-related, since I improperly understand how
to communicate with the device?
Home |
Main Index |
Thread Index |
Old Index