module_put(type->owner); 
module_put(type->driver.owner); 
int usb_serial_probe(struct usb_interface *interface,			       const struct usb_device_id *id){	struct usb_device *dev = interface_to_usbdev (interface);	struct usb_serial *serial = NULL;	struct usb_serial_port *port;	struct usb_host_interface *iface_desc;	struct usb_endpoint_descriptor *endpoint;	struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];	struct usb_endpoint_descriptor *interrupt_out_endpoint[MAX_NUM_PORTS];	struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];	struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];	struct usb_serial_driver *type = NULL;	int retval;	int minor;	int buffer_size;	int i;	int num_interrupt_in = 0;	int num_interrupt_out = 0;	int num_bulk_in = 0;	int num_bulk_out = 0;	int num_ports = 0;	int max_endpoints;	type = search_serial_device(interface);	if (!type) {		dbg("none matched");		return -ENODEV;	}	serial = create_serial (dev, interface, type);	if (!serial) {		dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__);		return -ENOMEM;	}	/* if this device type has a probe function, call it */	if (type->probe) {		const struct usb_device_id *id;		if (!try_module_get(type->owner)) {			dev_err(&interface->dev, "module get failed, exiting\n");			kfree (serial);			return -EIO;		}		id = usb_match_id(interface, type->id_table);		retval = type->probe(serial, id);		module_put(type->owner);		if (retval) {			dbg ("sub driver rejected device");			kfree (serial);			return retval;		}	}	/* descriptor matches, let's find the endpoints needed */	/* check out the endpoints */	iface_desc = interface->cur_altsetting;	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {		endpoint = &iface_desc->endpoint[i].desc;				if ((endpoint->bEndpointAddress & 0x80) &&		    ((endpoint->bmAttributes & 3) == 0x02)) {			/* we found a bulk in endpoint */			dbg("found bulk in on endpoint %d", i);			bulk_in_endpoint[num_bulk_in] = endpoint;			++num_bulk_in;		}		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&		    ((endpoint->bmAttributes & 3) == 0x02)) {			/* we found a bulk out endpoint */			dbg("found bulk out on endpoint %d", i);			bulk_out_endpoint[num_bulk_out] = endpoint;			++num_bulk_out;		}				if ((endpoint->bEndpointAddress & 0x80) &&		    ((endpoint->bmAttributes & 3) == 0x03)) {			/* we found a interrupt in endpoint */			dbg("found interrupt in on endpoint %d", i);			interrupt_in_endpoint[num_interrupt_in] = endpoint;			++num_interrupt_in;		}		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&		    ((endpoint->bmAttributes & 3) == 0x03)) {			/* we found an interrupt out endpoint */			dbg("found interrupt out on endpoint %d", i);			interrupt_out_endpoint[num_interrupt_out] = endpoint;			++num_interrupt_out;		}	}#if defined(CONFIG_USB_SERIAL_PL2303) || defined(CONFIG_USB_SERIAL_PL2303_MODULE)	/* BEGIN HORRIBLE HACK FOR PL2303 */ 	/* this is needed due to the looney way its endpoints are set up */	if (((le16_to_cpu(dev->descriptor.idVendor) == PL2303_VENDOR_ID) &&	     (le16_to_cpu(dev->descriptor.idProduct) == PL2303_PRODUCT_ID)) ||	    ((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) &&	     (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID))) {		if (interface != dev->actconfig->interface[0]) {			/* check out the endpoints of the other interface*/			iface_desc = dev->actconfig->interface[0]->cur_altsetting;			for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {				endpoint = &iface_desc->endpoint[i].desc;				if ((endpoint->bEndpointAddress & 0x80) &&				    ((endpoint->bmAttributes & 3) == 0x03)) {					/* we found a interrupt in endpoint */					dbg("found interrupt in for Prolific device on separate interface");					interrupt_in_endpoint[num_interrupt_in] = endpoint;					++num_interrupt_in;				}			}		}		/* Now make sure the PL-2303 is configured correctly.		 * If not, give up now and hope this hack will work		 * properly during a later invocation of usb_serial_probe		 */		if (num_bulk_in == 0 || num_bulk_out == 0) {			dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n");			kfree (serial);			return -ENODEV;		}	}	/* END HORRIBLE HACK FOR PL2303 */#endif	/* found all that we need */	dev_info(&interface->dev, "%s converter detected\n", type->name);#ifdef CONFIG_USB_SERIAL_GENERIC	if (type == &usb_serial_generic_device) {		num_ports = num_bulk_out;		if (num_ports == 0) {			dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n");			kfree (serial);			return -EIO;		}	}#endif	if (!num_ports) {		/* if this device type has a calc_num_ports function, call it */		if (type->calc_num_ports) {			if (!try_module_get(type->owner)) {				dev_err(&interface->dev, "module get failed, exiting\n");				kfree (serial);				return -EIO;			}			num_ports = type->calc_num_ports (serial);			module_put(type->owner);		}		if (!num_ports)			num_ports = type->num_ports;	}	if (get_free_serial (serial, num_ports, &minor) == NULL) {		dev_err(&interface->dev, "No more free serial devices\n");		kfree (serial);		return -ENOMEM;	}	serial->minor = minor;	serial->num_ports = num_ports;	serial->num_bulk_in = num_bulk_in;	serial->num_bulk_out = num_bulk_out;	serial->num_interrupt_in = num_interrupt_in;	serial->num_interrupt_out = num_interrupt_out;	/* create our ports, we need as many as the max endpoints */	/* we don't use num_ports here cauz some devices have more endpoint pairs than ports */	max_endpoints = max(num_bulk_in, num_bulk_out);	max_endpoints = max(max_endpoints, num_interrupt_in);	max_endpoints = max(max_endpoints, num_interrupt_out);	max_endpoints = max(max_endpoints, (int)serial->num_ports);	serial->num_port_pointers = max_endpoints;	dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints);	for (i = 0; i < max_endpoints; ++i) {		port = kmalloc(sizeof(struct usb_serial_port), GFP_KERNEL);		if (!port)			goto probe_error;		memset(port, 0x00, sizeof(struct usb_serial_port));		port->number = i + serial->minor;		port->serial = serial;		spin_lock_init(&port->lock);		INIT_WORK(&port->work, usb_serial_port_softint, port);		serial->port[i] = port;	}	/* set up the endpoint information */	for (i = 0; i < num_bulk_in; ++i) {		endpoint = bulk_in_endpoint[i];		port = serial->port[i];		port->read_urb = usb_alloc_urb (0, GFP_KERNEL);		if (!port->read_urb) {			dev_err(&interface->dev, "No free urbs available\n");			goto probe_error;		}		buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);		port->bulk_in_size = buffer_size;		port->bulk_in_endpointAddress = endpoint->bEndpointAddress;		port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);		if (!port->bulk_in_buffer) {			dev_err(&interface->dev, "Couldn't allocate bulk_in_buffer\n");			goto probe_error;		}		usb_fill_bulk_urb (port->read_urb, dev,				   usb_rcvbulkpipe (dev,					   	    endpoint->bEndpointAddress),				   port->bulk_in_buffer, buffer_size,				   serial->type->read_bulk_callback,				   port);	}	for (i = 0; i < num_bulk_out; ++i) {		endpoint = bulk_out_endpoint[i];		port = serial->port[i];		port->write_urb = usb_alloc_urb(0, GFP_KERNEL);		if (!port->write_urb) {			dev_err(&interface->dev, "No free urbs available\n");			goto probe_error;		}		buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);		port->bulk_out_size = buffer_size;		port->bulk_out_endpointAddress = endpoint->bEndpointAddress;		port->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);		if (!port->bulk_out_buffer) {			dev_err(&interface->dev, "Couldn't allocate bulk_out_buffer\n");			goto probe_error;		}		usb_fill_bulk_urb (port->write_urb, dev,				   usb_sndbulkpipe (dev,						    endpoint->bEndpointAddress),				   port->bulk_out_buffer, buffer_size, 				   serial->type->write_bulk_callback,				   port);	}	if (serial->type->read_int_callback) {		for (i = 0; i < num_interrupt_in; ++i) {			endpoint = interrupt_in_endpoint[i];			port = serial->port[i];			port->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL);			if (!port->interrupt_in_urb) {				dev_err(&interface->dev, "No free urbs available\n");				goto probe_error;			}			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);			port->interrupt_in_endpointAddress = endpoint->bEndpointAddress;			port->interrupt_in_buffer = kmalloc (buffer_size, GFP_KERNEL);			if (!port->interrupt_in_buffer) {				dev_err(&interface->dev, "Couldn't allocate interrupt_in_buffer\n");				goto probe_error;			}			usb_fill_int_urb (port->interrupt_in_urb, dev, 					  usb_rcvintpipe (dev,							  endpoint->bEndpointAddress),					  port->interrupt_in_buffer, buffer_size, 					  serial->type->read_int_callback, port, 					  endpoint->bInterval);		}	} else if (num_interrupt_in) {		dbg("the device claims to support interrupt in transfers, but read_int_callback is not defined");	}		if (serial->type->write_int_callback) {		for (i = 0; i < num_interrupt_out; ++i) {			endpoint = interrupt_out_endpoint[i];			port = serial->port[i];			port->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL);			if (!port->interrupt_out_urb) {				dev_err(&interface->dev, "No free urbs available\n");				goto probe_error;			}			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);			port->interrupt_out_size = buffer_size;			port->interrupt_out_endpointAddress = endpoint->bEndpointAddress;			port->interrupt_out_buffer = kmalloc (buffer_size, GFP_KERNEL);			if (!port->interrupt_out_buffer) {				dev_err(&interface->dev, "Couldn't allocate interrupt_out_buffer\n");				goto probe_error;			}			usb_fill_int_urb (port->interrupt_out_urb, dev,					  usb_sndintpipe (dev,							  endpoint->bEndpointAddress),					  port->interrupt_out_buffer, buffer_size,					  serial->type->write_int_callback, port,					  endpoint->bInterval);		}	} else if (num_interrupt_out) {		dbg("the device claims to support interrupt out transfers, but write_int_callback is not defined");	}		/* if this device type has an attach function, call it */	if (type->attach) {		if (!try_module_get(type->owner)) {			dev_err(&interface->dev, "module get failed, exiting\n");			goto probe_error;		}		retval = type->attach (serial);		module_put(type->owner);		if (retval < 0)			goto probe_error;		if (retval > 0) {			/* quietly accept this device, but don't bind to a serial port			 * as it's about to disappear */			goto exit;		}	}	/* register all of the individual ports with the driver core */	for (i = 0; i < num_ports; ++i) {		port = serial->port[i];		port->dev.parent = &interface->dev;		port->dev.driver = NULL;		port->dev.bus = &usb_serial_bus_type;		port->dev.release = &port_release;		snprintf (&port->dev.bus_id[0], sizeof(port->dev.bus_id), "ttyUSB%d", port->number);		dbg ("%s - registering %s", __FUNCTION__, port->dev.bus_id);		device_register (&port->dev);	}	usb_serial_console_init (debug, minor);exit:	/* success */	usb_set_intfdata (interface, serial);	return 0;probe_error:	for (i = 0; i < num_bulk_in; ++i) {		port = serial->port[i];		if (!port)			continue;		if (port->read_urb)			usb_free_urb (port->read_urb);		kfree(port->bulk_in_buffer);	}	for (i = 0; i < num_bulk_out; ++i) {		port = serial->port[i];		if (!port)			continue;		if (port->write_urb)			usb_free_urb (port->write_urb);		kfree(port->bulk_out_buffer);	}	for (i = 0; i < num_interrupt_in; ++i) {		port = serial->port[i];		if (!port)			continue;		if (port->interrupt_in_urb)			usb_free_urb (port->interrupt_in_urb);		kfree(port->interrupt_in_buffer);	}	for (i = 0; i < num_interrupt_out; ++i) {		port = serial->port[i];		if (!port)			continue;		if (port->interrupt_out_urb)			usb_free_urb (port->interrupt_out_urb);		kfree(port->interrupt_out_buffer);	}	/* return the minor range that this device had */	return_serial (serial);	/* free up any memory that we allocated */	for (i = 0; i < serial->num_port_pointers; ++i)		kfree(serial->port[i]);	kfree (serial);	return -EIO;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/18fcac353fdc7cd072b0d24c8667042e675a4c11/usb-serial.c/buggy/drivers/usb/serial/usb-serial.c