Merge 5.3-rc4 into usb-next
We need the USB fixes in here as well. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
@@ -1843,8 +1843,6 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (as && as->usbm)
|
||||
dec_usb_memory_use_count(as->usbm, &as->usbm->urb_use_count);
|
||||
kfree(isopkt);
|
||||
kfree(dr);
|
||||
if (as)
|
||||
|
@@ -103,11 +103,6 @@ static DEFINE_SPINLOCK(hcd_urb_unlink_lock);
|
||||
/* wait queue for synchronous unlinks */
|
||||
DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue);
|
||||
|
||||
static inline int is_root_hub(struct usb_device *udev)
|
||||
{
|
||||
return (udev->parent == NULL);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
@@ -880,101 +875,6 @@ static int usb_rh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Show & store the current value of authorized_default
|
||||
*/
|
||||
static ssize_t authorized_default_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_device *rh_usb_dev = to_usb_device(dev);
|
||||
struct usb_bus *usb_bus = rh_usb_dev->bus;
|
||||
struct usb_hcd *hcd;
|
||||
|
||||
hcd = bus_to_hcd(usb_bus);
|
||||
return snprintf(buf, PAGE_SIZE, "%u\n", hcd->dev_policy);
|
||||
}
|
||||
|
||||
static ssize_t authorized_default_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
ssize_t result;
|
||||
unsigned val;
|
||||
struct usb_device *rh_usb_dev = to_usb_device(dev);
|
||||
struct usb_bus *usb_bus = rh_usb_dev->bus;
|
||||
struct usb_hcd *hcd;
|
||||
|
||||
hcd = bus_to_hcd(usb_bus);
|
||||
result = sscanf(buf, "%u\n", &val);
|
||||
if (result == 1) {
|
||||
hcd->dev_policy = val <= USB_DEVICE_AUTHORIZE_INTERNAL ?
|
||||
val : USB_DEVICE_AUTHORIZE_ALL;
|
||||
result = size;
|
||||
} else {
|
||||
result = -EINVAL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static DEVICE_ATTR_RW(authorized_default);
|
||||
|
||||
/*
|
||||
* interface_authorized_default_show - show default authorization status
|
||||
* for USB interfaces
|
||||
*
|
||||
* note: interface_authorized_default is the default value
|
||||
* for initializing the authorized attribute of interfaces
|
||||
*/
|
||||
static ssize_t interface_authorized_default_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_device *usb_dev = to_usb_device(dev);
|
||||
struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
|
||||
|
||||
return sprintf(buf, "%u\n", !!HCD_INTF_AUTHORIZED(hcd));
|
||||
}
|
||||
|
||||
/*
|
||||
* interface_authorized_default_store - store default authorization status
|
||||
* for USB interfaces
|
||||
*
|
||||
* note: interface_authorized_default is the default value
|
||||
* for initializing the authorized attribute of interfaces
|
||||
*/
|
||||
static ssize_t interface_authorized_default_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct usb_device *usb_dev = to_usb_device(dev);
|
||||
struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
|
||||
int rc = count;
|
||||
bool val;
|
||||
|
||||
if (strtobool(buf, &val) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (val)
|
||||
set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
|
||||
else
|
||||
clear_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
|
||||
|
||||
return rc;
|
||||
}
|
||||
static DEVICE_ATTR_RW(interface_authorized_default);
|
||||
|
||||
/* Group all the USB bus attributes */
|
||||
static struct attribute *usb_bus_attrs[] = {
|
||||
&dev_attr_authorized_default.attr,
|
||||
&dev_attr_interface_authorized_default.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct attribute_group usb_bus_attr_group = {
|
||||
.name = NULL, /* we want them in the same directory */
|
||||
.attrs = usb_bus_attrs,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
@@ -2894,32 +2794,11 @@ int usb_add_hcd(struct usb_hcd *hcd,
|
||||
if (retval != 0)
|
||||
goto err_register_root_hub;
|
||||
|
||||
retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group);
|
||||
if (retval < 0) {
|
||||
printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n",
|
||||
retval);
|
||||
goto error_create_attr_group;
|
||||
}
|
||||
if (hcd->uses_new_polling && HCD_POLL_RH(hcd))
|
||||
usb_hcd_poll_rh_status(hcd);
|
||||
|
||||
return retval;
|
||||
|
||||
error_create_attr_group:
|
||||
clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
|
||||
if (HC_IS_RUNNING(hcd->state))
|
||||
hcd->state = HC_STATE_QUIESCING;
|
||||
spin_lock_irq(&hcd_root_hub_lock);
|
||||
hcd->rh_registered = 0;
|
||||
spin_unlock_irq(&hcd_root_hub_lock);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
cancel_work_sync(&hcd->wakeup_work);
|
||||
#endif
|
||||
cancel_work_sync(&hcd->died_work);
|
||||
mutex_lock(&usb_bus_idr_lock);
|
||||
usb_disconnect(&rhdev); /* Sets rhdev to NULL */
|
||||
mutex_unlock(&usb_bus_idr_lock);
|
||||
err_register_root_hub:
|
||||
hcd->rh_pollable = 0;
|
||||
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
|
||||
@@ -2963,8 +2842,6 @@ void usb_remove_hcd(struct usb_hcd *hcd)
|
||||
dev_info(hcd->self.controller, "remove, state %x\n", hcd->state);
|
||||
|
||||
usb_get_dev(rhdev);
|
||||
sysfs_remove_group(&rhdev->dev.kobj, &usb_bus_attr_group);
|
||||
|
||||
clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
|
||||
if (HC_IS_RUNNING (hcd->state))
|
||||
hcd->state = HC_STATE_QUIESCING;
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/hcd.h>
|
||||
#include <linux/usb/quirks.h>
|
||||
#include <linux/of.h>
|
||||
#include "usb.h"
|
||||
@@ -922,6 +923,116 @@ static struct bin_attribute dev_bin_attr_descriptors = {
|
||||
.size = 18 + 65535, /* dev descr + max-size raw descriptor */
|
||||
};
|
||||
|
||||
/*
|
||||
* Show & store the current value of authorized_default
|
||||
*/
|
||||
static ssize_t authorized_default_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_device *rh_usb_dev = to_usb_device(dev);
|
||||
struct usb_bus *usb_bus = rh_usb_dev->bus;
|
||||
struct usb_hcd *hcd;
|
||||
|
||||
hcd = bus_to_hcd(usb_bus);
|
||||
return snprintf(buf, PAGE_SIZE, "%u\n", hcd->dev_policy);
|
||||
}
|
||||
|
||||
static ssize_t authorized_default_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
ssize_t result;
|
||||
unsigned int val;
|
||||
struct usb_device *rh_usb_dev = to_usb_device(dev);
|
||||
struct usb_bus *usb_bus = rh_usb_dev->bus;
|
||||
struct usb_hcd *hcd;
|
||||
|
||||
hcd = bus_to_hcd(usb_bus);
|
||||
result = sscanf(buf, "%u\n", &val);
|
||||
if (result == 1) {
|
||||
hcd->dev_policy = val <= USB_DEVICE_AUTHORIZE_INTERNAL ?
|
||||
val : USB_DEVICE_AUTHORIZE_ALL;
|
||||
result = size;
|
||||
} else {
|
||||
result = -EINVAL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static DEVICE_ATTR_RW(authorized_default);
|
||||
|
||||
/*
|
||||
* interface_authorized_default_show - show default authorization status
|
||||
* for USB interfaces
|
||||
*
|
||||
* note: interface_authorized_default is the default value
|
||||
* for initializing the authorized attribute of interfaces
|
||||
*/
|
||||
static ssize_t interface_authorized_default_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct usb_device *usb_dev = to_usb_device(dev);
|
||||
struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
|
||||
|
||||
return sprintf(buf, "%u\n", !!HCD_INTF_AUTHORIZED(hcd));
|
||||
}
|
||||
|
||||
/*
|
||||
* interface_authorized_default_store - store default authorization status
|
||||
* for USB interfaces
|
||||
*
|
||||
* note: interface_authorized_default is the default value
|
||||
* for initializing the authorized attribute of interfaces
|
||||
*/
|
||||
static ssize_t interface_authorized_default_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
struct usb_device *usb_dev = to_usb_device(dev);
|
||||
struct usb_hcd *hcd = bus_to_hcd(usb_dev->bus);
|
||||
int rc = count;
|
||||
bool val;
|
||||
|
||||
if (strtobool(buf, &val) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (val)
|
||||
set_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
|
||||
else
|
||||
clear_bit(HCD_FLAG_INTF_AUTHORIZED, &hcd->flags);
|
||||
|
||||
return rc;
|
||||
}
|
||||
static DEVICE_ATTR_RW(interface_authorized_default);
|
||||
|
||||
/* Group all the USB bus attributes */
|
||||
static struct attribute *usb_bus_attrs[] = {
|
||||
&dev_attr_authorized_default.attr,
|
||||
&dev_attr_interface_authorized_default.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const struct attribute_group usb_bus_attr_group = {
|
||||
.name = NULL, /* we want them in the same directory */
|
||||
.attrs = usb_bus_attrs,
|
||||
};
|
||||
|
||||
|
||||
static int add_default_authorized_attributes(struct device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (is_usb_device(dev))
|
||||
rc = sysfs_create_group(&dev->kobj, &usb_bus_attr_group);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void remove_default_authorized_attributes(struct device *dev)
|
||||
{
|
||||
if (is_usb_device(dev)) {
|
||||
sysfs_remove_group(&dev->kobj, &usb_bus_attr_group);
|
||||
}
|
||||
}
|
||||
|
||||
int usb_create_sysfs_dev_files(struct usb_device *udev)
|
||||
{
|
||||
struct device *dev = &udev->dev;
|
||||
@@ -938,7 +1049,14 @@ int usb_create_sysfs_dev_files(struct usb_device *udev)
|
||||
retval = add_power_attributes(dev);
|
||||
if (retval)
|
||||
goto error;
|
||||
|
||||
if (is_root_hub(udev)) {
|
||||
retval = add_default_authorized_attributes(dev);
|
||||
if (retval)
|
||||
goto error;
|
||||
}
|
||||
return retval;
|
||||
|
||||
error:
|
||||
usb_remove_sysfs_dev_files(udev);
|
||||
return retval;
|
||||
@@ -948,6 +1066,9 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev)
|
||||
{
|
||||
struct device *dev = &udev->dev;
|
||||
|
||||
if (is_root_hub(udev))
|
||||
remove_default_authorized_attributes(dev);
|
||||
|
||||
remove_power_attributes(dev);
|
||||
remove_persist_attributes(dev);
|
||||
device_remove_bin_file(dev, &dev_bin_attr_descriptors);
|
||||
|
@@ -156,6 +156,11 @@ static inline int is_usb_port(const struct device *dev)
|
||||
return dev->type == &usb_port_device_type;
|
||||
}
|
||||
|
||||
static inline int is_root_hub(struct usb_device *udev)
|
||||
{
|
||||
return (udev->parent == NULL);
|
||||
}
|
||||
|
||||
/* Do the same for device drivers and interface drivers. */
|
||||
|
||||
static inline int is_usb_device_driver(struct device_driver *drv)
|
||||
|
@@ -238,10 +238,15 @@ int xhci_rcar_init_quirk(struct usb_hcd *hcd)
|
||||
* pointers. So, this driver clears the AC64 bit of xhci->hcc_params
|
||||
* to call dma_set_coherent_mask(dev, DMA_BIT_MASK(32)) in
|
||||
* xhci_gen_setup().
|
||||
*
|
||||
* And, since the firmware/internal CPU control the USBSTS.STS_HALT
|
||||
* and the process speed is down when the roothub port enters U3,
|
||||
* long delay for the handshake of STS_HALT is neeed in xhci_suspend().
|
||||
*/
|
||||
if (xhci_rcar_is_gen2(hcd->self.controller) ||
|
||||
xhci_rcar_is_gen3(hcd->self.controller))
|
||||
xhci->quirks |= XHCI_NO_64BIT_SUPPORT;
|
||||
xhci_rcar_is_gen3(hcd->self.controller)) {
|
||||
xhci->quirks |= XHCI_NO_64BIT_SUPPORT | XHCI_SLOW_SUSPEND;
|
||||
}
|
||||
|
||||
if (!xhci_rcar_wait_for_pll_active(hcd))
|
||||
return -ETIMEDOUT;
|
||||
|
@@ -3089,8 +3089,18 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
|
||||
return;
|
||||
udev = (struct usb_device *) host_ep->hcpriv;
|
||||
vdev = xhci->devs[udev->slot_id];
|
||||
|
||||
/*
|
||||
* vdev may be lost due to xHC restore error and re-initialization
|
||||
* during S3/S4 resume. A new vdev will be allocated later by
|
||||
* xhci_discover_or_reset_device()
|
||||
*/
|
||||
if (!udev->slot_id || !vdev)
|
||||
return;
|
||||
ep_index = xhci_get_endpoint_index(&host_ep->desc);
|
||||
ep = &vdev->eps[ep_index];
|
||||
if (!ep)
|
||||
return;
|
||||
|
||||
/* Bail out if toggle is already being cleared by a endpoint reset */
|
||||
if (ep->ep_state & EP_HARD_CLEAR_TOGGLE) {
|
||||
|
@@ -866,19 +866,20 @@ static void iowarrior_disconnect(struct usb_interface *interface)
|
||||
dev = usb_get_intfdata(interface);
|
||||
mutex_lock(&iowarrior_open_disc_lock);
|
||||
usb_set_intfdata(interface, NULL);
|
||||
/* prevent device read, write and ioctl */
|
||||
dev->present = 0;
|
||||
|
||||
minor = dev->minor;
|
||||
mutex_unlock(&iowarrior_open_disc_lock);
|
||||
/* give back our minor - this will call close() locks need to be dropped at this point*/
|
||||
|
||||
/* give back our minor */
|
||||
usb_deregister_dev(interface, &iowarrior_class);
|
||||
|
||||
mutex_lock(&dev->mutex);
|
||||
|
||||
/* prevent device read, write and ioctl */
|
||||
dev->present = 0;
|
||||
|
||||
mutex_unlock(&dev->mutex);
|
||||
mutex_unlock(&iowarrior_open_disc_lock);
|
||||
|
||||
if (dev->opened) {
|
||||
/* There is a process that holds a filedescriptor to the device ,
|
||||
|
@@ -51,6 +51,7 @@ struct rio_usb_data {
|
||||
char *obuf, *ibuf; /* transfer buffers */
|
||||
char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */
|
||||
wait_queue_head_t wait_q; /* for timeouts */
|
||||
struct mutex lock; /* general race avoidance */
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(rio500_mutex);
|
||||
@@ -62,8 +63,10 @@ static int open_rio(struct inode *inode, struct file *file)
|
||||
|
||||
/* against disconnect() */
|
||||
mutex_lock(&rio500_mutex);
|
||||
mutex_lock(&(rio->lock));
|
||||
|
||||
if (rio->isopen || !rio->present) {
|
||||
mutex_unlock(&(rio->lock));
|
||||
mutex_unlock(&rio500_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
@@ -71,6 +74,7 @@ static int open_rio(struct inode *inode, struct file *file)
|
||||
|
||||
init_waitqueue_head(&rio->wait_q);
|
||||
|
||||
mutex_unlock(&(rio->lock));
|
||||
|
||||
dev_info(&rio->rio_dev->dev, "Rio opened.\n");
|
||||
mutex_unlock(&rio500_mutex);
|
||||
@@ -84,6 +88,7 @@ static int close_rio(struct inode *inode, struct file *file)
|
||||
|
||||
/* against disconnect() */
|
||||
mutex_lock(&rio500_mutex);
|
||||
mutex_lock(&(rio->lock));
|
||||
|
||||
rio->isopen = 0;
|
||||
if (!rio->present) {
|
||||
@@ -95,6 +100,7 @@ static int close_rio(struct inode *inode, struct file *file)
|
||||
} else {
|
||||
dev_info(&rio->rio_dev->dev, "Rio closed.\n");
|
||||
}
|
||||
mutex_unlock(&(rio->lock));
|
||||
mutex_unlock(&rio500_mutex);
|
||||
return 0;
|
||||
}
|
||||
@@ -109,7 +115,7 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
int retries;
|
||||
int retval=0;
|
||||
|
||||
mutex_lock(&rio500_mutex);
|
||||
mutex_lock(&(rio->lock));
|
||||
/* Sanity check to make sure rio is connected, powered, etc */
|
||||
if (rio->present == 0 || rio->rio_dev == NULL) {
|
||||
retval = -ENODEV;
|
||||
@@ -253,7 +259,7 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
|
||||
|
||||
err_out:
|
||||
mutex_unlock(&rio500_mutex);
|
||||
mutex_unlock(&(rio->lock));
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -273,12 +279,12 @@ write_rio(struct file *file, const char __user *buffer,
|
||||
int errn = 0;
|
||||
int intr;
|
||||
|
||||
intr = mutex_lock_interruptible(&rio500_mutex);
|
||||
intr = mutex_lock_interruptible(&(rio->lock));
|
||||
if (intr)
|
||||
return -EINTR;
|
||||
/* Sanity check to make sure rio is connected, powered, etc */
|
||||
if (rio->present == 0 || rio->rio_dev == NULL) {
|
||||
mutex_unlock(&rio500_mutex);
|
||||
mutex_unlock(&(rio->lock));
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -301,7 +307,7 @@ write_rio(struct file *file, const char __user *buffer,
|
||||
goto error;
|
||||
}
|
||||
if (signal_pending(current)) {
|
||||
mutex_unlock(&rio500_mutex);
|
||||
mutex_unlock(&(rio->lock));
|
||||
return bytes_written ? bytes_written : -EINTR;
|
||||
}
|
||||
|
||||
@@ -339,12 +345,12 @@ write_rio(struct file *file, const char __user *buffer,
|
||||
buffer += copy_size;
|
||||
} while (count > 0);
|
||||
|
||||
mutex_unlock(&rio500_mutex);
|
||||
mutex_unlock(&(rio->lock));
|
||||
|
||||
return bytes_written ? bytes_written : -EIO;
|
||||
|
||||
error:
|
||||
mutex_unlock(&rio500_mutex);
|
||||
mutex_unlock(&(rio->lock));
|
||||
return errn;
|
||||
}
|
||||
|
||||
@@ -361,12 +367,12 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
|
||||
char *ibuf;
|
||||
int intr;
|
||||
|
||||
intr = mutex_lock_interruptible(&rio500_mutex);
|
||||
intr = mutex_lock_interruptible(&(rio->lock));
|
||||
if (intr)
|
||||
return -EINTR;
|
||||
/* Sanity check to make sure rio is connected, powered, etc */
|
||||
if (rio->present == 0 || rio->rio_dev == NULL) {
|
||||
mutex_unlock(&rio500_mutex);
|
||||
mutex_unlock(&(rio->lock));
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -377,11 +383,11 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
|
||||
|
||||
while (count > 0) {
|
||||
if (signal_pending(current)) {
|
||||
mutex_unlock(&rio500_mutex);
|
||||
mutex_unlock(&(rio->lock));
|
||||
return read_count ? read_count : -EINTR;
|
||||
}
|
||||
if (!rio->rio_dev) {
|
||||
mutex_unlock(&rio500_mutex);
|
||||
mutex_unlock(&(rio->lock));
|
||||
return -ENODEV;
|
||||
}
|
||||
this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
|
||||
@@ -399,7 +405,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
|
||||
count = this_read = partial;
|
||||
} else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */
|
||||
if (!maxretry--) {
|
||||
mutex_unlock(&rio500_mutex);
|
||||
mutex_unlock(&(rio->lock));
|
||||
dev_err(&rio->rio_dev->dev,
|
||||
"read_rio: maxretry timeout\n");
|
||||
return -ETIME;
|
||||
@@ -409,19 +415,19 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
|
||||
finish_wait(&rio->wait_q, &wait);
|
||||
continue;
|
||||
} else if (result != -EREMOTEIO) {
|
||||
mutex_unlock(&rio500_mutex);
|
||||
mutex_unlock(&(rio->lock));
|
||||
dev_err(&rio->rio_dev->dev,
|
||||
"Read Whoops - result:%d partial:%u this_read:%u\n",
|
||||
result, partial, this_read);
|
||||
return -EIO;
|
||||
} else {
|
||||
mutex_unlock(&rio500_mutex);
|
||||
mutex_unlock(&(rio->lock));
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (this_read) {
|
||||
if (copy_to_user(buffer, ibuf, this_read)) {
|
||||
mutex_unlock(&rio500_mutex);
|
||||
mutex_unlock(&(rio->lock));
|
||||
return -EFAULT;
|
||||
}
|
||||
count -= this_read;
|
||||
@@ -429,7 +435,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
|
||||
buffer += this_read;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&rio500_mutex);
|
||||
mutex_unlock(&(rio->lock));
|
||||
return read_count;
|
||||
}
|
||||
|
||||
@@ -494,6 +500,8 @@ static int probe_rio(struct usb_interface *intf,
|
||||
}
|
||||
dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf);
|
||||
|
||||
mutex_init(&(rio->lock));
|
||||
|
||||
usb_set_intfdata (intf, rio);
|
||||
rio->present = 1;
|
||||
bail_out:
|
||||
@@ -511,10 +519,12 @@ static void disconnect_rio(struct usb_interface *intf)
|
||||
if (rio) {
|
||||
usb_deregister_dev(intf, &usb_rio_class);
|
||||
|
||||
mutex_lock(&(rio->lock));
|
||||
if (rio->isopen) {
|
||||
rio->isopen = 0;
|
||||
/* better let it finish - the release will do whats needed */
|
||||
rio->rio_dev = NULL;
|
||||
mutex_unlock(&(rio->lock));
|
||||
mutex_unlock(&rio500_mutex);
|
||||
return;
|
||||
}
|
||||
@@ -524,6 +534,7 @@ static void disconnect_rio(struct usb_interface *intf)
|
||||
dev_info(&intf->dev, "USB Rio disconnected.\n");
|
||||
|
||||
rio->present = 0;
|
||||
mutex_unlock(&(rio->lock));
|
||||
}
|
||||
mutex_unlock(&rio500_mutex);
|
||||
}
|
||||
|
@@ -92,7 +92,6 @@ static void yurex_delete(struct kref *kref)
|
||||
|
||||
dev_dbg(&dev->interface->dev, "%s\n", __func__);
|
||||
|
||||
usb_put_dev(dev->udev);
|
||||
if (dev->cntl_urb) {
|
||||
usb_kill_urb(dev->cntl_urb);
|
||||
kfree(dev->cntl_req);
|
||||
@@ -108,6 +107,7 @@ static void yurex_delete(struct kref *kref)
|
||||
dev->int_buffer, dev->urb->transfer_dma);
|
||||
usb_free_urb(dev->urb);
|
||||
}
|
||||
usb_put_dev(dev->udev);
|
||||
kfree(dev);
|
||||
}
|
||||
|
||||
|
@@ -379,7 +379,8 @@ static enum tcpm_state tcpm_default_state(struct tcpm_port *port)
|
||||
return SNK_UNATTACHED;
|
||||
else if (port->try_role == TYPEC_SOURCE)
|
||||
return SRC_UNATTACHED;
|
||||
else if (port->tcpc->config->default_role == TYPEC_SINK)
|
||||
else if (port->tcpc->config &&
|
||||
port->tcpc->config->default_role == TYPEC_SINK)
|
||||
return SNK_UNATTACHED;
|
||||
/* Fall through to return SRC_UNATTACHED */
|
||||
} else if (port->port_type == TYPEC_PORT_SNK) {
|
||||
@@ -586,7 +587,20 @@ static void tcpm_debugfs_init(struct tcpm_port *port)
|
||||
|
||||
static void tcpm_debugfs_exit(struct tcpm_port *port)
|
||||
{
|
||||
int i;
|
||||
|
||||
mutex_lock(&port->logbuffer_lock);
|
||||
for (i = 0; i < LOG_BUFFER_ENTRIES; i++) {
|
||||
kfree(port->logbuffer[i]);
|
||||
port->logbuffer[i] = NULL;
|
||||
}
|
||||
mutex_unlock(&port->logbuffer_lock);
|
||||
|
||||
debugfs_remove(port->dentry);
|
||||
if (list_empty(&rootdir->d_subdirs)) {
|
||||
debugfs_remove(rootdir);
|
||||
rootdir = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -1095,7 +1109,8 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt,
|
||||
break;
|
||||
case CMD_ATTENTION:
|
||||
/* Attention command does not have response */
|
||||
typec_altmode_attention(adev, p[1]);
|
||||
if (adev)
|
||||
typec_altmode_attention(adev, p[1]);
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
@@ -1147,20 +1162,26 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt,
|
||||
}
|
||||
break;
|
||||
case CMD_ENTER_MODE:
|
||||
typec_altmode_update_active(pdev, true);
|
||||
if (adev && pdev) {
|
||||
typec_altmode_update_active(pdev, true);
|
||||
|
||||
if (typec_altmode_vdm(adev, p[0], &p[1], cnt)) {
|
||||
response[0] = VDO(adev->svid, 1, CMD_EXIT_MODE);
|
||||
response[0] |= VDO_OPOS(adev->mode);
|
||||
return 1;
|
||||
if (typec_altmode_vdm(adev, p[0], &p[1], cnt)) {
|
||||
response[0] = VDO(adev->svid, 1,
|
||||
CMD_EXIT_MODE);
|
||||
response[0] |= VDO_OPOS(adev->mode);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
case CMD_EXIT_MODE:
|
||||
typec_altmode_update_active(pdev, false);
|
||||
if (adev && pdev) {
|
||||
typec_altmode_update_active(pdev, false);
|
||||
|
||||
/* Back to USB Operation */
|
||||
WARN_ON(typec_altmode_notify(adev, TYPEC_STATE_USB,
|
||||
NULL));
|
||||
/* Back to USB Operation */
|
||||
WARN_ON(typec_altmode_notify(adev,
|
||||
TYPEC_STATE_USB,
|
||||
NULL));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1170,8 +1191,10 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt,
|
||||
switch (cmd) {
|
||||
case CMD_ENTER_MODE:
|
||||
/* Back to USB Operation */
|
||||
WARN_ON(typec_altmode_notify(adev, TYPEC_STATE_USB,
|
||||
NULL));
|
||||
if (adev)
|
||||
WARN_ON(typec_altmode_notify(adev,
|
||||
TYPEC_STATE_USB,
|
||||
NULL));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1182,7 +1205,8 @@ static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt,
|
||||
}
|
||||
|
||||
/* Informing the alternate mode drivers about everything */
|
||||
typec_altmode_vdm(adev, p[0], &p[1], cnt);
|
||||
if (adev)
|
||||
typec_altmode_vdm(adev, p[0], &p[1], cnt);
|
||||
|
||||
return rlen;
|
||||
}
|
||||
@@ -4114,7 +4138,7 @@ static int tcpm_try_role(const struct typec_capability *cap, int role)
|
||||
mutex_lock(&port->lock);
|
||||
if (tcpc->try_role)
|
||||
ret = tcpc->try_role(tcpc, role);
|
||||
if (!ret && !tcpc->config->try_role_hw)
|
||||
if (!ret && (!tcpc->config || !tcpc->config->try_role_hw))
|
||||
port->try_role = role;
|
||||
port->try_src_count = 0;
|
||||
port->try_snk_count = 0;
|
||||
@@ -4699,7 +4723,7 @@ static int tcpm_copy_caps(struct tcpm_port *port,
|
||||
port->typec_caps.prefer_role = tcfg->default_role;
|
||||
port->typec_caps.type = tcfg->type;
|
||||
port->typec_caps.data = tcfg->data;
|
||||
port->self_powered = port->tcpc->config->self_powered;
|
||||
port->self_powered = tcfg->self_powered;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1018,7 +1018,7 @@ release_fw:
|
||||
******************************************************************************/
|
||||
static int ccg_fw_update(struct ucsi_ccg *uc, enum enum_flash_mode flash_mode)
|
||||
{
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
while (flash_mode != FLASH_NOT_NEEDED) {
|
||||
err = do_flash(uc, flash_mode);
|
||||
|
Reference in New Issue
Block a user