Prepare a little for having USB interrupt processing done outside the hard

interrupt level (in a thread or a softintr).
No real soft processing done yet.
This commit is contained in:
augustss 2000-02-22 11:30:54 +00:00
parent fdf401f582
commit 9056664327
5 changed files with 65 additions and 20 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ohci.c,v 1.71 2000/02/01 05:42:52 augustss Exp $ */
/* $NetBSD: ohci.c,v 1.72 2000/02/22 11:30:54 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
/*
@ -130,11 +130,10 @@ static void ohci_shutdown __P((void *v));
static void ohci_power __P((int, void *));
static usbd_status ohci_open __P((usbd_pipe_handle));
static void ohci_poll __P((struct usbd_bus *));
static void ohci_softintr __P((struct usbd_bus *));
static void ohci_waitintr __P((ohci_softc_t *,
usbd_xfer_handle));
static void ohci_rhsc __P((ohci_softc_t *, usbd_xfer_handle));
static void ohci_process_done __P((ohci_softc_t *,
ohci_physaddr_t));
static usbd_status ohci_device_request __P((usbd_xfer_handle xfer));
static void ohci_add_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *));
@ -264,6 +263,7 @@ struct ohci_pipe {
static struct usbd_bus_methods ohci_bus_methods = {
ohci_open,
ohci_poll,
ohci_softintr,
ohci_allocm,
ohci_freem,
ohci_allocx,
@ -990,7 +990,6 @@ ohci_intr1(sc)
intrs = 0;
done = LE(sc->sc_hcca->hcca_done_head);
if (done != 0) {
sc->sc_hcca->hcca_done_head = 0;
if (done & ~OHCI_DONE_INTRS)
intrs = OHCI_WDH;
if (done & OHCI_DONE_INTRS)
@ -1019,7 +1018,21 @@ ohci_intr1(sc)
intrs &= ~OHCI_SO;
}
if (eintrs & OHCI_WDH) {
ohci_process_done(sc, done &~ OHCI_DONE_INTRS);
done &= OHCI_DONE_INTRS;
if (sc->sc_done == 0)
sc->sc_done = done;
else {
/* Tack on at the end of sc_done. */
ohci_physaddr_t ldone;
ohci_soft_td_t *std;
for (ldone = sc->sc_done; ldone != 0;
ldone = LE(std->td.td_nexttd))
std = ohci_hash_find_td(sc, done);
std->td.td_nexttd = LE(done);
}
sc->sc_hcca->hcca_done_head = 0;
usb_schedsoftintr(&sc->sc_bus);
intrs &= ~OHCI_WDH;
}
if (eintrs & OHCI_RD) {
@ -1089,13 +1102,21 @@ char *ohci_cc_strs[] = {
#endif
void
ohci_process_done(sc, done)
ohci_softc_t *sc;
ohci_physaddr_t done;
ohci_softintr(bus)
struct usbd_bus *bus;
{
ohci_softc_t *sc = (ohci_softc_t *)bus;
ohci_physaddr_t done;
ohci_soft_td_t *std, *sdone, *stdnext;
usbd_xfer_handle xfer;
int len, cc;
int len, cc, s;
sc->sc_bus.intr_context++;
s = splhardusb();
done = sc->sc_done;
sc->sc_done = 0;
splx(s);
DPRINTFN(10,("ohci_process_done: done=0x%08lx\n", (u_long)done));
@ -1175,6 +1196,8 @@ ohci_process_done(sc, done)
usb_transfer_complete(xfer);
}
}
sc->sc_bus.intr_context--;
}
void

View File

@ -1,4 +1,4 @@
/* $NetBSD: ohcivar.h,v 1.19 2000/02/01 05:42:53 augustss Exp $ */
/* $NetBSD: ohcivar.h,v 1.20 2000/02/22 11:30:55 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohcivar.h,v 1.13 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@ -102,6 +102,8 @@ typedef struct ohci_softc {
usbd_xfer_handle sc_intrxfer;
ohci_physaddr_t sc_done;
char sc_vendor[16];
int sc_id_vendor;

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhci.c,v 1.84 2000/01/28 00:44:27 augustss Exp $ */
/* $NetBSD: uhci.c,v 1.85 2000/02/22 11:30:55 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@ -236,6 +236,7 @@ static void uhci_root_intr_done __P((usbd_xfer_handle));
static usbd_status uhci_open __P((usbd_pipe_handle));
static void uhci_poll __P((struct usbd_bus *));
static void uhci_softintr __P((struct usbd_bus *));
static usbd_status uhci_device_request __P((usbd_xfer_handle xfer));
@ -274,6 +275,7 @@ static void uhci_dump_td __P((uhci_soft_td_t *));
struct usbd_bus_methods uhci_bus_methods = {
uhci_open,
uhci_softintr,
uhci_poll,
uhci_allocm,
uhci_freem,
@ -950,7 +952,6 @@ uhci_intr(arg)
uhci_softc_t *sc = arg;
int status;
int ack;
uhci_intr_info_t *ii;
#ifdef UHCI_DEBUG
if (uhcidebug > 15) {
@ -998,8 +999,24 @@ uhci_intr(arg)
else /* nothing to acknowledge */
return (0);
sc->sc_bus.intr_context++;
sc->sc_bus.no_intrs++;
usb_schedsoftintr(&sc->sc_bus);
DPRINTFN(10, ("%s: uhci_intr: exit\n", USBDEVNAME(sc->sc_bus.bdev)));
return (1);
}
void
uhci_softintr(bus)
struct usbd_bus *bus;
{
uhci_softc_t *sc = (uhci_softc_t *)bus;
uhci_intr_info_t *ii;
DPRINTFN(10,("%s: uhci_softintr\n", USBDEVNAME(sc->sc_bus.bdev)));
sc->sc_bus.intr_context++;
/*
* Interrupts on UHCI really suck. When the host controller
@ -1015,11 +1032,7 @@ uhci_intr(arg)
for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list))
uhci_check_intr(sc, ii);
DPRINTFN(10, ("%s: uhci_intr: exit\n", USBDEVNAME(sc->sc_bus.bdev)));
sc->sc_bus.intr_context--;
return (1);
}
/* Check for an interrupt. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: usb.c,v 1.38 2000/02/02 07:33:59 augustss Exp $ */
/* $NetBSD: usb.c,v 1.39 2000/02/22 11:30:56 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb.c,v 1.20 1999/11/17 22:33:46 n_hibma Exp $ */
/*
@ -695,6 +695,12 @@ usb_add_event(type, uep)
psignal(usb_async_proc, SIGIO);
splx(s);
}
void
usb_schedsoftintr(bus)
struct usbd_bus *bus;
{
bus->methods->soft_intr(bus);
}
#if defined(__NetBSD__) || defined(__OpenBSD__)
int

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdivar.h,v 1.46 2000/01/19 01:16:40 augustss Exp $ */
/* $NetBSD: usbdivar.h,v 1.47 2000/02/22 11:30:56 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $ */
/*
@ -51,6 +51,7 @@ struct usbd_endpoint {
struct usbd_bus_methods {
usbd_status (*open_pipe)__P((struct usbd_pipe *pipe));
void (*soft_intr)__P((struct usbd_bus *));
void (*do_poll)__P((struct usbd_bus *));
usbd_status (*allocm)__P((struct usbd_bus *, usb_dma_t *,
u_int32_t bufsize));
@ -233,8 +234,8 @@ void usb_transfer_complete __P((usbd_xfer_handle xfer));
void usb_disconnect_port __P((struct usbd_port *up, device_ptr_t));
/* Routines from usb.c */
int usb_bus_count __P((void));
void usb_needs_explore __P((usbd_bus_handle));
void usb_schedsoftintr __P((struct usbd_bus *));
#ifdef DIAGNOSTIC
#define SPLUSBCHECK \