📄 ohci.h
字号:
#ifndef __LINUX_OHCI_H#define __LINUX_OHCI_H/* * Open Host Controller Interface data structures and defines. * * (C) Copyright 1999 Gregory P. Smith <greg@electricrain.com> * * $Id: ohci.h,v 1.6 1999/04/24 22:50:06 greg Exp $ */#include <linux/list.h>#include <asm/io.h>#include "usb.h"/* * Each TD must be aligned on a 16-byte boundary. From the OHCI v1.0 spec * it does not state that TDs must be contiguious in memory (due to the * use of the next_td field). This gives us extra room at the end of a * TD for our own driver specific data. * * This structure's size must be a multiple of 16 bytes. */struct ohci_td { /* OHCI Hardware fields */ __u32 info; __u32 cur_buf; /* Current Buffer Pointer */ __u32 next_td; /* Next TD Pointer */ __u32 buf_end; /* Memory Buffer End Pointer */ /* Driver specific fields */ struct list_head irq_list; /* Active interrupt list */ usb_device_irq completed; /* Completion handler routine */ void *data; /* XXX ? */ void *dev_id; /* XXX ? */ __u32 ed_bus; /* bus address of original ED */} __attribute((aligned(32)));#define OHCI_TD_ROUND (1 << 18) /* buffer rounding bit */#define OHCI_TD_D (3 << 11) /* direction of xfer: */#define OHCI_TD_D_IN (2 << 11)#define OHCI_TD_D_OUT (1 << 11)#define OHCI_TD_D_SETUP (0)#define td_set_dir_in(d) ((d) ? OHCI_TD_D_IN : OHCI_TD_D_OUT )#define td_set_dir_out(d) ((d) ? OHCI_TD_D_OUT : OHCI_TD_D_IN )#define OHCI_TD_IOC_DELAY (7 << 21) /* frame delay allowed before int. */#define OHCI_TD_IOC_OFF (OHCI_TD_IOC_DELAY) /* no interrupt on complete */#define OHCI_TD_DT (3 << 24) /* data toggle bits */#define td_force_toggle(b) (((b) | 2) << 24)#define OHCI_TD_ERRCNT (3 << 26) /* error count */#define td_errorcount(td) (((td) >> 26) & 3)#define OHCI_TD_CC (0xf << 28) /* condition code */#define OHCI_TD_CC_NEW (OHCI_TD_CC) /* set this on all unaccessed TDs! */#define td_cc_notaccessed(td) ((td >> 29) == 7)#define td_cc_accessed(td) ((td >> 29) != 7)#define td_cc_noerror(td) (((td) & OHCI_TD_CC) == 0)#define td_active(td) (!td_cc_noerror((td)) && (td_errorcount((td)) < 3))#define td_done(td) (td_cc_noerror((td)) || (td_errorcount((td)) == 3))/* * The endpoint descriptors also requires 16-byte alignment */struct ohci_ed { /* OHCI hardware fields */ __u32 status; __u32 tail_td; /* TD Queue tail pointer */ __u32 head_td; /* TD Queue head pointer */ __u32 next_ed; /* Next ED */} __attribute((aligned(16)));#define OHCI_ED_SKIP (1 << 14)#define OHCI_ED_MPS (0x7ff << 16)/* FIXME: should cap at the USB max packet size [0x4ff] */#define ed_set_maxpacket(s) (((s) << 16) & OHCI_ED_MPS)#define OHCI_ED_F_NORM (0)#define OHCI_ED_F_ISOC (1 << 15)#define ed_set_type_isoc(i) ((i) ? OHCI_ED_F_ISOC : OHCI_ED_F_NORM)#define OHCI_ED_S_LOW (1 << 13)#define OHCI_ED_S_HIGH (0)#define ed_set_speed(s) ((s) ? OHCI_ED_S_LOW : OHCI_ED_S_HIGH)#define OHCI_ED_D (3 << 11)#define OHCI_ED_D_IN (2 << 11)#define OHCI_ED_D_OUT (1 << 11)#define ed_set_dir_in(d) ((d) ? OHCI_ED_D_IN : OHCI_ED_D_OUT)#define ed_set_dir_out(d) ((d) ? OHCI_ED_D_OUT : OHCI_ED_D_IN)#define OHCI_ED_EN (0xf << 7)#define OHCI_ED_FA (0x7f)/* NOTE: bits 27-31 of the status dword are reserved for the driver *//* * We'll use this status flag for the non-predefined EDs to mark if * they're in use or not. * * FIXME: unimplemented (needed?) */#define ED_USED (1 << 31)/* * The HCCA (Host Controller Communications Area) is a 256 byte * structure defined in the OHCI spec. that the host controller is * told the base address of. It must be 256-byte aligned. */#define NUM_INTS 32 /* part of the OHCI standard */struct ohci_hcca { __u32 int_table[NUM_INTS]; /* Interrupt ED table */ __u16 frame_no; /* current frame number */ __u16 pad1; /* set to 0 on each frame_no change */ __u32 donehead; /* info returned for an interrupt */ u8 reserved_for_hc[116];} __attribute((aligned(256)));/* * The TD entries here are pre-allocated as Linus did with his simple * UHCI implementation. With the current state of this driver that * shouldn't be a problem. However if someone ever connects 127 * supported devices to this driver and tries to use them all at once: * a) They're insane! * b) They should code in dynamic allocation */struct ohci;/* * Warning: These constants must not be so large as to cause the * ohci_device structure to exceed one 4096 byte page. Or "weird * things will happen" as the alloc_ohci() function assumes that * its less than one page. (FIXME) */#define NUM_TDS 32 /* num of preallocated transfer descriptors */#define DATA_BUF_LEN 16 /* num of unsigned long's for the data buf *//* * For this "simple" driver we only support a single ED for each * polling rate. * * Later on this driver should be extended to use a full tree of EDs * so that there can be 32 different 32ms polling frames, etc. * Individual devices shouldn't need as many as the root hub in that * case; complicating how things are done at the moment. * * Bulk and Control transfers hang off of their own ED lists. */#define NUM_EDS 16 /* num of preallocated endpoint descriptors */#define ohci_to_usb(ohci) ((ohci)->usb)#define usb_to_ohci(usb) ((struct ohci_device *)(usb)->hcpriv)/* The usb_device must be first! */struct ohci_device { struct usb_device *usb; struct ohci *ohci; struct ohci_hcca *hcca; /* OHCI mem. mapped IO area */ struct ohci_ed ed[NUM_EDS]; /* Endpoint Descriptors */ struct ohci_td td[NUM_TDS]; /* Transfer Descriptors */ unsigned long data[DATA_BUF_LEN];};/* .... */#define ED_INT_1 0#define ED_INT_2 1#define ED_INT_4 2#define ED_INT_8 3#define ED_INT_16 4#define ED_INT_32 5#define ED_CONTROL 6#define ED_BULK 7#define ED_ISO ED_INT_1 /* same as 1ms interrupt queue */#define ED_FIRST_AVAIL 8 /* first non-reserved ED *//* * Given a period p in ms, convert it to the closest endpoint * interrupt frequency; rounding down. I'm sure many feel that this * is a gross macro. Feel free to toss it for actual code. */#define ms_to_ed_int(p) \ ((p >= 32) ? ED_INT_32 : \ ((p & 16) ? ED_INT_16 : \ ((p & 8) ? ED_INT_8 : \ ((p & 4) ? ED_INT_4 : \ ((p & 2) ? ED_INT_2 : \ ED_INT_1))))) /* hmm.. scheme or lisp anyone? *//* * This is the maximum number of root hub ports. I don't think we'll * ever see more than two as that's the space available on an ATX * motherboard's case, but it could happen. The OHCI spec allows for * up to 15... (which is insane!) * * Although I suppose several "ports" could be connected directly to * internal laptop devices such as a keyboard, mouse, camera and * serial/parallel ports. hmm... That'd be neat. */#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports *//* * This is the structure of the OHCI controller's memory mapped I/O * region. This is Memory Mapped I/O. You must use the readl() and * writel() macros defined in asm/io.h to access these!! */struct ohci_regs { /* control and status registers */ __u32 revision; __u32 control; __u32 cmdstatus; __u32 intrstatus; __u32 intrenable; __u32 intrdisable; /* memory pointers */ __u32 hcca; __u32 ed_periodcurrent; __u32 ed_controlhead; __u32 ed_controlcurrent; __u32 ed_bulkhead; __u32 ed_bulkcurrent; __u32 current_donehead; /* The driver should get this from the HCCA */ /* frame counters */ __u32 fminterval; __u32 fmremaining; __u32 fmnumber; __u32 periodicstart; __u32 lsthresh; /* Root hub ports */ struct ohci_roothub_regs { __u32 a; __u32 b; __u32 status; __u32 portstatus[MAX_ROOT_PORTS]; } roothub;} __attribute((aligned(32)));/* * Read a MMIO register and re-write it after ANDing with (m) */#define writel_mask(m, a) writel( (readl((__u32)(a))) & (__u32)(m), (__u32)(a) )/* * Read a MMIO register and re-write it after ORing with (b) */#define writel_set(b, a) writel( (readl((__u32)(a))) | (__u32)(b), (__u32)(a) )#define PORT_CCS (1) /* port current connect status */#define PORT_PES (1 << 1) /* port enable status */#define PORT_PSS (1 << 2) /* port suspend status */#define PORT_POCI (1 << 3) /* port overcurrent indicator */#define PORT_PRS (1 << 4) /* port reset status */#define PORT_PPS (1 << 8) /* port power status */#define PORT_LSDA (1 << 9) /* port low speed dev. attached */#define PORT_CSC (1 << 16) /* port connect status change */#define PORT_PESC (1 << 17) /* port enable status change */#define PORT_PSSC (1 << 18) /* port suspend status change */#define PORT_OCIC (1 << 19) /* port over current indicator chg */#define PORT_PRSC (1 << 20) /* port reset status change *//* * Interrupt register masks */#define OHCI_INTR_SO (1)#define OHCI_INTR_WDH (1 << 1)#define OHCI_INTR_SF (1 << 2)#define OHCI_INTR_RD (1 << 3)#define OHCI_INTR_UE (1 << 4)#define OHCI_INTR_FNO (1 << 5)#define OHCI_INTR_RHSC (1 << 6)#define OHCI_INTR_OC (1 << 30)#define OHCI_INTR_MIE (1 << 31)/* * Control register masks */#define OHCI_USB_OPER (2 << 6)#define OHCI_USB_SUSPEND (3 << 6)/* * This is the full ohci controller description * * Note how the "proper" USB information is just * a subset of what the full implementation needs. (Linus) */struct ohci { int irq; struct ohci_regs *regs; /* OHCI controller's memory */ struct usb_bus *bus; struct ohci_device *root_hub; /* Root hub & controller */ struct list_head interrupt_list; /* List of interrupt active TDs for this OHCI */};/* Debugging code */void show_ed(struct ohci_ed *ed);void show_td(struct ohci_td *td);void show_status(struct ohci *ohci);#endif/* vim:sw=8 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -