日期:2014-05-16 浏览次数:21199 次
struct usb_request {
void *buf;
unsigned length;
dma_addr_t dma;
unsigned no_interrupt:1;
unsigned zero:1;
unsigned short_not_ok:1;
void (*complete)(struct usb_ep *ep,
struct usb_request *req);
void *context;
struct list_head list;
int status;
unsigned actual;
};
(1)buf 字段是要接受或者发送数据存储的地方,而length代表了数据的长度。static irqreturn_t s3c2410_udc_irq(int dummy, void *_dev)
{
//这个是在设备控制器初始化的时候注册中断处理程序的语句:retval = request_irq(IRQ_USBD, s3c2410_udc_irq, IRQF_DISABLED, gadget_name, udc); 最后一个参数udc是一个struct s3c2410_udc
//的结构体,代表了一个USB设备控制器也就是s3c2410的设备控制器,这个结构体指针指向了一个已经初始化好了的struct s3c2410_udc变量。所以在中断处理程序开始在参数中提取了这个指针。
struct s3c2410_udc *dev = _dev;
int usb_status;
int usbd_status;
int pwr_reg;
int ep0csr;
int i;
u32 idx;
unsigned long flags;
//自旋锁,保护dev这个结构避免并发引起的竞态,因为是单处理器。这里的自旋锁退化成了一个禁止内核抢占的开关,上锁就是禁止内核抢占
spin_lock_irqsave(&dev->lock, flags);
/* Driver connected ? */
//当没有初始化好USB设备而发生中断时,清除中断标志
if (!dev->driver) {
/* Clear interrupts */
udc_write(udc_read(S3C2410_UDC_USB_INT_REG),
S3C2410_UDC_USB_INT_REG);
udc_write(udc_read(S3C2410_UDC_EP_INT_REG),
S3C2410_UDC_EP_INT_REG);
}
//s3c2440 USB设备控制器,因为有五个端点,每个端点的寄存器都相似。所以硬件设计的时候将寄存器分组了,名称一样但是物理寄存器不同。S3C2410_UDC_INDEX_REG寄存器代表了哪个组
/* Save index */
idx = udc_read(S3C2410_UDC_INDEX_REG);
//读取状态寄存器的值到局部变量中
/* Read status registers */
usb_status = udc_read(S3C2410_UDC_USB_INT_REG);
usbd_status = udc_read(S3C2410_UDC_EP_INT_REG);
pwr_reg = udc_read(S3C2410_UDC_PWR_REG);
//
udc_writeb(base_addr, S3C2410_UDC_INDEX_EP0, S3C2410_UDC_INDEX_REG);
ep0csr = udc_read(S3C2410_UDC_IN_CSR1_REG);
//打印调试信息
dprintk(DEBUG_NORMAL, "usbs=%02x, usbds=%02x, pwr=%02x ep0csr=%02x\n",
usb_status, usbd_status, pwr_reg, ep0csr);
/*
* Now, handle interrupts. There's two types :
* - Reset, Resume, Suspend coming -> usb_int_reg
* - EP -> ep_int_reg
*/
//下面就是不同的中断处理,复位对应这设备枚举的(1)
/* RESET */
if (usb_status & S3C2410_UDC_USBINT_RESET) {
/* two kind of reset :
* - reset start -> pwr reg = 8
* - reset end -> pwr reg = 0
**/
dprintk(DEBUG_NORMAL, "USB reset csr %x pwr %x\n",
ep0csr, pwr_reg);
dev->gadget.speed = USB_SPEED_UNKNOWN;
udc_write(0x00, S3C2410_UDC_INDEX_REG);
udc_write((dev->ep[0].ep.maxpacket & 0x7ff) >> 3,
S3C2410_UDC_MAXP_REG);
dev->address = 0;
dev->ep0state = EP0_IDLE;
dev->gadget.speed = USB_SPEED_FULL;
/* clear interrupt */