kernel: USB update from stlinux24_217
This commit is contained in:
		| @@ -49,7 +49,8 @@ config USB_ARCH_HAS_OHCI | ||||
| 	default y if CPU_SUBTYPE_SH7721 | ||||
| 	default y if CPU_SUBTYPE_SH7763 | ||||
| 	default y if CPU_SUBTYPE_SH7786 | ||||
| 	default y if CPU_SUBTYPE_FLI7510 | ||||
| 	default y if CPU_SUBTYPE_FLI75XX | ||||
| 	default y if CPU_SUBTYPE_STXH205 | ||||
| 	default y if CPU_SUBTYPE_STX5197 | ||||
| 	default y if CPU_SUBTYPE_STX5206 | ||||
| 	default y if CPU_SUBTYPE_STX7100 | ||||
| @@ -69,7 +70,8 @@ config USB_ARCH_HAS_EHCI | ||||
| 	default y if ARCH_IXP4XX | ||||
| 	default y if ARCH_W90X900 | ||||
| 	default y if ARCH_AT91SAM9G45 | ||||
| 	default y if CPU_SUBTYPE_FLI7510 | ||||
| 	default y if CPU_SUBTYPE_FLI75XX | ||||
| 	default y if CPU_SUBTYPE_STXH205 | ||||
| 	default y if CPU_SUBTYPE_STX5197 | ||||
| 	default y if CPU_SUBTYPE_STX5206 | ||||
| 	default y if CPU_SUBTYPE_STX7100 | ||||
|   | ||||
| @@ -1120,7 +1120,8 @@ skip_normal_probe: | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) | ||||
| 	if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 || | ||||
| 	    control_interface->cur_altsetting->desc.bNumEndpoints == 0) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	epctrl = &control_interface->cur_altsetting->endpoint[0].desc; | ||||
| @@ -1264,6 +1265,8 @@ made_compressed_probe: | ||||
| 		i = device_create_file(&intf->dev, &dev_attr_wCountryCodes); | ||||
| 		if (i < 0) { | ||||
| 			kfree(acm->country_codes); | ||||
| 			acm->country_codes = NULL; | ||||
| 			acm->country_code_size = 0; | ||||
| 			goto skip_countries; | ||||
| 		} | ||||
|  | ||||
| @@ -1272,6 +1275,8 @@ made_compressed_probe: | ||||
| 		if (i < 0) { | ||||
| 			device_remove_file(&intf->dev, &dev_attr_wCountryCodes); | ||||
| 			kfree(acm->country_codes); | ||||
| 			acm->country_codes = NULL; | ||||
| 			acm->country_code_size = 0; | ||||
| 			goto skip_countries; | ||||
| 		} | ||||
| 	} | ||||
| @@ -1528,6 +1533,16 @@ static struct usb_device_id acm_ids[] = { | ||||
| 	}, | ||||
| 	{ USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ | ||||
| 	}, | ||||
| 	/* Motorola H24 HSPA module: */ | ||||
| 	{ USB_DEVICE(0x22b8, 0x2d91) }, /* modem                                */ | ||||
| 	{ USB_DEVICE(0x22b8, 0x2d92) }, /* modem           + diagnostics        */ | ||||
| 	{ USB_DEVICE(0x22b8, 0x2d93) }, /* modem + AT port                      */ | ||||
| 	{ USB_DEVICE(0x22b8, 0x2d95) }, /* modem + AT port + diagnostics        */ | ||||
| 	{ USB_DEVICE(0x22b8, 0x2d96) }, /* modem                         + NMEA */ | ||||
| 	{ USB_DEVICE(0x22b8, 0x2d97) }, /* modem           + diagnostics + NMEA */ | ||||
| 	{ USB_DEVICE(0x22b8, 0x2d99) }, /* modem + AT port               + NMEA */ | ||||
| 	{ USB_DEVICE(0x22b8, 0x2d9a) }, /* modem + AT port + diagnostics + NMEA */ | ||||
|  | ||||
| 	{ USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ | ||||
| 	.driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on | ||||
| 					   data interface instead of | ||||
| @@ -1606,6 +1621,9 @@ static struct usb_device_id acm_ids[] = { | ||||
| 	{ NOKIA_PCSUITE_ACM_INFO(0x03cd), }, /* Nokia C7 */ | ||||
| 	{ SAMSUNG_PCSUITE_ACM_INFO(0x6651), }, /* Samsung GTi8510 (INNOV8) */ | ||||
|  | ||||
| 	/* Support for Owen devices */ | ||||
| 	{ USB_DEVICE(0x03eb, 0x0030), }, /* Owen SI30 */ | ||||
|  | ||||
| 	/* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */ | ||||
|  | ||||
| 	/* control interfaces without any protocol set */ | ||||
|   | ||||
| @@ -52,6 +52,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); | ||||
| #define WDM_READ		4 | ||||
| #define WDM_INT_STALL		5 | ||||
| #define WDM_POLL_RUNNING	6 | ||||
| #define WDM_OVERFLOW		10 | ||||
|  | ||||
|  | ||||
| #define WDM_MAX			16 | ||||
| @@ -115,6 +116,7 @@ static void wdm_in_callback(struct urb *urb) | ||||
| { | ||||
| 	struct wdm_device *desc = urb->context; | ||||
| 	int status = urb->status; | ||||
| 	int length = urb->actual_length; | ||||
|  | ||||
| 	spin_lock(&desc->iuspin); | ||||
|  | ||||
| @@ -144,9 +146,17 @@ static void wdm_in_callback(struct urb *urb) | ||||
| 	} | ||||
|  | ||||
| 	desc->rerr = status; | ||||
| 	desc->reslength = urb->actual_length; | ||||
| 	memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); | ||||
| 	desc->length += desc->reslength; | ||||
| 	if (length + desc->length > desc->wMaxCommand) { | ||||
| 		/* The buffer would overflow */ | ||||
| 		set_bit(WDM_OVERFLOW, &desc->flags); | ||||
| 	} else { | ||||
| 		/* we may already be in overflow */ | ||||
| 		if (!test_bit(WDM_OVERFLOW, &desc->flags)) { | ||||
| 			memmove(desc->ubuf + desc->length, desc->inbuf, length); | ||||
| 			desc->length += length; | ||||
| 			desc->reslength = length; | ||||
| 		} | ||||
| 	} | ||||
| 	wake_up(&desc->wait); | ||||
|  | ||||
| 	set_bit(WDM_READ, &desc->flags); | ||||
| @@ -277,7 +287,7 @@ static void cleanup(struct wdm_device *desc) | ||||
| 			desc->sbuf, | ||||
| 			desc->validity->transfer_dma); | ||||
| 	usb_buffer_free(interface_to_usbdev(desc->intf), | ||||
| 			desc->wMaxCommand, | ||||
| 			desc->bMaxPacketSize0, | ||||
| 			desc->inbuf, | ||||
| 			desc->response->transfer_dma); | ||||
| 	kfree(desc->orq); | ||||
| @@ -314,7 +324,7 @@ static ssize_t wdm_write | ||||
| 	if (r < 0) | ||||
| 		goto outnp; | ||||
|  | ||||
| 	if (!file->f_flags && O_NONBLOCK) | ||||
| 	if (!(file->f_flags & O_NONBLOCK)) | ||||
| 		r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, | ||||
| 								&desc->flags)); | ||||
| 	else | ||||
| @@ -398,6 +408,11 @@ retry: | ||||
| 			rv = -ENODEV; | ||||
| 			goto err; | ||||
| 		} | ||||
| 		if (test_bit(WDM_OVERFLOW, &desc->flags)) { | ||||
| 			clear_bit(WDM_OVERFLOW, &desc->flags); | ||||
| 			rv = -ENOBUFS; | ||||
| 			goto err; | ||||
| 		} | ||||
| 		i++; | ||||
| 		if (file->f_flags & O_NONBLOCK) { | ||||
| 			if (!test_bit(WDM_READ, &desc->flags)) { | ||||
| @@ -440,7 +455,10 @@ retry: | ||||
| 			spin_unlock_irq(&desc->iuspin); | ||||
| 			goto retry; | ||||
| 		} | ||||
|  | ||||
| 		if (!desc->reslength) { /* zero length read */ | ||||
| 			dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__); | ||||
| 			clear_bit(WDM_READ, &desc->flags); | ||||
| 			spin_unlock_irq(&desc->iuspin); | ||||
| 			goto retry; | ||||
| 		} | ||||
| @@ -458,7 +476,9 @@ retry: | ||||
| 	for (i = 0; i < desc->length - cntr; i++) | ||||
| 		desc->ubuf[i] = desc->ubuf[i + cntr]; | ||||
|  | ||||
| 	spin_lock_irq(&desc->iuspin); | ||||
| 	desc->length -= cntr; | ||||
| 	spin_unlock_irq(&desc->iuspin); | ||||
| 	/* in case we had outstanding data */ | ||||
| 	if (!desc->length) | ||||
| 		clear_bit(WDM_READ, &desc->flags); | ||||
| @@ -840,6 +860,7 @@ static int wdm_post_reset(struct usb_interface *intf) | ||||
| 	struct wdm_device *desc = usb_get_intfdata(intf); | ||||
| 	int rv; | ||||
|  | ||||
| 	clear_bit(WDM_OVERFLOW, &desc->flags); | ||||
| 	rv = recover_from_urb_loss(desc); | ||||
| 	mutex_unlock(&desc->plock); | ||||
| 	return 0; | ||||
|   | ||||
| @@ -267,7 +267,7 @@ usbtmc_abort_bulk_in_status: | ||||
| 				dev_err(dev, "usb_bulk_msg returned %d\n", rv); | ||||
| 				goto exit; | ||||
| 			} | ||||
| 		} while ((actual = max_size) && | ||||
| 		} while ((actual == max_size) && | ||||
| 			 (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN)); | ||||
|  | ||||
| 	if (actual == max_size) { | ||||
|   | ||||
| @@ -403,7 +403,7 @@ static void async_completed(struct urb *urb) | ||||
| 		sinfo.si_errno = as->status; | ||||
| 		sinfo.si_code = SI_ASYNCIO; | ||||
| 		sinfo.si_addr = as->userurb; | ||||
| 		pid = as->pid; | ||||
| 		pid = get_pid(as->pid); | ||||
| 		uid = as->uid; | ||||
| 		euid = as->euid; | ||||
| 		secid = as->secid; | ||||
| @@ -416,9 +416,11 @@ static void async_completed(struct urb *urb) | ||||
| 		cancel_bulk_urbs(ps, as->bulk_addr); | ||||
| 	spin_unlock(&ps->lock); | ||||
|  | ||||
| 	if (signr) | ||||
| 	if (signr) { | ||||
| 		kill_pid_info_as_uid(sinfo.si_signo, &sinfo, pid, uid, | ||||
| 				      euid, secid); | ||||
| 		put_pid(pid); | ||||
| 	} | ||||
|  | ||||
| 	wake_up(&ps->wait); | ||||
| } | ||||
| @@ -1452,10 +1454,14 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) | ||||
| 	void __user *addr = as->userurb; | ||||
| 	unsigned int i; | ||||
|  | ||||
| 	if (as->userbuffer && urb->actual_length) | ||||
| 		if (copy_to_user(as->userbuffer, urb->transfer_buffer, | ||||
| 				 urb->actual_length)) | ||||
| 	if (as->userbuffer && urb->actual_length) { | ||||
| 		if (urb->number_of_packets > 0)		/* Isochronous */ | ||||
| 			i = urb->transfer_buffer_length; | ||||
| 		else					/* Non-Isoc */ | ||||
| 			i = urb->actual_length; | ||||
| 		if (copy_to_user(as->userbuffer, urb->transfer_buffer, i)) | ||||
| 			return -EFAULT; | ||||
| 	} | ||||
| 	if (put_user(as->status, &userurb->status)) | ||||
| 		return -EFAULT; | ||||
| 	if (put_user(urb->actual_length, &userurb->actual_length)) | ||||
|   | ||||
| @@ -1187,13 +1187,22 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) | ||||
| 		for (; i < udev->actconfig->desc.bNumInterfaces; i++) { | ||||
| 			intf = udev->actconfig->interface[i]; | ||||
| 			status = usb_suspend_interface(udev, intf, msg); | ||||
|  | ||||
| 			/* Ignore errors during system sleep transitions */ | ||||
| 			if (!(msg.event & PM_EVENT_AUTO)) | ||||
| 				status = 0; | ||||
| 			if (status != 0) | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
| 	if (status == 0) | ||||
| 	if (status == 0) { | ||||
| 		status = usb_suspend_device(udev, msg); | ||||
|  | ||||
| 		/* Again, ignore errors during system sleep transitions */ | ||||
| 		if (!(msg.event & PM_EVENT_AUTO)) | ||||
| 			status = 0; | ||||
| 	} | ||||
|  | ||||
| 	/* If the suspend failed, resume interfaces that did get suspended */ | ||||
| 	if (status != 0) { | ||||
| 		pm_message_t msg2; | ||||
|   | ||||
| @@ -23,6 +23,7 @@ | ||||
| #include <linux/mutex.h> | ||||
| #include <linux/freezer.h> | ||||
| #include <linux/usb/quirks.h> | ||||
| #include <linux/random.h> | ||||
|  | ||||
| #include <asm/uaccess.h> | ||||
| #include <asm/byteorder.h> | ||||
| @@ -458,10 +459,8 @@ hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt) | ||||
|  * talking to TTs must queue control transfers (not just bulk and iso), so | ||||
|  * both can talk to the same hub concurrently. | ||||
|  */ | ||||
| static void hub_tt_work(struct work_struct *work) | ||||
| void _hub_tt_work(struct usb_hub *hub) | ||||
| { | ||||
| 	struct usb_hub		*hub = | ||||
| 		container_of(work, struct usb_hub, tt.clear_work); | ||||
| 	unsigned long		flags; | ||||
| 	int			limit = 100; | ||||
|  | ||||
| @@ -496,6 +495,14 @@ static void hub_tt_work(struct work_struct *work) | ||||
| 	spin_unlock_irqrestore (&hub->tt.lock, flags); | ||||
| } | ||||
|  | ||||
| void hub_tt_work(struct work_struct *work) | ||||
| { | ||||
| 	struct usb_hub		*hub = | ||||
| 		container_of(work, struct usb_hub, tt.clear_work); | ||||
|  | ||||
| 	_hub_tt_work(hub); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub | ||||
|  * @urb: an URB associated with the failed or incomplete split transaction | ||||
| @@ -543,7 +550,20 @@ int usb_hub_clear_tt_buffer(struct urb *urb) | ||||
| 	/* tell keventd to clear state for this TT */ | ||||
| 	spin_lock_irqsave (&tt->lock, flags); | ||||
| 	list_add_tail (&clear->clear_list, &tt->clear_list); | ||||
| 	schedule_work(&tt->clear_work); | ||||
| 	/* don't schedule on kevent if we're running on keventd (e.g., | ||||
| 	 * in hid_reset we can get here on kevent) unless on >=2.6.36 | ||||
| 	 */ | ||||
| 	if (!current_is_keventd()) | ||||
| 		/* put it on keventd */ | ||||
| 		schedule_work(&tt->clear_work); | ||||
| 	else { | ||||
| 		/* let khubd do it */ | ||||
| 		struct usb_hub		*hub = | ||||
| 			container_of(&tt->clear_work, struct usb_hub, | ||||
| 					tt.clear_work); | ||||
| 		kick_khubd(hub); | ||||
| 	} | ||||
|  | ||||
| 	spin_unlock_irqrestore (&tt->lock, flags); | ||||
| 	return 0; | ||||
| } | ||||
| @@ -1812,6 +1832,16 @@ int usb_new_device(struct usb_device *udev) | ||||
| 	/* Tell the world! */ | ||||
| 	announce_device(udev); | ||||
|  | ||||
| #if 0 | ||||
| 	if (udev->serial) | ||||
| 		add_device_randomness(udev->serial, strlen(udev->serial)); | ||||
| 	if (udev->product) | ||||
| 		add_device_randomness(udev->product, strlen(udev->product)); | ||||
| 	if (udev->manufacturer) | ||||
| 		add_device_randomness(udev->manufacturer, | ||||
| 				      strlen(udev->manufacturer)); | ||||
| #endif | ||||
|  | ||||
| 	/* Register the device.  The device driver is responsible | ||||
| 	 * for configuring the device and invoking the add-device | ||||
| 	 * notifier chain (used by usbfs and possibly others). | ||||
| @@ -2188,6 +2218,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | ||||
| 				USB_DEVICE_REMOTE_WAKEUP, 0, | ||||
| 				NULL, 0, | ||||
| 				USB_CTRL_SET_TIMEOUT); | ||||
|  | ||||
| 		/* System sleep transitions should never fail */ | ||||
| 		if (!(msg.event & PM_EVENT_AUTO)) | ||||
| 			status = 0; | ||||
| 	} else { | ||||
| 		/* device has up to 10 msec to fully suspend */ | ||||
| 		dev_dbg(&udev->dev, "usb %ssuspend\n", | ||||
| @@ -2427,16 +2461,15 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) | ||||
| 	struct usb_device	*hdev = hub->hdev; | ||||
| 	unsigned		port1; | ||||
|  | ||||
| 	/* fail if children aren't already suspended */ | ||||
| 	/* Warn if children aren't already suspended */ | ||||
| 	for (port1 = 1; port1 <= hdev->maxchild; port1++) { | ||||
| 		struct usb_device	*udev; | ||||
|  | ||||
| 		udev = hdev->children [port1-1]; | ||||
| 		if (udev && udev->can_submit) { | ||||
| 			if (!(msg.event & PM_EVENT_AUTO)) | ||||
| 				dev_dbg(&intf->dev, "port %d nyet suspended\n", | ||||
| 						port1); | ||||
| 			return -EBUSY; | ||||
| 			dev_warn(&intf->dev, "port %d nyet suspended\n", port1); | ||||
| 			if (msg.event & PM_EVENT_AUTO) | ||||
| 				return -EBUSY; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -3271,6 +3304,10 @@ static void hub_events(void) | ||||
| 		if (hub->quiescing) | ||||
| 			goto loop_autopm; | ||||
|  | ||||
| 		/* _hub_tt_work usually run on keventd */ | ||||
| 		if (!list_empty(&hub->tt.clear_list)) | ||||
| 			_hub_tt_work(hub); | ||||
|  | ||||
| 		if (hub->error) { | ||||
| 			dev_dbg (hub_dev, "resetting for error %d\n", | ||||
| 				hub->error); | ||||
|   | ||||
| @@ -38,6 +38,51 @@ static const struct usb_device_id usb_quirk_list[] = { | ||||
| 	/* Creative SB Audigy 2 NX */ | ||||
| 	{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Webcam C200 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x0802), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Webcam C250 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Webcam B/C500 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Webcam C600 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Webcam Pro 9000 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Webcam C905 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Webcam C210 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Webcam C260 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Webcam C310 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Webcam C910 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Webcam C160 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Webcam C270 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Quickcam Pro 9000 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Quickcam E3500 */ | ||||
| 	{ USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Quickcam Vision Pro */ | ||||
| 	{ USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Logitech Harmony 700-series */ | ||||
| 	{ USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, | ||||
|  | ||||
| @@ -69,6 +114,12 @@ static const struct usb_device_id usb_quirk_list[] = { | ||||
| 	{ USB_DEVICE(0x06a3, 0x0006), .driver_info = | ||||
| 			USB_QUIRK_CONFIG_INTF_STRINGS }, | ||||
|  | ||||
| 	/* Guillemot Webcam Hercules Dualpix Exchange (2nd ID) */ | ||||
| 	{ USB_DEVICE(0x06f8, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* Guillemot Webcam Hercules Dualpix Exchange*/ | ||||
| 	{ USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
| 	/* M-Systems Flash Disk Pioneers */ | ||||
| 	{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, | ||||
|  | ||||
|   | ||||
| @@ -449,7 +449,7 @@ static int dbgp_ehci_startup(void) | ||||
| 	writel(FLAG_CF, &ehci_regs->configured_flag); | ||||
|  | ||||
| 	/* Wait until the controller is no longer halted */ | ||||
| 	loop = 10; | ||||
| 	loop = 1000; | ||||
| 	do { | ||||
| 		status = readl(&ehci_regs->status); | ||||
| 		if (!(status & STS_HALT)) | ||||
|   | ||||
| @@ -1886,6 +1886,7 @@ static int dummy_hcd_probe(struct platform_device *pdev) | ||||
| 	if (!hcd) | ||||
| 		return -ENOMEM; | ||||
| 	the_controller = hcd_to_dummy (hcd); | ||||
| 	hcd->has_tt = 1; | ||||
|  | ||||
| 	retval = usb_add_hcd(hcd, 0, 0); | ||||
| 	if (retval != 0) { | ||||
|   | ||||
| @@ -373,7 +373,7 @@ int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume) | ||||
|  | ||||
| 	/* support autoresume for remote wakeup testing */ | ||||
| 	if (autoresume) | ||||
| 		sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||||
| 		loopback_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||||
|  | ||||
| 	/* support OTG systems */ | ||||
| 	if (gadget_is_otg(cdev->gadget)) { | ||||
|   | ||||
| @@ -41,7 +41,7 @@ | ||||
|  * (host controller _Structural_ parameters) | ||||
|  * see EHCI spec, Table 2-4 for each value | ||||
|  */ | ||||
| static void dbg_hcs_params (struct ehci_hcd *ehci, char *label) | ||||
| static inline void dbg_hcs_params(struct ehci_hcd *ehci, char *label) | ||||
| { | ||||
| 	u32	params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||||
|  | ||||
| @@ -85,7 +85,7 @@ static inline void dbg_hcs_params (struct ehci_hcd *ehci, char *label) {} | ||||
|  * (host controller _Capability_ parameters) | ||||
|  * see EHCI Spec, Table 2-5 for each value | ||||
|  * */ | ||||
| static void dbg_hcc_params (struct ehci_hcd *ehci, char *label) | ||||
| static inline void dbg_hcc_params(struct ehci_hcd *ehci, char *label) | ||||
| { | ||||
| 	u32	params = ehci_readl(ehci, &ehci->caps->hcc_params); | ||||
|  | ||||
|   | ||||
| @@ -84,7 +84,8 @@ static const char	hcd_name [] = "ehci_hcd"; | ||||
| #define EHCI_IAA_MSECS		10		/* arbitrary */ | ||||
| #define EHCI_IO_JIFFIES		(HZ/10)		/* io watchdog > irq_thresh */ | ||||
| #define EHCI_ASYNC_JIFFIES	(HZ/20)		/* async idle timeout */ | ||||
| #define EHCI_SHRINK_FRAMES	5		/* async qh unlink delay */ | ||||
| #define EHCI_SHRINK_JIFFIES	(DIV_ROUND_UP(HZ, 200) + 1) | ||||
| 						/* 200-ms async qh unlink delay */ | ||||
|  | ||||
| /* Initial IRQ latency:  faster than hw default */ | ||||
| static int log2_irq_thresh = 0;		// 0 to 6 | ||||
| @@ -139,10 +140,7 @@ timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action) | ||||
| 			break; | ||||
| 		/* case TIMER_ASYNC_SHRINK: */ | ||||
| 		default: | ||||
| 			/* add a jiffie since we synch against the | ||||
| 			 * 8 KHz uframe counter. | ||||
| 			 */ | ||||
| 			t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1; | ||||
| 			t = EHCI_SHRINK_JIFFIES; | ||||
| 			break; | ||||
| 		} | ||||
| 		mod_timer(&ehci->watchdog, t + jiffies); | ||||
| @@ -432,7 +430,7 @@ static void ehci_shutdown(struct usb_hcd *hcd) | ||||
| 	spin_unlock_irq(&ehci->lock); | ||||
| } | ||||
|  | ||||
| static void ehci_port_power (struct ehci_hcd *ehci, int is_on) | ||||
| static inline void ehci_port_power(struct ehci_hcd *ehci, int is_on) | ||||
| { | ||||
| 	unsigned port; | ||||
|  | ||||
|   | ||||
| @@ -264,7 +264,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | ||||
| 	u32			temp; | ||||
| 	u32			power_okay; | ||||
| 	int			i; | ||||
| 	u8			resume_needed = 0; | ||||
| 	unsigned long		resume_needed = 0; | ||||
|  | ||||
| 	if (time_before (jiffies, ehci->next_statechange)) | ||||
| 		msleep(5); | ||||
| @@ -328,7 +328,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | ||||
| 		if (test_bit(i, &ehci->bus_suspended) && | ||||
| 				(temp & PORT_SUSPEND)) { | ||||
| 			temp |= PORT_RESUME; | ||||
| 			resume_needed = 1; | ||||
| 			set_bit(i, &resume_needed); | ||||
| 		} | ||||
| 		ehci_writel(ehci, temp, &ehci->regs->port_status [i]); | ||||
| 	} | ||||
| @@ -343,8 +343,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | ||||
| 	i = HCS_N_PORTS (ehci->hcs_params); | ||||
| 	while (i--) { | ||||
| 		temp = ehci_readl(ehci, &ehci->regs->port_status [i]); | ||||
| 		if (test_bit(i, &ehci->bus_suspended) && | ||||
| 				(temp & PORT_SUSPEND)) { | ||||
| 		if (test_bit(i, &resume_needed)) { | ||||
| 			temp &= ~(PORT_RWC_BITS | PORT_RESUME); | ||||
| 			ehci_writel(ehci, temp, &ehci->regs->port_status [i]); | ||||
| 			ehci_vdbg (ehci, "resumed port %d\n", i + 1); | ||||
| @@ -779,10 +778,11 @@ static int ehci_hub_control ( | ||||
| 			 * power switching; they're allowed to just limit the | ||||
| 			 * current.  khubd will turn the power back on. | ||||
| 			 */ | ||||
| 			if (HCS_PPC (ehci->hcs_params)){ | ||||
| 			if ((temp & PORT_OC) && HCS_PPC(ehci->hcs_params)) { | ||||
| 				ehci_writel(ehci, | ||||
| 					temp & ~(PORT_RWC_BITS | PORT_POWER), | ||||
| 					status_reg); | ||||
| 				temp = ehci_readl(ehci, status_reg); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -103,7 +103,7 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) | ||||
| 	if (!(hw->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) { | ||||
| 		unsigned	is_out, epnum; | ||||
|  | ||||
| 		is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8)); | ||||
| 		is_out = qh->is_out; | ||||
| 		epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f; | ||||
| 		if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) { | ||||
| 			hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); | ||||
| @@ -936,6 +936,7 @@ done: | ||||
| 	hw = qh->hw; | ||||
| 	hw->hw_info1 = cpu_to_hc32(ehci, info1); | ||||
| 	hw->hw_info2 = cpu_to_hc32(ehci, info2); | ||||
| 	qh->is_out = !is_input; | ||||
| 	usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1); | ||||
| 	qh_refresh (ehci, qh); | ||||
| 	return qh; | ||||
| @@ -1216,6 +1217,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | ||||
|  | ||||
| 	prev->hw->hw_next = qh->hw->hw_next; | ||||
| 	prev->qh_next = qh->qh_next; | ||||
| 	if (ehci->qh_scan_next == qh) | ||||
| 		ehci->qh_scan_next = qh->qh_next.qh; | ||||
| 	wmb (); | ||||
|  | ||||
| 	/* If the controller isn't running, we don't have to wait for it */ | ||||
| @@ -1241,53 +1244,49 @@ static void scan_async (struct ehci_hcd *ehci) | ||||
| 	struct ehci_qh		*qh; | ||||
| 	enum ehci_timer_action	action = TIMER_IO_WATCHDOG; | ||||
|  | ||||
| 	ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index); | ||||
| 	timer_action_done (ehci, TIMER_ASYNC_SHRINK); | ||||
| rescan: | ||||
| 	stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state); | ||||
| 	qh = ehci->async->qh_next.qh; | ||||
| 	if (likely (qh != NULL)) { | ||||
| 		do { | ||||
| 			/* clean any finished work for this qh */ | ||||
| 			if (!list_empty(&qh->qtd_list) && (stopped || | ||||
| 					qh->stamp != ehci->stamp)) { | ||||
| 				int temp; | ||||
|  | ||||
| 				/* unlinks could happen here; completion | ||||
| 				 * reporting drops the lock.  rescan using | ||||
| 				 * the latest schedule, but don't rescan | ||||
| 				 * qhs we already finished (no looping) | ||||
| 				 * unless the controller is stopped. | ||||
| 				 */ | ||||
| 				qh = qh_get (qh); | ||||
| 				qh->stamp = ehci->stamp; | ||||
| 				temp = qh_completions (ehci, qh); | ||||
| 				if (qh->needs_rescan) | ||||
| 					unlink_async(ehci, qh); | ||||
| 				qh_put (qh); | ||||
| 				if (temp != 0) { | ||||
| 					goto rescan; | ||||
| 				} | ||||
| 			} | ||||
| 	ehci->qh_scan_next = ehci->async->qh_next.qh; | ||||
| 	while (ehci->qh_scan_next) { | ||||
| 		qh = ehci->qh_scan_next; | ||||
| 		ehci->qh_scan_next = qh->qh_next.qh; | ||||
|  rescan: | ||||
| 		/* clean any finished work for this qh */ | ||||
| 		if (!list_empty(&qh->qtd_list)) { | ||||
| 			int temp; | ||||
|  | ||||
| 			/* unlink idle entries, reducing DMA usage as well | ||||
| 			 * as HCD schedule-scanning costs.  delay for any qh | ||||
| 			 * we just scanned, there's a not-unusual case that it | ||||
| 			 * doesn't stay idle for long. | ||||
| 			 * (plus, avoids some kind of re-activation race.) | ||||
| 			/* | ||||
| 			 * Unlinks could happen here; completion reporting | ||||
| 			 * drops the lock.  That's why ehci->qh_scan_next | ||||
| 			 * always holds the next qh to scan; if the next qh | ||||
| 			 * gets unlinked then ehci->qh_scan_next is adjusted | ||||
| 			 * in start_unlink_async(). | ||||
| 			 */ | ||||
| 			if (list_empty(&qh->qtd_list) | ||||
| 					&& qh->qh_state == QH_STATE_LINKED) { | ||||
| 				if (!ehci->reclaim && (stopped || | ||||
| 					((ehci->stamp - qh->stamp) & 0x1fff) | ||||
| 						>= EHCI_SHRINK_FRAMES * 8)) | ||||
| 					start_unlink_async(ehci, qh); | ||||
| 				else | ||||
| 					action = TIMER_ASYNC_SHRINK; | ||||
| 			} | ||||
| 			qh = qh_get(qh); | ||||
| 			temp = qh_completions(ehci, qh); | ||||
| 			if (qh->needs_rescan) | ||||
| 				unlink_async(ehci, qh); | ||||
| 			qh->unlink_time = jiffies + EHCI_SHRINK_JIFFIES; | ||||
| 			qh_put(qh); | ||||
| 			if (temp != 0) | ||||
| 				goto rescan; | ||||
| 		} | ||||
|  | ||||
| 			qh = qh->qh_next.qh; | ||||
| 		} while (qh); | ||||
| 		/* unlink idle entries, reducing DMA usage as well | ||||
| 		 * as HCD schedule-scanning costs.  delay for any qh | ||||
| 		 * we just scanned, there's a not-unusual case that it | ||||
| 		 * doesn't stay idle for long. | ||||
| 		 * (plus, avoids some kind of re-activation race.) | ||||
| 		 */ | ||||
| 		if (list_empty(&qh->qtd_list) | ||||
| 				&& qh->qh_state == QH_STATE_LINKED) { | ||||
| 			if (!ehci->reclaim && (stopped || | ||||
| 					time_after_eq(jiffies, qh->unlink_time))) | ||||
| 				start_unlink_async(ehci, qh); | ||||
| 			else | ||||
| 				action = TIMER_ASYNC_SHRINK; | ||||
| 		} | ||||
| 	} | ||||
| 	if (action == TIMER_ASYNC_SHRINK) | ||||
| 		timer_action (ehci, TIMER_ASYNC_SHRINK); | ||||
|   | ||||
| @@ -62,7 +62,7 @@ stm_ehci_bus_resume(struct usb_hcd *hcd) | ||||
|  | ||||
| static const struct hc_driver ehci_stm_hc_driver = { | ||||
| 	.description = hcd_name, | ||||
| 	.product_desc = "st-ehci", | ||||
| 	.product_desc = "STMicroelectronics EHCI Host Controller", | ||||
| 	.hcd_priv_size = sizeof(struct ehci_hcd), | ||||
|  | ||||
| 	/* | ||||
| @@ -199,6 +199,7 @@ static struct platform_driver ehci_hcd_stm_driver = { | ||||
| 	.shutdown = usb_hcd_platform_shutdown, | ||||
| 	.driver = { | ||||
| 		.name = "stm-ehci", | ||||
| 		.owner = THIS_MODULE, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| @@ -216,7 +217,7 @@ int stm_ehci_hcd_unregister(struct platform_device *dev) | ||||
| 	ret = ehci_hcd_stm_remove(dev); | ||||
| 	mutex_unlock(&stm_ehci_usb_mutex); | ||||
| 	if (ret) | ||||
| 		dgb_print("[STM][USB] Error on %s 0x%x\n", __func__, dev); | ||||
| 		dgb_print("[STM][USB] Error on %s %p\n", __func__, dev); | ||||
| 	return ret; | ||||
|  | ||||
| } | ||||
| @@ -230,7 +231,7 @@ int stm_ehci_hcd_register(struct platform_device *dev) | ||||
| 	ret = ehci_hcd_stm_probe(dev); | ||||
| 	mutex_unlock(&stm_ehci_usb_mutex); | ||||
| 	if (ret) | ||||
| 		dgb_print("[STM][USB] Error on %s 0x%x\n", __func__, dev); | ||||
| 		dgb_print("[STM][USB] Error on %s %p\n", __func__, dev); | ||||
| 	return ret; | ||||
| } | ||||
| EXPORT_SYMBOL(stm_ehci_hcd_register); | ||||
|   | ||||
| @@ -74,6 +74,7 @@ struct ehci_hcd {			/* one per controller */ | ||||
| 	/* async schedule support */ | ||||
| 	struct ehci_qh		*async; | ||||
| 	struct ehci_qh		*reclaim; | ||||
| 	struct ehci_qh		*qh_scan_next; | ||||
| 	unsigned		scanning : 1; | ||||
|  | ||||
| 	/* periodic schedule support */ | ||||
| @@ -116,7 +117,6 @@ struct ehci_hcd {			/* one per controller */ | ||||
| 	struct timer_list	iaa_watchdog; | ||||
| 	struct timer_list	watchdog; | ||||
| 	unsigned long		actions; | ||||
| 	unsigned		stamp; | ||||
| 	unsigned		random_frame; | ||||
| 	unsigned long		next_statechange; | ||||
| 	ktime_t			last_periodic_enable; | ||||
| @@ -336,6 +336,7 @@ struct ehci_qh { | ||||
| 	struct ehci_qh		*reclaim;	/* next to reclaim */ | ||||
|  | ||||
| 	struct ehci_hcd		*ehci; | ||||
| 	unsigned long		unlink_time; | ||||
|  | ||||
| 	/* | ||||
| 	 * Do NOT use atomic operations for QH refcounting. On some CPUs | ||||
| @@ -367,6 +368,7 @@ struct ehci_qh { | ||||
| #define NO_FRAME ((unsigned short)~0)			/* pick new start */ | ||||
|  | ||||
| 	struct usb_device	*dev;		/* access to TT */ | ||||
| 	unsigned		is_out:1;	/* bulk or intr OUT */ | ||||
| 	unsigned		clearing_tt:1;	/* Clear-TT-Buf in progress */ | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| /* | ||||
|  * Freescale QUICC Engine USB Host Controller Driver | ||||
|  * | ||||
|  * Copyright (c) Freescale Semicondutor, Inc. 2006. | ||||
|  * Copyright (c) Freescale Semicondutor, Inc. 2006, 2011. | ||||
|  *               Shlomi Gridish <gridish@freescale.com> | ||||
|  *               Jerry Huang <Chang-Ming.Huang@freescale.com> | ||||
|  * Copyright (c) Logic Product Development, Inc. 2007 | ||||
| @@ -810,9 +810,11 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb) | ||||
| 		ed->dev_addr = usb_pipedevice(urb->pipe); | ||||
| 		ed->max_pkt_size = usb_maxpacket(urb->dev, urb->pipe, | ||||
| 			usb_pipeout(urb->pipe)); | ||||
| 		/* setup stage */ | ||||
| 		td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, FHCI_TA_SETUP, | ||||
| 			USB_TD_TOGGLE_DATA0, urb->setup_packet, 8, 0, 0, true); | ||||
|  | ||||
| 		/* data stage */ | ||||
| 		if (data_len > 0) { | ||||
| 			td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, | ||||
| 				usb_pipeout(urb->pipe) ? FHCI_TA_OUT : | ||||
| @@ -820,9 +822,18 @@ void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb) | ||||
| 				USB_TD_TOGGLE_DATA1, data, data_len, 0, 0, | ||||
| 				true); | ||||
| 		} | ||||
| 		td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, | ||||
| 			usb_pipeout(urb->pipe) ? FHCI_TA_IN : FHCI_TA_OUT, | ||||
| 			USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true); | ||||
|  | ||||
| 		/* status stage */ | ||||
| 		if (data_len > 0) | ||||
| 			td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, | ||||
| 				(usb_pipeout(urb->pipe) ? FHCI_TA_IN : | ||||
| 							  FHCI_TA_OUT), | ||||
| 				USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true); | ||||
| 		else | ||||
| 			 td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, | ||||
| 				FHCI_TA_IN, | ||||
| 				USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true); | ||||
|  | ||||
| 		urb_state = US_CTRL_SETUP; | ||||
| 		break; | ||||
| 	case FHCI_TF_ISO: | ||||
|   | ||||
| @@ -71,20 +71,21 @@ static int stm_usb_boot(struct platform_device *pdev) | ||||
| 	void *wrapper_base = usb_data->ahb2stbus_wrapper_glue_base; | ||||
| 	void *protocol_base = usb_data->ahb2stbus_protocol_base; | ||||
| 	unsigned long reg, req_reg; | ||||
| 	unsigned long flags = pl_data->flags; | ||||
|  | ||||
| 	if (pl_data->flags & | ||||
| 		(STM_PLAT_USB_FLAGS_STRAP_8BIT | | ||||
| 		 STM_PLAT_USB_FLAGS_STRAP_16BIT)) { | ||||
|  | ||||
| 	if (flags & (STM_PLAT_USB_FLAGS_STRAP_8BIT | | ||||
| 		     STM_PLAT_USB_FLAGS_STRAP_16BIT)) { | ||||
| 		/* Set strap mode */ | ||||
| 		reg = readl(wrapper_base + AHB2STBUS_STRAP_OFFSET); | ||||
| 		if (pl_data->flags & STM_PLAT_USB_FLAGS_STRAP_16BIT) | ||||
| 		if (flags & STM_PLAT_USB_FLAGS_STRAP_16BIT) | ||||
| 			reg |= AHB2STBUS_STRAP_16_BIT; | ||||
| 		else | ||||
| 			reg &= ~AHB2STBUS_STRAP_16_BIT; | ||||
| 		writel(reg, wrapper_base + AHB2STBUS_STRAP_OFFSET); | ||||
| 	} | ||||
|  | ||||
| 	if (pl_data->flags & STM_PLAT_USB_FLAGS_STRAP_PLL) { | ||||
| 	if (flags & STM_PLAT_USB_FLAGS_STRAP_PLL) { | ||||
| 		/* Start PLL */ | ||||
| 		reg = readl(wrapper_base + AHB2STBUS_STRAP_OFFSET); | ||||
| 		writel(reg | AHB2STBUS_STRAP_PLL, | ||||
| @@ -95,7 +96,7 @@ static int stm_usb_boot(struct platform_device *pdev) | ||||
| 		mdelay(30); | ||||
| 	} | ||||
|  | ||||
| 	if (pl_data->flags & STM_PLAT_USB_FLAGS_OPC_MSGSIZE_CHUNKSIZE) { | ||||
| 	if (flags & STM_PLAT_USB_FLAGS_OPC_MSGSIZE_CHUNKSIZE) { | ||||
| 		/* Set the STBus Opcode Config for load/store 32 */ | ||||
| 		writel(AHB2STBUS_STBUS_OPC_32BIT, | ||||
| 			protocol_base + AHB2STBUS_STBUS_OPC_OFFSET); | ||||
| @@ -109,7 +110,7 @@ static int stm_usb_boot(struct platform_device *pdev) | ||||
| 			protocol_base + AHB2STBUS_CHUNKSIZE_OFFSET); | ||||
| 	} | ||||
|  | ||||
| 	if (pl_data->flags & | ||||
| 	if (flags & | ||||
| 		(STM_PLAT_USB_FLAGS_STBUS_CONFIG_THRESHOLD128 | | ||||
| 		STM_PLAT_USB_FLAGS_STBUS_CONFIG_THRESHOLD256)) { | ||||
|  | ||||
| @@ -134,24 +135,14 @@ static int stm_usb_boot(struct platform_device *pdev) | ||||
|  | ||||
| static int stm_usb_remove(struct platform_device *pdev) | ||||
| { | ||||
| 	struct resource *res; | ||||
| 	struct device *dev = &pdev->dev; | ||||
| 	struct drv_usb_data *dr_data = platform_get_drvdata(pdev); | ||||
|  | ||||
| 	platform_device_unregister(dr_data->ehci_device); | ||||
| 	platform_device_unregister(dr_data->ohci_device); | ||||
|  | ||||
| 	stm_device_power(dr_data->device_state, stm_device_power_off); | ||||
|  | ||||
| 	stm_usb_clk_disable(dr_data); | ||||
|  | ||||
| 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wrapper"); | ||||
| 	devm_release_mem_region(dev, res->start, resource_size(res)); | ||||
| 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "protocol"); | ||||
| 	devm_release_mem_region(dev, res->start, resource_size(res)); | ||||
|  | ||||
| 	if (dr_data->ehci_device) | ||||
| 		platform_device_unregister(dr_data->ehci_device); | ||||
| 	if (dr_data->ohci_device) | ||||
| 		platform_device_unregister(dr_data->ohci_device); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -191,7 +182,7 @@ static int __init stm_usb_probe(struct platform_device *pdev) | ||||
| 	struct drv_usb_data *dr_data; | ||||
| 	struct device *dev = &pdev->dev; | ||||
| 	struct resource *res; | ||||
| 	int ret = 0, i; | ||||
| 	int i; | ||||
| 	static char __initdata *usb_clks_n[USB_CLKS_NR] = { | ||||
| 		[USB_48_CLK] = "usb_48_clk", | ||||
| 		[USB_IC_CLK] = "usb_ic_clk", | ||||
| @@ -200,7 +191,7 @@ static int __init stm_usb_probe(struct platform_device *pdev) | ||||
| 	resource_size_t len; | ||||
|  | ||||
| 	dgb_print("\n"); | ||||
| 	dr_data = kzalloc(sizeof(struct drv_usb_data), GFP_KERNEL); | ||||
| 	dr_data = devm_kzalloc(dev, sizeof(*dr_data), GFP_KERNEL); | ||||
| 	if (!dr_data) | ||||
| 		return -ENOMEM; | ||||
|  | ||||
| @@ -215,57 +206,47 @@ static int __init stm_usb_probe(struct platform_device *pdev) | ||||
|  | ||||
| 	stm_usb_clk_enable(dr_data); | ||||
|  | ||||
| 	dr_data->device_state = devm_stm_device_init(&pdev->dev, | ||||
| 		plat_data->device_config); | ||||
| 	if (!dr_data->device_state) { | ||||
| 		ret = -EBUSY; | ||||
| 		goto err_0; | ||||
| 	} | ||||
| 	dr_data->device_state = | ||||
| 		devm_stm_device_init(&pdev->dev, plat_data->device_config); | ||||
| 	if (!dr_data->device_state) | ||||
| 		return -EBUSY; | ||||
|  | ||||
| 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wrapper"); | ||||
| 	if (!res) { | ||||
| 		ret = -ENXIO; | ||||
| 		goto err_0; | ||||
| 	} | ||||
| 	if (!res) | ||||
| 		return -ENXIO; | ||||
|  | ||||
| 	len = resource_size(res); | ||||
| 	if (devm_request_mem_region(dev, res->start, len, pdev->name) < 0) { | ||||
| 		ret = -EBUSY; | ||||
| 		goto err_0; | ||||
| 	} | ||||
| 	if (devm_request_mem_region(dev, res->start, len, pdev->name) < 0) | ||||
| 		return -EBUSY; | ||||
|  | ||||
| 	dr_data->ahb2stbus_wrapper_glue_base = | ||||
| 		devm_ioremap_nocache(dev, res->start, len); | ||||
|  | ||||
| 	if (!dr_data->ahb2stbus_wrapper_glue_base) { | ||||
| 		ret = -EFAULT; | ||||
| 		goto err_1; | ||||
| 	} | ||||
| 	if (!dr_data->ahb2stbus_wrapper_glue_base) | ||||
| 		return -EFAULT; | ||||
|  | ||||
| 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "protocol"); | ||||
| 	if (!res) { | ||||
| 		ret = -ENXIO; | ||||
| 		goto err_2; | ||||
| 	} | ||||
| 	if (!res) | ||||
| 		return -ENXIO; | ||||
|  | ||||
| 	len = resource_size(res); | ||||
| 	if (devm_request_mem_region(dev, res->start, len, pdev->name) < 0) { | ||||
| 		ret = -EBUSY; | ||||
| 		goto err_2; | ||||
| 	} | ||||
| 	if (devm_request_mem_region(dev, res->start, len, pdev->name) < 0) | ||||
| 		return -EBUSY; | ||||
|  | ||||
| 	dr_data->ahb2stbus_protocol_base = | ||||
| 		devm_ioremap_nocache(dev, res->start, len); | ||||
|  | ||||
| 	if (!dr_data->ahb2stbus_protocol_base) { | ||||
| 		ret = -EFAULT; | ||||
| 		goto err_3; | ||||
| 	} | ||||
| 	if (!dr_data->ahb2stbus_protocol_base) | ||||
| 		return -EFAULT; | ||||
|  | ||||
| 	stm_usb_boot(pdev); | ||||
|  | ||||
| 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ehci"); | ||||
| 	if (res) { | ||||
| 		dr_data->ehci_device = stm_usb_device_create("stm-ehci", | ||||
| 			pdev->id, pdev); | ||||
| 		if (IS_ERR(dr_data->ehci_device)) { | ||||
| 			ret = (int)dr_data->ehci_device; | ||||
| 			goto err_4; | ||||
| 		} | ||||
| 		if (IS_ERR(dr_data->ehci_device)) | ||||
| 			return PTR_ERR(dr_data->ehci_device); | ||||
| 	} | ||||
|  | ||||
| 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ohci"); | ||||
| @@ -273,10 +254,8 @@ static int __init stm_usb_probe(struct platform_device *pdev) | ||||
| 		dr_data->ohci_device = | ||||
| 			stm_usb_device_create("stm-ohci", pdev->id, pdev); | ||||
| 		if (IS_ERR(dr_data->ohci_device)) { | ||||
| 			if (dr_data->ehci_device) | ||||
| 				platform_device_del(dr_data->ehci_device); | ||||
| 			ret = (int)dr_data->ohci_device; | ||||
| 			goto err_4; | ||||
| 			platform_device_del(dr_data->ehci_device); | ||||
| 			return PTR_ERR(dr_data->ohci_device); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -285,21 +264,7 @@ static int __init stm_usb_probe(struct platform_device *pdev) | ||||
| 	pm_suspend_ignore_children(&pdev->dev, 1); | ||||
| 	pm_runtime_enable(&pdev->dev); | ||||
|  | ||||
| 	return ret; | ||||
|  | ||||
| err_4: | ||||
| 	devm_iounmap(dev, dr_data->ahb2stbus_protocol_base); | ||||
| err_3: | ||||
| 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "protocol"); | ||||
| 	devm_release_mem_region(dev, res->start, resource_size(res)); | ||||
| err_2: | ||||
| 	devm_iounmap(dev, dr_data->ahb2stbus_wrapper_glue_base); | ||||
| err_1: | ||||
| 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wrapper"); | ||||
| 	devm_release_mem_region(dev, res->start, resource_size(res)); | ||||
| err_0: | ||||
| 	kfree(dr_data); | ||||
| 	return ret; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void stm_usb_shutdown(struct platform_device *pdev) | ||||
|   | ||||
| @@ -56,7 +56,7 @@ static int stm_ohci_bus_suspend(struct usb_hcd *hcd) | ||||
|  | ||||
| static const struct hc_driver ohci_st40_hc_driver = { | ||||
| 	.description =		hcd_name, | ||||
| 	.product_desc =		"stm-ohci", | ||||
| 	.product_desc =		"STMicroelectronics OHCI Host Controller", | ||||
| 	.hcd_priv_size =	sizeof(struct ohci_hcd), | ||||
|  | ||||
| 	/* generic hardware linkage */ | ||||
| @@ -165,6 +165,7 @@ static struct platform_driver ohci_hcd_stm_driver = { | ||||
| 	.shutdown = usb_hcd_platform_shutdown, | ||||
| 	.driver = { | ||||
| 		.name = "stm-ohci", | ||||
| 		.owner = THIS_MODULE, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| @@ -183,7 +184,7 @@ int stm_ohci_hcd_unregister(struct platform_device *dev) | ||||
| 	ret = ohci_hcd_stm_remove(dev); | ||||
| 	mutex_unlock(&stm_ohci_usb_mutex); | ||||
| 	if (ret) | ||||
| 		dgb_print("[STM][USB] Error on %s 0x%x\n", __func__, dev); | ||||
| 		dgb_print("[STM][USB] Error on %s %p\n", __func__, dev); | ||||
| 	return ret; | ||||
| } | ||||
| EXPORT_SYMBOL(stm_ohci_hcd_unregister); | ||||
| @@ -196,7 +197,7 @@ int stm_ohci_hcd_register(struct platform_device *dev) | ||||
| 	ret = ohci_hcd_stm_probe(dev); | ||||
| 	mutex_unlock(&stm_ohci_usb_mutex); | ||||
| 	if (ret) | ||||
| 		dgb_print("[STM][USB] Error on %s 0x%x\n", __func__, dev); | ||||
| 		dgb_print("[STM][USB] Error on %s %p\n", __func__, dev); | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|   | ||||
| @@ -34,6 +34,8 @@ | ||||
| #define OHCI_INTRSTATUS		0x0c | ||||
| #define OHCI_INTRENABLE		0x10 | ||||
| #define OHCI_INTRDISABLE	0x14 | ||||
| #define OHCI_FMINTERVAL		0x34 | ||||
| #define OHCI_HCR		(1 << 0)	/* host controller reset */ | ||||
| #define OHCI_OCR		(1 << 3)	/* ownership change request */ | ||||
| #define OHCI_CTRL_RWC		(1 << 9)	/* remote wakeup connected */ | ||||
| #define OHCI_CTRL_IR		(1 << 8)	/* interrupt routing */ | ||||
| @@ -204,6 +206,32 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) | ||||
|  | ||||
| 	/* reset controller, preserving RWC (and possibly IR) */ | ||||
| 	writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); | ||||
| 	readl(base + OHCI_CONTROL); | ||||
|  | ||||
| 	/* Some NVIDIA controllers stop working if kept in RESET for too long */ | ||||
| 	if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) { | ||||
| 		u32 fminterval; | ||||
| 		int cnt; | ||||
|  | ||||
| 		/* drive reset for at least 50 ms (7.1.7.5) */ | ||||
| 		msleep(50); | ||||
|  | ||||
| 		/* software reset of the controller, preserving HcFmInterval */ | ||||
| 		fminterval = readl(base + OHCI_FMINTERVAL); | ||||
| 		writel(OHCI_HCR, base + OHCI_CMDSTATUS); | ||||
|  | ||||
| 		/* reset requires max 10 us delay */ | ||||
| 		for (cnt = 30; cnt > 0; --cnt) {	/* ... allow extra time */ | ||||
| 			if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0) | ||||
| 				break; | ||||
| 			udelay(1); | ||||
| 		} | ||||
| 		writel(fminterval, base + OHCI_FMINTERVAL); | ||||
|  | ||||
| 		/* Now we're in the SUSPEND state with all devices reset | ||||
| 		 * and wakeups and interrupts disabled | ||||
| 		 */ | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * disable interrupts | ||||
| @@ -390,12 +418,12 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | ||||
| 	void __iomem *op_reg_base; | ||||
| 	u32 val; | ||||
| 	int timeout; | ||||
| 	int len = pci_resource_len(pdev, 0); | ||||
|  | ||||
| 	if (!mmio_resource_enabled(pdev, 0)) | ||||
| 		return; | ||||
|  | ||||
| 	base = ioremap_nocache(pci_resource_start(pdev, 0), | ||||
| 				pci_resource_len(pdev, 0)); | ||||
| 	base = ioremap_nocache(pci_resource_start(pdev, 0), len); | ||||
| 	if (base == NULL) | ||||
| 		return; | ||||
|  | ||||
| @@ -405,9 +433,17 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | ||||
| 	 */ | ||||
| 	ext_cap_offset = xhci_find_next_cap_offset(base, XHCI_HCC_PARAMS_OFFSET); | ||||
| 	do { | ||||
| 		if ((ext_cap_offset + sizeof(val)) > len) { | ||||
| 			/* We're reading garbage from the controller */ | ||||
| 			dev_warn(&pdev->dev, | ||||
| 				 "xHCI controller failing to respond"); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		if (!ext_cap_offset) | ||||
| 			/* We've reached the end of the extended capabilities */ | ||||
| 			goto hc_init; | ||||
|  | ||||
| 		val = readl(base + ext_cap_offset); | ||||
| 		if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY) | ||||
| 			break; | ||||
| @@ -416,7 +452,7 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | ||||
|  | ||||
| 	/* If the BIOS owns the HC, signal that the OS wants it, and wait */ | ||||
| 	if (val & XHCI_HC_BIOS_OWNED) { | ||||
| 		writel(val & XHCI_HC_OS_OWNED, base + ext_cap_offset); | ||||
| 		writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset); | ||||
|  | ||||
| 		/* Wait for 5 seconds with 10 microsecond polling interval */ | ||||
| 		timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED, | ||||
| @@ -430,9 +466,13 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* Disable any BIOS SMIs */ | ||||
| 	writel(XHCI_LEGACY_DISABLE_SMI, | ||||
| 			base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); | ||||
| 	val = readl(base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); | ||||
| 	/* Mask off (turn off) any enabled SMIs */ | ||||
| 	val &= XHCI_LEGACY_DISABLE_SMI; | ||||
| 	/* Mask all SMI events bits, RW1C */ | ||||
| 	val |= XHCI_LEGACY_SMI_EVENTS; | ||||
| 	/* Disable any BIOS SMIs and clear all SMI events*/ | ||||
| 	writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); | ||||
|  | ||||
| hc_init: | ||||
| 	op_reg_base = base + XHCI_HC_LENGTH(readl(base)); | ||||
| @@ -470,6 +510,22 @@ hc_init: | ||||
|  | ||||
| static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) | ||||
| { | ||||
| 	/* Skip Netlogic mips SoC's internal PCI USB controller. | ||||
| 	 * This device does not need/support EHCI/OHCI handoff | ||||
| 	 */ | ||||
| 	if (pdev->vendor == 0x184e)	/* vendor Netlogic */ | ||||
| 		return; | ||||
| 	if (pdev->class != PCI_CLASS_SERIAL_USB_UHCI && | ||||
| 			pdev->class != PCI_CLASS_SERIAL_USB_OHCI && | ||||
| 			pdev->class != PCI_CLASS_SERIAL_USB_EHCI && | ||||
| 			pdev->class != PCI_CLASS_SERIAL_USB_XHCI) | ||||
| 		return; | ||||
|  | ||||
| 	if (pci_enable_device(pdev) < 0) { | ||||
| 		dev_warn(&pdev->dev, "Can't enable PCI device, " | ||||
| 				"BIOS handoff failed.\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 	if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI) | ||||
| 		quirk_usb_handoff_uhci(pdev); | ||||
| 	else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI) | ||||
| @@ -478,5 +534,6 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) | ||||
| 		quirk_usb_disable_ehci(pdev); | ||||
| 	else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI) | ||||
| 		quirk_usb_handoff_xhci(pdev); | ||||
| 	pci_disable_device(pdev); | ||||
| } | ||||
| DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); | ||||
|   | ||||
| @@ -104,7 +104,7 @@ void qset_clear(struct whc *whc, struct whc_qset *qset) | ||||
| { | ||||
| 	qset->td_start = qset->td_end = qset->ntds = 0; | ||||
|  | ||||
| 	qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T); | ||||
| 	qset->qh.link = cpu_to_le64(QH_LINK_NTDS(8) | QH_LINK_T); | ||||
| 	qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK; | ||||
| 	qset->qh.err_count = 0; | ||||
| 	qset->qh.scratch[0] = 0; | ||||
|   | ||||
| @@ -62,8 +62,9 @@ | ||||
| /* USB Legacy Support Control and Status Register  - section 7.1.2 */ | ||||
| /* Add this offset, plus the value of xECP in HCCPARAMS to the base address */ | ||||
| #define XHCI_LEGACY_CONTROL_OFFSET	(0x04) | ||||
| /* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ | ||||
| #define	XHCI_LEGACY_DISABLE_SMI		((0x3 << 1) + (0xff << 5) + (0x7 << 17)) | ||||
| /* bits 1:3, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */ | ||||
| #define	XHCI_LEGACY_DISABLE_SMI		((0x7 << 1) + (0xff << 5) + (0x7 << 17)) | ||||
| #define XHCI_LEGACY_SMI_EVENTS		(0x7 << 29) | ||||
|  | ||||
| /* command register values to disable interrupts and halt the HC */ | ||||
| /* start/stop HC execution - do not write unless HC is halted*/ | ||||
|   | ||||
| @@ -150,7 +150,7 @@ int xhci_reset(struct xhci_hcd *xhci) | ||||
| 	xhci_to_hcd(xhci)->state = HC_STATE_HALT; | ||||
|  | ||||
| 	ret = handshake(xhci, &xhci->op_regs->command, | ||||
| 			CMD_RESET, 0, 250 * 1000); | ||||
| 			CMD_RESET, 0, 10 * 1000 * 1000); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
|  | ||||
| @@ -979,6 +979,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | ||||
| 	u32 added_ctxs; | ||||
| 	unsigned int last_ctx; | ||||
| 	u32 new_add_flags, new_drop_flags, new_slot_info; | ||||
| 	struct xhci_virt_device *virt_dev; | ||||
| 	int ret = 0; | ||||
|  | ||||
| 	ret = xhci_check_args(hcd, udev, ep, 1, __func__); | ||||
| @@ -1007,11 +1008,25 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | ||||
| 	in_ctx = xhci->devs[udev->slot_id]->in_ctx; | ||||
| 	out_ctx = xhci->devs[udev->slot_id]->out_ctx; | ||||
| 	virt_dev = xhci->devs[udev->slot_id]; | ||||
| 	in_ctx = virt_dev->in_ctx; | ||||
| 	out_ctx = virt_dev->out_ctx; | ||||
| 	ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | ||||
| 	ep_index = xhci_get_endpoint_index(&ep->desc); | ||||
| 	ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); | ||||
|  | ||||
| 	/* If this endpoint is already in use, and the upper layers are trying | ||||
| 	 * to add it again without dropping it, reject the addition. | ||||
| 	 */ | ||||
| 	if (virt_dev->eps[ep_index].ring && | ||||
| 			!(le32_to_cpu(ctrl_ctx->drop_flags) & | ||||
| 				xhci_get_endpoint_flag(&ep->desc))) { | ||||
| 		xhci_warn(xhci, "Trying to add endpoint 0x%x " | ||||
| 				"without dropping it.\n", | ||||
| 				(unsigned int) ep->desc.bEndpointAddress); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | ||||
| 	/* If the HCD has already noted the endpoint is enabled, | ||||
| 	 * ignore this request. | ||||
| 	 */ | ||||
| @@ -1026,8 +1041,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | ||||
| 	 * process context, not interrupt context (or so documenation | ||||
| 	 * for usb_set_interface() and usb_set_configuration() claim). | ||||
| 	 */ | ||||
| 	if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], | ||||
| 				udev, ep, GFP_KERNEL) < 0) { | ||||
| 	if (xhci_endpoint_init(xhci, virt_dev, udev, ep, GFP_NOIO) < 0) { | ||||
| 		dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", | ||||
| 				__func__, ep->desc.bEndpointAddress); | ||||
| 		return -ENOMEM; | ||||
|   | ||||
| @@ -110,18 +110,20 @@ void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring) | ||||
| 	struct xhci_segment *seg; | ||||
| 	struct xhci_segment *first_seg; | ||||
|  | ||||
| 	if (!ring || !ring->first_seg) | ||||
| 	if (!ring) | ||||
| 		return; | ||||
| 	first_seg = ring->first_seg; | ||||
| 	seg = first_seg->next; | ||||
| 	xhci_dbg(xhci, "Freeing ring at %p\n", ring); | ||||
| 	while (seg != first_seg) { | ||||
| 		struct xhci_segment *next = seg->next; | ||||
| 		xhci_segment_free(xhci, seg); | ||||
| 		seg = next; | ||||
| 	if (ring->first_seg) { | ||||
| 		first_seg = ring->first_seg; | ||||
| 		seg = first_seg->next; | ||||
| 		xhci_dbg(xhci, "Freeing ring at %p\n", ring); | ||||
| 		while (seg != first_seg) { | ||||
| 			struct xhci_segment *next = seg->next; | ||||
| 			xhci_segment_free(xhci, seg); | ||||
| 			seg = next; | ||||
| 		} | ||||
| 		xhci_segment_free(xhci, first_seg); | ||||
| 		ring->first_seg = NULL; | ||||
| 	} | ||||
| 	xhci_segment_free(xhci, first_seg); | ||||
| 	ring->first_seg = NULL; | ||||
| 	kfree(ring); | ||||
| } | ||||
|  | ||||
| @@ -470,26 +472,42 @@ static unsigned int xhci_parse_exponent_interval(struct usb_device *udev, | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Convert bInterval expressed in frames (in 1-255 range) to exponent of | ||||
|  * Convert bInterval expressed in microframes (in 1-255 range) to exponent of | ||||
|  * microframes, rounded down to nearest power of 2. | ||||
|  */ | ||||
| static unsigned int xhci_parse_frame_interval(struct usb_device *udev, | ||||
| 		struct usb_host_endpoint *ep) | ||||
| static unsigned int xhci_microframes_to_exponent(struct usb_device *udev, | ||||
| 		struct usb_host_endpoint *ep, unsigned int desc_interval, | ||||
| 		unsigned int min_exponent, unsigned int max_exponent) | ||||
| { | ||||
| 	unsigned int interval; | ||||
|  | ||||
| 	interval = fls(8 * ep->desc.bInterval) - 1; | ||||
| 	interval = clamp_val(interval, 3, 10); | ||||
| 	if ((1 << interval) != 8 * ep->desc.bInterval) | ||||
| 	interval = fls(desc_interval) - 1; | ||||
| 	interval = clamp_val(interval, min_exponent, max_exponent); | ||||
| 	if ((1 << interval) != desc_interval) | ||||
| 		dev_warn(&udev->dev, | ||||
| 			 "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n", | ||||
| 			 ep->desc.bEndpointAddress, | ||||
| 			 1 << interval, | ||||
| 			 8 * ep->desc.bInterval); | ||||
| 			 desc_interval); | ||||
|  | ||||
| 	return interval; | ||||
| } | ||||
|  | ||||
| static unsigned int xhci_parse_microframe_interval(struct usb_device *udev, | ||||
| 		struct usb_host_endpoint *ep) | ||||
| { | ||||
| 	return xhci_microframes_to_exponent(udev, ep, | ||||
| 			ep->desc.bInterval, 0, 15); | ||||
| } | ||||
|  | ||||
|  | ||||
| static unsigned int xhci_parse_frame_interval(struct usb_device *udev, | ||||
| 		struct usb_host_endpoint *ep) | ||||
| { | ||||
| 	return xhci_microframes_to_exponent(udev, ep, | ||||
| 			ep->desc.bInterval * 8, 3, 10); | ||||
| } | ||||
|  | ||||
| /* Return the polling or NAK interval. | ||||
|  * | ||||
|  * The polling interval is expressed in "microframes".  If xHCI's Interval field | ||||
| @@ -508,7 +526,7 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev, | ||||
| 		/* Max NAK rate */ | ||||
| 		if (usb_endpoint_xfer_control(&ep->desc) || | ||||
| 		    usb_endpoint_xfer_bulk(&ep->desc)) { | ||||
| 			interval = ep->desc.bInterval; | ||||
| 			interval = xhci_parse_microframe_interval(udev, ep); | ||||
| 			break; | ||||
| 		} | ||||
| 		/* Fall through - SS and HS isoc/int have same decoding */ | ||||
| @@ -916,11 +934,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | ||||
| 	int i; | ||||
|  | ||||
| 	/* Free the Event Ring Segment Table and the actual Event Ring */ | ||||
| 	if (xhci->ir_set) { | ||||
| 		xhci_writel(xhci, 0, &xhci->ir_set->erst_size); | ||||
| 		xhci_write_64(xhci, 0, &xhci->ir_set->erst_base); | ||||
| 		xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue); | ||||
| 	} | ||||
| 	size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); | ||||
| 	if (xhci->erst.entries) | ||||
| 		pci_free_consistent(pdev, size, | ||||
| @@ -932,7 +945,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | ||||
| 	xhci->event_ring = NULL; | ||||
| 	xhci_dbg(xhci, "Freed event ring\n"); | ||||
|  | ||||
| 	xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring); | ||||
| 	xhci->cmd_ring_reserved_trbs = 0; | ||||
| 	if (xhci->cmd_ring) | ||||
| 		xhci_ring_free(xhci, xhci->cmd_ring); | ||||
| 	xhci->cmd_ring = NULL; | ||||
| @@ -951,7 +964,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) | ||||
| 	xhci->device_pool = NULL; | ||||
| 	xhci_dbg(xhci, "Freed device context pool\n"); | ||||
|  | ||||
| 	xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr); | ||||
| 	if (xhci->dcbaa) | ||||
| 		pci_free_consistent(pdev, sizeof(*xhci->dcbaa), | ||||
| 				xhci->dcbaa, xhci->dcbaa->dma); | ||||
| @@ -1128,6 +1140,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | ||||
|  | ||||
| fail: | ||||
| 	xhci_warn(xhci, "Couldn't initialize memory\n"); | ||||
| 	xhci_halt(xhci); | ||||
| 	xhci_reset(xhci); | ||||
| 	xhci_mem_cleanup(xhci); | ||||
| 	return -ENOMEM; | ||||
| } | ||||
|   | ||||
| @@ -54,8 +54,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"); | ||||
| @@ -99,8 +100,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; | ||||
|   | ||||
| @@ -24,7 +24,7 @@ | ||||
|  | ||||
| #define VENDOR_ID	0x0fc5 | ||||
| #define PRODUCT_ID	0x1227 | ||||
| #define MAXLEN		6 | ||||
| #define MAXLEN		8 | ||||
|  | ||||
| /* table of devices that work with this driver */ | ||||
| static struct usb_device_id id_table[] = { | ||||
|   | ||||
| @@ -1041,7 +1041,7 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, | ||||
| 		nevents = mon_bin_queued(rp); | ||||
|  | ||||
| 		sp = (struct mon_bin_stats __user *)arg; | ||||
| 		if (put_user(rp->cnt_lost, &sp->dropped)) | ||||
| 		if (put_user(ndropped, &sp->dropped)) | ||||
| 			return -EFAULT; | ||||
| 		if (put_user(nevents, &sp->queued)) | ||||
| 			return -EFAULT; | ||||
|   | ||||
| @@ -94,6 +94,7 @@ static struct usb_device_id id_table [] = { | ||||
| 	{ USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ | ||||
| 	{ USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ | ||||
| 	{ USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ | ||||
| 	{ USB_DEVICE(0x10C4, 0x81A9) }, /* Multiplex RC Interface */ | ||||
| 	{ USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ | ||||
| 	{ USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */ | ||||
| 	{ USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ | ||||
| @@ -135,10 +136,13 @@ static struct usb_device_id id_table [] = { | ||||
| 	{ USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */ | ||||
| 	{ USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */ | ||||
| 	{ USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */ | ||||
| 	{ USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */ | ||||
| 	{ USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */ | ||||
| 	{ USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ | ||||
| 	{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ | ||||
| 	{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ | ||||
| 	{ USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ | ||||
| 	{ USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ | ||||
| 	{ USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ | ||||
| 	{ } /* Terminating Entry */ | ||||
| }; | ||||
| @@ -359,8 +363,8 @@ static inline int cp210x_set_config_single(struct usb_serial_port *port, | ||||
|  * Quantises the baud rate as per AN205 Table 1 | ||||
|  */ | ||||
| static unsigned int cp210x_quantise_baudrate(unsigned int baud) { | ||||
| 	if      (baud <= 56)       baud = 0; | ||||
| 	else if (baud <= 300)      baud = 300; | ||||
| 	if (baud <= 300) | ||||
| 		baud = 300; | ||||
| 	else if (baud <= 600)      baud = 600; | ||||
| 	else if (baud <= 1200)     baud = 1200; | ||||
| 	else if (baud <= 1800)     baud = 1800; | ||||
|   | ||||
| @@ -105,6 +105,7 @@ static int   ftdi_jtag_probe(struct usb_serial *serial); | ||||
| static int   ftdi_mtxorb_hack_setup(struct usb_serial *serial); | ||||
| static int   ftdi_NDI_device_setup(struct usb_serial *serial); | ||||
| static int   ftdi_stmclite_probe(struct usb_serial *serial); | ||||
| static int   ftdi_8u2232c_probe(struct usb_serial *serial); | ||||
| static void  ftdi_USB_UIRT_setup(struct ftdi_private *priv); | ||||
| static void  ftdi_HE_TIRA1_setup(struct ftdi_private *priv); | ||||
|  | ||||
| @@ -132,6 +133,10 @@ static struct ftdi_sio_quirk ftdi_stmclite_quirk = { | ||||
| 	.probe	= ftdi_stmclite_probe, | ||||
| }; | ||||
|  | ||||
| static struct ftdi_sio_quirk ftdi_8u2232c_quirk = { | ||||
| 	.probe	= ftdi_8u2232c_probe, | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * The 8U232AM has the same API as the sio except for: | ||||
|  * - it can support MUCH higher baudrates; up to: | ||||
| @@ -155,6 +160,7 @@ static struct ftdi_sio_quirk ftdi_stmclite_quirk = { | ||||
|  * /sys/bus/usb/ftdi_sio/new_id, then send patch/report! | ||||
|  */ | ||||
| static struct usb_device_id id_table_combined [] = { | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_CTI_MINI_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_CTI_NANO_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, | ||||
| @@ -181,7 +187,8 @@ static struct usb_device_id id_table_combined [] = { | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) , | ||||
| 		.driver_info = (kernel_ulong_t)&ftdi_8u2232c_quirk }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_4232H_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, | ||||
| @@ -203,6 +210,8 @@ static struct usb_device_id id_table_combined [] = { | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_XF_640_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_XF_642_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_URBAN_0_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_URBAN_1_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_MTXORB_0_PID) }, | ||||
| @@ -730,6 +739,7 @@ static struct usb_device_id id_table_combined [] = { | ||||
| 	{ USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) }, | ||||
| 	{ USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), | ||||
| 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||||
| 	{ USB_DEVICE(FIC_VID, FIC_NEO1973_DEBUG_PID), | ||||
| @@ -740,6 +750,8 @@ static struct usb_device_id id_table_combined [] = { | ||||
| 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||||
| 	{ USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID), | ||||
| 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||||
| 	{ USB_DEVICE(FTDI_VID, LMI_LM3S_ICDI_BOARD_PID), | ||||
| 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID), | ||||
| 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||||
| 	{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, | ||||
| @@ -786,6 +798,7 @@ static struct usb_device_id id_table_combined [] = { | ||||
| 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||||
| 	{ USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), | ||||
| 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||||
| 	{ USB_DEVICE(HORNBY_VID, HORNBY_ELITE_PID) }, | ||||
| 	{ USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, | ||||
| 	{ USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), | ||||
| 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||||
| @@ -794,6 +807,8 @@ static struct usb_device_id id_table_combined [] = { | ||||
| 	{ USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), | ||||
| 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||||
| 	{ USB_DEVICE(FTDI_VID, TI_XDS100V2_PID), | ||||
| 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||||
| 	{ USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) }, | ||||
| @@ -825,11 +840,13 @@ static struct usb_device_id id_table_combined [] = { | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_CINTERION_MC55I_PID) }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, | ||||
| 	{ USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), | ||||
| 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||||
| 	{ USB_DEVICE(ST_VID, ST_STMCLT1030_PID), | ||||
| 		.driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk }, | ||||
| 	{ USB_DEVICE(FTDI_VID, FTDI_RF_R106) }, | ||||
| 	{ },					/* Optional parameter entry */ | ||||
| 	{ }					/* Terminating entry */ | ||||
| }; | ||||
| @@ -1339,8 +1356,7 @@ static int set_serial_info(struct tty_struct *tty, | ||||
| 		goto check_and_exit; | ||||
| 	} | ||||
|  | ||||
| 	if ((new_serial.baud_base != priv->baud_base) && | ||||
| 	    (new_serial.baud_base < 9600)) { | ||||
| 	if (new_serial.baud_base != priv->baud_base) { | ||||
| 	    	unlock_kernel(); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| @@ -1762,6 +1778,19 @@ static int ftdi_jtag_probe(struct usb_serial *serial) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int ftdi_8u2232c_probe(struct usb_serial *serial) | ||||
| { | ||||
| 	struct usb_device *udev = serial->dev; | ||||
|  | ||||
| 	dbg("%s", __func__); | ||||
|  | ||||
| 	if ((udev->manufacturer) && | ||||
| 	    (strcmp(udev->manufacturer, "CALAO Systems") == 0)) | ||||
| 		return ftdi_jtag_probe(serial); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * First and second port on STMCLiteadaptors is reserved for JTAG interface | ||||
|  * and the forth port for pio | ||||
| @@ -1841,6 +1870,7 @@ static int ftdi_submit_read_urb(struct usb_serial_port *port, gfp_t mem_flags) | ||||
|  | ||||
| static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | ||||
| { /* ftdi_open */ | ||||
| 	struct ktermios dummy; | ||||
| 	struct usb_device *dev = port->serial->dev; | ||||
| 	struct ftdi_private *priv = usb_get_serial_port_data(port); | ||||
| 	unsigned long flags; | ||||
| @@ -1868,8 +1898,10 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) | ||||
| 	   This is same behaviour as serial.c/rs_open() - Kuba */ | ||||
|  | ||||
| 	/* ftdi_set_termios  will send usb control messages */ | ||||
| 	if (tty) | ||||
| 		ftdi_set_termios(tty, port, tty->termios); | ||||
| 	if (tty) { | ||||
| 		memset(&dummy, 0, sizeof(dummy)); | ||||
| 		ftdi_set_termios(tty, port, &dummy); | ||||
| 	} | ||||
|  | ||||
| 	/* Not throttled */ | ||||
| 	spin_lock_irqsave(&port->lock, flags); | ||||
| @@ -2332,13 +2364,23 @@ static void ftdi_set_termios(struct tty_struct *tty, | ||||
|  | ||||
| 	cflag = termios->c_cflag; | ||||
|  | ||||
| 	/* FIXME -For this cut I don't care if the line is really changing or | ||||
| 	   not  - so just do the change regardless  - should be able to | ||||
| 	   compare old_termios and tty->termios */ | ||||
| 	if (!old_termios) | ||||
| 		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) | ||||
| 		goto no_c_cflag_changes; | ||||
|  | ||||
| 	/* NOTE These routines can get interrupted by | ||||
| 	   ftdi_sio_read_bulk_callback  - need to examine what this means - | ||||
| 	   don't see any problems yet */ | ||||
|  | ||||
| 	if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) == | ||||
| 	    (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB))) | ||||
| 		goto no_data_parity_stop_changes; | ||||
|  | ||||
| no_skip: | ||||
| 	/* Set number of data bits, parity, stop bits */ | ||||
|  | ||||
| 	termios->c_cflag &= ~CMSPAR; | ||||
| @@ -2375,6 +2417,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | ||||
| 	} | ||||
|  | ||||
| 	/* Now do the baudrate */ | ||||
| no_data_parity_stop_changes: | ||||
| 	if ((cflag & CBAUD) == B0) { | ||||
| 		/* Disable flow control */ | ||||
| 		if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||||
| @@ -2400,6 +2443,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | ||||
|  | ||||
| 	/* Set flow control */ | ||||
| 	/* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ | ||||
| no_c_cflag_changes: | ||||
| 	if (cflag & CRTSCTS) { | ||||
| 		dbg("%s Setting to CRTSCTS flow control", __func__); | ||||
| 		if (usb_control_msg(dev, | ||||
|   | ||||
| @@ -38,6 +38,13 @@ | ||||
| /* www.candapter.com Ewert Energy Systems CANdapter device */ | ||||
| #define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ | ||||
|  | ||||
| /* | ||||
|  * Texas Instruments XDS100v2 JTAG / BeagleBone A3 | ||||
|  * http://processors.wiki.ti.com/index.php/XDS100 | ||||
|  * http://beagleboard.org/bone | ||||
|  */ | ||||
| #define TI_XDS100V2_PID		0xa6d0 | ||||
|  | ||||
| #define FTDI_NXTCAM_PID		0xABB8 /* NXTCam for Mindstorms NXT */ | ||||
|  | ||||
| /* US Interface Navigator (http://www.usinterface.com/) */ | ||||
| @@ -53,6 +60,7 @@ | ||||
| /* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */ | ||||
| #define LMI_LM3S_DEVEL_BOARD_PID	0xbcd8 | ||||
| #define LMI_LM3S_EVAL_BOARD_PID		0xbcd9 | ||||
| #define LMI_LM3S_ICDI_BOARD_PID		0xbcda | ||||
|  | ||||
| #define FTDI_TURTELIZER_PID	0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */ | ||||
|  | ||||
| @@ -110,6 +118,7 @@ | ||||
|  | ||||
| /* Propox devices */ | ||||
| #define FTDI_PROPOX_JTAGCABLEII_PID	0xD738 | ||||
| #define FTDI_PROPOX_ISPCABLEIII_PID	0xD739 | ||||
|  | ||||
| /* Lenz LI-USB Computer Interface. */ | ||||
| #define FTDI_LENZ_LIUSB_PID	0xD780 | ||||
| @@ -419,9 +428,11 @@ | ||||
| #define PROTEGO_SPECIAL_4	0xFC73	/* special/unknown device */ | ||||
|  | ||||
| /* | ||||
|  * DSS-20 Sync Station for Sony Ericsson P800 | ||||
|  * Sony Ericsson product ids | ||||
|  */ | ||||
| #define FTDI_DSS20_PID          0xFC82 | ||||
| #define FTDI_DSS20_PID		0xFC82	/* DSS-20 Sync Station for Sony Ericsson P800 */ | ||||
| #define FTDI_URBAN_0_PID	0xFC8A	/* Sony Ericsson Urban, uart #0 */ | ||||
| #define FTDI_URBAN_1_PID	0xFC8B	/* Sony Ericsson Urban, uart #1 */ | ||||
|  | ||||
| /* www.irtrans.de device */ | ||||
| #define FTDI_IRTRANS_PID 0xFC60 /* Product Id */ | ||||
| @@ -519,6 +530,12 @@ | ||||
| #define ADI_GNICE_PID 		0xF000 | ||||
| #define ADI_GNICEPLUS_PID 	0xF001 | ||||
|  | ||||
| /* | ||||
|  * Hornby Elite | ||||
|  */ | ||||
| #define HORNBY_VID		0x04D8 | ||||
| #define HORNBY_ELITE_PID	0x000A | ||||
|  | ||||
| /* | ||||
|  * RATOC REX-USB60F | ||||
|  */ | ||||
| @@ -1164,4 +1181,21 @@ | ||||
| /* USB-Nano-485*/ | ||||
| #define FTDI_CTI_NANO_PID	0xF60B | ||||
|  | ||||
| /* | ||||
|  * ZeitControl cardsystems GmbH rfid-readers http://zeitconrol.de | ||||
|  */ | ||||
| /* TagTracer MIFARE*/ | ||||
| #define FTDI_ZEITCONTROL_TAGTRACE_MIFARE_PID	0xF7C0 | ||||
|  | ||||
| /* | ||||
|  * Rainforest Automation | ||||
|  */ | ||||
| /* ZigBee controller */ | ||||
| #define FTDI_RF_R106		0x8A28 | ||||
|  | ||||
| /* | ||||
|  * Product: HCP HIT GPRS modem | ||||
|  * Manufacturer: HCP d.o.o. | ||||
|  * ATI command output: Cinterion MC55i | ||||
|  */ | ||||
| #define FTDI_CINTERION_MC55I_PID	0xA951 | ||||
|   | ||||
| @@ -974,10 +974,7 @@ static void garmin_close(struct usb_serial_port *port) | ||||
| 	if (!serial) | ||||
| 		return; | ||||
|  | ||||
| 	mutex_lock(&port->serial->disc_mutex); | ||||
|  | ||||
| 	if (!port->serial->disconnected) | ||||
| 		garmin_clear(garmin_data_p); | ||||
| 	garmin_clear(garmin_data_p); | ||||
|  | ||||
| 	/* shutdown our urbs */ | ||||
| 	usb_kill_urb(port->read_urb); | ||||
| @@ -986,8 +983,6 @@ static void garmin_close(struct usb_serial_port *port) | ||||
| 	/* keep reset state so we know that we must start a new session */ | ||||
| 	if (garmin_data_p->state != STATE_RESET) | ||||
| 		garmin_data_p->state = STATE_DISCONNECTED; | ||||
|  | ||||
| 	mutex_unlock(&port->serial->disc_mutex); | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -574,6 +574,9 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout, | ||||
| 	wait_queue_t wait; | ||||
| 	unsigned long flags; | ||||
|  | ||||
| 	if (!tty) | ||||
| 		return; | ||||
|  | ||||
| 	if (!timeout) | ||||
| 		timeout = (HZ * EDGE_CLOSING_WAIT)/100; | ||||
|  | ||||
| @@ -2664,15 +2667,7 @@ cleanup: | ||||
|  | ||||
| static void edge_disconnect(struct usb_serial *serial) | ||||
| { | ||||
| 	int i; | ||||
| 	struct edgeport_port *edge_port; | ||||
|  | ||||
| 	dbg("%s", __func__); | ||||
|  | ||||
| 	for (i = 0; i < serial->num_ports; ++i) { | ||||
| 		edge_port = usb_get_serial_port_data(serial->port[i]); | ||||
| 		edge_remove_sysfs_attrs(edge_port->port); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void edge_release(struct usb_serial *serial) | ||||
| @@ -2927,6 +2922,7 @@ static struct usb_serial_driver edgeport_1port_device = { | ||||
| 	.disconnect		= edge_disconnect, | ||||
| 	.release		= edge_release, | ||||
| 	.port_probe		= edge_create_sysfs_attrs, | ||||
| 	.port_remove		= edge_remove_sysfs_attrs, | ||||
| 	.ioctl			= edge_ioctl, | ||||
| 	.set_termios		= edge_set_termios, | ||||
| 	.tiocmget		= edge_tiocmget, | ||||
| @@ -2957,6 +2953,7 @@ static struct usb_serial_driver edgeport_2port_device = { | ||||
| 	.disconnect		= edge_disconnect, | ||||
| 	.release		= edge_release, | ||||
| 	.port_probe		= edge_create_sysfs_attrs, | ||||
| 	.port_remove		= edge_remove_sysfs_attrs, | ||||
| 	.ioctl			= edge_ioctl, | ||||
| 	.set_termios		= edge_set_termios, | ||||
| 	.tiocmget		= edge_tiocmget, | ||||
|   | ||||
| @@ -1181,9 +1181,12 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty) | ||||
| 	} | ||||
|  | ||||
| 	spin_lock_irqsave(&mos7840_port->pool_lock, flags); | ||||
| 	for (i = 0; i < NUM_URBS; ++i) | ||||
| 		if (mos7840_port->busy[i]) | ||||
| 			chars += URB_TRANSFER_BUFFER_SIZE; | ||||
| 	for (i = 0; i < NUM_URBS; ++i) { | ||||
| 		if (mos7840_port->busy[i]) { | ||||
| 			struct urb *urb = mos7840_port->write_urb_pool[i]; | ||||
| 			chars += urb->transfer_buffer_length; | ||||
| 		} | ||||
| 	} | ||||
| 	spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); | ||||
| 	dbg("%s - returns %d", __func__, chars); | ||||
| 	return chars; | ||||
| @@ -2566,7 +2569,6 @@ error: | ||||
| 		kfree(mos7840_port->ctrl_buf); | ||||
| 		usb_free_urb(mos7840_port->control_urb); | ||||
| 		kfree(mos7840_port); | ||||
| 		serial->port[i] = NULL; | ||||
| 	} | ||||
| 	return status; | ||||
| } | ||||
| @@ -2633,6 +2635,7 @@ static void mos7840_release(struct usb_serial *serial) | ||||
| 		mos7840_port = mos7840_get_port_private(serial->port[i]); | ||||
| 		dbg("mos7840_port %d = %p", i, mos7840_port); | ||||
| 		if (mos7840_port) { | ||||
| 			usb_free_urb(mos7840_port->control_urb); | ||||
| 			kfree(mos7840_port->ctrl_buf); | ||||
| 			kfree(mos7840_port->dr); | ||||
| 			kfree(mos7840_port); | ||||
|   | ||||
| @@ -317,7 +317,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 (!wport->write_urb_busy) | ||||
| 		room = wport->bulk_out_size - OMNINET_HEADERLEN; | ||||
|  | ||||
| 	dbg("%s - returns %d", __func__, room); | ||||
|   | ||||
| @@ -618,6 +618,7 @@ static const struct usb_device_id option_ids[] = { | ||||
| 	{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, | ||||
| 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ | ||||
| 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | ||||
| 	{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ | ||||
| 	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ | ||||
| 	{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, | ||||
| 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, | ||||
|   | ||||
| @@ -100,6 +100,8 @@ static struct usb_device_id id_table [] = { | ||||
| 	{ USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) }, | ||||
| 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, | ||||
| 	{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, | ||||
| 	{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, | ||||
| 	{ USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) }, | ||||
| 	{ }					/* Terminating entry */ | ||||
| }; | ||||
|  | ||||
| @@ -615,10 +617,28 @@ static void pl2303_set_termios(struct tty_struct *tty, | ||||
| 				baud = 6000000; | ||||
| 		} | ||||
| 		dbg("%s - baud set = %d", __func__, baud); | ||||
| 		buf[0] = baud & 0xff; | ||||
| 		buf[1] = (baud >> 8) & 0xff; | ||||
| 		buf[2] = (baud >> 16) & 0xff; | ||||
| 		buf[3] = (baud >> 24) & 0xff; | ||||
| 		if (baud <= 115200) { | ||||
| 			buf[0] = baud & 0xff; | ||||
| 			buf[1] = (baud >> 8) & 0xff; | ||||
| 			buf[2] = (baud >> 16) & 0xff; | ||||
| 			buf[3] = (baud >> 24) & 0xff; | ||||
| 		} else { | ||||
| 			/* apparently the formula for higher speeds is: | ||||
| 			 * baudrate = 12M * 32 / (2^buf[1]) / buf[0] | ||||
| 			 */ | ||||
| 			unsigned tmp = 12*1000*1000*32 / baud; | ||||
| 			buf[3] = 0x80; | ||||
| 			buf[2] = 0; | ||||
| 			buf[1] = (tmp >= 256); | ||||
| 			while (tmp >= 256) { | ||||
| 				tmp >>= 2; | ||||
| 				buf[1] <<= 1; | ||||
| 			} | ||||
| 			if (tmp > 256) { | ||||
| 				tmp %= 256; | ||||
| 			} | ||||
| 			buf[0] = tmp; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* For reference buf[4]=0 is 1 stop bits */ | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
|  *	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. | ||||
|  *  | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #define BENQ_VENDOR_ID			0x04a5 | ||||
| @@ -140,3 +140,12 @@ | ||||
| /* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */ | ||||
| #define SANWA_VENDOR_ID		0x11ad | ||||
| #define SANWA_PRODUCT_ID	0x0001 | ||||
|  | ||||
| /* ADLINK ND-6530 RS232,RS485 and RS422 adapter */ | ||||
| #define ADLINK_VENDOR_ID		0x0b63 | ||||
| #define ADLINK_ND6530_PRODUCT_ID	0x6530 | ||||
|  | ||||
| /* SMART USB Serial Adapter */ | ||||
| #define SMART_VENDOR_ID	0x0b8c | ||||
| #define SMART_PRODUCT_ID	0x2303 | ||||
|  | ||||
|   | ||||
| @@ -28,6 +28,7 @@ static const struct usb_device_id id_table[] = { | ||||
| 	{USB_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */ | ||||
| 	{USB_DEVICE(0x03f0, 0x1f1d)},	/* HP un2400 Gobi Modem Device */ | ||||
| 	{USB_DEVICE(0x03f0, 0x201d)},	/* HP un2400 Gobi QDL Device */ | ||||
| 	{USB_DEVICE(0x03f0, 0x371d)},	/* HP un2430 Mobile Broadband Module */ | ||||
| 	{USB_DEVICE(0x04da, 0x250d)},	/* Panasonic Gobi Modem device */ | ||||
| 	{USB_DEVICE(0x04da, 0x250c)},	/* Panasonic Gobi QDL device */ | ||||
| 	{USB_DEVICE(0x413c, 0x8172)},	/* Dell Gobi Modem device */ | ||||
| @@ -45,6 +46,7 @@ static const struct usb_device_id id_table[] = { | ||||
| 	{USB_DEVICE(0x05c6, 0x9203)},	/* Generic Gobi Modem device */ | ||||
| 	{USB_DEVICE(0x05c6, 0x9222)},	/* Generic Gobi Modem device */ | ||||
| 	{USB_DEVICE(0x05c6, 0x9008)},	/* Generic Gobi QDL device */ | ||||
| 	{USB_DEVICE(0x05c6, 0x9009)},	/* Generic Gobi Modem device */ | ||||
| 	{USB_DEVICE(0x05c6, 0x9201)},	/* Generic Gobi QDL device */ | ||||
| 	{USB_DEVICE(0x05c6, 0x9221)},	/* Generic Gobi QDL device */ | ||||
| 	{USB_DEVICE(0x05c6, 0x9231)},	/* Generic Gobi QDL device */ | ||||
| @@ -78,6 +80,7 @@ static const struct usb_device_id id_table[] = { | ||||
| 	{USB_DEVICE(0x1199, 0x9008)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||||
| 	{USB_DEVICE(0x1199, 0x9009)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||||
| 	{USB_DEVICE(0x1199, 0x900a)},	/* Sierra Wireless Gobi 2000 Modem device (VT773) */ | ||||
| 	{USB_DEVICE(0x1199, 0x9011)},   /* Sierra Wireless Gobi 2000 Modem device (MC8305) */ | ||||
| 	{USB_DEVICE(0x16d8, 0x8001)},	/* CMDTech Gobi 2000 QDL device (VU922) */ | ||||
| 	{USB_DEVICE(0x16d8, 0x8002)},	/* CMDTech Gobi 2000 Modem device (VU922) */ | ||||
| 	{USB_DEVICE(0x05c6, 0x9204)},	/* Gobi 2000 QDL device */ | ||||
|   | ||||
| @@ -925,6 +925,7 @@ static void sierra_release(struct usb_serial *serial) | ||||
| 			continue; | ||||
| 		kfree(portdata); | ||||
| 	} | ||||
| 	kfree(serial->private); | ||||
| } | ||||
|  | ||||
| #ifdef CONFIG_PM | ||||
|   | ||||
| @@ -1071,6 +1071,12 @@ int usb_serial_probe(struct usb_interface *interface, | ||||
| 		serial->attached = 1; | ||||
| 	} | ||||
|  | ||||
| 	/* Avoid race with tty_open and serial_install by setting the | ||||
| 	 * disconnected flag and not clearing it until all ports have been | ||||
| 	 * registered. | ||||
| 	 */ | ||||
| 	serial->disconnected = 1; | ||||
|  | ||||
| 	if (get_free_serial(serial, num_ports, &minor) == NULL) { | ||||
| 		dev_err(&interface->dev, "No more free serial devices\n"); | ||||
| 		goto probe_error; | ||||
| @@ -1093,6 +1099,8 @@ int usb_serial_probe(struct usb_interface *interface, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	serial->disconnected = 0; | ||||
|  | ||||
| 	usb_serial_console_init(debug, minor); | ||||
|  | ||||
| exit: | ||||
|   | ||||
| @@ -576,6 +576,7 @@ no_firmware: | ||||
| 		"%s: please contact support@connecttech.com\n", | ||||
| 		serial->type->description); | ||||
| 	kfree(result); | ||||
| 	kfree(command); | ||||
| 	return -ENODEV; | ||||
|  | ||||
| no_command_private: | ||||
|   | ||||
| @@ -58,7 +58,9 @@ | ||||
|  | ||||
| void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) | ||||
| { | ||||
| 	/* Pad the SCSI command with zeros out to 12 bytes | ||||
| 	/* | ||||
| 	 * Pad the SCSI command with zeros out to 12 bytes.  If the | ||||
| 	 * command already is 12 bytes or longer, leave it alone. | ||||
| 	 * | ||||
| 	 * NOTE: This only works because a scsi_cmnd struct field contains | ||||
| 	 * a unsigned char cmnd[16], so we know we have storage available | ||||
| @@ -66,9 +68,6 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) | ||||
| 	for (; srb->cmd_len<12; srb->cmd_len++) | ||||
| 		srb->cmnd[srb->cmd_len] = 0; | ||||
|  | ||||
| 	/* set command length to 12 bytes */ | ||||
| 	srb->cmd_len = 12; | ||||
|  | ||||
| 	/* send the command to the transport layer */ | ||||
| 	usb_stor_invoke_transport(srb, us); | ||||
| } | ||||
|   | ||||
| @@ -693,6 +693,9 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) | ||||
| 		int temp_result; | ||||
| 		struct scsi_eh_save ses; | ||||
| 		int sense_size = US_SENSE_SIZE; | ||||
| 		struct scsi_sense_hdr sshdr; | ||||
| 		const u8 *scdd; | ||||
| 		u8 fm_ili; | ||||
|  | ||||
| 		/* device supports and needs bigger sense buffer */ | ||||
| 		if (us->fflags & US_FL_SANE_SENSE) | ||||
| @@ -776,32 +779,30 @@ Retry_Sense: | ||||
| 			srb->sense_buffer[7] = (US_SENSE_SIZE - 8); | ||||
| 		} | ||||
|  | ||||
| 		scsi_normalize_sense(srb->sense_buffer, SCSI_SENSE_BUFFERSIZE, | ||||
| 				     &sshdr); | ||||
|  | ||||
| 		US_DEBUGP("-- Result from auto-sense is %d\n", temp_result); | ||||
| 		US_DEBUGP("-- code: 0x%x, key: 0x%x, ASC: 0x%x, ASCQ: 0x%x\n", | ||||
| 			  srb->sense_buffer[0], | ||||
| 			  srb->sense_buffer[2] & 0xf, | ||||
| 			  srb->sense_buffer[12],  | ||||
| 			  srb->sense_buffer[13]); | ||||
| 			  sshdr.response_code, sshdr.sense_key, | ||||
| 			  sshdr.asc, sshdr.ascq); | ||||
| #ifdef CONFIG_USB_STORAGE_DEBUG | ||||
| 		usb_stor_show_sense( | ||||
| 			  srb->sense_buffer[2] & 0xf, | ||||
| 			  srb->sense_buffer[12],  | ||||
| 			  srb->sense_buffer[13]); | ||||
| 		usb_stor_show_sense(sshdr.sense_key, sshdr.asc, sshdr.ascq); | ||||
| #endif | ||||
|  | ||||
| 		/* set the result so the higher layers expect this data */ | ||||
| 		srb->result = SAM_STAT_CHECK_CONDITION; | ||||
|  | ||||
| 		scdd = scsi_sense_desc_find(srb->sense_buffer, | ||||
| 					    SCSI_SENSE_BUFFERSIZE, 4); | ||||
| 		fm_ili = (scdd ? scdd[3] : srb->sense_buffer[2]) & 0xA0; | ||||
|  | ||||
| 		/* We often get empty sense data.  This could indicate that | ||||
| 		 * everything worked or that there was an unspecified | ||||
| 		 * problem.  We have to decide which. | ||||
| 		 */ | ||||
| 		if (	/* Filemark 0, ignore EOM, ILI 0, no sense */ | ||||
| 				(srb->sense_buffer[2] & 0xaf) == 0 && | ||||
| 			/* No ASC or ASCQ */ | ||||
| 				srb->sense_buffer[12] == 0 && | ||||
| 				srb->sense_buffer[13] == 0) { | ||||
|  | ||||
| 		if (sshdr.sense_key == 0 && sshdr.asc == 0 && sshdr.ascq == 0 && | ||||
| 		    fm_ili == 0) { | ||||
| 			/* If things are really okay, then let's show that. | ||||
| 			 * Zero out the sense buffer so the higher layers | ||||
| 			 * won't realize we did an unsolicited auto-sense. | ||||
| @@ -816,7 +817,10 @@ Retry_Sense: | ||||
| 			 */ | ||||
| 			} else { | ||||
| 				srb->result = DID_ERROR << 16; | ||||
| 				srb->sense_buffer[2] = HARDWARE_ERROR; | ||||
| 				if ((sshdr.response_code & 0x72) == 0x72) | ||||
| 					srb->sense_buffer[1] = HARDWARE_ERROR; | ||||
| 				else | ||||
| 					srb->sense_buffer[2] = HARDWARE_ERROR; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -1857,6 +1857,13 @@ UNUSUAL_DEV(  0x1370, 0x6828, 0x0110, 0x0110, | ||||
| 		US_SC_DEVICE, US_PR_DEVICE, NULL, | ||||
| 		US_FL_IGNORE_RESIDUE ), | ||||
|  | ||||
| /* Reported by Qinglin Ye <yestyle@gmail.com> */ | ||||
| UNUSUAL_DEV(  0x13fe, 0x3600, 0x0100, 0x0100, | ||||
| 		"Kingston", | ||||
| 		"DT 101 G2", | ||||
| 		US_SC_DEVICE, US_PR_DEVICE, NULL, | ||||
| 		US_FL_BULK_IGNORE_TAG ), | ||||
|  | ||||
| /* Reported by Francesco Foresti <frafore@tiscali.it> */ | ||||
| UNUSUAL_DEV(  0x14cd, 0x6600, 0x0201, 0x0201, | ||||
| 		"Super Top", | ||||
| @@ -1977,6 +1984,16 @@ UNUSUAL_DEV(  0x4146, 0xba01, 0x0100, 0x0100, | ||||
| 		"Micro Mini 1GB", | ||||
| 		US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), | ||||
|  | ||||
| /* | ||||
|  * Nick Bowler <nbowler@elliptictech.com> | ||||
|  * SCSI stack spams (otherwise harmless) error messages. | ||||
|  */ | ||||
| UNUSUAL_DEV(  0xc251, 0x4003, 0x0100, 0x0100, | ||||
| 		"Keil Software, Inc.", | ||||
| 		"V2M MotherBoard", | ||||
| 		US_SC_DEVICE, US_PR_DEVICE, NULL, | ||||
| 		US_FL_NOT_LOCKABLE), | ||||
|  | ||||
| /* Reported by Andrew Simmons <andrew.simmons@gmail.com> */ | ||||
| UNUSUAL_DEV(  0xed06, 0x4500, 0x0001, 0x0001, | ||||
| 		"DataStor", | ||||
|   | ||||
| @@ -1025,6 +1025,7 @@ static struct usb_driver usb_storage_driver = { | ||||
| 	.post_reset =	usb_stor_post_reset, | ||||
| 	.id_table =	usb_storage_usb_ids, | ||||
| 	.soft_unbind =	1, | ||||
| 	.no_dynamic_id = 1, | ||||
| }; | ||||
|  | ||||
| static int __init usb_stor_init(void) | ||||
|   | ||||
| @@ -46,7 +46,7 @@ struct ehci_caps { | ||||
| #define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1))  /* true: periodic_size changes*/ | ||||
| #define HCC_64BIT_ADDR(p)       ((p)&(1))       /* true: can use 64-bit addr */ | ||||
| 	u8		portroute [8];	 /* nibbles for routing - offset 0xC */ | ||||
| } __attribute__ ((packed)); | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* Section 2.3 Host Controller Operational Registers */ | ||||
| @@ -125,7 +125,7 @@ struct ehci_regs { | ||||
| #define PORT_CSC	(1<<1)		/* connect status change */ | ||||
| #define PORT_CONNECT	(1<<0)		/* device connected */ | ||||
| #define PORT_RWC_BITS   (PORT_CSC | PORT_PEC | PORT_OCC) | ||||
| } __attribute__ ((packed)); | ||||
| }; | ||||
|  | ||||
| #define USBMODE		0x68		/* USB Device mode */ | ||||
| #define USBMODE_SDIS	(1<<3)		/* Stream disable */ | ||||
| @@ -169,7 +169,7 @@ struct ehci_dbg_port { | ||||
| 	u32	data47; | ||||
| 	u32	address; | ||||
| #define DBGP_EPADDR(dev, ep)	(((dev)<<8)|(ep)) | ||||
| } __attribute__ ((packed)); | ||||
| }; | ||||
|  | ||||
| #ifdef CONFIG_EARLY_PRINTK_DBGP | ||||
| #include <linux/init.h> | ||||
|   | ||||
| @@ -171,7 +171,8 @@ extern void usbnet_cdc_unbind (struct usbnet *, struct usb_interface *); | ||||
| enum skb_state { | ||||
| 	illegal = 0, | ||||
| 	tx_start, tx_done, | ||||
| 	rx_start, rx_done, rx_cleanup | ||||
| 	rx_start, rx_done, rx_cleanup, | ||||
| 	unlink_start | ||||
| }; | ||||
|  | ||||
| struct skb_data {	/* skb->cb is one of these */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user