Turn xfer allocation into a method in the HC driver. The reason is that

an HC driver may want to subclass the xfer to have additional private fields.
This commit is contained in:
augustss 2000-01-18 20:11:00 +00:00
parent 1de974fc2e
commit f14036861f
6 changed files with 92 additions and 29 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ohci.c,v 1.61 2000/01/16 13:12:06 augustss Exp $ */
/* $NetBSD: ohci.c,v 1.62 2000/01/18 20:11:00 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
/*
@ -153,6 +153,9 @@ static usbd_status ohci_allocm __P((struct usbd_bus *, usb_dma_t *,
u_int32_t));
static void ohci_freem __P((struct usbd_bus *, usb_dma_t *));
static usbd_xfer_handle ohci_allocx __P((struct usbd_bus *));
static void ohci_freex __P((struct usbd_bus *, usbd_xfer_handle));
static usbd_status ohci_root_ctrl_transfer __P((usbd_xfer_handle));
static usbd_status ohci_root_ctrl_start __P((usbd_xfer_handle));
static void ohci_root_ctrl_abort __P((usbd_xfer_handle));
@ -262,6 +265,8 @@ static struct usbd_bus_methods ohci_bus_methods = {
ohci_poll,
ohci_allocm,
ohci_freem,
ohci_allocx,
ohci_freex,
};
static struct usbd_pipe_methods ohci_root_ctrl_methods = {
@ -612,6 +617,8 @@ ohci_init(sc)
for (i = 0; i < OHCI_HASH_SIZE; i++)
LIST_INIT(&sc->sc_hash_tds[i]);
SIMPLEQ_INIT(&sc->sc_free_xfers);
/* Allocate the HCCA area. */
err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE,
OHCI_HCCA_ALIGN, &sc->sc_hccadma);
@ -819,6 +826,31 @@ ohci_freem(bus, dma)
usb_freemem(&sc->sc_bus, dma);
}
usbd_xfer_handle
ohci_allocx(bus)
struct usbd_bus *bus;
{
struct ohci_softc *sc = (struct ohci_softc *)bus;
usbd_xfer_handle xfer;
xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
if (xfer != NULL)
SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, xfer, next);
else
xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT);
return (xfer);
}
void
ohci_freex(bus, xfer)
struct usbd_bus *bus;
usbd_xfer_handle xfer;
{
struct ohci_softc *sc = (struct ohci_softc *)bus;
SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
}
/*
* Shut down the controller when the system is going down.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: ohcivar.h,v 1.17 2000/01/16 10:35:25 augustss Exp $ */
/* $NetBSD: ohcivar.h,v 1.18 2000/01/18 20:11:00 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohcivar.h,v 1.13 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@ -98,6 +98,8 @@ typedef struct ohci_softc {
ohci_soft_td_t *sc_freetds;
ohci_soft_itd_t *sc_freeitds;
SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
usbd_xfer_handle sc_intrxfer;
char sc_vendor[16];

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhci.c,v 1.75 2000/01/17 01:01:07 augustss Exp $ */
/* $NetBSD: uhci.c,v 1.76 2000/01/18 20:11:00 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@ -195,6 +195,9 @@ static usbd_status uhci_allocm __P((struct usbd_bus *, usb_dma_t *,
u_int32_t));
static void uhci_freem __P((struct usbd_bus *, usb_dma_t *));
static usbd_xfer_handle uhci_allocx __P((struct usbd_bus *));
static void uhci_freex __P((struct usbd_bus *, usbd_xfer_handle));
static usbd_status uhci_device_ctrl_transfer __P((usbd_xfer_handle));
static usbd_status uhci_device_ctrl_start __P((usbd_xfer_handle));
static void uhci_device_ctrl_abort __P((usbd_xfer_handle));
@ -273,6 +276,8 @@ struct usbd_bus_methods uhci_bus_methods = {
uhci_poll,
uhci_allocm,
uhci_freem,
uhci_allocx,
uhci_freex,
};
struct usbd_pipe_methods uhci_root_ctrl_methods = {
@ -417,6 +422,8 @@ uhci_init(sc)
LIST_INIT(&sc->sc_intrhead);
SIMPLEQ_INIT(&sc->sc_free_xfers);
/* Set up the bus struct. */
sc->sc_bus.methods = &uhci_bus_methods;
sc->sc_bus.pipe_size = sizeof(struct uhci_pipe);
@ -462,6 +469,7 @@ uhci_detach(sc, flags)
struct uhci_softc *sc;
int flags;
{
usbd_xfer_handle xfer;
int rv = 0;
if (sc->sc_child != NULL)
@ -473,7 +481,16 @@ uhci_detach(sc, flags)
powerhook_disestablish(sc->sc_powerhook);
shutdownhook_disestablish(sc->sc_shutdownhook);
/* free data structures XXX */
/* Free all xfers associated with this HC. */
for (;;) {
xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
if (xfer == NULL)
break;
SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, xfer, next);
free(xfer, M_USB);
}
/* XXX free other data structures XXX */
return (rv);
}
@ -497,6 +514,31 @@ uhci_freem(bus, dma)
usb_freemem(&((struct uhci_softc *)bus)->sc_bus, dma);
}
usbd_xfer_handle
uhci_allocx(bus)
struct usbd_bus *bus;
{
struct uhci_softc *sc = (struct uhci_softc *)bus;
usbd_xfer_handle xfer;
xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
if (xfer != NULL)
SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, xfer, next);
else
xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT);
return (xfer);
}
void
uhci_freex(bus, xfer)
struct usbd_bus *bus;
usbd_xfer_handle xfer;
{
struct uhci_softc *sc = (struct uhci_softc *)bus;
SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
}
/*
* Shut down the controller when the system is going down.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: uhcivar.h,v 1.20 2000/01/16 10:27:51 augustss Exp $ */
/* $NetBSD: uhcivar.h,v 1.21 2000/01/18 20:11:01 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhcivar.h,v 1.14 1999/11/17 22:33:42 n_hibma Exp $ */
/*
@ -143,6 +143,8 @@ typedef struct uhci_softc {
uhci_soft_td_t *sc_freetds; /* TD free list */
uhci_soft_qh_t *sc_freeqhs; /* QH free list */
SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
u_int8_t sc_addr; /* device address */
u_int8_t sc_conf; /* device configuration */

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdi.c,v 1.57 2000/01/16 23:11:43 augustss Exp $ */
/* $NetBSD: usbdi.c,v 1.58 2000/01/18 20:11:01 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */
/*
@ -81,9 +81,6 @@ static void usbd_do_request_async_cb
__P((usbd_xfer_handle, usbd_private_handle, usbd_status));
static void usbd_start_next __P((usbd_pipe_handle pipe));
static SIMPLEQ_HEAD(, usbd_xfer) usbd_free_xfers =
SIMPLEQ_HEAD_INITIALIZER(usbd_free_xfers);
static int usbd_nbuses = 0;
void
@ -95,18 +92,7 @@ usbd_init()
void
usbd_finish()
{
usbd_xfer_handle xfer;
if (--usbd_nbuses == 0) {
/* Last controller is gone, free all xfers. */
for (;;) {
xfer = SIMPLEQ_FIRST(&usbd_free_xfers);
if (xfer == NULL)
break;
SIMPLEQ_REMOVE_HEAD(&usbd_free_xfers, xfer, next);
free(xfer, M_USB);
}
}
--usbd_nbuses;
}
static __inline int usbd_xfer_isread __P((usbd_xfer_handle xfer));
@ -377,13 +363,9 @@ usbd_alloc_xfer(dev)
{
usbd_xfer_handle xfer;
xfer = SIMPLEQ_FIRST(&usbd_free_xfers);
if (xfer != NULL)
SIMPLEQ_REMOVE_HEAD(&usbd_free_xfers, xfer, next);
else
xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT);
xfer = dev->bus->methods->allocx(dev->bus);
if (xfer == NULL)
return (0);
return (NULL);
memset(xfer, 0, sizeof *xfer);
xfer->device = dev;
DPRINTFN(5,("usbd_alloc_xfer() = %p\n", xfer));
@ -397,7 +379,7 @@ usbd_free_xfer(xfer)
DPRINTFN(5,("usbd_free_xfer: %p\n", xfer));
if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
usbd_free_buffer(xfer);
SIMPLEQ_INSERT_HEAD(&usbd_free_xfers, xfer, next);
xfer->device->bus->methods->freex(xfer->device->bus, xfer);
return (USBD_NORMAL_COMPLETION);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: usbdivar.h,v 1.43 2000/01/16 09:43:43 augustss Exp $ */
/* $NetBSD: usbdivar.h,v 1.44 2000/01/18 20:11:01 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $ */
/*
@ -55,6 +55,9 @@ struct usbd_bus_methods {
usbd_status (*allocm)__P((struct usbd_bus *, usb_dma_t *,
u_int32_t bufsize));
void (*freem)__P((struct usbd_bus *, usb_dma_t *));
struct usbd_xfer * (*allocx)__P((struct usbd_bus *));
void (*freex)__P((struct usbd_bus *,
struct usbd_xfer *));
};
struct usbd_pipe_methods {