static void dtf_function_disable(struct usb_function *f) { struct dtf_dev *dev = func_to_dtf(f); int speed_check; _dbgmsg( "IN\n" ); if( dev->mCtrl_ep_enbl == 1 ) { dev->mCtrl_ep_enbl = 0; _dbgmsg_gadget( "usb_ep_disable(%s)\n", dev->pg.ep_intr->name ); usb_ep_disable( dev->pg.ep_intr ); } if( dev->mData_ep_enbl == 1 ) { dev->mData_ep_enbl = 0; _dbgmsg_gadget( "usb_ep_dequeue\n" ); usb_ep_dequeue( dev->pg.ep_out, dev->pg.mReq_out ); _dbgmsg_gadget( "usb_ep_disable(%s)\n", dev->pg.ep_intr->name ); usb_ep_disable( dev->pg.ep_in ); _dbgmsg_gadget( "usb_ep_disable(%s)\n", dev->pg.ep_out->name ); usb_ep_disable( dev->pg.ep_out ); } speed_check = (_dtf_dev->cdev->gadget->speed == USB_SPEED_HIGH)?(1):(0); dtf_if_out_disable(speed_check); _dbgmsg( "OUT\n" ); }
static int dtf_function_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; struct dtf_dev *dev = func_to_dtf(f); int ret; _dbgmsg( "IN\n" ); dev->cdev = cdev; /* allocate Interface IDs */ ret = dtf_allocate_interface_ids( c, f ); if( ret < 0 ) { printk( KERN_ERR "allocate interface IDs error\n" ); return ret; } /* allocate endpoints */ ret = dtf_allocate_endpoints( c, f ); if( ret < 0 ) { printk( KERN_ERR "allocate endpoints error\n" ); return ret; } _dbgmsg( "OUT\n" ); return 0; }
static int dtf_function_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct dtf_dev *dev = func_to_dtf(f); struct usb_composite_dev *cdev = f->config->cdev; int ret; int set_alt_end = 0; int speed_check = 0; _dbgmsg("dtf_function_set_alt(intf=%d,alt=%d)\n", intf, alt); /* MSEMSEMSE */ if( dev->pg.mCtrl_id == intf ) { _dbgmsg_gadget( "usb_ep_enable(%s)\n", dev->pg.ep_intr->name ); /* MSEMSEMSE */ ret = usb_ep_enable( dev->pg.ep_intr, ep_choose( cdev->gadget, &vPg1_epintr_desc_hs, &vPg1_epintr_desc ) ); if( ret ) { _dbgmsg( "usb_ep_enable error pg1 ep_intr ret = %d\n", ret );/* MSEMSEMSE */ return ret; } dev->mCtrl_ep_enbl = 1; } else if( dev->pg.mData_id == intf ) { _dbgmsg_gadget( "usb_ep_enable(%s)\n", dev->pg.ep_in->name ); /* MSEMSEMSE */ ret = usb_ep_enable( dev->pg.ep_in, ep_choose( cdev->gadget, &vPg1_epin_desc_hs, &vPg1_epin_desc ) ); if( ret ) { _dbgmsg( "usb_ep_enable error pg1 ep_in ret = %d\n", ret ); /* MSEMSEMSE */ return ret; } _dbgmsg_gadget( "usb_ep_enable(%s)\n", dev->pg.ep_out->name ); /* MSEMSEMSE */ ret = usb_ep_enable( dev->pg.ep_out, ep_choose( cdev->gadget, &vPg1_epout_desc_hs, &vPg1_epout_desc ) ); if( ret ) { _dbgmsg( "usb_ep_enable error pg1 ep_out ret = %d\n", ret );/* MSEMSEMSE */ usb_ep_disable(dev->pg.ep_in); return ret; } dev->pg.mReq_out->length = 512; usb_ep_queue( dev->pg.ep_out, dev->pg.mReq_out, GFP_ATOMIC ); dev->mData_ep_enbl = 1; } else { _dbgmsg( "unknown interface number\n" ); /* MSEMSEMSE */ } set_alt_end = ( (dev->mCtrl_ep_enbl) & (dev->mData_ep_enbl) ); speed_check = (dev->cdev->gadget->speed == USB_SPEED_HIGH)?(1):(0); if (set_alt_end == 1) { dtf_if_out_set_alt( speed_check ); } return 0; }
static void dtf_function_unbind(struct usb_configuration *c, struct usb_function *f) { struct dtf_dev *dev = func_to_dtf(f); _dbgmsg( "IN\n" ); spin_lock_irq(&dev->lock); dtf_request_free( dev->pg.mReq_intr, dev->pg.ep_intr ); dtf_request_free( dev->pg.mReq_in, dev->pg.ep_in ); dtf_request_free( dev->pg.mReq_out, dev->pg.ep_out ); spin_unlock_irq(&dev->lock); _dbgmsg( "OUT\n" ); }
static int dtf_allocate_interface_ids( struct usb_configuration *c, struct usb_function *f ) { int id; struct dtf_dev *dev = func_to_dtf(f); _dbgmsg( "IN\n" ); /* Allocate Interface ID: PipeGroup1 communication interface */ _dbgmsg_gadget( "usb_interface_id\n" ); id = usb_interface_id(c, f); _dbgmsg( "usb_interface_id() = %d\n", id ); if( id < 0 ) return id; dev->pg.mCtrl_id = id; id = 0; /* fixed interface number */ vPg1_intf_comm_desc.bInterfaceNumber = id; vPg1_union_desc.bMasterInterface0 = id; /* Allocate Interface ID: PipeGroup1 bulk interface */ _dbgmsg_gadget( "usb_interface_id\n" ); id = usb_interface_id(c, f); _dbgmsg( "usb_interface_id() = %d(%d)\n", id, vPg1_intf_comm_desc.bInterfaceNumber ); if( id < 0 ) return id; dev->pg.mData_id = id; id = 1; /* fixed interface number */ vPg1_intf_bulk_desc.bInterfaceNumber = id; vPg1_union_desc.bSlaveInterface0 = id; vPg1_call_mng.bDataInterface = id; _dbgmsg( "usb_interface_id() = %d(%d)\n", id, vPg1_intf_bulk_desc.bInterfaceNumber ); _dbgmsg( "OUT\n" ); return 0; }
static int dtf_allocate_endpoints(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; struct dtf_dev *dev = func_to_dtf(f); struct usb_request *req; struct usb_ep *ep; _dbgmsg( "IN\n" ); /* allocate endpoints: PipeGroup1 intrrupt */ _dbgmsg_gadget( "usb_ep_autoconfig\n" ); ep = usb_ep_autoconfig(cdev->gadget, &vPg1_epintr_desc); if( !ep ) { _dbgmsg( "usb_ep_autoconfig for PG1 ep_intr failed\n" ); return -ENODEV; } _dbgmsg("usb_ep_autoconfig for PG1 ep_intr got %s\n", ep->name); ep->driver_data = dev; dev->pg.ep_intr = ep; /* allocate endpoints: PipeGroup1 bulk(in) */ _dbgmsg_gadget( "usb_ep_autoconfig\n" ); ep = usb_ep_autoconfig(cdev->gadget, &vPg1_epin_desc); if( !ep ) { _dbgmsg( "usb_ep_autoconfig for PG1 ep_in failed\n" ); return -ENODEV; } _dbgmsg("usb_ep_autoconfig for PG1 ep_in got %s\n", ep->name); ep->driver_data = dev; dev->pg.ep_in = ep; /* allocate endpoints: PipeGroup1 bulk(out) */ _dbgmsg_gadget( "usb_ep_autoconfig\n" ); ep = usb_ep_autoconfig(cdev->gadget, &vPg1_epout_desc); if( !ep ) { _dbgmsg( "usb_ep_autoconfig for PG1 ep_out failed\n" ); return -ENODEV; } _dbgmsg("usb_ep_autoconfig for PG1 ep_out got %s\n", ep->name); ep->driver_data = dev; dev->pg.ep_out = ep; /* support high speed hardware */ if (gadget_is_dualspeed(cdev->gadget)) { vPg1_epintr_desc_hs.bEndpointAddress = vPg1_epintr_desc.bEndpointAddress; vPg1_epin_desc_hs.bEndpointAddress = vPg1_epin_desc.bEndpointAddress; vPg1_epout_desc_hs.bEndpointAddress = vPg1_epout_desc.bEndpointAddress; } _dbgmsg("%s speed %s: PG1[INTR/%s, IN/%s, OUT/%s]\n", gadget_is_dualspeed(cdev->gadget) ? "dual" : "full", f->name, dev->pg.ep_intr->name, dev->pg.ep_in->name, dev->pg.ep_out->name); /* allocate request for endpoints */ req = dtf_request_new( dev->pg.ep_intr, 16 ); if(!req) { _dbgmsg( "create request error\n" ); return -ENODEV; } req->complete = dtf_complete_intr; dev->pg.mReq_intr = req; req = dtf_request_new( dev->pg.ep_in, 512 ); if(!req) { _dbgmsg( "create request error\n" ); return -ENODEV; } req->complete = dtf_complete_in; dev->pg.mReq_in = req; req = dtf_request_new( dev->pg.ep_out, 512 ); if(!req) { _dbgmsg( "create request error\n" ); return -ENODEV; } req->complete = dtf_complete_out; dev->pg.mReq_out = req; _dbgmsg( "OUT\n" ); return 0; }