mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
Merge tag 'v4.9.251' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into odroidg12-4.9.y
This is the 4.9.251 stable release Change-Id: I46d3e088d6b63324528986a8ff1d8e026fea5362
This commit is contained in:
4
Makefile
4
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 250
|
||||
SUBLEVEL = 251
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
@@ -350,7 +350,7 @@ OBJDUMP = $(CROSS_COMPILE)objdump
|
||||
AWK = awk
|
||||
GENKSYMS = scripts/genksyms/genksyms
|
||||
INSTALLKERNEL := installkernel
|
||||
DEPMOD = /sbin/depmod
|
||||
DEPMOD = depmod
|
||||
PERL = perl
|
||||
PYTHON = python
|
||||
CHECK = sparse
|
||||
|
||||
@@ -166,9 +166,6 @@ static u8 mtrr_type_lookup_variable(u64 start, u64 end, u64 *partial_end,
|
||||
*repeat = 0;
|
||||
*uniform = 1;
|
||||
|
||||
/* Make end inclusive instead of exclusive */
|
||||
end--;
|
||||
|
||||
prev_match = MTRR_TYPE_INVALID;
|
||||
for (i = 0; i < num_var_ranges; ++i) {
|
||||
unsigned short start_state, end_state, inclusive;
|
||||
@@ -260,6 +257,9 @@ u8 mtrr_type_lookup(u64 start, u64 end, u8 *uniform)
|
||||
int repeat;
|
||||
u64 partial_end;
|
||||
|
||||
/* Make end inclusive instead of exclusive */
|
||||
end--;
|
||||
|
||||
if (!mtrr_state_set)
|
||||
return MTRR_TYPE_INVALID;
|
||||
|
||||
|
||||
@@ -697,6 +697,8 @@ int pud_free_pmd_page(pud_t *pud, unsigned long addr)
|
||||
}
|
||||
|
||||
free_page((unsigned long)pmd_sv);
|
||||
|
||||
pgtable_pmd_page_dtor(virt_to_page(pmd));
|
||||
free_page((unsigned long)pmd);
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -3615,7 +3615,7 @@ static int idt77252_init_one(struct pci_dev *pcidev,
|
||||
|
||||
if ((err = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32)))) {
|
||||
printk("idt77252: can't enable DMA for PCI device at %s\n", pci_name(pcidev));
|
||||
return err;
|
||||
goto err_out_disable_pdev;
|
||||
}
|
||||
|
||||
card = kzalloc(sizeof(struct idt77252_dev), GFP_KERNEL);
|
||||
|
||||
@@ -2364,7 +2364,7 @@ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
|
||||
if (fwnode_is_primary(fn)) {
|
||||
dev->fwnode = fn->secondary;
|
||||
if (!(parent && fn == parent->fwnode))
|
||||
fn->secondary = ERR_PTR(-ENODEV);
|
||||
fn->secondary = NULL;
|
||||
} else {
|
||||
dev->fwnode = NULL;
|
||||
}
|
||||
|
||||
@@ -1190,7 +1190,7 @@ static int ethoc_probe(struct platform_device *pdev)
|
||||
ret = mdiobus_register(priv->mdio);
|
||||
if (ret) {
|
||||
dev_err(&netdev->dev, "failed to register MDIO bus\n");
|
||||
goto free2;
|
||||
goto free3;
|
||||
}
|
||||
|
||||
ret = ethoc_mdio_probe(netdev);
|
||||
@@ -1222,6 +1222,7 @@ error2:
|
||||
netif_napi_del(&priv->napi);
|
||||
error:
|
||||
mdiobus_unregister(priv->mdio);
|
||||
free3:
|
||||
mdiobus_free(priv->mdio);
|
||||
free2:
|
||||
if (priv->clk)
|
||||
|
||||
@@ -3939,12 +3939,12 @@ static int ucc_geth_remove(struct platform_device* ofdev)
|
||||
struct device_node *np = ofdev->dev.of_node;
|
||||
|
||||
unregister_netdev(dev);
|
||||
free_netdev(dev);
|
||||
ucc_geth_memclean(ugeth);
|
||||
if (of_phy_is_fixed_link(np))
|
||||
of_phy_deregister_fixed_link(np);
|
||||
of_node_put(ugeth->ug_info->tbi_node);
|
||||
of_node_put(ugeth->ug_info->phy_node);
|
||||
free_netdev(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -447,6 +447,10 @@ static void __lb_other_process(struct hns_nic_ring_data *ring_data,
|
||||
/* for mutl buffer*/
|
||||
new_skb = skb_copy(skb, GFP_ATOMIC);
|
||||
dev_kfree_skb_any(skb);
|
||||
if (!new_skb) {
|
||||
netdev_err(ndev, "skb alloc failed\n");
|
||||
return;
|
||||
}
|
||||
skb = new_skb;
|
||||
|
||||
check_ok = 0;
|
||||
|
||||
@@ -1602,9 +1602,6 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
|
||||
* USB_CDC_NOTIFY_NETWORK_CONNECTION notification shall be
|
||||
* sent by device after USB_CDC_NOTIFY_SPEED_CHANGE.
|
||||
*/
|
||||
netif_info(dev, link, dev->net,
|
||||
"network connection: %sconnected\n",
|
||||
!!event->wValue ? "" : "dis");
|
||||
usbnet_link_change(dev, !!event->wValue, 0);
|
||||
break;
|
||||
|
||||
|
||||
@@ -1357,14 +1357,16 @@ static int virtnet_set_channels(struct net_device *dev,
|
||||
|
||||
get_online_cpus();
|
||||
err = virtnet_set_queues(vi, queue_pairs);
|
||||
if (!err) {
|
||||
netif_set_real_num_tx_queues(dev, queue_pairs);
|
||||
netif_set_real_num_rx_queues(dev, queue_pairs);
|
||||
|
||||
virtnet_set_affinity(vi);
|
||||
if (err) {
|
||||
put_online_cpus();
|
||||
goto err;
|
||||
}
|
||||
virtnet_set_affinity(vi);
|
||||
put_online_cpus();
|
||||
|
||||
netif_set_real_num_tx_queues(dev, queue_pairs);
|
||||
netif_set_real_num_rx_queues(dev, queue_pairs);
|
||||
err:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -572,6 +572,13 @@ static void ppp_timer(unsigned long arg)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ppp->lock, flags);
|
||||
/* mod_timer could be called after we entered this function but
|
||||
* before we got the lock.
|
||||
*/
|
||||
if (timer_pending(&proto->timer)) {
|
||||
spin_unlock_irqrestore(&ppp->lock, flags);
|
||||
return;
|
||||
}
|
||||
switch (proto->state) {
|
||||
case STOPPING:
|
||||
case REQ_SENT:
|
||||
|
||||
@@ -133,9 +133,13 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
|
||||
misc_pdev = of_find_device_by_node(args.np);
|
||||
of_node_put(args.np);
|
||||
|
||||
if (!misc_pdev || !platform_get_drvdata(misc_pdev))
|
||||
if (!misc_pdev)
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
|
||||
if (!platform_get_drvdata(misc_pdev)) {
|
||||
put_device(&misc_pdev->dev);
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
}
|
||||
data->dev = &misc_pdev->dev;
|
||||
|
||||
if (of_find_property(np, "disable-over-current", NULL))
|
||||
|
||||
@@ -1849,6 +1849,10 @@ static const struct usb_device_id acm_ids[] = {
|
||||
{ USB_DEVICE(0x04d8, 0x0083), /* Bootloader mode */
|
||||
.driver_info = IGNORE_DEVICE,
|
||||
},
|
||||
|
||||
{ USB_DEVICE(0x04d8, 0xf58b),
|
||||
.driver_info = IGNORE_DEVICE,
|
||||
},
|
||||
#endif
|
||||
|
||||
/*Samsung phone in firmware update mode */
|
||||
|
||||
@@ -289,8 +289,25 @@ static int usblp_ctrl_msg(struct usblp *usblp, int request, int type, int dir, i
|
||||
#define usblp_reset(usblp)\
|
||||
usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_TYPE_CLASS, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0)
|
||||
|
||||
#define usblp_hp_channel_change_request(usblp, channel, buffer) \
|
||||
usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, channel, buffer, 1)
|
||||
static int usblp_hp_channel_change_request(struct usblp *usblp, int channel, u8 *new_channel)
|
||||
{
|
||||
u8 *buf;
|
||||
int ret;
|
||||
|
||||
buf = kzalloc(1, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST,
|
||||
USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE,
|
||||
channel, buf, 1);
|
||||
if (ret == 0)
|
||||
*new_channel = buf[0];
|
||||
|
||||
kfree(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* See the description for usblp_select_alts() below for the usage
|
||||
|
||||
@@ -270,6 +270,7 @@ config USB_CONFIGFS_NCM
|
||||
depends on NET
|
||||
select USB_U_ETHER
|
||||
select USB_F_NCM
|
||||
select CRC32
|
||||
help
|
||||
NCM is an advanced protocol for Ethernet encapsulation, allows
|
||||
grouping of several ethernet frames into one USB transfer and
|
||||
@@ -319,6 +320,7 @@ config USB_CONFIGFS_EEM
|
||||
depends on NET
|
||||
select USB_U_ETHER
|
||||
select USB_F_EEM
|
||||
select CRC32
|
||||
help
|
||||
CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM
|
||||
and therefore can be supported by more hardware. Technically ECM and
|
||||
|
||||
@@ -392,8 +392,11 @@ int usb_function_deactivate(struct usb_function *function)
|
||||
|
||||
spin_lock_irqsave(&cdev->lock, flags);
|
||||
|
||||
if (cdev->deactivations == 0)
|
||||
if (cdev->deactivations == 0) {
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
status = usb_gadget_deactivate(cdev->gadget);
|
||||
spin_lock_irqsave(&cdev->lock, flags);
|
||||
}
|
||||
if (status == 0)
|
||||
cdev->deactivations++;
|
||||
|
||||
@@ -424,8 +427,11 @@ int usb_function_activate(struct usb_function *function)
|
||||
status = -EINVAL;
|
||||
else {
|
||||
cdev->deactivations--;
|
||||
if (cdev->deactivations == 0)
|
||||
if (cdev->deactivations == 0) {
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
status = usb_gadget_activate(cdev->gadget);
|
||||
spin_lock_irqsave(&cdev->lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&cdev->lock, flags);
|
||||
|
||||
@@ -290,9 +290,16 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item,
|
||||
|
||||
static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page)
|
||||
{
|
||||
char *udc_name = to_gadget_info(item)->composite.gadget_driver.udc_name;
|
||||
struct gadget_info *gi = to_gadget_info(item);
|
||||
char *udc_name;
|
||||
int ret;
|
||||
|
||||
return sprintf(page, "%s\n", udc_name ?: "");
|
||||
mutex_lock(&gi->lock);
|
||||
udc_name = gi->composite.gadget_driver.udc_name;
|
||||
ret = sprintf(page, "%s\n", udc_name ?: "");
|
||||
mutex_unlock(&gi->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int unregister_gadget(struct gadget_info *gi)
|
||||
@@ -1272,9 +1279,9 @@ static void purge_configs_funcs(struct gadget_info *gi)
|
||||
|
||||
cfg = container_of(c, struct config_usb_cfg, c);
|
||||
|
||||
list_for_each_entry_safe(f, tmp, &c->functions, list) {
|
||||
list_for_each_entry_safe_reverse(f, tmp, &c->functions, list) {
|
||||
|
||||
list_move_tail(&f->list, &cfg->func_list);
|
||||
list_move(&f->list, &cfg->func_list);
|
||||
if (f->unbind) {
|
||||
dev_dbg(&gi->cdev.gadget->dev,
|
||||
"unbind function '%s'/%p\n",
|
||||
@@ -1630,7 +1637,7 @@ static const struct usb_gadget_driver configfs_driver_template = {
|
||||
.suspend = configfs_composite_suspend,
|
||||
.resume = configfs_composite_resume,
|
||||
|
||||
.max_speed = USB_SPEED_SUPER,
|
||||
.max_speed = USB_SPEED_SUPER_PLUS,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "configfs-gadget",
|
||||
@@ -1753,7 +1760,7 @@ static struct config_group *gadgets_make(
|
||||
gi->composite.unbind = configfs_do_nothing;
|
||||
gi->composite.suspend = NULL;
|
||||
gi->composite.resume = NULL;
|
||||
gi->composite.max_speed = USB_SPEED_SUPER;
|
||||
gi->composite.max_speed = USB_SPEED_SUPER_PLUS;
|
||||
|
||||
spin_lock_init(&gi->spinlock);
|
||||
mutex_init(&gi->lock);
|
||||
|
||||
@@ -1120,6 +1120,7 @@ fail_tx_reqs:
|
||||
printer_req_free(dev->in_ep, req);
|
||||
}
|
||||
|
||||
usb_free_all_descriptors(f);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
@@ -766,7 +766,7 @@ static struct usb_endpoint_descriptor fs_epout_desc = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_OUT,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
|
||||
.wMaxPacketSize = cpu_to_le16(1023),
|
||||
/* .wMaxPacketSize = DYNAMIC */
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
@@ -775,7 +775,7 @@ static struct usb_endpoint_descriptor hs_epout_desc = {
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
/* .wMaxPacketSize = DYNAMIC */
|
||||
.bInterval = 4,
|
||||
};
|
||||
|
||||
@@ -843,7 +843,7 @@ static struct usb_endpoint_descriptor fs_epin_desc = {
|
||||
|
||||
.bEndpointAddress = USB_DIR_IN,
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
|
||||
.wMaxPacketSize = cpu_to_le16(1023),
|
||||
/* .wMaxPacketSize = DYNAMIC */
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
@@ -852,7 +852,7 @@ static struct usb_endpoint_descriptor hs_epin_desc = {
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
|
||||
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
|
||||
.wMaxPacketSize = cpu_to_le16(1024),
|
||||
/* .wMaxPacketSize = DYNAMIC */
|
||||
.bInterval = 4,
|
||||
};
|
||||
|
||||
@@ -963,12 +963,28 @@ free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep)
|
||||
"%s:%d Error!\n", __func__, __LINE__);
|
||||
}
|
||||
|
||||
static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
|
||||
static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
|
||||
struct usb_endpoint_descriptor *ep_desc,
|
||||
unsigned int factor, bool is_playback)
|
||||
enum usb_device_speed speed, bool is_playback)
|
||||
{
|
||||
int chmask, srate, ssize;
|
||||
u16 max_packet_size;
|
||||
u16 max_size_bw, max_size_ep;
|
||||
unsigned int factor;
|
||||
|
||||
switch (speed) {
|
||||
case USB_SPEED_FULL:
|
||||
max_size_ep = 1023;
|
||||
factor = 1000;
|
||||
break;
|
||||
|
||||
case USB_SPEED_HIGH:
|
||||
max_size_ep = 1024;
|
||||
factor = 8000;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (is_playback) {
|
||||
chmask = uac2_opts->p_chmask;
|
||||
@@ -980,10 +996,12 @@ static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
|
||||
ssize = uac2_opts->c_ssize;
|
||||
}
|
||||
|
||||
max_packet_size = num_channels(chmask) * ssize *
|
||||
max_size_bw = num_channels(chmask) * ssize *
|
||||
DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)));
|
||||
ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size,
|
||||
le16_to_cpu(ep_desc->wMaxPacketSize)));
|
||||
ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw,
|
||||
max_size_ep));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1082,10 +1100,33 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
|
||||
uac2->c_prm.uac2 = uac2;
|
||||
|
||||
/* Calculate wMaxPacketSize according to audio bandwidth */
|
||||
set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true);
|
||||
set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false);
|
||||
set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true);
|
||||
set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false);
|
||||
ret = set_ep_max_packet_size(uac2_opts, &fs_epin_desc, USB_SPEED_FULL,
|
||||
true);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = set_ep_max_packet_size(uac2_opts, &fs_epout_desc, USB_SPEED_FULL,
|
||||
false);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = set_ep_max_packet_size(uac2_opts, &hs_epin_desc, USB_SPEED_HIGH,
|
||||
true);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = set_ep_max_packet_size(uac2_opts, &hs_epout_desc, USB_SPEED_HIGH,
|
||||
false);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
|
||||
hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
|
||||
|
||||
@@ -207,8 +207,10 @@ static int acm_ms_bind(struct usb_composite_dev *cdev)
|
||||
struct usb_descriptor_header *usb_desc;
|
||||
|
||||
usb_desc = usb_otg_descriptor_alloc(gadget);
|
||||
if (!usb_desc)
|
||||
if (!usb_desc) {
|
||||
status = -ENOMEM;
|
||||
goto fail_string_ids;
|
||||
}
|
||||
usb_otg_descriptor_init(gadget, usb_desc);
|
||||
otg_desc[0] = usb_desc;
|
||||
otg_desc[1] = NULL;
|
||||
|
||||
@@ -4462,19 +4462,19 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci,
|
||||
{
|
||||
unsigned long long timeout_ns;
|
||||
|
||||
/* Prevent U1 if service interval is shorter than U1 exit latency */
|
||||
if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) {
|
||||
if (xhci_service_interval_to_ns(desc) <= udev->u1_params.mel) {
|
||||
dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n");
|
||||
return USB3_LPM_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
if (xhci->quirks & XHCI_INTEL_HOST)
|
||||
timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc);
|
||||
else
|
||||
timeout_ns = udev->u1_params.sel;
|
||||
|
||||
/* Prevent U1 if service interval is shorter than U1 exit latency */
|
||||
if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) {
|
||||
if (xhci_service_interval_to_ns(desc) <= timeout_ns) {
|
||||
dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n");
|
||||
return USB3_LPM_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
/* The U1 timeout is encoded in 1us intervals.
|
||||
* Don't return a timeout of zero, because that's USB3_LPM_DISABLED.
|
||||
*/
|
||||
@@ -4526,19 +4526,19 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci,
|
||||
{
|
||||
unsigned long long timeout_ns;
|
||||
|
||||
/* Prevent U2 if service interval is shorter than U2 exit latency */
|
||||
if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) {
|
||||
if (xhci_service_interval_to_ns(desc) <= udev->u2_params.mel) {
|
||||
dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n");
|
||||
return USB3_LPM_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
if (xhci->quirks & XHCI_INTEL_HOST)
|
||||
timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc);
|
||||
else
|
||||
timeout_ns = udev->u2_params.sel;
|
||||
|
||||
/* Prevent U2 if service interval is shorter than U2 exit latency */
|
||||
if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) {
|
||||
if (xhci_service_interval_to_ns(desc) <= timeout_ns) {
|
||||
dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n");
|
||||
return USB3_LPM_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
/* The U2 timeout is encoded in 256us intervals */
|
||||
timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000);
|
||||
/* If the necessary timeout value is bigger than what we can set in the
|
||||
|
||||
@@ -507,6 +507,9 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer,
|
||||
timeout = schedule_timeout(YUREX_WRITE_TIMEOUT);
|
||||
finish_wait(&dev->waitq, &wait);
|
||||
|
||||
/* make sure URB is idle after timeout or (spurious) CMD_ACK */
|
||||
usb_kill_urb(dev->cntl_urb);
|
||||
|
||||
mutex_unlock(&dev->io_mutex);
|
||||
|
||||
if (retval < 0) {
|
||||
|
||||
@@ -553,23 +553,29 @@ static int iuu_uart_flush(struct usb_serial_port *port)
|
||||
struct device *dev = &port->dev;
|
||||
int i;
|
||||
int status;
|
||||
u8 rxcmd = IUU_UART_RX;
|
||||
u8 *rxcmd;
|
||||
struct iuu_private *priv = usb_get_serial_port_data(port);
|
||||
|
||||
if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0)
|
||||
return -EIO;
|
||||
|
||||
rxcmd = kmalloc(1, GFP_KERNEL);
|
||||
if (!rxcmd)
|
||||
return -ENOMEM;
|
||||
|
||||
rxcmd[0] = IUU_UART_RX;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
status = bulk_immediate(port, &rxcmd, 1);
|
||||
status = bulk_immediate(port, rxcmd, 1);
|
||||
if (status != IUU_OPERATION_OK) {
|
||||
dev_dbg(dev, "%s - uart_flush_write error\n", __func__);
|
||||
return status;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
status = read_immediate(port, &priv->len, 1);
|
||||
if (status != IUU_OPERATION_OK) {
|
||||
dev_dbg(dev, "%s - uart_flush_read error\n", __func__);
|
||||
return status;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (priv->len > 0) {
|
||||
@@ -577,12 +583,16 @@ static int iuu_uart_flush(struct usb_serial_port *port)
|
||||
status = read_immediate(port, priv->buf, priv->len);
|
||||
if (status != IUU_OPERATION_OK) {
|
||||
dev_dbg(dev, "%s - uart_flush_read error\n", __func__);
|
||||
return status;
|
||||
goto out_free;
|
||||
}
|
||||
}
|
||||
}
|
||||
dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__);
|
||||
iuu_led(port, 0, 0xF000, 0, 0xFF);
|
||||
|
||||
out_free:
|
||||
kfree(rxcmd);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -559,10 +559,8 @@ exit:
|
||||
static void keyspan_pda_write_bulk_callback(struct urb *urb)
|
||||
{
|
||||
struct usb_serial_port *port = urb->context;
|
||||
struct keyspan_pda_private *priv;
|
||||
|
||||
set_bit(0, &port->write_urbs_free);
|
||||
priv = usb_get_serial_port_data(port);
|
||||
|
||||
/* queue up a wakeup at scheduler time */
|
||||
usb_serial_port_softint(port);
|
||||
|
||||
@@ -2043,6 +2043,7 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */
|
||||
.driver_info = RSVD(6) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */
|
||||
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */
|
||||
|
||||
@@ -163,6 +163,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999,
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_BROKEN_FUA),
|
||||
|
||||
/* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */
|
||||
UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999,
|
||||
"PNY",
|
||||
"Pro Elite SSD",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_NO_ATA_1X),
|
||||
|
||||
/* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */
|
||||
UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999,
|
||||
"PNY",
|
||||
|
||||
@@ -377,6 +377,7 @@ static void handle_tx(struct vhost_net *net)
|
||||
size_t hdr_size;
|
||||
struct socket *sock;
|
||||
struct vhost_net_ubuf_ref *uninitialized_var(ubufs);
|
||||
struct ubuf_info *ubuf;
|
||||
bool zcopy, zcopy_used;
|
||||
int sent_pkts = 0;
|
||||
|
||||
@@ -444,9 +445,7 @@ static void handle_tx(struct vhost_net *net)
|
||||
|
||||
/* use msg_control to pass vhost zerocopy ubuf info to skb */
|
||||
if (zcopy_used) {
|
||||
struct ubuf_info *ubuf;
|
||||
ubuf = nvq->ubuf_info + nvq->upend_idx;
|
||||
|
||||
vq->heads[nvq->upend_idx].id = cpu_to_vhost32(vq, head);
|
||||
vq->heads[nvq->upend_idx].len = VHOST_DMA_IN_PROGRESS;
|
||||
ubuf->callback = vhost_zerocopy_callback;
|
||||
@@ -465,7 +464,8 @@ static void handle_tx(struct vhost_net *net)
|
||||
err = sock->ops->sendmsg(sock, &msg, len);
|
||||
if (unlikely(err < 0)) {
|
||||
if (zcopy_used) {
|
||||
vhost_net_ubuf_put(ubufs);
|
||||
if (vq->heads[ubuf->desc].len == VHOST_DMA_IN_PROGRESS)
|
||||
vhost_net_ubuf_put(ubufs);
|
||||
nvq->upend_idx = ((unsigned)nvq->upend_idx - 1)
|
||||
% UIO_MAXIOV;
|
||||
}
|
||||
|
||||
@@ -713,11 +713,9 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
|
||||
}
|
||||
|
||||
/*
|
||||
* Map the VRAM cacheable for performance. This is also required for
|
||||
* VM Connect to display properly for ARM64 Linux VM, as the host also
|
||||
* maps the VRAM cacheable.
|
||||
* Map the VRAM cacheable for performance.
|
||||
*/
|
||||
fb_virt = ioremap_cache(par->mem->start, screen_fb_size);
|
||||
fb_virt = ioremap_wc(par->mem->start, screen_fb_size);
|
||||
if (!fb_virt)
|
||||
goto err2;
|
||||
|
||||
|
||||
@@ -167,12 +167,14 @@ static inline void red_set_vars(struct red_vars *v)
|
||||
v->qcount = -1;
|
||||
}
|
||||
|
||||
static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog)
|
||||
static inline bool red_check_params(u32 qth_min, u32 qth_max, u8 Wlog, u8 Scell_log)
|
||||
{
|
||||
if (fls(qth_min) + Wlog > 32)
|
||||
return false;
|
||||
if (fls(qth_max) + Wlog > 32)
|
||||
return false;
|
||||
if (Scell_log >= 32)
|
||||
return false;
|
||||
if (qth_max < qth_min)
|
||||
return false;
|
||||
return true;
|
||||
|
||||
@@ -3467,17 +3467,24 @@ static void pwq_adjust_max_active(struct pool_workqueue *pwq)
|
||||
* is updated and visible.
|
||||
*/
|
||||
if (!freezable || !workqueue_freezing) {
|
||||
bool kick = false;
|
||||
|
||||
pwq->max_active = wq->saved_max_active;
|
||||
|
||||
while (!list_empty(&pwq->delayed_works) &&
|
||||
pwq->nr_active < pwq->max_active)
|
||||
pwq->nr_active < pwq->max_active) {
|
||||
pwq_activate_first_delayed(pwq);
|
||||
kick = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to kick a worker after thawed or an unbound wq's
|
||||
* max_active is bumped. It's a slow path. Do it always.
|
||||
* max_active is bumped. In realtime scenarios, always kicking a
|
||||
* worker will cause interference on the isolated cpu cores, so
|
||||
* let's kick iff work items were activated.
|
||||
*/
|
||||
wake_up_worker(pwq->pool);
|
||||
if (kick)
|
||||
wake_up_worker(pwq->pool);
|
||||
} else {
|
||||
pwq->max_active = 0;
|
||||
}
|
||||
|
||||
@@ -83,14 +83,14 @@ static int clear_bits_ll(unsigned long *addr, unsigned long mask_to_clear)
|
||||
* users set the same bit, one user will return remain bits, otherwise
|
||||
* return 0.
|
||||
*/
|
||||
static int bitmap_set_ll(unsigned long *map, int start, int nr)
|
||||
static int bitmap_set_ll(unsigned long *map, unsigned long start, unsigned long nr)
|
||||
{
|
||||
unsigned long *p = map + BIT_WORD(start);
|
||||
const int size = start + nr;
|
||||
const unsigned long size = start + nr;
|
||||
int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
|
||||
unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
|
||||
|
||||
while (nr - bits_to_set >= 0) {
|
||||
while (nr >= bits_to_set) {
|
||||
if (set_bits_ll(p, mask_to_set))
|
||||
return nr;
|
||||
nr -= bits_to_set;
|
||||
@@ -118,14 +118,15 @@ static int bitmap_set_ll(unsigned long *map, int start, int nr)
|
||||
* users clear the same bit, one user will return remain bits,
|
||||
* otherwise return 0.
|
||||
*/
|
||||
static int bitmap_clear_ll(unsigned long *map, int start, int nr)
|
||||
static unsigned long
|
||||
bitmap_clear_ll(unsigned long *map, unsigned long start, unsigned long nr)
|
||||
{
|
||||
unsigned long *p = map + BIT_WORD(start);
|
||||
const int size = start + nr;
|
||||
const unsigned long size = start + nr;
|
||||
int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG);
|
||||
unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start);
|
||||
|
||||
while (nr - bits_to_clear >= 0) {
|
||||
while (nr >= bits_to_clear) {
|
||||
if (clear_bits_ll(p, mask_to_clear))
|
||||
return nr;
|
||||
nr -= bits_to_clear;
|
||||
@@ -184,8 +185,8 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy
|
||||
size_t size, int nid)
|
||||
{
|
||||
struct gen_pool_chunk *chunk;
|
||||
int nbits = size >> pool->min_alloc_order;
|
||||
int nbytes = sizeof(struct gen_pool_chunk) +
|
||||
unsigned long nbits = size >> pool->min_alloc_order;
|
||||
unsigned long nbytes = sizeof(struct gen_pool_chunk) +
|
||||
BITS_TO_LONGS(nbits) * sizeof(long);
|
||||
|
||||
chunk = vzalloc_node(nbytes, nid);
|
||||
@@ -242,7 +243,7 @@ void gen_pool_destroy(struct gen_pool *pool)
|
||||
struct list_head *_chunk, *_next_chunk;
|
||||
struct gen_pool_chunk *chunk;
|
||||
int order = pool->min_alloc_order;
|
||||
int bit, end_bit;
|
||||
unsigned long bit, end_bit;
|
||||
|
||||
list_for_each_safe(_chunk, _next_chunk, &pool->chunks) {
|
||||
chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
|
||||
@@ -293,7 +294,7 @@ unsigned long gen_pool_alloc_algo(struct gen_pool *pool, size_t size,
|
||||
struct gen_pool_chunk *chunk;
|
||||
unsigned long addr = 0;
|
||||
int order = pool->min_alloc_order;
|
||||
int nbits, start_bit, end_bit, remain;
|
||||
unsigned long nbits, start_bit, end_bit, remain;
|
||||
|
||||
#ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
|
||||
BUG_ON(in_nmi());
|
||||
@@ -376,7 +377,7 @@ void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size)
|
||||
{
|
||||
struct gen_pool_chunk *chunk;
|
||||
int order = pool->min_alloc_order;
|
||||
int start_bit, nbits, remain;
|
||||
unsigned long start_bit, nbits, remain;
|
||||
|
||||
#ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
|
||||
BUG_ON(in_nmi());
|
||||
@@ -638,7 +639,7 @@ unsigned long gen_pool_best_fit(unsigned long *map, unsigned long size,
|
||||
index = bitmap_find_next_zero_area(map, size, start, nr, 0);
|
||||
|
||||
while (index < size) {
|
||||
int next_bit = find_next_bit(map, size, index + nr);
|
||||
unsigned long next_bit = find_next_bit(map, size, index + nr);
|
||||
if ((next_bit - index) < len) {
|
||||
len = next_bit - index;
|
||||
start_bit = index;
|
||||
|
||||
@@ -292,7 +292,7 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb)
|
||||
.flowi4_iif = LOOPBACK_IFINDEX,
|
||||
.flowi4_oif = l3mdev_master_ifindex_rcu(dev),
|
||||
.daddr = ip_hdr(skb)->saddr,
|
||||
.flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
|
||||
.flowi4_tos = ip_hdr(skb)->tos & IPTOS_RT_MASK,
|
||||
.flowi4_scope = scope,
|
||||
.flowi4_mark = vmark ? skb->mark : 0,
|
||||
};
|
||||
|
||||
@@ -975,7 +975,7 @@ int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
|
||||
int payload, i, ret;
|
||||
|
||||
/* Find the NCSI device */
|
||||
nd = ncsi_find_dev(dev);
|
||||
nd = ncsi_find_dev(orig_dev);
|
||||
ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL;
|
||||
if (!ndp)
|
||||
return -ENODEV;
|
||||
|
||||
@@ -113,20 +113,6 @@ htable_size(u8 hbits)
|
||||
return hsize * sizeof(struct hbucket *) + sizeof(struct htable);
|
||||
}
|
||||
|
||||
/* Compute htable_bits from the user input parameter hashsize */
|
||||
static u8
|
||||
htable_bits(u32 hashsize)
|
||||
{
|
||||
/* Assume that hashsize == 2^htable_bits */
|
||||
u8 bits = fls(hashsize - 1);
|
||||
|
||||
if (jhash_size(bits) != hashsize)
|
||||
/* Round up to the first 2^n value */
|
||||
bits = fls(hashsize);
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
#ifdef IP_SET_HASH_WITH_NETS
|
||||
#if IPSET_NET_COUNT > 1
|
||||
#define __CIDR(cidr, i) (cidr[i])
|
||||
@@ -1309,7 +1295,11 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set,
|
||||
get_random_bytes(&h->initval, sizeof(h->initval));
|
||||
set->timeout = IPSET_NO_TIMEOUT;
|
||||
|
||||
hbits = htable_bits(hashsize);
|
||||
/* Compute htable_bits from the user input parameter hashsize.
|
||||
* Assume that hashsize == 2^htable_bits,
|
||||
* otherwise round up to the first 2^n value.
|
||||
*/
|
||||
hbits = fls(hashsize - 1);
|
||||
hsize = htable_size(hbits);
|
||||
if (hsize == 0) {
|
||||
kfree(h);
|
||||
|
||||
@@ -106,6 +106,9 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par)
|
||||
} cfg;
|
||||
int ret;
|
||||
|
||||
if (strnlen(info->name, sizeof(est->name)) >= sizeof(est->name))
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
net_get_random_once(&jhash_rnd, sizeof(jhash_rnd));
|
||||
|
||||
mutex_lock(&xt_rateest_mutex);
|
||||
|
||||
@@ -425,7 +425,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt)
|
||||
|
||||
ctl = nla_data(tb[TCA_CHOKE_PARMS]);
|
||||
|
||||
if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog))
|
||||
if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log))
|
||||
return -EINVAL;
|
||||
|
||||
if (ctl->limit > CHOKE_MAX_QUEUE)
|
||||
|
||||
@@ -356,7 +356,7 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp,
|
||||
struct gred_sched *table = qdisc_priv(sch);
|
||||
struct gred_sched_data *q = table->tab[dp];
|
||||
|
||||
if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog))
|
||||
if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log))
|
||||
return -EINVAL;
|
||||
|
||||
if (!q) {
|
||||
|
||||
@@ -184,7 +184,7 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt)
|
||||
max_P = tb[TCA_RED_MAX_P] ? nla_get_u32(tb[TCA_RED_MAX_P]) : 0;
|
||||
|
||||
ctl = nla_data(tb[TCA_RED_PARMS]);
|
||||
if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog))
|
||||
if (!red_check_params(ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Scell_log))
|
||||
return -EINVAL;
|
||||
|
||||
if (ctl->limit > 0) {
|
||||
|
||||
@@ -645,7 +645,7 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
|
||||
}
|
||||
|
||||
if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max,
|
||||
ctl_v1->Wlog))
|
||||
ctl_v1->Wlog, ctl_v1->Scell_log))
|
||||
return -EINVAL;
|
||||
if (ctl_v1 && ctl_v1->qth_min) {
|
||||
p = kmalloc(sizeof(*p), GFP_KERNEL);
|
||||
|
||||
@@ -14,6 +14,8 @@ if ! test -r System.map ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# legacy behavior: "depmod" in /sbin, no /sbin in PATH
|
||||
PATH="$PATH:/sbin"
|
||||
if [ -z $(command -v $DEPMOD) ]; then
|
||||
echo "Warning: 'make modules_install' requires $DEPMOD. Please install it." >&2
|
||||
echo "This is probably in the kmod package." >&2
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#
|
||||
|
||||
import gdb
|
||||
import sys
|
||||
|
||||
from linux import utils
|
||||
|
||||
@@ -23,10 +24,11 @@ class LxDmesg(gdb.Command):
|
||||
super(LxDmesg, self).__init__("lx-dmesg", gdb.COMMAND_DATA)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
log_buf_addr = int(str(gdb.parse_and_eval("log_buf")).split()[0], 16)
|
||||
log_first_idx = int(gdb.parse_and_eval("log_first_idx"))
|
||||
log_next_idx = int(gdb.parse_and_eval("log_next_idx"))
|
||||
log_buf_len = int(gdb.parse_and_eval("log_buf_len"))
|
||||
log_buf_addr = int(str(gdb.parse_and_eval(
|
||||
"(void *)'printk.c'::log_buf")).split()[0], 16)
|
||||
log_first_idx = int(gdb.parse_and_eval("'printk.c'::log_first_idx"))
|
||||
log_next_idx = int(gdb.parse_and_eval("'printk.c'::log_next_idx"))
|
||||
log_buf_len = int(gdb.parse_and_eval("'printk.c'::log_buf_len"))
|
||||
|
||||
inf = gdb.inferiors()[0]
|
||||
start = log_buf_addr + log_first_idx
|
||||
@@ -51,13 +53,19 @@ class LxDmesg(gdb.Command):
|
||||
continue
|
||||
|
||||
text_len = utils.read_u16(log_buf[pos + 10:pos + 12])
|
||||
text = log_buf[pos + 16:pos + 16 + text_len].decode()
|
||||
text = log_buf[pos + 16:pos + 16 + text_len].decode(
|
||||
encoding='utf8', errors='replace')
|
||||
time_stamp = utils.read_u64(log_buf[pos:pos + 8])
|
||||
|
||||
for line in text.splitlines():
|
||||
gdb.write("[{time:12.6f}] {line}\n".format(
|
||||
msg = u"[{time:12.6f}] {line}\n".format(
|
||||
time=time_stamp / 1000000000.0,
|
||||
line=line))
|
||||
line=line)
|
||||
# With python2 gdb.write will attempt to convert unicode to
|
||||
# ascii and might fail so pass an utf8-encoded str instead.
|
||||
if sys.hexversion < 0x03000000:
|
||||
msg = msg.encode(encoding='utf8', errors='replace')
|
||||
gdb.write(msg)
|
||||
|
||||
pos += length
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class LxVersion(gdb.Command):
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
# linux_banner should contain a newline
|
||||
gdb.write(gdb.parse_and_eval("linux_banner").string())
|
||||
gdb.write(gdb.parse_and_eval("(char *)linux_banner").string())
|
||||
|
||||
LxVersion()
|
||||
|
||||
|
||||
@@ -1001,6 +1001,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
|
||||
static const struct hda_device_id snd_hda_id_conexant[] = {
|
||||
HDA_CODEC_ENTRY(0x14f11f86, "CX8070", patch_conexant_auto),
|
||||
HDA_CODEC_ENTRY(0x14f12008, "CX8200", patch_conexant_auto),
|
||||
HDA_CODEC_ENTRY(0x14f120d0, "CX11970", patch_conexant_auto),
|
||||
HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto),
|
||||
HDA_CODEC_ENTRY(0x14f15047, "CX20551 (Waikiki)", patch_conexant_auto),
|
||||
HDA_CODEC_ENTRY(0x14f15051, "CX20561 (Hermosa)", patch_conexant_auto),
|
||||
|
||||
@@ -1867,6 +1867,8 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi *umidi,
|
||||
ms_ep = find_usb_ms_endpoint_descriptor(hostep);
|
||||
if (!ms_ep)
|
||||
continue;
|
||||
if (ms_ep->bNumEmbMIDIJack > 0x10)
|
||||
continue;
|
||||
if (usb_endpoint_dir_out(ep)) {
|
||||
if (endpoints[epidx].out_ep) {
|
||||
if (++epidx >= MIDI_MAX_ENDPOINTS) {
|
||||
@@ -2119,6 +2121,8 @@ static int snd_usbmidi_detect_roland(struct snd_usb_midi *umidi,
|
||||
cs_desc[1] == USB_DT_CS_INTERFACE &&
|
||||
cs_desc[2] == 0xf1 &&
|
||||
cs_desc[3] == 0x02) {
|
||||
if (cs_desc[4] > 0x10 || cs_desc[5] > 0x10)
|
||||
continue;
|
||||
endpoint->in_cables = (1 << cs_desc[4]) - 1;
|
||||
endpoint->out_cables = (1 << cs_desc[5]) - 1;
|
||||
return snd_usbmidi_detect_endpoints(umidi, endpoint, 1);
|
||||
|
||||
Reference in New Issue
Block a user