示例#1
0
int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress)
{
	int 		tmp, i;
	unsigned char	buf [13];

	tmp = usb_string(dev->udev, iMACAddress, buf, sizeof buf);
	if (tmp != 12) {
		dev_dbg(&dev->udev->dev,
			"bad MAC string %d fetch, %d\n", iMACAddress, tmp);
		if (tmp >= 0)
			tmp = -EINVAL;
		return tmp;
	}
	for (i = tmp = 0; i < 6; i++, tmp += 2)
		dev->net->dev_addr [i] =
			(hex_to_bin(buf[tmp]) << 4) + hex_to_bin(buf[tmp + 1]);
	return 0;
}
示例#2
0
static inline int
get_ethernet_addr(struct usbnet *dev, struct usb_cdc_ether_desc *e)
{
	int 		tmp, i;
	unsigned char	buf [13];

	tmp = usb_string(dev->udev, e->iMACAddress, buf, sizeof buf);
	if (tmp != 12) {
		dev_dbg(&dev->udev->dev,
			"bad MAC string %d fetch, %d\n", e->iMACAddress, tmp);
		if (tmp >= 0)
			tmp = -EINVAL;
		return tmp;
	}
	for (i = tmp = 0; i < 6; i++, tmp += 2)
		dev->net->dev_addr [i] =
			(nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]);
	return 0;
}
示例#3
0
static int cxacru_usb_probe(struct usb_interface *intf,
		const struct usb_device_id *id)
{
	struct usb_device *usb_dev = interface_to_usbdev(intf);
	char buf[15];

	/* Avoid ADSL routers (cx82310_eth).
	 * Abort if bDeviceClass is 0xff and iProduct is "USB NET CARD".
	 */
	if (usb_dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC
			&& usb_string(usb_dev, usb_dev->descriptor.iProduct,
				buf, sizeof(buf)) > 0) {
		if (!strcmp(buf, "USB NET CARD")) {
			dev_info(&intf->dev, "ignoring cx82310_eth device\n");
			return -ENODEV;
		}
	}

	return usbatm_usb_probe(intf, id, &cxacru_driver);
}
示例#4
0
/**
 * getSerialNum - function to read the serial number from a USB board
 *   
 *  result - int - serial number of the board
 *                 Returns (negative) error code on failure.
 */
int getSerialNum(struct usb_cypress *dev)
{
  int i, result, len;
  char buffer[MAX_SERIAL_LENGTH] = {0};

  if( dev == NULL )
    {
      printk("getSerialNum error: Passed in NULL pointer\n");
      return -1;
    }

  //Read in USB iSerialNumber descriptor string
  len = usb_string(dev->udev, dev->udev->descriptor.iSerialNumber, buffer, MAX_SERIAL_LENGTH); 
  
  result = 0;

  //Return error code
  if( len <= 0 )
    {
      printk("Error reading USB serial number:%d\n",len);
      return len;  // return failure.
    }

  //Loop through and convert it to an integer
  for (i = 0; i < len; i++)
    {
      if( (buffer[i] < '0') || (buffer[i] > '9') )
	{
	  printk("Error in serial Number - Non Numeral Digit '%c' found!!!\n",buffer[i]);
	  return -1;
	}
      result = result*10 + buffer[i] - '0';
    }

  //Return serial number
  return result;
}
示例#5
0
文件: af9015.c 项目: ChineseDr/linux
static int af9015_probe(struct usb_interface *intf,
                        const struct usb_device_id *id)
{
    struct usb_device *udev = interface_to_usbdev(intf);
    char manufacturer[sizeof("ITE Technologies, Inc.")];

    memset(manufacturer, 0, sizeof(manufacturer));
    usb_string(udev, udev->descriptor.iManufacturer,
               manufacturer, sizeof(manufacturer));
    /*
     * There is two devices having same ID but different chipset. One uses
     * AF9015 and the other IT9135 chipset. Only difference seen on lsusb
     * is iManufacturer string.
     *
     * idVendor           0x0ccd TerraTec Electronic GmbH
     * idProduct          0x0099
     * bcdDevice            2.00
     * iManufacturer           1 Afatech
     * iProduct                2 DVB-T 2
     *
     * idVendor           0x0ccd TerraTec Electronic GmbH
     * idProduct          0x0099
     * bcdDevice            2.00
     * iManufacturer           1 ITE Technologies, Inc.
     * iProduct                2 DVB-T TV Stick
     */
    if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VID_TERRATEC) &&
            (le16_to_cpu(udev->descriptor.idProduct) == 0x0099)) {
        if (!strcmp("ITE Technologies, Inc.", manufacturer)) {
            dev_dbg(&udev->dev, "%s: rejecting device\n", __func__);
            return -ENODEV;
        }
    }

    return dvb_usbv2_probe(intf, id);
}
示例#6
0
文件: pwc-if.c 项目: AK101111/linux
static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct pwc_device *pdev = NULL;
	int vendor_id, product_id, type_id;
	int rc;
	int features = 0;
	int compression = 0;
	int my_power_save = power_save;
	char serial_number[30], *name;

	vendor_id = le16_to_cpu(udev->descriptor.idVendor);
	product_id = le16_to_cpu(udev->descriptor.idProduct);

	/* Check if we can handle this device */
	PWC_DEBUG_PROBE("probe() called [%04X %04X], if %d\n",
		vendor_id, product_id,
		intf->altsetting->desc.bInterfaceNumber);

	/* the interfaces are probed one by one. We are only interested in the
	   video interface (0) now.
	   Interface 1 is the Audio Control, and interface 2 Audio itself.
	 */
	if (intf->altsetting->desc.bInterfaceNumber > 0)
		return -ENODEV;

	if (vendor_id == 0x0471) {
		switch (product_id) {
		case 0x0302:
			PWC_INFO("Philips PCA645VC USB webcam detected.\n");
			name = "Philips 645 webcam";
			type_id = 645;
			break;
		case 0x0303:
			PWC_INFO("Philips PCA646VC USB webcam detected.\n");
			name = "Philips 646 webcam";
			type_id = 646;
			break;
		case 0x0304:
			PWC_INFO("Askey VC010 type 2 USB webcam detected.\n");
			name = "Askey VC010 webcam";
			type_id = 646;
			break;
		case 0x0307:
			PWC_INFO("Philips PCVC675K (Vesta) USB webcam detected.\n");
			name = "Philips 675 webcam";
			type_id = 675;
			break;
		case 0x0308:
			PWC_INFO("Philips PCVC680K (Vesta Pro) USB webcam detected.\n");
			name = "Philips 680 webcam";
			type_id = 680;
			break;
		case 0x030C:
			PWC_INFO("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n");
			name = "Philips 690 webcam";
			type_id = 690;
			break;
		case 0x0310:
			PWC_INFO("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n");
			name = "Philips 730 webcam";
			type_id = 730;
			break;
		case 0x0311:
			PWC_INFO("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n");
			name = "Philips 740 webcam";
			type_id = 740;
			break;
		case 0x0312:
			PWC_INFO("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n");
			name = "Philips 750 webcam";
			type_id = 750;
			break;
		case 0x0313:
			PWC_INFO("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n");
			name = "Philips 720K/40 webcam";
			type_id = 720;
			break;
		case 0x0329:
			PWC_INFO("Philips SPC 900NC USB webcam detected.\n");
			name = "Philips SPC 900NC webcam";
			type_id = 740;
			break;
		case 0x032C:
			PWC_INFO("Philips SPC 880NC USB webcam detected.\n");
			name = "Philips SPC 880NC webcam";
			type_id = 740;
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else if (vendor_id == 0x069A) {
		switch(product_id) {
		case 0x0001:
			PWC_INFO("Askey VC010 type 1 USB webcam detected.\n");
			name = "Askey VC010 webcam";
			type_id = 645;
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else if (vendor_id == 0x046d) {
		switch(product_id) {
		case 0x08b0:
			PWC_INFO("Logitech QuickCam Pro 3000 USB webcam detected.\n");
			name = "Logitech QuickCam Pro 3000";
			type_id = 740; /* CCD sensor */
			break;
		case 0x08b1:
			PWC_INFO("Logitech QuickCam Notebook Pro USB webcam detected.\n");
			name = "Logitech QuickCam Notebook Pro";
			type_id = 740; /* CCD sensor */
			break;
		case 0x08b2:
			PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n");
			name = "Logitech QuickCam Pro 4000";
			type_id = 740; /* CCD sensor */
			if (my_power_save == -1)
				my_power_save = 1;
			break;
		case 0x08b3:
			PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n");
			name = "Logitech QuickCam Zoom";
			type_id = 740; /* CCD sensor */
			break;
		case 0x08B4:
			PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n");
			name = "Logitech QuickCam Zoom";
			type_id = 740; /* CCD sensor */
			if (my_power_save == -1)
				my_power_save = 1;
			break;
		case 0x08b5:
			PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n");
			name = "Logitech QuickCam Orbit";
			type_id = 740; /* CCD sensor */
			if (my_power_save == -1)
				my_power_save = 1;
			features |= FEATURE_MOTOR_PANTILT;
			break;
		case 0x08b6:
			PWC_INFO("Logitech/Cisco VT Camera webcam detected.\n");
			name = "Cisco VT Camera";
			type_id = 740; /* CCD sensor */
			break;
		case 0x08b7:
			PWC_INFO("Logitech ViewPort AV 100 webcam detected.\n");
			name = "Logitech ViewPort AV 100";
			type_id = 740; /* CCD sensor */
			break;
		case 0x08b8: /* Where this released? */
			PWC_INFO("Logitech QuickCam detected (reserved ID).\n");
			name = "Logitech QuickCam (res.)";
			type_id = 730; /* Assuming CMOS */
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else if (vendor_id == 0x055d) {
		/* I don't know the difference between the C10 and the C30;
		   I suppose the difference is the sensor, but both cameras
		   work equally well with a type_id of 675
		 */
		switch(product_id) {
		case 0x9000:
			PWC_INFO("Samsung MPC-C10 USB webcam detected.\n");
			name = "Samsung MPC-C10";
			type_id = 675;
			break;
		case 0x9001:
			PWC_INFO("Samsung MPC-C30 USB webcam detected.\n");
			name = "Samsung MPC-C30";
			type_id = 675;
			break;
		case 0x9002:
			PWC_INFO("Samsung SNC-35E (v3.0) USB webcam detected.\n");
			name = "Samsung MPC-C30";
			type_id = 740;
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else if (vendor_id == 0x041e) {
		switch(product_id) {
		case 0x400c:
			PWC_INFO("Creative Labs Webcam 5 detected.\n");
			name = "Creative Labs Webcam 5";
			type_id = 730;
			if (my_power_save == -1)
				my_power_save = 1;
			break;
		case 0x4011:
			PWC_INFO("Creative Labs Webcam Pro Ex detected.\n");
			name = "Creative Labs Webcam Pro Ex";
			type_id = 740;
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else if (vendor_id == 0x04cc) {
		switch(product_id) {
		case 0x8116:
			PWC_INFO("Sotec Afina Eye USB webcam detected.\n");
			name = "Sotec Afina Eye";
			type_id = 730;
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else if (vendor_id == 0x06be) {
		switch(product_id) {
		case 0x8116:
			/* This is essentially the same cam as the Sotec Afina Eye */
			PWC_INFO("AME Co. Afina Eye USB webcam detected.\n");
			name = "AME Co. Afina Eye";
			type_id = 750;
			break;
		default:
			return -ENODEV;
			break;
		}

	}
	else if (vendor_id == 0x0d81) {
		switch(product_id) {
		case 0x1900:
			PWC_INFO("Visionite VCS-UC300 USB webcam detected.\n");
			name = "Visionite VCS-UC300";
			type_id = 740; /* CCD sensor */
			break;
		case 0x1910:
			PWC_INFO("Visionite VCS-UM100 USB webcam detected.\n");
			name = "Visionite VCS-UM100";
			type_id = 730; /* CMOS sensor */
			break;
		default:
			return -ENODEV;
			break;
		}
	}
	else
		return -ENODEV; /* Not any of the know types; but the list keeps growing. */

	if (my_power_save == -1)
		my_power_save = 0;

	memset(serial_number, 0, 30);
	usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
	PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number);

	if (udev->descriptor.bNumConfigurations > 1)
		PWC_WARNING("Warning: more than 1 configuration available.\n");

	/* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */
	pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL);
	if (pdev == NULL) {
		PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
		return -ENOMEM;
	}
	pdev->type = type_id;
	pdev->features = features;
	pwc_construct(pdev); /* set min/max sizes correct */

	mutex_init(&pdev->v4l2_lock);
	mutex_init(&pdev->vb_queue_lock);
	spin_lock_init(&pdev->queued_bufs_lock);
	INIT_LIST_HEAD(&pdev->queued_bufs);

	pdev->udev = udev;
	pdev->power_save = my_power_save;

	/* Init videobuf2 queue structure */
	pdev->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	pdev->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
	pdev->vb_queue.drv_priv = pdev;
	pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf);
	pdev->vb_queue.ops = &pwc_vb_queue_ops;
	pdev->vb_queue.mem_ops = &vb2_vmalloc_memops;
	pdev->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
	rc = vb2_queue_init(&pdev->vb_queue);
	if (rc < 0) {
		PWC_ERROR("Oops, could not initialize vb2 queue.\n");
		goto err_free_mem;
	}

	/* Init video_device structure */
	pdev->vdev = pwc_template;
	strcpy(pdev->vdev.name, name);
	pdev->vdev.queue = &pdev->vb_queue;
	pdev->vdev.queue->lock = &pdev->vb_queue_lock;
	video_set_drvdata(&pdev->vdev, pdev);

	pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
	PWC_DEBUG_PROBE("Release: %04x\n", pdev->release);

	/* Allocate USB command buffers */
	pdev->ctrl_buf = kmalloc(sizeof(pdev->cmd_buf), GFP_KERNEL);
	if (!pdev->ctrl_buf) {
		PWC_ERROR("Oops, could not allocate memory for pwc_device.\n");
		rc = -ENOMEM;
		goto err_free_mem;
	}

#ifdef CONFIG_USB_PWC_DEBUG
	/* Query sensor type */
	if (pwc_get_cmos_sensor(pdev, &rc) >= 0) {
		PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n",
				pdev->vdev.name,
				pwc_sensor_type_to_string(rc), rc);
	}
#endif

	/* Set the leds off */
	pwc_set_leds(pdev, 0, 0);

	/* Setup initial videomode */
	rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT,
				V4L2_PIX_FMT_YUV420, 30, &compression, 1);
	if (rc)
		goto err_free_mem;

	/* Register controls (and read default values from camera */
	rc = pwc_init_controls(pdev);
	if (rc) {
		PWC_ERROR("Failed to register v4l2 controls (%d).\n", rc);
		goto err_free_mem;
	}

	/* And powerdown the camera until streaming starts */
	pwc_camera_power(pdev, 0);

	/* Register the v4l2_device structure */
	pdev->v4l2_dev.release = pwc_video_release;
	rc = v4l2_device_register(&intf->dev, &pdev->v4l2_dev);
	if (rc) {
		PWC_ERROR("Failed to register v4l2-device (%d).\n", rc);
		goto err_free_controls;
	}

	pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler;
	pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
	pdev->vdev.lock = &pdev->v4l2_lock;

	rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1);
	if (rc < 0) {
		PWC_ERROR("Failed to register as video device (%d).\n", rc);
		goto err_unregister_v4l2_dev;
	}
	PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev));

#ifdef CONFIG_USB_PWC_INPUT_EVDEV
	/* register webcam snapshot button input device */
	pdev->button_dev = input_allocate_device();
	if (!pdev->button_dev) {
		rc = -ENOMEM;
		goto err_video_unreg;
	}

	usb_make_path(udev, pdev->button_phys, sizeof(pdev->button_phys));
	strlcat(pdev->button_phys, "/input0", sizeof(pdev->button_phys));

	pdev->button_dev->name = "PWC snapshot button";
	pdev->button_dev->phys = pdev->button_phys;
	usb_to_input_id(pdev->udev, &pdev->button_dev->id);
	pdev->button_dev->dev.parent = &pdev->udev->dev;
	pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
	pdev->button_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);

	rc = input_register_device(pdev->button_dev);
	if (rc) {
		input_free_device(pdev->button_dev);
		pdev->button_dev = NULL;
		goto err_video_unreg;
	}
#endif

	return 0;

#ifdef CONFIG_USB_PWC_INPUT_EVDEV
err_video_unreg:
	video_unregister_device(&pdev->vdev);
#endif
err_unregister_v4l2_dev:
	v4l2_device_unregister(&pdev->v4l2_dev);
err_free_controls:
	v4l2_ctrl_handler_free(&pdev->ctrl_handler);
err_free_mem:
	kfree(pdev->ctrl_buf);
	kfree(pdev);
	return rc;
}
示例#7
0
/**
 *	iowarrior_probe
 *
 *	Called by the usb core when a new device is connected that it thinks
 *	this driver might be interested in.
 */
static int iowarrior_probe(struct usb_interface *interface,
			   const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(interface);
	struct iowarrior *dev = NULL;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	int i;
	int retval = -ENOMEM;

	/* allocate memory for our device state and initialize it */
	dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL);
	if (dev == NULL) {
		dev_err(&interface->dev, "Out of memory\n");
		return retval;
	}

	mutex_init(&dev->mutex);

	atomic_set(&dev->intr_idx, 0);
	atomic_set(&dev->read_idx, 0);
	spin_lock_init(&dev->intr_idx_lock);
	atomic_set(&dev->overflow_flag, 0);
	init_waitqueue_head(&dev->read_wait);
	atomic_set(&dev->write_busy, 0);
	init_waitqueue_head(&dev->write_wait);

	dev->udev = udev;
	dev->interface = interface;

	iface_desc = interface->cur_altsetting;
	dev->product_id = le16_to_cpu(udev->descriptor.idProduct);

	/* set up the endpoint information */
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (usb_endpoint_is_int_in(endpoint))
			dev->int_in_endpoint = endpoint;
		if (usb_endpoint_is_int_out(endpoint))
			/* this one will match for the IOWarrior56 only */
			dev->int_out_endpoint = endpoint;
	}
	/* we have to check the report_size often, so remember it in the endianess suitable for our machine */
	dev->report_size = usb_endpoint_maxp(dev->int_in_endpoint);
	if ((dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) &&
	    (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56))
		/* IOWarrior56 has wMaxPacketSize different from report size */
		dev->report_size = 7;

	/* create the urb and buffer for reading */
	dev->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->int_in_urb) {
		dev_err(&interface->dev, "Couldn't allocate interrupt_in_urb\n");
		goto error;
	}
	dev->int_in_buffer = kmalloc(dev->report_size, GFP_KERNEL);
	if (!dev->int_in_buffer) {
		dev_err(&interface->dev, "Couldn't allocate int_in_buffer\n");
		goto error;
	}
	usb_fill_int_urb(dev->int_in_urb, dev->udev,
			 usb_rcvintpipe(dev->udev,
					dev->int_in_endpoint->bEndpointAddress),
			 dev->int_in_buffer, dev->report_size,
			 iowarrior_callback, dev,
			 dev->int_in_endpoint->bInterval);
	/* create an internal buffer for interrupt data from the device */
	dev->read_queue =
	    kmalloc(((dev->report_size + 1) * MAX_INTERRUPT_BUFFER),
		    GFP_KERNEL);
	if (!dev->read_queue) {
		dev_err(&interface->dev, "Couldn't allocate read_queue\n");
		goto error;
	}
	/* Get the serial-number of the chip */
	memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial));
	usb_string(udev, udev->descriptor.iSerialNumber, dev->chip_serial,
		   sizeof(dev->chip_serial));
	if (strlen(dev->chip_serial) != 8)
		memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial));

	/* Set the idle timeout to 0, if this is interface 0 */
	if (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) {
	    usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
			    0x0A,
			    USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
			    0, NULL, 0, USB_CTRL_SET_TIMEOUT);
	}
	/* allow device read and ioctl */
	dev->present = 1;

	/* we can register the device now, as it is ready */
	usb_set_intfdata(interface, dev);

	retval = usb_register_dev(interface, &iowarrior_class);
	if (retval) {
		/* something prevented us from registering this driver */
		dev_err(&interface->dev, "Not able to get a minor for this device.\n");
		usb_set_intfdata(interface, NULL);
		goto error;
	}

	dev->minor = interface->minor;

	/* let the user know what node this device is now attached to */
	dev_info(&interface->dev, "IOWarrior product=0x%x, serial=%s interface=%d "
		 "now attached to iowarrior%d\n", dev->product_id, dev->chip_serial,
		 iface_desc->desc.bInterfaceNumber, dev->minor - IOWARRIOR_MINOR_BASE);
	return retval;

error:
	iowarrior_delete(dev);
	return retval;
}
/**
 * adu_probe
 *
 * Called by the usb core when a new device is connected that it thinks
 * this driver might be interested in.
 */
static int adu_probe(struct usb_interface *interface,
		     const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(interface);
	struct adu_device *dev = NULL;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	int retval = -ENODEV;
	int in_end_size;
	int out_end_size;
	int i;

	dbg(2," %s : enter", __func__);

	if (udev == NULL) {
		dev_err(&interface->dev, "udev is NULL.\n");
		goto exit;
	}

	/* allocate memory for our device state and initialize it */
	dev = kzalloc(sizeof(struct adu_device), GFP_KERNEL);
	if (dev == NULL) {
		dev_err(&interface->dev, "Out of memory\n");
		retval = -ENOMEM;
		goto exit;
	}

	mutex_init(&dev->mtx);
	spin_lock_init(&dev->buflock);
	dev->udev = udev;
	init_waitqueue_head(&dev->read_wait);
	init_waitqueue_head(&dev->write_wait);

	iface_desc = &interface->altsetting[0];

	/* set up the endpoint information */
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (usb_endpoint_is_int_in(endpoint))
			dev->interrupt_in_endpoint = endpoint;

		if (usb_endpoint_is_int_out(endpoint))
			dev->interrupt_out_endpoint = endpoint;
	}
	if (dev->interrupt_in_endpoint == NULL) {
		dev_err(&interface->dev, "interrupt in endpoint not found\n");
		goto error;
	}
	if (dev->interrupt_out_endpoint == NULL) {
		dev_err(&interface->dev, "interrupt out endpoint not found\n");
		goto error;
	}

	in_end_size = usb_endpoint_maxp(dev->interrupt_in_endpoint);
	out_end_size = usb_endpoint_maxp(dev->interrupt_out_endpoint);

	dev->read_buffer_primary = kmalloc((4 * in_end_size), GFP_KERNEL);
	if (!dev->read_buffer_primary) {
		dev_err(&interface->dev, "Couldn't allocate read_buffer_primary\n");
		retval = -ENOMEM;
		goto error;
	}

	/* debug code prime the buffer */
	memset(dev->read_buffer_primary, 'a', in_end_size);
	memset(dev->read_buffer_primary + in_end_size, 'b', in_end_size);
	memset(dev->read_buffer_primary + (2 * in_end_size), 'c', in_end_size);
	memset(dev->read_buffer_primary + (3 * in_end_size), 'd', in_end_size);

	dev->read_buffer_secondary = kmalloc((4 * in_end_size), GFP_KERNEL);
	if (!dev->read_buffer_secondary) {
		dev_err(&interface->dev, "Couldn't allocate read_buffer_secondary\n");
		retval = -ENOMEM;
		goto error;
	}

	/* debug code prime the buffer */
	memset(dev->read_buffer_secondary, 'e', in_end_size);
	memset(dev->read_buffer_secondary + in_end_size, 'f', in_end_size);
	memset(dev->read_buffer_secondary + (2 * in_end_size), 'g', in_end_size);
	memset(dev->read_buffer_secondary + (3 * in_end_size), 'h', in_end_size);

	dev->interrupt_in_buffer = kmalloc(in_end_size, GFP_KERNEL);
	if (!dev->interrupt_in_buffer) {
		dev_err(&interface->dev, "Couldn't allocate interrupt_in_buffer\n");
		goto error;
	}

	/* debug code prime the buffer */
	memset(dev->interrupt_in_buffer, 'i', in_end_size);

	dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->interrupt_in_urb) {
		dev_err(&interface->dev, "Couldn't allocate interrupt_in_urb\n");
		goto error;
	}
	dev->interrupt_out_buffer = kmalloc(out_end_size, GFP_KERNEL);
	if (!dev->interrupt_out_buffer) {
		dev_err(&interface->dev, "Couldn't allocate interrupt_out_buffer\n");
		goto error;
	}
	dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->interrupt_out_urb) {
		dev_err(&interface->dev, "Couldn't allocate interrupt_out_urb\n");
		goto error;
	}

	if (!usb_string(udev, udev->descriptor.iSerialNumber, dev->serial_number,
			sizeof(dev->serial_number))) {
		dev_err(&interface->dev, "Could not retrieve serial number\n");
		goto error;
	}
	dbg(2," %s : serial_number=%s", __func__, dev->serial_number);

	/* we can register the device now, as it is ready */
	usb_set_intfdata(interface, dev);

	retval = usb_register_dev(interface, &adu_class);

	if (retval) {
		/* something prevented us from registering this driver */
		dev_err(&interface->dev, "Not able to get a minor for this device.\n");
		usb_set_intfdata(interface, NULL);
		goto error;
	}

	dev->minor = interface->minor;

	/* let the user know what node this device is now attached to */
	dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d\n",
		 le16_to_cpu(udev->descriptor.idProduct), dev->serial_number,
		 (dev->minor - ADU_MINOR_BASE));
exit:
	dbg(2," %s : leave, return value %p (dev)", __func__, dev);

	return retval;

error:
	adu_delete(dev);
	return retval;
}
示例#9
0
/*
 * probe function for new CPC-USB devices
 */
static int cpcusb_probe(struct usb_interface *interface,
			const struct usb_device_id *id)
{
	CPC_USB_T *card = NULL;
	CPC_CHAN_T *chan = NULL;

	struct usb_device *udev = interface_to_usbdev(interface);
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;

	int i, j, retval = -ENOMEM, slot;

	slot = cpcusb_get_free_slot();
	if (slot < 0) {
		info("No more devices supported");
		return -ENOMEM;
	}

	/* allocate memory for our device state and initialize it */
	card = kzalloc(sizeof(CPC_USB_T), GFP_KERNEL);
	if (!card) {
		err("Out of memory");
		return -ENOMEM;
	}
	CPCUSB_Table[slot] = card;

	/* allocate and initialize the channel struct */
	card->chan = kmalloc(sizeof(CPC_CHAN_T), GFP_KERNEL);
	if (!card->chan) {
		kfree(card);
		err("Out of memory");
		return -ENOMEM;
	}

	chan = card->chan;
	memset(chan, 0, sizeof(CPC_CHAN_T));
	ResetBuffer(chan);

	semaphore_init(&card->sem);
	spin_lock_init(&card->slock);

	card->udev = udev;
	card->interface = interface;
	if (udev->descriptor.iSerialNumber) {
		usb_string(udev, udev->descriptor.iSerialNumber, card->serialNumber,
				   128);
		info("Serial %s", card->serialNumber);
	}

	card->productId = udev->descriptor.idProduct;
	info("Product %s",
	     card->productId == USB_CPCUSB_LPC2119_PRODUCT_ID ?
			 "CPC-USB/ARM7" : "CPC-USB/M16C");

	/* set up the endpoint information */
	/* check out the endpoints */
	/* use only the first bulk-in and bulk-out endpoints */
	iface_desc = &interface->altsetting[0];
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (!card->num_intr_in &&
		    (endpoint->bEndpointAddress & USB_DIR_IN) &&
		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
		     == USB_ENDPOINT_XFER_INT)) {
			card->intr_in_urb = usb_alloc_urb(0, GFP_KERNEL);
			card->num_intr_in = 1;

			if (!card->intr_in_urb) {
				err("No free urbs available");
				goto error;
			}

			dbg("intr_in urb %d", card->num_intr_in);
		}

		if (!card->num_bulk_in &&
		    (endpoint->bEndpointAddress & USB_DIR_IN) &&
		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
		     == USB_ENDPOINT_XFER_BULK)) {
			card->num_bulk_in = 2;
			for (j = 0; j < CPC_USB_URB_CNT; j++) {
				card->urbs[j].size = endpoint->wMaxPacketSize;
				card->urbs[j].urb = usb_alloc_urb(0, GFP_KERNEL);
				if (!card->urbs[j].urb) {
					err("No free urbs available");
					goto error;
				}
				card->urbs[j].buffer =
				    usb_buffer_alloc(udev,
						     card->urbs[j].size,
						     GFP_KERNEL,
						     &card->urbs[j].urb->transfer_dma);
				if (!card->urbs[j].buffer) {
					err("Couldn't allocate bulk_in_buffer");
					goto error;
				}
			}
			info("%s - %d reading URB's allocated",
			     __func__, CPC_USB_URB_CNT);
		}

		if (!card->num_bulk_out &&
		    !(endpoint->bEndpointAddress & USB_DIR_IN) &&
		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
		     == USB_ENDPOINT_XFER_BULK)) {

			card->num_bulk_out = 2;

			for (j = 0; j < CPC_USB_URB_CNT; j++) {
				card->wrUrbs[j].size =
				    endpoint->wMaxPacketSize;
				card->wrUrbs[j].urb =
				    usb_alloc_urb(0, GFP_KERNEL);
				if (!card->wrUrbs[j].urb) {
					err("No free urbs available");
					goto error;
				}
				card->wrUrbs[j].buffer = usb_buffer_alloc(udev,
							       card->wrUrbs[j].size, GFP_KERNEL,
							       &card->wrUrbs[j].urb->transfer_dma);

				if (!card->wrUrbs[j].buffer) {
					err("Couldn't allocate bulk_out_buffer");
					goto error;
				}

				usb_fill_bulk_urb(card->wrUrbs[j].urb, udev,
						usb_sndbulkpipe(udev, endpoint->bEndpointAddress),
						card->wrUrbs[j].buffer,
						card->wrUrbs[j].size,
						cpcusb_write_bulk_callback,
						card);
			}

			info("%s - %d writing URB's allocated", __func__, CPC_USB_URB_CNT);
		}
	}

	if (!(card->num_bulk_in && card->num_bulk_out)) {
		err("Couldn't find both bulk-in and bulk-out endpoints");
		goto error;
	}

	/* allow device read, write and ioctl */
	card->present = 1;

	/* we can register the device now, as it is ready */
	usb_set_intfdata(interface, card);
	retval = usb_register_dev(interface, &cpcusb_class);

	if (retval) {
		/* something prevented us from registering this driver */
		err("Not able to get a minor for this device.");
		usb_set_intfdata(interface, NULL);
		goto error;
	}

	card->chan->minor = card->minor = interface->minor;

	chan->buf = vmalloc(sizeof(CPC_MSG_T) * CPC_MSG_BUF_CNT);
	if (chan->buf == NULL) {
		err("Out of memory");
		retval = -ENOMEM;
		goto error;
	}
	info("Allocated memory for %d messages (%lu kbytes)",
	     CPC_MSG_BUF_CNT, (long unsigned int)(sizeof(CPC_MSG_T) * CPC_MSG_BUF_CNT) / 1000);
	memset(chan->buf, 0, sizeof(CPC_MSG_T) * CPC_MSG_BUF_CNT);

	ResetBuffer(chan);

	card->chan->CPCWait_q = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL);
	if (!card->chan->CPCWait_q) {
		err("Out of memory");
		retval = -ENOMEM;
		goto error;
	}
	init_waitqueue_head(card->chan->CPCWait_q);

	CPCUSB_Table[slot] = card;
	card->idx = slot;
	CPCUsbCnt++;

	/* let the user know what node this device is now attached to */
	info("Device now attached to USB-%d", card->minor);
	return 0;

error:
	for (j = 0; j < CPC_USB_URB_CNT; j++) {
		if (card->urbs[j].buffer) {
			usb_buffer_free(card->udev, card->urbs[j].size,
					card->urbs[j].buffer,
					card->urbs[j].urb->transfer_dma);
			card->urbs[j].buffer = NULL;
		}
		if (card->urbs[j].urb) {
			usb_free_urb(card->urbs[j].urb);
			card->urbs[j].urb = NULL;
		}
	}

	cpcusb_delete(card);
	return retval;
}
static int igorplugusb_remote_probe(struct usb_interface *intf,
				    const struct usb_device_id *id)
{
	struct usb_device *dev;
	struct usb_host_interface *idesc = NULL;
	struct usb_endpoint_descriptor *ep;
	struct igorplug *ir = NULL;
	struct lirc_driver *driver = NULL;
	int devnum, pipe, maxp;
	char buf[63], name[128] = "";
	int ret;

	dprintk(DRIVER_NAME ": usb probe called.\n");

	dev = interface_to_usbdev(intf);

	idesc = intf->cur_altsetting;

	if (idesc->desc.bNumEndpoints != 1)
		return -ENODEV;

	ep = &idesc->endpoint->desc;
	if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
	    != USB_DIR_IN)
	    || (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
	    != USB_ENDPOINT_XFER_CONTROL)
		return -ENODEV;

	pipe = usb_rcvctrlpipe(dev, ep->bEndpointAddress);
	devnum = dev->devnum;
	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));

	dprintk(DRIVER_NAME "[%d]: bytes_in_key=%zu maxp=%d\n",
		devnum, CODE_LENGTH, maxp);

	ir = devm_kzalloc(&intf->dev, sizeof(*ir), GFP_KERNEL);
	if (!ir)
		return -ENOMEM;

	driver = devm_kzalloc(&intf->dev, sizeof(*driver), GFP_KERNEL);
	if (!driver)
		return -ENOMEM;

	ir->buf_in = usb_alloc_coherent(dev, DEVICE_BUFLEN + DEVICE_HEADERLEN,
					GFP_ATOMIC, &ir->dma_in);
	if (!ir->buf_in)
		return -ENOMEM;

	strcpy(driver->name, DRIVER_NAME " ");
	driver->minor = -1;
	driver->code_length = CODE_LENGTH * 8; /* in bits */
	driver->features = LIRC_CAN_REC_MODE2;
	driver->data = ir;
	driver->chunk_size = CODE_LENGTH;
	driver->buffer_size = DEVICE_BUFLEN + ADDITIONAL_LIRC_BYTES;
	driver->set_use_inc = &set_use_inc;
	driver->set_use_dec = &set_use_dec;
	driver->sample_rate = sample_rate;    /* per second */
	driver->add_to_buf = &igorplugusb_remote_poll;
	driver->dev = &intf->dev;
	driver->owner = THIS_MODULE;

	ret = lirc_register_driver(driver);
	if (ret < 0) {
		usb_free_coherent(dev, DEVICE_BUFLEN + DEVICE_HEADERLEN,
			ir->buf_in, ir->dma_in);
		return ret;
	}

	driver->minor = ret;
	ir->d = driver;
	ir->devnum = devnum;
	ir->usbdev = dev;
	ir->len_in = DEVICE_BUFLEN + DEVICE_HEADERLEN;
	ir->in_space = 1; /* First mode2 event is a space. */
	do_gettimeofday(&ir->last_time);

	if (dev->descriptor.iManufacturer
	    && usb_string(dev, dev->descriptor.iManufacturer,
			  buf, sizeof(buf)) > 0)
		strlcpy(name, buf, sizeof(name));
	if (dev->descriptor.iProduct
	    && usb_string(dev, dev->descriptor.iProduct, buf, sizeof(buf)) > 0)
		snprintf(name + strlen(name), sizeof(name) - strlen(name),
			 " %s", buf);
	printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name,
	       dev->bus->busnum, devnum);

	/* clear device buffer */
	ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
		SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN,
		/*unused*/0, /*unused*/0,
		/*dummy*/ir->buf_in, /*dummy*/ir->len_in,
		/*timeout*/HZ * USB_CTRL_GET_TIMEOUT);
	if (ret < 0)
		printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n",
			devnum, ret);

	usb_set_intfdata(intf, ir);
	return 0;
}
示例#11
0
static int iowarrior_probe(struct usb_interface *interface,
			   const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(interface);
	struct iowarrior *dev = NULL;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	int i;
	int retval = -ENOMEM;

	/*                                                        */
	dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL);
	if (dev == NULL) {
		dev_err(&interface->dev, "Out of memory\n");
		return retval;
	}

	mutex_init(&dev->mutex);

	atomic_set(&dev->intr_idx, 0);
	atomic_set(&dev->read_idx, 0);
	spin_lock_init(&dev->intr_idx_lock);
	atomic_set(&dev->overflow_flag, 0);
	init_waitqueue_head(&dev->read_wait);
	atomic_set(&dev->write_busy, 0);
	init_waitqueue_head(&dev->write_wait);

	dev->udev = udev;
	dev->interface = interface;

	iface_desc = interface->cur_altsetting;
	dev->product_id = le16_to_cpu(udev->descriptor.idProduct);

	/*                                 */
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (usb_endpoint_is_int_in(endpoint))
			dev->int_in_endpoint = endpoint;
		if (usb_endpoint_is_int_out(endpoint))
			/*                                              */
			dev->int_out_endpoint = endpoint;
	}
	/*                                                                                                  */
	dev->report_size = usb_endpoint_maxp(dev->int_in_endpoint);
	if ((dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) &&
	    (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56))
		/*                                                           */
		dev->report_size = 7;

	/*                                       */
	dev->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->int_in_urb) {
		dev_err(&interface->dev, "Couldn't allocate interrupt_in_urb\n");
		goto error;
	}
	dev->int_in_buffer = kmalloc(dev->report_size, GFP_KERNEL);
	if (!dev->int_in_buffer) {
		dev_err(&interface->dev, "Couldn't allocate int_in_buffer\n");
		goto error;
	}
	usb_fill_int_urb(dev->int_in_urb, dev->udev,
			 usb_rcvintpipe(dev->udev,
					dev->int_in_endpoint->bEndpointAddress),
			 dev->int_in_buffer, dev->report_size,
			 iowarrior_callback, dev,
			 dev->int_in_endpoint->bInterval);
	/*                                                              */
	dev->read_queue =
	    kmalloc(((dev->report_size + 1) * MAX_INTERRUPT_BUFFER),
		    GFP_KERNEL);
	if (!dev->read_queue) {
		dev_err(&interface->dev, "Couldn't allocate read_queue\n");
		goto error;
	}
	/*                                   */
	memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial));
	usb_string(udev, udev->descriptor.iSerialNumber, dev->chip_serial,
		   sizeof(dev->chip_serial));
	if (strlen(dev->chip_serial) != 8)
		memset(dev->chip_serial, 0x00, sizeof(dev->chip_serial));

	/*                                                   */
	if (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) {
	    usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
			    0x0A,
			    USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
			    0, NULL, 0, USB_CTRL_SET_TIMEOUT);
	}
	/*                             */
	dev->present = 1;

	/*                                                */
	usb_set_intfdata(interface, dev);

	retval = usb_register_dev(interface, &iowarrior_class);
	if (retval) {
		/*                                                     */
		dev_err(&interface->dev, "Not able to get a minor for this device.\n");
		usb_set_intfdata(interface, NULL);
		goto error;
	}

	dev->minor = interface->minor;

	/*                                                            */
	dev_info(&interface->dev, "IOWarrior product=0x%x, serial=%s interface=%d "
		 "now attached to iowarrior%d\n", dev->product_id, dev->chip_serial,
		 iface_desc->desc.bInterfaceNumber, dev->minor - IOWARRIOR_MINOR_BASE);
	return retval;

error:
	iowarrior_delete(dev);
	return retval;
}
示例#12
0
文件: message.c 项目: kzlin129/tt-gpl
/*
 * usb_set_configuration - Makes a particular device setting be current
 * @dev: the device whose configuration is being updated
 * @configuration: the configuration being chosen.
 * Context: !in_interrupt(), caller owns the device lock
 *
 * This is used to enable non-default device modes.  Not all devices
 * use this kind of configurability; many devices only have one
 * configuration.
 *
 * USB device configurations may affect Linux interoperability,
 * power consumption and the functionality available.  For example,
 * the default configuration is limited to using 100mA of bus power,
 * so that when certain device functionality requires more power,
 * and the device is bus powered, that functionality should be in some
 * non-default device configuration.  Other device modes may also be
 * reflected as configuration options, such as whether two ISDN
 * channels are available independently; and choosing between open
 * standard device protocols (like CDC) or proprietary ones.
 *
 * Note that USB has an additional level of device configurability,
 * associated with interfaces.  That configurability is accessed using
 * usb_set_interface().
 *
 * This call is synchronous. The calling context must be able to sleep,
 * must own the device lock, and must not hold the driver model's USB
 * bus rwsem; usb device driver probe() methods cannot use this routine.
 *
 * Returns zero on success, or else the status code returned by the
 * underlying call that failed.  On successful completion, each interface
 * in the original device configuration has been destroyed, and each one
 * in the new configuration has been probed by all relevant usb device
 * drivers currently known to the kernel.
 */
int usb_set_configuration(struct usb_device *dev, int configuration)
{
	int i, ret;
	struct usb_host_config *cp = NULL;
	struct usb_interface **new_interfaces = NULL;
	int n, nintf;

	for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
		if (dev->config[i].desc.bConfigurationValue == configuration) {
			cp = &dev->config[i];
			break;
		}
	}
	if ((!cp && configuration != 0))
		return -EINVAL;

	/* The USB spec says configuration 0 means unconfigured.
	 * But if a device includes a configuration numbered 0,
	 * we will accept it as a correctly configured state.
	 */
	if (cp && configuration == 0)
		dev_warn(&dev->dev, "config 0 descriptor??\n");

	if (dev->state == USB_STATE_SUSPENDED)
		return -EHOSTUNREACH;

	/* Allocate memory for new interfaces before doing anything else,
	 * so that if we run out then nothing will have changed. */
	n = nintf = 0;
	if (cp) {
		nintf = cp->desc.bNumInterfaces;
		new_interfaces = kmalloc(nintf * sizeof(*new_interfaces),
				GFP_KERNEL);
		if (!new_interfaces) {
			dev_err(&dev->dev, "Out of memory");
			return -ENOMEM;
		}

		for (; n < nintf; ++n) {
			new_interfaces[n] = kmalloc(
					sizeof(struct usb_interface),
					GFP_KERNEL);
			if (!new_interfaces[n]) {
				dev_err(&dev->dev, "Out of memory");
				ret = -ENOMEM;
free_interfaces:
				while (--n >= 0)
					kfree(new_interfaces[n]);
				kfree(new_interfaces);
				return ret;
			}
		}
	}

	/* if it's already configured, clear out old state first.
	 * getting rid of old interfaces means unbinding their drivers.
	 */
	if (dev->state != USB_STATE_ADDRESS)
		usb_disable_device (dev, 1);	// Skip ep0

	if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
			USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
			NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0)
		goto free_interfaces;

	dev->actconfig = cp;
	if (!cp)
		usb_set_device_state(dev, USB_STATE_ADDRESS);
	else {
		usb_set_device_state(dev, USB_STATE_CONFIGURED);

		/* Initialize the new interface structures and the
		 * hc/hcd/usbcore interface/endpoint state.
		 */
		for (i = 0; i < nintf; ++i) {
			struct usb_interface_cache *intfc;
			struct usb_interface *intf;
			struct usb_host_interface *alt;

			cp->interface[i] = intf = new_interfaces[i];
			memset(intf, 0, sizeof(*intf));
			intfc = cp->intf_cache[i];
			intf->altsetting = intfc->altsetting;
			intf->num_altsetting = intfc->num_altsetting;
			kref_get(&intfc->ref);

			alt = usb_altnum_to_altsetting(intf, 0);

			/* No altsetting 0?  We'll assume the first altsetting.
			 * We could use a GetInterface call, but if a device is
			 * so non-compliant that it doesn't have altsetting 0
			 * then I wouldn't trust its reply anyway.
			 */
			if (!alt)
				alt = &intf->altsetting[0];

			intf->cur_altsetting = alt;
			usb_enable_interface(dev, intf);
			intf->dev.parent = &dev->dev;
			intf->dev.driver = NULL;
			intf->dev.bus = &usb_bus_type;
			intf->dev.dma_mask = dev->dev.dma_mask;
			intf->dev.release = release_interface;
			device_initialize (&intf->dev);
			sprintf (&intf->dev.bus_id[0], "%d-%s:%d.%d",
				 dev->bus->busnum, dev->devpath,
				 configuration,
				 alt->desc.bInterfaceNumber);
		}
		kfree(new_interfaces);

		if ((cp->desc.iConfiguration) &&
		    (cp->string == NULL)) {
			cp->string = kmalloc(256, GFP_KERNEL);
			if (cp->string)
				usb_string(dev, cp->desc.iConfiguration, cp->string, 256);
		}

		/* Now that all the interfaces are set up, register them
		 * to trigger binding of drivers to interfaces.  probe()
		 * routines may install different altsettings and may
		 * claim() any interfaces not yet bound.  Many class drivers
		 * need that: CDC, audio, video, etc.
		 */
		for (i = 0; i < nintf; ++i) {
			struct usb_interface *intf = cp->interface[i];
			struct usb_interface_descriptor *desc;

			desc = &intf->altsetting [0].desc;
			dev_dbg (&dev->dev,
				"adding %s (config #%d, interface %d)\n",
				intf->dev.bus_id, configuration,
				desc->bInterfaceNumber);
			ret = device_add (&intf->dev);
			if (ret != 0) {
				dev_err(&dev->dev,
					"device_add(%s) --> %d\n",
					intf->dev.bus_id,
					ret);
				continue;
			}
			if ((intf->cur_altsetting->desc.iInterface) &&
			    (intf->cur_altsetting->string == NULL)) {
				intf->cur_altsetting->string = kmalloc(256, GFP_KERNEL);
				if (intf->cur_altsetting->string)
					usb_string(dev, intf->cur_altsetting->desc.iInterface,
						   intf->cur_altsetting->string, 256);
			}
			usb_create_sysfs_intf_files (intf);
		}
	}

	return 0;
}
示例#13
0
static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct ld_usb *dev = NULL;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	char *buffer;
	int i;
	int retval = -ENOMEM;

	

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (dev == NULL) {
		dev_err(&intf->dev, "Out of memory\n");
		goto exit;
	}
	mutex_init(&dev->mutex);
	spin_lock_init(&dev->rbsl);
	dev->intf = intf;
	init_waitqueue_head(&dev->read_wait);
	init_waitqueue_head(&dev->write_wait);

	
	if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VENDOR_ID_LD) &&
	    ((le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_CASSY) ||
	     (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_COM3LAB)) &&
	    (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) {
		buffer = kmalloc(256, GFP_KERNEL);
		if (buffer == NULL) {
			dev_err(&intf->dev, "Couldn't allocate string buffer\n");
			goto error;
		}
		
		usb_string(udev, 255, buffer, 256);
		kfree(buffer);
	}

	iface_desc = intf->cur_altsetting;

	
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (usb_endpoint_is_int_in(endpoint))
			dev->interrupt_in_endpoint = endpoint;

		if (usb_endpoint_is_int_out(endpoint))
			dev->interrupt_out_endpoint = endpoint;
	}
	if (dev->interrupt_in_endpoint == NULL) {
		dev_err(&intf->dev, "Interrupt in endpoint not found\n");
		goto error;
	}
	if (dev->interrupt_out_endpoint == NULL)
		dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");

	dev->interrupt_in_endpoint_size = usb_endpoint_maxp(dev->interrupt_in_endpoint);
	dev->ring_buffer = kmalloc(ring_buffer_size*(sizeof(size_t)+dev->interrupt_in_endpoint_size), GFP_KERNEL);
	if (!dev->ring_buffer) {
		dev_err(&intf->dev, "Couldn't allocate ring_buffer\n");
		goto error;
	}
	dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
	if (!dev->interrupt_in_buffer) {
		dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n");
		goto error;
	}
	dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->interrupt_in_urb) {
		dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n");
		goto error;
	}
	dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? usb_endpoint_maxp(dev->interrupt_out_endpoint) :
									 udev->descriptor.bMaxPacketSize0;
	dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL);
	if (!dev->interrupt_out_buffer) {
		dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n");
		goto error;
	}
	dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->interrupt_out_urb) {
		dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
		goto error;
	}
	dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
	if (dev->interrupt_out_endpoint)
		dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;

	
	usb_set_intfdata(intf, dev);

	retval = usb_register_dev(intf, &ld_usb_class);
	if (retval) {
		
		dev_err(&intf->dev, "Not able to get a minor for this device.\n");
		usb_set_intfdata(intf, NULL);
		goto error;
	}

	
	dev_info(&intf->dev, "LD USB Device #%d now attached to major %d minor %d\n",
		(intf->minor - USB_LD_MINOR_BASE), USB_MAJOR, intf->minor);

exit:
	return retval;

error:
	ld_usb_delete(dev);

	return retval;
}
示例#14
0
文件: advinit.c 项目: rct225/scanside
static INT32S __devinit advdrv_init_one(struct usb_interface *interface, const struct usb_device_id *id)
{
	private_data *privdata = NULL;
	adv_device *device = NULL;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	struct semaphore *urb_sema = NULL;
	INT8U strbuf[50];
	INT32U tmp;
	INT32S ret = 0;
	INT16U i;

	
	/* allocate urb sema */
	urb_sema = kmalloc(sizeof(struct semaphore), GFP_KERNEL);
	if (urb_sema == NULL) {
		return -ENOMEM;
	}
	init_MUTEX(urb_sema);
	

	/* allocate device structure */
	device = (adv_device *) kmalloc(sizeof(adv_device), GFP_KERNEL);
	if (device == NULL) {
		kfree(urb_sema);
		return -ENOMEM;
	}
	memset(device, 0, sizeof(adv_device));
	
	/* allocate private data structure */
	privdata = kmalloc(sizeof(private_data), GFP_KERNEL);
	if (privdata == NULL) {
		kfree(urb_sema);
		kfree(device);
		return -ENOMEM;
	}
	memset(privdata, 0, sizeof(private_data));
	
	/* initialize the private data in the device */
	privdata->udev = usb_get_dev(interface_to_usbdev(interface));
	privdata->interface = interface;
	privdata->usb_urb_sema = urb_sema;
	privdata->device_type = (id->idProduct << 16) | privdata->udev->descriptor.bcdDevice;


	/* get board id */
	ret = adv_usb_ctrl_msg(privdata->udev, usb_rcvctrlpipe(privdata->udev, 0),
			       MAJOR_SYSTEM, 0x40|0x80, MINOR_READ_SWITCHID, 0,
			       (INT8U *) &privdata->board_id, sizeof(INT16U));
	if (ret < 0) {
		kfree(urb_sema);
		kfree(device);
		kfree(privdata);
		return ret;
	}

	/* get USB speed (low, full or high) */
	ret = usb_string(privdata->udev, privdata->udev->descriptor.iProduct,
			 strbuf, sizeof(strbuf));
	if (ret < 0) {
		kfree(urb_sema);
		kfree(device);
		kfree(privdata);
		return ret;
	}
	
	if (strstr(strbuf, "(LS)") != NULL) {
		privdata->usb_speed = USB_SPEED_LOW;
	} else if (strstr(strbuf, "(FS)") != NULL) {
		privdata->usb_speed = USB_SPEED_FULL;
	} else if (strstr(strbuf, "(HS)") != NULL) {
		privdata->usb_speed = USB_SPEED_HIGH;
	}

	
	/* select pipe */
	tmp = 2;
	ret = adv_usb_ctrl_msg(privdata->udev, usb_sndctrlpipe(privdata->udev, 0),
			       MAJOR_DIRECT_IO, 0x40, MINOR_DIRECT_WRITE, 0x501,
			       &tmp, sizeof(INT32U));
	if (ret < 0) {
		kfree(urb_sema);
		kfree(device);
		kfree(privdata);
		return ret;
	}
	
	/* init queue, spinlock and process info list */
	adv_process_info_header_init(&privdata->ptr_process_info);
	spin_lock_init(&privdata->spinlock);
	init_waitqueue_head(&privdata->event_wait);
	tasklet_init(&privdata->urb_tasklet, urb_tasklet_fn, (PTR_T) device);
	INIT_WORK(&privdata->fai_stop_work, adv_fai_stop_work, (VOID *) device);


	/* probe endpoint */
	iface_desc = interface->cur_altsetting;
	for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
		endpoint = &iface_desc->endpoint[i].desc;

		if(!privdata->bulk_endpointAddr &&
		   (endpoint->bEndpointAddress & USB_DIR_IN) &&
		   ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
		    == USB_ENDPOINT_XFER_BULK)) {
			privdata->bulk_endpointAddr = endpoint->bEndpointAddress;
			privdata->max_urbbuf_len = 1 << 14; /* 16KB */
		}
	}
	privdata->control_endpointAddr = 0;
	
	/* support multi-card */
	switch (privdata->device_type) {
	case USB4711A:
		privdata->board_id &= 0x0f;
		advdrv_device_set_devname(device, "usb4711");
		break;
	case USB4711B:
		privdata->board_id &= 0x0f;
		advdrv_device_set_devname(device, "usb4711a");
		break;
	default:
		kfree(urb_sema);
		kfree(device);
		kfree(privdata);
		return -EINVAL;
	}

	/* link the info into the other structures */
	_ADV_SET_DEVICE_PRIVDATA(device, privdata);
	_ADV_SET_DEVICE_BOARDID(device, privdata->board_id);
	usb_set_intfdata(interface, device);


	/* add device into driver list */
	ret = advdrv_add_device(&usb4711_driver, device);
	if (ret) {
		kfree(urb_sema);
		kfree(device);
		kfree(privdata);
		KdPrint("Add device failed!\n");
		return ret;
	}

	KdPrint("Add a USB-4711 device: type=%xh; boardID=%xh.\n",
		privdata->device_type, privdata->board_id);


	return 0;
}
示例#15
0
static int usb_lmpcm_probe(struct usb_interface *intf, const struct usb_device_id *id) {

	struct usb_device *dev = interface_to_usbdev(intf);
	struct usb_host_interface *interface;


	struct usb_endpoint_descriptor *endpoint;
	lmpcm_t *mouse;
	int pipe, maxp;
	char *buf;


	// Get mouse endpoint

	interface = intf->cur_altsetting;

	if ( interface->desc.bNumEndpoints != 1 ) return -ENODEV;
	endpoint = &interface->endpoint[0].desc;


	// Check endpoint

	if (!(endpoint->bEndpointAddress & USB_DIR_IN))
		return -ENODEV;

	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
		return -ENODEV;


	// Create endpoint pipe

	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));


	// Create lmpcm object

	if (!(mouse = lmpcm_new(dev)))
		return -ENOMEM;

	// Initialize input device

	input_device_init(mouse->inputdev,intf,dev);


	// Set device name

	if (!(buf = kmalloc(63, GFP_KERNEL))) {
		lmpcm_free(mouse);
		return -ENOMEM;
	}


	if (dev->descriptor.iManufacturer &&
		usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0)
			strcat(mouse->name, buf);

	if (dev->descriptor.iProduct &&
		usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0)
			sprintf(mouse->name, "%s %s", mouse->name, buf);

	if (!strlen(mouse->name))
		sprintf(mouse->name, "lmpcm_usb.c: Logitech MediaPlay Mouse on usb%04x:%04x",
			mouse->inputdev->id.vendor, mouse->inputdev->id.product);

	kfree(buf);


	// Initialize interrupt transfer

	usb_fill_int_urb(mouse->urb,dev,pipe,mouse->data,((maxp > 8)?8:maxp),usb_lmpcm_handle,mouse,endpoint->bInterval);
	mouse->urb->transfer_dma = mouse->data_dma;
	mouse->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;


	// Register input device

	input_register_device(mouse->inputdev);


	printk(KERN_INFO "lmpcm_usb.c: Detected device: %s\n", mouse->name);

	// Set usb handler interface data

	usb_set_intfdata(intf,mouse);


	return 0;

}
示例#16
0
static int __devinit init_card(struct snd_usb_caiaqdev *dev)
{
	char *c;
	struct usb_device *usb_dev = dev->chip.dev;
	struct snd_card *card = dev->chip.card;
	int err, len;
	
	if (usb_set_interface(usb_dev, 0, 1) != 0) {
		log("can't set alt interface.\n");
		return -EIO;
	}

	usb_init_urb(&dev->ep1_in_urb);
	usb_init_urb(&dev->midi_out_urb);

	usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev, 
			  usb_rcvbulkpipe(usb_dev, 0x1),
			  dev->ep1_in_buf, EP1_BUFSIZE, 
			  usb_ep1_command_reply_dispatch, dev);

	usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev, 
			  usb_sndbulkpipe(usb_dev, 0x1),
			  dev->midi_out_buf, EP1_BUFSIZE, 
			  snd_usb_caiaq_midi_output_done, dev);
	
	init_waitqueue_head(&dev->ep1_wait_queue);
	init_waitqueue_head(&dev->prepare_wait_queue);
	
	if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0)
		return -EIO;

	err = snd_usb_caiaq_send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
	if (err)
		return err;

	if (!wait_event_timeout(dev->ep1_wait_queue, dev->spec_received, HZ))
		return -ENODEV;

	usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
		   dev->vendor_name, CAIAQ_USB_STR_LEN);
	
	usb_string(usb_dev, usb_dev->descriptor.iProduct,
		   dev->product_name, CAIAQ_USB_STR_LEN);
	
	usb_string(usb_dev, usb_dev->descriptor.iSerialNumber,
		   dev->serial, CAIAQ_USB_STR_LEN);

	/* terminate serial string at first white space occurence */
	c = strchr(dev->serial, ' ');
	if (c)
		*c = '\0';
	
	strcpy(card->driver, MODNAME);
	strcpy(card->shortname, dev->product_name);

	len = snprintf(card->longname, sizeof(card->longname),
		       "%s %s (serial %s, ",
		       dev->vendor_name, dev->product_name, dev->serial);

	if (len < sizeof(card->longname) - 2)
		len += usb_make_path(usb_dev, card->longname + len,
				     sizeof(card->longname) - len);

	card->longname[len++] = ')';
	card->longname[len] = '\0';
	setup_card(dev);
	return 0;
}
示例#17
0
文件: ldusb.c 项目: krzk/linux
/**
 *	ld_usb_probe
 *
 *	Called by the usb core when a new device is connected that it thinks
 *	this driver might be interested in.
 */
static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct ld_usb *dev = NULL;
	struct usb_host_interface *iface_desc;
	char *buffer;
	int retval = -ENOMEM;
	int res;

	/* allocate memory for our device state and initialize it */

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev)
		goto exit;
	mutex_init(&dev->mutex);
	spin_lock_init(&dev->rbsl);
	dev->intf = intf;
	init_waitqueue_head(&dev->read_wait);
	init_waitqueue_head(&dev->write_wait);

	/* workaround for early firmware versions on fast computers */
	if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VENDOR_ID_LD) &&
	    ((le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_CASSY) ||
	     (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_LD_COM3LAB)) &&
	    (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) {
		buffer = kmalloc(256, GFP_KERNEL);
		if (!buffer)
			goto error;
		/* usb_string makes SETUP+STALL to leave always ControlReadLoop */
		usb_string(udev, 255, buffer, 256);
		kfree(buffer);
	}

	iface_desc = intf->cur_altsetting;

	res = usb_find_last_int_in_endpoint(iface_desc,
			&dev->interrupt_in_endpoint);
	if (res) {
		dev_err(&intf->dev, "Interrupt in endpoint not found\n");
		retval = res;
		goto error;
	}

	res = usb_find_last_int_out_endpoint(iface_desc,
			&dev->interrupt_out_endpoint);
	if (res)
		dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");

	dev->interrupt_in_endpoint_size = usb_endpoint_maxp(dev->interrupt_in_endpoint);
	dev->ring_buffer =
		kmalloc_array(ring_buffer_size,
			      sizeof(size_t) + dev->interrupt_in_endpoint_size,
			      GFP_KERNEL);
	if (!dev->ring_buffer)
		goto error;
	dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
	if (!dev->interrupt_in_buffer)
		goto error;
	dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->interrupt_in_urb)
		goto error;
	dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? usb_endpoint_maxp(dev->interrupt_out_endpoint) :
									 udev->descriptor.bMaxPacketSize0;
	dev->interrupt_out_buffer =
		kmalloc_array(write_buffer_size,
			      dev->interrupt_out_endpoint_size, GFP_KERNEL);
	if (!dev->interrupt_out_buffer)
		goto error;
	dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->interrupt_out_urb)
		goto error;
	dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
	if (dev->interrupt_out_endpoint)
		dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;

	/* we can register the device now, as it is ready */
	usb_set_intfdata(intf, dev);

	retval = usb_register_dev(intf, &ld_usb_class);
	if (retval) {
		/* something prevented us from registering this driver */
		dev_err(&intf->dev, "Not able to get a minor for this device.\n");
		usb_set_intfdata(intf, NULL);
		goto error;
	}

	/* let the user know what node this device is now attached to */
	dev_info(&intf->dev, "LD USB Device #%d now attached to major %d minor %d\n",
		(intf->minor - USB_LD_MINOR_BASE), USB_MAJOR, intf->minor);

exit:
	return retval;

error:
	ld_usb_delete(dev);

	return retval;
}
示例#18
0
static void *probe_usbpd(struct usb_device *dev, unsigned int ifnum,
			 const struct usb_device_id *id)
{
	struct usbpd_usb_data *usbpd;
	struct usb_interface_descriptor *interface;
	struct usb_endpoint_descriptor *endpoint;
	int ep, direction, i, nusbpd, pusbpd;
	char prod[64];

	pusbpd = -1;
	for(i=0,nusbpd=0;i<USBPD_MINORS;i++){
		if(usbpd_instance_table[i].present)
			nusbpd++;
		else if(pusbpd == -1)
			pusbpd = i;
	}

	if(nusbpd < USBPD_MINORS && pusbpd != -1){
		usbpd = &usbpd_instance_table[pusbpd];
	}
	else{
		printk(KERN_ERR "usbpd: no more free usbpd devices\n");
		return NULL;
	}

	dbg("probe_usbpd: ifnum = %d", ifnum);

	down(&usbpd->lock);
	usbpd->pdtype = UNKNOWN;

/*
	if (dev->descriptor.idVendor != 0x54c) {
		warn(KERN_INFO "Not Sony's product = 0x%02x", dev->descriptor.idVendor);
		up(&usbpd->lock);
		return NULL;
	}
*/

	memset(prod, 0, sizeof(prod));
	if(usb_string(dev, dev->descriptor.iProduct, prod, sizeof(prod)-1) > 0){
		dbg("ProductName = %s", prod);
	}

	if ((dev->descriptor.idVendor == 0x54c) && (dev->descriptor.idProduct == 0x35 /* NWWM */)){
		usbpd->pdtype = NWWM;
	}
	else if ((dev->descriptor.idVendor == 0x54c) && (dev->descriptor.idProduct == 0x1f || /* VMC */
	                                                 dev->descriptor.idProduct == 0x6f)){
		usbpd->pdtype = VMC;
	}
	else if(!strncmp("Net MD", prod, strlen("Net MD")) /* NetMD */ ){
		usbpd->pdtype = NETMD;
	}

	if(usbpd->pdtype == UNKNOWN){
		warn(KERN_INFO "This USBPD(0x%02x/0x%02x) is not supported/tested." ,dev->descriptor.idVendor,dev->descriptor.idProduct);
		up(&usbpd->lock);
		return NULL;
	}

	info("USB USBPD(%d/%d) found at address %d", pusbpd+1, nusbpd+1, dev->devnum);

	usbpd->present = 1;
	usbpd->usbpd_dev = dev;

	interface = &dev->actconfig->interface[ifnum].altsetting[0];

	if (!(usbpd->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) {
		err("probe_usbpd: Not enough memory for the output buffer");
		up(&usbpd->lock);
		return NULL;
	}
	dbg("probe_usbpd: obuf address:%p", usbpd->obuf);

	if (!(usbpd->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) {
		err("probe_usbpd: Not enough memory for the input buffer");
		kfree(usbpd->obuf);
		up(&usbpd->lock);
		return NULL;
	}
	dbg("probe_usbpd: ibuf address:%p", usbpd->ibuf);

	endpoint = interface->endpoint;
	usbpd->bulk_in_ep = usbpd->bulk_out_ep = -1;
	for(i=0;i<2;i++){
		ep = endpoint [i].bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
		direction = endpoint [i].bEndpointAddress & USB_ENDPOINT_DIR_MASK;
		if (direction == USB_DIR_IN)
			usbpd->bulk_in_ep = ep;
		else
			usbpd->bulk_out_ep = ep;
	}

	if(usbpd->bulk_in_ep == -1 || usbpd->bulk_out_ep == -1
		|| endpoint [0].bmAttributes != USB_ENDPOINT_XFER_BULK
		|| endpoint [1].bmAttributes != USB_ENDPOINT_XFER_BULK){
		dbg("Bogus endpoints");
	}

	dbg("bulk_in_ep = %d, bulk_out_ep = %d", usbpd->bulk_in_ep, usbpd->bulk_out_ep);

	up(&usbpd->lock);
	return usbpd;
}
示例#19
0
/* Probe if this driver wants to serve an USB device

   This entry point is called whenever a new device is attached to the bus.
   Then the device driver has to create a new instance of its internal data
   structures for the new device.

   The  dev argument specifies the device context, which contains pointers
   to all USB descriptors. The  interface argument specifies the interface
   number. If a USB driver wants to bind itself to a particular device and
   interface it has to return a pointer. This pointer normally references
   the device driver's context structure.

   Probing normally is done by checking the vendor and product identifications
   or the class and subclass definitions. If they match the interface number
   is compared with the ones supported by the driver. When probing is done
   class based it might be necessary to parse some more USB descriptors because
   the device properties can differ in a wide range.
*/
static void *auerswald_probe(struct usb_device *usbdev, unsigned int ifnum,
			     const struct usb_device_id *id)
{
	struct auerswald *cp = NULL;
	DECLARE_WAIT_QUEUE_HEAD(wqh);
	unsigned int dtindex;
	unsigned int u = 0;
	char *pbuf;
	int ret;

	dbg("probe: vendor id 0x%x, device id 0x%x ifnum:%d",
	    usbdev->descriptor.idVendor, usbdev->descriptor.idProduct,
	    ifnum);

	/* See if the device offered us matches that we can accept */
	if (usbdev->descriptor.idVendor != ID_AUERSWALD)
		return NULL;

	/* we use only the first -and only- interface */
	if (ifnum != 0)
		return NULL;

	/* prevent module unloading while sleeping */
	MOD_INC_USE_COUNT;

	/* allocate memory for our device and intialize it */
	cp = kmalloc(sizeof(struct auerswald), GFP_KERNEL);
	if (cp == NULL) {
		err("out of memory");
		goto pfail;
	}

	/* Initialize device descriptor */
	memset(cp, 0, sizeof(struct auerswald));
	init_MUTEX(&cp->mutex);
	cp->usbdev = usbdev;
	auerchain_init(&cp->controlchain);
	auerbuf_init(&cp->bufctl);
	init_waitqueue_head(&cp->bufferwait);
	auerisdn_init_dev(cp);

	/* find a free slot in the device table */
	down(&auerdev_table_mutex);
	for (dtindex = 0; dtindex < AUER_MAX_DEVICES; ++dtindex) {
		if (auerdev_table[dtindex] == NULL)
			break;
	}
	if (dtindex >= AUER_MAX_DEVICES) {
		err("more than %d devices plugged in, can not handle this device", AUER_MAX_DEVICES);
		up(&auerdev_table_mutex);
		goto pfail;
	}

	/* Give the device a name */
	sprintf(cp->name, AU_PREFIX "%d", dtindex);

	/* Store the index */
	cp->dtindex = dtindex;
	auerdev_table[dtindex] = cp;
	up(&auerdev_table_mutex);

	/* initialize the devfs node for this device and register it */
	cp->devfs = devfs_register(usb_devfs_handle, cp->name,
				   DEVFS_FL_DEFAULT, USB_MAJOR,
				   AUER_MINOR_BASE + dtindex,
				   S_IFCHR | S_IRUGO | S_IWUGO,
				   &auerswald_fops, NULL);

	/* Get the usb version of the device */
	cp->version = cp->usbdev->descriptor.bcdDevice;
	dbg("Version is %X", cp->version);

	/* allow some time to settle the device */
	sleep_on_timeout(&wqh, HZ / 3);

	/* Try to get a suitable textual description of the device */
	/* Device name: */
	ret =
	    usb_string(cp->usbdev, AUSI_DEVICE, cp->dev_desc,
		       AUSI_DLEN - 1);
	if (ret >= 0) {
		u += ret;
		/* Append Serial Number */
		memcpy(&cp->dev_desc[u], ",Ser# ", 6);
		u += 6;
		ret =
		    usb_string(cp->usbdev, AUSI_SERIALNR, &cp->dev_desc[u],
			       AUSI_DLEN - u - 1);
		if (ret >= 0) {
			u += ret;
			/* Append subscriber number */
			memcpy(&cp->dev_desc[u], ", ", 2);
			u += 2;
			ret =
			    usb_string(cp->usbdev, AUSI_MSN,
				       &cp->dev_desc[u],
				       AUSI_DLEN - u - 1);
			if (ret >= 0) {
				u += ret;
			}
		}
	}
	cp->dev_desc[u] = '\0';
	info("device is a %s", cp->dev_desc);

	/* get the maximum allowed control transfer length */
	pbuf = (char *) kmalloc(2, GFP_KERNEL);	/* use an allocated buffer because of urb target */
	if (!pbuf) {
		err("out of memory");
		goto pfail;
	}
	ret = usb_control_msg(cp->usbdev,			/* pointer to device */
			      usb_rcvctrlpipe(cp->usbdev, 0),	/* pipe to control endpoint */
			      AUV_GETINFO,			/* USB message request value */
			      AUT_RREQ,				/* USB message request type value */
			      0,				/* USB message value */
			      AUDI_MBCTRANS,			/* USB message index value */
			      pbuf,				/* pointer to the receive buffer */
			      2,				/* length of the buffer */
			      HZ * 2);				/* time to wait for the message to complete before timing out */
	if (ret == 2) {
		cp->maxControlLength = le16_to_cpup(pbuf);
		kfree(pbuf);
		dbg("setup: max. allowed control transfersize is %d bytes",
		    cp->maxControlLength);
	} else {
		kfree(pbuf);
		err("setup: getting max. allowed control transfer length failed with error %d", ret);
		goto pfail;
	}
	/* allocate a chain for the control messages */
	if (auerchain_setup(&cp->controlchain, AUCH_ELEMENTS)) {
		err("out of memory");
		goto pfail;
	}

	/* allocate buffers for control messages */
	if (auerbuf_setup
	    (&cp->bufctl, AU_RBUFFERS * 2,
	     cp->maxControlLength + AUH_SIZE)) {
		err("out of memory");
		goto pfail;
	}

	/* start the interrupt endpoint */
	if (auerswald_int_open(cp)) {
		err("int endpoint failed");
		goto pfail;
	}

	/* Try to connect to hisax interface */
	if (auerisdn_probe(cp)) {
		err("hisax connect failed");
		goto pfail;
	}

	/* all OK */
	return cp;

	/* Error exit: clean up the memory */
      pfail:auerswald_delete(cp);
	MOD_DEC_USE_COUNT;
	return NULL;
}
示例#20
0
/*
 * "ioctl" file op
 */
static int hiddev_ioctl(struct inode *inode, struct file *file,
			unsigned int cmd, unsigned long arg)
{
	struct hiddev_list *list = file->private_data;
	struct hiddev *hiddev = list->hiddev;
	struct hid_device *hid = hiddev->hid;
	struct usb_device *dev = hid->dev;
	struct hiddev_collection_info cinfo;
	struct hiddev_report_info rinfo;
	struct hiddev_field_info finfo;
	struct hiddev_usage_ref_multi uref_multi;
	struct hiddev_usage_ref *uref = &uref_multi.uref;
	struct hiddev_devinfo dinfo;
	struct hid_report *report;
	struct hid_field *field;
	int i;

	if (!hiddev->exist) return -EIO;

	switch (cmd) {

	case HIDIOCGVERSION:
		return put_user(HID_VERSION, (int *) arg);

	case HIDIOCAPPLICATION:
		if (arg < 0 || arg >= hid->maxapplication)
			return -EINVAL;

		for (i = 0; i < hid->maxcollection; i++)
			if (hid->collection[i].type == 
			    HID_COLLECTION_APPLICATION && arg-- == 0)
				break;
		
		if (i == hid->maxcollection)
			return -EINVAL;

		return hid->collection[i].usage;

	case HIDIOCGDEVINFO:
		dinfo.bustype = BUS_USB;
		dinfo.busnum = dev->bus->busnum;
		dinfo.devnum = dev->devnum;
		dinfo.ifnum = hid->ifnum;
		dinfo.vendor = dev->descriptor.idVendor;
		dinfo.product = dev->descriptor.idProduct;
		dinfo.version = dev->descriptor.bcdDevice;
		dinfo.num_applications = hid->maxapplication;
		if (copy_to_user((void *) arg, &dinfo, sizeof(dinfo)))
			return -EFAULT;
		return 0;

	case HIDIOCGFLAG:
		return put_user(list->flags, (int *) arg);

	case HIDIOCSFLAG:
		{
			int newflags;
			if (get_user(newflags, (int *) arg))
				return -EFAULT;

			if ((newflags & ~HIDDEV_FLAGS) != 0 ||
			    ((newflags & HIDDEV_FLAG_REPORT) != 0 &&
			     (newflags & HIDDEV_FLAG_UREF) == 0))
				return -EINVAL;

			list->flags = newflags;

			return 0;
		}

	case HIDIOCGSTRING:
		{
			int idx, len;
			char *buf;

			if (get_user(idx, (int *) arg))
				return -EFAULT;

			if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
				return -ENOMEM;

			if ((len = usb_string(dev, idx, buf, HID_STRING_SIZE-1)) < 0) {
				kfree(buf);
				return -EINVAL;
			}

			if (copy_to_user((void *) (arg+sizeof(int)), buf, len+1)) {
				kfree(buf);
				return -EFAULT;
			}

			kfree(buf);

			return len;
		}

	case HIDIOCINITREPORT:
		hid_init_reports(hid);

		return 0;

	case HIDIOCGREPORT:
		if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
			return -EFAULT;

		if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
			return -EINVAL;

		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		hid_read_report(hid, report);

		return 0;

	case HIDIOCSREPORT:
		if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
			return -EFAULT;

		if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
			return -EINVAL;

		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		hid_write_report(hid, report);

		return 0;

	case HIDIOCGREPORTINFO:
		if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
			return -EFAULT;

		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		rinfo.num_fields = report->maxfield;

		if (copy_to_user((void *) arg, &rinfo, sizeof(rinfo)))
			return -EFAULT;
		return 0;

	case HIDIOCGFIELDINFO:
		if (copy_from_user(&finfo, (void *) arg, sizeof(finfo)))
			return -EFAULT;
		rinfo.report_type = finfo.report_type;
		rinfo.report_id = finfo.report_id;
		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		if (finfo.field_index >= report->maxfield)
			return -EINVAL;

		field = report->field[finfo.field_index];
		memset(&finfo, 0, sizeof(finfo));
		finfo.report_type = rinfo.report_type;
		finfo.report_id = rinfo.report_id;
		finfo.field_index = field->report_count - 1;
		finfo.maxusage = field->maxusage;
		finfo.flags = field->flags;
		finfo.physical = field->physical;
		finfo.logical = field->logical;
		finfo.application = field->application;
		finfo.logical_minimum = field->logical_minimum;
		finfo.logical_maximum = field->logical_maximum;
		finfo.physical_minimum = field->physical_minimum;
		finfo.physical_maximum = field->physical_maximum;
		finfo.unit_exponent = field->unit_exponent;
		finfo.unit = field->unit;

		if (copy_to_user((void *) arg, &finfo, sizeof(finfo)))
			return -EFAULT;
		return 0;

	case HIDIOCGUCODE:
		if (copy_from_user(uref, (void *) arg, sizeof(*uref)))
			return -EFAULT;

		rinfo.report_type = uref->report_type;
		rinfo.report_id = uref->report_id;
		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		if (uref->field_index >= report->maxfield)
			return -EINVAL;

		field = report->field[uref->field_index];
		if (uref->usage_index >= field->maxusage)
			return -EINVAL;

		uref->usage_code = field->usage[uref->usage_index].hid;

		if (copy_to_user((void *) arg, uref, sizeof(*uref)))
			return -EFAULT;
		return 0;

	case HIDIOCGUSAGE:
	case HIDIOCSUSAGE:
	case HIDIOCGUSAGES:
	case HIDIOCSUSAGES:
	case HIDIOCGCOLLECTIONINDEX:
		if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
			if (copy_from_user(&uref_multi, (void *) arg, 
					   sizeof(uref_multi)))
				return -EFAULT;
		} else {
			if (copy_from_user(uref, (void *) arg, sizeof(*uref)))
				return -EFAULT;
		}

		if (cmd != HIDIOCGUSAGE && 
		    cmd != HIDIOCGUSAGES &&
		    uref->report_type == HID_REPORT_TYPE_INPUT)
			return -EINVAL;

		if (uref->report_id == HID_REPORT_ID_UNKNOWN) {
			field = hiddev_lookup_usage(hid, uref);
			if (field == NULL)
				return -EINVAL;
		} else {
			rinfo.report_type = uref->report_type;
			rinfo.report_id = uref->report_id;
			if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
				return -EINVAL;

			if (uref->field_index >= report->maxfield)
				return -EINVAL;

			field = report->field[uref->field_index];
			if (uref->usage_index >= field->maxusage)
				return -EINVAL;

			if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
				if (uref_multi.num_values >= HID_MAX_USAGES || 
				    uref->usage_index >= field->maxusage || 
				   (uref->usage_index + uref_multi.num_values) >= field->maxusage)
					return -EINVAL;
			}
		}

		switch (cmd) {
		case HIDIOCGUSAGE:
			uref->value = field->value[uref->usage_index];
			return copy_to_user((void *) arg, uref, sizeof(*uref));

		case HIDIOCSUSAGE:
			field->value[uref->usage_index] = uref->value;
			return 0;

		case HIDIOCGCOLLECTIONINDEX:
			return field->usage[uref->usage_index].collection_index;
		case HIDIOCGUSAGES:
			for (i = 0; i < uref_multi.num_values; i++)
				uref_multi.values[i] = 
				    field->value[uref->usage_index + i];
			if (copy_to_user((void *) arg, &uref_multi, 
					 sizeof(uref_multi)))
				return -EFAULT;
			return 0;
		case HIDIOCSUSAGES:
			for (i = 0; i < uref_multi.num_values; i++)
				field->value[uref->usage_index + i] = 
				    uref_multi.values[i];
			return 0;
		}
		break;

	case HIDIOCGCOLLECTIONINFO:
		if (copy_from_user(&cinfo, (void *) arg, sizeof(cinfo)))
			return -EFAULT;

		if (cinfo.index >= hid->maxcollection)
			return -EINVAL;

		cinfo.type = hid->collection[cinfo.index].type;
		cinfo.usage = hid->collection[cinfo.index].usage;
		cinfo.level = hid->collection[cinfo.index].level;

		if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
			return -EFAULT;
		return 0;

	default:

		if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
			return -EINVAL;

		if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) {
			int len;
			if (!hid->name) return 0;
			len = strlen(hid->name) + 1;
			if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
			return copy_to_user((char *) arg, hid->name, len) ?
				-EFAULT : len;
		}
	}
	return -EINVAL;
}
示例#21
0
static int usb_remote_probe(struct usb_interface *intf,
				const struct usb_device_id *id)
{
	struct usb_device *dev = NULL;
	struct usb_host_interface *idesc = NULL;
	struct usb_host_endpoint *ep_ctl2;
#else
static void *usb_remote_probe(struct usb_device *dev, unsigned int ifnum,
				const struct usb_device_id *id)
{
	struct usb_interface *intf;
	struct usb_interface_descriptor *idesc;
	struct usb_endpoint_descriptor *ep_ctl2;
#endif
	struct igorplug *ir = NULL;
	struct lirc_driver *driver = NULL;
	int devnum, pipe, maxp;
	int minor = 0;
	char buf[63], name[128] = "";
	int mem_failure = 0;
	int ret;

	dprintk(": usb probe called.\n");

#if defined(KERNEL_2_5)
	dev = interface_to_usbdev(intf);

#  if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5)
	idesc = &intf->altsetting[intf->act_altsetting];  /* in 2.6.4 */
#  else
	idesc = intf->cur_altsetting;  /* in 2.6.6 */
#  endif

	if (idesc->desc.bNumEndpoints != 1)
		return -ENODEV;
	ep_ctl2 = idesc->endpoint;
	if (((ep_ctl2->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK)
	    != USB_DIR_IN)
	    || (ep_ctl2->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
	    != USB_ENDPOINT_XFER_CONTROL)
		return -ENODEV;
	pipe = usb_rcvctrlpipe(dev, ep_ctl2->desc.bEndpointAddress);
#else
	intf = &dev->actconfig->interface[ifnum];
	idesc = &intf->altsetting[intf->act_altsetting];
	if (idesc->bNumEndpoints != 1)
		return NULL;
	ep_ctl2 = idesc->endpoint;
	if (((ep_ctl2->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
	    != USB_DIR_IN)
	    || (ep_ctl2->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
	    != USB_ENDPOINT_XFER_CONTROL)
		return NULL;
	pipe = usb_rcvctrlpipe(dev, ep_ctl2->bEndpointAddress);
#endif
	devnum = dev->devnum;
	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));

	dprintk(DRIVER_NAME "[%d]: bytes_in_key=%d maxp=%d\n",
		devnum, CODE_LENGTH, maxp);


	mem_failure = 0;
	ir = kzalloc(sizeof(struct igorplug), GFP_KERNEL);
	if (!ir) {
		mem_failure = 1;
		goto mem_failure_switch;
	}

	driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
	if (!driver) {
		mem_failure = 2;
		goto mem_failure_switch;
	}

#if defined(KERNEL_2_5)
	ir->buf_in = usb_buffer_alloc(dev,
			      DEVICE_BUFLEN+DEVICE_HEADERLEN,
			      GFP_ATOMIC, &ir->dma_in);
#else
	ir->buf_in = kmalloc(DEVICE_BUFLEN+DEVICE_HEADERLEN,
			     GFP_KERNEL);
#endif
	if (!ir->buf_in) {
		mem_failure = 3;
		goto mem_failure_switch;
	}

	strcpy(driver->name, DRIVER_NAME " ");
	driver->minor = -1;
	driver->code_length = CODE_LENGTH * 8; /* in bits */
	driver->features = LIRC_CAN_REC_MODE2;
	driver->data = ir;
	driver->buffer_size = DEVICE_BUFLEN + ADDITIONAL_LIRC_BYTES;
	driver->set_use_inc = &set_use_inc;
	driver->set_use_dec = &set_use_dec;
	driver->sample_rate = sample_rate;    /* per second */
	driver->add_to_buf = &usb_remote_poll;
#ifdef LIRC_HAVE_SYSFS
	driver->dev = &intf->dev;
#endif
	driver->owner = THIS_MODULE;

	minor = lirc_register_driver(driver);
	if (minor < 0)
		mem_failure = 9;

mem_failure_switch:

	switch (mem_failure) {
	case 9:
#if defined(KERNEL_2_5)
		usb_buffer_free(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN,
			ir->buf_in, ir->dma_in);
#else
		kfree(ir->buf_in);
#endif
	case 3:
		kfree(driver);
	case 2:
		kfree(ir);
	case 1:
		printk(KERN_ERR DRIVER_NAME "[%d]: out of memory (code=%d)\n",
			devnum, mem_failure);
#if defined(KERNEL_2_5)
		return -ENOMEM;
#else
		return NULL;
#endif
	}

	driver->minor = minor;
	ir->d = driver;
	ir->devnum = devnum;
	ir->usbdev = dev;
	ir->len_in = DEVICE_BUFLEN+DEVICE_HEADERLEN;
	ir->in_space = 1; /* First mode2 event is a space. */
	do_gettimeofday(&ir->last_time);

	if (dev->descriptor.iManufacturer
	    && usb_string(dev, dev->descriptor.iManufacturer,
			  buf, sizeof(buf)) > 0)
		strlcpy(name, buf, sizeof(name));
	if (dev->descriptor.iProduct
	    && usb_string(dev, dev->descriptor.iProduct, buf, sizeof(buf)) > 0)
		snprintf(name + strlen(name), sizeof(name) - strlen(name),
			 " %s", buf);
	printk(KERN_INFO DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name,
	       dev->bus->busnum, devnum);

	/* clear device buffer */
	ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
		SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN,
		/*unused*/0, /*unused*/0,
		/*dummy*/ir->buf_in, /*dummy*/ir->len_in,
		/*timeout*/HZ * USB_CTRL_GET_TIMEOUT);
	if (ret < 0)
		printk(KERN_WARNING DRIVER_NAME
		       "[%d]: SET_INFRABUFFER_EMPTY: error %d\n",
			devnum, ret);

#if defined(KERNEL_2_5)
	usb_set_intfdata(intf, ir);
	return 0;
#else
	return ir;
#endif
}


#if defined(KERNEL_2_5)
static void usb_remote_disconnect(struct usb_interface *intf)
{
	struct usb_device *dev = interface_to_usbdev(intf);
	struct igorplug *ir = usb_get_intfdata(intf);
#else
static void usb_remote_disconnect(struct usb_device *dev, void *ptr)
{
	struct igorplug *ir = ptr;
#endif

	if (!ir || !ir->d)
		return;

	printk(KERN_INFO DRIVER_NAME
	       "[%d]: usb remote disconnected\n", ir->devnum);

	lirc_unregister_driver(ir->d->minor);

	lirc_buffer_free(ir->d->rbuf);
	kfree(ir->d->rbuf);
	kfree(ir->d);


#if defined(KERNEL_2_5)
	usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in);
#else
	kfree(ir->buf_in);
#endif

	kfree(ir);
}

static struct usb_device_id usb_remote_id_table [] = {
	/* Igor Plug USB (Atmel's Manufact. ID) */
	{ USB_DEVICE(0x03eb, 0x0002) },
	/* Fit PC2 Infrared Adapter */
	{ USB_DEVICE(0x03eb, 0x21fe) },

	/* Terminating entry */
	{ }
};

static struct usb_driver usb_remote_driver = {
	LIRC_THIS_MODULE(.owner = THIS_MODULE)
	.name =		DRIVER_NAME,
	.probe =	usb_remote_probe,
	.disconnect =	usb_remote_disconnect,
	.id_table =	usb_remote_id_table
};

static int __init usb_remote_init(void)
{
	int i;

	printk(KERN_INFO DRIVER_NAME ": " DRIVER_DESC " v" DRIVER_VERSION "\n");
	printk(KERN_INFO DRIVER_NAME ": " DRIVER_AUTHOR "\n");
	dprintk(": debug mode enabled\n");

	i = usb_register(&usb_remote_driver);
	if (i < 0) {
		printk(KERN_ERR DRIVER_NAME
		       ": usb register failed, result = %d\n", i);
		return -ENODEV;
	}

	return 0;
}
示例#22
0
文件: ldusb.c 项目: kzlin129/tt-gpl
/**
 *	ld_usb_probe
 *
 *	Called by the usb core when a new device is connected that it thinks
 *	this driver might be interested in.
 */
static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct ld_usb *dev = NULL;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	char *buffer;
	int i;
	int retval = -ENOMEM;

	/* allocate memory for our device state and intialize it */

	dev = kmalloc(sizeof(*dev), GFP_KERNEL);
	if (dev == NULL) {
		dev_err(&intf->dev, "Out of memory\n");
		goto exit;
	}
	memset(dev, 0x00, sizeof(*dev));
	init_MUTEX(&dev->sem);
	dev->intf = intf;
	init_waitqueue_head(&dev->read_wait);
	init_waitqueue_head(&dev->write_wait);

	/* workaround for early firmware versions on fast computers */
	if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VENDOR_ID_LD) &&
	    ((le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_CASSY) ||
	     (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_COM3LAB)) &&
	    (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) {
		buffer = kmalloc(256, GFP_KERNEL);
		if (buffer == NULL) {
			dev_err(&intf->dev, "Couldn't allocate string buffer\n");
			goto error;
		}
		/* usb_string makes SETUP+STALL to leave always ControlReadLoop */
		usb_string(udev, 255, buffer, 256);
		kfree(buffer);
	}

	iface_desc = intf->cur_altsetting;

	/* set up the endpoint information */
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
			dev->interrupt_in_endpoint = endpoint;
		}

		if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) &&
		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
			dev->interrupt_out_endpoint = endpoint;
		}
	}
	if (dev->interrupt_in_endpoint == NULL) {
		dev_err(&intf->dev, "Interrupt in endpoint not found\n");
		goto error;
	}
	if (dev->interrupt_out_endpoint == NULL)
		dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");

	dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
	dev->ring_buffer = kmalloc(ring_buffer_size*(sizeof(size_t)+dev->interrupt_in_endpoint_size), GFP_KERNEL);
	if (!dev->ring_buffer) {
		dev_err(&intf->dev, "Couldn't allocate ring_buffer\n");
		goto error;
	}
	dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
	if (!dev->interrupt_in_buffer) {
		dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n");
		goto error;
	}
	dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->interrupt_in_urb) {
		dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n");
		goto error;
	}
	dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
									 udev->descriptor.bMaxPacketSize0;
	dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL);
	if (!dev->interrupt_out_buffer) {
		dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n");
		goto error;
	}
	dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!dev->interrupt_out_urb) {
		dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
		goto error;
	}
	dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
	if (dev->interrupt_out_endpoint)
		dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;

	/* we can register the device now, as it is ready */
	usb_set_intfdata(intf, dev);

	retval = usb_register_dev(intf, &ld_usb_class);
	if (retval) {
		/* something prevented us from registering this driver */
		dev_err(&intf->dev, "Not able to get a minor for this device.\n");
		usb_set_intfdata(intf, NULL);
		goto error;
	}

	/* let the user know what node this device is now attached to */
	dev_info(&intf->dev, "LD USB Device #%d now attached to major %d minor %d\n",
		(intf->minor - USB_LD_MINOR_BASE), USB_MAJOR, intf->minor);

exit:
	return retval;

error:
	ld_usb_delete(dev);

	return retval;
}
示例#23
0
文件: device.c 项目: AiWinters/linux
static int init_card(struct snd_usb_caiaqdev *dev)
{
	char *c, usbpath[32];
	struct usb_device *usb_dev = dev->chip.dev;
	struct snd_card *card = dev->chip.card;
	int err, len;

	if (usb_set_interface(usb_dev, 0, 1) != 0) {
		log("can't set alt interface.\n");
		return -EIO;
	}

	usb_init_urb(&dev->ep1_in_urb);
	usb_init_urb(&dev->midi_out_urb);

	usb_fill_bulk_urb(&dev->ep1_in_urb, usb_dev,
			  usb_rcvbulkpipe(usb_dev, 0x1),
			  dev->ep1_in_buf, EP1_BUFSIZE,
			  usb_ep1_command_reply_dispatch, dev);

	usb_fill_bulk_urb(&dev->midi_out_urb, usb_dev,
			  usb_sndbulkpipe(usb_dev, 0x1),
			  dev->midi_out_buf, EP1_BUFSIZE,
			  snd_usb_caiaq_midi_output_done, dev);

	init_waitqueue_head(&dev->ep1_wait_queue);
	init_waitqueue_head(&dev->prepare_wait_queue);

	if (usb_submit_urb(&dev->ep1_in_urb, GFP_KERNEL) != 0)
		return -EIO;

	err = snd_usb_caiaq_send_command(dev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
	if (err)
		return err;

	if (!wait_event_timeout(dev->ep1_wait_queue, dev->spec_received, HZ))
		return -ENODEV;

	usb_string(usb_dev, usb_dev->descriptor.iManufacturer,
		   dev->vendor_name, CAIAQ_USB_STR_LEN);

	usb_string(usb_dev, usb_dev->descriptor.iProduct,
		   dev->product_name, CAIAQ_USB_STR_LEN);

	strlcpy(card->driver, MODNAME, sizeof(card->driver));
	strlcpy(card->shortname, dev->product_name, sizeof(card->shortname));
	strlcpy(card->mixername, dev->product_name, sizeof(card->mixername));

	/* if the id was not passed as module option, fill it with a shortened
	 * version of the product string which does not contain any
	 * whitespaces */

	if (*card->id == '\0') {
		char id[sizeof(card->id)];

		memset(id, 0, sizeof(id));

		for (c = card->shortname, len = 0;
			*c && len < sizeof(card->id); c++)
			if (*c != ' ')
				id[len++] = *c;

		snd_card_set_id(card, id);
	}

	usb_make_path(usb_dev, usbpath, sizeof(usbpath));
	snprintf(card->longname, sizeof(card->longname),
		       "%s %s (%s)",
		       dev->vendor_name, dev->product_name, usbpath);

	setup_card(dev);
	return 0;
}
示例#24
0
/* Send close command to device */
static int usb_8dev_cmd_close(struct usb_8dev_priv *priv)
{
	struct usb_8dev_cmd_msg inmsg;
	struct usb_8dev_cmd_msg outmsg = {
		.channel = 0,
		.command = USB_8DEV_CLOSE,
		.opt1 = 0,
		.opt2 = 0
	};

	return usb_8dev_send_cmd(priv, &outmsg, &inmsg);
}

/* Get firmware and hardware version */
static int usb_8dev_cmd_version(struct usb_8dev_priv *priv, u32 *res)
{
	struct usb_8dev_cmd_msg	inmsg;
	struct usb_8dev_cmd_msg	outmsg = {
		.channel = 0,
		.command = USB_8DEV_GET_SOFTW_HARDW_VER,
		.opt1 = 0,
		.opt2 = 0
	};

	int err = usb_8dev_send_cmd(priv, &outmsg, &inmsg);
	if (err)
		return err;

	*res = be32_to_cpup((__be32 *)inmsg.data);

	return err;
}

/* Set network device mode
 *
 * Maybe we should leave this function empty, because the device
 * set mode variable with open command.
 */
static int usb_8dev_set_mode(struct net_device *netdev, enum can_mode mode)
{
	struct usb_8dev_priv *priv = netdev_priv(netdev);
	int err = 0;

	switch (mode) {
	case CAN_MODE_START:
		err = usb_8dev_cmd_open(priv);
		if (err)
			netdev_warn(netdev, "couldn't start device");
		break;

	default:
		return -EOPNOTSUPP;
	}

	return err;
}

/* Read error/status frames */
static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
				struct usb_8dev_rx_msg *msg)
{
	struct can_frame *cf;
	struct sk_buff *skb;
	struct net_device_stats *stats = &priv->netdev->stats;

	/* Error message:
	 * byte 0: Status
	 * byte 1: bit   7: Receive Passive
	 * byte 1: bit 0-6: Receive Error Counter
	 * byte 2: Transmit Error Counter
	 * byte 3: Always 0 (maybe reserved for future use)
	 */

	u8 state = msg->data[0];
	u8 rxerr = msg->data[1] & USB_8DEV_RP_MASK;
	u8 txerr = msg->data[2];
	int rx_errors = 0;
	int tx_errors = 0;

	skb = alloc_can_err_skb(priv->netdev, &cf);
	if (!skb)
		return;

	switch (state) {
	case USB_8DEV_STATUSMSG_OK:
		priv->can.state = CAN_STATE_ERROR_ACTIVE;
		cf->can_id |= CAN_ERR_PROT;
		cf->data[2] = CAN_ERR_PROT_ACTIVE;
		break;
	case USB_8DEV_STATUSMSG_BUSOFF:
		priv->can.state = CAN_STATE_BUS_OFF;
		cf->can_id |= CAN_ERR_BUSOFF;
		can_bus_off(priv->netdev);
		break;
	case USB_8DEV_STATUSMSG_OVERRUN:
	case USB_8DEV_STATUSMSG_BUSLIGHT:
	case USB_8DEV_STATUSMSG_BUSHEAVY:
		cf->can_id |= CAN_ERR_CRTL;
		break;
	default:
		priv->can.state = CAN_STATE_ERROR_WARNING;
		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
		priv->can.can_stats.bus_error++;
		break;
	}

	switch (state) {
	case USB_8DEV_STATUSMSG_OK:
	case USB_8DEV_STATUSMSG_BUSOFF:
		break;
	case USB_8DEV_STATUSMSG_ACK:
		cf->can_id |= CAN_ERR_ACK;
		tx_errors = 1;
		break;
	case USB_8DEV_STATUSMSG_CRC:
		cf->data[2] |= CAN_ERR_PROT_UNSPEC;
		cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ |
			       CAN_ERR_PROT_LOC_CRC_DEL;
		rx_errors = 1;
		break;
	case USB_8DEV_STATUSMSG_BIT0:
		cf->data[2] |= CAN_ERR_PROT_BIT0;
		tx_errors = 1;
		break;
	case USB_8DEV_STATUSMSG_BIT1:
		cf->data[2] |= CAN_ERR_PROT_BIT1;
		tx_errors = 1;
		break;
	case USB_8DEV_STATUSMSG_FORM:
		cf->data[2] |= CAN_ERR_PROT_FORM;
		rx_errors = 1;
		break;
	case USB_8DEV_STATUSMSG_STUFF:
		cf->data[2] |= CAN_ERR_PROT_STUFF;
		rx_errors = 1;
		break;
	case USB_8DEV_STATUSMSG_OVERRUN:
		cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
		stats->rx_over_errors++;
		rx_errors = 1;
		break;
	case USB_8DEV_STATUSMSG_BUSLIGHT:
		priv->can.state = CAN_STATE_ERROR_WARNING;
		cf->data[1] = (txerr > rxerr) ?
			CAN_ERR_CRTL_TX_WARNING :
			CAN_ERR_CRTL_RX_WARNING;
		priv->can.can_stats.error_warning++;
		break;
	case USB_8DEV_STATUSMSG_BUSHEAVY:
		priv->can.state = CAN_STATE_ERROR_PASSIVE;
		cf->data[1] = (txerr > rxerr) ?
			CAN_ERR_CRTL_TX_PASSIVE :
			CAN_ERR_CRTL_RX_PASSIVE;
		priv->can.can_stats.error_passive++;
		break;
	default:
		netdev_warn(priv->netdev,
			    "Unknown status/error message (%d)\n", state);
		break;
	}

	if (tx_errors) {
		cf->data[2] |= CAN_ERR_PROT_TX;
		stats->tx_errors++;
	}

	if (rx_errors)
		stats->rx_errors++;

	cf->data[6] = txerr;
	cf->data[7] = rxerr;

	priv->bec.txerr = txerr;
	priv->bec.rxerr = rxerr;

	netif_rx(skb);

	stats->rx_packets++;
	stats->rx_bytes += cf->can_dlc;
}

/* Read data and status frames */
static void usb_8dev_rx_can_msg(struct usb_8dev_priv *priv,
				struct usb_8dev_rx_msg *msg)
{
	struct can_frame *cf;
	struct sk_buff *skb;
	struct net_device_stats *stats = &priv->netdev->stats;

	if (msg->type == USB_8DEV_TYPE_ERROR_FRAME &&
		   msg->flags == USB_8DEV_ERR_FLAG) {
		usb_8dev_rx_err_msg(priv, msg);
	} else if (msg->type == USB_8DEV_TYPE_CAN_FRAME) {
		skb = alloc_can_skb(priv->netdev, &cf);
		if (!skb)
			return;

		cf->can_id = be32_to_cpu(msg->id);
		cf->can_dlc = get_can_dlc(msg->dlc & 0xF);

		if (msg->flags & USB_8DEV_EXTID)
			cf->can_id |= CAN_EFF_FLAG;

		if (msg->flags & USB_8DEV_RTR)
			cf->can_id |= CAN_RTR_FLAG;
		else
			memcpy(cf->data, msg->data, cf->can_dlc);

		netif_rx(skb);

		stats->rx_packets++;
		stats->rx_bytes += cf->can_dlc;

		can_led_event(priv->netdev, CAN_LED_EVENT_RX);
	} else {
		netdev_warn(priv->netdev, "frame type %d unknown",
			 msg->type);
	}

}

/* Callback for reading data from device
 *
 * Check urb status, call read function and resubmit urb read operation.
 */
static void usb_8dev_read_bulk_callback(struct urb *urb)
{
	struct usb_8dev_priv *priv = urb->context;
	struct net_device *netdev;
	int retval;
	int pos = 0;

	netdev = priv->netdev;

	if (!netif_device_present(netdev))
		return;

	switch (urb->status) {
	case 0: /* success */
		break;

	case -ENOENT:
	case -ESHUTDOWN:
		return;

	default:
		netdev_info(netdev, "Rx URB aborted (%d)\n",
			 urb->status);
		goto resubmit_urb;
	}

	while (pos < urb->actual_length) {
		struct usb_8dev_rx_msg *msg;

		if (pos + sizeof(struct usb_8dev_rx_msg) > urb->actual_length) {
			netdev_err(priv->netdev, "format error\n");
			break;
		}

		msg = (struct usb_8dev_rx_msg *)(urb->transfer_buffer + pos);
		usb_8dev_rx_can_msg(priv, msg);

		pos += sizeof(struct usb_8dev_rx_msg);
	}

resubmit_urb:
	usb_fill_bulk_urb(urb, priv->udev,
			  usb_rcvbulkpipe(priv->udev, USB_8DEV_ENDP_DATA_RX),
			  urb->transfer_buffer, RX_BUFFER_SIZE,
			  usb_8dev_read_bulk_callback, priv);

	retval = usb_submit_urb(urb, GFP_ATOMIC);

	if (retval == -ENODEV)
		netif_device_detach(netdev);
	else if (retval)
		netdev_err(netdev,
			"failed resubmitting read bulk urb: %d\n", retval);
}

/* Callback handler for write operations
 *
 * Free allocated buffers, check transmit status and
 * calculate statistic.
 */
static void usb_8dev_write_bulk_callback(struct urb *urb)
{
	struct usb_8dev_tx_urb_context *context = urb->context;
	struct usb_8dev_priv *priv;
	struct net_device *netdev;

	BUG_ON(!context);

	priv = context->priv;
	netdev = priv->netdev;

	/* free up our allocated buffer */
	usb_free_coherent(urb->dev, urb->transfer_buffer_length,
			  urb->transfer_buffer, urb->transfer_dma);

	atomic_dec(&priv->active_tx_urbs);

	if (!netif_device_present(netdev))
		return;

	if (urb->status)
		netdev_info(netdev, "Tx URB aborted (%d)\n",
			 urb->status);

	netdev->stats.tx_packets++;
	netdev->stats.tx_bytes += context->dlc;

	can_get_echo_skb(netdev, context->echo_index);

	can_led_event(netdev, CAN_LED_EVENT_TX);

	/* Release context */
	context->echo_index = MAX_TX_URBS;

	netif_wake_queue(netdev);
}

/* Send data to device */
static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb,
				      struct net_device *netdev)
{
	struct usb_8dev_priv *priv = netdev_priv(netdev);
	struct net_device_stats *stats = &netdev->stats;
	struct can_frame *cf = (struct can_frame *) skb->data;
	struct usb_8dev_tx_msg *msg;
	struct urb *urb;
	struct usb_8dev_tx_urb_context *context = NULL;
	u8 *buf;
	int i, err;
	size_t size = sizeof(struct usb_8dev_tx_msg);

	if (can_dropped_invalid_skb(netdev, skb))
		return NETDEV_TX_OK;

	/* create a URB, and a buffer for it, and copy the data to the URB */
	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb) {
		netdev_err(netdev, "No memory left for URBs\n");
		goto nomem;
	}

	buf = usb_alloc_coherent(priv->udev, size, GFP_ATOMIC,
				 &urb->transfer_dma);
	if (!buf) {
		netdev_err(netdev, "No memory left for USB buffer\n");
		goto nomembuf;
	}

	memset(buf, 0, size);

	msg = (struct usb_8dev_tx_msg *)buf;
	msg->begin = USB_8DEV_DATA_START;
	msg->flags = 0x00;

	if (cf->can_id & CAN_RTR_FLAG)
		msg->flags |= USB_8DEV_RTR;

	if (cf->can_id & CAN_EFF_FLAG)
		msg->flags |= USB_8DEV_EXTID;

	msg->id = cpu_to_be32(cf->can_id & CAN_ERR_MASK);
	msg->dlc = cf->can_dlc;
	memcpy(msg->data, cf->data, cf->can_dlc);
	msg->end = USB_8DEV_DATA_END;

	for (i = 0; i < MAX_TX_URBS; i++) {
		if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) {
			context = &priv->tx_contexts[i];
			break;
		}
	}

	/* May never happen! When this happens we'd more URBs in flight as
	 * allowed (MAX_TX_URBS).
	 */
	if (!context)
		goto nofreecontext;

	context->priv = priv;
	context->echo_index = i;
	context->dlc = cf->can_dlc;

	usb_fill_bulk_urb(urb, priv->udev,
			  usb_sndbulkpipe(priv->udev, USB_8DEV_ENDP_DATA_TX),
			  buf, size, usb_8dev_write_bulk_callback, context);
	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	usb_anchor_urb(urb, &priv->tx_submitted);

	can_put_echo_skb(skb, netdev, context->echo_index);

	atomic_inc(&priv->active_tx_urbs);

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (unlikely(err))
		goto failed;
	else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS)
		/* Slow down tx path */
		netif_stop_queue(netdev);

	/* Release our reference to this URB, the USB core will eventually free
	 * it entirely.
	 */
	usb_free_urb(urb);

	return NETDEV_TX_OK;

nofreecontext:
	usb_free_coherent(priv->udev, size, buf, urb->transfer_dma);
	usb_free_urb(urb);

	netdev_warn(netdev, "couldn't find free context");

	return NETDEV_TX_BUSY;

failed:
	can_free_echo_skb(netdev, context->echo_index);

	usb_unanchor_urb(urb);
	usb_free_coherent(priv->udev, size, buf, urb->transfer_dma);

	atomic_dec(&priv->active_tx_urbs);

	if (err == -ENODEV)
		netif_device_detach(netdev);
	else
		netdev_warn(netdev, "failed tx_urb %d\n", err);

nomembuf:
	usb_free_urb(urb);

nomem:
	dev_kfree_skb(skb);
	stats->tx_dropped++;

	return NETDEV_TX_OK;
}

static int usb_8dev_get_berr_counter(const struct net_device *netdev,
				     struct can_berr_counter *bec)
{
	struct usb_8dev_priv *priv = netdev_priv(netdev);

	bec->txerr = priv->bec.txerr;
	bec->rxerr = priv->bec.rxerr;

	return 0;
}

/* Start USB device */
static int usb_8dev_start(struct usb_8dev_priv *priv)
{
	struct net_device *netdev = priv->netdev;
	int err, i;

	for (i = 0; i < MAX_RX_URBS; i++) {
		struct urb *urb = NULL;
		u8 *buf;

		/* create a URB, and a buffer for it */
		urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!urb) {
			netdev_err(netdev, "No memory left for URBs\n");
			err = -ENOMEM;
			break;
		}

		buf = usb_alloc_coherent(priv->udev, RX_BUFFER_SIZE, GFP_KERNEL,
					 &urb->transfer_dma);
		if (!buf) {
			netdev_err(netdev, "No memory left for USB buffer\n");
			usb_free_urb(urb);
			err = -ENOMEM;
			break;
		}

		usb_fill_bulk_urb(urb, priv->udev,
				  usb_rcvbulkpipe(priv->udev,
						  USB_8DEV_ENDP_DATA_RX),
				  buf, RX_BUFFER_SIZE,
				  usb_8dev_read_bulk_callback, priv);
		urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
		usb_anchor_urb(urb, &priv->rx_submitted);

		err = usb_submit_urb(urb, GFP_KERNEL);
		if (err) {
			usb_unanchor_urb(urb);
			usb_free_coherent(priv->udev, RX_BUFFER_SIZE, buf,
					  urb->transfer_dma);
			usb_free_urb(urb);
			break;
		}

		/* Drop reference, USB core will take care of freeing it */
		usb_free_urb(urb);
	}

	/* Did we submit any URBs */
	if (i == 0) {
		netdev_warn(netdev, "couldn't setup read URBs\n");
		return err;
	}

	/* Warn if we've couldn't transmit all the URBs */
	if (i < MAX_RX_URBS)
		netdev_warn(netdev, "rx performance may be slow\n");

	err = usb_8dev_cmd_open(priv);
	if (err)
		goto failed;

	priv->can.state = CAN_STATE_ERROR_ACTIVE;

	return 0;

failed:
	if (err == -ENODEV)
		netif_device_detach(priv->netdev);

	netdev_warn(netdev, "couldn't submit control: %d\n", err);

	return err;
}

/* Open USB device */
static int usb_8dev_open(struct net_device *netdev)
{
	struct usb_8dev_priv *priv = netdev_priv(netdev);
	int err;

	/* common open */
	err = open_candev(netdev);
	if (err)
		return err;

	can_led_event(netdev, CAN_LED_EVENT_OPEN);

	/* finally start device */
	err = usb_8dev_start(priv);
	if (err) {
		if (err == -ENODEV)
			netif_device_detach(priv->netdev);

		netdev_warn(netdev, "couldn't start device: %d\n",
			 err);

		close_candev(netdev);

		return err;
	}

	netif_start_queue(netdev);

	return 0;
}

static void unlink_all_urbs(struct usb_8dev_priv *priv)
{
	int i;

	usb_kill_anchored_urbs(&priv->rx_submitted);

	usb_kill_anchored_urbs(&priv->tx_submitted);
	atomic_set(&priv->active_tx_urbs, 0);

	for (i = 0; i < MAX_TX_URBS; i++)
		priv->tx_contexts[i].echo_index = MAX_TX_URBS;
}

/* Close USB device */
static int usb_8dev_close(struct net_device *netdev)
{
	struct usb_8dev_priv *priv = netdev_priv(netdev);
	int err = 0;

	/* Send CLOSE command to CAN controller */
	err = usb_8dev_cmd_close(priv);
	if (err)
		netdev_warn(netdev, "couldn't stop device");

	priv->can.state = CAN_STATE_STOPPED;

	netif_stop_queue(netdev);

	/* Stop polling */
	unlink_all_urbs(priv);

	close_candev(netdev);

	can_led_event(netdev, CAN_LED_EVENT_STOP);

	return err;
}

static const struct net_device_ops usb_8dev_netdev_ops = {
	.ndo_open = usb_8dev_open,
	.ndo_stop = usb_8dev_close,
	.ndo_start_xmit = usb_8dev_start_xmit,
	.ndo_change_mtu = can_change_mtu,
};

static const struct can_bittiming_const usb_8dev_bittiming_const = {
	.name = "usb_8dev",
	.tseg1_min = 1,
	.tseg1_max = 16,
	.tseg2_min = 1,
	.tseg2_max = 8,
	.sjw_max = 4,
	.brp_min = 1,
	.brp_max = 1024,
	.brp_inc = 1,
};

/* Probe USB device
 *
 * Check device and firmware.
 * Set supported modes and bittiming constants.
 * Allocate some memory.
 */
static int usb_8dev_probe(struct usb_interface *intf,
			 const struct usb_device_id *id)
{
	struct net_device *netdev;
	struct usb_8dev_priv *priv;
	int i, err = -ENOMEM;
	u32 version;
	char buf[18];
	struct usb_device *usbdev = interface_to_usbdev(intf);

	/* product id looks strange, better we also check iProduct string */
	if (usb_string(usbdev, usbdev->descriptor.iProduct, buf,
		       sizeof(buf)) > 0 && strcmp(buf, "USB2CAN converter")) {
		dev_info(&usbdev->dev, "ignoring: not an USB2CAN converter\n");
		return -ENODEV;
	}

	netdev = alloc_candev(sizeof(struct usb_8dev_priv), MAX_TX_URBS);
	if (!netdev) {
		dev_err(&intf->dev, "Couldn't alloc candev\n");
		return -ENOMEM;
	}

	priv = netdev_priv(netdev);

	priv->udev = usbdev;
	priv->netdev = netdev;

	priv->can.state = CAN_STATE_STOPPED;
	priv->can.clock.freq = USB_8DEV_ABP_CLOCK;
	priv->can.bittiming_const = &usb_8dev_bittiming_const;
	priv->can.do_set_mode = usb_8dev_set_mode;
	priv->can.do_get_berr_counter = usb_8dev_get_berr_counter;
	priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
				      CAN_CTRLMODE_LISTENONLY |
				      CAN_CTRLMODE_ONE_SHOT;

	netdev->netdev_ops = &usb_8dev_netdev_ops;

	netdev->flags |= IFF_ECHO; /* we support local echo */

	init_usb_anchor(&priv->rx_submitted);

	init_usb_anchor(&priv->tx_submitted);
	atomic_set(&priv->active_tx_urbs, 0);

	for (i = 0; i < MAX_TX_URBS; i++)
		priv->tx_contexts[i].echo_index = MAX_TX_URBS;

	priv->cmd_msg_buffer = kzalloc(sizeof(struct usb_8dev_cmd_msg),
				      GFP_KERNEL);
	if (!priv->cmd_msg_buffer)
		goto cleanup_candev;

	usb_set_intfdata(intf, priv);

	SET_NETDEV_DEV(netdev, &intf->dev);

	mutex_init(&priv->usb_8dev_cmd_lock);

	err = register_candev(netdev);
	if (err) {
		netdev_err(netdev,
			"couldn't register CAN device: %d\n", err);
		goto cleanup_cmd_msg_buffer;
	}

	err = usb_8dev_cmd_version(priv, &version);
	if (err) {
		netdev_err(netdev, "can't get firmware version\n");
		goto cleanup_unregister_candev;
	} else {
		netdev_info(netdev,
			 "firmware: %d.%d, hardware: %d.%d\n",
			 (version>>24) & 0xff, (version>>16) & 0xff,
			 (version>>8) & 0xff, version & 0xff);
	}

	devm_can_led_init(netdev);

	return 0;

cleanup_unregister_candev:
	unregister_netdev(priv->netdev);

cleanup_cmd_msg_buffer:
	kfree(priv->cmd_msg_buffer);

cleanup_candev:
	free_candev(netdev);

	return err;

}

/* Called by the usb core when driver is unloaded or device is removed */
static void usb_8dev_disconnect(struct usb_interface *intf)
{
	struct usb_8dev_priv *priv = usb_get_intfdata(intf);

	usb_set_intfdata(intf, NULL);

	if (priv) {
		netdev_info(priv->netdev, "device disconnected\n");

		unregister_netdev(priv->netdev);
		free_candev(priv->netdev);

		unlink_all_urbs(priv);
	}

}

static struct usb_driver usb_8dev_driver = {
	.name =		"usb_8dev",
	.probe =	usb_8dev_probe,
	.disconnect =	usb_8dev_disconnect,
	.id_table =	usb_8dev_table,
};

module_usb_driver(usb_8dev_driver);

MODULE_AUTHOR("Bernd Krumboeck <*****@*****.**>");
MODULE_DESCRIPTION("CAN driver for 8 devices USB2CAN interfaces");
MODULE_LICENSE("GPL v2");
示例#25
0
/*
 * "ioctl" file op
 */
static int hiddev_ioctl(struct inode *inode, struct file *file,
			unsigned int cmd, unsigned long arg)
{
	struct hiddev_list *list = file->private_data;
	struct hiddev *hiddev = list->hiddev;
	struct hid_device *hid = hiddev->hid;
	struct usb_device *dev = hid->dev;
	struct hiddev_report_info rinfo;
	struct hiddev_usage_ref uref;
	struct hid_report *report;
	struct hid_field *field;

	if (!hiddev->exist) return -EIO;

	switch (cmd) {

	case HIDIOCGVERSION:
		return put_user(HID_VERSION, (int *) arg);

	case HIDIOCAPPLICATION:
		if (arg < 0 || arg >= hid->maxapplication)
			return -EINVAL;
		return hid->application[arg];

	case HIDIOCGDEVINFO:
	{
		struct hiddev_devinfo dinfo;
		dinfo.bustype = BUS_USB;
		dinfo.busnum = dev->bus->busnum;
		dinfo.devnum = dev->devnum;
		dinfo.ifnum = hid->ifnum;
		dinfo.vendor = dev->descriptor.idVendor;
		dinfo.product = dev->descriptor.idProduct;
		dinfo.version = dev->descriptor.bcdDevice;
		dinfo.num_applications = hid->maxapplication;
		return copy_to_user((void *) arg, &dinfo, sizeof(dinfo));
	}

	case HIDIOCGSTRING:
		{
			int idx, len;
			char *buf;

			if (get_user(idx, (int *) arg))
				return -EFAULT;

			if ((buf = kmalloc(HID_STRING_SIZE, GFP_KERNEL)) == NULL)
				return -ENOMEM;

			if ((len = usb_string(dev, idx, buf, HID_STRING_SIZE-1)) < 0) {
				kfree(buf);
				return -EINVAL;
			}

			if (copy_to_user((void *) (arg+sizeof(int)), buf, len+1)) {
				kfree(buf);
				return -EFAULT;
			}

			kfree(buf);

			return len;
		}

	case HIDIOCINITREPORT:

		hid_init_reports(hid);

		return 0;

	case HIDIOCGREPORT:
		if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
			return -EFAULT;

		if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT)
			return -EINVAL;

		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		hid_read_report(hid, report);

		return 0;

	case HIDIOCSREPORT:
		if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
			return -EFAULT;

		if (rinfo.report_type == HID_REPORT_TYPE_INPUT)
			return -EINVAL;

		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		hid_write_report(hid, report);

		return 0;

	case HIDIOCGREPORTINFO:
		if (copy_from_user(&rinfo, (void *) arg, sizeof(rinfo)))
			return -EFAULT;

		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		rinfo.num_fields = report->maxfield;

		return copy_to_user((void *) arg, &rinfo, sizeof(rinfo));

	case HIDIOCGFIELDINFO:
	{
		struct hiddev_field_info finfo;
		if (copy_from_user(&finfo, (void *) arg, sizeof(finfo)))
			return -EFAULT;
		rinfo.report_type = finfo.report_type;
		rinfo.report_id = finfo.report_id;
		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		if (finfo.field_index >= report->maxfield)
			return -EINVAL;

		field = report->field[finfo.field_index];
		memset(&finfo, 0, sizeof(finfo));
		finfo.report_type = rinfo.report_type;
		finfo.report_id = rinfo.report_id;
		finfo.field_index = field->report_count - 1;
		finfo.maxusage = field->maxusage;
		finfo.flags = field->flags;
		finfo.physical = field->physical;
		finfo.logical = field->logical;
		finfo.application = field->application;
		finfo.logical_minimum = field->logical_minimum;
		finfo.logical_maximum = field->logical_maximum;
		finfo.physical_minimum = field->physical_minimum;
		finfo.physical_maximum = field->physical_maximum;
		finfo.unit_exponent = field->unit_exponent;
		finfo.unit = field->unit;

		return copy_to_user((void *) arg, &finfo, sizeof(finfo));
	}

	case HIDIOCGUCODE:
		if (copy_from_user(&uref, (void *) arg, sizeof(uref)))
			return -EFAULT;

		rinfo.report_type = uref.report_type;
		rinfo.report_id = uref.report_id;
		if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
			return -EINVAL;

		if (uref.field_index >= report->maxfield)
			return -EINVAL;

		field = report->field[uref.field_index];
		if (uref.usage_index >= field->maxusage)
			return -EINVAL;

		uref.usage_code = field->usage[uref.usage_index].hid;

		return copy_to_user((void *) arg, &uref, sizeof(uref));

	case HIDIOCGUSAGE:
		if (copy_from_user(&uref, (void *) arg, sizeof(uref)))
			return -EFAULT;

		if (uref.report_id == HID_REPORT_ID_UNKNOWN) {
			field = hiddev_lookup_usage(hid, &uref);
			if (field == NULL)
				return -EINVAL;
		} else {
			rinfo.report_type = uref.report_type;
			rinfo.report_id = uref.report_id;
			if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
				return -EINVAL;

			if (uref.field_index >= report->maxfield)
				return -EINVAL;

			field = report->field[uref.field_index];
			if (uref.usage_index >= field->maxusage)
				return -EINVAL;
		}

		uref.value = field->value[uref.usage_index];

		return copy_to_user((void *) arg, &uref, sizeof(uref));

	case HIDIOCSUSAGE:
		if (copy_from_user(&uref, (void *) arg, sizeof(uref)))
			return -EFAULT;

		if (uref.report_type == HID_REPORT_TYPE_INPUT)
			return -EINVAL;

		if (uref.report_id == HID_REPORT_ID_UNKNOWN) {
			field = hiddev_lookup_usage(hid, &uref);
			if (field == NULL)
				return -EINVAL;
		} else {
			rinfo.report_type = uref.report_type;
			rinfo.report_id = uref.report_id;
			if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL)
				return -EINVAL;

			if (uref.field_index >= report->maxfield)
				return -EINVAL;

			field = report->field[uref.field_index];
			if (uref.usage_index >= field->maxusage)
				return -EINVAL;
		}

		field->value[uref.usage_index] = uref.value;

		return 0;

	default:

		if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ)
			return -EINVAL;

		if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) {
			int len;
			if (!hid->name) return 0;
			len = strlen(hid->name) + 1;
			if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
			return copy_to_user((char *) arg, hid->name, len) ?
				-EFAULT : len;
		}
	}
	return -EINVAL;
}