Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Nov 2004 17:44:26 +0100
From:      Hans Petter Selasky <hselasky@c2i.net>
To:        "M. Warner Losh" <imp@bsdimp.com>
Cc:        freebsd-usb@freebsd.org
Subject:   Re: new USB driver
Message-ID:  <20041108174425.A283@curly.tele2.no>
In-Reply-To: <20041107.130436.91313722.imp@bsdimp.com>; from imp@bsdimp.com on Sun, Nov 07, 2004 at 01:04:36PM -0700
References:  <20041107194658.B466@curly.tele2.no> <20041107.130436.91313722.imp@bsdimp.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, Nov 07, 2004 at 01:04:36PM -0700, M. Warner Losh wrote:
> In message: <20041107194658.B466@curly.tele2.no>
>             Hans Petter Selasky <hselasky@c2i.net> writes:
> : I wondered if I could have my new USB driver up for discussion?
> 
> Sure.
> 
> : What do you think about it?
> 
> There seems to be a whole lot of changes swizzled into this new driver
> that aren't documented in your mail.  

> Looking at ums.c shows huge
> differences, for example.  It mostly looks like there's about a month
> of changes into current that just aren't present.  this makes it hard
> to diff and compare the drivers.
>
It is difficult to diff this USB driver with the existing one, because much
code has been rewritten.

A short introduction to my USB-setup sequence: (see the function 
usbd_do_request_flags() in the file _usb_transfer.c for an example) 

1) usbd_transfer_setup() 

This routine sets up a list of usbd_xfer pointers.

This routine takes basically three arguments:
A usbd_device pointer, an iface index and a pointer to a structure of type 
usbd_config.

This call is similar to usbd_open_pipe, except that all memory needed for the 
transfer, transfer buffer, TD's and QH's are allocated in one memory block. 
This reduce the amount of error handling code, hence there is only one place 
where memory allocation may fail. This ensures that all memory is freed when 
the transfer is done (unlike the current USB driver which never frees the TD's 
and QH's used). This optimizes the drivers, by enabling the drivers to write 
directly into the memory buffer being used for transfer.

2) usbd_start_transfer()
2) usbd_start_transfer()

This function calls the callback which starts the transfer, if the transfer was 
not started. This function can be called more than one time without having the 
callback called twice for convenience.

3) usbd_stop_transfer()

This function stops the transfer, and can be called even if 
usbd_start_transfer() was not previously called. usbd_start_transfer() can be 
called after that usbd_stop_transfer() has been called to re-start the 
transfer. If usbd_stop_transfer() is called when the transfer was started, the 
callback is called with ``xfer->error'' set to USBD_CANCELLED.

4) usbd_transfer_unsetup()

This function unlinks TD's and QH's from the controllers memory and frees all 
memory.

About the callbacks:

 * the USB-driver automatically recovers from errors if 
 * ``xfer->clearstall_xfer'' is set
 *
 * Host-transmit callback example (bulk/interrupt/isochronous):
 * ============================================================
 * static void
 * usb_callback_tx(struct usbd_xfer *xfer)
 * {
 *   USBD_CHECK_STATUS(xfer);
 *
 * tr_transferred:
 * tr_setup:
 *
 *   ... setup ``xfer->length'' ...
 *
 *   ... write data to buffer ...
 *
 * tr_error:
 *
 *   ... [re-]transfer ``xfer->buffer'' ...
 *
 *   usbd_start_hardware(xfer);
 *   return;
 * }
 *
 * Host-receive callback example (bulk/interrupt/isochronous):
 * ===========================================================
 * static void
 * usb_callback_rx(struct usbd_xfer *xfer)
 * {
 *   USBD_CHECK_STATUS(xfer);
 *
 * tr_transferred:
 *
 *   ... process data in buffer ...
 *
 * tr_setup:
 *
 *   ... setup ``xfer->length'' ...
 *
 * tr_error:
 *
 *   ... [re-]transfer ``xfer->buffer'' ...
 *
 *   usbd_start_hardware(xfer);
 *   return;
 * }

The callback system handles recursation. It is possible to start/stop another 
xfer from a "callback". The callbacks are protected by the mutex pointed to by 
xfer->priv_mtx;

All memory is allocated before transfer, and not during transfer.

There are some more differences, but that will be details. My new USB driver 
is built upon the FreeBSD-5-current USB driver, but it is not fully compatible 
with it.

So is it a candidate for a new /sys/ directory?


By the way, some BUGS in the FreeBSD-5-current USB driver:

Last time I tried to abort a transfer and then start it again it didn't work. 

The current USB driver does not handle isochronous over-/under-flow very well.
There is no check after that the first transfer has been started to see if the
frames are inserted at the correct position in time. After XDU, isochronous
transfers are not usable.

Yours
-HPS



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20041108174425.A283>