Commit 691a5599 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6:
  USB: sisusbvga: add USB ID for 0711:0918 Magic Control Technology Corp.
  USB: automatically enable RHSC interrupts
  USB: Don't rebind before "complete" callback
  USB: Add new PM callback methods for USB
  USB: Defer Set-Interface for suspended devices
  USB: Add udev argument to interface suspend/resume functions
  USB: cdc-acm: don't unlock acm->mutex on error path
  MUSB: Fix index register corruption seen with g_ether and Windows host
  usb: musb: get rid of MUSB_LOGLEVEL and use parameter
  usb: musb: get rid of procfs entry
  USB: Fix pxa27x_udc usb speed handling.
  USB: cdc-acm: quirk for Conexant CX93010 USB modem
  USB: fix bug in usb_unlink_anchored_urbs()
  usb-serial: option support HSDPA modem A2502
  USB: ISP1760: fixed trivial math in comment
parents cce7496d eaea0435
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -589,8 +589,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
	tasklet_schedule(&acm->urb_task);

done:
err_out:
	mutex_unlock(&acm->mutex);
err_out:
	mutex_unlock(&open_mutex);
	return rv;

@@ -1362,6 +1362,9 @@ static struct usb_device_id acm_ids[] = {
	{ USB_DEVICE(0x0803, 0x3095), /* Zoom Telephonics Model 3095F USB MODEM */
	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
	},
	{ USB_DEVICE(0x0572, 0x1321), /* Conexant USB MODEM CX93010 */
	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
	},

	/* control interfaces with various AT-command sets */
	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
+49 −47
Original line number Diff line number Diff line
@@ -230,6 +230,13 @@ static int usb_probe_interface(struct device *dev)
		 */
		intf->pm_usage_cnt = !(driver->supports_autosuspend);

		/* Carry out a deferred switch to altsetting 0 */
		if (intf->needs_altsetting0) {
			usb_set_interface(udev, intf->altsetting[0].
					desc.bInterfaceNumber, 0);
			intf->needs_altsetting0 = 0;
		}

		error = driver->probe(intf, id);
		if (error) {
			mark_quiesced(intf);
@@ -266,8 +273,17 @@ static int usb_unbind_interface(struct device *dev)

	driver->disconnect(intf);

	/* reset other interface state */
	usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
	/* Reset other interface state.
	 * We cannot do a Set-Interface if the device is suspended or
	 * if it is prepared for a system sleep (since installing a new
	 * altsetting means creating new endpoint device entries).
	 * When either of these happens, defer the Set-Interface.
	 */
	if (!error && intf->dev.power.status == DPM_ON)
		usb_set_interface(udev, intf->altsetting[0].
				desc.bInterfaceNumber, 0);
	else
		intf->needs_altsetting0 = 1;
	usb_set_intfdata(intf, NULL);

	intf->condition = USB_INTERFACE_UNBOUND;
@@ -798,7 +814,8 @@ void usb_forced_unbind_intf(struct usb_interface *intf)
 * The caller must hold @intf's device's lock, but not its pm_mutex
 * and not @intf->dev.sem.
 *
 * FIXME: The caller must block system sleep transitions.
 * Note: Rebinds will be skipped if a system sleep transition is in
 * progress and the PM "complete" callback hasn't occurred yet.
 */
void usb_rebind_intf(struct usb_interface *intf)
{
@@ -814,11 +831,13 @@ void usb_rebind_intf(struct usb_interface *intf)
	}

	/* Try to rebind the interface */
	if (intf->dev.power.status == DPM_ON) {
		intf->needs_binding = 0;
		rc = device_attach(&intf->dev);
		if (rc < 0)
			dev_warn(&intf->dev, "rebind failed: %d\n", rc);
	}
}

#ifdef CONFIG_PM

@@ -829,7 +848,6 @@ void usb_rebind_intf(struct usb_interface *intf)
 * or rebind interfaces that have been unbound, according to @action.
 *
 * The caller must hold @udev's device lock.
 * FIXME: For rebinds, the caller must block system sleep transitions.
 */
static void do_unbind_rebind(struct usb_device *udev, int action)
{
@@ -851,22 +869,8 @@ static void do_unbind_rebind(struct usb_device *udev, int action)
				}
				break;
			case DO_REBIND:
				if (intf->needs_binding) {

	/* FIXME: The next line is needed because we are going to probe
	 * the interface, but as far as the PM core is concerned the
	 * interface is still suspended.  The problem wouldn't exist
	 * if we could rebind the interface during the interface's own
	 * resume() call, but at the time the usb_device isn't locked!
	 *
	 * The real solution will be to carry this out during the device's
	 * complete() callback.  Until that is implemented, we have to
	 * use this hack.
	 */
//					intf->dev.power.sleeping = 0;

				if (intf->needs_binding)
					usb_rebind_intf(intf);
				}
				break;
			}
		}
@@ -926,14 +930,14 @@ static int usb_resume_device(struct usb_device *udev)
}

/* Caller has locked intf's usb_device's pm mutex */
static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
static int usb_suspend_interface(struct usb_device *udev,
		struct usb_interface *intf, pm_message_t msg)
{
	struct usb_driver	*driver;
	int			status = 0;

	/* with no hardware, USB interfaces only use FREEZE and ON states */
	if (interface_to_usbdev(intf)->state == USB_STATE_NOTATTACHED ||
			!is_active(intf))
	if (udev->state == USB_STATE_NOTATTACHED || !is_active(intf))
		goto done;

	if (intf->condition == USB_INTERFACE_UNBOUND)	/* This can't happen */
@@ -944,7 +948,7 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
		status = driver->suspend(intf, msg);
		if (status == 0)
			mark_quiesced(intf);
		else if (!interface_to_usbdev(intf)->auto_pm)
		else if (!udev->auto_pm)
			dev_err(&intf->dev, "%s error %d\n",
					"suspend", status);
	} else {
@@ -961,13 +965,13 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
}

/* Caller has locked intf's usb_device's pm_mutex */
static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
static int usb_resume_interface(struct usb_device *udev,
		struct usb_interface *intf, int reset_resume)
{
	struct usb_driver	*driver;
	int			status = 0;

	if (interface_to_usbdev(intf)->state == USB_STATE_NOTATTACHED ||
			is_active(intf))
	if (udev->state == USB_STATE_NOTATTACHED || is_active(intf))
		goto done;

	/* Don't let autoresume interfere with unbinding */
@@ -975,8 +979,17 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
		goto done;

	/* Can't resume it if it doesn't have a driver. */
	if (intf->condition == USB_INTERFACE_UNBOUND)
	if (intf->condition == USB_INTERFACE_UNBOUND) {

		/* Carry out a deferred switch to altsetting 0 */
		if (intf->needs_altsetting0 &&
				intf->dev.power.status == DPM_ON) {
			usb_set_interface(udev, intf->altsetting[0].
					desc.bInterfaceNumber, 0);
			intf->needs_altsetting0 = 0;
		}
		goto done;
	}

	/* Don't resume if the interface is marked for rebinding */
	if (intf->needs_binding)
@@ -1151,7 +1164,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
	if (udev->actconfig) {
		for (; i < udev->actconfig->desc.bNumInterfaces; i++) {
			intf = udev->actconfig->interface[i];
			status = usb_suspend_interface(intf, msg);
			status = usb_suspend_interface(udev, intf, msg);
			if (status != 0)
				break;
		}
@@ -1163,7 +1176,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
	if (status != 0) {
		while (--i >= 0) {
			intf = udev->actconfig->interface[i];
			usb_resume_interface(intf, 0);
			usb_resume_interface(udev, intf, 0);
		}

		/* Try another autosuspend when the interfaces aren't busy */
@@ -1276,7 +1289,7 @@ static int usb_resume_both(struct usb_device *udev)
	if (status == 0 && udev->actconfig) {
		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
			intf = udev->actconfig->interface[i];
			usb_resume_interface(intf, udev->reset_resume);
			usb_resume_interface(udev, intf, udev->reset_resume);
		}
	}

@@ -1605,12 +1618,10 @@ int usb_external_resume_device(struct usb_device *udev)
	return status;
}

static int usb_suspend(struct device *dev, pm_message_t message)
int usb_suspend(struct device *dev, pm_message_t message)
{
	struct usb_device	*udev;

	if (!is_usb_device(dev))	/* Ignore PM for interfaces */
		return 0;
	udev = to_usb_device(dev);

	/* If udev is already suspended, we can skip this suspend and
@@ -1629,12 +1640,10 @@ static int usb_suspend(struct device *dev, pm_message_t message)
	return usb_external_suspend_device(udev, message);
}

static int usb_resume(struct device *dev)
int usb_resume(struct device *dev)
{
	struct usb_device	*udev;

	if (!is_usb_device(dev))	/* Ignore PM for interfaces */
		return 0;
	udev = to_usb_device(dev);

	/* If udev->skip_sys_resume is set then udev was already suspended
@@ -1646,17 +1655,10 @@ static int usb_resume(struct device *dev)
	return usb_external_resume_device(udev);
}

#else

#define usb_suspend	NULL
#define usb_resume	NULL

#endif /* CONFIG_PM */

struct bus_type usb_bus_type = {
	.name =		"usb",
	.match =	usb_device_match,
	.uevent =	usb_uevent,
	.suspend =	usb_suspend,
	.resume =	usb_resume,
};
+0 −9
Original line number Diff line number Diff line
@@ -924,15 +924,6 @@ static int register_root_hub(struct usb_hcd *hcd)
	return retval;
}

void usb_enable_root_hub_irq (struct usb_bus *bus)
{
	struct usb_hcd *hcd;

	hcd = container_of (bus, struct usb_hcd, self);
	if (hcd->driver->hub_irq_enable && hcd->state != HC_STATE_HALT)
		hcd->driver->hub_irq_enable (hcd);
}


/*-------------------------------------------------------------------------*/

+0 −4
Original line number Diff line number Diff line
@@ -212,8 +212,6 @@ struct hc_driver {
	int	(*bus_suspend)(struct usb_hcd *);
	int	(*bus_resume)(struct usb_hcd *);
	int	(*start_port_reset)(struct usb_hcd *, unsigned port_num);
	void	(*hub_irq_enable)(struct usb_hcd *);
		/* Needed only if port-change IRQs are level-triggered */

		/* force handover of high-speed port to full-speed companion */
	void	(*relinquish_port)(struct usb_hcd *, int);
@@ -379,8 +377,6 @@ extern struct list_head usb_bus_list;
extern struct mutex usb_bus_list_lock;
extern wait_queue_head_t usb_kill_urb_queue;

extern void usb_enable_root_hub_irq(struct usb_bus *bus);

extern int usb_find_interface_driver(struct usb_device *dev,
	struct usb_interface *interface);

+0 −9
Original line number Diff line number Diff line
@@ -2102,8 +2102,6 @@ int usb_port_resume(struct usb_device *udev)
	}

	clear_bit(port1, hub->busy_bits);
	if (!hub->hdev->parent && !hub->busy_bits[0])
		usb_enable_root_hub_irq(hub->hdev->bus);

	status = check_port_resume_type(udev,
			hub, port1, status, portchange, portstatus);
@@ -3081,11 +3079,6 @@ static void hub_events(void)
			}
		}

		/* If this is a root hub, tell the HCD it's okay to
		 * re-enable port-change interrupts now. */
		if (!hdev->parent && !hub->busy_bits[0])
			usb_enable_root_hub_irq(hdev->bus);

loop_autopm:
		/* Allow autosuspend if we're not going to run again */
		if (list_empty(&hub->event_list))
@@ -3311,8 +3304,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
			break;
	}
	clear_bit(port1, parent_hub->busy_bits);
	if (!parent_hdev->parent && !parent_hub->busy_bits[0])
		usb_enable_root_hub_irq(parent_hdev->bus);

	if (ret < 0)
		goto re_enumerate;
Loading