日期:2014-05-16 浏览次数:21016 次
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 */