GitLab has been upgraded to 13.3.6. If you encounter any issues mail code@riscosopen.org

Commit 75f42235 authored by Jeffrey Lee's avatar Jeffrey Lee

Fix aborts on reset/*rmkill USBDriver

Detail:
  c/cmodule, cmhg/modhead - Don't shutdown DWC layer during Service_USBDriver_Dying. Instead, only do it during Service_ModulePostFinal/Service_PreReset(/module finialisation). Also during Service_PreReset, deregister with USBDriver. This ensures we're deregistered with USBDriver before we shut down the DWC layer, and so don't have to worry about receiving events from USBDriver after the DWC layer is shut down.
  c/dwc_common_riscos, c/dwc_otg_riscos, h/dwc_common_riscos - Improve handling of DWC endpoint disable callbacks. The memory block for the endpoint now has a flag set in its header when a callback is pending, allowing us to avoid double-free situations if both ourselves and the DWC layer decide to free the endpoint.
  c/softc_root - Correct some debug messages
  dwc/driver/c/dwc_otg_hcd - Fix qh_list_free to use DWC_LIST_FOREACH_SAFE (as dwc_otg_hcd_qh_remove_and_free will remove entries from the list) - fixes potential double-free if a non-empty list is being freed
  dwc/driver/c/dwc_otg_hcd_intr - Fix building of debug builds
Admin:
  Tested in Pi ROM with high processor vectors
  Resets and killing/reiniting USBDriver now works properly


Version 0.08. Tagged as 'DWCDriver-0_08'
parent 2c8ed4d4
/* (0.07)
/* (0.08)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.07
#define Module_MajorVersion_CMHG 0.08
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 02 Aug 2012
#define Module_Date_CMHG 04 Aug 2012
#define Module_MajorVersion "0.07"
#define Module_Version 7
#define Module_MajorVersion "0.08"
#define Module_Version 8
#define Module_MinorVersion ""
#define Module_Date "02 Aug 2012"
#define Module_Date "04 Aug 2012"
#define Module_ApplicationDate "02-Aug-12"
#define Module_ApplicationDate "04-Aug-12"
#define Module_ComponentName "DWCDriver"
#define Module_ComponentPath "mixed/RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver"
#define Module_FullVersion "0.07"
#define Module_HelpVersion "0.07 (02 Aug 2012)"
#define Module_LibraryVersionInfo "0:7"
#define Module_FullVersion "0.08"
#define Module_HelpVersion "0.08 (04 Aug 2012)"
#define Module_LibraryVersionInfo "0:8"
......@@ -343,6 +343,7 @@ void module_services(int service_number, _kernel_swi_regs *r, void *pw)
}
}
break;
#if 0 /* Don't shutdown the driver here, wait for ModulePostFinal. This avoids us having to deal with USBDriver calling us to close pipes and cancel transfers after we've shutdown the DWC layer */
case Service_USBDriver_Dying:
dprintf (("", "Deregistering with USB driver\n"));
/* USBDriver will do the deregistering at this point, since
......@@ -352,13 +353,26 @@ void module_services(int service_number, _kernel_swi_regs *r, void *pw)
usb_soft = NULL;
shutdown_driver();
break;
#endif
default:break;
}
break;
case Service_PreReset:
dprintf (("", "Svce prereset %x %x\n",Service_PreReset,service_number));
shutdown_driver(); /* Should be safe to do this without deregistering the bus */
if (usb_soft != NULL)
{
_swix (USBDriver_DeRegisterBus, _IN(0), usb_soft);
usb_soft=NULL;
}
shutdown_driver();
break;
case Service_ModulePostFinal:
if(!strcmp((const char *) r->r[2],"USBDriver"))
{
dprintf(("","Svce postfinal USBDriver\n"));
usb_soft = NULL;
shutdown_driver();
}
default:break;
}
}
......@@ -446,6 +460,7 @@ riscos_cancel_abort_pipe (void* v)
_kernel_oserror *endpoint_disable_cb(_kernel_swi_regs *r,void *pw,void *handle)
{
dprintf(("","endpoint_disable_cb: %08x\n",handle));
dwc_otg_hcd_endpoint_disable(dwc_soft.hcd,handle,250);
return NULL;
}
......
......@@ -136,9 +136,12 @@ struct mem_chain {
union {
struct mem_chain *next; /* Free blocks point at the next block in the chain */
struct mem_chain **bucket; /* Allocated blocks point at the bucket they belong in */
uint32_t flags; /* Allocated blocks also have two flag bits in their bottom word */
} u;
};
#define BUCKET_FLAG_PENDING_CB 1 /* an endpoint_disable_cb is pending for this alloc. This flags avoids us having multiple pending disable callbacks for the same endpoint, and allows us to cancel our callback if DWC decides to free the endpoint before we do */
static struct mem_chain *mem_buckets[MAX_BUCKET_SIZE/BUCKET_GRANULARITY];
void *__DWC_ALLOC(uint32_t size)
......@@ -174,6 +177,7 @@ void *__DWC_ALLOC(uint32_t size)
}
block->u.bucket = bucket;
memset(block+1,0,size-8); /* Subtract 8 bytes for heap block header and our header */
dprintf(("","dwc_alloc -> %08x\n",block+1));
return block+1;
}
......@@ -187,7 +191,15 @@ void __DWC_FREE(void *addr)
{
if(!addr)
return;
dprintf(("","dwc_free -> %08x\n",addr));
struct mem_chain *block = ((struct mem_chain *) addr)-1;
uint32_t flags = block->u.flags & 0x3;
block->u.flags &= ~flags;
if(flags & BUCKET_FLAG_PENDING_CB)
{
dprintf(("","cancelling endpoint_disable_cb\n"));
callx_remove_callback(endpoint_disable_cb,addr);
}
struct mem_chain **bucket = block->u.bucket;
if(!bucket)
{
......@@ -209,6 +221,18 @@ char *DWC_STRDUP(char const *str)
return c;
}
void register_endpoint_disable_cb(void *addr)
{
if(!addr)
return;
struct mem_chain *block = ((struct mem_chain *) addr)-1;
dprintf(("","register_endpoint_disable_cb: %08x %d\n",addr,block->u.flags & BUCKET_FLAG_PENDING_CB));
if(block->u.flags & BUCKET_FLAG_PENDING_CB)
return;
block->u.flags |= BUCKET_FLAG_PENDING_CB;
callx_add_callback(endpoint_disable_cb,addr);
}
/* Wait queues */
struct dwc_waitq_entry
......
......@@ -45,6 +45,7 @@
#include "dwc_os.h"
#include "dwc_otg_riscos.h"
#include "dwc_common_riscos.h"
#include "dwc/driver/dwc_otg_hcd_if.h"
#include "dwc/driver/dwc_otg_dbg.h"
......@@ -396,7 +397,7 @@ static int hcd_op_complete(dwc_otg_hcd_t *hcd,void *urb_handle,dwc_otg_hcd_urb_t
*/
if(epipe->request)
{
callx_add_callback(endpoint_disable_cb,epipe->dwc_priv);
register_endpoint_disable_cb(epipe->dwc_priv);
epipe->dwc_priv = 0;
}
......
......@@ -357,7 +357,7 @@ void softc_root_ctrl_abort(usbd_xfer_handle xfer)
void softc_root_ctrl_close(usbd_pipe_handle pipe)
{
DPRINTF(("musb_root_ctrl_close\n"));
DPRINTF(("softc_root_ctrl_close\n"));
/* Nothing to do. */
NOTUSED(pipe);
}
......@@ -396,7 +396,7 @@ void softc_root_intr_abort(usbd_xfer_handle xfer)
int s;
if (xfer->pipe->intrxfer == xfer) {
DPRINTF(("musb_root_intr_abort: remove\n"));
DPRINTF(("softc_root_intr_abort: remove\n"));
xfer->pipe->intrxfer = NULL;
}
xfer->status = USBD_CANCELLED;
......@@ -409,7 +409,7 @@ void softc_root_intr_close(usbd_pipe_handle pipe)
{
dwc_softc_t *sc = (dwc_softc_t *)pipe->device->bus;
DPRINTF(("musb_root_intr_close\n"));
DPRINTF(("softc_root_intr_close\n"));
sc->sc_intrxfer = NULL;
}
......
......@@ -21,7 +21,8 @@ initialisation-code: module_init
finalisation-code: module_final
service-call-handler: module_services Service_USB,
Service_PreReset
Service_PreReset,
Service_ModulePostFinal
title-string: COMPONENT
......
......@@ -696,7 +696,7 @@ static void reset_tasklet_func(void *data)
static void qh_list_free(dwc_otg_hcd_t * hcd, dwc_list_link_t * qh_list)
{
dwc_list_link_t *item;
dwc_list_link_t *item,*item_tmp;
dwc_otg_qh_t *qh;
if (!qh_list->next) {
......@@ -707,7 +707,7 @@ static void qh_list_free(dwc_otg_hcd_t * hcd, dwc_list_link_t * qh_list)
/* Ensure there are no QTDs or URBs left. */
kill_urbs_in_qh_list(hcd, qh_list);
DWC_LIST_FOREACH(item, qh_list) {
DWC_LIST_FOREACH_SAFE(item, item_tmp, qh_list) {
qh = DWC_LIST_ENTRY(item, dwc_otg_qh_t, qh_list_entry);
dwc_otg_hcd_qh_remove_and_free(hcd, qh);
}
......
......@@ -63,7 +63,7 @@ int32_t dwc_otg_hcd_handle_intr(dwc_otg_hcd_t * dwc_otg_hcd)
dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
gintsts_data_t gintsts;
#ifdef SOF_FIX
#if defined(SOF_FIX) || defined(DEBUG)
dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
gintmsk_data_t gintmsk;
#endif
......
......@@ -31,4 +31,6 @@
extern _kernel_oserror *dwc_common_riscos_init(void);
extern void dwc_common_riscos_shutdown(void);
extern void register_endpoint_disable_cb(void *addr);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment