int protocol_configure_device(struct vfs_device_t *dev) { unsigned int pipe = usb_sndctrlpipe(dev->udev, 0x00); int r; r = usb_reset_configuration(dev->udev); DBG("reset config : %d\n", r); usb_reset_endpoint(dev->udev, dev->bulkin_data_endpointAddr); usb_reset_endpoint(dev->udev, dev->bulkin_ctrl_endpointAddr); usb_reset_endpoint(dev->udev, dev->bulkout_endpointAddr); r = usb_control_msg(dev->udev, pipe, 3, 0, 1, 1, NULL, 0, 300 * HZ / 1000); DBG("ctrl_io : pipe=%u, result=%d\n", pipe, r); usb_set_device_state(dev->udev, USB_STATE_CONFIGURED); return r; }
int usb_stor_clear_halt(struct us_data *us, unsigned int pipe) { int result; int endp = usb_pipeendpoint(pipe); if (usb_pipein (pipe)) endp |= USB_DIR_IN; result = usb_stor_control_msg(us, us->send_ctrl_pipe, USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, USB_ENDPOINT_HALT, endp, NULL, 0, 3*HZ); if (result >= 0) usb_reset_endpoint(us->pusb_dev, endp); US_DEBUGP("%s: result = %d\n", __func__, result); return result; }
//----- usb_stor_clear_halt() --------------------- int usb_stor_clear_halt(struct us_data *us, unsigned int pipe) { int result; int endp = usb_pipeendpoint(pipe); //printk("transport --- usb_stor_clear_halt\n"); if (usb_pipein (pipe)) endp |= USB_DIR_IN; result = usb_stor_control_msg(us, us->send_ctrl_pipe, USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, USB_ENDPOINT_HALT, endp, NULL, 0, 3*HZ); /* reset the endpoint toggle */ if (result >= 0) //usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0); usb_reset_endpoint(us->pusb_dev, endp); return result; }
static void usb_ctrl_complete(struct urb *urb) { struct st5481_adapter *adapter = urb->context; struct st5481_ctrl *ctrl = &adapter->ctrl; struct ctrl_msg *ctrl_msg; if (unlikely(urb->status < 0)) { switch (urb->status) { case -ENOENT: case -ESHUTDOWN: case -ECONNRESET: DBG(1, "urb killed status %d", urb->status); return; default: WARNING("urb status %d", urb->status); break; } } ctrl_msg = (struct ctrl_msg *)urb->setup_packet; if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) { le16_to_cpus(&ctrl_msg->dr.wIndex); usb_reset_endpoint(adapter->usb_dev, ctrl_msg->dr.wIndex); } if (ctrl_msg->complete) ctrl_msg->complete(ctrl_msg->context); clear_bit(0, &ctrl->busy); usb_next_ctrl_msg(urb, adapter); return; }
static int pcan_usb_plugin(struct usb_interface *interface, const struct usb_device_id *id) { int err; int i, dev_ctrl_count, sizeof_if; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; struct usb_device *usb_dev = interface_to_usbdev(interface); struct pcan_usb_interface *usb_if; int (*device_init)(struct pcan_usb_interface *); DPRINTK(KERN_DEBUG "%s: %s(0x%04x, 0x%04x, 0x%04x)\n", DEVICE_NAME, __FUNCTION__, usb_dev->descriptor.idVendor, usb_dev->descriptor.idProduct, usb_dev->descriptor.bcdDevice); /* check endpoint addresses (numbers) and associated max data length */ /* (only from setting 0) */ /* Since USB-PRO defines also a LIN interface, should reject it when */ /* adapter plugged: make use of endpoint addresses (no other way...) */ iface_desc = &interface->altsetting[0]; DPRINTK(KERN_DEBUG "%s: %s(): bNumEndpoints=%d\n", DEVICE_NAME, __FUNCTION__, iface_desc->desc.bNumEndpoints); for (i=0; i < iface_desc->desc.bNumEndpoints; i++) { struct usb_endpoint_descriptor *endpoint = &iface_desc->endpoint[i].desc; /* Below is the list of valid ep addreses. All other ep address */ /* is considered as not-CAN interface address => no dev created */ switch (endpoint->bEndpointAddress) { case 0x01: case 0x81: case 0x02: case 0x82: case 0x03: case 0x83: break; default: #ifdef DEBUG printk(KERN_INFO "%s: %s(): EP address %02x not in CAN range.\n", DEVICE_NAME, __FUNCTION__, endpoint->bEndpointAddress); printk(KERN_INFO "%s: %s(): ignoring the whole USB interface\n", DEVICE_NAME, __FUNCTION__); #endif return -ENODEV; } } // take the 1st configuration (it's default) if ((err = usb_reset_configuration(usb_dev)) < 0) { printk(KERN_ERR "%s: usb_set_configuration() failed!\n", DEVICE_NAME); return err; } // only 1 interface is supported // Note: HW_USB_PRO: interface#0 for CAN, #1 for LIN if ((err = usb_set_interface(usb_dev, 0, 0)) < 0) { printk(KERN_ERR "%s: usb_set_interface() failed!\n", DEVICE_NAME); return err; } /* Now, according to device id, create as many device as CAN controllers */ switch (usb_dev->descriptor.idProduct) { #ifdef HW_USB_PRO case PCAN_USBPRO_PRODUCT_ID: dev_ctrl_count = 2; device_init = pcan_usbpro_init; break; #endif case PCAN_USB_PRODUCT_ID: default: dev_ctrl_count = 1; device_init = pcan_usb_init; break; } printk(KERN_INFO "%s: new ", DEVICE_NAME); if (usb_dev->speed == USB_SPEED_HIGH) printk("high speed "); printk("usb adapter with %u CAN controller(s) detected\n", dev_ctrl_count); /* create our interface object for the USB device */ sizeof_if = sizeof(struct pcan_usb_interface) + \ sizeof(struct pcandev) * (dev_ctrl_count-1); usb_if = (struct pcan_usb_interface *)kmalloc(sizeof_if, GFP_KERNEL); if (usb_if == NULL) { printk(KERN_ERR "%s: kmalloc(%d) failed!\n", DEVICE_NAME, sizeof_if); return err; } memset(usb_if, '\0', sizeof_if); // store pointer to kernel supplied usb_dev usb_if->usb_dev = usb_dev; usb_if->usb_intf = interface; usb_if->dev_ctrl_count = dev_ctrl_count; // preset finish flags atomic_set(&usb_if->cmd_sync_complete, 0); atomic_set(&usb_if->cmd_async_complete, 1); // preset active URB counter atomic_set(&usb_if->active_urbs, 0); init_waitqueue_head(&usb_if->usb_wait_queue); /* get endpoint addresses (numbers) and associated max data length */ /* (only from setting 0) */ #ifdef HW_USB_PRO /* * Function Interface Endpoints DeviceId * --------- --------- ----------------------------------------- * Control 0 * CAN 0 "CAN-Device", * USB\VID_0c72&PID_000d&MI_00 * 1=Command, bidi for both CAN_Ctrller * 2=CAN-Controller 0, rcv (IN) both CAN-Ctrller, * transmit (OUT) CAN-Ctrl#0, * 3=CAN-Controller 1 transmit (OUT) CAN-Ctrl#1 * LIN 1 "LIN-Device", * USB\VID_0c72&PID_000d&MI_01 * 4=Command, * 5=Controller 0, * 6=Controller 1 */ #endif for (i=0; i < iface_desc->desc.bNumEndpoints; i++) { PCAN_ENDPOINT *pipe_addr = NULL; endpoint = &iface_desc->endpoint[i].desc; DPRINTK(KERN_DEBUG "%s: %s(): EP[%d]={addr=%d max=%d}\n", DEVICE_NAME, __FUNCTION__, i, endpoint->bEndpointAddress, endpoint->wMaxPacketSize); switch (endpoint->bEndpointAddress) { case 0x01: pipe_addr = &usb_if->pipe_cmd_out; break; case 0x81: pipe_addr = &usb_if->pipe_cmd_in; break; case 0x02: switch (usb_dev->descriptor.idProduct) { #ifdef HW_USB_PRO case PCAN_USBPRO_PRODUCT_ID: #endif case PCAN_USB_PRODUCT_ID: default: pipe_addr = &usb_if->dev[0].port.usb.pipe_write; break; } break; case 0x82: pipe_addr = &usb_if->pipe_read; break; #ifdef HW_USB_PRO case 0x03: switch (usb_dev->descriptor.idProduct) { case PCAN_USBPRO_PRODUCT_ID: pipe_addr = &usb_if->dev[1].port.usb.pipe_write; break; } #endif case 0x83: /* Unused pipe for PCAN-USB-PRO */ /* But seems that need to be reset too... */ /* TBD */ break; default: continue; } if (pipe_addr) { pipe_addr->ucNumber = endpoint->bEndpointAddress; pipe_addr->wDataSz = le16_to_cpu(endpoint->wMaxPacketSize); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) usb_reset_endpoint(usb_dev, endpoint->bEndpointAddress); #endif } /* ucRevision needs to be defined before allocating resources (PCAN-USB) */ #if defined(__LITTLE_ENDIAN) usb_if->ucHardcodedDevNr = (uint8_t)(usb_if->usb_dev->descriptor.bcdDevice & 0xff); usb_if->ucRevision = (uint8_t)(usb_if->usb_dev->descriptor.bcdDevice >> 8); #elif defined(__BIG_ENDIAN) usb_if->ucHardcodedDevNr = (uint8_t)(usb_if->usb_dev->descriptor.bcdDevice >> 8); usb_if->ucRevision = (uint8_t)(usb_if->usb_dev->descriptor.bcdDevice & 0xff); #else #error "Please fix the endianness defines in <asm/byteorder.h>" #endif DPRINTK(KERN_DEBUG "%s(): ucHardcodedDevNr=0x%02x ucRevision=0x%02X\n", __func__, usb_if->ucHardcodedDevNr, usb_if->ucRevision); if ((err = pcan_usb_allocate_resources(usb_if))) goto reject; usb_set_intfdata(interface, usb_if); /* call initialisation callback for entire device */ device_init(usb_if); /* install the reception part for the interface */ if (!atomic_read(&usb_if->read_data.use_count)) { FILL_BULK_URB(&usb_if->read_data, usb_if->usb_dev, usb_rcvbulkpipe(usb_if->usb_dev, usb_if->pipe_read.ucNumber), usb_if->read_buffer_addr[0], usb_if->read_buffer_size, pcan_usb_read_notify, usb_if); // submit urb if ((err = __usb_submit_urb(&usb_if->read_data))) { printk(KERN_ERR "%s: %s() can't submit! (%d)\n", DEVICE_NAME, __FUNCTION__, err); goto reject; } atomic_inc(&usb_if->active_urbs); } /* next, initialize each controller */ for (i=0; i < usb_if->dev_ctrl_count; i++) { err = pcan_usb_create_dev(usb_if, i); if (err != 0) { for (; i > 0; i--) { // TBD pcan_usb_delete_dev(); } break; } } reject: return err; }