On Thu, Apr 18, 2002, David Brownell <[EMAIL PROTECTED]> wrote:
> > > ... though I wonder if the way uhci.c works, it might not leave the
> > > qh->dev field valid rather "late" after unlinking associated URBs.
> > 
> > qh->dev is always valid.
> > 
> > > That'd be fine, except uhci_free_dev() doesn't ensure that such
> > > device state is all gone.  (No such logic in usb-uhci.c either.)
> > 
> > What device state?
> 
> Those non-null qh->dev pointers.

It may be non-null, but qh is not on any list. There is no way that it
can be referenced after uhci_free_qh is called.

> >     If reference counting is working like it should be,
> > the only time uhci_free_dev is called is when there are no URB's, TD's
> > and QH's assigned to that device.
> 
> Well, certainly no URBs ... but the higher level code can't know
> anything about HCD level state (TDs, QHs/EDs, etc).  That's
> what I'd understood the HCD deallocate() call -- in this case
> called uhci_free_dev() -- was responsible for cleaning.
> 
> If, as you say, deallocate() shouldn't handle that, then what does?
> 
> Yes, I just noticed that deallocate is called after the refcount goes
> to zero.  While that's something I want to call a bug, it clearly won't
> affect UHCI (that call is a NOP) or OHCI or EHCI (other reasons),
> another reading is that something else (but what?) is expected to
> clear that state.  OHCI and EHCI both use that call as the "clean
> up device state" hook; seems we're into areas where the HCDs
> interpret the same usbcore calls differently (trouble).
> 
> Like I said, I was just wondering ... I don't know the uhci innards,
> but noticed that uhci_pci_remove() calls a routine in that BUG()
> stack -- uhci_free_pending_qhs() -- only _after_ all the drivers
> were disconnected.  That sure looks like uhci.c expected some
> TD/QH type state to linger on and so need "late" cleanup, so it
> provided the "something else" on that code path.
> 
> What I was trying to to point out was that such cleanup would also
> be needed in more typical disconnect cases, and I don't see any
> way to force it to happen ... certainly not where I'd have expected
> it to be, in the deallocate() code!

I don't think you understand how reference counting works. Let me give
you an example:

function call                           reference count (device)
-------------                           ------------------------
usb_alloc_dev                           1 (starts at one)

[enumeration, module probing, etc]

usb_control_msg (send 8 bytes)          1
 uhci_submit_urb                        1
  uhci_inc_dev_use                      2 (once for the urb)
  uhci_submit_control                   2
   uhci_alloc_td                        3 (SETUP)
   uhci_alloc_td                        4 (DATA)
   uhci_alloc_td                        5 (STATUS)
   uhci_alloc_qh                        6

[other processing waiting for URB to finish]
[user unplugs device]

usb_disconnect                          6
 usb_free_dev                           5

[more processing, URB times out or fails. it wasn't explicitly unlinked]

uhci_interrupt                          5
 uhci_transfer_result                   5
  uhci_result_control                   5
   uhci_unlink_generic                  5
    uhci_remove_qh                      5 (qh added to qh_remove_list)
 uhci_finish_completion                 5
  uhci_call_completion                  5
    uhci_destroy_urb_priv               5
     uhci_free_td                       4
     uhci_free_td                       3
     uhci_free_td                       2
  uhci_dec_dev_use                      1 (done with URB)

[more processing, next interrupt occurs]

uhci_interrupt                          1
 uhci_free_pending_qhs                  1
  uhci_free_qh                          0

As you can see, the only time the reference count would hit 0 is when
uhci.c is done with all QH's, TD's and URB's for that device. The only
way uhci_free_dev can be called is when the reference count is 0.

Thusly, there is no way uhci_free_dev can be called with any QH's, TD's
and URB's still being used. That's why uhci_free_dev is empty, because
when it's called, there's always nothing to cleanup for that device.

The only way that this can't be true would be because of a reference
counting bug somewhere. I'm pretty confident that uhci.c is correct in
the way it does reference counting.

I'll double check the uhci_pci_remove path as well. That is a little
tricky and not well tested.

JE


_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to