Merge 4.6-rc5 into usb-next

We want the USB fixes in here as well.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Greg Kroah-Hartman 2016-04-25 10:50:11 -07:00
commit 69b4269eff
8 changed files with 268 additions and 52 deletions

View File

@ -314,7 +314,7 @@ void qset_free_std(struct whc *whc, struct whc_std *std)
kfree(std->bounce_buf); kfree(std->bounce_buf);
} }
if (std->pl_virt) { if (std->pl_virt) {
if (std->dma_addr) if (!dma_mapping_error(whc->wusbhc.dev, std->dma_addr))
dma_unmap_single(whc->wusbhc.dev, std->dma_addr, dma_unmap_single(whc->wusbhc.dev, std->dma_addr,
std->num_pointers * sizeof(struct whc_page_list_entry), std->num_pointers * sizeof(struct whc_page_list_entry),
DMA_TO_DEVICE); DMA_TO_DEVICE);
@ -535,9 +535,11 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u
list_for_each_entry(std, &qset->stds, list_node) { list_for_each_entry(std, &qset->stds, list_node) {
if (std->ntds_remaining == -1) { if (std->ntds_remaining == -1) {
pl_len = std->num_pointers * sizeof(struct whc_page_list_entry); pl_len = std->num_pointers * sizeof(struct whc_page_list_entry);
std->ntds_remaining = ntds--;
std->dma_addr = dma_map_single(whc->wusbhc.dev, std->pl_virt, std->dma_addr = dma_map_single(whc->wusbhc.dev, std->pl_virt,
pl_len, DMA_TO_DEVICE); pl_len, DMA_TO_DEVICE);
if (dma_mapping_error(whc->wusbhc.dev, std->dma_addr))
return -EFAULT;
std->ntds_remaining = ntds--;
} }
} }
return 0; return 0;
@ -618,6 +620,8 @@ static int qset_add_urb_sg_linearize(struct whc *whc, struct whc_qset *qset,
std->dma_addr = dma_map_single(&whc->umc->dev, std->bounce_buf, std->len, std->dma_addr = dma_map_single(&whc->umc->dev, std->bounce_buf, std->len,
is_out ? DMA_TO_DEVICE : DMA_FROM_DEVICE); is_out ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
if (dma_mapping_error(&whc->umc->dev, std->dma_addr))
return -EFAULT;
if (qset_fill_page_list(whc, std, mem_flags) < 0) if (qset_fill_page_list(whc, std, mem_flags) < 0)
return -ENOMEM; return -ENOMEM;

View File

@ -1768,7 +1768,7 @@ static int xhci_requires_manual_halt_cleanup(struct xhci_hcd *xhci,
if (trb_comp_code == COMP_TX_ERR || if (trb_comp_code == COMP_TX_ERR ||
trb_comp_code == COMP_BABBLE || trb_comp_code == COMP_BABBLE ||
trb_comp_code == COMP_SPLIT_ERR) trb_comp_code == COMP_SPLIT_ERR)
/* The 0.96 spec says a babbling control endpoint /* The 0.95 spec says a babbling control endpoint
* is not halted. The 0.96 spec says it is. Some HW * is not halted. The 0.96 spec says it is. Some HW
* claims to be 0.95 compliant, but it halts the control * claims to be 0.95 compliant, but it halts the control
* endpoint anyway. Check if a babble halted the * endpoint anyway. Check if a babble halted the

View File

@ -388,7 +388,6 @@ err_files:
err_port: err_port:
dev_set_drvdata(&udev->dev, NULL); dev_set_drvdata(&udev->dev, NULL);
usb_put_dev(udev); usb_put_dev(udev);
kthread_stop_put(sdev->ud.eh);
busid_priv->sdev = NULL; busid_priv->sdev = NULL;
stub_device_free(sdev); stub_device_free(sdev);
@ -449,7 +448,7 @@ static void stub_disconnect(struct usb_device *udev)
} }
/* If usb reset is called from event handler */ /* If usb reset is called from event handler */
if (busid_priv->sdev->ud.eh == current) if (usbip_in_eh(current))
return; return;
/* shutdown the current connection */ /* shutdown the current connection */

View File

@ -769,12 +769,19 @@ EXPORT_SYMBOL_GPL(usbip_recv_xbuff);
static int __init usbip_core_init(void) static int __init usbip_core_init(void)
{ {
int ret;
pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); pr_info(DRIVER_DESC " v" USBIP_VERSION "\n");
ret = usbip_init_eh();
if (ret)
return ret;
return 0; return 0;
} }
static void __exit usbip_core_exit(void) static void __exit usbip_core_exit(void)
{ {
usbip_finish_eh();
return; return;
} }

View File

@ -267,7 +267,6 @@ struct usbip_device {
struct task_struct *tcp_tx; struct task_struct *tcp_tx;
unsigned long event; unsigned long event;
struct task_struct *eh;
wait_queue_head_t eh_waitq; wait_queue_head_t eh_waitq;
struct eh_ops { struct eh_ops {
@ -313,10 +312,13 @@ void usbip_pad_iso(struct usbip_device *ud, struct urb *urb);
int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb); int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb);
/* usbip_event.c */ /* usbip_event.c */
int usbip_init_eh(void);
void usbip_finish_eh(void);
int usbip_start_eh(struct usbip_device *ud); int usbip_start_eh(struct usbip_device *ud);
void usbip_stop_eh(struct usbip_device *ud); void usbip_stop_eh(struct usbip_device *ud);
void usbip_event_add(struct usbip_device *ud, unsigned long event); void usbip_event_add(struct usbip_device *ud, unsigned long event);
int usbip_event_happened(struct usbip_device *ud); int usbip_event_happened(struct usbip_device *ud);
int usbip_in_eh(struct task_struct *task);
static inline int interface_to_busnum(struct usb_interface *interface) static inline int interface_to_busnum(struct usb_interface *interface)
{ {

View File

@ -1,5 +1,6 @@
/* /*
* Copyright (C) 2003-2008 Takahiro Hirofuchi * Copyright (C) 2003-2008 Takahiro Hirofuchi
* Copyright (C) 2015 Nobuo Iwata
* *
* This is free software; you can redistribute it and/or modify * This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -19,17 +20,68 @@
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include "usbip_common.h" #include "usbip_common.h"
static int event_handler(struct usbip_device *ud) struct usbip_event {
{ struct list_head node;
usbip_dbg_eh("enter\n"); struct usbip_device *ud;
};
/* static DEFINE_SPINLOCK(event_lock);
* Events are handled by only this thread. static LIST_HEAD(event_list);
*/
while (usbip_event_happened(ud)) { static void set_event(struct usbip_device *ud, unsigned long event)
{
unsigned long flags;
spin_lock_irqsave(&ud->lock, flags);
ud->event |= event;
spin_unlock_irqrestore(&ud->lock, flags);
}
static void unset_event(struct usbip_device *ud, unsigned long event)
{
unsigned long flags;
spin_lock_irqsave(&ud->lock, flags);
ud->event &= ~event;
spin_unlock_irqrestore(&ud->lock, flags);
}
static struct usbip_device *get_event(void)
{
struct usbip_event *ue = NULL;
struct usbip_device *ud = NULL;
unsigned long flags;
spin_lock_irqsave(&event_lock, flags);
if (!list_empty(&event_list)) {
ue = list_first_entry(&event_list, struct usbip_event, node);
list_del(&ue->node);
}
spin_unlock_irqrestore(&event_lock, flags);
if (ue) {
ud = ue->ud;
kfree(ue);
}
return ud;
}
static struct task_struct *worker_context;
static void event_handler(struct work_struct *work)
{
struct usbip_device *ud;
if (worker_context == NULL) {
worker_context = current;
}
while ((ud = get_event()) != NULL) {
usbip_dbg_eh("pending event %lx\n", ud->event); usbip_dbg_eh("pending event %lx\n", ud->event);
/* /*
@ -38,79 +90,102 @@ static int event_handler(struct usbip_device *ud)
*/ */
if (ud->event & USBIP_EH_SHUTDOWN) { if (ud->event & USBIP_EH_SHUTDOWN) {
ud->eh_ops.shutdown(ud); ud->eh_ops.shutdown(ud);
ud->event &= ~USBIP_EH_SHUTDOWN; unset_event(ud, USBIP_EH_SHUTDOWN);
} }
/* Reset the device. */ /* Reset the device. */
if (ud->event & USBIP_EH_RESET) { if (ud->event & USBIP_EH_RESET) {
ud->eh_ops.reset(ud); ud->eh_ops.reset(ud);
ud->event &= ~USBIP_EH_RESET; unset_event(ud, USBIP_EH_RESET);
} }
/* Mark the device as unusable. */ /* Mark the device as unusable. */
if (ud->event & USBIP_EH_UNUSABLE) { if (ud->event & USBIP_EH_UNUSABLE) {
ud->eh_ops.unusable(ud); ud->eh_ops.unusable(ud);
ud->event &= ~USBIP_EH_UNUSABLE; unset_event(ud, USBIP_EH_UNUSABLE);
} }
/* Stop the error handler. */ /* Stop the error handler. */
if (ud->event & USBIP_EH_BYE) if (ud->event & USBIP_EH_BYE)
return -1; usbip_dbg_eh("removed %p\n", ud);
wake_up(&ud->eh_waitq);
} }
return 0;
}
static int event_handler_loop(void *data)
{
struct usbip_device *ud = data;
while (!kthread_should_stop()) {
wait_event_interruptible(ud->eh_waitq,
usbip_event_happened(ud) ||
kthread_should_stop());
usbip_dbg_eh("wakeup\n");
if (event_handler(ud) < 0)
break;
}
return 0;
} }
int usbip_start_eh(struct usbip_device *ud) int usbip_start_eh(struct usbip_device *ud)
{ {
init_waitqueue_head(&ud->eh_waitq); init_waitqueue_head(&ud->eh_waitq);
ud->event = 0; ud->event = 0;
ud->eh = kthread_run(event_handler_loop, ud, "usbip_eh");
if (IS_ERR(ud->eh)) {
pr_warn("Unable to start control thread\n");
return PTR_ERR(ud->eh);
}
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(usbip_start_eh); EXPORT_SYMBOL_GPL(usbip_start_eh);
void usbip_stop_eh(struct usbip_device *ud) void usbip_stop_eh(struct usbip_device *ud)
{ {
if (ud->eh == current) unsigned long pending = ud->event & ~USBIP_EH_BYE;
return; /* do not wait for myself */
kthread_stop(ud->eh); if (!(ud->event & USBIP_EH_BYE))
usbip_dbg_eh("usbip_eh has finished\n"); usbip_dbg_eh("usbip_eh stopping but not removed\n");
if (pending)
usbip_dbg_eh("usbip_eh waiting completion %lx\n", pending);
wait_event_interruptible(ud->eh_waitq, !(ud->event & ~USBIP_EH_BYE));
usbip_dbg_eh("usbip_eh has stopped\n");
} }
EXPORT_SYMBOL_GPL(usbip_stop_eh); EXPORT_SYMBOL_GPL(usbip_stop_eh);
#define WORK_QUEUE_NAME "usbip_event"
static struct workqueue_struct *usbip_queue;
static DECLARE_WORK(usbip_work, event_handler);
int usbip_init_eh(void)
{
usbip_queue = create_singlethread_workqueue(WORK_QUEUE_NAME);
if (usbip_queue == NULL) {
pr_err("failed to create usbip_event\n");
return -ENOMEM;
}
return 0;
}
void usbip_finish_eh(void)
{
flush_workqueue(usbip_queue);
destroy_workqueue(usbip_queue);
usbip_queue = NULL;
}
void usbip_event_add(struct usbip_device *ud, unsigned long event) void usbip_event_add(struct usbip_device *ud, unsigned long event)
{ {
struct usbip_event *ue;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&ud->lock, flags); if (ud->event & USBIP_EH_BYE)
ud->event |= event; return;
wake_up(&ud->eh_waitq);
spin_unlock_irqrestore(&ud->lock, flags); set_event(ud, event);
spin_lock_irqsave(&event_lock, flags);
list_for_each_entry_reverse(ue, &event_list, node) {
if (ue->ud == ud)
goto out;
}
ue = kmalloc(sizeof(struct usbip_event), GFP_ATOMIC);
if (ue == NULL)
goto out;
ue->ud = ud;
list_add_tail(&ue->node, &event_list);
queue_work(usbip_queue, &usbip_work);
out:
spin_unlock_irqrestore(&event_lock, flags);
} }
EXPORT_SYMBOL_GPL(usbip_event_add); EXPORT_SYMBOL_GPL(usbip_event_add);
@ -127,3 +202,12 @@ int usbip_event_happened(struct usbip_device *ud)
return happened; return happened;
} }
EXPORT_SYMBOL_GPL(usbip_event_happened); EXPORT_SYMBOL_GPL(usbip_event_happened);
int usbip_in_eh(struct task_struct *task)
{
if (task == worker_context)
return 1;
return 0;
}
EXPORT_SYMBOL_GPL(usbip_in_eh);

View File

@ -893,7 +893,6 @@ out:
error_nodev: error_nodev:
return; return;
wusb_dev_sysfs_rm(wusb_dev);
error_add_sysfs: error_add_sysfs:
wusb_dev_bos_rm(wusb_dev); wusb_dev_bos_rm(wusb_dev);
error_bos_add: error_bos_add:

View File

@ -105,6 +105,13 @@
#define USB_REQ_LOOPBACK_DATA_READ 0x16 #define USB_REQ_LOOPBACK_DATA_READ 0x16
#define USB_REQ_SET_INTERFACE_DS 0x17 #define USB_REQ_SET_INTERFACE_DS 0x17
/* specific requests for USB Power Delivery */
#define USB_REQ_GET_PARTNER_PDO 20
#define USB_REQ_GET_BATTERY_STATUS 21
#define USB_REQ_SET_PDO 22
#define USB_REQ_GET_VDM 23
#define USB_REQ_SEND_VDM 24
/* The Link Power Management (LPM) ECN defines USB_REQ_TEST_AND_SET command, /* The Link Power Management (LPM) ECN defines USB_REQ_TEST_AND_SET command,
* used by hubs to put ports into a new L1 suspend state, except that it * used by hubs to put ports into a new L1 suspend state, except that it
* forgot to define its number ... * forgot to define its number ...
@ -165,6 +172,22 @@
#define USB_DEV_STAT_U2_ENABLED 3 /* transition into U2 state */ #define USB_DEV_STAT_U2_ENABLED 3 /* transition into U2 state */
#define USB_DEV_STAT_LTM_ENABLED 4 /* Latency tolerance messages */ #define USB_DEV_STAT_LTM_ENABLED 4 /* Latency tolerance messages */
/*
* Feature selectors from Table 9-8 USB Power Delivery spec
*/
#define USB_DEVICE_BATTERY_WAKE_MASK 40
#define USB_DEVICE_OS_IS_PD_AWARE 41
#define USB_DEVICE_POLICY_MODE 42
#define USB_PORT_PR_SWAP 43
#define USB_PORT_GOTO_MIN 44
#define USB_PORT_RETURN_POWER 45
#define USB_PORT_ACCEPT_PD_REQUEST 46
#define USB_PORT_REJECT_PD_REQUEST 47
#define USB_PORT_PORT_PD_RESET 48
#define USB_PORT_C_PORT_PD_CHANGE 49
#define USB_PORT_CABLE_PD_RESET 50
#define USB_DEVICE_CHARGING_POLICY 54
/** /**
* struct usb_ctrlrequest - SETUP data for a USB device control request * struct usb_ctrlrequest - SETUP data for a USB device control request
* @bRequestType: matches the USB bmRequestType field * @bRequestType: matches the USB bmRequestType field
@ -913,6 +936,104 @@ struct usb_ssp_cap_descriptor {
#define USB_SSP_SUBLINK_SPEED_LSM (0xff << 16) /* Lanespeed mantissa */ #define USB_SSP_SUBLINK_SPEED_LSM (0xff << 16) /* Lanespeed mantissa */
} __attribute__((packed)); } __attribute__((packed));
/*
* USB Power Delivery Capability Descriptor:
* Defines capabilities for PD
*/
/* Defines the various PD Capabilities of this device */
#define USB_PD_POWER_DELIVERY_CAPABILITY 0x06
/* Provides information on each battery supported by the device */
#define USB_PD_BATTERY_INFO_CAPABILITY 0x07
/* The Consumer characteristics of a Port on the device */
#define USB_PD_PD_CONSUMER_PORT_CAPABILITY 0x08
/* The provider characteristics of a Port on the device */
#define USB_PD_PD_PROVIDER_PORT_CAPABILITY 0x09
struct usb_pd_cap_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDevCapabilityType; /* set to USB_PD_POWER_DELIVERY_CAPABILITY */
__u8 bReserved;
__le32 bmAttributes;
#define USB_PD_CAP_BATTERY_CHARGING (1 << 1) /* supports Battery Charging specification */
#define USB_PD_CAP_USB_PD (1 << 2) /* supports USB Power Delivery specification */
#define USB_PD_CAP_PROVIDER (1 << 3) /* can provide power */
#define USB_PD_CAP_CONSUMER (1 << 4) /* can consume power */
#define USB_PD_CAP_CHARGING_POLICY (1 << 5) /* supports CHARGING_POLICY feature */
#define USB_PD_CAP_TYPE_C_CURRENT (1 << 6) /* supports power capabilities defined in the USB Type-C Specification */
#define USB_PD_CAP_PWR_AC (1 << 8)
#define USB_PD_CAP_PWR_BAT (1 << 9)
#define USB_PD_CAP_PWR_USE_V_BUS (1 << 14)
__le16 bmProviderPorts; /* Bit zero refers to the UFP of the device */
__le16 bmConsumerPorts;
__le16 bcdBCVersion;
__le16 bcdPDVersion;
__le16 bcdUSBTypeCVersion;
} __attribute__((packed));
struct usb_pd_cap_battery_info_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDevCapabilityType;
/* Index of string descriptor shall contain the user friendly name for this battery */
__u8 iBattery;
/* Index of string descriptor shall contain the Serial Number String for this battery */
__u8 iSerial;
__u8 iManufacturer;
__u8 bBatteryId; /* uniquely identifies this battery in status Messages */
__u8 bReserved;
/*
* Shall contain the Battery Charge value above which this
* battery is considered to be fully charged but not necessarily
* topped off.
*/
__le32 dwChargedThreshold; /* in mWh */
/*
* Shall contain the minimum charge level of this battery such
* that above this threshold, a device can be assured of being
* able to power up successfully (see Battery Charging 1.2).
*/
__le32 dwWeakThreshold; /* in mWh */
__le32 dwBatteryDesignCapacity; /* in mWh */
__le32 dwBatteryLastFullchargeCapacity; /* in mWh */
} __attribute__((packed));
struct usb_pd_cap_consumer_port_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDevCapabilityType;
__u8 bReserved;
__u8 bmCapabilities;
/* port will oerate under: */
#define USB_PD_CAP_CONSUMER_BC (1 << 0) /* BC */
#define USB_PD_CAP_CONSUMER_PD (1 << 1) /* PD */
#define USB_PD_CAP_CONSUMER_TYPE_C (1 << 2) /* USB Type-C Current */
__le16 wMinVoltage; /* in 50mV units */
__le16 wMaxVoltage; /* in 50mV units */
__u16 wReserved;
__le32 dwMaxOperatingPower; /* in 10 mW - operating at steady state */
__le32 dwMaxPeakPower; /* in 10mW units - operating at peak power */
__le32 dwMaxPeakPowerTime; /* in 100ms units - duration of peak */
#define USB_PD_CAP_CONSUMER_UNKNOWN_PEAK_POWER_TIME 0xffff
} __attribute__((packed));
struct usb_pd_cap_provider_port_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDevCapabilityType;
__u8 bReserved1;
__u8 bmCapabilities;
/* port will oerate under: */
#define USB_PD_CAP_PROVIDER_BC (1 << 0) /* BC */
#define USB_PD_CAP_PROVIDER_PD (1 << 1) /* PD */
#define USB_PD_CAP_PROVIDER_TYPE_C (1 << 2) /* USB Type-C Current */
__u8 bNumOfPDObjects;
__u8 bReserved2;
__le32 wPowerDataObject[];
} __attribute__((packed));
/* /*
* Precision time measurement capability descriptor: advertised by devices and * Precision time measurement capability descriptor: advertised by devices and
* hubs that support PTM * hubs that support PTM