static int ds_probe()

in masters/ds2490.c [987:1068]


static int ds_probe(struct usb_interface *intf,
		    const struct usb_device_id *udev_id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct usb_endpoint_descriptor *endpoint;
	struct usb_host_interface *iface_desc;
	struct ds_device *dev;
	int i, err, alt;

	dev = kzalloc(sizeof(struct ds_device), GFP_KERNEL);
	if (!dev) {
		pr_info("Failed to allocate new DS9490R structure.\n");
		return -ENOMEM;
	}
	dev->udev = usb_get_dev(udev);
	if (!dev->udev) {
		err = -ENOMEM;
		goto err_out_free;
	}
	memset(dev->ep, 0, sizeof(dev->ep));

	usb_set_intfdata(intf, dev);

	err = usb_reset_configuration(dev->udev);
	if (err) {
		dev_err(&dev->udev->dev,
			"Failed to reset configuration: err=%d.\n", err);
		goto err_out_clear;
	}

	/* alternative 3, 1ms interrupt (greatly speeds search), 64 byte bulk */
	alt = 3;
	err = usb_set_interface(dev->udev,
		intf->cur_altsetting->desc.bInterfaceNumber, alt);
	if (err) {
		dev_err(&dev->udev->dev, "Failed to set alternative setting %d "
			"for %d interface: err=%d.\n", alt,
			intf->cur_altsetting->desc.bInterfaceNumber, err);
		goto err_out_clear;
	}

	iface_desc = intf->cur_altsetting;
	if (iface_desc->desc.bNumEndpoints != NUM_EP-1) {
		pr_info("Num endpoints=%d. It is not DS9490R.\n",
			iface_desc->desc.bNumEndpoints);
		err = -EINVAL;
		goto err_out_clear;
	}

	/*
	 * This loop doesn'd show control 0 endpoint,
	 * so we will fill only 1-3 endpoints entry.
	 */
	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;

		dev->ep[i+1] = endpoint->bEndpointAddress;
#if 0
		printk("%d: addr=%x, size=%d, dir=%s, type=%x\n",
			i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize),
			(endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT",
			endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
#endif
	}

	err = ds_w1_init(dev);
	if (err)
		goto err_out_clear;

	mutex_lock(&ds_mutex);
	list_add_tail(&dev->ds_entry, &ds_devices);
	mutex_unlock(&ds_mutex);

	return 0;

err_out_clear:
	usb_set_intfdata(intf, NULL);
	usb_put_dev(dev->udev);
err_out_free:
	kfree(dev);
	return err;
}