Merge tag 'LA.UM.9.14.1.r1-21100-QCM6490.QISI15.0' of https://git.codelinaro.org/clo/la/kernel/msm-5.4 into android13-5.4-lahaina

LA.UM.9.14.1.r1-21100-QCM6490.QISI15.0

* tag 'LA.UM.9.14.1.r1-21100-QCM6490.QISI15.0' of https://git.codelinaro.org/clo/la/kernel/msm-5.4:
  msm:kgsl: Prevent sign extension on alignments
  reverting all USB patches
  msm: eva: OOB write issue in fence processing
  kgsl: gmu: Use num_vma for safe GMU VMAs array access
  net: Add netdevice notification for bridge activity
  bridge: port structure members from 5.4 kernel
  net: bridge: Fix for co-located mode
  UPSTREAM: usb: gadget: configfs: Add frame-based frame format support
  kgsl: Add buffer overflow check for perfcounter dynamic list
  usb: gadget: uvc: Add grey and I420 YUV UVC format support
  mtd: msm_qpic_nand: Use flash device ECC capability for erase page
  mtd: msm_qpic_nand: check for page_erased bit along with op_err
  UPSTREAM: usb: dwc3: Wait for EndXfer command completion
  netfilter: fix NATTYPE refresh timeout issue
  usb: gadget: uvc: Modify UVC_NUM_REQUESTS
  reverting enum-conversion, Handle CPU state and all USB patches
  msm: cvp: Fix for kernel address exposure vulnerability to user
  cnss: Init reserved memory device
  cnss: Dump stack by stack_trace_print
  cnss: Add support for building CNSS as a loadable module
  FROMLIST: media: venus: Add a check for packet size
  Add configures to enable CNSS platform driver
  FROMLIST: media: venus: Fix OOB read due to missing payload bound check
  dma-mapping-fast: Fix PMD offset calculation for non-2M aligned start aperture
  crypto: qcedev - fix UAF in crypto-qti driver
  msm: adsprpc: Prevent refcount increment for duplicate dmahandles
  dmaengine: msm_gpi: fix to avoid null pointer access
  mdm: ipa3: support IPoGRE new IOCTL and proc params
  msm: mhi_dev: Workqueue to handle host wakeup in M3+D0
  iommu: Fix invalid access in av8l_fast_unmap_public
  msm: mhi_dev: Handle host wakeup in M3/D0
  msm: ep_pcie: Wake host in D3cold handling if wake is pending
  FROMGIT: media: venus: hfi: add a check to handle OOB in sfr region
  FROMGIT: media: venus: hfi: add check to handle incorrect queue size
  FROMGIT: media: venus: hfi_parser: add check to avoid out of bound access
  Revert "msm_ipa: Install exception rule for PPPoE-MPLS"
  firmware: qcom_scm: do not clear dump mode from shutdown
  msm: adsprpc: Avoid taking reference for group_info
  adsprpc: Handle UAF scenario in put_args
  msm: eva: Adding kref count for cvp_get_inst_from_id
  wifi: cfg80211: Increase akm_suites array size in cfg80211_crypto_settings
  thermal: qcom: Add support to update tsens trip based on nvmem data

 Conflicts:
	Makefile
	arch/arm64/include/asm/cputype.h
	drivers/char/adsprpc.c
	drivers/hid/hid-ids.h
	drivers/net/usb/rtl8150.c
	drivers/platform/Kconfig
	drivers/platform/Makefile
	drivers/soc/qcom/mdt_loader.c
	drivers/soc/qcom/rpmh-rsc.c
	drivers/usb/core/quirks.c
	drivers/usb/dwc3/dwc3-qcom.c
	drivers/usb/dwc3/gadget.c
	drivers/usb/gadget/function/f_fs.c
	drivers/usb/gadget/function/f_ncm.c
	mm/slub.c
	mm/zsmalloc.c
	net/ipv4/tcp_output.c
	scripts/Makefile.extrawarn

Change-Id: Ia4f3356ed4a105a2f3b0feda3e78725a01a970b2
This commit is contained in:
Michael Bestas 2026-04-30 20:46:30 +03:00
commit 9f0d3e60bc
No known key found for this signature in database
GPG key ID: CC95044519BE6669
132 changed files with 1676 additions and 1149 deletions

View file

@ -265,6 +265,71 @@ Description: Specific uncompressed frame descriptors
bmCapabilities - still image support, fixed frame-rate
support
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased
Date: Oct 2025
KernelVersion: 5.4
Description: Framebased format descriptors
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased/name
Date: Oct 2025
KernelVersion: 5.4
Description: Specific framebased format descriptors
================== =======================================
bFormatIndex unique id for this format descriptor;
only defined after parent header is
linked into the streaming class;
read-only
bmaControls this format's data for bmaControls in
the streaming header
bmInterlaceFlags specifies interlace information,
read-only
bAspectRatioY the X dimension of the picture aspect
ratio, read-only
bAspectRatioX the Y dimension of the picture aspect
ratio, read-only
bDefaultFrameIndex optimum frame index for this stream
bBitsPerPixel number of bits per pixel used to
specify color in the decoded video
frame
guidFormat globally unique id used to identify
stream-encoding format
================== =======================================
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/framebased/name/name
Date: Sept 2024
KernelVersion: 5.15
Description: Specific framebased frame descriptors
========================= =====================================
bFrameIndex unique id for this framedescriptor;
only defined after parent format is
linked into the streaming header;
read-only
dwFrameInterval indicates how frame interval can be
programmed; a number of values
separated by newline can be specified
dwDefaultFrameInterval the frame interval the device would
like to use as default
dwBytesPerLine Specifies the number of bytes per line
of video for packed fixed frame size
formats, allowing the receiver to
perform stride alignment of the video.
If the bVariableSize value (above) is
TRUE (1), or if the format does not
permit such alignment, this value shall
be set to zero (0).
dwMaxBitRate the maximum bit rate at the shortest
frame interval in bps
dwMinBitRate the minimum bit rate at the longest
frame interval in bps
wHeight height of decoded bitmap frame in px
wWidth width of decoded bitmam frame in px
bmCapabilities still image support, fixed frame-rate
support
========================= =====================================
What: /config/usb-gadget/gadget/functions/uvc.name/streaming/header
Date: Dec 2014
KernelVersion: 4.0

View file

@ -1 +1 @@
LTS_5.4.289_4c8fb3275889
LTS_5.4.302_91d385eb2a41

View file

@ -51,6 +51,10 @@ CONFIG_CNSS_ASYNC=y
CONFIG_CNSS_QCA6490=y
CONFIG_CNSS_UTILS=y
# CONFIG_CNSS_GENL is not set
CONFIG_CNSS=m
CONFIG_CNSS_CRYPTO=y
CONFIG_CNSS_PCI=y
CONFIG_CNSS_LOGGER=m
CONFIG_QCOM_MEMORY_DUMP_V2=y
CONFIG_PACKET=y
CONFIG_UNIX=y

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*/
/* Uncomment this block to log an error on every VERIFY failure */
@ -62,6 +62,7 @@
#define TZ_PIL_AUTH_QDSP6_PROC 1
#define FASTRPC_DMAHANDLE_NOMAP (16)
#define FASTRPC_MAP_DMA_HANDLE 0x20000
#define FASTRPC_ENOSUCH 39
#define DEBUGFS_SIZE 3072
@ -1128,7 +1129,7 @@ static void fastrpc_mmap_add(struct fastrpc_mmap *map)
}
static int fastrpc_mmap_find(struct fastrpc_file *fl, int fd,
uintptr_t va, size_t len, int mflags, int refs,
uintptr_t va, size_t len, int mflags, bool refs,
struct fastrpc_mmap **ppmap)
{
struct fastrpc_mmap *match = NULL, *map = NULL;
@ -1306,7 +1307,7 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags)
dma_free_attrs(me->dev, map->size, (void *)map->va,
(dma_addr_t)map->phys, (unsigned long)map->attr);
}
} else if (map->flags == FASTRPC_DMAHANDLE_NOMAP) {
} else if (map->flags & FASTRPC_DMAHANDLE_NOMAP) {
trace_fastrpc_dma_unmap(cid, map->phys, map->size);
if (!IS_ERR_OR_NULL(map->table))
dma_buf_unmap_attachment(map->attach, map->table,
@ -1391,6 +1392,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
unsigned long flags;
int err = 0, vmid, sgl_index = 0;
struct scatterlist *sgl = NULL;
bool take_ref = true;
if (!fl) {
err = -EBADF;
@ -1404,7 +1406,9 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
}
chan = &apps->channel[cid];
if (!fastrpc_mmap_find(fl, fd, va, len, mflags, 1, ppmap))
if (mflags & FASTRPC_MAP_DMA_HANDLE)
take_ref = false;
if (!fastrpc_mmap_find(fl, fd, va, len, mflags, take_ref, ppmap))
return 0;
map = kzalloc(sizeof(*map), GFP_KERNEL);
VERIFY(err, !IS_ERR_OR_NULL(map));
@ -1442,7 +1446,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd,
if (err)
goto bail;
}
} else if (mflags == FASTRPC_DMAHANDLE_NOMAP) {
} else if (mflags & FASTRPC_DMAHANDLE_NOMAP) {
if (map->attr & FASTRPC_ATTR_KEEP_MAP) {
ADSPRPC_ERR("Invalid attribute 0x%x for fd %d\n",
map->attr, fd);
@ -2502,10 +2506,10 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
handles = REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc);
mutex_lock(&ctx->fl->map_mutex);
for (i = bufs; i < bufs + handles; i++) {
int dmaflags = 0;
int dmaflags = FASTRPC_MAP_DMA_HANDLE;
if (ctx->attrs && (ctx->attrs[i] & FASTRPC_ATTR_NOMAP))
dmaflags = FASTRPC_DMAHANDLE_NOMAP;
dmaflags |= FASTRPC_DMAHANDLE_NOMAP;
if (ctx->fds && (ctx->fds[i] != -1))
err = fastrpc_mmap_create(ctx->fl, ctx->fds[i],
FASTRPC_ATTR_NOVA, 0, 0, dmaflags,
@ -2666,7 +2670,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx)
if (ctx->maps[i]) {
/* check if map still exist */
if (!fastrpc_mmap_find(ctx->fl, ctx->fds[i], 0, 0,
0, 0, &mmap)) {
0, false, &mmap)) {
if (mmap) {
pages[i].addr = mmap->phys;
pages[i].size = mmap->size;
@ -2881,7 +2885,7 @@ static int put_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
if (!fdlist[i])
break;
if (!fastrpc_mmap_find(ctx->fl, (int)fdlist[i], 0, 0,
0, 0, &mmap)) {
0, false, &mmap)) {
if (mmap && mmap->dma_handle_refs) {
mmap->dma_handle_refs = 0;
fastrpc_mmap_free(mmap, 0);
@ -4961,7 +4965,7 @@ static int fastrpc_internal_munmap_fd(struct fastrpc_file *fl,
}
mutex_lock(&fl->internal_map_mutex);
mutex_lock(&fl->map_mutex);
err = fastrpc_mmap_find(fl, ud->fd, ud->va, ud->len, 0, 0, &map);
err = fastrpc_mmap_find(fl, ud->fd, ud->va, ud->len, 0, false, &map);
if (err) {
ADSPRPC_ERR(
"mapping not found to unmap fd 0x%x, va 0x%llx, len 0x%x, err %d\n",

View file

@ -329,10 +329,6 @@ int qcedev_check_and_map_buffer(void *handle,
mapped_size = binfo->ion_buf.mapped_buf_size;
atomic_inc(&binfo->ref_count);
/* Add buffer mapping information to regd buffer list */
mutex_lock(&qce_hndl->registeredbufs.lock);
list_add_tail(&binfo->list, &qce_hndl->registeredbufs.list);
mutex_unlock(&qce_hndl->registeredbufs.lock);
}
/* Make sure the offset is within the mapped range */
@ -344,6 +340,13 @@ int qcedev_check_and_map_buffer(void *handle,
goto unmap;
}
if (!found) {
/* Add buffer mapping information to regd buffer list */
mutex_lock(&qce_hndl->registeredbufs.lock);
list_add_tail(&binfo->list, &qce_hndl->registeredbufs.list);
mutex_unlock(&qce_hndl->registeredbufs.lock);
}
/* return the mapped virtual address adjusted by offset */
*vaddr += offset;
@ -352,9 +355,6 @@ int qcedev_check_and_map_buffer(void *handle,
unmap:
if (!found) {
qcedev_unmap_buffer(handle, mem_client, binfo);
mutex_lock(&qce_hndl->registeredbufs.lock);
list_del(&binfo->list);
mutex_unlock(&qce_hndl->registeredbufs.lock);
}
error:

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/atomic.h>
@ -2524,6 +2525,12 @@ struct dma_async_tx_descriptor *gpi_prep_slave_sg(struct dma_chan *chan,
for_each_sg(sgl, sg, sg_len, i) {
tre = sg_virt(sg);
if (!tre) {
kfree(gpi_desc);
GPII_ERR(gpii, gpii_chan->chid, "TRE address is null\n");
return NULL;
}
if (sg_len == 1) {
tre_type =
MSM_GPI_TRE_TYPE(((struct msm_gpi_tre *)tre));

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/clk/qcom.h>
@ -2523,6 +2524,7 @@ int a6xx_perfcounter_update(struct adreno_device *adreno_dev,
struct cpu_gpu_lock *lock = ptr;
u32 *data = ptr + sizeof(*lock);
int i, offset = 0;
u32 pending_pairs = 2; /* No of pairs to add: <select,value> and <cntl,1> */
if (cpu_gpu_lock(lock)) {
cpu_gpu_unlock(lock);
@ -2546,6 +2548,13 @@ int a6xx_perfcounter_update(struct adreno_device *adreno_dev,
offset += 2;
}
/* Ensure there is enough space in the reglist buffer for new pairs */
if ((offset + (pending_pairs * 2)) >=
(adreno_dev->pwrup_reglist->size / sizeof(u32))) {
cpu_gpu_unlock(lock);
return -ENOSPC;
}
/*
* For all targets A6XX_RBBM_PERFCTR_CNTL needs to be the last entry,
* so overwrite the existing A6XX_RBBM_PERFCNTL_CTRL and add it back to

View file

@ -593,7 +593,7 @@ static int find_vma_block(struct a6xx_gmu_device *gmu, u32 addr, u32 size)
{
int i;
for (i = 0; i < GMU_MEM_TYPE_MAX; i++) {
for (i = 0; i < gmu->num_vmas; i++) {
struct gmu_vma_entry *vma = &gmu->vma[i];
if ((addr >= vma->start) &&
@ -2685,10 +2685,13 @@ int a6xx_gmu_probe(struct kgsl_device *device,
if (ret)
goto error;
if (adreno_is_a650_family(adreno_dev))
if (adreno_is_a650_family(adreno_dev)) {
gmu->vma = a6xx_gmu_vma;
else
gmu->num_vmas = ARRAY_SIZE(a6xx_gmu_vma);
} else {
gmu->vma = a6xx_gmu_vma_legacy;
gmu->num_vmas = ARRAY_SIZE(a6xx_gmu_vma_legacy);
}
/* Map and reserve GMU CSRs registers */
ret = a6xx_gmu_reg_probe(adreno_dev);

View file

@ -187,6 +187,8 @@ struct a6xx_gmu_device {
/** @global_entries: To keep track of number of gmu buffers */
u32 global_entries;
struct gmu_vma_entry *vma;
/** @num_vmas: Number of entries in the @vma array */
u32 num_vmas;
unsigned int log_wptr_retention;
/** @cm3_fault: whether gmu received a cm3 fault interrupt */
atomic_t cm3_fault;

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2008-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <uapi/linux/msm_ion.h>
@ -4054,9 +4054,9 @@ static unsigned long _gpu_set_svm_region(struct kgsl_process_private *private,
return addr;
}
static unsigned long get_align(struct kgsl_mem_entry *entry)
unsigned long kgsl_get_align(struct kgsl_memdesc *memdesc)
{
int bit = kgsl_memdesc_get_align(&entry->memdesc);
u32 bit = kgsl_memdesc_get_align(memdesc);
if (bit >= ilog2(SZ_2M))
return SZ_2M;
@ -4065,7 +4065,7 @@ static unsigned long get_align(struct kgsl_mem_entry *entry)
else if (bit >= ilog2(SZ_64K))
return SZ_64K;
return SZ_4K;
return PAGE_SIZE;
}
static unsigned long set_svm_area(struct file *file,
@ -4098,7 +4098,7 @@ static unsigned long get_svm_unmapped_area(struct file *file,
{
struct kgsl_device_private *dev_priv = file->private_data;
struct kgsl_process_private *private = dev_priv->process_priv;
unsigned long align = get_align(entry);
unsigned long align = kgsl_get_align(&entry->memdesc);
unsigned long ret, iova;
u64 start = 0, end = 0;
struct vm_area_struct *vma;

View file

@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2008-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef __KGSL_H
#define __KGSL_H
@ -473,6 +473,8 @@ void kgsl_mmu_remove_global(struct kgsl_device *device,
struct kgsl_memdesc *memdesc);
/* Helper functions */
unsigned long kgsl_get_align(struct kgsl_memdesc *memdesc);
int kgsl_request_irq(struct platform_device *pdev, const char *name,
irq_handler_t handler, void *data);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2002,2008-2021, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/debugfs.h>
@ -146,7 +147,7 @@ static const char *memtype_str(int memtype)
static char get_alignflag(const struct kgsl_memdesc *m)
{
int align = kgsl_memdesc_get_align(m);
u32 align = kgsl_memdesc_get_align(m);
if (align >= ilog2(SZ_1M))
return 'L';

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2011-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/bitfield.h>
@ -2229,8 +2229,7 @@ static int kgsl_iommu_get_gpuaddr(struct kgsl_pagetable *pagetable,
size = kgsl_memdesc_footprint(memdesc);
align = max_t(uint64_t, 1 << kgsl_memdesc_get_align(memdesc),
PAGE_SIZE);
align = kgsl_get_align(memdesc);
if (memdesc->flags & KGSL_MEMFLAGS_FORCE_32BIT) {
start = pt->compat_va_start;

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2002,2007-2020, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef __KGSL_SHAREDMEM_H
#define __KGSL_SHAREDMEM_H
@ -157,7 +158,7 @@ void kgsl_free_globals(struct kgsl_device *device);
*
* Returns the alignment requested, as power of 2 exponent.
*/
static inline int
static inline u32
kgsl_memdesc_get_align(const struct kgsl_memdesc *memdesc)
{
return MEMFLAGS(memdesc->flags, KGSL_MEMALIGN_MASK,

View file

@ -197,8 +197,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
if (!input_device->hid_desc)
goto cleanup;
input_device->report_desc_size = le16_to_cpu(
desc->rpt_desc.wDescriptorLength);
input_device->report_desc_size = desc->desc[0].wDescriptorLength;
if (input_device->report_desc_size == 0) {
input_device->dev_info_status = -EINVAL;
goto cleanup;
@ -214,7 +213,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
memcpy(input_device->report_desc,
((unsigned char *)desc) + desc->bLength,
le16_to_cpu(desc->rpt_desc.wDescriptorLength));
desc->desc[0].wDescriptorLength);
/* Send the ack */
memset(&ack, 0, sizeof(struct mousevsc_prt_msg));

View file

@ -984,11 +984,12 @@ static int usbhid_parse(struct hid_device *hid)
struct usb_host_interface *interface = intf->cur_altsetting;
struct usb_device *dev = interface_to_usbdev (intf);
struct hid_descriptor *hdesc;
struct hid_class_descriptor *hcdesc;
u32 quirks = 0;
unsigned int rsize = 0;
char *rdesc;
int ret;
int ret, n;
int num_descriptors;
size_t offset = offsetof(struct hid_descriptor, desc);
quirks = hid_lookup_quirk(hid);
@ -1010,19 +1011,20 @@ static int usbhid_parse(struct hid_device *hid)
return -ENODEV;
}
if (!hdesc->bNumDescriptors ||
hdesc->bLength != sizeof(*hdesc) +
(hdesc->bNumDescriptors - 1) * sizeof(*hcdesc)) {
dbg_hid("hid descriptor invalid, bLen=%hhu bNum=%hhu\n",
hdesc->bLength, hdesc->bNumDescriptors);
if (hdesc->bLength < sizeof(struct hid_descriptor)) {
dbg_hid("hid descriptor is too short\n");
return -EINVAL;
}
hid->version = le16_to_cpu(hdesc->bcdHID);
hid->country = hdesc->bCountryCode;
if (hdesc->rpt_desc.bDescriptorType == HID_DT_REPORT)
rsize = le16_to_cpu(hdesc->rpt_desc.wDescriptorLength);
num_descriptors = min_t(int, hdesc->bNumDescriptors,
(hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
for (n = 0; n < num_descriptors; n++)
if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
dbg_hid("weird size of report descriptor (%u)\n", rsize);
@ -1050,11 +1052,6 @@ static int usbhid_parse(struct hid_device *hid)
goto err;
}
if (hdesc->bNumDescriptors > 1)
hid_warn(intf,
"%u unsupported optional hid class descriptors\n",
(int)(hdesc->bNumDescriptors - 1));
hid->quirks |= quirks;
return 0;

View file

@ -244,8 +244,12 @@ static void fast_smmu_unmap_page(struct device *dev, dma_addr_t iova,
}
spin_lock_irqsave(&mapping->lock, flags);
av8l_fast_unmap_public(mapping->pgtbl_ops, iova, len);
if (unlikely(!av8l_fast_unmap_public(mapping->pgtbl_ops, iova, len)))
goto fail;
__fast_smmu_free_iova(mapping, iova, len);
fail:
spin_unlock_irqrestore(&mapping->lock, flags);
trace_unmap(to_msm_iommu_domain(mapping->domain), iova - offset, len,
@ -385,7 +389,8 @@ static void fast_smmu_unmap_sg(struct device *dev,
len = ALIGN(sg_dma_address(sg) + sg_dma_len(sg) - (start - offset),
FAST_PAGE_SIZE);
av8l_fast_unmap_public(mapping->pgtbl_ops, start, len);
if (unlikely(!av8l_fast_unmap_public(mapping->pgtbl_ops, start, len)))
return;
spin_lock_irqsave(&mapping->lock, flags);
__fast_smmu_free_iova(mapping, start, len);
@ -653,7 +658,10 @@ static void fast_smmu_free(struct device *dev, size_t size,
size = ALIGN(size, FAST_PAGE_SIZE);
spin_lock_irqsave(&mapping->lock, flags);
av8l_fast_unmap_public(mapping->pgtbl_ops, dma_handle, size);
if (unlikely(!av8l_fast_unmap_public(mapping->pgtbl_ops, dma_handle, size)))
goto fail;
__fast_smmu_free_iova(mapping, dma_handle, size);
spin_unlock_irqrestore(&mapping->lock, flags);
@ -674,6 +682,11 @@ static void fast_smmu_free(struct device *dev, size_t size,
if (page)
dma_free_contiguous(dev, page, size);
return;
fail:
spin_unlock_irqrestore(&mapping->lock, flags);
}
static int fast_smmu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,

View file

@ -127,7 +127,14 @@
#define PTE_SH_IDX(pte) (pte & AV8L_FAST_PTE_SH_MASK)
#define iopte_pmd_offset(pmds, base, iova) (pmds + ((iova - base) >> 12))
#define iopte_pmd_offset(pmds, base, iova) \
({ \
typeof(iova) __iova = (iova); \
typeof(base) __base = (base); \
typeof(pmds) __pmds = (pmds); \
(__iova < __base) ? ERR_PTR(-EINVAL) : \
__pmds + ((__iova - ALIGN_DOWN(__base, SZ_2M)) >> AV8L_FAST_PAGE_SHIFT); \
})
static inline dma_addr_t av8l_dma_addr(void *addr)
{
@ -202,6 +209,12 @@ void av8l_fast_clear_stale_ptes(struct io_pgtable_ops *ops, u64 base,
struct io_pgtable *iop = iof_pgtable_ops_to_pgtable(ops);
av8l_fast_iopte *pmdp = iopte_pmd_offset(data->pmds, data->base, base);
if (IS_ERR(pmdp)) {
pr_err("Invalid iova : 0x%lx, as it is less than base : 0x%llx\n",
iova, data->base);
return;
}
for (i = base >> AV8L_FAST_PAGE_SHIFT;
i <= (end >> AV8L_FAST_PAGE_SHIFT); ++i) {
if (!(*pmdp & AV8L_FAST_PTE_VALID)) {
@ -254,6 +267,12 @@ static int av8l_fast_map(struct io_pgtable_ops *ops, unsigned long iova,
unsigned long i, nptes = size >> AV8L_FAST_PAGE_SHIFT;
av8l_fast_iopte pte;
if (IS_ERR(ptep)) {
pr_err("Invalid iova : 0x%lx, as it is less than base : 0x%llx\n",
iova, data->base);
return -EINVAL;
}
pte = av8l_fast_prot_to_pte(data, prot);
paddr &= AV8L_FAST_PTE_ADDR_MASK;
for (i = 0; i < nptes; i++, paddr += SZ_4K) {
@ -286,6 +305,12 @@ __av8l_fast_unmap(struct io_pgtable_ops *ops, unsigned long iova,
ptep = iopte_pmd_offset(data->pmds, data->base, iova);
nptes = size >> AV8L_FAST_PAGE_SHIFT;
if (IS_ERR(ptep)) {
pr_err("Invalid iova : 0x%lx, as it is less than base : 0x%llx\n",
iova, data->base);
return 0;
}
memset(ptep, val, sizeof(*ptep) * nptes);
av8l_clean_range(&iop->cfg, ptep, ptep + nptes);
if (!allow_stale_tlb)
@ -295,10 +320,10 @@ __av8l_fast_unmap(struct io_pgtable_ops *ops, unsigned long iova,
}
/* caller must take care of tlb cache maintenance */
void av8l_fast_unmap_public(struct io_pgtable_ops *ops, unsigned long iova,
size_t av8l_fast_unmap_public(struct io_pgtable_ops *ops, unsigned long iova,
size_t size)
{
__av8l_fast_unmap(ops, iova, size, true);
return __av8l_fast_unmap(ops, iova, size, true);
}
static size_t av8l_fast_unmap(struct io_pgtable_ops *ops, unsigned long iova,
@ -383,6 +408,12 @@ static bool av8l_fast_iova_coherent(struct io_pgtable_ops *ops,
struct av8l_fast_io_pgtable *data = iof_pgtable_ops_to_data(ops);
av8l_fast_iopte *ptep = iopte_pmd_offset(data->pmds, data->base, iova);
if (IS_ERR(ptep)) {
pr_err("Invalid iova : 0x%lx, as it is less than base : 0x%llx\n",
iova, data->base);
return false;
}
return ((PTE_MAIR_IDX(*ptep) == AV8L_FAST_MAIR_ATTR_IDX_CACHE) &&
((PTE_SH_IDX(*ptep) == AV8L_FAST_PTE_SH_OS) ||
(PTE_SH_IDX(*ptep) == AV8L_FAST_PTE_SH_IS)));

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/debugfs.h>
@ -135,6 +135,8 @@ static int msm_cvp_initialize_core(struct platform_device *pdev,
INIT_LIST_HEAD(&core->instances);
mutex_init(&core->lock);
mutex_init(&core->clk_lock);
mutex_init(&core->idr_mtx);
idr_init(&core->sess_idr);
core->state = CVP_CORE_UNINIT;
for (i = SYS_MSG_INDEX(SYS_MSG_START);
@ -506,6 +508,8 @@ static int msm_cvp_remove(struct platform_device *pdev)
msm_cvp_free_platform_resources(&core->resources);
sysfs_remove_group(&pdev->dev.kobj, &msm_cvp_core_attr_group);
dev_set_drvdata(&pdev->dev, NULL);
idr_destroy(&core->sess_idr);
mutex_destroy(&core->idr_mtx);
mutex_destroy(&core->lock);
mutex_destroy(&core->clk_lock);
kfree(core);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <asm/memory.h>
@ -29,6 +30,7 @@
#include "cvp_hfi_helper.h"
#include "cvp_hfi_io.h"
#include "msm_cvp_dsp.h"
#include "msm_cvp.h"
#define FIRMWARE_SIZE 0X00A00000
#define REG_ADDR_OFFSET_BITMASK 0x000FFFFF
@ -469,6 +471,7 @@ static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags)
{
int rc;
struct cvp_hal_session *temp;
struct msm_cvp_inst *inst = NULL;
if (msm_cvp_dsp_disable)
return 0;
@ -480,9 +483,10 @@ static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags)
/* don't suspend if cvp session is not paused */
if (!(temp->flags & SESSION_PAUSE)) {
inst = (struct msm_cvp_inst *)temp->session_id;
dprintk(CVP_DSP,
"%s: cvp session %x not paused\n",
__func__, hash32_ptr(temp));
__func__, inst->sess_id);
return -EBUSY;
}
}
@ -2224,12 +2228,17 @@ static void __session_clean(struct cvp_hal_session *session)
{
struct cvp_hal_session *temp, *next;
struct iris_hfi_device *device;
struct msm_cvp_core *core = NULL;
struct msm_cvp_inst *inst = NULL;
void *tmp = NULL;
if (!session || !session->device) {
dprintk(CVP_WARN, "%s: invalid params\n", __func__);
return;
}
device = session->device;
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
inst = (struct msm_cvp_inst *) session->session_id;
dprintk(CVP_SESS, "deleted the session: %pK\n", session);
/*
* session might have been removed from the device list in
@ -2241,6 +2250,13 @@ static void __session_clean(struct cvp_hal_session *session)
break;
}
}
/* Remove the IDR id assigned to this session */
mutex_lock(&core->idr_mtx);
tmp = idr_remove(&core->sess_idr, inst->sess_id);
if (tmp != session)
dprintk(CVP_WARN, "%s: session\n", __func__);
mutex_unlock(&core->idr_mtx);
/* Poison the session handle with zeros */
*session = (struct cvp_hal_session){ {0} };
kfree(session);
@ -2278,6 +2294,9 @@ static int iris_hfi_session_init(void *device, void *session_id,
struct cvp_hfi_cmd_sys_session_init_packet pkt;
struct iris_hfi_device *dev;
struct cvp_hal_session *s;
struct msm_cvp_core *core;
struct msm_cvp_inst *inst;
int id = 0;
if (!device || !new_session) {
dprintk(CVP_ERR, "%s - invalid input\n", __func__);
@ -2285,6 +2304,8 @@ static int iris_hfi_session_init(void *device, void *session_id,
}
dev = device;
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
inst = session_id;
mutex_lock(&dev->lock);
s = kzalloc(sizeof(*s), GFP_KERNEL);
@ -2295,15 +2316,35 @@ static int iris_hfi_session_init(void *device, void *session_id,
s->session_id = session_id;
s->device = dev;
mutex_lock(&core->idr_mtx);
idr_preload(GFP_KERNEL);
/* Need to think if we can use core->lock or dev->lock or need a
* different new lock for this?
*/
id = idr_alloc(&core->sess_idr, (void *)s, 0x7FFF0000, INT_MAX, GFP_NOWAIT);
idr_preload_end();
mutex_unlock(&core->idr_mtx);
if (id < 0) {
dprintk(CVP_ERR,
"%s: idr allocation failed for session %pK of inst %pK\n",
__func__, s, session_id);
goto err_session_init_fail;
}
dprintk(CVP_SESS,
"%s: inst %pK, session %pK\n", __func__, session_id, s);
"%s: inst %pK, session %pK, idr_id = 0x%x\n", __func__, session_id, s, id);
list_add_tail(&s->list, &dev->sess_head);
__set_default_sys_properties(device);
inst->sess_id = id;
if (call_hfi_pkt_op(dev, session_init, &pkt, s)) {
dprintk(CVP_ERR, "session_init: failed to create packet\n");
inst->sess_id = 0x0000DEAD;
goto err_session_init_fail;
}
@ -2317,6 +2358,7 @@ static int iris_hfi_session_init(void *device, void *session_id,
err_session_init_fail:
if (s)
__session_clean(s);
inst->sess_id = 0;
*new_session = NULL;
mutex_unlock(&dev->lock);
return -EINVAL;
@ -2878,9 +2920,11 @@ static struct cvp_hal_session *__get_session(struct iris_hfi_device *device,
u32 session_id)
{
struct cvp_hal_session *temp = NULL;
struct msm_cvp_inst *inst = NULL;
list_for_each_entry(temp, &device->sess_head, list) {
if (session_id == hash32_ptr(temp))
inst = (struct msm_cvp_inst *)temp->session_id;
if (session_id == inst->sess_id)
return temp;
}
@ -3059,6 +3103,7 @@ static int __response_handler(struct iris_hfi_device *device)
/* Process the packet types that we're interested in */
process_system_msg(info, device, raw_packet);
/* This session_id is a double pointer to the idr_id of session */
session_id = get_session_id(info);
/*
* hfi_process_msg_packet provides a session_id that's a hashed
@ -3070,11 +3115,6 @@ static int __response_handler(struct iris_hfi_device *device)
if (session_id) {
struct cvp_hal_session *session = NULL;
if (upper_32_bits((uintptr_t)*session_id) != 0) {
dprintk(CVP_ERR,
"Upper 32-bits != 0 for sess_id=%pK\n",
*session_id);
}
session = __get_session(device,
(u32)(uintptr_t)*session_id);
if (!session) {

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include "hfi_packetization.h"
@ -208,7 +209,7 @@ inline int cvp_create_pkt_cmd_sys_session_init(
pkt->size = sizeof(struct cvp_hfi_cmd_sys_session_init_packet);
pkt->packet_type = HFI_CMD_SYS_SESSION_INIT;
pkt->session_id = hash32_ptr(session);
pkt->session_id = inst->sess_id;
pkt->session_type = inst->prop.type;
pkt->session_kmask = inst->prop.kernel_mask;
pkt->session_prio = inst->prop.priority;
@ -266,13 +267,14 @@ int cvp_create_pkt_cmd_session_cmd(struct cvp_hal_session_cmd_pkt *pkt,
int pkt_type, struct cvp_hal_session *session)
{
int rc = 0;
struct msm_cvp_inst *inst = session->session_id;
if (!pkt)
return -EINVAL;
pkt->size = sizeof(struct cvp_hal_session_cmd_pkt);
pkt->packet_type = pkt_type;
pkt->session_id = hash32_ptr(session);
pkt->session_id = inst->sess_id;
return rc;
}
@ -305,13 +307,14 @@ int cvp_create_pkt_cmd_session_set_buffers(
{
int rc = 0;
struct cvp_hfi_cmd_session_set_buffers_packet *pkt;
struct msm_cvp_inst *inst = session->session_id;
if (!cmd || !session)
if (!cmd || !session || !inst)
return -EINVAL;
pkt = (struct cvp_hfi_cmd_session_set_buffers_packet *)cmd;
pkt->packet_type = HFI_CMD_SESSION_CVP_SET_BUFFERS;
pkt->session_id = hash32_ptr(session);
pkt->session_id = inst->sess_id;
pkt->buf_type.iova = iova;
pkt->buf_type.size = size;
pkt->size = sizeof(struct cvp_hfi_cmd_session_set_buffers_packet);
@ -324,13 +327,14 @@ int cvp_create_pkt_cmd_session_release_buffers(
struct cvp_hal_session *session)
{
struct cvp_session_release_buffers_packet *pkt;
struct msm_cvp_inst *inst = session->session_id;
if (!cmd || !session)
if (!cmd || !session || !inst)
return -EINVAL;
pkt = (struct cvp_session_release_buffers_packet *)cmd;
pkt->packet_type = HFI_CMD_SESSION_CVP_RELEASE_BUFFERS;
pkt->session_id = hash32_ptr(session);
pkt->session_id = inst->sess_id;
pkt->num_buffers = 1;
pkt->buffer_type = 0;
pkt->size = sizeof(struct cvp_session_release_buffers_packet) +
@ -347,6 +351,7 @@ int cvp_create_pkt_cmd_session_send(
int def_idx;
struct cvp_hal_session_cmd_pkt *ptr =
(struct cvp_hal_session_cmd_pkt *)in_pkt;
struct msm_cvp_inst *inst = session->session_id;
if (!out_pkt || !in_pkt || !session)
return -EINVAL;
@ -354,7 +359,7 @@ int cvp_create_pkt_cmd_session_send(
if (ptr->size > MAX_HFI_PKT_SIZE * sizeof(unsigned int))
goto error_hfi_packet;
if (ptr->session_id != hash32_ptr(session))
if (ptr->session_id != inst->sess_id)
goto error_hfi_packet;
def_idx = get_pkt_index(ptr);

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/bitops.h>
@ -462,7 +462,7 @@ static struct msm_cvp_inst *cvp_get_inst_from_id(struct msm_cvp_core *core,
retry:
if (mutex_trylock(&core->lock)) {
list_for_each_entry(inst, &core->instances, list) {
if (hash32_ptr(inst->session) == session_id) {
if (inst->sess_id == session_id) {
match = true;
break;
}

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include "msm_cvp.h"
@ -14,6 +15,47 @@ struct cvp_power_level {
unsigned long bw_sum;
};
void *get_sessObj_from_idr(struct msm_cvp_inst *inst)
{
void *sessObj = NULL;
struct msm_cvp_core *core = NULL;
if (!inst || !inst->core) {
dprintk(CVP_ERR, "%s: invalid params\n", __func__);
return NULL;
}
core = inst->core;
mutex_lock(&core->idr_mtx);
sessObj = idr_find(&core->sess_idr, inst->sess_id);
mutex_unlock(&core->idr_mtx);
if (!sessObj)
dprintk(CVP_ERR, "%s: Could not find the sess obj for given idr id\n",
__func__);
return sessObj;
}
u32 get_sessId_from_idr(void *session)
{
void *ptr = NULL;
u32 sess_id = -1;
struct msm_cvp_core *core = NULL;
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
if (!session || !core)
return -EINVAL;
mutex_lock(&core->idr_mtx);
idr_for_each_entry(&core->sess_idr, ptr, sess_id) {
if (ptr == session) {
mutex_unlock(&core->idr_mtx);
return sess_id;
}
}
mutex_unlock(&core->idr_mtx);
return sess_id;
}
static int msm_cvp_get_session_info(struct msm_cvp_inst *inst,
struct cvp_kmd_session_info *session)
{
@ -30,7 +72,7 @@ static int msm_cvp_get_session_info(struct msm_cvp_inst *inst,
return -ECONNRESET;
s->cur_cmd_type = CVP_KMD_GET_SESSION_INFO;
session->session_id = hash32_ptr(inst->session);
session->session_id = inst->sess_id;
dprintk(CVP_SESS, "%s: id 0x%x\n", __func__, session->session_id);
s->cur_cmd_type = 0;
@ -699,6 +741,13 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst,
f->output_index = kfc->output_index;
}
if (f->num_fences >= (MAX_HFI_FENCE_SIZE / 2)) {
dprintk(CVP_ERR, "%s: Max number of fences exceeded! Max number supported: %d",
__func__, (MAX_HFI_FENCE_SIZE / 2));
cvp_free_fence_data(f);
msm_cvp_unmap_frame(inst, pkt->client_data.kdata);
goto exit;
}
dprintk(CVP_SYNX, "%s: frameID %llu ktid %llu\n",
__func__, f->frame_id, pkt->client_data.kdata);
@ -1227,7 +1276,7 @@ static int msm_cvp_session_stop(struct msm_cvp_inst *inst,
sq->state = QUEUE_STOP;
pr_info(CVP_DBG_TAG "Stop session: %pK session_id = %d\n",
"sess", inst, hash32_ptr(inst->session));
"sess", inst, inst->sess_id);
spin_unlock(&sq->lock);
wake_up_all(&inst->session_queue.wq);
@ -1251,7 +1300,7 @@ int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst)
sq->state = QUEUE_STOP;
dprintk(CVP_SESS, "Stop session queue: %pK session_id = %d\n",
inst, hash32_ptr(inst->session));
inst, inst->sess_id);
spin_unlock(&sq->lock);
wake_up_all(&inst->session_queue.wq);
@ -1551,7 +1600,7 @@ static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state)
ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1);
dprintk(CVP_SYNX, "%s: (%#x) flush frame %llu %llu wait_list\n",
__func__, hash32_ptr(inst->session), ktid, f->frame_id);
__func__, inst->sess_id, ktid, f->frame_id);
list_del_init(&f->list);
msm_cvp_unmap_frame(inst, f->pkt->client_data.kdata);
@ -1564,7 +1613,7 @@ static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state)
ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1);
dprintk(CVP_SYNX, "%s: (%#x)flush frame %llu %llu sched_list\n",
__func__, hash32_ptr(inst->session), ktid, f->frame_id);
__func__, inst->sess_id, ktid, f->frame_id);
cvp_cancel_synx(inst, CVP_INPUT_SYNX, f, synx_state);
}
@ -1612,14 +1661,14 @@ static int cvp_flush_all(struct msm_cvp_inst *inst)
return -ECONNRESET;
dprintk(CVP_SESS, "session %llx (%#x)flush all starts\n",
inst, hash32_ptr(inst->session));
inst, inst->sess_id);
q = &inst->fence_cmd_queue;
hdev = inst->core->device;
cvp_clean_fence_queue(inst, SYNX_STATE_SIGNALED_CANCEL);
dprintk(CVP_SESS, "%s: (%#x) send flush to fw\n",
__func__, hash32_ptr(inst->session));
__func__, inst->sess_id);
/* Send flush to FW */
rc = call_hfi_op(hdev, session_flush, (void *)inst->session);
@ -1636,7 +1685,7 @@ static int cvp_flush_all(struct msm_cvp_inst *inst)
__func__, rc);
dprintk(CVP_SESS, "%s: (%#x) received flush from fw\n",
__func__, hash32_ptr(inst->session));
__func__, inst->sess_id);
exit:
rc = cvp_drain_fence_sched_list(inst);
@ -1859,10 +1908,10 @@ int msm_cvp_session_deinit(struct msm_cvp_inst *inst)
return -EINVAL;
}
dprintk(CVP_SESS, "%s: inst %pK (%#x)\n", __func__,
inst, hash32_ptr(inst->session));
inst, inst->sess_id);
session = (struct cvp_hal_session *)inst->session;
if (!session)
session = (struct cvp_hal_session *)get_sessObj_from_idr(inst);
if (!session || session != inst->session)
return rc;
rc = msm_cvp_comm_try_state(inst, MSM_CVP_CLOSE_DONE);
@ -1883,7 +1932,7 @@ int msm_cvp_session_init(struct msm_cvp_inst *inst)
}
dprintk(CVP_SESS, "%s: inst %pK (%#x)\n", __func__,
inst, hash32_ptr(inst->session));
inst, inst->sess_id);
/* set default frequency */
inst->clk_data.core_id = 0;

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef _MSM_CVP_H_
@ -34,4 +35,6 @@ int msm_cvp_session_init(struct msm_cvp_inst *inst);
int msm_cvp_session_deinit(struct msm_cvp_inst *inst);
int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst);
int cvp_stop_clean_fence_queue(struct msm_cvp_inst *inst);
void *get_sessObj_from_idr(struct msm_cvp_inst *inst);
u32 get_sessId_from_idr(void *session);
#endif

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include "msm_cvp_common.h"
@ -14,7 +14,7 @@
do { \
clear_bit(idx, &inst->dma_cache.usage_bitmap); \
dprintk(CVP_MEM, "clear %x bit %d dma_cache bitmap 0x%llx\n", \
hash32_ptr(inst->session), smem->bitmap_index, \
inst->sess_id, smem->bitmap_index, \
inst->dma_cache.usage_bitmap); \
} while (0)
@ -22,7 +22,7 @@
do { \
set_bit(idx, &inst->dma_cache.usage_bitmap); \
dprintk(CVP_MEM, "Set %x bit %d dma_cache bitmap 0x%llx\n", \
hash32_ptr(inst->session), idx, \
inst->sess_id, idx, \
inst->dma_cache.usage_bitmap); \
} while (0)
@ -36,7 +36,7 @@ void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst,
if (smem->dma_buf) {
dprintk(tag,
"%s: %x : %s size %d flags %#x iova %#x idx %d ref %d",
str, hash32_ptr(inst->session), smem->dma_buf->name,
str, inst->sess_id, smem->dma_buf->name,
smem->size, smem->flags, smem->device_addr,
smem->bitmap_index, smem->refcount);
}
@ -51,13 +51,13 @@ static void print_internal_buffer(u32 tag, const char *str,
if (cbuf->smem->dma_buf) {
dprintk(tag,
"%s: %x : fd %d off %d %s size %d iova %#x",
str, hash32_ptr(inst->session), cbuf->fd,
str, inst->sess_id, cbuf->fd,
cbuf->offset, cbuf->smem->dma_buf->name, cbuf->size,
cbuf->smem->device_addr);
} else {
dprintk(tag,
"%s: %x : idx %2d fd %d off %d size %d iova %#x",
str, hash32_ptr(inst->session), cbuf->fd,
str, inst->sess_id, cbuf->fd,
cbuf->offset, cbuf->size, cbuf->smem->device_addr);
}
}
@ -77,7 +77,7 @@ void print_client_buffer(u32 tag, const char *str,
dprintk(tag,
"%s: %x : idx %2d fd %d off %d size %d type %d flags 0x%x\n",
str, hash32_ptr(inst->session), cbuf->index, cbuf->fd,
str, inst->sess_id, cbuf->index, cbuf->fd,
cbuf->offset, cbuf->size, cbuf->type, cbuf->flags);
}
@ -154,7 +154,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf)
}
if (buf->index) {
rc = cvp_dsp_register_buffer(hash32_ptr(session), buf->fd,
rc = cvp_dsp_register_buffer(inst->sess_id, buf->fd,
smem->dma_buf->size, buf->size, buf->offset,
buf->index, (uint32_t)smem->device_addr);
if (rc) {
@ -227,7 +227,7 @@ int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf)
}
if (buf->index) {
rc = cvp_dsp_deregister_buffer(hash32_ptr(session), buf->fd,
rc = cvp_dsp_deregister_buffer(inst->sess_id, buf->fd,
cbuf->smem->dma_buf->size, buf->size, buf->offset,
buf->index, (uint32_t)cbuf->smem->device_addr);
if (rc) {
@ -545,7 +545,7 @@ void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid)
ktid &= (FENCE_BIT - 1);
dprintk(CVP_MEM, "%s: (%#x) unmap frame %llu\n",
__func__, hash32_ptr(inst->session), ktid);
__func__, inst->sess_id, ktid);
found = false;
mutex_lock(&inst->frames.lock);
@ -587,7 +587,7 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst,
smem = pbuf->smem;
dprintk(CVP_MEM, "unmap persist: %x %d %d %#x",
hash32_ptr(inst->session), pbuf->fd,
inst->sess_id, pbuf->fd,
pbuf->size, smem->device_addr);
if (smem->bitmap_index >= MAX_DMABUF_NUMS) {
@ -785,7 +785,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst)
list_for_each_entry_safe(cbuf, dummy, &inst->cvpdspbufs.list,
list) {
print_internal_buffer(CVP_MEM, "remove dspbufs", inst, cbuf);
rc = cvp_dsp_deregister_buffer(hash32_ptr(session),
rc = cvp_dsp_deregister_buffer(inst->sess_id,
cbuf->fd, cbuf->smem->dma_buf->size, cbuf->size,
cbuf->offset, cbuf->index,
(uint32_t)cbuf->smem->device_addr);
@ -955,7 +955,7 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst)
if (buf->ownership == DRIVER) {
dprintk(CVP_MEM,
"%s: %x : fd %d %s size %d",
"free arp", hash32_ptr(inst->session), buf->fd,
"free arp", inst->sess_id, buf->fd,
smem->dma_buf->name, buf->size);
msm_cvp_smem_free(smem);
kmem_cache_free(cvp_driver->smem_cache, smem);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/jiffies.h>
@ -195,23 +196,31 @@ struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core,
{
int rc = 0;
struct cvp_hfi_device *hdev;
struct msm_cvp_inst *s;
struct msm_cvp_inst *inst;
void *sessObj = NULL;
s = cvp_get_inst(core, session_id);
if (!s) {
dprintk(CVP_ERR, "%s session doesn't exit\n",
inst = cvp_get_inst(core, session_id);
if (!inst) {
dprintk(CVP_ERR, "%s Inst doesn't exit\n",
__builtin_return_address(0));
return NULL;
}
hdev = s->core->device;
rc = call_hfi_op(hdev, validate_session, s->session, __func__);
if (rc) {
cvp_put_inst(s);
s = NULL;
sessObj = get_sessObj_from_idr(inst);
if (!sessObj || sessObj != inst->session) {
dprintk(CVP_ERR,
"Either sessionObj is null or not matching with inst->session\n");
return NULL;
}
return s;
hdev = inst->core->device;
rc = call_hfi_op(hdev, validate_session, sessObj, __func__);
if (rc) {
cvp_put_inst(inst);
inst = NULL;
}
return inst;
}
static void cvp_handle_session_cmd_done(enum hal_command_response cmd,
@ -486,7 +495,7 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data)
}
dprintk(CVP_SESS, "%s: cvp session %#x\n", __func__,
hash32_ptr(inst->session));
inst->sess_id);
signal_session_msg_receipt(cmd, inst);
cvp_put_inst(inst);
@ -568,7 +577,7 @@ static void handle_session_error(enum hal_command_response cmd, void *data)
hdev = inst->core->device;
dprintk(CVP_ERR, "Session error received for inst %pK session %x\n",
inst, hash32_ptr(inst->session));
inst, inst->sess_id);
if (response->status == CVP_ERR_MAX_CLIENTS) {
dprintk(CVP_WARN, "Too many clients, rejecting %pK", inst);
@ -901,7 +910,7 @@ static int msm_comm_session_abort(struct msm_cvp_inst *inst)
abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE);
dprintk(CVP_WARN, "%s: inst %pK session %x\n", __func__,
inst, hash32_ptr(inst->session));
inst, inst->sess_id);
rc = call_hfi_op(hdev, session_abort, (void *)inst->session);
if (rc) {
dprintk(CVP_ERR,
@ -914,7 +923,7 @@ static int msm_comm_session_abort(struct msm_cvp_inst *inst)
inst->core->resources.msm_cvp_hw_rsp_timeout));
if (!rc) {
dprintk(CVP_ERR, "%s: inst %pK session %x abort timed out\n",
__func__, inst, hash32_ptr(inst->session));
__func__, inst, inst->sess_id);
call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
dump_hfi_queue(hdev->hfi_device_data);
msm_cvp_comm_generate_sys_error(inst);
@ -1268,7 +1277,7 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state)
}
dprintk(CVP_SESS,
"Trying to move inst: %pK (%#x) from: %#x to %#x\n",
inst, hash32_ptr(inst->session), inst->state, state);
inst, inst->sess_id, inst->state, state);
mutex_lock(&inst->sync_lock);
if (inst->state == MSM_CVP_CORE_INVALID) {
@ -1281,7 +1290,7 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state)
flipped_state = get_flipped_state(inst->state, state);
dprintk(CVP_SESS,
"inst: %pK (%#x) flipped_state = %#x %x\n",
inst, hash32_ptr(inst->session), flipped_state, state);
inst, inst->sess_id, flipped_state, state);
switch (flipped_state) {
case MSM_CVP_CORE_UNINIT_DONE:
case MSM_CVP_CORE_INIT:
@ -1491,7 +1500,7 @@ int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst)
return 0;
}
dprintk(CVP_WARN, "%s: inst %pK, session %x state %d\n", __func__,
inst, hash32_ptr(inst->session), inst->state);
inst, inst->sess_id, inst->state);
/*
* We're internally forcibly killing the session, if fw is aware of
* the session send session_abort to firmware to clean up and release
@ -1503,7 +1512,7 @@ int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst)
if (rc) {
dprintk(CVP_ERR,
"%s: inst %pK session %x abort failed\n",
__func__, inst, hash32_ptr(inst->session));
__func__, inst, inst->sess_id);
change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID);
} else {
change_cvp_inst_state(inst, MSM_CVP_CORE_UNINIT);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/dma-direction.h>
@ -165,7 +166,7 @@ void *msm_cvp_open(int core_id, int session_type)
list_for_each_entry(inst, &core->instances, list)
dprintk(CVP_ERR, "inst %pK, cmd %d id %d\n",
inst, inst->cur_cmd_type,
hash32_ptr(inst->session));
inst->sess_id);
mutex_unlock(&core->lock);
return NULL;
@ -369,7 +370,7 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst)
synx_uninitialize(inst->synx_session_id);
pr_info(CVP_DBG_TAG "Closed cvp instance: %pK session_id = %d\n",
"sess", inst, hash32_ptr(inst->session));
"sess", inst, inst->sess_id);
if (inst->cur_cmd_type)
dprintk(CVP_ERR, "deleted instance has pending cmd %d\n",
inst->cur_cmd_type);

View file

@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef _MSM_CVP_INTERNAL_H_
@ -290,6 +291,8 @@ struct msm_cvp_core {
unsigned long curr_freq;
struct cvp_cycle_info dyn_clk;
atomic64_t kernel_trans_id;
struct idr sess_idr;
struct mutex idr_mtx;
};
struct msm_cvp_inst {
@ -301,6 +304,7 @@ struct msm_cvp_inst {
struct cvp_session_queue session_queue_fence;
struct cvp_session_event event_handler;
void *session;
u32 sess_id;
enum instance_state state;
struct msm_cvp_list freqs;
struct msm_cvp_list persistbufs;

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include "msm_cvp_common.h"
@ -20,7 +21,7 @@ void cvp_dump_fence_queue(struct msm_cvp_inst *inst)
ssid = inst->synx_session_id;
mutex_lock(&q->lock);
dprintk(CVP_WARN, "inst %x fence q mode %d, ssid %d\n",
hash32_ptr(inst->session), q->mode, ssid.client_id);
inst->sess_id, q->mode, ssid.client_id);
dprintk(CVP_WARN, "fence cmdq wait list:\n");
list_for_each_entry(f, &q->wait_list, list) {

View file

@ -27,8 +27,10 @@ static void event_seq_changed(struct venus_core *core, struct venus_inst *inst,
struct hfi_colour_space *colour_info;
struct hfi_buffer_requirements *bufreq;
struct hfi_extradata_input_crop *crop;
struct hfi_dpb_counts *dpb_count;
u32 ptype, rem_bytes;
u32 size_read = 0;
u8 *data_ptr;
u32 ptype;
inst->error = HFI_ERR_NONE;
@ -38,80 +40,120 @@ static void event_seq_changed(struct venus_core *core, struct venus_inst *inst,
break;
default:
inst->error = HFI_ERR_SESSION_INVALID_PARAMETER;
goto done;
inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
return;
}
event.event_type = pkt->event_data1;
num_properties_changed = pkt->event_data2;
if (!num_properties_changed) {
inst->error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;
goto done;
}
if (!num_properties_changed)
goto error;
data_ptr = (u8 *)&pkt->ext_event_data[0];
rem_bytes = pkt->shdr.hdr.size - sizeof(*pkt);
do {
if (rem_bytes < sizeof(u32))
goto error;
ptype = *((u32 *)data_ptr);
data_ptr += sizeof(u32);
rem_bytes -= sizeof(u32);
switch (ptype) {
case HFI_PROPERTY_PARAM_FRAME_SIZE:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_framesize))
goto error;
frame_sz = (struct hfi_framesize *)data_ptr;
event.width = frame_sz->width;
event.height = frame_sz->height;
data_ptr += sizeof(*frame_sz);
size_read = sizeof(struct hfi_framesize);
break;
case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_profile_level))
goto error;
profile_level = (struct hfi_profile_level *)data_ptr;
event.profile = profile_level->profile;
event.level = profile_level->level;
data_ptr += sizeof(*profile_level);
size_read = sizeof(struct hfi_profile_level);
break;
case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_bit_depth))
goto error;
pixel_depth = (struct hfi_bit_depth *)data_ptr;
event.bit_depth = pixel_depth->bit_depth;
data_ptr += sizeof(*pixel_depth);
size_read = sizeof(struct hfi_bit_depth);
break;
case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_pic_struct))
goto error;
pic_struct = (struct hfi_pic_struct *)data_ptr;
event.pic_struct = pic_struct->progressive_only;
data_ptr += sizeof(*pic_struct);
size_read = sizeof(struct hfi_pic_struct);
break;
case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_colour_space))
goto error;
colour_info = (struct hfi_colour_space *)data_ptr;
event.colour_space = colour_info->colour_space;
data_ptr += sizeof(*colour_info);
size_read = sizeof(struct hfi_colour_space);
break;
case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(u32))
goto error;
event.entropy_mode = *(u32 *)data_ptr;
data_ptr += sizeof(u32);
size_read = sizeof(u32);
break;
case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_buffer_requirements))
goto error;
bufreq = (struct hfi_buffer_requirements *)data_ptr;
event.buf_count = HFI_BUFREQ_COUNT_MIN(bufreq, ver);
data_ptr += sizeof(*bufreq);
event.buf_count = hfi_bufreq_get_count_min(bufreq, ver);
size_read = sizeof(struct hfi_buffer_requirements);
break;
case HFI_INDEX_EXTRADATA_INPUT_CROP:
data_ptr += sizeof(u32);
if (rem_bytes < sizeof(struct hfi_extradata_input_crop))
goto error;
crop = (struct hfi_extradata_input_crop *)data_ptr;
event.input_crop.left = crop->left;
event.input_crop.top = crop->top;
event.input_crop.width = crop->width;
event.input_crop.height = crop->height;
data_ptr += sizeof(*crop);
size_read = sizeof(struct hfi_extradata_input_crop);
break;
case HFI_PROPERTY_PARAM_VDEC_DPB_COUNTS:
if (rem_bytes < sizeof(struct hfi_dpb_counts))
goto error;
dpb_count = (struct hfi_dpb_counts *)data_ptr;
event.buf_count = dpb_count->fw_min_cnt;
size_read = sizeof(struct hfi_dpb_counts);
break;
default:
size_read = 0;
break;
}
data_ptr += size_read;
rem_bytes -= size_read;
num_properties_changed--;
} while (num_properties_changed > 0);
done:
inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
return;
error:
inst->error = HFI_ERR_SESSION_INSUFFICIENT_RESOURCES;
inst->ops->event_notify(inst, EVT_SYS_EVENT_CHANGE, &event);
}

View file

@ -2,7 +2,7 @@
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include "msm_qpic_nand.h"
@ -1944,7 +1944,7 @@ free_dma:
if (last_pos < ecc_bytes_percw_in_bits)
num_zero_bits++;
if (num_zero_bits > 4) {
if (num_zero_bits > info->flash_dev.ecc_capability) {
*erased_page = false;
goto free_mem;
}
@ -1955,8 +1955,8 @@ free_dma:
num_zero_bits = last_pos = next_pos = 0;
ecc_temp += chip->ecc_parity_bytes;
}
if ((n == cwperpage) && (num_zero_bits <= 4))
if ((n == cwperpage) &&
(num_zero_bits <= info->flash_dev.ecc_capability))
*erased_page = true;
free_mem:
kfree(ecc);
@ -2163,6 +2163,33 @@ static int msm_nand_read_pagescope(struct mtd_info *mtd, loff_t from,
goto free_dma;
/* Check for flash status errors */
pageerr = rawerr = 0;
/*
* PAGE_ERASED bit will set only if all
* CODEWORD_ERASED bit of all codewords
* of the page is set.
*
* PAGE_ERASED bit is a 'logical and' of all
* CODEWORD_ERASED bit of all codewords i.e.
* even if one codeword is detected as not
* an erased codeword, PAGE_ERASED bit will unset.
*/
for (n = rw_params.start_sector; n < cwperpage; n++) {
if ((dma_buffer->result[n].erased_cw_status &
(1 << PAGE_ERASED)) &&
(dma_buffer->result[n].buffer_status &
NUM_ERRORS)) {
err = msm_nand_is_erased_page_ps(mtd,
from, ops,
&rw_params,
&erased_page);
if (err)
goto free_dma;
if (erased_page)
rawerr = -EIO;
break;
}
}
for (n = rw_params.start_sector; n < cwperpage; n++) {
if (dma_buffer->result[n].flash_status & (FS_OP_ERR |
FS_MPU_ERR)) {
@ -2554,7 +2581,7 @@ free_dma:
if (last_pos < ecc_bytes_percw_in_bits)
num_zero_bits++;
if (num_zero_bits > 4) {
if (num_zero_bits > info->flash_dev.ecc_capability) {
*erased_page = false;
goto free_mem;
}
@ -2566,7 +2593,8 @@ free_dma:
ecc_temp += chip->ecc_parity_bytes;
}
if ((n == cwperpage) && (num_zero_bits <= 4))
if ((n == cwperpage) &&
(num_zero_bits <= info->flash_dev.ecc_capability))
*erased_page = true;
free_mem:
kfree(ecc);
@ -2760,6 +2788,33 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from,
goto free_dma;
/* Check for flash status errors */
pageerr = rawerr = 0;
/*
* PAGE_ERASED bit will set only if all
* CODEWORD_ERASED bit of all codewords
* of the page is set.
*
* PAGE_ERASED bit is a 'logical and' of all
* CODEWORD_ERASED bit of all codewords i.e.
* even if one codeword is detected as not
* an erased codeword, PAGE_ERASED bit will unset.
*/
for (n = rw_params.start_sector; n < cwperpage; n++) {
if ((dma_buffer->result[n].erased_cw_status &
(1 << PAGE_ERASED)) &&
(dma_buffer->result[n].buffer_status &
NUM_ERRORS)) {
err = msm_nand_is_erased_page(mtd,
from, ops,
&rw_params,
&erased_page);
if (err)
goto free_dma;
if (erased_page)
rawerr = -EIO;
break;
}
}
for (n = rw_params.start_sector; n < cwperpage; n++) {
if (dma_buffer->result[n].flash_status & (FS_OP_ERR |
FS_MPU_ERR)) {

View file

@ -154,7 +154,10 @@
#define RESET_ERASED_DET (1 << AUTO_DETECT_RES)
#define ACTIVE_ERASED_DET (0 << AUTO_DETECT_RES)
#define CLR_ERASED_PAGE_DET (RESET_ERASED_DET | MASK_ECC)
#define SET_ERASED_PAGE_DET (ACTIVE_ERASED_DET | MASK_ECC)
#define SET_ERASED_PAGE_DET (ACTIVE_ERASED_DET | MASK_ECC | SET_N_MAX_ZEROS)
#define N_MAX_ZEROS 2
#define MAX_ECC_BIT_FLIPS 4
#define SET_N_MAX_ZEROS (MAX_ECC_BIT_FLIPS << N_MAX_ZEROS)
#define MSM_NAND_ERASED_CW_DETECT_STATUS(info) MSM_NAND_REG(info, 0x300EC)
#define PAGE_ALL_ERASED 7
@ -163,6 +166,7 @@
#define CODEWORD_ERASED 4
#define ERASED_PAGE ((1 << PAGE_ALL_ERASED) | (1 << PAGE_ERASED))
#define ERASED_CW ((1 << CODEWORD_ALL_ERASED) | (1 << CODEWORD_ERASED))
#define NUM_ERRORS 0x1f
#define MSM_NAND_CTRL(info) MSM_NAND_REG(info, 0x30F00)
#define BAM_MODE_EN 0

View file

@ -3,7 +3,9 @@
# Makefile for CNSS platform driver
#
obj-$(CONFIG_CNSS_PCI) += cnss_pci.o
obj-$(CONFIG_CNSS_SDIO) += cnss_sdio.o
obj-$(CONFIG_CNSS) += cnss_common.o
obj-$(CONFIG_CNSS_LOGGER) += logger/
obj-$(CONFIG_CNSS) += cnss.o
cnss-$(CONFIG_CNSS_PCI) += cnss_pci.o
cnss-$(CONFIG_CNSS_SDIO) += cnss_sdio.o
cnss-y += cnss_common.o
obj-$(CONFIG_CNSS_LOGGER) += logger/

View file

@ -242,13 +242,21 @@ int cnss_set_cpus_allowed_ptr(struct task_struct *task, ulong cpu)
}
EXPORT_SYMBOL(cnss_set_cpus_allowed_ptr);
/* wlan prop driver cannot invoke show_stack
* function directly, so to invoke this function it
* call wcnss_dump_stack function
*/
#define ENTRIES_COUNT 32
void cnss_dump_stack(struct task_struct *task)
{
show_stack(task, NULL);
const int cnss_spaces = 4;
unsigned long cnss_entries[ENTRIES_COUNT] = {0};
struct stack_trace cnss_trace = {
.nr_entries = 0,
.skip = 0,
.entries = &cnss_entries[0],
.max_entries = ENTRIES_COUNT,
};
save_stack_trace_tsk(task, &cnss_trace);
stack_trace_print(cnss_entries, cnss_trace.nr_entries,
cnss_spaces);
}
EXPORT_SYMBOL(cnss_dump_stack);

View file

@ -31,6 +31,8 @@
#include <linux/log2.h>
#include <linux/etherdevice.h>
#include <linux/msm_pcie.h>
#include <linux/of_reserved_mem.h>
#include <linux/cma.h>
#include <soc/qcom/subsystem_restart.h>
#include <soc/qcom/subsystem_notif.h>
#include <soc/qcom/ramdump.h>
@ -1618,6 +1620,43 @@ static void cnss_pcie_reset_platform_ops(struct device *dev)
dev->platform_data = NULL;
}
#if IS_ENABLED(CONFIG_ARCH_QCOM)
/**
* cnss_pci_of_reserved_mem_device_init() - Assign reserved memory region
* to given PCI device
* @pdev: context pointer of pdev
*
* This function shall call corresponding of_reserved_mem_device* API to
* assign reserved memory region to PCI device based on where the memory is
* defined and attached to (platform device of_node or PCI device of_node)
* in device tree.
*
* Return: 0 for success, negative value for error
*/
static int cnss_pci_of_reserved_mem_device_init(struct pci_dev *pdev)
{
struct device *dev_pci = &pdev->dev;
int ret;
/* Use of_reserved_mem_device_init_by_idx() if reserved memory is
* attached to platform device of_node.
*/
ret = of_reserved_mem_device_init(dev_pci);
if (ret)
pr_err("Failed to init reserved mem device, err = %d\n",
ret);
if (dev_pci->cma_area)
pr_debug("CMA area is %s\n", cma_get_name(dev_pci->cma_area));
return ret;
}
#else
static int cnss_pci_of_reserved_mem_device_init(struct pci_dev *pdev)
{
return 0;
}
#endif
static int cnss_wlan_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
@ -1634,6 +1673,7 @@ static int cnss_wlan_pci_probe(struct pci_dev *pdev,
atomic_set(&penv->fw_available, 0);
penv->device_id = pdev->device;
cnss_pci_of_reserved_mem_device_init(pdev);
if (penv->smmu_iova_len) {
ret = cnss_smmu_init(&pdev->dev);
if (ret) {

View file

@ -222,6 +222,7 @@ int qtnf_cmd_send_start_ap(struct qtnf_vif *vif,
struct qlink_auth_encr *aen;
int ret;
int i;
int n;
if (!qtnf_cmd_start_ap_can_fit(vif, s))
return -E2BIG;
@ -253,8 +254,9 @@ int qtnf_cmd_send_start_ap(struct qtnf_vif *vif,
for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++)
aen->ciphers_pairwise[i] =
cpu_to_le32(s->crypto.ciphers_pairwise[i]);
aen->n_akm_suites = cpu_to_le32(s->crypto.n_akm_suites);
for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++)
n = min(QLINK_MAX_NR_AKM_SUITES, s->crypto.n_akm_suites);
aen->n_akm_suites = cpu_to_le32(n);
for (i = 0; i < n; i++)
aen->akm_suites[i] = cpu_to_le32(s->crypto.akm_suites[i]);
aen->control_port = s->crypto.control_port;
aen->control_port_no_encrypt = s->crypto.control_port_no_encrypt;
@ -2200,6 +2202,7 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif,
struct qlink_auth_encr *aen;
int ret;
int i;
int n;
u32 connect_flags = 0;
cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
@ -2256,9 +2259,10 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif,
aen->ciphers_pairwise[i] =
cpu_to_le32(sme->crypto.ciphers_pairwise[i]);
aen->n_akm_suites = cpu_to_le32(sme->crypto.n_akm_suites);
n = min(QLINK_MAX_NR_AKM_SUITES, sme->crypto.n_akm_suites);
aen->n_akm_suites = cpu_to_le32(n);
for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++)
for (i = 0; i < n; i++)
aen->akm_suites[i] = cpu_to_le32(sme->crypto.akm_suites[i]);
aen->control_port = sme->crypto.control_port;

View file

@ -2179,6 +2179,11 @@ int ep_pcie_core_disable_endpoint(void)
if (atomic_read(&dev->host_wake_pending)) {
EP_PCIE_DBG(dev, "PCIe V%d: wake pending, init wakeup\n",
dev->rev);
/*
* Clear the wake pending otherwise ep_pcie_core_wakeup_host_internal
* will return without WAKE toggle
*/
atomic_set(&dev->host_wake_pending, 0);
ep_pcie_core_wakeup_host_internal(EP_PCIE_EVENT_PM_D3_COLD);
}

View file

@ -39,7 +39,7 @@
/* Wait time on the device for Host to set BHI_INTVEC */
#define MHI_BHI_INTVEC_MAX_CNT 200
#define MHI_BHI_INTVEC_WAIT_MS 50
#define MHI_WAKEUP_TIMEOUT_CNT 20
#define MHI_WAKEUP_TIMEOUT_CNT 25
#define MHI_MASK_CH_EV_LEN 32
#define MHI_RING_CMD_ID 0
#define MHI_RING_PRIMARY_EVT_ID 1

View file

@ -12,6 +12,7 @@
#include "mhi_hwio.h"
#include "mhi_sm.h"
#include <linux/interrupt.h>
#include <linux/delay.h>
#define MHI_SM_DBG(fmt, args...) \
mhi_log(MHI_MSG_DBG, fmt, ##args)
@ -28,7 +29,11 @@
#define PCIE_EP_TIMER_US 500000000
#define MHI_IPA_DISABLE_DELAY_MS 10
#define MHI_IPA_DISABLE_COUNTER 20
/* Maximum wait time for D state transitions to D3hot */
#define M3_DO_WAKEUP_TIMEOUT_MS 2500
static void wait_d3_and_wakeup(struct work_struct *work);
static int mhi_dev_sm_get_mhi_pcie_states(uint32_t *mstate, uint32_t *dstate);
static inline const char *mhi_sm_dev_event_str(enum mhi_dev_event state)
{
@ -235,6 +240,8 @@ struct mhi_sm_dev {
struct mutex mhi_state_lock;
bool syserr_occurred;
struct workqueue_struct *mhi_sm_wq;
struct workqueue_struct *mhi_wake_wq;
struct work_struct mhi_wake_work;
atomic_t pending_device_events;
atomic_t pending_pcie_events;
struct mhi_sm_stats stats;
@ -734,12 +741,12 @@ exit:
* mhi_sm_wakeup_host() - wakeup MHI-host
*@event: MHI state chenge event
*
* Sends wekup event to MHI-host via EP-PCIe, in case MHI is in M3 state.
* Sends wakeup event to MHI-host via EP-PCIe, in case MHI is in M3 state.
*
* Return: 0:success
* negative: failure
*/
static int mhi_sm_wakeup_host(enum mhi_dev_event event)
static int mhi_sm_wakeup_host(void)
{
int res = 0;
enum ep_pcie_event pcie_event;
@ -754,7 +761,8 @@ static int mhi_sm_wakeup_host(enum mhi_dev_event event)
} else if (mhi_sm_ctx->mhi_state == MHI_DEV_M3_STATE) {
/*
* Check and send D3_HOT to enable waking up the host
* using inband PME.
* using inband PME if the host is in D3_HOT state, otherwise
* send D3_COLD to wake up the host.
*/
if (mhi_sm_ctx->d_state == MHI_SM_EP_PCIE_D3_HOT_STATE)
pcie_event = EP_PCIE_EVENT_PM_D3_HOT;
@ -906,9 +914,7 @@ static void mhi_sm_dev_event_manager(struct work_struct *work)
break;
case MHI_DEV_EVENT_HW_ACC_WAKEUP:
case MHI_DEV_EVENT_CORE_WAKEUP:
res = mhi_sm_wakeup_host(chg_event->event);
if (res)
MHI_SM_ERR("Failed to wakeup MHI host\n");
queue_work(mhi_sm_ctx->mhi_wake_wq, &mhi_sm_ctx->mhi_wake_work);
break;
case MHI_DEV_EVENT_CTRL_TRIG:
case MHI_DEV_EVENT_M1_STATE:
@ -1119,9 +1125,19 @@ int mhi_dev_sm_init(struct mhi_dev *mhi_dev)
if (!mhi_sm_ctx->mhi_sm_wq) {
MHI_SM_ERR("Failed to create singlethread_workqueue: sm_wq\n");
res = -ENOMEM;
goto fail_init_wq;
goto fail_init_sm_wq;
}
if (!mhi_sm_ctx->mhi_wake_wq)
mhi_sm_ctx->mhi_wake_wq = alloc_workqueue(
"mhi_wake_wq", WQ_HIGHPRI | WQ_UNBOUND, 1);
if (!mhi_sm_ctx->mhi_wake_wq) {
MHI_SM_ERR("Failed to create singlethread_workqueue: wake_wq\n");
res = -ENOMEM;
goto fail_init_wake_wq;
}
INIT_WORK(&mhi_sm_ctx->mhi_wake_work, wait_d3_and_wakeup);
mutex_init(&mhi_sm_ctx->mhi_state_lock);
mhi_sm_ctx->mhi_dev = mhi_dev;
mhi_sm_ctx->mhi_state = MHI_DEV_RESET_STATE;
@ -1134,7 +1150,10 @@ int mhi_dev_sm_init(struct mhi_dev *mhi_dev)
MHI_SM_FUNC_EXIT();
return 0;
fail_init_wq:
fail_init_wake_wq:
flush_workqueue(mhi_sm_ctx->mhi_sm_wq);
destroy_workqueue(mhi_sm_ctx->mhi_sm_wq);
fail_init_sm_wq:
mhi_sm_ctx = NULL;
mhi_sm_debugfs_destroy();
return res;
@ -1162,20 +1181,20 @@ int mhi_dev_sm_exit(struct mhi_dev *mhi_dev)
EXPORT_SYMBOL(mhi_dev_sm_exit);
/**
* mhi_dev_sm_get_mhi_state() -Get current MHI state.
* mhi_dev_sm_get_mhi_pcie_states() -Get current MHI and Pcie states.
* @state: return param
*
* Returns the current MHI state of the state machine.
* Returns the current MHI and PCIe states of the state machine.
*
* Return: 0 success
* -EINVAL: invalid param
* -EFAULT: state machine isn't initialized
*/
int mhi_dev_sm_get_mhi_state(enum mhi_dev_state *state)
static int mhi_dev_sm_get_mhi_pcie_states(uint32_t *mstate, uint32_t *dstate)
{
MHI_SM_FUNC_ENTRY();
if (!state) {
if (!mstate || !dstate) {
MHI_SM_ERR("Fail: Null argument\n");
return -EINVAL;
}
@ -1183,15 +1202,60 @@ int mhi_dev_sm_get_mhi_state(enum mhi_dev_state *state)
MHI_SM_ERR("Fail: MHI SM is not initialized\n");
return -EFAULT;
}
*state = mhi_sm_ctx->mhi_state;
mutex_lock(&mhi_sm_ctx->mhi_state_lock);
*mstate = mhi_sm_ctx->mhi_state;
*dstate = mhi_sm_ctx->d_state;
mutex_unlock(&mhi_sm_ctx->mhi_state_lock);
MHI_SM_DBG("state machine states are: %s and %s\n",
mhi_sm_mstate_str(*state),
mhi_sm_dstate_str(mhi_sm_ctx->d_state));
mhi_sm_mstate_str(*mstate),
mhi_sm_dstate_str(*dstate));
MHI_SM_FUNC_EXIT();
return 0;
}
EXPORT_SYMBOL(mhi_dev_sm_get_mhi_state);
static void wait_d3_and_wakeup(struct work_struct *work)
{
struct mhi_sm_dev *mhi_sm_ctx = container_of(work, struct mhi_sm_dev, mhi_wake_work);
enum mhi_dev_state mstate;
enum mhi_sm_ep_pcie_state dstate;
ktime_t timeout = 0;
if (mhi_dev_sm_get_mhi_pcie_states(&mstate, &dstate)) {
MHI_SM_ERR("Unable to read states\n");
return;
}
/*
* Handle host wakeup in M3 + D0 states.
* When a MHI WAKE request is received while device is in D0,
* wait for D3 and wakeup the host using inband PME.
* If the MHI state changes to M0 while waiting for D3,
* exit, since both MHI and the device are in active state
*/
if (dstate == MHI_SM_EP_PCIE_D0_STATE) {
timeout = ktime_add_ms(ktime_get(), M3_DO_WAKEUP_TIMEOUT_MS);
while (1) {
mhi_dev_sm_get_mhi_pcie_states(&mstate, &dstate);
if (mstate == MHI_DEV_M0_STATE) {
MHI_SM_DBG("M0 state received\n");
return;
}
if (dstate == MHI_SM_EP_PCIE_D3_HOT_STATE ||
dstate == MHI_SM_EP_PCIE_D3_COLD_STATE) {
MHI_SM_DBG("D3 state received\n");
goto send_host_wakeup;
}
if (ktime_after(ktime_get(), timeout)) {
MHI_SM_ERR("Neither received D3 nor M0 in stipulated time\n");
return;
}
usleep_range(1000, 2000);
}
}
send_host_wakeup:
if (dstate == MHI_SM_EP_PCIE_D3_HOT_STATE || dstate == MHI_SM_EP_PCIE_D3_COLD_STATE)
mhi_sm_wakeup_host();
}
/**
* mhi_dev_sm_set_ready() -Set MHI state to ready.

View file

@ -42,7 +42,6 @@ int mhi_dev_sm_init(struct mhi_dev *dev);
int mhi_dev_sm_exit(struct mhi_dev *dev);
int mhi_dev_sm_set_ready(void);
int mhi_dev_notify_sm_event(enum mhi_dev_event event);
int mhi_dev_sm_get_mhi_state(enum mhi_dev_state *state);
int mhi_dev_sm_syserr(void);
void mhi_dev_sm_pcie_handler(struct ep_pcie_notify *notify);

View file

@ -984,6 +984,94 @@ cleanup:
return ret;
}
static void cxacru_upload_firmware(struct cxacru_data *instance,
const struct firmware *fw,
const struct firmware *bp)
{
int ret;
struct usbatm_data *usbatm = instance->usbatm;
struct usb_device *usb_dev = usbatm->usb_dev;
__le16 signature[] = { usb_dev->descriptor.idVendor,
usb_dev->descriptor.idProduct };
__le32 val;
usb_dbg(usbatm, "%s\n", __func__);
/* FirmwarePllFClkValue */
val = cpu_to_le32(instance->modem_type->pll_f_clk);
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4);
if (ret) {
usb_err(usbatm, "FirmwarePllFClkValue failed: %d\n", ret);
return;
}
/* FirmwarePllBClkValue */
val = cpu_to_le32(instance->modem_type->pll_b_clk);
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4);
if (ret) {
usb_err(usbatm, "FirmwarePllBClkValue failed: %d\n", ret);
return;
}
/* Enable SDRAM */
val = cpu_to_le32(SDRAM_ENA);
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4);
if (ret) {
usb_err(usbatm, "Enable SDRAM failed: %d\n", ret);
return;
}
/* Firmware */
usb_info(usbatm, "loading firmware\n");
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size);
if (ret) {
usb_err(usbatm, "Firmware upload failed: %d\n", ret);
return;
}
/* Boot ROM patch */
if (instance->modem_type->boot_rom_patch) {
usb_info(usbatm, "loading boot ROM patch\n");
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size);
if (ret) {
usb_err(usbatm, "Boot ROM patching failed: %d\n", ret);
return;
}
}
/* Signature */
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) signature, 4);
if (ret) {
usb_err(usbatm, "Signature storing failed: %d\n", ret);
return;
}
usb_info(usbatm, "starting device\n");
if (instance->modem_type->boot_rom_patch) {
val = cpu_to_le32(BR_ADDR);
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4);
} else {
ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0);
}
if (ret) {
usb_err(usbatm, "Passing control to firmware failed: %d\n", ret);
return;
}
/* Delay to allow firmware to start up. */
msleep_interruptible(1000);
usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD));
usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD));
usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_DATA));
usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_DATA));
ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
if (ret < 0) {
usb_err(usbatm, "modem failed to initialize: %d\n", ret);
return;
}
}
static int cxacru_find_firmware(struct cxacru_data *instance,
char *phase, const struct firmware **fw_p)
@ -1010,14 +1098,8 @@ static int cxacru_heavy_init(struct usbatm_data *usbatm_instance,
{
const struct firmware *fw, *bp;
struct cxacru_data *instance = usbatm_instance->driver_data;
struct usbatm_data *usbatm = instance->usbatm;
struct usb_device *usb_dev = usbatm->usb_dev;
__le16 signature[] = { usb_dev->descriptor.idVendor,
usb_dev->descriptor.idProduct };
__le32 val;
int ret;
int ret = cxacru_find_firmware(instance, "fw", &fw);
ret = cxacru_find_firmware(instance, "fw", &fw);
if (ret) {
usb_warn(usbatm_instance, "firmware (cxacru-fw.bin) unavailable (system misconfigured?)\n");
return ret;
@ -1032,82 +1114,8 @@ static int cxacru_heavy_init(struct usbatm_data *usbatm_instance,
}
}
/* FirmwarePllFClkValue */
val = cpu_to_le32(instance->modem_type->pll_f_clk);
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4);
if (ret) {
usb_err(usbatm, "FirmwarePllFClkValue failed: %d\n", ret);
goto done;
}
cxacru_upload_firmware(instance, fw, bp);
/* FirmwarePllBClkValue */
val = cpu_to_le32(instance->modem_type->pll_b_clk);
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4);
if (ret) {
usb_err(usbatm, "FirmwarePllBClkValue failed: %d\n", ret);
goto done;
}
/* Enable SDRAM */
val = cpu_to_le32(SDRAM_ENA);
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4);
if (ret) {
usb_err(usbatm, "Enable SDRAM failed: %d\n", ret);
goto done;
}
/* Firmware */
usb_info(usbatm, "loading firmware\n");
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size);
if (ret) {
usb_err(usbatm, "Firmware upload failed: %d\n", ret);
goto done;
}
/* Boot ROM patch */
if (instance->modem_type->boot_rom_patch) {
usb_info(usbatm, "loading boot ROM patch\n");
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size);
if (ret) {
usb_err(usbatm, "Boot ROM patching failed: %d\n", ret);
goto done;
}
}
/* Signature */
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) signature, 4);
if (ret) {
usb_err(usbatm, "Signature storing failed: %d\n", ret);
goto done;
}
usb_info(usbatm, "starting device\n");
if (instance->modem_type->boot_rom_patch) {
val = cpu_to_le32(BR_ADDR);
ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_STACK_ADDR, (u8 *) &val, 4);
} else {
ret = cxacru_fw(usb_dev, FW_GOTO_MEM, 0x0, 0x0, FW_ADDR, NULL, 0);
}
if (ret) {
usb_err(usbatm, "Passing control to firmware failed: %d\n", ret);
goto done;
}
/* Delay to allow firmware to start up. */
msleep_interruptible(1000);
usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_CMD));
usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_CMD));
usb_clear_halt(usb_dev, usb_sndbulkpipe(usb_dev, CXACRU_EP_DATA));
usb_clear_halt(usb_dev, usb_rcvbulkpipe(usb_dev, CXACRU_EP_DATA));
ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
if (ret < 0) {
usb_err(usbatm, "modem failed to initialize: %d\n", ret);
goto done;
}
done:
if (instance->modem_type->boot_rom_patch)
release_firmware(bp);
release_firmware(fw);
@ -1127,10 +1135,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
struct cxacru_data *instance;
struct usb_device *usb_dev = interface_to_usbdev(intf);
struct usb_host_endpoint *cmd_ep = usb_dev->ep_in[CXACRU_EP_CMD];
static const u8 ep_addrs[] = {
CXACRU_EP_CMD + USB_DIR_IN,
CXACRU_EP_CMD + USB_DIR_OUT,
0};
struct usb_endpoint_descriptor *in, *out;
int ret;
/* instance init */
@ -1178,11 +1183,13 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
}
if (usb_endpoint_xfer_int(&cmd_ep->desc))
ret = usb_check_int_endpoints(intf, ep_addrs);
ret = usb_find_common_endpoints(intf->cur_altsetting,
NULL, NULL, &in, &out);
else
ret = usb_check_bulk_endpoints(intf, ep_addrs);
ret = usb_find_common_endpoints(intf->cur_altsetting,
&in, &out, NULL, NULL);
if (!ret) {
if (ret) {
usb_err(usbatm_instance, "cxacru_bind: interface has incorrect endpoints\n");
ret = -ENODEV;
goto fail;

View file

@ -1920,7 +1920,6 @@ static int cdns3_gadget_ep_disable(struct usb_ep *ep)
"%s is already disabled\n", priv_ep->name))
return 0;
local_bh_disable();
spin_lock_irqsave(&priv_dev->lock, flags);
trace_cdns3_gadget_ep_disable(priv_ep);
@ -1977,7 +1976,6 @@ static int cdns3_gadget_ep_disable(struct usb_ep *ep)
priv_ep->flags &= ~EP_ENABLED;
spin_unlock_irqrestore(&priv_dev->lock, flags);
local_bh_enable();
return ret;
}

View file

@ -277,19 +277,8 @@ static inline int ci_role_start(struct ci_hdrc *ci, enum ci_role role)
return -ENXIO;
ret = ci->roles[role]->start(ci);
if (ret)
return ret;
ci->role = role;
if (ci->usb_phy) {
if (role == CI_ROLE_HOST)
usb_phy_set_event(ci->usb_phy, USB_EVENT_ID);
else
/* in device mode but vbus is invalid*/
usb_phy_set_event(ci->usb_phy, USB_EVENT_NONE);
}
if (!ret)
ci->role = role;
return ret;
}
@ -303,9 +292,6 @@ static inline void ci_role_stop(struct ci_hdrc *ci)
ci->role = CI_ROLE_END;
ci->roles[role]->stop(ci);
if (ci->usb_phy)
usb_phy_set_event(ci->usb_phy, USB_EVENT_NONE);
}
static inline enum usb_role ci_role_to_usb_role(struct ci_hdrc *ci)

View file

@ -340,11 +340,11 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
pdata.flags |= CI_HDRC_IMX_IS_HSIC;
data->usbmisc_data->hsic = 1;
data->pinctrl = devm_pinctrl_get(dev);
if (PTR_ERR(data->pinctrl) == -ENODEV)
data->pinctrl = NULL;
else if (IS_ERR(data->pinctrl))
return dev_err_probe(dev, PTR_ERR(data->pinctrl),
"pinctrl get failed\n");
if (IS_ERR(data->pinctrl)) {
dev_err(dev, "pinctrl get failed, err=%ld\n",
PTR_ERR(data->pinctrl));
return PTR_ERR(data->pinctrl);
}
pinctrl_hsic_idle = pinctrl_lookup_state(data->pinctrl, "idle");
if (IS_ERR(pinctrl_hsic_idle)) {
@ -369,14 +369,17 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
return PTR_ERR(data->pinctrl_hsic_active);
}
data->hsic_pad_regulator =
devm_regulator_get_optional(dev, "hsic");
if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) {
data->hsic_pad_regulator = devm_regulator_get(dev, "hsic");
if (PTR_ERR(data->hsic_pad_regulator) == -EPROBE_DEFER) {
return -EPROBE_DEFER;
} else if (PTR_ERR(data->hsic_pad_regulator) == -ENODEV) {
/* no pad regualator is needed */
data->hsic_pad_regulator = NULL;
} else if (IS_ERR(data->hsic_pad_regulator))
return dev_err_probe(dev, PTR_ERR(data->hsic_pad_regulator),
"Get HSIC pad regulator error\n");
} else if (IS_ERR(data->hsic_pad_regulator)) {
dev_err(dev, "Get HSIC pad regulator error: %ld\n",
PTR_ERR(data->hsic_pad_regulator));
return PTR_ERR(data->hsic_pad_regulator);
}
if (data->hsic_pad_regulator) {
ret = regulator_enable(data->hsic_pad_regulator);
@ -417,11 +420,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) {
pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL;
data->override_phy_control = true;
ret = usb_phy_init(pdata.usb_phy);
if (ret) {
dev_err(dev, "Failed to init phy\n");
goto err_clk;
}
usb_phy_init(pdata.usb_phy);
}
if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM)
@ -430,7 +429,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
ret = imx_usbmisc_init(data->usbmisc_data);
if (ret) {
dev_err(dev, "usbmisc init failed, ret=%d\n", ret);
goto phy_shutdown;
goto err_clk;
}
data->ci_pdev = ci_hdrc_add_device(dev,
@ -438,8 +437,10 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
&pdata);
if (IS_ERR(data->ci_pdev)) {
ret = PTR_ERR(data->ci_pdev);
dev_err_probe(dev, ret, "ci_hdrc_add_device failed\n");
goto phy_shutdown;
if (ret != -EPROBE_DEFER)
dev_err(dev, "ci_hdrc_add_device failed, err=%d\n",
ret);
goto err_clk;
}
ret = imx_usbmisc_init_post(data->usbmisc_data);
@ -459,9 +460,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
disable_device:
ci_hdrc_remove_device(data->ci_pdev);
phy_shutdown:
if (data->override_phy_control)
usb_phy_shutdown(data->phy);
err_clk:
imx_disable_unprepare_clks(dev);
disable_hsic_regulator:

View file

@ -1533,68 +1533,44 @@ static const struct usb_ep_ops usb_ep_ops = {
/******************************************************************************
* GADGET block
*****************************************************************************/
/**
* ci_hdrc_gadget_connect: caller makes sure gadget driver is binded
*/
static void ci_hdrc_gadget_connect(struct usb_gadget *_gadget, int is_active)
{
struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget);
if (is_active) {
pm_runtime_get_sync(&_gadget->dev);
hw_device_reset(ci);
spin_lock_irq(&ci->lock);
if (ci->driver) {
hw_device_state(ci, ci->ep0out->qh.dma);
usb_gadget_set_state(_gadget, USB_STATE_POWERED);
spin_unlock_irq(&ci->lock);
usb_udc_vbus_handler(_gadget, true);
} else {
spin_unlock_irq(&ci->lock);
}
} else {
usb_udc_vbus_handler(_gadget, false);
if (ci->driver)
ci->driver->disconnect(&ci->gadget);
hw_device_state(ci, 0);
if (ci->platdata->notify_event)
ci->platdata->notify_event(ci,
CI_HDRC_CONTROLLER_STOPPED_EVENT);
_gadget_stop_activity(&ci->gadget);
pm_runtime_put_sync(&_gadget->dev);
usb_gadget_set_state(_gadget, USB_STATE_NOTATTACHED);
}
}
static int ci_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
{
struct ci_hdrc *ci = container_of(_gadget, struct ci_hdrc, gadget);
unsigned long flags;
int ret = 0;
int gadget_ready = 0;
spin_lock_irqsave(&ci->lock, flags);
ci->vbus_active = is_active;
if (ci->driver)
gadget_ready = 1;
spin_unlock_irqrestore(&ci->lock, flags);
if (ci->usb_phy)
usb_phy_set_charger_state(ci->usb_phy, is_active ?
USB_CHARGER_PRESENT : USB_CHARGER_ABSENT);
if (ci->platdata->notify_event)
ret = ci->platdata->notify_event(ci,
CI_HDRC_CONTROLLER_VBUS_EVENT);
if (ci->usb_phy) {
if (is_active)
usb_phy_set_event(ci->usb_phy, USB_EVENT_VBUS);
else
usb_phy_set_event(ci->usb_phy, USB_EVENT_NONE);
if (gadget_ready) {
if (is_active) {
pm_runtime_get_sync(&_gadget->dev);
hw_device_reset(ci);
hw_device_state(ci, ci->ep0out->qh.dma);
usb_gadget_set_state(_gadget, USB_STATE_POWERED);
usb_udc_vbus_handler(_gadget, true);
} else {
usb_udc_vbus_handler(_gadget, false);
if (ci->driver)
ci->driver->disconnect(&ci->gadget);
hw_device_state(ci, 0);
if (ci->platdata->notify_event)
ci->platdata->notify_event(ci,
CI_HDRC_CONTROLLER_STOPPED_EVENT);
_gadget_stop_activity(&ci->gadget);
pm_runtime_put_sync(&_gadget->dev);
usb_gadget_set_state(_gadget, USB_STATE_NOTATTACHED);
}
}
if (ci->driver)
ci_hdrc_gadget_connect(_gadget, is_active);
return ret;
return 0;
}
static int ci_udc_wakeup(struct usb_gadget *_gadget)
@ -1818,10 +1794,18 @@ static int ci_udc_start(struct usb_gadget *gadget,
return retval;
}
if (ci->vbus_active)
ci_hdrc_gadget_connect(gadget, 1);
else
pm_runtime_get_sync(&ci->gadget.dev);
if (ci->vbus_active) {
hw_device_reset(ci);
} else {
usb_udc_vbus_handler(&ci->gadget, false);
pm_runtime_put_sync(&ci->gadget.dev);
return retval;
}
retval = hw_device_state(ci, ci->ep0out->qh.dma);
if (retval)
pm_runtime_put_sync(&ci->gadget.dev);
return retval;
}
@ -1851,7 +1835,6 @@ static int ci_udc_stop(struct usb_gadget *gadget)
unsigned long flags;
spin_lock_irqsave(&ci->lock, flags);
ci->driver = NULL;
if (ci->vbus_active) {
hw_device_state(ci, 0);
@ -1864,6 +1847,7 @@ static int ci_udc_stop(struct usb_gadget *gadget)
pm_runtime_put(&ci->gadget.dev);
}
ci->driver = NULL;
spin_unlock_irqrestore(&ci->lock, flags);
ci_udc_stop_for_otg_fsm(ci);
@ -1906,9 +1890,6 @@ static irqreturn_t udc_irq(struct ci_hdrc *ci)
if (USBi_PCI & intr) {
ci->gadget.speed = hw_port_is_high_speed(ci) ?
USB_SPEED_HIGH : USB_SPEED_FULL;
if (ci->usb_phy)
usb_phy_set_event(ci->usb_phy,
USB_EVENT_ENUMERATED);
if (ci->suspended) {
if (ci->driver->resume) {
spin_unlock(&ci->lock);

View file

@ -359,7 +359,7 @@ static void acm_process_notification(struct acm *acm, unsigned char *buf)
static void acm_ctrl_irq(struct urb *urb)
{
struct acm *acm = urb->context;
struct usb_cdc_notification *dr;
struct usb_cdc_notification *dr = urb->transfer_buffer;
unsigned int current_size = urb->actual_length;
unsigned int expected_size, copy_size, alloc_size;
int retval;
@ -386,25 +386,14 @@ static void acm_ctrl_irq(struct urb *urb)
usb_mark_last_busy(acm->dev);
if (acm->nb_index == 0) {
/*
* The first chunk of a message must contain at least the
* notification header with the length field, otherwise we
* can't get an expected_size.
*/
if (current_size < sizeof(struct usb_cdc_notification)) {
dev_dbg(&acm->control->dev, "urb too short\n");
goto exit;
}
dr = urb->transfer_buffer;
} else {
if (acm->nb_index)
dr = (struct usb_cdc_notification *)acm->notification_buffer;
}
/* size = notification-header + (optional) data */
expected_size = sizeof(struct usb_cdc_notification) +
le16_to_cpu(dr->wLength);
if (acm->nb_index != 0 || current_size < expected_size) {
if (current_size < expected_size) {
/* notification is transmitted fragmented, reassemble */
if (acm->nb_size < expected_size) {
u8 *new_buffer;
@ -1520,6 +1509,8 @@ skip_countries:
acm->nb_index = 0;
acm->nb_size = 0;
dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
acm->line.dwDTERate = cpu_to_le32(9600);
acm->line.bDataBits = 8;
acm_set_line(acm, &acm->line);
@ -1527,12 +1518,6 @@ skip_countries:
usb_driver_claim_interface(&acm_driver, data_interface, acm);
usb_set_intfdata(data_interface, acm);
if (quirks & CLEAR_HALT_CONDITIONS) {
/* errors intentionally ignored */
usb_clear_halt(usb_dev, acm->in);
usb_clear_halt(usb_dev, acm->out);
}
tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor,
&control_interface->dev);
if (IS_ERR(tty_dev)) {
@ -1540,7 +1525,10 @@ skip_countries:
goto alloc_fail6;
}
dev_info(&intf->dev, "ttyACM%d: USB ACM device\n", minor);
if (quirks & CLEAR_HALT_CONDITIONS) {
usb_clear_halt(usb_dev, acm->in);
usb_clear_halt(usb_dev, acm->out);
}
return 0;
alloc_fail6:
@ -1745,16 +1733,13 @@ static const struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},
{ USB_DEVICE(0x045b, 0x023c), /* Renesas R-Car H3 USB Download mode */
{ USB_DEVICE(0x045b, 0x023c), /* Renesas USB Download mode */
.driver_info = DISABLE_ECHO, /* Don't echo banner */
},
{ USB_DEVICE(0x045b, 0x0247), /* Renesas R-Car D3 USB Download mode */
{ USB_DEVICE(0x045b, 0x0248), /* Renesas USB Download mode */
.driver_info = DISABLE_ECHO, /* Don't echo banner */
},
{ USB_DEVICE(0x045b, 0x0248), /* Renesas R-Car M3-N USB Download mode */
.driver_info = DISABLE_ECHO, /* Don't echo banner */
},
{ USB_DEVICE(0x045b, 0x024D), /* Renesas R-Car E3 USB Download mode */
{ USB_DEVICE(0x045b, 0x024D), /* Renesas USB Download mode */
.driver_info = DISABLE_ECHO, /* Don't echo banner */
},
{ USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */

View file

@ -89,6 +89,7 @@ struct wdm_device {
u16 wMaxCommand;
u16 wMaxPacketSize;
__le16 inum;
int reslength;
int length;
int read;
int count;
@ -200,11 +201,6 @@ static void wdm_in_callback(struct urb *urb)
if (desc->rerr == 0 && status != -EPIPE)
desc->rerr = status;
if (length == 0) {
dev_dbg(&desc->intf->dev, "received ZLP\n");
goto skip_zlp;
}
if (length + desc->length > desc->wMaxCommand) {
/* The buffer would overflow */
set_bit(WDM_OVERFLOW, &desc->flags);
@ -213,18 +209,18 @@ static void wdm_in_callback(struct urb *urb)
if (!test_bit(WDM_OVERFLOW, &desc->flags)) {
memmove(desc->ubuf + desc->length, desc->inbuf, length);
desc->length += length;
desc->reslength = length;
}
}
skip_error:
if (desc->rerr) {
/*
* If there was a ZLP or an error, userspace may decide to not
* read any data after poll'ing.
* Since there was an error, userspace may decide to not read
* any data after poll'ing.
* We should respond to further attempts from the device to send
* data, so that we can get unstuck.
*/
skip_zlp:
schedule_work(&desc->service_outs_intr);
} else {
set_bit(WDM_READ, &desc->flags);
@ -575,6 +571,15 @@ retry:
goto retry;
}
if (!desc->reslength) { /* zero length read */
dev_dbg(&desc->intf->dev, "zero length - clearing WDM_READ\n");
clear_bit(WDM_READ, &desc->flags);
rv = service_outstanding_interrupt(desc);
spin_unlock_irq(&desc->iuspin);
if (rv < 0)
goto err;
goto retry;
}
cntr = desc->length;
spin_unlock_irq(&desc->iuspin);
}
@ -834,7 +839,7 @@ static void service_interrupt_work(struct work_struct *work)
spin_lock_irq(&desc->iuspin);
service_outstanding_interrupt(desc);
if (!desc->resp_count && (desc->length || desc->rerr)) {
if (!desc->resp_count) {
set_bit(WDM_READ, &desc->flags);
wake_up(&desc->wait);
}

View file

@ -1337,12 +1337,11 @@ static int usblp_set_protocol(struct usblp *usblp, int protocol)
if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL)
return -EINVAL;
alts = usblp->protocol[protocol].alt_setting;
if (alts < 0)
return -EINVAL;
/* Don't unnecessarily set the interface if there's a single alt. */
if (usblp->intf->num_altsetting > 1) {
alts = usblp->protocol[protocol].alt_setting;
if (alts < 0)
return -EINVAL;
r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
if (r < 0) {
printk(KERN_ERR "usblp: can't set desired altsetting %d on interface %d\n",

View file

@ -485,8 +485,6 @@ static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data,
u8 tag;
__u8 stb;
int rv;
long wait_rv;
unsigned long expire;
dev_dbg(dev, "Enter ioctl_read_stb iin_ep_present: %d\n",
data->iin_ep_present);
@ -529,18 +527,16 @@ static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data,
}
if (data->iin_ep_present) {
expire = msecs_to_jiffies(file_data->timeout);
wait_rv = wait_event_interruptible_timeout(
rv = wait_event_interruptible_timeout(
data->waitq,
atomic_read(&data->iin_data_valid) != 0,
expire);
if (wait_rv < 0) {
dev_dbg(dev, "wait interrupted %ld\n", wait_rv);
rv = wait_rv;
file_data->timeout);
if (rv < 0) {
dev_dbg(dev, "wait interrupted %d\n", rv);
goto exit;
}
if (wait_rv == 0) {
if (rv == 0) {
dev_dbg(dev, "wait timed out\n");
rv = -ETIMEDOUT;
goto exit;
@ -560,8 +556,6 @@ static int usbtmc488_ioctl_read_stb(struct usbtmc_file_data *file_data,
rv = put_user(stb, (__u8 __user *)arg);
dev_dbg(dev, "stb:0x%02x received %d\n", (unsigned int)stb, rv);
rv = 0;
exit:
/* bump interrupt bTag */
data->iin_bTag += 1;
@ -578,9 +572,9 @@ static int usbtmc488_ioctl_wait_srq(struct usbtmc_file_data *file_data,
{
struct usbtmc_device_data *data = file_data->data;
struct device *dev = &data->intf->dev;
int rv;
u32 timeout;
unsigned long expire;
long wait_rv;
if (!data->iin_ep_present) {
dev_dbg(dev, "no interrupt endpoint present\n");
@ -594,24 +588,25 @@ static int usbtmc488_ioctl_wait_srq(struct usbtmc_file_data *file_data,
mutex_unlock(&data->io_mutex);
wait_rv = wait_event_interruptible_timeout(
data->waitq,
atomic_read(&file_data->srq_asserted) != 0 ||
atomic_read(&file_data->closing),
expire);
rv = wait_event_interruptible_timeout(
data->waitq,
atomic_read(&file_data->srq_asserted) != 0 ||
atomic_read(&file_data->closing),
expire);
mutex_lock(&data->io_mutex);
/* Note! disconnect or close could be called in the meantime */
if (atomic_read(&file_data->closing) || data->zombie)
return -ENODEV;
rv = -ENODEV;
if (wait_rv < 0) {
dev_dbg(dev, "%s - wait interrupted %ld\n", __func__, wait_rv);
return wait_rv;
if (rv < 0) {
/* dev can be invalid now! */
pr_debug("%s - wait interrupted %d\n", __func__, rv);
return rv;
}
if (wait_rv == 0) {
if (rv == 0) {
dev_dbg(dev, "%s - wait timed out\n", __func__);
return -ETIMEDOUT;
}
@ -805,7 +800,6 @@ static ssize_t usbtmc_generic_read(struct usbtmc_file_data *file_data,
unsigned long expire;
int bufcount = 1;
int again = 0;
long wait_rv;
/* mutex already locked */
@ -918,24 +912,19 @@ static ssize_t usbtmc_generic_read(struct usbtmc_file_data *file_data,
if (!(flags & USBTMC_FLAG_ASYNC)) {
dev_dbg(dev, "%s: before wait time %lu\n",
__func__, expire);
wait_rv = wait_event_interruptible_timeout(
retval = wait_event_interruptible_timeout(
file_data->wait_bulk_in,
usbtmc_do_transfer(file_data),
expire);
dev_dbg(dev, "%s: wait returned %ld\n",
__func__, wait_rv);
dev_dbg(dev, "%s: wait returned %d\n",
__func__, retval);
if (wait_rv < 0) {
retval = wait_rv;
if (retval <= 0) {
if (retval == 0)
retval = -ETIMEDOUT;
goto error;
}
if (wait_rv == 0) {
retval = -ETIMEDOUT;
goto error;
}
}
urb = usb_get_from_anchor(&file_data->in_anchor);
@ -1361,10 +1350,7 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf,
if (!buffer)
return -ENOMEM;
retval = mutex_lock_interruptible(&data->io_mutex);
if (retval < 0)
goto exit_nolock;
mutex_lock(&data->io_mutex);
if (data->zombie) {
retval = -ENODEV;
goto exit;
@ -1487,7 +1473,6 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf,
exit:
mutex_unlock(&data->io_mutex);
exit_nolock:
kfree(buffer);
return retval;
}

View file

@ -55,12 +55,6 @@
#define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */
#define USB_PING_RESPONSE_TIME 400 /* ns */
/*
* Give SS hubs 200ms time after wake to train downstream links before
* assuming no port activity and allowing hub to runtime suspend back.
*/
#define USB_SS_PORT_U0_WAKE_TIME 200 /* ms */
/* Protect struct usb_device->state and ->children members
* Note: Both are also protected by ->dev.sem, except that ->state can
* change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */
@ -1061,7 +1055,6 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
goto init2;
goto init3;
}
kref_get(&hub->kref);
/* The superspeed hub except for root hub has to use Hub Depth
@ -1310,17 +1303,6 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
device_unlock(&hdev->dev);
}
if (type == HUB_RESUME && hub_is_superspeed(hub->hdev)) {
/* give usb3 downstream links training time after hub resume */
usb_autopm_get_interface_no_resume(
to_usb_interface(hub->intfdev));
queue_delayed_work(system_power_efficient_wq,
&hub->post_resume_work,
msecs_to_jiffies(USB_SS_PORT_U0_WAKE_TIME));
return;
}
kref_put(&hub->kref, hub_release);
}
@ -1339,14 +1321,6 @@ static void hub_init_func3(struct work_struct *ws)
hub_activate(hub, HUB_INIT3);
}
static void hub_post_resume(struct work_struct *ws)
{
struct usb_hub *hub = container_of(ws, struct usb_hub, post_resume_work.work);
usb_autopm_put_interface_async(to_usb_interface(hub->intfdev));
kref_put(&hub->kref, hub_release);
}
enum hub_quiescing_type {
HUB_DISCONNECT, HUB_PRE_RESET, HUB_SUSPEND
};
@ -1372,7 +1346,6 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
/* Stop hub_wq and related activity */
del_timer_sync(&hub->irq_urb_retry);
flush_delayed_work(&hub->post_resume_work);
usb_kill_urb(hub->urb);
if (hub->has_indicators)
cancel_delayed_work_sync(&hub->leds);
@ -1823,17 +1796,6 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
desc = intf->cur_altsetting;
hdev = interface_to_usbdev(intf);
/*
* The USB 2.0 spec prohibits hubs from having more than one
* configuration or interface, and we rely on this prohibition.
* Refuse to accept a device that violates it.
*/
if (hdev->descriptor.bNumConfigurations > 1 ||
hdev->actconfig->desc.bNumInterfaces > 1) {
dev_err(&intf->dev, "Invalid hub with more than one config or interface\n");
return -EINVAL;
}
/*
* Set default autosuspend delay as 0 to speedup bus suspend,
* based on the below considerations:
@ -1919,7 +1881,6 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
hub->hdev = hdev;
INIT_DELAYED_WORK(&hub->leds, led_work);
INIT_DELAYED_WORK(&hub->init_work, NULL);
INIT_DELAYED_WORK(&hub->post_resume_work, hub_post_resume);
INIT_WORK(&hub->events, hub_event);
spin_lock_init(&hub->irq_urb_lock);
timer_setup(&hub->irq_urb_retry, hub_retry_irq_urb, 0);
@ -2635,13 +2596,13 @@ int usb_new_device(struct usb_device *udev)
err = sysfs_create_link(&udev->dev.kobj,
&port_dev->dev.kobj, "port");
if (err)
goto out_del_dev;
goto fail;
err = sysfs_create_link(&port_dev->dev.kobj,
&udev->dev.kobj, "device");
if (err) {
sysfs_remove_link(&udev->dev.kobj, "port");
goto out_del_dev;
goto fail;
}
if (!test_and_set_bit(port1, hub->child_usage_bits))
@ -2653,8 +2614,6 @@ int usb_new_device(struct usb_device *udev)
pm_runtime_put_sync_autosuspend(&udev->dev);
return err;
out_del_dev:
device_del(&udev->dev);
fail:
usb_set_device_state(udev, USB_STATE_NOTATTACHED);
pm_runtime_disable(&udev->dev);
@ -2787,8 +2746,6 @@ static unsigned hub_is_wusb(struct usb_hub *hub)
#define SET_CONFIG_TRIES (2 * (use_both_schemes + 1))
#define USE_NEW_SCHEME(i, scheme) ((i) / 2 == (int)(scheme))
#define DETECT_DISCONNECT_TRIES 5
#define HUB_ROOT_RESET_TIME 60 /* times are in msec */
#define HUB_SHORT_RESET_TIME 10
#define HUB_BH_RESET_TIME 50
@ -5424,8 +5381,6 @@ static void port_event(struct usb_hub *hub, int port1)
struct usb_device *udev = port_dev->child;
struct usb_device *hdev = hub->hdev;
u16 portstatus, portchange;
int i = 0;
int err;
connect_change = test_bit(port1, hub->change_bits);
clear_bit(port1, hub->event_bits);
@ -5502,30 +5457,17 @@ static void port_event(struct usb_hub *hub, int port1)
connect_change = 1;
/*
* Avoid trying to recover a USB3 SS.Inactive port with a warm reset if
* the device was disconnected. A 12ms disconnect detect timer in
* SS.Inactive state transitions the port to RxDetect automatically.
* SS.Inactive link error state is common during device disconnect.
* Warm reset a USB3 protocol port if it's in
* SS.Inactive state.
*/
while (hub_port_warm_reset_required(hub, port1, portstatus)) {
if ((i++ < DETECT_DISCONNECT_TRIES) && udev) {
u16 unused;
msleep(20);
hub_port_status(hub, port1, &portstatus, &unused);
dev_dbg(&port_dev->dev, "Wait for inactive link disconnect detect\n");
continue;
} else if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION)
if (hub_port_warm_reset_required(hub, port1, portstatus)) {
dev_dbg(&port_dev->dev, "do warm reset\n");
if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION)
|| udev->state == USB_STATE_NOTATTACHED) {
dev_dbg(&port_dev->dev, "do warm reset, port only\n");
err = hub_port_reset(hub, port1, NULL,
HUB_BH_RESET_TIME, true);
if (!udev && err == -ENOTCONN)
connect_change = 0;
else if (err < 0)
if (hub_port_reset(hub, port1, NULL,
HUB_BH_RESET_TIME, true) < 0)
hub_port_disable(hub, port1, 1);
} else {
dev_dbg(&port_dev->dev, "do warm reset, full device\n");
usb_unlock_port(port_dev);
usb_lock_device(udev);
usb_reset_device(udev);
@ -5533,7 +5475,6 @@ static void port_event(struct usb_hub *hub, int port1)
usb_lock_port(port_dev);
connect_change = 0;
}
break;
}
if (connect_change)
@ -5881,7 +5822,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
struct usb_hub *parent_hub;
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
struct usb_device_descriptor descriptor = udev->descriptor;
struct usb_interface *intf;
struct usb_host_bos *bos;
char buf[50];
int i, j, ret = 0;
@ -5944,18 +5884,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
if (!udev->actconfig)
goto done;
/*
* Some devices can't handle setting default altsetting 0 with a
* Set-Interface request. Disable host-side endpoints of those
* interfaces here. Enable and reset them back after host has set
* its internal endpoint structures during usb_hcd_alloc_bandwith()
*/
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
intf = udev->actconfig->interface[i];
if (intf->cur_altsetting->desc.bAlternateSetting == 0)
usb_disable_interface(udev, intf, true);
}
mutex_lock(hcd->bandwidth_mutex);
ret = usb_hcd_alloc_bandwidth(udev, udev->actconfig, NULL, NULL);
if (ret < 0) {
@ -5999,11 +5927,12 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
*/
for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
struct usb_host_config *config = udev->actconfig;
struct usb_interface *intf = config->interface[i];
struct usb_interface_descriptor *desc;
intf = config->interface[i];
desc = &intf->cur_altsetting->desc;
if (desc->bAlternateSetting == 0) {
usb_disable_interface(udev, intf, true);
usb_enable_interface(udev, intf, true);
ret = 0;
} else {

View file

@ -69,7 +69,6 @@ struct usb_hub {
u8 indicator[USB_MAXCHILDREN];
struct delayed_work leds;
struct delayed_work init_work;
struct delayed_work post_resume_work;
struct work_struct events;
spinlock_t irq_urb_lock;
struct timer_list irq_urb_retry;

View file

@ -294,11 +294,10 @@ static int usb_port_runtime_suspend(struct device *dev)
static void usb_port_shutdown(struct device *dev)
{
struct usb_port *port_dev = to_usb_port(dev);
struct usb_device *udev = port_dev->child;
if (udev && !udev->port_is_suspended) {
usb_disable_usb2_hardware_lpm(udev);
usb_unlocked_disable_lpm(udev);
if (port_dev->child) {
usb_disable_usb2_hardware_lpm(port_dev->child);
usb_unlocked_disable_lpm(port_dev->child);
}
}

View file

@ -224,8 +224,7 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME },
/* Logitech HD Webcam C270 */
{ USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME |
USB_QUIRK_NO_LPM},
{ USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME },
/* Logitech HD Pro Webcams C920, C920-C, C922, C925e and C930e */
{ USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
@ -339,10 +338,6 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x0638, 0x0a13), .driver_info =
USB_QUIRK_STRING_FETCH_255 },
/* Prolific Single-LUN Mass Storage Card Reader */
{ USB_DEVICE(0x067b, 0x2731), .driver_info = USB_QUIRK_DELAY_INIT |
USB_QUIRK_NO_LPM },
/* Saitek Cyborg Gold Joystick */
{ USB_DEVICE(0x06a3, 0x0006), .driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS },
@ -367,13 +362,6 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM },
{ USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM },
/* SanDisk Corp. SanDisk 3.2Gen1 */
{ USB_DEVICE(0x0781, 0x5596), .driver_info = USB_QUIRK_DELAY_INIT },
{ USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT },
/* SanDisk Extreme 55AE */
{ USB_DEVICE(0x0781, 0x55ae), .driver_info = USB_QUIRK_NO_LPM },
/* Realforce 87U Keyboard */
{ USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM },
@ -446,9 +434,6 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x0c45, 0x7056), .driver_info =
USB_QUIRK_IGNORE_REMOTE_WAKEUP },
/* Sony Xperia XZ1 Compact (lilac) smartphone in fastboot mode */
{ USB_DEVICE(0x0fce, 0x0dde), .driver_info = USB_QUIRK_NO_LPM },
/* Action Semiconductor flash disk */
{ USB_DEVICE(0x10d6, 0x2200), .driver_info =
USB_QUIRK_STRING_FETCH_255 },
@ -463,8 +448,6 @@ static const struct usb_device_id usb_quirk_list[] = {
/* Huawei 4G LTE module */
{ USB_DEVICE(0x12d1, 0x15bb), .driver_info =
USB_QUIRK_DISCONNECT_SUSPEND },
{ USB_DEVICE(0x12d1, 0x15c1), .driver_info =
USB_QUIRK_DISCONNECT_SUSPEND },
{ USB_DEVICE(0x12d1, 0x15c3), .driver_info =
USB_QUIRK_DISCONNECT_SUSPEND },
@ -541,16 +524,10 @@ static const struct usb_device_id usb_quirk_list[] = {
/* Blackmagic Design UltraStudio SDI */
{ USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
/* Teclast disk */
{ USB_DEVICE(0x1f75, 0x0917), .driver_info = USB_QUIRK_NO_LPM },
/* Hauppauge HVR-950q */
{ USB_DEVICE(0x2040, 0x7200), .driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS },
/* VLI disk */
{ USB_DEVICE(0x2109, 0x0711), .driver_info = USB_QUIRK_NO_LPM },
/* Raydium Touchscreen */
{ USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM },
@ -731,7 +708,7 @@ void usb_detect_quirks(struct usb_device *udev)
udev->quirks ^= usb_detect_dynamic_quirks(udev);
if (udev->quirks)
dev_dbg(&udev->dev, "USB quirks for this device: 0x%x\n",
dev_dbg(&udev->dev, "USB quirks for this device: %x\n",
udev->quirks);
#ifdef CONFIG_USB_DEFAULT_PERSIST

View file

@ -490,7 +490,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
/* Check that the pipe's type matches the endpoint's type */
if (usb_pipe_type_check(urb->dev, urb->pipe))
dev_warn_once(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n",
dev_WARN(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n",
usb_pipetype(urb->pipe), pipetypes[xfertype]);
/* Check against a simple/standard policy */

View file

@ -717,16 +717,15 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
dev_set_name(&dev->dev, "usb%d", bus->busnum);
root_hub = 1;
} else {
int n;
/* match any labeling on the hubs; it's one-based */
if (parent->devpath[0] == '0') {
n = snprintf(dev->devpath, sizeof(dev->devpath), "%d", port1);
snprintf(dev->devpath, sizeof dev->devpath,
"%d", port1);
/* Root ports are not counted in route string */
dev->route = 0;
} else {
n = snprintf(dev->devpath, sizeof(dev->devpath), "%s.%d",
parent->devpath, port1);
snprintf(dev->devpath, sizeof dev->devpath,
"%s.%d", parent->devpath, port1);
/* Route string assumes hubs have less than 16 ports */
if (port1 < 15)
dev->route = parent->route +
@ -735,11 +734,6 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,
dev->route = parent->route +
(15 << ((parent->level - 1)*4));
}
if (n >= sizeof(dev->devpath)) {
usb_put_hcd(bus_to_hcd(bus));
usb_put_dev(dev);
return NULL;
}
dev->dev.parent = &parent->dev;
dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath);

View file

@ -4548,7 +4548,6 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget)
spin_lock_irqsave(&hsotg->lock, flags);
hsotg->driver = NULL;
hsotg->gadget.dev.of_node = NULL;
hsotg->gadget.speed = USB_SPEED_UNKNOWN;
hsotg->enabled = 0;

View file

@ -120,19 +120,17 @@ static void __dwc3_set_mode(struct work_struct *work)
if (dwc->dr_mode != USB_DR_MODE_OTG)
return;
pm_runtime_get_sync(dwc->dev);
if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_OTG)
dwc3_otg_update(dwc, 0);
if (!dwc->desired_dr_role)
goto out;
return;
if (dwc->desired_dr_role == dwc->current_dr_role)
goto out;
return;
if (dwc->desired_dr_role == DWC3_GCTL_PRTCAP_OTG && dwc->edev)
goto out;
return;
switch (dwc->current_dr_role) {
case DWC3_GCTL_PRTCAP_HOST:
@ -196,9 +194,6 @@ static void __dwc3_set_mode(struct work_struct *work)
break;
}
out:
pm_runtime_mark_last_busy(dwc->dev);
pm_runtime_put_autosuspend(dwc->dev);
}
void dwc3_set_mode(struct dwc3 *dwc, u32 mode)

View file

@ -529,9 +529,6 @@ static int dwc3_meson_g12a_remove(struct platform_device *pdev)
usb_role_switch_unregister(priv->role_switch);
put_device(priv->switch_desc.udc);
put_device(priv->switch_desc.usb2_port);
of_platform_depopulate(dev);
for (i = 0 ; i < PHY_COUNT ; ++i) {

View file

@ -641,13 +641,13 @@ static int dwc3_qcom_probe(struct platform_device *pdev)
ret = reset_control_deassert(qcom->resets);
if (ret) {
dev_err(&pdev->dev, "failed to deassert resets, err=%d\n", ret);
return ret;
goto reset_assert;
}
ret = dwc3_qcom_clk_init(qcom, of_clk_get_parent_count(np));
if (ret) {
dev_err(dev, "failed to get clocks\n");
return ret;
goto reset_assert;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@ -729,6 +729,8 @@ clk_disable:
if (qcom->gdsc)
if (regulator_disable(qcom->gdsc))
dev_err(qcom->dev, "unable to disable usb3 gdsc\n");
reset_assert:
reset_control_assert(qcom->resets);
return ret;
}
@ -752,6 +754,8 @@ static int dwc3_qcom_remove(struct platform_device *pdev)
}
qcom->num_clocks = 0;
reset_control_assert(qcom->resets);
pm_runtime_allow(dev);
pm_runtime_disable(dev);

View file

@ -491,6 +491,10 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
dwc3_gadget_ep_get_transfer_index(dep);
}
if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER &&
!(cmd & DWC3_DEPCMD_CMDIOC))
mdelay(1);
if (saved_config) {
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
reg |= saved_config;
@ -3531,15 +3535,6 @@ out:
static void dwc3_gadget_endpoint_transfer_not_ready(struct dwc3_ep *dep,
const struct dwc3_event_depevt *event)
{
/*
* During a device-initiated disconnect, a late xferNotReady event can
* be generated after the End Transfer command resets the event filter,
* but before the controller is halted. Ignore it to prevent a new
* transfer from starting.
*/
if (!dep->dwc->connected)
return;
dwc3_gadget_endpoint_frame_from_event(dep, event);
(void) __dwc3_gadget_start_isoc(dep);
}
@ -3750,9 +3745,6 @@ int dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt)
else
dep->flags |= DWC3_EP_END_TRANSFER_PENDING;
if (dwc3_is_usb31(dwc) || dwc->revision < DWC3_REVISION_310A)
udelay(100);
return ret;
}
EXPORT_SYMBOL(dwc3_stop_active_transfer);

View file

@ -678,10 +678,6 @@ int __init early_xdbc_setup_hardware(void)
xdbc.table_base = NULL;
xdbc.out_buf = NULL;
early_iounmap(xdbc.xhci_base, xdbc.xhci_length);
xdbc.xhci_base = NULL;
xdbc.xhci_length = 0;
}
return ret;

View file

@ -970,11 +970,10 @@ static int set_config(struct usb_composite_dev *cdev,
else
power = min(power, 900U);
done:
if (power > USB_SELF_POWER_VBUS_MAX_DRAW ||
(c && !(c->bmAttributes & USB_CONFIG_ATT_SELFPOWER)))
usb_gadget_clear_selfpowered(gadget);
else
if (power <= USB_SELF_POWER_VBUS_MAX_DRAW)
usb_gadget_set_selfpowered(gadget);
else
usb_gadget_clear_selfpowered(gadget);
usb_gadget_vbus_draw(gadget, power);
if (result >= 0 && cdev->delayed_status)
@ -2322,11 +2321,6 @@ int composite_os_desc_req_prepare(struct usb_composite_dev *cdev,
if (!cdev->os_desc_req->buf) {
ret = -ENOMEM;
usb_ep_free_request(ep0, cdev->os_desc_req);
/*
* Set os_desc_req to NULL so that composite_dev_cleanup()
* will not try to free it again.
*/
cdev->os_desc_req = NULL;
goto end;
}
cdev->os_desc_req->context = cdev;
@ -2452,10 +2446,7 @@ void composite_suspend(struct usb_gadget *gadget)
cdev->suspended = 1;
if (cdev->config &&
cdev->config->bmAttributes & USB_CONFIG_ATT_SELFPOWER)
usb_gadget_set_selfpowered(gadget);
usb_gadget_set_selfpowered(gadget);
usb_gadget_vbus_draw(gadget, 2);
}
@ -2487,11 +2478,8 @@ void composite_resume(struct usb_gadget *gadget)
else
maxpower = min(maxpower, 900U);
if (maxpower > USB_SELF_POWER_VBUS_MAX_DRAW ||
!(cdev->config->bmAttributes & USB_CONFIG_ATT_SELFPOWER))
if (maxpower > USB_SELF_POWER_VBUS_MAX_DRAW)
usb_gadget_clear_selfpowered(gadget);
else
usb_gadget_set_selfpowered(gadget);
usb_gadget_vbus_draw(gadget, maxpower);
}

View file

@ -938,8 +938,6 @@ static ssize_t os_desc_qw_sign_store(struct config_item *item, const char *page,
struct gadget_info *gi = os_desc_item_to_gadget_info(item);
int res, l;
if (!len)
return len;
l = min((int)len, OS_STRING_QW_SIGN_LEN >> 1);
if (page[l - 1] == '\n')
--l;
@ -1441,8 +1439,6 @@ static int configfs_composite_bind(struct usb_gadget *gadget,
cdev->use_os_string = true;
cdev->b_vendor_code = gi->b_vendor_code;
memcpy(cdev->qw_sign, gi->qw_sign, OS_STRING_QW_SIGN_LEN);
} else {
cdev->use_os_string = false;
}
if (gadget_is_otg(gadget) && !otg_desc[0]) {

View file

@ -2254,12 +2254,7 @@ static int ffs_func_eps_enable(struct ffs_function *func)
ep = func->eps;
epfile = ffs->epfiles;
count = ffs->eps_count;
if (!epfile) {
ret = -ENOMEM;
goto done;
}
while (count--) {
while(count--) {
ep->ep->driver_data = ep;
ret = config_ep_by_speed(func->gadget, &func->function, ep->ep);
@ -2285,7 +2280,6 @@ static int ffs_func_eps_enable(struct ffs_function *func)
}
wake_up_interruptible(&ffs->wait);
done:
spin_unlock_irqrestore(&func->ffs->eps_lock, flags);
return ret;

View file

@ -114,8 +114,8 @@ static struct hid_descriptor hidg_desc = {
.bcdHID = cpu_to_le16(0x0101),
.bCountryCode = 0x00,
.bNumDescriptors = 0x1,
/*.rpt_desc.bDescriptorType = DYNAMIC */
/*.rpt_desc.wDescriptorLength = DYNAMIC */
/*.desc[0].bDescriptorType = DYNAMIC */
/*.desc[0].wDescriptorLenght = DYNAMIC */
};
/* Super-Speed Support */
@ -496,7 +496,7 @@ try_again:
}
req->status = 0;
req->zero = 1;
req->zero = 0;
req->length = count;
req->complete = f_hidg_req_complete;
req->context = hidg;
@ -730,8 +730,8 @@ static int hidg_setup(struct usb_function *f,
struct hid_descriptor hidg_desc_copy = hidg_desc;
VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: HID\n");
hidg_desc_copy.rpt_desc.bDescriptorType = HID_DT_REPORT;
hidg_desc_copy.rpt_desc.wDescriptorLength =
hidg_desc_copy.desc[0].bDescriptorType = HID_DT_REPORT;
hidg_desc_copy.desc[0].wDescriptorLength =
cpu_to_le16(hidg->report_desc_length);
length = min_t(unsigned short, length,
@ -767,7 +767,7 @@ stall:
return -EOPNOTSUPP;
respond:
req->zero = 1;
req->zero = 0;
req->length = length;
status = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC);
if (status < 0)
@ -972,8 +972,8 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f)
* We can use hidg_desc struct here but we should not relay
* that its content won't change after returning from this function.
*/
hidg_desc.rpt_desc.bDescriptorType = HID_DT_REPORT;
hidg_desc.rpt_desc.wDescriptorLength =
hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT;
hidg_desc.desc[0].wDescriptorLength =
cpu_to_le16(hidg->report_desc_length);
hidg_hs_in_ep_desc.bEndpointAddress =

View file

@ -87,7 +87,7 @@ struct f_midi {
struct snd_rawmidi_substream *out_substream[MAX_PORTS];
unsigned long out_triggered;
struct work_struct work;
struct tasklet_struct tasklet;
unsigned int in_ports;
unsigned int out_ports;
int index;
@ -282,7 +282,7 @@ f_midi_complete(struct usb_ep *ep, struct usb_request *req)
/* Our transmit completed. See if there's more to go.
* f_midi_transmit eats req, don't queue it again. */
req->length = 0;
queue_work(system_highpri_wq, &midi->work);
f_midi_transmit(midi);
return;
}
break;
@ -698,11 +698,9 @@ drop_out:
f_midi_drop_out_substreams(midi);
}
static void f_midi_in_work(struct work_struct *work)
static void f_midi_in_tasklet(unsigned long data)
{
struct f_midi *midi;
midi = container_of(work, struct f_midi, work);
struct f_midi *midi = (struct f_midi *) data;
f_midi_transmit(midi);
}
@ -739,7 +737,7 @@ static void f_midi_in_trigger(struct snd_rawmidi_substream *substream, int up)
VDBG(midi, "%s() %d\n", __func__, up);
midi->in_ports_array[substream->number].active = up;
if (up)
queue_work(system_highpri_wq, &midi->work);
tasklet_hi_schedule(&midi->tasklet);
}
static int f_midi_out_open(struct snd_rawmidi_substream *substream)
@ -877,7 +875,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
int status, n, jack = 1, i = 0, endpoint_descriptor_index = 0;
midi->gadget = cdev->gadget;
INIT_WORK(&midi->work, f_midi_in_work);
tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi);
status = f_midi_register_card(midi);
if (status < 0)
goto fail_register;
@ -999,11 +997,11 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
}
/* configure the endpoint descriptors ... */
ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports);
ms_out_desc.bNumEmbMIDIJack = midi->out_ports;
ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports);
ms_out_desc.bNumEmbMIDIJack = midi->in_ports;
ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports);
ms_in_desc.bNumEmbMIDIJack = midi->in_ports;
ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports);
ms_in_desc.bNumEmbMIDIJack = midi->out_ports;
/* ... and add them to the list */
endpoint_descriptor_index = i;

View file

@ -245,6 +245,7 @@ static int bot_send_write_request(struct usbg_cmd *cmd)
{
struct f_uas *fu = cmd->fu;
struct se_cmd *se_cmd = &cmd->se_cmd;
struct usb_gadget *gadget = fuas_to_gadget(fu);
int ret;
init_completion(&cmd->write_complete);
@ -255,6 +256,22 @@ static int bot_send_write_request(struct usbg_cmd *cmd)
return -EINVAL;
}
if (!gadget->sg_supported) {
cmd->data_buf = kmalloc(se_cmd->data_length, GFP_KERNEL);
if (!cmd->data_buf)
return -ENOMEM;
fu->bot_req_out->buf = cmd->data_buf;
} else {
fu->bot_req_out->buf = NULL;
fu->bot_req_out->num_sgs = se_cmd->t_data_nents;
fu->bot_req_out->sg = se_cmd->t_data_sg;
}
fu->bot_req_out->complete = usbg_data_write_cmpl;
fu->bot_req_out->length = se_cmd->data_length;
fu->bot_req_out->context = cmd;
ret = usbg_prepare_w_request(cmd, fu->bot_req_out);
if (ret)
goto cleanup;
@ -954,7 +971,6 @@ static void usbg_data_write_cmpl(struct usb_ep *ep, struct usb_request *req)
return;
cleanup:
target_put_sess_cmd(se_cmd);
transport_generic_free_cmd(&cmd->se_cmd, 0);
}
@ -1047,7 +1063,8 @@ static void usbg_cmd_work(struct work_struct *work)
out:
transport_send_check_condition_and_sense(se_cmd,
TCM_UNSUPPORTED_SCSI_OPCODE, 0);
TCM_UNSUPPORTED_SCSI_OPCODE, 1);
transport_generic_free_cmd(&cmd->se_cmd, 0);
}
static struct usbg_cmd *usbg_get_cmd(struct f_uas *fu,
@ -1176,7 +1193,8 @@ static void bot_cmd_work(struct work_struct *work)
out:
transport_send_check_condition_and_sense(se_cmd,
TCM_UNSUPPORTED_SCSI_OPCODE, 0);
TCM_UNSUPPORTED_SCSI_OPCODE, 1);
transport_generic_free_cmd(&cmd->se_cmd, 0);
}
static int bot_submit_command(struct f_uas *fu,
@ -1320,14 +1338,14 @@ static struct se_portal_group *usbg_make_tpg(struct se_wwn *wwn,
struct usbg_tport *tport = container_of(wwn, struct usbg_tport,
tport_wwn);
struct usbg_tpg *tpg;
u16 tpgt;
unsigned long tpgt;
int ret;
struct f_tcm_opts *opts;
unsigned i;
if (strstr(name, "tpgt_") != name)
return ERR_PTR(-EINVAL);
if (kstrtou16(name + 5, 0, &tpgt))
if (kstrtoul(name + 5, 0, &tpgt) || tpgt > UINT_MAX)
return ERR_PTR(-EINVAL);
ret = -ENODEV;
mutex_lock(&tpg_instances_lock);
@ -1999,39 +2017,43 @@ static int tcm_bind(struct usb_configuration *c, struct usb_function *f)
bot_intf_desc.bInterfaceNumber = iface;
uasp_intf_desc.bInterfaceNumber = iface;
fu->iface = iface;
ep = usb_ep_autoconfig(gadget, &uasp_fs_bi_desc);
ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bi_desc,
&uasp_bi_ep_comp_desc);
if (!ep)
goto ep_fail;
fu->ep_in = ep;
ep = usb_ep_autoconfig(gadget, &uasp_fs_bo_desc);
ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_bo_desc,
&uasp_bo_ep_comp_desc);
if (!ep)
goto ep_fail;
fu->ep_out = ep;
ep = usb_ep_autoconfig(gadget, &uasp_fs_status_desc);
ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_status_desc,
&uasp_status_in_ep_comp_desc);
if (!ep)
goto ep_fail;
fu->ep_status = ep;
ep = usb_ep_autoconfig(gadget, &uasp_fs_cmd_desc);
ep = usb_ep_autoconfig_ss(gadget, &uasp_ss_cmd_desc,
&uasp_cmd_comp_desc);
if (!ep)
goto ep_fail;
fu->ep_cmd = ep;
/* Assume endpoint addresses are the same for both speeds */
uasp_bi_desc.bEndpointAddress = uasp_fs_bi_desc.bEndpointAddress;
uasp_bo_desc.bEndpointAddress = uasp_fs_bo_desc.bEndpointAddress;
uasp_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress;
uasp_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress;
uasp_status_desc.bEndpointAddress =
uasp_fs_status_desc.bEndpointAddress;
uasp_cmd_desc.bEndpointAddress = uasp_fs_cmd_desc.bEndpointAddress;
uasp_ss_status_desc.bEndpointAddress;
uasp_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress;
uasp_ss_bi_desc.bEndpointAddress = uasp_fs_bi_desc.bEndpointAddress;
uasp_ss_bo_desc.bEndpointAddress = uasp_fs_bo_desc.bEndpointAddress;
uasp_ss_status_desc.bEndpointAddress =
uasp_fs_status_desc.bEndpointAddress;
uasp_ss_cmd_desc.bEndpointAddress = uasp_fs_cmd_desc.bEndpointAddress;
uasp_fs_bi_desc.bEndpointAddress = uasp_ss_bi_desc.bEndpointAddress;
uasp_fs_bo_desc.bEndpointAddress = uasp_ss_bo_desc.bEndpointAddress;
uasp_fs_status_desc.bEndpointAddress =
uasp_ss_status_desc.bEndpointAddress;
uasp_fs_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress;
ret = usb_assign_descriptors(f, uasp_fs_function_desc,
uasp_hs_function_desc, uasp_ss_function_desc,

View file

@ -808,9 +808,9 @@ static struct usb_function_instance *uvc_alloc_inst(void)
cd->wObjectiveFocalLengthMax = cpu_to_le16(0);
cd->wOcularFocalLength = cpu_to_le16(0);
cd->bControlSize = 3;
cd->bmControls[0] = 2;
cd->bmControls[1] = 0;
cd->bmControls[2] = 0;
cd->bmControls[0] = 62;
cd->bmControls[1] = 126;
cd->bmControls[2] = 10;
pd = &opts->uvc_processing;
pd->bLength = UVC_DT_PROCESSING_UNIT_SIZE(2);
@ -820,8 +820,8 @@ static struct usb_function_instance *uvc_alloc_inst(void)
pd->bSourceID = 1;
pd->wMaxMultiplier = cpu_to_le16(16*1024);
pd->bControlSize = 2;
pd->bmControls[0] = 1;
pd->bmControls[1] = 0;
pd->bmControls[0] = 91;
pd->bmControls[1] = 23;
pd->iProcessing = 0;
pd->bmVideoStandards = 0;

View file

@ -286,8 +286,8 @@ __acquires(&port->port_lock)
break;
}
if (do_tty_wake)
tty_port_tty_wakeup(&port->port);
if (do_tty_wake && port->port.tty)
tty_wakeup(port->port.tty);
return status;
}
@ -564,7 +564,7 @@ static int gs_start_io(struct gs_port *port)
gs_start_tx(port);
/* Unblock any pending writes into our circular buffer, in case
* we didn't in gs_start_tx() */
tty_port_tty_wakeup(&port->port);
tty_wakeup(port->port.tty);
} else {
/* Free reqs only if we are still connected */
if (port->port_usb) {

View file

@ -65,7 +65,7 @@ extern unsigned int uvc_gadget_trace_param;
* Driver specific constants
*/
#define UVC_NUM_REQUESTS 4
#define UVC_NUM_REQUESTS 64
#define UVC_MAX_REQUEST_SIZE 64
#define UVC_MAX_EVENTS 4

View file

@ -762,16 +762,19 @@ static const struct uvcg_config_group_type uvcg_control_grp_type = {
/* -----------------------------------------------------------------------------
* streaming/uncompressed
* streaming/mjpeg
* streaming/framebased
*/
static const char * const uvcg_format_names[] = {
"uncompressed",
"mjpeg",
"framebased"
};
enum uvcg_format_type {
UVCG_UNCOMPRESSED = 0,
UVCG_MJPEG,
UVCG_FRAMEBASED,
};
struct uvcg_format {
@ -1080,6 +1083,7 @@ struct uvcg_frame {
u32 dw_max_video_frame_buffer_size;
u32 dw_default_frame_interval;
u8 b_frame_interval_type;
u32 dw_bytes_perline;
} __attribute__((packed)) frame;
u32 *dw_frame_interval;
};
@ -1190,6 +1194,7 @@ UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, 32);
UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, 32);
UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize, 32);
UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, 32);
UVCG_FRAME_ATTR(dw_bytes_perline, dwBytesPerLine, 32);
#undef UVCG_FRAME_ATTR
@ -1324,7 +1329,7 @@ end:
UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval);
static struct configfs_attribute *uvcg_frame_attrs[] = {
static struct configfs_attribute *uvcg_frame_attrs1[] = {
&uvcg_frame_attr_b_frame_index,
&uvcg_frame_attr_bm_capabilities,
&uvcg_frame_attr_w_width,
@ -1337,12 +1342,32 @@ static struct configfs_attribute *uvcg_frame_attrs[] = {
NULL,
};
static const struct config_item_type uvcg_frame_type = {
static struct configfs_attribute *uvcg_frame_attrs2[] = {
&uvcg_frame_attr_b_frame_index,
&uvcg_frame_attr_bm_capabilities,
&uvcg_frame_attr_w_width,
&uvcg_frame_attr_w_height,
&uvcg_frame_attr_dw_min_bit_rate,
&uvcg_frame_attr_dw_max_bit_rate,
&uvcg_frame_attr_dw_max_video_frame_buffer_size,
&uvcg_frame_attr_dw_default_frame_interval,
&uvcg_frame_attr_dw_frame_interval,
&uvcg_frame_attr_dw_bytes_perline,
NULL,
};
static const struct config_item_type uvcg_frame_type1 = {
.ct_item_ops = &uvcg_config_item_ops,
.ct_attrs = uvcg_frame_attrs,
.ct_attrs = uvcg_frame_attrs1,
.ct_owner = THIS_MODULE,
};
static const struct config_item_type uvcg_frame_type2 = {
.ct_item_ops = &uvcg_config_item_ops,
.ct_attrs = uvcg_frame_attrs2,
.ct_owner = THIS_MODULE,
};
static struct config_item *uvcg_frame_make(struct config_group *group,
const char *name)
{
@ -1363,6 +1388,7 @@ static struct config_item *uvcg_frame_make(struct config_group *group,
h->frame.dw_max_bit_rate = 55296000;
h->frame.dw_max_video_frame_buffer_size = 460800;
h->frame.dw_default_frame_interval = 666666;
h->frame.dw_bytes_perline = 0;
opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
opts = to_f_uvc_opts(opts_item);
@ -1375,6 +1401,9 @@ static struct config_item *uvcg_frame_make(struct config_group *group,
} else if (fmt->type == UVCG_MJPEG) {
h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG;
h->fmt_type = UVCG_MJPEG;
} else if (fmt->type == UVCG_FRAMEBASED) {
h->frame.b_descriptor_subtype = UVC_VS_FRAME_FRAME_BASED;
h->fmt_type = UVCG_FRAMEBASED;
} else {
mutex_unlock(&opts->lock);
kfree(h);
@ -1383,7 +1412,10 @@ static struct config_item *uvcg_frame_make(struct config_group *group,
++fmt->num_frames;
mutex_unlock(&opts->lock);
config_item_init_type_name(&h->item, name, &uvcg_frame_type);
if (fmt->type == UVCG_FRAMEBASED)
config_item_init_type_name(&h->item, name, &uvcg_frame_type2);
else
config_item_init_type_name(&h->item, name, &uvcg_frame_type1);
return &h->item;
}
@ -1413,9 +1445,6 @@ static void uvcg_format_set_indices(struct config_group *fmt)
list_for_each_entry(ci, &fmt->cg_children, ci_entry) {
struct uvcg_frame *frm;
if (ci->ci_type != &uvcg_frame_type)
continue;
frm = to_uvcg_frame(ci);
frm->frame.b_frame_index = i++;
}
@ -1856,6 +1885,260 @@ static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = {
.name = "mjpeg",
};
/* -----------------------------------------------------------------------------
* streaming/framebased/<NAME>
*/
struct uvcg_framebased {
struct uvcg_format fmt;
struct uvc_format_framebased desc;
};
static inline struct uvcg_framebased *to_uvcg_framebased(struct config_item *item)
{
return container_of(to_uvcg_format(item), struct uvcg_framebased, fmt);
}
static struct configfs_group_operations uvcg_framebased_group_ops = {
.make_item = uvcg_frame_make,
.drop_item = uvcg_frame_drop,
};
#define UVCG_FRAMEBASED_ATTR_RO(cname, aname, bits) \
static ssize_t uvcg_framebased_##cname##_show(struct config_item *item, \
char *page) \
{ \
struct uvcg_framebased *u = to_uvcg_framebased(item); \
struct f_uvc_opts *opts; \
struct config_item *opts_item; \
struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
int result; \
\
mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
\
opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; \
opts = to_f_uvc_opts(opts_item); \
\
mutex_lock(&opts->lock); \
result = scnprintf(page, PAGE_SIZE, "%u\n", le##bits##_to_cpu(u->desc.aname));\
mutex_unlock(&opts->lock); \
\
mutex_unlock(su_mutex); \
return result; \
} \
\
UVC_ATTR_RO(uvcg_framebased_, cname, aname)
#define UVCG_FRAMEBASED_ATTR(cname, aname, bits) \
static ssize_t uvcg_framebased_##cname##_show(struct config_item *item, \
char *page) \
{ \
struct uvcg_framebased *u = to_uvcg_framebased(item); \
struct f_uvc_opts *opts; \
struct config_item *opts_item; \
struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
int result; \
\
mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
\
opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
opts = to_f_uvc_opts(opts_item); \
\
mutex_lock(&opts->lock); \
result = scnprintf(page, PAGE_SIZE, "%u\n", le##bits##_to_cpu(u->desc.aname));\
mutex_unlock(&opts->lock); \
\
mutex_unlock(su_mutex); \
return result; \
} \
\
static ssize_t \
uvcg_framebased_##cname##_store(struct config_item *item, \
const char *page, size_t len) \
{ \
struct uvcg_framebased *u = to_uvcg_framebased(item); \
struct f_uvc_opts *opts; \
struct config_item *opts_item; \
struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \
int ret; \
u8 num; \
\
mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \
\
opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
opts = to_f_uvc_opts(opts_item); \
\
mutex_lock(&opts->lock); \
if (u->fmt.linked || opts->refcnt) { \
ret = -EBUSY; \
goto end; \
} \
\
ret = kstrtou8(page, 0, &num); \
if (ret) \
goto end; \
\
if (num > 255) { \
ret = -EINVAL; \
goto end; \
} \
u->desc.aname = num; \
ret = len; \
end: \
mutex_unlock(&opts->lock); \
mutex_unlock(su_mutex); \
return ret; \
} \
\
UVC_ATTR(uvcg_framebased_, cname, aname)
UVCG_FRAMEBASED_ATTR_RO(b_format_index, bFormatIndex, 8);
UVCG_FRAMEBASED_ATTR_RO(b_bits_per_pixel, bBitsPerPixel, 8);
UVCG_FRAMEBASED_ATTR(b_default_frame_index, bDefaultFrameIndex, 8);
UVCG_FRAMEBASED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, 8);
UVCG_FRAMEBASED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, 8);
UVCG_FRAMEBASED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, 8);
#undef UVCG_FRAMEBASED_ATTR
#undef UVCG_FRAMEBASED_ATTR_RO
static ssize_t uvcg_framebased_guid_format_show(struct config_item *item,
char *page)
{
struct uvcg_framebased *ch = to_uvcg_framebased(item);
struct f_uvc_opts *opts;
struct config_item *opts_item;
struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
mutex_lock(su_mutex); /* for navigating configfs hierarchy */
opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
opts = to_f_uvc_opts(opts_item);
mutex_lock(&opts->lock);
memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat));
mutex_unlock(&opts->lock);
mutex_unlock(su_mutex);
return sizeof(ch->desc.guidFormat);
}
static ssize_t uvcg_framebased_guid_format_store(struct config_item *item,
const char *page, size_t len)
{
struct uvcg_framebased *ch = to_uvcg_framebased(item);
struct f_uvc_opts *opts;
struct config_item *opts_item;
struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex;
int ret;
mutex_lock(su_mutex); /* for navigating configfs hierarchy */
opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;
opts = to_f_uvc_opts(opts_item);
mutex_lock(&opts->lock);
if (ch->fmt.linked || opts->refcnt) {
ret = -EBUSY;
goto end;
}
memcpy(ch->desc.guidFormat, page,
min(sizeof(ch->desc.guidFormat), len));
ret = sizeof(ch->desc.guidFormat);
end:
mutex_unlock(&opts->lock);
mutex_unlock(su_mutex);
return ret;
}
UVC_ATTR(uvcg_framebased_, guid_format, guidFormat);
static inline ssize_t
uvcg_framebased_bma_controls_show(struct config_item *item, char *page)
{
struct uvcg_framebased *u = to_uvcg_framebased(item);
return uvcg_format_bma_controls_show(&u->fmt, page);
}
static inline ssize_t
uvcg_framebased_bma_controls_store(struct config_item *item,
const char *page, size_t len)
{
struct uvcg_framebased *u = to_uvcg_framebased(item);
return uvcg_format_bma_controls_store(&u->fmt, page, len);
}
UVC_ATTR(uvcg_framebased_, bma_controls, bmaControls);
static struct configfs_attribute *uvcg_framebased_attrs[] = {
&uvcg_framebased_attr_b_format_index,
&uvcg_framebased_attr_b_default_frame_index,
&uvcg_framebased_attr_b_bits_per_pixel,
&uvcg_framebased_attr_b_aspect_ratio_x,
&uvcg_framebased_attr_b_aspect_ratio_y,
&uvcg_framebased_attr_bm_interface_flags,
&uvcg_framebased_attr_bma_controls,
&uvcg_framebased_attr_guid_format,
NULL,
};
static const struct config_item_type uvcg_framebased_type = {
.ct_item_ops = &uvcg_config_item_ops,
.ct_group_ops = &uvcg_framebased_group_ops,
.ct_attrs = uvcg_framebased_attrs,
.ct_owner = THIS_MODULE,
};
static struct config_group *uvcg_framebased_make(struct config_group *group,
const char *name)
{
static char guid[] = { /*Declear frame based as H264 format*/
'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00,
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
};
struct uvcg_framebased *h;
h = kzalloc(sizeof(*h), GFP_KERNEL);
if (!h)
return ERR_PTR(-ENOMEM);
h->desc.bLength = UVC_DT_FORMAT_FRAMEBASED_SIZE;
h->desc.bDescriptorType = USB_DT_CS_INTERFACE;
h->desc.bDescriptorSubType = UVC_VS_FORMAT_FRAME_BASED;
memcpy(h->desc.guidFormat, guid, sizeof(guid));
h->desc.bBitsPerPixel = 0;
h->desc.bDefaultFrameIndex = 1;
h->desc.bAspectRatioX = 0;
h->desc.bAspectRatioY = 0;
h->desc.bmInterfaceFlags = 0;
h->desc.bCopyProtect = 0;
h->desc.bVariableSize = 1;
h->fmt.type = UVCG_FRAMEBASED;
config_group_init_type_name(&h->fmt.group, name,
&uvcg_framebased_type);
return &h->fmt.group;
}
static struct configfs_group_operations uvcg_framebased_grp_ops = {
.make_group = uvcg_framebased_make,
};
static const struct uvcg_config_group_type uvcg_framebased_grp_type = {
.type = {
.ct_item_ops = &uvcg_config_item_ops,
.ct_group_ops = &uvcg_framebased_grp_ops,
.ct_owner = THIS_MODULE,
},
.name = "framebased",
};
/* -----------------------------------------------------------------------------
* streaming/color_matching/default
*/
@ -2001,6 +2284,7 @@ static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h,
if (ret)
return ret;
grp = &f->fmt->group;
j = 0;
list_for_each_entry(item, &grp->cg_children, ci_entry) {
frm = to_uvcg_frame(item);
ret = fun(frm, priv2, priv3, j++, UVCG_FRAME);
@ -2049,6 +2333,11 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
container_of(fmt, struct uvcg_mjpeg, fmt);
*size += sizeof(m->desc);
} else if (fmt->type == UVCG_FRAMEBASED) {
struct uvcg_framebased *f =
container_of(fmt, struct uvcg_framebased, fmt);
*size += sizeof(f->desc);
} else {
return -EINVAL;
}
@ -2059,6 +2348,11 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
int sz = sizeof(frm->dw_frame_interval);
*size += sizeof(frm->frame);
/*
* framebased has duplicate member with uncompressed and
* mjpeg, so minus it
*/
*size -= sizeof(u32);
*size += frm->frame.b_frame_interval_type * sz;
}
break;
@ -2069,6 +2363,27 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
return 0;
}
static int __uvcg_copy_framebased_desc(void *dest, struct uvcg_frame *frm,
int sz)
{
struct uvc_frame_framebased *desc = dest;
desc->bLength = frm->frame.b_length;
desc->bDescriptorType = frm->frame.b_descriptor_type;
desc->bDescriptorSubType = frm->frame.b_descriptor_subtype;
desc->bFrameIndex = frm->frame.b_frame_index;
desc->bmCapabilities = frm->frame.bm_capabilities;
desc->wWidth = frm->frame.w_width;
desc->wHeight = frm->frame.w_height;
desc->dwMinBitRate = frm->frame.dw_min_bit_rate;
desc->dwMaxBitRate = frm->frame.dw_max_bit_rate;
desc->dwDefaultFrameInterval = frm->frame.dw_default_frame_interval;
desc->bFrameIntervalType = frm->frame.b_frame_interval_type;
desc->dwBytesPerLine = frm->frame.dw_bytes_perline;
return 0;
}
/*
* Fill an array of streaming descriptors.
*
@ -2123,6 +2438,15 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
m->desc.bNumFrameDescriptors = fmt->num_frames;
memcpy(*dest, &m->desc, sizeof(m->desc));
*dest += sizeof(m->desc);
} else if (fmt->type == UVCG_FRAMEBASED) {
struct uvcg_framebased *f =
container_of(fmt, struct uvcg_framebased,
fmt);
f->desc.bFormatIndex = n + 1;
f->desc.bNumFrameDescriptors = fmt->num_frames;
memcpy(*dest, &f->desc, sizeof(f->desc));
*dest += sizeof(f->desc);
} else {
return -EINVAL;
}
@ -2132,8 +2456,11 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
struct uvcg_frame *frm = priv1;
struct uvc_descriptor_header *h = *dest;
sz = sizeof(frm->frame);
memcpy(*dest, &frm->frame, sz);
sz = sizeof(frm->frame) - 4;
if (frm->fmt_type != UVCG_FRAMEBASED)
memcpy(*dest, &frm->frame, sz);
else
__uvcg_copy_framebased_desc(*dest, frm, sz);
*dest += sz;
sz = frm->frame.b_frame_interval_type *
sizeof(*frm->dw_frame_interval);
@ -2145,6 +2472,9 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
else if (frm->fmt_type == UVCG_MJPEG)
h->bLength = UVC_DT_FRAME_MJPEG_SIZE(
frm->frame.b_frame_interval_type);
else if (frm->fmt_type == UVCG_FRAMEBASED)
h->bLength = UVC_DT_FRAME_FRAMEBASED_SIZE(
frm->frame.b_frame_interval_type);
}
break;
}
@ -2357,6 +2687,7 @@ static const struct uvcg_config_group_type uvcg_streaming_grp_type = {
&uvcg_streaming_header_grp_type,
&uvcg_uncompressed_grp_type,
&uvcg_mjpeg_grp_type,
&uvcg_framebased_grp_type,
&uvcg_color_matching_grp_type,
&uvcg_streaming_class_grp_type,
NULL,

View file

@ -58,6 +58,9 @@ struct uvc_format {
static struct uvc_format uvc_formats[] = {
{ 16, V4L2_PIX_FMT_YUYV },
{ 0, V4L2_PIX_FMT_MJPEG },
{ 0, V4L2_PIX_FMT_H264 },
{ 12, V4L2_PIX_FMT_YUV420 },
{ 8, V4L2_PIX_FMT_GREY },
};
static int

View file

@ -542,9 +542,6 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx)
d->vhub = vhub;
d->index = idx;
d->name = devm_kasprintf(parent, GFP_KERNEL, "port%d", idx+1);
if (!d->name)
return -ENOMEM;
d->regs = vhub->regs + 0x100 + 0x10 * idx;
ast_vhub_init_ep0(vhub, &d->ep0, d);

View file

@ -748,7 +748,7 @@ static int dummy_dequeue(struct usb_ep *_ep, struct usb_request *_req)
struct dummy *dum;
int retval = -EINVAL;
unsigned long flags;
struct dummy_request *req = NULL, *iter;
struct dummy_request *req = NULL;
if (!_ep || !_req)
return retval;
@ -758,26 +758,25 @@ static int dummy_dequeue(struct usb_ep *_ep, struct usb_request *_req)
if (!dum->driver)
return -ESHUTDOWN;
spin_lock_irqsave(&dum->lock, flags);
list_for_each_entry(iter, &ep->queue, queue) {
if (&iter->req != _req)
continue;
list_del_init(&iter->queue);
_req->status = -ECONNRESET;
req = iter;
retval = 0;
break;
local_irq_save(flags);
spin_lock(&dum->lock);
list_for_each_entry(req, &ep->queue, queue) {
if (&req->req == _req) {
list_del_init(&req->queue);
_req->status = -ECONNRESET;
retval = 0;
break;
}
}
spin_unlock(&dum->lock);
if (retval == 0) {
dev_dbg(udc_dev(dum),
"dequeued req %p from %s, len %d buf %p\n",
req, _ep->name, _req->length, _req->buf);
spin_unlock(&dum->lock);
usb_gadget_giveback_request(_ep, _req);
spin_lock(&dum->lock);
}
spin_unlock_irqrestore(&dum->lock, flags);
local_irq_restore(flags);
return retval;
}

View file

@ -306,7 +306,7 @@ struct renesas_usb3_request {
struct list_head queue;
};
#define USB3_EP_NAME_SIZE 16
#define USB3_EP_NAME_SIZE 8
struct renesas_usb3_ep {
struct usb_ep ep;
struct renesas_usb3 *usb3;
@ -2551,7 +2551,6 @@ static int renesas_usb3_remove(struct platform_device *pdev)
struct renesas_usb3 *usb3 = platform_get_drvdata(pdev);
debugfs_remove_recursive(usb3->dentry);
put_device(usb3->host_dev);
device_remove_file(&pdev->dev, &dev_attr_role);
cancel_work_sync(&usb3->role_work);

View file

@ -1925,7 +1925,7 @@ error:
if (hcd) {
kfree(max3421_hcd->tx);
kfree(max3421_hcd->rx);
if (!IS_ERR_OR_NULL(max3421_hcd->spi_thread))
if (max3421_hcd->spi_thread)
kthread_stop(max3421_hcd->spi_thread);
usb_put_hcd(hcd);
}
@ -1956,12 +1956,6 @@ max3421_remove(struct spi_device *spi)
return 0;
}
static const struct spi_device_id max3421_spi_ids[] = {
{ "max3421" },
{ },
};
MODULE_DEVICE_TABLE(spi, max3421_spi_ids);
static const struct of_device_id max3421_of_match_table[] = {
{ .compatible = "maxim,max3421", },
{},
@ -1971,7 +1965,6 @@ MODULE_DEVICE_TABLE(of, max3421_of_match_table);
static struct spi_driver max3421_driver = {
.probe = max3421_probe,
.remove = max3421_remove,
.id_table = max3421_spi_ids,
.driver = {
.name = "max3421-hcd",
.of_match_table = of_match_ptr(max3421_of_match_table),

View file

@ -165,25 +165,6 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
return 0;
}
static int ohci_quirk_loongson(struct usb_hcd *hcd)
{
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
/*
* Loongson's LS7A OHCI controller (rev 0x02) has a
* flaw. MMIO register with offset 0x60/64 is treated
* as legacy PS2-compatible keyboard/mouse interface.
* Since OHCI only use 4KB BAR resource, LS7A OHCI's
* 32KB BAR is wrapped around (the 2nd 4KB BAR space
* is the same as the 1st 4KB internally). So add 4KB
* offset (0x1000) to the OHCI registers as a quirk.
*/
if (pdev->revision == 0x2)
hcd->regs += SZ_4K; /* SZ_4K = 0x1000 */
return 0;
}
static int ohci_quirk_qemu(struct usb_hcd *hcd)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
@ -243,10 +224,6 @@ static const struct pci_device_id ohci_pci_quirks[] = {
PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
.driver_data = (unsigned long)ohci_quirk_amd700,
},
{
PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, 0x7a24),
.driver_data = (unsigned long)ohci_quirk_loongson,
},
{
.vendor = PCI_VENDOR_ID_APPLE,
.device = 0x003f,

View file

@ -945,15 +945,6 @@ static void quirk_usb_disable_ehci(struct pci_dev *pdev)
* booting from USB disk or using a usb keyboard
*/
hcc_params = readl(base + EHCI_HCC_PARAMS);
/* LS7A EHCI controller doesn't have extended capabilities, the
* EECP (EHCI Extended Capabilities Pointer) field of HCCPARAMS
* register should be 0x0 but it reads as 0xa0. So clear it to
* avoid error messages on boot.
*/
if (pdev->vendor == PCI_VENDOR_ID_LOONGSON && pdev->device == 0x7a14)
hcc_params &= ~(0xffL << 8);
offset = (hcc_params >> 8) & 0xff;
while (offset && --count) {
pci_read_config_dword(pdev, offset, &cap);

View file

@ -122,7 +122,7 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)
}
/* Get and enable clock if any specified */
uhci->clk = devm_clk_get_optional(&pdev->dev, NULL);
uhci->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(uhci->clk)) {
ret = PTR_ERR(uhci->clk);
goto err_rmr;

View file

@ -975,15 +975,8 @@ int xhci_dbc_suspend(struct xhci_hcd *xhci)
if (!dbc)
return 0;
switch (dbc->state) {
case DS_ENABLED:
case DS_CONNECTED:
case DS_CONFIGURED:
if (dbc->state == DS_CONFIGURED)
dbc->resume_required = 1;
break;
default:
break;
}
xhci_dbc_stop(xhci);

View file

@ -629,7 +629,8 @@ static int xhci_enter_test_mode(struct xhci_hcd *xhci,
if (!xhci->devs[i])
continue;
retval = xhci_disable_and_free_slot(xhci, i);
retval = xhci_disable_slot(xhci, i);
xhci_free_virt_device(xhci, i);
if (retval)
xhci_err(xhci, "Failed to disable slot %d, %d. Enter test mode anyway\n",
i, retval);

View file

@ -879,20 +879,21 @@ free_tts:
* will be manipulated by the configure endpoint, allocate device, or update
* hub functions while this function is removing the TT entries from the list.
*/
void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev,
int slot_id)
void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
{
struct xhci_virt_device *dev;
int i;
int old_active_eps = 0;
/* Slot ID 0 is reserved */
if (slot_id == 0 || !dev)
if (slot_id == 0 || !xhci->devs[slot_id])
return;
/* If device ctx array still points to _this_ device, clear it */
if (dev->out_ctx &&
xhci->dcbaa->dev_context_ptrs[slot_id] == cpu_to_le64(dev->out_ctx->dma))
xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
dev = xhci->devs[slot_id];
xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
if (!dev)
return;
trace_xhci_free_virt_device(dev);
@ -931,9 +932,8 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev,
if (dev->udev && dev->udev->slot_id)
dev->udev->slot_id = 0;
if (xhci->devs[slot_id] == dev)
xhci->devs[slot_id] = NULL;
kfree(dev);
kfree(xhci->devs[slot_id]);
xhci->devs[slot_id] = NULL;
}
/*
@ -975,7 +975,7 @@ static void xhci_free_virt_devices_depth_first(struct xhci_hcd *xhci, int slot_i
out:
/* we are now at a leaf device */
xhci_debugfs_remove_slot(xhci, slot_id);
xhci_free_virt_device(xhci, vdev, slot_id);
xhci_free_virt_device(xhci, slot_id);
}
int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
@ -1214,8 +1214,6 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
ep0_ctx->deq = cpu_to_le64(dev->eps[0].ring->first_seg->dma |
dev->eps[0].ring->cycle_state);
ep0_ctx->tx_info = cpu_to_le32(EP_AVG_TRB_LENGTH(8));
trace_xhci_setup_addressable_virt_device(dev);
/* Steps 7 and 8 were done in xhci_alloc_virt_device() */

View file

@ -26,8 +26,8 @@
#define SPARSE_CNTL_ENABLE 0xC12C
/* Device for a quirk */
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
#define PCI_DEVICE_ID_FRESCO_LOGIC_FL1009 0x1009
#define PCI_DEVICE_ID_FRESCO_LOGIC_FL1100 0x1100
#define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400 0x1400
@ -36,8 +36,8 @@
#define PCI_DEVICE_ID_EJ168 0x7023
#define PCI_DEVICE_ID_EJ188 0x7052
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_XHCI 0x9cb1
#define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5
#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f

View file

@ -977,15 +977,12 @@ static void xhci_kill_endpoint_urbs(struct xhci_hcd *xhci,
*/
void xhci_hc_died(struct xhci_hcd *xhci)
{
bool notify;
int i, j;
if (xhci->xhc_state & XHCI_STATE_DYING)
return;
notify = !(xhci->xhc_state & XHCI_STATE_REMOVING);
if (notify)
xhci_err(xhci, "xHCI host controller not responding, assume dead\n");
xhci_err(xhci, "xHCI host controller not responding, assume dead\n");
xhci->xhc_state |= XHCI_STATE_DYING;
xhci_cleanup_command_queue(xhci);
@ -999,7 +996,7 @@ void xhci_hc_died(struct xhci_hcd *xhci)
}
/* inform usb core hc died if PCI remove isn't already handling it */
if (notify)
if (!(xhci->xhc_state & XHCI_STATE_REMOVING))
usb_hc_died(xhci_to_hcd(xhci));
}
@ -1262,8 +1259,7 @@ static void xhci_handle_cmd_enable_slot(struct xhci_hcd *xhci, int slot_id,
command->slot_id = 0;
}
static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id,
u32 cmd_comp_code)
static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id)
{
struct xhci_virt_device *virt_dev;
struct xhci_slot_ctx *slot_ctx;
@ -1278,10 +1274,6 @@ static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id,
if (xhci->quirks & XHCI_EP_LIMIT_QUIRK)
/* Delete default control endpoint resources */
xhci_free_device_endpoint_resources(xhci, virt_dev, true);
if (cmd_comp_code == COMP_SUCCESS) {
xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
xhci->devs[slot_id] = NULL;
}
}
static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id,
@ -1521,7 +1513,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
xhci_handle_cmd_enable_slot(xhci, slot_id, cmd, cmd_comp_code);
break;
case TRB_DISABLE_SLOT:
xhci_handle_cmd_disable_slot(xhci, slot_id, cmd_comp_code);
xhci_handle_cmd_disable_slot(xhci, slot_id);
break;
case TRB_CONFIG_EP:
if (!cmd->completion)
@ -4233,8 +4225,7 @@ static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd,
if ((xhci->xhc_state & XHCI_STATE_DYING) ||
(xhci->xhc_state & XHCI_STATE_HALTED)) {
xhci_dbg(xhci, "xHCI dying or halted, can't queue_command. state: 0x%x\n",
xhci->xhc_state);
xhci_dbg(xhci, "xHCI dying or halted, can't queue_command\n");
return -ESHUTDOWN;
}

View file

@ -139,8 +139,7 @@ int xhci_halt(struct xhci_hcd *xhci)
ret = xhci_handshake(&xhci->op_regs->status,
STS_HALT, STS_HALT, 3 * XHCI_MAX_HALT_USEC);
if (ret) {
if (!(xhci->xhc_state & XHCI_STATE_DYING))
xhci_warn(xhci, "Host halt failed, %d\n", ret);
xhci_warn(xhci, "Host halt failed, %d\n", ret);
return ret;
}
xhci->xhc_state |= XHCI_STATE_HALTED;
@ -205,8 +204,7 @@ int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us)
state = readl(&xhci->op_regs->status);
if (state == ~(u32)0) {
if (!(xhci->xhc_state & XHCI_STATE_DYING))
xhci_warn(xhci, "Host not accessible, reset failed.\n");
xhci_warn(xhci, "Host not accessible, reset failed.\n");
return -ENODEV;
}
@ -4132,7 +4130,7 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
xhci_disable_slot(xhci, udev->slot_id);
spin_lock_irqsave(&xhci->lock, flags);
xhci_free_virt_device(xhci, virt_dev, udev->slot_id);
xhci_free_virt_device(xhci, udev->slot_id);
spin_unlock_irqrestore(&xhci->lock, flags);
}
@ -4181,16 +4179,6 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id)
return ret;
}
int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id)
{
struct xhci_virt_device *vdev = xhci->devs[slot_id];
int ret;
ret = xhci_disable_slot(xhci, slot_id);
xhci_free_virt_device(xhci, vdev, slot_id);
return ret;
}
/*
* Checks if we have enough host controller resources for the default control
* endpoint.
@ -4296,7 +4284,8 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
return 1;
disable_slot:
xhci_disable_and_free_slot(xhci, udev->slot_id);
xhci_disable_slot(xhci, udev->slot_id);
xhci_free_virt_device(xhci, udev->slot_id);
return 0;
}
@ -4425,7 +4414,8 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
dev_warn(&udev->dev, "Device not responding to setup %s.\n", act);
mutex_unlock(&xhci->mutex);
ret = xhci_disable_and_free_slot(xhci, udev->slot_id);
ret = xhci_disable_slot(xhci, udev->slot_id);
xhci_free_virt_device(xhci, udev->slot_id);
if (!ret) {
if (xhci_alloc_dev(hcd, udev) == 1)
xhci_setup_addressable_virt_dev(xhci, udev);

View file

@ -2031,7 +2031,7 @@ void xhci_dbg_trace(struct xhci_hcd *xhci, void (*trace)(struct va_format *),
/* xHCI memory management */
void xhci_mem_cleanup(struct xhci_hcd *xhci);
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags);
void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev, int slot_id);
void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id);
int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags);
int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev);
void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci,
@ -2123,7 +2123,6 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
struct usb_tt *tt, gfp_t mem_flags);
int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id);
int xhci_ext_cap_init(struct xhci_hcd *xhci);
int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup);

View file

@ -68,20 +68,18 @@
* The magic limit was calculated so that it allows the monitoring
* application to pick data once in two ticks. This way, another application,
* which presumably drives the bus, gets to hog CPU, yet we collect our data.
*
* Originally, for a 480 Mbit/s bus this required a buffer of about 1 MB. For
* modern 20 Gbps buses, this value increases to over 50 MB. The maximum
* buffer size is set to 64 MiB to accommodate this.
* If HZ is 100, a 480 mbit/s bus drives 614 KB every jiffy. USB has an
* enormous overhead built into the bus protocol, so we need about 1000 KB.
*
* This is still too much for most cases, where we just snoop a few
* descriptor fetches for enumeration. So, the default is a "reasonable"
* amount for typical, low-throughput use cases.
* amount for systems with HZ=250 and incomplete bus saturation.
*
* XXX What about multi-megabyte URBs which take minutes to transfer?
*/
#define BUFF_MAX CHUNK_ALIGN(64*1024*1024)
#define BUFF_DFL CHUNK_ALIGN(300*1024)
#define BUFF_MIN CHUNK_ALIGN(8*1024)
#define BUFF_MAX CHUNK_ALIGN(1200*1024)
#define BUFF_DFL CHUNK_ALIGN(300*1024)
#define BUFF_MIN CHUNK_ALIGN(8*1024)
/*
* The per-event API header (2 per URB).

View file

@ -1910,7 +1910,6 @@ static int musb_gadget_stop(struct usb_gadget *g)
* gadget driver here and have everything work;
* that currently misbehaves.
*/
usb_gadget_set_state(g, USB_STATE_NOTATTACHED);
/* Force check of devctl register for PM runtime */
schedule_delayed_work(&musb->irq_work, 0);
@ -2019,7 +2018,6 @@ void musb_g_disconnect(struct musb *musb)
case OTG_STATE_B_PERIPHERAL:
case OTG_STATE_B_IDLE:
musb->xceiv->otg->state = OTG_STATE_B_IDLE;
usb_gadget_set_state(&musb->g, USB_STATE_NOTATTACHED);
break;
case OTG_STATE_B_SRP_INIT:
break;

View file

@ -476,13 +476,13 @@ static int omap2430_probe(struct platform_device *pdev)
ARRAY_SIZE(musb_resources));
if (ret) {
dev_err(&pdev->dev, "failed to add resources\n");
goto err_put_control_otghs;
goto err2;
}
ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
if (ret) {
dev_err(&pdev->dev, "failed to add platform_data\n");
goto err_put_control_otghs;
goto err2;
}
pm_runtime_enable(glue->dev);
@ -497,9 +497,7 @@ static int omap2430_probe(struct platform_device *pdev)
err3:
pm_runtime_disable(glue->dev);
err_put_control_otghs:
if (!IS_ERR(glue->control_otghs))
put_device(glue->control_otghs);
err2:
platform_device_put(musb);
@ -513,8 +511,6 @@ static int omap2430_remove(struct platform_device *pdev)
platform_device_unregister(glue->musb);
pm_runtime_disable(glue->dev);
if (!IS_ERR(glue->control_otghs))
put_device(glue->control_otghs);
return 0;
}

View file

@ -394,7 +394,6 @@ static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy)
static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
{
bool vbus_is_on = false;
enum usb_phy_events last_event = mxs_phy->phy.last_event;
/* If the SoCs don't need to disconnect line without vbus, quit */
if (!(mxs_phy->data->flags & MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS))
@ -406,8 +405,7 @@ static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
if (on && ((!vbus_is_on && !mxs_phy_is_otg_host(mxs_phy))
|| (last_event == USB_EVENT_VBUS)))
if (on && !vbus_is_on && !mxs_phy_is_otg_host(mxs_phy))
__mxs_phy_disconnect_line(mxs_phy, true);
else
__mxs_phy_disconnect_line(mxs_phy, false);

View file

@ -328,8 +328,9 @@ static int twl6030_set_vbus(struct phy_companion *comparator, bool enabled)
static int twl6030_usb_probe(struct platform_device *pdev)
{
u32 ret;
struct twl6030_usb *twl;
int status, err, ret;
int status, err;
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;

View file

@ -313,10 +313,8 @@ static int usbhsc_clk_get(struct device *dev, struct usbhs_priv *priv)
priv->clks[1] = of_clk_get(dev_of_node(dev), 1);
if (PTR_ERR(priv->clks[1]) == -ENOENT)
priv->clks[1] = NULL;
else if (IS_ERR(priv->clks[1])) {
clk_put(priv->clks[0]);
else if (IS_ERR(priv->clks[1]))
return PTR_ERR(priv->clks[1]);
}
return 0;
}
@ -680,29 +678,10 @@ static int usbhs_probe(struct platform_device *pdev)
INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug);
spin_lock_init(usbhs_priv_to_lock(priv));
/*
* Acquire clocks and enable power management (PM) early in the
* probe process, as the driver accesses registers during
* initialization. Ensure the device is active before proceeding.
*/
pm_runtime_enable(dev);
ret = usbhsc_clk_get(dev, priv);
if (ret)
goto probe_pm_disable;
ret = pm_runtime_resume_and_get(dev);
if (ret)
goto probe_clk_put;
ret = usbhsc_clk_prepare_enable(priv);
if (ret)
goto probe_pm_put;
/* call pipe and module init */
ret = usbhs_pipe_probe(priv);
if (ret < 0)
goto probe_clk_dis_unprepare;
return ret;
ret = usbhs_fifo_probe(priv);
if (ret < 0)
@ -719,6 +698,10 @@ static int usbhs_probe(struct platform_device *pdev)
if (ret)
goto probe_fail_rst;
ret = usbhsc_clk_get(dev, priv);
if (ret)
goto probe_fail_clks;
/*
* deviece reset here because
* USB device might be used in boot loader.
@ -734,7 +717,7 @@ static int usbhs_probe(struct platform_device *pdev)
dev_warn(dev, "USB function not selected (GPIO %d)\n",
priv->dparam.enable_gpio);
ret = -ENOTSUPP;
goto probe_assert_rest;
goto probe_end_mod_exit;
}
}
@ -748,19 +731,14 @@ static int usbhs_probe(struct platform_device *pdev)
ret = usbhs_platform_call(priv, hardware_init, pdev);
if (ret < 0) {
dev_err(dev, "platform init failed.\n");
goto probe_assert_rest;
goto probe_end_mod_exit;
}
/* reset phy for connection */
usbhs_platform_call(priv, phy_reset, pdev);
/*
* Disable the clocks that were enabled earlier in the probe path,
* and let the driver handle the clocks beyond this point.
*/
usbhsc_clk_disable_unprepare(priv);
pm_runtime_put(dev);
/* power control */
pm_runtime_enable(dev);
if (!usbhs_get_dparam(priv, runtime_pwctrl)) {
usbhsc_power_ctrl(priv, 1);
usbhs_mod_autonomy_mode(priv);
@ -777,7 +755,9 @@ static int usbhs_probe(struct platform_device *pdev)
return ret;
probe_assert_rest:
probe_end_mod_exit:
usbhsc_clk_put(priv);
probe_fail_clks:
reset_control_assert(priv->rsts);
probe_fail_rst:
usbhs_mod_remove(priv);
@ -785,14 +765,6 @@ probe_end_fifo_exit:
usbhs_fifo_remove(priv);
probe_end_pipe_exit:
usbhs_pipe_remove(priv);
probe_clk_dis_unprepare:
usbhsc_clk_disable_unprepare(priv);
probe_pm_put:
pm_runtime_put(dev);
probe_clk_put:
usbhsc_clk_put(priv);
probe_pm_disable:
pm_runtime_disable(dev);
dev_info(dev, "probe failed (%d)\n", ret);
@ -805,8 +777,6 @@ static int usbhs_remove(struct platform_device *pdev)
dev_dbg(&pdev->dev, "usb remove\n");
flush_delayed_work(&priv->notify_hotplug_work);
/* power off */
if (!usbhs_get_dparam(priv, runtime_pwctrl))
usbhsc_power_ctrl(priv, 0);

View file

@ -1094,7 +1094,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
goto usbhs_mod_gadget_probe_err_gpriv;
}
gpriv->transceiver = devm_usb_get_phy(dev, USB_PHY_TYPE_UNDEFINED);
gpriv->transceiver = usb_get_phy(USB_PHY_TYPE_UNDEFINED);
dev_info(dev, "%stransceiver found\n",
!IS_ERR(gpriv->transceiver) ? "" : "no ");

View file

@ -317,15 +317,14 @@ usb_role_switch_register(struct device *parent,
sw->dev.type = &usb_role_dev_type;
dev_set_name(&sw->dev, "%s-role-switch", dev_name(parent));
sw->registered = true;
ret = device_register(&sw->dev);
if (ret) {
sw->registered = false;
put_device(&sw->dev);
return ERR_PTR(ret);
}
sw->registered = true;
/* TODO: Symlinks for the host port and the device controller. */
return sw;

View file

@ -224,7 +224,6 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
{ USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
{ USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
{ USB_DEVICE(0x1B93, 0x1013) }, /* Phoenix Contact UPS Device */
{ USB_DEVICE(0x1BA4, 0x0002) }, /* Silicon Labs 358x factory default */
{ USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */
{ USB_DEVICE(0x1D6F, 0x0010) }, /* Seluxit ApS RF Dongle */

View file

@ -781,8 +781,6 @@ static const struct usb_device_id id_table_combined[] = {
.driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
{ USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID),
.driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
{ USB_DEVICE(FTDI_NDI_VID, FTDI_NDI_EMGUIDE_GEMINI_PID),
.driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
{ USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
{ USB_DEVICE(NOVITUS_VID, NOVITUS_BONO_E_PID) },
{ USB_DEVICE(FTDI_VID, RTSYSTEMS_USB_VX8_PID) },
@ -1059,22 +1057,6 @@ static const struct usb_device_id id_table_combined[] = {
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
/* GMC devices */
{ USB_DEVICE(GMC_VID, GMC_Z216C_PID) },
/* Altera USB Blaster 3 */
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_6022_PID, 1) },
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_6025_PID, 2) },
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_6026_PID, 2) },
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_6026_PID, 3) },
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_6029_PID, 2) },
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602A_PID, 2) },
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602A_PID, 3) },
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602C_PID, 1) },
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602D_PID, 1) },
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602D_PID, 2) },
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 1) },
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 2) },
{ USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 3) },
/* Abacus Electrics */
{ USB_DEVICE(FTDI_VID, ABACUS_OPTICAL_PROBE_PID) },
{ } /* Terminating entry */
};

View file

@ -197,9 +197,6 @@
#define FTDI_NDI_FUTURE_3_PID 0xDA73 /* NDI future device #3 */
#define FTDI_NDI_AURORA_SCU_PID 0xDA74 /* NDI Aurora SCU */
#define FTDI_NDI_VID 0x23F2
#define FTDI_NDI_EMGUIDE_GEMINI_PID 0x0003 /* NDI Emguide Gemini */
/*
* ChamSys Limited (www.chamsys.co.uk) USB wing/interface product IDs
*/
@ -438,11 +435,6 @@
#define LINX_FUTURE_1_PID 0xF44B /* Linx future device */
#define LINX_FUTURE_2_PID 0xF44C /* Linx future device */
/*
* Abacus Electrics
*/
#define ABACUS_OPTICAL_PROBE_PID 0xf458 /* ABACUS ELECTRICS Optical Probe */
/*
* Oceanic product ids
*/
@ -1613,16 +1605,3 @@
*/
#define GMC_VID 0x1cd7
#define GMC_Z216C_PID 0x0217 /* GMC Z216C Adapter IR-USB */
/*
* Altera USB Blaster 3 (http://www.altera.com).
*/
#define ALTERA_VID 0x09fb
#define ALTERA_UB3_6022_PID 0x6022
#define ALTERA_UB3_6025_PID 0x6025
#define ALTERA_UB3_6026_PID 0x6026
#define ALTERA_UB3_6029_PID 0x6029
#define ALTERA_UB3_602A_PID 0x602a
#define ALTERA_UB3_602C_PID 0x602c
#define ALTERA_UB3_602D_PID 0x602d
#define ALTERA_UB3_602E_PID 0x602e

View file

@ -273,7 +273,6 @@ static void option_instat_callback(struct urb *urb);
#define QUECTEL_PRODUCT_EM05CN 0x0312
#define QUECTEL_PRODUCT_EM05G_GR 0x0313
#define QUECTEL_PRODUCT_EM05G_RS 0x0314
#define QUECTEL_PRODUCT_RG255C 0x0316
#define QUECTEL_PRODUCT_EM12 0x0512
#define QUECTEL_PRODUCT_RM500Q 0x0800
#define QUECTEL_PRODUCT_RM520N 0x0801
@ -612,16 +611,23 @@ static void option_instat_callback(struct urb *urb);
/* Sierra Wireless products */
#define SIERRA_VENDOR_ID 0x1199
#define SIERRA_PRODUCT_EM9191 0x90d3
#define SIERRA_PRODUCT_EM9291 0x90e3
/* UNISOC (Spreadtrum) products */
#define UNISOC_VENDOR_ID 0x1782
/* TOZED LT70-C based on UNISOC SL8563 uses UNISOC's vendor ID */
#define TOZED_PRODUCT_LT70C 0x4055
#define UNISOC_PRODUCT_UIS7720 0x4064
/* Luat Air72*U series based on UNISOC UIS8910 uses UNISOC's vendor ID */
#define LUAT_PRODUCT_AIR720U 0x4e00
/* MeiG Smart Technology products */
#define MEIGSMART_VENDOR_ID 0x2dee
/* MeiG Smart SRM825L based on Qualcomm 315 */
#define MEIGSMART_PRODUCT_SRM825L 0x4d22
/* MeiG Smart SLM320 based on UNISOC UIS8910 */
#define MEIGSMART_PRODUCT_SLM320 0x4d41
/* MeiG Smart SLM770A based on ASR1803 */
#define MEIGSMART_PRODUCT_SLM770A 0x4d57
/* Device flags */
/* Highest interface number which can be used with NCTRL() and RSVD() */
@ -1272,9 +1278,6 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG650V, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG650V, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG255C, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG255C, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RG255C, 0xff, 0xff, 0x40) },
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
{ USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
@ -1327,18 +1330,7 @@ static const struct usb_device_id option_ids[] = {
.driver_info = NCTRL(0) | RSVD(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1033, 0xff), /* Telit LE910C1-EUX (ECM) */
.driver_info = NCTRL(0) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1034, 0xff), /* Telit LE910C4-WWX (rmnet) */
.driver_info = RSVD(2) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1035, 0xff) }, /* Telit LE910C4-WWX (ECM) */
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1036, 0xff) }, /* Telit LE910C4-WWX */
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1037, 0xff), /* Telit LE910C4-WWX (rmnet) */
.driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1038, 0xff), /* Telit LE910C4-WWX (rmnet) */
.driver_info = NCTRL(0) | RSVD(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x103b, 0xff), /* Telit LE910C4-WWX */
.driver_info = NCTRL(0) | NCTRL(1) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x103c, 0xff), /* Telit LE910C4-WWX */
.driver_info = NCTRL(0) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0),
.driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1),
@ -1375,87 +1367,42 @@ static const struct usb_device_id option_ids[] = {
.driver_info = NCTRL(2) | RSVD(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1063, 0xff), /* Telit LN920 (ECM) */
.driver_info = NCTRL(0) | RSVD(1) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990A (rmnet) */
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1070, 0xff), /* Telit FN990 (rmnet) */
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990A (MBIM) */
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1071, 0xff), /* Telit FN990 (MBIM) */
.driver_info = NCTRL(0) | RSVD(1) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990A (RNDIS) */
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1072, 0xff), /* Telit FN990 (RNDIS) */
.driver_info = NCTRL(2) | RSVD(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990A (ECM) */
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990 (ECM) */
.driver_info = NCTRL(0) | RSVD(1) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990A (PCIe) */
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990 (PCIe) */
.driver_info = RSVD(0) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1077, 0xff), /* Telit FN990A (rmnet + audio) */
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1080, 0xff), /* Telit FE990 (rmnet) */
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1078, 0xff), /* Telit FN990A (MBIM + audio) */
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1081, 0xff), /* Telit FE990 (MBIM) */
.driver_info = NCTRL(0) | RSVD(1) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1079, 0xff), /* Telit FN990A (RNDIS + audio) */
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1082, 0xff), /* Telit FE990 (RNDIS) */
.driver_info = NCTRL(2) | RSVD(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1080, 0xff), /* Telit FE990A (rmnet) */
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1081, 0xff), /* Telit FE990A (MBIM) */
.driver_info = NCTRL(0) | RSVD(1) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1082, 0xff), /* Telit FE990A (RNDIS) */
.driver_info = NCTRL(2) | RSVD(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1083, 0xff), /* Telit FE990A (ECM) */
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1083, 0xff), /* Telit FE990 (ECM) */
.driver_info = NCTRL(0) | RSVD(1) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a0, 0xff), /* Telit FN20C04 (rmnet) */
.driver_info = RSVD(0) | NCTRL(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a2, 0xff), /* Telit FN920C04 (MBIM) */
.driver_info = NCTRL(4) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a3, 0xff), /* Telit FN920C04 (ECM) */
.driver_info = NCTRL(4) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a4, 0xff), /* Telit FN20C04 (rmnet) */
.driver_info = RSVD(0) | NCTRL(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a7, 0xff), /* Telit FN920C04 (MBIM) */
.driver_info = NCTRL(4) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a8, 0xff), /* Telit FN920C04 (ECM) */
.driver_info = NCTRL(4) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a9, 0xff), /* Telit FN20C04 (rmnet) */
.driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10aa, 0xff), /* Telit FN920C04 (MBIM) */
.driver_info = NCTRL(3) | RSVD(4) | RSVD(5) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b0, 0xff, 0xff, 0x30), /* Telit FE990B (rmnet) */
.driver_info = NCTRL(5) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b0, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b0, 0xff, 0xff, 0x60) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b1, 0xff, 0xff, 0x30), /* Telit FE990B (MBIM) */
.driver_info = NCTRL(6) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b1, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b1, 0xff, 0xff, 0x60) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b2, 0xff, 0xff, 0x30), /* Telit FE990B (RNDIS) */
.driver_info = NCTRL(6) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b2, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b2, 0xff, 0xff, 0x60) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b3, 0xff, 0xff, 0x30), /* Telit FE990B (ECM) */
.driver_info = NCTRL(6) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b3, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b3, 0xff, 0xff, 0x60) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c0, 0xff), /* Telit FE910C04 (rmnet) */
.driver_info = RSVD(0) | NCTRL(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c4, 0xff), /* Telit FE910C04 (rmnet) */
.driver_info = RSVD(0) | NCTRL(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10c8, 0xff), /* Telit FE910C04 (rmnet) */
.driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d0, 0xff, 0xff, 0x30), /* Telit FN990B (rmnet) */
.driver_info = NCTRL(5) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d0, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d0, 0xff, 0xff, 0x60) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10c7, 0xff, 0xff, 0x30), /* Telit FE910C04 (ECM) */
.driver_info = NCTRL(4) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10c7, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d1, 0xff, 0xff, 0x30), /* Telit FN990B (MBIM) */
.driver_info = NCTRL(6) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d1, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d1, 0xff, 0xff, 0x60) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d2, 0xff, 0xff, 0x30), /* Telit FN990B (RNDIS) */
.driver_info = NCTRL(6) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d2, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d2, 0xff, 0xff, 0x60) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d3, 0xff, 0xff, 0x30), /* Telit FN990B (ECM) */
.driver_info = NCTRL(6) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d3, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10d3, 0xff, 0xff, 0x60) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
.driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
@ -2123,12 +2070,6 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9003, 0xff) }, /* Simcom SIM7500/SIM7600 MBIM mode */
{ USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9011, 0xff), /* Simcom SIM7500/SIM7600 RNDIS mode */
.driver_info = RSVD(7) },
{ USB_DEVICE(0x1e0e, 0x9071), /* Simcom SIM8230 RMNET mode */
.driver_info = RSVD(3) | RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9078, 0xff), /* Simcom SIM8230 ECM mode */
.driver_info = RSVD(5) },
{ USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x907b, 0xff), /* Simcom SIM8230 RNDIS mode */
.driver_info = RSVD(5) },
{ USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9205, 0xff) }, /* Simcom SIM7070/SIM7080/SIM7090 AT+ECM mode */
{ USB_DEVICE_INTERFACE_CLASS(0x1e0e, 0x9206, 0xff) }, /* Simcom SIM7070/SIM7080/SIM7090 AT-only mode */
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
@ -2378,10 +2319,6 @@ static const struct usb_device_id option_ids[] = {
.driver_info = RSVD(3) },
{ USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe145, 0xff), /* Foxconn T99W651 RNDIS */
.driver_info = RSVD(5) | RSVD(6) },
{ USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe15f, 0xff), /* Foxconn T99W709 */
.driver_info = RSVD(5) },
{ USB_DEVICE_INTERFACE_CLASS(0x0489, 0xe167, 0xff), /* Foxconn T99W640 MBIM */
.driver_info = RSVD(3) },
{ USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */
.driver_info = RSVD(4) | RSVD(5) | RSVD(6) },
{ USB_DEVICE(0x1782, 0x4d10) }, /* Fibocom L610 (AT mode) */
@ -2410,14 +2347,6 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a05, 0xff) }, /* Fibocom FM650-CN (NCM mode) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff) }, /* Fibocom FM650-CN (RNDIS mode) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a07, 0xff) }, /* Fibocom FM650-CN (MBIM mode) */
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d41, 0xff, 0, 0) }, /* MeiG Smart SLM320 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d57, 0xff, 0, 0) }, /* MeiG Smart SLM770A */
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0, 0) }, /* MeiG Smart SRM815 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x02) }, /* MeiG Smart SLM828 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0x10, 0x03) }, /* MeiG Smart SLM828 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM815 and SRM825L */
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825L */
{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825L */
{ 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 */
@ -2472,16 +2401,17 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, UNISOC_PRODUCT_UIS7720, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM320, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SLM770A, 0xff, 0, 0) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(MEIGSMART_VENDOR_ID, MEIGSMART_PRODUCT_SRM825L, 0xff, 0xff, 0x60) },
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */
.driver_info = NCTRL(1) },
{ USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0640, 0xff), /* TCL IK512 ECM */
.driver_info = NCTRL(3) },
{ USB_DEVICE_INTERFACE_CLASS(0x2949, 0x8700, 0xff) }, /* Neoway N723-EA */
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);

View file

@ -555,7 +555,7 @@ static void qt2_process_read_urb(struct urb *urb)
newport = *(ch + 3);
if (newport >= serial->num_ports) {
if (newport > serial->num_ports) {
dev_err(&port->dev,
"%s - port change to invalid port: %i\n",
__func__, newport);

View file

@ -101,11 +101,6 @@ DEVICE(nokia, NOKIA_IDS);
{ USB_DEVICE(0x09d7, 0x0100) } /* NovAtel FlexPack GPS */
DEVICE_N(novatel_gps, NOVATEL_IDS, 3);
/* OWON electronic test and measurement equipment driver */
#define OWON_IDS() \
{ USB_DEVICE(0x5345, 0x1234) } /* HDS200 oscilloscopes and others */
DEVICE(owon, OWON_IDS);
/* Siemens USB/MPI adapter */
#define SIEMENS_IDS() \
{ USB_DEVICE(0x908, 0x0004) }
@ -140,7 +135,6 @@ static struct usb_serial_driver * const serial_drivers[] = {
&motorola_tetra_device,
&nokia_device,
&novatel_gps_device,
&owon_device,
&siemens_mpi_device,
&suunto_device,
&vivopay_device,
@ -160,7 +154,6 @@ static const struct usb_device_id id_table[] = {
MOTOROLA_TETRA_IDS(),
NOKIA_IDS(),
NOVATEL_IDS(),
OWON_IDS(),
SIEMENS_IDS(),
SUUNTO_IDS(),
VIVOPAY_IDS(),

Some files were not shown because too many files have changed in this diff Show more