Commits (34)
  • Jeffrey Lee's avatar
    Handle absolute pointing devices in a more sensible manner · 59cb172b
    Jeffrey Lee authored
    Detail:
      build/c/usbmouse - For absolute pointing devices, use the PointerV_Report "Abso" call to report absolute positions instead of relative
      build/Version - Bump USBDriver version number
    Admin:
      Based on code supplied by Chris Mahoney; allows USB touchscreens such as the Adafruit AR1100 to work under RISC OS
      Tested locally in an Iyonix ROM build (with regular mouse)
    
    
    Version 0.94. Tagged as 'NetBSD-0_94'
    59cb172b
  • Robert Sprowson's avatar
    Fix to system variable launch & debug build · a9d698a9
    Robert Sprowson authored
    ohcimodule.c:
     Variable renamed so it builds with debug enabled.
    usbmodule.c:
     Tighten up the logic deciding when to launch a USB$<thing> variable, previously it would be launched both for the initial device attach and then again for each interface.
     Remove local <stdlib.h> function prototypes.
     Reindent to 4 spaces to match the rest of the file.
     Fix confusion of ->dv_unit being an int not a pointer.
    Submission from Colin Granville. Built, but not tested.
    
    Version 0.95. Tagged as 'NetBSD-0_95'
    a9d698a9
  • Robert Sprowson's avatar
    Build fix · 656fe21f
    Robert Sprowson authored
    Don't set RES_OBJ to an empty string.
    Rename merged messages variable to be merged resources dir (even though not used in that manner here).
    
    Version 0.96. Tagged as 'NetBSD-0_96'
    656fe21f
  • Jeffrey Lee's avatar
    Add memory barriers · c3ccfd15
    Jeffrey Lee authored
    Detail:
      dev/usb/h/usb_port - Implement usb_syncmem to call the appropriate memory barrier function. Required for when PCI_RAMAlloc starts returning Normal, non-cacheable memory rather than Device (although technically these barriers have always been needed for ARMv6+)
      build/c/port - Memory barrier implementation; uses the appropriate OS routine if available, otherwise uses a null op.
      build/Version - Bump EHCIDriver version number (the only module that uses these barriers so far)
    Admin:
      Tested on BB-xM, PandaBoard
    
    
    Version 0.97. Tagged as 'NetBSD-0_97'
    c3ccfd15
  • Robert Sprowson's avatar
    Trim unused headers · c5e9a6fa
    Robert Sprowson authored
    c5e9a6fa
  • Robert Sprowson's avatar
    Correction to include guard · f42c7dcf
    Robert Sprowson authored
    f42c7dcf
  • Robert Sprowson's avatar
    Export USBDriver definitions to normal location · c6cbb401
    Robert Sprowson authored
    USBDriver was not exporting its SWI (and other) definitions to the export directory like other modules do, meaning the host controller drivers all have to reach into this component to get their hands on it.
    Makefile:
      Export an assembler header, conversion to C, and SWI definitions from CMHG.
      Rationalise the dev/usb/h/* headers which are exported in addition to those that are pertinent to host controllers (was missing usbdivar, and was exporting unused usbdi_util).
      Export machine/h/bus too.
      As it's unusual for a CModule to output both a library and module and headers, the EXPDIR has been divided into EXPLIBDIR for those things in C:USB, and EXPDIR for the others.
    ehcimodule.c/ohcimodule.c:
      Use the exported USBDriver.h
    
    Version 0.98. Tagged as 'NetBSD-0_98'
    c6cbb401
  • ROOL's avatar
    Update USB device table · 3cb1f971
    ROOL authored
    From NetBSD 1.698.
    3cb1f971
  • ROOL's avatar
    Fix to interface matching function · 496328e3
    ROOL authored
    Use -1 as the invalid mark, so that an accidental match on interface=0 alternate=0 is no longer possible.
    Submission from Colin Granville.
    
    Version 0.99. Tagged as 'NetBSD-0_99'
    496328e3
  • Robert Sprowson's avatar
    Add some missing struct members · 2318e734
    Robert Sprowson authored
    From NetBSD dev/usb/usbdivar.h 1.109.
    As these extra members change the struct layout, bump the API version number too. Having carefully analysed which headers are actually required by host controllers (in NetBSD-0_98) also be explicit about them in Hdr/USBDriver rather than the former vague comment in h/usbdivar.
    
    Hdr/USBDriver:
      Relocate API define here.
    usbmodule.c:
      Include USBDriver.h to get the API define.
    usbdivar.h:
      Add struct members from recent NetBSD.
    
    Version 1.00. Tagged as 'NetBSD-1_00'
    2318e734
  • ROOL's avatar
    Allow the endpoint validation string to include a direction flag · 1d4b111e
    ROOL authored
    However, internally we get that info from the descriptor, so mask it off.
    Submission from Colin Granville.
    
    No version number bump, it's already been incremented today.
    
    Version 1.01. Tagged as 'NetBSD-1_01'
    1d4b111e
  • Robert Sprowson's avatar
    Build fix · d86cd0ec
    Robert Sprowson authored
    In products using OHCIDriver/EHCIDriver when they came to do a header export would overwrite the USBDriver header with an empty one.
    d86cd0ec
  • John Ballance's avatar
    Minor makefile correction to enable o_hal component creation, and change to... · fe80026a
    John Ballance authored
    Minor makefile correction to enable o_hal component creation, and change to !MkExport to export EHCI and OHCI elements as well
    
    Detail:
    Admin:
      tested in iMx6 build
    
    
    Version 1.02. Tagged as 'NetBSD-1_02'
    fe80026a
  • ROOL's avatar
    Update table of device quirks · 02ba7000
    ROOL authored
    Detail:
      From NetBSD usb_quirks.c revision 1.81.
      usbmodule: NULL is for pointer types, not ints.
      usb_quirks: Group the RISC OS specific ones together, disable the non applicable UQ_APPLE_ISO ones, UQ_LOST_CS_DESC doesn't apply either but is only used for USB modem drivers not ported here. Untangle ifdefs around usbd_find_quirk().
    Admin:
      Removed unused source file ums.c
    
    Version 1.03. Tagged as 'NetBSD-1_03'
    02ba7000
  • Robert Sprowson's avatar
    Internationalisation, help, and syntax improvments · 2f96fb78
    Robert Sprowson authored
    Assign a proper error number and translate "Incompatible USBDriver version".
    Don't bother internationalising the *commands which are for debug builds only.
    Rephrase the help for USBQuirk so it makes sense, and trim the unmatched '<' from the syntax example.
    Bracket the USBDiscover help with the same switch that governs the code, which has been disabled for over a decade.
    
    Version 1.04. Tagged as 'NetBSD-1_04'
    2f96fb78
  • ROOL's avatar
    Add support for HAL_USBPortPower to EHCI host controller · 1a57aefd
    ROOL authored
    Detail:
      When signalled as a feature of the HAL device, call HAL_USBPortPower to turn on the port.
    Admin:
      Submission from Willi Theiss.
    
    Version 1.05. Tagged as 'NetBSD-1_05'
    1a57aefd
  • Ben Avison's avatar
    Fix HAL breakages caused by HAL_USBPortPower calls · 09c2d619
    Ben Avison authored
    Detail:
      In version 1.05, the USB library which is exported for the use of the HAL
      keyboard scan code unconditionally required the HAL_USBPortPower symbol.
      Not all HALs provide that entry point; for those that didn't, they would
      no longer link. Fixed by use of a bit of magic assembler.
    Admin:
      Verified that OMAP3 ROM now builds again.
    
    Version 1.06. Tagged as 'NetBSD-1_06'
    09c2d619
  • Robert Sprowson's avatar
    Resolve porting mistake on initial bus registration · 3ced0223
    Robert Sprowson authored
    On first registering a new bus in the the NetBSD build of the code usb_kthread_create(usb_create_event_thread, sc) is called which in turn creates the main event thread ("usb_event_thread").
    The first thing usb_event_thread() does is set
      sc->sc_bus->needs_explore = 1;
      usb_discover(sc);
    however in the RISC OS version of the code (usb.c around line 254) only the first action is performed, no discover happens.
    This change schedules a callback via usb_needs_explore_callback() which in turn calls discover_callback() when the OS is next free, which calls usb_discover() for each bus in an equivalent way to NetBSD's event thread. There's then no longer any need for the special one-shot 11s rediscover callback, only the repeating 30s rediscover is needed.
    
    For reference, the places that set needs_explore in this version are all in usb.c
      Line 254: set, but doesn't schedule a callback, as noted above
      Line 339: code not compiled for __riscos
      Line 548: set, does schedule a callback
      Line 727: cleared, in usb_discover()
      Line 743: set, does schedule a callback
      Line 756: code not called in RISC OS
    
    NetBSD uses 500ms initial delay before discover, then 60s between discovers (or until requested by a hub, whichever is sooner).
    RISC OS has a periodic callback of 30s (in usbmodule.c) and an initial discover of however long it is from the bus being registered until callbacks next fire usb_event_thread(), assumed ~500ms.
    
    Version 1.07. Tagged as 'NetBSD-1_07'
    3ced0223
  • ROOL's avatar
    Add support for HC with hardware enumerate phase · 25810b20
    ROOL authored
    Detail:
      Support controllers such as the XHCI which perform some steps of enumeration themselves in hardware, thereby needing some steps of the software enumeration to be bypassed.
      usb.c:
        Internally permit addr of 0, to represent the root hub, since the controller is responsible for allocating 1+. Merged from NetBSD 1.144.
      usb_subr.c:
        Test pointers against NULL not 0. Merged from NetBSD 1.191.
        Add 4 new bus methods, for prior to enumeration, address assignment phase, post enumeration fixup, and device removal.
      usbdivar.h:
        Prototypes of 4 new bus methods.
    Admin:
      HC API version number bumped.
      Submission from Elesar.
    
    Version 1.08. Tagged as 'NetBSD-1_08'
    25810b20
  • ROOL's avatar
    Init structures for OHCI & EHCI unused members · 15af186e
    ROOL authored
    Detail:
      Play safe, put NULLs in for the unused HC overrides.
    
    Version 1.08. Not tagged
    15af186e
  • Robert Sprowson's avatar
    Don't build a veneer that points to nothing · 4a445ff6
    Robert Sprowson authored
    The safety struct fillers added in OHCIDriver 0.44 and EHCIDriver 0.30 respectively were being carefully replaced by veneers to nothing. Skip veneer generation is the method isn't implemented.
    
    Version 1.09. Tagged as 'NetBSD-1_09'
    4a445ff6
  • John Ballance's avatar
    Fixes for Isochronous data transfer · c7052860
    John Ballance authored
    Detail:
    Frontend
    ========
    
    NetBSD.build.c.usbmodule
    	frontend isochronous changes
    	forces reads to always be multiple of maxpacket
    NetBSD.dev.usb.c.usb_subr
    	datatoggle fix
    	panic fix
    NetBSD.dev.usb.c.usbdi
    	usbd_transfer changed so that bufrem is passed the xfer pointer instead of the buffer pointer
    	fixed missing braces in usbd_clear_endpoint_stall
    
    EHCI
    ====
    
    The HS (USB2) isochronous as been rewritten and isochronous split transactions - FS (USB1) over a HS Connection - has been added
    
    NetBSD.dev.usb.c.ehci
    NetBSD.dev.usb.h.ehcireg
    NetBSD.dev.usb.h.ehcivar
    
    OHCI
    ====
    
    Changes to the NetBSD backend to get isochronous transfers working on a OHCI device. While it did have isochronous support it wasn't working properly.
    
    NetBSD.dev.usb.c.ohci
    
    Admin:
      Submitted by Colin Granville
    Tested in iMx6
    
    Version 1.10. Tagged as 'NetBSD-1_10'
    c7052860
  • John Ballance's avatar
    Updated module versions to better identify recent changes · 30334cb8
    John Ballance authored
    Admin:
    
    
    Version 1.11. Tagged as 'NetBSD-1_11'
    30334cb8
  • ROOL's avatar
    Revert accidental commits · 0cd6671a
    ROOL authored
    Admin:
      These changes are currently subject to rework via the normal submissions channel.
    0cd6671a
  • Jeffrey Lee's avatar
    Don't pretend to mess with cacheability of pages · 1b483023
    Jeffrey Lee authored
    Detail:
      build/c/port - Fix vtophys requesting that pages are made uncacheable. They're already uncacheable (all allocated via PCI_RAMAlloc), and once we're done with the pages we never do a 'make cacheable' call to balance it out
      build/Version - Bump version numbers of modules which use vtophys
    Admin:
      Untested
    
    
    Version 1.10. Tagged as 'NetBSD-1_10'
    1b483023
  • Jeffrey Lee's avatar
    Fix tagging mess with the reverted changes - move tag for current version beyond 1_10/1_11 · dfd6481c
    Jeffrey Lee authored
    Version 1.12. Tagged as 'NetBSD-1_12'
    dfd6481c
  • Robert Sprowson's avatar
    Fix for too short a memset · 6286e1ad
    Robert Sprowson authored
    Found by pattern matching, this is the same change as DWCDriver-0_27.
    
    Version 1.13. Tagged as 'NetBSD-1_13'
    6286e1ad
  • Jeffrey Lee's avatar
    Use HAL_TimerIRQClear in HAL library · 8755ffc9
    Jeffrey Lee authored
    Detail:
      build/c/usbhal - Don't assume HAL_IRQClear will clear the timer interrupt, use HAL_TimerIRQClear as well.
    Admin:
      Tested on BB-xM
    
    
    Version 1.14. Tagged as 'NetBSD-1_14'
    8755ffc9
  • Robert Sprowson's avatar
    Fix for uninitialised wMaxPacketSize causing enumeration FS failure · dcef3f13
    Robert Sprowson authored
    The order of the new device enumeration means we have the initial device descriptor (hence bMaxPacketSize) but don't compute wMaxPacketSize until after addressing.
    The XHCI HC needs this value by the addressing stage in order to setup the control endpoint context (other HC don't need it until later) so the specific case of a full speed device whose endpoint 0 has a non default max packet size would be set up using the default (of 64), then when the full device descriptor is requested the packet looks like a short transfer and the transaction ends having only collected (eg) 8 bytes. This would then appear as vendor &0000 product &0000 and not get any further.
    Tested on Titanium.
    
    Version 1.15. Tagged as 'NetBSD-1_15'
    dcef3f13
  • Jeffrey Lee's avatar
    Revise TouchBook touchpad fix · 6360b406
    Jeffrey Lee authored
    Detail:
      build/c/usbmouse - Because the touchpad sends data that's consistent with a Boot protocol mouse, the data it sends is shorter than the expected size. This can result in bogus scroll wheel data being read from off the end of the buffer. Fix this by completely ignoring the report descriptor that the device returns and instead using a descriptor that's consistent with a Boot protocol mouse.
      build/Version - Increase USBDriver version number
    Admin:
      Tested on TouchBook
      Fixes issue seen where garbage data at the end of the buffer would result in windows scrolling for every mouse interrupt
    
    
    Version 1.16. Tagged as 'NetBSD-1_16'
    6360b406
  • ROOL's avatar
    Case change to match documentation · 7a2b2a81
    ROOL authored
    Detail:
      DeRegisterBus->DeregisterBus. Since clients calling this SWI are compiled C or assembler, this doesn't affect existing modules which remain binary compatible.
    Admin:
      Submission for USB bounty.
    
    Version 1.17. Tagged as 'NetBSD-1_17'
    7a2b2a81
  • ROOL's avatar
    Messages fixes, internationalisation, minor clean ups · 6460aa49
    ROOL authored
    Detail:
      USBDriver was performing unnecessary messages file reopening on Service_ResourceFSStarted (MessageTrans does this itself), remove this.
      Internationalised USBDriver, in particular its *Commands.
      Fixed standalone builds to output the messages file objects in the right place (Makefile mistake).
      Changed OHCIDriver and EHCIDriver to use allocated error bases rather than 0.
      Sync'd, where possible, the OHCIDriver and EHCIDriver sources which share a common heritage. Tentative shared interrupt support fixes for non-PCI attached controllers. Comment blocks & indentation improved.
      Export min() macro in usb_port.h.
      CMHG updated to not listen for unwanted services.
    Admin:
      Submission for USB bounty.
      Tested on Pandaboard and Pi 2. OHCIDriver untested but low risk.
    
    Version 1.18. Tagged as 'NetBSD-1_18'
    6460aa49
  • ROOL's avatar
    Missing newline from device info printout · bf77d323
    ROOL authored
    Detail:
      During internationalisation, the last line lost its newline.
    Admin:
      Submission from Colin Granville.
    
    Version 1.19. Tagged as 'NetBSD-1_19'
    bf77d323
  • ROOL's avatar
    Get a new tag · 57d31931
    ROOL authored
    Admin:
      This is a (server side) copy of the component previously called RiscOS/Sources/HWSupport/USB/NetBSD to be used for ongoing development, retaining the significant revision history.
      Submission for USB bounty.
    57d31931
/* (0.93)
/* (1.19)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.93
#define Module_MajorVersion_CMHG 1.19
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 06 Jan 2015
#define Module_Date_CMHG 15 Jul 2017
#define Module_MajorVersion "0.93"
#define Module_Version 93
#define Module_MajorVersion "1.19"
#define Module_Version 119
#define Module_MinorVersion ""
#define Module_Date "06 Jan 2015"
#define Module_Date "15 Jul 2017"
#define Module_ApplicationDate "06-Jan-15"
#define Module_ApplicationDate "15-Jul-17"
#define Module_ComponentName "NetBSD"
#define Module_ComponentPath "mixed/RiscOS/Sources/HWSupport/USB/NetBSD"
#define Module_ComponentName "USBDriver"
#define Module_ComponentPath "mixed/RiscOS/Sources/HWSupport/USB/USBDriver"
#define Module_FullVersion "0.93"
#define Module_HelpVersion "0.93 (06 Jan 2015)"
#define Module_LibraryVersionInfo "0:93"
#define Module_FullVersion "1.19"
#define Module_HelpVersion "1.19 (15 Jul 2017)"
#define Module_LibraryVersionInfo "1:19"
......@@ -15,3 +15,7 @@
Dir <Obey$Dir>
amu_machine export PHASE=hdrs COMPONENT=USBDriver
amu_machine export PHASE=libs COMPONENT=USBDriver
amu_machine export PHASE=hdrs COMPONENT=EHCIDriver
amu_machine export PHASE=libs COMPONENT=EHCIDriver
amu_machine export PHASE=hdrs COMPONENT=OHCIDriver
amu_machine export PHASE=libs COMPONENT=OHCIDriver
; Copyright 2015 Castle Technology Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
SUBT Exported USBDriver constants
OldOpt SETA {OPT}
OPT OptNoList+OptNoP1List
SWIClass SETS USBDriverSWI_Name
^ USBDriverSWI_Base
AddSWI USBDriver_RegisterBus
AddSWI USBDriver_DeregisterBus
AddSWI USBDriver_InsertTransfer
AddSWI USBDriver_TransferComplete
AddSWI USBDriver_ScheduleSoftInterrupt
AddSWI USBDriver_Version
; The structures in the 4 exported headers
; NetBSD/dev/usb/h/usb NetBSD/dev/usb/h/usbdivar
; NetBSD/dev/usb/h/usbdi NetBSD/dev/usb/h/usb_port
; are used by the USB host controller drivers to communicate with the main
; USBDriver module. Thus, we need to make sure that they only register
; with USBDriver if both modules use compatible structure definitions.
; So, whenever you make a backwards-incompatible change to these shared
; structures, make sure you update this API version to the version of the
; USBDriver module that first implemented those changes (not the dummy value
; in VersionNum file!).
RISCOS_USBDRIVER_API_VERSION * 80
OPT OldOpt
END
......@@ -23,7 +23,6 @@ CUSTOMEXP = custom
COMPONENT ?= NetBSD
CINCLUDES = -Itbox:,TCPIPLibs:,^.,OS:,C:USB
CDEFINES += ${CDEBUG} -DKERNEL -D_KERNEL -Dpaddr_t=int -D__P(A)=A -DKLD_MODULE -DDISABLE_PACKED
RES_OBJ =
RES_AREA = resource_files
LIBS = ${CALLXLIB} ${ASMUTILS}
......@@ -44,15 +43,17 @@ ifeq ("${COMPONENT}","EHCIDriver")
CMHGFILE = ehcimodhead
CMHGDEPENDS = ehcimodule
MSGS_ORIGIN = LocalRes:EHCIMessages
MSGS_DEST = Resources.EHCIDriver.Messages
OBJS = ehcimodule ehci port call_veneer \
triggercbs usbroothub_subr
OBJS_HAL = o_hal.ehci o_hal.usbroothub_subr o_hal.ehcihal
OBJS_HAL = o_hal.ehci o_hal.usbroothub_subr o_hal.ehcihal o_hal.ehcihalasm
endif
ifeq ("${COMPONENT}","OHCIDriver")
CMHGFILE = ohcimodhead
CMHGDEPENDS = ohcimodule
MSGS_ORIGIN = LocalRes:OHCIMessages
MSGS_DEST = Resources.OHCIDriver.Messages
OBJS = ohcimodule ohci port call_veneer \
triggercbs
OBJS_HAL = o_hal.ohci
......@@ -62,6 +63,7 @@ ifeq ("${COMPONENT}","USBDriver")
CMHGFILE = usbmodhead
CMHGDEPENDS = usbmouse usbmodule usbkboard
MSGS_ORIGIN = LocalRes:USBMessages
MSGS_DEST = Resources.USBDriver.Messages
OBJS = usbmodule port usb usbdi usb_subr \
usbdi_util usb_quirks uhub usbmouse usbkboard \
hid bufman triggercbs call_veneer
......@@ -78,7 +80,7 @@ include CModule
CFLAGS += -wp -wc
LDFLAGS += -LIST maps.${TARGET} -MAP -Xref -Symbols rm.sym${TARGET}
DBG_LIBS += ${NET5LIBS}
EXPDIR = <Lib$Dir>.USB
EXPLIBDIR = <Lib$Dir>.USB
#
# HAL library rules
......@@ -115,27 +117,42 @@ ${DIRS}::
${MKDIR} maps
${MKDIR} bin
export: export_${PHASE}
export: export_${PHASE}_${COMPONENT}
@${NOP}
export_libs: ${EXPDIR}.o.${COMPONENT}
@echo ${COMPONENT}: library export complete
export_hdrs: ^.dev.usb.h.usbdevs
${MKDIR} ${EXPDIR}.dev.usb.h
${MKDIR} ${EXPDIR}.h
${MKDIR} ${EXPDIR}.sys.h
${MKDIR} ${EXPDIR}.Hdr
${CP} ^.dev.usb.h.usb ${EXPDIR}.dev.usb.h.usb ${CPFLAGS}
${CP} ^.dev.usb.h.usbdevs ${EXPDIR}.dev.usb.h.usbdevs ${CPFLAGS}
${CP} ^.dev.usb.h.usbdi ${EXPDIR}.dev.usb.h.usbdi ${CPFLAGS}
${CP} ^.dev.usb.h.usbdi_util ${EXPDIR}.dev.usb.h.usbdi_util ${CPFLAGS}
${CP} ^.dev.usb.h.usb_port ${EXPDIR}.dev.usb.h.usb_port ${CPFLAGS}
${CP} h.USBDevFS ${EXPDIR}.h.USBDevFS ${CPFLAGS}
${CP} ^.sys.h.device ${EXPDIR}.sys.h.device ${CPFLAGS}
${CP} ^.VersionNum ${EXPDIR}.LibVersion ${CPFLAGS}
${CP} Hdr.usbhal ${EXPDIR}.Hdr.usbhal ${CPFLAGS}
@echo ${COMPONENT}: header export complete
export_libs_${COMPONENT}: ${EXPLIBDIR}.o.${COMPONENT}
@${ECHO} ${COMPONENT}: library export complete
export_hdrs_USBDriver: h.${CMHGFILE} ^.dev.usb.h.usbdevs
${MKDIR} o
${MKDIR} ${EXPLIBDIR}.dev.usb.h
${MKDIR} ${EXPLIBDIR}.sys.h
${MKDIR} ${EXPLIBDIR}.machine.h
${MKDIR} ${EXPLIBDIR}.h
${MKDIR} ${EXPLIBDIR}.Hdr
# DeviceFS/Service call interface
${CP} h.USBDevFS ${EXPLIBDIR}.h.USBDevFS ${CPFLAGS}
# Host driver interface
${CP} ^.dev.usb.h.usb ${EXPLIBDIR}.dev.usb.h.usb ${CPFLAGS}
${CP} ^.dev.usb.h.usbdi ${EXPLIBDIR}.dev.usb.h.usbdi ${CPFLAGS}
${CP} ^.dev.usb.h.usbdivar ${EXPLIBDIR}.dev.usb.h.usbdivar ${CPFLAGS}
${CP} ^.dev.usb.h.usb_port ${EXPLIBDIR}.dev.usb.h.usb_port ${CPFLAGS}
${CP} ^.sys.h.device ${EXPLIBDIR}.sys.h.device ${CPFLAGS}
${CP} ^.machine.h.bus ${EXPLIBDIR}.machine.h.bus ${CPFLAGS}
${CP} ^.VersionNum ${EXPLIBDIR}.LibVersion ${CPFLAGS}
# Workspace size for HAL allocation (only)
${CP} Hdr.usbhal ${EXPLIBDIR}.Hdr.usbhal ${CPFLAGS}
# Conversion of the USB device database
${CP} ^.dev.usb.h.usbdevs ${EXPLIBDIR}.dev.usb.h.usbdevs ${CPFLAGS}
# Equivalent of ASMHDRS and ASMCHDRS and CMHGAUTOHDR
${CP} Hdr.USBDriver ${EXP_HDR}.USBDriver ${CPFLAGS}
${HDR2H} Hdr.USBDriver ${C_EXP_HDR}.USBDriver
${DO} ${AWK} -- "/.ifndef ${CMHGFILE_SWIPREFIX}/,/endif/" h.${CMHGFILE} > o._h_USBDriver
${FAPPEND} ${C_EXP_HDR}.USBDriver ${C_EXP_HDR}.USBDriver o._h_USBDriver
@${ECHO} ${COMPONENT}: header export complete
export_hdrs_EHCIDriver export_hdrs_OHCIDriver:
@${ECHO} ${COMPONENT}: header export complete
resources: resources_${COMPONENT}
......@@ -143,20 +160,20 @@ resources_OHCIDriver: LocalRes:OHCIMessages
${MKDIR} ${RESFSDIR}
${TOKENCHECK} LocalRes:OHCIMessages
${CP} LocalRes:OHCIMessages ${RESFSDIR}.Messages ${CPFLAGS}
@echo ${COMPONENT}: resources copied to Messages module
@${ECHO} ${COMPONENT}: resources copied to Messages module
resources_EHCIDriver: LocalRes:EHCIMessages
${MKDIR} ${RESFSDIR}
${TOKENCHECK} LocalRes:EHCIMessages
${CP} LocalRes:EHCIMessages ${RESFSDIR}.Messages ${CPFLAGS}
@echo ${COMPONENT}: resources copied to Messages module
@${ECHO} ${COMPONENT}: resources copied to Messages module
resources_USBDriver: LocalRes:USBDriver ${DEVICELIST}
${MKDIR} ${RESFSDIR}
${TOKENCHECK} LocalRes:USBMessages
${CP} LocalRes:USBMessages ${RESFSDIR}.Messages ${CPFLAGS}
${CP} ${DEVICELIST} ${RESFSDIR}.USBDevs ${CPFLAGS}
@echo ${COMPONENT}: resources copied to Messages module
@${ECHO} ${COMPONENT}: resources copied to Messages module
#
# Static dependencies
......@@ -164,17 +181,16 @@ resources_USBDriver: LocalRes:USBDriver ${DEVICELIST}
^.dev.usb.h.usbdevs ^.dev.usb.h.usbdevs_data: ^.dev.usb.usbdevs ^.dev.usb.devlist2h/awk
${GAWK} -v os="${UNAME} -s" -f ^.dev.usb.devlist2h/awk ^.dev.usb.usbdevs
${EXPDIR}.o.${COMPONENT}: ${OBJS_HAL} ${DIRS}
${MKDIR} ${EXPDIR}.o
${EXPLIBDIR}.o.${COMPONENT}: ${OBJS_HAL} ${DIRS}
${MKDIR} ${EXPLIBDIR}.o
${AR} ${ARFLAGS} $@ ${OBJS_HAL}
${MERGEDMDIR}.${COMPONENT}Msgs: ${MSGS_ORIGIN}
${MKDIR} ${MERGEDMDIR}
${MERGEDRDIR}.${COMPONENT}Msgs: ${MSGS_ORIGIN}
${MKDIR} ${MERGEDRDIR}
${TOKENCHECK} ${MSGS_ORIGIN}
${CP} ${MSGS_ORIGIN} $@ ${CPFLAGS}
o.${COMPONENT}Res od.${COMPONENT}Res: ${MERGEDMDIR}.${COMPONENT}Msgs ${DIRS}
${RESGEN} ${RES_AREA} $@ ${MERGEDMDIR}.${COMPONENT}Msgs ${RES_PATH}
o.${COMPONENT}Res od.${COMPONENT}Res: ${MERGEDRDIR}.${COMPONENT}Msgs ${DIRS}
${RESGEN} ${RES_AREA} $@ ${MERGEDRDIR}.${COMPONENT}Msgs ${MSGS_DEST}
# Dynamic dependencies:
......@@ -2,11 +2,11 @@
VersionNum file really,as a work around define them here so the CMHG
file remains unaltered */
#define OHCIDriverModule_Module_Date_CMHG 05 Jan 2015
#define OHCIDriverModule_MajorVersion_CMHG 0.42
#define OHCIDriverModule_Module_Date_CMHG 17 Dec 2016
#define OHCIDriverModule_MajorVersion_CMHG 0.48
#define EHCIDriverModule_Module_Date_CMHG 05 Jan 2015
#define EHCIDriverModule_MajorVersion_CMHG 0.26
#define EHCIDriverModule_Module_Date_CMHG 17 Dec 2016
#define EHCIDriverModule_MajorVersion_CMHG 0.34
#define USBDriverModule_Module_Date_CMHG 02 Jan 2015
#define USBDriverModule_MajorVersion_CMHG 0.72
#define USBDriverModule_Module_Date_CMHG 18 Mar 2017
#define USBDriverModule_MajorVersion_CMHG 0.86
......@@ -52,6 +52,7 @@ extern size_t HAL_USBControllerInfo(int idx,usbinfo *info,size_t size);
extern int HAL_IRQEnable(int device);
extern int HAL_IRQDisable(int device);
extern void HAL_IRQClear(int device);
extern int (*GetHAL_USBPortPower(void))(int idx,int port,int state);
extern device_ptr_t register_bus(device_ptr_t bus);
static void init_device(usbinfo *info,int idx)
......@@ -71,6 +72,14 @@ static void init_device(usbinfo *info,int idx)
HAL_IRQEnable(ehci->sc_irqdevno);
/* Register with USBDriver */
register_bus((device_ptr_t) ehci);
/* Switch on the ports (if under HAL control) */
if(info->flags & HALUSBControllerFlag_HAL_Port_Power && GetHAL_USBPortPower() != NULL)
{
for (int i = 0; i < ehci->sc_noport; i++)
{
GetHAL_USBPortPower()(idx, i, 1);
}
}
}
void USBHAL_EHCIDriver_Init(void)
......
......@@ -12,13 +12,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ehcimodhead.h"
#include "USBDriver.h"
#include "swis.h"
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <machine/bus.h>
#include "swis.h"
#include <sys/queue.h>
#include <sys/types.h>
......@@ -34,20 +32,28 @@
#include "Global/Services.h"
#include "Global/HALEntries.h"
#include "Interface/PCI.h"
#include "Interface/USBDriver.h"
#include "callx/callx.h"
#include "toolbox.h"
/* Have to avoid including stdio as there's a clash with the BSD stuff */
#define __stdio_h
#include "ehcimodhead.h"
#include "DebugLib/DebugLib.h"
#include "USBDevFS.h"
#define ErrorBase_EHCIDriver 0x820A40
#define ErrorBlock_EHCI_NoReinit { (ErrorBase_EHCIDriver+0), "NumParm" }
#define ErrorBlock_EHCI_NoEHCI { (ErrorBase_EHCIDriver+1), "E01" }
#define ErrorBlock_EHCI_ClaimVeneer { (ErrorBase_EHCIDriver+2), "E02" }
#define ErrorBlock_EHCI_USBTooOld { (ErrorBase_EHCIDriver+3), "E03" }
typedef struct
{
int errnum;
char errtok[8];
} _kernel_tokerror;
extern uint64_t gettime (void);
/* for debugging */
#ifdef EHCI_DEBUG
extern int ehcidebug;
......@@ -58,48 +64,34 @@ int irq_device;
char debugname[16];
#endif
void* private_word;
volatile int* ehci_base;
ehci_softc_t ehci_soft;
struct device * usb_soft = NULL;
extern int * init_veneer (void);
//extern void* resource_files (void);
extern void* resource_files (void);
#ifdef EHCI_DEBUG
extern uint64_t gettime (void);
extern void ehci_dump_regs (ehci_softc_t *);
//extern void ehci_dump_ed (ehci_soft_ed_t*);
#endif
extern void ehci_abort_xfer (void*, int);
void* private_word;
MessagesFD mod_messages;
volatile int* ehci_base;
ehci_softc_t ehci_soft;
struct device * usb_soft = NULL;
int* magic = NULL;
int pci_device = -1;
int hal_device = -1;
int instance = 0;
int device_number;
int unhandled_irqs;
int registers_32bit=0;
static bool registering=false; /* True/false for whether we're in the middle of registering. Avoids nested registration attempt during ROM init. */
static bool hal_portpower = false; /* Whether to use HAL_PortPower to control the port */
/*---------------------------------------------------------------------------*/
/* Driver instance creation */
/*---------------------------------------------------------------------------*/
void build_veneer (int* vn, int* st, size_t sz)
{
int i;
......@@ -108,6 +100,9 @@ void build_veneer (int* vn, int* st, size_t sz)
for (i = 0; i < sz / sizeof (void*); ++i) {
int* entry = entry_table + 2 * i;
/* if the method isn't implemented, don't veneer it */
if (st[i] == NULL) continue;
/* copy function pointer into veneer */
vn[i] = st[i];
......@@ -131,14 +126,6 @@ void build_veneer (int* vn, int* st, size_t sz)
entry_table + 2 * (sz / sizeof (void*)) - 1);
}
int pci_device = -1;
int hal_device = -1;
int instance = 0;
int device_number;
int unhandled_irqs;
int registers_32bit=0;
static bool registering=false; /* True/false for whether we're in the middle of registering. Avoids nested registration attempt during ROM init. */
_kernel_oserror* register_bus(void *in,struct device **out)
{
*out = NULL;
......@@ -148,7 +135,13 @@ _kernel_oserror* register_bus(void *in,struct device **out)
if(e)
return e;
if(version < RISCOS_USBDRIVER_API_VERSION)
return (_kernel_oserror*)"\0\0\0\0USBDriver too old";
{
static const _kernel_tokerror err_usbtooold = ErrorBlock_EHCI_USBTooOld;
return _swix (MessageTrans_ErrorLookup, _INR(0,2),
&err_usbtooold, &mod_messages, 0 /* Internal buffer */);
}
/* Now attempt to register */
registering = true;
e = _swix(USBDriver_RegisterBus, _INR(0,1)|_OUT(0),in,RISCOS_USBDRIVER_API_VERSION,out);
......@@ -157,6 +150,26 @@ _kernel_oserror* register_bus(void *in,struct device **out)
return e;
}
static void name_root_hub(int pcidevice)
{
if (pci_device == -1)
{
_kernel_oserror *e;
e = _swix (MessageTrans_Lookup, _INR(0,3),
&mod_messages, "UkRoot", ehci_soft.sc_vendor, sizeof(ehci_soft.sc_vendor));
if (e) strcpy(ehci_soft.sc_vendor, " ");
}
else
{
char *v = NULL;
_swix (PCI_ReadInfo, _INR(0,3), PCI_ReadInfo_Vendor, &v, sizeof(v), pci_device);
if (v == NULL) v = " ";
strncpy (ehci_soft.sc_vendor, v, sizeof ehci_soft.sc_vendor-1);
}
}
_kernel_oserror* new_instance (_kernel_swi_regs* r, void* pw, void* h)
{
_kernel_oserror * e;
......@@ -164,8 +177,9 @@ _kernel_oserror* new_instance (_kernel_swi_regs* r, void* pw, void* h)
(void) r;
(void) pw;
/* fill in the device name in the callback so that our service call handler
is threaded and there to respond to PCI calls */
name_root_hub(pci_device);
/* register with the usbdriver module if it's already resident */
dprintf (("", "Registering with USB driver\n"));
......@@ -176,6 +190,14 @@ _kernel_oserror* new_instance (_kernel_swi_regs* r, void* pw, void* h)
}
else
{
if (hal_portpower)
{
for (int i = 0; i < ehci_soft.sc_noport; i++)
{
_swix(OS_Hardware, _INR(0,2) | _INR(8,9),
hal_device, i, 1, OSHW_CallHAL, EntryNo_HAL_USBPortPower);
}
}
dprintf (("", "Registering with USB driver-done\n"));
}
......@@ -195,8 +217,9 @@ _kernel_oserror* new_instance (_kernel_swi_regs* r, void* pw, void* h)
return NULL;
}
/*---------------------------------------------------------------------------*/
/* CMHG module initialisation */
/*---------------------------------------------------------------------------*/
_kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
_kernel_oserror* e = 0;
bool ettf = false;
......@@ -241,19 +264,30 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
pci_device = (int) strtol (endptr+1, NULL, 0);
else if(*endptr == 'H')
hal_device = (int) strtol (endptr+1, NULL, 0);
else if(*endptr > 32)
else
{
return (_kernel_oserror*)
"\1\0\0\0"Module_Title" can't be reinitialised";
static const _kernel_tokerror err_noreinit = ErrorBlock_EHCI_NoReinit;
return _swix (MessageTrans_ErrorLookup, _INR(0,2),
&err_noreinit, 0 /* Global messages */, 0 /* Internal buffer */);
}
else
pci_device = 0;
}
else
{
pci_device = 0;
#ifdef STANDALONE
/* Only first instance registers the messages in ResourceFS */
e = _swix (ResourceFS_RegisterFiles, _IN (0), resource_files ());
if (e != NULL) return e;
#endif
}
e = _swix (MessageTrans_OpenFile, _INR(0,2),
&mod_messages,
Module_MessagesFile,
0);
if (e) goto error_dereg;
/* find the next possible controller */
if(pci_device >= 0)
{
......@@ -304,7 +338,7 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
e = _swix(OS_Hardware, _INR(0,2)|_INR(8,9)|_OUT(0),
hal_device, &usbinfo, sizeof usbinfo,
0, EntryNo_HAL_USBControllerInfo,
OSHW_CallHAL, EntryNo_HAL_USBControllerInfo,
&usbinfolen);
if (!e && (usbinfolen == sizeof(usbinfo)) && (usbinfo.type == HALUSBControllerType_EHCI))
{
......@@ -315,16 +349,26 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
registers_32bit = 1;
if(usbinfo.flags & HALUSBControllerFlag_EHCI_ETTF)
ettf = true;
if(usbinfo.flags & HALUSBControllerFlag_HAL_Port_Power)
hal_portpower = true;
break;
}
else if(e || !usbinfolen)
{
/* Reached end of list */
return (_kernel_oserror*) "\0\0\0\0No EHCI devices found";
static const _kernel_tokerror err_noehci = ErrorBlock_EHCI_NoEHCI;
e = _swix (MessageTrans_ErrorLookup, _INR(0,2),
&err_noehci, &mod_messages, 0 /* Internal buffer */);
goto error;
}
} while(1);
}
memset (&ehci_soft, 0, sizeof ehci_soft);
sprintf (ehci_soft.sc_bus.bdev.dv_xname, "EHCI%d", instance);
ehci_soft.sc_irqdevno = device_number;
dprintf (("Main_0", "interrupt device %d\n", device_number));
dprintf (("Main_0", "hardware address %p\n", ehci_base));
......@@ -336,21 +380,21 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
irq0 = gettime () / 1000;
#endif
_swix (OS_ClaimDeviceVector, _INR(0,4),
device_number| (1u<<31), usb_irq_entry, pw, 0, 0);
_swix (OS_Hardware, _IN(0) | _INR(8,9),
device_number, 0, EntryNo_HAL_IRQEnable);
if ((magic = init_veneer ()) == NULL)
{
return (_kernel_oserror*) "\0\0\0\0Couldn't claim magic";
static const _kernel_tokerror err_claimveneer = ErrorBlock_EHCI_ClaimVeneer;
e = _swix (MessageTrans_ErrorLookup, _INR(0,2),
&err_claimveneer, &mod_messages, 0 /* Internal buffer */);
goto error;
}
dprintf (("", "magic at %p", magic));
memset (&ehci_soft, 0, sizeof ehci_soft);
sprintf (ehci_soft.sc_bus.bdev.dv_xname, "EHCI%d", instance);
ehci_soft.sc_irqdevno = device_number;
_swix (OS_ClaimDeviceVector, _INR(0,2),
device_number | ((pci_device == -1)?0:(1u<<31)),
usb_irq_entry, pw);
_swix (OS_Hardware, _IN(0) | _INR(8,9),
device_number, OSHW_CallHAL, EntryNo_HAL_IRQEnable);
if (ettf)
{
......@@ -363,28 +407,36 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
/* in BSD this is called from sys/pci/ehci_pci.c */
ehci_init (&ehci_soft);
dprintf (("", "Finished module initialisation\n"));
/* try and start a new instance to catch any more controllers on the bus */
/* try and start a new instance to catch any more controllers on the bus,
done in a callback so that this instance is threaded and the instance
count goes up */
/* also register with the usbdriver module if it's already resident */
callx_add_callback (new_instance, 0);
callx_add_callback (new_instance, 0);
return 0;
return NULL;
error:
dprintf (("","Failed initialisation: %s\n", e->errmess));
_swix (MessageTrans_CloseFile, _IN(0), &mod_messages);
error_dereg:
#ifdef STANDALONE
if (podule_base == 0) _swix (ResourceFS_DeregisterFiles, _IN(0), resource_files ());
#endif
return e;
}
/*---------------------------------------------------------------------------*/
/* CMHG module finalisation */
/*---------------------------------------------------------------------------*/
_kernel_oserror *module_final(int fatal, int podule, void *pw)
{
if (usb_soft != NULL)
{
_swix (USBDriver_DeRegisterBus, _IN(0), usb_soft);
_swix (USBDriver_DeregisterBus, _IN(0), usb_soft);
usb_soft=NULL;
}
// need to stop the controller
......@@ -395,18 +447,32 @@ _kernel_oserror *module_final(int fatal, int podule, void *pw)
/* don't disable the interrupt since it is shared, the OS will disable it
when noone is left responding */
// _swix (OS_Hardware, _IN(0) | _INR(8,9),
// device_number, 0, EntryNo_HAL_IRQDisable);
// device_number, OSHW_CallHAL, EntryNo_HAL_IRQDisable);
callx_remove_all_callbacks ();
callx_remove_all_callafters ();
callx_remove_all_calleverys ();
_swix (OS_ReleaseDeviceVector, _INR(0,4),
device_number | (1u<<31), usb_irq_entry, pw, 0, 0);
_swix (OS_ReleaseDeviceVector, _INR(0,2),
device_number | ((pci_device == -1)?0:(1u<<31)),
usb_irq_entry, pw);
if (magic) _swix (OS_Module, _IN(0)|_IN(2), 7, magic);
_swix (MessageTrans_CloseFile, _IN(0), &mod_messages);
#ifdef STANDALONE
/* only remove files for last instantiation */
if (podule == 0)
{
_swix (ResourceFS_DeregisterFiles, _IN (0), resource_files ());
}
#endif
return NULL;
}
/*---------------------------------------------------------------------------*/
/* CMHG module service calls */
/*---------------------------------------------------------------------------*/
void module_services(int service_number, _kernel_swi_regs *r, void *pw)
{
dprintf (("", "svce %x reason %x\n",service_number,r->r[0]));
......@@ -433,11 +499,13 @@ void module_services(int service_number, _kernel_swi_regs *r, void *pw)
case Service_USB_USBDriverDying:
dprintf (("", "Deregistering with USB driver\n"));
/* USBDriver will do the deregistering at this point, since
it's SWIs are not active anymore */
its SWIs are not active anymore */
ehci_detach(&ehci_soft,0);
ehci_shutdown(&ehci_soft);
usb_soft = NULL;
memset (&ehci_soft, 0, sizeof ehci_soft);
sprintf (ehci_soft.sc_bus.bdev.dv_xname, "EHCI%d", instance);
name_root_hub (pci_device);
ehci_init (&ehci_soft);
break;
default:break;
......@@ -452,16 +520,23 @@ void module_services(int service_number, _kernel_swi_regs *r, void *pw)
callx_remove_all_callbacks ();
callx_remove_all_callafters ();
callx_remove_all_calleverys ();
_swix (OS_ReleaseDeviceVector, _INR(0,4),
device_number | (1u<<31), usb_irq_entry, pw, 0, 0);
_swix (OS_ReleaseDeviceVector, _INR(0,2),
device_number | ((pci_device == -1)?0:(1u<<31)),
usb_irq_entry, pw);
break;
default:break;
#ifdef STANDALONE
case Service_ResourceFSStarting:
/* Re-register the messages */
(*(void (*)(void *, void *, void *, void *))r->r[2]) (resource_files (), 0, 0, (void *)r->r[3]);
break;
#endif
}
}
#define OREAD(o) ehci_base[o/4]
#ifdef EHCI_DEBUG
/*---------------------------------------------------------------------------*/
/* CMHG module commands - only used for debugging */
/*---------------------------------------------------------------------------*/
_kernel_oserror *module_commands(const char *arg_string, int argc, int cmd_no, void *pw)
{
ehci_softc_t* sc = &ehci_soft;
......@@ -557,16 +632,9 @@ _kernel_oserror *module_commands(const char *arg_string, int argc, int cmd_no, v
}
#endif
/*---------------------------------------------------------------------------*/
/* CMHG interrupt veneer handler */
/*---------------------------------------------------------------------------*/
int usb_irq_handler(_kernel_swi_regs *r, void *pw)
{
int ret;
......@@ -576,7 +644,7 @@ int usb_irq_handler(_kernel_swi_regs *r, void *pw)
#ifdef EHCI_DEBUG
int u2s, u2s1;
_swix (OS_Hardware, _INR(8,9)|_OUT(0),
0, EntryNo_HAL_CounterRead, &u2s);
OSHW_CallHAL, EntryNo_HAL_CounterRead, &u2s);
// irqs++;
// ehci_softc_t* sc = &ehci_soft;
// if (ehcidebug > 1) dprintf (("", "Frame index: %x\n",
......@@ -593,7 +661,7 @@ int usb_irq_handler(_kernel_swi_regs *r, void *pw)
else
{
_swix (OS_Hardware, _INR(8,9)|_OUT(0),
0, EntryNo_HAL_CounterRead, &u2s1);
OSHW_CallHAL, EntryNo_HAL_CounterRead, &u2s1);
int t = (u2s - u2s1) * 5;
if (t < 0) t += 10000000; /* it wrapped */
if (ehcidebug > 1) dprintf(("", "irq for: %d nsecs\n", t));
......@@ -603,6 +671,9 @@ int usb_irq_handler(_kernel_swi_regs *r, void *pw)
return ret;
}
/*---------------------------------------------------------------------------*/
/* Leaf functions */
/*---------------------------------------------------------------------------*/
void bus_space_write_4 (bus_space_tag_t iot, bus_space_handle_t ioh, int o, int x)
{
#ifdef EHCI_DEBUG0
......@@ -741,35 +812,6 @@ riscos_abort_pipe (void* v)
callx_add_callback (_riscos_abort_pipe, v);
}
void
usb_schedsoftintr (struct usbd_bus* sc)
{
......
......@@ -33,6 +33,7 @@
#include "Global/HALEntries.h"
#include "Global/OsBytes.h"
#include "Interface/PCI.h"
#include "Interface/USBDriver.h"
#include "callx/callx.h"
#include "toolbox.h"
......@@ -40,17 +41,19 @@
#define __stdio_h
#include "ohcimodhead.h"
#include "USBDriver.h"
#include "DebugLib/DebugLib.h"
#include "USBDevFS.h"
#define OHCIEmulator_GetRegisters 0x54a80
#define OHCIEmulator_ClaimDeviceVector 0x054a81
#define OHCIEmulator_ReleaseDeviceVector 0x054a82
#define OHCIEmulator_ReadWord 0x054a83
#define OHCIEmulator_WriteWord 0x054a84
#define OHCIVendorUnknownRootName "Built-in"
#define ErrorBase_OHCIDriver 0x820A00
#define ErrorBlock_OHCI_NoReinit { (ErrorBase_OHCIDriver+0), "NumParm" }
#define ErrorBlock_OHCI_NoOHCI { (ErrorBase_OHCIDriver+1), "E01" }
#define ErrorBlock_OHCI_ClaimVeneer { (ErrorBase_OHCIDriver+2), "E02" }
#define ErrorBlock_OHCI_USBTooOld { (ErrorBase_OHCIDriver+3), "E03" }
typedef struct
{
int errnum;
char errtok[8];
} _kernel_tokerror;
/* for debugging */
#ifdef OHCI_DEBUG
......@@ -96,7 +99,9 @@ int instance = 0;
int device_number;
static bool registering=false; /* True/false for whether we're in the middle of registering. Avoids nested registration attempt during ROM init. */
/* Port power controls - only used by HAL devices */
/*---------------------------------------------------------------------------*/
/* Port power controls - only used by HAL devices */
/*---------------------------------------------------------------------------*/
void (*ohci_ppower)(int port, int state);
int (*ohci_error)(int port); /* Never gets used? */
void (*ohci_pirqclear)(int port);
......@@ -119,37 +124,6 @@ typedef struct p_err_chk
} p_err_chk;
static p_err_chk pchk;
void build_veneer (int* vn, int* st, size_t sz)
{
int i;
dprintf (("", "writing veneer from %p at %p\n", st, vn));
int* entry_table = vn + sz / sizeof (void*);
for (i = 0; i < sz / sizeof (void*); ++i) {
int* entry = entry_table + 2 * i;
/* copy function pointer into veneer */
vn[i] = st[i];
/* copy new pointer into structure */
st[i] = (int) entry;
/* LDR ip, function[i] */
entry[0] = 0xe51fC000 /* LDR ip, [pc, #-0] */
+ 8 /* go back to current instruction */
+ i * 8 /* go back to beginning of veneers */
+ sz /* go back to beginning of struct */
- i * 4; /* go to func pointer */
/* B common */
entry[1] = 0xea000000 /* B here + 8 */
| ((magic - entry - 1) & 0x00ffffff);
/* branch to diff */
}
_swix(OS_SynchroniseCodeAreas, _INR(0,2), 1,
entry_table,
entry_table + 2 * (sz / sizeof (void*)) - 1);
}
/* Read overcurrent state of port (1's based numbering).
* Returns 0 if OK, non-0 if overcurrent
*/
......@@ -300,6 +274,43 @@ int usb_overcurrent_handler(_kernel_swi_regs *r, void *pw)
return 1;
}
/*---------------------------------------------------------------------------*/
/* Driver instance creation */
/*---------------------------------------------------------------------------*/
void build_veneer (int* vn, int* st, size_t sz)
{
int i;
dprintf (("", "writing veneer from %p at %p\n", st, vn));
int* entry_table = vn + sz / sizeof (void*);
for (i = 0; i < sz / sizeof (void*); ++i) {
int* entry = entry_table + 2 * i;
/* if the method isn't implemented, don't veneer it */
if (st[i] == NULL) continue;
/* copy function pointer into veneer */
vn[i] = st[i];
/* copy new pointer into structure */
st[i] = (int) entry;
/* LDR ip, function[i] */
entry[0] = 0xe51fC000 /* LDR ip, [pc, #-0] */
+ 8 /* go back to current instruction */
+ i * 8 /* go back to beginning of veneers */
+ sz /* go back to beginning of struct */
- i * 4; /* go to func pointer */
/* B common */
entry[1] = 0xea000000 /* B here + 8 */
| ((magic - entry - 1) & 0x00ffffff);
/* branch to diff */
}
_swix(OS_SynchroniseCodeAreas, _INR(0,2), 1,
entry_table,
entry_table + 2 * (sz / sizeof (void*)) - 1);
}
_kernel_oserror* register_bus(void *in,struct device **out)
{
*out = NULL;
......@@ -309,7 +320,13 @@ _kernel_oserror* register_bus(void *in,struct device **out)
if(e)
return e;
if(version < RISCOS_USBDRIVER_API_VERSION)
return (_kernel_oserror*)"\0\0\0\0USBDriver too old";
{
static const _kernel_tokerror err_usbtooold = ErrorBlock_OHCI_USBTooOld;
return _swix (MessageTrans_ErrorLookup, _INR(0,2),
&err_usbtooold, &mod_messages, 0 /* Internal buffer */);
}
/* Now attempt to register */
registering = true;
e = _swix(USBDriver_RegisterBus, _INR(0,1)|_OUT(0),in,RISCOS_USBDRIVER_API_VERSION,out);
......@@ -318,10 +335,29 @@ _kernel_oserror* register_bus(void *in,struct device **out)
return e;
}
static void name_root_hub(int pcidevice)
{
if (pci_device == -1)
{
_kernel_oserror *e;
e = _swix (MessageTrans_Lookup, _INR(0,3),
&mod_messages, "UkRoot", ohci_soft.sc_vendor, sizeof(ohci_soft.sc_vendor));
if (e) strcpy(ohci_soft.sc_vendor, " ");
}
else
{
char *v = NULL;
_swix (PCI_ReadInfo, _INR(0,3), PCI_ReadInfo_Vendor, &v, sizeof(v), pci_device);
if (v == NULL) v = " ";
strncpy (ohci_soft.sc_vendor, v, sizeof ohci_soft.sc_vendor-1);
}
}
_kernel_oserror* new_instance (_kernel_swi_regs* r, void* pw, void* h)
{
_kernel_oserror * e;
char* v=NULL;
(void) r;
(void) pw;
......@@ -329,18 +365,10 @@ _kernel_oserror* new_instance (_kernel_swi_regs* r, void* pw, void* h)
/* fill in the device name in the callback so that our service call handler
is threaded and there to respond to PCI calls */
if (pci_device == -1)
{
strncpy (ohci_soft.sc_vendor, OHCIVendorUnknownRootName, sizeof ohci_soft.sc_vendor-1);
}
else
{
_swix (PCI_ReadInfo, _INR(0,3), (1<<16), &v, 4, pci_device);
if (v == 0) v = (char *)" ";
strncpy (ohci_soft.sc_vendor, v, sizeof ohci_soft.sc_vendor-1);
}
/* now we know the root hub info, register it with USBDriver */
dprintf (("", "Init-Registering with USB driver\n"));
name_root_hub(pci_device);
/* register with the usbdriver module if it's already resident */
dprintf (("", "Registering with USB driver\n"));
e = register_bus(&ohci_soft, &usb_soft);
if (e)
{
......@@ -365,9 +393,9 @@ _kernel_oserror* new_instance (_kernel_swi_regs* r, void* pw, void* h)
return NULL;
}
/*---------------------------------------------------------------------------*/
/* CMHG module initialisation */
/*---------------------------------------------------------------------------*/
_kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
size_t i;
_kernel_oserror *e;
......@@ -420,14 +448,17 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
hal_device = (int) strtol (endptr+1, NULL, 0);
else
{
return (_kernel_oserror*)
"\1\0\0\0"Module_Title" can't be reinitialised";
static const _kernel_tokerror err_noreinit = ErrorBlock_OHCI_NoReinit;
return _swix (MessageTrans_ErrorLookup, _INR(0,2),
&err_noreinit, 0 /* Global messages */, 0 /* Internal buffer */);
}
}
else
{
pci_device = 0;
#ifdef STANDALONE
/* Only first instance registers the messages in ResourceFS */
e = _swix (ResourceFS_RegisterFiles, _IN (0), resource_files ());
if (e != NULL) return e;
#endif
......@@ -437,10 +468,9 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
&mod_messages,
Module_MessagesFile,
0);
if (e) return e;
/* see if there are any more USB OHCI controllers */
if (e) goto error_dereg;
/* find the next possible controller */
if(pci_device >= 0)
{
/* Looking for PCI device */
......@@ -507,10 +537,16 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
ohci_error = do_ohci_perror;
ohci_pirqclear = do_ohci_pirqclear;
}
break;
}
else if(e || !usbinfolen)
{
return (_kernel_oserror*) "\0\0\0\0No OHCI devices found";
/* Reached end of list */
static const _kernel_tokerror err_noohci = ErrorBlock_OHCI_NoOHCI;
e = _swix (MessageTrans_ErrorLookup, _INR(0,2),
&err_noohci, &mod_messages, 0 /* Internal buffer */);
goto error;
}
} while(1);
}
......@@ -529,7 +565,7 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
&hal_oc_device[i]);
if (hal_oc_device[i] != -1)
{
dprintf(("", "HAL port %d is overcurrent device %d\n", port, hal_oc_device[i]));
dprintf(("", "HAL port %d is overcurrent device %d\n", i, hal_oc_device[i]));
}
}
else
......@@ -543,21 +579,8 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
sprintf (ohci_soft.sc_bus.bdev.dv_xname, "OHCI%d", instance);
ohci_soft.sc_irqdevno = device_number;
if (pci_device == -1)
{
strncpy(ohci_soft.sc_vendor, OHCIVendorUnknownRootName, sizeof ohci_soft.sc_vendor-1);
}
else
{
char *v = NULL;
_swix (PCI_ReadInfo, _INR(0,3), PCI_ReadInfo_Vendor, &v, sizeof(v), pci_device);
if (v == NULL) v = (char *)" ";
strncpy (ohci_soft.sc_vendor, v, sizeof ohci_soft.sc_vendor-1);
}
dprintf (("Main_0", "interrupt device %d\n", device_number));
dprintf (("Main_0", "hardware address %p\n", ohci_base));
private_word = pw;
......@@ -565,22 +588,26 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
const char *c = getenv("ohcidebug");
usbdebug = ohcidebug = (c?atoi(c):0);
#endif
_swix (OS_ClaimDeviceVector, _INR(0,2),
device_number | ((pci_device == -1)?0:(1u<<31)),
usb_irq_entry, pw);
_swix (OS_Hardware, _IN(0) | _INR(8,9),
device_number, OSHW_CallHAL, EntryNo_HAL_IRQEnable);
if ((magic = init_veneer ()) == NULL)
{
return (_kernel_oserror*) "\0\0\0\0Couldn't claim magic";
static const _kernel_tokerror err_claimveneer = ErrorBlock_OHCI_ClaimVeneer;
e = _swix (MessageTrans_ErrorLookup, _INR(0,2),
&err_claimveneer, &mod_messages, 0 /* Internal buffer */);
goto error;
}
dprintf (("", "magic at %p", magic));
_swix (OS_ClaimDeviceVector, _INR(0,2),
device_number | ((pci_device == -1)?0:(1u<<31)),
usb_irq_entry, pw);
_swix (OS_Hardware, _IN(0) | _INR(8,9),
device_number, OSHW_CallHAL, EntryNo_HAL_IRQEnable);
/* for the L7205, clocks need to be started */
/* in BSD this is called from sys/pci/ohci_pci.c */
ohci_init (&ohci_soft);
ohci_soft.sc_vendor[0]='\0'; // flag no svce_PCI yet
dprintf (("", "Finished module initialisation\n"));
......@@ -601,14 +628,21 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
callx_add_callback (new_instance, 0);
return 0;
return NULL;
error:
dprintf (("Failed initialisation: %s\n", e->errmess));
_swix (MessageTrans_CloseFile, _IN(0), &mod_messages);
error_dereg:
#ifdef STANDALONE
if (podule_base == 0) _swix (ResourceFS_DeregisterFiles, _IN(0), resource_files ());
#endif
return e;
}
/*---------------------------------------------------------------------------*/
/* CMHG module finalisation */
/*---------------------------------------------------------------------------*/
_kernel_oserror *module_final(int fatal, int podule, void *pw)
{
int v;
......@@ -617,7 +651,10 @@ _kernel_oserror *module_final(int fatal, int podule, void *pw)
dprintf (("", "OHCIDriver finalising\n"));
if (usb_soft != NULL)
_swix (USBDriver_DeRegisterBus, _IN(0), usb_soft);
{
_swix (USBDriver_DeregisterBus, _IN(0), usb_soft);
usb_soft=NULL;
}
#ifdef OHCI_DEBUG
module_commands (0, 0, CMD_OHCIEDS, pw);
......@@ -681,6 +718,9 @@ _kernel_oserror *module_final(int fatal, int podule, void *pw)
return NULL;
}
/*---------------------------------------------------------------------------*/
/* CMHG module service calls */
/*---------------------------------------------------------------------------*/
static void service_pci (_kernel_swi_regs* r)
{
dprintf (("", "Service PCI, r0 = %x, r1 = %x, r2 = %x\n",
......@@ -721,7 +761,6 @@ static void service_pci (_kernel_swi_regs* r)
void module_services(int service_number, _kernel_swi_regs *r, void *pw)
{
char* v = "";
switch (service_number) {
case Service_PCI:
service_pci (r);
......@@ -755,18 +794,15 @@ void module_services(int service_number, _kernel_swi_regs *r, void *pw)
case Service_USB_USBDriverStarting:
if ((usb_soft == NULL) && !registering)
{
if(ohci_soft.sc_vendor[0]!='\0') // (means svce_PCI has happened)
{ /* we're here in callback.. so foo we go */
dprintf (("", "Registering with USB driver from svcecall\n"));
_kernel_oserror *e = register_bus(&ohci_soft,&usb_soft);
if(e)
{
dprintf (("", "Failed to register: %s\n", e->errmess));
}
else
{
dprintf (("", "Registering with USB driver from svcecall-done\n"));
}
dprintf (("", "Registering with USB driver from svcecall\n"));
_kernel_oserror *e = register_bus(&ohci_soft,&usb_soft);
if(e)
{
dprintf (("", "Failed to register: %s\n", e->errmess));
}
else
{
dprintf (("", "Registering with USB driver from svcecall-done\n"));
}
}
break;
......@@ -777,26 +813,28 @@ void module_services(int service_number, _kernel_swi_regs *r, void *pw)
usb_soft = NULL;
memset (&ohci_soft, 0, sizeof ohci_soft);
sprintf (ohci_soft.sc_bus.bdev.dv_xname, "OHCI%d", instance);
if (pci_device == -1)
strncpy(ohci_soft.sc_vendor, OHCIVendorUnknownRootName, sizeof ohci_soft.sc_vendor-1);
else
{
_swix (PCI_ReadInfo, _INR(0,3), (1<<16), &v, 4, pci_device);
if (v == 0) v = (char *)" ";
strncpy (ohci_soft.sc_vendor, v, sizeof ohci_soft.sc_vendor-1);
}
name_root_hub (pci_device);
ohci_init (&ohci_soft);
break;
}
break;
#ifdef STANDALONE
case Service_ResourceFSStarting:
/* Re-register the messages */
(*(void (*)(void *, void *, void *, void *))r->r[2]) (resource_files (), 0, 0, (void *)r->r[3]);
break;
#endif
}
}
#define OREAD(o) ohci_base[o/4]
#ifdef OHCI_DEBUG
/*---------------------------------------------------------------------------*/
/* CMHG module commands - only used for debugging */
/*---------------------------------------------------------------------------*/
_kernel_oserror *module_commands(const char *arg_string, int argc, int cmd_no, void *pw)
{
#define OREAD(o) ohci_base[o/4]
switch (cmd_no) {
case CMD_OHCIRegs:
printf
......@@ -964,6 +1002,9 @@ int vsync(_kernel_swi_regs *r, void *pw)
}
#endif
/*---------------------------------------------------------------------------*/
/* CMHG interrupt veneer handler */
/*---------------------------------------------------------------------------*/
int usb_irq_handler(_kernel_swi_regs *r, void *pw)
{
int ret;
......@@ -1008,6 +1049,9 @@ int usb_irq_handler(_kernel_swi_regs *r, void *pw)
return ret;
}
/*---------------------------------------------------------------------------*/
/* Leaf functions */
/*---------------------------------------------------------------------------*/
void bus_space_write_4 (bus_space_tag_t iot, bus_space_handle_t ioh, int o, int x)
{
#ifdef OHCI_DEBUG
......
......@@ -20,7 +20,6 @@
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
......@@ -31,6 +30,9 @@
#include "sys/callout.h"
#include "sys/time.h"
#include "Global/HALEntries.h"
#include "Global/OSMisc.h"
#include <sys/types.h>
#include "dev/usb/usb_port.h"
#ifdef USB_DEBUG
extern int usbdebug;
......@@ -141,7 +143,6 @@ selwakeup(struct selinfo *selinfo)
}
typedef int devclass_t;
typedef int caddr_t;
void*
devclass_get_softc (devclass_t dc, int unit)
......@@ -183,7 +184,7 @@ callout_init (struct callout* c,int ignored)
#ifdef USB_DEBUG0
if (usbdebug > 15) dprintf (("Port", "callout init %p\n", c));
#endif
memset (c, 0, sizeof c);
memset (c, 0, sizeof (*c));
}
_kernel_oserror*
......@@ -224,7 +225,7 @@ int kthread_create (void (f) (void*), void* h) {
return 0;
}
int kthread_create1 (int (f) (void*), void* a, void* b, char* c, char* d)
int kthread_create1 (void (f) (void*), void* a, void* b, char* c, char* d)
{
(void) f;
(void) a;
......@@ -349,8 +350,9 @@ int wakeup (void* ident) {
return 0;
}
void kthread_exit (void) {
int kthread_exit (int status) {
// dprintf (("Port", "exit thread\n"));
return 0;
}
void device_probe_and_attach (void) {
......@@ -371,16 +373,16 @@ ratecheck (void* a, void* b)
void* usbd_print;
void* vtophys (void** v)
int vtophys (void* v)
{
#ifndef EMULATE
struct {
void* page;
int page;
void* logical;
void* physical;
int physical;
} block;
block.logical = v;
_swix (OS_Memory, _INR (0, 2), (1<<9) + (1<<13) + (2<<14), &block, 1);
_swix (OS_Memory, _INR (0, 2), (1<<9) + (1<<13), &block, 1);
return block.physical;
#else
......@@ -416,15 +418,12 @@ void free_contig (void **mem)
char*
device_get_nameunit (void)
{
return "OHCI USB device";
}
int min (int a, int b)
{
if (a < b) return a;
return b;
return "Root device";
}
#ifdef logprintf
#undef logprintf
#endif
void logprintf (char* format, ...)
{
va_list p;
......@@ -464,3 +463,35 @@ void riscos_irqclear(int devno)
{
_swix(OS_Hardware, _IN(0)|_INR(8,9), devno, 0, EntryNo_HAL_IRQClear);
}
static void barriers_init(void);
barrier_func barriers[3] =
{
barriers_init, /* Lazy approach to initialisation! */
barriers_init,
barriers_init,
};
static void barriers_null(void)
{
}
void barriers_init(void)
{
/* Get the appropriate barrier ARMops */
if (_swix(OS_MMUControl, _IN(0)|_OUT(0), MMUCReason_GetARMop + (ARMop_DMB_ReadWrite<<8), &barriers[BARRIER_READ+BARRIER_WRITE-1])
|| _swix(OS_MMUControl, _IN(0)|_OUT(0), MMUCReason_GetARMop + (ARMop_DMB_Write<<8), &barriers[BARRIER_WRITE-1])
|| _swix(OS_MMUControl, _IN(</