High speed isochronous support, from Jeremy Morse as part of Google

Summer of Code 2008.
This commit is contained in:
jmcneill 2008-08-02 22:23:18 +00:00
parent bd85f4f930
commit 4e6a458107
3 changed files with 869 additions and 57 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: ehcireg.h,v 1.27 2008/04/28 20:23:58 martin Exp $ */
/* $NetBSD: ehcireg.h,v 1.28 2008/08/02 22:23:18 jmcneill Exp $ */
/*
* Copyright (c) 2001, 2004 The NetBSD Foundation, Inc.
@ -188,10 +188,41 @@ typedef u_int32_t ehci_link_t;
typedef u_int32_t ehci_physaddr_t;
typedef u_int32_t ehci_isoc_trans_t;
typedef u_int32_t ehci_isoc_bufr_ptr_t;
/* Isochronous Transfer Descriptor */
typedef struct {
volatile ehci_link_t itd_next;
/* XXX many more */
volatile ehci_link_t itd_next;
volatile ehci_isoc_trans_t itd_ctl[8];
#define EHCI_ITD_GET_STATUS(x) (((x) >> 28) & 0xf)
#define EHCI_ITD_SET_STATUS(x) (((x) & 0xf) << 28)
#define EHCI_ITD_ACTIVE 0x80000000
#define EHCI_ITD_BUF_ERR 0x40000000
#define EHCI_ITD_BABBLE 0x20000000
#define EHCI_ITD_ERROR 0x10000000
#define EHCI_ITD_GET_LEN(x) (((x) >> 16) & 0xfff)
#define EHCI_ITD_SET_LEN(x) (((x) & 0xfff) << 16)
#define EHCI_ITD_IOC 0x8000
#define EHCI_ITD_GET_IOC(x) (((x) >> 15) & 1)
#define EHCI_ITD_SET_IOC(x) (((x) << 15) & EHCI_ITD_IOC)
#define EHCI_ITD_GET_PG(x) (((x) >> 12) & 0xf)
#define EHCI_ITD_SET_PG(x) (((x) & 0xf) << 12)
#define EHCI_ITD_GET_OFFS(x) (((x) >> 0) & 0xfff)
#define EHCI_ITD_SET_OFFS(x) (((x) & 0xfff) << 0)
volatile ehci_isoc_bufr_ptr_t itd_bufr[7];
#define EHCI_ITD_GET_BPTR(x) ((x) & 0xfffff000)
#define EHCI_ITD_SET_BPTR(x) ((x) & 0xfffff000)
#define EHCI_ITD_GET_EP(x) (((x) >> 8) & 0xf)
#define EHCI_ITD_SET_EP(x) (((x) & 0xf) << 8)
#define EHCI_ITD_GET_DADDR(x) ((x) & 0x7f)
#define EHCI_ITD_SET_DADDR(x) ((x) & 0x7f)
#define EHCI_ITD_GET_DIR(x) (((x) >> 11) & 1)
#define EHCI_ITD_SET_DIR(x) (((x) & 1) << 11)
#define EHCI_ITD_GET_MAXPKT(x) ((x) & 0x7ff)
#define EHCI_ITD_SET_MAXPKT(x) ((x) & 0x7ff)
#define EHCI_ITD_GET_MULTI(x) ((x) & 0x3)
#define EHCI_ITD_SET_MULTI(x) ((x) & 0x3)
} ehci_itd_t;
#define EHCI_ITD_ALIGN 32

View File

@ -1,4 +1,4 @@
/* $NetBSD: ehcivar.h,v 1.31 2008/06/28 17:42:53 bouyer Exp $ */
/* $NetBSD: ehcivar.h,v 1.32 2008/08/02 22:23:18 jmcneill Exp $ */
/*
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -54,12 +54,36 @@ typedef struct ehci_soft_qh {
#define EHCI_SQH_SIZE ((sizeof (struct ehci_soft_qh) + EHCI_QH_ALIGN - 1) / EHCI_QH_ALIGN * EHCI_QH_ALIGN)
#define EHCI_SQH_CHUNK (EHCI_PAGE_SIZE / EHCI_SQH_SIZE)
typedef struct ehci_soft_itd {
ehci_itd_t itd;
union {
struct {
/* soft_itds links in a periodic frame*/
struct ehci_soft_itd *next;
struct ehci_soft_itd *prev;
} frame_list;
/* circular list of free itds */
LIST_ENTRY(ehci_soft_itd) free_list;
} u;
struct ehci_soft_itd *xfer_next; /* Next soft_itd in xfer */
ehci_physaddr_t physaddr;
usb_dma_t dma;
int offs;
int slot;
struct timeval t; /* store free time */
} ehci_soft_itd_t;
#define EHCI_ITD_SIZE ((sizeof(struct ehci_soft_itd) + EHCI_QH_ALIGN - 1) / EHCI_ITD_ALIGN * EHCI_ITD_ALIGN)
#define EHCI_ITD_CHUNK (EHCI_PAGE_SIZE / EHCI_ITD_SIZE)
struct ehci_xfer {
struct usbd_xfer xfer;
struct usb_task abort_task;
LIST_ENTRY(ehci_xfer) inext; /* list of active xfers */
ehci_soft_qtd_t *sqtdstart;
ehci_soft_qtd_t *sqtdend;
ehci_soft_itd_t *itdstart;
ehci_soft_itd_t *itdend;
u_int isoc_len;
int isdone; /* used only when DIAGNOSTIC is defined */
};
#define EXFER(xfer) ((struct ehci_xfer *)(xfer))
@ -81,6 +105,8 @@ struct ehci_soft_islot {
#define EHCI_HASH_SIZE 128
#define EHCI_COMPANION_MAX 8
#define EHCI_FREE_LIST_INTERVAL 100
typedef struct ehci_softc {
device_t sc_dev;
struct usbd_bus sc_bus;
@ -107,10 +133,16 @@ typedef struct ehci_softc {
struct ehci_soft_islot sc_islots[EHCI_INTRQHS];
/* jcmm - an array matching sc_flist, but with software pointers,
* not hardware address pointers
*/
struct ehci_soft_itd **sc_softitds;
LIST_HEAD(, ehci_xfer) sc_intrhead;
ehci_soft_qh_t *sc_freeqhs;
ehci_soft_qtd_t *sc_freeqtds;
LIST_HEAD(sc_freeitds, ehci_soft_itd) sc_freeitds;
int sc_noport;
u_int8_t sc_hasppc; /* has Port Power Control */