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