Module Name: src Committed By: skrll Date: Tue Jan 22 13:06:41 UTC 2013
Modified Files: src/sys/dev/usb: dwc_otg.c Log Message: Simplify dwc_otg_standard_done and always call dwc_host_channel_free on the last (attempted) TD. We were leaking channels before. Remove dwc_otg_device_done in the process. To generate a diff of this commit: cvs rdiff -u -r1.33 -r1.34 src/sys/dev/usb/dwc_otg.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/dwc_otg.c diff -u src/sys/dev/usb/dwc_otg.c:1.33 src/sys/dev/usb/dwc_otg.c:1.34 --- src/sys/dev/usb/dwc_otg.c:1.33 Tue Jan 22 13:03:25 2013 +++ src/sys/dev/usb/dwc_otg.c Tue Jan 22 13:06:41 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_otg.c,v 1.33 2013/01/22 13:03:25 skrll Exp $ */ +/* $NetBSD: dwc_otg.c,v 1.34 2013/01/22 13:06:41 skrll Exp $ */ /*- * Copyright (c) 2012 Hans Petter Selasky. All rights reserved. @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dwc_otg.c,v 1.33 2013/01/22 13:03:25 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dwc_otg.c,v 1.34 2013/01/22 13:06:41 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -245,8 +245,6 @@ Static void dwc_otg_worker(struct work Static void dwc_otg_rhc(void *); Static void dwc_otg_vbus_interrupt(struct dwc_otg_softc *); Static void dwc_otg_standard_done(usbd_xfer_handle); -Static usbd_status dwc_otg_standard_done_sub(usbd_xfer_handle); -Static void dwc_otg_device_done(usbd_xfer_handle, usbd_status); Static void dwc_otg_setup_standard_chain(usbd_xfer_handle); Static void dwc_otg_start_standard_chain(usbd_xfer_handle); @@ -3994,120 +3992,51 @@ dwc_otg_rhc(void *addr) } -Static usbd_status -dwc_otg_standard_done_sub(usbd_xfer_handle xfer) +Static void +dwc_otg_standard_done(usbd_xfer_handle xfer) { - struct dwc_otg_xfer *dxfer = (struct dwc_otg_xfer *)xfer; - usbd_pipe_handle pipe = xfer->pipe; + struct dwc_otg_xfer *dxfer = DWC_OTG_XFER2DXFER(xfer); + struct dwc_otg_softc *sc = xfer->pipe->device->bus->hci_private; struct dwc_otg_td *td; - uint32_t len; - usbd_status error; + usbd_status err = 0; - DPRINTFN(9, "td %p\n", dxfer->td_transfer_cache); + DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n", + xfer, xfer->pipe->endpoint); - td = dxfer->td_transfer_cache; + /* reset scanner */ - do { - xfer->actlen += td->actlen; + for (td = dxfer->td_transfer_first; ; td = td->obj_next) { - len = td->remainder; + xfer->actlen += td->actlen; /* store last data toggle */ - pipe->endpoint->datatoggle = td->toggle; + xfer->pipe->endpoint->datatoggle = td->toggle; /* Check for transfer error */ if (td->error_any) { /* the transfer is finished */ - error = (td->error_stall ? USBD_STALLED : USBD_IOERROR); - td = NULL; + err = (td->error_stall ? USBD_STALLED : USBD_IOERROR); break; } + /* Check for short transfer */ - if (len > 0) { - //if (xfer->flags & USBD_SHORT_XFER_OK) { - if (0) { - /* follow alt next */ - if (td->alt_next) { - td = td->obj_next; - } else { - td = NULL; - } - } else { - /* the transfer is finished */ - td = NULL; - } - error = 0; + if (td->remainder > 0) { + /* the transfer is finished */ + err = 0; break; } - td = td->obj_next; - - /* this USB frame is complete */ - error = 0; - break; - - } while (0); - - /* update transfer cache */ - - dxfer->td_transfer_cache = td; - - return error; -} - -Static void -dwc_otg_standard_done(usbd_xfer_handle xfer) -{ - struct dwc_otg_xfer *dxfer = DWC_OTG_XFER2DXFER(xfer); - - struct dwc_otg_td *td; - usbd_status err = 0; - - DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n", - xfer, xfer->pipe->endpoint); - - /* reset scanner */ - - dxfer->td_transfer_cache = dxfer->td_transfer_first; - td = dxfer->td_transfer_first; - - while (td != NULL) { - err = dwc_otg_standard_done_sub(xfer); - if (dxfer->td_transfer_cache == NULL) { - goto done; - } + /* this TD is complete - move onto next if more to do */ if (td == dxfer->td_transfer_last) break; - td = td->obj_next; } -done: - dwc_otg_device_done(xfer, err); -} - - -/*------------------------------------------------------------------------* - * dwc_otg_device_done - * - * NOTE: this function can be called more than one time on the - * same USB transfer! - *------------------------------------------------------------------------*/ -Static void -dwc_otg_device_done(usbd_xfer_handle xfer, usbd_status error) -{ - struct dwc_otg_xfer *dxfer = (struct dwc_otg_xfer *)xfer; - struct dwc_otg_softc *sc = DWC_OTG_XFER2SC(xfer); - - DPRINTFN(9, "xfer=%p, endpoint=%p, error=%d\n", - xfer, xfer->pipe->endpoint, error); - struct dwc_otg_td *td; KASSERT(mutex_owned(&sc->sc_intr_lock)); - td = dxfer->td_transfer_first; if (td != NULL) dwc_otg_host_channel_free(td); - xfer->status = error; + xfer->status = err; TAILQ_REMOVE(&sc->sc_active, dxfer, xnext); callout_stop(&xfer->timeout_handle);