예제 #1
0
파일: protocol.c 프로젝트: hawell/vfs
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;
}
예제 #2
0
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;
}
예제 #3
0
//----- 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;
}
예제 #5
0
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;
}