Commit b1fbb6ed authored by Kevin Bracey's avatar Kevin Bracey
Browse files

Added support for HAL USB devices.

Attempted interrupt hole fix.

Version 0.21, 1.22.2.1. Tagged as 'NetBSD-0_21-1_22_2_1'
parent 778cee75
/* (0.21)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.2.
* Last processed by srccommit version: 1.68.
*
*/
#define Module_MajorVersion_CMHG 0.21
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 21 Jan 2004
#define Module_MinorVersion_CMHG 1.22.2.1
#define Module_Date_CMHG 16 Feb 2004
#define Module_MajorVersion "0.21"
#define Module_Version 21
#define Module_MinorVersion ""
#define Module_Date "21 Jan 2004"
#define Module_MinorVersion "1.22.2.1"
#define Module_Date "16 Feb 2004"
#define Module_ApplicationDate "21-Jan-04"
#define Module_ApplicationDate "16-Feb-04"
#define Module_ComponentName "NetBSD"
#define Module_ComponentPath "RiscOS/Sources/HWSupport/USB/NetBSD"
#define Module_FullVersion "0.21"
#define Module_HelpVersion "0.21 (21 Jan 2004)"
#define Module_FullVersion "0.21 (1.22.2.1)"
#define Module_HelpVersion "0.21 (16 Feb 2004) 1.22.2.1"
#define Module_LibraryVersionInfo "0:21"
......@@ -14,5 +14,6 @@ usbkboard.o \
hid.o \
bufman.o \
triggercbs.o \
usbmsgs.o
usbmsgs.o \
call_veneer.o
#ugen.o
......@@ -134,10 +134,18 @@ _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 */
_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)
[sizeof ohci_soft.sc_vendor - 1] = '\0';
if (pci_device == -1)
{
strcpy (ohci_soft.sc_vendor, "Unknown");
return NULL;
}
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)
[sizeof ohci_soft.sc_vendor - 1] = '\0';
}
/* allow enough space for name, % and number, then space, and
another number */
......@@ -215,6 +223,26 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
0xFFFFFF,
pci_device,
&pci_device);
if (e || pci_device == 0) {
struct
{
int type;
int flags;
void *hw;
int devno;
} usbinfo;
size_t usbinfolen;
e = _swix(OS_Hardware, _INR(0,2)|_INR(8,9)|_OUT(0),
0, &usbinfo, sizeof usbinfo,
0, EntryNo_HAL_USBControllerInfo,
&usbinfolen);
if (!e && usbinfolen >= sizeof usbinfo) {
device_number = usbinfo.devno;
ohci_base = usbinfo.hw;
pci_device = -1;
}
}
if (e) goto error;
} while (0);//pci_device == 2 || pci_device == 3);
......@@ -231,30 +259,38 @@ _kernel_oserror *module_init(const char *cmd_tail, int podule_base, void *pw) {
dprintf (("Main_0", "Found OHCI controller on device %d\n", pci_device));
/* now establish our interrupt and address */
if (pci_device != -1)
{
/* now establish our interrupt and address */
e = _swix(PCI_ReadInfo, _INR(0,3),
PCI_ReadInfo_IntDeviceVector,
&device_number,
sizeof device_number,
pci_device);
if (e) goto error;
e = _swix(PCI_ReadInfo, _INR(0,3),
PCI_ReadInfo_IntDeviceVector,
&device_number,
sizeof device_number,
pci_device);
if (e) goto error;
dprintf (("Main_0", "interrupt device %d\n", device_number));
dprintf (("Main_0", "interrupt device %d\n", device_number));
e = _swix(PCI_HardwareAddress, _INR(0,1)|_IN(3)|_OUT(4),
0, 0, pci_device, &ohci_base);
if (e) goto error;
e = _swix(PCI_HardwareAddress, _INR(0,1)|_IN(3)|_OUT(4),
0, 0, pci_device, &ohci_base);
if (e) goto error;
dprintf (("Main_0", "hardware address %p\n", ohci_base));
dprintf (("Main_0", "hardware address %p\n", ohci_base));
}
memset (&ohci_soft, 0, sizeof ohci_soft);
sprintf (ohci_soft.sc_bus.bdev.dv_xname, "OHCI%d", instance);
_swix (PCI_ReadInfo, _INR(0,3), (1<<16), &v, 4, pci_device);
strncpy (ohci_soft.sc_vendor, v, sizeof ohci_soft.sc_vendor)
[sizeof ohci_soft.sc_vendor - 1] = '\0';
if (pci_device == -1)
strcpy(ohci_soft.sc_vendor, "Unknown");
else
{
_swix (PCI_ReadInfo, _INR(0,3), (1<<16), &v, 4, pci_device);
strncpy (ohci_soft.sc_vendor, v, sizeof ohci_soft.sc_vendor)
[sizeof ohci_soft.sc_vendor - 1] = '\0';
}
private_word = pw;
......@@ -449,9 +485,14 @@ 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);
_swix (PCI_ReadInfo, _INR(0,3), (1<<16), &v, 4, pci_device);
strncpy (ohci_soft.sc_vendor, v, sizeof ohci_soft.sc_vendor)
[sizeof ohci_soft.sc_vendor - 1] = '\0';
if (pci_device == -1)
strcpy(ohci_soft.sc_vendor, "Unknown");
else
{
_swix (PCI_ReadInfo, _INR(0,3), (1<<16), &v, 4, pci_device);
strncpy (ohci_soft.sc_vendor, v, sizeof ohci_soft.sc_vendor)
[sizeof ohci_soft.sc_vendor - 1] = '\0';
}
ohci_init (&ohci_soft);
break;
}
......@@ -658,6 +699,10 @@ int usb_irq_handler(_kernel_swi_regs *r, void *pw)
it hangs */
ret = !ohci_intr (&ohci_soft);
// the chip requires its interrupts cleared
_swix(OS_Hardware, _IN(0)|_INR(8,9), device_number,
0, EntryNo_HAL_IRQClear);
#ifdef OHCI_DEBUG
if (ret)
{
......
......@@ -36,6 +36,8 @@ int total_sleep;
extern void detach_hub (struct device*);
extern void detach_device (struct device*);
extern uint32_t hal_veneer2(uint32_t (*)(void), void*, ...);
static uint64_t gettime (void)
{
uint32_t cs;
......@@ -61,7 +63,7 @@ static uint64_t gettime (void)
}
_swix (OS_ReadMonotonicTime, _OUT(0), &cs);
return (uint64_t) (max_count - (readcode) ()) * ns_factor +
return (uint64_t) (max_count - hal_veneer2(readcode,ws)) * ns_factor +
((uint64_t) cs) * 10000000 /* 1e7 */;
}
......
......@@ -2324,12 +2324,12 @@ _kernel_oserror* clear_endpoint_stall
E_BadRequest, &mod_messages, &e, sizeof e, cp);
}
#endif
udev->str[i]->xfer->status = USBD_NORMAL_COMPLETION;
return NULL;
}
}
return uerror (E_NoStream);
}
......@@ -2457,7 +2457,7 @@ _kernel_oserror* driver (_kernel_swi_regs* r, void* pw)
break;
case DeviceFSCallDevice_USBRequest:
{
struct req { int a, b; } rq = (struct req) { r->r[3], r->r[4] };
struct req { int a, b; } rq = { r->r[3], r->r[4] };
int err = usbd_do_request (udev->sc_udev, (void*) &rq, (char*)r->r[5]);
#if 1
if (err != 0) return uerror (E_BadRequest);
......
......@@ -69,4 +69,17 @@ common STMFD sp!, {v1,v2,fp,lr}
LDMFD sp!, {v1,v2,fp,pc}
magic_end
; hal_veneer(code, ws) up to 2 arguments supported
EXPORT hal_veneer2
hal_veneer2
STMFD sp!,{r9,lr}
MOV ip, a1
MOV r9, a2
MOV a1, a3
MOV a2, a4
MOV lr, pc
MOV pc, ip
LDMFD sp!,{r9,pc}
END
......@@ -868,7 +868,10 @@ ohci_init(ohci_softc_t *sc)
OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
/* disable all interrupts and then switch on all desired interrupts */
OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
#ifndef __riscos
/* KJB fix */
OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE);
#endif
/* switch on desired functional features */
ctl = OREAD4(sc, OHCI_CONTROL);
ctl &= ~(OHCI_CBSR_MASK | OHCI_LES | OHCI_HCFS_MASK | OHCI_IR);
......@@ -1244,6 +1247,10 @@ ohci_rhsc_able(ohci_softc_t *sc, int on)
DPRINTFN(4, ("ohci_rhsc_able: on=%d\n", on));
if (on) {
sc->sc_eintrs |= OHCI_RHSC;
#ifdef __riscos
/* KJB fix */
if (sc->sc_intrxfer)
#endif
OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC);
} else {
sc->sc_eintrs &= ~OHCI_RHSC;
......@@ -2731,6 +2738,11 @@ ohci_root_intr_start(usbd_xfer_handle xfer)
sc->sc_intrxfer = xfer;
#ifdef __riscos
/* KJB fix */
OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE);
#endif
return (USBD_IN_PROGRESS);
}
......@@ -2758,6 +2770,10 @@ ohci_root_intr_close(usbd_pipe_handle pipe)
DPRINTF(("ohci_root_intr_close\n"));
#ifdef __riscos
/* KJB fix */
OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
#endif
sc->sc_intrxfer = NULL;
}
......
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