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_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; }
void dtf_if_in_clear_halt_out(void) { _dbgmsg_in( "IN\n" ); _dbgmsg_gadget( "usb_ep_clear_halt\n" ); usb_ep_clear_halt( _dtf_dev->pg.ep_out ); _dbgmsg_in( "OUT\n" ); }
void dtf_if_in_set_halt_bulk_in(void) { _dbgmsg_in( "IN\n" ); _dbgmsg_gadget( "usb_ep_set_halt\n" ); usb_ep_set_halt( _dtf_dev->pg.ep_in ); _dbgmsg_in( "OUT\n" ); }
static int dtf_bind_config(struct usb_configuration *c) { struct dtf_dev *dev = _dtf_dev; int ret; _dbgmsg( "IN\n" ); dev->cdev = c->cdev; dev->function.name = "dtf"; dev->function.descriptors = vFs_dtf_descs; dev->function.hs_descriptors = vHs_dtf_descs; dev->function.bind = dtf_function_bind; dev->function.unbind = dtf_function_unbind; dev->function.setup = dtf_function_setup; dev->function.set_alt = dtf_function_set_alt; dev->function.disable = dtf_function_disable; dev->function.suspend = dtf_function_suspend; dev->function.resume = dtf_function_resume; dev->mCtrl_ep_enbl = 0; dev->mData_ep_enbl = 0; _dbgmsg_gadget( "usb_add_function\n" ); ret = usb_add_function(c, &dev->function); _dbgmsg( "OUT(%d)\n", ret ); return ret; }
void dtf_if_in_clear_halt_bulk_in(void) { _dbgmsg_in( "IN\n" ); /* MSEMSEMSE */ _dbgmsg_gadget( "usb_ep_clear_halt\n" ); /* MSEMSEMSE */ usb_ep_clear_halt( _dtf_dev->pg.ep_in ); _dbgmsg_in( "OUT\n" ); /* MSEMSEMSE */ }
void dtf_if_in_set_halt_out(void) { _dbgmsg_in( "IN\n" ); /* MSEMSEMSE */ _dbgmsg_gadget( "usb_ep_set_halt\n" ); /* MSEMSEMSE */ usb_ep_set_halt( _dtf_dev->pg.ep_out ); _dbgmsg_in( "OUT\n" ); /* MSEMSEMSE */ }
static void dtf_request_free(struct usb_request *req, struct usb_ep *ep) { _dbgmsg( "IN\n" ); if(req) { kfree( req->buf ); _dbgmsg_gadget( "usb_ep_free_request\n" ); usb_ep_free_request( ep, req ); } _dbgmsg( "OUT\n" ); }
static struct usb_request *dtf_request_new(struct usb_ep *ep, int buffer_size) { struct usb_request *req = usb_ep_alloc_request(ep, GFP_KERNEL); _dbgmsg_gadget( "_dbgmsg_gadget\n" ); req = usb_ep_alloc_request(ep, GFP_KERNEL); if (!req) { _dbgmsg_gadget( "usb_ep_alloc_request error\n" ); return NULL; } /* now allocate buffers for the requests */ req->buf = kmalloc(buffer_size, GFP_KERNEL); if (!req->buf) { _dbgmsg_gadget( "usb_ep_free_request\n" ); usb_ep_free_request(ep, req); return NULL; } return req; }
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; }
/* DTF IF */ int dtf_if_in_intr_in(unsigned size, const char *data) { struct usb_ep *ep; struct usb_request *req = NULL; int ret; _dbgmsg_in( "IN\n" ); ep = _dtf_dev->pg.ep_intr; req = _dtf_dev->pg.mReq_intr; req->length = size; memcpy( req->buf, data, size ); _dbgmsg_gadget( "usb_ep_queue\n" ); ret = usb_ep_queue( ep, req, GFP_KERNEL ); _dbgmsg_in( "OUT ret: %d\n", ret ); return ret; }
static void dtf_complete_out(struct usb_ep *ep, struct usb_request *req) { struct dtf_dev *dev = _dtf_dev; _dbgmsg( "IN\n" ); dtf_if_out_complete_out(req->status, (int)req->actual, (char *)req->buf); if ( dev->mData_ep_enbl == 1 ) { dev->pg.mReq_out->length = 512; _dbgmsg_gadget( "usb_ep_queue\n" ); usb_ep_queue( dev->pg.ep_out, dev->pg.mReq_out, GFP_ATOMIC ); } _dbgmsg( "OUT\n" ); }
void dtf_if_in_ctrl_out(int length) { struct dtf_dev *dev = _dtf_dev; struct usb_composite_dev *cdev = dev->cdev; struct usb_request *req = cdev->req; int ret; _dbgmsg_in( "IN(length=%d)\n", length ); cdev->gadget->ep0->driver_data = dev; req->complete = dtf_ctrl_complete; req->zero = 0; req->length = length; _dbgmsg_gadget( "usb_ep_queue\n" ); ret = usb_ep_queue(cdev->gadget->ep0, req, GFP_KERNEL); if (ret < 0) { _dbgmsg_in( "usb_ep_queue error %d\n", ret ); } _dbgmsg_in( "OUT\n" ); }
void dtf_if_in_ctrl_in(int length, const char *data) { struct dtf_dev *dev = _dtf_dev; struct usb_composite_dev *cdev = dev->cdev; struct usb_request *req = cdev->req; int ret; _dbgmsg_in( "IN\n" ); req->zero = 0; req->length = length; if ( length > 0 ) { memcpy( req->buf, data, length ); } _dbgmsg_gadget( "usb_ep_queue\n" ); ret = usb_ep_queue(cdev->gadget->ep0, req, GFP_KERNEL); if (ret < 0) { _dbgmsg_in( "usb_ep_queue error %d\n", ret ); } _dbgmsg_in( "OUT\n" ); }
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; }