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