mirror of
https://github.com/joel16/android_kernel_sony_msm8994_rework.git
synced 2024-11-23 03:50:08 +00:00
Merge tag 'v3.10.106' into lineage-15.1
a07ea93 Linux 3.10.106 4155279 dccp: fix freeing skb too early for IPV6_RECVPKTINFO 66cb324 char: lp: fix possible integer overflow in lp_setup() 2f954a6 dccp/tcp: do not inherit mc_list from parent e64530f mm/huge_memory.c: respect FOLL_FORCE/FOLL_COW for thp 43fe818 fs: exec: apply CLOEXEC before changing dumpable task flags 8676954 ipv6: handle -EFAULT from skb_copy_bits 030e0b5 tty: n_hdlc: get rid of racy n_hdlc.tbuf a9511e7 TTY: n_hdlc, fix lockdep false positive 211bcbc KVM: kvm_io_bus_unregister_dev() should never fail d8abb8b kvm: exclude ioeventfd from counting kvm_io_range limit dd8db85 KVM: x86: clear bus pointer when destroyed 620d73a sctp: deny peeloff operation on asocs with threads sleeping on it 1f7cb73 sctp: avoid BUG_ON on sctp_wait_for_sndbuf abcfcd0 ipv6: fix the use of pcpu_tstats in ip6_tunnel e246c09 ipv6: pointer math error in ip6_tnl_parse_tlv_enc_lim() 72bbf33 ipv6: fix ip6_tnl_parse_tlv_enc_lim() 3bdb157 xc2028: Fix use-after-free bug properly d9a854e xc2028: unlock on error in xc2028_set_config() bb4884f xc2028: avoid use after free 9391c80 Drivers: hv: avoid vfree() on crash 801c8a0 can: Fix kernel panic at security_sock_rcv_skb 414989d mm/init: fix zone boundary creation 5765ee4 USB: dummy-hcd: fix bug in stop_activity (handle ep0) 15668b4 USB: fix problems with duplicate endpoint addresses 60f704b ping: implement proper locking 3d46433 USB: usbtmc: add missing endpoint sanity check 8c11dce perf trace: Use the syscall raw_syscalls:sys_enter timestamp 8ceaec0 net: sctp: rework multihoming retransmission path selection to rfc4960 ad1336d Staging: vt6655-6: potential NULL dereference in hostap_disable_hostapd() bda0832 tun: Fix TUN_PKT_STRIP setting bfac362 ARM: dts: imx31: fix AVIC base address 3e721e2 ARM: dts: imx31: move CCM device node to AIPS2 bus devices d1f922a MIPS: KGDB: Use kernel context for sleeping threads 43f8c8b l2tp: take reference on sessions being dumped 509fda4 net: phy: handle state correctly in phy_stop_machine 9bc8935 netfilter: arp_tables: fix invoking 32bit "iptable -P INPUT ACCEPT" failed in 64bit kernel 6d5f780 ring-buffer: Have ring_buffer_iter_empty() return true when empty 95948b1 tracing: Allocate the snapshot buffer before enabling probe 57420af rtl8150: Use heap buffers for all register access 6a1d611 pegasus: Use heap buffers for all register access 797971a powerpc: Disable HFSCR[TM] if TM is not supported 6800d88 char: Drop bogus dependency of DEVPORT on !M68K d5efe5c net/mlx4_core: Fix racy CQ (Completion Queue) free 2b3d0c0 net/mlx4_en: Fix bad WQE issue 6f68a8d s390/decompressor: fix initrd corruption caused by bss clear bc37f9a metag/usercopy: Add missing fixups 816a1ae metag/usercopy: Fix src fixup in from user rapf loops cabb4ce metag/usercopy: Set flags before ADDZ 9a83add8 metag/usercopy: Add early abort to copy_to_user 994c8e5 metag/usercopy: Fix alignment error checking 13e03cf ring-buffer: Fix return value check in test_ringbuffer() b8054bf ptrace: fix PTRACE_LISTEN race corrupting task->state 4fbf100 ipv4: igmp: Allow removing groups from a removed interface 98dcb81 i2c: at91: manage unexpected RXRDY flag when starting a transfer d106ce3 USB: OHCI: Fix race between ED unlink and URB submission 62bdbcf ACPI / PNP: Reserve ACPI resources at the fs_initcall_sync stage 23b2b0e ACPI / resources: free memory on error in add_region_before() 0f06de4 ACPI / PNP: Avoid conflicting resource reservations a11b00f ALSA: ctxfi: Fix the incorrect check of dma_set_mask() call 4b0ca39 ALSA: ctxfi: Fallback DMA mask to 32bit 21ec215 scsi: libsas: fix ata xfer length 3f102dc ext4: mark inode dirty after converting inline directory e32d76a mmc: ushc: fix NULL-deref at probe 735a19d uwb: hwa-rc: fix NULL-deref at probe b00b018 uwb: i1480-dfu: fix NULL-deref at probe 626f277 USB: wusbcore: fix NULL-deref at probe 712c7fb USB: idmouse: fix NULL-deref at probe 79e603e USB: uss720: fix NULL-deref at probe 9a15264 Input: cm109 - validate number of endpoints before using them e121cd4 Input: yealink - validate number of endpoints before using them ab84b30 Input: hanwang - validate number of endpoints before using them ec5cc03 Input: ims-pcu - validate number of endpoints before using them e24a53a net: unix: properly re-increment inflight counter of GC discarded candidates de9d09c net: properly release sk_frag.page d7a6842 xen: do not re-use pirq number cached in pci device msi msg data 47bad91 isdn/gigaset: fix NULL-deref at probe 1e0d06b perf/core: Fix event inheritance on fork() 20af6b4 net sched actions: decrement module reference count after table flush. 29c4bf4 dccp/tcp: fix routing redirect race 9cfe942 net: net_enable_timestamp() can be called from irq contexts 12f1a0f locking/static_keys: Add static_key_{en,dis}able() helpers 7c72e85 ipv4: mask tos for input route e5c6b9c vxlan: correctly validate VXLAN ID against VXLAN_N_VID cb32438 USB: serial: io_ti: fix information leak in completion handler 58a600a USB: serial: io_ti: fix NULL-deref in interrupt callback 04992d7 USB: iowarrior: fix NULL-deref in write 88ee631 USB: iowarrior: fix NULL-deref at probe 50b6074 USB: serial: omninet: fix reference leaks at open 61ab4e5 USB: serial: safe_serial: fix information leak in completion handler 2b6aa62 tracing: Add #undef to fix compile error 06a5c0b MIPS: ip27: Disable qlge driver in defconfig 5e44fdd USB: serial: digi_acceleport: fix OOB-event processing 7c75989 USB: serial: digi_acceleport: fix OOB data sanity check cc3d0c2 dm: flush queued bios when process blocks to avoid deadlock ebd9572 nlm: Ensure callback code also checks that the files match 5bb7a6c ktest: Fix child exit code processing 2c31873 IB/ipoib: Fix deadlock between rmmod and set_mode 8e68a4d s390/qdio: clear DSCI prior to scanning multiple input queues 58ccba8 NFSv4: fix getacl head length estimation e9a1e1c RDMA/core: Fix incorrect structure packing for booleans 5beea85 fuse: add missing FR_FORCE f90660e ath9k: use correct OTP register offsets for the AR9340 and AR9550 6390114 scsi: aacraid: Reorder Adapter status check 0259f8b uvcvideo: Fix a wrong macro 9dc2420 MIPS: Handle microMIPS jumps in the same way as MIPS32/MIPS64 jumps 8577fb6 MIPS: Calculate microMIPS ra properly when unwinding the stack a3e70c3 MIPS: Fix is_jump_ins() handling of 16b microMIPS instructions 9c01ee5 MIPS: Fix get_frame_info() handling of microMIPS function size 15d2aa7 MIPS: Prevent unaligned accesses during stack unwinding 1809a78 MIPS: Clear ISA bit correctly in get_frame_info() e51712a MIPS: OCTEON: Fix copy_from_user fault handling for large buffers beb27bf net/sched: em_meta: Fix 'meta vlan' to correctly recognize zero VID frames 37fdac5 vti4: Don't count header length twice. 3ac993d net: 6lowpan: fix lowpan_header_create non-compression memcpy call c4c175d drm/nv50/disp: min/max are reversed in nv50_crtc_gamma_set() dad5635 mfd: pm8921: Potential NULL dereference in pm8921_remove() 511ae3b ocfs2: do not write error flag to user structure we cannot copy from/to 7fb0b44 goldfish: Sanitize the broken interrupt handler d3926e1 x86/platform/goldfish: Prevent unconditional loading 9ce78b1 USB: serial: ark3116: fix register-accessor error handling 1110205 USB: serial: opticon: fix CTS retrieval at open 3e642b8 USB: serial: spcp8x5: fix modem-status handling c151418 USB: serial: ftdi_sio: fix line-status over-reporting af1f7fb USB: serial: ftdi_sio: fix extreme low-latency setting aa814ed USB: serial: ftdi_sio: fix modem-status error handling c8c6bd8 USB: serial: mos7840: fix another NULL-deref at open 0b5240c net: socket: fix recvmmsg not returning error from sock_error 9aab359 packet: Do not call fanout_release from atomic contexts 2a272ab packet: fix races in fanout_add() 3d75337 l2tp: do not use udp_ioctl() c6dfb87 ping: fix a null pointer dereference a05c8e3 ip6_gre: fix ip6gre_err() invalid reads 96296cd netlabel: out of bound access in cipso_v4_validate() 050c309 ipv4: keep skb->dst around in presence of IP options efca6f5 net: use a work queue to defer net_disable_timestamp() work 5c9d55e drm/i915: fix use-after-free in page_flip_completed() 01e26ca scsi: zfcp: fix use-after-free by not tracing WKA port open/close on failed send 22ae324 mac80211: Fix adding of mesh vendor IEs fcd0b44 ARM: 8643/3: arm/ptrace: Preserve previous registers for short regset write dd105cf svcrpc: fix oops in absence of krb5 module 5bcc3fa tcp: initialize max window for a new fastopen socket 48decd9 net: fix harmonize_features() vs NETIF_F_HIGHDMA b2c6a97 platform/x86: intel_mid_powerbtn: Set IRQ_ONESHOT a632ba4 s5k4ecgx: select CRC32 helper 784e4e9 drm/i915: Don't leak edid in intel_crt_detect_ddc() 7c2e0b9 crypto: caam - fix non-hmac hashes d3005b0 fuse: do not use iocb after it may have been freed abae7dd ite-cir: initialize use_demodulator before using it ef60264 ARM: ux500: fix prcmu_is_cpu_in_wfi() calculation 518a744 arm64/ptrace: Reject attempts to set incomplete hardware breakpoint fields b36ad64 arm64/ptrace: Avoid uninitialised struct padding in fpr_set() f4c0fd3 arm64/ptrace: Preserve previous registers for short regset write 13c485b ubifs: Fix journal replay wrt. xattr nodes 490960c mtd: nand: xway: disable module support 8bc899e mmc: mxs-mmc: Fix additional cycles after transmission stop 6a4a5fd svcrpc: don't leak contexts on PROC_DESTROY 2024f68 ARM: dts: imx31: fix clock control module interrupts description 016f803 perf scripting: Avoid leaking the scripting_context variable 7d26287 IB/mlx4: Fix port query for 56Gb Ethernet links dcb7311 IB/mlx4: Set traffic class in AH 2292bda powerpc/ibmebus: Fix device reference leaks in sysfs interface 34c23b2 powerpc/ibmebus: Fix further device reference leaks c242797 NFSv4.1: nfs4_fl_prepare_ds must be careful about reporting success. 0954c87 x86/cpu: Fix bootup crashes by sanitizing the argument of the 'clearcpuid=' command-line option 2c65c73 USB: serial: ch341: fix modem-control and B0 handling 2563aee USB: serial: ch341: fix resume after reset 8024b1a USB: serial: ch341: fix open and resume after B0 352ba51 USB: serial: ch341: fix control-message error handling 6a9f8d8 USB: serial: ch341: fix open error handling 86e0a6b USB: serial: ch341: fix initial modem-control state b031f56 USB: serial: kl5kusb105: fix line-state error handling 10e96e6 mm/hugetlb.c: fix reservation race when freeing surplus pages 4323a76 Input: i8042 - add Pegatron touchpad to noloop table 8b372d3 powerpc: Fix build warning on 32-bit PPC 8ec6068 gro: Disable frag0 optimization on IPv6 ext headers f2c23ae gro: use min_t() in skb_gro_reset_offset() 9872698 gro: Enter slow-path if there is no tailroom 8d82183 net: stmmac: Fix race between stmmac_drv_probe and stmmac_open 4949c9e net, sched: fix soft lockup in tc_classify 3dc64c4 ser_gigaset: return -ENOMEM on error instead of success b734c02 powerpc/pci/rpadlpar: Fix device reference leaks 985d68b mmc: mmc_test: Uninitialized return value 6075e94 target/iscsi: Fix double free in lio_target_tiqn_addtpg() 4d091cf scsi: mvsas: fix command_active typo 7712b94 iommu/amd: Fix the left value check of cmd buffer b09fd95 clk: clk-wm831x: fix a logic error 232e0c1 hwmon: (ds620) Fix overflows seen when writing temperature limits 5c9b542 cris: Only build flash rescue image if CONFIG_ETRAX_AXISFLASHMAP is selected 34c8357 usb: dwc3: gadget: always unmap EP0 requests 57eb4ca staging: iio: ad7606: fix improper setting of oversampling pins 7a30277 USB: serial: kl5kusb105: abort on open exception path b1d2451 ALSA: usb-audio: Fix bogus error return in snd_usb_create_stream() 1a2f2df usb: musb: Fix trying to free already-free IRQ 4 5a45bdd usb: xhci-mem: use passed in GFP flags instead of GFP_KERNEL 56a4835 USB: serial: mos7720: fix parallel probe 756f54d USB: serial: mos7720: fix parport use-after-free on probe errors 54cd03a USB: serial: mos7720: fix use-after-free on probe errors 5a896b11 USB: serial: mos7720: fix NULL-deref at open e514b71 USB: serial: mos7840: fix NULL-deref at open 810fb7b USB: serial: kobil_sct: fix NULL-deref in write ba35ae7 USB: serial: cyberjack: fix NULL-deref at open 7449b98 USB: serial: oti6858: fix NULL-deref at open be7c031 USB: serial: io_edgeport: fix NULL-deref at open 52bc1e3 USB: serial: ti_usb_3410_5052: fix NULL-deref at open a5d48a1 USB: serial: garmin_gps: fix memory leak on failed URB submit e3c79a8 USB: serial: iuu_phoenix: fix NULL-deref at open 7d04b5c USB: serial: io_ti: fix another NULL-deref at open 0d90b3d USB: serial: io_ti: fix NULL-deref at open 7244497 USB: serial: spcp8x5: fix NULL-deref at open 1df7c66 USB: serial: keyspan_pda: verify endpoints at probe 18b787d USB: serial: pl2303: fix NULL-deref at open 4f2b2d8 USB: serial: quatech2: fix sleep-while-atomic in close c15d09c USB: serial: omninet: fix NULL-derefs at open and disconnect 7e3f800 usb: gadget: composite: Test get_alt() presence instead of set_alt() ecf33ba powerpc: Convert cmp to cmpd in idle enter sequence 029555a IB/multicast: Check ib_find_pkey() return value 67ae25b IB/mad: Fix an array index check 882f8f1 ftrace/x86_32: Set ftrace_stub to weak to prevent gcc from using short jumps to it 1c2287b scsi: zfcp: fix rport unblock race with LUN recovery 5d35a96 scsi: zfcp: do not trace pure benign residual HBA responses at default level 5453950 scsi: zfcp: fix use-after-"free" in FC ingress path after TMF 97c6c85 block: protect iterate_bdevs() against concurrent close 49c8225 f2fs: set ->owner for debugfs status file's file_operations e74af99 ext4: return -ENOMEM instead of success b70876f ext4: reject inodes with negative size ac3d8fb ext4: fix stack memory corruption with 64k block size cafd215 ext4: fix mballoc breakage with 64k block size 625208a crypto: caam - fix AEAD givenc descriptors 725da55 block_dev: don't test bdev->bd_contains when it is not stable 6017ea9 USB: serial: kl5kusb105: fix open error path 6e97d31 Btrfs: fix tree search logic when replaying directory entry deletes 57bf12f hotplug: Make register and unregister notifier API symmetric 3d1b965 m68k: Fix ndelay() macro 07f0386 locking/rtmutex: Prevent dequeue vs. unlock race 9488a477 ext4: fix data exposure after a crash d19182e KEYS: fix keyctl_set_reqkey_keyring() to not leak thread keyrings 5b22a8a KEYS: Change the name of the dead type to ".dead" to prevent user access 8e728d2 KEYS: Disallow keyrings beginning with '.' to be joined as session keyrings cbd95d1 xfrm_user: validate XFRM_MSG_NEWAE incoming ESN size harder ccf8544 xfrm_user: validate XFRM_MSG_NEWAE XFRMA_REPLAY_ESN_VAL replay_window 452655e tcp: avoid infinite loop in tcp_splice_read() a71b419 selinux: fix off-by-one in setprocattr e39ab83 fbdev: color map copying bounds checking 1026a8c tmpfs: clear S_ISGID when setting posix ACLs dd2421b posix_acl: Clear SGID bit when setting file permissions 27bf4b6 KVM: x86: Introduce segmented_write_std 2dd7d7e KVM: x86: fix emulation of "MOV SS, null selector" dd7d4be libceph: don't set weight to IN when OSD is destroyed 3751051 EVM: Use crypto_memneq() for digest comparisons 5fd5381 crypto: crypto_memneq - add equality testing of memory regions w/o timing leaks 4bfb6dd packet: fix race condition in packet_set_ring Signed-off-by: Rk779 <Rahulkrishna585@gmail.com> Conflicts: drivers/video/fbcmap.c fs/ext3/acl.c fs/generic_acl.c net/ipv4/ping.c
This commit is contained in:
parent
67250f4ea7
commit
194365cbe6
@ -77,7 +77,7 @@ Examples:
|
||||
clks: ccm@53f80000{
|
||||
compatible = "fsl,imx31-ccm";
|
||||
reg = <0x53f80000 0x4000>;
|
||||
interrupts = <0 31 0x04 0 53 0x04>;
|
||||
interrupts = <31>, <53>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
|
@ -965,6 +965,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
When zero, profiling data is discarded and associated
|
||||
debugfs files are removed at module unload time.
|
||||
|
||||
goldfish [X86] Enable the goldfish android emulator platform.
|
||||
Don't use this when you are not running on the
|
||||
android emulator
|
||||
|
||||
gpt [EFI] Forces disk with valid GPT signature but
|
||||
invalid Protective MBR to be treated as GPT.
|
||||
|
||||
|
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 105
|
||||
SUBLEVEL = 106
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
|
@ -20,11 +20,11 @@
|
||||
serial4 = &uart5;
|
||||
};
|
||||
|
||||
avic: avic-interrupt-controller@60000000 {
|
||||
avic: interrupt-controller@68000000 {
|
||||
compatible = "fsl,imx31-avic", "fsl,avic";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
reg = <0x60000000 0x100000>;
|
||||
reg = <0x68000000 0x100000>;
|
||||
};
|
||||
|
||||
soc {
|
||||
@ -93,13 +93,6 @@
|
||||
clock-names = "ipg", "per";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
clks: ccm@53f80000{
|
||||
compatible = "fsl,imx31-ccm";
|
||||
reg = <0x53f80000 0x4000>;
|
||||
interrupts = <0 31 0x04 0 53 0x04>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
aips@53f00000 { /* AIPS2 */
|
||||
@ -109,6 +102,13 @@
|
||||
reg = <0x53f00000 0x100000>;
|
||||
ranges;
|
||||
|
||||
clks: ccm@53f80000{
|
||||
compatible = "fsl,imx31-ccm";
|
||||
reg = <0x53f80000 0x4000>;
|
||||
interrupts = <31>, <53>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
gpt: timer@53f90000 {
|
||||
compatible = "fsl,imx31-gpt";
|
||||
reg = <0x53f90000 0x4000>;
|
||||
|
@ -600,7 +600,7 @@ static int gpr_set(struct task_struct *target,
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
int ret;
|
||||
struct pt_regs newregs;
|
||||
struct pt_regs newregs = *task_pt_regs(target);
|
||||
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
&newregs,
|
||||
|
@ -128,8 +128,8 @@ bool prcmu_pending_irq(void)
|
||||
*/
|
||||
bool prcmu_is_cpu_in_wfi(int cpu)
|
||||
{
|
||||
return readl(PRCM_ARM_WFI_STANDBY) & cpu ? PRCM_ARM_WFI_STANDBY_WFI1 :
|
||||
PRCM_ARM_WFI_STANDBY_WFI0;
|
||||
return readl(PRCM_ARM_WFI_STANDBY) &
|
||||
(cpu ? PRCM_ARM_WFI_STANDBY_WFI1 : PRCM_ARM_WFI_STANDBY_WFI0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -75,6 +75,7 @@ struct user_fpsimd_state {
|
||||
__uint128_t vregs[32];
|
||||
__u32 fpsr;
|
||||
__u32 fpcr;
|
||||
__u32 __reserved[2];
|
||||
};
|
||||
|
||||
struct user_hwdebug_state {
|
||||
|
@ -447,6 +447,8 @@ static int hw_break_set(struct task_struct *target,
|
||||
/* (address, ctrl) registers */
|
||||
limit = regset->n * regset->size;
|
||||
while (count && offset < limit) {
|
||||
if (count < PTRACE_HBP_ADDR_SZ)
|
||||
return -EINVAL;
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &addr,
|
||||
offset, offset + PTRACE_HBP_ADDR_SZ);
|
||||
if (ret)
|
||||
@ -456,6 +458,8 @@ static int hw_break_set(struct task_struct *target,
|
||||
return ret;
|
||||
offset += PTRACE_HBP_ADDR_SZ;
|
||||
|
||||
if (!count)
|
||||
break;
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl,
|
||||
offset, offset + PTRACE_HBP_CTRL_SZ);
|
||||
if (ret)
|
||||
@ -492,7 +496,7 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
int ret;
|
||||
struct user_pt_regs newregs;
|
||||
struct user_pt_regs newregs = task_pt_regs(target)->user_regs;
|
||||
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newregs, 0, -1);
|
||||
if (ret)
|
||||
@ -522,7 +526,8 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
int ret;
|
||||
struct user_fpsimd_state newstate;
|
||||
struct user_fpsimd_state newstate =
|
||||
target->thread.fpsimd_state.user_fpsimd;
|
||||
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newstate, 0, -1);
|
||||
if (ret)
|
||||
@ -545,7 +550,7 @@ static int tls_set(struct task_struct *target, const struct user_regset *regset,
|
||||
const void *kbuf, const void __user *ubuf)
|
||||
{
|
||||
int ret;
|
||||
unsigned long tls;
|
||||
unsigned long tls = target->thread.tp_value;
|
||||
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1);
|
||||
if (ret)
|
||||
|
@ -10,6 +10,9 @@
|
||||
|
||||
asflags-y += $(LINUXINCLUDE)
|
||||
ccflags-y += -O2 $(LINUXINCLUDE)
|
||||
|
||||
ifdef CONFIG_ETRAX_AXISFLASHMAP
|
||||
|
||||
arch-$(CONFIG_ETRAX_ARCH_V10) = v10
|
||||
arch-$(CONFIG_ETRAX_ARCH_V32) = v32
|
||||
|
||||
@ -28,6 +31,11 @@ $(obj)/rescue.bin: $(obj)/rescue.o FORCE
|
||||
$(call if_changed,objcopy)
|
||||
cp -p $(obj)/rescue.bin $(objtree)
|
||||
|
||||
else
|
||||
$(obj)/rescue.bin:
|
||||
|
||||
endif
|
||||
|
||||
$(obj)/testrescue.bin: $(obj)/testrescue.o
|
||||
$(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/testrescue.o tr.bin
|
||||
# Pad it to 784 bytes
|
||||
|
@ -114,6 +114,6 @@ static inline void __udelay(unsigned long usecs)
|
||||
*/
|
||||
#define HZSCALE (268435456 / (1000000 / HZ))
|
||||
|
||||
#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000));
|
||||
#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000))
|
||||
|
||||
#endif /* defined(_M68K_DELAY_H) */
|
||||
|
@ -260,27 +260,31 @@
|
||||
"MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"22:\n" \
|
||||
"MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"SUB %3, %3, #32\n" \
|
||||
"23:\n" \
|
||||
"MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"SUB %3, %3, #32\n" \
|
||||
"24:\n" \
|
||||
"MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"25:\n" \
|
||||
"MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"26:\n" \
|
||||
"SUB %3, %3, #32\n" \
|
||||
"DCACHE [%1+#-64], D0Ar6\n" \
|
||||
"BR $Lloop"id"\n" \
|
||||
\
|
||||
"MOV RAPF, %1\n" \
|
||||
"25:\n" \
|
||||
"MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"26:\n" \
|
||||
"MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"SUB %3, %3, #32\n" \
|
||||
"27:\n" \
|
||||
"MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"28:\n" \
|
||||
"MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"SUB %0, %0, #8\n" \
|
||||
"29:\n" \
|
||||
"SUB %3, %3, #32\n" \
|
||||
"30:\n" \
|
||||
"MGETL D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"31:\n" \
|
||||
"MSETL [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"32:\n" \
|
||||
"SUB %0, %0, #8\n" \
|
||||
"33:\n" \
|
||||
"SETL [%0++], D0.7, D1.7\n" \
|
||||
"SUB %3, %3, #32\n" \
|
||||
"1:" \
|
||||
@ -312,11 +316,15 @@
|
||||
" .long 26b,3b\n" \
|
||||
" .long 27b,3b\n" \
|
||||
" .long 28b,3b\n" \
|
||||
" .long 29b,4b\n" \
|
||||
" .long 29b,3b\n" \
|
||||
" .long 30b,3b\n" \
|
||||
" .long 31b,3b\n" \
|
||||
" .long 32b,3b\n" \
|
||||
" .long 33b,4b\n" \
|
||||
" .previous\n" \
|
||||
: "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \
|
||||
: "0" (to), "1" (from), "2" (ret), "3" (n) \
|
||||
: "D1Ar1", "D0Ar2", "memory")
|
||||
: "D1Ar1", "D0Ar2", "cc", "memory")
|
||||
|
||||
/* rewind 'to' and 'from' pointers when a fault occurs
|
||||
*
|
||||
@ -342,7 +350,7 @@
|
||||
#define __asm_copy_to_user_64bit_rapf_loop(to, from, ret, n, id)\
|
||||
__asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \
|
||||
"LSR D0Ar2, D0Ar2, #8\n" \
|
||||
"AND D0Ar2, D0Ar2, #0x7\n" \
|
||||
"ANDS D0Ar2, D0Ar2, #0x7\n" \
|
||||
"ADDZ D0Ar2, D0Ar2, #4\n" \
|
||||
"SUB D0Ar2, D0Ar2, #1\n" \
|
||||
"MOV D1Ar1, #4\n" \
|
||||
@ -403,47 +411,55 @@
|
||||
"MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"22:\n" \
|
||||
"MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"SUB %3, %3, #16\n" \
|
||||
"23:\n" \
|
||||
"MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"24:\n" \
|
||||
"MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"SUB %3, %3, #16\n" \
|
||||
"25:\n" \
|
||||
"24:\n" \
|
||||
"MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"26:\n" \
|
||||
"25:\n" \
|
||||
"MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"26:\n" \
|
||||
"SUB %3, %3, #16\n" \
|
||||
"27:\n" \
|
||||
"MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"28:\n" \
|
||||
"MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"29:\n" \
|
||||
"SUB %3, %3, #16\n" \
|
||||
"30:\n" \
|
||||
"MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"31:\n" \
|
||||
"MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"32:\n" \
|
||||
"SUB %3, %3, #16\n" \
|
||||
"DCACHE [%1+#-64], D0Ar6\n" \
|
||||
"BR $Lloop"id"\n" \
|
||||
\
|
||||
"MOV RAPF, %1\n" \
|
||||
"29:\n" \
|
||||
"MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"30:\n" \
|
||||
"MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"SUB %3, %3, #16\n" \
|
||||
"31:\n" \
|
||||
"MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"32:\n" \
|
||||
"MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"SUB %3, %3, #16\n" \
|
||||
"33:\n" \
|
||||
"MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"34:\n" \
|
||||
"MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"SUB %3, %3, #16\n" \
|
||||
"35:\n" \
|
||||
"MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"SUB %3, %3, #16\n" \
|
||||
"36:\n" \
|
||||
"MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"SUB %0, %0, #4\n" \
|
||||
"MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"37:\n" \
|
||||
"MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"38:\n" \
|
||||
"SUB %3, %3, #16\n" \
|
||||
"39:\n" \
|
||||
"MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"40:\n" \
|
||||
"MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"41:\n" \
|
||||
"SUB %3, %3, #16\n" \
|
||||
"42:\n" \
|
||||
"MGETD D0FrT, D0.5, D0.6, D0.7, [%1++]\n" \
|
||||
"43:\n" \
|
||||
"MSETD [%0++], D0FrT, D0.5, D0.6, D0.7\n" \
|
||||
"44:\n" \
|
||||
"SUB %0, %0, #4\n" \
|
||||
"45:\n" \
|
||||
"SETD [%0++], D0.7\n" \
|
||||
"SUB %3, %3, #16\n" \
|
||||
"1:" \
|
||||
@ -483,11 +499,19 @@
|
||||
" .long 34b,3b\n" \
|
||||
" .long 35b,3b\n" \
|
||||
" .long 36b,3b\n" \
|
||||
" .long 37b,4b\n" \
|
||||
" .long 37b,3b\n" \
|
||||
" .long 38b,3b\n" \
|
||||
" .long 39b,3b\n" \
|
||||
" .long 40b,3b\n" \
|
||||
" .long 41b,3b\n" \
|
||||
" .long 42b,3b\n" \
|
||||
" .long 43b,3b\n" \
|
||||
" .long 44b,3b\n" \
|
||||
" .long 45b,4b\n" \
|
||||
" .previous\n" \
|
||||
: "=r" (to), "=r" (from), "=r" (ret), "=d" (n) \
|
||||
: "0" (to), "1" (from), "2" (ret), "3" (n) \
|
||||
: "D1Ar1", "D0Ar2", "memory")
|
||||
: "D1Ar1", "D0Ar2", "cc", "memory")
|
||||
|
||||
/* rewind 'to' and 'from' pointers when a fault occurs
|
||||
*
|
||||
@ -513,7 +537,7 @@
|
||||
#define __asm_copy_to_user_32bit_rapf_loop(to, from, ret, n, id)\
|
||||
__asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \
|
||||
"LSR D0Ar2, D0Ar2, #8\n" \
|
||||
"AND D0Ar2, D0Ar2, #0x7\n" \
|
||||
"ANDS D0Ar2, D0Ar2, #0x7\n" \
|
||||
"ADDZ D0Ar2, D0Ar2, #4\n" \
|
||||
"SUB D0Ar2, D0Ar2, #1\n" \
|
||||
"MOV D1Ar1, #4\n" \
|
||||
@ -538,23 +562,31 @@ unsigned long __copy_user(void __user *pdst, const void *psrc,
|
||||
if ((unsigned long) src & 1) {
|
||||
__asm_copy_to_user_1(dst, src, retn);
|
||||
n--;
|
||||
if (retn)
|
||||
return retn + n;
|
||||
}
|
||||
if ((unsigned long) dst & 1) {
|
||||
/* Worst case - byte copy */
|
||||
while (n > 0) {
|
||||
__asm_copy_to_user_1(dst, src, retn);
|
||||
n--;
|
||||
if (retn)
|
||||
return retn + n;
|
||||
}
|
||||
}
|
||||
if (((unsigned long) src & 2) && n >= 2) {
|
||||
__asm_copy_to_user_2(dst, src, retn);
|
||||
n -= 2;
|
||||
if (retn)
|
||||
return retn + n;
|
||||
}
|
||||
if ((unsigned long) dst & 2) {
|
||||
/* Second worst case - word copy */
|
||||
while (n >= 2) {
|
||||
__asm_copy_to_user_2(dst, src, retn);
|
||||
n -= 2;
|
||||
if (retn)
|
||||
return retn + n;
|
||||
}
|
||||
}
|
||||
|
||||
@ -569,6 +601,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc,
|
||||
while (n >= 8) {
|
||||
__asm_copy_to_user_8x64(dst, src, retn);
|
||||
n -= 8;
|
||||
if (retn)
|
||||
return retn + n;
|
||||
}
|
||||
}
|
||||
if (n >= RAPF_MIN_BUF_SIZE) {
|
||||
@ -581,6 +615,8 @@ unsigned long __copy_user(void __user *pdst, const void *psrc,
|
||||
while (n >= 8) {
|
||||
__asm_copy_to_user_8x64(dst, src, retn);
|
||||
n -= 8;
|
||||
if (retn)
|
||||
return retn + n;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -588,11 +624,15 @@ unsigned long __copy_user(void __user *pdst, const void *psrc,
|
||||
while (n >= 16) {
|
||||
__asm_copy_to_user_16(dst, src, retn);
|
||||
n -= 16;
|
||||
if (retn)
|
||||
return retn + n;
|
||||
}
|
||||
|
||||
while (n >= 4) {
|
||||
__asm_copy_to_user_4(dst, src, retn);
|
||||
n -= 4;
|
||||
if (retn)
|
||||
return retn + n;
|
||||
}
|
||||
|
||||
switch (n) {
|
||||
@ -609,6 +649,10 @@ unsigned long __copy_user(void __user *pdst, const void *psrc,
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we get here, retn correctly reflects the number of failing
|
||||
* bytes.
|
||||
*/
|
||||
return retn;
|
||||
}
|
||||
EXPORT_SYMBOL(__copy_user);
|
||||
@ -789,29 +833,49 @@ EXPORT_SYMBOL(__copy_user);
|
||||
*
|
||||
* Rationale:
|
||||
* A fault occurs while reading from user buffer, which is the
|
||||
* source. Since the fault is at a single address, we only
|
||||
* need to rewind by 8 bytes.
|
||||
* source.
|
||||
* Since we don't write to kernel buffer until we read first,
|
||||
* the kernel buffer is at the right state and needn't be
|
||||
* corrected.
|
||||
* corrected, but the source must be rewound to the beginning of
|
||||
* the block, which is LSM_STEP*8 bytes.
|
||||
* LSM_STEP is bits 10:8 in TXSTATUS which is already read
|
||||
* and stored in D0Ar2
|
||||
*
|
||||
* NOTE: If a fault occurs at the last operation in M{G,S}ETL
|
||||
* LSM_STEP will be 0. ie: we do 4 writes in our case, if
|
||||
* a fault happens at the 4th write, LSM_STEP will be 0
|
||||
* instead of 4. The code copes with that.
|
||||
*/
|
||||
#define __asm_copy_from_user_64bit_rapf_loop(to, from, ret, n, id) \
|
||||
__asm_copy_user_64bit_rapf_loop(to, from, ret, n, id, \
|
||||
"SUB %1, %1, #8\n")
|
||||
"LSR D0Ar2, D0Ar2, #5\n" \
|
||||
"ANDS D0Ar2, D0Ar2, #0x38\n" \
|
||||
"ADDZ D0Ar2, D0Ar2, #32\n" \
|
||||
"SUB %1, %1, D0Ar2\n")
|
||||
|
||||
/* rewind 'from' pointer when a fault occurs
|
||||
*
|
||||
* Rationale:
|
||||
* A fault occurs while reading from user buffer, which is the
|
||||
* source. Since the fault is at a single address, we only
|
||||
* need to rewind by 4 bytes.
|
||||
* source.
|
||||
* Since we don't write to kernel buffer until we read first,
|
||||
* the kernel buffer is at the right state and needn't be
|
||||
* corrected.
|
||||
* corrected, but the source must be rewound to the beginning of
|
||||
* the block, which is LSM_STEP*4 bytes.
|
||||
* LSM_STEP is bits 10:8 in TXSTATUS which is already read
|
||||
* and stored in D0Ar2
|
||||
*
|
||||
* NOTE: If a fault occurs at the last operation in M{G,S}ETL
|
||||
* LSM_STEP will be 0. ie: we do 4 writes in our case, if
|
||||
* a fault happens at the 4th write, LSM_STEP will be 0
|
||||
* instead of 4. The code copes with that.
|
||||
*/
|
||||
#define __asm_copy_from_user_32bit_rapf_loop(to, from, ret, n, id) \
|
||||
__asm_copy_user_32bit_rapf_loop(to, from, ret, n, id, \
|
||||
"SUB %1, %1, #4\n")
|
||||
"LSR D0Ar2, D0Ar2, #6\n" \
|
||||
"ANDS D0Ar2, D0Ar2, #0x1c\n" \
|
||||
"ADDZ D0Ar2, D0Ar2, #16\n" \
|
||||
"SUB %1, %1, D0Ar2\n")
|
||||
|
||||
|
||||
/* Copy from user to kernel, zeroing the bytes that were inaccessible in
|
||||
@ -830,6 +894,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc,
|
||||
if ((unsigned long) src & 1) {
|
||||
__asm_copy_from_user_1(dst, src, retn);
|
||||
n--;
|
||||
if (retn)
|
||||
goto copy_exception_bytes;
|
||||
}
|
||||
if ((unsigned long) dst & 1) {
|
||||
/* Worst case - byte copy */
|
||||
@ -843,6 +909,8 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc,
|
||||
if (((unsigned long) src & 2) && n >= 2) {
|
||||
__asm_copy_from_user_2(dst, src, retn);
|
||||
n -= 2;
|
||||
if (retn)
|
||||
goto copy_exception_bytes;
|
||||
}
|
||||
if ((unsigned long) dst & 2) {
|
||||
/* Second worst case - word copy */
|
||||
@ -854,12 +922,6 @@ unsigned long __copy_user_zeroing(void *pdst, const void __user *psrc,
|
||||
}
|
||||
}
|
||||
|
||||
/* We only need one check after the unalignment-adjustments,
|
||||
because if both adjustments were done, either both or
|
||||
neither reference had an exception. */
|
||||
if (retn != 0)
|
||||
goto copy_exception_bytes;
|
||||
|
||||
#ifdef USE_RAPF
|
||||
/* 64 bit copy loop */
|
||||
if (!(((unsigned long) src | (unsigned long) dst) & 7)) {
|
||||
|
@ -208,18 +208,18 @@ EXC( STORE t2, UNIT(6)(dst), s_exc_p10u)
|
||||
ADD src, src, 16*NBYTES
|
||||
EXC( STORE t3, UNIT(7)(dst), s_exc_p9u)
|
||||
ADD dst, dst, 16*NBYTES
|
||||
EXC( LOAD t0, UNIT(-8)(src), l_exc_copy)
|
||||
EXC( LOAD t1, UNIT(-7)(src), l_exc_copy)
|
||||
EXC( LOAD t2, UNIT(-6)(src), l_exc_copy)
|
||||
EXC( LOAD t3, UNIT(-5)(src), l_exc_copy)
|
||||
EXC( LOAD t0, UNIT(-8)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t1, UNIT(-7)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t2, UNIT(-6)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t3, UNIT(-5)(src), l_exc_copy_rewind16)
|
||||
EXC( STORE t0, UNIT(-8)(dst), s_exc_p8u)
|
||||
EXC( STORE t1, UNIT(-7)(dst), s_exc_p7u)
|
||||
EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u)
|
||||
EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u)
|
||||
EXC( LOAD t0, UNIT(-4)(src), l_exc_copy)
|
||||
EXC( LOAD t1, UNIT(-3)(src), l_exc_copy)
|
||||
EXC( LOAD t2, UNIT(-2)(src), l_exc_copy)
|
||||
EXC( LOAD t3, UNIT(-1)(src), l_exc_copy)
|
||||
EXC( LOAD t0, UNIT(-4)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t1, UNIT(-3)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t2, UNIT(-2)(src), l_exc_copy_rewind16)
|
||||
EXC( LOAD t3, UNIT(-1)(src), l_exc_copy_rewind16)
|
||||
EXC( STORE t0, UNIT(-4)(dst), s_exc_p4u)
|
||||
EXC( STORE t1, UNIT(-3)(dst), s_exc_p3u)
|
||||
EXC( STORE t2, UNIT(-2)(dst), s_exc_p2u)
|
||||
@ -383,6 +383,10 @@ done:
|
||||
nop
|
||||
END(memcpy)
|
||||
|
||||
l_exc_copy_rewind16:
|
||||
/* Rewind src and dst by 16*NBYTES for l_exc_copy */
|
||||
SUB src, src, 16*NBYTES
|
||||
SUB dst, dst, 16*NBYTES
|
||||
l_exc_copy:
|
||||
/*
|
||||
* Copy bytes from src until faulting load address (or until a
|
||||
|
@ -206,7 +206,6 @@ CONFIG_MLX4_EN=m
|
||||
# CONFIG_MLX4_DEBUG is not set
|
||||
CONFIG_TEHUTI=m
|
||||
CONFIG_BNX2X=m
|
||||
CONFIG_QLGE=m
|
||||
CONFIG_SFC=m
|
||||
CONFIG_BE2NET=m
|
||||
CONFIG_LIBERTAS_THINFIRM=m
|
||||
|
@ -236,9 +236,6 @@ static int compute_signal(int tt)
|
||||
void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
|
||||
{
|
||||
int reg;
|
||||
struct thread_info *ti = task_thread_info(p);
|
||||
unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32;
|
||||
struct pt_regs *regs = (struct pt_regs *)ksp - 1;
|
||||
#if (KGDB_GDB_REG_SIZE == 32)
|
||||
u32 *ptr = (u32 *)gdb_regs;
|
||||
#else
|
||||
@ -246,25 +243,46 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
|
||||
#endif
|
||||
|
||||
for (reg = 0; reg < 16; reg++)
|
||||
*(ptr++) = regs->regs[reg];
|
||||
*(ptr++) = 0;
|
||||
|
||||
/* S0 - S7 */
|
||||
for (reg = 16; reg < 24; reg++)
|
||||
*(ptr++) = regs->regs[reg];
|
||||
*(ptr++) = p->thread.reg16;
|
||||
*(ptr++) = p->thread.reg17;
|
||||
*(ptr++) = p->thread.reg18;
|
||||
*(ptr++) = p->thread.reg19;
|
||||
*(ptr++) = p->thread.reg20;
|
||||
*(ptr++) = p->thread.reg21;
|
||||
*(ptr++) = p->thread.reg22;
|
||||
*(ptr++) = p->thread.reg23;
|
||||
|
||||
for (reg = 24; reg < 28; reg++)
|
||||
*(ptr++) = 0;
|
||||
|
||||
/* GP, SP, FP, RA */
|
||||
for (reg = 28; reg < 32; reg++)
|
||||
*(ptr++) = regs->regs[reg];
|
||||
*(ptr++) = (long)p;
|
||||
*(ptr++) = p->thread.reg29;
|
||||
*(ptr++) = p->thread.reg30;
|
||||
*(ptr++) = p->thread.reg31;
|
||||
|
||||
*(ptr++) = regs->cp0_status;
|
||||
*(ptr++) = regs->lo;
|
||||
*(ptr++) = regs->hi;
|
||||
*(ptr++) = regs->cp0_badvaddr;
|
||||
*(ptr++) = regs->cp0_cause;
|
||||
*(ptr++) = regs->cp0_epc;
|
||||
*(ptr++) = p->thread.cp0_status;
|
||||
|
||||
/* lo, hi */
|
||||
*(ptr++) = 0;
|
||||
*(ptr++) = 0;
|
||||
|
||||
/*
|
||||
* BadVAddr, Cause
|
||||
* Ideally these would come from the last exception frame up the stack
|
||||
* but that requires unwinding, otherwise we can't know much for sure.
|
||||
*/
|
||||
*(ptr++) = 0;
|
||||
*(ptr++) = 0;
|
||||
|
||||
/*
|
||||
* PC
|
||||
* use return address (RA), i.e. the moment after return from resume()
|
||||
*/
|
||||
*(ptr++) = p->thread.reg31;
|
||||
}
|
||||
|
||||
void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
|
||||
|
@ -214,11 +214,9 @@ struct mips_frame_info {
|
||||
#define J_TARGET(pc,target) \
|
||||
(((unsigned long)(pc) & 0xf0000000) | ((target) << 2))
|
||||
|
||||
static inline int is_ra_save_ins(union mips_instruction *ip)
|
||||
static inline int is_ra_save_ins(union mips_instruction *ip, int *poff)
|
||||
{
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
union mips_instruction mmi;
|
||||
|
||||
/*
|
||||
* swsp ra,offset
|
||||
* swm16 reglist,offset(sp)
|
||||
@ -228,29 +226,71 @@ static inline int is_ra_save_ins(union mips_instruction *ip)
|
||||
*
|
||||
* microMIPS is way more fun...
|
||||
*/
|
||||
if (mm_insn_16bit(ip->halfword[0])) {
|
||||
mmi.word = (ip->halfword[0] << 16);
|
||||
return ((mmi.mm16_r5_format.opcode == mm_swsp16_op &&
|
||||
mmi.mm16_r5_format.rt == 31) ||
|
||||
(mmi.mm16_m_format.opcode == mm_pool16c_op &&
|
||||
mmi.mm16_m_format.func == mm_swm16_op));
|
||||
if (mm_insn_16bit(ip->halfword[1])) {
|
||||
switch (ip->mm16_r5_format.opcode) {
|
||||
case mm_swsp16_op:
|
||||
if (ip->mm16_r5_format.rt != 31)
|
||||
return 0;
|
||||
|
||||
*poff = ip->mm16_r5_format.simmediate;
|
||||
*poff = (*poff << 2) / sizeof(ulong);
|
||||
return 1;
|
||||
|
||||
case mm_pool16c_op:
|
||||
switch (ip->mm16_m_format.func) {
|
||||
case mm_swm16_op:
|
||||
*poff = ip->mm16_m_format.imm;
|
||||
*poff += 1 + ip->mm16_m_format.rlist;
|
||||
*poff = (*poff << 2) / sizeof(ulong);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mmi.halfword[0] = ip->halfword[1];
|
||||
mmi.halfword[1] = ip->halfword[0];
|
||||
return ((mmi.mm_m_format.opcode == mm_pool32b_op &&
|
||||
mmi.mm_m_format.rd > 9 &&
|
||||
mmi.mm_m_format.base == 29 &&
|
||||
mmi.mm_m_format.func == mm_swm32_func) ||
|
||||
(mmi.i_format.opcode == mm_sw32_op &&
|
||||
mmi.i_format.rs == 29 &&
|
||||
mmi.i_format.rt == 31));
|
||||
|
||||
switch (ip->i_format.opcode) {
|
||||
case mm_sw32_op:
|
||||
if (ip->i_format.rs != 29)
|
||||
return 0;
|
||||
if (ip->i_format.rt != 31)
|
||||
return 0;
|
||||
|
||||
*poff = ip->i_format.simmediate / sizeof(ulong);
|
||||
return 1;
|
||||
|
||||
case mm_pool32b_op:
|
||||
switch (ip->mm_m_format.func) {
|
||||
case mm_swm32_func:
|
||||
if (ip->mm_m_format.rd < 0x10)
|
||||
return 0;
|
||||
if (ip->mm_m_format.base != 29)
|
||||
return 0;
|
||||
|
||||
*poff = ip->mm_m_format.simmediate;
|
||||
*poff += (ip->mm_m_format.rd & 0xf) * sizeof(u32);
|
||||
*poff /= sizeof(ulong);
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
/* sw / sd $ra, offset($sp) */
|
||||
return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
|
||||
ip->i_format.rs == 29 &&
|
||||
ip->i_format.rt == 31;
|
||||
if ((ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) &&
|
||||
ip->i_format.rs == 29 && ip->i_format.rt == 31) {
|
||||
*poff = ip->i_format.simmediate / sizeof(ulong);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -265,13 +305,16 @@ static inline int is_jump_ins(union mips_instruction *ip)
|
||||
*
|
||||
* microMIPS is kind of more fun...
|
||||
*/
|
||||
union mips_instruction mmi;
|
||||
if (mm_insn_16bit(ip->halfword[1])) {
|
||||
if ((ip->mm16_r5_format.opcode == mm_pool16c_op &&
|
||||
(ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mmi.word = (ip->halfword[0] << 16);
|
||||
|
||||
if ((mmi.mm16_r5_format.opcode == mm_pool16c_op &&
|
||||
(mmi.mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) ||
|
||||
ip->j_format.opcode == mm_jal32_op)
|
||||
if (ip->j_format.opcode == mm_j32_op)
|
||||
return 1;
|
||||
if (ip->j_format.opcode == mm_jal32_op)
|
||||
return 1;
|
||||
if (ip->r_format.opcode != mm_pool32a_op ||
|
||||
ip->r_format.func != mm_pool32axf_op)
|
||||
@ -299,15 +342,13 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
|
||||
*
|
||||
* microMIPS is not more fun...
|
||||
*/
|
||||
if (mm_insn_16bit(ip->halfword[0])) {
|
||||
union mips_instruction mmi;
|
||||
|
||||
mmi.word = (ip->halfword[0] << 16);
|
||||
return ((mmi.mm16_r3_format.opcode == mm_pool16d_op &&
|
||||
mmi.mm16_r3_format.simmediate && mm_addiusp_func) ||
|
||||
(mmi.mm16_r5_format.opcode == mm_pool16d_op &&
|
||||
mmi.mm16_r5_format.rt == 29));
|
||||
if (mm_insn_16bit(ip->halfword[1])) {
|
||||
return (ip->mm16_r3_format.opcode == mm_pool16d_op &&
|
||||
ip->mm16_r3_format.simmediate && mm_addiusp_func) ||
|
||||
(ip->mm16_r5_format.opcode == mm_pool16d_op &&
|
||||
ip->mm16_r5_format.rt == 29);
|
||||
}
|
||||
|
||||
return (ip->mm_i_format.opcode == mm_addiu32_op &&
|
||||
ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29);
|
||||
#else
|
||||
@ -322,30 +363,36 @@ static inline int is_sp_move_ins(union mips_instruction *ip)
|
||||
|
||||
static int get_frame_info(struct mips_frame_info *info)
|
||||
{
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
union mips_instruction *ip = (void *) (((char *) info->func) - 1);
|
||||
#else
|
||||
union mips_instruction *ip = info->func;
|
||||
#endif
|
||||
unsigned max_insns = info->func_size / sizeof(union mips_instruction);
|
||||
unsigned i;
|
||||
bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS);
|
||||
union mips_instruction insn, *ip, *ip_end;
|
||||
const unsigned int max_insns = 128;
|
||||
unsigned int i;
|
||||
|
||||
info->pc_offset = -1;
|
||||
info->frame_size = 0;
|
||||
|
||||
ip = (void *)msk_isa16_mode((ulong)info->func);
|
||||
if (!ip)
|
||||
goto err;
|
||||
|
||||
if (max_insns == 0)
|
||||
max_insns = 128U; /* unknown function size */
|
||||
max_insns = min(128U, max_insns);
|
||||
ip_end = (void *)ip + info->func_size;
|
||||
|
||||
for (i = 0; i < max_insns; i++, ip++) {
|
||||
for (i = 0; i < max_insns && ip < ip_end; i++, ip++) {
|
||||
if (is_mmips && mm_insn_16bit(ip->halfword[0])) {
|
||||
insn.halfword[0] = 0;
|
||||
insn.halfword[1] = ip->halfword[0];
|
||||
} else if (is_mmips) {
|
||||
insn.halfword[0] = ip->halfword[1];
|
||||
insn.halfword[1] = ip->halfword[0];
|
||||
} else {
|
||||
insn.word = ip->word;
|
||||
}
|
||||
|
||||
if (is_jump_ins(ip))
|
||||
if (is_jump_ins(&insn))
|
||||
break;
|
||||
|
||||
if (!info->frame_size) {
|
||||
if (is_sp_move_ins(ip))
|
||||
if (is_sp_move_ins(&insn))
|
||||
{
|
||||
#ifdef CONFIG_CPU_MICROMIPS
|
||||
if (mm_insn_16bit(ip->halfword[0]))
|
||||
@ -368,11 +415,9 @@ static int get_frame_info(struct mips_frame_info *info)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (info->pc_offset == -1 && is_ra_save_ins(ip)) {
|
||||
info->pc_offset =
|
||||
ip->i_format.simmediate / sizeof(long);
|
||||
if (info->pc_offset == -1 &&
|
||||
is_ra_save_ins(&insn, &info->pc_offset))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (info->frame_size && info->pc_offset >= 0) /* nested */
|
||||
return 0;
|
||||
|
@ -180,6 +180,7 @@ static int ibmebus_create_device(struct device_node *dn)
|
||||
static int ibmebus_create_devices(const struct of_device_id *matches)
|
||||
{
|
||||
struct device_node *root, *child;
|
||||
struct device *dev;
|
||||
int ret = 0;
|
||||
|
||||
root = of_find_node_by_path("/");
|
||||
@ -188,9 +189,12 @@ static int ibmebus_create_devices(const struct of_device_id *matches)
|
||||
if (!of_match_node(matches, child))
|
||||
continue;
|
||||
|
||||
if (bus_find_device(&ibmebus_bus_type, NULL, child,
|
||||
ibmebus_match_node))
|
||||
dev = bus_find_device(&ibmebus_bus_type, NULL, child,
|
||||
ibmebus_match_node);
|
||||
if (dev) {
|
||||
put_device(dev);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = ibmebus_create_device(child);
|
||||
if (ret) {
|
||||
@ -262,6 +266,7 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct device_node *dn = NULL;
|
||||
struct device *dev;
|
||||
char *path;
|
||||
ssize_t rc = 0;
|
||||
|
||||
@ -269,8 +274,10 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
||||
if (bus_find_device(&ibmebus_bus_type, NULL, path,
|
||||
ibmebus_match_path)) {
|
||||
dev = bus_find_device(&ibmebus_bus_type, NULL, path,
|
||||
ibmebus_match_path);
|
||||
if (dev) {
|
||||
put_device(dev);
|
||||
printk(KERN_WARNING "%s: %s has already been probed\n",
|
||||
__func__, path);
|
||||
rc = -EEXIST;
|
||||
@ -306,6 +313,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus,
|
||||
if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path,
|
||||
ibmebus_match_path))) {
|
||||
of_device_unregister(to_platform_device(dev));
|
||||
put_device(dev);
|
||||
|
||||
kfree(path);
|
||||
return count;
|
||||
|
@ -94,7 +94,7 @@ _GLOBAL(power7_nap)
|
||||
std r0,0(r1)
|
||||
ptesync
|
||||
ld r0,0(r1)
|
||||
1: cmp cr0,r0,r0
|
||||
1: cmpd cr0,r0,r0
|
||||
bne 1b
|
||||
PPC_NAP
|
||||
b .
|
||||
|
@ -295,7 +295,7 @@ _GLOBAL(flush_instruction_cache)
|
||||
lis r3, KERNELBASE@h
|
||||
iccci 0,r3
|
||||
#endif
|
||||
#elif CONFIG_FSL_BOOKE
|
||||
#elif defined(CONFIG_FSL_BOOKE)
|
||||
BEGIN_FTR_SECTION
|
||||
mfspr r3,SPRN_L1CSR0
|
||||
ori r3,r3,L1CSR0_CFI|L1CSR0_CLFC
|
||||
|
@ -142,6 +142,15 @@ static void check_smt_enabled(void)
|
||||
of_node_put(dn);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fixup HFSCR:TM based on CPU features. The bit is set by our
|
||||
* early asm init because at that point we haven't updated our
|
||||
* CPU features from firmware and device-tree. Here we have,
|
||||
* so let's do it.
|
||||
*/
|
||||
if (cpu_has_feature(CPU_FTR_HVMODE) && !cpu_has_feature(CPU_FTR_TM_COMP))
|
||||
mtspr(SPRN_HFSCR, mfspr(SPRN_HFSCR) & ~HFSCR_TM);
|
||||
}
|
||||
|
||||
/* Look for smt-enabled= cmdline option */
|
||||
|
@ -138,31 +138,34 @@ static void check_ipl_parmblock(void *start, unsigned long size)
|
||||
|
||||
unsigned long decompress_kernel(void)
|
||||
{
|
||||
unsigned long output_addr;
|
||||
unsigned char *output;
|
||||
void *output, *kernel_end;
|
||||
|
||||
output_addr = ((unsigned long) &_end + HEAP_SIZE + 4095UL) & -4096UL;
|
||||
check_ipl_parmblock((void *) 0, output_addr + SZ__bss_start);
|
||||
memset(&_bss, 0, &_ebss - &_bss);
|
||||
free_mem_ptr = (unsigned long)&_end;
|
||||
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
|
||||
output = (unsigned char *) output_addr;
|
||||
output = (void *) ALIGN((unsigned long) &_end + HEAP_SIZE, PAGE_SIZE);
|
||||
kernel_end = output + SZ__bss_start;
|
||||
check_ipl_parmblock((void *) 0, (unsigned long) kernel_end);
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
/*
|
||||
* Move the initrd right behind the end of the decompressed
|
||||
* kernel image.
|
||||
* kernel image. This also prevents initrd corruption caused by
|
||||
* bss clearing since kernel_end will always be located behind the
|
||||
* current bss section..
|
||||
*/
|
||||
if (INITRD_START && INITRD_SIZE &&
|
||||
INITRD_START < (unsigned long) output + SZ__bss_start) {
|
||||
check_ipl_parmblock(output + SZ__bss_start,
|
||||
INITRD_START + INITRD_SIZE);
|
||||
memmove(output + SZ__bss_start,
|
||||
(void *) INITRD_START, INITRD_SIZE);
|
||||
INITRD_START = (unsigned long) output + SZ__bss_start;
|
||||
if (INITRD_START && INITRD_SIZE && kernel_end > (void *) INITRD_START) {
|
||||
check_ipl_parmblock(kernel_end, INITRD_SIZE);
|
||||
memmove(kernel_end, (void *) INITRD_START, INITRD_SIZE);
|
||||
INITRD_START = (unsigned long) kernel_end;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Clear bss section. free_mem_ptr and free_mem_end_ptr need to be
|
||||
* initialized afterwards since they reside in bss.
|
||||
*/
|
||||
memset(&_bss, 0, &_ebss - &_bss);
|
||||
free_mem_ptr = (unsigned long) &_end;
|
||||
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
|
||||
|
||||
puts("Uncompressing Linux... ");
|
||||
decompress(input_data, input_len, NULL, NULL, output, NULL, error);
|
||||
puts("Ok, booting the kernel.\n");
|
||||
|
@ -1066,7 +1066,7 @@ static __init int setup_disablecpuid(char *arg)
|
||||
{
|
||||
int bit;
|
||||
|
||||
if (get_option(&arg, &bit) && bit < NCAPINTS*32)
|
||||
if (get_option(&arg, &bit) && bit >= 0 && bit < NCAPINTS * 32)
|
||||
setup_clear_cpu_cap(bit);
|
||||
else
|
||||
return 0;
|
||||
|
@ -1103,8 +1103,8 @@ ftrace_graph_call:
|
||||
jmp ftrace_stub
|
||||
#endif
|
||||
|
||||
.globl ftrace_stub
|
||||
ftrace_stub:
|
||||
/* This is weak to keep gas from relaxing the jumps */
|
||||
WEAK(ftrace_stub)
|
||||
ret
|
||||
END(ftrace_caller)
|
||||
|
||||
|
@ -906,6 +906,20 @@ static int segmented_read_std(struct x86_emulate_ctxt *ctxt,
|
||||
return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception);
|
||||
}
|
||||
|
||||
static int segmented_write_std(struct x86_emulate_ctxt *ctxt,
|
||||
struct segmented_address addr,
|
||||
void *data,
|
||||
unsigned int size)
|
||||
{
|
||||
int rc;
|
||||
ulong linear;
|
||||
|
||||
rc = linearize(ctxt, addr, size, true, &linear);
|
||||
if (rc != X86EMUL_CONTINUE)
|
||||
return rc;
|
||||
return ctxt->ops->write_std(ctxt, linear, data, size, &ctxt->exception);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch the next byte of the instruction being emulated which is pointed to
|
||||
* by ctxt->_eip, then increment ctxt->_eip.
|
||||
@ -1599,7 +1613,6 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt,
|
||||
&ctxt->exception);
|
||||
}
|
||||
|
||||
/* Does not support long mode */
|
||||
static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
|
||||
u16 selector, int seg)
|
||||
{
|
||||
@ -1612,6 +1625,21 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
|
||||
int ret;
|
||||
u16 dummy;
|
||||
|
||||
|
||||
/*
|
||||
* None of MOV, POP and LSS can load a NULL selector in CPL=3, but
|
||||
* they can load it at CPL<3 (Intel's manual says only LSS can,
|
||||
* but it's wrong).
|
||||
*
|
||||
* However, the Intel manual says that putting IST=1/DPL=3 in
|
||||
* an interrupt gate will result in SS=3 (the AMD manual instead
|
||||
* says it doesn't), so allow SS=3 in __load_segment_descriptor
|
||||
* and only forbid it here.
|
||||
*/
|
||||
if (seg == VCPU_SREG_SS && selector == 3 &&
|
||||
ctxt->mode == X86EMUL_MODE_PROT64)
|
||||
return emulate_exception(ctxt, GP_VECTOR, 0, true);
|
||||
|
||||
memset(&seg_desc, 0, sizeof seg_desc);
|
||||
|
||||
if (ctxt->mode == X86EMUL_MODE_REAL) {
|
||||
@ -1634,20 +1662,34 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
|
||||
rpl = selector & 3;
|
||||
cpl = ctxt->ops->cpl(ctxt);
|
||||
|
||||
/* NULL selector is not valid for TR, CS and SS (except for long mode) */
|
||||
if ((seg == VCPU_SREG_CS
|
||||
|| (seg == VCPU_SREG_SS
|
||||
&& (ctxt->mode != X86EMUL_MODE_PROT64 || rpl != cpl))
|
||||
|| seg == VCPU_SREG_TR)
|
||||
&& null_selector)
|
||||
goto exception;
|
||||
|
||||
/* TR should be in GDT only */
|
||||
if (seg == VCPU_SREG_TR && (selector & (1 << 2)))
|
||||
goto exception;
|
||||
|
||||
if (null_selector) /* for NULL selector skip all following checks */
|
||||
/* NULL selector is not valid for TR, CS and (except for long mode) SS */
|
||||
if (null_selector) {
|
||||
if (seg == VCPU_SREG_CS || seg == VCPU_SREG_TR)
|
||||
goto exception;
|
||||
|
||||
if (seg == VCPU_SREG_SS) {
|
||||
if (ctxt->mode != X86EMUL_MODE_PROT64 || rpl != cpl)
|
||||
goto exception;
|
||||
|
||||
/*
|
||||
* ctxt->ops->set_segment expects the CPL to be in
|
||||
* SS.DPL, so fake an expand-up 32-bit data segment.
|
||||
*/
|
||||
seg_desc.type = 3;
|
||||
seg_desc.p = 1;
|
||||
seg_desc.s = 1;
|
||||
seg_desc.dpl = cpl;
|
||||
seg_desc.d = 1;
|
||||
seg_desc.g = 1;
|
||||
}
|
||||
|
||||
/* Skip all following checks */
|
||||
goto load;
|
||||
}
|
||||
|
||||
ret = read_segment_descriptor(ctxt, selector, &seg_desc, &desc_addr);
|
||||
if (ret != X86EMUL_CONTINUE)
|
||||
@ -3333,8 +3375,8 @@ static int emulate_store_desc_ptr(struct x86_emulate_ctxt *ctxt,
|
||||
}
|
||||
/* Disable writeback. */
|
||||
ctxt->dst.type = OP_NONE;
|
||||
return segmented_write(ctxt, ctxt->dst.addr.mem,
|
||||
&desc_ptr, 2 + ctxt->op_bytes);
|
||||
return segmented_write_std(ctxt, ctxt->dst.addr.mem,
|
||||
&desc_ptr, 2 + ctxt->op_bytes);
|
||||
}
|
||||
|
||||
static int em_sgdt(struct x86_emulate_ctxt *ctxt)
|
||||
|
@ -227,23 +227,14 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
|
||||
return 1;
|
||||
|
||||
list_for_each_entry(msidesc, &dev->msi_list, list) {
|
||||
__read_msi_msg(msidesc, &msg);
|
||||
pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
|
||||
((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
|
||||
if (msg.data != XEN_PIRQ_MSI_DATA ||
|
||||
xen_irq_from_pirq(pirq) < 0) {
|
||||
pirq = xen_allocate_pirq_msi(dev, msidesc);
|
||||
if (pirq < 0) {
|
||||
irq = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
xen_msi_compose_msg(dev, pirq, &msg);
|
||||
__write_msi_msg(msidesc, &msg);
|
||||
dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq);
|
||||
} else {
|
||||
dev_dbg(&dev->dev,
|
||||
"xen: msi already bound to pirq=%d\n", pirq);
|
||||
pirq = xen_allocate_pirq_msi(dev, msidesc);
|
||||
if (pirq < 0) {
|
||||
irq = -ENODEV;
|
||||
goto error;
|
||||
}
|
||||
xen_msi_compose_msg(dev, pirq, &msg);
|
||||
__write_msi_msg(msidesc, &msg);
|
||||
dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq);
|
||||
irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq,
|
||||
(type == PCI_CAP_ID_MSIX) ?
|
||||
"msi-x" : "msi",
|
||||
|
@ -42,10 +42,22 @@ static struct resource goldfish_pdev_bus_resources[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static bool goldfish_enable __initdata;
|
||||
|
||||
static int __init goldfish_setup(char *str)
|
||||
{
|
||||
goldfish_enable = true;
|
||||
return 0;
|
||||
}
|
||||
__setup("goldfish", goldfish_setup);
|
||||
|
||||
static int __init goldfish_init(void)
|
||||
{
|
||||
if (!goldfish_enable)
|
||||
return -ENODEV;
|
||||
|
||||
platform_device_register_simple("goldfish_pdev_bus", -1,
|
||||
goldfish_pdev_bus_resources, 2);
|
||||
goldfish_pdev_bus_resources, 2);
|
||||
return 0;
|
||||
}
|
||||
device_initcall(goldfish_init);
|
||||
|
@ -2,8 +2,13 @@
|
||||
# Cryptographic API
|
||||
#
|
||||
|
||||
# memneq MUST be built with -Os or -O0 to prevent early-return optimizations
|
||||
# that will defeat memneq's actual purpose to prevent timing attacks.
|
||||
CFLAGS_REMOVE_memneq.o := -O1 -O2 -O3
|
||||
CFLAGS_memneq.o := -Os
|
||||
|
||||
obj-$(CONFIG_CRYPTO) += crypto.o
|
||||
crypto-y := api.o cipher.o compress.o
|
||||
crypto-y := api.o cipher.o compress.o memneq.o
|
||||
|
||||
obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include "public_key.h"
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
@ -189,12 +190,12 @@ static int RSA_verify(const u8 *H, const u8 *EM, size_t k, size_t hash_size,
|
||||
}
|
||||
}
|
||||
|
||||
if (memcmp(asn1_template, EM + T_offset, asn1_size) != 0) {
|
||||
if (crypto_memneq(asn1_template, EM + T_offset, asn1_size) != 0) {
|
||||
kleave(" = -EBADMSG [EM[T] ASN.1 mismatch]");
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
if (memcmp(H, EM + T_offset + asn1_size, hash_size) != 0) {
|
||||
if (crypto_memneq(H, EM + T_offset + asn1_size, hash_size) != 0) {
|
||||
kleave(" = -EKEYREJECTED [EM[T] hash mismatch]");
|
||||
return -EKEYREJECTED;
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ static void authenc_verify_ahash_update_done(struct crypto_async_request *areq,
|
||||
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
|
||||
authsize, 0);
|
||||
|
||||
err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
|
||||
err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@ -227,7 +227,7 @@ static void authenc_verify_ahash_done(struct crypto_async_request *areq,
|
||||
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
|
||||
authsize, 0);
|
||||
|
||||
err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
|
||||
err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@ -463,7 +463,7 @@ static int crypto_authenc_verify(struct aead_request *req,
|
||||
ihash = ohash + authsize;
|
||||
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
|
||||
authsize, 0);
|
||||
return memcmp(ihash, ohash, authsize) ? -EBADMSG : 0;
|
||||
return crypto_memneq(ihash, ohash, authsize) ? -EBADMSG : 0;
|
||||
}
|
||||
|
||||
static int crypto_authenc_iverify(struct aead_request *req, u8 *iv,
|
||||
|
@ -247,7 +247,7 @@ static void authenc_esn_verify_ahash_update_done(struct crypto_async_request *ar
|
||||
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
|
||||
authsize, 0);
|
||||
|
||||
err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
|
||||
err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@ -296,7 +296,7 @@ static void authenc_esn_verify_ahash_update_done2(struct crypto_async_request *a
|
||||
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
|
||||
authsize, 0);
|
||||
|
||||
err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
|
||||
err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@ -336,7 +336,7 @@ static void authenc_esn_verify_ahash_done(struct crypto_async_request *areq,
|
||||
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
|
||||
authsize, 0);
|
||||
|
||||
err = memcmp(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
|
||||
err = crypto_memneq(ihash, ahreq->result, authsize) ? -EBADMSG : 0;
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@ -568,7 +568,7 @@ static int crypto_authenc_esn_verify(struct aead_request *req)
|
||||
ihash = ohash + authsize;
|
||||
scatterwalk_map_and_copy(ihash, areq_ctx->sg, areq_ctx->cryptlen,
|
||||
authsize, 0);
|
||||
return memcmp(ihash, ohash, authsize) ? -EBADMSG : 0;
|
||||
return crypto_memneq(ihash, ohash, authsize) ? -EBADMSG : 0;
|
||||
}
|
||||
|
||||
static int crypto_authenc_esn_iverify(struct aead_request *req, u8 *iv,
|
||||
|
@ -364,7 +364,7 @@ static void crypto_ccm_decrypt_done(struct crypto_async_request *areq,
|
||||
|
||||
if (!err) {
|
||||
err = crypto_ccm_auth(req, req->dst, cryptlen);
|
||||
if (!err && memcmp(pctx->auth_tag, pctx->odata, authsize))
|
||||
if (!err && crypto_memneq(pctx->auth_tag, pctx->odata, authsize))
|
||||
err = -EBADMSG;
|
||||
}
|
||||
aead_request_complete(req, err);
|
||||
@ -423,7 +423,7 @@ static int crypto_ccm_decrypt(struct aead_request *req)
|
||||
return err;
|
||||
|
||||
/* verify */
|
||||
if (memcmp(authtag, odata, authsize))
|
||||
if (crypto_memneq(authtag, odata, authsize))
|
||||
return -EBADMSG;
|
||||
|
||||
return err;
|
||||
|
@ -582,7 +582,7 @@ static int crypto_gcm_verify(struct aead_request *req,
|
||||
|
||||
crypto_xor(auth_tag, iauth_tag, 16);
|
||||
scatterwalk_map_and_copy(iauth_tag, req->src, cryptlen, authsize, 0);
|
||||
return memcmp(iauth_tag, auth_tag, authsize) ? -EBADMSG : 0;
|
||||
return crypto_memneq(iauth_tag, auth_tag, authsize) ? -EBADMSG : 0;
|
||||
}
|
||||
|
||||
static void gcm_decrypt_done(struct crypto_async_request *areq, int err)
|
||||
|
138
crypto/memneq.c
Normal file
138
crypto/memneq.c
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Constant-time equality testing of memory regions.
|
||||
*
|
||||
* Authors:
|
||||
*
|
||||
* James Yonan <james@openvpn.net>
|
||||
* Daniel Borkmann <dborkman@redhat.com>
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2013 OpenVPN Technologies, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2013 OpenVPN Technologies, Inc. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of OpenVPN Technologies nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <crypto/algapi.h>
|
||||
|
||||
#ifndef __HAVE_ARCH_CRYPTO_MEMNEQ
|
||||
|
||||
/* Generic path for arbitrary size */
|
||||
static inline unsigned long
|
||||
__crypto_memneq_generic(const void *a, const void *b, size_t size)
|
||||
{
|
||||
unsigned long neq = 0;
|
||||
|
||||
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
||||
while (size >= sizeof(unsigned long)) {
|
||||
neq |= *(unsigned long *)a ^ *(unsigned long *)b;
|
||||
a += sizeof(unsigned long);
|
||||
b += sizeof(unsigned long);
|
||||
size -= sizeof(unsigned long);
|
||||
}
|
||||
#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
|
||||
while (size > 0) {
|
||||
neq |= *(unsigned char *)a ^ *(unsigned char *)b;
|
||||
a += 1;
|
||||
b += 1;
|
||||
size -= 1;
|
||||
}
|
||||
return neq;
|
||||
}
|
||||
|
||||
/* Loop-free fast-path for frequently used 16-byte size */
|
||||
static inline unsigned long __crypto_memneq_16(const void *a, const void *b)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||
if (sizeof(unsigned long) == 8)
|
||||
return ((*(unsigned long *)(a) ^ *(unsigned long *)(b))
|
||||
| (*(unsigned long *)(a+8) ^ *(unsigned long *)(b+8)));
|
||||
else if (sizeof(unsigned int) == 4)
|
||||
return ((*(unsigned int *)(a) ^ *(unsigned int *)(b))
|
||||
| (*(unsigned int *)(a+4) ^ *(unsigned int *)(b+4))
|
||||
| (*(unsigned int *)(a+8) ^ *(unsigned int *)(b+8))
|
||||
| (*(unsigned int *)(a+12) ^ *(unsigned int *)(b+12)));
|
||||
else
|
||||
#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
|
||||
return ((*(unsigned char *)(a) ^ *(unsigned char *)(b))
|
||||
| (*(unsigned char *)(a+1) ^ *(unsigned char *)(b+1))
|
||||
| (*(unsigned char *)(a+2) ^ *(unsigned char *)(b+2))
|
||||
| (*(unsigned char *)(a+3) ^ *(unsigned char *)(b+3))
|
||||
| (*(unsigned char *)(a+4) ^ *(unsigned char *)(b+4))
|
||||
| (*(unsigned char *)(a+5) ^ *(unsigned char *)(b+5))
|
||||
| (*(unsigned char *)(a+6) ^ *(unsigned char *)(b+6))
|
||||
| (*(unsigned char *)(a+7) ^ *(unsigned char *)(b+7))
|
||||
| (*(unsigned char *)(a+8) ^ *(unsigned char *)(b+8))
|
||||
| (*(unsigned char *)(a+9) ^ *(unsigned char *)(b+9))
|
||||
| (*(unsigned char *)(a+10) ^ *(unsigned char *)(b+10))
|
||||
| (*(unsigned char *)(a+11) ^ *(unsigned char *)(b+11))
|
||||
| (*(unsigned char *)(a+12) ^ *(unsigned char *)(b+12))
|
||||
| (*(unsigned char *)(a+13) ^ *(unsigned char *)(b+13))
|
||||
| (*(unsigned char *)(a+14) ^ *(unsigned char *)(b+14))
|
||||
| (*(unsigned char *)(a+15) ^ *(unsigned char *)(b+15)));
|
||||
}
|
||||
|
||||
/* Compare two areas of memory without leaking timing information,
|
||||
* and with special optimizations for common sizes. Users should
|
||||
* not call this function directly, but should instead use
|
||||
* crypto_memneq defined in crypto/algapi.h.
|
||||
*/
|
||||
noinline unsigned long __crypto_memneq(const void *a, const void *b,
|
||||
size_t size)
|
||||
{
|
||||
switch (size) {
|
||||
case 16:
|
||||
return __crypto_memneq_16(a, b);
|
||||
default:
|
||||
return __crypto_memneq_generic(a, b, size);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(__crypto_memneq);
|
||||
|
||||
#endif /* __HAVE_ARCH_CRYPTO_MEMNEQ */
|
@ -173,7 +173,7 @@ static void __init acpi_request_region (struct acpi_generic_address *gas,
|
||||
request_mem_region(addr, length, desc);
|
||||
}
|
||||
|
||||
static void __init acpi_reserve_resources(void)
|
||||
static int __init acpi_reserve_resources(void)
|
||||
{
|
||||
acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
|
||||
"ACPI PM1a_EVT_BLK");
|
||||
@ -202,7 +202,10 @@ static void __init acpi_reserve_resources(void)
|
||||
if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
|
||||
acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
|
||||
acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
|
||||
|
||||
return 0;
|
||||
}
|
||||
fs_initcall_sync(acpi_reserve_resources);
|
||||
|
||||
void acpi_os_printf(const char *fmt, ...)
|
||||
{
|
||||
@ -1724,7 +1727,6 @@ acpi_status __init acpi_os_initialize(void)
|
||||
|
||||
acpi_status __init acpi_os_initialize1(void)
|
||||
{
|
||||
acpi_reserve_resources();
|
||||
kacpid_wq = alloc_workqueue("kacpid", 0, 1);
|
||||
kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
|
||||
kacpi_hotplug_wq = alloc_workqueue("kacpi_hotplug", 0, 1);
|
||||
|
@ -1020,7 +1020,6 @@ int device_add(struct device *dev)
|
||||
struct kobject *kobj;
|
||||
struct class_interface *class_intf;
|
||||
int error = -EINVAL;
|
||||
struct kobject *glue_dir = NULL;
|
||||
|
||||
dev = get_device(dev);
|
||||
if (!dev)
|
||||
|
@ -857,7 +857,11 @@ static int __init lp_setup (char *str)
|
||||
} else if (!strcmp(str, "auto")) {
|
||||
parport_nr[0] = LP_PARPORT_AUTO;
|
||||
} else if (!strcmp(str, "none")) {
|
||||
parport_nr[parport_ptr++] = LP_PARPORT_NONE;
|
||||
if (parport_ptr < LP_NO)
|
||||
parport_nr[parport_ptr++] = LP_PARPORT_NONE;
|
||||
else
|
||||
printk(KERN_INFO "lp: too many ports, %s ignored.\n",
|
||||
str);
|
||||
} else if (!strcmp(str, "reset")) {
|
||||
reset = 1;
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ static int wm831x_clkout_is_enabled(struct clk_hw *hw)
|
||||
if (ret < 0) {
|
||||
dev_err(wm831x->dev, "Unable to read CLOCK_CONTROL_1: %d\n",
|
||||
ret);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return (ret & WM831X_CLKOUT_ENA) != 0;
|
||||
|
@ -422,7 +422,9 @@ static int aead_set_sh_desc(struct crypto_aead *aead)
|
||||
|
||||
/* Will read cryptlen */
|
||||
append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
|
||||
aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
|
||||
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
|
||||
FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
|
||||
append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
|
||||
|
||||
/* Write ICV */
|
||||
append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
|
||||
|
@ -1793,6 +1793,7 @@ caam_hash_alloc(struct device *ctrldev, struct caam_hash_template *template,
|
||||
template->name);
|
||||
snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
|
||||
template->driver_name);
|
||||
t_alg->ahash_alg.setkey = NULL;
|
||||
}
|
||||
alg->cra_module = THIS_MODULE;
|
||||
alg->cra_init = caam_hash_cra_init;
|
||||
|
@ -428,6 +428,7 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
|
||||
struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private;
|
||||
struct edid *edid;
|
||||
struct i2c_adapter *i2c;
|
||||
bool ret = false;
|
||||
|
||||
BUG_ON(crt->base.type != INTEL_OUTPUT_ANALOG);
|
||||
|
||||
@ -444,17 +445,17 @@ static bool intel_crt_detect_ddc(struct drm_connector *connector)
|
||||
*/
|
||||
if (!is_digital) {
|
||||
DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
|
||||
return true;
|
||||
ret = true;
|
||||
} else {
|
||||
DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n");
|
||||
}
|
||||
|
||||
DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n");
|
||||
} else {
|
||||
DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [no valid EDID found]\n");
|
||||
}
|
||||
|
||||
kfree(edid);
|
||||
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum drm_connector_status
|
||||
|
@ -7052,9 +7052,9 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
|
||||
|
||||
wake_up_all(&dev_priv->pending_flip_queue);
|
||||
|
||||
queue_work(dev_priv->wq, &work->work);
|
||||
|
||||
trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj);
|
||||
|
||||
queue_work(dev_priv->wq, &work->work);
|
||||
}
|
||||
|
||||
void intel_finish_page_flip(struct drm_device *dev, int pipe)
|
||||
|
@ -1253,7 +1253,7 @@ nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
|
||||
uint32_t start, uint32_t size)
|
||||
{
|
||||
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
|
||||
u32 end = max(start + size, (u32)256);
|
||||
u32 end = min_t(u32, start + size, 256);
|
||||
u32 i;
|
||||
|
||||
for (i = start; i < end; i++) {
|
||||
|
@ -193,7 +193,7 @@ cleanup:
|
||||
*
|
||||
* This routine is called normally during driver unloading or exiting.
|
||||
*/
|
||||
void hv_cleanup(void)
|
||||
void hv_cleanup(bool crash)
|
||||
{
|
||||
union hv_x64_msr_hypercall_contents hypercall_msr;
|
||||
|
||||
@ -203,7 +203,8 @@ void hv_cleanup(void)
|
||||
if (hv_context.hypercall_page) {
|
||||
hypercall_msr.as_uint64 = 0;
|
||||
wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
|
||||
vfree(hv_context.hypercall_page);
|
||||
if (!crash)
|
||||
vfree(hv_context.hypercall_page);
|
||||
hv_context.hypercall_page = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -519,7 +519,7 @@ extern struct hv_context hv_context;
|
||||
|
||||
extern int hv_init(void);
|
||||
|
||||
extern void hv_cleanup(void);
|
||||
extern void hv_cleanup(bool crash);
|
||||
|
||||
extern int hv_post_message(union hv_connection_id connection_id,
|
||||
enum hv_message_type message_type,
|
||||
|
@ -618,7 +618,7 @@ err_unregister:
|
||||
bus_unregister(&hv_bus);
|
||||
|
||||
err_cleanup:
|
||||
hv_cleanup();
|
||||
hv_cleanup(false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -841,7 +841,7 @@ static void __exit vmbus_exit(void)
|
||||
free_irq(irq, hv_acpi_dev);
|
||||
vmbus_free_channels();
|
||||
bus_unregister(&hv_bus);
|
||||
hv_cleanup();
|
||||
hv_cleanup(false);
|
||||
acpi_bus_unregister_driver(&vmbus_acpi_driver);
|
||||
hv_cpu_hotplug_quirk(false);
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
val = (val * 10 / 625) * 8;
|
||||
val = (clamp_val(val, -128000, 128000) * 10 / 625) * 8;
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
data->temp[attr->index] = val;
|
||||
|
@ -273,8 +273,14 @@ error:
|
||||
|
||||
static void at91_twi_read_next_byte(struct at91_twi_dev *dev)
|
||||
{
|
||||
if (dev->buf_len <= 0)
|
||||
/*
|
||||
* If we are in this case, it means there is garbage data in RHR, so
|
||||
* delete them.
|
||||
*/
|
||||
if (!dev->buf_len) {
|
||||
at91_twi_read(dev, AT91_TWI_RHR);
|
||||
return;
|
||||
}
|
||||
|
||||
*dev->buf = at91_twi_read(dev, AT91_TWI_RHR) & 0xff;
|
||||
--dev->buf_len;
|
||||
@ -371,6 +377,24 @@ static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id)
|
||||
|
||||
if (!irqstatus)
|
||||
return IRQ_NONE;
|
||||
/*
|
||||
* In reception, the behavior of the twi device (before sama5d2) is
|
||||
* weird. There is some magic about RXRDY flag! When a data has been
|
||||
* almost received, the reception of a new one is anticipated if there
|
||||
* is no stop command to send. That is the reason why ask for sending
|
||||
* the stop command not on the last data but on the second last one.
|
||||
*
|
||||
* Unfortunately, we could still have the RXRDY flag set even if the
|
||||
* transfer is done and we have read the last data. It might happen
|
||||
* when the i2c slave device sends too quickly data after receiving the
|
||||
* ack from the master. The data has been almost received before having
|
||||
* the order to send stop. In this case, sending the stop command could
|
||||
* cause a RXRDY interrupt with a TXCOMP one. It is better to manage
|
||||
* the RXRDY interrupt first in order to not keep garbage data in the
|
||||
* Receive Holding Register for the next transfer.
|
||||
*/
|
||||
if (irqstatus & AT91_TWI_RXRDY)
|
||||
at91_twi_read_next_byte(dev);
|
||||
|
||||
/*
|
||||
* When a NACK condition is detected, the I2C controller sets the NACK,
|
||||
@ -413,8 +437,6 @@ static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id)
|
||||
if (irqstatus & (AT91_TWI_TXCOMP | AT91_TWI_NACK)) {
|
||||
at91_disable_twi_interrupts(dev);
|
||||
complete(&dev->cmd_complete);
|
||||
} else if (irqstatus & AT91_TWI_RXRDY) {
|
||||
at91_twi_read_next_byte(dev);
|
||||
} else if (irqstatus & AT91_TWI_TXRDY) {
|
||||
at91_twi_write_next_byte(dev);
|
||||
}
|
||||
@ -429,7 +451,6 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
|
||||
{
|
||||
int ret;
|
||||
bool has_unre_flag = dev->pdata->has_unre_flag;
|
||||
unsigned sr;
|
||||
|
||||
/*
|
||||
* WARNING: the TXCOMP bit in the Status Register is NOT a clear on
|
||||
@ -466,7 +487,7 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
|
||||
dev->transfer_status = 0;
|
||||
|
||||
/* Clear pending interrupts, such as NACK. */
|
||||
sr = at91_twi_read(dev, AT91_TWI_SR);
|
||||
at91_twi_read(dev, AT91_TWI_SR);
|
||||
|
||||
if (!dev->buf_len) {
|
||||
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK);
|
||||
@ -474,11 +495,6 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
|
||||
} else if (dev->msg->flags & I2C_M_RD) {
|
||||
unsigned start_flags = AT91_TWI_START;
|
||||
|
||||
if (sr & AT91_TWI_RXRDY) {
|
||||
dev_err(dev->dev, "RXRDY still set!");
|
||||
at91_twi_read(dev, AT91_TWI_RHR);
|
||||
}
|
||||
|
||||
/* if only one byte is to be read, immediately stop transfer */
|
||||
if (dev->buf_len <= 1 && !(dev->msg->flags & I2C_M_RECV_LEN))
|
||||
start_flags |= AT91_TWI_STOP;
|
||||
|
@ -1598,7 +1598,7 @@ find_mad_agent(struct ib_mad_port_private *port_priv,
|
||||
if (!class)
|
||||
goto out;
|
||||
if (convert_mgmt_class(mad->mad_hdr.mgmt_class) >=
|
||||
IB_MGMT_MAX_METHODS)
|
||||
ARRAY_SIZE(class->method_table))
|
||||
goto out;
|
||||
method = class->method_table[convert_mgmt_class(
|
||||
mad->mad_hdr.mgmt_class)];
|
||||
|
@ -516,8 +516,11 @@ static void join_handler(int status, struct ib_sa_mcmember_rec *rec,
|
||||
if (status)
|
||||
process_join_error(group, status);
|
||||
else {
|
||||
ib_find_pkey(group->port->dev->device, group->port->port_num,
|
||||
be16_to_cpu(rec->pkey), &pkey_index);
|
||||
|
||||
if (ib_find_pkey(group->port->dev->device,
|
||||
group->port->port_num, be16_to_cpu(rec->pkey),
|
||||
&pkey_index))
|
||||
pkey_index = MCAST_INVALID_PKEY_INDEX;
|
||||
|
||||
spin_lock_irq(&group->port->lock);
|
||||
group->rec = *rec;
|
||||
|
@ -118,7 +118,9 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr
|
||||
!(1 << ah->av.eth.stat_rate & dev->caps.stat_rate_support))
|
||||
--ah->av.eth.stat_rate;
|
||||
}
|
||||
|
||||
ah->av.eth.sl_tclass_flowlabel |=
|
||||
cpu_to_be32((ah_attr->grh.traffic_class << 20) |
|
||||
ah_attr->grh.flow_label);
|
||||
/*
|
||||
* HW requires multicast LID so we just choose one.
|
||||
*/
|
||||
@ -126,7 +128,7 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr
|
||||
ah->av.ib.dlid = cpu_to_be16(0xc000);
|
||||
|
||||
memcpy(ah->av.eth.dgid, ah_attr->grh.dgid.raw, 16);
|
||||
ah->av.eth.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 29);
|
||||
ah->av.eth.sl_tclass_flowlabel |= cpu_to_be32(ah_attr->sl << 29);
|
||||
|
||||
return &ah->ibah;
|
||||
}
|
||||
|
@ -312,9 +312,11 @@ static int eth_link_query_port(struct ib_device *ibdev, u8 port,
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
props->active_width = (((u8 *)mailbox->buf)[5] == 0x40) ?
|
||||
IB_WIDTH_4X : IB_WIDTH_1X;
|
||||
props->active_speed = IB_SPEED_QDR;
|
||||
props->active_width = (((u8 *)mailbox->buf)[5] == 0x40) ||
|
||||
(((u8 *)mailbox->buf)[5] == 0x20 /*56Gb*/) ?
|
||||
IB_WIDTH_4X : IB_WIDTH_1X;
|
||||
props->active_speed = (((u8 *)mailbox->buf)[5] == 0x20 /*56Gb*/) ?
|
||||
IB_SPEED_FDR : IB_SPEED_QDR;
|
||||
props->port_cap_flags = IB_PORT_CM_SUP;
|
||||
props->gid_tbl_len = mdev->dev->caps.gid_table_len[port];
|
||||
props->max_msg_sz = mdev->dev->caps.max_msg_sz;
|
||||
|
@ -1482,12 +1482,14 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
|
||||
|
||||
ret = ipoib_set_mode(dev, buf);
|
||||
|
||||
rtnl_unlock();
|
||||
/* The assumption is that the function ipoib_set_mode returned
|
||||
* with the rtnl held by it, if not the value -EBUSY returned,
|
||||
* then no need to rtnl_unlock
|
||||
*/
|
||||
if (ret != -EBUSY)
|
||||
rtnl_unlock();
|
||||
|
||||
if (!ret)
|
||||
return count;
|
||||
|
||||
return ret;
|
||||
return (!ret || ret == -EBUSY) ? count : ret;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode);
|
||||
|
@ -234,8 +234,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf)
|
||||
priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
|
||||
|
||||
ipoib_flush_paths(dev);
|
||||
rtnl_lock();
|
||||
return 0;
|
||||
return (!rtnl_trylock()) ? -EBUSY : 0;
|
||||
}
|
||||
|
||||
if (!strcmp(buf, "datagram\n")) {
|
||||
@ -244,8 +243,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf)
|
||||
dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu));
|
||||
rtnl_unlock();
|
||||
ipoib_flush_paths(dev);
|
||||
rtnl_lock();
|
||||
return 0;
|
||||
return (!rtnl_trylock()) ? -EBUSY : 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
|
@ -669,6 +669,10 @@ static int cm109_usb_probe(struct usb_interface *intf,
|
||||
int error = -ENOMEM;
|
||||
|
||||
interface = intf->cur_altsetting;
|
||||
|
||||
if (interface->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
endpoint = &interface->endpoint[0].desc;
|
||||
|
||||
if (!usb_endpoint_is_int_in(endpoint))
|
||||
|
@ -1437,6 +1437,10 @@ static int ims_pcu_parse_cdc_data(struct usb_interface *intf, struct ims_pcu *pc
|
||||
return -EINVAL;
|
||||
|
||||
alt = pcu->ctrl_intf->cur_altsetting;
|
||||
|
||||
if (alt->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
pcu->ep_ctrl = &alt->endpoint[0].desc;
|
||||
pcu->max_ctrl_size = usb_endpoint_maxp(pcu->ep_ctrl);
|
||||
|
||||
|
@ -876,6 +876,10 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
int ret, pipe, i;
|
||||
|
||||
interface = intf->cur_altsetting;
|
||||
|
||||
if (interface->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
endpoint = &interface->endpoint[0].desc;
|
||||
if (!usb_endpoint_is_int_in(endpoint))
|
||||
return -ENODEV;
|
||||
|
@ -211,6 +211,12 @@ static const struct dmi_system_id __initconst i8042_dmi_noloop_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_VERSION, "Rev 1"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "PEGATRON CORPORATION"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "C15B"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -341,6 +341,9 @@ static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id
|
||||
int error;
|
||||
int i;
|
||||
|
||||
if (intf->cur_altsetting->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
hanwang = kzalloc(sizeof(struct hanwang), GFP_KERNEL);
|
||||
input_dev = input_allocate_device();
|
||||
if (!hanwang || !input_dev) {
|
||||
|
@ -1029,7 +1029,7 @@ again:
|
||||
next_tail = (tail + sizeof(*cmd)) % iommu->cmd_buf_size;
|
||||
left = (head - next_tail) % iommu->cmd_buf_size;
|
||||
|
||||
if (left <= 2) {
|
||||
if (left <= 0x20) {
|
||||
struct iommu_cmd sync_cmd;
|
||||
volatile u64 sem = 0;
|
||||
int ret;
|
||||
|
@ -2317,6 +2317,9 @@ static int gigaset_probe(struct usb_interface *interface,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (hostif->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
dev_info(&udev->dev,
|
||||
"%s: Device matched (Vendor: 0x%x, Product: 0x%x)\n",
|
||||
__func__, le16_to_cpu(udev->descriptor.idVendor),
|
||||
|
@ -787,8 +787,10 @@ static int __init ser_gigaset_init(void)
|
||||
driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
|
||||
GIGASET_MODULENAME, GIGASET_DEVNAME,
|
||||
&ops, THIS_MODULE);
|
||||
if (!driver)
|
||||
if (!driver) {
|
||||
rc = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = tty_register_ldisc(N_GIGASET_M101, &gigaset_ldisc);
|
||||
if (rc != 0) {
|
||||
|
@ -976,11 +976,62 @@ int dm_set_target_max_io_len(struct dm_target *ti, sector_t len)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dm_set_target_max_io_len);
|
||||
|
||||
/*
|
||||
* Flush current->bio_list when the target map method blocks.
|
||||
* This fixes deadlocks in snapshot and possibly in other targets.
|
||||
*/
|
||||
struct dm_offload {
|
||||
struct blk_plug plug;
|
||||
struct blk_plug_cb cb;
|
||||
};
|
||||
|
||||
static void flush_current_bio_list(struct blk_plug_cb *cb, bool from_schedule)
|
||||
{
|
||||
struct dm_offload *o = container_of(cb, struct dm_offload, cb);
|
||||
struct bio_list list;
|
||||
struct bio *bio;
|
||||
|
||||
INIT_LIST_HEAD(&o->cb.list);
|
||||
|
||||
if (unlikely(!current->bio_list))
|
||||
return;
|
||||
|
||||
list = *current->bio_list;
|
||||
bio_list_init(current->bio_list);
|
||||
|
||||
while ((bio = bio_list_pop(&list))) {
|
||||
struct bio_set *bs = bio->bi_pool;
|
||||
if (unlikely(!bs) || bs == fs_bio_set) {
|
||||
bio_list_add(current->bio_list, bio);
|
||||
continue;
|
||||
}
|
||||
|
||||
spin_lock(&bs->rescue_lock);
|
||||
bio_list_add(&bs->rescue_list, bio);
|
||||
queue_work(bs->rescue_workqueue, &bs->rescue_work);
|
||||
spin_unlock(&bs->rescue_lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void dm_offload_start(struct dm_offload *o)
|
||||
{
|
||||
blk_start_plug(&o->plug);
|
||||
o->cb.callback = flush_current_bio_list;
|
||||
list_add(&o->cb.list, ¤t->plug->cb_list);
|
||||
}
|
||||
|
||||
static void dm_offload_end(struct dm_offload *o)
|
||||
{
|
||||
list_del(&o->cb.list);
|
||||
blk_finish_plug(&o->plug);
|
||||
}
|
||||
|
||||
static void __map_bio(struct dm_target_io *tio)
|
||||
{
|
||||
int r;
|
||||
sector_t sector;
|
||||
struct mapped_device *md;
|
||||
struct dm_offload o;
|
||||
struct bio *clone = &tio->clone;
|
||||
struct dm_target *ti = tio->ti;
|
||||
|
||||
@ -994,7 +1045,11 @@ static void __map_bio(struct dm_target_io *tio)
|
||||
*/
|
||||
atomic_inc(&tio->io->io_count);
|
||||
sector = clone->bi_sector;
|
||||
|
||||
dm_offload_start(&o);
|
||||
r = ti->type->map(ti, clone);
|
||||
dm_offload_end(&o);
|
||||
|
||||
if (r == DM_MAPIO_REMAPPED) {
|
||||
/* the bio has been remapped so dispatch it */
|
||||
|
||||
|
@ -549,6 +549,7 @@ config VIDEO_S5K6AA
|
||||
config VIDEO_S5K4ECGX
|
||||
tristate "Samsung S5K4ECGX sensor support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
select CRC32
|
||||
---help---
|
||||
This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M
|
||||
camera sensor with an embedded SoC image signal processor.
|
||||
|
@ -263,6 +263,8 @@ static void ite_set_carrier_params(struct ite_dev *dev)
|
||||
|
||||
if (allowance > ITE_RXDCR_MAX)
|
||||
allowance = ITE_RXDCR_MAX;
|
||||
|
||||
use_demodulator = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,6 +289,14 @@ static void free_firmware(struct xc2028_data *priv)
|
||||
int i;
|
||||
tuner_dbg("%s called\n", __func__);
|
||||
|
||||
/* free allocated f/w string */
|
||||
if (priv->fname != firmware_name)
|
||||
kfree(priv->fname);
|
||||
priv->fname = NULL;
|
||||
|
||||
priv->state = XC2028_NO_FIRMWARE;
|
||||
memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
|
||||
|
||||
if (!priv->firm)
|
||||
return;
|
||||
|
||||
@ -299,9 +307,6 @@ static void free_firmware(struct xc2028_data *priv)
|
||||
|
||||
priv->firm = NULL;
|
||||
priv->firm_size = 0;
|
||||
priv->state = XC2028_NO_FIRMWARE;
|
||||
|
||||
memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
|
||||
}
|
||||
|
||||
static int load_all_firmwares(struct dvb_frontend *fe,
|
||||
@ -890,9 +895,9 @@ read_not_reliable:
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
free_firmware(priv);
|
||||
priv->state = XC2028_SLEEP;
|
||||
|
||||
memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
|
||||
if (retry_count < 8) {
|
||||
msleep(50);
|
||||
retry_count++;
|
||||
@ -1314,11 +1319,8 @@ static int xc2028_dvb_release(struct dvb_frontend *fe)
|
||||
mutex_lock(&xc2028_list_mutex);
|
||||
|
||||
/* only perform final cleanup if this is the last instance */
|
||||
if (hybrid_tuner_report_instance_count(priv) == 1) {
|
||||
if (hybrid_tuner_report_instance_count(priv) == 1)
|
||||
free_firmware(priv);
|
||||
kfree(priv->ctrl.fname);
|
||||
priv->ctrl.fname = NULL;
|
||||
}
|
||||
|
||||
if (priv)
|
||||
hybrid_tuner_release_state(priv);
|
||||
@ -1381,8 +1383,6 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
|
||||
|
||||
/*
|
||||
* Copy the config data.
|
||||
* For the firmware name, keep a local copy of the string,
|
||||
* in order to avoid troubles during device release.
|
||||
*/
|
||||
kfree(priv->ctrl.fname);
|
||||
priv->ctrl.fname = NULL;
|
||||
@ -1392,6 +1392,7 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
|
||||
if (priv->ctrl.fname == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
|
||||
|
||||
/*
|
||||
* If firmware name changed, frees firmware. As free_firmware will
|
||||
@ -1406,10 +1407,15 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
|
||||
|
||||
if (priv->state == XC2028_NO_FIRMWARE) {
|
||||
if (!firmware_name[0])
|
||||
priv->fname = priv->ctrl.fname;
|
||||
priv->fname = kstrdup(p->fname, GFP_KERNEL);
|
||||
else
|
||||
priv->fname = firmware_name;
|
||||
|
||||
if (!priv->fname) {
|
||||
rc = -ENOMEM;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
rc = request_firmware_nowait(THIS_MODULE, 1,
|
||||
priv->fname,
|
||||
priv->i2c_props.adap->dev.parent,
|
||||
|
@ -375,7 +375,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
|
||||
nextbuf = NULL;
|
||||
spin_unlock_irqrestore(&queue->irqlock, flags);
|
||||
|
||||
buf->state = buf->error ? VB2_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
|
||||
buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
|
||||
vb2_set_plane_payload(&buf->buf, 0, buf->bytesused);
|
||||
vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE);
|
||||
|
||||
|
@ -795,7 +795,7 @@ static int mmc_test_nonblock_transfer(struct mmc_test_card *test,
|
||||
struct mmc_async_req *cur_areq = &test_areq[0].areq;
|
||||
struct mmc_async_req *other_areq = &test_areq[1].areq;
|
||||
int i;
|
||||
int ret;
|
||||
int ret = RESULT_OK;
|
||||
|
||||
test_areq[0].test = test;
|
||||
test_areq[1].test = test;
|
||||
|
@ -312,6 +312,9 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host)
|
||||
cmd0 = BF_SSP(cmd->opcode, CMD0_CMD);
|
||||
cmd1 = cmd->arg;
|
||||
|
||||
if (cmd->opcode == MMC_STOP_TRANSMISSION)
|
||||
cmd0 |= BM_SSP_CMD0_APPEND_8CYC;
|
||||
|
||||
if (host->sdio_irq_en) {
|
||||
ctrl0 |= BM_SSP_CTRL0_SDIO_IRQ_CHECK;
|
||||
cmd0 |= BM_SSP_CMD0_CONT_CLKING_EN | BM_SSP_CMD0_SLOW_CLKING_EN;
|
||||
@ -420,8 +423,7 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host)
|
||||
ssp->base + HW_SSP_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
if ((cmd->opcode == MMC_STOP_TRANSMISSION) ||
|
||||
(cmd->opcode == SD_IO_RW_EXTENDED))
|
||||
if (cmd->opcode == SD_IO_RW_EXTENDED)
|
||||
cmd0 |= BM_SSP_CMD0_APPEND_8CYC;
|
||||
|
||||
cmd1 = cmd->arg;
|
||||
|
@ -426,6 +426,9 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id
|
||||
struct ushc_data *ushc;
|
||||
int ret;
|
||||
|
||||
if (intf->cur_altsetting->desc.bNumEndpoints < 1)
|
||||
return -ENODEV;
|
||||
|
||||
mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev);
|
||||
if (mmc == NULL)
|
||||
return -ENOMEM;
|
||||
|
@ -541,7 +541,7 @@ config MTD_NAND_FSMC
|
||||
Flexible Static Memory Controller (FSMC)
|
||||
|
||||
config MTD_NAND_XWAY
|
||||
tristate "Support for NAND on Lantiq XWAY SoC"
|
||||
bool "Support for NAND on Lantiq XWAY SoC"
|
||||
depends on LANTIQ && SOC_TYPE_XWAY
|
||||
select MTD_NAND_PLATFORM
|
||||
help
|
||||
|
@ -57,13 +57,19 @@ void mlx4_cq_completion(struct mlx4_dev *dev, u32 cqn)
|
||||
{
|
||||
struct mlx4_cq *cq;
|
||||
|
||||
rcu_read_lock();
|
||||
cq = radix_tree_lookup(&mlx4_priv(dev)->cq_table.tree,
|
||||
cqn & (dev->caps.num_cqs - 1));
|
||||
rcu_read_unlock();
|
||||
|
||||
if (!cq) {
|
||||
mlx4_dbg(dev, "Completion event for bogus CQ %08x\n", cqn);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Acessing the CQ outside of rcu_read_lock is safe, because
|
||||
* the CQ is freed only after interrupt handling is completed.
|
||||
*/
|
||||
++cq->arm_sn;
|
||||
|
||||
cq->comp(cq);
|
||||
@ -74,23 +80,19 @@ void mlx4_cq_event(struct mlx4_dev *dev, u32 cqn, int event_type)
|
||||
struct mlx4_cq_table *cq_table = &mlx4_priv(dev)->cq_table;
|
||||
struct mlx4_cq *cq;
|
||||
|
||||
spin_lock(&cq_table->lock);
|
||||
|
||||
rcu_read_lock();
|
||||
cq = radix_tree_lookup(&cq_table->tree, cqn & (dev->caps.num_cqs - 1));
|
||||
if (cq)
|
||||
atomic_inc(&cq->refcount);
|
||||
|
||||
spin_unlock(&cq_table->lock);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (!cq) {
|
||||
mlx4_warn(dev, "Async event for bogus CQ %08x\n", cqn);
|
||||
mlx4_dbg(dev, "Async event for bogus CQ %08x\n", cqn);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Acessing the CQ outside of rcu_read_lock is safe, because
|
||||
* the CQ is freed only after interrupt handling is completed.
|
||||
*/
|
||||
cq->event(cq, event_type);
|
||||
|
||||
if (atomic_dec_and_test(&cq->refcount))
|
||||
complete(&cq->free);
|
||||
}
|
||||
|
||||
static int mlx4_SW2HW_CQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
|
||||
@ -261,9 +263,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
spin_lock_irq(&cq_table->lock);
|
||||
spin_lock(&cq_table->lock);
|
||||
err = radix_tree_insert(&cq_table->tree, cq->cqn, cq);
|
||||
spin_unlock_irq(&cq_table->lock);
|
||||
spin_unlock(&cq_table->lock);
|
||||
if (err)
|
||||
goto err_icm;
|
||||
|
||||
@ -303,9 +305,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
|
||||
return 0;
|
||||
|
||||
err_radix:
|
||||
spin_lock_irq(&cq_table->lock);
|
||||
spin_lock(&cq_table->lock);
|
||||
radix_tree_delete(&cq_table->tree, cq->cqn);
|
||||
spin_unlock_irq(&cq_table->lock);
|
||||
spin_unlock(&cq_table->lock);
|
||||
|
||||
err_icm:
|
||||
mlx4_cq_free_icm(dev, cq->cqn);
|
||||
@ -324,11 +326,11 @@ void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq)
|
||||
if (err)
|
||||
mlx4_warn(dev, "HW2SW_CQ failed (%d) for CQN %06x\n", err, cq->cqn);
|
||||
|
||||
synchronize_irq(priv->eq_table.eq[cq->vector].irq);
|
||||
|
||||
spin_lock_irq(&cq_table->lock);
|
||||
spin_lock(&cq_table->lock);
|
||||
radix_tree_delete(&cq_table->tree, cq->cqn);
|
||||
spin_unlock_irq(&cq_table->lock);
|
||||
spin_unlock(&cq_table->lock);
|
||||
|
||||
synchronize_irq(priv->eq_table.eq[cq->vector].irq);
|
||||
|
||||
if (atomic_dec_and_test(&cq->refcount))
|
||||
complete(&cq->free);
|
||||
|
@ -350,8 +350,14 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
|
||||
ring->cqn = priv->rx_cq[ring_ind].mcq.cqn;
|
||||
|
||||
ring->stride = stride;
|
||||
if (ring->stride <= TXBB_SIZE)
|
||||
if (ring->stride <= TXBB_SIZE) {
|
||||
/* Stamp first unused send wqe */
|
||||
__be32 *ptr = (__be32 *)ring->buf;
|
||||
__be32 stamp = cpu_to_be32(1 << STAMP_SHIFT);
|
||||
*ptr = stamp;
|
||||
/* Move pointer to start of rx section */
|
||||
ring->buf += TXBB_SIZE;
|
||||
}
|
||||
|
||||
ring->log_stride = ffs(ring->stride) - 1;
|
||||
ring->buf_size = ring->size * ring->stride;
|
||||
|
@ -2697,12 +2697,6 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
|
||||
spin_lock_init(&priv->lock);
|
||||
spin_lock_init(&priv->tx_lock);
|
||||
|
||||
ret = register_netdev(ndev);
|
||||
if (ret) {
|
||||
pr_err("%s: ERROR %i registering the device\n", __func__, ret);
|
||||
goto error_netdev_register;
|
||||
}
|
||||
|
||||
priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME);
|
||||
if (IS_ERR(priv->stmmac_clk)) {
|
||||
pr_warn("%s: warning: cannot get CSR clock\n", __func__);
|
||||
@ -2733,13 +2727,23 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
|
||||
}
|
||||
}
|
||||
|
||||
ret = register_netdev(ndev);
|
||||
if (ret) {
|
||||
netdev_err(priv->dev, "%s: ERROR %i registering the device\n",
|
||||
__func__, ret);
|
||||
goto error_netdev_register;
|
||||
}
|
||||
|
||||
return priv;
|
||||
|
||||
error_netdev_register:
|
||||
if (priv->pcs != STMMAC_PCS_RGMII &&
|
||||
priv->pcs != STMMAC_PCS_TBI &&
|
||||
priv->pcs != STMMAC_PCS_RTBI)
|
||||
stmmac_mdio_unregister(ndev);
|
||||
error_mdio_register:
|
||||
clk_put(priv->stmmac_clk);
|
||||
error_clk_get:
|
||||
unregister_netdev(ndev);
|
||||
error_netdev_register:
|
||||
netif_napi_del(&priv->napi);
|
||||
error_free_netdev:
|
||||
free_netdev(ndev);
|
||||
|
@ -474,7 +474,7 @@ void phy_stop_machine(struct phy_device *phydev)
|
||||
cancel_delayed_work_sync(&phydev->state_queue);
|
||||
|
||||
mutex_lock(&phydev->lock);
|
||||
if (phydev->state > PHY_UP)
|
||||
if (phydev->state > PHY_UP && phydev->state != PHY_HALTED)
|
||||
phydev->state = PHY_UP;
|
||||
mutex_unlock(&phydev->lock);
|
||||
|
||||
|
@ -1272,12 +1272,16 @@ static ssize_t tun_put_user(struct tun_struct *tun,
|
||||
{
|
||||
struct tun_pi pi = { 0, skb->protocol };
|
||||
ssize_t total = 0;
|
||||
int vnet_hdr_sz = 0;
|
||||
|
||||
if (tun->flags & TUN_VNET_HDR)
|
||||
vnet_hdr_sz = tun->vnet_hdr_sz;
|
||||
|
||||
if (!(tun->flags & TUN_NO_PI)) {
|
||||
if ((len -= sizeof(pi)) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (len < skb->len) {
|
||||
if (len < skb->len + vnet_hdr_sz) {
|
||||
/* Packet will be striped */
|
||||
pi.flags |= TUN_PKT_STRIP;
|
||||
}
|
||||
@ -1287,9 +1291,9 @@ static ssize_t tun_put_user(struct tun_struct *tun,
|
||||
total += sizeof(pi);
|
||||
}
|
||||
|
||||
if (tun->flags & TUN_VNET_HDR) {
|
||||
if (vnet_hdr_sz) {
|
||||
struct virtio_net_hdr gso = { 0 }; /* no info leak */
|
||||
if ((len -= tun->vnet_hdr_sz) < 0)
|
||||
if ((len -= vnet_hdr_sz) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (skb_is_gso(skb)) {
|
||||
@ -1332,7 +1336,7 @@ static ssize_t tun_put_user(struct tun_struct *tun,
|
||||
if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total,
|
||||
sizeof(gso))))
|
||||
return -EFAULT;
|
||||
total += tun->vnet_hdr_sz;
|
||||
total += vnet_hdr_sz;
|
||||
}
|
||||
|
||||
len = min_t(int, skb->len, len);
|
||||
|
@ -126,40 +126,61 @@ static void async_ctrl_callback(struct urb *urb)
|
||||
|
||||
static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
|
||||
{
|
||||
u8 *buf;
|
||||
int ret;
|
||||
|
||||
buf = kmalloc(size, GFP_NOIO);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0),
|
||||
PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0,
|
||||
indx, data, size, 1000);
|
||||
indx, buf, size, 1000);
|
||||
if (ret < 0)
|
||||
netif_dbg(pegasus, drv, pegasus->net,
|
||||
"%s returned %d\n", __func__, ret);
|
||||
else if (ret <= size)
|
||||
memcpy(data, buf, ret);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
|
||||
static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
|
||||
const void *data)
|
||||
{
|
||||
u8 *buf;
|
||||
int ret;
|
||||
|
||||
buf = kmemdup(data, size, GFP_NOIO);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
|
||||
PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0,
|
||||
indx, data, size, 100);
|
||||
indx, buf, size, 100);
|
||||
if (ret < 0)
|
||||
netif_dbg(pegasus, drv, pegasus->net,
|
||||
"%s returned %d\n", __func__, ret);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
|
||||
{
|
||||
u8 *buf;
|
||||
int ret;
|
||||
|
||||
buf = kmemdup(&data, 1, GFP_NOIO);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
|
||||
PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data,
|
||||
indx, &data, 1, 1000);
|
||||
indx, buf, 1, 1000);
|
||||
if (ret < 0)
|
||||
netif_dbg(pegasus, drv, pegasus->net,
|
||||
"%s returned %d\n", __func__, ret);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -156,16 +156,36 @@ static const char driver_name [] = "rtl8150";
|
||||
*/
|
||||
static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
|
||||
{
|
||||
return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
|
||||
RTL8150_REQ_GET_REGS, RTL8150_REQT_READ,
|
||||
indx, 0, data, size, 500);
|
||||
void *buf;
|
||||
int ret;
|
||||
|
||||
buf = kmalloc(size, GFP_NOIO);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
|
||||
RTL8150_REQ_GET_REGS, RTL8150_REQT_READ,
|
||||
indx, 0, buf, size, 500);
|
||||
if (ret > 0 && ret <= size)
|
||||
memcpy(data, buf, ret);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
|
||||
static int set_registers(rtl8150_t * dev, u16 indx, u16 size, const void *data)
|
||||
{
|
||||
return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
|
||||
RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE,
|
||||
indx, 0, data, size, 500);
|
||||
void *buf;
|
||||
int ret;
|
||||
|
||||
buf = kmemdup(data, size, GFP_NOIO);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
|
||||
RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE,
|
||||
indx, 0, buf, size, 500);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void async_set_reg_cb(struct urb *urb)
|
||||
|
@ -1386,7 +1386,7 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
|
||||
|
||||
if (data[IFLA_VXLAN_ID]) {
|
||||
__u32 id = nla_get_u32(data[IFLA_VXLAN_ID]);
|
||||
if (id >= VXLAN_VID_MASK)
|
||||
if (id >= VXLAN_N_VID)
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
|
@ -71,13 +71,13 @@
|
||||
#define AR9300_OTP_BASE \
|
||||
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000)
|
||||
#define AR9300_OTP_STATUS \
|
||||
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30018 : 0x15f18)
|
||||
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x31018 : 0x15f18)
|
||||
#define AR9300_OTP_STATUS_TYPE 0x7
|
||||
#define AR9300_OTP_STATUS_VALID 0x4
|
||||
#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
|
||||
#define AR9300_OTP_STATUS_SM_BUSY 0x1
|
||||
#define AR9300_OTP_READ_DATA \
|
||||
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3001c : 0x15f1c)
|
||||
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3101c : 0x15f1c)
|
||||
|
||||
enum targetPowerHTRates {
|
||||
HT_TARGET_RATE_0_8_16,
|
||||
|
@ -259,8 +259,13 @@ static int dlpar_add_phb(char *drc_name, struct device_node *dn)
|
||||
|
||||
static int dlpar_add_vio_slot(char *drc_name, struct device_node *dn)
|
||||
{
|
||||
if (vio_find_node(dn))
|
||||
struct vio_dev *vio_dev;
|
||||
|
||||
vio_dev = vio_find_node(dn);
|
||||
if (vio_dev) {
|
||||
put_device(&vio_dev->dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!vio_register_device_node(dn)) {
|
||||
printk(KERN_ERR
|
||||
@ -336,6 +341,9 @@ static int dlpar_remove_vio_slot(char *drc_name, struct device_node *dn)
|
||||
return -EINVAL;
|
||||
|
||||
vio_unregister_device(vio_dev);
|
||||
|
||||
put_device(&vio_dev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -153,23 +153,26 @@ static int goldfish_new_pdev(void)
|
||||
static irqreturn_t goldfish_pdev_bus_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
irqreturn_t ret = IRQ_NONE;
|
||||
|
||||
while (1) {
|
||||
u32 op = readl(pdev_bus_base + PDEV_BUS_OP);
|
||||
switch (op) {
|
||||
case PDEV_BUS_OP_DONE:
|
||||
return IRQ_NONE;
|
||||
|
||||
switch (op) {
|
||||
case PDEV_BUS_OP_REMOVE_DEV:
|
||||
goldfish_pdev_remove();
|
||||
ret = IRQ_HANDLED;
|
||||
break;
|
||||
|
||||
case PDEV_BUS_OP_ADD_DEV:
|
||||
goldfish_new_pdev();
|
||||
ret = IRQ_HANDLED;
|
||||
break;
|
||||
|
||||
case PDEV_BUS_OP_DONE:
|
||||
default:
|
||||
return ret;
|
||||
}
|
||||
ret = IRQ_HANDLED;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int goldfish_pdev_bus_probe(struct platform_device *pdev)
|
||||
|
@ -78,8 +78,8 @@ static int mfld_pb_probe(struct platform_device *pdev)
|
||||
|
||||
input_set_capability(input, EV_KEY, KEY_POWER);
|
||||
|
||||
error = request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_NO_SUSPEND,
|
||||
DRIVER_NAME, input);
|
||||
error = request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_NO_SUSPEND |
|
||||
IRQF_ONESHOT, DRIVER_NAME, input);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev, "Unable to request irq %d for mfld power"
|
||||
"button\n", irq);
|
||||
|
@ -142,11 +142,11 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq)
|
||||
struct qdio_q *q;
|
||||
int i;
|
||||
|
||||
for_each_input_queue(irq, q, i) {
|
||||
if (!references_shared_dsci(irq) &&
|
||||
has_multiple_inq_on_dsci(irq))
|
||||
xchg(q->irq_ptr->dsci, 0);
|
||||
if (!references_shared_dsci(irq) &&
|
||||
has_multiple_inq_on_dsci(irq))
|
||||
xchg(irq->dsci, 0);
|
||||
|
||||
for_each_input_queue(irq, q, i) {
|
||||
if (q->u.in.queue_start_poll) {
|
||||
/* skip if polling is enabled or already in work */
|
||||
if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
|
||||
|
@ -282,11 +282,12 @@ void zfcp_dbf_rec_trig(char *tag, struct zfcp_adapter *adapter,
|
||||
|
||||
|
||||
/**
|
||||
* zfcp_dbf_rec_run - trace event related to running recovery
|
||||
* zfcp_dbf_rec_run_lvl - trace event related to running recovery
|
||||
* @level: trace level to be used for event
|
||||
* @tag: identifier for event
|
||||
* @erp: erp_action running
|
||||
*/
|
||||
void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp)
|
||||
void zfcp_dbf_rec_run_lvl(int level, char *tag, struct zfcp_erp_action *erp)
|
||||
{
|
||||
struct zfcp_dbf *dbf = erp->adapter->dbf;
|
||||
struct zfcp_dbf_rec *rec = &dbf->rec_buf;
|
||||
@ -312,10 +313,20 @@ void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp)
|
||||
else
|
||||
rec->u.run.rec_count = atomic_read(&erp->adapter->erp_counter);
|
||||
|
||||
debug_event(dbf->rec, 1, rec, sizeof(*rec));
|
||||
debug_event(dbf->rec, level, rec, sizeof(*rec));
|
||||
spin_unlock_irqrestore(&dbf->rec_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_dbf_rec_run - trace event related to running recovery
|
||||
* @tag: identifier for event
|
||||
* @erp: erp_action running
|
||||
*/
|
||||
void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp)
|
||||
{
|
||||
zfcp_dbf_rec_run_lvl(1, tag, erp);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_dbf_rec_run_wka - trace wka port event with info like running recovery
|
||||
* @tag: identifier for event
|
||||
|
@ -2,7 +2,7 @@
|
||||
* zfcp device driver
|
||||
* debug feature declarations
|
||||
*
|
||||
* Copyright IBM Corp. 2008, 2015
|
||||
* Copyright IBM Corp. 2008, 2016
|
||||
*/
|
||||
|
||||
#ifndef ZFCP_DBF_H
|
||||
@ -283,6 +283,30 @@ struct zfcp_dbf {
|
||||
struct zfcp_dbf_scsi scsi_buf;
|
||||
};
|
||||
|
||||
/**
|
||||
* zfcp_dbf_hba_fsf_resp_suppress - true if we should not trace by default
|
||||
* @req: request that has been completed
|
||||
*
|
||||
* Returns true if FCP response with only benign residual under count.
|
||||
*/
|
||||
static inline
|
||||
bool zfcp_dbf_hba_fsf_resp_suppress(struct zfcp_fsf_req *req)
|
||||
{
|
||||
struct fsf_qtcb *qtcb = req->qtcb;
|
||||
u32 fsf_stat = qtcb->header.fsf_status;
|
||||
struct fcp_resp *fcp_rsp;
|
||||
u8 rsp_flags, fr_status;
|
||||
|
||||
if (qtcb->prefix.qtcb_type != FSF_IO_COMMAND)
|
||||
return false; /* not an FCP response */
|
||||
fcp_rsp = (struct fcp_resp *)&qtcb->bottom.io.fcp_rsp;
|
||||
rsp_flags = fcp_rsp->fr_flags;
|
||||
fr_status = fcp_rsp->fr_status;
|
||||
return (fsf_stat == FSF_FCP_RSP_AVAILABLE) &&
|
||||
(rsp_flags == FCP_RESID_UNDER) &&
|
||||
(fr_status == SAM_STAT_GOOD);
|
||||
}
|
||||
|
||||
static inline
|
||||
void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req)
|
||||
{
|
||||
@ -304,7 +328,9 @@ void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req)
|
||||
zfcp_dbf_hba_fsf_resp("fs_perr", 1, req);
|
||||
|
||||
} else if (qtcb->header.fsf_status != FSF_GOOD) {
|
||||
zfcp_dbf_hba_fsf_resp("fs_ferr", 1, req);
|
||||
zfcp_dbf_hba_fsf_resp("fs_ferr",
|
||||
zfcp_dbf_hba_fsf_resp_suppress(req)
|
||||
? 5 : 1, req);
|
||||
|
||||
} else if ((req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
|
||||
(req->fsf_command == FSF_QTCB_OPEN_LUN)) {
|
||||
@ -388,4 +414,15 @@ void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag)
|
||||
_zfcp_dbf_scsi(tmp_tag, 1, scmnd, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_dbf_scsi_nullcmnd() - trace NULLify of SCSI command in dev/tgt-reset.
|
||||
* @scmnd: SCSI command that was NULLified.
|
||||
* @fsf_req: request that owned @scmnd.
|
||||
*/
|
||||
static inline void zfcp_dbf_scsi_nullcmnd(struct scsi_cmnd *scmnd,
|
||||
struct zfcp_fsf_req *fsf_req)
|
||||
{
|
||||
_zfcp_dbf_scsi("scfc__1", 3, scmnd, fsf_req);
|
||||
}
|
||||
|
||||
#endif /* ZFCP_DBF_H */
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Error Recovery Procedures (ERP).
|
||||
*
|
||||
* Copyright IBM Corp. 2002, 2015
|
||||
* Copyright IBM Corp. 2002, 2016
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "zfcp"
|
||||
@ -1212,6 +1212,62 @@ static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_erp_try_rport_unblock - unblock rport if no more/new recovery
|
||||
* @port: zfcp_port whose fc_rport we should try to unblock
|
||||
*/
|
||||
static void zfcp_erp_try_rport_unblock(struct zfcp_port *port)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct zfcp_adapter *adapter = port->adapter;
|
||||
int port_status;
|
||||
struct Scsi_Host *shost = adapter->scsi_host;
|
||||
struct scsi_device *sdev;
|
||||
|
||||
write_lock_irqsave(&adapter->erp_lock, flags);
|
||||
port_status = atomic_read(&port->status);
|
||||
if ((port_status & ZFCP_STATUS_COMMON_UNBLOCKED) == 0 ||
|
||||
(port_status & (ZFCP_STATUS_COMMON_ERP_INUSE |
|
||||
ZFCP_STATUS_COMMON_ERP_FAILED)) != 0) {
|
||||
/* new ERP of severity >= port triggered elsewhere meanwhile or
|
||||
* local link down (adapter erp_failed but not clear unblock)
|
||||
*/
|
||||
zfcp_dbf_rec_run_lvl(4, "ertru_p", &port->erp_action);
|
||||
write_unlock_irqrestore(&adapter->erp_lock, flags);
|
||||
return;
|
||||
}
|
||||
spin_lock(shost->host_lock);
|
||||
__shost_for_each_device(sdev, shost) {
|
||||
struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev);
|
||||
int lun_status;
|
||||
|
||||
if (zsdev->port != port)
|
||||
continue;
|
||||
/* LUN under port of interest */
|
||||
lun_status = atomic_read(&zsdev->status);
|
||||
if ((lun_status & ZFCP_STATUS_COMMON_ERP_FAILED) != 0)
|
||||
continue; /* unblock rport despite failed LUNs */
|
||||
/* LUN recovery not given up yet [maybe follow-up pending] */
|
||||
if ((lun_status & ZFCP_STATUS_COMMON_UNBLOCKED) == 0 ||
|
||||
(lun_status & ZFCP_STATUS_COMMON_ERP_INUSE) != 0) {
|
||||
/* LUN blocked:
|
||||
* not yet unblocked [LUN recovery pending]
|
||||
* or meanwhile blocked [new LUN recovery triggered]
|
||||
*/
|
||||
zfcp_dbf_rec_run_lvl(4, "ertru_l", &zsdev->erp_action);
|
||||
spin_unlock(shost->host_lock);
|
||||
write_unlock_irqrestore(&adapter->erp_lock, flags);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* now port has no child or all children have completed recovery,
|
||||
* and no ERP of severity >= port was meanwhile triggered elsewhere
|
||||
*/
|
||||
zfcp_scsi_schedule_rport_register(port);
|
||||
spin_unlock(shost->host_lock);
|
||||
write_unlock_irqrestore(&adapter->erp_lock, flags);
|
||||
}
|
||||
|
||||
static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
|
||||
{
|
||||
struct zfcp_adapter *adapter = act->adapter;
|
||||
@ -1222,6 +1278,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
|
||||
case ZFCP_ERP_ACTION_REOPEN_LUN:
|
||||
if (!(act->status & ZFCP_STATUS_ERP_NO_REF))
|
||||
scsi_device_put(sdev);
|
||||
zfcp_erp_try_rport_unblock(port);
|
||||
break;
|
||||
|
||||
case ZFCP_ERP_ACTION_REOPEN_PORT:
|
||||
@ -1232,7 +1289,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
|
||||
*/
|
||||
if (act->step != ZFCP_ERP_STEP_UNINITIALIZED)
|
||||
if (result == ZFCP_ERP_SUCCEEDED)
|
||||
zfcp_scsi_schedule_rport_register(port);
|
||||
zfcp_erp_try_rport_unblock(port);
|
||||
/* fall through */
|
||||
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
|
||||
put_device(&port->dev);
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* External function declarations.
|
||||
*
|
||||
* Copyright IBM Corp. 2002, 2015
|
||||
* Copyright IBM Corp. 2002, 2016
|
||||
*/
|
||||
|
||||
#ifndef ZFCP_EXT_H
|
||||
@ -49,6 +49,8 @@ extern void zfcp_dbf_adapter_unregister(struct zfcp_adapter *);
|
||||
extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *,
|
||||
struct zfcp_port *, struct scsi_device *, u8, u8);
|
||||
extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *);
|
||||
extern void zfcp_dbf_rec_run_lvl(int level, char *tag,
|
||||
struct zfcp_erp_action *erp);
|
||||
extern void zfcp_dbf_rec_run_wka(char *, struct zfcp_fc_wka_port *, u64);
|
||||
extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *);
|
||||
extern void zfcp_dbf_hba_fsf_res(char *, int, struct zfcp_fsf_req *);
|
||||
|
@ -1607,7 +1607,7 @@ out:
|
||||
int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
|
||||
{
|
||||
struct zfcp_qdio *qdio = wka_port->adapter->qdio;
|
||||
struct zfcp_fsf_req *req = NULL;
|
||||
struct zfcp_fsf_req *req;
|
||||
int retval = -EIO;
|
||||
|
||||
spin_lock_irq(&qdio->req_q_lock);
|
||||
@ -1636,7 +1636,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
|
||||
zfcp_fsf_req_free(req);
|
||||
out:
|
||||
spin_unlock_irq(&qdio->req_q_lock);
|
||||
if (req && !IS_ERR(req))
|
||||
if (!retval)
|
||||
zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id);
|
||||
return retval;
|
||||
}
|
||||
@ -1662,7 +1662,7 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
|
||||
int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
|
||||
{
|
||||
struct zfcp_qdio *qdio = wka_port->adapter->qdio;
|
||||
struct zfcp_fsf_req *req = NULL;
|
||||
struct zfcp_fsf_req *req;
|
||||
int retval = -EIO;
|
||||
|
||||
spin_lock_irq(&qdio->req_q_lock);
|
||||
@ -1691,7 +1691,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
|
||||
zfcp_fsf_req_free(req);
|
||||
out:
|
||||
spin_unlock_irq(&qdio->req_q_lock);
|
||||
if (req && !IS_ERR(req))
|
||||
if (!retval)
|
||||
zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id);
|
||||
return retval;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Interface to the FSF support functions.
|
||||
*
|
||||
* Copyright IBM Corp. 2002, 2015
|
||||
* Copyright IBM Corp. 2002, 2016
|
||||
*/
|
||||
|
||||
#ifndef FSF_H
|
||||
@ -86,6 +86,7 @@
|
||||
#define FSF_APP_TAG_CHECK_FAILURE 0x00000082
|
||||
#define FSF_REF_TAG_CHECK_FAILURE 0x00000083
|
||||
#define FSF_ADAPTER_STATUS_AVAILABLE 0x000000AD
|
||||
#define FSF_FCP_RSP_AVAILABLE 0x000000AF
|
||||
#define FSF_UNKNOWN_COMMAND 0x000000E2
|
||||
#define FSF_UNKNOWN_OP_SUBTYPE 0x000000E3
|
||||
#define FSF_INVALID_COMMAND_OPTION 0x000000E5
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Data structure and helper functions for tracking pending FSF
|
||||
* requests.
|
||||
*
|
||||
* Copyright IBM Corp. 2009
|
||||
* Copyright IBM Corp. 2009, 2016
|
||||
*/
|
||||
|
||||
#ifndef ZFCP_REQLIST_H
|
||||
@ -180,4 +180,32 @@ static inline void zfcp_reqlist_move(struct zfcp_reqlist *rl,
|
||||
spin_unlock_irqrestore(&rl->lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_reqlist_apply_for_all() - apply a function to every request.
|
||||
* @rl: the requestlist that contains the target requests.
|
||||
* @f: the function to apply to each request; the first parameter of the
|
||||
* function will be the target-request; the second parameter is the same
|
||||
* pointer as given with the argument @data.
|
||||
* @data: freely chosen argument; passed through to @f as second parameter.
|
||||
*
|
||||
* Uses :c:macro:`list_for_each_entry` to iterate over the lists in the hash-
|
||||
* table (not a 'safe' variant, so don't modify the list).
|
||||
*
|
||||
* Holds @rl->lock over the entire request-iteration.
|
||||
*/
|
||||
static inline void
|
||||
zfcp_reqlist_apply_for_all(struct zfcp_reqlist *rl,
|
||||
void (*f)(struct zfcp_fsf_req *, void *), void *data)
|
||||
{
|
||||
struct zfcp_fsf_req *req;
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
|
||||
spin_lock_irqsave(&rl->lock, flags);
|
||||
for (i = 0; i < ZFCP_REQ_LIST_BUCKETS; i++)
|
||||
list_for_each_entry(req, &rl->buckets[i], list)
|
||||
f(req, data);
|
||||
spin_unlock_irqrestore(&rl->lock, flags);
|
||||
}
|
||||
|
||||
#endif /* ZFCP_REQLIST_H */
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Interface to Linux SCSI midlayer.
|
||||
*
|
||||
* Copyright IBM Corp. 2002, 2015
|
||||
* Copyright IBM Corp. 2002, 2016
|
||||
*/
|
||||
|
||||
#define KMSG_COMPONENT "zfcp"
|
||||
@ -109,9 +109,7 @@ int zfcp_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scpnt)
|
||||
}
|
||||
|
||||
if (unlikely(!(status & ZFCP_STATUS_COMMON_UNBLOCKED))) {
|
||||
/* This could be either
|
||||
* open LUN pending: this is temporary, will result in
|
||||
* open LUN or ERP_FAILED, so retry command
|
||||
/* This could be
|
||||
* call to rport_delete pending: mimic retry from
|
||||
* fc_remote_port_chkready until rport is BLOCKED
|
||||
*/
|
||||
@ -230,6 +228,57 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct zfcp_scsi_req_filter {
|
||||
u8 tmf_scope;
|
||||
u32 lun_handle;
|
||||
u32 port_handle;
|
||||
};
|
||||
|
||||
static void zfcp_scsi_forget_cmnd(struct zfcp_fsf_req *old_req, void *data)
|
||||
{
|
||||
struct zfcp_scsi_req_filter *filter =
|
||||
(struct zfcp_scsi_req_filter *)data;
|
||||
|
||||
/* already aborted - prevent side-effects - or not a SCSI command */
|
||||
if (old_req->data == NULL || old_req->fsf_command != FSF_QTCB_FCP_CMND)
|
||||
return;
|
||||
|
||||
/* (tmf_scope == FCP_TMF_TGT_RESET || tmf_scope == FCP_TMF_LUN_RESET) */
|
||||
if (old_req->qtcb->header.port_handle != filter->port_handle)
|
||||
return;
|
||||
|
||||
if (filter->tmf_scope == FCP_TMF_LUN_RESET &&
|
||||
old_req->qtcb->header.lun_handle != filter->lun_handle)
|
||||
return;
|
||||
|
||||
zfcp_dbf_scsi_nullcmnd((struct scsi_cmnd *)old_req->data, old_req);
|
||||
old_req->data = NULL;
|
||||
}
|
||||
|
||||
static void zfcp_scsi_forget_cmnds(struct zfcp_scsi_dev *zsdev, u8 tm_flags)
|
||||
{
|
||||
struct zfcp_adapter *adapter = zsdev->port->adapter;
|
||||
struct zfcp_scsi_req_filter filter = {
|
||||
.tmf_scope = FCP_TMF_TGT_RESET,
|
||||
.port_handle = zsdev->port->handle,
|
||||
};
|
||||
unsigned long flags;
|
||||
|
||||
if (tm_flags == FCP_TMF_LUN_RESET) {
|
||||
filter.tmf_scope = FCP_TMF_LUN_RESET;
|
||||
filter.lun_handle = zsdev->lun_handle;
|
||||
}
|
||||
|
||||
/*
|
||||
* abort_lock secures against other processings - in the abort-function
|
||||
* and normal cmnd-handler - of (struct zfcp_fsf_req *)->data
|
||||
*/
|
||||
write_lock_irqsave(&adapter->abort_lock, flags);
|
||||
zfcp_reqlist_apply_for_all(adapter->req_list, zfcp_scsi_forget_cmnd,
|
||||
&filter);
|
||||
write_unlock_irqrestore(&adapter->abort_lock, flags);
|
||||
}
|
||||
|
||||
static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
|
||||
{
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
|
||||
@ -262,8 +311,10 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
|
||||
if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
|
||||
zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags);
|
||||
retval = FAILED;
|
||||
} else
|
||||
} else {
|
||||
zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags);
|
||||
zfcp_scsi_forget_cmnds(zfcp_sdev, tm_flags);
|
||||
}
|
||||
|
||||
zfcp_fsf_req_free(fsf_req);
|
||||
return retval;
|
||||
|
@ -358,17 +358,24 @@ static int aac_src_check_health(struct aac_dev *dev)
|
||||
{
|
||||
u32 status = src_readl(dev, MUnit.OMR);
|
||||
|
||||
/*
|
||||
* Check to see if the board failed any self tests.
|
||||
*/
|
||||
if (unlikely(status & SELF_TEST_FAILED))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Check to see if the board panic'd.
|
||||
*/
|
||||
if (unlikely(status & KERNEL_PANIC))
|
||||
return (status >> 16) & 0xFF;
|
||||
goto err_blink;
|
||||
|
||||
/*
|
||||
* Check to see if the board failed any self tests.
|
||||
*/
|
||||
if (unlikely(status & SELF_TEST_FAILED))
|
||||
goto err_out;
|
||||
|
||||
/*
|
||||
* Check to see if the board failed any self tests.
|
||||
*/
|
||||
if (unlikely(status & MONITOR_PANIC))
|
||||
goto err_out;
|
||||
|
||||
/*
|
||||
* Wait for the adapter to be up and running.
|
||||
*/
|
||||
@ -378,6 +385,12 @@ static int aac_src_check_health(struct aac_dev *dev)
|
||||
* Everything is OK
|
||||
*/
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
return -1;
|
||||
|
||||
err_blink:
|
||||
return (status > 16) & 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,7 +219,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
|
||||
task->num_scatter = qc->n_elem;
|
||||
} else {
|
||||
for_each_sg(qc->sg, sg, qc->n_elem, si)
|
||||
xfer += sg->length;
|
||||
xfer += sg_dma_len(sg);
|
||||
|
||||
task->total_xfer_len = xfer;
|
||||
task->num_scatter = si;
|
||||
|
@ -621,7 +621,7 @@ static void mvs_94xx_command_active(struct mvs_info *mvi, u32 slot_idx)
|
||||
{
|
||||
u32 tmp;
|
||||
tmp = mvs_cr32(mvi, MVS_COMMAND_ACTIVE+(slot_idx >> 3));
|
||||
if (tmp && 1 << (slot_idx % 32)) {
|
||||
if (tmp & 1 << (slot_idx % 32)) {
|
||||
mv_printk("command active %08X, slot [%x].\n", tmp, slot_idx);
|
||||
mvs_cw32(mvi, MVS_COMMAND_ACTIVE + (slot_idx >> 3),
|
||||
1 << (slot_idx % 32));
|
||||
|
@ -185,7 +185,7 @@ static ssize_t ad7606_store_oversampling_ratio(struct device *dev,
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
gpio_set_value(st->pdata->gpio_os0, (ret >> 0) & 1);
|
||||
gpio_set_value(st->pdata->gpio_os1, (ret >> 1) & 1);
|
||||
gpio_set_value(st->pdata->gpio_os1, (ret >> 2) & 1);
|
||||
gpio_set_value(st->pdata->gpio_os2, (ret >> 2) & 1);
|
||||
st->oversampling = lval;
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
|
||||
|
@ -133,7 +133,8 @@ static int hostap_disable_hostapd(struct vnt_private *pDevice, int rtnl_locked)
|
||||
DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n",
|
||||
pDevice->dev->name, pDevice->apdev->name);
|
||||
}
|
||||
free_netdev(pDevice->apdev);
|
||||
if (pDevice->apdev)
|
||||
free_netdev(pDevice->apdev);
|
||||
pDevice->apdev = NULL;
|
||||
pDevice->bEnable8021x = false;
|
||||
pDevice->bEnableHostWEP = false;
|
||||
|
@ -256,7 +256,6 @@ err_out:
|
||||
iscsi_release_param_list(tpg->param_list);
|
||||
tpg->param_list = NULL;
|
||||
}
|
||||
kfree(tpg);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -989,7 +989,7 @@ static int usbtmc_probe(struct usb_interface *intf,
|
||||
|
||||
dev_dbg(&intf->dev, "%s called\n", __func__);
|
||||
|
||||
data = kmalloc(sizeof(struct usbtmc_device_data), GFP_KERNEL);
|
||||
data = kzalloc(sizeof(struct usbtmc_device_data), GFP_KERNEL);
|
||||
if (!data) {
|
||||
dev_err(&intf->dev, "Unable to allocate kernel memory\n");
|
||||
return -ENOMEM;
|
||||
@ -1035,6 +1035,12 @@ static int usbtmc_probe(struct usb_interface *intf,
|
||||
}
|
||||
}
|
||||
|
||||
if (!data->bulk_out || !data->bulk_in) {
|
||||
dev_err(&intf->dev, "bulk endpoints not found\n");
|
||||
retcode = -ENODEV;
|
||||
goto err_put;
|
||||
}
|
||||
|
||||
retcode = get_capabilities(data);
|
||||
if (retcode)
|
||||
dev_err(&intf->dev, "can't read capabilities\n");
|
||||
@ -1058,6 +1064,7 @@ static int usbtmc_probe(struct usb_interface *intf,
|
||||
error_register:
|
||||
sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp);
|
||||
sysfs_remove_group(&intf->dev.kobj, &data_attr_grp);
|
||||
err_put:
|
||||
kref_put(&data->kref, usbtmc_delete);
|
||||
return retcode;
|
||||
}
|
||||
|
@ -207,6 +207,16 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
|
||||
if (ifp->desc.bNumEndpoints >= num_ep)
|
||||
goto skip_to_next_endpoint_or_interface_descriptor;
|
||||
|
||||
/* Check for duplicate endpoint addresses */
|
||||
for (i = 0; i < ifp->desc.bNumEndpoints; ++i) {
|
||||
if (ifp->endpoint[i].desc.bEndpointAddress ==
|
||||
d->bEndpointAddress) {
|
||||
dev_warn(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n",
|
||||
cfgno, inum, asnum, d->bEndpointAddress);
|
||||
goto skip_to_next_endpoint_or_interface_descriptor;
|
||||
}
|
||||
}
|
||||
|
||||
endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints];
|
||||
++ifp->desc.bNumEndpoints;
|
||||
|
||||
|
@ -326,11 +326,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
|
||||
if (req->request.status == -EINPROGRESS)
|
||||
req->request.status = status;
|
||||
|
||||
if (dwc->ep0_bounced && dep->number == 0)
|
||||
if (dwc->ep0_bounced && dep->number <= 1)
|
||||
dwc->ep0_bounced = false;
|
||||
else
|
||||
usb_gadget_unmap_request(&dwc->gadget, &req->request,
|
||||
req->direction);
|
||||
|
||||
usb_gadget_unmap_request(&dwc->gadget, &req->request,
|
||||
req->direction);
|
||||
|
||||
dev_dbg(dwc->dev, "request %pK from %s completed %d/%d ===> %d\n",
|
||||
req, dep->name, req->request.actual,
|
||||
|
@ -1441,9 +1441,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||
value = min(w_length, (u16) 1);
|
||||
break;
|
||||
|
||||
/* function drivers must handle get/set altsetting; if there's
|
||||
* no get() method, we know only altsetting zero works.
|
||||
*/
|
||||
/* function drivers must handle get/set altsetting */
|
||||
case USB_REQ_SET_INTERFACE:
|
||||
if (ctrl->bRequestType != USB_RECIP_INTERFACE)
|
||||
goto unknown;
|
||||
@ -1452,7 +1450,13 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
|
||||
f = cdev->config->interface[intf];
|
||||
if (!f)
|
||||
break;
|
||||
if (w_value && !f->set_alt)
|
||||
|
||||
/*
|
||||
* If there's no get_alt() method, we know only altsetting zero
|
||||
* works. There is no need to check if set_alt() is not NULL
|
||||
* as we check this in usb_add_function().
|
||||
*/
|
||||
if (w_value && !f->get_alt)
|
||||
break;
|
||||
/*
|
||||
* We put interfaces in default settings (alt 0)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user