socsvn commit: r257757 - soc2013/bguan/head/sys/dev/xen/usbfront
bguan at FreeBSD.org
bguan at FreeBSD.org
Fri Sep 27 11:31:04 UTC 2013
Author: bguan
Date: Fri Sep 27 11:31:04 2013
New Revision: 257757
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=257757
Log:
set the pipe methods for xen usb host controller
Modified:
soc2013/bguan/head/sys/dev/xen/usbfront/xenhci.h
Modified: soc2013/bguan/head/sys/dev/xen/usbfront/xenhci.h
==============================================================================
--- soc2013/bguan/head/sys/dev/xen/usbfront/xenhci.h Fri Sep 27 11:30:51 2013 (r257756)
+++ soc2013/bguan/head/sys/dev/xen/usbfront/xenhci.h Fri Sep 27 11:31:04 2013 (r257757)
@@ -33,11 +33,13 @@
#include <xen/interface/io/ring.h>
#include <xen/interface/grant_table.h>
+#define XENUSB_BEBUG
+
#define XENHCI_MAX_DEVICES MIN(USB_MAX_DEVICES, 128)
#define XENHCI_PAGE_SIZE 4096 /* bytes */
-//#define TASK_COMM_LEN 16 /* Task command name length */
+#define TASK_COMM_LEN 16 /* Task command name length (taken from Linux)*/
#define GRANT_INVALID_REF 0
@@ -61,10 +63,421 @@
LIST_HEAD(list_head, list_head);
+
+#define XENHCI_MAX_ENDPOINTS 32 /* hardcoded - do not change */
+#define XENHCI_MAX_EVENTS (16 * 13)
+#define XENHCI_MAX_COMMANDS (16 * 1)
+#define XENHCI_MAX_RSEG 1
+#define XENHCI_MAX_TRANSFERS 4
+
+#if USB_MAX_EP_STREAMS == 8
+#define XENHCI_MAX_STREAMS 8
+#define XENHCI_MAX_STREAMS_LOG 3
+#elif USB_MAX_EP_STREAMS == 1
+#define XENHCI_MAX_STREAMS 1
+#define XENHCI_MAX_STREAMS_LOG 0
+#else
+#error "The USB_MAX_EP_STREAMS value is not supported."
+#endif
+
+#define XENHCI_TRB_ALIGN 16 /* bytes */
+#define XENHCI_TD_ALIGN 64 /* bytes */
+
+#define XENHCI_TD_PAGE_NBUF 17 /* units, room enough for 64Kbytes */
+#define XENHCI_TD_PAGE_SIZE 4096 /* bytes */
+#define XENHCI_TD_PAYLOAD_MAX (XENHCI_TD_PAGE_SIZE * (XENHCI_TD_PAGE_NBUF - 1))
+
+struct xenhci_trb {
+ volatile uint64_t qwTrb0;
+#define XENHCI_TRB_0_WLENGTH_MASK (0xFFFFULL << 48)
+ volatile uint32_t dwTrb2;
+#define XENHCI_TRB_2_ERROR_GET(x) (((x) >> 24) & 0xFF)
+#define XENHCI_TRB_2_ERROR_SET(x) (((x) & 0xFF) << 24)
+#define XENHCI_TRB_2_TDSZ_GET(x) (((x) >> 17) & 0x1F)
+#define XENHCI_TRB_2_TDSZ_SET(x) (((x) & 0x1F) << 17)
+#define XENHCI_TRB_2_REM_GET(x) ((x) & 0xFFFFFF)
+#define XENHCI_TRB_2_REM_SET(x) ((x) & 0xFFFFFF)
+#define XENHCI_TRB_2_BYTES_GET(x) ((x) & 0x1FFFF)
+#define XENHCI_TRB_2_BYTES_SET(x) ((x) & 0x1FFFF)
+#define XENHCI_TRB_2_IRQ_GET(x) (((x) >> 22) & 0x3FF)
+#define XENHCI_TRB_2_IRQ_SET(x) (((x) & 0x3FF) << 22)
+#define XENHCI_TRB_2_STREAM_GET(x) (((x) >> 16) & 0xFFFF)
+#define XENHCI_TRB_2_STREAM_SET(x) (((x) & 0xFFFF) << 16)
+
+ volatile uint32_t dwTrb3;
+#define XENHCI_TRB_3_TYPE_GET(x) (((x) >> 10) & 0x3F)
+#define XENHCI_TRB_3_TYPE_SET(x) (((x) & 0x3F) << 10)
+#define XENHCI_TRB_3_CYCLE_BIT (1U << 0)
+#define XENHCI_TRB_3_TC_BIT (1U << 1) /* command ring only */
+#define XENHCI_TRB_3_ENT_BIT (1U << 1) /* transfer ring only */
+#define XENHCI_TRB_3_ISP_BIT (1U << 2)
+#define XENHCI_TRB_3_NSNOOP_BIT (1U << 3)
+#define XENHCI_TRB_3_CHAIN_BIT (1U << 4)
+#define XENHCI_TRB_3_IOC_BIT (1U << 5)
+#define XENHCI_TRB_3_IDT_BIT (1U << 6)
+#define XENHCI_TRB_3_TBC_GET(x) (((x) >> 7) & 3)
+#define XENHCI_TRB_3_TBC_SET(x) (((x) & 3) << 7)
+#define XENHCI_TRB_3_BEI_BIT (1U << 9)
+#define XENHCI_TRB_3_DCEP_BIT (1U << 9)
+#define XENHCI_TRB_3_PRSV_BIT (1U << 9)
+#define XENHCI_TRB_3_BSR_BIT (1U << 9)
+#define XENHCI_TRB_3_TRT_MASK (3U << 16)
+#define XENHCI_TRB_3_TRT_NONE (0U << 16)
+#define XENHCI_TRB_3_TRT_OUT (2U << 16)
+#define XENHCI_TRB_3_TRT_IN (3U << 16)
+#define XENHCI_TRB_3_DIR_IN (1U << 16)
+#define XENHCI_TRB_3_TLBPC_GET(x) (((x) >> 16) & 0xF)
+#define XENHCI_TRB_3_TLBPC_SET(x) (((x) & 0xF) << 16)
+#define XENHCI_TRB_3_EP_GET(x) (((x) >> 16) & 0x1F)
+#define XENHCI_TRB_3_EP_SET(x) (((x) & 0x1F) << 16)
+#define XENHCI_TRB_3_FRID_GET(x) (((x) >> 20) & 0x7FF)
+#define XENHCI_TRB_3_FRID_SET(x) (((x) & 0x7FF) << 20)
+#define XENHCI_TRB_3_ISO_SIA_BIT (1U << 31)
+#define XENHCI_TRB_3_SUSP_EP_BIT (1U << 23)
+#define XENHCI_TRB_3_SLOT_GET(x) (((x) >> 24) & 0xFF)
+#define XENHCI_TRB_3_SLOT_SET(x) (((x) & 0xFF) << 24)
+
+/* Commands */
+#define XENHCI_TRB_TYPE_RESERVED 0x00
+#define XENHCI_TRB_TYPE_NORMAL 0x01
+#define XENHCI_TRB_TYPE_SETUP_STAGE 0x02
+#define XENHCI_TRB_TYPE_DATA_STAGE 0x03
+#define XENHCI_TRB_TYPE_STATUS_STAGE 0x04
+#define XENHCI_TRB_TYPE_ISOCH 0x05
+#define XENHCI_TRB_TYPE_LINK 0x06
+#define XENHCI_TRB_TYPE_EVENT_DATA 0x07
+#define XENHCI_TRB_TYPE_NOOP 0x08
+#define XENHCI_TRB_TYPE_ENABLE_SLOT 0x09
+#define XENHCI_TRB_TYPE_DISABLE_SLOT 0x0A
+#define XENHCI_TRB_TYPE_ADDRESS_DEVICE 0x0B
+#define XENHCI_TRB_TYPE_CONFIGURE_EP 0x0C
+#define XENHCI_TRB_TYPE_EVALUATE_CTX 0x0D
+#define XENHCI_TRB_TYPE_RESET_EP 0x0E
+#define XENHCI_TRB_TYPE_STOP_EP 0x0F
+#define XENHCI_TRB_TYPE_SET_TR_DEQUEUE 0x10
+#define XENHCI_TRB_TYPE_RESET_DEVICE 0x11
+#define XENHCI_TRB_TYPE_FORCE_EVENT 0x12
+#define XENHCI_TRB_TYPE_NEGOTIATE_BW 0x13
+#define XENHCI_TRB_TYPE_SET_LATENCY_TOL 0x14
+#define XENHCI_TRB_TYPE_GET_PORT_BW 0x15
+#define XENHCI_TRB_TYPE_FORCE_HEADER 0x16
+#define XENHCI_TRB_TYPE_NOOP_CMD 0x17
+
+/* Events */
+#define XENHCI_TRB_EVENT_TRANSFER 0x20
+#define XENHCI_TRB_EVENT_CMD_COMPLETE 0x21
+#define XENHCI_TRB_EVENT_PORT_STS_CHANGE 0x22
+#define XENHCI_TRB_EVENT_BW_REQUEST 0x23
+#define XENHCI_TRB_EVENT_DOORBELL 0x24
+#define XENHCI_TRB_EVENT_HOST_CTRL 0x25
+#define XENHCI_TRB_EVENT_DEVICE_NOTIFY 0x26
+#define XENHCI_TRB_EVENT_MFINDEX_WRAP 0x27
+
+/* Error codes */
+#define XENHCI_TRB_ERROR_INVALID 0x00
+#define XENHCI_TRB_ERROR_SUCCESS 0x01
+#define XENHCI_TRB_ERROR_DATA_BUF 0x02
+#define XENHCI_TRB_ERROR_BABBLE 0x03
+#define XENHCI_TRB_ERROR_XACT 0x04
+#define XENHCI_TRB_ERROR_TRB 0x05
+#define XENHCI_TRB_ERROR_STALL 0x06
+#define XENHCI_TRB_ERROR_RESOURCE 0x07
+#define XENHCI_TRB_ERROR_BANDWIDTH 0x08
+#define XENHCI_TRB_ERROR_NO_SLOTS 0x09
+#define XENHCI_TRB_ERROR_STREAM_TYPE 0x0A
+#define XENHCI_TRB_ERROR_SLOT_NOT_ON 0x0B
+#define XENHCI_TRB_ERROR_ENDP_NOT_ON 0x0C
+#define XENHCI_TRB_ERROR_SHORT_PKT 0x0D
+#define XENHCI_TRB_ERROR_RING_UNDERRUN 0x0E
+#define XENHCI_TRB_ERROR_RING_OVERRUN 0x0F
+#define XENHCI_TRB_ERROR_VF_RING_FULL 0x10
+#define XENHCI_TRB_ERROR_PARAMETER 0x11
+#define XENHCI_TRB_ERROR_BW_OVERRUN 0x12
+#define XENHCI_TRB_ERROR_CONTEXT_STATE 0x13
+#define XENHCI_TRB_ERROR_NO_PING_RESP 0x14
+#define XENHCI_TRB_ERROR_EV_RING_FULL 0x15
+#define XENHCI_TRB_ERROR_INCOMPAT_DEV 0x16
+#define XENHCI_TRB_ERROR_MISSED_SERVICE 0x17
+#define XENHCI_TRB_ERROR_CMD_RING_STOP 0x18
+#define XENHCI_TRB_ERROR_CMD_ABORTED 0x19
+#define XENHCI_TRB_ERROR_STOPPED 0x1A
+#define XENHCI_TRB_ERROR_LENGTH 0x1B
+#define XENHCI_TRB_ERROR_BAD_MELAT 0x1D
+#define XENHCI_TRB_ERROR_ISOC_OVERRUN 0x1F
+#define XENHCI_TRB_ERROR_EVENT_LOST 0x20
+#define XENHCI_TRB_ERROR_UNDEFINED 0x21
+#define XENHCI_TRB_ERROR_INVALID_SID 0x22
+#define XENHCI_TRB_ERROR_SEC_BW 0x23
+#define XENHCI_TRB_ERROR_SPLIT_XACT 0x24
+} __aligned(4);
+
+struct xenhci_td {
+ struct xenhci_trb td_trb[XENHCI_TD_PAGE_NBUF + 1];
+
+/*
+ * Extra information needed:
+ */
+ uint64_t td_self;
+ struct xenhci_td *next;
+ struct xenhci_td *alt_next;
+ struct xenhci_td *obj_next;
+ struct usb_page_cache *page_cache;
+ uint32_t len;
+ uint32_t remainder;
+ uint8_t ntrb;
+ uint8_t status;
+} __aligned(XENHCI_TRB_ALIGN);
+
+enum {
+ XENHCI_ST_DISABLED,
+ XENHCI_ST_ENABLED,
+ XENHCI_ST_DEFAULT,
+ XENHCI_ST_ADDRESSED,
+ XENHCI_ST_CONFIGURED,
+ XENHCI_ST_MAX
+};
+
+struct xenhci_event_ring_seg {
+ volatile uint64_t qwEvrsTablePtr;
+ volatile uint32_t dwEvrsTableSize;
+ volatile uint32_t dwEvrsReserved;
+};
+
+struct xenhci_hw_root {
+ struct xenhci_event_ring_seg hwr_ring_seg[XENHCI_MAX_RSEG];
+ struct {
+ volatile uint64_t dummy;
+ } __aligned(64) padding;
+ struct xenhci_trb hwr_events[XENHCI_MAX_EVENTS];
+ struct xenhci_trb hwr_commands[XENHCI_MAX_COMMANDS];
+};
+
+struct xenhci_endpoint_ext {
+ struct xenhci_trb *trb;
+ struct usb_xfer *xfer[XENHCI_MAX_TRANSFERS * XENHCI_MAX_STREAMS];
+ struct usb_page_cache *page_cache;
+ uint64_t physaddr;
+ uint8_t trb_used[XENHCI_MAX_STREAMS];
+ uint8_t trb_index[XENHCI_MAX_STREAMS];
+ uint8_t trb_halted;
+ uint8_t trb_running;
+ uint8_t trb_ep_mode;
+};
+/////////////////////////////////////////////
+
+#define XENHCI_VIRTUAL_FRAMELIST_COUNT 128 /* units */
+
+
+/* Link types */
+#define XENHCI_LINK_TERMINATE 0x00000001
+
+
+/*
+ * Isochronous Transfer Descriptor. This descriptor is used for high speed
+ * transfers only.
+ */
+struct xenhci_itd {
+ volatile uint32_t itd_next;
+ volatile uint32_t itd_status[8];
+#define XENHCI_ITD_SET_LEN(x) ((x) << 16)
+#define XENHCI_ITD_GET_LEN(x) (((x) >> 16) & 0xFFF)
+#define XENHCI_ITD_IOC (1 << 15)
+#define XENHCI_ITD_SET_PG(x) ((x) << 12)
+#define XENHCI_ITD_GET_PG(x) (((x) >> 12) & 0x7)
+#define XENHCI_ITD_SET_OFFS(x) (x)
+#define XENHCI_ITD_GET_OFFS(x) (((x) >> 0) & 0xFFF)
+#define XENHCI_ITD_ACTIVE (1 << 31)
+#define XENHCI_ITD_DATABUFERR (1 << 30)
+#define XENHCI_ITD_BABBLE (1 << 29)
+#define XENHCI_ITD_XACTERR (1 << 28)
+ volatile uint32_t itd_bp[7];
+ /* itd_bp[0] */
+#define XENHCI_ITD_SET_ADDR(x) (x)
+#define XENHCI_ITD_GET_ADDR(x) (((x) >> 0) & 0x7F)
+#define XENHCI_ITD_SET_ENDPT(x) ((x) << 8)
+#define XENHCI_ITD_GET_ENDPT(x) (((x) >> 8) & 0xF)
+ /* itd_bp[1] */
+#define XENHCI_ITD_SET_DIR_IN (1 << 11)
+#define XENHCI_ITD_SET_DIR_OUT (0 << 11)
+#define XENHCI_ITD_SET_MPL(x) (x)
+#define XENHCI_ITD_GET_MPL(x) (((x) >> 0) & 0x7FF)
+ volatile uint32_t itd_bp_hi[7];
+/*
+ * Extra information needed:
+ */
+ uint32_t itd_self;
+ struct xenhci_itd *next;
+ struct xenhci_itd *prev;
+ struct xenhci_itd *obj_next;
+ struct usb_page_cache *page_cache;
+} __aligned(XENHCI_ITD_ALIGN);
+
+typedef struct xenhci_itd xenhci_itd_t;
+
+/*
+ * Split Transaction Isochronous Transfer Descriptor. This descriptor is used
+ * for full speed transfers only.
+ */
+struct xenhci_sitd {
+ volatile uint32_t sitd_next;
+ volatile uint32_t sitd_portaddr;
+#define XENHCI_SITD_SET_DIR_OUT (0 << 31)
+#define XENHCI_SITD_SET_DIR_IN (1 << 31)
+#define XENHCI_SITD_SET_ADDR(x) (x)
+#define XENHCI_SITD_GET_ADDR(x) ((x) & 0x7F)
+#define XENHCI_SITD_SET_ENDPT(x) ((x) << 8)
+#define XENHCI_SITD_GET_ENDPT(x) (((x) >> 8) & 0xF)
+#define XENHCI_SITD_GET_DIR(x) ((x) >> 31)
+#define XENHCI_SITD_SET_PORT(x) ((x) << 24)
+#define XENHCI_SITD_GET_PORT(x) (((x) >> 24) & 0x7F)
+#define XENHCI_SITD_SET_HUBA(x) ((x) << 16)
+#define XENHCI_SITD_GET_HUBA(x) (((x) >> 16) & 0x7F)
+ volatile uint32_t sitd_mask;
+#define XENHCI_SITD_SET_SMASK(x) (x)
+#define XENHCI_SITD_SET_CMASK(x) ((x) << 8)
+ volatile uint32_t sitd_status;
+#define XENHCI_SITD_COMPLETE_SPLIT (1<<1)
+#define XENHCI_SITD_START_SPLIT (0<<1)
+#define XENHCI_SITD_MISSED_MICRO_FRAME (1<<2)
+#define XENHCI_SITD_XACTERR (1<<3)
+#define XENHCI_SITD_BABBLE (1<<4)
+#define XENHCI_SITD_DATABUFERR (1<<5)
+#define XENHCI_SITD_ERROR (1<<6)
+#define XENHCI_SITD_ACTIVE (1<<7)
+#define XENHCI_SITD_IOC (1<<31)
+#define XENHCI_SITD_SET_LEN(len) ((len)<<16)
+#define XENHCI_SITD_GET_LEN(x) (((x)>>16) & 0x3FF)
+ volatile uint32_t sitd_bp[2];
+ volatile uint32_t sitd_back;
+ volatile uint32_t sitd_bp_hi[2];
+/*
+ * Extra information needed:
+ */
+ uint32_t sitd_self;
+ struct xenhci_sitd *next;
+ struct xenhci_sitd *prev;
+ struct xenhci_sitd *obj_next;
+ struct usb_page_cache *page_cache;
+} __aligned(XENHCI_SITD_ALIGN);
+
+typedef struct xenhci_sitd xenhci_sitd_t;
+
+/* Queue Element Transfer Descriptor */
+struct xenhci_qtd {
+ volatile uint32_t qtd_next;
+ volatile uint32_t qtd_altnext;
+ volatile uint32_t qtd_status;
+#define XENHCI_QTD_GET_STATUS(x) (((x) >> 0) & 0xff)
+#define XENHCI_QTD_SET_STATUS(x) ((x) << 0)
+#define XENHCI_QTD_ACTIVE 0x80
+#define XENHCI_QTD_HALTED 0x40
+#define XENHCI_QTD_BUFERR 0x20
+#define XENHCI_QTD_BABBLE 0x10
+#define XENHCI_QTD_XACTERR 0x08
+#define XENHCI_QTD_MISSEDMICRO 0x04
+#define XENHCI_QTD_SPLITXSTATE 0x02
+#define XENHCI_QTD_PINGSTATE 0x01
+#define XENHCI_QTD_STATERRS 0x74
+#define XENHCI_QTD_GET_PID(x) (((x) >> 8) & 0x3)
+#define XENHCI_QTD_SET_PID(x) ((x) << 8)
+#define XENHCI_QTD_PID_OUT 0x0
+#define XENHCI_QTD_PID_IN 0x1
+#define XENHCI_QTD_PID_SETUP 0x2
+#define XENHCI_QTD_GET_CERR(x) (((x) >> 10) & 0x3)
+#define XENHCI_QTD_SET_CERR(x) ((x) << 10)
+#define XENHCI_QTD_GET_C_PAGE(x) (((x) >> 12) & 0x7)
+#define XENHCI_QTD_SET_C_PAGE(x) ((x) << 12)
+#define XENHCI_QTD_GET_IOC(x) (((x) >> 15) & 0x1)
+#define XENHCI_QTD_IOC 0x00008000
+#define XENHCI_QTD_GET_BYTES(x) (((x) >> 16) & 0x7fff)
+#define XENHCI_QTD_SET_BYTES(x) ((x) << 16)
+#define XENHCI_QTD_GET_TOGGLE(x) (((x) >> 31) & 0x1)
+#define XENHCI_QTD_SET_TOGGLE(x) ((x) << 31)
+#define XENHCI_QTD_TOGGLE_MASK 0x80000000
+#define XENHCI_QTD_NBUFFERS 5
+#define XENHCI_QTD_PAYLOAD_MAX ((XENHCI_QTD_NBUFFERS-1)*XENHCI_PAGE_SIZE)
+ volatile uint32_t qtd_buffer[XENHCI_QTD_NBUFFERS];
+ volatile uint32_t qtd_buffer_hi[XENHCI_QTD_NBUFFERS];
+/*
+ * Extra information needed:
+ */
+ struct xenhci_qtd *alt_next;
+ struct xenhci_qtd *obj_next;
+ struct usb_page_cache *page_cache;
+ uint32_t qtd_self;
+ uint16_t len;
+} __aligned(XENHCI_QTD_ALIGN);
+
+typedef struct xenhci_qtd xenhci_qtd_t;
+
+/* Queue Head Sub Structure */
+struct xenhci_qh_sub {
+ volatile uint32_t qtd_next;
+ volatile uint32_t qtd_altnext;
+ volatile uint32_t qtd_status;
+ volatile uint32_t qtd_buffer[XENHCI_QTD_NBUFFERS];
+ volatile uint32_t qtd_buffer_hi[XENHCI_QTD_NBUFFERS];
+} __aligned(4);
+
+/* Queue Head */
+struct xenhci_qh {
+ volatile uint32_t qh_link;
+ volatile uint32_t qh_endp;
+#define XENHCI_QH_GET_ADDR(x) (((x) >> 0) & 0x7f) /* endpoint addr */
+#define XENHCI_QH_SET_ADDR(x) (x)
+#define XENHCI_QH_ADDRMASK 0x0000007f
+#define XENHCI_QH_GET_INACT(x) (((x) >> 7) & 0x01) /* inactivate on next */
+#define XENHCI_QH_INACT 0x00000080
+#define XENHCI_QH_GET_ENDPT(x) (((x) >> 8) & 0x0f) /* endpoint no */
+#define XENHCI_QH_SET_ENDPT(x) ((x) << 8)
+#define XENHCI_QH_GET_EPS(x) (((x) >> 12) & 0x03) /* endpoint speed */
+#define XENHCI_QH_SET_EPS(x) ((x) << 12)
+#define XENHCI_QH_SPEED_FULL 0x0
+#define XENHCI_QH_SPEED_LOW 0x1
+#define XENHCI_QH_SPEED_HIGH 0x2
+#define XENHCI_QH_GET_DTC(x) (((x) >> 14) & 0x01) /* data toggle control */
+#define XENHCI_QH_DTC 0x00004000
+#define XENHCI_QH_GET_HRECL(x) (((x) >> 15) & 0x01) /* head of reclamation */
+#define XENHCI_QH_HRECL 0x00008000
+#define XENHCI_QH_GET_MPL(x) (((x) >> 16) & 0x7ff) /* max packet len */
+#define XENHCI_QH_SET_MPL(x) ((x) << 16)
+#define XENHCI_QH_MPLMASK 0x07ff0000
+#define XENHCI_QH_GET_CTL(x) (((x) >> 27) & 0x01) /* control endpoint */
+#define XENHCI_QH_CTL 0x08000000
+#define XENHCI_QH_GET_NRL(x) (((x) >> 28) & 0x0f) /* NAK reload */
+#define XENHCI_QH_SET_NRL(x) ((x) << 28)
+ volatile uint32_t qh_endphub;
+#define XENHCI_QH_GET_SMASK(x) (((x) >> 0) & 0xff) /* intr sched mask */
+#define XENHCI_QH_SET_SMASK(x) ((x) << 0)
+#define XENHCI_QH_GET_CMASK(x) (((x) >> 8) & 0xff) /* split completion mask */
+#define XENHCI_QH_SET_CMASK(x) ((x) << 8)
+#define XENHCI_QH_GET_HUBA(x) (((x) >> 16) & 0x7f) /* hub address */
+#define XENHCI_QH_SET_HUBA(x) ((x) << 16)
+#define XENHCI_QH_GET_PORT(x) (((x) >> 23) & 0x7f) /* hub port */
+#define XENHCI_QH_SET_PORT(x) ((x) << 23)
+#define XENHCI_QH_GET_MULT(x) (((x) >> 30) & 0x03) /* pipe multiplier */
+#define XENHCI_QH_SET_MULT(x) ((x) << 30)
+ volatile uint32_t qh_curqtd;
+ struct xenhci_qh_sub qh_qtd;
+/*
+ * Extra information needed:
+ */
+ struct xenhci_qh *next;
+ struct xenhci_qh *prev;
+ struct xenhci_qh *obj_next;
+ struct usb_page_cache *page_cache;
+ uint32_t qh_self;
+} __aligned(XENHCI_QH_ALIGN);
+
+typedef struct xenhci_qh xenhci_qh_t;
+
+/////////////////////////////////////////////
+
/* ring request shadow */
struct usb_shadow {
usbif_urb_request_t req;
- struct urb *urb;
+ //struct urb *urb;
+ struct usb_xfer *xfer;
};
/* virtual roothub port status */
@@ -103,7 +516,7 @@
union xenhci_hub_desc {
struct usb_status stat;
struct usb_port_status ps;
- //struct usb_hub_ss_descriptor hubd;
+ struct usb_hub_descriptor hubd;
uint8_t temp[128];
};
@@ -132,9 +545,11 @@
struct usb_callout sc_callout;
union xenhci_hub_desc sc_hub_desc;
+ struct sx sc_cmd_sx;//TODO???
+
struct usb_device *sc_devices[XENHCI_MAX_DEVICES];
- /* number of XHCI device slots */
+ /* number of XENHCI device slots */
uint8_t sc_noslot;
/* number of ports on root HUB */
uint8_t sc_noport; //<32 in xen
@@ -143,10 +558,18 @@
/* root HUB device configuration */
uint8_t sc_conf;
uint8_t sc_hub_idata[2];
+ /* device configuration */
+ uint8_t sc_addr;
/* vendor string for root HUB */
char sc_vendor[16];
+ // usb transfer
+ struct xenhci_qh *sc_async_p_last;
+ struct xenhci_qh *sc_intr_p_last[XENHCI_VIRTUAL_FRAMELIST_COUNT];
+ struct xenhci_sitd *sc_isoc_fs_p_last[XENHCI_VIRTUAL_FRAMELIST_COUNT];
+ struct xenhci_itd *sc_isoc_hs_p_last[XENHCI_VIRTUAL_FRAMELIST_COUNT];
+
/* Virtual Host Controller has 4 urb queues */
LIST_ENTRY(list_head) pending_submit_list; //??
@@ -179,14 +602,44 @@
unsigned long shadow_free;
/* ring response thread */
- struct task *kthread;//struct task_struct *kthread;
+ //struct task *kthread;//struct task_struct *kthread;
//LIST_ENTRY(list_head) *wait_list; //wait_queue_head_t wq;??
struct taskqueue *wait_taskqueue;
unsigned int waiting_resp;//
};
+#define XENHCI_CMD_LOCK(sc) sx_xlock(&(sc)->sc_cmd_sx)
+#define XENHCI_CMD_UNLOCK(sc) sx_xunlock(&(sc)->sc_cmd_sx)
+
+/*
+ * Normal little-endian only conversion routines.
+ */
+static __inline uint32_t
+htohc32(const struct xenhci_softc *sc, const uint32_t v)
+{
+ return htole32(v);
+}
+
+static __inline uint16_t
+htohc16(const struct xenhci_softc *sc, const uint16_t v)
+{
+ return htole16(v);
+}
+
+static __inline uint32_t
+hc32toh(const struct xenhci_softc *sc, const uint32_t v)
+{
+ return le32toh(v);
+}
+
+static __inline uint16_t
+hc16toh(const struct xenhci_softc *sc, const uint16_t v)
+{
+ return le16toh(v);
+}
/* prototypes */
-usb_error_t xenhci_init(struct xenhci_softc *, device_t);
+usb_error_t xenhci_init(struct xenhci_softc *, device_t);
+void xenhci_uninit(struct xenhci_softc *);
#endif /* _USBFRONT_H_ */
More information about the svn-soc-all
mailing list