Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d5bc23b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6:
  USB: option.c: add support for D-Link DWM-162-U5
  USB: usbmon: fix bug in mon_buff_area_shrink
  USB: xhci: Fix scratchpad deallocation.
  USB: xhci: Fix TRB physical to virtual address translation.
  USB: xhci: Fix bug memory free after failed initialization.
  USB: cdc_acm: Fix memory leak after hangup
  USB: cdc_acm: Fix race condition when opening tty
  USB: ohci: quirk AMD prefetch for USB 1.1 ISO transfer
parents 78db1caa ff854ce0
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -609,9 +609,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)

	acm->throttle = 0;

	tasklet_schedule(&acm->urb_task);
	set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
	rv = tty_port_block_til_ready(&acm->port, tty, filp);
	tasklet_schedule(&acm->urb_task);
done:
	mutex_unlock(&acm->mutex);
err_out:
@@ -686,15 +686,21 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)

	/* Perform the closing process and see if we need to do the hardware
	   shutdown */
	if (!acm || tty_port_close_start(&acm->port, tty, filp) == 0)
	if (!acm)
		return;
	acm_port_down(acm, 0);
	tty_port_close_end(&acm->port, tty);
	if (tty_port_close_start(&acm->port, tty, filp) == 0) {
		mutex_lock(&open_mutex);
		if (!acm->dev) {
			tty_port_tty_set(&acm->port, NULL);
	if (!acm->dev)
			acm_tty_unregister(acm);
			tty->driver_data = NULL;
		}
		mutex_unlock(&open_mutex);
		return;
	}
	acm_port_down(acm, 0);
	tty_port_close_end(&acm->port, tty);
	tty_port_tty_set(&acm->port, NULL);
}

static int acm_tty_write(struct tty_struct *tty,
+5 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ static int ohci_restart (struct ohci_hcd *ohci);
#ifdef CONFIG_PCI
static void quirk_amd_pll(int state);
static void amd_iso_dev_put(void);
static void sb800_prefetch(struct ohci_hcd *ohci, int on);
#else
static inline void quirk_amd_pll(int state)
{
@@ -96,6 +97,10 @@ static inline void amd_iso_dev_put(void)
{
	return;
}
static inline void sb800_prefetch(struct ohci_hcd *ohci, int on)
{
	return;
}
#endif


+20 −0
Original line number Diff line number Diff line
@@ -177,6 +177,13 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
		return 0;

	pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);

	/* SB800 needs pre-fetch fix */
	if ((rev >= 0x40) && (rev <= 0x4f)) {
		ohci->flags |= OHCI_QUIRK_AMD_PREFETCH;
		ohci_dbg(ohci, "enabled AMD prefetch quirk\n");
	}

	if ((rev > 0x3b) || (rev < 0x30)) {
		pci_dev_put(amd_smbus_dev);
		amd_smbus_dev = NULL;
@@ -262,6 +269,19 @@ static void amd_iso_dev_put(void)

}

static void sb800_prefetch(struct ohci_hcd *ohci, int on)
{
	struct pci_dev *pdev;
	u16 misc;

	pdev = to_pci_dev(ohci_to_hcd(ohci)->self.controller);
	pci_read_config_word(pdev, 0x50, &misc);
	if (on == 0)
		pci_write_config_word(pdev, 0x50, misc & 0xfcff);
	else
		pci_write_config_word(pdev, 0x50, misc | 0x0300);
}

/* List of quirks for OHCI */
static const struct pci_device_id ohci_pci_quirks[] = {
	{
+12 −6
Original line number Diff line number Diff line
@@ -49,9 +49,12 @@ __acquires(ohci->lock)
	switch (usb_pipetype (urb->pipe)) {
	case PIPE_ISOCHRONOUS:
		ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--;
		if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
				&& quirk_amdiso(ohci))
		if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) {
			if (quirk_amdiso(ohci))
				quirk_amd_pll(1);
			if (quirk_amdprefetch(ohci))
				sb800_prefetch(ohci, 0);
		}
		break;
	case PIPE_INTERRUPT:
		ohci_to_hcd(ohci)->self.bandwidth_int_reqs--;
@@ -680,9 +683,12 @@ static void td_submit_urb (
				data + urb->iso_frame_desc [cnt].offset,
				urb->iso_frame_desc [cnt].length, urb, cnt);
		}
		if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
				&& quirk_amdiso(ohci))
		if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) {
			if (quirk_amdiso(ohci))
				quirk_amd_pll(0);
			if (quirk_amdprefetch(ohci))
				sb800_prefetch(ohci, 1);
		}
		periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0
			&& ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0;
		break;
+9 −0
Original line number Diff line number Diff line
@@ -402,6 +402,7 @@ struct ohci_hcd {
#define	OHCI_QUIRK_FRAME_NO	0x80			/* no big endian frame_no shift */
#define	OHCI_QUIRK_HUB_POWER	0x100			/* distrust firmware power/oc setup */
#define	OHCI_QUIRK_AMD_ISO	0x200			/* ISO transfers*/
#define	OHCI_QUIRK_AMD_PREFETCH	0x400			/* pre-fetch for ISO transfer */
	// there are also chip quirks/bugs in init logic

	struct work_struct	nec_work;	/* Worker for NEC quirk */
@@ -433,6 +434,10 @@ static inline int quirk_amdiso(struct ohci_hcd *ohci)
{
	return ohci->flags & OHCI_QUIRK_AMD_ISO;
}
static inline int quirk_amdprefetch(struct ohci_hcd *ohci)
{
	return ohci->flags & OHCI_QUIRK_AMD_PREFETCH;
}
#else
static inline int quirk_nec(struct ohci_hcd *ohci)
{
@@ -446,6 +451,10 @@ static inline int quirk_amdiso(struct ohci_hcd *ohci)
{
	return 0;
}
static inline int quirk_amdprefetch(struct ohci_hcd *ohci)
{
	return 0;
}
#endif

/* convert between an hcd pointer and the corresponding ohci_hcd */
Loading