📄 pehci.h
字号:
typedef struct isp1761_mem_addr {
void *phy_addr; /* Physical address of the memory */
void *virt_addr; /* after ioremap() function call */
__u8 usage;
__u32 blk_size; /*block size*/
}isp1761_mem_addr_t;
#endif
struct ehci_itd {
/* first part defined by EHCI spec */
u32 hw_next; /* see EHCI 3.3.1 */
u32 hw_transaction [8]; /* see EHCI 3.3.2 */
#define EHCI_ISOC_ACTIVE (1<<31) /* activate transfer this slot */
#define EHCI_ISOC_BUF_ERR (1<<30) /* Data buffer error */
#define EHCI_ISOC_BABBLE (1<<29) /* babble detected */
#define EHCI_ISOC_XACTERR (1<<28) /* XactErr - transaction error */
#define EHCI_ITD_LENGTH(tok) (((tok)>>16) & 0x7fff)
#define EHCI_ITD_IOC (1 << 15) /* interrupt on complete */
u32 hw_bufp [7]; /* see EHCI 3.3.3 */
u32 hw_bufp_hi [7]; /* Appendix B */
/* the rest is HCD-private */
dma_addr_t itd_dma; /* for this itd */
struct urb *urb;
struct list_head itd_list; /* list of urb frames' itds */
dma_addr_t buf_dma; /* frame's buffer address */
/* for now, only one hw_transaction per itd */
u32 transaction;
u16 index; /* in urb->iso_frame_desc */
u16 uframe; /* in periodic schedule */
u16 usecs;
/*memory address*/
struct isp1761_mem_addr mem_addr;
int length;
u32 multi;
u32 framenumber;
u32 ptdframe;
int itd_index;
/*scheduling fields*/
u32 ssplit;
u32 csplit;
};
/*
* EHCI Specification 0.95 Section 3.5
* QTD: describe data transfer components (buffer, direction, ...)
* See Fig 3-6 "Queue Element Transfer Descriptor Block Diagram".
*
* These are associated only with "QH" (Queue Head) structures,
* used with control, bulk, and interrupt transfers.
*/
struct ehci_qtd {
/* first part defined by EHCI spec */
u32 hw_next; /* see EHCI 3.5.1 */
u32 hw_alt_next; /* see EHCI 3.5.2 */
u32 hw_token; /* see EHCI 3.5.3 */
u32 hw_buf [5]; /* see EHCI 3.5.4 */
u32 hw_buf_hi [5]; /* Appendix B */
/* the rest is HCD-private */
dma_addr_t qtd_dma; /* qtd address */
struct list_head qtd_list; /* sw qtd list */
struct urb *urb; /* qtd's urb */
size_t length; /* length of buffer */
u32 state; /*state of the qtd*/
#define QTD_STATE_NEW 0x100
#define QTD_STATE_DONE 0x200
#define QTD_STATE_SCHEDULED 0x400
#define QTD_STATE_LAST 0x800
struct isp1761_mem_addr mem_addr;
};
#define QTD_TOGGLE (1 << 31) /* data toggle */
#define QTD_LENGTH(tok) (((tok)>>16) & 0x7fff)
#define QTD_IOC (1 << 15) /* interrupt on complete */
#define QTD_CERR(tok) (((tok)>>10) & 0x3)
#define QTD_PID(tok) (((tok)>>8) & 0x3)
#define QTD_STS_ACTIVE (1 << 7) /* HC may execute this */
#define QTD_STS_HALT (1 << 6) /* halted on error */
#define QTD_STS_DBE (1 << 5) /* data buffer error (in HC) */
#define QTD_STS_BABBLE (1 << 4) /* device was babbling (qtd halted) */
#define QTD_STS_XACT (1 << 3) /* device gave illegal response */
#define QTD_STS_MMF (1 << 2) /* incomplete split transaction */
#define QTD_STS_STS (1 << 1) /* split transaction state */
#define QTD_STS_PING (1 << 0) /* issue PING? */
/* for periodic/async schedules and qtd lists, mark end of list */
#define EHCI_LIST_END __constant_cpu_to_le32(1) /* "null pointer" to hw */
#define QTD_NEXT(dma) cpu_to_le32((u32)dma)
struct _phci_driver;
struct _isp1761_hcd;
#define EHCI_MAX_ROOT_PORTS 1
#include "../drivers/usb/core/hcd.h"
/*host controller*/
typedef struct _phci_hcd {
struct usb_hcd usb_hcd;
spinlock_t lock;
/* async schedule support */
struct ehci_qh *async;
struct ehci_qh *reclaim;
/* periodic schedule support */
unsigned periodic_size;
int next_uframe; /* scan periodic, start here */
int periodic_sched; /* periodic activity count */
struct usb_device *otgdev; /*otg deice, with address 2*/
struct timer_list rh_timer; /* drives root hub */
struct list_head dev_list; /* devices on this bus */
struct list_head urb_list; /*iso testing*/
/*msec break in interrupts*/
atomic_t nuofsofs;
atomic_t missedsofs;
struct isp1761_dev *dev;
/*hw info*/
u8 *iobase;
u32 iolength;
u8 *plxiobase;
u32 plxiolength;
int irq; /* irq allocated */
int state;/*state of the host controller*/
unsigned long reset_done[EHCI_MAX_ROOT_PORTS];
ehci_regs regs;
struct _isp1761_qha qha;
struct _isp1761_qhint qhint;
struct _isp1761_isoptd isotd;
struct tasklet_struct tasklet;
/*this timer is going to run every 20 msec*/
struct timer_list watchdog;
void (*worker_function) (struct _phci_hcd* hcd);
struct _periodic_list periodic_list[PTD_PERIODIC_SIZE];
}phci_hcd,*pphci_hcd;
/*usb_device->hcpriv, points to this structure*/
typedef struct hcd_dev{
struct list_head dev_list;
struct list_head urb_list;
}hcd_dev;
#define usb_hcd_to_pehci_hcd(hcd) container_of(hcd, struct _phci_hcd, usb_hcd)
/*td allocation*/
#ifdef CONFIG_PHCI_MEM_SLAB
#define qha_alloc(t,c) kmem_cache_alloc(c,ALLOC_FLAGS)
#define qha_free(c,x) kmem_cache_free(c,x)
static kmem_cache_t *qha_cache, *qh_cache,*qtd_cache;
static int phci_hcd_mem_init (void)
{
/* qha TDs accessed by controllers and host */
qha_cache = kmem_cache_create ("phci_ptd", sizeof (isp1761_qha), 0,
SLAB_HWCACHE_ALIGN, NULL, NULL);
if (!qha_cache) {
printk("no TD cache?");
return -ENOMEM;
}
/* qh TDs accessed by controllers and host */
qh_cache = kmem_cache_create ("phci_ptd", sizeof (isp1761_qha), 0,
SLAB_HWCACHE_ALIGN, NULL, NULL);
if (!qh_cache) {
printk("no TD cache?");
return -ENOMEM;
}
/* qtd accessed by controllers and host */
qtd_cache = kmem_cache_create ("phci_ptd", sizeof (isp1761_qha), 0,
SLAB_HWCACHE_ALIGN, NULL, NULL);
if (!qtd_cache) {
printk("no TD cache?");
return -ENOMEM;
}
return 0;
}
static void
phci_mem_cleanup(void)
{
if (qha_cache && kmem_cache_destroy (qha_cache))
err ("td_cache remained");
qha_cache = 0;
}
#else
#define qha_alloc(t,c) kmalloc(t,ALLOC_FLAGS)
#define qha_free(c,x) kfree(x)
#define qha_cache 0
/*memory constants*/
#define BLK_256_ 32 /*8k*/
#define BLK_1024_ 20 /*20K*/
#define BLK_4096_ 8 /*32K*/
#define BLK_TOTAL (BLK_256_ + BLK_1024_ + BLK_4096_)
#define BLK_SIZE_256 256
#define BLK_SIZE_1024 1024
#define BLK_SIZE_4096 4096
static void phci_hcd_mem_init(void);
static inline void phci_mem_cleanup (void) { return; }
#endif
#define PORT_WKOC_E (1<<22) /* wake on overcurrent (enable) */
#define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */
#define PORT_WKCONN_E (1<<20) /* wake on connect (enable) */
/* 19:16 for port testing */
/* 15:14 for using port indicator leds (if HCS_INDICATOR allows) */
#define PORT_OWNER (1<<13) /* true: companion hc owns this port */
#define PORT_POWER (1<<12) /* true: has power (see PPC) */
#define PORT_USB11(x) (((x)&(3<<10))==(1<<10)) /* USB 1.1 device */
/* 11:10 for detecting lowspeed devices (reset vs release ownership) */
/* 9 reserved */
#define PORT_RESET (1<<8) /* reset port */
#define PORT_SUSPEND (1<<7) /* suspend port */
#define PORT_RESUME (1<<6) /* resume it */
#define PORT_OCC (1<<5) /* over current change */
#define PORT_OC (1<<4) /* over current active */
#define PORT_PEC (1<<3) /* port enable change */
#define PORT_PE (1<<2) /* port enable */
#define PORT_CSC (1<<1) /* connect status change */
#define PORT_CONNECT (1<<0) /* device connected */
/*Legends,
* ATL control, bulk transfer
* INTL interrupt transfer
* ISTL iso transfer
* */
/*buffer(transfer) bitmaps*/
#define ATL_BUFFER 0x1
#define INT_BUFFER 0x2
#define ISO_BUFFER 0x4
#define BUFFER_MAP 0x7
/* buffer type for Philips HC */
#define TD_PTD_BUFF_TYPE_ATL 0 /* ATL buffer */
#define TD_PTD_BUFF_TYPE_INTL 1 /* INTL buffer */
#define TD_PTD_BUFF_TYPE_ISTL 2 /* ISO buffer */
#define TD_PTD_TOTAL_BUFF_TYPES (TD_PTD_BUFF_TYPE_ISTL +1)
/*maximum number of tds per transfer type*/
#define TD_PTD_MAX_BUFF_TDS 32
/*invalid td index in the headers*/
#define TD_PTD_INV_PTD_INDEX 0xFFFFFFFF
/*Host controller buffer defination*/
#define INVALID_FRAME_NUMBER 0xFFFFFFFF
/*per td transfer size*/
#define HC_ATL_PL_SIZE 4096
#define HC_ISTL_PL_SIZE 1024
#define HC_INTL_PL_SIZE 1024
/*TD_PTD_MAP states*/
#define TD_PTD_NEW 0x0000
#define TD_PTD_ACTIVE 0x0001
#define TD_PTD_IDLE 0x0002
#define TD_PTD_REMOVE 0x0004
#define TD_PTD_RELOAD 0x0008
#define TD_PTD_IN_SCHEDULE 0x0010
#define TD_PTD_DONE 0x0020
#define PTD_RETRY(x) (((x) >> 23) & 0x3)
#define PTD_PID(x) (((x) >> 10) & (0x3))
#define PTD_NEXTTOGGLE(x) (((x) >> 25) & (0x1))
#define PTD_XFERRED_LENGTH(x) ((x) & 0x7fff)
#define PTD_XFERRED_NONHSLENGTH(x) ((x) & 0x7ff)
#define PTD_PING_STATE(x) (((x) >> 26) & (0x1))
/* urb state*/
#define DELETE_URB 0x0008
#define NO_TRANSFER_ACTIVE 0xFFFFFFFF
#define MAX_PTD_BUFFER_SIZE 4096 /*max ptd size*/
/*information of the td in headers of host memory*/
typedef struct td_ptd_map {
u32 state; /* ACTIVE, NEW, TO_BE_REMOVED */
u8 datatoggle; /*to preserve the data toggle for ATL/ISTL transfers*/
u32 ptd_bitmap; /* Bitmap of this ptd in HC headers */
u32 ptd_header_addr;/* headers address of this td */
u32 ptd_data_addr; /*data address of this td to write in and read from*/
/*this is address is actual RAM address not the CPU address
* RAM address = (CPU ADDRESS-0x400) >> 3
* */
u32 ptd_ram_data_addr;
u8 lasttd; /*last td , complete the transfer*/
struct ehci_qh *qh; /* endpoint */
struct ehci_qtd *qtd; /* qtds for this endpoint */
struct ehci_itd *itd; /*itd pointer*/
/*iso specific only*/
u32 grouptdmap; /*if td need to complete with error, then process all the tds
in the groupmap */
} td_ptd_map_t;
/*buffer(ATL/ISTL/INTL) managemnet*/
typedef struct td_ptd_map_buff {
u8 buffer_type; /* Buffer type: BUFF_TYPE_ATL/INTL/ISTL0/ISTL1 */
u8 active_ptds; /* number of active td's in the buffer */
u8 total_ptds; /* Total number of td's present in the buffer (active + tobe removed + skip) */
u8 max_ptds; /* Maximum number of ptd's(32) this buffer can withstand */
u32 active_ptd_bitmap; /* Active PTD's bitmap */
u32 pending_ptd_bitmap; /* skip PTD's bitmap */
td_ptd_map_t map_list[TD_PTD_MAX_BUFF_TDS]; /* td_ptd_map list */
} td_ptd_map_buff_t;
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -