b434e4bcd4
* refs/heads/tmp-314ab78: Linux 4.19.84 kvm: x86: mmu: Recovery of shattered NX large pages kvm: Add helper function for creating VM worker threads kvm: mmu: ITLB_MULTIHIT mitigation KVM: vmx, svm: always run with EFER.NXE=1 when shadow paging is active KVM: x86: add tracepoints around __direct_map and FNAME(fetch) KVM: x86: change kvm_mmu_page_get_gfn BUG_ON to WARN_ON KVM: x86: remove now unneeded hugepage gfn adjustment KVM: x86: make FNAME(fetch) and __direct_map more similar kvm: mmu: Do not release the page inside mmu_set_spte() kvm: Convert kvm_lock to a mutex kvm: x86, powerpc: do not allow clearing largepages debugfs entry Documentation: Add ITLB_MULTIHIT documentation cpu/speculation: Uninline and export CPU mitigations helpers x86/cpu: Add Tremont to the cpu vulnerability whitelist x86/bugs: Add ITLB_MULTIHIT bug infrastructure x86/speculation/taa: Fix printing of TAA_MSG_SMT on IBRS_ALL CPUs x86/tsx: Add config options to set tsx=on|off|auto x86/speculation/taa: Add documentation for TSX Async Abort x86/tsx: Add "auto" option to the tsx= cmdline parameter kvm/x86: Export MDS_NO=0 to guests when TSX is enabled x86/speculation/taa: Add sysfs reporting for TSX Async Abort x86/speculation/taa: Add mitigation for TSX Async Abort x86/cpu: Add a "tsx=" cmdline option with TSX disabled by default x86/cpu: Add a helper function x86_read_arch_cap_msr() x86/msr: Add the IA32_TSX_CTRL MSR KVM: x86: use Intel speculation bugs and features as derived in generic x86 code drm/i915/cmdparser: Fix jump whitelist clearing drm/i915/gen8+: Add RC6 CTX corruption WA drm/i915: Lower RM timeout to avoid DSI hard hangs drm/i915/cmdparser: Ignore Length operands during command matching drm/i915/cmdparser: Add support for backward jumps drm/i915/cmdparser: Use explicit goto for error paths drm/i915: Add gen9 BCS cmdparsing drm/i915: Allow parsing of unsized batches drm/i915: Support ro ppgtt mapped cmdparser shadow buffers drm/i915: Add support for mandatory cmdparsing drm/i915: Remove Master tables from cmdparser drm/i915: Disable Secure Batches for gen6+ drm/i915: Rename gen7 cmdparser tables vsock/virtio: fix sock refcnt holding during the shutdown iio: imu: mpu6050: Fix FIFO layout for ICM20602 net: prevent load/store tearing on sk->sk_stamp netfilter: ipset: Copy the right MAC address in hash:ip,mac IPv6 sets usbip: Fix free of unallocated memory in vhci tx cgroup,writeback: don't switch wbs immediately on dead wbs if the memcg is dead mm/filemap.c: don't initiate writeback if mapping has no dirty pages iio: imu: inv_mpu6050: fix no data on MPU6050 iio: imu: mpu6050: Add support for the ICM 20602 IMU blkcg: make blkcg_print_stat() print stats only for online blkgs pinctrl: cherryview: Fix irq_valid_mask calculation ocfs2: protect extent tree in ocfs2_prepare_inode_for_write() pinctrl: intel: Avoid potential glitches if pin is in GPIO mode e1000: fix memory leaks igb: Fix constant media auto sense switching when no cable is connected net: ethernet: arc: add the missed clk_disable_unprepare NFSv4: Don't allow a cached open with a revoked delegation usb: dwc3: gadget: fix race when disabling ep with cancelled xfers hv_netvsc: Fix error handling in netvsc_attach() drm/amd/display: Passive DP->HDMI dongle detection fix drm/amdgpu: If amdgpu_ib_schedule fails return back the error. iommu/amd: Apply the same IVRS IOAPIC workaround to Acer Aspire A315-41 net: mscc: ocelot: refuse to overwrite the port's native vlan net: mscc: ocelot: fix vlan_filtering when enslaving to bridge before link is up net: hisilicon: Fix "Trying to free already-free IRQ" fjes: Handle workqueue allocation failure nvme-multipath: fix possible io hang after ctrl reconnect scsi: qla2xxx: stop timer in shutdown path RDMA/hns: Prevent memory leaks of eq->buf_list RDMA/iw_cxgb4: Avoid freeing skb twice in arp failure case usbip: tools: Fix read_usb_vudc_device() error path handling USB: ldusb: use unsigned size format specifiers USB: Skip endpoints with 0 maxpacket length perf/x86/uncore: Fix event group support perf/x86/amd/ibs: Handle erratum #420 only on the affected CPU family (10h) perf/x86/amd/ibs: Fix reading of the IBS OpData register and thus precise RIP validity usb: dwc3: remove the call trace of USBx_GFLADJ usb: gadget: configfs: fix concurrent issue between composite APIs usb: dwc3: pci: prevent memory leak in dwc3_pci_probe usb: gadget: composite: Fix possible double free memory bug usb: gadget: udc: atmel: Fix interrupt storm in FIFO mode. usb: fsl: Check memory resource before releasing it macsec: fix refcnt leak in module exit routine bonding: fix unexpected IFF_BONDING bit unset ipvs: move old_secure_tcp into struct netns_ipvs ipvs: don't ignore errors in case refcounting ip_vs module fails netfilter: nf_flow_table: set timeout before insertion into hashes scsi: qla2xxx: Initialized mailbox to prevent driver load failure scsi: lpfc: Honor module parameter lpfc_use_adisc net: openvswitch: free vport unless register_netdevice() succeeds RDMA/uverbs: Prevent potential underflow scsi: qla2xxx: fixup incorrect usage of host_byte net/mlx5: prevent memory leak in mlx5_fpga_conn_create_cq net/mlx5e: TX, Fix consumer index of error cqe dump RDMA/qedr: Fix reported firmware version iw_cxgb4: fix ECN check on the passive accept RDMA/mlx5: Clear old rate limit when closing QP HID: intel-ish-hid: fix wrong error handling in ishtp_cl_alloc_tx_ring() dmaengine: sprd: Fix the possible memory leak issue dmaengine: xilinx_dma: Fix control reg update in vdma_channel_set_config HID: google: add magnemite/masterball USB ids PCI: tegra: Enable Relaxed Ordering only for Tegra20 & Tegra30 usbip: Implement SG support to vhci-hcd and stub driver usbip: Fix vhci_urb_enqueue() URB null transfer buffer error path sched/fair: Fix -Wunused-but-set-variable warnings sched/fair: Fix low cpu usage with high throttling by removing expiration of cpu-local slices ALSA: usb-audio: Fix copy&paste error in the validator ALSA: usb-audio: remove some dead code ALSA: usb-audio: Fix possible NULL dereference at create_yamaha_midi_quirk() ALSA: usb-audio: Clean up check_input_term() ALSA: usb-audio: Remove superfluous bLength checks ALSA: usb-audio: Unify the release of usb_mixer_elem_info objects ALSA: usb-audio: Simplify parse_audio_unit() ALSA: usb-audio: More validations of descriptor units configfs: fix a deadlock in configfs_symlink() configfs: provide exclusion between IO and removals configfs: new object reprsenting tree fragments configfs_register_group() shouldn't be (and isn't) called in rmdirable parts configfs: stash the data we need into configfs_buffer at open time can: peak_usb: fix slab info leak can: mcba_usb: fix use-after-free on disconnect can: dev: add missing of_node_put() after calling of_get_child_by_name() can: gs_usb: gs_can_open(): prevent memory leak can: rx-offload: can_rx_offload_queue_sorted(): fix error handling, avoid skb mem leak can: peak_usb: fix a potential out-of-sync while decoding packets can: c_can: c_can_poll(): only read status register after status IRQ can: flexcan: disable completely the ECC mechanism can: usb_8dev: fix use-after-free on disconnect SMB3: Fix persistent handles reconnect x86/apic/32: Avoid bogus LDR warnings intel_th: pci: Add Jasper Lake PCH support intel_th: pci: Add Comet Lake PCH support netfilter: ipset: Fix an error code in ip_set_sockfn_get() netfilter: nf_tables: Align nft_expr private data to 64-bit ARM: sunxi: Fix CPU powerdown on A83T iio: srf04: fix wrong limitation in distance measuring iio: imu: adis16480: make sure provided frequency is positive iio: adc: stm32-adc: fix stopping dma ceph: add missing check in d_revalidate snapdir handling ceph: fix use-after-free in __ceph_remove_cap() arm64: Do not mask out PTE_RDONLY in pte_same() soundwire: bus: set initial value to port_status soundwire: depend on ACPI HID: wacom: generic: Treat serial number and related fields as unsigned drm/radeon: fix si_enable_smc_cac() failed issue perf tools: Fix time sorting tools: gpio: Use !building_out_of_srctree to determine srctree dump_stack: avoid the livelock of the dump_lock mm, vmstat: hide /proc/pagetypeinfo from normal users mm: thp: handle page cache THP correctly in PageTransCompoundMap mm, meminit: recalculate pcpu batch and high limits after init completes mm: memcontrol: fix network errors from failing __GFP_ATOMIC charges ALSA: hda/ca0132 - Fix possible workqueue stall ALSA: bebob: fix to detect configured source of sampling clock for Focusrite Saffire Pro i/o series ALSA: timer: Fix incorrectly assigned timer instance net: hns: Fix the stray netpoll locks causing deadlock in NAPI path ipv6: fixes rt6_probe() and fib6_nh->last_probe init net: mscc: ocelot: fix NULL pointer on LAG slave removal net: mscc: ocelot: don't handle netdev events for other netdevs qede: fix NULL pointer deref in __qede_remove() NFC: st21nfca: fix double free nfc: netlink: fix double device reference drop NFC: fdp: fix incorrect free object net: usb: qmi_wwan: add support for DW5821e with eSIM support net: qualcomm: rmnet: Fix potential UAF when unregistering net: fix data-race in neigh_event_send() net: ethernet: octeon_mgmt: Account for second possible VLAN header ipv4: Fix table id reference in fib_sync_down_addr CDC-NCM: handle incomplete transfer of MTU bonding: fix state transition issue in link monitoring Linux 4.19.83 usb: gadget: udc: core: Fix segfault if udc_bind_to_driver() for pending driver fails arm64: dts: ti: k3-am65-main: Fix gic-its node unit-address ASoC: pcm3168a: The codec does not support S32_LE selftests/powerpc: Fix compile error on tlbie_test due to newer gcc selftests/powerpc: Add test case for tlbie vs mtpidr ordering issue powerpc/mm: Fixup tlbie vs mtpidr/mtlpidr ordering issue on POWER9 platform/x86: pmc_atom: Add Siemens SIMATIC IPC227E to critclk_systems DMI table wireless: Skip directory when generating certificates net/flow_dissector: switch to siphash r8152: add device id for Lenovo ThinkPad USB-C Dock Gen 2 net: dsa: fix switch tree list net: usb: lan78xx: Connect PHY before registering MAC net: bcmgenet: reset 40nm EPHY on energy detect net: phy: bcm7xxx: define soft_reset for 40nm EPHY net: bcmgenet: don't set phydev->link from MAC net: dsa: b53: Do not clear existing mirrored port mask net/mlx5e: Fix ethtool self test: link speed r8169: fix wrong PHY ID issue with RTL8168dp net/mlx5e: Fix handling of compressed CQEs in case of low NAPI budget selftests: fib_tests: add more tests for metric update ipv4: fix route update on metric change. net: add READ_ONCE() annotation in __skb_wait_for_more_packets() net: use skb_queue_empty_lockless() in busy poll contexts net: use skb_queue_empty_lockless() in poll() handlers udp: use skb_queue_empty_lockless() net: add skb_queue_empty_lockless() vxlan: check tun_info options_len properly udp: fix data-race in udp_set_dev_scratch() selftests: net: reuseport_dualstack: fix uninitalized parameter net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol() net: usb: lan78xx: Disable interrupts before calling generic_handle_irq() netns: fix GFP flags in rtnl_net_notifyid() net/mlx4_core: Dynamically set guaranteed amount of counters per VF net: hisilicon: Fix ping latency when deal with high throughput net: fix sk_page_frag() recursion from memory reclaim net: ethernet: ftgmac100: Fix DMA coherency issue with SW checksum net: dsa: bcm_sf2: Fix IMP setup for port different than 8 net: annotate lockless accesses to sk->sk_napi_id net: annotate accesses to sk->sk_incoming_cpu inet: stop leaking jiffies on the wire erspan: fix the tun_info options_len check for erspan dccp: do not leak jiffies on the wire cxgb4: fix panic when attaching to ULD fail nbd: handle racing with error'ed out commands nbd: protect cmd->status with cmd->lock cifs: Fix cifsInodeInfo lock_sem deadlock when reconnect occurs i2c: stm32f7: remove warning when compiling with W=1 i2c: stm32f7: fix a race in slave mode with arbitration loss irq i2c: stm32f7: fix first byte to send in slave mode irqchip/gic-v3-its: Use the exact ITSList for VMOVP MIPS: bmips: mark exception vectors as char arrays of: unittest: fix memory leak in unittest_data_add ARM: 8926/1: v7m: remove register save to stack before svc tracing: Fix "gfp_t" format for synthetic events scsi: target: core: Do not overwrite CDB byte 1 drm/amdgpu: fix potential VM faults ARM: davinci: dm365: Fix McBSP dma_slave_map entry perf kmem: Fix memory leak in compact_gfp_flags() 8250-men-mcb: fix error checking when get_num_ports returns -ENODEV perf c2c: Fix memory leak in build_cl_output() ARM: dts: imx7s: Correct GPT's ipg clock source scsi: fix kconfig dependency warning related to 53C700_LE_ON_BE scsi: sni_53c710: fix compilation error scsi: scsi_dh_alua: handle RTPG sense code correctly during state transitions scsi: qla2xxx: fix a potential NULL pointer dereference ARM: mm: fix alignment handler faults under memory pressure pinctrl: ns2: Fix off by one bugs in ns2_pinmux_enable() ARM: dts: logicpd-torpedo-som: Remove twl_keypad ASoc: rockchip: i2s: Fix RPM imbalance ASoC: wm_adsp: Don't generate kcontrols without READ flags regulator: pfuze100-regulator: Variable "val" in pfuze100_regulator_probe() could be uninitialized ASoC: rt5682: add NULL handler to set_jack function regulator: ti-abb: Fix timeout in ti_abb_wait_txdone/ti_abb_clear_all_txdone arm64: dts: Fix gpio to pinmux mapping arm64: dts: allwinner: a64: sopine-baseboard: Add PHY regulator delay arm64: dts: allwinner: a64: pine64-plus: Add PHY regulator delay ASoC: wm8994: Do not register inapplicable controls for WM1811 regulator: of: fix suspend-min/max-voltage parsing kbuild: add -fcf-protection=none when using retpoline flags Linux 4.19.82 Revert "ALSA: hda: Flush interrupts on disabling" powerpc/powernv: Fix CPU idle to be called with IRQs disabled ALSA: usb-audio: Add DSD support for Gustard U16/X26 USB Interface ALSA: usb-audio: Update DSD support quirks for Oppo and Rotel ALSA: usb-audio: DSD auto-detection for Playback Designs ALSA: timer: Fix mutex deadlock at releasing card ALSA: timer: Simplify error path in snd_timer_open() sch_netem: fix rcu splat in netem_enqueue() net: usb: sr9800: fix uninitialized local variable bonding: fix potential NULL deref in bond_update_slave_arr NFC: pn533: fix use-after-free and memleaks rxrpc: Fix trace-after-put looking at the put peer record rxrpc: rxrpc_peer needs to hold a ref on the rxrpc_local record rxrpc: Fix call ref leak llc: fix sk_buff leak in llc_conn_service() llc: fix sk_buff leak in llc_sap_state_process() batman-adv: Avoid free/alloc race when handling OGM buffer NFS: Fix an RCU lock leak in nfs4_refresh_delegation_stateid() drm/amdgpu/powerplay/vega10: allow undervolting in p7 dmaengine: cppi41: Fix cppi41_dma_prep_slave_sg() when idle dmaengine: qcom: bam_dma: Fix resource leak rtlwifi: Fix potential overflow on P2P code arm64: Ensure VM_WRITE|VM_SHARED ptes are clean by default s390/idle: fix cpu idle time calculation s390/cmm: fix information leak in cmm_timeout_handler() nl80211: fix validation of mesh path nexthop HID: fix error message in hid_open_report() HID: Fix assumption that devices have inputs HID: i2c-hid: add Trekstor Primebook C11B to descriptor override scsi: target: cxgbit: Fix cxgbit_fw4_ack() USB: serial: whiteheat: fix line-speed endianness USB: serial: whiteheat: fix potential slab corruption usb: xhci: fix __le32/__le64 accessors in debugfs code USB: ldusb: fix control-message timeout USB: ldusb: fix ring-buffer locking usb-storage: Revert commit 747668dbc061 ("usb-storage: Set virt_boundary_mask to avoid SG overflows") USB: gadget: Reject endpoints with 0 maxpacket value UAS: Revert commit 3ae62a42090f ("UAS: fix alignment of scatter/gather segments") ALSA: hda/realtek - Add support for ALC623 ALSA: hda/realtek - Fix 2 front mics of codec 0x623 ALSA: bebob: Fix prototype of helper function to return negative value fuse: truncate pending writes on O_TRUNC fuse: flush dirty data/metadata before non-truncate setattr ath6kl: fix a NULL-ptr-deref bug in ath6kl_usb_alloc_urb_from_pipe() thunderbolt: Use 32-bit writes when writing ring producer/consumer USB: legousbtower: fix a signedness bug in tower_probe() nbd: verify socket is supported during setup iwlwifi: exclude GEO SAR support for 3168 ALSA: hda/realtek: Reduce the Headphone static noise on XPS 9350/9360 ARM: 8914/1: NOMMU: Fix exc_ret for XIP tracing: Initialize iter->seq after zeroing in tracing_read_pipe() s390/uaccess: avoid (false positive) compiler warnings NFSv4: Fix leak of clp->cl_acceptor string nbd: fix possible sysfs duplicate warning virt: vbox: fix memory leak in hgcm_call_preprocess_linaddr MIPS: fw: sni: Fix out of bounds init of o32 stack MIPS: include: Mark __xchg as __always_inline iio: imu: adis16400: release allocated memory on failure drm/amdgpu: fix memory leak perf/x86/amd: Change/fix NMI latency mitigation to use a timestamp sched/vtime: Fix guest/system mis-accounting on task switch x86/cpu: Add Comet Lake to the Intel CPU models header arm64: armv8_deprecated: Checking return value for memory allocation fs: ocfs2: fix a possible null-pointer dereference in ocfs2_info_scan_inode_alloc() fs: ocfs2: fix a possible null-pointer dereference in ocfs2_write_end_nolock() fs: ocfs2: fix possible null-pointer dereferences in ocfs2_xa_prepare_entry() ocfs2: clear zero in unaligned direct IO x86/xen: Return from panic notifier MIPS: include: Mark __cmpxchg as __always_inline efi/x86: Do not clean dummy variable in kexec path efi/cper: Fix endianness of PCIe class code serial: mctrl_gpio: Check for NULL pointer fs: cifs: mute -Wunused-const-variable message gpio: max77620: Use correct unit for debounce times tty: n_hdlc: fix build on SPARC tty: serial: owl: Fix the link time qualifier of 'owl_uart_exit()' arm64: ftrace: Ensure synchronisation in PLT setup for Neoverse-N1 #1542419 nfs: Fix nfsi->nrequests count error on nfs_inode_remove_request HID: hyperv: Use in-place iterator API in the channel callback RDMA/iwcm: Fix a lock inversion issue RDMA/hfi1: Prevent memory leak in sdma_init staging: rtl8188eu: fix null dereference when kzalloc fails perf annotate: Return appropriate error code for allocation failures perf annotate: Propagate the symbol__annotate() error return perf annotate: Fix the signedness of failure returns perf annotate: Propagate perf_env__arch() error perf tools: Propagate get_cpuid() error perf jevents: Fix period for Intel fixed counters perf script brstackinsn: Fix recovery from LBR/binary mismatch perf map: Fix overlapped map handling perf tests: Avoid raising SEGV using an obvious NULL dereference libsubcmd: Make _FORTIFY_SOURCE defines dependent on the feature iio: fix center temperature of bmc150-accel-core iio: adc: meson_saradc: Fix memory allocation order power: supply: max14656: fix potential use-after-free drm/amd/display: fix odm combine pipe reset PCI/PME: Fix possible use-after-free on remove net: dsa: mv88e6xxx: Release lock while requesting IRQ exec: load_script: Do not exec truncated interpreter path ext4: disallow files with EXT4_JOURNAL_DATA_FL from EXT4_IOC_SWAP_BOOT media: vimc: Remove unused but set variables ALSA: hda/realtek - Apply ALC294 hp init also for S4 resume cifs: add credits from unmatched responses/messages CIFS: Respect SMB2 hdr preamble size in read responses scsi: lpfc: Correct localport timeout duration error mlxsw: spectrum: Set LAG port collector only when active arm64: kpti: Whitelist HiSilicon Taishan v110 CPUs arm64: Add MIDR encoding for HiSilicon Taishan CPUs rtc: pcf8523: set xtal load capacitance from DT usb: handle warm-reset port requests on hub resume ALSA: usb-audio: Cleanup DSD whitelist usb: dwc3: gadget: clear DWC3_EP_TRANSFER_STARTED on cmd complete usb: dwc3: gadget: early giveback if End Transfer already completed samples: bpf: fix: seg fault with NULL pointer arg HID: steam: fix deadlock with input devices. HID: steam: fix boot loop with bluetooth firmware NFSv4: Ensure that the state manager exits the loop on SIGKILL HID: Add ASUS T100CHI keyboard dock battery quirks staging: mt7621-pinctrl: use pinconf-generic for 'dt_node_to_map' and 'dt_free_map' scripts/setlocalversion: Improve -dirty check with git-status --no-optional-locks clk: boston: unregister clks on failure in clk_boston_setup() ath10k: assign 'n_cipher_suites = 11' for WCN3990 to enable WPA3 platform/x86: Fix config space access for intel_atomisp2_pm platform/x86: Add the VLV ISP PCI ID to atomisp2_pm HID: i2c-hid: Add Odys Winbook 13 to descriptor override HID: i2c-hid: Ignore input report if there's no data present on Elan touchpanels HID: i2c-hid: Disable runtime PM for LG touchscreen netfilter: ipset: Make invalid MAC address checks consistent Btrfs: fix deadlock on tree root leaf when finding free extent PCI: Fix Switchtec DMA aliasing quirk dmesg noise bcache: fix input overflow to writeback_rate_minimum drm/msm/dpu: handle failures while initializing displays x86/cpu: Add Atom Tremont (Jacobsville) tools/power turbostat: fix goldmont C-state limit decoding usb: dwc2: fix unbalanced use of external vbus-supply HID: i2c-hid: add Direkt-Tek DTLAPY133-1 to descriptor override f2fs: fix to recover inode->i_flags of inode block during POR f2fs: fix to recover inode's i_gc_failures during POR powerpc/powernv: hold device_hotplug_lock when calling memtrace_offline_pages() sc16is7xx: Fix for "Unexpected interrupt: 8" scsi: lpfc: Fix a duplicate 0711 log message number. f2fs: flush quota blocks after turnning it off wil6210: fix freeing of rx buffers in EDMA mode btrfs: tracepoints: Fix wrong parameter order for qgroup events btrfs: qgroup: Always free PREALLOC META reserve in btrfs_delalloc_release_extents() Btrfs: fix memory leak due to concurrent append writes with fiemap Btrfs: fix inode cache block reserve leak on failure to allocate data space dm snapshot: rework COW throttling to fix deadlock dm snapshot: introduce account_start_copy() and account_end_copy() zram: fix race between backing_dev_show and backing_dev_store Conflicts: arch/arm64/include/asm/cputype.h drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c drivers/net/wireless/ath/wil6210/txrx_edma.c drivers/usb/dwc3/gadget.c include/linux/cpu.h kernel/cpu.c Following USB commits were reverted on importing android-4.19.57 into msm-4.19 due to BootTimeRunner failure. android-4.19-q.82 introduced new usb changes [1] that fixed the regression, hence it is safe to restore the reverts. It is done in this merge. 9c423fd89("usb: dwc3: Reset num_trbs after skipping") 385cacd95("usb: dwc3: gadget: Clear req->needs_extra_trb flag on cleanup") 6edcdd0e6("usb: dwc3: gadget: remove wait_end_transfer") d7ff2e3ff("usb: dwc3: gadget: move requests to cancelled_list") bba5f9878("usb: dwc3: gadget: introduce cancelled_list") 65e1f3403("usb: dwc3: gadget: extract dwc3_gadget_ep_skip_trbs()") 56092bd50("usb: dwc3: gadget: use num_trbs when skipping TRBs on->dequeue()") 2a2b1c4dc("usb: dwc3: gadget: track number of TRBs per request") 420b1237c("usb: dwc3: gadget: combine unaligned and zero flags") 62805d319("Revert "usb: dwc3: gadget: Clear req->needs_extra_trb flag on cleanup"") [1] a0608eec29("usb: dwc3: gadget: clear DWC3_EP_TRANSFER_STARTED on cmd complete") d0e8b35e91("usb: dwc3: gadget: early giveback if End Transfer already completed") Change-Id: I77c3490d2c1cf7c8233a7e797c6f217f737621a2 Signed-off-by: Ivaylo Georgiev <irgeorgiev@codeaurora.org>
841 lines
18 KiB
C
841 lines
18 KiB
C
/*
|
|
BlueZ - Bluetooth protocol stack for Linux
|
|
Copyright (C) 2000-2001 Qualcomm Incorporated
|
|
|
|
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License version 2 as
|
|
published by the Free Software Foundation;
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
|
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
|
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
|
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
|
SOFTWARE IS DISCLAIMED.
|
|
*/
|
|
|
|
/* Bluetooth address family and sockets. */
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/debugfs.h>
|
|
#include <linux/stringify.h>
|
|
#include <linux/sched/signal.h>
|
|
|
|
#include <asm/ioctls.h>
|
|
|
|
#include <net/bluetooth/bluetooth.h>
|
|
#include <linux/proc_fs.h>
|
|
|
|
#include "leds.h"
|
|
#include "selftest.h"
|
|
|
|
/* Bluetooth sockets */
|
|
#define BT_MAX_PROTO 8
|
|
static const struct net_proto_family *bt_proto[BT_MAX_PROTO];
|
|
static DEFINE_RWLOCK(bt_proto_lock);
|
|
|
|
static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
|
|
static const char *const bt_key_strings[BT_MAX_PROTO] = {
|
|
"sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
|
|
"sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
|
|
"sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
|
|
"sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM",
|
|
"sk_lock-AF_BLUETOOTH-BTPROTO_BNEP",
|
|
"sk_lock-AF_BLUETOOTH-BTPROTO_CMTP",
|
|
"sk_lock-AF_BLUETOOTH-BTPROTO_HIDP",
|
|
"sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
|
|
};
|
|
|
|
static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
|
|
static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
|
|
"slock-AF_BLUETOOTH-BTPROTO_L2CAP",
|
|
"slock-AF_BLUETOOTH-BTPROTO_HCI",
|
|
"slock-AF_BLUETOOTH-BTPROTO_SCO",
|
|
"slock-AF_BLUETOOTH-BTPROTO_RFCOMM",
|
|
"slock-AF_BLUETOOTH-BTPROTO_BNEP",
|
|
"slock-AF_BLUETOOTH-BTPROTO_CMTP",
|
|
"slock-AF_BLUETOOTH-BTPROTO_HIDP",
|
|
"slock-AF_BLUETOOTH-BTPROTO_AVDTP",
|
|
};
|
|
|
|
void bt_sock_reclassify_lock(struct sock *sk, int proto)
|
|
{
|
|
BUG_ON(!sk);
|
|
BUG_ON(!sock_allow_reclassification(sk));
|
|
|
|
sock_lock_init_class_and_name(sk,
|
|
bt_slock_key_strings[proto], &bt_slock_key[proto],
|
|
bt_key_strings[proto], &bt_lock_key[proto]);
|
|
}
|
|
EXPORT_SYMBOL(bt_sock_reclassify_lock);
|
|
|
|
int bt_sock_register(int proto, const struct net_proto_family *ops)
|
|
{
|
|
int err = 0;
|
|
|
|
if (proto < 0 || proto >= BT_MAX_PROTO)
|
|
return -EINVAL;
|
|
|
|
write_lock(&bt_proto_lock);
|
|
|
|
if (bt_proto[proto])
|
|
err = -EEXIST;
|
|
else
|
|
bt_proto[proto] = ops;
|
|
|
|
write_unlock(&bt_proto_lock);
|
|
|
|
return err;
|
|
}
|
|
EXPORT_SYMBOL(bt_sock_register);
|
|
|
|
void bt_sock_unregister(int proto)
|
|
{
|
|
if (proto < 0 || proto >= BT_MAX_PROTO)
|
|
return;
|
|
|
|
write_lock(&bt_proto_lock);
|
|
bt_proto[proto] = NULL;
|
|
write_unlock(&bt_proto_lock);
|
|
}
|
|
EXPORT_SYMBOL(bt_sock_unregister);
|
|
|
|
#ifdef CONFIG_PARANOID_NETWORK
|
|
static inline int current_has_bt_admin(void)
|
|
{
|
|
return !current_euid();
|
|
}
|
|
|
|
static inline int current_has_bt(void)
|
|
{
|
|
return current_has_bt_admin();
|
|
}
|
|
# else
|
|
static inline int current_has_bt_admin(void)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
static inline int current_has_bt(void)
|
|
{
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
static int bt_sock_create(struct net *net, struct socket *sock, int proto,
|
|
int kern)
|
|
{
|
|
int err;
|
|
|
|
if (proto == BTPROTO_RFCOMM || proto == BTPROTO_SCO ||
|
|
proto == BTPROTO_L2CAP) {
|
|
if (!current_has_bt())
|
|
return -EPERM;
|
|
} else if (!current_has_bt_admin())
|
|
return -EPERM;
|
|
|
|
if (net != &init_net)
|
|
return -EAFNOSUPPORT;
|
|
|
|
if (proto < 0 || proto >= BT_MAX_PROTO)
|
|
return -EINVAL;
|
|
|
|
if (!bt_proto[proto])
|
|
request_module("bt-proto-%d", proto);
|
|
|
|
err = -EPROTONOSUPPORT;
|
|
|
|
read_lock(&bt_proto_lock);
|
|
|
|
if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
|
|
err = bt_proto[proto]->create(net, sock, proto, kern);
|
|
if (!err)
|
|
bt_sock_reclassify_lock(sock->sk, proto);
|
|
module_put(bt_proto[proto]->owner);
|
|
}
|
|
|
|
read_unlock(&bt_proto_lock);
|
|
|
|
return err;
|
|
}
|
|
|
|
void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
|
|
{
|
|
write_lock(&l->lock);
|
|
sk_add_node(sk, &l->head);
|
|
write_unlock(&l->lock);
|
|
}
|
|
EXPORT_SYMBOL(bt_sock_link);
|
|
|
|
void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
|
|
{
|
|
write_lock(&l->lock);
|
|
sk_del_node_init(sk);
|
|
write_unlock(&l->lock);
|
|
}
|
|
EXPORT_SYMBOL(bt_sock_unlink);
|
|
|
|
void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh)
|
|
{
|
|
BT_DBG("parent %p, sk %p", parent, sk);
|
|
|
|
sock_hold(sk);
|
|
|
|
if (bh)
|
|
bh_lock_sock_nested(sk);
|
|
else
|
|
lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
|
|
|
|
list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
|
|
bt_sk(sk)->parent = parent;
|
|
|
|
if (bh)
|
|
bh_unlock_sock(sk);
|
|
else
|
|
release_sock(sk);
|
|
|
|
parent->sk_ack_backlog++;
|
|
}
|
|
EXPORT_SYMBOL(bt_accept_enqueue);
|
|
|
|
/* Calling function must hold the sk lock.
|
|
* bt_sk(sk)->parent must be non-NULL meaning sk is in the parent list.
|
|
*/
|
|
void bt_accept_unlink(struct sock *sk)
|
|
{
|
|
BT_DBG("sk %p state %d", sk, sk->sk_state);
|
|
|
|
list_del_init(&bt_sk(sk)->accept_q);
|
|
bt_sk(sk)->parent->sk_ack_backlog--;
|
|
bt_sk(sk)->parent = NULL;
|
|
sock_put(sk);
|
|
}
|
|
EXPORT_SYMBOL(bt_accept_unlink);
|
|
|
|
struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
|
|
{
|
|
struct bt_sock *s, *n;
|
|
struct sock *sk;
|
|
|
|
BT_DBG("parent %p", parent);
|
|
|
|
restart:
|
|
list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
|
|
sk = (struct sock *)s;
|
|
|
|
/* Prevent early freeing of sk due to unlink and sock_kill */
|
|
sock_hold(sk);
|
|
lock_sock(sk);
|
|
|
|
/* Check sk has not already been unlinked via
|
|
* bt_accept_unlink() due to serialisation caused by sk locking
|
|
*/
|
|
if (!bt_sk(sk)->parent) {
|
|
BT_DBG("sk %p, already unlinked", sk);
|
|
release_sock(sk);
|
|
sock_put(sk);
|
|
|
|
/* Restart the loop as sk is no longer in the list
|
|
* and also avoid a potential infinite loop because
|
|
* list_for_each_entry_safe() is not thread safe.
|
|
*/
|
|
goto restart;
|
|
}
|
|
|
|
/* sk is safely in the parent list so reduce reference count */
|
|
sock_put(sk);
|
|
|
|
/* FIXME: Is this check still needed */
|
|
if (sk->sk_state == BT_CLOSED) {
|
|
bt_accept_unlink(sk);
|
|
release_sock(sk);
|
|
continue;
|
|
}
|
|
|
|
if (sk->sk_state == BT_CONNECTED || !newsock ||
|
|
test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) {
|
|
bt_accept_unlink(sk);
|
|
if (newsock)
|
|
sock_graft(sk, newsock);
|
|
|
|
release_sock(sk);
|
|
return sk;
|
|
}
|
|
|
|
release_sock(sk);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
EXPORT_SYMBOL(bt_accept_dequeue);
|
|
|
|
int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
|
|
int flags)
|
|
{
|
|
int noblock = flags & MSG_DONTWAIT;
|
|
struct sock *sk = sock->sk;
|
|
struct sk_buff *skb;
|
|
size_t copied;
|
|
size_t skblen;
|
|
int err;
|
|
|
|
BT_DBG("sock %p sk %p len %zu", sock, sk, len);
|
|
|
|
if (flags & MSG_OOB)
|
|
return -EOPNOTSUPP;
|
|
|
|
skb = skb_recv_datagram(sk, flags, noblock, &err);
|
|
if (!skb) {
|
|
if (sk->sk_shutdown & RCV_SHUTDOWN)
|
|
return 0;
|
|
|
|
return err;
|
|
}
|
|
|
|
skblen = skb->len;
|
|
copied = skb->len;
|
|
if (len < copied) {
|
|
msg->msg_flags |= MSG_TRUNC;
|
|
copied = len;
|
|
}
|
|
|
|
skb_reset_transport_header(skb);
|
|
err = skb_copy_datagram_msg(skb, 0, msg, copied);
|
|
if (err == 0) {
|
|
sock_recv_ts_and_drops(msg, sk, skb);
|
|
|
|
if (msg->msg_name && bt_sk(sk)->skb_msg_name)
|
|
bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
|
|
&msg->msg_namelen);
|
|
}
|
|
|
|
skb_free_datagram(sk, skb);
|
|
|
|
if (flags & MSG_TRUNC)
|
|
copied = skblen;
|
|
|
|
return err ? : copied;
|
|
}
|
|
EXPORT_SYMBOL(bt_sock_recvmsg);
|
|
|
|
static long bt_sock_data_wait(struct sock *sk, long timeo)
|
|
{
|
|
DECLARE_WAITQUEUE(wait, current);
|
|
|
|
add_wait_queue(sk_sleep(sk), &wait);
|
|
for (;;) {
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
|
|
if (!skb_queue_empty(&sk->sk_receive_queue))
|
|
break;
|
|
|
|
if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN))
|
|
break;
|
|
|
|
if (signal_pending(current) || !timeo)
|
|
break;
|
|
|
|
sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
|
|
release_sock(sk);
|
|
timeo = schedule_timeout(timeo);
|
|
lock_sock(sk);
|
|
sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
|
|
}
|
|
|
|
__set_current_state(TASK_RUNNING);
|
|
remove_wait_queue(sk_sleep(sk), &wait);
|
|
return timeo;
|
|
}
|
|
|
|
int bt_sock_stream_recvmsg(struct socket *sock, struct msghdr *msg,
|
|
size_t size, int flags)
|
|
{
|
|
struct sock *sk = sock->sk;
|
|
int err = 0;
|
|
size_t target, copied = 0;
|
|
long timeo;
|
|
|
|
if (flags & MSG_OOB)
|
|
return -EOPNOTSUPP;
|
|
|
|
BT_DBG("sk %p size %zu", sk, size);
|
|
|
|
lock_sock(sk);
|
|
|
|
target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
|
|
timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
|
|
|
|
do {
|
|
struct sk_buff *skb;
|
|
int chunk;
|
|
|
|
skb = skb_dequeue(&sk->sk_receive_queue);
|
|
if (!skb) {
|
|
if (copied >= target)
|
|
break;
|
|
|
|
err = sock_error(sk);
|
|
if (err)
|
|
break;
|
|
if (sk->sk_shutdown & RCV_SHUTDOWN)
|
|
break;
|
|
|
|
err = -EAGAIN;
|
|
if (!timeo)
|
|
break;
|
|
|
|
timeo = bt_sock_data_wait(sk, timeo);
|
|
|
|
if (signal_pending(current)) {
|
|
err = sock_intr_errno(timeo);
|
|
goto out;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
chunk = min_t(unsigned int, skb->len, size);
|
|
if (skb_copy_datagram_msg(skb, 0, msg, chunk)) {
|
|
skb_queue_head(&sk->sk_receive_queue, skb);
|
|
if (!copied)
|
|
copied = -EFAULT;
|
|
break;
|
|
}
|
|
copied += chunk;
|
|
size -= chunk;
|
|
|
|
sock_recv_ts_and_drops(msg, sk, skb);
|
|
|
|
if (!(flags & MSG_PEEK)) {
|
|
int skb_len = skb_headlen(skb);
|
|
|
|
if (chunk <= skb_len) {
|
|
__skb_pull(skb, chunk);
|
|
} else {
|
|
struct sk_buff *frag;
|
|
|
|
__skb_pull(skb, skb_len);
|
|
chunk -= skb_len;
|
|
|
|
skb_walk_frags(skb, frag) {
|
|
if (chunk <= frag->len) {
|
|
/* Pulling partial data */
|
|
skb->len -= chunk;
|
|
skb->data_len -= chunk;
|
|
__skb_pull(frag, chunk);
|
|
break;
|
|
} else if (frag->len) {
|
|
/* Pulling all frag data */
|
|
chunk -= frag->len;
|
|
skb->len -= frag->len;
|
|
skb->data_len -= frag->len;
|
|
__skb_pull(frag, frag->len);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (skb->len) {
|
|
skb_queue_head(&sk->sk_receive_queue, skb);
|
|
break;
|
|
}
|
|
kfree_skb(skb);
|
|
|
|
} else {
|
|
/* put message back and return */
|
|
skb_queue_head(&sk->sk_receive_queue, skb);
|
|
break;
|
|
}
|
|
} while (size);
|
|
|
|
out:
|
|
release_sock(sk);
|
|
return copied ? : err;
|
|
}
|
|
EXPORT_SYMBOL(bt_sock_stream_recvmsg);
|
|
|
|
static inline __poll_t bt_accept_poll(struct sock *parent)
|
|
{
|
|
struct bt_sock *s, *n;
|
|
struct sock *sk;
|
|
|
|
list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
|
|
sk = (struct sock *)s;
|
|
if (sk->sk_state == BT_CONNECTED ||
|
|
(test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags) &&
|
|
sk->sk_state == BT_CONNECT2))
|
|
return EPOLLIN | EPOLLRDNORM;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
__poll_t bt_sock_poll(struct file *file, struct socket *sock,
|
|
poll_table *wait)
|
|
{
|
|
struct sock *sk = sock->sk;
|
|
__poll_t mask = 0;
|
|
|
|
BT_DBG("sock %p, sk %p", sock, sk);
|
|
|
|
poll_wait(file, sk_sleep(sk), wait);
|
|
|
|
if (sk->sk_state == BT_LISTEN)
|
|
return bt_accept_poll(sk);
|
|
|
|
if (sk->sk_err || !skb_queue_empty_lockless(&sk->sk_error_queue))
|
|
mask |= EPOLLERR |
|
|
(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? EPOLLPRI : 0);
|
|
|
|
if (sk->sk_shutdown & RCV_SHUTDOWN)
|
|
mask |= EPOLLRDHUP | EPOLLIN | EPOLLRDNORM;
|
|
|
|
if (sk->sk_shutdown == SHUTDOWN_MASK)
|
|
mask |= EPOLLHUP;
|
|
|
|
if (!skb_queue_empty_lockless(&sk->sk_receive_queue))
|
|
mask |= EPOLLIN | EPOLLRDNORM;
|
|
|
|
if (sk->sk_state == BT_CLOSED)
|
|
mask |= EPOLLHUP;
|
|
|
|
if (sk->sk_state == BT_CONNECT ||
|
|
sk->sk_state == BT_CONNECT2 ||
|
|
sk->sk_state == BT_CONFIG)
|
|
return mask;
|
|
|
|
if (!test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags) && sock_writeable(sk))
|
|
mask |= EPOLLOUT | EPOLLWRNORM | EPOLLWRBAND;
|
|
else
|
|
sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
|
|
|
|
return mask;
|
|
}
|
|
EXPORT_SYMBOL(bt_sock_poll);
|
|
|
|
int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
|
{
|
|
struct sock *sk = sock->sk;
|
|
struct sk_buff *skb;
|
|
long amount;
|
|
int err;
|
|
|
|
BT_DBG("sk %p cmd %x arg %lx", sk, cmd, arg);
|
|
|
|
switch (cmd) {
|
|
case TIOCOUTQ:
|
|
if (sk->sk_state == BT_LISTEN)
|
|
return -EINVAL;
|
|
|
|
amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
|
|
if (amount < 0)
|
|
amount = 0;
|
|
err = put_user(amount, (int __user *) arg);
|
|
break;
|
|
|
|
case TIOCINQ:
|
|
if (sk->sk_state == BT_LISTEN)
|
|
return -EINVAL;
|
|
|
|
lock_sock(sk);
|
|
skb = skb_peek(&sk->sk_receive_queue);
|
|
amount = skb ? skb->len : 0;
|
|
release_sock(sk);
|
|
err = put_user(amount, (int __user *) arg);
|
|
break;
|
|
|
|
case SIOCGSTAMP:
|
|
err = sock_get_timestamp(sk, (struct timeval __user *) arg);
|
|
break;
|
|
|
|
case SIOCGSTAMPNS:
|
|
err = sock_get_timestampns(sk, (struct timespec __user *) arg);
|
|
break;
|
|
|
|
default:
|
|
err = -ENOIOCTLCMD;
|
|
break;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
EXPORT_SYMBOL(bt_sock_ioctl);
|
|
|
|
/* This function expects the sk lock to be held when called */
|
|
int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
|
|
{
|
|
DECLARE_WAITQUEUE(wait, current);
|
|
int err = 0;
|
|
|
|
BT_DBG("sk %p", sk);
|
|
|
|
add_wait_queue(sk_sleep(sk), &wait);
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
while (sk->sk_state != state) {
|
|
if (!timeo) {
|
|
err = -EINPROGRESS;
|
|
break;
|
|
}
|
|
|
|
if (signal_pending(current)) {
|
|
err = sock_intr_errno(timeo);
|
|
break;
|
|
}
|
|
|
|
release_sock(sk);
|
|
timeo = schedule_timeout(timeo);
|
|
lock_sock(sk);
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
|
|
err = sock_error(sk);
|
|
if (err)
|
|
break;
|
|
}
|
|
__set_current_state(TASK_RUNNING);
|
|
remove_wait_queue(sk_sleep(sk), &wait);
|
|
return err;
|
|
}
|
|
EXPORT_SYMBOL(bt_sock_wait_state);
|
|
|
|
/* This function expects the sk lock to be held when called */
|
|
int bt_sock_wait_ready(struct sock *sk, unsigned long flags)
|
|
{
|
|
DECLARE_WAITQUEUE(wait, current);
|
|
unsigned long timeo;
|
|
int err = 0;
|
|
|
|
BT_DBG("sk %p", sk);
|
|
|
|
timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
|
|
|
|
add_wait_queue(sk_sleep(sk), &wait);
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
while (test_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags)) {
|
|
if (!timeo) {
|
|
err = -EAGAIN;
|
|
break;
|
|
}
|
|
|
|
if (signal_pending(current)) {
|
|
err = sock_intr_errno(timeo);
|
|
break;
|
|
}
|
|
|
|
release_sock(sk);
|
|
timeo = schedule_timeout(timeo);
|
|
lock_sock(sk);
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
|
|
err = sock_error(sk);
|
|
if (err)
|
|
break;
|
|
}
|
|
__set_current_state(TASK_RUNNING);
|
|
remove_wait_queue(sk_sleep(sk), &wait);
|
|
|
|
return err;
|
|
}
|
|
EXPORT_SYMBOL(bt_sock_wait_ready);
|
|
|
|
#ifdef CONFIG_PROC_FS
|
|
static void *bt_seq_start(struct seq_file *seq, loff_t *pos)
|
|
__acquires(seq->private->l->lock)
|
|
{
|
|
struct bt_sock_list *l = PDE_DATA(file_inode(seq->file));
|
|
|
|
read_lock(&l->lock);
|
|
return seq_hlist_start_head(&l->head, *pos);
|
|
}
|
|
|
|
static void *bt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|
{
|
|
struct bt_sock_list *l = PDE_DATA(file_inode(seq->file));
|
|
|
|
return seq_hlist_next(v, &l->head, pos);
|
|
}
|
|
|
|
static void bt_seq_stop(struct seq_file *seq, void *v)
|
|
__releases(seq->private->l->lock)
|
|
{
|
|
struct bt_sock_list *l = PDE_DATA(file_inode(seq->file));
|
|
|
|
read_unlock(&l->lock);
|
|
}
|
|
|
|
static int bt_seq_show(struct seq_file *seq, void *v)
|
|
{
|
|
struct bt_sock_list *l = PDE_DATA(file_inode(seq->file));
|
|
|
|
if (v == SEQ_START_TOKEN) {
|
|
seq_puts(seq ,"sk RefCnt Rmem Wmem User Inode Parent");
|
|
|
|
if (l->custom_seq_show) {
|
|
seq_putc(seq, ' ');
|
|
l->custom_seq_show(seq, v);
|
|
}
|
|
|
|
seq_putc(seq, '\n');
|
|
} else {
|
|
struct sock *sk = sk_entry(v);
|
|
struct bt_sock *bt = bt_sk(sk);
|
|
|
|
seq_printf(seq,
|
|
"%pK %-6d %-6u %-6u %-6u %-6lu %-6lu",
|
|
sk,
|
|
refcount_read(&sk->sk_refcnt),
|
|
sk_rmem_alloc_get(sk),
|
|
sk_wmem_alloc_get(sk),
|
|
from_kuid(seq_user_ns(seq), sock_i_uid(sk)),
|
|
sock_i_ino(sk),
|
|
bt->parent? sock_i_ino(bt->parent): 0LU);
|
|
|
|
if (l->custom_seq_show) {
|
|
seq_putc(seq, ' ');
|
|
l->custom_seq_show(seq, v);
|
|
}
|
|
|
|
seq_putc(seq, '\n');
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static const struct seq_operations bt_seq_ops = {
|
|
.start = bt_seq_start,
|
|
.next = bt_seq_next,
|
|
.stop = bt_seq_stop,
|
|
.show = bt_seq_show,
|
|
};
|
|
|
|
int bt_procfs_init(struct net *net, const char *name,
|
|
struct bt_sock_list *sk_list,
|
|
int (* seq_show)(struct seq_file *, void *))
|
|
{
|
|
sk_list->custom_seq_show = seq_show;
|
|
|
|
if (!proc_create_seq_data(name, 0, net->proc_net, &bt_seq_ops, sk_list))
|
|
return -ENOMEM;
|
|
return 0;
|
|
}
|
|
|
|
void bt_procfs_cleanup(struct net *net, const char *name)
|
|
{
|
|
remove_proc_entry(name, net->proc_net);
|
|
}
|
|
#else
|
|
int bt_procfs_init(struct net *net, const char *name,
|
|
struct bt_sock_list *sk_list,
|
|
int (* seq_show)(struct seq_file *, void *))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void bt_procfs_cleanup(struct net *net, const char *name)
|
|
{
|
|
}
|
|
#endif
|
|
EXPORT_SYMBOL(bt_procfs_init);
|
|
EXPORT_SYMBOL(bt_procfs_cleanup);
|
|
|
|
static const struct net_proto_family bt_sock_family_ops = {
|
|
.owner = THIS_MODULE,
|
|
.family = PF_BLUETOOTH,
|
|
.create = bt_sock_create,
|
|
};
|
|
|
|
struct dentry *bt_debugfs;
|
|
EXPORT_SYMBOL_GPL(bt_debugfs);
|
|
|
|
#define VERSION __stringify(BT_SUBSYS_VERSION) "." \
|
|
__stringify(BT_SUBSYS_REVISION)
|
|
|
|
static int __init bt_init(void)
|
|
{
|
|
int err;
|
|
|
|
sock_skb_cb_check_size(sizeof(struct bt_skb_cb));
|
|
|
|
BT_INFO("Core ver %s", VERSION);
|
|
|
|
err = bt_selftest();
|
|
if (err < 0)
|
|
return err;
|
|
|
|
bt_debugfs = debugfs_create_dir("bluetooth", NULL);
|
|
|
|
bt_leds_init();
|
|
|
|
err = bt_sysfs_init();
|
|
if (err < 0)
|
|
return err;
|
|
|
|
err = sock_register(&bt_sock_family_ops);
|
|
if (err)
|
|
goto cleanup_sysfs;
|
|
|
|
BT_INFO("HCI device and connection manager initialized");
|
|
|
|
err = hci_sock_init();
|
|
if (err)
|
|
goto unregister_socket;
|
|
|
|
err = l2cap_init();
|
|
if (err)
|
|
goto cleanup_socket;
|
|
|
|
err = sco_init();
|
|
if (err)
|
|
goto cleanup_cap;
|
|
|
|
err = mgmt_init();
|
|
if (err)
|
|
goto cleanup_sco;
|
|
|
|
return 0;
|
|
|
|
cleanup_sco:
|
|
sco_exit();
|
|
cleanup_cap:
|
|
l2cap_exit();
|
|
cleanup_socket:
|
|
hci_sock_cleanup();
|
|
unregister_socket:
|
|
sock_unregister(PF_BLUETOOTH);
|
|
cleanup_sysfs:
|
|
bt_sysfs_cleanup();
|
|
return err;
|
|
}
|
|
|
|
static void __exit bt_exit(void)
|
|
{
|
|
mgmt_exit();
|
|
|
|
sco_exit();
|
|
|
|
l2cap_exit();
|
|
|
|
hci_sock_cleanup();
|
|
|
|
sock_unregister(PF_BLUETOOTH);
|
|
|
|
bt_sysfs_cleanup();
|
|
|
|
bt_leds_cleanup();
|
|
|
|
debugfs_remove_recursive(bt_debugfs);
|
|
}
|
|
|
|
subsys_initcall(bt_init);
|
|
module_exit(bt_exit);
|
|
|
|
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
|
|
MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
|
|
MODULE_VERSION(VERSION);
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);
|