diff options
Diffstat (limited to 'drivers/usb')
107 files changed, 869 insertions, 2341 deletions
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 75eca764522..53a7bc07dd8 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -6,6 +6,8 @@  obj-$(CONFIG_USB)		+= core/ +obj-$(CONFIG_USB_OTG_UTILS)	+= otg/ +  obj-$(CONFIG_USB_DWC3)		+= dwc3/  obj-$(CONFIG_USB_MON)		+= mon/ @@ -51,7 +53,6 @@ obj-$(CONFIG_USB_SPEEDTOUCH)	+= atm/  obj-$(CONFIG_USB_MUSB_HDRC)	+= musb/  obj-$(CONFIG_USB_RENESAS_USBHS)	+= renesas_usbhs/ -obj-$(CONFIG_USB_OTG_UTILS)	+= otg/  obj-$(CONFIG_USB_GADGET)	+= gadget/  obj-$(CONFIG_USB_COMMON)	+= usb-common.o diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c index 57ae44cd0b8..6f3b6e26739 100644 --- a/drivers/usb/c67x00/c67x00-drv.c +++ b/drivers/usb/c67x00/c67x00-drv.c @@ -225,21 +225,10 @@ static struct platform_driver c67x00_driver = {  		.name = "c67x00",  	},  }; -MODULE_ALIAS("platform:c67x00"); - -static int __init c67x00_init(void) -{ -	return platform_driver_register(&c67x00_driver); -} -static void __exit c67x00_exit(void) -{ -	platform_driver_unregister(&c67x00_driver); -} - -module_init(c67x00_init); -module_exit(c67x00_exit); +module_platform_driver(c67x00_driver);  MODULE_AUTHOR("Peter Korsgaard, Jan Veldeman, Grant Likely");  MODULE_DESCRIPTION("Cypress C67X00 USB Controller Driver");  MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:c67x00"); diff --git a/drivers/usb/c67x00/c67x00-hcd.c b/drivers/usb/c67x00/c67x00-hcd.c index d3e1356d091..75e47b860a5 100644 --- a/drivers/usb/c67x00/c67x00-hcd.c +++ b/drivers/usb/c67x00/c67x00-hcd.c @@ -271,7 +271,6 @@ static void c67x00_hcd_irq(struct c67x00_sie *sie, u16 int_status, u16 msg)  	if (int_status & SOFEOP_FLG(sie->sie_num)) {  		c67x00_ll_usb_clear_status(sie, SOF_EOP_IRQ_FLG);  		c67x00_sched_kick(c67x00); -		set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);  	}  } diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index e8c564a5334..d9d9340abe6 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -58,12 +58,62 @@ static struct usb_driver acm_driver;  static struct tty_driver *acm_tty_driver;  static struct acm *acm_table[ACM_TTY_MINORS]; -static DEFINE_MUTEX(open_mutex); +static DEFINE_MUTEX(acm_table_lock); -#define ACM_READY(acm)	(acm && acm->dev && acm->port.count) +/* + * acm_table accessors + */ -static const struct tty_port_operations acm_port_ops = { -}; +/* + * Look up an ACM structure by index. If found and not disconnected, increment + * its refcount and return it with its mutex held. + */ +static struct acm *acm_get_by_index(unsigned index) +{ +	struct acm *acm; + +	mutex_lock(&acm_table_lock); +	acm = acm_table[index]; +	if (acm) { +		mutex_lock(&acm->mutex); +		if (acm->disconnected) { +			mutex_unlock(&acm->mutex); +			acm = NULL; +		} else { +			tty_port_get(&acm->port); +			mutex_unlock(&acm->mutex); +		} +	} +	mutex_unlock(&acm_table_lock); +	return acm; +} + +/* + * Try to find an available minor number and if found, associate it with 'acm'. + */ +static int acm_alloc_minor(struct acm *acm) +{ +	int minor; + +	mutex_lock(&acm_table_lock); +	for (minor = 0; minor < ACM_TTY_MINORS; minor++) { +		if (!acm_table[minor]) { +			acm_table[minor] = acm; +			break; +		} +	} +	mutex_unlock(&acm_table_lock); + +	return minor; +} + +/* Release the minor number associated with 'acm'.  */ +static void acm_release_minor(struct acm *acm) +{ +	mutex_lock(&acm_table_lock); +	acm_table[acm->minor] = NULL; +	mutex_unlock(&acm_table_lock); +}  /*   * Functions for ACM control messages. @@ -267,9 +317,6 @@ static void acm_ctrl_irq(struct urb *urb)  		goto exit;  	} -	if (!ACM_READY(acm)) -		goto exit; -  	usb_mark_last_busy(acm->dev);  	data = (unsigned char *)(dr + 1); @@ -429,8 +476,7 @@ static void acm_write_bulk(struct urb *urb)  	spin_lock_irqsave(&acm->write_lock, flags);  	acm_write_done(acm, wb);  	spin_unlock_irqrestore(&acm->write_lock, flags); -	if (ACM_READY(acm)) -		schedule_work(&acm->work); +	schedule_work(&acm->work);  }  static void acm_softint(struct work_struct *work) @@ -440,8 +486,6 @@ static void acm_softint(struct work_struct *work)  	dev_vdbg(&acm->data->dev, "%s\n", __func__); -	if (!ACM_READY(acm)) -		return;  	tty = tty_port_tty_get(&acm->port);  	if (!tty)  		return; @@ -453,93 +497,122 @@ static void acm_softint(struct work_struct *work)   * TTY handlers   */ -static int acm_tty_open(struct tty_struct *tty, struct file *filp) +static int acm_tty_install(struct tty_driver *driver, struct tty_struct *tty)  {  	struct acm *acm; -	int rv = -ENODEV; - -	mutex_lock(&open_mutex); +	int retval; -	acm = acm_table[tty->index]; -	if (!acm || !acm->dev) -		goto out; -	else -		rv = 0; +	dev_dbg(tty->dev, "%s\n", __func__); -	dev_dbg(&acm->control->dev, "%s\n", __func__); +	acm = acm_get_by_index(tty->index); +	if (!acm) +		return -ENODEV; -	set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); +	retval = tty_init_termios(tty); +	if (retval) +		goto error_init_termios;  	tty->driver_data = acm; -	tty_port_tty_set(&acm->port, tty); -	if (usb_autopm_get_interface(acm->control) < 0) -		goto early_bail; -	else -		acm->control->needs_remote_wakeup = 1; +	/* Final install (we use the default method) */ +	tty_driver_kref_get(driver); +	tty->count++; +	driver->ttys[tty->index] = tty; + +	return 0; + +error_init_termios: +	tty_port_put(&acm->port); +	return retval; +} + +static int acm_tty_open(struct tty_struct *tty, struct file *filp) +{ +	struct acm *acm = tty->driver_data; + +	dev_dbg(tty->dev, "%s\n", __func__); + +	return tty_port_open(&acm->port, tty, filp); +} + +static int acm_port_activate(struct tty_port *port, struct tty_struct *tty) +{ +	struct acm *acm = container_of(port, struct acm, port); +	int retval = -ENODEV; + +	dev_dbg(&acm->control->dev, "%s\n", __func__);  	mutex_lock(&acm->mutex); -	if (acm->port.count++) { -		mutex_unlock(&acm->mutex); -		usb_autopm_put_interface(acm->control); -		goto out; -	} +	if (acm->disconnected) +		goto disconnected; + +	retval = usb_autopm_get_interface(acm->control); +	if (retval) +		goto error_get_interface; + +	/* +	 * FIXME: Why do we need this? Allocating 64K of physically contiguous +	 * memory is really nasty... +	 */ +	set_bit(TTY_NO_WRITE_SPLIT, &tty->flags); +	acm->control->needs_remote_wakeup = 1;  	acm->ctrlurb->dev = acm->dev;  	if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) {  		dev_err(&acm->control->dev,  			"%s - usb_submit_urb(ctrl irq) failed\n", __func__); -		goto bail_out; +		goto error_submit_urb;  	} -	if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) && +	acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS; +	if (acm_set_control(acm, acm->ctrlout) < 0 &&  	    (acm->ctrl_caps & USB_CDC_CAP_LINE)) -		goto bail_out; +		goto error_set_control;  	usb_autopm_put_interface(acm->control);  	if (acm_submit_read_urbs(acm, GFP_KERNEL)) -		goto bail_out; - -	set_bit(ASYNCB_INITIALIZED, &acm->port.flags); -	rv = tty_port_block_til_ready(&acm->port, tty, filp); +		goto error_submit_read_urbs;  	mutex_unlock(&acm->mutex); -out: -	mutex_unlock(&open_mutex); -	return rv; -bail_out: -	acm->port.count--; -	mutex_unlock(&acm->mutex); +	return 0; + +error_submit_read_urbs: +	acm->ctrlout = 0; +	acm_set_control(acm, acm->ctrlout); +error_set_control: +	usb_kill_urb(acm->ctrlurb); +error_submit_urb:  	usb_autopm_put_interface(acm->control); -early_bail: -	mutex_unlock(&open_mutex); -	tty_port_tty_set(&acm->port, NULL); -	return -EIO; +error_get_interface: +disconnected: +	mutex_unlock(&acm->mutex); +	return retval;  } -static void acm_tty_unregister(struct acm *acm) +static void acm_port_destruct(struct tty_port *port)  { -	int i; +	struct acm *acm = container_of(port, struct acm, port); + +	dev_dbg(&acm->control->dev, "%s\n", __func__);  	tty_unregister_device(acm_tty_driver, acm->minor); +	acm_release_minor(acm);  	usb_put_intf(acm->control); -	acm_table[acm->minor] = NULL; -	usb_free_urb(acm->ctrlurb); -	for (i = 0; i < ACM_NW; i++) -		usb_free_urb(acm->wb[i].urb); -	for (i = 0; i < acm->rx_buflimit; i++) -		usb_free_urb(acm->read_urbs[i]);  	kfree(acm->country_codes);  	kfree(acm);  } -static void acm_port_down(struct acm *acm) +static void acm_port_shutdown(struct tty_port *port)  { +	struct acm *acm = container_of(port, struct acm, port);  	int i; -	if (acm->dev) { +	dev_dbg(&acm->control->dev, "%s\n", __func__); + +	mutex_lock(&acm->mutex); +	if (!acm->disconnected) {  		usb_autopm_get_interface(acm->control);  		acm_set_control(acm, acm->ctrlout = 0);  		usb_kill_urb(acm->ctrlurb); @@ -550,40 +623,28 @@ static void acm_port_down(struct acm *acm)  		acm->control->needs_remote_wakeup = 0;  		usb_autopm_put_interface(acm->control);  	} +	mutex_unlock(&acm->mutex); +} + +static void acm_tty_cleanup(struct tty_struct *tty) +{ +	struct acm *acm = tty->driver_data; +	dev_dbg(&acm->control->dev, "%s\n", __func__); +	tty_port_put(&acm->port);  }  static void acm_tty_hangup(struct tty_struct *tty)  {  	struct acm *acm = tty->driver_data; +	dev_dbg(&acm->control->dev, "%s\n", __func__);  	tty_port_hangup(&acm->port); -	mutex_lock(&open_mutex); -	acm_port_down(acm); -	mutex_unlock(&open_mutex);  }  static void acm_tty_close(struct tty_struct *tty, struct file *filp)  {  	struct acm *acm = tty->driver_data; - -	/* Perform the closing process and see if we need to do the hardware -	   shutdown */ -	if (!acm) -		return; - -	mutex_lock(&open_mutex); -	if (tty_port_close_start(&acm->port, tty, filp) == 0) { -		if (!acm->dev) { -			tty_port_tty_set(&acm->port, NULL); -			acm_tty_unregister(acm); -			tty->driver_data = NULL; -		} -		mutex_unlock(&open_mutex); -		return; -	} -	acm_port_down(acm); -	tty_port_close_end(&acm->port, tty); -	tty_port_tty_set(&acm->port, NULL); -	mutex_unlock(&open_mutex); +	dev_dbg(&acm->control->dev, "%s\n", __func__); +	tty_port_close(&acm->port, tty, filp);  }  static int acm_tty_write(struct tty_struct *tty, @@ -595,8 +656,6 @@ static int acm_tty_write(struct tty_struct *tty,  	int wbn;  	struct acm_wb *wb; -	if (!ACM_READY(acm)) -		return -EINVAL;  	if (!count)  		return 0; @@ -625,8 +684,6 @@ static int acm_tty_write(struct tty_struct *tty,  static int acm_tty_write_room(struct tty_struct *tty)  {  	struct acm *acm = tty->driver_data; -	if (!ACM_READY(acm)) -		return -EINVAL;  	/*  	 * Do not let the line discipline to know that we have a reserve,  	 * or it might get too enthusiastic. @@ -637,7 +694,11 @@ static int acm_tty_write_room(struct tty_struct *tty)  static int acm_tty_chars_in_buffer(struct tty_struct *tty)  {  	struct acm *acm = tty->driver_data; -	if (!ACM_READY(acm)) +	/* +	 * if the device was unplugged then any remaining characters fell out +	 * of the connector ;) +	 */ +	if (acm->disconnected)  		return 0;  	/*  	 * This is inaccurate (overcounts), but it works. @@ -649,9 +710,6 @@ static void acm_tty_throttle(struct tty_struct *tty)  {  	struct acm *acm = tty->driver_data; -	if (!ACM_READY(acm)) -		return; -  	spin_lock_irq(&acm->read_lock);  	acm->throttle_req = 1;  	spin_unlock_irq(&acm->read_lock); @@ -662,9 +720,6 @@ static void acm_tty_unthrottle(struct tty_struct *tty)  	struct acm *acm = tty->driver_data;  	unsigned int was_throttled; -	if (!ACM_READY(acm)) -		return; -  	spin_lock_irq(&acm->read_lock);  	was_throttled = acm->throttled;  	acm->throttled = 0; @@ -679,8 +734,7 @@ static int acm_tty_break_ctl(struct tty_struct *tty, int state)  {  	struct acm *acm = tty->driver_data;  	int retval; -	if (!ACM_READY(acm)) -		return -EINVAL; +  	retval = acm_send_break(acm, state ? 0xffff : 0);  	if (retval < 0)  		dev_dbg(&acm->control->dev, "%s - send break failed\n", @@ -692,9 +746,6 @@ static int acm_tty_tiocmget(struct tty_struct *tty)  {  	struct acm *acm = tty->driver_data; -	if (!ACM_READY(acm)) -		return -EINVAL; -  	return (acm->ctrlout & ACM_CTRL_DTR ? TIOCM_DTR : 0) |  	       (acm->ctrlout & ACM_CTRL_RTS ? TIOCM_RTS : 0) |  	       (acm->ctrlin  & ACM_CTRL_DSR ? TIOCM_DSR : 0) | @@ -709,9 +760,6 @@ static int acm_tty_tiocmset(struct tty_struct *tty,  	struct acm *acm = tty->driver_data;  	unsigned int newctrl; -	if (!ACM_READY(acm)) -		return -EINVAL; -  	newctrl = acm->ctrlout;  	set = (set & TIOCM_DTR ? ACM_CTRL_DTR : 0) |  					(set & TIOCM_RTS ? ACM_CTRL_RTS : 0); @@ -728,11 +776,6 @@ static int acm_tty_tiocmset(struct tty_struct *tty,  static int acm_tty_ioctl(struct tty_struct *tty,  					unsigned int cmd, unsigned long arg)  { -	struct acm *acm = tty->driver_data; - -	if (!ACM_READY(acm)) -		return -EINVAL; -  	return -ENOIOCTLCMD;  } @@ -756,9 +799,6 @@ static void acm_tty_set_termios(struct tty_struct *tty,  	struct usb_cdc_line_coding newline;  	int newctrl = acm->ctrlout; -	if (!ACM_READY(acm)) -		return; -  	newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty));  	newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0;  	newline.bParityType = termios->c_cflag & PARENB ? @@ -788,6 +828,12 @@ static void acm_tty_set_termios(struct tty_struct *tty,  	}  } +static const struct tty_port_operations acm_port_ops = { +	.shutdown = acm_port_shutdown, +	.activate = acm_port_activate, +	.destruct = acm_port_destruct, +}; +  /*   * USB probe and disconnect routines.   */ @@ -1047,12 +1093,6 @@ skip_normal_probe:  	}  made_compressed_probe:  	dev_dbg(&intf->dev, "interfaces are valid\n"); -	for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++); - -	if (minor == ACM_TTY_MINORS) { -		dev_err(&intf->dev, "no more free acm devices\n"); -		return -ENODEV; -	}  	acm = kzalloc(sizeof(struct acm), GFP_KERNEL);  	if (acm == NULL) { @@ -1060,6 +1100,13 @@ made_compressed_probe:  		goto alloc_fail;  	} +	minor = acm_alloc_minor(acm); +	if (minor == ACM_TTY_MINORS) { +		dev_err(&intf->dev, "no more free acm devices\n"); +		kfree(acm); +		return -ENODEV; +	} +  	ctrlsize = usb_endpoint_maxp(epctrl);  	readsize = usb_endpoint_maxp(epread) *  				(quirks == SINGLE_RX_URB ? 1 : 2); @@ -1218,8 +1265,6 @@ skip_countries:  	usb_get_intf(control_interface);  	tty_register_device(acm_tty_driver, minor, &control_interface->dev); -	acm_table[minor] = acm; -  	return 0;  alloc_fail7:  	for (i = 0; i < ACM_NW; i++) @@ -1234,6 +1279,7 @@ alloc_fail5:  alloc_fail4:  	usb_free_coherent(usb_dev, ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);  alloc_fail2: +	acm_release_minor(acm);  	kfree(acm);  alloc_fail:  	return -ENOMEM; @@ -1259,12 +1305,16 @@ static void acm_disconnect(struct usb_interface *intf)  	struct acm *acm = usb_get_intfdata(intf);  	struct usb_device *usb_dev = interface_to_usbdev(intf);  	struct tty_struct *tty; +	int i; + +	dev_dbg(&intf->dev, "%s\n", __func__);  	/* sibling interface is already cleaning up */  	if (!acm)  		return; -	mutex_lock(&open_mutex); +	mutex_lock(&acm->mutex); +	acm->disconnected = true;  	if (acm->country_codes) {  		device_remove_file(&acm->control->dev,  				&dev_attr_wCountryCodes); @@ -1272,33 +1322,32 @@ static void acm_disconnect(struct usb_interface *intf)  				&dev_attr_iCountryCodeRelDate);  	}  	device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); -	acm->dev = NULL;  	usb_set_intfdata(acm->control, NULL);  	usb_set_intfdata(acm->data, NULL); +	mutex_unlock(&acm->mutex); + +	tty = tty_port_tty_get(&acm->port); +	if (tty) { +		tty_vhangup(tty); +		tty_kref_put(tty); +	}  	stop_data_traffic(acm); +	usb_free_urb(acm->ctrlurb); +	for (i = 0; i < ACM_NW; i++) +		usb_free_urb(acm->wb[i].urb); +	for (i = 0; i < acm->rx_buflimit; i++) +		usb_free_urb(acm->read_urbs[i]);  	acm_write_buffers_free(acm); -	usb_free_coherent(usb_dev, acm->ctrlsize, acm->ctrl_buffer, -			  acm->ctrl_dma); +	usb_free_coherent(usb_dev, acm->ctrlsize, acm->ctrl_buffer, acm->ctrl_dma);  	acm_read_buffers_free(acm);  	if (!acm->combined_interfaces)  		usb_driver_release_interface(&acm_driver, intf == acm->control ?  					acm->data : acm->control); -	if (acm->port.count == 0) { -		acm_tty_unregister(acm); -		mutex_unlock(&open_mutex); -		return; -	} - -	mutex_unlock(&open_mutex); -	tty = tty_port_tty_get(&acm->port); -	if (tty) { -		tty_hangup(tty); -		tty_kref_put(tty); -	} +	tty_port_put(&acm->port);  }  #ifdef CONFIG_PM @@ -1325,16 +1374,10 @@ static int acm_suspend(struct usb_interface *intf, pm_message_t message)  	if (cnt)  		return 0; -	/* -	we treat opened interfaces differently, -	we must guard against open -	*/ -	mutex_lock(&acm->mutex); -	if (acm->port.count) +	if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags))  		stop_data_traffic(acm); -	mutex_unlock(&acm->mutex);  	return 0;  } @@ -1353,8 +1396,7 @@ static int acm_resume(struct usb_interface *intf)  	if (cnt)  		return 0; -	mutex_lock(&acm->mutex); -	if (acm->port.count) { +	if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) {  		rv = usb_submit_urb(acm->ctrlurb, GFP_NOIO);  		spin_lock_irq(&acm->write_lock); @@ -1378,7 +1420,6 @@ static int acm_resume(struct usb_interface *intf)  	}  err_out: -	mutex_unlock(&acm->mutex);  	return rv;  } @@ -1387,15 +1428,14 @@ static int acm_reset_resume(struct usb_interface *intf)  	struct acm *acm = usb_get_intfdata(intf);  	struct tty_struct *tty; -	mutex_lock(&acm->mutex); -	if (acm->port.count) { +	if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) {  		tty = tty_port_tty_get(&acm->port);  		if (tty) {  			tty_hangup(tty);  			tty_kref_put(tty);  		}  	} -	mutex_unlock(&acm->mutex); +  	return acm_resume(intf);  } @@ -1594,8 +1634,10 @@ static struct usb_driver acm_driver = {   */  static const struct tty_operations acm_ops = { +	.install =		acm_tty_install,  	.open =			acm_tty_open,  	.close =		acm_tty_close, +	.cleanup =		acm_tty_cleanup,  	.hangup =		acm_tty_hangup,  	.write =		acm_tty_write,  	.write_room =		acm_tty_write_room, diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index ca7937f26e2..35ef887b741 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -101,6 +101,7 @@ struct acm {  	int transmitting;  	spinlock_t write_lock;  	struct mutex mutex; +	bool disconnected;  	struct usb_cdc_line_coding line;		/* bits, stop, parity */  	struct work_struct work;			/* work queue entry for line discipline waking up */  	unsigned int ctrlin;				/* input control lines (DCD, DSR, RI, break, overruns) */ diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e3beaf229ee..d8cf06f186f 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -86,6 +86,7 @@ struct async {  	void __user *userbuffer;  	void __user *userurb;  	struct urb *urb; +	unsigned int mem_usage;  	int status;  	u32 secid;  	u8 bulk_addr; @@ -108,8 +109,44 @@ enum snoop_when {  #define USB_DEVICE_DEV		MKDEV(USB_DEVICE_MAJOR, 0) -#define	MAX_USBFS_BUFFER_SIZE	16384 +/* Limit on the total amount of memory we can allocate for transfers */ +static unsigned usbfs_memory_mb = 16; +module_param(usbfs_memory_mb, uint, 0644); +MODULE_PARM_DESC(usbfs_memory_mb, +		"maximum MB allowed for usbfs buffers (0 = no limit)"); +/* Hard limit, necessary to avoid aithmetic overflow */ +#define USBFS_XFER_MAX		(UINT_MAX / 2 - 1000000) + +static atomic_t usbfs_memory_usage;	/* Total memory currently allocated */ + +/* Check whether it's okay to allocate more memory for a transfer */ +static int usbfs_increase_memory_usage(unsigned amount) +{ +	unsigned lim; + +	/* +	 * Convert usbfs_memory_mb to bytes, avoiding overflows. +	 * 0 means use the hard limit (effectively unlimited). +	 */ +	lim = ACCESS_ONCE(usbfs_memory_mb); +	if (lim == 0 || lim > (USBFS_XFER_MAX >> 20)) +		lim = USBFS_XFER_MAX; +	else +		lim <<= 20; + +	atomic_add(amount, &usbfs_memory_usage); +	if (atomic_read(&usbfs_memory_usage) <= lim) +		return 0; +	atomic_sub(amount, &usbfs_memory_usage); +	return -ENOMEM; +} + +/* Memory for a transfer is being deallocated */ +static void usbfs_decrease_memory_usage(unsigned amount) +{ +	atomic_sub(amount, &usbfs_memory_usage); +}  static int connected(struct dev_state *ps)  { @@ -253,6 +290,7 @@ static void free_async(struct async *as)  	kfree(as->urb->transfer_buffer);  	kfree(as->urb->setup_packet);  	usb_free_urb(as->urb); +	usbfs_decrease_memory_usage(as->mem_usage);  	kfree(as);  } @@ -792,9 +830,15 @@ static int proc_control(struct dev_state *ps, void __user *arg)  	wLength = ctrl.wLength;		/* To suppress 64k PAGE_SIZE warning */  	if (wLength > PAGE_SIZE)  		return -EINVAL; +	ret = usbfs_increase_memory_usage(PAGE_SIZE + sizeof(struct urb) + +			sizeof(struct usb_ctrlrequest)); +	if (ret) +		return ret;  	tbuf = (unsigned char *)__get_free_page(GFP_KERNEL); -	if (!tbuf) -		return -ENOMEM; +	if (!tbuf) { +		ret = -ENOMEM; +		goto done; +	}  	tmo = ctrl.timeout;  	snoop(&dev->dev, "control urb: bRequestType=%02x "  		"bRequest=%02x wValue=%04x " @@ -806,8 +850,8 @@ static int proc_control(struct dev_state *ps, void __user *arg)  	if (ctrl.bRequestType & 0x80) {  		if (ctrl.wLength && !access_ok(VERIFY_WRITE, ctrl.data,  					       ctrl.wLength)) { -			free_page((unsigned long)tbuf); -			return -EINVAL; +			ret = -EINVAL; +			goto done;  		}  		pipe = usb_rcvctrlpipe(dev, 0);  		snoop_urb(dev, NULL, pipe, ctrl.wLength, tmo, SUBMIT, NULL, 0); @@ -821,15 +865,15 @@ static int proc_control(struct dev_state *ps, void __user *arg)  			  tbuf, max(i, 0));  		if ((i > 0) && ctrl.wLength) {  			if (copy_to_user(ctrl.data, tbuf, i)) { -				free_page((unsigned long)tbuf); -				return -EFAULT; +				ret = -EFAULT; +				goto done;  			}  		}  	} else {  		if (ctrl.wLength) {  			if (copy_from_user(tbuf, ctrl.data, ctrl.wLength)) { -				free_page((unsigned long)tbuf); -				return -EFAULT; +				ret = -EFAULT; +				goto done;  			}  		}  		pipe = usb_sndctrlpipe(dev, 0); @@ -843,14 +887,18 @@ static int proc_control(struct dev_state *ps, void __user *arg)  		usb_lock_device(dev);  		snoop_urb(dev, NULL, pipe, max(i, 0), min(i, 0), COMPLETE, NULL, 0);  	} -	free_page((unsigned long)tbuf);  	if (i < 0 && i != -EPIPE) {  		dev_printk(KERN_DEBUG, &dev->dev, "usbfs: USBDEVFS_CONTROL "  			   "failed cmd %s rqt %u rq %u len %u ret %d\n",  			   current->comm, ctrl.bRequestType, ctrl.bRequest,  			   ctrl.wLength, i);  	} -	return i; +	ret = i; + done: +	free_page((unsigned long) tbuf); +	usbfs_decrease_memory_usage(PAGE_SIZE + sizeof(struct urb) + +			sizeof(struct usb_ctrlrequest)); +	return ret;  }  static int proc_bulk(struct dev_state *ps, void __user *arg) @@ -877,15 +925,20 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)  	if (!usb_maxpacket(dev, pipe, !(bulk.ep & USB_DIR_IN)))  		return -EINVAL;  	len1 = bulk.len; -	if (len1 > MAX_USBFS_BUFFER_SIZE) +	if (len1 >= USBFS_XFER_MAX)  		return -EINVAL; -	if (!(tbuf = kmalloc(len1, GFP_KERNEL))) -		return -ENOMEM; +	ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb)); +	if (ret) +		return ret; +	if (!(tbuf = kmalloc(len1, GFP_KERNEL))) { +		ret = -ENOMEM; +		goto done; +	}  	tmo = bulk.timeout;  	if (bulk.ep & 0x80) {  		if (len1 && !access_ok(VERIFY_WRITE, bulk.data, len1)) { -			kfree(tbuf); -			return -EINVAL; +			ret = -EINVAL; +			goto done;  		}  		snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, NULL, 0); @@ -896,15 +949,15 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)  		if (!i && len2) {  			if (copy_to_user(bulk.data, tbuf, len2)) { -				kfree(tbuf); -				return -EFAULT; +				ret = -EFAULT; +				goto done;  			}  		}  	} else {  		if (len1) {  			if (copy_from_user(tbuf, bulk.data, len1)) { -				kfree(tbuf); -				return -EFAULT; +				ret = -EFAULT; +				goto done;  			}  		}  		snoop_urb(dev, NULL, pipe, len1, tmo, SUBMIT, tbuf, len1); @@ -914,10 +967,11 @@ static int proc_bulk(struct dev_state *ps, void __user *arg)  		usb_lock_device(dev);  		snoop_urb(dev, NULL, pipe, len2, i, COMPLETE, NULL, 0);  	} +	ret = (i < 0 ? i : len2); + done:  	kfree(tbuf); -	if (i < 0) -		return i; -	return len2; +	usbfs_decrease_memory_usage(len1 + sizeof(struct urb)); +	return ret;  }  static int proc_resetep(struct dev_state *ps, void __user *arg) @@ -1062,7 +1116,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  {  	struct usbdevfs_iso_packet_desc *isopkt = NULL;  	struct usb_host_endpoint *ep; -	struct async *as; +	struct async *as = NULL;  	struct usb_ctrlrequest *dr = NULL;  	unsigned int u, totlen, isofrmlen;  	int ret, ifnum = -1; @@ -1095,32 +1149,30 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  	}  	if (!ep)  		return -ENOENT; + +	u = 0;  	switch(uurb->type) {  	case USBDEVFS_URB_TYPE_CONTROL:  		if (!usb_endpoint_xfer_control(&ep->desc))  			return -EINVAL; -		/* min 8 byte setup packet, -		 * max 8 byte setup plus an arbitrary data stage */ -		if (uurb->buffer_length < 8 || -		    uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE)) +		/* min 8 byte setup packet */ +		if (uurb->buffer_length < 8)  			return -EINVAL;  		dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);  		if (!dr)  			return -ENOMEM;  		if (copy_from_user(dr, uurb->buffer, 8)) { -			kfree(dr); -			return -EFAULT; +			ret = -EFAULT; +			goto error;  		}  		if (uurb->buffer_length < (le16_to_cpup(&dr->wLength) + 8)) { -			kfree(dr); -			return -EINVAL; +			ret = -EINVAL; +			goto error;  		}  		ret = check_ctrlrecip(ps, dr->bRequestType, dr->bRequest,  				      le16_to_cpup(&dr->wIndex)); -		if (ret) { -			kfree(dr); -			return ret; -		} +		if (ret) +			goto error;  		uurb->number_of_packets = 0;  		uurb->buffer_length = le16_to_cpup(&dr->wLength);  		uurb->buffer += 8; @@ -1138,6 +1190,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  			__le16_to_cpup(&dr->wValue),  			__le16_to_cpup(&dr->wIndex),  			__le16_to_cpup(&dr->wLength)); +		u = sizeof(struct usb_ctrlrequest);  		break;  	case USBDEVFS_URB_TYPE_BULK: @@ -1151,8 +1204,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  			goto interrupt_urb;  		}  		uurb->number_of_packets = 0; -		if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) -			return -EINVAL;  		break;  	case USBDEVFS_URB_TYPE_INTERRUPT: @@ -1160,8 +1211,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  			return -EINVAL;   interrupt_urb:  		uurb->number_of_packets = 0; -		if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) -			return -EINVAL;  		break;  	case USBDEVFS_URB_TYPE_ISO: @@ -1176,50 +1225,53 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  		if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL)))  			return -ENOMEM;  		if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) { -			kfree(isopkt); -			return -EFAULT; +			ret = -EFAULT; +			goto error;  		}  		for (totlen = u = 0; u < uurb->number_of_packets; u++) {  			/* arbitrary limit,  			 * sufficient for USB 2.0 high-bandwidth iso */  			if (isopkt[u].length > 8192) { -				kfree(isopkt); -				return -EINVAL; +				ret = -EINVAL; +				goto error;  			}  			totlen += isopkt[u].length;  		} -		/* 3072 * 64 microframes */ -		if (totlen > 196608) { -			kfree(isopkt); -			return -EINVAL; -		} +		u *= sizeof(struct usb_iso_packet_descriptor);  		uurb->buffer_length = totlen;  		break;  	default:  		return -EINVAL;  	} + +	if (uurb->buffer_length >= USBFS_XFER_MAX) { +		ret = -EINVAL; +		goto error; +	}  	if (uurb->buffer_length > 0 &&  			!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,  				uurb->buffer, uurb->buffer_length)) { -		kfree(isopkt); -		kfree(dr); -		return -EFAULT; +		ret = -EFAULT; +		goto error;  	}  	as = alloc_async(uurb->number_of_packets);  	if (!as) { -		kfree(isopkt); -		kfree(dr); -		return -ENOMEM; +		ret = -ENOMEM; +		goto error;  	} +	u += sizeof(struct async) + sizeof(struct urb) + uurb->buffer_length; +	ret = usbfs_increase_memory_usage(u); +	if (ret) +		goto error; +	as->mem_usage = u; +  	if (uurb->buffer_length > 0) {  		as->urb->transfer_buffer = kmalloc(uurb->buffer_length,  				GFP_KERNEL);  		if (!as->urb->transfer_buffer) { -			kfree(isopkt); -			kfree(dr); -			free_async(as); -			return -ENOMEM; +			ret = -ENOMEM; +			goto error;  		}  		/* Isochronous input data may end up being discontiguous  		 * if some of the packets are short.  Clear the buffer so @@ -1253,6 +1305,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  	as->urb->transfer_buffer_length = uurb->buffer_length;  	as->urb->setup_packet = (unsigned char *)dr; +	dr = NULL;  	as->urb->start_frame = uurb->start_frame;  	as->urb->number_of_packets = uurb->number_of_packets;  	if (uurb->type == USBDEVFS_URB_TYPE_ISO || @@ -1268,6 +1321,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  		totlen += isopkt[u].length;  	}  	kfree(isopkt); +	isopkt = NULL;  	as->ps = ps;  	as->userurb = arg;  	if (is_in && uurb->buffer_length > 0) @@ -1282,8 +1336,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  	if (!is_in && uurb->buffer_length > 0) {  		if (copy_from_user(as->urb->transfer_buffer, uurb->buffer,  				uurb->buffer_length)) { -			free_async(as); -			return -EFAULT; +			ret = -EFAULT; +			goto error;  		}  	}  	snoop_urb(ps->dev, as->userurb, as->urb->pipe, @@ -1329,10 +1383,16 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,  		snoop_urb(ps->dev, as->userurb, as->urb->pipe,  				0, ret, COMPLETE, NULL, 0);  		async_removepending(as); -		free_async(as); -		return ret; +		goto error;  	}  	return 0; + + error: +	kfree(isopkt); +	kfree(dr); +	if (as) +		free_async(as); +	return ret;  }  static int proc_submiturb(struct dev_state *ps, void __user *arg) diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 45887a0ff87..73abd8a0647 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -45,10 +45,12 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,  	struct usb_dynid *dynid;  	u32 idVendor = 0;  	u32 idProduct = 0; +	unsigned int bInterfaceClass = 0;  	int fields = 0;  	int retval = 0; -	fields = sscanf(buf, "%x %x", &idVendor, &idProduct); +	fields = sscanf(buf, "%x %x %x", &idVendor, &idProduct, +					&bInterfaceClass);  	if (fields < 2)  		return -EINVAL; @@ -60,6 +62,10 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,  	dynid->id.idVendor = idVendor;  	dynid->id.idProduct = idProduct;  	dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; +	if (fields == 3) { +		dynid->id.bInterfaceClass = (u8)bInterfaceClass; +		dynid->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS; +	}  	spin_lock(&dynids->lock);  	list_add_tail(&dynid->node, &dynids->list); diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index a004db35f6d..d136b8f4c8a 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -453,10 +453,6 @@ static int resume_common(struct device *dev, int event)  	pci_set_master(pci_dev); -	clear_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); -	if (hcd->shared_hcd) -		clear_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); -  	if (hcd->driver->pci_resume && !HCD_DEAD(hcd)) {  		if (event != PM_EVENT_AUTO_RESUME)  			wait_for_companions(pci_dev, hcd); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 13222d352a6..eb19cba34ac 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -658,7 +658,7 @@ error:  				len > offsetof(struct usb_device_descriptor,  						bDeviceProtocol))  			((struct usb_device_descriptor *) ubuf)-> -					bDeviceProtocol = 1; +				bDeviceProtocol = USB_HUB_PR_HS_SINGLE_TT;  	}  	/* any errors get returned through the urb completion */ @@ -1168,20 +1168,6 @@ int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,  	if (urb->unlinked)  		return -EBUSY;  	urb->unlinked = status; - -	/* IRQ setup can easily be broken so that USB controllers -	 * never get completion IRQs ... maybe even the ones we need to -	 * finish unlinking the initial failed usb_set_address() -	 * or device descriptor fetch. -	 */ -	if (!HCD_SAW_IRQ(hcd) && !is_root_hub(urb->dev)) { -		dev_warn(hcd->self.controller, "Unlink after no-IRQ?  " -			"Controller is probably using the wrong IRQ.\n"); -		set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); -		if (hcd->shared_hcd) -			set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); -	} -  	return 0;  }  EXPORT_SYMBOL_GPL(usb_hcd_check_unlink_urb); @@ -1412,11 +1398,10 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,  					ret = -EAGAIN;  				else  					urb->transfer_flags |= URB_DMA_MAP_SG; -				if (n != urb->num_sgs) { -					urb->num_sgs = n; +				urb->num_mapped_sgs = n; +				if (n != urb->num_sgs)  					urb->transfer_flags |=  							URB_DMA_SG_COMBINED; -				}  			} else if (urb->sg) {  				struct scatterlist *sg = urb->sg;  				urb->transfer_dma = dma_map_page( @@ -2148,16 +2133,12 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)  	 */  	local_irq_save(flags); -	if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd))) { +	if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd)))  		rc = IRQ_NONE; -	} else if (hcd->driver->irq(hcd) == IRQ_NONE) { +	else if (hcd->driver->irq(hcd) == IRQ_NONE)  		rc = IRQ_NONE; -	} else { -		set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); -		if (hcd->shared_hcd) -			set_bit(HCD_FLAG_SAW_IRQ, &hcd->shared_hcd->flags); +	else  		rc = IRQ_HANDLED; -	}  	local_irq_restore(flags);  	return rc; diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 79781461eec..79d339e2e70 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -84,7 +84,7 @@ struct usb_hub {  static inline int hub_is_superspeed(struct usb_device *hdev)  { -	return (hdev->descriptor.bDeviceProtocol == 3); +	return (hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS);  }  /* Protect struct usb_device->state and ->children members @@ -1041,58 +1041,58 @@ static int hub_configure(struct usb_hub *hub,  		dev_dbg(hub_dev, "standalone hub\n");  	switch (wHubCharacteristics & HUB_CHAR_LPSM) { -		case 0x00: -			dev_dbg(hub_dev, "ganged power switching\n"); -			break; -		case 0x01: -			dev_dbg(hub_dev, "individual port power switching\n"); -			break; -		case 0x02: -		case 0x03: -			dev_dbg(hub_dev, "no power switching (usb 1.0)\n"); -			break; +	case HUB_CHAR_COMMON_LPSM: +		dev_dbg(hub_dev, "ganged power switching\n"); +		break; +	case HUB_CHAR_INDV_PORT_LPSM: +		dev_dbg(hub_dev, "individual port power switching\n"); +		break; +	case HUB_CHAR_NO_LPSM: +	case HUB_CHAR_LPSM: +		dev_dbg(hub_dev, "no power switching (usb 1.0)\n"); +		break;  	}  	switch (wHubCharacteristics & HUB_CHAR_OCPM) { -		case 0x00: -			dev_dbg(hub_dev, "global over-current protection\n"); -			break; -		case 0x08: -			dev_dbg(hub_dev, "individual port over-current protection\n"); -			break; -		case 0x10: -		case 0x18: -			dev_dbg(hub_dev, "no over-current protection\n"); -                        break; +	case HUB_CHAR_COMMON_OCPM: +		dev_dbg(hub_dev, "global over-current protection\n"); +		break; +	case HUB_CHAR_INDV_PORT_OCPM: +		dev_dbg(hub_dev, "individual port over-current protection\n"); +		break; +	case HUB_CHAR_NO_OCPM: +	case HUB_CHAR_OCPM: +		dev_dbg(hub_dev, "no over-current protection\n"); +		break;  	}  	spin_lock_init (&hub->tt.lock);  	INIT_LIST_HEAD (&hub->tt.clear_list);  	INIT_WORK(&hub->tt.clear_work, hub_tt_work);  	switch (hdev->descriptor.bDeviceProtocol) { -		case 0: -			break; -		case 1: -			dev_dbg(hub_dev, "Single TT\n"); -			hub->tt.hub = hdev; -			break; -		case 2: -			ret = usb_set_interface(hdev, 0, 1); -			if (ret == 0) { -				dev_dbg(hub_dev, "TT per port\n"); -				hub->tt.multi = 1; -			} else -				dev_err(hub_dev, "Using single TT (err %d)\n", -					ret); -			hub->tt.hub = hdev; -			break; -		case 3: -			/* USB 3.0 hubs don't have a TT */ -			break; -		default: -			dev_dbg(hub_dev, "Unrecognized hub protocol %d\n", -				hdev->descriptor.bDeviceProtocol); -			break; +	case USB_HUB_PR_FS: +		break; +	case USB_HUB_PR_HS_SINGLE_TT: +		dev_dbg(hub_dev, "Single TT\n"); +		hub->tt.hub = hdev; +		break; +	case USB_HUB_PR_HS_MULTI_TT: +		ret = usb_set_interface(hdev, 0, 1); +		if (ret == 0) { +			dev_dbg(hub_dev, "TT per port\n"); +			hub->tt.multi = 1; +		} else +			dev_err(hub_dev, "Using single TT (err %d)\n", +				ret); +		hub->tt.hub = hdev; +		break; +	case USB_HUB_PR_SS: +		/* USB 3.0 hubs don't have a TT */ +		break; +	default: +		dev_dbg(hub_dev, "Unrecognized hub protocol %d\n", +			hdev->descriptor.bDeviceProtocol); +		break;  	}  	/* Note 8 FS bit times == (8 bits / 12000000 bps) ~= 666ns */ @@ -1360,7 +1360,6 @@ descriptor_error:  	return -ENODEV;  } -/* No BKL needed */  static int  hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)  { diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 3888778582c..45e8479c377 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -132,20 +132,6 @@ static inline int is_usb_device_driver(struct device_driver *drv)  			for_devices;  } -/* translate USB error codes to codes user space understands */ -static inline int usb_translate_errors(int error_code) -{ -	switch (error_code) { -	case 0: -	case -ENOMEM: -	case -ENODEV: -		return error_code; -	default: -		return -EIO; -	} -} - -  /* for labeling diagnostics */  extern const char *usbcore_name; diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 5809bf413d7..3274ac8f120 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -394,9 +394,9 @@ static struct platform_driver dwc3_omap_driver = {  	},  }; +module_platform_driver(dwc3_omap_driver); +  MODULE_ALIAS("platform:omap-dwc3");  MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");  MODULE_LICENSE("Dual BSD/GPL");  MODULE_DESCRIPTION("DesignWare USB3 OMAP Glue Layer"); - -module_platform_driver(dwc3_omap_driver); diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index d64072c06ef..71108c26c56 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -15,6 +15,7 @@  menuconfig USB_GADGET  	tristate "USB Gadget Support" +	select NLS  	help  	   USB is a master/slave protocol, organized with one master  	   host (such as a PC) controlling up to 127 peripheral devices. diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index e00cf92409c..f75c56a259a 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c @@ -2814,20 +2814,7 @@ static struct platform_driver udc_driver = {  #endif  }; -static int __init qe_udc_init(void) -{ -	printk(KERN_INFO "%s: %s, %s\n", driver_name, driver_desc, -			DRIVER_VERSION); -	return platform_driver_register(&udc_driver); -} - -static void __exit qe_udc_exit(void) -{ -	platform_driver_unregister(&udc_driver); -} - -module_init(qe_udc_init); -module_exit(qe_udc_exit); +module_platform_driver(udc_driver);  MODULE_DESCRIPTION(DRIVER_DESC);  MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 892412103dd..0114fd33fbe 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -2463,24 +2463,11 @@ static struct platform_driver udc_driver = {  #endif  	},  }; -MODULE_ALIAS("platform:pxa-u2o"); + +module_platform_driver(udc_driver);  MODULE_DESCRIPTION(DRIVER_DESC);  MODULE_AUTHOR("Chao Xie <chao.xie@marvell.com>");  MODULE_VERSION(DRIVER_VERSION);  MODULE_LICENSE("GPL"); - - -static int __init init(void) -{ -	return platform_driver_register(&udc_driver); -} -module_init(init); - - -static void __exit cleanup(void) -{ -	platform_driver_unregister(&udc_driver); -} -module_exit(cleanup); - +MODULE_ALIAS("platform:pxa-u2o"); diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index b31448229f0..c59156c0061 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c @@ -3467,18 +3467,7 @@ static struct platform_driver s3c_hsotg_driver = {  	.resume		= s3c_hsotg_resume,  }; -static int __init s3c_hsotg_modinit(void) -{ -	return platform_driver_register(&s3c_hsotg_driver); -} - -static void __exit s3c_hsotg_modexit(void) -{ -	platform_driver_unregister(&s3c_hsotg_driver); -} - -module_init(s3c_hsotg_modinit); -module_exit(s3c_hsotg_modexit); +module_platform_driver(s3c_hsotg_driver);  MODULE_DESCRIPTION("Samsung S3C USB High-speed/OtG device");  MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 20a553b46ae..787ac5baae9 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -1377,21 +1377,10 @@ static struct platform_driver s3c_hsudc_driver = {  	},  	.probe		= s3c_hsudc_probe,  }; -MODULE_ALIAS("platform:s3c-hsudc"); - -static int __init s3c_hsudc_modinit(void) -{ -	return platform_driver_register(&s3c_hsudc_driver); -} -static void __exit s3c_hsudc_modexit(void) -{ -	platform_driver_unregister(&s3c_hsudc_driver); -} - -module_init(s3c_hsudc_modinit); -module_exit(s3c_hsudc_modexit); +module_platform_driver(s3c_hsudc_driver);  MODULE_DESCRIPTION("Samsung S3C24XX USB high-speed controller driver");  MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");  MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:s3c-hsudc"); diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c index 58c4d37d312..4d25b9009ed 100644 --- a/drivers/usb/gadget/usbstring.c +++ b/drivers/usb/gadget/usbstring.c @@ -13,82 +13,17 @@  #include <linux/string.h>  #include <linux/device.h>  #include <linux/init.h> +#include <linux/nls.h>  #include <linux/usb/ch9.h>  #include <linux/usb/gadget.h> -#include <asm/unaligned.h> - - -static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len) -{ -	int	count = 0; -	u8	c; -	u16	uchar; - -	/* this insists on correct encodings, though not minimal ones. -	 * BUT it currently rejects legit 4-byte UTF-8 code points, -	 * which need surrogate pairs.  (Unicode 3.1 can use them.) -	 */ -	while (len != 0 && (c = (u8) *s++) != 0) { -		if (unlikely(c & 0x80)) { -			// 2-byte sequence: -			// 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx -			if ((c & 0xe0) == 0xc0) { -				uchar = (c & 0x1f) << 6; - -				c = (u8) *s++; -				if ((c & 0xc0) != 0x80) -					goto fail; -				c &= 0x3f; -				uchar |= c; - -			// 3-byte sequence (most CJKV characters): -			// zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx -			} else if ((c & 0xf0) == 0xe0) { -				uchar = (c & 0x0f) << 12; - -				c = (u8) *s++; -				if ((c & 0xc0) != 0x80) -					goto fail; -				c &= 0x3f; -				uchar |= c << 6; - -				c = (u8) *s++; -				if ((c & 0xc0) != 0x80) -					goto fail; -				c &= 0x3f; -				uchar |= c; - -				/* no bogus surrogates */ -				if (0xd800 <= uchar && uchar <= 0xdfff) -					goto fail; - -			// 4-byte sequence (surrogate pairs, currently rare): -			// 11101110wwwwzzzzyy + 110111yyyyxxxxxx -			//     = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx -			// (uuuuu = wwww + 1) -			// FIXME accept the surrogate code points (only) - -			} else -				goto fail; -		} else -			uchar = c; -		put_unaligned_le16(uchar, cp++); -		count++; -		len--; -	} -	return count; -fail: -	return -1; -} -  /**   * usb_gadget_get_string - fill out a string descriptor    * @table: of c strings encoded using UTF-8   * @id: string id, from low byte of wValue in get string descriptor - * @buf: at least 256 bytes + * @buf: at least 256 bytes, must be 16-bit aligned   *   * Finds the UTF-8 string matching the ID, and converts it into a   * string descriptor in utf16-le. @@ -125,8 +60,8 @@ usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf)  	/* string descriptors have length, tag, then UTF16-LE text */  	len = min ((size_t) 126, strlen (s->s)); -	memset (buf + 2, 0, 2 * len);	/* zero all the bytes */ -	len = utf8_to_utf16le(s->s, (__le16 *)&buf[2], len); +	len = utf8s_to_utf16s(s->s, len, UTF16_LITTLE_ENDIAN, +			(wchar_t *) &buf[2], 126);  	if (len < 0)  		return -EINVAL;  	buf [0] = (len + 1) * 2; diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index 18bafa99fe5..bf7441afed1 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c @@ -23,6 +23,7 @@ static int au1xxx_ehci_setup(struct usb_hcd *hcd)  	int ret = ehci_init(hcd);  	ehci->need_io_watchdog = 0; +	ehci_reset(ehci);  	return ret;  } diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 3ff9f82f726..c4c76ab204c 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -48,6 +48,10 @@  #include <asm/system.h>  #include <asm/unaligned.h> +#if defined(CONFIG_PPC_PS3) +#include <asm/firmware.h> +#endif +  /*-------------------------------------------------------------------------*/  /* @@ -230,12 +234,58 @@ static int ehci_halt (struct ehci_hcd *ehci)  			  STS_HALT, STS_HALT, 16 * 125);  } +#if defined(CONFIG_USB_SUSPEND) && defined(CONFIG_PPC_PS3) + +/* + * The EHCI controller of the Cell Super Companion Chip used in the + * PS3 will stop the root hub after all root hub ports are suspended. + * When in this condition handshake will return -ETIMEDOUT.  The + * STS_HLT bit will not be set, so inspection of the frame index is + * used here to test for the condition.  If the condition is found + * return success to allow the USB suspend to complete. + */ + +static int handshake_for_broken_root_hub(struct ehci_hcd *ehci, +					 void __iomem *ptr, u32 mask, u32 done, +					 int usec) +{ +	unsigned int old_index; +	int error; + +	if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) +		return -ETIMEDOUT; + +	old_index = ehci_read_frame_index(ehci); + +	error = handshake(ehci, ptr, mask, done, usec); + +	if (error == -ETIMEDOUT && ehci_read_frame_index(ehci) == old_index) +		return 0; + +	return error; +} + +#else + +static int handshake_for_broken_root_hub(struct ehci_hcd *ehci, +					 void __iomem *ptr, u32 mask, u32 done, +					 int usec) +{ +	return -ETIMEDOUT; +} + +#endif +  static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,  				       u32 mask, u32 done, int usec)  {  	int error;  	error = handshake(ehci, ptr, mask, done, usec); +	if (error == -ETIMEDOUT) +		error = handshake_for_broken_root_hub(ehci, ptr, mask, done, +						      usec); +  	if (error) {  		ehci_halt(ehci);  		ehci->rh_state = EHCI_RH_HALTED; @@ -620,6 +670,7 @@ static int ehci_init(struct usb_hcd *hcd)  	hw = ehci->async->hw;  	hw->hw_next = QH_NEXT(ehci, ehci->async->qh_dma);  	hw->hw_info1 = cpu_to_hc32(ehci, QH_HEAD); +	hw->hw_info1 |= cpu_to_hc32(ehci, (1 << 7));	/* I = 1 */  	hw->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT);  	hw->hw_qtd_next = EHCI_LIST_END(ehci);  	ehci->async->qh_state = QH_STATE_LINKED; @@ -677,22 +728,13 @@ static int ehci_init(struct usb_hcd *hcd)  static int ehci_run (struct usb_hcd *hcd)  {  	struct ehci_hcd		*ehci = hcd_to_ehci (hcd); -	int			retval;  	u32			temp;  	u32			hcc_params;  	hcd->uses_new_polling = 1;  	/* EHCI spec section 4.1 */ -	/* -	 * TDI driver does the ehci_reset in their reset callback. -	 * Don't reset here, because configuration settings will -	 * vanish. -	 */ -	if (!ehci_is_TDI(ehci) && (retval = ehci_reset(ehci)) != 0) { -		ehci_mem_cleanup(ehci); -		return retval; -	} +  	ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);  	ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next); @@ -1324,7 +1366,7 @@ MODULE_LICENSE ("GPL");  #define PLATFORM_DRIVER		ehci_pxa168_driver  #endif -#ifdef CONFIG_NLM_XLR +#ifdef CONFIG_CPU_XLR  #include "ehci-xls.c"  #define PLATFORM_DRIVER		ehci_xls_driver  #endif diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c index ba1f5136113..c0104882c72 100644 --- a/drivers/usb/host/ehci-octeon.c +++ b/drivers/usb/host/ehci-octeon.c @@ -155,6 +155,8 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev)  	/* cache this readonly data; minimize chip reads */  	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); +	ehci_reset(ehci); +  	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (ret) {  		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index e39b0297bad..e33baf9052c 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -228,6 +228,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)  	/* cache this readonly data; minimize chip reads */  	omap_ehci->hcs_params = readl(&omap_ehci->caps->hcs_params); +	ehci_reset(omap_ehci); +  	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (ret) {  		dev_err(dev, "failed to add hcd with err %d\n", ret); diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 2dc32da75cf..a20e496eb47 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c @@ -21,6 +21,34 @@  #include <asm/firmware.h>  #include <asm/ps3.h> +static void ps3_ehci_setup_insnreg(struct ehci_hcd *ehci) +{ +	/* PS3 HC internal setup register offsets. */ + +	enum ps3_ehci_hc_insnreg { +		ps3_ehci_hc_insnreg01 = 0x084, +		ps3_ehci_hc_insnreg02 = 0x088, +		ps3_ehci_hc_insnreg03 = 0x08c, +	}; + +	/* PS3 EHCI HC errata fix 316 - The PS3 EHCI HC will reset its +	 * internal INSNREGXX setup regs back to the chip default values +	 * on Host Controller Reset (CMD_RESET) or Light Host Controller +	 * Reset (CMD_LRESET).  The work-around for this is for the HC +	 * driver to re-initialise these regs when ever the HC is reset. +	 */ + +	/* Set burst transfer counts to 256 out, 32 in. */ + +	writel_be(0x01000020, (void __iomem *)ehci->regs + +		ps3_ehci_hc_insnreg01); + +	/* Enable burst transfer counts. */ + +	writel_be(0x00000001, (void __iomem *)ehci->regs + +		ps3_ehci_hc_insnreg03); +} +  static int ps3_ehci_hc_reset(struct usb_hcd *hcd)  {  	int result; @@ -49,6 +77,8 @@ static int ps3_ehci_hc_reset(struct usb_hcd *hcd)  	ehci_reset(ehci); +	ps3_ehci_setup_insnreg(ehci); +  	return result;  } diff --git a/drivers/usb/host/ehci-pxa168.c b/drivers/usb/host/ehci-pxa168.c index ac0c16e8f53..8d0e7a22e71 100644 --- a/drivers/usb/host/ehci-pxa168.c +++ b/drivers/usb/host/ehci-pxa168.c @@ -299,7 +299,7 @@ static int __devinit ehci_pxa168_drv_probe(struct platform_device *pdev)  	ehci = hcd_to_ehci(hcd);  	ehci->caps = hcd->regs + 0x100;  	ehci->regs = hcd->regs + 0x100 + -		HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); +		HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));  	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);  	hcd->has_tt = 1;  	ehci->sbrn = 0x20; diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 4e4066c35a0..36ca5077cdf 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -373,6 +373,17 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)   retry_xacterr:  		if ((token & QTD_STS_ACTIVE) == 0) { +			/* Report Data Buffer Error: non-fatal but useful */ +			if (token & QTD_STS_DBE) +				ehci_dbg(ehci, +					"detected DataBufferErr for urb %p ep%d%s len %d, qtd %p [qh %p]\n", +					urb, +					usb_endpoint_num(&urb->ep->desc), +					usb_endpoint_dir_in(&urb->ep->desc) ? "in" : "out", +					urb->transfer_buffer_length, +					qtd, +					qh); +  			/* on STALL, error, and short reads this urb must  			 * complete and all its qtds must be recycled.  			 */ @@ -647,7 +658,7 @@ qh_urb_transaction (  	/*  	 * data transfer stage:  buffer setup  	 */ -	i = urb->num_sgs; +	i = urb->num_mapped_sgs;  	if (len > 0 && i > 0) {  		sg = urb->sg;  		buf = sg_dma_address(sg); diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index 024b65c4990..293f7412992 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c @@ -14,8 +14,6 @@  #include <linux/clk.h>  #include <linux/platform_device.h> -#include <mach/regs-pmu.h> -#include <plat/cpu.h>  #include <plat/ehci.h>  #include <plat/usb-phy.h> @@ -136,6 +134,8 @@ static int __devinit s5p_ehci_probe(struct platform_device *pdev)  	/* cache this readonly data; minimize chip reads */  	ehci->hcs_params = readl(&ehci->caps->hcs_params); +	ehci_reset(ehci); +  	err = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (err) {  		dev_err(&pdev->dev, "Failed to add USB HCD\n"); diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c index 54d1ab8aec4..c1eda73916c 100644 --- a/drivers/usb/host/ehci-vt8500.c +++ b/drivers/usb/host/ehci-vt8500.c @@ -132,6 +132,8 @@ static int vt8500_ehci_drv_probe(struct platform_device *pdev)  	ehci_port_power(ehci, 1); +	ehci_reset(ehci); +  	ret = usb_add_hcd(hcd, pdev->resource[1].start,  			  IRQF_SHARED);  	if (ret == 0) { diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index d661cf7de14..3d2e26cbb34 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -78,6 +78,8 @@ static int __devinit usb_w90x900_probe(const struct hc_driver *driver,  	if (irq < 0)  		goto err4; +	ehci_reset(ehci); +  	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (retval != 0)  		goto err4; diff --git a/drivers/usb/host/ehci-xls.c b/drivers/usb/host/ehci-xls.c index b4fb511d24b..72f08196f8c 100644 --- a/drivers/usb/host/ehci-xls.c +++ b/drivers/usb/host/ehci-xls.c @@ -69,7 +69,7 @@ int ehci_xls_probe_internal(const struct hc_driver *driver,  	}  	hcd->rsrc_start = res->start; -	hcd->rsrc_len = res->end - res->start + 1; +	hcd->rsrc_len = resource_size(res);  	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,  				driver->description)) { diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 4ed6d19f2a5..d2623747b48 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -824,17 +824,7 @@ static struct platform_driver of_fhci_driver = {  	.remove		= __devexit_p(of_fhci_remove),  }; -static int __init fhci_module_init(void) -{ -	return platform_driver_register(&of_fhci_driver); -} -module_init(fhci_module_init); - -static void __exit fhci_module_exit(void) -{ -	platform_driver_unregister(&of_fhci_driver); -} -module_exit(fhci_module_exit); +module_platform_driver(of_fhci_driver);  MODULE_DESCRIPTION("USB Freescale Host Controller Interface Driver");  MODULE_AUTHOR("Shlomi Gridish <gridish@freescale.com>, " diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 9037035ad1e..7916e56a725 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -297,17 +297,7 @@ static struct platform_driver fsl_usb2_mph_dr_driver = {  	.remove	= __devexit_p(fsl_usb2_mph_dr_of_remove),  }; -static int __init fsl_usb2_mph_dr_init(void) -{ -	return platform_driver_register(&fsl_usb2_mph_dr_driver); -} -module_init(fsl_usb2_mph_dr_init); - -static void __exit fsl_usb2_mph_dr_exit(void) -{ -	platform_driver_unregister(&fsl_usb2_mph_dr_driver); -} -module_exit(fsl_usb2_mph_dr_exit); +module_platform_driver(fsl_usb2_mph_dr_driver);  MODULE_DESCRIPTION("FSL MPH DR OF devices driver");  MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>"); diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 9bfac657572..565d79f06e6 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c @@ -776,7 +776,6 @@ static int hwahc_probe(struct usb_interface *usb_iface,  		goto error_alloc;  	}  	usb_hcd->wireless = 1; -	set_bit(HCD_FLAG_SAW_IRQ, &usb_hcd->flags);  	wusbhc = usb_hcd_to_wusbhc(usb_hcd);  	hwahc = container_of(wusbhc, struct hwahc, wusbhc);  	hwahc_init(hwahc); diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index 2ee18cfa1ef..6923bcb8aa6 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -1924,18 +1924,7 @@ static struct platform_driver imx21_hcd_driver = {  	.resume = NULL,  }; -static int __init imx21_hcd_init(void) -{ -	return platform_driver_register(&imx21_hcd_driver); -} - -static void __exit imx21_hcd_cleanup(void) -{ -	platform_driver_unregister(&imx21_hcd_driver); -} - -module_init(imx21_hcd_init); -module_exit(imx21_hcd_cleanup); +module_platform_driver(imx21_hcd_driver);  MODULE_DESCRIPTION("i.MX21 USB Host controller");  MODULE_AUTHOR("Martin Fuzzey"); diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 27dfab80ed8..fc72d44bf78 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -32,6 +32,13 @@ static struct kmem_cache *qtd_cachep;  static struct kmem_cache *qh_cachep;  static struct kmem_cache *urb_listitem_cachep; +enum queue_head_types { +	QH_CONTROL, +	QH_BULK, +	QH_INTERRUPT, +	QH_END +}; +  struct isp1760_hcd {  	u32 hcs_params;  	spinlock_t		lock; @@ -40,7 +47,7 @@ struct isp1760_hcd {  	struct slotinfo		int_slots[32];  	int			int_done_map;  	struct memory_chunk memory_pool[BLOCKS]; -	struct list_head	controlqhs, bulkqhs, interruptqhs; +	struct list_head	qh_list[QH_END];  	/* periodic schedule support */  #define	DEFAULT_I_TDPS		1024 @@ -406,12 +413,12 @@ static int priv_init(struct usb_hcd *hcd)  {  	struct isp1760_hcd		*priv = hcd_to_priv(hcd);  	u32			hcc_params; +	int i;  	spin_lock_init(&priv->lock); -	INIT_LIST_HEAD(&priv->interruptqhs); -	INIT_LIST_HEAD(&priv->controlqhs); -	INIT_LIST_HEAD(&priv->bulkqhs); +	for (i = 0; i < QH_END; i++) +		INIT_LIST_HEAD(&priv->qh_list[i]);  	/*  	 * hw default: 1K periodic list heads, one per frame. @@ -930,9 +937,9 @@ void schedule_ptds(struct usb_hcd *hcd)  	struct isp1760_hcd *priv;  	struct isp1760_qh *qh, *qh_next;  	struct list_head *ep_queue; -	struct usb_host_endpoint *ep;  	LIST_HEAD(urb_list);  	struct urb_listitem *urb_listitem, *urb_listitem_next; +	int i;  	if (!hcd) {  		WARN_ON(1); @@ -944,28 +951,13 @@ void schedule_ptds(struct usb_hcd *hcd)  	/*  	 * check finished/retired xfers, transfer payloads, call urb_done()  	 */ -	ep_queue = &priv->interruptqhs; -	while (ep_queue) { +	for (i = 0; i < QH_END; i++) { +		ep_queue = &priv->qh_list[i];  		list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list) { -			ep = list_entry(qh->qtd_list.next, struct isp1760_qtd, -							qtd_list)->urb->ep;  			collect_qtds(hcd, qh, &urb_list); -			if (list_empty(&qh->qtd_list)) { +			if (list_empty(&qh->qtd_list))  				list_del(&qh->qh_list); -				if (ep->hcpriv == NULL) { -					/* Endpoint has been disabled, so we -					can free the associated queue head. */ -					qh_free(qh); -				} -			}  		} - -		if (ep_queue == &priv->interruptqhs) -			ep_queue = &priv->controlqhs; -		else if (ep_queue == &priv->controlqhs) -			ep_queue = &priv->bulkqhs; -		else -			ep_queue = NULL;  	}  	list_for_each_entry_safe(urb_listitem, urb_listitem_next, &urb_list, @@ -998,17 +990,10 @@ void schedule_ptds(struct usb_hcd *hcd)  	 *  	 * I'm sure this scheme could be improved upon!  	 */ -	ep_queue = &priv->controlqhs; -	while (ep_queue) { +	for (i = 0; i < QH_END; i++) { +		ep_queue = &priv->qh_list[i];  		list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list)  			enqueue_qtds(hcd, qh); - -		if (ep_queue == &priv->controlqhs) -			ep_queue = &priv->interruptqhs; -		else if (ep_queue == &priv->interruptqhs) -			ep_queue = &priv->bulkqhs; -		else -			ep_queue = NULL;  	}  } @@ -1543,16 +1528,16 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,  	switch (usb_pipetype(urb->pipe)) {  	case PIPE_CONTROL: -		ep_queue = &priv->controlqhs; +		ep_queue = &priv->qh_list[QH_CONTROL];  		break;  	case PIPE_BULK: -		ep_queue = &priv->bulkqhs; +		ep_queue = &priv->qh_list[QH_BULK];  		break;  	case PIPE_INTERRUPT:  		if (urb->interval < 0)  			return -EINVAL;  		/* FIXME: Check bandwidth  */ -		ep_queue = &priv->interruptqhs; +		ep_queue = &priv->qh_list[QH_INTERRUPT];  		break;  	case PIPE_ISOCHRONOUS:  		dev_err(hcd->self.controller, "%s: isochronous USB packets " @@ -1714,8 +1699,8 @@ static void isp1760_endpoint_disable(struct usb_hcd *hcd,  {  	struct isp1760_hcd *priv = hcd_to_priv(hcd);  	unsigned long spinflags; -	struct isp1760_qh *qh; -	struct isp1760_qtd *qtd; +	struct isp1760_qh *qh, *qh_iter; +	int i;  	spin_lock_irqsave(&priv->lock, spinflags); @@ -1723,14 +1708,17 @@ static void isp1760_endpoint_disable(struct usb_hcd *hcd,  	if (!qh)  		goto out; -	list_for_each_entry(qtd, &qh->qtd_list, qtd_list) -		if (qtd->status != QTD_RETIRE) { -			dequeue_urb_from_qtd(hcd, qh, qtd); -			qtd->urb->status = -ECONNRESET; -		} +	WARN_ON(!list_empty(&qh->qtd_list)); +	for (i = 0; i < QH_END; i++) +		list_for_each_entry(qh_iter, &priv->qh_list[i], qh_list) +			if (qh_iter == qh) { +				list_del(&qh_iter->qh_list); +				i = QH_END; +				break; +			} +	qh_free(qh);  	ep->hcpriv = NULL; -	/* Cannot free qh here since it will be parsed by schedule_ptds() */  	schedule_ptds(hcd); diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index a7dc1e1d45f..b605224fb9e 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c @@ -47,9 +47,9 @@ static int of_isp1760_probe(struct platform_device *dev)  	int virq;  	resource_size_t res_len;  	int ret; -	const unsigned int *prop;  	unsigned int devflags = 0;  	enum of_gpio_flags gpio_flags; +	u32 bus_width = 0;  	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);  	if (!drvdata) @@ -77,8 +77,8 @@ static int of_isp1760_probe(struct platform_device *dev)  		devflags |= ISP1760_FLAG_ISP1761;  	/* Some systems wire up only 16 of the 32 data lines */ -	prop = of_get_property(dp, "bus-width", NULL); -	if (prop && *prop == 16) +	of_property_read_u32(dp, "bus-width", &bus_width); +	if (bus_width == 16)  		devflags |= ISP1760_FLAG_BUS_WIDTH_16;  	if (of_get_property(dp, "port1-otg", NULL) != NULL) diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 9b66df8278f..40d886adff5 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c @@ -173,12 +173,9 @@ static int ohci_hcd_au1xxx_drv_suspend(struct device *dev)  	 * mark HW unaccessible, bail out if RH has been resumed. Use  	 * the spinlock to properly synchronize with possible pending  	 * RH suspend or resume activity. -	 * -	 * This is still racy as hcd->state is manipulated outside of -	 * any locks =P But that will be a different fix.  	 */  	spin_lock_irqsave(&ohci->lock, flags); -	if (hcd->state != HC_STATE_SUSPENDED) { +	if (ohci->rh_state != OHCI_RH_SUSPENDED) {  		rc = -EINVAL;  		goto bail;  	} diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index d7d34492934..5179fcd73d8 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -127,6 +127,19 @@ static char *hcfs2string (int state)  	return "?";  } +static const char *rh_state_string(struct ohci_hcd *ohci) +{ +	switch (ohci->rh_state) { +	case OHCI_RH_HALTED: +		return "halted"; +	case OHCI_RH_SUSPENDED: +		return "suspended"; +	case OHCI_RH_RUNNING: +		return "running"; +	} +	return "?"; +} +  // dump control and status registers  static void  ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size) @@ -136,9 +149,10 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)  	temp = ohci_readl (controller, ®s->revision) & 0xff;  	ohci_dbg_sw (controller, next, size, -		"OHCI %d.%d, %s legacy support registers\n", +		"OHCI %d.%d, %s legacy support registers, rh state %s\n",  		0x03 & (temp >> 4), (temp & 0x0f), -		(temp & 0x0100) ? "with" : "NO"); +		(temp & 0x0100) ? "with" : "NO", +		rh_state_string(controller));  	temp = ohci_readl (controller, ®s->control);  	ohci_dbg_sw (controller, next, size, diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index dc45d489d00..3d63574d2c7 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c @@ -179,8 +179,6 @@ static int ohci_hcd_ep93xx_drv_suspend(struct platform_device *pdev, pm_message_  	ohci->next_statechange = jiffies;  	ep93xx_stop_hc(&pdev->dev); -	hcd->state = HC_STATE_SUSPENDED; -  	return 0;  } diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index b2639191549..4fa5d8c4d23 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -209,7 +209,7 @@ static int ohci_urb_enqueue (  		retval = -ENODEV;  		goto fail;  	} -	if (!HC_IS_RUNNING(hcd->state)) { +	if (ohci->rh_state != OHCI_RH_RUNNING) {  		retval = -ENODEV;  		goto fail;  	} @@ -274,7 +274,7 @@ static int ohci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)  	rc = usb_hcd_check_unlink_urb(hcd, urb, status);  	if (rc) {  		;	/* Do nothing */ -	} else if (HC_IS_RUNNING(hcd->state)) { +	} else if (ohci->rh_state == OHCI_RH_RUNNING) {  		urb_priv_t  *urb_priv;  		/* Unless an IRQ completed the unlink while it was being @@ -321,7 +321,7 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep)  rescan:  	spin_lock_irqsave (&ohci->lock, flags); -	if (!HC_IS_RUNNING (hcd->state)) { +	if (ohci->rh_state != OHCI_RH_RUNNING) {  sanitize:  		ed->state = ED_IDLE;  		if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT) @@ -377,6 +377,7 @@ static void ohci_usb_reset (struct ohci_hcd *ohci)  	ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);  	ohci->hc_control &= OHCI_CTRL_RWC;  	ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); +	ohci->rh_state = OHCI_RH_HALTED;  }  /* ohci_shutdown forcibly disables IRQs and DMA, helping kexec and @@ -500,7 +501,7 @@ static int ohci_init (struct ohci_hcd *ohci)  	if (distrust_firmware)  		ohci->flags |= OHCI_QUIRK_HUB_POWER; -	disable (ohci); +	ohci->rh_state = OHCI_RH_HALTED;  	ohci->regs = hcd->regs;  	/* REVISIT this BIOS handshake is now moved into PCI "quirks", and @@ -575,7 +576,7 @@ static int ohci_run (struct ohci_hcd *ohci)  	int			first = ohci->fminterval == 0;  	struct usb_hcd		*hcd = ohci_to_hcd(ohci); -	disable (ohci); +	ohci->rh_state = OHCI_RH_HALTED;  	/* boot firmware should have set this up (5.1.1.3.1) */  	if (first) { @@ -688,7 +689,7 @@ retry:  	ohci->hc_control &= OHCI_CTRL_RWC;  	ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;  	ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); -	hcd->state = HC_STATE_RUNNING; +	ohci->rh_state = OHCI_RH_RUNNING;  	/* wake on ConnectStatusChange, matching external hubs */  	ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status); @@ -725,7 +726,6 @@ retry:  	// POTPGT delay is bits 24-31, in 2 ms units.  	mdelay ((val >> 23) & 0x1fe); -	hcd->state = HC_STATE_RUNNING;  	if (quirk_zfmicro(ohci)) {  		/* Create timer to watch for bad queue state on ZF Micro */ @@ -761,7 +761,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)  	 * of dead, unclocked, or unplugged (CardBus...) devices  	 */  	if (ints == ~(u32)0) { -		disable (ohci); +		ohci->rh_state = OHCI_RH_HALTED;  		ohci_dbg (ohci, "device removed!\n");  		usb_hc_died(hcd);  		return IRQ_HANDLED; @@ -771,7 +771,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)  	ints &= ohci_readl(ohci, ®s->intrenable);  	/* interrupt for some other device? */ -	if (ints == 0 || unlikely(hcd->state == HC_STATE_HALT)) +	if (ints == 0 || unlikely(ohci->rh_state == OHCI_RH_HALTED))  		return IRQ_NOTMINE;  	if (ints & OHCI_INTR_UE) { @@ -786,8 +786,8 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)  			schedule_work (&ohci->nec_work);  		} else { -			disable (ohci);  			ohci_err (ohci, "OHCI Unrecoverable Error, disabled\n"); +			ohci->rh_state = OHCI_RH_HALTED;  			usb_hc_died(hcd);  		} @@ -871,11 +871,11 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)  	if ((ints & OHCI_INTR_SF) != 0  			&& !ohci->ed_rm_list  			&& !ohci->ed_to_check -			&& HC_IS_RUNNING(hcd->state)) +			&& ohci->rh_state == OHCI_RH_RUNNING)  		ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable);  	spin_unlock (&ohci->lock); -	if (HC_IS_RUNNING(hcd->state)) { +	if (ohci->rh_state == OHCI_RH_RUNNING) {  		ohci_writel (ohci, ints, ®s->intrstatus);  		ohci_writel (ohci, OHCI_INTR_MIE, ®s->intrenable);  		// flush those writes @@ -929,7 +929,7 @@ static int ohci_restart (struct ohci_hcd *ohci)  	struct urb_priv *priv;  	spin_lock_irq(&ohci->lock); -	disable (ohci); +	ohci->rh_state = OHCI_RH_HALTED;  	/* Recycle any "live" eds/tds (and urbs). */  	if (!list_empty (&ohci->pending)) @@ -1111,7 +1111,7 @@ MODULE_LICENSE ("GPL");  #define PLATFORM_DRIVER		ohci_hcd_ath79_driver  #endif -#ifdef CONFIG_NLM_XLR +#ifdef CONFIG_CPU_XLR  #include "ohci-xls.c"  #define PLATFORM_DRIVER		ohci_xls_driver  #endif diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 2f00040fc40..836772dfabd 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -111,6 +111,7 @@ __acquires(ohci->lock)  	if (!autostop) {  		ohci->next_statechange = jiffies + msecs_to_jiffies (5);  		ohci->autostop = 0; +		ohci->rh_state = OHCI_RH_SUSPENDED;  	}  done: @@ -140,7 +141,7 @@ __acquires(ohci->lock)  	if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {  		/* this can happen after resuming a swsusp snapshot */ -		if (hcd->state == HC_STATE_RESUMING) { +		if (ohci->rh_state != OHCI_RH_RUNNING) {  			ohci_dbg (ohci, "BIOS/SMM active, control %03x\n",  					ohci->hc_control);  			status = -EBUSY; @@ -274,6 +275,7 @@ skip_resume:  		(void) ohci_readl (ohci, &ohci->regs->control);  	} +	ohci->rh_state = OHCI_RH_RUNNING;  	return 0;  } @@ -336,11 +338,8 @@ static void ohci_finish_controller_resume(struct usb_hcd *hcd)  	/* If needed, reinitialize and suspend the root hub */  	if (need_reinit) {  		spin_lock_irq(&ohci->lock); -		hcd->state = HC_STATE_RESUMING;  		ohci_rh_resume(ohci); -		hcd->state = HC_STATE_QUIESCING;  		ohci_rh_suspend(ohci, 0); -		hcd->state = HC_STATE_SUSPENDED;  		spin_unlock_irq(&ohci->lock);  	} diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index e4b8782cc6e..db3968656d2 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -516,7 +516,6 @@ static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message)  	ohci->next_statechange = jiffies;  	omap_ohci_clock_power(0); -	ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;  	return 0;  } diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index bc01b064585..6109810cc2d 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -308,12 +308,9 @@ static int ohci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)  	 * mark HW unaccessible, bail out if RH has been resumed. Use  	 * the spinlock to properly synchronize with possible pending  	 * RH suspend or resume activity. -	 * -	 * This is still racy as hcd->state is manipulated outside of -	 * any locks =P But that will be a different fix.  	 */  	spin_lock_irqsave (&ohci->lock, flags); -	if (hcd->state != HC_STATE_SUSPENDED) { +	if (ohci->rh_state != OHCI_RH_SUSPENDED) {  		rc = -EINVAL;  		goto bail;  	} diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 29dfefe1c72..6313e4439f3 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -502,8 +502,6 @@ static int ohci_hcd_pxa27x_drv_suspend(struct device *dev)  	ohci->ohci.next_statechange = jiffies;  	pxa27x_stop_hc(ohci, dev); -	hcd->state = HC_STATE_SUSPENDED; -  	return 0;  } diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 15dc51ded61..c5a1ea9145f 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -912,7 +912,7 @@ rescan_all:  		/* only take off EDs that the HC isn't using, accounting for  		 * frame counter wraps and EDs with partially retired TDs  		 */ -		if (likely (HC_IS_RUNNING(ohci_to_hcd(ohci)->state))) { +		if (likely(ohci->rh_state == OHCI_RH_RUNNING)) {  			if (tick_before (tick, ed->tick)) {  skip_ed:  				last = &ed->ed_next; @@ -1012,7 +1012,7 @@ rescan_this:  		/* but if there's work queued, reschedule */  		if (!list_empty (&ed->td_list)) { -			if (HC_IS_RUNNING(ohci_to_hcd(ohci)->state)) +			if (ohci->rh_state == OHCI_RH_RUNNING)  				ed_schedule (ohci, ed);  		} @@ -1021,9 +1021,7 @@ rescan_this:  	}  	/* maybe reenable control and bulk lists */ -	if (HC_IS_RUNNING(ohci_to_hcd(ohci)->state) -			&& ohci_to_hcd(ohci)->state != HC_STATE_QUIESCING -			&& !ohci->ed_rm_list) { +	if (ohci->rh_state == OHCI_RH_RUNNING && !ohci->ed_rm_list) {  		u32	command = 0, control = 0;  		if (ohci->ed_controltail) { diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index a1877c47601..56dcf069246 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -486,15 +486,66 @@ static int __devexit ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev)  	return 0;  } +#ifdef CONFIG_PM +static int ohci_hcd_s3c2410_drv_suspend(struct device *dev) +{ +	struct usb_hcd *hcd = dev_get_drvdata(dev); +	struct ohci_hcd *ohci = hcd_to_ohci(hcd); +	struct platform_device *pdev = to_platform_device(dev); +	unsigned long flags; +	int rc = 0; + +	/* +	 * Root hub was already suspended. Disable irq emission and +	 * mark HW unaccessible, bail out if RH has been resumed. Use +	 * the spinlock to properly synchronize with possible pending +	 * RH suspend or resume activity. +	 */ +	spin_lock_irqsave(&ohci->lock, flags); +	if (ohci->rh_state != OHCI_RH_SUSPENDED) { +		rc = -EINVAL; +		goto bail; +	} + +	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + +	s3c2410_stop_hc(pdev); +bail: +	spin_unlock_irqrestore(&ohci->lock, flags); + +	return rc; +} + +static int ohci_hcd_s3c2410_drv_resume(struct device *dev) +{ +	struct usb_hcd *hcd = dev_get_drvdata(dev); +	struct platform_device *pdev = to_platform_device(dev); + +	s3c2410_start_hc(pdev, hcd); + +	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); +	ohci_finish_controller_resume(hcd); + +	return 0; +} +#else +#define ohci_hcd_s3c2410_drv_suspend	NULL +#define ohci_hcd_s3c2410_drv_resume	NULL +#endif + +static const struct dev_pm_ops ohci_hcd_s3c2410_pm_ops = { +	.suspend	= ohci_hcd_s3c2410_drv_suspend, +	.resume		= ohci_hcd_s3c2410_drv_resume, +}; +  static struct platform_driver ohci_hcd_s3c2410_driver = {  	.probe		= ohci_hcd_s3c2410_drv_probe,  	.remove		= __devexit_p(ohci_hcd_s3c2410_drv_remove),  	.shutdown	= usb_hcd_platform_shutdown, -	/*.suspend	= ohci_hcd_s3c2410_drv_suspend, */ -	/*.resume	= ohci_hcd_s3c2410_drv_resume, */  	.driver		= {  		.owner	= THIS_MODULE,  		.name	= "s3c2410-ohci", +		.pm	= &ohci_hcd_s3c2410_pm_ops,  	},  }; diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c index afc4eb6bb9d..84686d90805 100644 --- a/drivers/usb/host/ohci-sh.c +++ b/drivers/usb/host/ohci-sh.c @@ -29,7 +29,6 @@ static int ohci_sh_start(struct usb_hcd *hcd)  	ohci_hcd_init(ohci);  	ohci_init(ohci);  	ohci_run(ohci); -	hcd->state = HC_STATE_RUNNING;  	return 0;  } diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index 968cea2b6d4..5596ac2ba1c 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -224,7 +224,6 @@ static int ohci_sm501_suspend(struct platform_device *pdev, pm_message_t msg)  	ohci->next_statechange = jiffies;  	sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 0); -	ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;  	return 0;  } diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index 69874654f3b..95c16489e88 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -203,7 +203,6 @@ static int spear_ohci_hcd_drv_suspend(struct platform_device *dev,  	ohci->next_statechange = jiffies;  	spear_stop_ohci(ohci_p); -	ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED;  	return 0;  } diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index 06331d93117..120bfe6ede3 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c @@ -318,9 +318,6 @@ static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t s  		if (ret)  			return ret;  	} - -	hcd->state = HC_STATE_SUSPENDED; -  	return 0;  } diff --git a/drivers/usb/host/ohci-xls.c b/drivers/usb/host/ohci-xls.c index a3a9c6f45b9..a2247867af8 100644 --- a/drivers/usb/host/ohci-xls.c +++ b/drivers/usb/host/ohci-xls.c @@ -40,7 +40,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver,  		goto err1;  	}  	hcd->rsrc_start = res->start; -	hcd->rsrc_len = res->end - res->start + 1; +	hcd->rsrc_len = resource_size(res);  	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,  			driver->description)) { diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 0795b934d00..8ff6f7ea96f 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -344,6 +344,12 @@ typedef struct urb_priv {   * a subset of what the full implementation needs. (Linus)   */ +enum ohci_rh_state { +	OHCI_RH_HALTED, +	OHCI_RH_SUSPENDED, +	OHCI_RH_RUNNING +}; +  struct ohci_hcd {  	spinlock_t		lock; @@ -384,6 +390,7 @@ struct ohci_hcd {  	/*  	 * driver state  	 */ +	enum ohci_rh_state	rh_state;  	int			num_ports;  	int			load [NUM_INTS];  	u32			hc_control;	/* copy of hc control reg */ @@ -679,11 +686,6 @@ static inline u16 ohci_hwPSW(const struct ohci_hcd *ohci,  /*-------------------------------------------------------------------------*/ -static inline void disable (struct ohci_hcd *ohci) -{ -	ohci_to_hcd(ohci)->state = HC_STATE_HALT; -} -  #define	FI			0x2edf		/* 12000 bits per frame (-1) */  #define	FSMP(fi)		(0x7fff & ((6 * ((fi) - 210)) / 7))  #define	FIT			(1 << 31) @@ -707,7 +709,7 @@ static inline void periodic_reinit (struct ohci_hcd *ohci)  #define read_roothub(hc, register, mask) ({ \  	u32 temp = ohci_readl (hc, &hc->regs->roothub.register); \  	if (temp == -1) \ -		disable (hc); \ +		hc->rh_state = OHCI_RH_HALTED; \  	else if (hc->flags & OHCI_QUIRK_AMD756) \  		while (temp & mask) \  			temp = ohci_readl (hc, &hc->regs->roothub.register); \ diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index dcd889803f0..6f62de5c6e3 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -3951,24 +3951,7 @@ static struct platform_driver oxu_driver = {  	}  }; -static int __init oxu_module_init(void) -{ -	int retval = 0; - -	retval = platform_driver_register(&oxu_driver); -	if (retval < 0) -		return retval; - -	return retval; -} - -static void __exit oxu_module_cleanup(void) -{ -	platform_driver_unregister(&oxu_driver); -} - -module_init(oxu_module_init); -module_exit(oxu_module_cleanup); +module_platform_driver(oxu_driver);  MODULE_DESCRIPTION("Oxford OXU210HP HCD driver - ver. " DRIVER_VERSION);  MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index f6ca80ee4ce..d2c6f5ac462 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -943,7 +943,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,  	if (usb_pipein(urb->pipe))  		status |= TD_CTRL_SPD; -	i = urb->num_sgs; +	i = urb->num_mapped_sgs;  	if (len > 0 && i > 0) {  		sg = urb->sg;  		data = sg_dma_address(sg); diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index a403b53e86b..76083ae9213 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c @@ -443,7 +443,7 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u  	remaining = urb->transfer_buffer_length; -	for_each_sg(urb->sg, sg, urb->num_sgs, i) { +	for_each_sg(urb->sg, sg, urb->num_mapped_sgs, i) {  		dma_addr_t dma_addr;  		size_t dma_remaining;  		dma_addr_t sp, ep; @@ -561,7 +561,7 @@ static int qset_add_urb_sg_linearize(struct whc *whc, struct whc_qset *qset,  	remaining = urb->transfer_buffer_length; -	for_each_sg(urb->sg, sg, urb->num_sgs, i) { +	for_each_sg(urb->sg, sg, urb->num_mapped_sgs, i) {  		size_t len;  		size_t sg_remaining;  		void *orig; diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 430e88fd3f6..35e257f79c7 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -57,17 +57,15 @@ static void xhci_common_hub_descriptor(struct xhci_hcd *xhci,  	desc->bHubContrCurrent = 0;  	desc->bNbrPorts = ports; -	/* Ugh, these should be #defines, FIXME */ -	/* Using table 11-13 in USB 2.0 spec. */  	temp = 0; -	/* Bits 1:0 - support port power switching, or power always on */ +	/* Bits 1:0 - support per-port power switching, or power always on */  	if (HCC_PPC(xhci->hcc_params)) -		temp |= 0x0001; +		temp |= HUB_CHAR_INDV_PORT_LPSM;  	else -		temp |= 0x0002; +		temp |= HUB_CHAR_NO_LPSM;  	/* Bit  2 - root hubs are not part of a compound device */  	/* Bits 4:3 - individual port over current protection */ -	temp |= 0x0008; +	temp |= HUB_CHAR_INDV_PORT_OCPM;  	/* Bits 6:5 - no TTs in root ports */  	/* Bit  7 - no port indicators */  	desc->wHubCharacteristics = cpu_to_le16(temp); @@ -86,9 +84,9 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,  	ports = xhci->num_usb2_ports;  	xhci_common_hub_descriptor(xhci, desc, ports); -	desc->bDescriptorType = 0x29; +	desc->bDescriptorType = USB_DT_HUB;  	temp = 1 + (ports / 8); -	desc->bDescLength = 7 + 2 * temp; +	desc->bDescLength = USB_DT_HUB_NONVAR_SIZE + 2 * temp;  	/* The Device Removable bits are reported on a byte granularity.  	 * If the port doesn't exist within that byte, the bit is set to 0. @@ -137,8 +135,8 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,  	ports = xhci->num_usb3_ports;  	xhci_common_hub_descriptor(xhci, desc, ports); -	desc->bDescriptorType = 0x2a; -	desc->bDescLength = 12; +	desc->bDescriptorType = USB_DT_SS_HUB; +	desc->bDescLength = USB_DT_SS_HUB_SIZE;  	/* header decode latency should be zero for roothubs,  	 * see section 4.23.5.2. diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 9f1d4b15d81..d030f0b2bfa 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2390,17 +2390,7 @@ hw_died:  irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd)  { -	irqreturn_t ret; -	struct xhci_hcd *xhci; - -	xhci = hcd_to_xhci(hcd); -	set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); -	if (xhci->shared_hcd) -		set_bit(HCD_FLAG_SAW_IRQ, &xhci->shared_hcd->flags); - -	ret = xhci_irq(hcd); - -	return ret; +	return xhci_irq(hcd);  }  /****		Endpoint Ring Operations	****/ @@ -2561,7 +2551,7 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb)  	struct scatterlist *sg;  	sg = NULL; -	num_sgs = urb->num_sgs; +	num_sgs = urb->num_mapped_sgs;  	temp = urb->transfer_buffer_length;  	xhci_dbg(xhci, "count sg list trbs: \n"); @@ -2745,7 +2735,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,  		return -EINVAL;  	num_trbs = count_sg_trbs_needed(xhci, urb); -	num_sgs = urb->num_sgs; +	num_sgs = urb->num_mapped_sgs;  	total_packet_count = roundup(urb->transfer_buffer_length,  			usb_endpoint_maxp(&urb->ep->desc)); diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c index fe1d44319d0..8f725f65191 100644 --- a/drivers/usb/misc/isight_firmware.c +++ b/drivers/usb/misc/isight_firmware.c @@ -55,8 +55,9 @@ static int isight_firmware_load(struct usb_interface *intf,  	ptr = firmware->data; +	buf[0] = 0x01;  	if (usb_control_msg -	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\1", 1, +	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1,  	     300) != 1) {  		printk(KERN_ERR  		       "Failed to initialise isight firmware loader\n"); @@ -100,8 +101,9 @@ static int isight_firmware_load(struct usb_interface *intf,  		}  	} +	buf[0] = 0x00;  	if (usb_control_msg -	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1, +	    (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1,  	     300) != 1) {  		printk(KERN_ERR "isight firmware loading completion failed\n");  		ret = -ENODEV; diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index bd6d00802ea..959145baf3c 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1765,7 +1765,6 @@ static int test_unaligned_bulk(   * off just killing the userspace task and waiting for it to exit.   */ -/* No BKL needed */  static int  usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)  { diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index b63ab157010..227c1dfa6be 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -661,7 +661,6 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb,  		handled = IRQ_HANDLED;  		musb->is_active = 1; -		set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags);  		musb->ep0_stage = MUSB_EP0_START; diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c index 0f420b25e9a..2a52ff1b493 100644 --- a/drivers/usb/otg/fsl_otg.c +++ b/drivers/usb/otg/fsl_otg.c @@ -1151,18 +1151,7 @@ struct platform_driver fsl_otg_driver = {  	},  }; -static int __init fsl_usb_otg_init(void) -{ -	pr_info(DRIVER_INFO "\n"); -	return platform_driver_register(&fsl_otg_driver); -} -module_init(fsl_usb_otg_init); - -static void __exit fsl_usb_otg_exit(void) -{ -	platform_driver_unregister(&fsl_otg_driver); -} -module_exit(fsl_usb_otg_exit); +module_platform_driver(fsl_otg_driver);  MODULE_DESCRIPTION(DRIVER_INFO);  MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 08c679c0dde..aa94e33e688 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -637,18 +637,7 @@ static struct platform_driver renesas_usbhs_driver = {  	.remove		= __devexit_p(usbhs_remove),  }; -static int __init usbhs_init(void) -{ -	return platform_driver_register(&renesas_usbhs_driver); -} - -static void __exit usbhs_exit(void) -{ -	platform_driver_unregister(&renesas_usbhs_driver); -} - -module_init(usbhs_init); -module_exit(usbhs_exit); +module_platform_driver(renesas_usbhs_driver);  MODULE_LICENSE("GPL");  MODULE_DESCRIPTION("Renesas USB driver"); diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index bade761a1e5..75659e0c735 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -1268,7 +1268,7 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv)  		return -ENOMEM;  	} -	pipe_info = kzalloc(sizeof(*pipe_info) * pipe_size, GFP_KERNEL); +	pipe_info = kcalloc(pipe_size, sizeof(*pipe_info), GFP_KERNEL);  	if (!pipe_info) {  		dev_err(dev, "Could not allocate pipe_info\n");  		goto usbhs_mod_host_probe_err; diff --git a/drivers/usb/serial/ChangeLog.history b/drivers/usb/serial/ChangeLog.history deleted file mode 100644 index f13fd488ebe..00000000000 --- a/drivers/usb/serial/ChangeLog.history +++ /dev/null @@ -1,730 +0,0 @@ -This is the contents of some of the drivers/usb/serial/ files that had  old -changelog comments.  They were quite old, and out of date, and we don't keep -them anymore, so I've put them here, away from the source files, in case -people still care to see them. - -- Greg Kroah-Hartman <greg@kroah.com> October 20, 2005 - ------------------------------------------------------------------------ -usb-serial.h Change Log comments: - - (03/26/2002) gkh -	removed the port->tty check from port_paranoia_check() due to serial -	consoles not having a tty device assigned to them. - - (12/03/2001) gkh -	removed active from the port structure. -	added documentation to the usb_serial_device_type structure - - (10/10/2001) gkh -	added vendor and product to serial structure.  Needed to determine device -	owner when the device is disconnected. - - (05/30/2001) gkh -	added sem to port structure and removed port_lock - - (10/05/2000) gkh -	Added interrupt_in_endpointAddress and bulk_in_endpointAddress to help -	fix bug with urb->dev not being set properly, now that the usb core -	needs it. - - (09/11/2000) gkh -	Added usb_serial_debug_data function to help get rid of #DEBUG in the -	drivers. - - (08/28/2000) gkh -	Added port_lock to port structure. - - (08/08/2000) gkh -	Added open_count to port structure. - - (07/23/2000) gkh -	Added bulk_out_endpointAddress to port structure. - - (07/19/2000) gkh, pberger, and borchers -	Modifications to allow usb-serial drivers to be modules. - ------------------------------------------------------------------------ -usb-serial.c Change Log comments: - - (12/10/2002) gkh -	Split the ports off into their own struct device, and added a -	usb-serial bus driver. - - (11/19/2002) gkh -	removed a few #ifdefs for the generic code and cleaned up the failure -	logic in initialization. - - (10/02/2002) gkh -	moved the console code to console.c and out of this file. - - (06/05/2002) gkh -	moved location of startup() call in serial_probe() until after all -	of the port information and endpoints are initialized.  This makes -	things easier for some drivers. - - (04/10/2002) gkh -	added serial_read_proc function which creates a -	/proc/tty/driver/usb-serial file. - - (03/27/2002) gkh -	Got USB serial console code working properly and merged into the main -	version of the tree.  Thanks to Randy Dunlap for the initial version -	of this code, and for pushing me to finish it up. -	The USB serial console works with any usb serial driver device. - - (03/21/2002) gkh -	Moved all manipulation of port->open_count into the core.  Now the -	individual driver's open and close functions are called only when the -	first open() and last close() is called.  Making the drivers a bit -	smaller and simpler. -	Fixed a bug if a driver didn't have the owner field set. - - (02/26/2002) gkh -	Moved all locking into the main serial_* functions, instead of having -	the individual drivers have to grab the port semaphore.  This should -	reduce races. -	Reworked the MOD_INC logic a bit to always increment and decrement, even -	if the generic driver is being used. - - (10/10/2001) gkh -	usb_serial_disconnect() now sets the serial->dev pointer is to NULL to -	help prevent child drivers from accessing the device since it is now -	gone. - - (09/13/2001) gkh -	Moved generic driver initialize after we have registered with the USB -	core.  Thanks to Randy Dunlap for pointing this problem out. - - (07/03/2001) gkh -	Fixed module paramater size.  Thanks to John Brockmeyer for the pointer. -	Fixed vendor and product getting defined through the MODULE_PARM macro -	if the Generic driver wasn't compiled in. -	Fixed problem with generic_shutdown() not being called for drivers that -	don't have a shutdown() function. - - (06/06/2001) gkh -	added evil hack that is needed for the prolific pl2303 device due to the -	crazy way its endpoints are set up. - - (05/30/2001) gkh -	switched from using spinlock to a semaphore, which fixes lots of problems. - - (04/08/2001) gb -	Identify version on module load. - - 2001_02_05 gkh -	Fixed buffer overflows bug with the generic serial driver.  Thanks to -	Todd Squires <squirest@ct0.com> for fixing this. - - (01/10/2001) gkh -	Fixed bug where the generic serial adaptor grabbed _any_ device that was -	offered to it. - - (12/12/2000) gkh -	Removed MOD_INC and MOD_DEC from poll and disconnect functions, and -	moved them to the serial_open and serial_close functions. -	Also fixed bug with there not being a MOD_DEC for the generic driver -	(thanks to Gary Brubaker for finding this.) - - (11/29/2000) gkh -	Small NULL pointer initialization cleanup which saves a bit of disk image - - (11/01/2000) Adam J. Richter -	instead of using idVendor/idProduct pairs, usb serial drivers -	now identify their hardware interest with usb_device_id tables, -	which they usually have anyhow for use with MODULE_DEVICE_TABLE. - - (10/05/2000) gkh -	Fixed bug with urb->dev not being set properly, now that the usb -	core needs it. - - (09/11/2000) gkh -	Removed DEBUG #ifdefs with call to usb_serial_debug_data - - (08/28/2000) gkh -	Added port_lock to port structure. -	Added locks for SMP safeness to generic driver -	Fixed the ability to open a generic device's port more than once. - - (07/23/2000) gkh -	Added bulk_out_endpointAddress to port structure. - - (07/19/2000) gkh, pberger, and borchers -	Modifications to allow usb-serial drivers to be modules. - - (07/03/2000) gkh -	Added more debugging to serial_ioctl call - - (06/25/2000) gkh -	Changed generic_write_bulk_callback to not call wake_up_interruptible -	directly, but to have port_softint do it at a safer time. - - (06/23/2000) gkh -	Cleaned up debugging statements in a quest to find UHCI timeout bug. - - (05/22/2000) gkh -	Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be -	removed from the individual device source files. - - (05/03/2000) gkh -	Added the Digi Acceleport driver from Al Borchers and Peter Berger. - - (05/02/2000) gkh -	Changed devfs and tty register code to work properly now. This was based on -	the ACM driver changes by Vojtech Pavlik. - - (04/27/2000) Ryan VanderBijl - 	Put calls to *_paranoia_checks into one function. - - (04/23/2000) gkh -	Fixed bug that Randy Dunlap found for Generic devices with no bulk out ports. -	Moved when the startup code printed out the devices that are supported. - - (04/19/2000) gkh -	Added driver for ZyXEL omni.net lcd plus ISDN TA -	Made startup info message specify which drivers were compiled in. - - (04/03/2000) gkh -	Changed the probe process to remove the module unload races. -	Changed where the tty layer gets initialized to have devfs work nicer. -	Added initial devfs support. - - (03/26/2000) gkh -	Split driver up into device specific pieces. - - (03/19/2000) gkh -	Fixed oops that could happen when device was removed while a program -	was talking to the device. -	Removed the static urbs and now all urbs are created and destroyed -	dynamically. -	Reworked the internal interface. Now everything is based on the -	usb_serial_port structure instead of the larger usb_serial structure. -	This fixes the bug that a multiport device could not have more than -	one port open at one time. - - (03/17/2000) gkh -	Added config option for debugging messages. -	Added patch for keyspan pda from Brian Warner. - - (03/06/2000) gkh -	Added the keyspan pda code from Brian Warner <warner@lothar.com> -	Moved a bunch of the port specific stuff into its own structure. This -	is in anticipation of the true multiport devices (there's a bug if you -	try to access more than one port of any multiport device right now) - - (02/21/2000) gkh -	Made it so that any serial devices only have to specify which functions -	they want to overload from the generic function calls (great, -	inheritance in C, in a driver, just what I wanted...) -	Added support for set_termios and ioctl function calls. No drivers take -	advantage of this yet. -	Removed the #ifdef MODULE, now there is no module specific code. -	Cleaned up a few comments in usb-serial.h that were wrong (thanks again -	to Miles Lott). -	Small fix to get_free_serial. - - (02/14/2000) gkh -	Removed the Belkin and Peracom functionality from the driver due to -	the lack of support from the vendor, and me not wanting people to -	accidenatly buy the device, expecting it to work with Linux. -	Added read_bulk_callback and write_bulk_callback to the type structure -	for the needs of the FTDI and WhiteHEAT driver. -	Changed all reverences to FTDI to FTDI_SIO at the request of Bill -	Ryder. -	Changed the output urb size back to the max endpoint size to make -	the ftdi_sio driver have it easier, and due to the fact that it didn't -	really increase the speed any. - - (02/11/2000) gkh -	Added VISOR_FUNCTION_CONSOLE to the visor startup function. This was a -	patch from Miles Lott (milos@insync.net). -	Fixed bug with not restoring the minor range that a device grabs, if -	the startup function fails (thanks Miles for finding this). - - (02/05/2000) gkh -	Added initial framework for the Keyspan PDA serial converter so that -	Brian Warner has a place to put his code. -	Made the ezusb specific functions generic enough that different -	devices can use them (whiteheat and keyspan_pda both need them). -	Split out a whole bunch of structure and other stuff to a separate -	usb-serial.h file. -	Made the Visor connection messages a little more understandable, now -	that Miles Lott (milos@insync.net) has gotten the Generic channel to -	work. Also made them always show up in the log file. - - (01/25/2000) gkh -	Added initial framework for FTDI serial converter so that Bill Ryder -	has a place to put his code. -	Added the vendor specific info from Handspring. Now we can print out -	informational debug messages as well as understand what is happening. - - (01/23/2000) gkh -	Fixed problem of crash when trying to open a port that didn't have a -	device assigned to it. Made the minor node finding a little smarter, -	now it looks to find a continuous space for the new device. - - (01/21/2000) gkh -	Fixed bug in visor_startup with patch from Miles Lott (milos@insync.net) -	Fixed get_serial_by_minor which was all messed up for multi port -	devices. Fixed multi port problem for generic devices. Now the number -	of ports is determined by the number of bulk out endpoints for the -	generic device. - - (01/19/2000) gkh -	Removed lots of cruft that was around from the old (pre urb) driver -	interface. -	Made the serial_table dynamic. This should save lots of memory when -	the number of minor nodes goes up to 256. -	Added initial support for devices that have more than one port. -	Added more debugging comments for the Visor, and added a needed -	set_configuration call. - - (01/17/2000) gkh -	Fixed the WhiteHEAT firmware (my processing tool had a bug) -	and added new debug loader firmware for it. -	Removed the put_char function as it isn't really needed. -	Added visor startup commands as found by the Win98 dump. - - (01/13/2000) gkh -	Fixed the vendor id for the generic driver to the one I meant it to be. - - (01/12/2000) gkh -	Forget the version numbering...that's pretty useless... -	Made the driver able to be compiled so that the user can select which -	converter they want to use. This allows people who only want the Visor -	support to not pay the memory size price of the WhiteHEAT. -	Fixed bug where the generic driver (idVendor=0000 and idProduct=0000) -	grabbed the root hub. Not good. - - version 0.4.0 (01/10/2000) gkh -	Added whiteheat.h containing the firmware for the ConnectTech WhiteHEAT -	device. Added startup function to allow firmware to be downloaded to -	a device if it needs to be. -	Added firmware download logic to the WhiteHEAT device. -	Started to add #defines to split up the different drivers for potential -	configuration option. - - version 0.3.1 (12/30/99) gkh -      Fixed problems with urb for bulk out. -      Added initial support for multiple sets of endpoints. This enables -      the Handspring Visor to be attached successfully. Only the first -      bulk in / bulk out endpoint pair is being used right now. - - version 0.3.0 (12/27/99) gkh -	Added initial support for the Handspring Visor based on a patch from -	Miles Lott (milos@sneety.insync.net) -	Cleaned up the code a bunch and converted over to using urbs only. - - version 0.2.3 (12/21/99) gkh -	Added initial support for the Connect Tech WhiteHEAT converter. -	Incremented the number of ports in expectation of getting the -	WhiteHEAT to work properly (4 ports per connection). -	Added notification on insertion and removal of what port the -	device is/was connected to (and what kind of device it was). - - version 0.2.2 (12/16/99) gkh -	Changed major number to the new allocated number. We're legal now! - - version 0.2.1 (12/14/99) gkh -	Fixed bug that happens when device node is opened when there isn't a -	device attached to it. Thanks to marek@webdesign.no for noticing this. - - version 0.2.0 (11/10/99) gkh -	Split up internals to make it easier to add different types of serial -	converters to the code. -	Added a "generic" driver that gets it's vendor and product id -	from when the module is loaded. Thanks to David E. Nelson (dnelson@jump.net) -	for the idea and sample code (from the usb scanner driver.) -	Cleared up any licensing questions by releasing it under the GNU GPL. - - version 0.1.2 (10/25/99) gkh - 	Fixed bug in detecting device. - - version 0.1.1 (10/05/99) gkh - 	Changed the major number to not conflict with anything else. - - version 0.1 (09/28/99) gkh - 	Can recognize the two different devices and start up a read from -	device when asked to. Writes also work. No control signals yet, this -	all is vendor specific data (i.e. no spec), also no control for -	different baud rates or other bit settings. -	Currently we are using the same devid as the acm driver. This needs -	to change. - ------------------------------------------------------------------------ -visor.c Change Log comments: - - (06/03/2003) Judd Montgomery <judd at jpilot.org> -     Added support for module parameter options for untested/unknown -     devices. - - (03/09/2003) gkh -	Added support for the Sony Clie NZ90V device.  Thanks to Martin Brachtl -	<brachtl@redgrep.cz> for the information. - - (03/05/2003) gkh -	Think Treo support is now working. - - (04/03/2002) gkh -	Added support for the Sony OS 4.1 devices.  Thanks to Hiroyuki ARAKI -	<hiro@zob.ne.jp> for the information. - - (03/27/2002) gkh -	Removed assumptions that port->tty was always valid (is not true -	for usb serial console devices.) - - (03/23/2002) gkh -	Added support for the Palm i705 device, thanks to Thomas Riemer -	<tom@netmech.com> for the information. - - (03/21/2002) gkh -	Added support for the Palm m130 device, thanks to Udo Eisenbarth -	<udo.eisenbarth@web.de> for the information. - - (02/27/2002) gkh -	Reworked the urb handling logic.  We have no more pool, but dynamically -	allocate the urb and the transfer buffer on the fly.  In testing this -	does not incure any measurable overhead.  This also relies on the fact -	that we have proper reference counting logic for urbs. - - (02/21/2002) SilaS -  Added initial support for the Palm m515 devices. - - (02/14/2002) gkh -	Added support for the Clie S-360 device. - - (12/18/2001) gkh -	Added better Clie support for 3.5 devices.  Thanks to Geoffrey Levand -	for the patch. - - (11/11/2001) gkh -	Added support for the m125 devices, and added check to prevent oopses -	for Clié devices that lie about the number of ports they have. - - (08/30/2001) gkh -	Added support for the Clie devices, both the 3.5 and 4.0 os versions. -	Many thanks to Daniel Burke, and Bryan Payne for helping with this. - - (08/23/2001) gkh -	fixed a few potential bugs pointed out by Oliver Neukum. - - (05/30/2001) gkh -	switched from using spinlock to a semaphore, which fixes lots of problems. - - (05/28/2000) gkh -	Added initial support for the Palm m500 and Palm m505 devices. - - (04/08/2001) gb -	Identify version on module load. - - (01/21/2000) gkh -	Added write_room and chars_in_buffer, as they were previously using the -	generic driver versions which is all wrong now that we are using an urb -	pool.  Thanks to Wolfgang Grandegger for pointing this out to me. -	Removed count assignment in the write function, which was not needed anymore -	either.  Thanks to Al Borchers for pointing this out. - - (12/12/2000) gkh -	Moved MOD_DEC to end of visor_close to be nicer, as the final write -	message can sleep. - - (11/12/2000) gkh -	Fixed bug with data being dropped on the floor by forcing tty->low_latency -	to be on.  Hopefully this fixes the OHCI issue! - - (11/01/2000) Adam J. Richter -	usb_device_id table support - - (10/05/2000) gkh -	Fixed bug with urb->dev not being set properly, now that the usb -	core needs it. - - (09/11/2000) gkh -	Got rid of always calling kmalloc for every urb we wrote out to the -	device. -	Added visor_read_callback so we can keep track of bytes in and out for -	those people who like to know the speed of their device. -	Removed DEBUG #ifdefs with call to usb_serial_debug_data - - (09/06/2000) gkh -	Fixed oops in visor_exit.  Need to uncomment usb_unlink_urb call _after_ -	the host controller drivers set urb->dev = NULL when the urb is finished. - - (08/28/2000) gkh -	Added locks for SMP safeness. - - (08/08/2000) gkh -	Fixed endian problem in visor_startup. -	Fixed MOD_INC and MOD_DEC logic and the ability to open a port more -	than once. - - (07/23/2000) gkh -	Added pool of write urbs to speed up transfers to the visor. - - (07/19/2000) gkh -	Added module_init and module_exit functions to handle the fact that this -	driver is a loadable module now. - - (07/03/2000) gkh -	Added visor_set_ioctl and visor_set_termios functions (they don't do much -	of anything, but are good for debugging.) - - (06/25/2000) gkh -	Fixed bug in visor_unthrottle that should help with the disconnect in PPP -	bug that people have been reporting. - - (06/23/2000) gkh -	Cleaned up debugging statements in a quest to find UHCI timeout bug. - - (04/27/2000) Ryan VanderBijl - 	Fixed memory leak in visor_close - - (03/26/2000) gkh -	Split driver up into device specific pieces. - ------------------------------------------------------------------------ -pl2303.c Change Log comments: - - 2002_Mar_26 gkh -	allowed driver to work properly if there is no tty assigned to a port -	(this happens for serial console devices.) - - 2001_Oct_06 gkh -	Added RTS and DTR line control.  Thanks to joe@bndlg.de for parts of it. - - 2001_Sep_19 gkh -	Added break support. - - 2001_Aug_30 gkh -	fixed oops in write_bulk_callback. - - 2001_Aug_28 gkh -	reworked buffer logic to be like other usb-serial drivers.  Hopefully -	removing some reported problems. - - 2001_Jun_06 gkh -	finished porting to 2.4 format. - - ------------------------------------------------------------------------ -io_edgeport.c Change Log comments: - - 2003_04_03 al borchers -  - fixed a bug (that shows up with dosemu) where the tty struct is -    used in a callback after it has been freed - - 2.3 2002_03_08 greg kroah-hartman -	- fixed bug when multiple devices were attached at the same time. - - 2.2 2001_11_14 greg kroah-hartman -	- fixed bug in edge_close that kept the port from being used more -	  than once. -	- fixed memory leak on device removal. -	- fixed potential double free of memory when command urb submitting -	  failed. -	- other small cleanups when the device is removed - - 2.1 2001_07_09 greg kroah-hartman -	- added support for TIOCMBIS and TIOCMBIC. - -     (04/08/2001) gb -	- Identify version on module load. - - 2.0 2001_03_05 greg kroah-hartman -	- reworked entire driver to fit properly in with the other usb-serial -	  drivers.  Occasional oopses still happen, but it's a good start. - - 1.2.3 (02/23/2001) greg kroah-hartman -	- changed device table to work properly for 2.4.x final format. -	- fixed problem with dropping data at high data rates. - - 1.2.2 (11/27/2000) greg kroah-hartman -	- cleaned up more NTisms. -	- Added device table for 2.4.0-test11 - - 1.2.1 (11/08/2000) greg kroah-hartman -	- Started to clean up NTisms. -	- Fixed problem with dev field of urb for kernels >= 2.4.0-test9 - - 1.2 (10/17/2000) David Iacovelli - 	Remove all EPIC code and GPL source -  Fix RELEVANT_IFLAG macro to include flow control -  changes port configuration changes. -  Fix redefinition of SERIAL_MAGIC -  Change all timeout values to 5 seconds -  Tried to fix the UHCI multiple urb submission, but failed miserably. -  it seems to work fine with OHCI. -  ( Greg take a look at the #if 0 at end of WriteCmdUsb() we must -    find a way to work arount this UHCI bug ) - - 1.1 (10/11/2000) David Iacovelli -  Fix XON/XOFF flow control to support both IXON and IXOFF - - 0.9.27 (06/30/2000) David Iacovelli -  Added transmit queue and now allocate urb for command writes. - - 0.9.26 (06/29/2000) David Iacovelli -  Add support for 80251 based edgeport - - 0.9.25 (06/27/2000) David Iacovelli -  Do not close the port if it has multiple opens. - - 0.9.24 (05/26/2000) David Iacovelli -  Add IOCTLs to support RXTX and JAVA POS -  and first cut at running BlackBox Demo - - 0.9.23 (05/24/2000) David Iacovelli -  Add IOCTLs to support RXTX and JAVA POS - - 0.9.22 (05/23/2000) David Iacovelli -  fixed bug in enumeration.  If epconfig turns on mapping by -  path after a device is already plugged in, we now update -  the mapping correctly - - 0.9.21 (05/16/2000) David Iacovelli -  Added BlockUntilChaseResp() to also wait for txcredits -  Updated the way we allocate and handle write URBs -	Add debug code to dump buffers - - 0.9.20 (05/01/2000) David Iacovelli -	change driver to use usb/tts/ - - 0.9.19 (05/01/2000) David Iacovelli -  Update code to compile if DEBUG is off - - 0.9.18 (04/28/2000) David Iacovelli -  cleanup and test tty_register with devfs - - 0.9.17 (04/27/2000) greg kroah-hartman - 	changed tty_register around to be like the way it - 	was before, but now it works properly with devfs. - - 0.9.16 (04/26/2000) david iacovelli -  Fixed bug in GetProductInfo() - - 0.9.15 (04/25/2000) david iacovelli -	Updated enumeration - - 0.9.14 (04/24/2000) david iacovelli -  Removed all config/status IOCTLS and -  converted to using /proc/edgeport -  still playing with devfs - - 0.9.13 (04/24/2000) david iacovelli -  Removed configuration based on ttyUSB0 -  Added support for configuration using /prod/edgeport -  first attempt at using devfs (not working yet!) -  Added IOCTL to GetProductInfo() -  Added support for custom baud rates -	Add support for random port numbers - - 0.9.12 (04/18/2000) david iacovelli -	added additional configuration IOCTLs -  use ttyUSB0 for configuration - - 0.9.11 (04/17/2000) greg kroah-hartman -	fixed module initialization race conditions. -	made all urbs dynamically allocated. -	made driver devfs compatible. now it only registers the tty device -	when the device is actually plugged in. - - 0.9.10 (04/13/2000) greg kroah-hartman -	added proc interface framework. - - 0.9.9 (04/13/2000) david iacovelli -	added enumeration code and ioctls to configure the device - - 0.9.8 (04/12/2000) david iacovelli -  Change interrupt read start when device is plugged in -  and stop when device is removed -	process interrupt reads when all ports are closed -  (keep value of rxBytesAvail consistent with the edgeport) -  set the USB_BULK_QUEUE flag so that we can shove a bunch -  of urbs at once down the pipe - - 0.9.7 (04/10/2000) david iacovelli - 	start to add enumeration code. -  generate serial number for epic devices -  add support for kdb - - 0.9.6 (03/30/2000) david iacovelli -  add IOCTL to get string, manufacture, and boot descriptors - - 0.9.5 (03/14/2000) greg kroah-hartman -	more error checking added to SerialOpen to try to fix UHCI open problem - - 0.9.4 (03/09/2000) greg kroah-hartman -	added more error checking to handle oops when data is hanging -	around and tty is abruptly closed. - - 0.9.3 (03/09/2000) david iacovelli -	Add epic support for xon/xoff chars -	play with performance - - 0.9.2 (03/08/2000) greg kroah-hartman -	changed most "info" calls to "dbg" -	implemented flow control properly in the termios call - - 0.9.1 (03/08/2000) david iacovelli -	added EPIC support -	enabled bootloader update - - 0.9 (03/08/2000) greg kroah-hartman -	Release to IO networks. -	Integrated changes that David made -  made getting urbs for writing SMP safe - - 0.8 (03/07/2000) greg kroah-hartman -	Release to IO networks. -	Fixed problems that were seen in code by David. -  Now both Edgeport/4 and Edgeport/2 works properly. -  Changed most of the functions to use port instead of serial. - - 0.7 (02/27/2000) greg kroah-hartman -	Milestone 3 release. -	Release to IO Networks -	ioctl for waiting on line change implemented. -	ioctl for getting statistics implemented. -	multiport support working. -	lsr and msr registers are now handled properly. -	change break now hooked up and working. -	support for all known Edgeport devices. - - 0.6 (02/22/2000) greg kroah-hartman -	Release to IO networks. -	CHASE is implemented correctly when port is closed. -	SerialOpen now blocks correctly until port is fully opened. - - 0.5 (02/20/2000) greg kroah-hartman -	Release to IO networks. -	Known problems: -		modem status register changes are not sent on to the user -		CHASE is not implemented when the port is closed. - - 0.4 (02/16/2000) greg kroah-hartman -	Second cut at the CeBit demo. -	Doesn't leak memory on every write to the port -	Still small leaks on startup. -	Added support for Edgeport/2 and Edgeport/8 - - 0.3 (02/15/2000) greg kroah-hartman -	CeBit demo release. -	Force the line settings to 4800, 8, 1, e for the demo. -	Warning! This version leaks memory like crazy! - - 0.2 (01/30/2000) greg kroah-hartman -	Milestone 1 release. -	Device is found by USB subsystem, enumerated, firmware is downloaded -	and the descriptors are printed to the debug log, config is set, and -	green light starts to blink. Open port works, and data can be sent -	and received at the default settings of the UART. Loopback connector -	and debug log confirms this. - - 0.1 (01/23/2000) greg kroah-hartman -	Initial release to help IO Networks try to set up their test system. -	Edgeport4 is recognized, firmware is downloaded, config is set so -	device blinks green light every 3 sec. Port is bound, but opening, -	closing, and sending data do not work properly. - - diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index d6921fa1403..f9f29b289f2 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -20,50 +20,7 @@   * TODO:   * -- Add true modem contol line query capability.  Currently we track the   *    states reported by the interrupt and the states we request. - * -- Add error reporting back to application for UART error conditions. - *    Just point me at how to implement this and I'll do it. I've put the - *    framework in, but haven't analyzed the "tty_flip" interface yet.   * -- Add support for flush commands - * -- Add everything that is missing :) - * - * 27-Nov-2001 gkh - * 	compressed all the differnent device entries into 1. - * - * 30-May-2001 gkh - *	switched from using spinlock to a semaphore, which fixes lots of - *	problems. - * - * 08-Apr-2001 gb - *	- Identify version on module load. - * - * 12-Mar-2001 gkh - *	- Added support for the GoHubs GO-COM232 device which is the same as the - *	  Peracom device. - * - * 06-Nov-2000 gkh - *	- Added support for the old Belkin and Peracom devices. - *	- Made the port able to be opened multiple times. - *	- Added some defaults incase the line settings are things these devices - *	  can't support. - * - * 18-Oct-2000 William Greathouse - *    Released into the wild (linux-usb-devel) - * - * 17-Oct-2000 William Greathouse - *    Add code to recognize firmware version and set hardware flow control - *    appropriately.  Belkin states that firmware prior to 3.05 does not - *    operate correctly in hardware handshake mode.  I have verified this - *    on firmware 2.05 -- for both RTS and DTR input flow control, the control - *    line is not reset.  The test performed by the Belkin Win* driver is - *    to enable hardware flow control for firmware 2.06 or greater and - *    for 1.00 or prior.  I am only enabling for 2.06 or greater. - * - * 12-Oct-2000 William Greathouse - *    First cut at supporting Belkin USB Serial Adapter F5U103 - *    I did not have a copy of the original work to support this - *    adapter, so pardon any stupid mistakes.  All of the information - *    I am using to write this driver was acquired by using a modified - *    UsbSnoop on Windows2000 and from examining the other USB drivers.   */  #include <linux/kernel.h> diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 6ae1c0688b5..0e77511060c 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -335,13 +335,12 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)  		goto out;  	dbg("%s - submitting interrupt urb", __func__); -	port->interrupt_in_urb->dev = serial->dev;  	r = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);  	if (r) {  		dev_err(&port->dev, "%s - failed submitting interrupt urb,"  			" error %d\n", __func__, r);  		ch341_close(port); -		return -EPROTO; +		goto out;  	}  	r = usb_serial_generic_open(tty, port); diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index fd67cc53545..7175bb107de 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -280,7 +280,10 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,  		dbg("%s - Unable to send config request, "  				"request=0x%x size=%d result=%d\n",  				__func__, request, size, result); -		return -EPROTO; +		if (result > 0) +			result = -EPROTO; + +		return result;  	}  	return 0; @@ -331,7 +334,10 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,  		dbg("%s - Unable to send request, "  				"request=0x%x size=%d result=%d\n",  				__func__, request, size, result); -		return -EPROTO; +		if (result > 0) +			result = -EPROTO; + +		return result;  	}  	return 0; @@ -395,10 +401,11 @@ static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)  	dbg("%s - port %d", __func__, port->number); -	if (cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_ENABLE)) { -		dev_err(&port->dev, "%s - Unable to enable UART\n", -				__func__); -		return -EPROTO; +	result = cp210x_set_config_single(port, CP210X_IFC_ENABLE, +								UART_ENABLE); +	if (result) { +		dev_err(&port->dev, "%s - Unable to enable UART\n", __func__); +		return result;  	}  	result = usb_serial_generic_open(tty, port); @@ -520,18 +527,13 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,  		cflag |= PARENB;  		break;  	case BITS_PARITY_MARK: -		dbg("%s - parity = MARK (not supported, disabling parity)", -				__func__); -		cflag &= ~PARENB; -		bits &= ~BITS_PARITY_MASK; -		cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); +		dbg("%s - parity = MARK", __func__); +		cflag |= (PARENB|PARODD|CMSPAR);  		break;  	case BITS_PARITY_SPACE: -		dbg("%s - parity = SPACE (not supported, disabling parity)", -				__func__); -		cflag &= ~PARENB; -		bits &= ~BITS_PARITY_MASK; -		cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2); +		dbg("%s - parity = SPACE", __func__); +		cflag &= ~PARODD; +		cflag |= (PARENB|CMSPAR);  		break;  	default:  		dbg("%s - Unknown parity mode, disabling parity", __func__); @@ -588,7 +590,6 @@ static void cp210x_set_termios(struct tty_struct *tty,  	if (!tty)  		return; -	tty->termios->c_cflag &= ~CMSPAR;  	cflag = tty->termios->c_cflag;  	old_cflag = old_termios->c_cflag;  	baud = cp210x_quantise_baudrate(tty_get_baud_rate(tty)); @@ -643,16 +644,27 @@ static void cp210x_set_termios(struct tty_struct *tty,  					"not supported by device\n");  	} -	if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { +	if ((cflag     & (PARENB|PARODD|CMSPAR)) != +	    (old_cflag & (PARENB|PARODD|CMSPAR))) {  		cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);  		bits &= ~BITS_PARITY_MASK;  		if (cflag & PARENB) { -			if (cflag & PARODD) { -				bits |= BITS_PARITY_ODD; -				dbg("%s - parity = ODD", __func__); +			if (cflag & CMSPAR) { +			    if (cflag & PARODD) { +				    bits |= BITS_PARITY_MARK; +				    dbg("%s - parity = MARK", __func__); +			    } else { +				    bits |= BITS_PARITY_SPACE; +				    dbg("%s - parity = SPACE", __func__); +			    }  			} else { -				bits |= BITS_PARITY_EVEN; -				dbg("%s - parity = EVEN", __func__); +			    if (cflag & PARODD) { +				    bits |= BITS_PARITY_ODD; +				    dbg("%s - parity = ODD", __func__); +			    } else { +				    bits |= BITS_PARITY_EVEN; +				    dbg("%s - parity = EVEN", __func__); +			    }  			}  		}  		if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index f744ab7a3b1..98bf8334983 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -138,7 +138,6 @@ static int cyberjack_startup(struct usb_serial *serial)  	for (i = 0; i < serial->num_ports; ++i) {  		int result; -		serial->port[i]->interrupt_in_urb->dev = serial->dev;  		result = usb_submit_urb(serial->port[i]->interrupt_in_urb,  					GFP_KERNEL);  		if (result) @@ -208,7 +207,6 @@ static void cyberjack_close(struct usb_serial_port *port)  static int cyberjack_write(struct tty_struct *tty,  	struct usb_serial_port *port, const unsigned char *buf, int count)  { -	struct usb_serial *serial = port->serial;  	struct cyberjack_private *priv = usb_get_serial_port_data(port);  	unsigned long flags;  	int result; @@ -221,22 +219,18 @@ static int cyberjack_write(struct tty_struct *tty,  		return 0;  	} -	spin_lock_bh(&port->lock); -	if (port->write_urb_busy) { -		spin_unlock_bh(&port->lock); +	if (!test_and_clear_bit(0, &port->write_urbs_free)) {  		dbg("%s - already writing", __func__);  		return 0;  	} -	port->write_urb_busy = 1; -	spin_unlock_bh(&port->lock);  	spin_lock_irqsave(&priv->lock, flags);  	if (count+priv->wrfilled > sizeof(priv->wrbuf)) {  		/* To much data for buffer. Reset buffer. */  		priv->wrfilled = 0; -		port->write_urb_busy = 0;  		spin_unlock_irqrestore(&priv->lock, flags); +		set_bit(0, &port->write_urbs_free);  		return 0;  	} @@ -265,13 +259,7 @@ static int cyberjack_write(struct tty_struct *tty,  		priv->wrsent = length;  		/* set up our urb */ -		usb_fill_bulk_urb(port->write_urb, serial->dev, -			      usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), -			      port->write_urb->transfer_buffer, length, -			      ((serial->type->write_bulk_callback) ? -			       serial->type->write_bulk_callback : -			       cyberjack_write_bulk_callback), -			      port); +		port->write_urb->transfer_buffer_length = length;  		/* send the data out the bulk port */  		result = usb_submit_urb(port->write_urb, GFP_ATOMIC); @@ -283,7 +271,7 @@ static int cyberjack_write(struct tty_struct *tty,  			priv->wrfilled = 0;  			priv->wrsent = 0;  			spin_unlock_irqrestore(&priv->lock, flags); -			port->write_urb_busy = 0; +			set_bit(0, &port->write_urbs_free);  			return 0;  		} @@ -351,7 +339,6 @@ static void cyberjack_read_int_callback(struct urb *urb)  		spin_unlock(&priv->lock);  		if (!old_rdtodo) { -			port->read_urb->dev = port->serial->dev;  			result = usb_submit_urb(port->read_urb, GFP_ATOMIC);  			if (result)  				dev_err(&port->dev, "%s - failed resubmitting " @@ -362,7 +349,6 @@ static void cyberjack_read_int_callback(struct urb *urb)  	}  resubmit: -	port->interrupt_in_urb->dev = port->serial->dev;  	result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);  	if (result)  		dev_err(&port->dev, "usb_submit_urb(read int) failed\n"); @@ -415,7 +401,6 @@ static void cyberjack_read_bulk_callback(struct urb *urb)  	/* Continue to read if we have still urbs to do. */  	if (todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/) { -		port->read_urb->dev = port->serial->dev;  		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);  		if (result)  			dev_err(&port->dev, "%s - failed resubmitting read " @@ -432,7 +417,7 @@ static void cyberjack_write_bulk_callback(struct urb *urb)  	dbg("%s - port %d", __func__, port->number); -	port->write_urb_busy = 0; +	set_bit(0, &port->write_urbs_free);  	if (status) {  		dbg("%s - nonzero write bulk status received: %d",  		    __func__, status); @@ -455,13 +440,7 @@ static void cyberjack_write_bulk_callback(struct urb *urb)  		priv->wrsent += length;  		/* set up our urb */ -		usb_fill_bulk_urb(port->write_urb, port->serial->dev, -			      usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress), -			      port->write_urb->transfer_buffer, length, -			      ((port->serial->type->write_bulk_callback) ? -			       port->serial->type->write_bulk_callback : -			       cyberjack_write_bulk_callback), -			      port); +		port->write_urb->transfer_buffer_length = length;  		/* send the data out the bulk port */  		result = usb_submit_urb(port->write_urb, GFP_ATOMIC); diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index d9906eb9d16..07680d6b792 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -16,32 +16,6 @@   *   * See http://geocities.com/i0xox0i for information on this driver and the   * earthmate usb device. - * - *  Lonnie Mendez <dignome@gmail.com> - *  4-29-2005 - *	Fixed problem where setting or retreiving the serial config would fail - *	with EPIPE.  Removed CRTS toggling so the driver behaves more like - *	other usbserial adapters.  Issued new interval of 1ms instead of the - *	default 10ms.  As a result, transfer speed has been substantially - *	increased from avg. 850bps to avg. 3300bps.  initial termios has also - *	been modified.  Cleaned up code and formatting issues so it is more - *	readable.  Replaced the C++ style comments. - * - *  Lonnie Mendez <dignome@gmail.com> - *  12-15-2004 - *	Incorporated write buffering from pl2303 driver.  Fixed bug with line - *	handling so both lines are raised in cypress_open. (was dropping rts) - *      Various code cleanups made as well along with other misc bug fixes. - * - *  Lonnie Mendez <dignome@gmail.com> - *  04-10-2004 - *	Driver modified to support dynamic line settings.  Various improvements - *      and features. - * - *  Neil Whelchel - *  10-2003 - *	Driver first released. - *   */  /* Thanks to Neil Whelchel for writing the first cypress m8 implementation @@ -1162,8 +1136,6 @@ static void cypress_unthrottle(struct tty_struct *tty)  		return;  	if (actually_throttled) { -		port->interrupt_in_urb->dev = port->serial->dev; -  		result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);  		if (result) {  			dev_err(&port->dev, "%s - failed submitting read urb, " @@ -1352,7 +1324,6 @@ static void cypress_write_int_callback(struct urb *urb)  		dbg("%s - nonzero write bulk status received: %d",  			__func__, status);  		port->interrupt_out_urb->transfer_buffer_length = 1; -		port->interrupt_out_urb->dev = port->serial->dev;  		result = usb_submit_urb(port->interrupt_out_urb, GFP_ATOMIC);  		if (!result)  			return; diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index e92cbefc0f8..6d26a77d0f2 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -13,222 +13,6 @@  *  *  Peter Berger (pberger@brimson.com)  *  Al Borchers (borchers@steinerpoint.com) -*  -* (12/03/2001) gkh -*	switched to using port->port.count instead of private version. -*	Removed port->active -* -* (04/08/2001) gb -*	Identify version on module load. -* -* (11/01/2000) Adam J. Richter -*	usb_device_id table support -*  -* (11/01/2000) pberger and borchers -*    -- Turned off the USB_DISABLE_SPD flag for write bulk urbs--it caused -*       USB 4 ports to hang on startup. -*    -- Serialized access to write urbs by adding the dp_write_urb_in_use -*       flag; otherwise, the driver caused SMP system hangs.  Watching the -*       urb status is not sufficient. -* -* (10/05/2000) gkh -*    -- Fixed bug with urb->dev not being set properly, now that the usb -*	core needs it. -*  -*  (8/8/2000) pberger and borchers -*    -- Fixed close so that  -*       - it can timeout while waiting for transmit idle, if needed; -*       - it ignores interrupts when flushing the port, turning -*         of modem signalling, and so on; -*       - it waits for the flush to really complete before returning. -*    -- Read_bulk_callback and write_bulk_callback check for a closed -*       port before using the tty struct or writing to the port. -*    -- The two changes above fix the oops caused by interrupted closes. -*    -- Added interruptible args to write_oob_command and set_modem_signals -*       and added a timeout arg to transmit_idle; needed for fixes to -*       close. -*    -- Added code for rx_throttle and rx_unthrottle so that input flow -*       control works. -*    -- Added code to set overrun, parity, framing, and break errors -*       (untested). -*    -- Set USB_DISABLE_SPD flag for write bulk urbs, so no 0 length -*       bulk writes are done.  These hung the Digi USB device.  The -*       0 length bulk writes were a new feature of usb-uhci added in -*       the 2.4.0-test6 kernels. -*    -- Fixed mod inc race in open; do mod inc before sleeping to wait -*       for a close to finish. -* -*  (7/31/2000) pberger -*    -- Fixed bugs with hardware handshaking: -*       - Added code to set/clear tty->hw_stopped in digi_read_oob_callback() -*         and digi_set_termios() -*    -- Added code in digi_set_termios() to -*       - add conditional in code handling transition from B0 to only -*         set RTS if RTS/CTS flow control is either not in use or if -*         the port is not currently throttled. -*       - handle turning off CRTSCTS. -* -*  (7/30/2000) borchers -*    -- Added support for more than one Digi USB device by moving -*       globals to a private structure in the pointed to from the -*       usb_serial structure. -*    -- Moved the modem change and transmit idle wait queues into -*       the port private structure, so each port has its own queue -*       rather than sharing global queues. -*    -- Added support for break signals. -* -*  (7/25/2000) pberger -*    -- Added USB-2 support.  Note: the USB-2 supports 3 devices: two -*       serial and a parallel port.  The parallel port is implemented -*       as a serial-to-parallel converter.  That is, the driver actually -*       presents all three USB-2 interfaces as serial ports, but the third -*       one physically connects to a parallel device.  Thus, for example, -*       one could plug a parallel printer into the USB-2's third port, -*       but from the kernel's (and userland's) point of view what's -*       actually out there is a serial device. -* -*  (7/15/2000) borchers -*    -- Fixed race in open when a close is in progress. -*    -- Keep count of opens and dec the module use count for each -*       outstanding open when shutdown is called (on disconnect). -*    -- Fixed sanity checks in read_bulk_callback and write_bulk_callback -*       so pointers are checked before use. -*    -- Split read bulk callback into in band and out of band -*       callbacks, and no longer restart read chains if there is -*       a status error or a sanity error.  This fixed the seg -*       faults and other errors we used to get on disconnect. -*    -- Port->active is once again a flag as usb-serial intended it -*       to be, not a count.  Since it was only a char it would -*       have been limited to 256 simultaneous opens.  Now the open -*       count is kept in the port private structure in dp_open_count. -*    -- Added code for modularization of the digi_acceleport driver. -* -*  (6/27/2000) pberger and borchers -*    -- Zeroed out sync field in the wakeup_task before first use; -*       otherwise the uninitialized value might prevent the task from -*       being scheduled. -*    -- Initialized ret value to 0 in write_bulk_callback, otherwise -*       the uninitialized value could cause a spurious debugging message. -* -*  (6/22/2000) pberger and borchers -*    -- Made cond_wait_... inline--apparently on SPARC the flags arg -*       to spin_lock_irqsave cannot be passed to another function -*       to call spin_unlock_irqrestore.  Thanks to Pauline Middelink. -*    -- In digi_set_modem_signals the inner nested spin locks use just -*       spin_lock() rather than spin_lock_irqsave().  The old code -*       mistakenly left interrupts off.  Thanks to Pauline Middelink. -*    -- copy_from_user (which can sleep) is no longer called while a -*       spinlock is held.  We copy to a local buffer before getting -*       the spinlock--don't like the extra copy but the code is simpler. -*    -- Printk and dbg are no longer called while a spin lock is held. -* -*  (6/4/2000) pberger and borchers -*    -- Replaced separate calls to spin_unlock_irqrestore and -*       interruptible_sleep_on_timeout with a new function -*       cond_wait_interruptible_timeout_irqrestore.  This eliminates -*       the race condition where the wake up could happen after -*       the unlock and before the sleep. -*    -- Close now waits for output to drain. -*    -- Open waits until any close in progress is finished. -*    -- All out of band responses are now processed, not just the -*       first in a USB packet. -*    -- Fixed a bug that prevented the driver from working when the -*       first Digi port was not the first USB serial port--the driver -*       was mistakenly using the external USB serial port number to -*       try to index into its internal ports. -*    -- Fixed an SMP bug -- write_bulk_callback is called directly from -*       an interrupt, so spin_lock_irqsave/spin_unlock_irqrestore are -*       needed for locks outside write_bulk_callback that are also -*       acquired by write_bulk_callback to prevent deadlocks. -*    -- Fixed support for select() by making digi_chars_in_buffer() -*       return 256 when -EINPROGRESS is set, as the line discipline -*       code in n_tty.c expects. -*    -- Fixed an include file ordering problem that prevented debugging -*       messages from working. -*    -- Fixed an intermittent timeout problem that caused writes to -*       sometimes get stuck on some machines on some kernels.  It turns -*       out in these circumstances write_chan() (in n_tty.c) was -*       asleep waiting for our wakeup call.  Even though we call -*       wake_up_interruptible() in digi_write_bulk_callback(), there is -*       a race condition that could cause the wakeup to fail: if our -*       wake_up_interruptible() call occurs between the time that our -*       driver write routine finishes and write_chan() sets current->state -*       to TASK_INTERRUPTIBLE, the effect of our wakeup setting the state -*       to TASK_RUNNING will be lost and write_chan's subsequent call to -*       schedule() will never return (unless it catches a signal). -*       This race condition occurs because write_bulk_callback() (and thus -*       the wakeup) are called asynchronously from an interrupt, rather than -*       from the scheduler.  We can avoid the race by calling the wakeup -*       from the scheduler queue and that's our fix:  Now, at the end of -*       write_bulk_callback() we queue up a wakeup call on the scheduler -*       task queue.  We still also invoke the wakeup directly since that -*       squeezes a bit more performance out of the driver, and any lost -*       race conditions will get cleaned up at the next scheduler run. -* -*       NOTE:  The problem also goes away if you comment out -*       the two code lines in write_chan() where current->state -*       is set to TASK_RUNNING just before calling driver.write() and to -*       TASK_INTERRUPTIBLE immediately afterwards.  This is why the -*       problem did not show up with the 2.2 kernels -- they do not -*       include that code. -* -*  (5/16/2000) pberger and borchers -*    -- Added timeouts to sleeps, to defend against lost wake ups. -*    -- Handle transition to/from B0 baud rate in digi_set_termios. -* -*  (5/13/2000) pberger and borchers -*    -- All commands now sent on out of band port, using -*       digi_write_oob_command. -*    -- Get modem control signals whenever they change, support TIOCMGET/ -*       SET/BIS/BIC ioctls. -*    -- digi_set_termios now supports parity, word size, stop bits, and -*       receive enable. -*    -- Cleaned up open and close, use digi_set_termios and -*       digi_write_oob_command to set port parameters. -*    -- Added digi_startup_device to start read chains on all ports. -*    -- Write buffer is only used when count==1, to be sure put_char can -*       write a char (unless the buffer is full). -* -*  (5/10/2000) pberger and borchers -*    -- Added MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT calls on open/close. -*    -- Fixed problem where the first incoming character is lost on -*       port opens after the first close on that port.  Now we keep -*       the read_urb chain open until shutdown. -*    -- Added more port conditioning calls in digi_open and digi_close. -*    -- Convert port->active to a use count so that we can deal with multiple -*       opens and closes properly. -*    -- Fixed some problems with the locking code. -* -*  (5/3/2000) pberger and borchers -*    -- First alpha version of the driver--many known limitations and bugs. -* -* -*  Locking and SMP -* -*  - Each port, including the out-of-band port, has a lock used to -*    serialize all access to the port's private structure. -*  - The port lock is also used to serialize all writes and access to -*    the port's URB. -*  - The port lock is also used for the port write_wait condition -*    variable.  Holding the port lock will prevent a wake up on the -*    port's write_wait; this can be used with cond_wait_... to be sure -*    the wake up is not lost in a race when dropping the lock and -*    sleeping waiting for the wakeup. -*  - digi_write() does not sleep, since it is sometimes called on -*    interrupt time. -*  - digi_write_bulk_callback() and digi_read_bulk_callback() are -*    called directly from interrupts.  Hence spin_lock_irqsave() -*    and spin_unlock_irqrestore() are used in the rest of the code -*    for any locks they acquire. -*  - digi_write_bulk_callback() gets the port lock before waking up -*    processes sleeping on the port write_wait.  It also schedules -*    wake ups so they happen from the scheduler, because the tty -*    system can miss wake ups from interrupts. -*  - All sleeps use a timeout of DIGI_RETRY_TIMEOUT before looping to -*    recheck the condition they are sleeping on.  This is defensive, -*    in case a wake up is lost. -*  - Following Documentation/DocBook/kernel-locking.tmpl no spin locks -*    are held when calling copy_to/from_user or printk.  */  #include <linux/kernel.h> @@ -654,7 +438,6 @@ static int digi_write_oob_command(struct usb_serial_port *port,  			len &= ~3;  		memcpy(oob_port->write_urb->transfer_buffer, buf, len);  		oob_port->write_urb->transfer_buffer_length = len; -		oob_port->write_urb->dev = port->serial->dev;  		ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);  		if (ret == 0) {  			oob_priv->dp_write_urb_in_use = 1; @@ -732,7 +515,6 @@ static int digi_write_inb_command(struct usb_serial_port *port,  			memcpy(data, buf, len);  			port->write_urb->transfer_buffer_length = len;  		} -		port->write_urb->dev = port->serial->dev;  		ret = usb_submit_urb(port->write_urb, GFP_ATOMIC);  		if (ret == 0) { @@ -803,7 +585,6 @@ static int digi_set_modem_signals(struct usb_serial_port *port,  	data[7] = 0;  	oob_port->write_urb->transfer_buffer_length = 8; -	oob_port->write_urb->dev = port->serial->dev;  	ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC);  	if (ret == 0) { @@ -899,10 +680,8 @@ static void digi_rx_unthrottle(struct tty_struct *tty)  	spin_lock_irqsave(&priv->dp_port_lock, flags);  	/* restart read chain */ -	if (priv->dp_throttle_restart) { -		port->read_urb->dev = port->serial->dev; +	if (priv->dp_throttle_restart)  		ret = usb_submit_urb(port->read_urb, GFP_ATOMIC); -	}  	/* turn throttle off */  	priv->dp_throttled = 0; @@ -1195,7 +974,6 @@ static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,  	}  	port->write_urb->transfer_buffer_length = data_len+2; -	port->write_urb->dev = port->serial->dev;  	*data++ = DIGI_CMD_SEND_DATA;  	*data++ = data_len; @@ -1271,7 +1049,6 @@ static void digi_write_bulk_callback(struct urb *urb)  			= (unsigned char)priv->dp_out_buf_len;  		port->write_urb->transfer_buffer_length =  						priv->dp_out_buf_len + 2; -		port->write_urb->dev = serial->dev;  		memcpy(port->write_urb->transfer_buffer + 2, priv->dp_out_buf,  			priv->dp_out_buf_len);  		ret = usb_submit_urb(port->write_urb, GFP_ATOMIC); @@ -1473,7 +1250,6 @@ static int digi_startup_device(struct usb_serial *serial)  	/* set USB_DISABLE_SPD flag for write bulk urbs */  	for (i = 0; i < serial->type->num_ports + 1; i++) {  		port = serial->port[i]; -		port->write_urb->dev = port->serial->dev;  		ret = usb_submit_urb(port->read_urb, GFP_KERNEL);  		if (ret != 0) {  			dev_err(&port->dev, @@ -1616,7 +1392,6 @@ static void digi_read_bulk_callback(struct urb *urb)  	}  	/* continue read */ -	urb->dev = port->serial->dev;  	ret = usb_submit_urb(urb, GFP_ATOMIC);  	if (ret != 0 && ret != -EPERM) {  		dev_err(&port->dev, diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ff3db5d056a..c290df97108 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2105,6 +2105,9 @@ static void ftdi_set_termios(struct tty_struct *tty,  	cflag = termios->c_cflag; +	if (old_termios == 0) +		goto no_skip; +  	if (old_termios->c_cflag == termios->c_cflag  	    && old_termios->c_ispeed == termios->c_ispeed  	    && old_termios->c_ospeed == termios->c_ospeed) @@ -2118,6 +2121,7 @@ static void ftdi_set_termios(struct tty_struct *tty,  	    (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)))  		goto no_data_parity_stop_changes; +no_skip:  	/* Set number of data bits, parity, stop bits */  	urb_value = 0; diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 1a49ca9c8ea..bf12565f8e8 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -901,7 +901,6 @@ static int garmin_init_session(struct usb_serial_port *port)  		usb_kill_urb(port->interrupt_in_urb);  		dbg("%s - adding interrupt input", __func__); -		port->interrupt_in_urb->dev = serial->dev;  		status = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);  		if (status)  			dev_err(&serial->dev->dev, @@ -1277,7 +1276,6 @@ static void garmin_read_int_callback(struct urb *urb)  	unsigned long flags;  	int retval;  	struct usb_serial_port *port = urb->context; -	struct usb_serial *serial = port->serial;  	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);  	unsigned char *data = urb->transfer_buffer;  	int status = urb->status; @@ -1311,12 +1309,6 @@ static void garmin_read_int_callback(struct urb *urb)  		if (0 == (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) {  			/* bulk data available */ -			usb_fill_bulk_urb(port->read_urb, serial->dev, -					usb_rcvbulkpipe(serial->dev, -						port->bulk_in_endpointAddress), -					port->read_urb->transfer_buffer, -					port->read_urb->transfer_buffer_length, -					garmin_read_bulk_callback, port);  			retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);  			if (retval) {  				dev_err(&port->dev, @@ -1353,7 +1345,6 @@ static void garmin_read_int_callback(struct urb *urb)  	garmin_read_process(garmin_data_p, data, urb->actual_length, 0); -	port->interrupt_in_urb->dev = port->serial->dev;  	retval = usb_submit_urb(urb, GFP_ATOMIC);  	if (retval)  		dev_err(&urb->dev->dev, diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index e4db5ad2bc5..f7403576f99 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -1,7 +1,7 @@  /*   * USB Serial Converter Generic functions   * - * Copyright (C) 2010 Johan Hovold (jhovold@gmail.com) + * Copyright (C) 2010 - 2011 Johan Hovold (jhovold@gmail.com)   * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com)   *   *	This program is free software; you can redistribute it and/or @@ -132,7 +132,7 @@ int usb_serial_generic_open(struct tty_struct *tty, struct usb_serial_port *port  	/* if we have a bulk endpoint, start reading from it */  	if (port->bulk_in_size) -		result = usb_serial_generic_submit_read_urb(port, GFP_KERNEL); +		result = usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);  	return result;  } @@ -157,8 +157,10 @@ static void generic_cleanup(struct usb_serial_port *port)  			kfifo_reset_out(&port->write_fifo);  			spin_unlock_irqrestore(&port->lock, flags);  		} -		if (port->bulk_in_size) -			usb_kill_urb(port->read_urb); +		if (port->bulk_in_size) { +			for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) +				usb_kill_urb(port->read_urbs[i]); +		}  	}  } @@ -308,19 +310,52 @@ int usb_serial_generic_chars_in_buffer(struct tty_struct *tty)  	return chars;  } -int usb_serial_generic_submit_read_urb(struct usb_serial_port *port, +static int usb_serial_generic_submit_read_urb(struct usb_serial_port *port, +						int index, gfp_t mem_flags) +{ +	int res; + +	if (!test_and_clear_bit(index, &port->read_urbs_free)) +		return 0; + +	dbg("%s - port %d, urb %d\n", __func__, port->number, index); + +	res = usb_submit_urb(port->read_urbs[index], mem_flags); +	if (res) { +		if (res != -EPERM) { +			dev_err(&port->dev, +					"%s - usb_submit_urb failed: %d\n", +					__func__, res); +		} +		set_bit(index, &port->read_urbs_free); +		return res; +	} + +	return 0; +} + +int usb_serial_generic_submit_read_urbs(struct usb_serial_port *port,  					gfp_t mem_flags)  { -	int result; +	int res; +	int i; -	result = usb_submit_urb(port->read_urb, mem_flags); -	if (result && result != -EPERM) { -		dev_err(&port->dev, "%s - error submitting urb: %d\n", -							__func__, result); +	dbg("%s - port %d", __func__, port->number); + +	for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { +		res = usb_serial_generic_submit_read_urb(port, i, mem_flags); +		if (res) +			goto err;  	} -	return result; + +	return 0; +err: +	for (; i >= 0; --i) +		usb_kill_urb(port->read_urbs[i]); + +	return res;  } -EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urb); +EXPORT_SYMBOL_GPL(usb_serial_generic_submit_read_urbs);  void usb_serial_generic_process_read_urb(struct urb *urb)  { @@ -356,14 +391,19 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)  {  	struct usb_serial_port *port = urb->context;  	unsigned char *data = urb->transfer_buffer; -	int status = urb->status;  	unsigned long flags; +	int i; -	dbg("%s - port %d", __func__, port->number); +	for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { +		if (urb == port->read_urbs[i]) +			break; +	} +	set_bit(i, &port->read_urbs_free); -	if (unlikely(status != 0)) { -		dbg("%s - nonzero read bulk status received: %d", -		    __func__, status); +	dbg("%s - port %d, urb %d, len %d\n", __func__, port->number, i, +							urb->actual_length); +	if (urb->status) { +		dbg("%s - non-zero urb status: %d\n", __func__, urb->status);  		return;  	} @@ -376,7 +416,7 @@ void usb_serial_generic_read_bulk_callback(struct urb *urb)  	port->throttled = port->throttle_req;  	if (!port->throttled) {  		spin_unlock_irqrestore(&port->lock, flags); -		usb_serial_generic_submit_read_urb(port, GFP_ATOMIC); +		usb_serial_generic_submit_read_urb(port, i, GFP_ATOMIC);  	} else  		spin_unlock_irqrestore(&port->lock, flags);  } @@ -443,7 +483,7 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)  	spin_unlock_irq(&port->lock);  	if (was_throttled) -		usb_serial_generic_submit_read_urb(port, GFP_KERNEL); +		usb_serial_generic_submit_read_urbs(port, GFP_KERNEL);  }  EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle); @@ -509,8 +549,9 @@ int usb_serial_generic_resume(struct usb_serial *serial)  		if (!test_bit(ASYNCB_INITIALIZED, &port->port.flags))  			continue; -		if (port->read_urb) { -			r = usb_submit_urb(port->read_urb, GFP_NOIO); +		if (port->bulk_in_size) { +			r = usb_serial_generic_submit_read_urbs(port, +								GFP_NOIO);  			if (r < 0)  				c++;  		} diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 2ee807523f5..abd2ee2b2f9 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -610,7 +610,6 @@ static void edge_interrupt_callback(struct urb *urb)  					/* we have pending bytes on the  					   bulk in pipe, send a request */ -					edge_serial->read_urb->dev = edge_serial->serial->dev;  					result = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC);  					if (result) {  						dev_err(&edge_serial->serial->dev->dev, "%s - usb_submit_urb(read bulk) failed with result = %d\n", __func__, result); @@ -711,7 +710,6 @@ static void edge_bulk_in_callback(struct urb *urb)  	/* check to see if there's any more data for us to read */  	if (edge_serial->rxBytesAvail > 0) {  		dbg("%s - posting a read", __func__); -		edge_serial->read_urb->dev = edge_serial->serial->dev;  		retval = usb_submit_urb(edge_serial->read_urb, GFP_ATOMIC);  		if (retval) {  			dev_err(&urb->dev->dev, @@ -1330,7 +1328,6 @@ static void send_more_port_data(struct edgeport_serial *edge_serial,  	edge_port->txCredits -= count;  	edge_port->icount.tx += count; -	urb->dev = edge_serial->serial->dev;  	status = usb_submit_urb(urb, GFP_ATOMIC);  	if (status) {  		/* something went wrong */ diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 0aac00afb5c..e44d375edaa 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -15,13 +15,6 @@   * For questions or problems with this driver, contact Inside Out   * Networks technical support, or Peter Berger <pberger@brimson.com>,   * or Al Borchers <alborchers@steinerpoint.com>. - * - * Version history: - * - *	July 11, 2002 	Removed 4 port device structure since all TI UMP - *			chips have only 2 ports - *			David Iacovelli (davidi@ionetworks.com) - *   */  #include <linux/kernel.h> @@ -1777,12 +1770,11 @@ static void edge_bulk_in_callback(struct urb *urb)  exit:  	/* continue read unless stopped */  	spin_lock(&edge_port->ep_lock); -	if (edge_port->ep_read_urb_state == EDGE_READ_URB_RUNNING) { -		urb->dev = edge_port->port->serial->dev; +	if (edge_port->ep_read_urb_state == EDGE_READ_URB_RUNNING)  		retval = usb_submit_urb(urb, GFP_ATOMIC); -	} else if (edge_port->ep_read_urb_state == EDGE_READ_URB_STOPPING) { +	else if (edge_port->ep_read_urb_state == EDGE_READ_URB_STOPPING)  		edge_port->ep_read_urb_state = EDGE_READ_URB_STOPPED; -	} +  	spin_unlock(&edge_port->ep_lock);  	if (retval)  		dev_err(&urb->dev->dev, @@ -1959,9 +1951,7 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)  			status = -EINVAL;  			goto release_es_lock;  		} -		urb->complete = edge_interrupt_callback;  		urb->context = edge_serial; -		urb->dev = dev;  		status = usb_submit_urb(urb, GFP_KERNEL);  		if (status) {  			dev_err(&port->dev, @@ -1987,9 +1977,7 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)  		goto unlink_int_urb;  	}  	edge_port->ep_read_urb_state = EDGE_READ_URB_RUNNING; -	urb->complete = edge_bulk_in_callback;  	urb->context = edge_port; -	urb->dev = dev;  	status = usb_submit_urb(urb, GFP_KERNEL);  	if (status) {  		dev_err(&port->dev, @@ -2118,12 +2106,7 @@ static void edge_send(struct tty_struct *tty)  				port->write_urb->transfer_buffer);  	/* set up our urb */ -	usb_fill_bulk_urb(port->write_urb, port->serial->dev, -			   usb_sndbulkpipe(port->serial->dev, -					    port->bulk_out_endpointAddress), -			   port->write_urb->transfer_buffer, count, -			   edge_bulk_out_callback, -			   port); +	port->write_urb->transfer_buffer_length = count;  	/* send the data out the bulk port */  	result = usb_submit_urb(port->write_urb, GFP_ATOMIC); @@ -2267,9 +2250,6 @@ static int restart_read(struct edgeport_port *edge_port)  	if (edge_port->ep_read_urb_state == EDGE_READ_URB_STOPPED) {  		urb = edge_port->port->read_urb; -		urb->complete = edge_bulk_in_callback; -		urb->context = edge_port; -		urb->dev = edge_port->port->serial->dev;  		status = usb_submit_urb(urb, GFP_ATOMIC);  	}  	edge_port->ep_read_urb_state = EDGE_READ_URB_RUNNING; diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 4735931b4c7..36f5cbe9048 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -8,40 +8,6 @@   *	it under the terms of the GNU General Public License as published by   *	the Free Software Foundation; either version 2 of the License, or   *	(at your option) any later version. - * - * (12/12/2002) ganesh - * 	Added support for practically all devices supported by ActiveSync - * 	on Windows. Thanks to Wes Cilldhaire <billybobjoehenrybob@hotmail.com>. - * - * (26/11/2002) ganesh - * 	Added insmod options to specify product and vendor id. - * 	Use modprobe ipaq vendor=0xfoo product=0xbar - * - * (26/7/2002) ganesh - * 	Fixed up broken error handling in ipaq_open. Retry the "kickstart" - * 	packet much harder - this drastically reduces connection failures. - * - * (30/4/2002) ganesh - * 	Added support for the Casio EM500. Completely untested. Thanks - * 	to info from Nathan <wfilardo@fuse.net> - * - * (19/3/2002) ganesh - *	Don't submit urbs while holding spinlocks. Not strictly necessary - *	in 2.5.x. - * - * (8/3/2002) ganesh - * 	The ipaq sometimes emits a '\0' before the CLIENT string. At this - * 	point of time, the ppp ldisc is not yet attached to the tty, so - * 	n_tty echoes "^ " to the ipaq, which messes up the chat. In 2.5.6-pre2 - * 	this causes a panic because echo_char() tries to sleep in interrupt - * 	context. - * 	The fix is to tell the upper layers that this is a raw device so that - * 	echoing is suppressed. Thanks to Lyle Lindholm for a detailed bug - * 	report. - * - * (25/2/2002) ganesh - * 	Added support for the HP Jornada 548 and 568. Completely untested. - * 	Thanks to info from Heath Robinson and Arieh Davidoff.   */  #include <linux/kernel.h> diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index ccbce4066d0..0c537da0d3c 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -22,38 +22,6 @@   *   * See Documentation/usb/usb-serial.txt for more information on using this   * driver - * - * 2008_Jun_02  Felipe Balbi <me@felipebalbi.com> - *	Introduced common header to be used also in USB Gadget Framework. - *	Still needs some other style fixes. - * - * 2007_Jun_21  Alan Cox <alan@lxorguk.ukuu.org.uk> - *	Minimal cleanups for some of the driver problens and tty layer abuse. - *	Still needs fixing to allow multiple dongles. - * - * 2002_Mar_07	greg kh - *	moved some needed structures and #define values from the - *	net/irda/irda-usb.h file into our file, as we don't want to depend on - *	that codebase compiling correctly :) - * - * 2002_Jan_14  gb - *	Added module parameter to force specific number of XBOFs. - *	Added ir_xbof_change(). - *	Reorganized read_bulk_callback error handling. - *	Switched from FILL_BULK_URB() to usb_fill_bulk_urb(). - * - * 2001_Nov_08  greg kh - *	Changed the irda_usb_find_class_desc() function based on comments and - *	code from Martin Diehl. - * - * 2001_Nov_01	greg kh - *	Added support for more IrDA USB devices. - *	Added support for zero packet.  Added buffer override paramater, so - *	users can transfer larger packets at once if they wish.  Both patches - *	came from Dag Brattli <dag@obexcode.com>. - * - * 2001_Oct_07	greg kh - *	initial version released.   */  #include <linux/kernel.h> diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 6aca631a407..64d0ffd4440 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -1168,15 +1168,14 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)  			  port->write_urb->transfer_buffer, 1,  			  read_rxcmd_callback, port);  	result = usb_submit_urb(port->write_urb, GFP_KERNEL); -  	if (result) {  		dev_err(&port->dev, "%s - failed submitting read urb,"  			" error %d\n", __func__, result);  		iuu_close(port); -		return -EPROTO;  	} else {  		dbg("%s - rxcmd OK", __func__);  	} +  	return result;  } diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index a442352d7b6..bc8dc203e81 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -25,73 +25,6 @@    Tip 'o the hat to IBM (and previously Linuxcare :) for supporting    staff in their work on open source projects. - -  Change History - -    2003sep04	LPM (Keyspan) add support for new single port product USA19HS. -				Improve setup message handling for all devices. - -    Wed Feb 19 22:00:00 PST 2003 (Jeffrey S. Laing <keyspan@jsl.com>) -      Merged the current (1/31/03) Keyspan code with the current (2.4.21-pre4) -      Linux source tree.  The Linux tree lacked support for the 49WLC and -      others.  The Keyspan patches didn't work with the current kernel. - -    2003jan30	LPM	add support for the 49WLC and MPR - -    Wed Apr 25 12:00:00 PST 2002 (Keyspan) -      Started with Hugh Blemings' code dated Jan 17, 2002.  All adapters -      now supported (including QI and QW).  Modified port open, port -      close, and send setup() logic to fix various data and endpoint -      synchronization bugs and device LED status bugs.  Changed keyspan_ -      write_room() to accurately return transmit buffer availability. -      Changed forwardingLength from 1 to 16 for all adapters. - -    Fri Oct 12 16:45:00 EST 2001 -      Preliminary USA-19QI and USA-28 support (both test OK for me, YMMV) - -    Wed Apr 25 12:00:00 PST 2002 (Keyspan) -      Started with Hugh Blemings' code dated Jan 17, 2002.  All adapters -      now supported (including QI and QW).  Modified port open, port -      close, and send setup() logic to fix various data and endpoint -      synchronization bugs and device LED status bugs.  Changed keyspan_ -      write_room() to accurately return transmit buffer availability. -      Changed forwardingLength from 1 to 16 for all adapters. - -    Fri Oct 12 16:45:00 EST 2001 -      Preliminary USA-19QI and USA-28 support (both test OK for me, YMMV) - -    Mon Oct  8 14:29:00 EST 2001 hugh -      Fixed bug that prevented mulitport devices operating correctly -      if they weren't the first unit attached. - -    Sat Oct  6 12:31:21 EST 2001 hugh -      Added support for USA-28XA and -28XB, misc cleanups, break support -      for usa26 based models thanks to David Gibson. - -    Thu May 31 11:56:42 PDT 2001 gkh -      switched from using spinlock to a semaphore - -    (04/08/2001) gb -	Identify version on module load. - -    (11/01/2000) Adam J. Richter -	usb_device_id table support. - -    Tue Oct 10 23:15:33 EST 2000 Hugh -      Merged Paul's changes with my USA-49W mods.  Work in progress -      still... - -    Wed Jul 19 14:00:42 EST 2000 gkh -      Added module_init and module_exit functions to handle the fact that -      this driver is a loadable module now. - -    Tue Jul 18 16:14:52 EST 2000 Hugh -      Basic character input/output for USA-19 now mostly works, -      fixed at 9600 baud for the moment. - -    Sat Jul  8 11:11:48 EST 2000 Hugh -      First public release - nothing works except the firmware upload. -      Tested on PPC and x86 architectures, seems to behave...  */ @@ -397,7 +330,6 @@ static int keyspan_write(struct tty_struct *tty,  		/* send the data out the bulk port */  		this_urb->transfer_buffer_length = todo + dataOffset; -		this_urb->dev = port->serial->dev;  		err = usb_submit_urb(this_urb, GFP_ATOMIC);  		if (err != 0)  			dbg("usb_submit_urb(write bulk) failed (%d)", err); @@ -463,7 +395,6 @@ static void	usa26_indat_callback(struct urb *urb)  	tty_kref_put(tty);  	/* Resubmit urb so we continue receiving */ -	urb->dev = port->serial->dev;  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0)  		dbg("%s - resubmit read urb failed. (%d)", __func__, err); @@ -559,7 +490,6 @@ static void	usa26_instat_callback(struct urb *urb)  	}  	/* Resubmit urb so we continue receiving */ -	urb->dev = serial->dev;  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0)  		dbg("%s - resubmit read urb failed. (%d)", __func__, err); @@ -609,7 +539,6 @@ static void usa28_indat_callback(struct urb *urb)  		tty_kref_put(tty);  		/* Resubmit urb so we continue receiving */ -		urb->dev = port->serial->dev;  		err = usb_submit_urb(urb, GFP_ATOMIC);  		if (err != 0)  			dbg("%s - resubmit read urb failed. (%d)", @@ -694,7 +623,6 @@ static void	usa28_instat_callback(struct urb *urb)  	}  		/* Resubmit urb so we continue receiving */ -	urb->dev = serial->dev;  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0)  		dbg("%s - resubmit read urb failed. (%d)", __func__, err); @@ -789,8 +717,6 @@ static void	usa49_instat_callback(struct urb *urb)  	}  	/* Resubmit urb so we continue receiving */ -	urb->dev = serial->dev; -  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0)  		dbg("%s - resubmit read urb failed. (%d)", __func__, err); @@ -848,7 +774,6 @@ static void	usa49_indat_callback(struct urb *urb)  	tty_kref_put(tty);  	/* Resubmit urb so we continue receiving */ -	urb->dev = port->serial->dev;  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0)  		dbg("%s - resubmit read urb failed. (%d)", __func__, err); @@ -919,8 +844,6 @@ static void usa49wg_indat_callback(struct urb *urb)  	}  	/* Resubmit urb so we continue receiving */ -	urb->dev = serial->dev; -  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0)  		dbg("%s - resubmit read urb failed. (%d)", __func__, err); @@ -996,7 +919,6 @@ static void usa90_indat_callback(struct urb *urb)  	}  	/* Resubmit urb so we continue receiving */ -	urb->dev = port->serial->dev;  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0)  		dbg("%s - resubmit read urb failed. (%d)", __func__, err); @@ -1047,7 +969,6 @@ static void	usa90_instat_callback(struct urb *urb)  	}  	/* Resubmit urb so we continue receiving */ -	urb->dev = serial->dev;  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0)  		dbg("%s - resubmit read urb failed. (%d)", __func__, err); @@ -1123,7 +1044,6 @@ static void	usa67_instat_callback(struct urb *urb)  	}  	/* Resubmit urb so we continue receiving */ -	urb->dev = serial->dev;  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err != 0)  		dbg("%s - resubmit read urb failed. (%d)", __func__, err); @@ -1223,7 +1143,6 @@ static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port)  		urb = p_priv->in_urbs[i];  		if (urb == NULL)  			continue; -		urb->dev = serial->dev;  		/* make sure endpoint data toggle is synchronized  		   with the device */ @@ -1239,7 +1158,6 @@ static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port)  		urb = p_priv->out_urbs[i];  		if (urb == NULL)  			continue; -		urb->dev = serial->dev;  		/* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),  						usb_pipeout(urb->pipe), 0); */  	} @@ -1956,7 +1874,6 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial,  	/* send the data out the device on control endpoint */  	this_urb->transfer_buffer_length = sizeof(msg); -	this_urb->dev = serial->dev;  	err = usb_submit_urb(this_urb, GFP_ATOMIC);  	if (err != 0)  		dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err); @@ -2084,7 +2001,6 @@ static int keyspan_usa28_send_setup(struct usb_serial *serial,  	/* send the data out the device on control endpoint */  	this_urb->transfer_buffer_length = sizeof(msg); -	this_urb->dev = serial->dev;  	err = usb_submit_urb(this_urb, GFP_ATOMIC);  	if (err != 0)  		dbg("%s - usb_submit_urb(setup) failed", __func__); @@ -2271,8 +2187,6 @@ static int keyspan_usa49_send_setup(struct usb_serial *serial,  		/* send the data out the device on control endpoint */  		this_urb->transfer_buffer_length = sizeof(msg); - -		this_urb->dev = serial->dev;  	}  	err = usb_submit_urb(this_urb, GFP_ATOMIC);  	if (err != 0) @@ -2415,7 +2329,6 @@ static int keyspan_usa90_send_setup(struct usb_serial *serial,  	/* send the data out the device on control endpoint */  	this_urb->transfer_buffer_length = sizeof(msg); -	this_urb->dev = serial->dev;  	err = usb_submit_urb(this_urb, GFP_ATOMIC);  	if (err != 0)  		dbg("%s - usb_submit_urb(setup) failed (%d)", __func__, err); @@ -2561,7 +2474,6 @@ static int keyspan_usa67_send_setup(struct usb_serial *serial,  	/* send the data out the device on control endpoint */  	this_urb->transfer_buffer_length = sizeof(msg); -	this_urb->dev = serial->dev;  	err = usb_submit_urb(this_urb, GFP_ATOMIC);  	if (err != 0) @@ -2650,14 +2562,12 @@ static int keyspan_startup(struct usb_serial *serial)  	keyspan_setup_urbs(serial);  	if (s_priv->instat_urb != NULL) { -		s_priv->instat_urb->dev = serial->dev;  		err = usb_submit_urb(s_priv->instat_urb, GFP_KERNEL);  		if (err != 0)  			dbg("%s - submit instat urb failed %d", __func__,  				err);  	}  	if (s_priv->indat_urb != NULL) { -		s_priv->indat_urb->dev = serial->dev;  		err = usb_submit_urb(s_priv->indat_urb, GFP_KERNEL);  		if (err != 0)  			dbg("%s - submit indat urb failed %d", __func__, diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index d5c0c6ab496..a40615674a6 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -12,59 +12,6 @@   *   * See Documentation/usb/usb-serial.txt for more information on using this   * driver - * - * (09/07/2001) gkh - *	cleaned up the Xircom support.  Added ids for Entregra device which is - *	the same as the Xircom device.  Enabled the code to be compiled for - *	either Xircom or Keyspan devices. - * - * (08/11/2001) Cristian M. Craciunescu - *	support for Xircom PGSDB9 - * - * (05/31/2001) gkh - *	switched from using spinlock to a semaphore, which fixes lots of - *	problems. - * - * (04/08/2001) gb - *	Identify version on module load. - * - * (11/01/2000) Adam J. Richter - *	usb_device_id table support - * - * (10/05/2000) gkh - *	Fixed bug with urb->dev not being set properly, now that the usb - *	core needs it. - * - * (08/28/2000) gkh - *	Added locks for SMP safeness. - *	Fixed MOD_INC and MOD_DEC logic and the ability to open a port more - *	than once. - * - * (07/20/2000) borchers - *	- keyspan_pda_write no longer sleeps if it is called on interrupt time; - *	  PPP and the line discipline with stty echo on can call write on - *	  interrupt time and this would cause an oops if write slept - *	- if keyspan_pda_write is in an interrupt, it will not call - *	  usb_control_msg (which sleeps) to query the room in the device - *	  buffer, it simply uses the current room value it has - *	- if the urb is busy or if it is throttled keyspan_pda_write just - *	  returns 0, rather than sleeping to wait for this to change; the - *	  write_chan code in n_tty.c will sleep if needed before calling - *	  keyspan_pda_write again - *	- if the device needs to be unthrottled, write now queues up the - *	  call to usb_control_msg (which sleeps) to unthrottle the device - *	- the wakeups from keyspan_pda_write_bulk_callback are queued rather - *	  than done directly from the callback to avoid the race in write_chan - *	- keyspan_pda_chars_in_buffer also indicates its buffer is full if the - *	  urb status is -EINPROGRESS, meaning it cannot write at the moment - * - * (07/19/2000) gkh - *	Added module_init and module_exit functions to handle the fact that this - *	driver is a loadable module now. - * - * (03/26/2000) gkh - *	Split driver up into device specific pieces. - *   */ @@ -290,7 +237,6 @@ static void keyspan_pda_rx_unthrottle(struct tty_struct *tty)  	struct usb_serial_port *port = tty->driver_data;  	/* just restart the receive interrupt URB */  	dbg("keyspan_pda_rx_unthrottle port %d", port->number); -	port->interrupt_in_urb->dev = port->serial->dev;  	if (usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL))  		dbg(" usb_submit_urb(read urb) failed");  } @@ -532,11 +478,11 @@ static int keyspan_pda_write(struct tty_struct *tty,  	   the device is full (wait until it says there is room)  	*/  	spin_lock_bh(&port->lock); -	if (port->write_urb_busy || priv->tx_throttled) { +	if (!test_bit(0, &port->write_urbs_free) || priv->tx_throttled) {  		spin_unlock_bh(&port->lock);  		return 0;  	} -	port->write_urb_busy = 1; +	clear_bit(0, &port->write_urbs_free);  	spin_unlock_bh(&port->lock);  	/* At this point the URB is in our control, nobody else can submit it @@ -598,7 +544,6 @@ static int keyspan_pda_write(struct tty_struct *tty,  		priv->tx_room -= count; -		port->write_urb->dev = port->serial->dev;  		rc = usb_submit_urb(port->write_urb, GFP_ATOMIC);  		if (rc) {  			dbg(" usb_submit_urb(write bulk) failed"); @@ -618,7 +563,7 @@ static int keyspan_pda_write(struct tty_struct *tty,  	rc = count;  exit:  	if (rc < 0) -		port->write_urb_busy = 0; +		set_bit(0, &port->write_urbs_free);  	return rc;  } @@ -628,7 +573,7 @@ static void keyspan_pda_write_bulk_callback(struct urb *urb)  	struct usb_serial_port *port = urb->context;  	struct keyspan_pda_private *priv; -	port->write_urb_busy = 0; +	set_bit(0, &port->write_urbs_free);  	priv = usb_get_serial_port_data(port);  	/* queue up a wakeup at scheduler time */ @@ -661,7 +606,7 @@ static int keyspan_pda_chars_in_buffer(struct tty_struct *tty)  	   n_tty.c:normal_poll() ) that we're not writeable. */  	spin_lock_irqsave(&port->lock, flags); -	if (port->write_urb_busy || priv->tx_throttled) +	if (!test_bit(0, &port->write_urbs_free) || priv->tx_throttled)  		ret = 256;  	spin_unlock_irqrestore(&port->lock, flags);  	return ret; @@ -717,7 +662,6 @@ static int keyspan_pda_open(struct tty_struct *tty,  	priv->tx_throttled = *room ? 0 : 1;  	/*Start reading from the device*/ -	port->interrupt_in_urb->dev = serial->dev;  	rc = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);  	if (rc) {  		dbg("%s - usb_submit_urb(read int) failed", __func__); diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index ddd146300dd..5d3beeeb5fd 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -20,18 +20,6 @@   *   * Supported readers: USB TWIN, KAAN Standard Plus and SecOVID Reader Plus   * (Adapter K), B1 Professional and KAAN Professional (Adapter B) - * - * (21/05/2004) tw - *      Fix bug with P'n'P readers - * - * (28/05/2003) tw - *      Add support for KAAN SIM - * - * (12/09/2002) tw - *      Adapted to 2.5. - * - * (11/08/2002) tw - *      Initial version.   */ @@ -231,9 +219,6 @@ static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)  	dbg("%s - port %d", __func__, port->number);  	priv = usb_get_serial_port_data(port); -	/* someone sets the dev to 0 if the close method has been called */ -	port->interrupt_in_urb->dev = port->serial->dev; -  	/* allocate memory for transfer buffer */  	transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);  	if (!transfer_buffer) @@ -393,8 +378,6 @@ static void kobil_read_int_callback(struct urb *urb)  		tty_flip_buffer_push(tty);  	}  	tty_kref_put(tty); -	/* someone sets the dev to 0 if the close method has been called */ -	port->interrupt_in_urb->dev = port->serial->dev;  	result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);  	dbg("%s - port %d Send read URB returns: %i", @@ -475,17 +458,9 @@ static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,  		priv->filled = 0;  		priv->cur_pos = 0; -		/* someone sets the dev to 0 if the close method -		   has been called */ -		port->interrupt_in_urb->dev = port->serial->dev; -  		/* start reading (except TWIN and KAAN SIM) */  		if (priv->device_type == KOBIL_ADAPTER_B_PRODUCT_ID ||  			priv->device_type == KOBIL_ADAPTER_K_PRODUCT_ID) { -			/* someone sets the dev to 0 if the close method has -			   been called */ -			port->interrupt_in_urb->dev = port->serial->dev; -  			result = usb_submit_urb(port->interrupt_in_urb,  								GFP_NOIO);  			dbg("%s - port %d Send read URB returns: %i", diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index ba0d28727cc..a975bb80303 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -19,50 +19,6 @@   *   DTR/RTS signal handling may be incomplete or incorrect. I have mainly   *   implemented what I have seen with SniffUSB or found in belkin_sa.c.   *   For further TODOs check also belkin_sa.c. - * - * TEST STATUS: - *   Basic tests have been performed with minicom/zmodem transfers and - *   modem dialing under Linux 2.4.0-test10 (for me it works fine). - * - * 04-Nov-2003 Bill Marr <marr at flex dot com> - *   - Mimic Windows driver by sending 2 USB 'device request' messages - *     following normal 'baud rate change' message.  This allows data to be - *     transmitted to RS-232 devices which don't assert the 'CTS' signal. - * - * 10-Nov-2001 Wolfgang Grandegger - *   - Fixed an endianess problem with the baudrate selection for PowerPC. - * - * 06-Dec-2001 Martin Hamilton <martinh@gnu.org> - *   - Added support for the Belkin F5U109 DB9 adaptor - * - * 30-May-2001 Greg Kroah-Hartman - *   - switched from using spinlock to a semaphore, which fixes lots of - *     problems. - * - * 04-May-2001 Stelian Pop - *   - Set the maximum bulk output size for Sitecom U232-P25 model to 16 bytes - *     instead of the device reported 32 (using 32 bytes causes many data - *     loss, Windows driver uses 16 too). - * - * 02-May-2001 Stelian Pop - *   - Fixed the baud calculation for Sitecom U232-P25 model - * - * 08-Apr-2001 gb - *   - Identify version on module load. - * - * 06-Jan-2001 Cornel Ciocirlan - *   - Added support for Sitecom U232-P25 model (Product Id 0x0230) - *   - Added support for D-Link DU-H3SP USB BAY (Product Id 0x0200) - * - * 29-Nov-2000 Greg Kroah-Hartman - *   - Added device id table to fit with 2.4.0-test11 structure. - *   - took out DEAL_WITH_TWO_INT_IN_ENDPOINTS #define as it's not needed - *     (lots of things will change if/when the usb-serial core changes to - *     handle these issues. - * - * 27-Nov-2000 Wolfgang Grandegge - *   A version for kernel 2.4.0-test10 released to the Linux community - *   (via linux-usb-devel).   */  #include <linux/kernel.h> @@ -526,7 +482,6 @@ static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)  	mct_u232_msr_to_state(&priv->control_state, priv->last_msr);  	spin_unlock_irqrestore(&priv->lock, flags); -	port->read_urb->dev = port->serial->dev;  	retval = usb_submit_urb(port->read_urb, GFP_KERNEL);  	if (retval) {  		dev_err(&port->dev, @@ -535,7 +490,6 @@ static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)  		goto error;  	} -	port->interrupt_in_urb->dev = port->serial->dev;  	retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);  	if (retval) {  		usb_kill_urb(port->read_urb); diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 3524a105d04..19d112f51b9 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -939,14 +939,7 @@ static void mos7720_bulk_in_callback(struct urb *urb)  	}  	tty_kref_put(tty); -	if (!port->read_urb) { -		dbg("URB KILLED !!!"); -		return; -	} -  	if (port->read_urb->status != -EINPROGRESS) { -		port->read_urb->dev = port->serial->dev; -  		retval = usb_submit_urb(port->read_urb, GFP_ATOMIC);  		if (retval)  			dbg("usb_submit_urb(read bulk) failed, retval = %d", @@ -1014,7 +1007,6 @@ static int mos77xx_calc_num_ports(struct usb_serial *serial)  static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port)  {  	struct usb_serial *serial; -	struct usb_serial_port *port0;  	struct urb *urb;  	struct moschip_port *mos7720_port;  	int response; @@ -1029,8 +1021,6 @@ static int mos7720_open(struct tty_struct *tty, struct usb_serial_port *port)  	if (mos7720_port == NULL)  		return -ENODEV; -	port0 = serial->port[0]; -  	usb_clear_halt(serial->dev, port->write_urb->pipe);  	usb_clear_halt(serial->dev, port->read_urb->pipe); @@ -1735,8 +1725,6 @@ static void change_port_settings(struct tty_struct *tty,  	write_mos_reg(serial, port_number, IER, 0x0c);  	if (port->read_urb->status != -EINPROGRESS) { -		port->read_urb->dev = serial->dev; -  		status = usb_submit_urb(port->read_urb, GFP_ATOMIC);  		if (status)  			dbg("usb_submit_urb(read bulk) failed, status = %d", @@ -1786,13 +1774,7 @@ static void mos7720_set_termios(struct tty_struct *tty,  	/* change the port settings to the new ones specified */  	change_port_settings(tty, mos7720_port, old_termios); -	if (!port->read_urb) { -		dbg("%s", "URB KILLED !!!!!"); -		return; -	} -  	if (port->read_urb->status != -EINPROGRESS) { -		port->read_urb->dev = serial->dev;  		status = usb_submit_urb(port->read_urb, GFP_ATOMIC);  		if (status)  			dbg("usb_submit_urb(read bulk) failed, status = %d", diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index c72abd52498..55cfd6265b9 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -792,8 +792,6 @@ static void mos7840_bulk_in_callback(struct urb *urb)  	} -	mos7840_port->read_urb->dev = serial->dev; -  	mos7840_port->read_urb_busy = true;  	retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); @@ -2058,7 +2056,6 @@ static void mos7840_change_port_settings(struct tty_struct *tty,  	mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);  	if (mos7840_port->read_urb_busy == false) { -		mos7840_port->read_urb->dev = serial->dev;  		mos7840_port->read_urb_busy = true;  		status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);  		if (status) { @@ -2130,7 +2127,6 @@ static void mos7840_set_termios(struct tty_struct *tty,  	}  	if (mos7840_port->read_urb_busy == false) { -		mos7840_port->read_urb->dev = serial->dev;  		mos7840_port->read_urb_busy = true;  		status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC);  		if (status) { diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 60f38d5e64f..45a8c55881d 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -9,31 +9,6 @@   * driver   *   * Please report both successes and troubles to the author at omninet@kroah.com - * - * (05/30/2001) gkh - *	switched from using spinlock to a semaphore, which fixes lots of - *	problems. - * - * (04/08/2001) gb - *	Identify version on module load. - * - * (11/01/2000) Adam J. Richter - *	usb_device_id table support - * - * (10/05/2000) gkh - *	Fixed bug with urb->dev not being set properly, now that the usb - *	core needs it. - * - * (08/28/2000) gkh - *	Added locks for SMP safeness. - *	Fixed MOD_INC and MOD_DEC logic and the ability to open a port more - *	than once. - *	Fixed potential race in omninet_write_bulk_callback - * - * (07/19/2000) gkh - *	Added module_init and module_exit functions to handle the fact that this - *	driver is a loadable module now. - *   */  #include <linux/kernel.h> @@ -44,7 +19,6 @@  #include <linux/tty_driver.h>  #include <linux/tty_flip.h>  #include <linux/module.h> -#include <linux/spinlock.h>  #include <linux/uaccess.h>  #include <linux/usb.h>  #include <linux/usb/serial.h> @@ -174,12 +148,6 @@ static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port)  	tty_port_tty_set(&wport->port, tty);  	/* Start reading from the device */ -	usb_fill_bulk_urb(port->read_urb, serial->dev, -			usb_rcvbulkpipe(serial->dev, -				port->bulk_in_endpointAddress), -			port->read_urb->transfer_buffer, -			port->read_urb->transfer_buffer_length, -			omninet_read_bulk_callback, port);  	result = usb_submit_urb(port->read_urb, GFP_KERNEL);  	if (result)  		dev_err(&port->dev, @@ -236,11 +204,6 @@ static void omninet_read_bulk_callback(struct urb *urb)  	}  	/* Continue trying to always read  */ -	usb_fill_bulk_urb(urb, port->serial->dev, -			usb_rcvbulkpipe(port->serial->dev, -					port->bulk_in_endpointAddress), -			urb->transfer_buffer, urb->transfer_buffer_length, -			omninet_read_bulk_callback, port);  	result = usb_submit_urb(urb, GFP_ATOMIC);  	if (result)  		dev_err(&port->dev, @@ -267,14 +230,10 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,  		return 0;  	} -	spin_lock_bh(&wport->lock); -	if (wport->write_urb_busy) { -		spin_unlock_bh(&wport->lock); +	if (!test_and_clear_bit(0, &port->write_urbs_free)) {  		dbg("%s - already writing", __func__);  		return 0;  	} -	wport->write_urb_busy = 1; -	spin_unlock_bh(&wport->lock);  	count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count; @@ -292,10 +251,9 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,  	/* send the data out the bulk port, always 64 bytes */  	wport->write_urb->transfer_buffer_length = 64; -	wport->write_urb->dev = serial->dev;  	result = usb_submit_urb(wport->write_urb, GFP_ATOMIC);  	if (result) { -		wport->write_urb_busy = 0; +		set_bit(0, &wport->write_urbs_free);  		dev_err(&port->dev,  			"%s - failed submitting write urb, error %d\n",  			__func__, result); @@ -314,8 +272,7 @@ static int omninet_write_room(struct tty_struct *tty)  	int room = 0; /* Default: no room */ -	/* FIXME: no consistent locking for write_urb_busy */ -	if (wport->write_urb_busy) +	if (test_bit(0, &wport->write_urbs_free))  		room = wport->bulk_out_size - OMNINET_HEADERLEN;  	dbg("%s - returns %d", __func__, room); @@ -332,7 +289,7 @@ static void omninet_write_bulk_callback(struct urb *urb)  	dbg("%s - port %0x", __func__, port->number); -	port->write_urb_busy = 0; +	set_bit(0, &port->write_urbs_free);  	if (status) {  		dbg("%s - nonzero write bulk status received: %d",  		    __func__, status); diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index c248a914743..691f57a9d71 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -384,7 +384,6 @@ static void opticon_unthrottle(struct tty_struct *tty)  	priv->actually_throttled = false;  	spin_unlock_irqrestore(&priv->lock, flags); -	priv->bulk_read_urb->dev = port->serial->dev;  	if (was_throttled) {  		result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC);  		if (result) diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 4c29e6c2bda..2161d1c3c08 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -264,7 +264,6 @@ static void setup_line(struct work_struct *work)  	spin_unlock_irqrestore(&priv->lock, flags);  	dbg("%s(): submitting interrupt urb", __func__); -	port->interrupt_in_urb->dev = port->serial->dev;  	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);  	if (result != 0) {  		dev_err(&port->dev, "%s(): usb_submit_urb() failed" @@ -321,7 +320,6 @@ static void send_data(struct work_struct *work)  		priv->flags.write_urb_in_use = 0;  		dbg("%s(): submitting interrupt urb", __func__); -		port->interrupt_in_urb->dev = port->serial->dev;  		result = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);  		if (result != 0) {  			dev_err(&port->dev, "%s(): usb_submit_urb() failed" @@ -334,7 +332,6 @@ static void send_data(struct work_struct *work)  					port->write_urb->transfer_buffer,  					count, &port->lock);  	port->write_urb->transfer_buffer_length = count; -	port->write_urb->dev = port->serial->dev;  	result = usb_submit_urb(port->write_urb, GFP_NOIO);  	if (result != 0) {  		dev_err(&port->dev, "%s(): usb_submit_urb() failed" @@ -583,13 +580,12 @@ static int oti6858_open(struct tty_struct *tty, struct usb_serial_port *port)  	kfree(buf);  	dbg("%s(): submitting interrupt urb", __func__); -	port->interrupt_in_urb->dev = serial->dev;  	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);  	if (result != 0) {  		dev_err(&port->dev, "%s(): usb_submit_urb() failed"  			       " with error %d\n", __func__, result);  		oti6858_close(port); -		return -EPROTO; +		return result;  	}  	/* setup termios */ @@ -837,7 +833,6 @@ static void oti6858_read_int_callback(struct urb *urb)  	if (can_recv) {  		int result; -		port->read_urb->dev = port->serial->dev;  		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);  		if (result != 0) {  			priv->flags.read_urb_in_use = 0; @@ -866,7 +861,6 @@ static void oti6858_read_int_callback(struct urb *urb)  		int result;  /*		dbg("%s(): submitting interrupt urb", __func__); */ -		urb->dev = port->serial->dev;  		result = usb_submit_urb(urb, GFP_ATOMIC);  		if (result != 0) {  			dev_err(&urb->dev->dev, @@ -894,18 +888,6 @@ static void oti6858_read_bulk_callback(struct urb *urb)  	spin_unlock_irqrestore(&priv->lock, flags);  	if (status != 0) { -		/* -		if (status == -EPROTO) { -			* PL2303 mysteriously fails with -EPROTO reschedule -			   the read * -			dbg("%s - caught -EPROTO, resubmitting the urb", -								__func__); -			result = usb_submit_urb(urb, GFP_ATOMIC); -			if (result) -				dev_err(&urb->dev->dev, "%s - failed resubmitting read urb, error %d\n", __func__, result); -			return; -		} -		*/  		dbg("%s(): unable to handle the error, exiting", __func__);  		return;  	} @@ -918,7 +900,6 @@ static void oti6858_read_bulk_callback(struct urb *urb)  	tty_kref_put(tty);  	/* schedule the interrupt urb */ -	port->interrupt_in_urb->dev = port->serial->dev;  	result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);  	if (result != 0 && result != -EPERM) {  		dev_err(&port->dev, "%s(): usb_submit_urb() failed," @@ -955,7 +936,6 @@ static void oti6858_write_bulk_callback(struct urb *urb)  		dbg("%s(): overflow in write", __func__);  		port->write_urb->transfer_buffer_length = 1; -		port->write_urb->dev = port->serial->dev;  		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);  		if (result) {  			dev_err(&port->dev, "%s(): usb_submit_urb() failed," @@ -968,7 +948,6 @@ static void oti6858_write_bulk_callback(struct urb *urb)  	priv->flags.write_urb_in_use = 0;  	/* schedule the interrupt urb if we are still open */ -	port->interrupt_in_urb->dev = port->serial->dev;  	dbg("%s(): submitting interrupt urb", __func__);  	result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);  	if (result != 0) { diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index fc2d66f7f4e..329295615d0 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -502,21 +502,20 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)  	if (tty)  		pl2303_set_termios(tty, port, &tmp_termios); -	dbg("%s - submitting read urb", __func__); -	result = usb_serial_generic_submit_read_urb(port, GFP_KERNEL); -	if (result) { -		pl2303_close(port); -		return -EPROTO; -	} -  	dbg("%s - submitting interrupt urb", __func__);  	result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);  	if (result) {  		dev_err(&port->dev, "%s - failed submitting interrupt urb,"  			" error %d\n", __func__, result); -		pl2303_close(port); -		return -EPROTO; +		return result;  	} + +	result = usb_serial_generic_open(tty, port); +	if (result) { +		usb_kill_urb(port->interrupt_in_urb); +		return result; +	} +  	port->port.drain_delay = 256;  	return 0;  } diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index b18179bda0d..f2485429172 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -681,7 +681,6 @@ static void sierra_instat_callback(struct urb *urb)  	/* Resubmit urb so we continue receiving IRQ data */  	if (status != -ESHUTDOWN && status != -ENOENT) {  		usb_mark_last_busy(serial->dev); -		urb->dev = serial->dev;  		err = usb_submit_urb(urb, GFP_ATOMIC);  		if (err && err != -EPERM)  			dev_err(&port->dev, "%s: resubmit intr urb " diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c index 7096f799b07..c70cc012d03 100644 --- a/drivers/usb/serial/symbolserial.c +++ b/drivers/usb/serial/symbolserial.c @@ -182,7 +182,6 @@ static void symbol_unthrottle(struct tty_struct *tty)  	priv->actually_throttled = false;  	spin_unlock_irq(&priv->lock); -	priv->int_urb->dev = port->serial->dev;  	if (was_throttled) {  		result = usb_submit_urb(priv->int_urb, GFP_KERNEL);  		if (result) diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index ea8445689c8..4af21f46096 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -535,9 +535,7 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port)  			status = -EINVAL;  			goto release_lock;  		} -		urb->complete = ti_interrupt_callback;  		urb->context = tdev; -		urb->dev = dev;  		status = usb_submit_urb(urb, GFP_KERNEL);  		if (status) {  			dev_err(&port->dev, @@ -619,9 +617,7 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port)  		goto unlink_int_urb;  	}  	tport->tp_read_urb_state = TI_READ_URB_RUNNING; -	urb->complete = ti_bulk_in_callback;  	urb->context = tport; -	urb->dev = dev;  	status = usb_submit_urb(urb, GFP_KERNEL);  	if (status) {  		dev_err(&port->dev, "%s - submit read urb failed, %d\n", @@ -1236,12 +1232,11 @@ static void ti_bulk_in_callback(struct urb *urb)  exit:  	/* continue to read unless stopping */  	spin_lock(&tport->tp_lock); -	if (tport->tp_read_urb_state == TI_READ_URB_RUNNING) { -		urb->dev = port->serial->dev; +	if (tport->tp_read_urb_state == TI_READ_URB_RUNNING)  		retval = usb_submit_urb(urb, GFP_ATOMIC); -	} else if (tport->tp_read_urb_state == TI_READ_URB_STOPPING) { +	else if (tport->tp_read_urb_state == TI_READ_URB_STOPPING)  		tport->tp_read_urb_state = TI_READ_URB_STOPPED; -	} +  	spin_unlock(&tport->tp_lock);  	if (retval)  		dev_err(dev, "%s - resubmit read urb failed, %d\n", @@ -1574,9 +1569,7 @@ static int ti_restart_read(struct ti_port *tport, struct tty_struct *tty)  		tport->tp_read_urb_state = TI_READ_URB_RUNNING;  		urb = tport->tp_port->read_urb;  		spin_unlock_irqrestore(&tport->tp_lock, flags); -		urb->complete = ti_bulk_in_callback;  		urb->context = tport; -		urb->dev = tport->tp_port->serial->dev;  		status = usb_submit_urb(urb, GFP_KERNEL);  	} else  {  		tport->tp_read_urb_state = TI_READ_URB_RUNNING; diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index cc274fdf262..ce6c1a65a54 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -50,7 +50,7 @@ static struct usb_driver usb_serial_driver = {  	.disconnect =	usb_serial_disconnect,  	.suspend =	usb_serial_suspend,  	.resume =	usb_serial_resume, -	.no_dynamic_id = 	1, +	.no_dynamic_id =	1,  	.supports_autosuspend =	1,  }; @@ -260,6 +260,10 @@ static int serial_activate(struct tty_port *tport, struct tty_struct *tty)  	else  		retval = port->serial->type->open(tty, port);  	mutex_unlock(&serial->disc_mutex); + +	if (retval < 0) +		retval = usb_translate_errors(retval); +  	return retval;  } @@ -360,7 +364,8 @@ static int serial_write(struct tty_struct *tty, const unsigned char *buf,  	/* pass on to the driver specific version of this function */  	retval = port->serial->type->write(tty, port, buf, count); - +	if (retval < 0) +		retval = usb_translate_errors(retval);  exit:  	return retval;  } @@ -562,8 +567,8 @@ static void kill_traffic(struct usb_serial_port *port)  {  	int i; -	usb_kill_urb(port->read_urb); -	usb_kill_urb(port->write_urb); +	for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) +		usb_kill_urb(port->read_urbs[i]);  	for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i)  		usb_kill_urb(port->write_urbs[i]);  	/* @@ -595,17 +600,17 @@ static void port_release(struct device *dev)  	kill_traffic(port);  	cancel_work_sync(&port->work); -	usb_free_urb(port->read_urb); -	usb_free_urb(port->write_urb);  	usb_free_urb(port->interrupt_in_urb);  	usb_free_urb(port->interrupt_out_urb); +	for (i = 0; i < ARRAY_SIZE(port->read_urbs); ++i) { +		usb_free_urb(port->read_urbs[i]); +		kfree(port->bulk_in_buffers[i]); +	}  	for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i) {  		usb_free_urb(port->write_urbs[i]);  		kfree(port->bulk_out_buffers[i]);  	}  	kfifo_free(&port->write_fifo); -	kfree(port->bulk_in_buffer); -	kfree(port->bulk_out_buffer);  	kfree(port->interrupt_in_buffer);  	kfree(port->interrupt_out_buffer);  	kfree(port); @@ -686,16 +691,18 @@ static int serial_carrier_raised(struct tty_port *port)  {  	struct usb_serial_port *p = container_of(port, struct usb_serial_port, port);  	struct usb_serial_driver *drv = p->serial->type; +  	if (drv->carrier_raised)  		return drv->carrier_raised(p);  	/* No carrier control - don't block */ -	return 1;	 +	return 1;  }  static void serial_dtr_rts(struct tty_port *port, int on)  {  	struct usb_serial_port *p = container_of(port, struct usb_serial_port, port);  	struct usb_serial_driver *drv = p->serial->type; +  	if (drv->dtr_rts)  		drv->dtr_rts(p, on);  } @@ -724,6 +731,7 @@ int usb_serial_probe(struct usb_interface *interface,  	unsigned int minor;  	int buffer_size;  	int i; +	int j;  	int num_interrupt_in = 0;  	int num_interrupt_out = 0;  	int num_bulk_in = 0; @@ -906,38 +914,41 @@ int usb_serial_probe(struct usb_interface *interface,  	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 = max_t(int, serial->type->bulk_in_size,  				usb_endpoint_maxp(endpoint));  		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, + +		for (j = 0; j < ARRAY_SIZE(port->read_urbs); ++j) { +			set_bit(j, &port->read_urbs_free); +			port->read_urbs[j] = usb_alloc_urb(0, GFP_KERNEL); +			if (!port->read_urbs[j]) { +				dev_err(&interface->dev, +						"No free urbs available\n"); +				goto probe_error; +			} +			port->bulk_in_buffers[j] = kmalloc(buffer_size, +								GFP_KERNEL); +			if (!port->bulk_in_buffers[j]) { +				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, +				goto probe_error; +			} +			usb_fill_bulk_urb(port->read_urbs[j], dev, +					usb_rcvbulkpipe(dev,  						endpoint->bEndpointAddress), -				port->bulk_in_buffer, buffer_size, -				serial->type->read_bulk_callback, port); +					port->bulk_in_buffers[j], buffer_size, +					serial->type->read_bulk_callback, +					port); +		} + +		port->read_urb = port->read_urbs[0]; +		port->bulk_in_buffer = port->bulk_in_buffers[0];  	}  	for (i = 0; i < num_bulk_out; ++i) { -		int j; -  		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; -		}  		if (kfifo_alloc(&port->write_fifo, PAGE_SIZE, GFP_KERNEL))  			goto probe_error;  		buffer_size = serial->type->bulk_out_size; @@ -945,17 +956,7 @@ int usb_serial_probe(struct usb_interface *interface,  			buffer_size = usb_endpoint_maxp(endpoint);  		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); +  		for (j = 0; j < ARRAY_SIZE(port->write_urbs); ++j) {  			set_bit(j, &port->write_urbs_free);  			port->write_urbs[j] = usb_alloc_urb(0, GFP_KERNEL); @@ -978,6 +979,9 @@ int usb_serial_probe(struct usb_interface *interface,  					serial->type->write_bulk_callback,  					port);  		} + +		port->write_urb = port->write_urbs[0]; +		port->bulk_out_buffer = port->bulk_out_buffers[0];  	}  	if (serial->type->read_int_callback) { @@ -1196,7 +1200,7 @@ static const struct tty_operations serial_ops = {  	.open =			serial_open,  	.close =		serial_close,  	.write =		serial_write, -	.hangup = 		serial_hangup, +	.hangup =		serial_hangup,  	.write_room =		serial_write_room,  	.ioctl =		serial_ioctl,  	.set_termios =		serial_set_termios, @@ -1206,9 +1210,9 @@ static const struct tty_operations serial_ops = {  	.chars_in_buffer =	serial_chars_in_buffer,  	.tiocmget =		serial_tiocmget,  	.tiocmset =		serial_tiocmset, -	.get_icount = 		serial_get_icount, -	.cleanup = 		serial_cleanup, -	.install = 		serial_install, +	.get_icount =		serial_get_icount, +	.cleanup =		serial_cleanup, +	.install =		serial_install,  	.proc_fops =		&serial_proc_fops,  }; @@ -1237,7 +1241,7 @@ static int __init usb_serial_init(void)  	usb_serial_tty_driver->owner = THIS_MODULE;  	usb_serial_tty_driver->driver_name = "usbserial"; -	usb_serial_tty_driver->name = 	"ttyUSB"; +	usb_serial_tty_driver->name = "ttyUSB";  	usb_serial_tty_driver->major = SERIAL_TTY_MAJOR;  	usb_serial_tty_driver->minor_start = 0;  	usb_serial_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; @@ -1336,7 +1340,6 @@ static void fixup_generic(struct usb_serial_driver *device)  int usb_serial_register(struct usb_serial_driver *driver)  { -	/* must be called with BKL held */  	int retval;  	if (usb_disabled()) @@ -1374,7 +1377,6 @@ EXPORT_SYMBOL_GPL(usb_serial_register);  void usb_serial_deregister(struct usb_serial_driver *device)  { -	/* must be called with BKL held */  	printk(KERN_INFO "USB Serial deregistering driver %s\n",  	       device->description);  	mutex_lock(&table_lock); diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c index 95a82148ee8..9b632e75321 100644 --- a/drivers/usb/serial/usb_debug.c +++ b/drivers/usb/serial/usb_debug.c @@ -40,7 +40,7 @@ static struct usb_driver debug_driver = {  	.probe =	usb_serial_probe,  	.disconnect =	usb_serial_disconnect,  	.id_table =	id_table, -	.no_dynamic_id = 	1, +	.no_dynamic_id =	1,  };  /* This HW really does not support a serial break, so one will be @@ -54,19 +54,18 @@ static void usb_debug_break_ctl(struct tty_struct *tty, int break_state)  	usb_serial_generic_write(tty, port, USB_DEBUG_BRK, USB_DEBUG_BRK_SIZE);  } -static void usb_debug_read_bulk_callback(struct urb *urb) +static void usb_debug_process_read_urb(struct urb *urb)  {  	struct usb_serial_port *port = urb->context;  	if (urb->actual_length == USB_DEBUG_BRK_SIZE && -	    memcmp(urb->transfer_buffer, USB_DEBUG_BRK, -		   USB_DEBUG_BRK_SIZE) == 0) { +		memcmp(urb->transfer_buffer, USB_DEBUG_BRK, +						USB_DEBUG_BRK_SIZE) == 0) {  		usb_serial_handle_break(port); -		usb_serial_generic_submit_read_urb(port, GFP_ATOMIC);  		return;  	} -	usb_serial_generic_read_bulk_callback(urb); +	usb_serial_generic_process_read_urb(urb);  }  static struct usb_serial_driver debug_device = { @@ -79,7 +78,7 @@ static struct usb_serial_driver debug_device = {  	.num_ports =		1,  	.bulk_out_size =	USB_DEBUG_MAX_PACKET_SIZE,  	.break_ctl =		usb_debug_break_ctl, -	.read_bulk_callback =	usb_debug_read_bulk_callback, +	.process_read_urb =	usb_debug_process_read_urb,  };  static int __init debug_init(void) diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 5b073bcc807..11af903cb09 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -14,57 +14,6 @@   *   * See Documentation/usb/usb-serial.txt for more information on using this   * driver - * - * (10/09/2002) Stuart MacDonald (stuartm@connecttech.com) - *	Upgrade to full working driver - * - * (05/30/2001) gkh - *	switched from using spinlock to a semaphore, which fixes lots of - *	problems. - * - * (04/08/2001) gb - *	Identify version on module load. - * - * 2001_Mar_19 gkh - *	Fixed MOD_INC and MOD_DEC logic, the ability to open a port more - *	than once, and the got the proper usb_device_id table entries so - *	the driver works again. - * - * (11/01/2000) Adam J. Richter - *	usb_device_id table support - * - * (10/05/2000) gkh - *	Fixed bug with urb->dev not being set properly, now that the usb - *	core needs it. - * - * (10/03/2000) smd - *	firmware is improved to guard against crap sent to device - *	firmware now replies CMD_FAILURE on bad things - *	read_callback fix you provided for private info struct - *	command_finished now indicates success or fail - *	setup_port struct now packed to avoid gcc padding - *	firmware uses 1 based port numbering, driver now handles that - * - * (09/11/2000) gkh - *	Removed DEBUG #ifdefs with call to usb_serial_debug_data - * - * (07/19/2000) gkh - *	Added module_init and module_exit functions to handle the fact that this - *	driver is a loadable module now. - *	Fixed bug with port->minor that was found by Al Borchers - * - * (07/04/2000) gkh - *	Added support for port settings. Baud rate can now be changed. Line - *	signals are not transferred to and from the tty layer yet, but things - *	seem to be working well now. - * - * (05/04/2000) gkh - *	First cut at open and close commands. Data can flow through the ports at - *	default speeds now. - * - * (03/26/2000) gkh - *	Split driver up into device specific pieces. - *   */  #include <linux/kernel.h> @@ -753,7 +702,6 @@ static void whiteheat_close(struct usb_serial_port *port)  static int whiteheat_write(struct tty_struct *tty,  	struct usb_serial_port *port, const unsigned char *buf, int count)  { -	struct usb_serial *serial = port->serial;  	struct whiteheat_private *info = usb_get_serial_port_data(port);  	struct whiteheat_urb_wrap *wrap;  	struct urb *urb; @@ -789,7 +737,6 @@ static int whiteheat_write(struct tty_struct *tty,  		usb_serial_debug_data(debug, &port->dev,  				__func__, bytes, urb->transfer_buffer); -		urb->dev = serial->dev;  		urb->transfer_buffer_length = bytes;  		result = usb_submit_urb(urb, GFP_ATOMIC);  		if (result) { @@ -1035,7 +982,6 @@ static void command_port_read_callback(struct urb *urb)  		dbg("%s - bad reply from firmware", __func__);  	/* Continue trying to always read */ -	command_port->read_urb->dev = command_port->serial->dev;  	result = usb_submit_urb(command_port->read_urb, GFP_ATOMIC);  	if (result)  		dbg("%s - failed resubmitting read urb, error %d", @@ -1141,7 +1087,6 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command,  	transfer_buffer[0] = command;  	memcpy(&transfer_buffer[1], data, datasize);  	command_port->write_urb->transfer_buffer_length = datasize + 1; -	command_port->write_urb->dev = port->serial->dev;  	retval = usb_submit_urb(command_port->write_urb, GFP_NOIO);  	if (retval) {  		dbg("%s - submit urb failed", __func__); @@ -1362,7 +1307,6 @@ static int start_command_port(struct usb_serial *serial)  		/* Work around HCD bugs */  		usb_clear_halt(serial->dev, command_port->read_urb->pipe); -		command_port->read_urb->dev = serial->dev;  		retval = usb_submit_urb(command_port->read_urb, GFP_KERNEL);  		if (retval) {  			dev_err(&serial->dev->dev, @@ -1410,7 +1354,6 @@ static int start_port_read(struct usb_serial_port *port)  		list_del(tmp);  		wrap = list_entry(tmp, struct whiteheat_urb_wrap, list);  		urb = wrap->urb; -		urb->dev = port->serial->dev;  		spin_unlock_irqrestore(&info->lock, flags);  		retval = usb_submit_urb(urb, GFP_KERNEL);  		if (retval) { @@ -1490,7 +1433,6 @@ static void rx_data_softint(struct work_struct *work)  			sent += tty_insert_flip_string(tty,  				urb->transfer_buffer, urb->actual_length); -		urb->dev = port->serial->dev;  		result = usb_submit_urb(urb, GFP_ATOMIC);  		if (result) {  			dev_err(&port->dev, diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index 42d0eaed4a0..9ce3bbab6d2 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c @@ -139,7 +139,7 @@ static int init_alauda(struct us_data *us);  { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \    .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id alauda_usb_ids[] = { +static struct usb_device_id alauda_usb_ids[] = {  #	include "unusual_alauda.h"  	{ }		/* Terminating entry */  }; diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c index c8447182118..740bfe6b2d2 100644 --- a/drivers/usb/storage/cypress_atacb.c +++ b/drivers/usb/storage/cypress_atacb.c @@ -43,7 +43,7 @@ MODULE_LICENSE("GPL");  { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \    .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id cypress_usb_ids[] = { +static struct usb_device_id cypress_usb_ids[] = {  #	include "unusual_cypress.h"  	{ }		/* Terminating entry */  }; diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index ded836b02d7..0d8d97c94f0 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c @@ -88,7 +88,7 @@ static int datafab_determine_lun(struct us_data *us,  { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \    .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id datafab_usb_ids[] = { +static struct usb_device_id datafab_usb_ids[] = {  #	include "unusual_datafab.h"  	{ }		/* Terminating entry */  }; diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index 9fbe742343c..b990726f144 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -42,7 +42,7 @@ MODULE_LICENSE("GPL");  { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \  	.driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id ene_ub6250_usb_ids[] = { +static struct usb_device_id ene_ub6250_usb_ids[] = {  #	include "unusual_ene_ub6250.h"  	{ }		/* Terminating entry */  }; @@ -607,8 +607,8 @@ static int sd_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb)  static int sd_scsi_read_capacity(struct us_data *us, struct scsi_cmnd *srb)  { -	u32   bl_num; -	u16    bl_len; +	u32	bl_num; +	u32	bl_len;  	unsigned int offset = 0;  	unsigned char    buf[8];  	struct scatterlist *sg = NULL; @@ -622,7 +622,7 @@ static int sd_scsi_read_capacity(struct us_data *us, struct scsi_cmnd *srb)  		else  			bl_num = (info->HC_C_SIZE + 1) * 1024 - 1;  	} else { -		bl_len = 1<<(info->SD_READ_BL_LEN); +		bl_len = 1 << (info->SD_READ_BL_LEN);  		bl_num = info->SD_Block_Mult * (info->SD_C_SIZE + 1)  				* (1 << (info->SD_C_SIZE_MULT + 2)) - 1;  	} @@ -777,7 +777,7 @@ static int ms_lib_free_logicalmap(struct us_data *us)  	return 0;  } -int ms_lib_alloc_logicalmap(struct us_data *us) +static int ms_lib_alloc_logicalmap(struct us_data *us)  {  	u32  i;  	struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; @@ -2248,7 +2248,7 @@ static int sd_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)  /*   * ms_scsi_irp()   */ -int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb) +static int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb)  {  	int result;  	struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra; diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index 6542ca40d50..8cf16f89c96 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c @@ -119,7 +119,7 @@ static int init_freecom(struct us_data *us);  { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \    .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id freecom_usb_ids[] = { +static struct usb_device_id freecom_usb_ids[] = {  #	include "unusual_freecom.h"  	{ }		/* Terminating entry */  }; diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index ffc4193e950..7b813036b48 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -76,7 +76,7 @@ static int isd200_Initialization(struct us_data *us);  { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \    .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id isd200_usb_ids[] = { +static struct usb_device_id isd200_usb_ids[] = {  #	include "unusual_isd200.h"  	{ }		/* Terminating entry */  }; diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index 6168596c5ac..5ef55c7d73e 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c @@ -71,7 +71,7 @@ MODULE_LICENSE("GPL");  { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \    .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id jumpshot_usb_ids[] = { +static struct usb_device_id jumpshot_usb_ids[] = {  #	include "unusual_jumpshot.h"  	{ }		/* Terminating entry */  }; diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index ba1b7890688..fb5bfb00d79 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c @@ -59,7 +59,7 @@ static int rio_karma_init(struct us_data *us);  { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \    .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id karma_usb_ids[] = { +static struct usb_device_id karma_usb_ids[] = {  #	include "unusual_karma.h"  	{ }		/* Terminating entry */  }; diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 1943be5a291..d29be3e8113 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c @@ -69,7 +69,7 @@ struct usb_onetouch {  { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \    .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id onetouch_usb_ids[] = { +static struct usb_device_id onetouch_usb_ids[] = {  #	include "unusual_onetouch.h"  	{ }		/* Terminating entry */  }; diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 0ce5f79197e..71147679cb1 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -398,10 +398,9 @@ static int rts51x_write_mem(struct us_data *us, u16 addr, u8 *data, u16 len)  	u8 cmnd[12] = { 0 };  	u8 *buf; -	buf = kmalloc(len, GFP_NOIO); +	buf = kmemdup(data, len, GFP_NOIO);  	if (buf == NULL)  		return USB_STOR_TRANSPORT_ERROR; -	memcpy(buf, data, len);  	US_DEBUGP("%s, addr = 0x%x, len = %d\n", __func__, addr, len); @@ -507,15 +506,14 @@ static int enable_oscillator(struct us_data *us)  static int __do_config_autodelink(struct us_data *us, u8 *data, u16 len)  {  	int retval; -	u16 addr = 0xFE47;  	u8 cmnd[12] = {0}; -	US_DEBUGP("%s, addr = 0x%x, len = %d\n", __FUNCTION__, addr, len); +	US_DEBUGP("%s, addr = 0xfe47, len = %d\n", __FUNCTION__, len);  	cmnd[0] = 0xF0;  	cmnd[1] = 0x0E; -	cmnd[2] = (u8)(addr >> 8); -	cmnd[3] = (u8)addr; +	cmnd[2] = 0xfe; +	cmnd[3] = 0x47;  	cmnd[4] = (u8)(len >> 8);  	cmnd[5] = (u8)len; @@ -818,7 +816,7 @@ static inline int working_scsi(struct scsi_cmnd *srb)  	return 1;  } -void rts51x_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) +static void rts51x_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)  {  	struct rts51x_chip *chip = (struct rts51x_chip *)(us->extra);  	static int card_first_show = 1; @@ -977,7 +975,7 @@ static void realtek_cr_destructor(void *extra)  }  #ifdef CONFIG_PM -int realtek_cr_suspend(struct usb_interface *iface, pm_message_t message) +static int realtek_cr_suspend(struct usb_interface *iface, pm_message_t message)  {  	struct us_data *us = usb_get_intfdata(iface); diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index bcb9a709d34..6ecbf44c7ec 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -71,7 +71,7 @@ static int usb_stor_sddr09_init(struct us_data *us);  { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \    .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id sddr09_usb_ids[] = { +static struct usb_device_id sddr09_usb_ids[] = {  #	include "unusual_sddr09.h"  	{ }		/* Terminating entry */  }; diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index 44dfed7754e..f2930441a2f 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c @@ -48,7 +48,7 @@ MODULE_LICENSE("GPL");  { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \    .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id sddr55_usb_ids[] = { +static struct usb_device_id sddr55_usb_ids[] = {  #	include "unusual_sddr55.h"  	{ }		/* Terminating entry */  }; diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 0b00091d2ae..7d642c8efed 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -170,7 +170,7 @@ static int init_usbat_flash(struct us_data *us);  { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \    .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id usbat_usb_ids[] = { +static struct usb_device_id usbat_usb_ids[] = {  #	include "unusual_usbat.h"  	{ }		/* Terminating entry */  }; diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c index 371f61733f0..fa810a83e83 100644 --- a/drivers/usb/wusbcore/security.c +++ b/drivers/usb/wusbcore/security.c @@ -354,7 +354,7 @@ int wusb_dev_4way_handshake(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev,  	struct wusb_keydvt_in keydvt_in;  	struct wusb_keydvt_out keydvt_out; -	hs = kzalloc(3*sizeof(hs[0]), GFP_KERNEL); +	hs = kcalloc(3, sizeof(hs[0]), GFP_KERNEL);  	if (hs == NULL) {  		dev_err(dev, "can't allocate handshake data\n");  		goto error_kzalloc;  |