static struct hid_device *usb_hid_configure(struct usb_interface *intf){	struct usb_host_interface *interface = intf->cur_altsetting;	struct usb_device *dev = interface_to_usbdev (intf);	struct hid_descriptor *hdesc;	struct hid_device *hid;	unsigned quirks = 0, rsize = 0;	char *buf, *rdesc;	int n;	for (n = 0; hid_blacklist[n].idVendor; n++)		if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) &&			(hid_blacklist[n].idProduct == le16_to_cpu(dev->descriptor.idProduct)))				quirks = hid_blacklist[n].quirks;	if (quirks & HID_QUIRK_IGNORE)		return NULL;	if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) ||		usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {			dbg("class descriptor not present\n");			return NULL;	}	for (n = 0; n < hdesc->bNumDescriptors; n++)		if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)			rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);	if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {		dbg("weird size of report descriptor (%u)", rsize);		return NULL;	}	if (!(rdesc = kmalloc(rsize, GFP_KERNEL))) {		dbg("couldn't allocate rdesc memory");		return NULL;	}	hid_set_idle(dev, interface->desc.bInterfaceNumber, 0, 0);	if ((n = hid_get_class_descriptor(dev, interface->desc.bInterfaceNumber, HID_DT_REPORT, rdesc, rsize)) < 0) {		dbg("reading report descriptor failed");		kfree(rdesc);		return NULL;	}#ifdef DEBUG_DATA	printk(KERN_DEBUG __FILE__ ": report descriptor (size %u, read %d) = ", rsize, n);	for (n = 0; n < rsize; n++)		printk(" %02x", (unsigned char) rdesc[n]);	printk("\n");#endif	if (!(hid = hid_parse_report(rdesc, n))) {		dbg("parsing report descriptor failed");		kfree(rdesc);		return NULL;	}	kfree(rdesc);	hid->quirks = quirks;	if (hid_alloc_buffers(dev, hid)) {		hid_free_buffers(dev, hid);		goto fail;	}	for (n = 0; n < interface->desc.bNumEndpoints; n++) {		struct usb_endpoint_descriptor *endpoint;		int pipe;		int interval;		endpoint = &interface->endpoint[n].desc;		if ((endpoint->bmAttributes & 3) != 3)		/* Not an interrupt endpoint */			continue;		/* handle potential highspeed HID correctly */		interval = endpoint->bInterval;		if (dev->speed == USB_SPEED_HIGH)			interval = 1 << (interval - 1);		/* Change the polling interval of mice. */		if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)			interval = hid_mousepoll_interval;				if (endpoint->bEndpointAddress & USB_DIR_IN) {			if (hid->urbin)				continue;			if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL)))				goto fail;			pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);			usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0,					 hid_irq_in, hid, interval);			hid->urbin->transfer_dma = hid->inbuf_dma;			hid->urbin->transfer_flags |=(URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK);		} else {			if (hid->urbout)				continue;			if (!(hid->urbout = usb_alloc_urb(0, GFP_KERNEL)))				goto fail;			pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress);			usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0,					 hid_irq_out, hid, interval);			hid->urbout->transfer_dma = hid->outbuf_dma;			hid->urbout->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_ASYNC_UNLINK);		}	}	if (!hid->urbin) {		err("couldn't find an input interrupt endpoint");		goto fail;	}	init_waitqueue_head(&hid->wait);	spin_lock_init(&hid->outlock);	spin_lock_init(&hid->ctrllock);	hid->version = le16_to_cpu(hdesc->bcdHID);	hid->country = hdesc->bCountryCode;	hid->dev = dev;	hid->intf = intf;	hid->ifnum = interface->desc.bInterfaceNumber;	hid->name[0] = 0;	if (!(buf = kmalloc(64, GFP_KERNEL)))		goto fail;	if (dev->manufacturer) {		strcat(hid->name, dev->manufacturer);		if (dev->product)			snprintf(hid->name, 64, "%s %s", hid->name, dev->product);	} else if (dev->product) {			snprintf(hid->name, 128, "%s", dev->product);	} else		snprintf(hid->name, 128, "%04x:%04x",			le16_to_cpu(dev->descriptor.idVendor),			le16_to_cpu(dev->descriptor.idProduct));	usb_make_path(dev, buf, 64);	snprintf(hid->phys, 64, "%s/input%d", buf,			intf->altsetting[0].desc.bInterfaceNumber);	if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)		hid->uniq[0] = 0;	kfree(buf);	hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);	if (!hid->urbctrl)		goto fail;	usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr,			     hid->ctrlbuf, 1, hid_ctrl, hid);	hid->urbctrl->setup_dma = hid->cr_dma;	hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;	hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | URB_ASYNC_UNLINK);	return hid;fail:	if (hid->urbin)		usb_free_urb(hid->urbin);	if (hid->urbout)		usb_free_urb(hid->urbout);	if (hid->urbctrl)		usb_free_urb(hid->urbctrl);	hid_free_buffers(dev, hid);	hid_free_device(hid);	return NULL;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/05f091ab4c8c1f12f8dd38ee789489904fea327d/hid-core.c/clean/drivers/usb/input/hid-core.c