Subject: Re: ohci_abort_xfer and disappearing interfaces
To: None <current-users@netbsd.org>
From: Christos Zoulas <christos@astron.com>
List: current-users
Date: 03/30/2006 19:08:50
In article <20060330181551.920755764@fnord.ir.bbn.com>,
Greg Troxel <gdt@ir.bbn.com> wrote:
>I have a Kyocera KPC650 EVDO interface card which has on it
>
>ohci
> uhub
> ugensa
> [ucom]
>
>This works fine with Verizon EVDO service.
>
>When removing the card, I get a panic. One backtrace shows ugensa's
>detach routine calling ohci_abort_xfer. This procedure checks
>sc->sc_dying (which is 1 in my backtrace), but then doesn't return
>after doing the 'software only' part. This seems wrong, but I have
>only a dim grasp of the USB stack. In general, I'd think the card
>removal event would walk the device tree rooted at the card and set
>sc->sc_dying to true but without doing anything else, and then go back
>and do state teardowns. The tricky part is that ugensa wants to shutdown
>bulk transfers (in case it was detached from a usb bus), but in this
>case not only the bus but the controller are gone already.
>
>Any clues?
>
>void
>ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
>{
> struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
> ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
> ohci_soft_ed_t *sed = opipe->sed;
> ohci_soft_td_t *p, *n;
> ohci_physaddr_t headp;
> int s, hit;
> int wake;
>
> DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p sed=%p\n", xfer, opipe,sed));
>
> if (sc->sc_dying) {
> /* If we're dying, just do the software part. */
> s = splusb();
> xfer->status = status; /* make software ignore it */
> usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
> usb_transfer_complete(xfer);
> splx(s);
>
>GDT: why is there no return here?
>
> }
>
> if (xfer->device->bus->intr_context || !curproc)
> panic("ohci_abort_xfer: not in process context");
>
Indeed. I just fixed it.
christos