📄 dm320.c.svn-base
字号:
struct dm320_request *req; ep = container_of (_ep, struct dm320_ep, ep); if (!_ep || !_req) return; req = container_of (_req, struct dm320_request, req); kfree (req); }static void *dm320_alloc_buffer (struct usb_ep *_ep,unsigned bytes,dma_addr_t *dma,int gfp_flags){ void *retval; struct dm320_ep *ep; ep = container_of (_ep, struct dm320_ep, ep); if (!_ep) return NULL; retval = kmalloc (bytes, gfp_flags); return retval;}static voiddm320_free_buffer(struct usb_ep *_ep,void *buf,dma_addr_t dma,unsigned bytes){ kfree (buf);}static struct usb_ep_ops dm320_ep_ops = { .enable = dm320_enable, .disable = dm320_disable, .alloc_request = dm320_alloc_request, .free_request = dm320_free_request, .alloc_buffer = dm320_alloc_buffer, .free_buffer = dm320_free_buffer, .queue = dm320_queue, .dequeue = dm320_dequeue, .set_halt = dm320_set_halt, .fifo_status = dm320_fifo_status, .fifo_flush = dm320_fifo_flush,};/* when a driver is successfully registered, it will receive * control requests including set_configuration(), which enables * non-control requests. then usb traffic follows until a * disconnect is reported. then a host may connect again, or * the driver might get unbound. */static int usb_gadget_register_driver (struct usb_gadget_driver *driver){ struct usb_ctrlrequest r; int retval = -22; unsigned i; if (!driver || (driver->speed != USB_SPEED_FULL) || !driver->bind || !driver->unbind || !driver->setup) { return -EINVAL; } if (!the_controller) return -ENODEV; if (the_controller->driver) return -EBUSY; for (i = 0; i < 4; i++) the_controller->ep [i].irqs = 0; /* hook up the driver ... */ the_controller->softconnect = 1; driver->driver.bus = NULL; the_controller->driver = driver; the_controller->gadget.dev.driver = &driver->driver; retval = driver->bind (&the_controller->gadget); if (retval) { DEBUG (the_controller, "bind to driver %s --> %d\n", driver->driver.name, retval); the_controller->driver = NULL; return retval; } /* ... then enable host detection and ep0; and we're ready * for set_configuration as well as eventual disconnect. */ ep0_start (the_controller); return 0;}EXPORT_SYMBOL (usb_gadget_register_driver);static int usb_gadget_unregister_driver (struct usb_gadget_driver *driver){ struct dm320 *dev = the_controller; unsigned long flags; if (!dev) return -ENODEV; if (!driver || driver != dev->driver) return -EINVAL; spin_lock_irqsave (&dev->lock, flags); stop_activity (dev, driver); spin_unlock_irqrestore (&dev->lock, flags); //dm320_pullup (&dev->gadget, 0); driver->unbind (&dev->gadget); dev->driver = NULL; printk("unregistered driver '%s'\n", driver->driver.name); return 0;}EXPORT_SYMBOL (usb_gadget_unregister_driver);static int dm320_get_frame (struct usb_gadget *_gadget){ struct dm320 *dev; unsigned long flags; u16 retval; if (!_gadget) return -ENODEV; dev = container_of (_gadget, struct dm320, gadget); spin_lock_irqsave (&dev->lock, flags); retval = readb(USB_FRAME2) << 8; /*read frame reg: 16bit value */ retval |= readb(USB_FRAME1); spin_unlock_irqrestore (&dev->lock, flags); return retval;}static int dm320_wakeup (struct usb_gadget *_gadget){ struct dm320 *dev; u8 tmp; unsigned long flags; if (!_gadget) return 0; dev = container_of (_gadget, struct dm320, gadget); spin_lock_irqsave (&dev->lock, flags); writeb (USB_POWER_RESUME,USB_POWER); spin_unlock_irqrestore (&dev->lock, flags); return 0;}static int dm320_set_selfpowered (struct usb_gadget *_gadget, int value){ struct dm320 *dev; if (!_gadget) return -ENODEV; dev = container_of (_gadget, struct dm320, gadget); dev->is_selfpowered = value; return 0;}static int dm320_pullup (struct usb_gadget *_gadget, int is_on){ struct dm320 *dev; unsigned long flags; if (!_gadget) return -ENODEV; dev = container_of (_gadget, struct dm320, gadget); spin_lock_irqsave (&dev->lock, flags); dev->softconnect = (is_on != 0); if (is_on) { /* Vishal: Code to enable detectiong of plug/unplug */ gio_set_bitset( GIO_DP_PULLUP ); // set D+ pullup } else { gio_set_bitclr( GIO_DP_PULLUP ); // clear D+ pullup /* Vishal: Code to enable detectiong of plug/unplug */ } spin_unlock_irqrestore (&dev->lock, flags); return 0;}static const struct usb_gadget_ops dm320_ops = { .get_frame = dm320_get_frame, .wakeup = dm320_wakeup, .set_selfpowered = dm320_set_selfpowered,};static struct dm320_ep *get_ep_by_addr (struct dm320 *dev, u16 wIndex){ struct dm320_ep *ep; if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0) return &dev->ep [0]; list_for_each_entry (ep, &dev->gadget.ep_list, ep.ep_list) { u8 bEndpointAddress; if (!ep->desc) continue; bEndpointAddress = ep->desc->bEndpointAddress; if ((wIndex ^ bEndpointAddress) & USB_DIR_IN) continue; if ((wIndex & 0x0f) == (bEndpointAddress & 0x0f)) return ep; } return NULL;}static int dm320_read_intr_regs( void ){ unsigned int nIntrTx = readb( USB_INTRTX1 ) & 0xFF; unsigned int nIntrRx = readb( USB_INTRRX1 ) & 0xFF; unsigned int nIntrUSB = readb( USB_INTRUSB ) & 0xFF; return( ( nIntrTx << 12 ) + ( ( nIntrRx >> 1 ) << 8 ) + nIntrUSB );}static int dm320_get_intr_by_priority( int iInterruptFlags ){ if( ( iInterruptFlags & USB_CONNECTED ) != 0 ) return USB_CONNECTED; if( ( iInterruptFlags & USB_DISCONNECTED ) != 0 ) return USB_DISCONNECTED; if( ( iInterruptFlags & USB_RESET ) != 0 ) return USB_RESET; // reset is first for device if( ( iInterruptFlags & USB_RESUME ) != 0 ) return USB_RESUME; if( ( iInterruptFlags & USB_SESSREQ ) != 0 ) return USB_SESSREQ; if( ( iInterruptFlags & USB_VBUSERR ) != 0 ) return USB_VBUSERR; if( ( iInterruptFlags & USB_SOF ) != 0 ) return USB_SOF; if( ( iInterruptFlags & USB_SUSPEND ) != 0 ) return USB_SUSPEND; if( ( iInterruptFlags & USB_CONTROL ) != 0 ) return USB_CONTROL; if( ( iInterruptFlags & USB_RXFIFO ) != 0 ) return USB_RXFIFO; if( ( iInterruptFlags & USB_TXFIFO ) != 0 ) return USB_TXFIFO; return USB_NO_INTERRUPT;}static uint8_t dm320_get_peripheral_addr( struct dm320 *dev ){ return dev->peripheral_addr;}static void dm320_set_addr_reg( unsigned char ucAddress ){ core_debug("dm320: %s:writing new address to the device\n", __FUNCTION__); writeb( ucAddress, USB_FADDR );}static void dm320_set_peripheral_addr( struct dm320 *dev, unsigned char ucNewAddress ) //USB_SetPeripheralAddr{ dev->peripheral_addr = ucNewAddress;}static void dm320_reset_service( ){ printk("dm320: %s\n", __FUNCTION__); flushEPFIFO(0); flushEPFIFO(1); flushEPFIFO(2); flushEPFIFO(3); return;}static void dm320_control_service(struct dm320 *dev){ struct usb_ctrlrequest r; struct dm320_ep *ep; u8 num, scratch; int tmp = 0; struct dm320_request *req; /* starting a control request? */ if (dev->gadget.speed == USB_SPEED_UNKNOWN) { dev->gadget.speed = USB_SPEED_FULL; DEBUG (dev, "%s speed\n",(dev->gadget.speed == USB_SPEED_HIGH)? "high" : "full"); } ep = &dev->ep[0]; ep->irqs++; /* make sure any leftover interrupt state is cleared */ while (!list_empty (&ep->queue)) { req = list_entry (ep->queue.next, struct dm320_request, queue); done (ep, req, (req->req.actual == req->req.length)? 0 : -EPROTO); } ep->stopped = 0; dev->protocol_stall = 0; if( USB_ReadEP( USB_EP0_SELECT, &r, sizeof(struct usb_ctrlrequest ) ) <= 0 ) return; /* watch control traffic at the token level, and force * synchronization before letting the status phase happen. */ ep->is_in = (r.bRequestType & USB_DIR_IN) != 0; if ((r.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) { dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY); goto delegate; } switch (r.bRequest) { case USB_REQ_GET_STATUS: { struct dm320_ep *e; u16 status = 0; dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND ); if ((r.bRequestType & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) { if ((e = get_ep_by_addr (dev, r.wIndex)) == 0 || r.wLength > 2) goto do_stall; set_fifo_bytecount (&dev->ep [0], 0); allow_status (ep); VDEBUG (dev, "%s stat %02x\n", ep->ep.name, status); goto next_endpoints; } else if ((r.bRequestType & USB_RECIP_MASK) == USB_RECIP_DEVICE) { if (r.wLength > 2) goto do_stall; if (dev->is_selfpowered) status = (1 << USB_DEVICE_SELF_POWERED); set_fifo_bytecount (&dev->ep [0], 0); allow_status (ep); VDEBUG (dev, "device stat %02x\n", status); goto next_endpoints; } else if ((r.bRequestType & USB_RECIP_MASK) == USB_RECIP_INTERFACE) { if (r.wLength > 2) goto do_stall; set_fifo_bytecount (&dev->ep [0], 0); allow_status (ep); VDEBUG (dev, "interface status %02x\n", status); goto next_endpoints; } } case USB_REQ_CLEAR_FEATURE: { struct dm320_ep *e; dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND ); if (r.bRequestType != USB_RECIP_ENDPOINT) goto delegate; if (r.wValue != USB_ENDPOINT_HALT || r.wLength != 0) goto do_stall; if ((e = get_ep_by_addr (dev, r.wIndex)) == 0) goto do_stall; clear_halt (e); allow_status (ep); VDEBUG (dev, "%s clear halt\n", ep->ep.name); goto next_endpoints; } case USB_REQ_SET_FEATURE: { struct dm320_ep *e; dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND ); if (r.bRequestType == USB_RECIP_DEVICE) { allow_status (ep); VDEBUG (dev, "test mode: %d\n", r.wIndex); goto next_endpoints; } else if (r.bRequestType != USB_RECIP_ENDPOINT) goto delegate; if (r.wValue != USB_ENDPOINT_HALT || r.wLength != 0) goto do_stall; if ((e = get_ep_by_addr (dev, r.wIndex)) == 0) goto do_stall; set_halt (e); allow_status (ep); VDEBUG (dev, "%s set halt\n", ep->ep.name); goto next_endpoints; } case USB_REQ_SET_ADDRESS: { dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND ); dm320_set_peripheral_addr(dev,r.wValue & 0xff); allow_status (ep); break; } case USB_REQ_GET_DESCRIPTOR: { dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY ); goto delegate; } case USB_REQ_SET_DESCRIPTOR: { dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY ); goto delegate; } case USB_REQ_GET_CONFIGURATION: { dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND); goto delegate; } case USB_REQ_SET_CONFIGURATION: { dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND); goto delegate; } case USB_REQ_GET_INTERFACE: { dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND); goto delegate; } case USB_REQ_SET_INTERFACE: { dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_DATAEND); goto delegate; } default: dm320_set_CSR0_reg( USB_CSR0_CLRRXRDY | USB_CSR0_SENDST ); break;delegate: //spin_unlock (&dev->lock); if(dev) if(&dev->gadget!= NULL && dev->driver!=NULL) tmp = dev->driver->setup (&dev->gadget, &r); else printk("dm320: Gadget device is NULL!!\n"); //spin_lock (&dev->lock); } /* stall ep0 on error */ if (tmp < 0) {do_stall: dev->protocol_stall = 1; }next_endpoints: return;}static int dm320_rx_service( struct dm320 *dev){ struct dm320_ep *ep; int count; int status; u8 num, scratch; int tmp = 0; struct dm320_request *req; struct usb_ep *_ep; u8 *buf; int status; ep = &dev->ep[EP_BULK_OUT_NUM]; ep->irqs++; if (!list_empty (&ep->queue)) { req = list_entry (ep->queue.next, struct dm320_request, queue); } else { //printk("%s: Pending interrupt\n", __FUNCTION__); rx_pending = 1 ; return 0; } read_fifo(ep, req); return 1;}static int dm320_tx_service(struct dm320 *dev ){ struct dm320_ep *ep; int count; int status; u8 num, scratch; int tmp = 0; struct dm320_request *req; struct usb_ep *_ep; u8 *buf;#ifdef PIPE_STALL writeb(EP_BULK_IN_NUM, USB_INDEX ); if( readb(USB_PER_TXCSR1) & USB_TXCSR1_SENTST) { writeb(readb(USB_PER_TXCSR1)& ~USB_TXCSR1_SENTST,USB_PER_TXCSR1); writeb(readb(USB_PER_TXCSR1)& ~USB_TXCSR1_SENDST,USB_PER_TXCSR1); printk("Bulk IN peipe stalled, clearing SENTST\n"); }#endif if (dev->gadget.speed == USB_SPEED_UNKNOWN) { dev->gadget.speed = USB_SPEED_FULL; DEBUG (dev, "%s speed\n",(dev->gadget.speed == USB_SPEED_HIGH)? "high" : "full"); } ep = &dev->ep[EP_BULK_IN_NUM]; ep->irqs++; if (!list_empty (&ep->queue)) req = list_entry (ep->queue.next, struct dm320_request, queue); else return 0; write_fifo(ep, req); return 1;}static void dm320_disconnect_service( ){ return;}static void dm320_suspend_service( ){ return;}void do_pending_transfers(){#if 0 writeb( iEndpoint, USB_INDEX ); writeb( readb( USB_PER_RXCSR1 ) & ~(USB_RXCSR1_RXPKTRDY), USB_PER_RXCSR1 );//manually clear RXPKTRDY bit in PER_RXCSR1 register#endif}void do_pending_transfers(){#if 0 writeb( iEndpoint, USB_INDEX ); writeb( readb( USB_PER_RXCSR1 ) & ~(USB_RXCSR1_RXPKTRDY), USB_PER_RXCSR1 );//manually clear RXPKTRDY bit in PER_RXCSR1 register#endif}static irqreturn_t handle_core_irqs(int irq, void *dev_id, struct pt_regs *regs )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -