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:
parent
fdf401f582
commit
9056664327
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
Loading…
Reference in New Issue