Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 3 Apr 2005 17:06:38 +0200
From:      Hans Petter Selasky <hselasky@c2i.net>
To:        Sebastien B <sebastien.b@swissinfo.org>
Cc:        freebsd-usb@freebsd.org
Subject:   Re: panic: uhci_abort_xfer: not in process context
Message-ID:  <200504031706.39252.hselasky@c2i.net>
In-Reply-To: <200504022220.49835.sebastien.b@swissinfo.org>
References:  <6.2.1.2.0.20050329222822.04f7c500@64.7.153.2> <200504021316.59434.hselasky@c2i.net> <200504022220.49835.sebastien.b@swissinfo.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Saturday 02 April 2005 22:20, Sebastien B wrote:
> > > > You can call usbd_transfer(), if the transfer is not
> > > > synchronous.
> > >
> > > But it is. To send network packets, I must perform two USB transfers on
> > > two different endpoints, and I must wait for the first one to complete
> > > before initiating the second.
> >
> > What you need to do is to allocate two [non synchronous] transfers
> > besides from the data transfer. The callback of the first transfer starts
> > the second transfer. The callback of the second transfer starts the data
> > transfer. Then you need to make a flag so that the first transfer is not
> > started again, before the data transfer has been started.
>
> This requires a quite complex locking mechanism by comparison to scheduling
> a software interrupt handler.

The existing USB driver is all under Giant. So locking will not be very 
complex. Don't forget to lock/unlock Giant if you call USB functions from a 
software interrupt handler.

> Why is using a software interrupt handler and synchronous transfers wrong ?

There is nothing wrong with creating your own thread to do things from, except 
you get a little overhead releated to task switch and you need to handle race 
conditions related to deatch. Somehow you need to abort the transfers that 
might be active and your thread needs to exit. This is all much simpler if 
you "chain" the USB-transfers. Then you simply abort the pipes you are using, 
and there is nothing more to consider.

>
> I've disabled the timeout in usbd_bulk_transfer() and it does not panic
> anymore. So this is indeed the timeout function which causes the panic when
> it is called.
>
Yes, the timeout in the existing USB driver does not work. The timeout is 
called because the transfer does not complete. Add some printf's and you will 
find out that usbd_bulk_transfer() does not return!


On Saturday 02 April 2005 17:32, Ian Dowse wrote:

>
> It would be possible to implement an asynchronous version of
> usbd_abort_pipe() that invokes a callback on completion. That seems
> like a good idea, as it would allow us to handle the cases where
> we need to initiate the abort from a callback.
>

If one doesn't block when a transfer is aborted, one has to block when the 
transfer is started again, so the problem is not solved. But I don't 
understand: If usbd_abort_pipe() is called from a non-blocking context for 
example an USB-callback, and it is able to detect this, why does it not pass 
a flag to the hardware abort routine to use DELAY() instead of tsleep()? Even 
if it is not efficient, that is a driver design problem. Also if a 
synchronous transfer is started from an USB-callback, why does the existing 
driver not poll the hardware until the transfer has finished?


Yours
--HPS



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