aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/acpi/acpi_numa.h4
-rw-r--r--include/acpi/cppc_acpi.h7
-rw-r--r--include/acpi/pcc.h29
-rw-r--r--include/acpi/platform/aclinux.h4
-rw-r--r--include/acpi/processor.h27
-rw-r--r--include/acpi/video.h2
-rw-r--r--include/asm-generic/atomic-long.h58
-rw-r--r--include/asm-generic/atomic.h47
-rw-r--r--include/asm-generic/atomic64.h15
-rw-r--r--include/asm-generic/barrier.h41
-rw-r--r--include/asm-generic/cputime_nsecs.h2
-rw-r--r--include/asm-generic/io.h71
-rw-r--r--include/asm-generic/iomap.h8
-rw-r--r--include/asm-generic/mutex-dec.h2
-rw-r--r--include/asm-generic/mutex-xchg.h6
-rw-r--r--include/asm-generic/qspinlock.h5
-rw-r--r--include/asm-generic/rwsem.h22
-rw-r--r--include/asm-generic/tlb.h59
-rw-r--r--include/asm-generic/vmlinux.lds.h10
-rw-r--r--include/clocksource/timer-sp804.h8
-rw-r--r--include/crypto/aead.h12
-rw-r--r--include/crypto/algapi.h4
-rw-r--r--include/crypto/chacha20.h1
-rw-r--r--include/crypto/cryptd.h5
-rw-r--r--include/crypto/dh.h29
-rw-r--r--include/crypto/drbg.h12
-rw-r--r--include/crypto/ecdh.h30
-rw-r--r--include/crypto/internal/aead.h21
-rw-r--r--include/crypto/internal/geniv.h2
-rw-r--r--include/crypto/internal/hash.h12
-rw-r--r--include/crypto/internal/kpp.h64
-rw-r--r--include/crypto/internal/rsa.h42
-rw-r--r--include/crypto/internal/skcipher.h122
-rw-r--r--include/crypto/kpp.h330
-rw-r--r--include/crypto/mcryptd.h8
-rw-r--r--include/crypto/null.h12
-rw-r--r--include/crypto/scatterwalk.h48
-rw-r--r--include/crypto/sha3.h29
-rw-r--r--include/crypto/skcipher.h207
-rw-r--r--include/dt-bindings/leds/leds-pca9532.h18
-rw-r--r--include/dt-bindings/pinctrl/stm32f746-pinfunc.h1324
-rw-r--r--include/linux/acpi.h79
-rw-r--r--include/linux/alarmtimer.h6
-rw-r--r--include/linux/ata.h41
-rw-r--r--include/linux/ath9k_platform.h1
-rw-r--r--include/linux/atomic.h747
-rw-r--r--include/linux/backing-dev.h2
-rw-r--r--include/linux/balloon_compaction.h51
-rw-r--r--include/linux/bcma/bcma_driver_chipcommon.h3
-rw-r--r--include/linux/bio.h85
-rw-r--r--include/linux/bitmap.h4
-rw-r--r--include/linux/blk-cgroup.h13
-rw-r--r--include/linux/blk-mq.h5
-rw-r--r--include/linux/blk_types.h95
-rw-r--r--include/linux/blkdev.h86
-rw-r--r--include/linux/blktrace_api.h2
-rw-r--r--include/linux/bpf.h45
-rw-r--r--include/linux/buffer_head.h14
-rw-r--r--include/linux/bvec.h96
-rw-r--r--include/linux/cec-funcs.h1899
-rw-r--r--include/linux/cec.h1011
-rw-r--r--include/linux/cgroup.h1
-rw-r--r--include/linux/clk.h4
-rw-r--r--include/linux/clocksource.h2
-rw-r--r--include/linux/compaction.h34
-rw-r--r--include/linux/compiler.h23
-rw-r--r--include/linux/console.h13
-rw-r--r--include/linux/console_struct.h38
-rw-r--r--include/linux/context_tracking.h15
-rw-r--r--include/linux/cpufreq.h289
-rw-r--r--include/linux/cpuidle.h18
-rw-r--r--include/linux/crypto.h31
-rw-r--r--include/linux/dax.h5
-rw-r--r--include/linux/dcache.h1
-rw-r--r--include/linux/debugobjects.h2
-rw-r--r--include/linux/device-mapper.h26
-rw-r--r--include/linux/dm-io.h3
-rw-r--r--include/linux/dma/hsu.h14
-rw-r--r--include/linux/drbd.h10
-rw-r--r--include/linux/drbd_genl.h7
-rw-r--r--include/linux/drbd_limits.h15
-rw-r--r--include/linux/efi.h200
-rw-r--r--include/linux/elevator.h15
-rw-r--r--include/linux/etherdevice.h23
-rw-r--r--include/linux/exportfs.h16
-rw-r--r--include/linux/extcon.h115
-rw-r--r--include/linux/extcon/extcon-adc-jack.h2
-rw-r--r--include/linux/fence.h2
-rw-r--r--include/linux/filter.h18
-rw-r--r--include/linux/frontswap.h34
-rw-r--r--include/linux/fs.h52
-rw-r--r--include/linux/fsnotify.h12
-rw-r--r--include/linux/fsnotify_backend.h20
-rw-r--r--include/linux/ftrace.h12
-rw-r--r--include/linux/genhd.h8
-rw-r--r--include/linux/gfp.h24
-rw-r--r--include/linux/hsi/hsi.h2
-rw-r--r--include/linux/huge_mm.h38
-rw-r--r--include/linux/i2c-smbus.h29
-rw-r--r--include/linux/i2c.h15
-rw-r--r--include/linux/icmpv6.h5
-rw-r--r--include/linux/ieee80211.h32
-rw-r--r--include/linux/ieee802154.h29
-rw-r--r--include/linux/iio/common/st_sensors.h6
-rw-r--r--include/linux/iio/iio.h22
-rw-r--r--include/linux/iio/sw_device.h70
-rw-r--r--include/linux/input.h2
-rw-r--r--include/linux/input/touchscreen.h21
-rw-r--r--include/linux/interrupt.h8
-rw-r--r--include/linux/iomap.h70
-rw-r--r--include/linux/ipmi.h2
-rw-r--r--include/linux/ipv6.h7
-rw-r--r--include/linux/irq.h16
-rw-r--r--include/linux/irqchip/arm-gic-v3.h4
-rw-r--r--include/linux/irqchip/arm-gic.h11
-rw-r--r--include/linux/irqdomain.h12
-rw-r--r--include/linux/jbd2.h23
-rw-r--r--include/linux/kasan.h2
-rw-r--r--include/linux/kdb.h2
-rw-r--r--include/linux/kernel.h1
-rw-r--r--include/linux/kernel_stat.h1
-rw-r--r--include/linux/khugepaged.h5
-rw-r--r--include/linux/ksm.h3
-rw-r--r--include/linux/leds-lp3952.h125
-rw-r--r--include/linux/leds-pca9532.h9
-rw-r--r--include/linux/leds.h14
-rw-r--r--include/linux/libata.h60
-rw-r--r--include/linux/libnvdimm.h24
-rw-r--r--include/linux/lightnvm.h34
-rw-r--r--include/linux/list.h10
-rw-r--r--include/linux/mdio-mux.h4
-rw-r--r--include/linux/memblock.h21
-rw-r--r--include/linux/memcontrol.h173
-rw-r--r--include/linux/memory_hotplug.h2
-rw-r--r--include/linux/memremap.h2
-rw-r--r--include/linux/mfd/rn5t618.h13
-rw-r--r--include/linux/mfd/tps65217.h1
-rw-r--r--include/linux/mfd/tps65218.h2
-rw-r--r--include/linux/micrel_phy.h1
-rw-r--r--include/linux/migrate.h17
-rw-r--r--include/linux/mlx4/device.h2
-rw-r--r--include/linux/mlx4/qp.h18
-rw-r--r--include/linux/mlx5/device.h11
-rw-r--r--include/linux/mlx5/driver.h48
-rw-r--r--include/linux/mlx5/fs.h12
-rw-r--r--include/linux/mlx5/mlx5_ifc.h293
-rw-r--r--include/linux/mlx5/port.h16
-rw-r--r--include/linux/mlx5/vport.h2
-rw-r--r--include/linux/mm.h70
-rw-r--r--include/linux/mm_inline.h19
-rw-r--r--include/linux/mm_types.h78
-rw-r--r--include/linux/mmdebug.h2
-rw-r--r--include/linux/mmzone.h176
-rw-r--r--include/linux/mod_devicetable.h16
-rw-r--r--include/linux/mpi.h3
-rw-r--r--include/linux/mroute.h1
-rw-r--r--include/linux/mroute6.h1
-rw-r--r--include/linux/msi.h8
-rw-r--r--include/linux/nd.h3
-rw-r--r--include/linux/net.h1
-rw-r--r--include/linux/netdev_features.h7
-rw-r--r--include/linux/netdevice.h156
-rw-r--r--include/linux/netfilter/x_tables.h8
-rw-r--r--include/linux/netfilter_bridge/ebtables.h2
-rw-r--r--include/linux/nvme-rdma.h71
-rw-r--r--include/linux/nvme.h406
-rw-r--r--include/linux/nvmem-consumer.h2
-rw-r--r--include/linux/of.h3
-rw-r--r--include/linux/of_fdt.h2
-rw-r--r--include/linux/of_mdio.h18
-rw-r--r--include/linux/of_reserved_mem.h25
-rw-r--r--include/linux/oom.h36
-rw-r--r--include/linux/page-flags.h128
-rw-r--r--include/linux/page_ext.h4
-rw-r--r--include/linux/page_owner.h12
-rw-r--r--include/linux/pagemap.h6
-rw-r--r--include/linux/percpu-refcount.h12
-rw-r--r--include/linux/perf_event.h35
-rw-r--r--include/linux/pfn_t.h5
-rw-r--r--include/linux/phy/phy.h17
-rw-r--r--include/linux/pinctrl/pinconf-generic.h2
-rw-r--r--include/linux/platform_data/at24.h11
-rw-r--r--include/linux/platform_data/b53.h33
-rw-r--r--include/linux/platform_data/sht3x.h25
-rw-r--r--include/linux/platform_data/spi-s3c64xx.h1
-rw-r--r--include/linux/pm_clock.h1
-rw-r--r--include/linux/pm_domain.h10
-rw-r--r--include/linux/pmem.h117
-rw-r--r--include/linux/power/max8903_charger.h6
-rw-r--r--include/linux/power_supply.h1
-rw-r--r--include/linux/printk.h17
-rw-r--r--include/linux/pstore.h3
-rw-r--r--include/linux/ptr_ring.h448
-rw-r--r--include/linux/qed/common_hsi.h397
-rw-r--r--include/linux/qed/eth_common.h124
-rw-r--r--include/linux/qed/iscsi_common.h1439
-rw-r--r--include/linux/qed/qed_chain.h556
-rw-r--r--include/linux/qed/qed_eth_if.h63
-rw-r--r--include/linux/qed/qed_if.h182
-rw-r--r--include/linux/qed/rdma_common.h44
-rw-r--r--include/linux/qed/roce_common.h17
-rw-r--r--include/linux/qed/storage_common.h91
-rw-r--r--include/linux/qed/tcp_common.h226
-rw-r--r--include/linux/quota.h4
-rw-r--r--include/linux/radix-tree.h1
-rw-r--r--include/linux/random.h12
-rw-r--r--include/linux/rbtree.h2
-rw-r--r--include/linux/rbtree_augmented.h13
-rw-r--r--include/linux/rcupdate.h31
-rw-r--r--include/linux/regmap.h49
-rw-r--r--include/linux/regulator/consumer.h6
-rw-r--r--include/linux/regulator/da9211.h5
-rw-r--r--include/linux/regulator/mt6323-regulator.h52
-rw-r--r--include/linux/rmap.h2
-rw-r--r--include/linux/rtnetlink.h5
-rw-r--r--include/linux/rwsem.h8
-rw-r--r--include/linux/rxrpc.h21
-rw-r--r--include/linux/sched.h35
-rw-r--r--include/linux/serial_8250.h1
-rw-r--r--include/linux/serial_core.h8
-rw-r--r--include/linux/sfi.h1
-rw-r--r--include/linux/shmem_fs.h45
-rw-r--r--include/linux/skb_array.h178
-rw-r--r--include/linux/skbuff.h18
-rw-r--r--include/linux/slab.h2
-rw-r--r--include/linux/slab_def.h5
-rw-r--r--include/linux/slub_def.h19
-rw-r--r--include/linux/spi/spi.h10
-rw-r--r--include/linux/spinlock_up.h10
-rw-r--r--include/linux/stmmac.h3
-rw-r--r--include/linux/stringhash.h12
-rw-r--r--include/linux/sunrpc/svcauth.h4
-rw-r--r--include/linux/suspend.h5
-rw-r--r--include/linux/swap.h23
-rw-r--r--include/linux/ti_wilink_st.h2
-rw-r--r--include/linux/time.h15
-rw-r--r--include/linux/timer.h34
-rw-r--r--include/linux/topology.h2
-rw-r--r--include/linux/torture.h4
-rw-r--r--include/linux/usb/gadget.h589
-rw-r--r--include/linux/usb/msm_hsusb.h200
-rw-r--r--include/linux/usb/of.h4
-rw-r--r--include/linux/usb/xhci_pdriver.h27
-rw-r--r--include/linux/userfaultfd_k.h8
-rw-r--r--include/linux/virtio_net.h101
-rw-r--r--include/linux/vm_event_item.h21
-rw-r--r--include/linux/vmstat.h111
-rw-r--r--include/linux/vt_kern.h7
-rw-r--r--include/linux/vtime.h50
-rw-r--r--include/linux/writeback.h5
-rw-r--r--include/media/cec-edid.h104
-rw-r--r--include/media/cec.h241
-rw-r--r--include/media/davinci/vpbe_display.h2
-rw-r--r--include/media/i2c/adv7511.h6
-rw-r--r--include/media/i2c/adv7604.h2
-rw-r--r--include/media/i2c/adv7842.h2
-rw-r--r--include/media/lirc_dev.h2
-rw-r--r--include/media/media-device.h260
-rw-r--r--include/media/media-devnode.h46
-rw-r--r--include/media/media-entity.h89
-rw-r--r--include/media/rc-core.h48
-rw-r--r--include/media/rc-map.h23
-rw-r--r--include/media/rcar-fcp.h37
-rw-r--r--include/media/tuner-types.h8
-rw-r--r--include/media/tveeprom.h18
-rw-r--r--include/media/v4l2-async.h39
-rw-r--r--include/media/v4l2-common.h92
-rw-r--r--include/media/v4l2-ctrls.h405
-rw-r--r--include/media/v4l2-dev.h364
-rw-r--r--include/media/v4l2-device.h198
-rw-r--r--include/media/v4l2-dv-timings.h2
-rw-r--r--include/media/v4l2-event.h125
-rw-r--r--include/media/v4l2-fh.h128
-rw-r--r--include/media/v4l2-ioctl.h266
-rw-r--r--include/media/v4l2-mc.h13
-rw-r--r--include/media/v4l2-subdev.h597
-rw-r--r--include/media/videobuf2-core.h96
-rw-r--r--include/media/videobuf2-dma-contig.h11
-rw-r--r--include/media/videobuf2-dma-sg.h3
-rw-r--r--include/media/vsp1.h29
-rw-r--r--include/net/6lowpan.h16
-rw-r--r--include/net/act_api.h119
-rw-r--r--include/net/addrconf.h10
-rw-r--r--include/net/bluetooth/hci.h3
-rw-r--r--include/net/bluetooth/hci_core.h10
-rw-r--r--include/net/bluetooth/mgmt.h1
-rw-r--r--include/net/cfg80211.h133
-rw-r--r--include/net/cfg802154.h13
-rw-r--r--include/net/codel_qdisc.h1
-rw-r--r--include/net/devlink.h3
-rw-r--r--include/net/dsa.h60
-rw-r--r--include/net/fib_rules.h24
-rw-r--r--include/net/gen_stats.h12
-rw-r--r--include/net/geneve.h9
-rw-r--r--include/net/gro_cells.h11
-rw-r--r--include/net/gtp.h2
-rw-r--r--include/net/ip.h1
-rw-r--r--include/net/ip6_route.h23
-rw-r--r--include/net/ip_tunnels.h2
-rw-r--r--include/net/l3mdev.h60
-rw-r--r--include/net/mac80211.h23
-rw-r--r--include/net/mac802154.h117
-rw-r--r--include/net/ncsi.h52
-rw-r--r--include/net/ndisc.h248
-rw-r--r--include/net/netevent.h1
-rw-r--r--include/net/netfilter/nf_conntrack.h13
-rw-r--r--include/net/netfilter/nf_conntrack_core.h2
-rw-r--r--include/net/netfilter/nf_conntrack_extend.h7
-rw-r--r--include/net/netfilter/nf_conntrack_helper.h15
-rw-r--r--include/net/netfilter/nf_conntrack_labels.h18
-rw-r--r--include/net/netfilter/nf_conntrack_zones.h45
-rw-r--r--include/net/netfilter/nf_log.h7
-rw-r--r--include/net/netfilter/nf_nat.h3
-rw-r--r--include/net/netfilter/nf_tables.h64
-rw-r--r--include/net/nfc/digital.h4
-rw-r--r--include/net/nfc/llc.h4
-rw-r--r--include/net/nl802154.h9
-rw-r--r--include/net/pkt_cls.h11
-rw-r--r--include/net/pkt_sched.h4
-rw-r--r--include/net/rtnetlink.h5
-rw-r--r--include/net/sch_generic.h158
-rw-r--r--include/net/sctp/sctp.h4
-rw-r--r--include/net/sctp/structs.h51
-rw-r--r--include/net/sctp/ulpevent.h12
-rw-r--r--include/net/switchdev.h8
-rw-r--r--include/net/tc_act/tc_bpf.h5
-rw-r--r--include/net/tc_act/tc_connmark.h5
-rw-r--r--include/net/tc_act/tc_csum.h5
-rw-r--r--include/net/tc_act/tc_defact.h9
-rw-r--r--include/net/tc_act/tc_gact.h7
-rw-r--r--include/net/tc_act/tc_ife.h5
-rw-r--r--include/net/tc_act/tc_ipt.h5
-rw-r--r--include/net/tc_act/tc_mirred.h14
-rw-r--r--include/net/tc_act/tc_nat.h7
-rw-r--r--include/net/tc_act/tc_pedit.h5
-rw-r--r--include/net/tc_act/tc_skbedit.h15
-rw-r--r--include/net/tc_act/tc_vlan.h5
-rw-r--r--include/net/tcp.h7
-rw-r--r--include/net/udp.h4
-rw-r--r--include/net/udp_tunnel.h42
-rw-r--r--include/net/vxlan.h13
-rw-r--r--include/ras/ras_event.h4
-rw-r--r--include/scsi/fc/fc_fip.h21
-rw-r--r--include/scsi/libfc.h1
-rw-r--r--include/scsi/libfcoe.h25
-rw-r--r--include/scsi/scsi_device.h1
-rw-r--r--include/scsi/scsi_host.h6
-rw-r--r--include/soc/fsl/qe/immap_qe.h5
-rw-r--r--include/soc/fsl/qe/qe.h19
-rw-r--r--include/soc/fsl/qe/qe_tdm.h94
-rw-r--r--include/soc/fsl/qe/ucc.h4
-rw-r--r--include/soc/fsl/qe/ucc_fast.h27
-rw-r--r--include/trace/events/bcache.h12
-rw-r--r--include/trace/events/block.h31
-rw-r--r--include/trace/events/compaction.h12
-rw-r--r--include/trace/events/devlink.h68
-rw-r--r--include/trace/events/f2fs.h39
-rw-r--r--include/trace/events/huge_memory.h50
-rw-r--r--include/trace/events/libata.h1
-rw-r--r--include/trace/events/mmflags.h1
-rw-r--r--include/trace/events/napi.h13
-rw-r--r--include/trace/events/printk.h12
-rw-r--r--include/trace/events/vmscan.h63
-rw-r--r--include/trace/events/writeback.h32
-rw-r--r--include/trace/perf.h2
-rw-r--r--include/trace/trace_events.h2
-rw-r--r--include/uapi/linux/batman_adv.h114
-rw-r--r--include/uapi/linux/bpf.h86
-rw-r--r--include/uapi/linux/can/bcm.h1
-rw-r--r--include/uapi/linux/cryptouser.h5
-rw-r--r--include/uapi/linux/devlink.h8
-rw-r--r--include/uapi/linux/dm-ioctl.h4
-rw-r--r--include/uapi/linux/elf-em.h1
-rw-r--r--include/uapi/linux/ethtool.h3
-rw-r--r--include/uapi/linux/fib_rules.h1
-rw-r--r--include/uapi/linux/gpio.h105
-rw-r--r--include/uapi/linux/i2c.h1
-rw-r--r--include/uapi/linux/icmp.h1
-rw-r--r--include/uapi/linux/if_bridge.h29
-rw-r--r--include/uapi/linux/if_ether.h1
-rw-r--r--include/uapi/linux/if_link.h14
-rw-r--r--include/uapi/linux/if_macsec.h2
-rw-r--r--include/uapi/linux/if_tunnel.h1
-rw-r--r--include/uapi/linux/iio/types.h1
-rw-r--r--include/uapi/linux/inet_diag.h1
-rw-r--r--include/uapi/linux/kexec.h1
-rw-r--r--include/uapi/linux/lirc.h39
-rw-r--r--include/uapi/linux/magic.h2
-rw-r--r--include/uapi/linux/media.h10
-rw-r--r--include/uapi/linux/ndctl.h1
-rw-r--r--include/uapi/linux/netfilter/nf_tables.h6
-rw-r--r--include/uapi/linux/netfilter/xt_NFLOG.h6
-rw-r--r--include/uapi/linux/netlink_diag.h1
-rw-r--r--include/uapi/linux/nl80211.h90
-rw-r--r--include/uapi/linux/openvswitch.h8
-rw-r--r--include/uapi/linux/perf_event.h6
-rw-r--r--include/uapi/linux/pkt_cls.h19
-rw-r--r--include/uapi/linux/sctp.h42
-rw-r--r--include/uapi/linux/serio.h1
-rw-r--r--include/uapi/linux/tc_act/tc_skbedit.h2
-rw-r--r--include/uapi/linux/tcp.h10
-rw-r--r--include/uapi/linux/tipc.h30
-rw-r--r--include/uapi/linux/tipc_netlink.h37
-rw-r--r--include/uapi/linux/videodev2.h14
-rw-r--r--include/uapi/linux/virtio_net.h9
-rw-r--r--include/uapi/linux/vsp1.h34
-rw-r--r--include/uapi/linux/wireless.h63
-rw-r--r--include/uapi/xen/evtchn.h15
-rw-r--r--include/xen/interface/hvm/params.h40
-rw-r--r--include/xen/interface/memory.h1
-rw-r--r--include/xen/interface/vcpu.h24
-rw-r--r--include/xen/interface/xen.h17
-rw-r--r--include/xen/xen-ops.h40
413 files changed, 18222 insertions, 4494 deletions
diff --git a/include/acpi/acpi_numa.h b/include/acpi/acpi_numa.h
index 94a37cd7fbda..d4b72944ccda 100644
--- a/include/acpi/acpi_numa.h
+++ b/include/acpi/acpi_numa.h
@@ -15,6 +15,10 @@ extern int pxm_to_node(int);
extern int node_to_pxm(int);
extern int acpi_map_pxm_to_node(int);
extern unsigned char acpi_srat_revision;
+extern int acpi_numa __initdata;
+
+extern void bad_srat(void);
+extern int srat_disabled(void);
#endif /* CONFIG_ACPI_NUMA */
#endif /* __ACP_NUMA_H */
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
index dad8af3ebeb5..284965cbc9af 100644
--- a/include/acpi/cppc_acpi.h
+++ b/include/acpi/cppc_acpi.h
@@ -15,10 +15,9 @@
#define _CPPC_ACPI_H
#include <linux/acpi.h>
-#include <linux/mailbox_controller.h>
-#include <linux/mailbox_client.h>
#include <linux/types.h>
+#include <acpi/pcc.h>
#include <acpi/processor.h>
/* Only support CPPCv2 for now. */
@@ -130,8 +129,4 @@ extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls);
extern int cppc_get_perf_caps(int cpu, struct cppc_perf_caps *caps);
extern int acpi_get_psd_map(struct cpudata **);
-/* Methods to interact with the PCC mailbox controller. */
-extern struct mbox_chan *
- pcc_mbox_request_channel(struct mbox_client *, unsigned int);
-
#endif /* _CPPC_ACPI_H*/
diff --git a/include/acpi/pcc.h b/include/acpi/pcc.h
new file mode 100644
index 000000000000..17a940a14477
--- /dev/null
+++ b/include/acpi/pcc.h
@@ -0,0 +1,29 @@
+/*
+ * PCC (Platform Communications Channel) methods
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#ifndef _PCC_H
+#define _PCC_H
+
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox_client.h>
+
+#ifdef CONFIG_PCC
+extern struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl,
+ int subspace_id);
+extern void pcc_mbox_free_channel(struct mbox_chan *chan);
+#else
+static inline struct mbox_chan *pcc_mbox_request_channel(struct mbox_client *cl,
+ int subspace_id)
+{
+ return NULL;
+}
+static inline void pcc_mbox_free_channel(struct mbox_chan *chan) { }
+#endif
+
+#endif /* _PCC_H */
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index 45c2d6528829..93b61b1f2beb 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -73,6 +73,10 @@
#define ACPI_DEBUGGER
#endif
+#ifdef CONFIG_ACPI_DEBUG
+#define ACPI_MUTEX_DEBUG
+#endif
+
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/ctype.h>
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 6f1805dd5d3c..bfe6b2e10f3a 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -39,6 +39,7 @@
#define ACPI_CSTATE_SYSTEMIO 0
#define ACPI_CSTATE_FFH 1
#define ACPI_CSTATE_HALT 2
+#define ACPI_CSTATE_INTEGER 3
#define ACPI_CX_DESC_LEN 32
@@ -67,9 +68,25 @@ struct acpi_processor_cx {
char desc[ACPI_CX_DESC_LEN];
};
+struct acpi_lpi_state {
+ u32 min_residency;
+ u32 wake_latency; /* worst case */
+ u32 flags;
+ u32 arch_flags;
+ u32 res_cnt_freq;
+ u32 enable_parent_state;
+ u64 address;
+ u8 index;
+ u8 entry_method;
+ char desc[ACPI_CX_DESC_LEN];
+};
+
struct acpi_processor_power {
int count;
- struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
+ union {
+ struct acpi_processor_cx states[ACPI_PROCESSOR_MAX_POWER];
+ struct acpi_lpi_state lpi_states[ACPI_PROCESSOR_MAX_POWER];
+ };
int timer_broadcast_on_state;
};
@@ -189,6 +206,7 @@ struct acpi_processor_flags {
u8 bm_control:1;
u8 bm_check:1;
u8 has_cst:1;
+ u8 has_lpi:1;
u8 power_setup_done:1;
u8 bm_rld_set:1;
u8 need_hotplug_init:1;
@@ -242,7 +260,7 @@ extern int acpi_processor_get_performance_info(struct acpi_processor *pr);
DECLARE_PER_CPU(struct acpi_processor *, processors);
extern struct acpi_processor_errata errata;
-#ifdef ARCH_HAS_POWER_INIT
+#if defined(ARCH_HAS_POWER_INIT) && defined(CONFIG_ACPI_PROCESSOR_CSTATE)
void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
unsigned int cpu);
int acpi_processor_ffh_cstate_probe(unsigned int cpu,
@@ -309,6 +327,7 @@ static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
/* in processor_core.c */
phys_cpuid_t acpi_get_phys_id(acpi_handle, int type, u32 acpi_id);
+phys_cpuid_t acpi_map_madt_entry(u32 acpi_id);
int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id);
int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id);
@@ -371,7 +390,7 @@ extern struct cpuidle_driver acpi_idle_driver;
#ifdef CONFIG_ACPI_PROCESSOR_IDLE
int acpi_processor_power_init(struct acpi_processor *pr);
int acpi_processor_power_exit(struct acpi_processor *pr);
-int acpi_processor_cst_has_changed(struct acpi_processor *pr);
+int acpi_processor_power_state_has_changed(struct acpi_processor *pr);
int acpi_processor_hotplug(struct acpi_processor *pr);
#else
static inline int acpi_processor_power_init(struct acpi_processor *pr)
@@ -384,7 +403,7 @@ static inline int acpi_processor_power_exit(struct acpi_processor *pr)
return -ENODEV;
}
-static inline int acpi_processor_cst_has_changed(struct acpi_processor *pr)
+static inline int acpi_processor_power_state_has_changed(struct acpi_processor *pr)
{
return -ENODEV;
}
diff --git a/include/acpi/video.h b/include/acpi/video.h
index 5731ccb42585..4536bd345ab4 100644
--- a/include/acpi/video.h
+++ b/include/acpi/video.h
@@ -54,7 +54,7 @@ extern int acpi_video_get_levels(struct acpi_device *device,
struct acpi_video_device_brightness **dev_br,
int *pmax_level);
#else
-static inline int acpi_video_register(void) { return 0; }
+static inline int acpi_video_register(void) { return -ENODEV; }
static inline void acpi_video_unregister(void) { return; }
static inline int acpi_video_get_edid(struct acpi_device *device, int type,
int device_id, void **edid)
diff --git a/include/asm-generic/atomic-long.h b/include/asm-generic/atomic-long.h
index 5e1f345b58dd..288cc9e96395 100644
--- a/include/asm-generic/atomic-long.h
+++ b/include/asm-generic/atomic-long.h
@@ -112,6 +112,62 @@ static __always_inline void atomic_long_dec(atomic_long_t *l)
ATOMIC_LONG_PFX(_dec)(v);
}
+#define ATOMIC_LONG_FETCH_OP(op, mo) \
+static inline long \
+atomic_long_fetch_##op##mo(long i, atomic_long_t *l) \
+{ \
+ ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
+ \
+ return (long)ATOMIC_LONG_PFX(_fetch_##op##mo)(i, v); \
+}
+
+ATOMIC_LONG_FETCH_OP(add, )
+ATOMIC_LONG_FETCH_OP(add, _relaxed)
+ATOMIC_LONG_FETCH_OP(add, _acquire)
+ATOMIC_LONG_FETCH_OP(add, _release)
+ATOMIC_LONG_FETCH_OP(sub, )
+ATOMIC_LONG_FETCH_OP(sub, _relaxed)
+ATOMIC_LONG_FETCH_OP(sub, _acquire)
+ATOMIC_LONG_FETCH_OP(sub, _release)
+ATOMIC_LONG_FETCH_OP(and, )
+ATOMIC_LONG_FETCH_OP(and, _relaxed)
+ATOMIC_LONG_FETCH_OP(and, _acquire)
+ATOMIC_LONG_FETCH_OP(and, _release)
+ATOMIC_LONG_FETCH_OP(andnot, )
+ATOMIC_LONG_FETCH_OP(andnot, _relaxed)
+ATOMIC_LONG_FETCH_OP(andnot, _acquire)
+ATOMIC_LONG_FETCH_OP(andnot, _release)
+ATOMIC_LONG_FETCH_OP(or, )
+ATOMIC_LONG_FETCH_OP(or, _relaxed)
+ATOMIC_LONG_FETCH_OP(or, _acquire)
+ATOMIC_LONG_FETCH_OP(or, _release)
+ATOMIC_LONG_FETCH_OP(xor, )
+ATOMIC_LONG_FETCH_OP(xor, _relaxed)
+ATOMIC_LONG_FETCH_OP(xor, _acquire)
+ATOMIC_LONG_FETCH_OP(xor, _release)
+
+#undef ATOMIC_LONG_FETCH_OP
+
+#define ATOMIC_LONG_FETCH_INC_DEC_OP(op, mo) \
+static inline long \
+atomic_long_fetch_##op##mo(atomic_long_t *l) \
+{ \
+ ATOMIC_LONG_PFX(_t) *v = (ATOMIC_LONG_PFX(_t) *)l; \
+ \
+ return (long)ATOMIC_LONG_PFX(_fetch_##op##mo)(v); \
+}
+
+ATOMIC_LONG_FETCH_INC_DEC_OP(inc,)
+ATOMIC_LONG_FETCH_INC_DEC_OP(inc, _relaxed)
+ATOMIC_LONG_FETCH_INC_DEC_OP(inc, _acquire)
+ATOMIC_LONG_FETCH_INC_DEC_OP(inc, _release)
+ATOMIC_LONG_FETCH_INC_DEC_OP(dec,)
+ATOMIC_LONG_FETCH_INC_DEC_OP(dec, _relaxed)
+ATOMIC_LONG_FETCH_INC_DEC_OP(dec, _acquire)
+ATOMIC_LONG_FETCH_INC_DEC_OP(dec, _release)
+
+#undef ATOMIC_LONG_FETCH_INC_DEC_OP
+
#define ATOMIC_LONG_OP(op) \
static __always_inline void \
atomic_long_##op(long i, atomic_long_t *l) \
@@ -124,9 +180,9 @@ atomic_long_##op(long i, atomic_long_t *l) \
ATOMIC_LONG_OP(add)
ATOMIC_LONG_OP(sub)
ATOMIC_LONG_OP(and)
+ATOMIC_LONG_OP(andnot)
ATOMIC_LONG_OP(or)
ATOMIC_LONG_OP(xor)
-ATOMIC_LONG_OP(andnot)
#undef ATOMIC_LONG_OP
diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h
index 74f1a3704d7a..9ed8b987185b 100644
--- a/include/asm-generic/atomic.h
+++ b/include/asm-generic/atomic.h
@@ -61,6 +61,18 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
return c c_op i; \
}
+#define ATOMIC_FETCH_OP(op, c_op) \
+static inline int atomic_fetch_##op(int i, atomic_t *v) \
+{ \
+ int c, old; \
+ \
+ c = v->counter; \
+ while ((old = cmpxchg(&v->counter, c, c c_op i)) != c) \
+ c = old; \
+ \
+ return c; \
+}
+
#else
#include <linux/irqflags.h>
@@ -88,6 +100,20 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
return ret; \
}
+#define ATOMIC_FETCH_OP(op, c_op) \
+static inline int atomic_fetch_##op(int i, atomic_t *v) \
+{ \
+ unsigned long flags; \
+ int ret; \
+ \
+ raw_local_irq_save(flags); \
+ ret = v->counter; \
+ v->counter = v->counter c_op i; \
+ raw_local_irq_restore(flags); \
+ \
+ return ret; \
+}
+
#endif /* CONFIG_SMP */
#ifndef atomic_add_return
@@ -98,6 +124,26 @@ ATOMIC_OP_RETURN(add, +)
ATOMIC_OP_RETURN(sub, -)
#endif
+#ifndef atomic_fetch_add
+ATOMIC_FETCH_OP(add, +)
+#endif
+
+#ifndef atomic_fetch_sub
+ATOMIC_FETCH_OP(sub, -)
+#endif
+
+#ifndef atomic_fetch_and
+ATOMIC_FETCH_OP(and, &)
+#endif
+
+#ifndef atomic_fetch_or
+ATOMIC_FETCH_OP(or, |)
+#endif
+
+#ifndef atomic_fetch_xor
+ATOMIC_FETCH_OP(xor, ^)
+#endif
+
#ifndef atomic_and
ATOMIC_OP(and, &)
#endif
@@ -110,6 +156,7 @@ ATOMIC_OP(or, |)
ATOMIC_OP(xor, ^)
#endif
+#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP
diff --git a/include/asm-generic/atomic64.h b/include/asm-generic/atomic64.h
index d48e78ccad3d..dad68bf46c77 100644
--- a/include/asm-generic/atomic64.h
+++ b/include/asm-generic/atomic64.h
@@ -27,16 +27,23 @@ extern void atomic64_##op(long long a, atomic64_t *v);
#define ATOMIC64_OP_RETURN(op) \
extern long long atomic64_##op##_return(long long a, atomic64_t *v);
-#define ATOMIC64_OPS(op) ATOMIC64_OP(op) ATOMIC64_OP_RETURN(op)
+#define ATOMIC64_FETCH_OP(op) \
+extern long long atomic64_fetch_##op(long long a, atomic64_t *v);
+
+#define ATOMIC64_OPS(op) ATOMIC64_OP(op) ATOMIC64_OP_RETURN(op) ATOMIC64_FETCH_OP(op)
ATOMIC64_OPS(add)
ATOMIC64_OPS(sub)
-ATOMIC64_OP(and)
-ATOMIC64_OP(or)
-ATOMIC64_OP(xor)
+#undef ATOMIC64_OPS
+#define ATOMIC64_OPS(op) ATOMIC64_OP(op) ATOMIC64_FETCH_OP(op)
+
+ATOMIC64_OPS(and)
+ATOMIC64_OPS(or)
+ATOMIC64_OPS(xor)
#undef ATOMIC64_OPS
+#undef ATOMIC64_FETCH_OP
#undef ATOMIC64_OP_RETURN
#undef ATOMIC64_OP
diff --git a/include/asm-generic/barrier.h b/include/asm-generic/barrier.h
index 1cceca146905..fe297b599b0a 100644
--- a/include/asm-generic/barrier.h
+++ b/include/asm-generic/barrier.h
@@ -194,7 +194,7 @@ do { \
})
#endif
-#endif
+#endif /* CONFIG_SMP */
/* Barriers for virtual machine guests when talking to an SMP host */
#define virt_mb() __smp_mb()
@@ -207,5 +207,44 @@ do { \
#define virt_store_release(p, v) __smp_store_release(p, v)
#define virt_load_acquire(p) __smp_load_acquire(p)
+/**
+ * smp_acquire__after_ctrl_dep() - Provide ACQUIRE ordering after a control dependency
+ *
+ * A control dependency provides a LOAD->STORE order, the additional RMB
+ * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} order,
+ * aka. (load)-ACQUIRE.
+ *
+ * Architectures that do not do load speculation can have this be barrier().
+ */
+#ifndef smp_acquire__after_ctrl_dep
+#define smp_acquire__after_ctrl_dep() smp_rmb()
+#endif
+
+/**
+ * smp_cond_load_acquire() - (Spin) wait for cond with ACQUIRE ordering
+ * @ptr: pointer to the variable to wait on
+ * @cond: boolean expression to wait for
+ *
+ * Equivalent to using smp_load_acquire() on the condition variable but employs
+ * the control dependency of the wait to reduce the barrier on many platforms.
+ *
+ * Due to C lacking lambda expressions we load the value of *ptr into a
+ * pre-named variable @VAL to be used in @cond.
+ */
+#ifndef smp_cond_load_acquire
+#define smp_cond_load_acquire(ptr, cond_expr) ({ \
+ typeof(ptr) __PTR = (ptr); \
+ typeof(*ptr) VAL; \
+ for (;;) { \
+ VAL = READ_ONCE(*__PTR); \
+ if (cond_expr) \
+ break; \
+ cpu_relax(); \
+ } \
+ smp_acquire__after_ctrl_dep(); \
+ VAL; \
+})
+#endif
+
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_GENERIC_BARRIER_H */
diff --git a/include/asm-generic/cputime_nsecs.h b/include/asm-generic/cputime_nsecs.h
index 0f1c6f315cdc..a84e28e0c634 100644
--- a/include/asm-generic/cputime_nsecs.h
+++ b/include/asm-generic/cputime_nsecs.h
@@ -50,6 +50,8 @@ typedef u64 __nocast cputime64_t;
(__force u64)(__ct)
#define nsecs_to_cputime(__nsecs) \
(__force cputime_t)(__nsecs)
+#define nsecs_to_cputime64(__nsecs) \
+ (__force cputime64_t)(__nsecs)
/*
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 002b81f6f2bc..7ef015eb3403 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -585,6 +585,16 @@ static inline u32 ioread32(const volatile void __iomem *addr)
}
#endif
+#ifdef CONFIG_64BIT
+#ifndef ioread64
+#define ioread64 ioread64
+static inline u64 ioread64(const volatile void __iomem *addr)
+{
+ return readq(addr);
+}
+#endif
+#endif /* CONFIG_64BIT */
+
#ifndef iowrite8
#define iowrite8 iowrite8
static inline void iowrite8(u8 value, volatile void __iomem *addr)
@@ -609,11 +619,21 @@ static inline void iowrite32(u32 value, volatile void __iomem *addr)
}
#endif
+#ifdef CONFIG_64BIT
+#ifndef iowrite64
+#define iowrite64 iowrite64
+static inline void iowrite64(u64 value, volatile void __iomem *addr)
+{
+ writeq(value, addr);
+}
+#endif
+#endif /* CONFIG_64BIT */
+
#ifndef ioread16be
#define ioread16be ioread16be
static inline u16 ioread16be(const volatile void __iomem *addr)
{
- return __be16_to_cpu(__raw_readw(addr));
+ return swab16(readw(addr));
}
#endif
@@ -621,15 +641,25 @@ static inline u16 ioread16be(const volatile void __iomem *addr)
#define ioread32be ioread32be
static inline u32 ioread32be(const volatile void __iomem *addr)
{
- return __be32_to_cpu(__raw_readl(addr));
+ return swab32(readl(addr));
+}
+#endif
+
+#ifdef CONFIG_64BIT
+#ifndef ioread64be
+#define ioread64be ioread64be
+static inline u64 ioread64be(const volatile void __iomem *addr)
+{
+ return swab64(readq(addr));
}
#endif
+#endif /* CONFIG_64BIT */
#ifndef iowrite16be
#define iowrite16be iowrite16be
static inline void iowrite16be(u16 value, void volatile __iomem *addr)
{
- __raw_writew(__cpu_to_be16(value), addr);
+ writew(swab16(value), addr);
}
#endif
@@ -637,10 +667,20 @@ static inline void iowrite16be(u16 value, void volatile __iomem *addr)
#define iowrite32be iowrite32be
static inline void iowrite32be(u32 value, volatile void __iomem *addr)
{
- __raw_writel(__cpu_to_be32(value), addr);
+ writel(swab32(value), addr);
}
#endif
+#ifdef CONFIG_64BIT
+#ifndef iowrite64be
+#define iowrite64be iowrite64be
+static inline void iowrite64be(u64 value, volatile void __iomem *addr)
+{
+ writeq(swab64(value), addr);
+}
+#endif
+#endif /* CONFIG_64BIT */
+
#ifndef ioread8_rep
#define ioread8_rep ioread8_rep
static inline void ioread8_rep(const volatile void __iomem *addr, void *buffer,
@@ -668,6 +708,17 @@ static inline void ioread32_rep(const volatile void __iomem *addr,
}
#endif
+#ifdef CONFIG_64BIT
+#ifndef ioread64_rep
+#define ioread64_rep ioread64_rep
+static inline void ioread64_rep(const volatile void __iomem *addr,
+ void *buffer, unsigned int count)
+{
+ readsq(addr, buffer, count);
+}
+#endif
+#endif /* CONFIG_64BIT */
+
#ifndef iowrite8_rep
#define iowrite8_rep iowrite8_rep
static inline void iowrite8_rep(volatile void __iomem *addr,
@@ -697,6 +748,18 @@ static inline void iowrite32_rep(volatile void __iomem *addr,
writesl(addr, buffer, count);
}
#endif
+
+#ifdef CONFIG_64BIT
+#ifndef iowrite64_rep
+#define iowrite64_rep iowrite64_rep
+static inline void iowrite64_rep(volatile void __iomem *addr,
+ const void *buffer,
+ unsigned int count)
+{
+ writesq(addr, buffer, count);
+}
+#endif
+#endif /* CONFIG_64BIT */
#endif /* CONFIG_GENERIC_IOMAP */
#ifdef __KERNEL__
diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
index d8f8622fa044..650fede33c25 100644
--- a/include/asm-generic/iomap.h
+++ b/include/asm-generic/iomap.h
@@ -30,12 +30,20 @@ extern unsigned int ioread16(void __iomem *);
extern unsigned int ioread16be(void __iomem *);
extern unsigned int ioread32(void __iomem *);
extern unsigned int ioread32be(void __iomem *);
+#ifdef CONFIG_64BIT
+extern u64 ioread64(void __iomem *);
+extern u64 ioread64be(void __iomem *);
+#endif
extern void iowrite8(u8, void __iomem *);
extern void iowrite16(u16, void __iomem *);
extern void iowrite16be(u16, void __iomem *);
extern void iowrite32(u32, void __iomem *);
extern void iowrite32be(u32, void __iomem *);
+#ifdef CONFIG_64BIT
+extern void iowrite64(u64, void __iomem *);
+extern void iowrite64be(u64, void __iomem *);
+#endif
/*
* "string" versions of the above. Note that they
diff --git a/include/asm-generic/mutex-dec.h b/include/asm-generic/mutex-dec.h
index fd694cfd678a..c54829d3de37 100644
--- a/include/asm-generic/mutex-dec.h
+++ b/include/asm-generic/mutex-dec.h
@@ -80,7 +80,7 @@ __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
static inline int
__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
{
- if (likely(atomic_cmpxchg_acquire(count, 1, 0) == 1))
+ if (likely(atomic_read(count) == 1 && atomic_cmpxchg_acquire(count, 1, 0) == 1))
return 1;
return 0;
}
diff --git a/include/asm-generic/mutex-xchg.h b/include/asm-generic/mutex-xchg.h
index a6b4a7bd6ac9..3269ec4e195f 100644
--- a/include/asm-generic/mutex-xchg.h
+++ b/include/asm-generic/mutex-xchg.h
@@ -91,8 +91,12 @@ __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
static inline int
__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
{
- int prev = atomic_xchg_acquire(count, 0);
+ int prev;
+ if (atomic_read(count) != 1)
+ return 0;
+
+ prev = atomic_xchg_acquire(count, 0);
if (unlikely(prev < 0)) {
/*
* The lock was marked contended so we must restore that
diff --git a/include/asm-generic/qspinlock.h b/include/asm-generic/qspinlock.h
index 05f05f17a7c2..9f0681bf1e87 100644
--- a/include/asm-generic/qspinlock.h
+++ b/include/asm-generic/qspinlock.h
@@ -111,10 +111,9 @@ static __always_inline void queued_spin_lock(struct qspinlock *lock)
static __always_inline void queued_spin_unlock(struct qspinlock *lock)
{
/*
- * smp_mb__before_atomic() in order to guarantee release semantics
+ * unlock() needs release semantics:
*/
- smp_mb__before_atomic();
- atomic_sub(_Q_LOCKED_VAL, &lock->val);
+ (void)atomic_sub_return_release(_Q_LOCKED_VAL, &lock->val);
}
#endif
diff --git a/include/asm-generic/rwsem.h b/include/asm-generic/rwsem.h
index 3fc94a046bf5..5be122e3d326 100644
--- a/include/asm-generic/rwsem.h
+++ b/include/asm-generic/rwsem.h
@@ -41,8 +41,8 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
{
long tmp;
- while ((tmp = sem->count) >= 0) {
- if (tmp == cmpxchg_acquire(&sem->count, tmp,
+ while ((tmp = atomic_long_read(&sem->count)) >= 0) {
+ if (tmp == atomic_long_cmpxchg_acquire(&sem->count, tmp,
tmp + RWSEM_ACTIVE_READ_BIAS)) {
return 1;
}
@@ -79,7 +79,7 @@ static inline int __down_write_trylock(struct rw_semaphore *sem)
{
long tmp;
- tmp = cmpxchg_acquire(&sem->count, RWSEM_UNLOCKED_VALUE,
+ tmp = atomic_long_cmpxchg_acquire(&sem->count, RWSEM_UNLOCKED_VALUE,
RWSEM_ACTIVE_WRITE_BIAS);
return tmp == RWSEM_UNLOCKED_VALUE;
}
@@ -107,14 +107,6 @@ static inline void __up_write(struct rw_semaphore *sem)
}
/*
- * implement atomic add functionality
- */
-static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
-{
- atomic_long_add(delta, (atomic_long_t *)&sem->count);
-}
-
-/*
* downgrade write lock to read lock
*/
static inline void __downgrade_write(struct rw_semaphore *sem)
@@ -134,13 +126,5 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
rwsem_downgrade_wake(sem);
}
-/*
- * implement exchange and add functionality
- */
-static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
-{
- return atomic_long_add_return(delta, (atomic_long_t *)&sem->count);
-}
-
#endif /* __KERNEL__ */
#endif /* _ASM_GENERIC_RWSEM_H */
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index 9dbb739cafa0..c6d667187608 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -107,6 +107,12 @@ struct mmu_gather {
struct mmu_gather_batch local;
struct page *__pages[MMU_GATHER_BUNDLE];
unsigned int batch_count;
+ /*
+ * __tlb_adjust_range will track the new addr here,
+ * that that we can adjust the range after the flush
+ */
+ unsigned long addr;
+ int page_size;
};
#define HAVE_GENERIC_MMU_GATHER
@@ -115,23 +121,20 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long
void tlb_flush_mmu(struct mmu_gather *tlb);
void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start,
unsigned long end);
-int __tlb_remove_page(struct mmu_gather *tlb, struct page *page);
-
-/* tlb_remove_page
- * Similar to __tlb_remove_page but will call tlb_flush_mmu() itself when
- * required.
- */
-static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
-{
- if (!__tlb_remove_page(tlb, page))
- tlb_flush_mmu(tlb);
-}
+extern bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page,
+ int page_size);
static inline void __tlb_adjust_range(struct mmu_gather *tlb,
unsigned long address)
{
tlb->start = min(tlb->start, address);
tlb->end = max(tlb->end, address + PAGE_SIZE);
+ /*
+ * Track the last address with which we adjusted the range. This
+ * will be used later to adjust again after a mmu_flush due to
+ * failed __tlb_remove_page
+ */
+ tlb->addr = address;
}
static inline void __tlb_reset_range(struct mmu_gather *tlb)
@@ -144,6 +147,40 @@ static inline void __tlb_reset_range(struct mmu_gather *tlb)
}
}
+static inline void tlb_remove_page_size(struct mmu_gather *tlb,
+ struct page *page, int page_size)
+{
+ if (__tlb_remove_page_size(tlb, page, page_size)) {
+ tlb_flush_mmu(tlb);
+ tlb->page_size = page_size;
+ __tlb_adjust_range(tlb, tlb->addr);
+ __tlb_remove_page_size(tlb, page, page_size);
+ }
+}
+
+static bool __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+ return __tlb_remove_page_size(tlb, page, PAGE_SIZE);
+}
+
+/* tlb_remove_page
+ * Similar to __tlb_remove_page but will call tlb_flush_mmu() itself when
+ * required.
+ */
+static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+ return tlb_remove_page_size(tlb, page, PAGE_SIZE);
+}
+
+static inline bool __tlb_remove_pte_page(struct mmu_gather *tlb, struct page *page)
+{
+ /* active->nr should be zero when we call this */
+ VM_BUG_ON_PAGE(tlb->active->nr, page);
+ tlb->page_size = PAGE_SIZE;
+ __tlb_adjust_range(tlb, tlb->addr);
+ return __tlb_remove_page(tlb, page);
+}
+
/*
* In the case of tlb vma handling, we can optimise these away in the
* case where we're doing a full MM flush. When we're doing a munmap,
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 081d0f258d4c..54643d1f5af4 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -250,6 +250,14 @@
VMLINUX_SYMBOL(__end_init_task) = .;
/*
+ * Allow architectures to handle ro_after_init data on their
+ * own by defining an empty RO_AFTER_INIT_DATA.
+ */
+#ifndef RO_AFTER_INIT_DATA
+#define RO_AFTER_INIT_DATA *(.data..ro_after_init)
+#endif
+
+/*
* Read only Data
*/
#define RO_DATA_SECTION(align) \
@@ -257,7 +265,7 @@
.rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start_rodata) = .; \
*(.rodata) *(.rodata.*) \
- *(.data..ro_after_init) /* Read only after init */ \
+ RO_AFTER_INIT_DATA /* Read only after init */ \
*(__vermagic) /* Kernel version magic */ \
. = ALIGN(8); \
VMLINUX_SYMBOL(__start___tracepoints_ptrs) = .; \
diff --git a/include/clocksource/timer-sp804.h b/include/clocksource/timer-sp804.h
index 1f8a1caa7cb4..7654d71243dd 100644
--- a/include/clocksource/timer-sp804.h
+++ b/include/clocksource/timer-sp804.h
@@ -3,10 +3,10 @@
struct clk;
-void __sp804_clocksource_and_sched_clock_init(void __iomem *,
- const char *, struct clk *, int);
-void __sp804_clockevents_init(void __iomem *, unsigned int,
- struct clk *, const char *);
+int __sp804_clocksource_and_sched_clock_init(void __iomem *,
+ const char *, struct clk *, int);
+int __sp804_clockevents_init(void __iomem *, unsigned int,
+ struct clk *, const char *);
void sp804_timer_disable(void __iomem *);
static inline void sp804_clocksource_init(void __iomem *base, const char *name)
diff --git a/include/crypto/aead.h b/include/crypto/aead.h
index 75174f80a106..12f84327ca36 100644
--- a/include/crypto/aead.h
+++ b/include/crypto/aead.h
@@ -112,11 +112,12 @@ struct aead_request {
* supplied during the decryption operation. This function is also
* responsible for checking the authentication tag size for
* validity.
- * @setkey: see struct ablkcipher_alg
- * @encrypt: see struct ablkcipher_alg
- * @decrypt: see struct ablkcipher_alg
- * @geniv: see struct ablkcipher_alg
- * @ivsize: see struct ablkcipher_alg
+ * @setkey: see struct skcipher_alg
+ * @encrypt: see struct skcipher_alg
+ * @decrypt: see struct skcipher_alg
+ * @geniv: see struct skcipher_alg
+ * @ivsize: see struct skcipher_alg
+ * @chunksize: see struct skcipher_alg
* @init: Initialize the cryptographic transformation object. This function
* is used to initialize the cryptographic transformation object.
* This function is called only once at the instantiation time, right
@@ -145,6 +146,7 @@ struct aead_alg {
unsigned int ivsize;
unsigned int maxauthsize;
+ unsigned int chunksize;
struct crypto_alg base;
};
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index eeafd21afb44..8637cdfe382a 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -244,6 +244,8 @@ static inline struct crypto_alg *crypto_attr_alg(struct rtattr *rta,
}
int crypto_attr_u32(struct rtattr *rta, u32 *num);
+int crypto_inst_setname(struct crypto_instance *inst, const char *name,
+ struct crypto_alg *alg);
void *crypto_alloc_instance2(const char *name, struct crypto_alg *alg,
unsigned int head);
struct crypto_instance *crypto_alloc_instance(const char *name,
@@ -440,8 +442,10 @@ static inline int crypto_memneq(const void *a, const void *b, size_t size)
static inline void crypto_yield(u32 flags)
{
+#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PREEMPT_VOLUNTARY)
if (flags & CRYPTO_TFM_REQ_MAY_SLEEP)
cond_resched();
+#endif
}
#endif /* _CRYPTO_ALGAPI_H */
diff --git a/include/crypto/chacha20.h b/include/crypto/chacha20.h
index 274bbaeeed0f..20d20f681a72 100644
--- a/include/crypto/chacha20.h
+++ b/include/crypto/chacha20.h
@@ -16,6 +16,7 @@ struct chacha20_ctx {
u32 key[8];
};
+void chacha20_block(u32 *state, void *stream);
void crypto_chacha20_init(u32 *state, struct chacha20_ctx *ctx, u8 *iv);
int crypto_chacha20_setkey(struct crypto_tfm *tfm, const u8 *key,
unsigned int keysize);
diff --git a/include/crypto/cryptd.h b/include/crypto/cryptd.h
index 1547f540c920..bc792d5a9e88 100644
--- a/include/crypto/cryptd.h
+++ b/include/crypto/cryptd.h
@@ -31,6 +31,7 @@ static inline struct cryptd_ablkcipher *__cryptd_ablkcipher_cast(
struct cryptd_ablkcipher *cryptd_alloc_ablkcipher(const char *alg_name,
u32 type, u32 mask);
struct crypto_blkcipher *cryptd_ablkcipher_child(struct cryptd_ablkcipher *tfm);
+bool cryptd_ablkcipher_queued(struct cryptd_ablkcipher *tfm);
void cryptd_free_ablkcipher(struct cryptd_ablkcipher *tfm);
struct cryptd_ahash {
@@ -48,6 +49,8 @@ struct cryptd_ahash *cryptd_alloc_ahash(const char *alg_name,
u32 type, u32 mask);
struct crypto_shash *cryptd_ahash_child(struct cryptd_ahash *tfm);
struct shash_desc *cryptd_shash_desc(struct ahash_request *req);
+/* Must be called without moving CPUs. */
+bool cryptd_ahash_queued(struct cryptd_ahash *tfm);
void cryptd_free_ahash(struct cryptd_ahash *tfm);
struct cryptd_aead {
@@ -64,6 +67,8 @@ struct cryptd_aead *cryptd_alloc_aead(const char *alg_name,
u32 type, u32 mask);
struct crypto_aead *cryptd_aead_child(struct cryptd_aead *tfm);
+/* Must be called without moving CPUs. */
+bool cryptd_aead_queued(struct cryptd_aead *tfm);
void cryptd_free_aead(struct cryptd_aead *tfm);
diff --git a/include/crypto/dh.h b/include/crypto/dh.h
new file mode 100644
index 000000000000..5102a8f282e6
--- /dev/null
+++ b/include/crypto/dh.h
@@ -0,0 +1,29 @@
+/*
+ * Diffie-Hellman secret to be used with kpp API along with helper functions
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto <salvatore.benedetto@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#ifndef _CRYPTO_DH_
+#define _CRYPTO_DH_
+
+struct dh {
+ void *key;
+ void *p;
+ void *g;
+ unsigned int key_size;
+ unsigned int p_size;
+ unsigned int g_size;
+};
+
+int crypto_dh_key_len(const struct dh *params);
+int crypto_dh_encode_key(char *buf, unsigned int len, const struct dh *params);
+int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params);
+
+#endif
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index d961b2b16f55..61580b19f9f6 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -43,6 +43,7 @@
#include <linux/random.h>
#include <linux/scatterlist.h>
#include <crypto/hash.h>
+#include <crypto/skcipher.h>
#include <linux/module.h>
#include <linux/crypto.h>
#include <linux/slab.h>
@@ -107,14 +108,25 @@ struct drbg_test_data {
struct drbg_state {
struct mutex drbg_mutex; /* lock around DRBG */
unsigned char *V; /* internal state 10.1.1.1 1a) */
+ unsigned char *Vbuf;
/* hash: static value 10.1.1.1 1b) hmac / ctr: key */
unsigned char *C;
+ unsigned char *Cbuf;
/* Number of RNG requests since last reseed -- 10.1.1.1 1c) */
size_t reseed_ctr;
size_t reseed_threshold;
/* some memory the DRBG can use for its operation */
unsigned char *scratchpad;
+ unsigned char *scratchpadbuf;
void *priv_data; /* Cipher handle */
+
+ struct crypto_skcipher *ctr_handle; /* CTR mode cipher handle */
+ struct skcipher_request *ctr_req; /* CTR mode request handle */
+ __u8 *ctr_null_value_buf; /* CTR mode unaligned buffer */
+ __u8 *ctr_null_value; /* CTR mode aligned zero buf */
+ struct completion ctr_completion; /* CTR mode async handler */
+ int ctr_async_err; /* CTR mode async error */
+
bool seeded; /* DRBG fully seeded? */
bool pr; /* Prediction resistance enabled? */
struct work_struct seed_work; /* asynchronous seeding support */
diff --git a/include/crypto/ecdh.h b/include/crypto/ecdh.h
new file mode 100644
index 000000000000..84bad548d194
--- /dev/null
+++ b/include/crypto/ecdh.h
@@ -0,0 +1,30 @@
+/*
+ * ECDH params to be used with kpp API
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto <salvatore.benedetto@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#ifndef _CRYPTO_ECDH_
+#define _CRYPTO_ECDH_
+
+/* Curves IDs */
+#define ECC_CURVE_NIST_P192 0x0001
+#define ECC_CURVE_NIST_P256 0x0002
+
+struct ecdh {
+ unsigned short curve_id;
+ char *key;
+ unsigned short key_size;
+};
+
+int crypto_ecdh_key_len(const struct ecdh *params);
+int crypto_ecdh_encode_key(char *buf, unsigned int len, const struct ecdh *p);
+int crypto_ecdh_decode_key(const char *buf, unsigned int len, struct ecdh *p);
+
+#endif
diff --git a/include/crypto/internal/aead.h b/include/crypto/internal/aead.h
index da3864991d4c..6ad8e31d3868 100644
--- a/include/crypto/internal/aead.h
+++ b/include/crypto/internal/aead.h
@@ -159,6 +159,27 @@ static inline struct aead_request *aead_get_backlog(struct aead_queue *queue)
return req ? container_of(req, struct aead_request, base) : NULL;
}
+static inline unsigned int crypto_aead_alg_chunksize(struct aead_alg *alg)
+{
+ return alg->chunksize;
+}
+
+/**
+ * crypto_aead_chunksize() - obtain chunk size
+ * @tfm: cipher handle
+ *
+ * The block size is set to one for ciphers such as CCM. However,
+ * you still need to provide incremental updates in multiples of
+ * the underlying block size as the IV does not have sub-block
+ * granularity. This is known in this API as the chunk size.
+ *
+ * Return: chunk size in bytes
+ */
+static inline unsigned int crypto_aead_chunksize(struct crypto_aead *tfm)
+{
+ return crypto_aead_alg_chunksize(crypto_aead_alg(tfm));
+}
+
int crypto_register_aead(struct aead_alg *alg);
void crypto_unregister_aead(struct aead_alg *alg);
int crypto_register_aeads(struct aead_alg *algs, int count);
diff --git a/include/crypto/internal/geniv.h b/include/crypto/internal/geniv.h
index 59333635e712..2bcfb931bc5b 100644
--- a/include/crypto/internal/geniv.h
+++ b/include/crypto/internal/geniv.h
@@ -20,7 +20,7 @@
struct aead_geniv_ctx {
spinlock_t lock;
struct crypto_aead *child;
- struct crypto_blkcipher *null;
+ struct crypto_skcipher *sknull;
u8 salt[] __attribute__ ((aligned(__alignof__(u32))));
};
diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h
index 49dae16f8929..1d4f365d8f03 100644
--- a/include/crypto/internal/hash.h
+++ b/include/crypto/internal/hash.h
@@ -114,14 +114,10 @@ int shash_ahash_update(struct ahash_request *req, struct shash_desc *desc);
int shash_ahash_finup(struct ahash_request *req, struct shash_desc *desc);
int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc);
-int shash_ahash_mcryptd_update(struct ahash_request *req,
- struct shash_desc *desc);
-int shash_ahash_mcryptd_final(struct ahash_request *req,
- struct shash_desc *desc);
-int shash_ahash_mcryptd_finup(struct ahash_request *req,
- struct shash_desc *desc);
-int shash_ahash_mcryptd_digest(struct ahash_request *req,
- struct shash_desc *desc);
+int ahash_mcryptd_update(struct ahash_request *desc);
+int ahash_mcryptd_final(struct ahash_request *desc);
+int ahash_mcryptd_finup(struct ahash_request *desc);
+int ahash_mcryptd_digest(struct ahash_request *desc);
int crypto_init_shash_ops_async(struct crypto_tfm *tfm);
diff --git a/include/crypto/internal/kpp.h b/include/crypto/internal/kpp.h
new file mode 100644
index 000000000000..ad3acf3649be
--- /dev/null
+++ b/include/crypto/internal/kpp.h
@@ -0,0 +1,64 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto <salvatore.benedetto@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+#ifndef _CRYPTO_KPP_INT_H
+#define _CRYPTO_KPP_INT_H
+#include <crypto/kpp.h>
+#include <crypto/algapi.h>
+
+/*
+ * Transform internal helpers.
+ */
+static inline void *kpp_request_ctx(struct kpp_request *req)
+{
+ return req->__ctx;
+}
+
+static inline void *kpp_tfm_ctx(struct crypto_kpp *tfm)
+{
+ return tfm->base.__crt_ctx;
+}
+
+static inline void kpp_request_complete(struct kpp_request *req, int err)
+{
+ req->base.complete(&req->base, err);
+}
+
+static inline const char *kpp_alg_name(struct crypto_kpp *tfm)
+{
+ return crypto_kpp_tfm(tfm)->__crt_alg->cra_name;
+}
+
+/**
+ * crypto_register_kpp() -- Register key-agreement protocol primitives algorithm
+ *
+ * Function registers an implementation of a key-agreement protocol primitive
+ * algorithm
+ *
+ * @alg: algorithm definition
+ *
+ * Return: zero on success; error code in case of error
+ */
+int crypto_register_kpp(struct kpp_alg *alg);
+
+/**
+ * crypto_unregister_kpp() -- Unregister key-agreement protocol primitive
+ * algorithm
+ *
+ * Function unregisters an implementation of a key-agreement protocol primitive
+ * algorithm
+ *
+ * @alg: algorithm definition
+ */
+void crypto_unregister_kpp(struct kpp_alg *alg);
+
+#endif
diff --git a/include/crypto/internal/rsa.h b/include/crypto/internal/rsa.h
index c7585bdecbc2..9e8f1590de98 100644
--- a/include/crypto/internal/rsa.h
+++ b/include/crypto/internal/rsa.h
@@ -12,12 +12,44 @@
*/
#ifndef _RSA_HELPER_
#define _RSA_HELPER_
-#include <linux/mpi.h>
+#include <linux/types.h>
+/**
+ * rsa_key - RSA key structure
+ * @n : RSA modulus raw byte stream
+ * @e : RSA public exponent raw byte stream
+ * @d : RSA private exponent raw byte stream
+ * @p : RSA prime factor p of n raw byte stream
+ * @q : RSA prime factor q of n raw byte stream
+ * @dp : RSA exponent d mod (p - 1) raw byte stream
+ * @dq : RSA exponent d mod (q - 1) raw byte stream
+ * @qinv : RSA CRT coefficient q^(-1) mod p raw byte stream
+ * @n_sz : length in bytes of RSA modulus n
+ * @e_sz : length in bytes of RSA public exponent
+ * @d_sz : length in bytes of RSA private exponent
+ * @p_sz : length in bytes of p field
+ * @q_sz : length in bytes of q field
+ * @dp_sz : length in bytes of dp field
+ * @dq_sz : length in bytes of dq field
+ * @qinv_sz : length in bytes of qinv field
+ */
struct rsa_key {
- MPI n;
- MPI e;
- MPI d;
+ const u8 *n;
+ const u8 *e;
+ const u8 *d;
+ const u8 *p;
+ const u8 *q;
+ const u8 *dp;
+ const u8 *dq;
+ const u8 *qinv;
+ size_t n_sz;
+ size_t e_sz;
+ size_t d_sz;
+ size_t p_sz;
+ size_t q_sz;
+ size_t dp_sz;
+ size_t dq_sz;
+ size_t qinv_sz;
};
int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
@@ -26,7 +58,5 @@ int rsa_parse_pub_key(struct rsa_key *rsa_key, const void *key,
int rsa_parse_priv_key(struct rsa_key *rsa_key, const void *key,
unsigned int key_len);
-void rsa_free_key(struct rsa_key *rsa_key);
-
extern struct crypto_template rsa_pkcs1pad_tmpl;
#endif
diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h
index 2cf7a61ece59..a21a95e1a375 100644
--- a/include/crypto/internal/skcipher.h
+++ b/include/crypto/internal/skcipher.h
@@ -19,12 +19,46 @@
struct rtattr;
+struct skcipher_instance {
+ void (*free)(struct skcipher_instance *inst);
+ union {
+ struct {
+ char head[offsetof(struct skcipher_alg, base)];
+ struct crypto_instance base;
+ } s;
+ struct skcipher_alg alg;
+ };
+};
+
struct crypto_skcipher_spawn {
struct crypto_spawn base;
};
extern const struct crypto_type crypto_givcipher_type;
+static inline struct crypto_instance *skcipher_crypto_instance(
+ struct skcipher_instance *inst)
+{
+ return &inst->s.base;
+}
+
+static inline struct skcipher_instance *skcipher_alg_instance(
+ struct crypto_skcipher *skcipher)
+{
+ return container_of(crypto_skcipher_alg(skcipher),
+ struct skcipher_instance, alg);
+}
+
+static inline void *skcipher_instance_ctx(struct skcipher_instance *inst)
+{
+ return crypto_instance_ctx(skcipher_crypto_instance(inst));
+}
+
+static inline void skcipher_request_complete(struct skcipher_request *req, int err)
+{
+ req->base.complete(&req->base, err);
+}
+
static inline void crypto_set_skcipher_spawn(
struct crypto_skcipher_spawn *spawn, struct crypto_instance *inst)
{
@@ -34,6 +68,12 @@ static inline void crypto_set_skcipher_spawn(
int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name,
u32 type, u32 mask);
+static inline int crypto_grab_skcipher2(struct crypto_skcipher_spawn *spawn,
+ const char *name, u32 type, u32 mask)
+{
+ return crypto_grab_skcipher(spawn, name, type, mask);
+}
+
struct crypto_alg *crypto_lookup_skcipher(const char *name, u32 type, u32 mask);
static inline void crypto_drop_skcipher(struct crypto_skcipher_spawn *spawn)
@@ -41,54 +81,42 @@ static inline void crypto_drop_skcipher(struct crypto_skcipher_spawn *spawn)
crypto_drop_spawn(&spawn->base);
}
-static inline struct crypto_alg *crypto_skcipher_spawn_alg(
+static inline struct skcipher_alg *crypto_skcipher_spawn_alg(
struct crypto_skcipher_spawn *spawn)
{
- return spawn->base.alg;
+ return container_of(spawn->base.alg, struct skcipher_alg, base);
}
-static inline struct crypto_ablkcipher *crypto_spawn_skcipher(
+static inline struct skcipher_alg *crypto_spawn_skcipher_alg(
struct crypto_skcipher_spawn *spawn)
{
- return __crypto_ablkcipher_cast(
- crypto_spawn_tfm(&spawn->base, crypto_skcipher_type(0),
- crypto_skcipher_mask(0)));
+ return crypto_skcipher_spawn_alg(spawn);
}
-int skcipher_null_givencrypt(struct skcipher_givcrypt_request *req);
-int skcipher_null_givdecrypt(struct skcipher_givcrypt_request *req);
-const char *crypto_default_geniv(const struct crypto_alg *alg);
-
-struct crypto_instance *skcipher_geniv_alloc(struct crypto_template *tmpl,
- struct rtattr **tb, u32 type,
- u32 mask);
-void skcipher_geniv_free(struct crypto_instance *inst);
-int skcipher_geniv_init(struct crypto_tfm *tfm);
-void skcipher_geniv_exit(struct crypto_tfm *tfm);
-
-static inline struct crypto_ablkcipher *skcipher_geniv_cipher(
- struct crypto_ablkcipher *geniv)
+static inline struct crypto_skcipher *crypto_spawn_skcipher(
+ struct crypto_skcipher_spawn *spawn)
{
- return crypto_ablkcipher_crt(geniv)->base;
+ return crypto_spawn_tfm2(&spawn->base);
}
-static inline int skcipher_enqueue_givcrypt(
- struct crypto_queue *queue, struct skcipher_givcrypt_request *request)
+static inline struct crypto_skcipher *crypto_spawn_skcipher2(
+ struct crypto_skcipher_spawn *spawn)
{
- return ablkcipher_enqueue_request(queue, &request->creq);
+ return crypto_spawn_skcipher(spawn);
}
-static inline struct skcipher_givcrypt_request *skcipher_dequeue_givcrypt(
- struct crypto_queue *queue)
+static inline void crypto_skcipher_set_reqsize(
+ struct crypto_skcipher *skcipher, unsigned int reqsize)
{
- return skcipher_givcrypt_cast(crypto_dequeue_request(queue));
+ skcipher->reqsize = reqsize;
}
-static inline void *skcipher_givcrypt_reqctx(
- struct skcipher_givcrypt_request *req)
-{
- return ablkcipher_request_ctx(&req->creq);
-}
+int crypto_register_skcipher(struct skcipher_alg *alg);
+void crypto_unregister_skcipher(struct skcipher_alg *alg);
+int crypto_register_skciphers(struct skcipher_alg *algs, int count);
+void crypto_unregister_skciphers(struct skcipher_alg *algs, int count);
+int skcipher_register_instance(struct crypto_template *tmpl,
+ struct skcipher_instance *inst);
static inline void ablkcipher_request_complete(struct ablkcipher_request *req,
int err)
@@ -96,12 +124,6 @@ static inline void ablkcipher_request_complete(struct ablkcipher_request *req,
req->base.complete(&req->base, err);
}
-static inline void skcipher_givcrypt_complete(
- struct skcipher_givcrypt_request *req, int err)
-{
- ablkcipher_request_complete(&req->creq, err);
-}
-
static inline u32 ablkcipher_request_flags(struct ablkcipher_request *req)
{
return req->base.flags;
@@ -122,5 +144,31 @@ static inline u32 skcipher_request_flags(struct skcipher_request *req)
return req->base.flags;
}
+static inline unsigned int crypto_skcipher_alg_min_keysize(
+ struct skcipher_alg *alg)
+{
+ if ((alg->base.cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+ CRYPTO_ALG_TYPE_BLKCIPHER)
+ return alg->base.cra_blkcipher.min_keysize;
+
+ if (alg->base.cra_ablkcipher.encrypt)
+ return alg->base.cra_ablkcipher.min_keysize;
+
+ return alg->min_keysize;
+}
+
+static inline unsigned int crypto_skcipher_alg_max_keysize(
+ struct skcipher_alg *alg)
+{
+ if ((alg->base.cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+ CRYPTO_ALG_TYPE_BLKCIPHER)
+ return alg->base.cra_blkcipher.max_keysize;
+
+ if (alg->base.cra_ablkcipher.encrypt)
+ return alg->base.cra_ablkcipher.max_keysize;
+
+ return alg->max_keysize;
+}
+
#endif /* _CRYPTO_INTERNAL_SKCIPHER_H */
diff --git a/include/crypto/kpp.h b/include/crypto/kpp.h
new file mode 100644
index 000000000000..30791f75c180
--- /dev/null
+++ b/include/crypto/kpp.h
@@ -0,0 +1,330 @@
+/*
+ * Key-agreement Protocol Primitives (KPP)
+ *
+ * Copyright (c) 2016, Intel Corporation
+ * Authors: Salvatore Benedetto <salvatore.benedetto@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ */
+
+#ifndef _CRYPTO_KPP_
+#define _CRYPTO_KPP_
+#include <linux/crypto.h>
+
+/**
+ * struct kpp_request
+ *
+ * @base: Common attributes for async crypto requests
+ * @src: Source data
+ * @dst: Destination data
+ * @src_len: Size of the input buffer
+ * @dst_len: Size of the output buffer. It needs to be at least
+ * as big as the expected result depending on the operation
+ * After operation it will be updated with the actual size of the
+ * result. In case of error where the dst sgl size was insufficient,
+ * it will be updated to the size required for the operation.
+ * @__ctx: Start of private context data
+ */
+struct kpp_request {
+ struct crypto_async_request base;
+ struct scatterlist *src;
+ struct scatterlist *dst;
+ unsigned int src_len;
+ unsigned int dst_len;
+ void *__ctx[] CRYPTO_MINALIGN_ATTR;
+};
+
+/**
+ * struct crypto_kpp - user-instantiated object which encapsulate
+ * algorithms and core processing logic
+ *
+ * @base: Common crypto API algorithm data structure
+ */
+struct crypto_kpp {
+ struct crypto_tfm base;
+};
+
+/**
+ * struct kpp_alg - generic key-agreement protocol primitives
+ *
+ * @set_secret: Function invokes the protocol specific function to
+ * store the secret private key along with parameters.
+ * The implementation knows how to decode thie buffer
+ * @generate_public_key: Function generate the public key to be sent to the
+ * counterpart. In case of error, where output is not big
+ * enough req->dst_len will be updated to the size
+ * required
+ * @compute_shared_secret: Function compute the shared secret as defined by
+ * the algorithm. The result is given back to the user.
+ * In case of error, where output is not big enough,
+ * req->dst_len will be updated to the size required
+ * @max_size: Function returns the size of the output buffer
+ * @init: Initialize the object. This is called only once at
+ * instantiation time. In case the cryptographic hardware
+ * needs to be initialized. Software fallback should be
+ * put in place here.
+ * @exit: Undo everything @init did.
+ *
+ * @reqsize: Request context size required by algorithm
+ * implementation
+ * @base Common crypto API algorithm data structure
+ */
+struct kpp_alg {
+ int (*set_secret)(struct crypto_kpp *tfm, void *buffer,
+ unsigned int len);
+ int (*generate_public_key)(struct kpp_request *req);
+ int (*compute_shared_secret)(struct kpp_request *req);
+
+ int (*max_size)(struct crypto_kpp *tfm);
+
+ int (*init)(struct crypto_kpp *tfm);
+ void (*exit)(struct crypto_kpp *tfm);
+
+ unsigned int reqsize;
+ struct crypto_alg base;
+};
+
+/**
+ * DOC: Generic Key-agreement Protocol Primitevs API
+ *
+ * The KPP API is used with the algorithm type
+ * CRYPTO_ALG_TYPE_KPP (listed as type "kpp" in /proc/crypto)
+ */
+
+/**
+ * crypto_alloc_kpp() - allocate KPP tfm handle
+ * @alg_name: is the name of the kpp algorithm (e.g. "dh", "ecdh")
+ * @type: specifies the type of the algorithm
+ * @mask: specifies the mask for the algorithm
+ *
+ * Allocate a handle for kpp algorithm. The returned struct crypto_kpp
+ * is requeried for any following API invocation
+ *
+ * Return: allocated handle in case of success; IS_ERR() is true in case of
+ * an error, PTR_ERR() returns the error code.
+ */
+struct crypto_kpp *crypto_alloc_kpp(const char *alg_name, u32 type, u32 mask);
+
+static inline struct crypto_tfm *crypto_kpp_tfm(struct crypto_kpp *tfm)
+{
+ return &tfm->base;
+}
+
+static inline struct kpp_alg *__crypto_kpp_alg(struct crypto_alg *alg)
+{
+ return container_of(alg, struct kpp_alg, base);
+}
+
+static inline struct crypto_kpp *__crypto_kpp_tfm(struct crypto_tfm *tfm)
+{
+ return container_of(tfm, struct crypto_kpp, base);
+}
+
+static inline struct kpp_alg *crypto_kpp_alg(struct crypto_kpp *tfm)
+{
+ return __crypto_kpp_alg(crypto_kpp_tfm(tfm)->__crt_alg);
+}
+
+static inline unsigned int crypto_kpp_reqsize(struct crypto_kpp *tfm)
+{
+ return crypto_kpp_alg(tfm)->reqsize;
+}
+
+static inline void kpp_request_set_tfm(struct kpp_request *req,
+ struct crypto_kpp *tfm)
+{
+ req->base.tfm = crypto_kpp_tfm(tfm);
+}
+
+static inline struct crypto_kpp *crypto_kpp_reqtfm(struct kpp_request *req)
+{
+ return __crypto_kpp_tfm(req->base.tfm);
+}
+
+/**
+ * crypto_free_kpp() - free KPP tfm handle
+ *
+ * @tfm: KPP tfm handle allocated with crypto_alloc_kpp()
+ */
+static inline void crypto_free_kpp(struct crypto_kpp *tfm)
+{
+ crypto_destroy_tfm(tfm, crypto_kpp_tfm(tfm));
+}
+
+/**
+ * kpp_request_alloc() - allocates kpp request
+ *
+ * @tfm: KPP tfm handle allocated with crypto_alloc_kpp()
+ * @gfp: allocation flags
+ *
+ * Return: allocated handle in case of success or NULL in case of an error.
+ */
+static inline struct kpp_request *kpp_request_alloc(struct crypto_kpp *tfm,
+ gfp_t gfp)
+{
+ struct kpp_request *req;
+
+ req = kmalloc(sizeof(*req) + crypto_kpp_reqsize(tfm), gfp);
+ if (likely(req))
+ kpp_request_set_tfm(req, tfm);
+
+ return req;
+}
+
+/**
+ * kpp_request_free() - zeroize and free kpp request
+ *
+ * @req: request to free
+ */
+static inline void kpp_request_free(struct kpp_request *req)
+{
+ kzfree(req);
+}
+
+/**
+ * kpp_request_set_callback() - Sets an asynchronous callback.
+ *
+ * Callback will be called when an asynchronous operation on a given
+ * request is finished.
+ *
+ * @req: request that the callback will be set for
+ * @flgs: specify for instance if the operation may backlog
+ * @cmpl: callback which will be called
+ * @data: private data used by the caller
+ */
+static inline void kpp_request_set_callback(struct kpp_request *req,
+ u32 flgs,
+ crypto_completion_t cmpl,
+ void *data)
+{
+ req->base.complete = cmpl;
+ req->base.data = data;
+ req->base.flags = flgs;
+}
+
+/**
+ * kpp_request_set_input() - Sets input buffer
+ *
+ * Sets parameters required by generate_public_key
+ *
+ * @req: kpp request
+ * @input: ptr to input scatter list
+ * @input_len: size of the input scatter list
+ */
+static inline void kpp_request_set_input(struct kpp_request *req,
+ struct scatterlist *input,
+ unsigned int input_len)
+{
+ req->src = input;
+ req->src_len = input_len;
+}
+
+/**
+ * kpp_request_set_output() - Sets output buffer
+ *
+ * Sets parameters required by kpp operation
+ *
+ * @req: kpp request
+ * @output: ptr to output scatter list
+ * @output_len: size of the output scatter list
+ */
+static inline void kpp_request_set_output(struct kpp_request *req,
+ struct scatterlist *output,
+ unsigned int output_len)
+{
+ req->dst = output;
+ req->dst_len = output_len;
+}
+
+enum {
+ CRYPTO_KPP_SECRET_TYPE_UNKNOWN,
+ CRYPTO_KPP_SECRET_TYPE_DH,
+ CRYPTO_KPP_SECRET_TYPE_ECDH,
+};
+
+/**
+ * struct kpp_secret - small header for packing secret buffer
+ *
+ * @type: define type of secret. Each kpp type will define its own
+ * @len: specify the len of the secret, include the header, that
+ * follows the struct
+ */
+struct kpp_secret {
+ unsigned short type;
+ unsigned short len;
+};
+
+/**
+ * crypto_kpp_set_secret() - Invoke kpp operation
+ *
+ * Function invokes the specific kpp operation for a given alg.
+ *
+ * @tfm: tfm handle
+ *
+ * Return: zero on success; error code in case of error
+ */
+static inline int crypto_kpp_set_secret(struct crypto_kpp *tfm, void *buffer,
+ unsigned int len)
+{
+ struct kpp_alg *alg = crypto_kpp_alg(tfm);
+
+ return alg->set_secret(tfm, buffer, len);
+}
+
+/**
+ * crypto_kpp_generate_public_key() - Invoke kpp operation
+ *
+ * Function invokes the specific kpp operation for generating the public part
+ * for a given kpp algorithm
+ *
+ * @req: kpp key request
+ *
+ * Return: zero on success; error code in case of error
+ */
+static inline int crypto_kpp_generate_public_key(struct kpp_request *req)
+{
+ struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+ struct kpp_alg *alg = crypto_kpp_alg(tfm);
+
+ return alg->generate_public_key(req);
+}
+
+/**
+ * crypto_kpp_compute_shared_secret() - Invoke kpp operation
+ *
+ * Function invokes the specific kpp operation for computing the shared secret
+ * for a given kpp algorithm.
+ *
+ * @req: kpp key request
+ *
+ * Return: zero on success; error code in case of error
+ */
+static inline int crypto_kpp_compute_shared_secret(struct kpp_request *req)
+{
+ struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
+ struct kpp_alg *alg = crypto_kpp_alg(tfm);
+
+ return alg->compute_shared_secret(req);
+}
+
+/**
+ * crypto_kpp_maxsize() - Get len for output buffer
+ *
+ * Function returns the output buffer size required
+ *
+ * @tfm: KPP tfm handle allocated with crypto_alloc_kpp()
+ *
+ * Return: minimum len for output buffer or error code if key hasn't been set
+ */
+static inline int crypto_kpp_maxsize(struct crypto_kpp *tfm)
+{
+ struct kpp_alg *alg = crypto_kpp_alg(tfm);
+
+ return alg->max_size(tfm);
+}
+
+#endif
diff --git a/include/crypto/mcryptd.h b/include/crypto/mcryptd.h
index c23ee1f7ee80..4a53c0d38cd2 100644
--- a/include/crypto/mcryptd.h
+++ b/include/crypto/mcryptd.h
@@ -39,7 +39,7 @@ struct mcryptd_instance_ctx {
};
struct mcryptd_hash_ctx {
- struct crypto_shash *child;
+ struct crypto_ahash *child;
struct mcryptd_alg_state *alg_state;
};
@@ -59,13 +59,13 @@ struct mcryptd_hash_request_ctx {
struct crypto_hash_walk walk;
u8 *out;
int flag;
- struct shash_desc desc;
+ struct ahash_request areq;
};
struct mcryptd_ahash *mcryptd_alloc_ahash(const char *alg_name,
u32 type, u32 mask);
-struct crypto_shash *mcryptd_ahash_child(struct mcryptd_ahash *tfm);
-struct shash_desc *mcryptd_shash_desc(struct ahash_request *req);
+struct crypto_ahash *mcryptd_ahash_child(struct mcryptd_ahash *tfm);
+struct ahash_request *mcryptd_ahash_desc(struct ahash_request *req);
void mcryptd_free_ahash(struct mcryptd_ahash *tfm);
void mcryptd_flusher(struct work_struct *work);
diff --git a/include/crypto/null.h b/include/crypto/null.h
index 06dc30d9f56e..3f0c59fb0a61 100644
--- a/include/crypto/null.h
+++ b/include/crypto/null.h
@@ -8,7 +8,17 @@
#define NULL_DIGEST_SIZE 0
#define NULL_IV_SIZE 0
-struct crypto_blkcipher *crypto_get_default_null_skcipher(void);
+struct crypto_skcipher *crypto_get_default_null_skcipher(void);
void crypto_put_default_null_skcipher(void);
+static inline struct crypto_skcipher *crypto_get_default_null_skcipher2(void)
+{
+ return crypto_get_default_null_skcipher();
+}
+
+static inline void crypto_put_default_null_skcipher2(void)
+{
+ crypto_put_default_null_skcipher();
+}
+
#endif
diff --git a/include/crypto/scatterwalk.h b/include/crypto/scatterwalk.h
index 35f99b68d037..880e6be9e95e 100644
--- a/include/crypto/scatterwalk.h
+++ b/include/crypto/scatterwalk.h
@@ -16,14 +16,10 @@
#ifndef _CRYPTO_SCATTERWALK_H
#define _CRYPTO_SCATTERWALK_H
-#include <asm/kmap_types.h>
#include <crypto/algapi.h>
-#include <linux/hardirq.h>
#include <linux/highmem.h>
#include <linux/kernel.h>
-#include <linux/mm.h>
#include <linux/scatterlist.h>
-#include <linux/sched.h>
static inline void scatterwalk_crypto_chain(struct scatterlist *head,
struct scatterlist *sg,
@@ -83,17 +79,53 @@ static inline void scatterwalk_unmap(void *vaddr)
kunmap_atomic(vaddr);
}
-void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg);
+static inline void scatterwalk_start(struct scatter_walk *walk,
+ struct scatterlist *sg)
+{
+ walk->sg = sg;
+ walk->offset = sg->offset;
+}
+
+static inline void *scatterwalk_map(struct scatter_walk *walk)
+{
+ return kmap_atomic(scatterwalk_page(walk)) +
+ offset_in_page(walk->offset);
+}
+
+static inline void scatterwalk_pagedone(struct scatter_walk *walk, int out,
+ unsigned int more)
+{
+ if (out) {
+ struct page *page;
+
+ page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
+ /* Test ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE first as
+ * PageSlab cannot be optimised away per se due to
+ * use of volatile pointer.
+ */
+ if (ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE && !PageSlab(page))
+ flush_dcache_page(page);
+ }
+
+ if (more && walk->offset >= walk->sg->offset + walk->sg->length)
+ scatterwalk_start(walk, sg_next(walk->sg));
+}
+
+static inline void scatterwalk_done(struct scatter_walk *walk, int out,
+ int more)
+{
+ if (!more || walk->offset >= walk->sg->offset + walk->sg->length ||
+ !(walk->offset & (PAGE_SIZE - 1)))
+ scatterwalk_pagedone(walk, out, more);
+}
+
void scatterwalk_copychunks(void *buf, struct scatter_walk *walk,
size_t nbytes, int out);
void *scatterwalk_map(struct scatter_walk *walk);
-void scatterwalk_done(struct scatter_walk *walk, int out, int more);
void scatterwalk_map_and_copy(void *buf, struct scatterlist *sg,
unsigned int start, unsigned int nbytes, int out);
-int scatterwalk_bytes_sglen(struct scatterlist *sg, int num_bytes);
-
struct scatterlist *scatterwalk_ffwd(struct scatterlist dst[2],
struct scatterlist *src,
unsigned int len);
diff --git a/include/crypto/sha3.h b/include/crypto/sha3.h
new file mode 100644
index 000000000000..f4c9f68f5ffe
--- /dev/null
+++ b/include/crypto/sha3.h
@@ -0,0 +1,29 @@
+/*
+ * Common values for SHA-3 algorithms
+ */
+#ifndef __CRYPTO_SHA3_H__
+#define __CRYPTO_SHA3_H__
+
+#define SHA3_224_DIGEST_SIZE (224 / 8)
+#define SHA3_224_BLOCK_SIZE (200 - 2 * SHA3_224_DIGEST_SIZE)
+
+#define SHA3_256_DIGEST_SIZE (256 / 8)
+#define SHA3_256_BLOCK_SIZE (200 - 2 * SHA3_256_DIGEST_SIZE)
+
+#define SHA3_384_DIGEST_SIZE (384 / 8)
+#define SHA3_384_BLOCK_SIZE (200 - 2 * SHA3_384_DIGEST_SIZE)
+
+#define SHA3_512_DIGEST_SIZE (512 / 8)
+#define SHA3_512_BLOCK_SIZE (200 - 2 * SHA3_512_DIGEST_SIZE)
+
+struct sha3_state {
+ u64 st[25];
+ unsigned int md_len;
+ unsigned int rsiz;
+ unsigned int rsizw;
+
+ unsigned int partial;
+ u8 buf[SHA3_224_BLOCK_SIZE];
+};
+
+#endif
diff --git a/include/crypto/skcipher.h b/include/crypto/skcipher.h
index 0f987f50bb52..cc4d98a7892e 100644
--- a/include/crypto/skcipher.h
+++ b/include/crypto/skcipher.h
@@ -65,86 +65,80 @@ struct crypto_skcipher {
struct crypto_tfm base;
};
-#define SKCIPHER_REQUEST_ON_STACK(name, tfm) \
- char __##name##_desc[sizeof(struct skcipher_request) + \
- crypto_skcipher_reqsize(tfm)] CRYPTO_MINALIGN_ATTR; \
- struct skcipher_request *name = (void *)__##name##_desc
-
-static inline struct crypto_ablkcipher *skcipher_givcrypt_reqtfm(
- struct skcipher_givcrypt_request *req)
-{
- return crypto_ablkcipher_reqtfm(&req->creq);
-}
+/**
+ * struct skcipher_alg - symmetric key cipher definition
+ * @min_keysize: Minimum key size supported by the transformation. This is the
+ * smallest key length supported by this transformation algorithm.
+ * This must be set to one of the pre-defined values as this is
+ * not hardware specific. Possible values for this field can be
+ * found via git grep "_MIN_KEY_SIZE" include/crypto/
+ * @max_keysize: Maximum key size supported by the transformation. This is the
+ * largest key length supported by this transformation algorithm.
+ * This must be set to one of the pre-defined values as this is
+ * not hardware specific. Possible values for this field can be
+ * found via git grep "_MAX_KEY_SIZE" include/crypto/
+ * @setkey: Set key for the transformation. This function is used to either
+ * program a supplied key into the hardware or store the key in the
+ * transformation context for programming it later. Note that this
+ * function does modify the transformation context. This function can
+ * be called multiple times during the existence of the transformation
+ * object, so one must make sure the key is properly reprogrammed into
+ * the hardware. This function is also responsible for checking the key
+ * length for validity. In case a software fallback was put in place in
+ * the @cra_init call, this function might need to use the fallback if
+ * the algorithm doesn't support all of the key sizes.
+ * @encrypt: Encrypt a scatterlist of blocks. This function is used to encrypt
+ * the supplied scatterlist containing the blocks of data. The crypto
+ * API consumer is responsible for aligning the entries of the
+ * scatterlist properly and making sure the chunks are correctly
+ * sized. In case a software fallback was put in place in the
+ * @cra_init call, this function might need to use the fallback if
+ * the algorithm doesn't support all of the key sizes. In case the
+ * key was stored in transformation context, the key might need to be
+ * re-programmed into the hardware in this function. This function
+ * shall not modify the transformation context, as this function may
+ * be called in parallel with the same transformation object.
+ * @decrypt: Decrypt a single block. This is a reverse counterpart to @encrypt
+ * and the conditions are exactly the same.
+ * @init: Initialize the cryptographic transformation object. This function
+ * is used to initialize the cryptographic transformation object.
+ * This function is called only once at the instantiation time, right
+ * after the transformation context was allocated. In case the
+ * cryptographic hardware has some special requirements which need to
+ * be handled by software, this function shall check for the precise
+ * requirement of the transformation and put any software fallbacks
+ * in place.
+ * @exit: Deinitialize the cryptographic transformation object. This is a
+ * counterpart to @init, used to remove various changes set in
+ * @init.
+ * @ivsize: IV size applicable for transformation. The consumer must provide an
+ * IV of exactly that size to perform the encrypt or decrypt operation.
+ * @chunksize: Equal to the block size except for stream ciphers such as
+ * CTR where it is set to the underlying block size.
+ * @base: Definition of a generic crypto algorithm.
+ *
+ * All fields except @ivsize are mandatory and must be filled.
+ */
+struct skcipher_alg {
+ int (*setkey)(struct crypto_skcipher *tfm, const u8 *key,
+ unsigned int keylen);
+ int (*encrypt)(struct skcipher_request *req);
+ int (*decrypt)(struct skcipher_request *req);
+ int (*init)(struct crypto_skcipher *tfm);
+ void (*exit)(struct crypto_skcipher *tfm);
-static inline int crypto_skcipher_givencrypt(
- struct skcipher_givcrypt_request *req)
-{
- struct ablkcipher_tfm *crt =
- crypto_ablkcipher_crt(skcipher_givcrypt_reqtfm(req));
- return crt->givencrypt(req);
-};
+ unsigned int min_keysize;
+ unsigned int max_keysize;
+ unsigned int ivsize;
+ unsigned int chunksize;
-static inline int crypto_skcipher_givdecrypt(
- struct skcipher_givcrypt_request *req)
-{
- struct ablkcipher_tfm *crt =
- crypto_ablkcipher_crt(skcipher_givcrypt_reqtfm(req));
- return crt->givdecrypt(req);
+ struct crypto_alg base;
};
-static inline void skcipher_givcrypt_set_tfm(
- struct skcipher_givcrypt_request *req, struct crypto_ablkcipher *tfm)
-{
- req->creq.base.tfm = crypto_ablkcipher_tfm(tfm);
-}
-
-static inline struct skcipher_givcrypt_request *skcipher_givcrypt_cast(
- struct crypto_async_request *req)
-{
- return container_of(ablkcipher_request_cast(req),
- struct skcipher_givcrypt_request, creq);
-}
-
-static inline struct skcipher_givcrypt_request *skcipher_givcrypt_alloc(
- struct crypto_ablkcipher *tfm, gfp_t gfp)
-{
- struct skcipher_givcrypt_request *req;
-
- req = kmalloc(sizeof(struct skcipher_givcrypt_request) +
- crypto_ablkcipher_reqsize(tfm), gfp);
-
- if (likely(req))
- skcipher_givcrypt_set_tfm(req, tfm);
-
- return req;
-}
-
-static inline void skcipher_givcrypt_free(struct skcipher_givcrypt_request *req)
-{
- kfree(req);
-}
-
-static inline void skcipher_givcrypt_set_callback(
- struct skcipher_givcrypt_request *req, u32 flags,
- crypto_completion_t compl, void *data)
-{
- ablkcipher_request_set_callback(&req->creq, flags, compl, data);
-}
-
-static inline void skcipher_givcrypt_set_crypt(
- struct skcipher_givcrypt_request *req,
- struct scatterlist *src, struct scatterlist *dst,
- unsigned int nbytes, void *iv)
-{
- ablkcipher_request_set_crypt(&req->creq, src, dst, nbytes, iv);
-}
-
-static inline void skcipher_givcrypt_set_giv(
- struct skcipher_givcrypt_request *req, u8 *giv, u64 seq)
-{
- req->giv = giv;
- req->seq = seq;
-}
+#define SKCIPHER_REQUEST_ON_STACK(name, tfm) \
+ char __##name##_desc[sizeof(struct skcipher_request) + \
+ crypto_skcipher_reqsize(tfm)] CRYPTO_MINALIGN_ATTR; \
+ struct skcipher_request *name = (void *)__##name##_desc
/**
* DOC: Symmetric Key Cipher API
@@ -231,12 +225,43 @@ static inline int crypto_has_skcipher(const char *alg_name, u32 type,
crypto_skcipher_mask(mask));
}
+/**
+ * crypto_has_skcipher2() - Search for the availability of an skcipher.
+ * @alg_name: is the cra_name / name or cra_driver_name / driver name of the
+ * skcipher
+ * @type: specifies the type of the skcipher
+ * @mask: specifies the mask for the skcipher
+ *
+ * Return: true when the skcipher is known to the kernel crypto API; false
+ * otherwise
+ */
+int crypto_has_skcipher2(const char *alg_name, u32 type, u32 mask);
+
static inline const char *crypto_skcipher_driver_name(
struct crypto_skcipher *tfm)
{
return crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm));
}
+static inline struct skcipher_alg *crypto_skcipher_alg(
+ struct crypto_skcipher *tfm)
+{
+ return container_of(crypto_skcipher_tfm(tfm)->__crt_alg,
+ struct skcipher_alg, base);
+}
+
+static inline unsigned int crypto_skcipher_alg_ivsize(struct skcipher_alg *alg)
+{
+ if ((alg->base.cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+ CRYPTO_ALG_TYPE_BLKCIPHER)
+ return alg->base.cra_blkcipher.ivsize;
+
+ if (alg->base.cra_ablkcipher.encrypt)
+ return alg->base.cra_ablkcipher.ivsize;
+
+ return alg->ivsize;
+}
+
/**
* crypto_skcipher_ivsize() - obtain IV size
* @tfm: cipher handle
@@ -251,6 +276,36 @@ static inline unsigned int crypto_skcipher_ivsize(struct crypto_skcipher *tfm)
return tfm->ivsize;
}
+static inline unsigned int crypto_skcipher_alg_chunksize(
+ struct skcipher_alg *alg)
+{
+ if ((alg->base.cra_flags & CRYPTO_ALG_TYPE_MASK) ==
+ CRYPTO_ALG_TYPE_BLKCIPHER)
+ return alg->base.cra_blocksize;
+
+ if (alg->base.cra_ablkcipher.encrypt)
+ return alg->base.cra_blocksize;
+
+ return alg->chunksize;
+}
+
+/**
+ * crypto_skcipher_chunksize() - obtain chunk size
+ * @tfm: cipher handle
+ *
+ * The block size is set to one for ciphers such as CTR. However,
+ * you still need to provide incremental updates in multiples of
+ * the underlying block size as the IV does not have sub-block
+ * granularity. This is known in this API as the chunk size.
+ *
+ * Return: chunk size in bytes
+ */
+static inline unsigned int crypto_skcipher_chunksize(
+ struct crypto_skcipher *tfm)
+{
+ return crypto_skcipher_alg_chunksize(crypto_skcipher_alg(tfm));
+}
+
/**
* crypto_skcipher_blocksize() - obtain block size of cipher
* @tfm: cipher handle
diff --git a/include/dt-bindings/leds/leds-pca9532.h b/include/dt-bindings/leds/leds-pca9532.h
new file mode 100644
index 000000000000..4d917aab7e1e
--- /dev/null
+++ b/include/dt-bindings/leds/leds-pca9532.h
@@ -0,0 +1,18 @@
+/*
+ * This header provides constants for pca9532 LED bindings.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef _DT_BINDINGS_LEDS_PCA9532_H
+#define _DT_BINDINGS_LEDS_PCA9532_H
+
+#define PCA9532_TYPE_NONE 0
+#define PCA9532_TYPE_LED 1
+#define PCA9532_TYPE_N2100_BEEP 2
+#define PCA9532_TYPE_GPIO 3
+#define PCA9532_LED_TIMER2 4
+
+#endif /* _DT_BINDINGS_LEDS_PCA9532_H */
diff --git a/include/dt-bindings/pinctrl/stm32f746-pinfunc.h b/include/dt-bindings/pinctrl/stm32f746-pinfunc.h
new file mode 100644
index 000000000000..6348c6a830e9
--- /dev/null
+++ b/include/dt-bindings/pinctrl/stm32f746-pinfunc.h
@@ -0,0 +1,1324 @@
+#ifndef _DT_BINDINGS_STM32F746_PINFUNC_H
+#define _DT_BINDINGS_STM32F746_PINFUNC_H
+
+#define STM32F746_PA0_FUNC_GPIO 0x0
+#define STM32F746_PA0_FUNC_TIM2_CH1_TIM2_ETR 0x2
+#define STM32F746_PA0_FUNC_TIM5_CH1 0x3
+#define STM32F746_PA0_FUNC_TIM8_ETR 0x4
+#define STM32F746_PA0_FUNC_USART2_CTS 0x8
+#define STM32F746_PA0_FUNC_UART4_TX 0x9
+#define STM32F746_PA0_FUNC_SAI2_SD_B 0xb
+#define STM32F746_PA0_FUNC_ETH_MII_CRS 0xc
+#define STM32F746_PA0_FUNC_EVENTOUT 0x10
+#define STM32F746_PA0_FUNC_ANALOG 0x11
+
+#define STM32F746_PA1_FUNC_GPIO 0x100
+#define STM32F746_PA1_FUNC_TIM2_CH2 0x102
+#define STM32F746_PA1_FUNC_TIM5_CH2 0x103
+#define STM32F746_PA1_FUNC_USART2_RTS 0x108
+#define STM32F746_PA1_FUNC_UART4_RX 0x109
+#define STM32F746_PA1_FUNC_QUADSPI_BK1_IO3 0x10a
+#define STM32F746_PA1_FUNC_SAI2_MCLK_B 0x10b
+#define STM32F746_PA1_FUNC_ETH_MII_RX_CLK_ETH_RMII_REF_CLK 0x10c
+#define STM32F746_PA1_FUNC_LCD_R2 0x10f
+#define STM32F746_PA1_FUNC_EVENTOUT 0x110
+#define STM32F746_PA1_FUNC_ANALOG 0x111
+
+#define STM32F746_PA2_FUNC_GPIO 0x200
+#define STM32F746_PA2_FUNC_TIM2_CH3 0x202
+#define STM32F746_PA2_FUNC_TIM5_CH3 0x203
+#define STM32F746_PA2_FUNC_TIM9_CH1 0x204
+#define STM32F746_PA2_FUNC_USART2_TX 0x208
+#define STM32F746_PA2_FUNC_SAI2_SCK_B 0x209
+#define STM32F746_PA2_FUNC_ETH_MDIO 0x20c
+#define STM32F746_PA2_FUNC_LCD_R1 0x20f
+#define STM32F746_PA2_FUNC_EVENTOUT 0x210
+#define STM32F746_PA2_FUNC_ANALOG 0x211
+
+#define STM32F746_PA3_FUNC_GPIO 0x300
+#define STM32F746_PA3_FUNC_TIM2_CH4 0x302
+#define STM32F746_PA3_FUNC_TIM5_CH4 0x303
+#define STM32F746_PA3_FUNC_TIM9_CH2 0x304
+#define STM32F746_PA3_FUNC_USART2_RX 0x308
+#define STM32F746_PA3_FUNC_OTG_HS_ULPI_D0 0x30b
+#define STM32F746_PA3_FUNC_ETH_MII_COL 0x30c
+#define STM32F746_PA3_FUNC_LCD_B5 0x30f
+#define STM32F746_PA3_FUNC_EVENTOUT 0x310
+#define STM32F746_PA3_FUNC_ANALOG 0x311
+
+#define STM32F746_PA4_FUNC_GPIO 0x400
+#define STM32F746_PA4_FUNC_SPI1_NSS_I2S1_WS 0x406
+#define STM32F746_PA4_FUNC_SPI3_NSS_I2S3_WS 0x407
+#define STM32F746_PA4_FUNC_USART2_CK 0x408
+#define STM32F746_PA4_FUNC_OTG_HS_SOF 0x40d
+#define STM32F746_PA4_FUNC_DCMI_HSYNC 0x40e
+#define STM32F746_PA4_FUNC_LCD_VSYNC 0x40f
+#define STM32F746_PA4_FUNC_EVENTOUT 0x410
+#define STM32F746_PA4_FUNC_ANALOG 0x411
+
+#define STM32F746_PA5_FUNC_GPIO 0x500
+#define STM32F746_PA5_FUNC_TIM2_CH1_TIM2_ETR 0x502
+#define STM32F746_PA5_FUNC_TIM8_CH1N 0x504
+#define STM32F746_PA5_FUNC_SPI1_SCK_I2S1_CK 0x506
+#define STM32F746_PA5_FUNC_OTG_HS_ULPI_CK 0x50b
+#define STM32F746_PA5_FUNC_LCD_R4 0x50f
+#define STM32F746_PA5_FUNC_EVENTOUT 0x510
+#define STM32F746_PA5_FUNC_ANALOG 0x511
+
+#define STM32F746_PA6_FUNC_GPIO 0x600
+#define STM32F746_PA6_FUNC_TIM1_BKIN 0x602
+#define STM32F746_PA6_FUNC_TIM3_CH1 0x603
+#define STM32F746_PA6_FUNC_TIM8_BKIN 0x604
+#define STM32F746_PA6_FUNC_SPI1_MISO 0x606
+#define STM32F746_PA6_FUNC_TIM13_CH1 0x60a
+#define STM32F746_PA6_FUNC_DCMI_PIXCLK 0x60e
+#define STM32F746_PA6_FUNC_LCD_G2 0x60f
+#define STM32F746_PA6_FUNC_EVENTOUT 0x610
+#define STM32F746_PA6_FUNC_ANALOG 0x611
+
+#define STM32F746_PA7_FUNC_GPIO 0x700
+#define STM32F746_PA7_FUNC_TIM1_CH1N 0x702
+#define STM32F746_PA7_FUNC_TIM3_CH2 0x703
+#define STM32F746_PA7_FUNC_TIM8_CH1N 0x704
+#define STM32F746_PA7_FUNC_SPI1_MOSI_I2S1_SD 0x706
+#define STM32F746_PA7_FUNC_TIM14_CH1 0x70a
+#define STM32F746_PA7_FUNC_ETH_MII_RX_DV_ETH_RMII_CRS_DV 0x70c
+#define STM32F746_PA7_FUNC_FMC_SDNWE 0x70d
+#define STM32F746_PA7_FUNC_EVENTOUT 0x710
+#define STM32F746_PA7_FUNC_ANALOG 0x711
+
+#define STM32F746_PA8_FUNC_GPIO 0x800
+#define STM32F746_PA8_FUNC_MCO1 0x801
+#define STM32F746_PA8_FUNC_TIM1_CH1 0x802
+#define STM32F746_PA8_FUNC_TIM8_BKIN2 0x804
+#define STM32F746_PA8_FUNC_I2C3_SCL 0x805
+#define STM32F746_PA8_FUNC_USART1_CK 0x808
+#define STM32F746_PA8_FUNC_OTG_FS_SOF 0x80b
+#define STM32F746_PA8_FUNC_LCD_R6 0x80f
+#define STM32F746_PA8_FUNC_EVENTOUT 0x810
+#define STM32F746_PA8_FUNC_ANALOG 0x811
+
+#define STM32F746_PA9_FUNC_GPIO 0x900
+#define STM32F746_PA9_FUNC_TIM1_CH2 0x902
+#define STM32F746_PA9_FUNC_I2C3_SMBA 0x905
+#define STM32F746_PA9_FUNC_SPI2_SCK_I2S2_CK 0x906
+#define STM32F746_PA9_FUNC_USART1_TX 0x908
+#define STM32F746_PA9_FUNC_DCMI_D0 0x90e
+#define STM32F746_PA9_FUNC_EVENTOUT 0x910
+#define STM32F746_PA9_FUNC_ANALOG 0x911
+
+#define STM32F746_PA10_FUNC_GPIO 0xa00
+#define STM32F746_PA10_FUNC_TIM1_CH3 0xa02
+#define STM32F746_PA10_FUNC_USART1_RX 0xa08
+#define STM32F746_PA10_FUNC_OTG_FS_ID 0xa0b
+#define STM32F746_PA10_FUNC_DCMI_D1 0xa0e
+#define STM32F746_PA10_FUNC_EVENTOUT 0xa10
+#define STM32F746_PA10_FUNC_ANALOG 0xa11
+
+#define STM32F746_PA11_FUNC_GPIO 0xb00
+#define STM32F746_PA11_FUNC_TIM1_CH4 0xb02
+#define STM32F746_PA11_FUNC_USART1_CTS 0xb08
+#define STM32F746_PA11_FUNC_CAN1_RX 0xb0a
+#define STM32F746_PA11_FUNC_OTG_FS_DM 0xb0b
+#define STM32F746_PA11_FUNC_LCD_R4 0xb0f
+#define STM32F746_PA11_FUNC_EVENTOUT 0xb10
+#define STM32F746_PA11_FUNC_ANALOG 0xb11
+
+#define STM32F746_PA12_FUNC_GPIO 0xc00
+#define STM32F746_PA12_FUNC_TIM1_ETR 0xc02
+#define STM32F746_PA12_FUNC_USART1_RTS 0xc08
+#define STM32F746_PA12_FUNC_SAI2_FS_B 0xc09
+#define STM32F746_PA12_FUNC_CAN1_TX 0xc0a
+#define STM32F746_PA12_FUNC_OTG_FS_DP 0xc0b
+#define STM32F746_PA12_FUNC_LCD_R5 0xc0f
+#define STM32F746_PA12_FUNC_EVENTOUT 0xc10
+#define STM32F746_PA12_FUNC_ANALOG 0xc11
+
+#define STM32F746_PA13_FUNC_GPIO 0xd00
+#define STM32F746_PA13_FUNC_JTMS_SWDIO 0xd01
+#define STM32F746_PA13_FUNC_EVENTOUT 0xd10
+#define STM32F746_PA13_FUNC_ANALOG 0xd11
+
+#define STM32F746_PA14_FUNC_GPIO 0xe00
+#define STM32F746_PA14_FUNC_JTCK_SWCLK 0xe01
+#define STM32F746_PA14_FUNC_EVENTOUT 0xe10
+#define STM32F746_PA14_FUNC_ANALOG 0xe11
+
+#define STM32F746_PA15_FUNC_GPIO 0xf00
+#define STM32F746_PA15_FUNC_JTDI 0xf01
+#define STM32F746_PA15_FUNC_TIM2_CH1_TIM2_ETR 0xf02
+#define STM32F746_PA15_FUNC_HDMI_CEC 0xf05
+#define STM32F746_PA15_FUNC_SPI1_NSS_I2S1_WS 0xf06
+#define STM32F746_PA15_FUNC_SPI3_NSS_I2S3_WS 0xf07
+#define STM32F746_PA15_FUNC_UART4_RTS 0xf09
+#define STM32F746_PA15_FUNC_EVENTOUT 0xf10
+#define STM32F746_PA15_FUNC_ANALOG 0xf11
+
+
+#define STM32F746_PB0_FUNC_GPIO 0x1000
+#define STM32F746_PB0_FUNC_TIM1_CH2N 0x1002
+#define STM32F746_PB0_FUNC_TIM3_CH3 0x1003
+#define STM32F746_PB0_FUNC_TIM8_CH2N 0x1004
+#define STM32F746_PB0_FUNC_UART4_CTS 0x1009
+#define STM32F746_PB0_FUNC_LCD_R3 0x100a
+#define STM32F746_PB0_FUNC_OTG_HS_ULPI_D1 0x100b
+#define STM32F746_PB0_FUNC_ETH_MII_RXD2 0x100c
+#define STM32F746_PB0_FUNC_EVENTOUT 0x1010
+#define STM32F746_PB0_FUNC_ANALOG 0x1011
+
+#define STM32F746_PB1_FUNC_GPIO 0x1100
+#define STM32F746_PB1_FUNC_TIM1_CH3N 0x1102
+#define STM32F746_PB1_FUNC_TIM3_CH4 0x1103
+#define STM32F746_PB1_FUNC_TIM8_CH3N 0x1104
+#define STM32F746_PB1_FUNC_LCD_R6 0x110a
+#define STM32F746_PB1_FUNC_OTG_HS_ULPI_D2 0x110b
+#define STM32F746_PB1_FUNC_ETH_MII_RXD3 0x110c
+#define STM32F746_PB1_FUNC_EVENTOUT 0x1110
+#define STM32F746_PB1_FUNC_ANALOG 0x1111
+
+#define STM32F746_PB2_FUNC_GPIO 0x1200
+#define STM32F746_PB2_FUNC_SAI1_SD_A 0x1207
+#define STM32F746_PB2_FUNC_SPI3_MOSI_I2S3_SD 0x1208
+#define STM32F746_PB2_FUNC_QUADSPI_CLK 0x120a
+#define STM32F746_PB2_FUNC_EVENTOUT 0x1210
+#define STM32F746_PB2_FUNC_ANALOG 0x1211
+
+#define STM32F746_PB3_FUNC_GPIO 0x1300
+#define STM32F746_PB3_FUNC_JTDO_TRACESWO 0x1301
+#define STM32F746_PB3_FUNC_TIM2_CH2 0x1302
+#define STM32F746_PB3_FUNC_SPI1_SCK_I2S1_CK 0x1306
+#define STM32F746_PB3_FUNC_SPI3_SCK_I2S3_CK 0x1307
+#define STM32F746_PB3_FUNC_EVENTOUT 0x1310
+#define STM32F746_PB3_FUNC_ANALOG 0x1311
+
+#define STM32F746_PB4_FUNC_GPIO 0x1400
+#define STM32F746_PB4_FUNC_NJTRST 0x1401
+#define STM32F746_PB4_FUNC_TIM3_CH1 0x1403
+#define STM32F746_PB4_FUNC_SPI1_MISO 0x1406
+#define STM32F746_PB4_FUNC_SPI3_MISO 0x1407
+#define STM32F746_PB4_FUNC_SPI2_NSS_I2S2_WS 0x1408
+#define STM32F746_PB4_FUNC_EVENTOUT 0x1410
+#define STM32F746_PB4_FUNC_ANALOG 0x1411
+
+#define STM32F746_PB5_FUNC_GPIO 0x1500
+#define STM32F746_PB5_FUNC_TIM3_CH2 0x1503
+#define STM32F746_PB5_FUNC_I2C1_SMBA 0x1505
+#define STM32F746_PB5_FUNC_SPI1_MOSI_I2S1_SD 0x1506
+#define STM32F746_PB5_FUNC_SPI3_MOSI_I2S3_SD 0x1507
+#define STM32F746_PB5_FUNC_CAN2_RX 0x150a
+#define STM32F746_PB5_FUNC_OTG_HS_ULPI_D7 0x150b
+#define STM32F746_PB5_FUNC_ETH_PPS_OUT 0x150c
+#define STM32F746_PB5_FUNC_FMC_SDCKE1 0x150d
+#define STM32F746_PB5_FUNC_DCMI_D10 0x150e
+#define STM32F746_PB5_FUNC_EVENTOUT 0x1510
+#define STM32F746_PB5_FUNC_ANALOG 0x1511
+
+#define STM32F746_PB6_FUNC_GPIO 0x1600
+#define STM32F746_PB6_FUNC_TIM4_CH1 0x1603
+#define STM32F746_PB6_FUNC_HDMI_CEC 0x1604
+#define STM32F746_PB6_FUNC_I2C1_SCL 0x1605
+#define STM32F746_PB6_FUNC_USART1_TX 0x1608
+#define STM32F746_PB6_FUNC_CAN2_TX 0x160a
+#define STM32F746_PB6_FUNC_QUADSPI_BK1_NCS 0x160b
+#define STM32F746_PB6_FUNC_FMC_SDNE1 0x160d
+#define STM32F746_PB6_FUNC_DCMI_D5 0x160e
+#define STM32F746_PB6_FUNC_EVENTOUT 0x1610
+#define STM32F746_PB6_FUNC_ANALOG 0x1611
+
+#define STM32F746_PB7_FUNC_GPIO 0x1700
+#define STM32F746_PB7_FUNC_TIM4_CH2 0x1703
+#define STM32F746_PB7_FUNC_I2C1_SDA 0x1705
+#define STM32F746_PB7_FUNC_USART1_RX 0x1708
+#define STM32F746_PB7_FUNC_FMC_NL 0x170d
+#define STM32F746_PB7_FUNC_DCMI_VSYNC 0x170e
+#define STM32F746_PB7_FUNC_EVENTOUT 0x1710
+#define STM32F746_PB7_FUNC_ANALOG 0x1711
+
+#define STM32F746_PB8_FUNC_GPIO 0x1800
+#define STM32F746_PB8_FUNC_TIM4_CH3 0x1803
+#define STM32F746_PB8_FUNC_TIM10_CH1 0x1804
+#define STM32F746_PB8_FUNC_I2C1_SCL 0x1805
+#define STM32F746_PB8_FUNC_CAN1_RX 0x180a
+#define STM32F746_PB8_FUNC_ETH_MII_TXD3 0x180c
+#define STM32F746_PB8_FUNC_SDMMC1_D4 0x180d
+#define STM32F746_PB8_FUNC_DCMI_D6 0x180e
+#define STM32F746_PB8_FUNC_LCD_B6 0x180f
+#define STM32F746_PB8_FUNC_EVENTOUT 0x1810
+#define STM32F746_PB8_FUNC_ANALOG 0x1811
+
+#define STM32F746_PB9_FUNC_GPIO 0x1900
+#define STM32F746_PB9_FUNC_TIM4_CH4 0x1903
+#define STM32F746_PB9_FUNC_TIM11_CH1 0x1904
+#define STM32F746_PB9_FUNC_I2C1_SDA 0x1905
+#define STM32F746_PB9_FUNC_SPI2_NSS_I2S2_WS 0x1906
+#define STM32F746_PB9_FUNC_CAN1_TX 0x190a
+#define STM32F746_PB9_FUNC_SDMMC1_D5 0x190d
+#define STM32F746_PB9_FUNC_DCMI_D7 0x190e
+#define STM32F746_PB9_FUNC_LCD_B7 0x190f
+#define STM32F746_PB9_FUNC_EVENTOUT 0x1910
+#define STM32F746_PB9_FUNC_ANALOG 0x1911
+
+#define STM32F746_PB10_FUNC_GPIO 0x1a00
+#define STM32F746_PB10_FUNC_TIM2_CH3 0x1a02
+#define STM32F746_PB10_FUNC_I2C2_SCL 0x1a05
+#define STM32F746_PB10_FUNC_SPI2_SCK_I2S2_CK 0x1a06
+#define STM32F746_PB10_FUNC_USART3_TX 0x1a08
+#define STM32F746_PB10_FUNC_OTG_HS_ULPI_D3 0x1a0b
+#define STM32F746_PB10_FUNC_ETH_MII_RX_ER 0x1a0c
+#define STM32F746_PB10_FUNC_LCD_G4 0x1a0f
+#define STM32F746_PB10_FUNC_EVENTOUT 0x1a10
+#define STM32F746_PB10_FUNC_ANALOG 0x1a11
+
+#define STM32F746_PB11_FUNC_GPIO 0x1b00
+#define STM32F746_PB11_FUNC_TIM2_CH4 0x1b02
+#define STM32F746_PB11_FUNC_I2C2_SDA 0x1b05
+#define STM32F746_PB11_FUNC_USART3_RX 0x1b08
+#define STM32F746_PB11_FUNC_OTG_HS_ULPI_D4 0x1b0b
+#define STM32F746_PB11_FUNC_ETH_MII_TX_EN_ETH_RMII_TX_EN 0x1b0c
+#define STM32F746_PB11_FUNC_LCD_G5 0x1b0f
+#define STM32F746_PB11_FUNC_EVENTOUT 0x1b10
+#define STM32F746_PB11_FUNC_ANALOG 0x1b11
+
+#define STM32F746_PB12_FUNC_GPIO 0x1c00
+#define STM32F746_PB12_FUNC_TIM1_BKIN 0x1c02
+#define STM32F746_PB12_FUNC_I2C2_SMBA 0x1c05
+#define STM32F746_PB12_FUNC_SPI2_NSS_I2S2_WS 0x1c06
+#define STM32F746_PB12_FUNC_USART3_CK 0x1c08
+#define STM32F746_PB12_FUNC_CAN2_RX 0x1c0a
+#define STM32F746_PB12_FUNC_OTG_HS_ULPI_D5 0x1c0b
+#define STM32F746_PB12_FUNC_ETH_MII_TXD0_ETH_RMII_TXD0 0x1c0c
+#define STM32F746_PB12_FUNC_OTG_HS_ID 0x1c0d
+#define STM32F746_PB12_FUNC_EVENTOUT 0x1c10
+#define STM32F746_PB12_FUNC_ANALOG 0x1c11
+
+#define STM32F746_PB13_FUNC_GPIO 0x1d00
+#define STM32F746_PB13_FUNC_TIM1_CH1N 0x1d02
+#define STM32F746_PB13_FUNC_SPI2_SCK_I2S2_CK 0x1d06
+#define STM32F746_PB13_FUNC_USART3_CTS 0x1d08
+#define STM32F746_PB13_FUNC_CAN2_TX 0x1d0a
+#define STM32F746_PB13_FUNC_OTG_HS_ULPI_D6 0x1d0b
+#define STM32F746_PB13_FUNC_ETH_MII_TXD1_ETH_RMII_TXD1 0x1d0c
+#define STM32F746_PB13_FUNC_EVENTOUT 0x1d10
+#define STM32F746_PB13_FUNC_ANALOG 0x1d11
+
+#define STM32F746_PB14_FUNC_GPIO 0x1e00
+#define STM32F746_PB14_FUNC_TIM1_CH2N 0x1e02
+#define STM32F746_PB14_FUNC_TIM8_CH2N 0x1e04
+#define STM32F746_PB14_FUNC_SPI2_MISO 0x1e06
+#define STM32F746_PB14_FUNC_USART3_RTS 0x1e08
+#define STM32F746_PB14_FUNC_TIM12_CH1 0x1e0a
+#define STM32F746_PB14_FUNC_OTG_HS_DM 0x1e0d
+#define STM32F746_PB14_FUNC_EVENTOUT 0x1e10
+#define STM32F746_PB14_FUNC_ANALOG 0x1e11
+
+#define STM32F746_PB15_FUNC_GPIO 0x1f00
+#define STM32F746_PB15_FUNC_RTC_REFIN 0x1f01
+#define STM32F746_PB15_FUNC_TIM1_CH3N 0x1f02
+#define STM32F746_PB15_FUNC_TIM8_CH3N 0x1f04
+#define STM32F746_PB15_FUNC_SPI2_MOSI_I2S2_SD 0x1f06
+#define STM32F746_PB15_FUNC_TIM12_CH2 0x1f0a
+#define STM32F746_PB15_FUNC_OTG_HS_DP 0x1f0d
+#define STM32F746_PB15_FUNC_EVENTOUT 0x1f10
+#define STM32F746_PB15_FUNC_ANALOG 0x1f11
+
+
+#define STM32F746_PC0_FUNC_GPIO 0x2000
+#define STM32F746_PC0_FUNC_SAI2_FS_B 0x2009
+#define STM32F746_PC0_FUNC_OTG_HS_ULPI_STP 0x200b
+#define STM32F746_PC0_FUNC_FMC_SDNWE 0x200d
+#define STM32F746_PC0_FUNC_LCD_R5 0x200f
+#define STM32F746_PC0_FUNC_EVENTOUT 0x2010
+#define STM32F746_PC0_FUNC_ANALOG 0x2011
+
+#define STM32F746_PC1_FUNC_GPIO 0x2100
+#define STM32F746_PC1_FUNC_TRACED0 0x2101
+#define STM32F746_PC1_FUNC_SPI2_MOSI_I2S2_SD 0x2106
+#define STM32F746_PC1_FUNC_SAI1_SD_A 0x2107
+#define STM32F746_PC1_FUNC_ETH_MDC 0x210c
+#define STM32F746_PC1_FUNC_EVENTOUT 0x2110
+#define STM32F746_PC1_FUNC_ANALOG 0x2111
+
+#define STM32F746_PC2_FUNC_GPIO 0x2200
+#define STM32F746_PC2_FUNC_SPI2_MISO 0x2206
+#define STM32F746_PC2_FUNC_OTG_HS_ULPI_DIR 0x220b
+#define STM32F746_PC2_FUNC_ETH_MII_TXD2 0x220c
+#define STM32F746_PC2_FUNC_FMC_SDNE0 0x220d
+#define STM32F746_PC2_FUNC_EVENTOUT 0x2210
+#define STM32F746_PC2_FUNC_ANALOG 0x2211
+
+#define STM32F746_PC3_FUNC_GPIO 0x2300
+#define STM32F746_PC3_FUNC_SPI2_MOSI_I2S2_SD 0x2306
+#define STM32F746_PC3_FUNC_OTG_HS_ULPI_NXT 0x230b
+#define STM32F746_PC3_FUNC_ETH_MII_TX_CLK 0x230c
+#define STM32F746_PC3_FUNC_FMC_SDCKE0 0x230d
+#define STM32F746_PC3_FUNC_EVENTOUT 0x2310
+#define STM32F746_PC3_FUNC_ANALOG 0x2311
+
+#define STM32F746_PC4_FUNC_GPIO 0x2400
+#define STM32F746_PC4_FUNC_I2S1_MCK 0x2406
+#define STM32F746_PC4_FUNC_SPDIFRX_IN2 0x2409
+#define STM32F746_PC4_FUNC_ETH_MII_RXD0_ETH_RMII_RXD0 0x240c
+#define STM32F746_PC4_FUNC_FMC_SDNE0 0x240d
+#define STM32F746_PC4_FUNC_EVENTOUT 0x2410
+#define STM32F746_PC4_FUNC_ANALOG 0x2411
+
+#define STM32F746_PC5_FUNC_GPIO 0x2500
+#define STM32F746_PC5_FUNC_SPDIFRX_IN3 0x2509
+#define STM32F746_PC5_FUNC_ETH_MII_RXD1_ETH_RMII_RXD1 0x250c
+#define STM32F746_PC5_FUNC_FMC_SDCKE0 0x250d
+#define STM32F746_PC5_FUNC_EVENTOUT 0x2510
+#define STM32F746_PC5_FUNC_ANALOG 0x2511
+
+#define STM32F746_PC6_FUNC_GPIO 0x2600
+#define STM32F746_PC6_FUNC_TIM3_CH1 0x2603
+#define STM32F746_PC6_FUNC_TIM8_CH1 0x2604
+#define STM32F746_PC6_FUNC_I2S2_MCK 0x2606
+#define STM32F746_PC6_FUNC_USART6_TX 0x2609
+#define STM32F746_PC6_FUNC_SDMMC1_D6 0x260d
+#define STM32F746_PC6_FUNC_DCMI_D0 0x260e
+#define STM32F746_PC6_FUNC_LCD_HSYNC 0x260f
+#define STM32F746_PC6_FUNC_EVENTOUT 0x2610
+#define STM32F746_PC6_FUNC_ANALOG 0x2611
+
+#define STM32F746_PC7_FUNC_GPIO 0x2700
+#define STM32F746_PC7_FUNC_TIM3_CH2 0x2703
+#define STM32F746_PC7_FUNC_TIM8_CH2 0x2704
+#define STM32F746_PC7_FUNC_I2S3_MCK 0x2707
+#define STM32F746_PC7_FUNC_USART6_RX 0x2709
+#define STM32F746_PC7_FUNC_SDMMC1_D7 0x270d
+#define STM32F746_PC7_FUNC_DCMI_D1 0x270e
+#define STM32F746_PC7_FUNC_LCD_G6 0x270f
+#define STM32F746_PC7_FUNC_EVENTOUT 0x2710
+#define STM32F746_PC7_FUNC_ANALOG 0x2711
+
+#define STM32F746_PC8_FUNC_GPIO 0x2800
+#define STM32F746_PC8_FUNC_TRACED1 0x2801
+#define STM32F746_PC8_FUNC_TIM3_CH3 0x2803
+#define STM32F746_PC8_FUNC_TIM8_CH3 0x2804
+#define STM32F746_PC8_FUNC_UART5_RTS 0x2808
+#define STM32F746_PC8_FUNC_USART6_CK 0x2809
+#define STM32F746_PC8_FUNC_SDMMC1_D0 0x280d
+#define STM32F746_PC8_FUNC_DCMI_D2 0x280e
+#define STM32F746_PC8_FUNC_EVENTOUT 0x2810
+#define STM32F746_PC8_FUNC_ANALOG 0x2811
+
+#define STM32F746_PC9_FUNC_GPIO 0x2900
+#define STM32F746_PC9_FUNC_MCO2 0x2901
+#define STM32F746_PC9_FUNC_TIM3_CH4 0x2903
+#define STM32F746_PC9_FUNC_TIM8_CH4 0x2904
+#define STM32F746_PC9_FUNC_I2C3_SDA 0x2905
+#define STM32F746_PC9_FUNC_I2S_CKIN 0x2906
+#define STM32F746_PC9_FUNC_UART5_CTS 0x2908
+#define STM32F746_PC9_FUNC_QUADSPI_BK1_IO0 0x290a
+#define STM32F746_PC9_FUNC_SDMMC1_D1 0x290d
+#define STM32F746_PC9_FUNC_DCMI_D3 0x290e
+#define STM32F746_PC9_FUNC_EVENTOUT 0x2910
+#define STM32F746_PC9_FUNC_ANALOG 0x2911
+
+#define STM32F746_PC10_FUNC_GPIO 0x2a00
+#define STM32F746_PC10_FUNC_SPI3_SCK_I2S3_CK 0x2a07
+#define STM32F746_PC10_FUNC_USART3_TX 0x2a08
+#define STM32F746_PC10_FUNC_UART4_TX 0x2a09
+#define STM32F746_PC10_FUNC_QUADSPI_BK1_IO1 0x2a0a
+#define STM32F746_PC10_FUNC_SDMMC1_D2 0x2a0d
+#define STM32F746_PC10_FUNC_DCMI_D8 0x2a0e
+#define STM32F746_PC10_FUNC_LCD_R2 0x2a0f
+#define STM32F746_PC10_FUNC_EVENTOUT 0x2a10
+#define STM32F746_PC10_FUNC_ANALOG 0x2a11
+
+#define STM32F746_PC11_FUNC_GPIO 0x2b00
+#define STM32F746_PC11_FUNC_SPI3_MISO 0x2b07
+#define STM32F746_PC11_FUNC_USART3_RX 0x2b08
+#define STM32F746_PC11_FUNC_UART4_RX 0x2b09
+#define STM32F746_PC11_FUNC_QUADSPI_BK2_NCS 0x2b0a
+#define STM32F746_PC11_FUNC_SDMMC1_D3 0x2b0d
+#define STM32F746_PC11_FUNC_DCMI_D4 0x2b0e
+#define STM32F746_PC11_FUNC_EVENTOUT 0x2b10
+#define STM32F746_PC11_FUNC_ANALOG 0x2b11
+
+#define STM32F746_PC12_FUNC_GPIO 0x2c00
+#define STM32F746_PC12_FUNC_TRACED3 0x2c01
+#define STM32F746_PC12_FUNC_SPI3_MOSI_I2S3_SD 0x2c07
+#define STM32F746_PC12_FUNC_USART3_CK 0x2c08
+#define STM32F746_PC12_FUNC_UART5_TX 0x2c09
+#define STM32F746_PC12_FUNC_SDMMC1_CK 0x2c0d
+#define STM32F746_PC12_FUNC_DCMI_D9 0x2c0e
+#define STM32F746_PC12_FUNC_EVENTOUT 0x2c10
+#define STM32F746_PC12_FUNC_ANALOG 0x2c11
+
+#define STM32F746_PC13_FUNC_GPIO 0x2d00
+#define STM32F746_PC13_FUNC_EVENTOUT 0x2d10
+#define STM32F746_PC13_FUNC_ANALOG 0x2d11
+
+#define STM32F746_PC14_FUNC_GPIO 0x2e00
+#define STM32F746_PC14_FUNC_EVENTOUT 0x2e10
+#define STM32F746_PC14_FUNC_ANALOG 0x2e11
+
+#define STM32F746_PC15_FUNC_GPIO 0x2f00
+#define STM32F746_PC15_FUNC_EVENTOUT 0x2f10
+#define STM32F746_PC15_FUNC_ANALOG 0x2f11
+
+
+#define STM32F746_PD0_FUNC_GPIO 0x3000
+#define STM32F746_PD0_FUNC_CAN1_RX 0x300a
+#define STM32F746_PD0_FUNC_FMC_D2 0x300d
+#define STM32F746_PD0_FUNC_EVENTOUT 0x3010
+#define STM32F746_PD0_FUNC_ANALOG 0x3011
+
+#define STM32F746_PD1_FUNC_GPIO 0x3100
+#define STM32F746_PD1_FUNC_CAN1_TX 0x310a
+#define STM32F746_PD1_FUNC_FMC_D3 0x310d
+#define STM32F746_PD1_FUNC_EVENTOUT 0x3110
+#define STM32F746_PD1_FUNC_ANALOG 0x3111
+
+#define STM32F746_PD2_FUNC_GPIO 0x3200
+#define STM32F746_PD2_FUNC_TRACED2 0x3201
+#define STM32F746_PD2_FUNC_TIM3_ETR 0x3203
+#define STM32F746_PD2_FUNC_UART5_RX 0x3209
+#define STM32F746_PD2_FUNC_SDMMC1_CMD 0x320d
+#define STM32F746_PD2_FUNC_DCMI_D11 0x320e
+#define STM32F746_PD2_FUNC_EVENTOUT 0x3210
+#define STM32F746_PD2_FUNC_ANALOG 0x3211
+
+#define STM32F746_PD3_FUNC_GPIO 0x3300
+#define STM32F746_PD3_FUNC_SPI2_SCK_I2S2_CK 0x3306
+#define STM32F746_PD3_FUNC_USART2_CTS 0x3308
+#define STM32F746_PD3_FUNC_FMC_CLK 0x330d
+#define STM32F746_PD3_FUNC_DCMI_D5 0x330e
+#define STM32F746_PD3_FUNC_LCD_G7 0x330f
+#define STM32F746_PD3_FUNC_EVENTOUT 0x3310
+#define STM32F746_PD3_FUNC_ANALOG 0x3311
+
+#define STM32F746_PD4_FUNC_GPIO 0x3400
+#define STM32F746_PD4_FUNC_USART2_RTS 0x3408
+#define STM32F746_PD4_FUNC_FMC_NOE 0x340d
+#define STM32F746_PD4_FUNC_EVENTOUT 0x3410
+#define STM32F746_PD4_FUNC_ANALOG 0x3411
+
+#define STM32F746_PD5_FUNC_GPIO 0x3500
+#define STM32F746_PD5_FUNC_USART2_TX 0x3508
+#define STM32F746_PD5_FUNC_FMC_NWE 0x350d
+#define STM32F746_PD5_FUNC_EVENTOUT 0x3510
+#define STM32F746_PD5_FUNC_ANALOG 0x3511
+
+#define STM32F746_PD6_FUNC_GPIO 0x3600
+#define STM32F746_PD6_FUNC_SPI3_MOSI_I2S3_SD 0x3606
+#define STM32F746_PD6_FUNC_SAI1_SD_A 0x3607
+#define STM32F746_PD6_FUNC_USART2_RX 0x3608
+#define STM32F746_PD6_FUNC_FMC_NWAIT 0x360d
+#define STM32F746_PD6_FUNC_DCMI_D10 0x360e
+#define STM32F746_PD6_FUNC_LCD_B2 0x360f
+#define STM32F746_PD6_FUNC_EVENTOUT 0x3610
+#define STM32F746_PD6_FUNC_ANALOG 0x3611
+
+#define STM32F746_PD7_FUNC_GPIO 0x3700
+#define STM32F746_PD7_FUNC_USART2_CK 0x3708
+#define STM32F746_PD7_FUNC_SPDIFRX_IN0 0x3709
+#define STM32F746_PD7_FUNC_FMC_NE1 0x370d
+#define STM32F746_PD7_FUNC_EVENTOUT 0x3710
+#define STM32F746_PD7_FUNC_ANALOG 0x3711
+
+#define STM32F746_PD8_FUNC_GPIO 0x3800
+#define STM32F746_PD8_FUNC_USART3_TX 0x3808
+#define STM32F746_PD8_FUNC_SPDIFRX_IN1 0x3809
+#define STM32F746_PD8_FUNC_FMC_D13 0x380d
+#define STM32F746_PD8_FUNC_EVENTOUT 0x3810
+#define STM32F746_PD8_FUNC_ANALOG 0x3811
+
+#define STM32F746_PD9_FUNC_GPIO 0x3900
+#define STM32F746_PD9_FUNC_USART3_RX 0x3908
+#define STM32F746_PD9_FUNC_FMC_D14 0x390d
+#define STM32F746_PD9_FUNC_EVENTOUT 0x3910
+#define STM32F746_PD9_FUNC_ANALOG 0x3911
+
+#define STM32F746_PD10_FUNC_GPIO 0x3a00
+#define STM32F746_PD10_FUNC_USART3_CK 0x3a08
+#define STM32F746_PD10_FUNC_FMC_D15 0x3a0d
+#define STM32F746_PD10_FUNC_LCD_B3 0x3a0f
+#define STM32F746_PD10_FUNC_EVENTOUT 0x3a10
+#define STM32F746_PD10_FUNC_ANALOG 0x3a11
+
+#define STM32F746_PD11_FUNC_GPIO 0x3b00
+#define STM32F746_PD11_FUNC_I2C4_SMBA 0x3b05
+#define STM32F746_PD11_FUNC_USART3_CTS 0x3b08
+#define STM32F746_PD11_FUNC_QUADSPI_BK1_IO0 0x3b0a
+#define STM32F746_PD11_FUNC_SAI2_SD_A 0x3b0b
+#define STM32F746_PD11_FUNC_FMC_A16_FMC_CLE 0x3b0d
+#define STM32F746_PD11_FUNC_EVENTOUT 0x3b10
+#define STM32F746_PD11_FUNC_ANALOG 0x3b11
+
+#define STM32F746_PD12_FUNC_GPIO 0x3c00
+#define STM32F746_PD12_FUNC_TIM4_CH1 0x3c03
+#define STM32F746_PD12_FUNC_LPTIM1_IN1 0x3c04
+#define STM32F746_PD12_FUNC_I2C4_SCL 0x3c05
+#define STM32F746_PD12_FUNC_USART3_RTS 0x3c08
+#define STM32F746_PD12_FUNC_QUADSPI_BK1_IO1 0x3c0a
+#define STM32F746_PD12_FUNC_SAI2_FS_A 0x3c0b
+#define STM32F746_PD12_FUNC_FMC_A17_FMC_ALE 0x3c0d
+#define STM32F746_PD12_FUNC_EVENTOUT 0x3c10
+#define STM32F746_PD12_FUNC_ANALOG 0x3c11
+
+#define STM32F746_PD13_FUNC_GPIO 0x3d00
+#define STM32F746_PD13_FUNC_TIM4_CH2 0x3d03
+#define STM32F746_PD13_FUNC_LPTIM1_OUT 0x3d04
+#define STM32F746_PD13_FUNC_I2C4_SDA 0x3d05
+#define STM32F746_PD13_FUNC_QUADSPI_BK1_IO3 0x3d0a
+#define STM32F746_PD13_FUNC_SAI2_SCK_A 0x3d0b
+#define STM32F746_PD13_FUNC_FMC_A18 0x3d0d
+#define STM32F746_PD13_FUNC_EVENTOUT 0x3d10
+#define STM32F746_PD13_FUNC_ANALOG 0x3d11
+
+#define STM32F746_PD14_FUNC_GPIO 0x3e00
+#define STM32F746_PD14_FUNC_TIM4_CH3 0x3e03
+#define STM32F746_PD14_FUNC_UART8_CTS 0x3e09
+#define STM32F746_PD14_FUNC_FMC_D0 0x3e0d
+#define STM32F746_PD14_FUNC_EVENTOUT 0x3e10
+#define STM32F746_PD14_FUNC_ANALOG 0x3e11
+
+#define STM32F746_PD15_FUNC_GPIO 0x3f00
+#define STM32F746_PD15_FUNC_TIM4_CH4 0x3f03
+#define STM32F746_PD15_FUNC_UART8_RTS 0x3f09
+#define STM32F746_PD15_FUNC_FMC_D1 0x3f0d
+#define STM32F746_PD15_FUNC_EVENTOUT 0x3f10
+#define STM32F746_PD15_FUNC_ANALOG 0x3f11
+
+
+#define STM32F746_PE0_FUNC_GPIO 0x4000
+#define STM32F746_PE0_FUNC_TIM4_ETR 0x4003
+#define STM32F746_PE0_FUNC_LPTIM1_ETR 0x4004
+#define STM32F746_PE0_FUNC_UART8_RX 0x4009
+#define STM32F746_PE0_FUNC_SAI2_MCLK_A 0x400b
+#define STM32F746_PE0_FUNC_FMC_NBL0 0x400d
+#define STM32F746_PE0_FUNC_DCMI_D2 0x400e
+#define STM32F746_PE0_FUNC_EVENTOUT 0x4010
+#define STM32F746_PE0_FUNC_ANALOG 0x4011
+
+#define STM32F746_PE1_FUNC_GPIO 0x4100
+#define STM32F746_PE1_FUNC_LPTIM1_IN2 0x4104
+#define STM32F746_PE1_FUNC_UART8_TX 0x4109
+#define STM32F746_PE1_FUNC_FMC_NBL1 0x410d
+#define STM32F746_PE1_FUNC_DCMI_D3 0x410e
+#define STM32F746_PE1_FUNC_EVENTOUT 0x4110
+#define STM32F746_PE1_FUNC_ANALOG 0x4111
+
+#define STM32F746_PE2_FUNC_GPIO 0x4200
+#define STM32F746_PE2_FUNC_TRACECLK 0x4201
+#define STM32F746_PE2_FUNC_SPI4_SCK 0x4206
+#define STM32F746_PE2_FUNC_SAI1_MCLK_A 0x4207
+#define STM32F746_PE2_FUNC_QUADSPI_BK1_IO2 0x420a
+#define STM32F746_PE2_FUNC_ETH_MII_TXD3 0x420c
+#define STM32F746_PE2_FUNC_FMC_A23 0x420d
+#define STM32F746_PE2_FUNC_EVENTOUT 0x4210
+#define STM32F746_PE2_FUNC_ANALOG 0x4211
+
+#define STM32F746_PE3_FUNC_GPIO 0x4300
+#define STM32F746_PE3_FUNC_TRACED0 0x4301
+#define STM32F746_PE3_FUNC_SAI1_SD_B 0x4307
+#define STM32F746_PE3_FUNC_FMC_A19 0x430d
+#define STM32F746_PE3_FUNC_EVENTOUT 0x4310
+#define STM32F746_PE3_FUNC_ANALOG 0x4311
+
+#define STM32F746_PE4_FUNC_GPIO 0x4400
+#define STM32F746_PE4_FUNC_TRACED1 0x4401
+#define STM32F746_PE4_FUNC_SPI4_NSS 0x4406
+#define STM32F746_PE4_FUNC_SAI1_FS_A 0x4407
+#define STM32F746_PE4_FUNC_FMC_A20 0x440d
+#define STM32F746_PE4_FUNC_DCMI_D4 0x440e
+#define STM32F746_PE4_FUNC_LCD_B0 0x440f
+#define STM32F746_PE4_FUNC_EVENTOUT 0x4410
+#define STM32F746_PE4_FUNC_ANALOG 0x4411
+
+#define STM32F746_PE5_FUNC_GPIO 0x4500
+#define STM32F746_PE5_FUNC_TRACED2 0x4501
+#define STM32F746_PE5_FUNC_TIM9_CH1 0x4504
+#define STM32F746_PE5_FUNC_SPI4_MISO 0x4506
+#define STM32F746_PE5_FUNC_SAI1_SCK_A 0x4507
+#define STM32F746_PE5_FUNC_FMC_A21 0x450d
+#define STM32F746_PE5_FUNC_DCMI_D6 0x450e
+#define STM32F746_PE5_FUNC_LCD_G0 0x450f
+#define STM32F746_PE5_FUNC_EVENTOUT 0x4510
+#define STM32F746_PE5_FUNC_ANALOG 0x4511
+
+#define STM32F746_PE6_FUNC_GPIO 0x4600
+#define STM32F746_PE6_FUNC_TRACED3 0x4601
+#define STM32F746_PE6_FUNC_TIM1_BKIN2 0x4602
+#define STM32F746_PE6_FUNC_TIM9_CH2 0x4604
+#define STM32F746_PE6_FUNC_SPI4_MOSI 0x4606
+#define STM32F746_PE6_FUNC_SAI1_SD_A 0x4607
+#define STM32F746_PE6_FUNC_SAI2_MCLK_B 0x460b
+#define STM32F746_PE6_FUNC_FMC_A22 0x460d
+#define STM32F746_PE6_FUNC_DCMI_D7 0x460e
+#define STM32F746_PE6_FUNC_LCD_G1 0x460f
+#define STM32F746_PE6_FUNC_EVENTOUT 0x4610
+#define STM32F746_PE6_FUNC_ANALOG 0x4611
+
+#define STM32F746_PE7_FUNC_GPIO 0x4700
+#define STM32F746_PE7_FUNC_TIM1_ETR 0x4702
+#define STM32F746_PE7_FUNC_UART7_RX 0x4709
+#define STM32F746_PE7_FUNC_QUADSPI_BK2_IO0 0x470b
+#define STM32F746_PE7_FUNC_FMC_D4 0x470d
+#define STM32F746_PE7_FUNC_EVENTOUT 0x4710
+#define STM32F746_PE7_FUNC_ANALOG 0x4711
+
+#define STM32F746_PE8_FUNC_GPIO 0x4800
+#define STM32F746_PE8_FUNC_TIM1_CH1N 0x4802
+#define STM32F746_PE8_FUNC_UART7_TX 0x4809
+#define STM32F746_PE8_FUNC_QUADSPI_BK2_IO1 0x480b
+#define STM32F746_PE8_FUNC_FMC_D5 0x480d
+#define STM32F746_PE8_FUNC_EVENTOUT 0x4810
+#define STM32F746_PE8_FUNC_ANALOG 0x4811
+
+#define STM32F746_PE9_FUNC_GPIO 0x4900
+#define STM32F746_PE9_FUNC_TIM1_CH1 0x4902
+#define STM32F746_PE9_FUNC_UART7_RTS 0x4909
+#define STM32F746_PE9_FUNC_QUADSPI_BK2_IO2 0x490b
+#define STM32F746_PE9_FUNC_FMC_D6 0x490d
+#define STM32F746_PE9_FUNC_EVENTOUT 0x4910
+#define STM32F746_PE9_FUNC_ANALOG 0x4911
+
+#define STM32F746_PE10_FUNC_GPIO 0x4a00
+#define STM32F746_PE10_FUNC_TIM1_CH2N 0x4a02
+#define STM32F746_PE10_FUNC_UART7_CTS 0x4a09
+#define STM32F746_PE10_FUNC_QUADSPI_BK2_IO3 0x4a0b
+#define STM32F746_PE10_FUNC_FMC_D7 0x4a0d
+#define STM32F746_PE10_FUNC_EVENTOUT 0x4a10
+#define STM32F746_PE10_FUNC_ANALOG 0x4a11
+
+#define STM32F746_PE11_FUNC_GPIO 0x4b00
+#define STM32F746_PE11_FUNC_TIM1_CH2 0x4b02
+#define STM32F746_PE11_FUNC_SPI4_NSS 0x4b06
+#define STM32F746_PE11_FUNC_SAI2_SD_B 0x4b0b
+#define STM32F746_PE11_FUNC_FMC_D8 0x4b0d
+#define STM32F746_PE11_FUNC_LCD_G3 0x4b0f
+#define STM32F746_PE11_FUNC_EVENTOUT 0x4b10
+#define STM32F746_PE11_FUNC_ANALOG 0x4b11
+
+#define STM32F746_PE12_FUNC_GPIO 0x4c00
+#define STM32F746_PE12_FUNC_TIM1_CH3N 0x4c02
+#define STM32F746_PE12_FUNC_SPI4_SCK 0x4c06
+#define STM32F746_PE12_FUNC_SAI2_SCK_B 0x4c0b
+#define STM32F746_PE12_FUNC_FMC_D9 0x4c0d
+#define STM32F746_PE12_FUNC_LCD_B4 0x4c0f
+#define STM32F746_PE12_FUNC_EVENTOUT 0x4c10
+#define STM32F746_PE12_FUNC_ANALOG 0x4c11
+
+#define STM32F746_PE13_FUNC_GPIO 0x4d00
+#define STM32F746_PE13_FUNC_TIM1_CH3 0x4d02
+#define STM32F746_PE13_FUNC_SPI4_MISO 0x4d06
+#define STM32F746_PE13_FUNC_SAI2_FS_B 0x4d0b
+#define STM32F746_PE13_FUNC_FMC_D10 0x4d0d
+#define STM32F746_PE13_FUNC_LCD_DE 0x4d0f
+#define STM32F746_PE13_FUNC_EVENTOUT 0x4d10
+#define STM32F746_PE13_FUNC_ANALOG 0x4d11
+
+#define STM32F746_PE14_FUNC_GPIO 0x4e00
+#define STM32F746_PE14_FUNC_TIM1_CH4 0x4e02
+#define STM32F746_PE14_FUNC_SPI4_MOSI 0x4e06
+#define STM32F746_PE14_FUNC_SAI2_MCLK_B 0x4e0b
+#define STM32F746_PE14_FUNC_FMC_D11 0x4e0d
+#define STM32F746_PE14_FUNC_LCD_CLK 0x4e0f
+#define STM32F746_PE14_FUNC_EVENTOUT 0x4e10
+#define STM32F746_PE14_FUNC_ANALOG 0x4e11
+
+#define STM32F746_PE15_FUNC_GPIO 0x4f00
+#define STM32F746_PE15_FUNC_TIM1_BKIN 0x4f02
+#define STM32F746_PE15_FUNC_FMC_D12 0x4f0d
+#define STM32F746_PE15_FUNC_LCD_R7 0x4f0f
+#define STM32F746_PE15_FUNC_EVENTOUT 0x4f10
+#define STM32F746_PE15_FUNC_ANALOG 0x4f11
+
+
+#define STM32F746_PF0_FUNC_GPIO 0x5000
+#define STM32F746_PF0_FUNC_I2C2_SDA 0x5005
+#define STM32F746_PF0_FUNC_FMC_A0 0x500d
+#define STM32F746_PF0_FUNC_EVENTOUT 0x5010
+#define STM32F746_PF0_FUNC_ANALOG 0x5011
+
+#define STM32F746_PF1_FUNC_GPIO 0x5100
+#define STM32F746_PF1_FUNC_I2C2_SCL 0x5105
+#define STM32F746_PF1_FUNC_FMC_A1 0x510d
+#define STM32F746_PF1_FUNC_EVENTOUT 0x5110
+#define STM32F746_PF1_FUNC_ANALOG 0x5111
+
+#define STM32F746_PF2_FUNC_GPIO 0x5200
+#define STM32F746_PF2_FUNC_I2C2_SMBA 0x5205
+#define STM32F746_PF2_FUNC_FMC_A2 0x520d
+#define STM32F746_PF2_FUNC_EVENTOUT 0x5210
+#define STM32F746_PF2_FUNC_ANALOG 0x5211
+
+#define STM32F746_PF3_FUNC_GPIO 0x5300
+#define STM32F746_PF3_FUNC_FMC_A3 0x530d
+#define STM32F746_PF3_FUNC_EVENTOUT 0x5310
+#define STM32F746_PF3_FUNC_ANALOG 0x5311
+
+#define STM32F746_PF4_FUNC_GPIO 0x5400
+#define STM32F746_PF4_FUNC_FMC_A4 0x540d
+#define STM32F746_PF4_FUNC_EVENTOUT 0x5410
+#define STM32F746_PF4_FUNC_ANALOG 0x5411
+
+#define STM32F746_PF5_FUNC_GPIO 0x5500
+#define STM32F746_PF5_FUNC_FMC_A5 0x550d
+#define STM32F746_PF5_FUNC_EVENTOUT 0x5510
+#define STM32F746_PF5_FUNC_ANALOG 0x5511
+
+#define STM32F746_PF6_FUNC_GPIO 0x5600
+#define STM32F746_PF6_FUNC_TIM10_CH1 0x5604
+#define STM32F746_PF6_FUNC_SPI5_NSS 0x5606
+#define STM32F746_PF6_FUNC_SAI1_SD_B 0x5607
+#define STM32F746_PF6_FUNC_UART7_RX 0x5609
+#define STM32F746_PF6_FUNC_QUADSPI_BK1_IO3 0x560a
+#define STM32F746_PF6_FUNC_EVENTOUT 0x5610
+#define STM32F746_PF6_FUNC_ANALOG 0x5611
+
+#define STM32F746_PF7_FUNC_GPIO 0x5700
+#define STM32F746_PF7_FUNC_TIM11_CH1 0x5704
+#define STM32F746_PF7_FUNC_SPI5_SCK 0x5706
+#define STM32F746_PF7_FUNC_SAI1_MCLK_B 0x5707
+#define STM32F746_PF7_FUNC_UART7_TX 0x5709
+#define STM32F746_PF7_FUNC_QUADSPI_BK1_IO2 0x570a
+#define STM32F746_PF7_FUNC_EVENTOUT 0x5710
+#define STM32F746_PF7_FUNC_ANALOG 0x5711
+
+#define STM32F746_PF8_FUNC_GPIO 0x5800
+#define STM32F746_PF8_FUNC_SPI5_MISO 0x5806
+#define STM32F746_PF8_FUNC_SAI1_SCK_B 0x5807
+#define STM32F746_PF8_FUNC_UART7_RTS 0x5809
+#define STM32F746_PF8_FUNC_TIM13_CH1 0x580a
+#define STM32F746_PF8_FUNC_QUADSPI_BK1_IO0 0x580b
+#define STM32F746_PF8_FUNC_EVENTOUT 0x5810
+#define STM32F746_PF8_FUNC_ANALOG 0x5811
+
+#define STM32F746_PF9_FUNC_GPIO 0x5900
+#define STM32F746_PF9_FUNC_SPI5_MOSI 0x5906
+#define STM32F746_PF9_FUNC_SAI1_FS_B 0x5907
+#define STM32F746_PF9_FUNC_UART7_CTS 0x5909
+#define STM32F746_PF9_FUNC_TIM14_CH1 0x590a
+#define STM32F746_PF9_FUNC_QUADSPI_BK1_IO1 0x590b
+#define STM32F746_PF9_FUNC_EVENTOUT 0x5910
+#define STM32F746_PF9_FUNC_ANALOG 0x5911
+
+#define STM32F746_PF10_FUNC_GPIO 0x5a00
+#define STM32F746_PF10_FUNC_DCMI_D11 0x5a0e
+#define STM32F746_PF10_FUNC_LCD_DE 0x5a0f
+#define STM32F746_PF10_FUNC_EVENTOUT 0x5a10
+#define STM32F746_PF10_FUNC_ANALOG 0x5a11
+
+#define STM32F746_PF11_FUNC_GPIO 0x5b00
+#define STM32F746_PF11_FUNC_SPI5_MOSI 0x5b06
+#define STM32F746_PF11_FUNC_SAI2_SD_B 0x5b0b
+#define STM32F746_PF11_FUNC_FMC_SDNRAS 0x5b0d
+#define STM32F746_PF11_FUNC_DCMI_D12 0x5b0e
+#define STM32F746_PF11_FUNC_EVENTOUT 0x5b10
+#define STM32F746_PF11_FUNC_ANALOG 0x5b11
+
+#define STM32F746_PF12_FUNC_GPIO 0x5c00
+#define STM32F746_PF12_FUNC_FMC_A6 0x5c0d
+#define STM32F746_PF12_FUNC_EVENTOUT 0x5c10
+#define STM32F746_PF12_FUNC_ANALOG 0x5c11
+
+#define STM32F746_PF13_FUNC_GPIO 0x5d00
+#define STM32F746_PF13_FUNC_I2C4_SMBA 0x5d05
+#define STM32F746_PF13_FUNC_FMC_A7 0x5d0d
+#define STM32F746_PF13_FUNC_EVENTOUT 0x5d10
+#define STM32F746_PF13_FUNC_ANALOG 0x5d11
+
+#define STM32F746_PF14_FUNC_GPIO 0x5e00
+#define STM32F746_PF14_FUNC_I2C4_SCL 0x5e05
+#define STM32F746_PF14_FUNC_FMC_A8 0x5e0d
+#define STM32F746_PF14_FUNC_EVENTOUT 0x5e10
+#define STM32F746_PF14_FUNC_ANALOG 0x5e11
+
+#define STM32F746_PF15_FUNC_GPIO 0x5f00
+#define STM32F746_PF15_FUNC_I2C4_SDA 0x5f05
+#define STM32F746_PF15_FUNC_FMC_A9 0x5f0d
+#define STM32F746_PF15_FUNC_EVENTOUT 0x5f10
+#define STM32F746_PF15_FUNC_ANALOG 0x5f11
+
+
+#define STM32F746_PG0_FUNC_GPIO 0x6000
+#define STM32F746_PG0_FUNC_FMC_A10 0x600d
+#define STM32F746_PG0_FUNC_EVENTOUT 0x6010
+#define STM32F746_PG0_FUNC_ANALOG 0x6011
+
+#define STM32F746_PG1_FUNC_GPIO 0x6100
+#define STM32F746_PG1_FUNC_FMC_A11 0x610d
+#define STM32F746_PG1_FUNC_EVENTOUT 0x6110
+#define STM32F746_PG1_FUNC_ANALOG 0x6111
+
+#define STM32F746_PG2_FUNC_GPIO 0x6200
+#define STM32F746_PG2_FUNC_FMC_A12 0x620d
+#define STM32F746_PG2_FUNC_EVENTOUT 0x6210
+#define STM32F746_PG2_FUNC_ANALOG 0x6211
+
+#define STM32F746_PG3_FUNC_GPIO 0x6300
+#define STM32F746_PG3_FUNC_FMC_A13 0x630d
+#define STM32F746_PG3_FUNC_EVENTOUT 0x6310
+#define STM32F746_PG3_FUNC_ANALOG 0x6311
+
+#define STM32F746_PG4_FUNC_GPIO 0x6400
+#define STM32F746_PG4_FUNC_FMC_A14_FMC_BA0 0x640d
+#define STM32F746_PG4_FUNC_EVENTOUT 0x6410
+#define STM32F746_PG4_FUNC_ANALOG 0x6411
+
+#define STM32F746_PG5_FUNC_GPIO 0x6500
+#define STM32F746_PG5_FUNC_FMC_A15_FMC_BA1 0x650d
+#define STM32F746_PG5_FUNC_EVENTOUT 0x6510
+#define STM32F746_PG5_FUNC_ANALOG 0x6511
+
+#define STM32F746_PG6_FUNC_GPIO 0x6600
+#define STM32F746_PG6_FUNC_DCMI_D12 0x660e
+#define STM32F746_PG6_FUNC_LCD_R7 0x660f
+#define STM32F746_PG6_FUNC_EVENTOUT 0x6610
+#define STM32F746_PG6_FUNC_ANALOG 0x6611
+
+#define STM32F746_PG7_FUNC_GPIO 0x6700
+#define STM32F746_PG7_FUNC_USART6_CK 0x6709
+#define STM32F746_PG7_FUNC_FMC_INT 0x670d
+#define STM32F746_PG7_FUNC_DCMI_D13 0x670e
+#define STM32F746_PG7_FUNC_LCD_CLK 0x670f
+#define STM32F746_PG7_FUNC_EVENTOUT 0x6710
+#define STM32F746_PG7_FUNC_ANALOG 0x6711
+
+#define STM32F746_PG8_FUNC_GPIO 0x6800
+#define STM32F746_PG8_FUNC_SPI6_NSS 0x6806
+#define STM32F746_PG8_FUNC_SPDIFRX_IN2 0x6808
+#define STM32F746_PG8_FUNC_USART6_RTS 0x6809
+#define STM32F746_PG8_FUNC_ETH_PPS_OUT 0x680c
+#define STM32F746_PG8_FUNC_FMC_SDCLK 0x680d
+#define STM32F746_PG8_FUNC_EVENTOUT 0x6810
+#define STM32F746_PG8_FUNC_ANALOG 0x6811
+
+#define STM32F746_PG9_FUNC_GPIO 0x6900
+#define STM32F746_PG9_FUNC_SPDIFRX_IN3 0x6908
+#define STM32F746_PG9_FUNC_USART6_RX 0x6909
+#define STM32F746_PG9_FUNC_QUADSPI_BK2_IO2 0x690a
+#define STM32F746_PG9_FUNC_SAI2_FS_B 0x690b
+#define STM32F746_PG9_FUNC_FMC_NE2_FMC_NCE 0x690d
+#define STM32F746_PG9_FUNC_DCMI_VSYNC 0x690e
+#define STM32F746_PG9_FUNC_EVENTOUT 0x6910
+#define STM32F746_PG9_FUNC_ANALOG 0x6911
+
+#define STM32F746_PG10_FUNC_GPIO 0x6a00
+#define STM32F746_PG10_FUNC_LCD_G3 0x6a0a
+#define STM32F746_PG10_FUNC_SAI2_SD_B 0x6a0b
+#define STM32F746_PG10_FUNC_FMC_NE3 0x6a0d
+#define STM32F746_PG10_FUNC_DCMI_D2 0x6a0e
+#define STM32F746_PG10_FUNC_LCD_B2 0x6a0f
+#define STM32F746_PG10_FUNC_EVENTOUT 0x6a10
+#define STM32F746_PG10_FUNC_ANALOG 0x6a11
+
+#define STM32F746_PG11_FUNC_GPIO 0x6b00
+#define STM32F746_PG11_FUNC_SPDIFRX_IN0 0x6b08
+#define STM32F746_PG11_FUNC_ETH_MII_TX_EN_ETH_RMII_TX_EN 0x6b0c
+#define STM32F746_PG11_FUNC_DCMI_D3 0x6b0e
+#define STM32F746_PG11_FUNC_LCD_B3 0x6b0f
+#define STM32F746_PG11_FUNC_EVENTOUT 0x6b10
+#define STM32F746_PG11_FUNC_ANALOG 0x6b11
+
+#define STM32F746_PG12_FUNC_GPIO 0x6c00
+#define STM32F746_PG12_FUNC_LPTIM1_IN1 0x6c04
+#define STM32F746_PG12_FUNC_SPI6_MISO 0x6c06
+#define STM32F746_PG12_FUNC_SPDIFRX_IN1 0x6c08
+#define STM32F746_PG12_FUNC_USART6_RTS 0x6c09
+#define STM32F746_PG12_FUNC_LCD_B4 0x6c0a
+#define STM32F746_PG12_FUNC_FMC_NE4 0x6c0d
+#define STM32F746_PG12_FUNC_LCD_B1 0x6c0f
+#define STM32F746_PG12_FUNC_EVENTOUT 0x6c10
+#define STM32F746_PG12_FUNC_ANALOG 0x6c11
+
+#define STM32F746_PG13_FUNC_GPIO 0x6d00
+#define STM32F746_PG13_FUNC_TRACED0 0x6d01
+#define STM32F746_PG13_FUNC_LPTIM1_OUT 0x6d04
+#define STM32F746_PG13_FUNC_SPI6_SCK 0x6d06
+#define STM32F746_PG13_FUNC_USART6_CTS 0x6d09
+#define STM32F746_PG13_FUNC_ETH_MII_TXD0_ETH_RMII_TXD0 0x6d0c
+#define STM32F746_PG13_FUNC_FMC_A24 0x6d0d
+#define STM32F746_PG13_FUNC_LCD_R0 0x6d0f
+#define STM32F746_PG13_FUNC_EVENTOUT 0x6d10
+#define STM32F746_PG13_FUNC_ANALOG 0x6d11
+
+#define STM32F746_PG14_FUNC_GPIO 0x6e00
+#define STM32F746_PG14_FUNC_TRACED1 0x6e01
+#define STM32F746_PG14_FUNC_LPTIM1_ETR 0x6e04
+#define STM32F746_PG14_FUNC_SPI6_MOSI 0x6e06
+#define STM32F746_PG14_FUNC_USART6_TX 0x6e09
+#define STM32F746_PG14_FUNC_QUADSPI_BK2_IO3 0x6e0a
+#define STM32F746_PG14_FUNC_ETH_MII_TXD1_ETH_RMII_TXD1 0x6e0c
+#define STM32F746_PG14_FUNC_FMC_A25 0x6e0d
+#define STM32F746_PG14_FUNC_LCD_B0 0x6e0f
+#define STM32F746_PG14_FUNC_EVENTOUT 0x6e10
+#define STM32F746_PG14_FUNC_ANALOG 0x6e11
+
+#define STM32F746_PG15_FUNC_GPIO 0x6f00
+#define STM32F746_PG15_FUNC_USART6_CTS 0x6f09
+#define STM32F746_PG15_FUNC_FMC_SDNCAS 0x6f0d
+#define STM32F746_PG15_FUNC_DCMI_D13 0x6f0e
+#define STM32F746_PG15_FUNC_EVENTOUT 0x6f10
+#define STM32F746_PG15_FUNC_ANALOG 0x6f11
+
+
+#define STM32F746_PH0_FUNC_GPIO 0x7000
+#define STM32F746_PH0_FUNC_EVENTOUT 0x7010
+#define STM32F746_PH0_FUNC_ANALOG 0x7011
+
+#define STM32F746_PH1_FUNC_GPIO 0x7100
+#define STM32F746_PH1_FUNC_EVENTOUT 0x7110
+#define STM32F746_PH1_FUNC_ANALOG 0x7111
+
+#define STM32F746_PH2_FUNC_GPIO 0x7200
+#define STM32F746_PH2_FUNC_LPTIM1_IN2 0x7204
+#define STM32F746_PH2_FUNC_QUADSPI_BK2_IO0 0x720a
+#define STM32F746_PH2_FUNC_SAI2_SCK_B 0x720b
+#define STM32F746_PH2_FUNC_ETH_MII_CRS 0x720c
+#define STM32F746_PH2_FUNC_FMC_SDCKE0 0x720d
+#define STM32F746_PH2_FUNC_LCD_R0 0x720f
+#define STM32F746_PH2_FUNC_EVENTOUT 0x7210
+#define STM32F746_PH2_FUNC_ANALOG 0x7211
+
+#define STM32F746_PH3_FUNC_GPIO 0x7300
+#define STM32F746_PH3_FUNC_QUADSPI_BK2_IO1 0x730a
+#define STM32F746_PH3_FUNC_SAI2_MCLK_B 0x730b
+#define STM32F746_PH3_FUNC_ETH_MII_COL 0x730c
+#define STM32F746_PH3_FUNC_FMC_SDNE0 0x730d
+#define STM32F746_PH3_FUNC_LCD_R1 0x730f
+#define STM32F746_PH3_FUNC_EVENTOUT 0x7310
+#define STM32F746_PH3_FUNC_ANALOG 0x7311
+
+#define STM32F746_PH4_FUNC_GPIO 0x7400
+#define STM32F746_PH4_FUNC_I2C2_SCL 0x7405
+#define STM32F746_PH4_FUNC_OTG_HS_ULPI_NXT 0x740b
+#define STM32F746_PH4_FUNC_EVENTOUT 0x7410
+#define STM32F746_PH4_FUNC_ANALOG 0x7411
+
+#define STM32F746_PH5_FUNC_GPIO 0x7500
+#define STM32F746_PH5_FUNC_I2C2_SDA 0x7505
+#define STM32F746_PH5_FUNC_SPI5_NSS 0x7506
+#define STM32F746_PH5_FUNC_FMC_SDNWE 0x750d
+#define STM32F746_PH5_FUNC_EVENTOUT 0x7510
+#define STM32F746_PH5_FUNC_ANALOG 0x7511
+
+#define STM32F746_PH6_FUNC_GPIO 0x7600
+#define STM32F746_PH6_FUNC_I2C2_SMBA 0x7605
+#define STM32F746_PH6_FUNC_SPI5_SCK 0x7606
+#define STM32F746_PH6_FUNC_TIM12_CH1 0x760a
+#define STM32F746_PH6_FUNC_ETH_MII_RXD2 0x760c
+#define STM32F746_PH6_FUNC_FMC_SDNE1 0x760d
+#define STM32F746_PH6_FUNC_DCMI_D8 0x760e
+#define STM32F746_PH6_FUNC_EVENTOUT 0x7610
+#define STM32F746_PH6_FUNC_ANALOG 0x7611
+
+#define STM32F746_PH7_FUNC_GPIO 0x7700
+#define STM32F746_PH7_FUNC_I2C3_SCL 0x7705
+#define STM32F746_PH7_FUNC_SPI5_MISO 0x7706
+#define STM32F746_PH7_FUNC_ETH_MII_RXD3 0x770c
+#define STM32F746_PH7_FUNC_FMC_SDCKE1 0x770d
+#define STM32F746_PH7_FUNC_DCMI_D9 0x770e
+#define STM32F746_PH7_FUNC_EVENTOUT 0x7710
+#define STM32F746_PH7_FUNC_ANALOG 0x7711
+
+#define STM32F746_PH8_FUNC_GPIO 0x7800
+#define STM32F746_PH8_FUNC_I2C3_SDA 0x7805
+#define STM32F746_PH8_FUNC_FMC_D16 0x780d
+#define STM32F746_PH8_FUNC_DCMI_HSYNC 0x780e
+#define STM32F746_PH8_FUNC_LCD_R2 0x780f
+#define STM32F746_PH8_FUNC_EVENTOUT 0x7810
+#define STM32F746_PH8_FUNC_ANALOG 0x7811
+
+#define STM32F746_PH9_FUNC_GPIO 0x7900
+#define STM32F746_PH9_FUNC_I2C3_SMBA 0x7905
+#define STM32F746_PH9_FUNC_TIM12_CH2 0x790a
+#define STM32F746_PH9_FUNC_FMC_D17 0x790d
+#define STM32F746_PH9_FUNC_DCMI_D0 0x790e
+#define STM32F746_PH9_FUNC_LCD_R3 0x790f
+#define STM32F746_PH9_FUNC_EVENTOUT 0x7910
+#define STM32F746_PH9_FUNC_ANALOG 0x7911
+
+#define STM32F746_PH10_FUNC_GPIO 0x7a00
+#define STM32F746_PH10_FUNC_TIM5_CH1 0x7a03
+#define STM32F746_PH10_FUNC_I2C4_SMBA 0x7a05
+#define STM32F746_PH10_FUNC_FMC_D18 0x7a0d
+#define STM32F746_PH10_FUNC_DCMI_D1 0x7a0e
+#define STM32F746_PH10_FUNC_LCD_R4 0x7a0f
+#define STM32F746_PH10_FUNC_EVENTOUT 0x7a10
+#define STM32F746_PH10_FUNC_ANALOG 0x7a11
+
+#define STM32F746_PH11_FUNC_GPIO 0x7b00
+#define STM32F746_PH11_FUNC_TIM5_CH2 0x7b03
+#define STM32F746_PH11_FUNC_I2C4_SCL 0x7b05
+#define STM32F746_PH11_FUNC_FMC_D19 0x7b0d
+#define STM32F746_PH11_FUNC_DCMI_D2 0x7b0e
+#define STM32F746_PH11_FUNC_LCD_R5 0x7b0f
+#define STM32F746_PH11_FUNC_EVENTOUT 0x7b10
+#define STM32F746_PH11_FUNC_ANALOG 0x7b11
+
+#define STM32F746_PH12_FUNC_GPIO 0x7c00
+#define STM32F746_PH12_FUNC_TIM5_CH3 0x7c03
+#define STM32F746_PH12_FUNC_I2C4_SDA 0x7c05
+#define STM32F746_PH12_FUNC_FMC_D20 0x7c0d
+#define STM32F746_PH12_FUNC_DCMI_D3 0x7c0e
+#define STM32F746_PH12_FUNC_LCD_R6 0x7c0f
+#define STM32F746_PH12_FUNC_EVENTOUT 0x7c10
+#define STM32F746_PH12_FUNC_ANALOG 0x7c11
+
+#define STM32F746_PH13_FUNC_GPIO 0x7d00
+#define STM32F746_PH13_FUNC_TIM8_CH1N 0x7d04
+#define STM32F746_PH13_FUNC_CAN1_TX 0x7d0a
+#define STM32F746_PH13_FUNC_FMC_D21 0x7d0d
+#define STM32F746_PH13_FUNC_LCD_G2 0x7d0f
+#define STM32F746_PH13_FUNC_EVENTOUT 0x7d10
+#define STM32F746_PH13_FUNC_ANALOG 0x7d11
+
+#define STM32F746_PH14_FUNC_GPIO 0x7e00
+#define STM32F746_PH14_FUNC_TIM8_CH2N 0x7e04
+#define STM32F746_PH14_FUNC_FMC_D22 0x7e0d
+#define STM32F746_PH14_FUNC_DCMI_D4 0x7e0e
+#define STM32F746_PH14_FUNC_LCD_G3 0x7e0f
+#define STM32F746_PH14_FUNC_EVENTOUT 0x7e10
+#define STM32F746_PH14_FUNC_ANALOG 0x7e11
+
+#define STM32F746_PH15_FUNC_GPIO 0x7f00
+#define STM32F746_PH15_FUNC_TIM8_CH3N 0x7f04
+#define STM32F746_PH15_FUNC_FMC_D23 0x7f0d
+#define STM32F746_PH15_FUNC_DCMI_D11 0x7f0e
+#define STM32F746_PH15_FUNC_LCD_G4 0x7f0f
+#define STM32F746_PH15_FUNC_EVENTOUT 0x7f10
+#define STM32F746_PH15_FUNC_ANALOG 0x7f11
+
+
+#define STM32F746_PI0_FUNC_GPIO 0x8000
+#define STM32F746_PI0_FUNC_TIM5_CH4 0x8003
+#define STM32F746_PI0_FUNC_SPI2_NSS_I2S2_WS 0x8006
+#define STM32F746_PI0_FUNC_FMC_D24 0x800d
+#define STM32F746_PI0_FUNC_DCMI_D13 0x800e
+#define STM32F746_PI0_FUNC_LCD_G5 0x800f
+#define STM32F746_PI0_FUNC_EVENTOUT 0x8010
+#define STM32F746_PI0_FUNC_ANALOG 0x8011
+
+#define STM32F746_PI1_FUNC_GPIO 0x8100
+#define STM32F746_PI1_FUNC_TIM8_BKIN2 0x8104
+#define STM32F746_PI1_FUNC_SPI2_SCK_I2S2_CK 0x8106
+#define STM32F746_PI1_FUNC_FMC_D25 0x810d
+#define STM32F746_PI1_FUNC_DCMI_D8 0x810e
+#define STM32F746_PI1_FUNC_LCD_G6 0x810f
+#define STM32F746_PI1_FUNC_EVENTOUT 0x8110
+#define STM32F746_PI1_FUNC_ANALOG 0x8111
+
+#define STM32F746_PI2_FUNC_GPIO 0x8200
+#define STM32F746_PI2_FUNC_TIM8_CH4 0x8204
+#define STM32F746_PI2_FUNC_SPI2_MISO 0x8206
+#define STM32F746_PI2_FUNC_FMC_D26 0x820d
+#define STM32F746_PI2_FUNC_DCMI_D9 0x820e
+#define STM32F746_PI2_FUNC_LCD_G7 0x820f
+#define STM32F746_PI2_FUNC_EVENTOUT 0x8210
+#define STM32F746_PI2_FUNC_ANALOG 0x8211
+
+#define STM32F746_PI3_FUNC_GPIO 0x8300
+#define STM32F746_PI3_FUNC_TIM8_ETR 0x8304
+#define STM32F746_PI3_FUNC_SPI2_MOSI_I2S2_SD 0x8306
+#define STM32F746_PI3_FUNC_FMC_D27 0x830d
+#define STM32F746_PI3_FUNC_DCMI_D10 0x830e
+#define STM32F746_PI3_FUNC_EVENTOUT 0x8310
+#define STM32F746_PI3_FUNC_ANALOG 0x8311
+
+#define STM32F746_PI4_FUNC_GPIO 0x8400
+#define STM32F746_PI4_FUNC_TIM8_BKIN 0x8404
+#define STM32F746_PI4_FUNC_SAI2_MCLK_A 0x840b
+#define STM32F746_PI4_FUNC_FMC_NBL2 0x840d
+#define STM32F746_PI4_FUNC_DCMI_D5 0x840e
+#define STM32F746_PI4_FUNC_LCD_B4 0x840f
+#define STM32F746_PI4_FUNC_EVENTOUT 0x8410
+#define STM32F746_PI4_FUNC_ANALOG 0x8411
+
+#define STM32F746_PI5_FUNC_GPIO 0x8500
+#define STM32F746_PI5_FUNC_TIM8_CH1 0x8504
+#define STM32F746_PI5_FUNC_SAI2_SCK_A 0x850b
+#define STM32F746_PI5_FUNC_FMC_NBL3 0x850d
+#define STM32F746_PI5_FUNC_DCMI_VSYNC 0x850e
+#define STM32F746_PI5_FUNC_LCD_B5 0x850f
+#define STM32F746_PI5_FUNC_EVENTOUT 0x8510
+#define STM32F746_PI5_FUNC_ANALOG 0x8511
+
+#define STM32F746_PI6_FUNC_GPIO 0x8600
+#define STM32F746_PI6_FUNC_TIM8_CH2 0x8604
+#define STM32F746_PI6_FUNC_SAI2_SD_A 0x860b
+#define STM32F746_PI6_FUNC_FMC_D28 0x860d
+#define STM32F746_PI6_FUNC_DCMI_D6 0x860e
+#define STM32F746_PI6_FUNC_LCD_B6 0x860f
+#define STM32F746_PI6_FUNC_EVENTOUT 0x8610
+#define STM32F746_PI6_FUNC_ANALOG 0x8611
+
+#define STM32F746_PI7_FUNC_GPIO 0x8700
+#define STM32F746_PI7_FUNC_TIM8_CH3 0x8704
+#define STM32F746_PI7_FUNC_SAI2_FS_A 0x870b
+#define STM32F746_PI7_FUNC_FMC_D29 0x870d
+#define STM32F746_PI7_FUNC_DCMI_D7 0x870e
+#define STM32F746_PI7_FUNC_LCD_B7 0x870f
+#define STM32F746_PI7_FUNC_EVENTOUT 0x8710
+#define STM32F746_PI7_FUNC_ANALOG 0x8711
+
+#define STM32F746_PI8_FUNC_GPIO 0x8800
+#define STM32F746_PI8_FUNC_EVENTOUT 0x8810
+#define STM32F746_PI8_FUNC_ANALOG 0x8811
+
+#define STM32F746_PI9_FUNC_GPIO 0x8900
+#define STM32F746_PI9_FUNC_CAN1_RX 0x890a
+#define STM32F746_PI9_FUNC_FMC_D30 0x890d
+#define STM32F746_PI9_FUNC_LCD_VSYNC 0x890f
+#define STM32F746_PI9_FUNC_EVENTOUT 0x8910
+#define STM32F746_PI9_FUNC_ANALOG 0x8911
+
+#define STM32F746_PI10_FUNC_GPIO 0x8a00
+#define STM32F746_PI10_FUNC_ETH_MII_RX_ER 0x8a0c
+#define STM32F746_PI10_FUNC_FMC_D31 0x8a0d
+#define STM32F746_PI10_FUNC_LCD_HSYNC 0x8a0f
+#define STM32F746_PI10_FUNC_EVENTOUT 0x8a10
+#define STM32F746_PI10_FUNC_ANALOG 0x8a11
+
+#define STM32F746_PI11_FUNC_GPIO 0x8b00
+#define STM32F746_PI11_FUNC_OTG_HS_ULPI_DIR 0x8b0b
+#define STM32F746_PI11_FUNC_EVENTOUT 0x8b10
+#define STM32F746_PI11_FUNC_ANALOG 0x8b11
+
+#define STM32F746_PI12_FUNC_GPIO 0x8c00
+#define STM32F746_PI12_FUNC_LCD_HSYNC 0x8c0f
+#define STM32F746_PI12_FUNC_EVENTOUT 0x8c10
+#define STM32F746_PI12_FUNC_ANALOG 0x8c11
+
+#define STM32F746_PI13_FUNC_GPIO 0x8d00
+#define STM32F746_PI13_FUNC_LCD_VSYNC 0x8d0f
+#define STM32F746_PI13_FUNC_EVENTOUT 0x8d10
+#define STM32F746_PI13_FUNC_ANALOG 0x8d11
+
+#define STM32F746_PI14_FUNC_GPIO 0x8e00
+#define STM32F746_PI14_FUNC_LCD_CLK 0x8e0f
+#define STM32F746_PI14_FUNC_EVENTOUT 0x8e10
+#define STM32F746_PI14_FUNC_ANALOG 0x8e11
+
+#define STM32F746_PI15_FUNC_GPIO 0x8f00
+#define STM32F746_PI15_FUNC_LCD_R0 0x8f0f
+#define STM32F746_PI15_FUNC_EVENTOUT 0x8f10
+#define STM32F746_PI15_FUNC_ANALOG 0x8f11
+
+
+#define STM32F746_PJ0_FUNC_GPIO 0x9000
+#define STM32F746_PJ0_FUNC_LCD_R1 0x900f
+#define STM32F746_PJ0_FUNC_EVENTOUT 0x9010
+#define STM32F746_PJ0_FUNC_ANALOG 0x9011
+
+#define STM32F746_PJ1_FUNC_GPIO 0x9100
+#define STM32F746_PJ1_FUNC_LCD_R2 0x910f
+#define STM32F746_PJ1_FUNC_EVENTOUT 0x9110
+#define STM32F746_PJ1_FUNC_ANALOG 0x9111
+
+#define STM32F746_PJ2_FUNC_GPIO 0x9200
+#define STM32F746_PJ2_FUNC_LCD_R3 0x920f
+#define STM32F746_PJ2_FUNC_EVENTOUT 0x9210
+#define STM32F746_PJ2_FUNC_ANALOG 0x9211
+
+#define STM32F746_PJ3_FUNC_GPIO 0x9300
+#define STM32F746_PJ3_FUNC_LCD_R4 0x930f
+#define STM32F746_PJ3_FUNC_EVENTOUT 0x9310
+#define STM32F746_PJ3_FUNC_ANALOG 0x9311
+
+#define STM32F746_PJ4_FUNC_GPIO 0x9400
+#define STM32F746_PJ4_FUNC_LCD_R5 0x940f
+#define STM32F746_PJ4_FUNC_EVENTOUT 0x9410
+#define STM32F746_PJ4_FUNC_ANALOG 0x9411
+
+#define STM32F746_PJ5_FUNC_GPIO 0x9500
+#define STM32F746_PJ5_FUNC_LCD_R6 0x950f
+#define STM32F746_PJ5_FUNC_EVENTOUT 0x9510
+#define STM32F746_PJ5_FUNC_ANALOG 0x9511
+
+#define STM32F746_PJ6_FUNC_GPIO 0x9600
+#define STM32F746_PJ6_FUNC_LCD_R7 0x960f
+#define STM32F746_PJ6_FUNC_EVENTOUT 0x9610
+#define STM32F746_PJ6_FUNC_ANALOG 0x9611
+
+#define STM32F746_PJ7_FUNC_GPIO 0x9700
+#define STM32F746_PJ7_FUNC_LCD_G0 0x970f
+#define STM32F746_PJ7_FUNC_EVENTOUT 0x9710
+#define STM32F746_PJ7_FUNC_ANALOG 0x9711
+
+#define STM32F746_PJ8_FUNC_GPIO 0x9800
+#define STM32F746_PJ8_FUNC_LCD_G1 0x980f
+#define STM32F746_PJ8_FUNC_EVENTOUT 0x9810
+#define STM32F746_PJ8_FUNC_ANALOG 0x9811
+
+#define STM32F746_PJ9_FUNC_GPIO 0x9900
+#define STM32F746_PJ9_FUNC_LCD_G2 0x990f
+#define STM32F746_PJ9_FUNC_EVENTOUT 0x9910
+#define STM32F746_PJ9_FUNC_ANALOG 0x9911
+
+#define STM32F746_PJ10_FUNC_GPIO 0x9a00
+#define STM32F746_PJ10_FUNC_LCD_G3 0x9a0f
+#define STM32F746_PJ10_FUNC_EVENTOUT 0x9a10
+#define STM32F746_PJ10_FUNC_ANALOG 0x9a11
+
+#define STM32F746_PJ11_FUNC_GPIO 0x9b00
+#define STM32F746_PJ11_FUNC_LCD_G4 0x9b0f
+#define STM32F746_PJ11_FUNC_EVENTOUT 0x9b10
+#define STM32F746_PJ11_FUNC_ANALOG 0x9b11
+
+#define STM32F746_PJ12_FUNC_GPIO 0x9c00
+#define STM32F746_PJ12_FUNC_LCD_B0 0x9c0f
+#define STM32F746_PJ12_FUNC_EVENTOUT 0x9c10
+#define STM32F746_PJ12_FUNC_ANALOG 0x9c11
+
+#define STM32F746_PJ13_FUNC_GPIO 0x9d00
+#define STM32F746_PJ13_FUNC_LCD_B1 0x9d0f
+#define STM32F746_PJ13_FUNC_EVENTOUT 0x9d10
+#define STM32F746_PJ13_FUNC_ANALOG 0x9d11
+
+#define STM32F746_PJ14_FUNC_GPIO 0x9e00
+#define STM32F746_PJ14_FUNC_LCD_B2 0x9e0f
+#define STM32F746_PJ14_FUNC_EVENTOUT 0x9e10
+#define STM32F746_PJ14_FUNC_ANALOG 0x9e11
+
+#define STM32F746_PJ15_FUNC_GPIO 0x9f00
+#define STM32F746_PJ15_FUNC_LCD_B3 0x9f0f
+#define STM32F746_PJ15_FUNC_EVENTOUT 0x9f10
+#define STM32F746_PJ15_FUNC_ANALOG 0x9f11
+
+
+#define STM32F746_PK0_FUNC_GPIO 0xa000
+#define STM32F746_PK0_FUNC_LCD_G5 0xa00f
+#define STM32F746_PK0_FUNC_EVENTOUT 0xa010
+#define STM32F746_PK0_FUNC_ANALOG 0xa011
+
+#define STM32F746_PK1_FUNC_GPIO 0xa100
+#define STM32F746_PK1_FUNC_LCD_G6 0xa10f
+#define STM32F746_PK1_FUNC_EVENTOUT 0xa110
+#define STM32F746_PK1_FUNC_ANALOG 0xa111
+
+#define STM32F746_PK2_FUNC_GPIO 0xa200
+#define STM32F746_PK2_FUNC_LCD_G7 0xa20f
+#define STM32F746_PK2_FUNC_EVENTOUT 0xa210
+#define STM32F746_PK2_FUNC_ANALOG 0xa211
+
+#define STM32F746_PK3_FUNC_GPIO 0xa300
+#define STM32F746_PK3_FUNC_LCD_B4 0xa30f
+#define STM32F746_PK3_FUNC_EVENTOUT 0xa310
+#define STM32F746_PK3_FUNC_ANALOG 0xa311
+
+#define STM32F746_PK4_FUNC_GPIO 0xa400
+#define STM32F746_PK4_FUNC_LCD_B5 0xa40f
+#define STM32F746_PK4_FUNC_EVENTOUT 0xa410
+#define STM32F746_PK4_FUNC_ANALOG 0xa411
+
+#define STM32F746_PK5_FUNC_GPIO 0xa500
+#define STM32F746_PK5_FUNC_LCD_B6 0xa50f
+#define STM32F746_PK5_FUNC_EVENTOUT 0xa510
+#define STM32F746_PK5_FUNC_ANALOG 0xa511
+
+#define STM32F746_PK6_FUNC_GPIO 0xa600
+#define STM32F746_PK6_FUNC_LCD_B7 0xa60f
+#define STM32F746_PK6_FUNC_EVENTOUT 0xa610
+#define STM32F746_PK6_FUNC_ANALOG 0xa611
+
+#define STM32F746_PK7_FUNC_GPIO 0xa700
+#define STM32F746_PK7_FUNC_LCD_DE 0xa70f
+#define STM32F746_PK7_FUNC_EVENTOUT 0xa710
+#define STM32F746_PK7_FUNC_ANALOG 0xa711
+
+#endif /* _DT_BINDINGS_STM32F746_PINFUNC_H */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 288fac5294f5..db7c8bd39a3c 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -208,7 +208,6 @@ void acpi_boot_table_init (void);
int acpi_mps_check (void);
int acpi_numa_init (void);
-void early_acpi_table_init(void *data, size_t size);
int acpi_table_init (void);
int acpi_table_parse(char *id, acpi_tbl_table_handler handler);
int __init acpi_parse_entries(char *id, unsigned long table_size,
@@ -232,12 +231,26 @@ int acpi_table_parse_madt(enum acpi_madt_type id,
int acpi_parse_mcfg (struct acpi_table_header *header);
void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
-/* the following four functions are architecture-dependent */
+/* the following numa functions are architecture-dependent */
void acpi_numa_slit_init (struct acpi_table_slit *slit);
+
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
+#else
+static inline void
+acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) { }
+#endif
+
void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
+
+#ifdef CONFIG_ARM64
+void acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa);
+#else
+static inline void
+acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa) { }
+#endif
+
int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
-void acpi_numa_arch_fixup(void);
#ifndef PHYS_CPUID_INVALID
typedef u32 phys_cpuid_t;
@@ -444,8 +457,12 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
#define OSC_SB_HOTPLUG_OST_SUPPORT 0x00000008
#define OSC_SB_APEI_SUPPORT 0x00000010
#define OSC_SB_CPC_SUPPORT 0x00000020
+#define OSC_SB_CPCV2_SUPPORT 0x00000040
+#define OSC_SB_PCLPI_SUPPORT 0x00000080
+#define OSC_SB_OSLPI_SUPPORT 0x00000100
extern bool osc_sb_apei_support_acked;
+extern bool osc_pc_lpi_support_confirmed;
/* PCI Host Bridge _OSC: Capabilities DWORD 2: Support Field */
#define OSC_PCI_EXT_CONFIG_SUPPORT 0x00000001
@@ -532,6 +549,24 @@ void acpi_walk_dep_device_list(acpi_handle handle);
struct platform_device *acpi_create_platform_device(struct acpi_device *);
#define ACPI_PTR(_ptr) (_ptr)
+static inline void acpi_device_set_enumerated(struct acpi_device *adev)
+{
+ adev->flags.visited = true;
+}
+
+static inline void acpi_device_clear_enumerated(struct acpi_device *adev)
+{
+ adev->flags.visited = false;
+}
+
+enum acpi_reconfig_event {
+ ACPI_RECONFIG_DEVICE_ADD = 0,
+ ACPI_RECONFIG_DEVICE_REMOVE,
+};
+
+int acpi_reconfig_notifier_register(struct notifier_block *nb);
+int acpi_reconfig_notifier_unregister(struct notifier_block *nb);
+
#else /* !CONFIG_ACPI */
#define acpi_disabled 1
@@ -543,6 +578,11 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *);
struct fwnode_handle;
+static inline bool acpi_dev_found(const char *hid)
+{
+ return false;
+}
+
static inline bool is_acpi_node(struct fwnode_handle *fwnode)
{
return false;
@@ -588,7 +628,6 @@ static inline const char *acpi_dev_name(struct acpi_device *adev)
return NULL;
}
-static inline void early_acpi_table_init(void *data, size_t size) { }
static inline void acpi_early_init(void) { }
static inline void acpi_subsystem_init(void) { }
@@ -654,6 +693,14 @@ static inline bool acpi_driver_match_device(struct device *dev,
return false;
}
+static inline union acpi_object *acpi_evaluate_dsm(acpi_handle handle,
+ const u8 *uuid,
+ int rev, int func,
+ union acpi_object *argv4)
+{
+ return NULL;
+}
+
static inline int acpi_device_uevent_modalias(struct device *dev,
struct kobj_uevent_env *env)
{
@@ -678,6 +725,24 @@ static inline enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev)
#define ACPI_PTR(_ptr) (NULL)
+static inline void acpi_device_set_enumerated(struct acpi_device *adev)
+{
+}
+
+static inline void acpi_device_clear_enumerated(struct acpi_device *adev)
+{
+}
+
+static inline int acpi_reconfig_notifier_register(struct notifier_block *nb)
+{
+ return -EINVAL;
+}
+
+static inline int acpi_reconfig_notifier_unregister(struct notifier_block *nb)
+{
+ return -EINVAL;
+}
+
#endif /* !CONFIG_ACPI */
#ifdef CONFIG_ACPI
@@ -997,4 +1062,10 @@ static inline struct fwnode_handle *acpi_get_next_subnode(struct device *dev,
#define acpi_probe_device_table(t) ({ int __r = 0; __r;})
#endif
+#ifdef CONFIG_ACPI_TABLE_UPGRADE
+void acpi_table_upgrade(void);
+#else
+static inline void acpi_table_upgrade(void) { }
+#endif
+
#endif /*_LINUX_ACPI_H*/
diff --git a/include/linux/alarmtimer.h b/include/linux/alarmtimer.h
index 52f3b7da4f2d..9d8031257a90 100644
--- a/include/linux/alarmtimer.h
+++ b/include/linux/alarmtimer.h
@@ -26,10 +26,10 @@ enum alarmtimer_restart {
* struct alarm - Alarm timer structure
* @node: timerqueue node for adding to the event list this value
* also includes the expiration time.
- * @period: Period for recuring alarms
+ * @timer: hrtimer used to schedule events while running
* @function: Function pointer to be executed when the timer fires.
- * @type: Alarm type (BOOTTIME/REALTIME)
- * @enabled: Flag that represents if the alarm is set to fire or not
+ * @type: Alarm type (BOOTTIME/REALTIME).
+ * @state: Flag that represents if the alarm is set to fire or not.
* @data: Internal data value.
*/
struct alarm {
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 99346be5a7ca..adbc812c009b 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -46,8 +46,9 @@ enum {
ATA_MAX_SECTORS_128 = 128,
ATA_MAX_SECTORS = 256,
ATA_MAX_SECTORS_1024 = 1024,
- ATA_MAX_SECTORS_LBA48 = 65535,/* TODO: 65536? */
+ ATA_MAX_SECTORS_LBA48 = 65535,/* avoid count to be 0000h */
ATA_MAX_SECTORS_TAPE = 65535,
+ ATA_MAX_TRIM_RNUM = 64, /* 512-byte payload / (6-byte LBA + 2-byte range per entry) */
ATA_ID_WORDS = 256,
ATA_ID_CONFIG = 0,
@@ -409,6 +410,9 @@ enum {
SETFEATURES_WC_ON = 0x02, /* Enable write cache */
SETFEATURES_WC_OFF = 0x82, /* Disable write cache */
+ SETFEATURES_RA_ON = 0xaa, /* Enable read look-ahead */
+ SETFEATURES_RA_OFF = 0x55, /* Disable read look-ahead */
+
/* Enable/Disable Automatic Acoustic Management */
SETFEATURES_AAM_ON = 0x42,
SETFEATURES_AAM_OFF = 0xC2,
@@ -519,16 +523,23 @@ enum {
SERR_DEV_XCHG = (1 << 26), /* device exchanged */
};
-enum ata_tf_protocols {
- /* ATA taskfile protocols */
- ATA_PROT_UNKNOWN, /* unknown/invalid */
- ATA_PROT_NODATA, /* no data */
- ATA_PROT_PIO, /* PIO data xfer */
- ATA_PROT_DMA, /* DMA */
- ATA_PROT_NCQ, /* NCQ */
- ATAPI_PROT_NODATA, /* packet command, no data */
- ATAPI_PROT_PIO, /* packet command, PIO data xfer*/
- ATAPI_PROT_DMA, /* packet command with special DMA sauce */
+enum ata_prot_flags {
+ /* protocol flags */
+ ATA_PROT_FLAG_PIO = (1 << 0), /* is PIO */
+ ATA_PROT_FLAG_DMA = (1 << 1), /* is DMA */
+ ATA_PROT_FLAG_NCQ = (1 << 2), /* is NCQ */
+ ATA_PROT_FLAG_ATAPI = (1 << 3), /* is ATAPI */
+
+ /* taskfile protocols */
+ ATA_PROT_UNKNOWN = (u8)-1,
+ ATA_PROT_NODATA = 0,
+ ATA_PROT_PIO = ATA_PROT_FLAG_PIO,
+ ATA_PROT_DMA = ATA_PROT_FLAG_DMA,
+ ATA_PROT_NCQ_NODATA = ATA_PROT_FLAG_NCQ,
+ ATA_PROT_NCQ = ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ,
+ ATAPI_PROT_NODATA = ATA_PROT_FLAG_ATAPI,
+ ATAPI_PROT_PIO = ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO,
+ ATAPI_PROT_DMA = ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA,
};
enum ata_ioctls {
@@ -1066,12 +1077,12 @@ static inline void ata_id_to_hd_driveid(u16 *id)
* TO NV CACHE PINNED SET.
*/
static inline unsigned ata_set_lba_range_entries(void *_buffer,
- unsigned buf_size, u64 sector, unsigned long count)
+ unsigned num, u64 sector, unsigned long count)
{
__le64 *buffer = _buffer;
unsigned i = 0, used_bytes;
- while (i < buf_size / 8 ) { /* 6-byte LBA + 2-byte range per entry */
+ while (i < num) {
u64 entry = sector |
((u64)(count > 0xffff ? 0xffff : count) << 48);
buffer[i++] = __cpu_to_le64(entry);
@@ -1095,13 +1106,13 @@ static inline bool ata_ok(u8 status)
static inline bool lba_28_ok(u64 block, u32 n_block)
{
/* check the ending block number: must be LESS THAN 0x0fffffff */
- return ((block + n_block) < ((1 << 28) - 1)) && (n_block <= 256);
+ return ((block + n_block) < ((1 << 28) - 1)) && (n_block <= ATA_MAX_SECTORS);
}
static inline bool lba_48_ok(u64 block, u32 n_block)
{
/* check the ending block number */
- return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536);
+ return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= ATA_MAX_SECTORS_LBA48);
}
#define sata_pmp_gscr_vendor(gscr) ((gscr)[SATA_PMP_GSCR_PROD_ID] & 0xffff)
diff --git a/include/linux/ath9k_platform.h b/include/linux/ath9k_platform.h
index e66153d60bd5..76860a461ed2 100644
--- a/include/linux/ath9k_platform.h
+++ b/include/linux/ath9k_platform.h
@@ -40,6 +40,7 @@ struct ath9k_platform_data {
bool tx_gain_buffalo;
bool disable_2ghz;
bool disable_5ghz;
+ bool led_active_high;
int (*get_mac_revision)(void);
int (*external_reset)(void);
diff --git a/include/linux/atomic.h b/include/linux/atomic.h
index e451534fe54d..e71835bf60a9 100644
--- a/include/linux/atomic.h
+++ b/include/linux/atomic.h
@@ -163,206 +163,265 @@
#endif
#endif /* atomic_dec_return_relaxed */
-/* atomic_xchg_relaxed */
-#ifndef atomic_xchg_relaxed
-#define atomic_xchg_relaxed atomic_xchg
-#define atomic_xchg_acquire atomic_xchg
-#define atomic_xchg_release atomic_xchg
-#else /* atomic_xchg_relaxed */
+/* atomic_fetch_add_relaxed */
+#ifndef atomic_fetch_add_relaxed
+#define atomic_fetch_add_relaxed atomic_fetch_add
+#define atomic_fetch_add_acquire atomic_fetch_add
+#define atomic_fetch_add_release atomic_fetch_add
-#ifndef atomic_xchg_acquire
-#define atomic_xchg_acquire(...) \
- __atomic_op_acquire(atomic_xchg, __VA_ARGS__)
+#else /* atomic_fetch_add_relaxed */
+
+#ifndef atomic_fetch_add_acquire
+#define atomic_fetch_add_acquire(...) \
+ __atomic_op_acquire(atomic_fetch_add, __VA_ARGS__)
#endif
-#ifndef atomic_xchg_release
-#define atomic_xchg_release(...) \
- __atomic_op_release(atomic_xchg, __VA_ARGS__)
+#ifndef atomic_fetch_add_release
+#define atomic_fetch_add_release(...) \
+ __atomic_op_release(atomic_fetch_add, __VA_ARGS__)
#endif
-#ifndef atomic_xchg
-#define atomic_xchg(...) \
- __atomic_op_fence(atomic_xchg, __VA_ARGS__)
+#ifndef atomic_fetch_add
+#define atomic_fetch_add(...) \
+ __atomic_op_fence(atomic_fetch_add, __VA_ARGS__)
+#endif
+#endif /* atomic_fetch_add_relaxed */
+
+/* atomic_fetch_inc_relaxed */
+#ifndef atomic_fetch_inc_relaxed
+
+#ifndef atomic_fetch_inc
+#define atomic_fetch_inc(v) atomic_fetch_add(1, (v))
+#define atomic_fetch_inc_relaxed(v) atomic_fetch_add_relaxed(1, (v))
+#define atomic_fetch_inc_acquire(v) atomic_fetch_add_acquire(1, (v))
+#define atomic_fetch_inc_release(v) atomic_fetch_add_release(1, (v))
+#else /* atomic_fetch_inc */
+#define atomic_fetch_inc_relaxed atomic_fetch_inc
+#define atomic_fetch_inc_acquire atomic_fetch_inc
+#define atomic_fetch_inc_release atomic_fetch_inc
+#endif /* atomic_fetch_inc */
+
+#else /* atomic_fetch_inc_relaxed */
+
+#ifndef atomic_fetch_inc_acquire
+#define atomic_fetch_inc_acquire(...) \
+ __atomic_op_acquire(atomic_fetch_inc, __VA_ARGS__)
#endif
-#endif /* atomic_xchg_relaxed */
-/* atomic_cmpxchg_relaxed */
-#ifndef atomic_cmpxchg_relaxed
-#define atomic_cmpxchg_relaxed atomic_cmpxchg
-#define atomic_cmpxchg_acquire atomic_cmpxchg
-#define atomic_cmpxchg_release atomic_cmpxchg
+#ifndef atomic_fetch_inc_release
+#define atomic_fetch_inc_release(...) \
+ __atomic_op_release(atomic_fetch_inc, __VA_ARGS__)
+#endif
-#else /* atomic_cmpxchg_relaxed */
+#ifndef atomic_fetch_inc
+#define atomic_fetch_inc(...) \
+ __atomic_op_fence(atomic_fetch_inc, __VA_ARGS__)
+#endif
+#endif /* atomic_fetch_inc_relaxed */
-#ifndef atomic_cmpxchg_acquire
-#define atomic_cmpxchg_acquire(...) \
- __atomic_op_acquire(atomic_cmpxchg, __VA_ARGS__)
+/* atomic_fetch_sub_relaxed */
+#ifndef atomic_fetch_sub_relaxed
+#define atomic_fetch_sub_relaxed atomic_fetch_sub
+#define atomic_fetch_sub_acquire atomic_fetch_sub
+#define atomic_fetch_sub_release atomic_fetch_sub
+
+#else /* atomic_fetch_sub_relaxed */
+
+#ifndef atomic_fetch_sub_acquire
+#define atomic_fetch_sub_acquire(...) \
+ __atomic_op_acquire(atomic_fetch_sub, __VA_ARGS__)
#endif
-#ifndef atomic_cmpxchg_release
-#define atomic_cmpxchg_release(...) \
- __atomic_op_release(atomic_cmpxchg, __VA_ARGS__)
+#ifndef atomic_fetch_sub_release
+#define atomic_fetch_sub_release(...) \
+ __atomic_op_release(atomic_fetch_sub, __VA_ARGS__)
#endif
-#ifndef atomic_cmpxchg
-#define atomic_cmpxchg(...) \
- __atomic_op_fence(atomic_cmpxchg, __VA_ARGS__)
+#ifndef atomic_fetch_sub
+#define atomic_fetch_sub(...) \
+ __atomic_op_fence(atomic_fetch_sub, __VA_ARGS__)
+#endif
+#endif /* atomic_fetch_sub_relaxed */
+
+/* atomic_fetch_dec_relaxed */
+#ifndef atomic_fetch_dec_relaxed
+
+#ifndef atomic_fetch_dec
+#define atomic_fetch_dec(v) atomic_fetch_sub(1, (v))
+#define atomic_fetch_dec_relaxed(v) atomic_fetch_sub_relaxed(1, (v))
+#define atomic_fetch_dec_acquire(v) atomic_fetch_sub_acquire(1, (v))
+#define atomic_fetch_dec_release(v) atomic_fetch_sub_release(1, (v))
+#else /* atomic_fetch_dec */
+#define atomic_fetch_dec_relaxed atomic_fetch_dec
+#define atomic_fetch_dec_acquire atomic_fetch_dec
+#define atomic_fetch_dec_release atomic_fetch_dec
+#endif /* atomic_fetch_dec */
+
+#else /* atomic_fetch_dec_relaxed */
+
+#ifndef atomic_fetch_dec_acquire
+#define atomic_fetch_dec_acquire(...) \
+ __atomic_op_acquire(atomic_fetch_dec, __VA_ARGS__)
#endif
-#endif /* atomic_cmpxchg_relaxed */
-#ifndef atomic64_read_acquire
-#define atomic64_read_acquire(v) smp_load_acquire(&(v)->counter)
+#ifndef atomic_fetch_dec_release
+#define atomic_fetch_dec_release(...) \
+ __atomic_op_release(atomic_fetch_dec, __VA_ARGS__)
#endif
-#ifndef atomic64_set_release
-#define atomic64_set_release(v, i) smp_store_release(&(v)->counter, (i))
+#ifndef atomic_fetch_dec
+#define atomic_fetch_dec(...) \
+ __atomic_op_fence(atomic_fetch_dec, __VA_ARGS__)
#endif
+#endif /* atomic_fetch_dec_relaxed */
-/* atomic64_add_return_relaxed */
-#ifndef atomic64_add_return_relaxed
-#define atomic64_add_return_relaxed atomic64_add_return
-#define atomic64_add_return_acquire atomic64_add_return
-#define atomic64_add_return_release atomic64_add_return
+/* atomic_fetch_or_relaxed */
+#ifndef atomic_fetch_or_relaxed
+#define atomic_fetch_or_relaxed atomic_fetch_or
+#define atomic_fetch_or_acquire atomic_fetch_or
+#define atomic_fetch_or_release atomic_fetch_or
-#else /* atomic64_add_return_relaxed */
+#else /* atomic_fetch_or_relaxed */
-#ifndef atomic64_add_return_acquire
-#define atomic64_add_return_acquire(...) \
- __atomic_op_acquire(atomic64_add_return, __VA_ARGS__)
+#ifndef atomic_fetch_or_acquire
+#define atomic_fetch_or_acquire(...) \
+ __atomic_op_acquire(atomic_fetch_or, __VA_ARGS__)
#endif
-#ifndef atomic64_add_return_release
-#define atomic64_add_return_release(...) \
- __atomic_op_release(atomic64_add_return, __VA_ARGS__)
+#ifndef atomic_fetch_or_release
+#define atomic_fetch_or_release(...) \
+ __atomic_op_release(atomic_fetch_or, __VA_ARGS__)
#endif
-#ifndef atomic64_add_return
-#define atomic64_add_return(...) \
- __atomic_op_fence(atomic64_add_return, __VA_ARGS__)
+#ifndef atomic_fetch_or
+#define atomic_fetch_or(...) \
+ __atomic_op_fence(atomic_fetch_or, __VA_ARGS__)
#endif
-#endif /* atomic64_add_return_relaxed */
+#endif /* atomic_fetch_or_relaxed */
-/* atomic64_inc_return_relaxed */
-#ifndef atomic64_inc_return_relaxed
-#define atomic64_inc_return_relaxed atomic64_inc_return
-#define atomic64_inc_return_acquire atomic64_inc_return
-#define atomic64_inc_return_release atomic64_inc_return
+/* atomic_fetch_and_relaxed */
+#ifndef atomic_fetch_and_relaxed
+#define atomic_fetch_and_relaxed atomic_fetch_and
+#define atomic_fetch_and_acquire atomic_fetch_and
+#define atomic_fetch_and_release atomic_fetch_and
-#else /* atomic64_inc_return_relaxed */
+#else /* atomic_fetch_and_relaxed */
-#ifndef atomic64_inc_return_acquire
-#define atomic64_inc_return_acquire(...) \
- __atomic_op_acquire(atomic64_inc_return, __VA_ARGS__)
+#ifndef atomic_fetch_and_acquire
+#define atomic_fetch_and_acquire(...) \
+ __atomic_op_acquire(atomic_fetch_and, __VA_ARGS__)
#endif
-#ifndef atomic64_inc_return_release
-#define atomic64_inc_return_release(...) \
- __atomic_op_release(atomic64_inc_return, __VA_ARGS__)
+#ifndef atomic_fetch_and_release
+#define atomic_fetch_and_release(...) \
+ __atomic_op_release(atomic_fetch_and, __VA_ARGS__)
#endif
-#ifndef atomic64_inc_return
-#define atomic64_inc_return(...) \
- __atomic_op_fence(atomic64_inc_return, __VA_ARGS__)
+#ifndef atomic_fetch_and
+#define atomic_fetch_and(...) \
+ __atomic_op_fence(atomic_fetch_and, __VA_ARGS__)
#endif
-#endif /* atomic64_inc_return_relaxed */
-
+#endif /* atomic_fetch_and_relaxed */
-/* atomic64_sub_return_relaxed */
-#ifndef atomic64_sub_return_relaxed
-#define atomic64_sub_return_relaxed atomic64_sub_return
-#define atomic64_sub_return_acquire atomic64_sub_return
-#define atomic64_sub_return_release atomic64_sub_return
+#ifdef atomic_andnot
+/* atomic_fetch_andnot_relaxed */
+#ifndef atomic_fetch_andnot_relaxed
+#define atomic_fetch_andnot_relaxed atomic_fetch_andnot
+#define atomic_fetch_andnot_acquire atomic_fetch_andnot
+#define atomic_fetch_andnot_release atomic_fetch_andnot
-#else /* atomic64_sub_return_relaxed */
+#else /* atomic_fetch_andnot_relaxed */
-#ifndef atomic64_sub_return_acquire
-#define atomic64_sub_return_acquire(...) \
- __atomic_op_acquire(atomic64_sub_return, __VA_ARGS__)
+#ifndef atomic_fetch_andnot_acquire
+#define atomic_fetch_andnot_acquire(...) \
+ __atomic_op_acquire(atomic_fetch_andnot, __VA_ARGS__)
#endif
-#ifndef atomic64_sub_return_release
-#define atomic64_sub_return_release(...) \
- __atomic_op_release(atomic64_sub_return, __VA_ARGS__)
+#ifndef atomic_fetch_andnot_release
+#define atomic_fetch_andnot_release(...) \
+ __atomic_op_release(atomic_fetch_andnot, __VA_ARGS__)
#endif
-#ifndef atomic64_sub_return
-#define atomic64_sub_return(...) \
- __atomic_op_fence(atomic64_sub_return, __VA_ARGS__)
+#ifndef atomic_fetch_andnot
+#define atomic_fetch_andnot(...) \
+ __atomic_op_fence(atomic_fetch_andnot, __VA_ARGS__)
#endif
-#endif /* atomic64_sub_return_relaxed */
+#endif /* atomic_fetch_andnot_relaxed */
+#endif /* atomic_andnot */
-/* atomic64_dec_return_relaxed */
-#ifndef atomic64_dec_return_relaxed
-#define atomic64_dec_return_relaxed atomic64_dec_return
-#define atomic64_dec_return_acquire atomic64_dec_return
-#define atomic64_dec_return_release atomic64_dec_return
+/* atomic_fetch_xor_relaxed */
+#ifndef atomic_fetch_xor_relaxed
+#define atomic_fetch_xor_relaxed atomic_fetch_xor
+#define atomic_fetch_xor_acquire atomic_fetch_xor
+#define atomic_fetch_xor_release atomic_fetch_xor
-#else /* atomic64_dec_return_relaxed */
+#else /* atomic_fetch_xor_relaxed */
-#ifndef atomic64_dec_return_acquire
-#define atomic64_dec_return_acquire(...) \
- __atomic_op_acquire(atomic64_dec_return, __VA_ARGS__)
+#ifndef atomic_fetch_xor_acquire
+#define atomic_fetch_xor_acquire(...) \
+ __atomic_op_acquire(atomic_fetch_xor, __VA_ARGS__)
#endif
-#ifndef atomic64_dec_return_release
-#define atomic64_dec_return_release(...) \
- __atomic_op_release(atomic64_dec_return, __VA_ARGS__)
+#ifndef atomic_fetch_xor_release
+#define atomic_fetch_xor_release(...) \
+ __atomic_op_release(atomic_fetch_xor, __VA_ARGS__)
#endif
-#ifndef atomic64_dec_return
-#define atomic64_dec_return(...) \
- __atomic_op_fence(atomic64_dec_return, __VA_ARGS__)
+#ifndef atomic_fetch_xor
+#define atomic_fetch_xor(...) \
+ __atomic_op_fence(atomic_fetch_xor, __VA_ARGS__)
#endif
-#endif /* atomic64_dec_return_relaxed */
+#endif /* atomic_fetch_xor_relaxed */
-/* atomic64_xchg_relaxed */
-#ifndef atomic64_xchg_relaxed
-#define atomic64_xchg_relaxed atomic64_xchg
-#define atomic64_xchg_acquire atomic64_xchg
-#define atomic64_xchg_release atomic64_xchg
-#else /* atomic64_xchg_relaxed */
+/* atomic_xchg_relaxed */
+#ifndef atomic_xchg_relaxed
+#define atomic_xchg_relaxed atomic_xchg
+#define atomic_xchg_acquire atomic_xchg
+#define atomic_xchg_release atomic_xchg
-#ifndef atomic64_xchg_acquire
-#define atomic64_xchg_acquire(...) \
- __atomic_op_acquire(atomic64_xchg, __VA_ARGS__)
+#else /* atomic_xchg_relaxed */
+
+#ifndef atomic_xchg_acquire
+#define atomic_xchg_acquire(...) \
+ __atomic_op_acquire(atomic_xchg, __VA_ARGS__)
#endif
-#ifndef atomic64_xchg_release
-#define atomic64_xchg_release(...) \
- __atomic_op_release(atomic64_xchg, __VA_ARGS__)
+#ifndef atomic_xchg_release
+#define atomic_xchg_release(...) \
+ __atomic_op_release(atomic_xchg, __VA_ARGS__)
#endif
-#ifndef atomic64_xchg
-#define atomic64_xchg(...) \
- __atomic_op_fence(atomic64_xchg, __VA_ARGS__)
+#ifndef atomic_xchg
+#define atomic_xchg(...) \
+ __atomic_op_fence(atomic_xchg, __VA_ARGS__)
#endif
-#endif /* atomic64_xchg_relaxed */
+#endif /* atomic_xchg_relaxed */
-/* atomic64_cmpxchg_relaxed */
-#ifndef atomic64_cmpxchg_relaxed
-#define atomic64_cmpxchg_relaxed atomic64_cmpxchg
-#define atomic64_cmpxchg_acquire atomic64_cmpxchg
-#define atomic64_cmpxchg_release atomic64_cmpxchg
+/* atomic_cmpxchg_relaxed */
+#ifndef atomic_cmpxchg_relaxed
+#define atomic_cmpxchg_relaxed atomic_cmpxchg
+#define atomic_cmpxchg_acquire atomic_cmpxchg
+#define atomic_cmpxchg_release atomic_cmpxchg
-#else /* atomic64_cmpxchg_relaxed */
+#else /* atomic_cmpxchg_relaxed */
-#ifndef atomic64_cmpxchg_acquire
-#define atomic64_cmpxchg_acquire(...) \
- __atomic_op_acquire(atomic64_cmpxchg, __VA_ARGS__)
+#ifndef atomic_cmpxchg_acquire
+#define atomic_cmpxchg_acquire(...) \
+ __atomic_op_acquire(atomic_cmpxchg, __VA_ARGS__)
#endif
-#ifndef atomic64_cmpxchg_release
-#define atomic64_cmpxchg_release(...) \
- __atomic_op_release(atomic64_cmpxchg, __VA_ARGS__)
+#ifndef atomic_cmpxchg_release
+#define atomic_cmpxchg_release(...) \
+ __atomic_op_release(atomic_cmpxchg, __VA_ARGS__)
#endif
-#ifndef atomic64_cmpxchg
-#define atomic64_cmpxchg(...) \
- __atomic_op_fence(atomic64_cmpxchg, __VA_ARGS__)
+#ifndef atomic_cmpxchg
+#define atomic_cmpxchg(...) \
+ __atomic_op_fence(atomic_cmpxchg, __VA_ARGS__)
#endif
-#endif /* atomic64_cmpxchg_relaxed */
+#endif /* atomic_cmpxchg_relaxed */
/* cmpxchg_relaxed */
#ifndef cmpxchg_relaxed
@@ -463,18 +522,28 @@ static inline void atomic_andnot(int i, atomic_t *v)
{
atomic_and(~i, v);
}
-#endif
-static inline __deprecated void atomic_clear_mask(unsigned int mask, atomic_t *v)
+static inline int atomic_fetch_andnot(int i, atomic_t *v)
{
- atomic_andnot(mask, v);
+ return atomic_fetch_and(~i, v);
}
-static inline __deprecated void atomic_set_mask(unsigned int mask, atomic_t *v)
+static inline int atomic_fetch_andnot_relaxed(int i, atomic_t *v)
{
- atomic_or(mask, v);
+ return atomic_fetch_and_relaxed(~i, v);
}
+static inline int atomic_fetch_andnot_acquire(int i, atomic_t *v)
+{
+ return atomic_fetch_and_acquire(~i, v);
+}
+
+static inline int atomic_fetch_andnot_release(int i, atomic_t *v)
+{
+ return atomic_fetch_and_release(~i, v);
+}
+#endif
+
/**
* atomic_inc_not_zero_hint - increment if not null
* @v: pointer of type atomic_t
@@ -558,36 +627,400 @@ static inline int atomic_dec_if_positive(atomic_t *v)
}
#endif
-/**
- * atomic_fetch_or - perform *p |= mask and return old value of *p
- * @mask: mask to OR on the atomic_t
- * @p: pointer to atomic_t
- */
-#ifndef atomic_fetch_or
-static inline int atomic_fetch_or(int mask, atomic_t *p)
-{
- int old, val = atomic_read(p);
+#ifdef CONFIG_GENERIC_ATOMIC64
+#include <asm-generic/atomic64.h>
+#endif
- for (;;) {
- old = atomic_cmpxchg(p, val, val | mask);
- if (old == val)
- break;
- val = old;
- }
+#ifndef atomic64_read_acquire
+#define atomic64_read_acquire(v) smp_load_acquire(&(v)->counter)
+#endif
- return old;
-}
+#ifndef atomic64_set_release
+#define atomic64_set_release(v, i) smp_store_release(&(v)->counter, (i))
#endif
-#ifdef CONFIG_GENERIC_ATOMIC64
-#include <asm-generic/atomic64.h>
+/* atomic64_add_return_relaxed */
+#ifndef atomic64_add_return_relaxed
+#define atomic64_add_return_relaxed atomic64_add_return
+#define atomic64_add_return_acquire atomic64_add_return
+#define atomic64_add_return_release atomic64_add_return
+
+#else /* atomic64_add_return_relaxed */
+
+#ifndef atomic64_add_return_acquire
+#define atomic64_add_return_acquire(...) \
+ __atomic_op_acquire(atomic64_add_return, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_add_return_release
+#define atomic64_add_return_release(...) \
+ __atomic_op_release(atomic64_add_return, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_add_return
+#define atomic64_add_return(...) \
+ __atomic_op_fence(atomic64_add_return, __VA_ARGS__)
+#endif
+#endif /* atomic64_add_return_relaxed */
+
+/* atomic64_inc_return_relaxed */
+#ifndef atomic64_inc_return_relaxed
+#define atomic64_inc_return_relaxed atomic64_inc_return
+#define atomic64_inc_return_acquire atomic64_inc_return
+#define atomic64_inc_return_release atomic64_inc_return
+
+#else /* atomic64_inc_return_relaxed */
+
+#ifndef atomic64_inc_return_acquire
+#define atomic64_inc_return_acquire(...) \
+ __atomic_op_acquire(atomic64_inc_return, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_inc_return_release
+#define atomic64_inc_return_release(...) \
+ __atomic_op_release(atomic64_inc_return, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_inc_return
+#define atomic64_inc_return(...) \
+ __atomic_op_fence(atomic64_inc_return, __VA_ARGS__)
+#endif
+#endif /* atomic64_inc_return_relaxed */
+
+
+/* atomic64_sub_return_relaxed */
+#ifndef atomic64_sub_return_relaxed
+#define atomic64_sub_return_relaxed atomic64_sub_return
+#define atomic64_sub_return_acquire atomic64_sub_return
+#define atomic64_sub_return_release atomic64_sub_return
+
+#else /* atomic64_sub_return_relaxed */
+
+#ifndef atomic64_sub_return_acquire
+#define atomic64_sub_return_acquire(...) \
+ __atomic_op_acquire(atomic64_sub_return, __VA_ARGS__)
#endif
+#ifndef atomic64_sub_return_release
+#define atomic64_sub_return_release(...) \
+ __atomic_op_release(atomic64_sub_return, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_sub_return
+#define atomic64_sub_return(...) \
+ __atomic_op_fence(atomic64_sub_return, __VA_ARGS__)
+#endif
+#endif /* atomic64_sub_return_relaxed */
+
+/* atomic64_dec_return_relaxed */
+#ifndef atomic64_dec_return_relaxed
+#define atomic64_dec_return_relaxed atomic64_dec_return
+#define atomic64_dec_return_acquire atomic64_dec_return
+#define atomic64_dec_return_release atomic64_dec_return
+
+#else /* atomic64_dec_return_relaxed */
+
+#ifndef atomic64_dec_return_acquire
+#define atomic64_dec_return_acquire(...) \
+ __atomic_op_acquire(atomic64_dec_return, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_dec_return_release
+#define atomic64_dec_return_release(...) \
+ __atomic_op_release(atomic64_dec_return, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_dec_return
+#define atomic64_dec_return(...) \
+ __atomic_op_fence(atomic64_dec_return, __VA_ARGS__)
+#endif
+#endif /* atomic64_dec_return_relaxed */
+
+
+/* atomic64_fetch_add_relaxed */
+#ifndef atomic64_fetch_add_relaxed
+#define atomic64_fetch_add_relaxed atomic64_fetch_add
+#define atomic64_fetch_add_acquire atomic64_fetch_add
+#define atomic64_fetch_add_release atomic64_fetch_add
+
+#else /* atomic64_fetch_add_relaxed */
+
+#ifndef atomic64_fetch_add_acquire
+#define atomic64_fetch_add_acquire(...) \
+ __atomic_op_acquire(atomic64_fetch_add, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_add_release
+#define atomic64_fetch_add_release(...) \
+ __atomic_op_release(atomic64_fetch_add, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_add
+#define atomic64_fetch_add(...) \
+ __atomic_op_fence(atomic64_fetch_add, __VA_ARGS__)
+#endif
+#endif /* atomic64_fetch_add_relaxed */
+
+/* atomic64_fetch_inc_relaxed */
+#ifndef atomic64_fetch_inc_relaxed
+
+#ifndef atomic64_fetch_inc
+#define atomic64_fetch_inc(v) atomic64_fetch_add(1, (v))
+#define atomic64_fetch_inc_relaxed(v) atomic64_fetch_add_relaxed(1, (v))
+#define atomic64_fetch_inc_acquire(v) atomic64_fetch_add_acquire(1, (v))
+#define atomic64_fetch_inc_release(v) atomic64_fetch_add_release(1, (v))
+#else /* atomic64_fetch_inc */
+#define atomic64_fetch_inc_relaxed atomic64_fetch_inc
+#define atomic64_fetch_inc_acquire atomic64_fetch_inc
+#define atomic64_fetch_inc_release atomic64_fetch_inc
+#endif /* atomic64_fetch_inc */
+
+#else /* atomic64_fetch_inc_relaxed */
+
+#ifndef atomic64_fetch_inc_acquire
+#define atomic64_fetch_inc_acquire(...) \
+ __atomic_op_acquire(atomic64_fetch_inc, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_inc_release
+#define atomic64_fetch_inc_release(...) \
+ __atomic_op_release(atomic64_fetch_inc, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_inc
+#define atomic64_fetch_inc(...) \
+ __atomic_op_fence(atomic64_fetch_inc, __VA_ARGS__)
+#endif
+#endif /* atomic64_fetch_inc_relaxed */
+
+/* atomic64_fetch_sub_relaxed */
+#ifndef atomic64_fetch_sub_relaxed
+#define atomic64_fetch_sub_relaxed atomic64_fetch_sub
+#define atomic64_fetch_sub_acquire atomic64_fetch_sub
+#define atomic64_fetch_sub_release atomic64_fetch_sub
+
+#else /* atomic64_fetch_sub_relaxed */
+
+#ifndef atomic64_fetch_sub_acquire
+#define atomic64_fetch_sub_acquire(...) \
+ __atomic_op_acquire(atomic64_fetch_sub, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_sub_release
+#define atomic64_fetch_sub_release(...) \
+ __atomic_op_release(atomic64_fetch_sub, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_sub
+#define atomic64_fetch_sub(...) \
+ __atomic_op_fence(atomic64_fetch_sub, __VA_ARGS__)
+#endif
+#endif /* atomic64_fetch_sub_relaxed */
+
+/* atomic64_fetch_dec_relaxed */
+#ifndef atomic64_fetch_dec_relaxed
+
+#ifndef atomic64_fetch_dec
+#define atomic64_fetch_dec(v) atomic64_fetch_sub(1, (v))
+#define atomic64_fetch_dec_relaxed(v) atomic64_fetch_sub_relaxed(1, (v))
+#define atomic64_fetch_dec_acquire(v) atomic64_fetch_sub_acquire(1, (v))
+#define atomic64_fetch_dec_release(v) atomic64_fetch_sub_release(1, (v))
+#else /* atomic64_fetch_dec */
+#define atomic64_fetch_dec_relaxed atomic64_fetch_dec
+#define atomic64_fetch_dec_acquire atomic64_fetch_dec
+#define atomic64_fetch_dec_release atomic64_fetch_dec
+#endif /* atomic64_fetch_dec */
+
+#else /* atomic64_fetch_dec_relaxed */
+
+#ifndef atomic64_fetch_dec_acquire
+#define atomic64_fetch_dec_acquire(...) \
+ __atomic_op_acquire(atomic64_fetch_dec, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_dec_release
+#define atomic64_fetch_dec_release(...) \
+ __atomic_op_release(atomic64_fetch_dec, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_dec
+#define atomic64_fetch_dec(...) \
+ __atomic_op_fence(atomic64_fetch_dec, __VA_ARGS__)
+#endif
+#endif /* atomic64_fetch_dec_relaxed */
+
+/* atomic64_fetch_or_relaxed */
+#ifndef atomic64_fetch_or_relaxed
+#define atomic64_fetch_or_relaxed atomic64_fetch_or
+#define atomic64_fetch_or_acquire atomic64_fetch_or
+#define atomic64_fetch_or_release atomic64_fetch_or
+
+#else /* atomic64_fetch_or_relaxed */
+
+#ifndef atomic64_fetch_or_acquire
+#define atomic64_fetch_or_acquire(...) \
+ __atomic_op_acquire(atomic64_fetch_or, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_or_release
+#define atomic64_fetch_or_release(...) \
+ __atomic_op_release(atomic64_fetch_or, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_or
+#define atomic64_fetch_or(...) \
+ __atomic_op_fence(atomic64_fetch_or, __VA_ARGS__)
+#endif
+#endif /* atomic64_fetch_or_relaxed */
+
+/* atomic64_fetch_and_relaxed */
+#ifndef atomic64_fetch_and_relaxed
+#define atomic64_fetch_and_relaxed atomic64_fetch_and
+#define atomic64_fetch_and_acquire atomic64_fetch_and
+#define atomic64_fetch_and_release atomic64_fetch_and
+
+#else /* atomic64_fetch_and_relaxed */
+
+#ifndef atomic64_fetch_and_acquire
+#define atomic64_fetch_and_acquire(...) \
+ __atomic_op_acquire(atomic64_fetch_and, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_and_release
+#define atomic64_fetch_and_release(...) \
+ __atomic_op_release(atomic64_fetch_and, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_and
+#define atomic64_fetch_and(...) \
+ __atomic_op_fence(atomic64_fetch_and, __VA_ARGS__)
+#endif
+#endif /* atomic64_fetch_and_relaxed */
+
+#ifdef atomic64_andnot
+/* atomic64_fetch_andnot_relaxed */
+#ifndef atomic64_fetch_andnot_relaxed
+#define atomic64_fetch_andnot_relaxed atomic64_fetch_andnot
+#define atomic64_fetch_andnot_acquire atomic64_fetch_andnot
+#define atomic64_fetch_andnot_release atomic64_fetch_andnot
+
+#else /* atomic64_fetch_andnot_relaxed */
+
+#ifndef atomic64_fetch_andnot_acquire
+#define atomic64_fetch_andnot_acquire(...) \
+ __atomic_op_acquire(atomic64_fetch_andnot, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_andnot_release
+#define atomic64_fetch_andnot_release(...) \
+ __atomic_op_release(atomic64_fetch_andnot, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_andnot
+#define atomic64_fetch_andnot(...) \
+ __atomic_op_fence(atomic64_fetch_andnot, __VA_ARGS__)
+#endif
+#endif /* atomic64_fetch_andnot_relaxed */
+#endif /* atomic64_andnot */
+
+/* atomic64_fetch_xor_relaxed */
+#ifndef atomic64_fetch_xor_relaxed
+#define atomic64_fetch_xor_relaxed atomic64_fetch_xor
+#define atomic64_fetch_xor_acquire atomic64_fetch_xor
+#define atomic64_fetch_xor_release atomic64_fetch_xor
+
+#else /* atomic64_fetch_xor_relaxed */
+
+#ifndef atomic64_fetch_xor_acquire
+#define atomic64_fetch_xor_acquire(...) \
+ __atomic_op_acquire(atomic64_fetch_xor, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_xor_release
+#define atomic64_fetch_xor_release(...) \
+ __atomic_op_release(atomic64_fetch_xor, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_fetch_xor
+#define atomic64_fetch_xor(...) \
+ __atomic_op_fence(atomic64_fetch_xor, __VA_ARGS__)
+#endif
+#endif /* atomic64_fetch_xor_relaxed */
+
+
+/* atomic64_xchg_relaxed */
+#ifndef atomic64_xchg_relaxed
+#define atomic64_xchg_relaxed atomic64_xchg
+#define atomic64_xchg_acquire atomic64_xchg
+#define atomic64_xchg_release atomic64_xchg
+
+#else /* atomic64_xchg_relaxed */
+
+#ifndef atomic64_xchg_acquire
+#define atomic64_xchg_acquire(...) \
+ __atomic_op_acquire(atomic64_xchg, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_xchg_release
+#define atomic64_xchg_release(...) \
+ __atomic_op_release(atomic64_xchg, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_xchg
+#define atomic64_xchg(...) \
+ __atomic_op_fence(atomic64_xchg, __VA_ARGS__)
+#endif
+#endif /* atomic64_xchg_relaxed */
+
+/* atomic64_cmpxchg_relaxed */
+#ifndef atomic64_cmpxchg_relaxed
+#define atomic64_cmpxchg_relaxed atomic64_cmpxchg
+#define atomic64_cmpxchg_acquire atomic64_cmpxchg
+#define atomic64_cmpxchg_release atomic64_cmpxchg
+
+#else /* atomic64_cmpxchg_relaxed */
+
+#ifndef atomic64_cmpxchg_acquire
+#define atomic64_cmpxchg_acquire(...) \
+ __atomic_op_acquire(atomic64_cmpxchg, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_cmpxchg_release
+#define atomic64_cmpxchg_release(...) \
+ __atomic_op_release(atomic64_cmpxchg, __VA_ARGS__)
+#endif
+
+#ifndef atomic64_cmpxchg
+#define atomic64_cmpxchg(...) \
+ __atomic_op_fence(atomic64_cmpxchg, __VA_ARGS__)
+#endif
+#endif /* atomic64_cmpxchg_relaxed */
+
#ifndef atomic64_andnot
static inline void atomic64_andnot(long long i, atomic64_t *v)
{
atomic64_and(~i, v);
}
+
+static inline long long atomic64_fetch_andnot(long long i, atomic64_t *v)
+{
+ return atomic64_fetch_and(~i, v);
+}
+
+static inline long long atomic64_fetch_andnot_relaxed(long long i, atomic64_t *v)
+{
+ return atomic64_fetch_and_relaxed(~i, v);
+}
+
+static inline long long atomic64_fetch_andnot_acquire(long long i, atomic64_t *v)
+{
+ return atomic64_fetch_and_acquire(~i, v);
+}
+
+static inline long long atomic64_fetch_andnot_release(long long i, atomic64_t *v)
+{
+ return atomic64_fetch_and_release(~i, v);
+}
#endif
#include <asm-generic/atomic-long.h>
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index c82794f20110..491a91717788 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -197,7 +197,7 @@ static inline int wb_congested(struct bdi_writeback *wb, int cong_bits)
}
long congestion_wait(int sync, long timeout);
-long wait_iff_congested(struct zone *zone, int sync, long timeout);
+long wait_iff_congested(struct pglist_data *pgdat, int sync, long timeout);
int pdflush_proc_obsolete(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
diff --git a/include/linux/balloon_compaction.h b/include/linux/balloon_compaction.h
index 9b0a15d06a4f..79542b2698ec 100644
--- a/include/linux/balloon_compaction.h
+++ b/include/linux/balloon_compaction.h
@@ -48,6 +48,7 @@
#include <linux/migrate.h>
#include <linux/gfp.h>
#include <linux/err.h>
+#include <linux/fs.h>
/*
* Balloon device information descriptor.
@@ -62,6 +63,7 @@ struct balloon_dev_info {
struct list_head pages; /* Pages enqueued & handled to Host */
int (*migratepage)(struct balloon_dev_info *, struct page *newpage,
struct page *page, enum migrate_mode mode);
+ struct inode *inode;
};
extern struct page *balloon_page_enqueue(struct balloon_dev_info *b_dev_info);
@@ -73,45 +75,19 @@ static inline void balloon_devinfo_init(struct balloon_dev_info *balloon)
spin_lock_init(&balloon->pages_lock);
INIT_LIST_HEAD(&balloon->pages);
balloon->migratepage = NULL;
+ balloon->inode = NULL;
}
#ifdef CONFIG_BALLOON_COMPACTION
-extern bool balloon_page_isolate(struct page *page);
+extern const struct address_space_operations balloon_aops;
+extern bool balloon_page_isolate(struct page *page,
+ isolate_mode_t mode);
extern void balloon_page_putback(struct page *page);
-extern int balloon_page_migrate(struct page *newpage,
+extern int balloon_page_migrate(struct address_space *mapping,
+ struct page *newpage,
struct page *page, enum migrate_mode mode);
/*
- * __is_movable_balloon_page - helper to perform @page PageBalloon tests
- */
-static inline bool __is_movable_balloon_page(struct page *page)
-{
- return PageBalloon(page);
-}
-
-/*
- * balloon_page_movable - test PageBalloon to identify balloon pages
- * and PagePrivate to check that the page is not
- * isolated and can be moved by compaction/migration.
- *
- * As we might return false positives in the case of a balloon page being just
- * released under us, this need to be re-tested later, under the page lock.
- */
-static inline bool balloon_page_movable(struct page *page)
-{
- return PageBalloon(page) && PagePrivate(page);
-}
-
-/*
- * isolated_balloon_page - identify an isolated balloon page on private
- * compaction/migration page lists.
- */
-static inline bool isolated_balloon_page(struct page *page)
-{
- return PageBalloon(page);
-}
-
-/*
* balloon_page_insert - insert a page into the balloon's page list and make
* the page->private assignment accordingly.
* @balloon : pointer to balloon device
@@ -124,7 +100,7 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon,
struct page *page)
{
__SetPageBalloon(page);
- SetPagePrivate(page);
+ __SetPageMovable(page, balloon->inode->i_mapping);
set_page_private(page, (unsigned long)balloon);
list_add(&page->lru, &balloon->pages);
}
@@ -140,11 +116,14 @@ static inline void balloon_page_insert(struct balloon_dev_info *balloon,
static inline void balloon_page_delete(struct page *page)
{
__ClearPageBalloon(page);
+ __ClearPageMovable(page);
set_page_private(page, 0);
- if (PagePrivate(page)) {
- ClearPagePrivate(page);
+ /*
+ * No touch page.lru field once @page has been isolated
+ * because VM is using the field.
+ */
+ if (!PageIsolated(page))
list_del(&page->lru);
- }
}
/*
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index a5ac2cad5cb7..b20e3d56253f 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -504,6 +504,9 @@
#define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000
#define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT 20
+#define BCMA_CCB_MII_MNG_CTL 0x0000
+#define BCMA_CCB_MII_MNG_CMD_DATA 0x0004
+
/* BCM4331 ChipControl numbers. */
#define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */
#define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 9faebf7f9a33..583c10810e32 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -41,44 +41,9 @@
#endif
#define BIO_MAX_PAGES 256
-#define BIO_MAX_SIZE (BIO_MAX_PAGES << PAGE_SHIFT)
-#define BIO_MAX_SECTORS (BIO_MAX_SIZE >> 9)
-/*
- * upper 16 bits of bi_rw define the io priority of this bio
- */
-#define BIO_PRIO_SHIFT (8 * sizeof(unsigned long) - IOPRIO_BITS)
-#define bio_prio(bio) ((bio)->bi_rw >> BIO_PRIO_SHIFT)
-#define bio_prio_valid(bio) ioprio_valid(bio_prio(bio))
-
-#define bio_set_prio(bio, prio) do { \
- WARN_ON(prio >= (1 << IOPRIO_BITS)); \
- (bio)->bi_rw &= ((1UL << BIO_PRIO_SHIFT) - 1); \
- (bio)->bi_rw |= ((unsigned long) (prio) << BIO_PRIO_SHIFT); \
-} while (0)
-
-/*
- * various member access, note that bio_data should of course not be used
- * on highmem page vectors
- */
-#define __bvec_iter_bvec(bvec, iter) (&(bvec)[(iter).bi_idx])
-
-#define bvec_iter_page(bvec, iter) \
- (__bvec_iter_bvec((bvec), (iter))->bv_page)
-
-#define bvec_iter_len(bvec, iter) \
- min((iter).bi_size, \
- __bvec_iter_bvec((bvec), (iter))->bv_len - (iter).bi_bvec_done)
-
-#define bvec_iter_offset(bvec, iter) \
- (__bvec_iter_bvec((bvec), (iter))->bv_offset + (iter).bi_bvec_done)
-
-#define bvec_iter_bvec(bvec, iter) \
-((struct bio_vec) { \
- .bv_page = bvec_iter_page((bvec), (iter)), \
- .bv_len = bvec_iter_len((bvec), (iter)), \
- .bv_offset = bvec_iter_offset((bvec), (iter)), \
-})
+#define bio_prio(bio) (bio)->bi_ioprio
+#define bio_set_prio(bio, prio) ((bio)->bi_ioprio = prio)
#define bio_iter_iovec(bio, iter) \
bvec_iter_bvec((bio)->bi_io_vec, (iter))
@@ -106,18 +71,23 @@ static inline bool bio_has_data(struct bio *bio)
{
if (bio &&
bio->bi_iter.bi_size &&
- !(bio->bi_rw & REQ_DISCARD))
+ bio_op(bio) != REQ_OP_DISCARD)
return true;
return false;
}
+static inline bool bio_no_advance_iter(struct bio *bio)
+{
+ return bio_op(bio) == REQ_OP_DISCARD || bio_op(bio) == REQ_OP_WRITE_SAME;
+}
+
static inline bool bio_is_rw(struct bio *bio)
{
if (!bio_has_data(bio))
return false;
- if (bio->bi_rw & BIO_NO_ADVANCE_ITER_MASK)
+ if (bio_no_advance_iter(bio))
return false;
return true;
@@ -193,39 +163,12 @@ static inline void *bio_data(struct bio *bio)
#define bio_for_each_segment_all(bvl, bio, i) \
for (i = 0, bvl = (bio)->bi_io_vec; i < (bio)->bi_vcnt; i++, bvl++)
-static inline void bvec_iter_advance(struct bio_vec *bv, struct bvec_iter *iter,
- unsigned bytes)
-{
- WARN_ONCE(bytes > iter->bi_size,
- "Attempted to advance past end of bvec iter\n");
-
- while (bytes) {
- unsigned len = min(bytes, bvec_iter_len(bv, *iter));
-
- bytes -= len;
- iter->bi_size -= len;
- iter->bi_bvec_done += len;
-
- if (iter->bi_bvec_done == __bvec_iter_bvec(bv, *iter)->bv_len) {
- iter->bi_bvec_done = 0;
- iter->bi_idx++;
- }
- }
-}
-
-#define for_each_bvec(bvl, bio_vec, iter, start) \
- for (iter = (start); \
- (iter).bi_size && \
- ((bvl = bvec_iter_bvec((bio_vec), (iter))), 1); \
- bvec_iter_advance((bio_vec), &(iter), (bvl).bv_len))
-
-
static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
unsigned bytes)
{
iter->bi_sector += bytes >> 9;
- if (bio->bi_rw & BIO_NO_ADVANCE_ITER_MASK)
+ if (bio_no_advance_iter(bio))
iter->bi_size -= bytes;
else
bvec_iter_advance(bio->bi_io_vec, iter, bytes);
@@ -253,10 +196,10 @@ static inline unsigned bio_segments(struct bio *bio)
* differently:
*/
- if (bio->bi_rw & REQ_DISCARD)
+ if (bio_op(bio) == REQ_OP_DISCARD)
return 1;
- if (bio->bi_rw & REQ_WRITE_SAME)
+ if (bio_op(bio) == REQ_OP_WRITE_SAME)
return 1;
bio_for_each_segment(bv, bio, iter)
@@ -473,7 +416,7 @@ static inline void bio_io_error(struct bio *bio)
struct request_queue;
extern int bio_phys_segments(struct request_queue *, struct bio *);
-extern int submit_bio_wait(int rw, struct bio *bio);
+extern int submit_bio_wait(struct bio *bio);
extern void bio_advance(struct bio *, unsigned);
extern void bio_init(struct bio *);
@@ -720,8 +663,6 @@ static inline void bio_inc_remaining(struct bio *bio)
* and the bvec_slabs[].
*/
#define BIO_POOL_SIZE 2
-#define BIOVEC_NR_POOLS 6
-#define BIOVEC_MAX_IDX (BIOVEC_NR_POOLS - 1)
struct bio_set {
struct kmem_cache *bio_slab;
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index e9b0b9ab07e5..27bfc0b631a9 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -267,6 +267,10 @@ static inline int bitmap_equal(const unsigned long *src1,
{
if (small_const_nbits(nbits))
return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
+#ifdef CONFIG_S390
+ else if (__builtin_constant_p(nbits) && (nbits % BITS_PER_LONG) == 0)
+ return !memcmp(src1, src2, nbits / 8);
+#endif
else
return __bitmap_equal(src1, src2, nbits);
}
diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h
index c02e669945e9..f77150a4a96a 100644
--- a/include/linux/blk-cgroup.h
+++ b/include/linux/blk-cgroup.h
@@ -590,25 +590,26 @@ static inline void blkg_rwstat_exit(struct blkg_rwstat *rwstat)
/**
* blkg_rwstat_add - add a value to a blkg_rwstat
* @rwstat: target blkg_rwstat
- * @rw: mask of REQ_{WRITE|SYNC}
+ * @op: REQ_OP
+ * @op_flags: rq_flag_bits
* @val: value to add
*
* Add @val to @rwstat. The counters are chosen according to @rw. The
* caller is responsible for synchronizing calls to this function.
*/
static inline void blkg_rwstat_add(struct blkg_rwstat *rwstat,
- int rw, uint64_t val)
+ int op, int op_flags, uint64_t val)
{
struct percpu_counter *cnt;
- if (rw & REQ_WRITE)
+ if (op_is_write(op))
cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_WRITE];
else
cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_READ];
__percpu_counter_add(cnt, val, BLKG_STAT_CPU_BATCH);
- if (rw & REQ_SYNC)
+ if (op_flags & REQ_SYNC)
cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_SYNC];
else
cnt = &rwstat->cpu_cnt[BLKG_RWSTAT_ASYNC];
@@ -713,9 +714,9 @@ static inline bool blkcg_bio_issue_check(struct request_queue *q,
if (!throtl) {
blkg = blkg ?: q->root_blkg;
- blkg_rwstat_add(&blkg->stat_bytes, bio->bi_rw,
+ blkg_rwstat_add(&blkg->stat_bytes, bio_op(bio), bio->bi_rw,
bio->bi_iter.bi_size);
- blkg_rwstat_add(&blkg->stat_ios, bio->bi_rw, 1);
+ blkg_rwstat_add(&blkg->stat_ios, bio_op(bio), bio->bi_rw, 1);
}
rcu_read_unlock();
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index 2498fdf3a503..e43bbffb5b7a 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -96,6 +96,7 @@ typedef int (init_request_fn)(void *, struct request *, unsigned int,
unsigned int, unsigned int);
typedef void (exit_request_fn)(void *, struct request *, unsigned int,
unsigned int);
+typedef int (reinit_request_fn)(void *, struct request *);
typedef void (busy_iter_fn)(struct blk_mq_hw_ctx *, struct request *, void *,
bool);
@@ -145,6 +146,7 @@ struct blk_mq_ops {
*/
init_request_fn *init_request;
exit_request_fn *exit_request;
+ reinit_request_fn *reinit_request;
};
enum {
@@ -196,6 +198,8 @@ enum {
struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
unsigned int flags);
+struct request *blk_mq_alloc_request_hctx(struct request_queue *q, int op,
+ unsigned int flags, unsigned int hctx_idx);
struct request *blk_mq_tag_to_rq(struct blk_mq_tags *tags, unsigned int tag);
struct cpumask *blk_mq_tags_cpumask(struct blk_mq_tags *tags);
@@ -243,6 +247,7 @@ void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset,
void blk_mq_freeze_queue(struct request_queue *q);
void blk_mq_unfreeze_queue(struct request_queue *q);
void blk_mq_freeze_queue_start(struct request_queue *q);
+int blk_mq_reinit_tagset(struct blk_mq_tag_set *set);
void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues);
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 77e5d81f07aa..f254eb264924 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -6,6 +6,7 @@
#define __LINUX_BLK_TYPES_H
#include <linux/types.h>
+#include <linux/bvec.h>
struct bio_set;
struct bio;
@@ -17,28 +18,7 @@ struct cgroup_subsys_state;
typedef void (bio_end_io_t) (struct bio *);
typedef void (bio_destructor_t) (struct bio *);
-/*
- * was unsigned short, but we might as well be ready for > 64kB I/O pages
- */
-struct bio_vec {
- struct page *bv_page;
- unsigned int bv_len;
- unsigned int bv_offset;
-};
-
#ifdef CONFIG_BLOCK
-
-struct bvec_iter {
- sector_t bi_sector; /* device address in 512 byte
- sectors */
- unsigned int bi_size; /* residual I/O count */
-
- unsigned int bi_idx; /* current index into bvl_vec */
-
- unsigned int bi_bvec_done; /* number of bytes completed in
- current bvec */
-};
-
/*
* main unit of I/O for the block layer and lower layers (ie drivers and
* stacking drivers)
@@ -46,11 +26,12 @@ struct bvec_iter {
struct bio {
struct bio *bi_next; /* request queue link */
struct block_device *bi_bdev;
- unsigned int bi_flags; /* status, command, etc */
int bi_error;
- unsigned long bi_rw; /* bottom bits READ/WRITE,
- * top bits priority
+ unsigned int bi_rw; /* bottom bits req flags,
+ * top bits REQ_OP
*/
+ unsigned short bi_flags; /* status, command, etc */
+ unsigned short bi_ioprio;
struct bvec_iter bi_iter;
@@ -107,6 +88,16 @@ struct bio {
struct bio_vec bi_inline_vecs[0];
};
+#define BIO_OP_SHIFT (8 * sizeof(unsigned int) - REQ_OP_BITS)
+#define bio_op(bio) ((bio)->bi_rw >> BIO_OP_SHIFT)
+
+#define bio_set_op_attrs(bio, op, op_flags) do { \
+ WARN_ON(op >= (1 << REQ_OP_BITS)); \
+ (bio)->bi_rw &= ((1 << BIO_OP_SHIFT) - 1); \
+ (bio)->bi_rw |= ((unsigned int) (op) << BIO_OP_SHIFT); \
+ (bio)->bi_rw |= op_flags; \
+} while (0)
+
#define BIO_RESET_BYTES offsetof(struct bio, bi_max_vecs)
/*
@@ -123,19 +114,25 @@ struct bio {
/*
* Flags starting here get preserved by bio_reset() - this includes
- * BIO_POOL_IDX()
+ * BVEC_POOL_IDX()
+ */
+#define BIO_RESET_BITS 10
+
+/*
+ * We support 6 different bvec pools, the last one is magic in that it
+ * is backed by a mempool.
*/
-#define BIO_RESET_BITS 13
-#define BIO_OWNS_VEC 13 /* bio_free() should free bvec */
+#define BVEC_POOL_NR 6
+#define BVEC_POOL_MAX (BVEC_POOL_NR - 1)
/*
- * top 4 bits of bio flags indicate the pool this bio came from
+ * Top 4 bits of bio flags indicate the pool the bvecs came from. We add
+ * 1 to the actual index so that 0 indicates that there are no bvecs to be
+ * freed.
*/
-#define BIO_POOL_BITS (4)
-#define BIO_POOL_NONE ((1UL << BIO_POOL_BITS) - 1)
-#define BIO_POOL_OFFSET (32 - BIO_POOL_BITS)
-#define BIO_POOL_MASK (1UL << BIO_POOL_OFFSET)
-#define BIO_POOL_IDX(bio) ((bio)->bi_flags >> BIO_POOL_OFFSET)
+#define BVEC_POOL_BITS (4)
+#define BVEC_POOL_OFFSET (16 - BVEC_POOL_BITS)
+#define BVEC_POOL_IDX(bio) ((bio)->bi_flags >> BVEC_POOL_OFFSET)
#endif /* CONFIG_BLOCK */
@@ -145,7 +142,6 @@ struct bio {
*/
enum rq_flag_bits {
/* common flags */
- __REQ_WRITE, /* not set, read. set, write */
__REQ_FAILFAST_DEV, /* no driver retries of device errors */
__REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */
__REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */
@@ -153,14 +149,11 @@ enum rq_flag_bits {
__REQ_SYNC, /* request is sync (sync write or read) */
__REQ_META, /* metadata io request */
__REQ_PRIO, /* boost priority in cfq */
- __REQ_DISCARD, /* request to discard sectors */
- __REQ_SECURE, /* secure discard (used with __REQ_DISCARD) */
- __REQ_WRITE_SAME, /* write same block many times */
__REQ_NOIDLE, /* don't anticipate more IO after this one */
__REQ_INTEGRITY, /* I/O includes block integrity payload */
__REQ_FUA, /* forced unit access */
- __REQ_FLUSH, /* request for cache flush */
+ __REQ_PREFLUSH, /* request for cache flush */
/* bio only flags */
__REQ_RAHEAD, /* read ahead, can fail anytime */
@@ -191,31 +184,25 @@ enum rq_flag_bits {
__REQ_NR_BITS, /* stops here */
};
-#define REQ_WRITE (1ULL << __REQ_WRITE)
#define REQ_FAILFAST_DEV (1ULL << __REQ_FAILFAST_DEV)
#define REQ_FAILFAST_TRANSPORT (1ULL << __REQ_FAILFAST_TRANSPORT)
#define REQ_FAILFAST_DRIVER (1ULL << __REQ_FAILFAST_DRIVER)
#define REQ_SYNC (1ULL << __REQ_SYNC)
#define REQ_META (1ULL << __REQ_META)
#define REQ_PRIO (1ULL << __REQ_PRIO)
-#define REQ_DISCARD (1ULL << __REQ_DISCARD)
-#define REQ_WRITE_SAME (1ULL << __REQ_WRITE_SAME)
#define REQ_NOIDLE (1ULL << __REQ_NOIDLE)
#define REQ_INTEGRITY (1ULL << __REQ_INTEGRITY)
#define REQ_FAILFAST_MASK \
(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
#define REQ_COMMON_MASK \
- (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \
- REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \
- REQ_SECURE | REQ_INTEGRITY | REQ_NOMERGE)
+ (REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | REQ_NOIDLE | \
+ REQ_PREFLUSH | REQ_FUA | REQ_INTEGRITY | REQ_NOMERGE)
#define REQ_CLONE_MASK REQ_COMMON_MASK
-#define BIO_NO_ADVANCE_ITER_MASK (REQ_DISCARD|REQ_WRITE_SAME)
-
/* This mask is used for both bio and request merge checking */
#define REQ_NOMERGE_FLAGS \
- (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_FLUSH_SEQ)
+ (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_PREFLUSH | REQ_FUA | REQ_FLUSH_SEQ)
#define REQ_RAHEAD (1ULL << __REQ_RAHEAD)
#define REQ_THROTTLED (1ULL << __REQ_THROTTLED)
@@ -233,15 +220,25 @@ enum rq_flag_bits {
#define REQ_PREEMPT (1ULL << __REQ_PREEMPT)
#define REQ_ALLOCED (1ULL << __REQ_ALLOCED)
#define REQ_COPY_USER (1ULL << __REQ_COPY_USER)
-#define REQ_FLUSH (1ULL << __REQ_FLUSH)
+#define REQ_PREFLUSH (1ULL << __REQ_PREFLUSH)
#define REQ_FLUSH_SEQ (1ULL << __REQ_FLUSH_SEQ)
#define REQ_IO_STAT (1ULL << __REQ_IO_STAT)
#define REQ_MIXED_MERGE (1ULL << __REQ_MIXED_MERGE)
-#define REQ_SECURE (1ULL << __REQ_SECURE)
#define REQ_PM (1ULL << __REQ_PM)
#define REQ_HASHED (1ULL << __REQ_HASHED)
#define REQ_MQ_INFLIGHT (1ULL << __REQ_MQ_INFLIGHT)
+enum req_op {
+ REQ_OP_READ,
+ REQ_OP_WRITE,
+ REQ_OP_DISCARD, /* request to discard sectors */
+ REQ_OP_SECURE_ERASE, /* request to securely erase sectors */
+ REQ_OP_WRITE_SAME, /* write same block many times */
+ REQ_OP_FLUSH, /* request for cache flush */
+};
+
+#define REQ_OP_BITS 3
+
typedef unsigned int blk_qc_t;
#define BLK_QC_T_NONE -1U
#define BLK_QC_T_SHIFT 16
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 3d9cf326574f..adf33079771e 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -90,18 +90,17 @@ struct request {
struct list_head queuelist;
union {
struct call_single_data csd;
- unsigned long fifo_time;
+ u64 fifo_time;
};
struct request_queue *q;
struct blk_mq_ctx *mq_ctx;
- u64 cmd_flags;
+ int cpu;
unsigned cmd_type;
+ u64 cmd_flags;
unsigned long atomic_flags;
- int cpu;
-
/* the following two fields are internal, NEVER access directly */
unsigned int __data_len; /* total data len */
sector_t __sector; /* sector cursor */
@@ -200,6 +199,20 @@ struct request {
struct request *next_rq;
};
+#define REQ_OP_SHIFT (8 * sizeof(u64) - REQ_OP_BITS)
+#define req_op(req) ((req)->cmd_flags >> REQ_OP_SHIFT)
+
+#define req_set_op(req, op) do { \
+ WARN_ON(op >= (1 << REQ_OP_BITS)); \
+ (req)->cmd_flags &= ((1ULL << REQ_OP_SHIFT) - 1); \
+ (req)->cmd_flags |= ((u64) (op) << REQ_OP_SHIFT); \
+} while (0)
+
+#define req_set_op_attrs(req, op, flags) do { \
+ req_set_op(req, op); \
+ (req)->cmd_flags |= flags; \
+} while (0)
+
static inline unsigned short req_get_ioprio(struct request *req)
{
return req->ioprio;
@@ -483,7 +496,7 @@ struct request_queue {
#define QUEUE_FLAG_DISCARD 14 /* supports DISCARD */
#define QUEUE_FLAG_NOXMERGES 15 /* No extended merges */
#define QUEUE_FLAG_ADD_RANDOM 16 /* Contributes to random pool */
-#define QUEUE_FLAG_SECDISCARD 17 /* supports SECDISCARD */
+#define QUEUE_FLAG_SECERASE 17 /* supports secure erase */
#define QUEUE_FLAG_SAME_FORCE 18 /* force complete on same CPU */
#define QUEUE_FLAG_DEAD 19 /* queue tear-down finished */
#define QUEUE_FLAG_INIT_DONE 20 /* queue is initialized */
@@ -492,6 +505,7 @@ struct request_queue {
#define QUEUE_FLAG_WC 23 /* Write back caching */
#define QUEUE_FLAG_FUA 24 /* device supports FUA writes */
#define QUEUE_FLAG_FLUSH_NQ 25 /* flush not queueuable */
+#define QUEUE_FLAG_DAX 26 /* device supports DAX */
#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \
(1 << QUEUE_FLAG_STACKABLE) | \
@@ -579,8 +593,9 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
#define blk_queue_stackable(q) \
test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags)
#define blk_queue_discard(q) test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags)
-#define blk_queue_secdiscard(q) (blk_queue_discard(q) && \
- test_bit(QUEUE_FLAG_SECDISCARD, &(q)->queue_flags))
+#define blk_queue_secure_erase(q) \
+ (test_bit(QUEUE_FLAG_SECERASE, &(q)->queue_flags))
+#define blk_queue_dax(q) test_bit(QUEUE_FLAG_DAX, &(q)->queue_flags)
#define blk_noretry_request(rq) \
((rq)->cmd_flags & (REQ_FAILFAST_DEV|REQ_FAILFAST_TRANSPORT| \
@@ -597,7 +612,7 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
#define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist)
-#define rq_data_dir(rq) ((int)((rq)->cmd_flags & 1))
+#define rq_data_dir(rq) (op_is_write(req_op(rq)) ? WRITE : READ)
/*
* Driver can handle struct request, if it either has an old style
@@ -616,14 +631,14 @@ static inline unsigned int blk_queue_cluster(struct request_queue *q)
/*
* We regard a request as sync, if either a read or a sync write
*/
-static inline bool rw_is_sync(unsigned int rw_flags)
+static inline bool rw_is_sync(int op, unsigned int rw_flags)
{
- return !(rw_flags & REQ_WRITE) || (rw_flags & REQ_SYNC);
+ return op == REQ_OP_READ || (rw_flags & REQ_SYNC);
}
static inline bool rq_is_sync(struct request *rq)
{
- return rw_is_sync(rq->cmd_flags);
+ return rw_is_sync(req_op(rq), rq->cmd_flags);
}
static inline bool blk_rl_full(struct request_list *rl, bool sync)
@@ -652,22 +667,10 @@ static inline bool rq_mergeable(struct request *rq)
if (rq->cmd_type != REQ_TYPE_FS)
return false;
- if (rq->cmd_flags & REQ_NOMERGE_FLAGS)
+ if (req_op(rq) == REQ_OP_FLUSH)
return false;
- return true;
-}
-
-static inline bool blk_check_merge_flags(unsigned int flags1,
- unsigned int flags2)
-{
- if ((flags1 & REQ_DISCARD) != (flags2 & REQ_DISCARD))
- return false;
-
- if ((flags1 & REQ_SECURE) != (flags2 & REQ_SECURE))
- return false;
-
- if ((flags1 & REQ_WRITE_SAME) != (flags2 & REQ_WRITE_SAME))
+ if (rq->cmd_flags & REQ_NOMERGE_FLAGS)
return false;
return true;
@@ -786,8 +789,6 @@ extern void blk_rq_init(struct request_queue *q, struct request *rq);
extern void blk_put_request(struct request *);
extern void __blk_put_request(struct request_queue *, struct request *);
extern struct request *blk_get_request(struct request_queue *, int, gfp_t);
-extern struct request *blk_make_request(struct request_queue *, struct bio *,
- gfp_t);
extern void blk_rq_set_block_pc(struct request *);
extern void blk_requeue_request(struct request_queue *, struct request *);
extern void blk_add_request_payload(struct request *rq, struct page *page,
@@ -800,6 +801,7 @@ extern int blk_rq_prep_clone(struct request *rq, struct request *rq_src,
extern void blk_rq_unprep_clone(struct request *rq);
extern int blk_insert_cloned_request(struct request_queue *q,
struct request *rq);
+extern int blk_rq_append_bio(struct request *rq, struct bio *bio);
extern void blk_delay_queue(struct request_queue *, unsigned long);
extern void blk_queue_split(struct request_queue *, struct bio **,
struct bio_set *);
@@ -879,12 +881,12 @@ static inline unsigned int blk_rq_cur_sectors(const struct request *rq)
}
static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q,
- unsigned int cmd_flags)
+ int op)
{
- if (unlikely(cmd_flags & REQ_DISCARD))
+ if (unlikely(op == REQ_OP_DISCARD))
return min(q->limits.max_discard_sectors, UINT_MAX >> 9);
- if (unlikely(cmd_flags & REQ_WRITE_SAME))
+ if (unlikely(op == REQ_OP_WRITE_SAME))
return q->limits.max_write_same_sectors;
return q->limits.max_sectors;
@@ -904,18 +906,19 @@ static inline unsigned int blk_max_size_offset(struct request_queue *q,
(offset & (q->limits.chunk_sectors - 1));
}
-static inline unsigned int blk_rq_get_max_sectors(struct request *rq)
+static inline unsigned int blk_rq_get_max_sectors(struct request *rq,
+ sector_t offset)
{
struct request_queue *q = rq->q;
if (unlikely(rq->cmd_type != REQ_TYPE_FS))
return q->limits.max_hw_sectors;
- if (!q->limits.chunk_sectors || (rq->cmd_flags & REQ_DISCARD))
- return blk_queue_get_max_sectors(q, rq->cmd_flags);
+ if (!q->limits.chunk_sectors || (req_op(rq) == REQ_OP_DISCARD))
+ return blk_queue_get_max_sectors(q, req_op(rq));
- return min(blk_max_size_offset(q, blk_rq_pos(rq)),
- blk_queue_get_max_sectors(q, rq->cmd_flags));
+ return min(blk_max_size_offset(q, offset),
+ blk_queue_get_max_sectors(q, req_op(rq)));
}
static inline unsigned int blk_rq_count_bios(struct request *rq)
@@ -1135,13 +1138,16 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt,
return bqt->tag_index[tag];
}
-#define BLKDEV_DISCARD_SECURE 0x01 /* secure discard */
+
+#define BLKDEV_DISCARD_SECURE (1 << 0) /* issue a secure erase */
+#define BLKDEV_DISCARD_ZERO (1 << 1) /* must reliably zero data */
extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *);
extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
sector_t nr_sects, gfp_t gfp_mask, unsigned long flags);
extern int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
- sector_t nr_sects, gfp_t gfp_mask, int type, struct bio **biop);
+ sector_t nr_sects, gfp_t gfp_mask, int flags,
+ struct bio **biop);
extern int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
sector_t nr_sects, gfp_t gfp_mask, struct page *page);
extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
@@ -1659,7 +1665,7 @@ static inline bool integrity_req_gap_front_merge(struct request *req,
*/
struct blk_dax_ctl {
sector_t sector;
- void __pmem *addr;
+ void *addr;
long size;
pfn_t pfn;
};
@@ -1670,8 +1676,8 @@ struct block_device_operations {
int (*rw_page)(struct block_device *, sector_t, struct page *, int rw);
int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long);
- long (*direct_access)(struct block_device *, sector_t, void __pmem **,
- pfn_t *, long);
+ long (*direct_access)(struct block_device *, sector_t, void **, pfn_t *,
+ long);
unsigned int (*check_events) (struct gendisk *disk,
unsigned int clearing);
/* ->media_changed() is DEPRECATED, use ->check_events() instead */
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 0f3172b8b225..cceb72f9e29f 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -118,7 +118,7 @@ static inline int blk_cmd_buf_len(struct request *rq)
}
extern void blk_dump_cmd(char *buf, struct request *rq);
-extern void blk_fill_rwbs(char *rwbs, u32 rw, int bytes);
+extern void blk_fill_rwbs(char *rwbs, int op, u32 rw, int bytes);
#endif /* CONFIG_EVENT_TRACING && CONFIG_BLOCK */
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 0de4de6dd43e..11134238417d 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -11,14 +11,17 @@
#include <linux/workqueue.h>
#include <linux/file.h>
#include <linux/percpu.h>
+#include <linux/err.h>
+struct perf_event;
struct bpf_map;
/* map is generic key/value storage optionally accesible by eBPF programs */
struct bpf_map_ops {
/* funcs callable from userspace (via syscall) */
struct bpf_map *(*map_alloc)(union bpf_attr *attr);
- void (*map_free)(struct bpf_map *);
+ void (*map_release)(struct bpf_map *map, struct file *map_file);
+ void (*map_free)(struct bpf_map *map);
int (*map_get_next_key)(struct bpf_map *map, void *key, void *next_key);
/* funcs callable from userspace and from eBPF programs */
@@ -27,8 +30,9 @@ struct bpf_map_ops {
int (*map_delete_elem)(struct bpf_map *map, void *key);
/* funcs called by prog_array and perf_event_array map */
- void *(*map_fd_get_ptr) (struct bpf_map *map, int fd);
- void (*map_fd_put_ptr) (void *ptr);
+ void *(*map_fd_get_ptr)(struct bpf_map *map, struct file *map_file,
+ int fd);
+ void (*map_fd_put_ptr)(void *ptr);
};
struct bpf_map {
@@ -189,15 +193,28 @@ struct bpf_array {
void __percpu *pptrs[0] __aligned(8);
};
};
+
#define MAX_TAIL_CALL_CNT 32
+struct bpf_event_entry {
+ struct perf_event *event;
+ struct file *perf_file;
+ struct file *map_file;
+ struct rcu_head rcu;
+};
+
u64 bpf_tail_call(u64 ctx, u64 r2, u64 index, u64 r4, u64 r5);
u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
-void bpf_fd_array_map_clear(struct bpf_map *map);
+
bool bpf_prog_array_compatible(struct bpf_array *array, const struct bpf_prog *fp);
const struct bpf_func_proto *bpf_get_trace_printk_proto(void);
-const struct bpf_func_proto *bpf_get_event_output_proto(void);
+
+typedef unsigned long (*bpf_ctx_copy_t)(void *dst, const void *src,
+ unsigned long off, unsigned long len);
+
+u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
+ void *ctx, u64 ctx_size, bpf_ctx_copy_t ctx_copy);
#ifdef CONFIG_BPF_SYSCALL
DECLARE_PER_CPU(int, bpf_prog_active);
@@ -206,9 +223,10 @@ void bpf_register_prog_type(struct bpf_prog_type_list *tl);
void bpf_register_map_type(struct bpf_map_type_list *tl);
struct bpf_prog *bpf_prog_get(u32 ufd);
+struct bpf_prog *bpf_prog_get_type(u32 ufd, enum bpf_prog_type type);
+struct bpf_prog *bpf_prog_add(struct bpf_prog *prog, int i);
struct bpf_prog *bpf_prog_inc(struct bpf_prog *prog);
void bpf_prog_put(struct bpf_prog *prog);
-void bpf_prog_put_rcu(struct bpf_prog *prog);
struct bpf_map *bpf_map_get_with_uref(u32 ufd);
struct bpf_map *__bpf_map_get(struct fd f);
@@ -231,8 +249,13 @@ int bpf_percpu_hash_update(struct bpf_map *map, void *key, void *value,
u64 flags);
int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
u64 flags);
+
int bpf_stackmap_copy(struct bpf_map *map, void *key, void *value);
+int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file,
+ void *key, void *value, u64 map_flags);
+void bpf_fd_array_map_clear(struct bpf_map *map);
+
/* memcpy that is used with 8-byte aligned pointers, power-of-8 size and
* forced to use 'long' read/writes to try to atomically copy long counters.
* Best-effort only. No barriers here, since it _will_ race with concurrent
@@ -261,11 +284,17 @@ static inline struct bpf_prog *bpf_prog_get(u32 ufd)
return ERR_PTR(-EOPNOTSUPP);
}
-static inline void bpf_prog_put(struct bpf_prog *prog)
+static inline struct bpf_prog *bpf_prog_get_type(u32 ufd,
+ enum bpf_prog_type type)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+static inline struct bpf_prog *bpf_prog_add(struct bpf_prog *prog, int i)
{
+ return ERR_PTR(-EOPNOTSUPP);
}
-static inline void bpf_prog_put_rcu(struct bpf_prog *prog)
+static inline void bpf_prog_put(struct bpf_prog *prog)
{
}
#endif /* CONFIG_BPF_SYSCALL */
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index d48daa3f6f20..ebbacd14d450 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -187,12 +187,13 @@ struct buffer_head *alloc_buffer_head(gfp_t gfp_flags);
void free_buffer_head(struct buffer_head * bh);
void unlock_buffer(struct buffer_head *bh);
void __lock_buffer(struct buffer_head *bh);
-void ll_rw_block(int, int, struct buffer_head * bh[]);
+void ll_rw_block(int, int, int, struct buffer_head * bh[]);
int sync_dirty_buffer(struct buffer_head *bh);
-int __sync_dirty_buffer(struct buffer_head *bh, int rw);
-void write_dirty_buffer(struct buffer_head *bh, int rw);
-int _submit_bh(int rw, struct buffer_head *bh, unsigned long bio_flags);
-int submit_bh(int, struct buffer_head *);
+int __sync_dirty_buffer(struct buffer_head *bh, int op_flags);
+void write_dirty_buffer(struct buffer_head *bh, int op_flags);
+int _submit_bh(int op, int op_flags, struct buffer_head *bh,
+ unsigned long bio_flags);
+int submit_bh(int, int, struct buffer_head *);
void write_boundary_block(struct block_device *bdev,
sector_t bblock, unsigned blocksize);
int bh_uptodate_or_lock(struct buffer_head *bh);
@@ -208,6 +209,9 @@ void block_invalidatepage(struct page *page, unsigned int offset,
unsigned int length);
int block_write_full_page(struct page *page, get_block_t *get_block,
struct writeback_control *wbc);
+int __block_write_full_page(struct inode *inode, struct page *page,
+ get_block_t *get_block, struct writeback_control *wbc,
+ bh_end_io_t *handler);
int block_read_full_page(struct page*, get_block_t*);
int block_is_partially_uptodate(struct page *page, unsigned long from,
unsigned long count);
diff --git a/include/linux/bvec.h b/include/linux/bvec.h
new file mode 100644
index 000000000000..701b64a3b7c5
--- /dev/null
+++ b/include/linux/bvec.h
@@ -0,0 +1,96 @@
+/*
+ * bvec iterator
+ *
+ * Copyright (C) 2001 Ming Lei <ming.lei@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 Licens
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-
+ */
+#ifndef __LINUX_BVEC_ITER_H
+#define __LINUX_BVEC_ITER_H
+
+#include <linux/kernel.h>
+#include <linux/bug.h>
+
+/*
+ * was unsigned short, but we might as well be ready for > 64kB I/O pages
+ */
+struct bio_vec {
+ struct page *bv_page;
+ unsigned int bv_len;
+ unsigned int bv_offset;
+};
+
+struct bvec_iter {
+ sector_t bi_sector; /* device address in 512 byte
+ sectors */
+ unsigned int bi_size; /* residual I/O count */
+
+ unsigned int bi_idx; /* current index into bvl_vec */
+
+ unsigned int bi_bvec_done; /* number of bytes completed in
+ current bvec */
+};
+
+/*
+ * various member access, note that bio_data should of course not be used
+ * on highmem page vectors
+ */
+#define __bvec_iter_bvec(bvec, iter) (&(bvec)[(iter).bi_idx])
+
+#define bvec_iter_page(bvec, iter) \
+ (__bvec_iter_bvec((bvec), (iter))->bv_page)
+
+#define bvec_iter_len(bvec, iter) \
+ min((iter).bi_size, \
+ __bvec_iter_bvec((bvec), (iter))->bv_len - (iter).bi_bvec_done)
+
+#define bvec_iter_offset(bvec, iter) \
+ (__bvec_iter_bvec((bvec), (iter))->bv_offset + (iter).bi_bvec_done)
+
+#define bvec_iter_bvec(bvec, iter) \
+((struct bio_vec) { \
+ .bv_page = bvec_iter_page((bvec), (iter)), \
+ .bv_len = bvec_iter_len((bvec), (iter)), \
+ .bv_offset = bvec_iter_offset((bvec), (iter)), \
+})
+
+static inline void bvec_iter_advance(const struct bio_vec *bv,
+ struct bvec_iter *iter,
+ unsigned bytes)
+{
+ WARN_ONCE(bytes > iter->bi_size,
+ "Attempted to advance past end of bvec iter\n");
+
+ while (bytes) {
+ unsigned len = min(bytes, bvec_iter_len(bv, *iter));
+
+ bytes -= len;
+ iter->bi_size -= len;
+ iter->bi_bvec_done += len;
+
+ if (iter->bi_bvec_done == __bvec_iter_bvec(bv, *iter)->bv_len) {
+ iter->bi_bvec_done = 0;
+ iter->bi_idx++;
+ }
+ }
+}
+
+#define for_each_bvec(bvl, bio_vec, iter, start) \
+ for (iter = (start); \
+ (iter).bi_size && \
+ ((bvl = bvec_iter_bvec((bio_vec), (iter))), 1); \
+ bvec_iter_advance((bio_vec), &(iter), (bvl).bv_len))
+
+#endif /* __LINUX_BVEC_ITER_H */
diff --git a/include/linux/cec-funcs.h b/include/linux/cec-funcs.h
new file mode 100644
index 000000000000..82c3d3b7269d
--- /dev/null
+++ b/include/linux/cec-funcs.h
@@ -0,0 +1,1899 @@
+/*
+ * cec - HDMI Consumer Electronics Control message functions
+ *
+ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * Alternatively you can redistribute this file under the terms of the
+ * BSD license as stated below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The names of its contributors may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * Note: this framework is still in staging and it is likely the API
+ * will change before it goes out of staging.
+ *
+ * Once it is moved out of staging this header will move to uapi.
+ */
+#ifndef _CEC_UAPI_FUNCS_H
+#define _CEC_UAPI_FUNCS_H
+
+#include <linux/cec.h>
+
+/* One Touch Play Feature */
+static inline void cec_msg_active_source(struct cec_msg *msg, __u16 phys_addr)
+{
+ msg->len = 4;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_ACTIVE_SOURCE;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+}
+
+static inline void cec_ops_active_source(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+static inline void cec_msg_image_view_on(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_IMAGE_VIEW_ON;
+}
+
+static inline void cec_msg_text_view_on(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_TEXT_VIEW_ON;
+}
+
+
+/* Routing Control Feature */
+static inline void cec_msg_inactive_source(struct cec_msg *msg,
+ __u16 phys_addr)
+{
+ msg->len = 4;
+ msg->msg[1] = CEC_MSG_INACTIVE_SOURCE;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+}
+
+static inline void cec_ops_inactive_source(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+static inline void cec_msg_request_active_source(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_REQUEST_ACTIVE_SOURCE;
+ msg->reply = reply ? CEC_MSG_ACTIVE_SOURCE : 0;
+}
+
+static inline void cec_msg_routing_information(struct cec_msg *msg,
+ __u16 phys_addr)
+{
+ msg->len = 4;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_ROUTING_INFORMATION;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+}
+
+static inline void cec_ops_routing_information(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+static inline void cec_msg_routing_change(struct cec_msg *msg,
+ bool reply,
+ __u16 orig_phys_addr,
+ __u16 new_phys_addr)
+{
+ msg->len = 6;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_ROUTING_CHANGE;
+ msg->msg[2] = orig_phys_addr >> 8;
+ msg->msg[3] = orig_phys_addr & 0xff;
+ msg->msg[4] = new_phys_addr >> 8;
+ msg->msg[5] = new_phys_addr & 0xff;
+ msg->reply = reply ? CEC_MSG_ROUTING_INFORMATION : 0;
+}
+
+static inline void cec_ops_routing_change(const struct cec_msg *msg,
+ __u16 *orig_phys_addr,
+ __u16 *new_phys_addr)
+{
+ *orig_phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+ *new_phys_addr = (msg->msg[4] << 8) | msg->msg[5];
+}
+
+static inline void cec_msg_set_stream_path(struct cec_msg *msg, __u16 phys_addr)
+{
+ msg->len = 4;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_SET_STREAM_PATH;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+}
+
+static inline void cec_ops_set_stream_path(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+
+/* Standby Feature */
+static inline void cec_msg_standby(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_STANDBY;
+}
+
+
+/* One Touch Record Feature */
+static inline void cec_msg_record_off(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_RECORD_OFF;
+}
+
+struct cec_op_arib_data {
+ __u16 transport_id;
+ __u16 service_id;
+ __u16 orig_network_id;
+};
+
+struct cec_op_atsc_data {
+ __u16 transport_id;
+ __u16 program_number;
+};
+
+struct cec_op_dvb_data {
+ __u16 transport_id;
+ __u16 service_id;
+ __u16 orig_network_id;
+};
+
+struct cec_op_channel_data {
+ __u8 channel_number_fmt;
+ __u16 major;
+ __u16 minor;
+};
+
+struct cec_op_digital_service_id {
+ __u8 service_id_method;
+ __u8 dig_bcast_system;
+ union {
+ struct cec_op_arib_data arib;
+ struct cec_op_atsc_data atsc;
+ struct cec_op_dvb_data dvb;
+ struct cec_op_channel_data channel;
+ };
+};
+
+struct cec_op_record_src {
+ __u8 type;
+ union {
+ struct cec_op_digital_service_id digital;
+ struct {
+ __u8 ana_bcast_type;
+ __u16 ana_freq;
+ __u8 bcast_system;
+ } analog;
+ struct {
+ __u8 plug;
+ } ext_plug;
+ struct {
+ __u16 phys_addr;
+ } ext_phys_addr;
+ };
+};
+
+static inline void cec_set_digital_service_id(__u8 *msg,
+ const struct cec_op_digital_service_id *digital)
+{
+ *msg++ = (digital->service_id_method << 7) | digital->dig_bcast_system;
+ if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) {
+ *msg++ = (digital->channel.channel_number_fmt << 2) |
+ (digital->channel.major >> 8);
+ *msg++ = digital->channel.major && 0xff;
+ *msg++ = digital->channel.minor >> 8;
+ *msg++ = digital->channel.minor & 0xff;
+ *msg++ = 0;
+ *msg++ = 0;
+ return;
+ }
+ switch (digital->dig_bcast_system) {
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN:
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE:
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT:
+ case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T:
+ *msg++ = digital->atsc.transport_id >> 8;
+ *msg++ = digital->atsc.transport_id & 0xff;
+ *msg++ = digital->atsc.program_number >> 8;
+ *msg++ = digital->atsc.program_number & 0xff;
+ *msg++ = 0;
+ *msg++ = 0;
+ break;
+ default:
+ *msg++ = digital->dvb.transport_id >> 8;
+ *msg++ = digital->dvb.transport_id & 0xff;
+ *msg++ = digital->dvb.service_id >> 8;
+ *msg++ = digital->dvb.service_id & 0xff;
+ *msg++ = digital->dvb.orig_network_id >> 8;
+ *msg++ = digital->dvb.orig_network_id & 0xff;
+ break;
+ }
+}
+
+static inline void cec_get_digital_service_id(const __u8 *msg,
+ struct cec_op_digital_service_id *digital)
+{
+ digital->service_id_method = msg[0] >> 7;
+ digital->dig_bcast_system = msg[0] & 0x7f;
+ if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) {
+ digital->channel.channel_number_fmt = msg[1] >> 2;
+ digital->channel.major = ((msg[1] & 3) << 6) | msg[2];
+ digital->channel.minor = (msg[3] << 8) | msg[4];
+ return;
+ }
+ digital->dvb.transport_id = (msg[1] << 8) | msg[2];
+ digital->dvb.service_id = (msg[3] << 8) | msg[4];
+ digital->dvb.orig_network_id = (msg[5] << 8) | msg[6];
+}
+
+static inline void cec_msg_record_on_own(struct cec_msg *msg)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_RECORD_ON;
+ msg->msg[2] = CEC_OP_RECORD_SRC_OWN;
+}
+
+static inline void cec_msg_record_on_digital(struct cec_msg *msg,
+ const struct cec_op_digital_service_id *digital)
+{
+ msg->len = 10;
+ msg->msg[1] = CEC_MSG_RECORD_ON;
+ msg->msg[2] = CEC_OP_RECORD_SRC_DIGITAL;
+ cec_set_digital_service_id(msg->msg + 3, digital);
+}
+
+static inline void cec_msg_record_on_analog(struct cec_msg *msg,
+ __u8 ana_bcast_type,
+ __u16 ana_freq,
+ __u8 bcast_system)
+{
+ msg->len = 7;
+ msg->msg[1] = CEC_MSG_RECORD_ON;
+ msg->msg[2] = CEC_OP_RECORD_SRC_ANALOG;
+ msg->msg[3] = ana_bcast_type;
+ msg->msg[4] = ana_freq >> 8;
+ msg->msg[5] = ana_freq & 0xff;
+ msg->msg[6] = bcast_system;
+}
+
+static inline void cec_msg_record_on_plug(struct cec_msg *msg,
+ __u8 plug)
+{
+ msg->len = 4;
+ msg->msg[1] = CEC_MSG_RECORD_ON;
+ msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PLUG;
+ msg->msg[3] = plug;
+}
+
+static inline void cec_msg_record_on_phys_addr(struct cec_msg *msg,
+ __u16 phys_addr)
+{
+ msg->len = 5;
+ msg->msg[1] = CEC_MSG_RECORD_ON;
+ msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PHYS_ADDR;
+ msg->msg[3] = phys_addr >> 8;
+ msg->msg[4] = phys_addr & 0xff;
+}
+
+static inline void cec_msg_record_on(struct cec_msg *msg,
+ const struct cec_op_record_src *rec_src)
+{
+ switch (rec_src->type) {
+ case CEC_OP_RECORD_SRC_OWN:
+ cec_msg_record_on_own(msg);
+ break;
+ case CEC_OP_RECORD_SRC_DIGITAL:
+ cec_msg_record_on_digital(msg, &rec_src->digital);
+ break;
+ case CEC_OP_RECORD_SRC_ANALOG:
+ cec_msg_record_on_analog(msg,
+ rec_src->analog.ana_bcast_type,
+ rec_src->analog.ana_freq,
+ rec_src->analog.bcast_system);
+ break;
+ case CEC_OP_RECORD_SRC_EXT_PLUG:
+ cec_msg_record_on_plug(msg, rec_src->ext_plug.plug);
+ break;
+ case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR:
+ cec_msg_record_on_phys_addr(msg,
+ rec_src->ext_phys_addr.phys_addr);
+ break;
+ }
+}
+
+static inline void cec_ops_record_on(const struct cec_msg *msg,
+ struct cec_op_record_src *rec_src)
+{
+ rec_src->type = msg->msg[2];
+ switch (rec_src->type) {
+ case CEC_OP_RECORD_SRC_OWN:
+ break;
+ case CEC_OP_RECORD_SRC_DIGITAL:
+ cec_get_digital_service_id(msg->msg + 3, &rec_src->digital);
+ break;
+ case CEC_OP_RECORD_SRC_ANALOG:
+ rec_src->analog.ana_bcast_type = msg->msg[3];
+ rec_src->analog.ana_freq =
+ (msg->msg[4] << 8) | msg->msg[5];
+ rec_src->analog.bcast_system = msg->msg[6];
+ break;
+ case CEC_OP_RECORD_SRC_EXT_PLUG:
+ rec_src->ext_plug.plug = msg->msg[3];
+ break;
+ case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR:
+ rec_src->ext_phys_addr.phys_addr =
+ (msg->msg[3] << 8) | msg->msg[4];
+ break;
+ }
+}
+
+static inline void cec_msg_record_status(struct cec_msg *msg, __u8 rec_status)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_RECORD_STATUS;
+ msg->msg[2] = rec_status;
+}
+
+static inline void cec_ops_record_status(const struct cec_msg *msg,
+ __u8 *rec_status)
+{
+ *rec_status = msg->msg[2];
+}
+
+static inline void cec_msg_record_tv_screen(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_RECORD_TV_SCREEN;
+ msg->reply = reply ? CEC_MSG_RECORD_ON : 0;
+}
+
+
+/* Timer Programming Feature */
+static inline void cec_msg_timer_status(struct cec_msg *msg,
+ __u8 timer_overlap_warning,
+ __u8 media_info,
+ __u8 prog_info,
+ __u8 prog_error,
+ __u8 duration_hr,
+ __u8 duration_min)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_TIMER_STATUS;
+ msg->msg[2] = (timer_overlap_warning << 7) |
+ (media_info << 5) |
+ (prog_info ? 0x10 : 0) |
+ (prog_info ? prog_info : prog_error);
+ if (prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE ||
+ prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE ||
+ prog_error == CEC_OP_PROG_ERROR_DUPLICATE) {
+ msg->len += 2;
+ msg->msg[3] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[4] = ((duration_min / 10) << 4) | (duration_min % 10);
+ }
+}
+
+static inline void cec_ops_timer_status(const struct cec_msg *msg,
+ __u8 *timer_overlap_warning,
+ __u8 *media_info,
+ __u8 *prog_info,
+ __u8 *prog_error,
+ __u8 *duration_hr,
+ __u8 *duration_min)
+{
+ *timer_overlap_warning = msg->msg[2] >> 7;
+ *media_info = (msg->msg[2] >> 5) & 3;
+ if (msg->msg[2] & 0x10) {
+ *prog_info = msg->msg[2] & 0xf;
+ *prog_error = 0;
+ } else {
+ *prog_info = 0;
+ *prog_error = msg->msg[2] & 0xf;
+ }
+ if (*prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE ||
+ *prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE ||
+ *prog_error == CEC_OP_PROG_ERROR_DUPLICATE) {
+ *duration_hr = (msg->msg[3] >> 4) * 10 + (msg->msg[3] & 0xf);
+ *duration_min = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ } else {
+ *duration_hr = *duration_min = 0;
+ }
+}
+
+static inline void cec_msg_timer_cleared_status(struct cec_msg *msg,
+ __u8 timer_cleared_status)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_TIMER_CLEARED_STATUS;
+ msg->msg[2] = timer_cleared_status;
+}
+
+static inline void cec_ops_timer_cleared_status(const struct cec_msg *msg,
+ __u8 *timer_cleared_status)
+{
+ *timer_cleared_status = msg->msg[2];
+}
+
+static inline void cec_msg_clear_analogue_timer(struct cec_msg *msg,
+ bool reply,
+ __u8 day,
+ __u8 month,
+ __u8 start_hr,
+ __u8 start_min,
+ __u8 duration_hr,
+ __u8 duration_min,
+ __u8 recording_seq,
+ __u8 ana_bcast_type,
+ __u16 ana_freq,
+ __u8 bcast_system)
+{
+ msg->len = 13;
+ msg->msg[1] = CEC_MSG_CLEAR_ANALOGUE_TIMER;
+ msg->msg[2] = day;
+ msg->msg[3] = month;
+ /* Hours and minutes are in BCD format */
+ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
+ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
+ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
+ msg->msg[8] = recording_seq;
+ msg->msg[9] = ana_bcast_type;
+ msg->msg[10] = ana_freq >> 8;
+ msg->msg[11] = ana_freq & 0xff;
+ msg->msg[12] = bcast_system;
+ msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;
+}
+
+static inline void cec_ops_clear_analogue_timer(const struct cec_msg *msg,
+ __u8 *day,
+ __u8 *month,
+ __u8 *start_hr,
+ __u8 *start_min,
+ __u8 *duration_hr,
+ __u8 *duration_min,
+ __u8 *recording_seq,
+ __u8 *ana_bcast_type,
+ __u16 *ana_freq,
+ __u8 *bcast_system)
+{
+ *day = msg->msg[2];
+ *month = msg->msg[3];
+ /* Hours and minutes are in BCD format */
+ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
+ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
+ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
+ *recording_seq = msg->msg[8];
+ *ana_bcast_type = msg->msg[9];
+ *ana_freq = (msg->msg[10] << 8) | msg->msg[11];
+ *bcast_system = msg->msg[12];
+}
+
+static inline void cec_msg_clear_digital_timer(struct cec_msg *msg,
+ bool reply,
+ __u8 day,
+ __u8 month,
+ __u8 start_hr,
+ __u8 start_min,
+ __u8 duration_hr,
+ __u8 duration_min,
+ __u8 recording_seq,
+ const struct cec_op_digital_service_id *digital)
+{
+ msg->len = 16;
+ msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;
+ msg->msg[1] = CEC_MSG_CLEAR_DIGITAL_TIMER;
+ msg->msg[2] = day;
+ msg->msg[3] = month;
+ /* Hours and minutes are in BCD format */
+ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
+ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
+ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
+ msg->msg[8] = recording_seq;
+ cec_set_digital_service_id(msg->msg + 9, digital);
+}
+
+static inline void cec_ops_clear_digital_timer(const struct cec_msg *msg,
+ __u8 *day,
+ __u8 *month,
+ __u8 *start_hr,
+ __u8 *start_min,
+ __u8 *duration_hr,
+ __u8 *duration_min,
+ __u8 *recording_seq,
+ struct cec_op_digital_service_id *digital)
+{
+ *day = msg->msg[2];
+ *month = msg->msg[3];
+ /* Hours and minutes are in BCD format */
+ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
+ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
+ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
+ *recording_seq = msg->msg[8];
+ cec_get_digital_service_id(msg->msg + 9, digital);
+}
+
+static inline void cec_msg_clear_ext_timer(struct cec_msg *msg,
+ bool reply,
+ __u8 day,
+ __u8 month,
+ __u8 start_hr,
+ __u8 start_min,
+ __u8 duration_hr,
+ __u8 duration_min,
+ __u8 recording_seq,
+ __u8 ext_src_spec,
+ __u8 plug,
+ __u16 phys_addr)
+{
+ msg->len = 13;
+ msg->msg[1] = CEC_MSG_CLEAR_EXT_TIMER;
+ msg->msg[2] = day;
+ msg->msg[3] = month;
+ /* Hours and minutes are in BCD format */
+ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
+ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
+ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
+ msg->msg[8] = recording_seq;
+ msg->msg[9] = ext_src_spec;
+ msg->msg[10] = plug;
+ msg->msg[11] = phys_addr >> 8;
+ msg->msg[12] = phys_addr & 0xff;
+ msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;
+}
+
+static inline void cec_ops_clear_ext_timer(const struct cec_msg *msg,
+ __u8 *day,
+ __u8 *month,
+ __u8 *start_hr,
+ __u8 *start_min,
+ __u8 *duration_hr,
+ __u8 *duration_min,
+ __u8 *recording_seq,
+ __u8 *ext_src_spec,
+ __u8 *plug,
+ __u16 *phys_addr)
+{
+ *day = msg->msg[2];
+ *month = msg->msg[3];
+ /* Hours and minutes are in BCD format */
+ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
+ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
+ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
+ *recording_seq = msg->msg[8];
+ *ext_src_spec = msg->msg[9];
+ *plug = msg->msg[10];
+ *phys_addr = (msg->msg[11] << 8) | msg->msg[12];
+}
+
+static inline void cec_msg_set_analogue_timer(struct cec_msg *msg,
+ bool reply,
+ __u8 day,
+ __u8 month,
+ __u8 start_hr,
+ __u8 start_min,
+ __u8 duration_hr,
+ __u8 duration_min,
+ __u8 recording_seq,
+ __u8 ana_bcast_type,
+ __u16 ana_freq,
+ __u8 bcast_system)
+{
+ msg->len = 13;
+ msg->msg[1] = CEC_MSG_SET_ANALOGUE_TIMER;
+ msg->msg[2] = day;
+ msg->msg[3] = month;
+ /* Hours and minutes are in BCD format */
+ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
+ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
+ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
+ msg->msg[8] = recording_seq;
+ msg->msg[9] = ana_bcast_type;
+ msg->msg[10] = ana_freq >> 8;
+ msg->msg[11] = ana_freq & 0xff;
+ msg->msg[12] = bcast_system;
+ msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0;
+}
+
+static inline void cec_ops_set_analogue_timer(const struct cec_msg *msg,
+ __u8 *day,
+ __u8 *month,
+ __u8 *start_hr,
+ __u8 *start_min,
+ __u8 *duration_hr,
+ __u8 *duration_min,
+ __u8 *recording_seq,
+ __u8 *ana_bcast_type,
+ __u16 *ana_freq,
+ __u8 *bcast_system)
+{
+ *day = msg->msg[2];
+ *month = msg->msg[3];
+ /* Hours and minutes are in BCD format */
+ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
+ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
+ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
+ *recording_seq = msg->msg[8];
+ *ana_bcast_type = msg->msg[9];
+ *ana_freq = (msg->msg[10] << 8) | msg->msg[11];
+ *bcast_system = msg->msg[12];
+}
+
+static inline void cec_msg_set_digital_timer(struct cec_msg *msg,
+ bool reply,
+ __u8 day,
+ __u8 month,
+ __u8 start_hr,
+ __u8 start_min,
+ __u8 duration_hr,
+ __u8 duration_min,
+ __u8 recording_seq,
+ const struct cec_op_digital_service_id *digital)
+{
+ msg->len = 16;
+ msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0;
+ msg->msg[1] = CEC_MSG_SET_DIGITAL_TIMER;
+ msg->msg[2] = day;
+ msg->msg[3] = month;
+ /* Hours and minutes are in BCD format */
+ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
+ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
+ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
+ msg->msg[8] = recording_seq;
+ cec_set_digital_service_id(msg->msg + 9, digital);
+}
+
+static inline void cec_ops_set_digital_timer(const struct cec_msg *msg,
+ __u8 *day,
+ __u8 *month,
+ __u8 *start_hr,
+ __u8 *start_min,
+ __u8 *duration_hr,
+ __u8 *duration_min,
+ __u8 *recording_seq,
+ struct cec_op_digital_service_id *digital)
+{
+ *day = msg->msg[2];
+ *month = msg->msg[3];
+ /* Hours and minutes are in BCD format */
+ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
+ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
+ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
+ *recording_seq = msg->msg[8];
+ cec_get_digital_service_id(msg->msg + 9, digital);
+}
+
+static inline void cec_msg_set_ext_timer(struct cec_msg *msg,
+ bool reply,
+ __u8 day,
+ __u8 month,
+ __u8 start_hr,
+ __u8 start_min,
+ __u8 duration_hr,
+ __u8 duration_min,
+ __u8 recording_seq,
+ __u8 ext_src_spec,
+ __u8 plug,
+ __u16 phys_addr)
+{
+ msg->len = 13;
+ msg->msg[1] = CEC_MSG_SET_EXT_TIMER;
+ msg->msg[2] = day;
+ msg->msg[3] = month;
+ /* Hours and minutes are in BCD format */
+ msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);
+ msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);
+ msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);
+ msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);
+ msg->msg[8] = recording_seq;
+ msg->msg[9] = ext_src_spec;
+ msg->msg[10] = plug;
+ msg->msg[11] = phys_addr >> 8;
+ msg->msg[12] = phys_addr & 0xff;
+ msg->reply = reply ? CEC_MSG_TIMER_STATUS : 0;
+}
+
+static inline void cec_ops_set_ext_timer(const struct cec_msg *msg,
+ __u8 *day,
+ __u8 *month,
+ __u8 *start_hr,
+ __u8 *start_min,
+ __u8 *duration_hr,
+ __u8 *duration_min,
+ __u8 *recording_seq,
+ __u8 *ext_src_spec,
+ __u8 *plug,
+ __u16 *phys_addr)
+{
+ *day = msg->msg[2];
+ *month = msg->msg[3];
+ /* Hours and minutes are in BCD format */
+ *start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);
+ *start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);
+ *duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);
+ *duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);
+ *recording_seq = msg->msg[8];
+ *ext_src_spec = msg->msg[9];
+ *plug = msg->msg[10];
+ *phys_addr = (msg->msg[11] << 8) | msg->msg[12];
+}
+
+static inline void cec_msg_set_timer_program_title(struct cec_msg *msg,
+ const char *prog_title)
+{
+ unsigned int len = strlen(prog_title);
+
+ if (len > 14)
+ len = 14;
+ msg->len = 2 + len;
+ msg->msg[1] = CEC_MSG_SET_TIMER_PROGRAM_TITLE;
+ memcpy(msg->msg + 2, prog_title, len);
+}
+
+static inline void cec_ops_set_timer_program_title(const struct cec_msg *msg,
+ char *prog_title)
+{
+ unsigned int len = msg->len > 2 ? msg->len - 2 : 0;
+
+ if (len > 14)
+ len = 14;
+ memcpy(prog_title, msg->msg + 2, len);
+ prog_title[len] = '\0';
+}
+
+/* System Information Feature */
+static inline void cec_msg_cec_version(struct cec_msg *msg, __u8 cec_version)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_CEC_VERSION;
+ msg->msg[2] = cec_version;
+}
+
+static inline void cec_ops_cec_version(const struct cec_msg *msg,
+ __u8 *cec_version)
+{
+ *cec_version = msg->msg[2];
+}
+
+static inline void cec_msg_get_cec_version(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GET_CEC_VERSION;
+ msg->reply = reply ? CEC_MSG_CEC_VERSION : 0;
+}
+
+static inline void cec_msg_report_physical_addr(struct cec_msg *msg,
+ __u16 phys_addr, __u8 prim_devtype)
+{
+ msg->len = 5;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_REPORT_PHYSICAL_ADDR;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+ msg->msg[4] = prim_devtype;
+}
+
+static inline void cec_ops_report_physical_addr(const struct cec_msg *msg,
+ __u16 *phys_addr, __u8 *prim_devtype)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+ *prim_devtype = msg->msg[4];
+}
+
+static inline void cec_msg_give_physical_addr(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_PHYSICAL_ADDR;
+ msg->reply = reply ? CEC_MSG_REPORT_PHYSICAL_ADDR : 0;
+}
+
+static inline void cec_msg_set_menu_language(struct cec_msg *msg,
+ const char *language)
+{
+ msg->len = 5;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_SET_MENU_LANGUAGE;
+ memcpy(msg->msg + 2, language, 3);
+}
+
+static inline void cec_ops_set_menu_language(const struct cec_msg *msg,
+ char *language)
+{
+ memcpy(language, msg->msg + 2, 3);
+ language[3] = '\0';
+}
+
+static inline void cec_msg_get_menu_language(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GET_MENU_LANGUAGE;
+ msg->reply = reply ? CEC_MSG_SET_MENU_LANGUAGE : 0;
+}
+
+/*
+ * Assumes a single RC Profile byte and a single Device Features byte,
+ * i.e. no extended features are supported by this helper function.
+ *
+ * As of CEC 2.0 no extended features are defined, should those be added
+ * in the future, then this function needs to be adapted or a new function
+ * should be added.
+ */
+static inline void cec_msg_report_features(struct cec_msg *msg,
+ __u8 cec_version, __u8 all_device_types,
+ __u8 rc_profile, __u8 dev_features)
+{
+ msg->len = 6;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_REPORT_FEATURES;
+ msg->msg[2] = cec_version;
+ msg->msg[3] = all_device_types;
+ msg->msg[4] = rc_profile;
+ msg->msg[5] = dev_features;
+}
+
+static inline void cec_ops_report_features(const struct cec_msg *msg,
+ __u8 *cec_version, __u8 *all_device_types,
+ const __u8 **rc_profile, const __u8 **dev_features)
+{
+ const __u8 *p = &msg->msg[4];
+
+ *cec_version = msg->msg[2];
+ *all_device_types = msg->msg[3];
+ *rc_profile = p;
+ while (p < &msg->msg[14] && (*p & CEC_OP_FEAT_EXT))
+ p++;
+ if (!(*p & CEC_OP_FEAT_EXT)) {
+ *dev_features = p + 1;
+ while (p < &msg->msg[15] && (*p & CEC_OP_FEAT_EXT))
+ p++;
+ }
+ if (*p & CEC_OP_FEAT_EXT)
+ *rc_profile = *dev_features = NULL;
+}
+
+static inline void cec_msg_give_features(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_FEATURES;
+ msg->reply = reply ? CEC_MSG_REPORT_FEATURES : 0;
+}
+
+/* Deck Control Feature */
+static inline void cec_msg_deck_control(struct cec_msg *msg,
+ __u8 deck_control_mode)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_DECK_CONTROL;
+ msg->msg[2] = deck_control_mode;
+}
+
+static inline void cec_ops_deck_control(const struct cec_msg *msg,
+ __u8 *deck_control_mode)
+{
+ *deck_control_mode = msg->msg[2];
+}
+
+static inline void cec_msg_deck_status(struct cec_msg *msg,
+ __u8 deck_info)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_DECK_STATUS;
+ msg->msg[2] = deck_info;
+}
+
+static inline void cec_ops_deck_status(const struct cec_msg *msg,
+ __u8 *deck_info)
+{
+ *deck_info = msg->msg[2];
+}
+
+static inline void cec_msg_give_deck_status(struct cec_msg *msg,
+ bool reply,
+ __u8 status_req)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_GIVE_DECK_STATUS;
+ msg->msg[2] = status_req;
+ msg->reply = reply ? CEC_MSG_DECK_STATUS : 0;
+}
+
+static inline void cec_ops_give_deck_status(const struct cec_msg *msg,
+ __u8 *status_req)
+{
+ *status_req = msg->msg[2];
+}
+
+static inline void cec_msg_play(struct cec_msg *msg,
+ __u8 play_mode)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_PLAY;
+ msg->msg[2] = play_mode;
+}
+
+static inline void cec_ops_play(const struct cec_msg *msg,
+ __u8 *play_mode)
+{
+ *play_mode = msg->msg[2];
+}
+
+
+/* Tuner Control Feature */
+struct cec_op_tuner_device_info {
+ __u8 rec_flag;
+ __u8 tuner_display_info;
+ bool is_analog;
+ union {
+ struct cec_op_digital_service_id digital;
+ struct {
+ __u8 ana_bcast_type;
+ __u16 ana_freq;
+ __u8 bcast_system;
+ } analog;
+ };
+};
+
+static inline void cec_msg_tuner_device_status_analog(struct cec_msg *msg,
+ __u8 rec_flag,
+ __u8 tuner_display_info,
+ __u8 ana_bcast_type,
+ __u16 ana_freq,
+ __u8 bcast_system)
+{
+ msg->len = 7;
+ msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS;
+ msg->msg[2] = (rec_flag << 7) | tuner_display_info;
+ msg->msg[3] = ana_bcast_type;
+ msg->msg[4] = ana_freq >> 8;
+ msg->msg[5] = ana_freq & 0xff;
+ msg->msg[6] = bcast_system;
+}
+
+static inline void cec_msg_tuner_device_status_digital(struct cec_msg *msg,
+ __u8 rec_flag, __u8 tuner_display_info,
+ const struct cec_op_digital_service_id *digital)
+{
+ msg->len = 10;
+ msg->msg[1] = CEC_MSG_TUNER_DEVICE_STATUS;
+ msg->msg[2] = (rec_flag << 7) | tuner_display_info;
+ cec_set_digital_service_id(msg->msg + 3, digital);
+}
+
+static inline void cec_msg_tuner_device_status(struct cec_msg *msg,
+ const struct cec_op_tuner_device_info *tuner_dev_info)
+{
+ if (tuner_dev_info->is_analog)
+ cec_msg_tuner_device_status_analog(msg,
+ tuner_dev_info->rec_flag,
+ tuner_dev_info->tuner_display_info,
+ tuner_dev_info->analog.ana_bcast_type,
+ tuner_dev_info->analog.ana_freq,
+ tuner_dev_info->analog.bcast_system);
+ else
+ cec_msg_tuner_device_status_digital(msg,
+ tuner_dev_info->rec_flag,
+ tuner_dev_info->tuner_display_info,
+ &tuner_dev_info->digital);
+}
+
+static inline void cec_ops_tuner_device_status(const struct cec_msg *msg,
+ struct cec_op_tuner_device_info *tuner_dev_info)
+{
+ tuner_dev_info->is_analog = msg->len < 10;
+ tuner_dev_info->rec_flag = msg->msg[2] >> 7;
+ tuner_dev_info->tuner_display_info = msg->msg[2] & 0x7f;
+ if (tuner_dev_info->is_analog) {
+ tuner_dev_info->analog.ana_bcast_type = msg->msg[3];
+ tuner_dev_info->analog.ana_freq = (msg->msg[4] << 8) | msg->msg[5];
+ tuner_dev_info->analog.bcast_system = msg->msg[6];
+ return;
+ }
+ cec_get_digital_service_id(msg->msg + 3, &tuner_dev_info->digital);
+}
+
+static inline void cec_msg_give_tuner_device_status(struct cec_msg *msg,
+ bool reply,
+ __u8 status_req)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_GIVE_TUNER_DEVICE_STATUS;
+ msg->msg[2] = status_req;
+ msg->reply = reply ? CEC_MSG_TUNER_DEVICE_STATUS : 0;
+}
+
+static inline void cec_ops_give_tuner_device_status(const struct cec_msg *msg,
+ __u8 *status_req)
+{
+ *status_req = msg->msg[2];
+}
+
+static inline void cec_msg_select_analogue_service(struct cec_msg *msg,
+ __u8 ana_bcast_type,
+ __u16 ana_freq,
+ __u8 bcast_system)
+{
+ msg->len = 6;
+ msg->msg[1] = CEC_MSG_SELECT_ANALOGUE_SERVICE;
+ msg->msg[2] = ana_bcast_type;
+ msg->msg[3] = ana_freq >> 8;
+ msg->msg[4] = ana_freq & 0xff;
+ msg->msg[5] = bcast_system;
+}
+
+static inline void cec_ops_select_analogue_service(const struct cec_msg *msg,
+ __u8 *ana_bcast_type,
+ __u16 *ana_freq,
+ __u8 *bcast_system)
+{
+ *ana_bcast_type = msg->msg[2];
+ *ana_freq = (msg->msg[3] << 8) | msg->msg[4];
+ *bcast_system = msg->msg[5];
+}
+
+static inline void cec_msg_select_digital_service(struct cec_msg *msg,
+ const struct cec_op_digital_service_id *digital)
+{
+ msg->len = 9;
+ msg->msg[1] = CEC_MSG_SELECT_DIGITAL_SERVICE;
+ cec_set_digital_service_id(msg->msg + 2, digital);
+}
+
+static inline void cec_ops_select_digital_service(const struct cec_msg *msg,
+ struct cec_op_digital_service_id *digital)
+{
+ cec_get_digital_service_id(msg->msg + 2, digital);
+}
+
+static inline void cec_msg_tuner_step_decrement(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_TUNER_STEP_DECREMENT;
+}
+
+static inline void cec_msg_tuner_step_increment(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_TUNER_STEP_INCREMENT;
+}
+
+
+/* Vendor Specific Commands Feature */
+static inline void cec_msg_device_vendor_id(struct cec_msg *msg, __u32 vendor_id)
+{
+ msg->len = 5;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_DEVICE_VENDOR_ID;
+ msg->msg[2] = vendor_id >> 16;
+ msg->msg[3] = (vendor_id >> 8) & 0xff;
+ msg->msg[4] = vendor_id & 0xff;
+}
+
+static inline void cec_ops_device_vendor_id(const struct cec_msg *msg,
+ __u32 *vendor_id)
+{
+ *vendor_id = (msg->msg[2] << 16) | (msg->msg[3] << 8) | msg->msg[4];
+}
+
+static inline void cec_msg_give_device_vendor_id(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_DEVICE_VENDOR_ID;
+ msg->reply = reply ? CEC_MSG_DEVICE_VENDOR_ID : 0;
+}
+
+static inline void cec_msg_vendor_remote_button_up(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_VENDOR_REMOTE_BUTTON_UP;
+}
+
+
+/* OSD Display Feature */
+static inline void cec_msg_set_osd_string(struct cec_msg *msg,
+ __u8 disp_ctl,
+ const char *osd)
+{
+ unsigned int len = strlen(osd);
+
+ if (len > 13)
+ len = 13;
+ msg->len = 3 + len;
+ msg->msg[1] = CEC_MSG_SET_OSD_STRING;
+ msg->msg[2] = disp_ctl;
+ memcpy(msg->msg + 3, osd, len);
+}
+
+static inline void cec_ops_set_osd_string(const struct cec_msg *msg,
+ __u8 *disp_ctl,
+ char *osd)
+{
+ unsigned int len = msg->len > 3 ? msg->len - 3 : 0;
+
+ *disp_ctl = msg->msg[2];
+ if (len > 13)
+ len = 13;
+ memcpy(osd, msg->msg + 3, len);
+ osd[len] = '\0';
+}
+
+
+/* Device OSD Transfer Feature */
+static inline void cec_msg_set_osd_name(struct cec_msg *msg, const char *name)
+{
+ unsigned int len = strlen(name);
+
+ if (len > 14)
+ len = 14;
+ msg->len = 2 + len;
+ msg->msg[1] = CEC_MSG_SET_OSD_NAME;
+ memcpy(msg->msg + 2, name, len);
+}
+
+static inline void cec_ops_set_osd_name(const struct cec_msg *msg,
+ char *name)
+{
+ unsigned int len = msg->len > 2 ? msg->len - 2 : 0;
+
+ if (len > 14)
+ len = 14;
+ memcpy(name, msg->msg + 2, len);
+ name[len] = '\0';
+}
+
+static inline void cec_msg_give_osd_name(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_OSD_NAME;
+ msg->reply = reply ? CEC_MSG_SET_OSD_NAME : 0;
+}
+
+
+/* Device Menu Control Feature */
+static inline void cec_msg_menu_status(struct cec_msg *msg,
+ __u8 menu_state)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_MENU_STATUS;
+ msg->msg[2] = menu_state;
+}
+
+static inline void cec_ops_menu_status(const struct cec_msg *msg,
+ __u8 *menu_state)
+{
+ *menu_state = msg->msg[2];
+}
+
+static inline void cec_msg_menu_request(struct cec_msg *msg,
+ bool reply,
+ __u8 menu_req)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_MENU_REQUEST;
+ msg->msg[2] = menu_req;
+ msg->reply = reply ? CEC_MSG_MENU_STATUS : 0;
+}
+
+static inline void cec_ops_menu_request(const struct cec_msg *msg,
+ __u8 *menu_req)
+{
+ *menu_req = msg->msg[2];
+}
+
+struct cec_op_ui_command {
+ __u8 ui_cmd;
+ bool has_opt_arg;
+ union {
+ struct cec_op_channel_data channel_identifier;
+ __u8 ui_broadcast_type;
+ __u8 ui_sound_presentation_control;
+ __u8 play_mode;
+ __u8 ui_function_media;
+ __u8 ui_function_select_av_input;
+ __u8 ui_function_select_audio_input;
+ };
+};
+
+static inline void cec_msg_user_control_pressed(struct cec_msg *msg,
+ const struct cec_op_ui_command *ui_cmd)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_USER_CONTROL_PRESSED;
+ msg->msg[2] = ui_cmd->ui_cmd;
+ if (!ui_cmd->has_opt_arg)
+ return;
+ switch (ui_cmd->ui_cmd) {
+ case 0x56:
+ case 0x57:
+ case 0x60:
+ case 0x68:
+ case 0x69:
+ case 0x6a:
+ /* The optional operand is one byte for all these ui commands */
+ msg->len++;
+ msg->msg[3] = ui_cmd->play_mode;
+ break;
+ case 0x67:
+ msg->len += 4;
+ msg->msg[3] = (ui_cmd->channel_identifier.channel_number_fmt << 2) |
+ (ui_cmd->channel_identifier.major >> 8);
+ msg->msg[4] = ui_cmd->channel_identifier.major && 0xff;
+ msg->msg[5] = ui_cmd->channel_identifier.minor >> 8;
+ msg->msg[6] = ui_cmd->channel_identifier.minor & 0xff;
+ break;
+ }
+}
+
+static inline void cec_ops_user_control_pressed(const struct cec_msg *msg,
+ struct cec_op_ui_command *ui_cmd)
+{
+ ui_cmd->ui_cmd = msg->msg[2];
+ ui_cmd->has_opt_arg = false;
+ if (msg->len == 3)
+ return;
+ switch (ui_cmd->ui_cmd) {
+ case 0x56:
+ case 0x57:
+ case 0x60:
+ case 0x68:
+ case 0x69:
+ case 0x6a:
+ /* The optional operand is one byte for all these ui commands */
+ ui_cmd->play_mode = msg->msg[3];
+ ui_cmd->has_opt_arg = true;
+ break;
+ case 0x67:
+ if (msg->len < 7)
+ break;
+ ui_cmd->has_opt_arg = true;
+ ui_cmd->channel_identifier.channel_number_fmt = msg->msg[3] >> 2;
+ ui_cmd->channel_identifier.major = ((msg->msg[3] & 3) << 6) | msg->msg[4];
+ ui_cmd->channel_identifier.minor = (msg->msg[5] << 8) | msg->msg[6];
+ break;
+ }
+}
+
+static inline void cec_msg_user_control_released(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_USER_CONTROL_RELEASED;
+}
+
+/* Remote Control Passthrough Feature */
+
+/* Power Status Feature */
+static inline void cec_msg_report_power_status(struct cec_msg *msg,
+ __u8 pwr_state)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_REPORT_POWER_STATUS;
+ msg->msg[2] = pwr_state;
+}
+
+static inline void cec_ops_report_power_status(const struct cec_msg *msg,
+ __u8 *pwr_state)
+{
+ *pwr_state = msg->msg[2];
+}
+
+static inline void cec_msg_give_device_power_status(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_DEVICE_POWER_STATUS;
+ msg->reply = reply ? CEC_MSG_REPORT_POWER_STATUS : 0;
+}
+
+/* General Protocol Messages */
+static inline void cec_msg_feature_abort(struct cec_msg *msg,
+ __u8 abort_msg, __u8 reason)
+{
+ msg->len = 4;
+ msg->msg[1] = CEC_MSG_FEATURE_ABORT;
+ msg->msg[2] = abort_msg;
+ msg->msg[3] = reason;
+}
+
+static inline void cec_ops_feature_abort(const struct cec_msg *msg,
+ __u8 *abort_msg, __u8 *reason)
+{
+ *abort_msg = msg->msg[2];
+ *reason = msg->msg[3];
+}
+
+/* This changes the current message into a feature abort message */
+static inline void cec_msg_reply_feature_abort(struct cec_msg *msg, __u8 reason)
+{
+ cec_msg_set_reply_to(msg, msg);
+ msg->len = 4;
+ msg->msg[2] = msg->msg[1];
+ msg->msg[3] = reason;
+ msg->msg[1] = CEC_MSG_FEATURE_ABORT;
+}
+
+static inline void cec_msg_abort(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_ABORT;
+}
+
+
+/* System Audio Control Feature */
+static inline void cec_msg_report_audio_status(struct cec_msg *msg,
+ __u8 aud_mute_status,
+ __u8 aud_vol_status)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_REPORT_AUDIO_STATUS;
+ msg->msg[2] = (aud_mute_status << 7) | (aud_vol_status & 0x7f);
+}
+
+static inline void cec_ops_report_audio_status(const struct cec_msg *msg,
+ __u8 *aud_mute_status,
+ __u8 *aud_vol_status)
+{
+ *aud_mute_status = msg->msg[2] >> 7;
+ *aud_vol_status = msg->msg[2] & 0x7f;
+}
+
+static inline void cec_msg_give_audio_status(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_AUDIO_STATUS;
+ msg->reply = reply ? CEC_MSG_REPORT_AUDIO_STATUS : 0;
+}
+
+static inline void cec_msg_set_system_audio_mode(struct cec_msg *msg,
+ __u8 sys_aud_status)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_SET_SYSTEM_AUDIO_MODE;
+ msg->msg[2] = sys_aud_status;
+}
+
+static inline void cec_ops_set_system_audio_mode(const struct cec_msg *msg,
+ __u8 *sys_aud_status)
+{
+ *sys_aud_status = msg->msg[2];
+}
+
+static inline void cec_msg_system_audio_mode_request(struct cec_msg *msg,
+ bool reply,
+ __u16 phys_addr)
+{
+ msg->len = phys_addr == 0xffff ? 2 : 4;
+ msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+ msg->reply = reply ? CEC_MSG_SET_SYSTEM_AUDIO_MODE : 0;
+
+}
+
+static inline void cec_ops_system_audio_mode_request(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ if (msg->len < 4)
+ *phys_addr = 0xffff;
+ else
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+static inline void cec_msg_system_audio_mode_status(struct cec_msg *msg,
+ __u8 sys_aud_status)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_SYSTEM_AUDIO_MODE_STATUS;
+ msg->msg[2] = sys_aud_status;
+}
+
+static inline void cec_ops_system_audio_mode_status(const struct cec_msg *msg,
+ __u8 *sys_aud_status)
+{
+ *sys_aud_status = msg->msg[2];
+}
+
+static inline void cec_msg_give_system_audio_mode_status(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS;
+ msg->reply = reply ? CEC_MSG_SYSTEM_AUDIO_MODE_STATUS : 0;
+}
+
+static inline void cec_msg_report_short_audio_descriptor(struct cec_msg *msg,
+ __u8 num_descriptors,
+ const __u32 *descriptors)
+{
+ unsigned int i;
+
+ if (num_descriptors > 4)
+ num_descriptors = 4;
+ msg->len = 2 + num_descriptors * 3;
+ msg->msg[1] = CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR;
+ for (i = 0; i < num_descriptors; i++) {
+ msg->msg[2 + i * 3] = (descriptors[i] >> 16) & 0xff;
+ msg->msg[3 + i * 3] = (descriptors[i] >> 8) & 0xff;
+ msg->msg[4 + i * 3] = descriptors[i] & 0xff;
+ }
+}
+
+static inline void cec_ops_report_short_audio_descriptor(const struct cec_msg *msg,
+ __u8 *num_descriptors,
+ __u32 *descriptors)
+{
+ unsigned int i;
+
+ *num_descriptors = (msg->len - 2) / 3;
+ if (*num_descriptors > 4)
+ *num_descriptors = 4;
+ for (i = 0; i < *num_descriptors; i++)
+ descriptors[i] = (msg->msg[2 + i * 3] << 16) |
+ (msg->msg[3 + i * 3] << 8) |
+ msg->msg[4 + i * 3];
+}
+
+static inline void cec_msg_request_short_audio_descriptor(struct cec_msg *msg,
+ bool reply,
+ __u8 num_descriptors,
+ const __u8 *audio_format_id,
+ const __u8 *audio_format_code)
+{
+ unsigned int i;
+
+ if (num_descriptors > 4)
+ num_descriptors = 4;
+ msg->len = 2 + num_descriptors;
+ msg->msg[1] = CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR;
+ msg->reply = reply ? CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR : 0;
+ for (i = 0; i < num_descriptors; i++)
+ msg->msg[2 + i] = (audio_format_id[i] << 6) |
+ (audio_format_code[i] & 0x3f);
+}
+
+static inline void cec_ops_request_short_audio_descriptor(const struct cec_msg *msg,
+ __u8 *num_descriptors,
+ __u8 *audio_format_id,
+ __u8 *audio_format_code)
+{
+ unsigned int i;
+
+ *num_descriptors = msg->len - 2;
+ if (*num_descriptors > 4)
+ *num_descriptors = 4;
+ for (i = 0; i < *num_descriptors; i++) {
+ audio_format_id[i] = msg->msg[2 + i] >> 6;
+ audio_format_code[i] = msg->msg[2 + i] & 0x3f;
+ }
+}
+
+
+/* Audio Rate Control Feature */
+static inline void cec_msg_set_audio_rate(struct cec_msg *msg,
+ __u8 audio_rate)
+{
+ msg->len = 3;
+ msg->msg[1] = CEC_MSG_SET_AUDIO_RATE;
+ msg->msg[2] = audio_rate;
+}
+
+static inline void cec_ops_set_audio_rate(const struct cec_msg *msg,
+ __u8 *audio_rate)
+{
+ *audio_rate = msg->msg[2];
+}
+
+
+/* Audio Return Channel Control Feature */
+static inline void cec_msg_report_arc_initiated(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_REPORT_ARC_INITIATED;
+}
+
+static inline void cec_msg_initiate_arc(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_INITIATE_ARC;
+ msg->reply = reply ? CEC_MSG_REPORT_ARC_INITIATED : 0;
+}
+
+static inline void cec_msg_request_arc_initiation(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_REQUEST_ARC_INITIATION;
+ msg->reply = reply ? CEC_MSG_INITIATE_ARC : 0;
+}
+
+static inline void cec_msg_report_arc_terminated(struct cec_msg *msg)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_REPORT_ARC_TERMINATED;
+}
+
+static inline void cec_msg_terminate_arc(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_TERMINATE_ARC;
+ msg->reply = reply ? CEC_MSG_REPORT_ARC_TERMINATED : 0;
+}
+
+static inline void cec_msg_request_arc_termination(struct cec_msg *msg,
+ bool reply)
+{
+ msg->len = 2;
+ msg->msg[1] = CEC_MSG_REQUEST_ARC_TERMINATION;
+ msg->reply = reply ? CEC_MSG_TERMINATE_ARC : 0;
+}
+
+
+/* Dynamic Audio Lipsync Feature */
+/* Only for CEC 2.0 and up */
+static inline void cec_msg_report_current_latency(struct cec_msg *msg,
+ __u16 phys_addr,
+ __u8 video_latency,
+ __u8 low_latency_mode,
+ __u8 audio_out_compensated,
+ __u8 audio_out_delay)
+{
+ msg->len = 7;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_REPORT_CURRENT_LATENCY;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+ msg->msg[4] = video_latency;
+ msg->msg[5] = (low_latency_mode << 2) | audio_out_compensated;
+ msg->msg[6] = audio_out_delay;
+}
+
+static inline void cec_ops_report_current_latency(const struct cec_msg *msg,
+ __u16 *phys_addr,
+ __u8 *video_latency,
+ __u8 *low_latency_mode,
+ __u8 *audio_out_compensated,
+ __u8 *audio_out_delay)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+ *video_latency = msg->msg[4];
+ *low_latency_mode = (msg->msg[5] >> 2) & 1;
+ *audio_out_compensated = msg->msg[5] & 3;
+ *audio_out_delay = msg->msg[6];
+}
+
+static inline void cec_msg_request_current_latency(struct cec_msg *msg,
+ bool reply,
+ __u16 phys_addr)
+{
+ msg->len = 4;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_REQUEST_CURRENT_LATENCY;
+ msg->msg[2] = phys_addr >> 8;
+ msg->msg[3] = phys_addr & 0xff;
+ msg->reply = reply ? CEC_MSG_REPORT_CURRENT_LATENCY : 0;
+}
+
+static inline void cec_ops_request_current_latency(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+
+/* Capability Discovery and Control Feature */
+static inline void cec_msg_cdc_hec_inquire_state(struct cec_msg *msg,
+ __u16 phys_addr1,
+ __u16 phys_addr2)
+{
+ msg->len = 9;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_CDC_MESSAGE;
+ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
+ msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE;
+ msg->msg[5] = phys_addr1 >> 8;
+ msg->msg[6] = phys_addr1 & 0xff;
+ msg->msg[7] = phys_addr2 >> 8;
+ msg->msg[8] = phys_addr2 & 0xff;
+}
+
+static inline void cec_ops_cdc_hec_inquire_state(const struct cec_msg *msg,
+ __u16 *phys_addr,
+ __u16 *phys_addr1,
+ __u16 *phys_addr2)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+ *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];
+ *phys_addr2 = (msg->msg[7] << 8) | msg->msg[8];
+}
+
+static inline void cec_msg_cdc_hec_report_state(struct cec_msg *msg,
+ __u16 target_phys_addr,
+ __u8 hec_func_state,
+ __u8 host_func_state,
+ __u8 enc_func_state,
+ __u8 cdc_errcode,
+ __u8 has_field,
+ __u16 hec_field)
+{
+ msg->len = has_field ? 10 : 8;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_CDC_MESSAGE;
+ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
+ msg->msg[4] = CEC_MSG_CDC_HEC_REPORT_STATE;
+ msg->msg[5] = target_phys_addr >> 8;
+ msg->msg[6] = target_phys_addr & 0xff;
+ msg->msg[7] = (hec_func_state << 6) |
+ (host_func_state << 4) |
+ (enc_func_state << 2) |
+ cdc_errcode;
+ if (has_field) {
+ msg->msg[8] = hec_field >> 8;
+ msg->msg[9] = hec_field & 0xff;
+ }
+}
+
+static inline void cec_ops_cdc_hec_report_state(const struct cec_msg *msg,
+ __u16 *phys_addr,
+ __u16 *target_phys_addr,
+ __u8 *hec_func_state,
+ __u8 *host_func_state,
+ __u8 *enc_func_state,
+ __u8 *cdc_errcode,
+ __u8 *has_field,
+ __u16 *hec_field)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+ *target_phys_addr = (msg->msg[5] << 8) | msg->msg[6];
+ *hec_func_state = msg->msg[7] >> 6;
+ *host_func_state = (msg->msg[7] >> 4) & 3;
+ *enc_func_state = (msg->msg[7] >> 4) & 3;
+ *cdc_errcode = msg->msg[7] & 3;
+ *has_field = msg->len >= 10;
+ *hec_field = *has_field ? ((msg->msg[8] << 8) | msg->msg[9]) : 0;
+}
+
+static inline void cec_msg_cdc_hec_set_state(struct cec_msg *msg,
+ __u16 phys_addr1,
+ __u16 phys_addr2,
+ __u8 hec_set_state,
+ __u16 phys_addr3,
+ __u16 phys_addr4,
+ __u16 phys_addr5)
+{
+ msg->len = 10;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_CDC_MESSAGE;
+ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
+ msg->msg[4] = CEC_MSG_CDC_HEC_INQUIRE_STATE;
+ msg->msg[5] = phys_addr1 >> 8;
+ msg->msg[6] = phys_addr1 & 0xff;
+ msg->msg[7] = phys_addr2 >> 8;
+ msg->msg[8] = phys_addr2 & 0xff;
+ msg->msg[9] = hec_set_state;
+ if (phys_addr3 != CEC_PHYS_ADDR_INVALID) {
+ msg->msg[msg->len++] = phys_addr3 >> 8;
+ msg->msg[msg->len++] = phys_addr3 & 0xff;
+ if (phys_addr4 != CEC_PHYS_ADDR_INVALID) {
+ msg->msg[msg->len++] = phys_addr4 >> 8;
+ msg->msg[msg->len++] = phys_addr4 & 0xff;
+ if (phys_addr5 != CEC_PHYS_ADDR_INVALID) {
+ msg->msg[msg->len++] = phys_addr5 >> 8;
+ msg->msg[msg->len++] = phys_addr5 & 0xff;
+ }
+ }
+ }
+}
+
+static inline void cec_ops_cdc_hec_set_state(const struct cec_msg *msg,
+ __u16 *phys_addr,
+ __u16 *phys_addr1,
+ __u16 *phys_addr2,
+ __u8 *hec_set_state,
+ __u16 *phys_addr3,
+ __u16 *phys_addr4,
+ __u16 *phys_addr5)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+ *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];
+ *phys_addr2 = (msg->msg[7] << 8) | msg->msg[8];
+ *hec_set_state = msg->msg[9];
+ *phys_addr3 = *phys_addr4 = *phys_addr5 = CEC_PHYS_ADDR_INVALID;
+ if (msg->len >= 12)
+ *phys_addr3 = (msg->msg[10] << 8) | msg->msg[11];
+ if (msg->len >= 14)
+ *phys_addr4 = (msg->msg[12] << 8) | msg->msg[13];
+ if (msg->len >= 16)
+ *phys_addr5 = (msg->msg[14] << 8) | msg->msg[15];
+}
+
+static inline void cec_msg_cdc_hec_set_state_adjacent(struct cec_msg *msg,
+ __u16 phys_addr1,
+ __u8 hec_set_state)
+{
+ msg->len = 8;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_CDC_MESSAGE;
+ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
+ msg->msg[4] = CEC_MSG_CDC_HEC_SET_STATE_ADJACENT;
+ msg->msg[5] = phys_addr1 >> 8;
+ msg->msg[6] = phys_addr1 & 0xff;
+ msg->msg[7] = hec_set_state;
+}
+
+static inline void cec_ops_cdc_hec_set_state_adjacent(const struct cec_msg *msg,
+ __u16 *phys_addr,
+ __u16 *phys_addr1,
+ __u8 *hec_set_state)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+ *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];
+ *hec_set_state = msg->msg[7];
+}
+
+static inline void cec_msg_cdc_hec_request_deactivation(struct cec_msg *msg,
+ __u16 phys_addr1,
+ __u16 phys_addr2,
+ __u16 phys_addr3)
+{
+ msg->len = 11;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_CDC_MESSAGE;
+ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
+ msg->msg[4] = CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION;
+ msg->msg[5] = phys_addr1 >> 8;
+ msg->msg[6] = phys_addr1 & 0xff;
+ msg->msg[7] = phys_addr2 >> 8;
+ msg->msg[8] = phys_addr2 & 0xff;
+ msg->msg[9] = phys_addr3 >> 8;
+ msg->msg[10] = phys_addr3 & 0xff;
+}
+
+static inline void cec_ops_cdc_hec_request_deactivation(const struct cec_msg *msg,
+ __u16 *phys_addr,
+ __u16 *phys_addr1,
+ __u16 *phys_addr2,
+ __u16 *phys_addr3)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+ *phys_addr1 = (msg->msg[5] << 8) | msg->msg[6];
+ *phys_addr2 = (msg->msg[7] << 8) | msg->msg[8];
+ *phys_addr3 = (msg->msg[9] << 8) | msg->msg[10];
+}
+
+static inline void cec_msg_cdc_hec_notify_alive(struct cec_msg *msg)
+{
+ msg->len = 5;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_CDC_MESSAGE;
+ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
+ msg->msg[4] = CEC_MSG_CDC_HEC_NOTIFY_ALIVE;
+}
+
+static inline void cec_ops_cdc_hec_notify_alive(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+static inline void cec_msg_cdc_hec_discover(struct cec_msg *msg)
+{
+ msg->len = 5;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_CDC_MESSAGE;
+ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
+ msg->msg[4] = CEC_MSG_CDC_HEC_DISCOVER;
+}
+
+static inline void cec_ops_cdc_hec_discover(const struct cec_msg *msg,
+ __u16 *phys_addr)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+}
+
+static inline void cec_msg_cdc_hpd_set_state(struct cec_msg *msg,
+ __u8 input_port,
+ __u8 hpd_state)
+{
+ msg->len = 6;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_CDC_MESSAGE;
+ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
+ msg->msg[4] = CEC_MSG_CDC_HPD_SET_STATE;
+ msg->msg[5] = (input_port << 4) | hpd_state;
+}
+
+static inline void cec_ops_cdc_hpd_set_state(const struct cec_msg *msg,
+ __u16 *phys_addr,
+ __u8 *input_port,
+ __u8 *hpd_state)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+ *input_port = msg->msg[5] >> 4;
+ *hpd_state = msg->msg[5] & 0xf;
+}
+
+static inline void cec_msg_cdc_hpd_report_state(struct cec_msg *msg,
+ __u8 hpd_state,
+ __u8 hpd_error)
+{
+ msg->len = 6;
+ msg->msg[0] |= 0xf; /* broadcast */
+ msg->msg[1] = CEC_MSG_CDC_MESSAGE;
+ /* msg[2] and msg[3] (phys_addr) are filled in by the CEC framework */
+ msg->msg[4] = CEC_MSG_CDC_HPD_REPORT_STATE;
+ msg->msg[5] = (hpd_state << 4) | hpd_error;
+}
+
+static inline void cec_ops_cdc_hpd_report_state(const struct cec_msg *msg,
+ __u16 *phys_addr,
+ __u8 *hpd_state,
+ __u8 *hpd_error)
+{
+ *phys_addr = (msg->msg[2] << 8) | msg->msg[3];
+ *hpd_state = msg->msg[5] >> 4;
+ *hpd_error = msg->msg[5] & 0xf;
+}
+
+#endif
diff --git a/include/linux/cec.h b/include/linux/cec.h
new file mode 100644
index 000000000000..b3e22893a002
--- /dev/null
+++ b/include/linux/cec.h
@@ -0,0 +1,1011 @@
+/*
+ * cec - HDMI Consumer Electronics Control public header
+ *
+ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * Alternatively you can redistribute this file under the terms of the
+ * BSD license as stated below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The names of its contributors may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * Note: this framework is still in staging and it is likely the API
+ * will change before it goes out of staging.
+ *
+ * Once it is moved out of staging this header will move to uapi.
+ */
+#ifndef _CEC_UAPI_H
+#define _CEC_UAPI_H
+
+#include <linux/types.h>
+
+#define CEC_MAX_MSG_SIZE 16
+
+/**
+ * struct cec_msg - CEC message structure.
+ * @tx_ts: Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the
+ * driver when the message transmission has finished.
+ * @rx_ts: Timestamp in nanoseconds using CLOCK_MONOTONIC. Set by the
+ * driver when the message was received.
+ * @len: Length in bytes of the message.
+ * @timeout: The timeout (in ms) that is used to timeout CEC_RECEIVE.
+ * Set to 0 if you want to wait forever. This timeout can also be
+ * used with CEC_TRANSMIT as the timeout for waiting for a reply.
+ * If 0, then it will use a 1 second timeout instead of waiting
+ * forever as is done with CEC_RECEIVE.
+ * @sequence: The framework assigns a sequence number to messages that are
+ * sent. This can be used to track replies to previously sent
+ * messages.
+ * @flags: Set to 0.
+ * @msg: The message payload.
+ * @reply: This field is ignored with CEC_RECEIVE and is only used by
+ * CEC_TRANSMIT. If non-zero, then wait for a reply with this
+ * opcode. Set to CEC_MSG_FEATURE_ABORT if you want to wait for
+ * a possible ABORT reply. If there was an error when sending the
+ * msg or FeatureAbort was returned, then reply is set to 0.
+ * If reply is non-zero upon return, then len/msg are set to
+ * the received message.
+ * If reply is zero upon return and status has the
+ * CEC_TX_STATUS_FEATURE_ABORT bit set, then len/msg are set to
+ * the received feature abort message.
+ * If reply is zero upon return and status has the
+ * CEC_TX_STATUS_MAX_RETRIES bit set, then no reply was seen at
+ * all. If reply is non-zero for CEC_TRANSMIT and the message is a
+ * broadcast, then -EINVAL is returned.
+ * if reply is non-zero, then timeout is set to 1000 (the required
+ * maximum response time).
+ * @rx_status: The message receive status bits. Set by the driver.
+ * @tx_status: The message transmit status bits. Set by the driver.
+ * @tx_arb_lost_cnt: The number of 'Arbitration Lost' events. Set by the driver.
+ * @tx_nack_cnt: The number of 'Not Acknowledged' events. Set by the driver.
+ * @tx_low_drive_cnt: The number of 'Low Drive Detected' events. Set by the
+ * driver.
+ * @tx_error_cnt: The number of 'Error' events. Set by the driver.
+ */
+struct cec_msg {
+ __u64 tx_ts;
+ __u64 rx_ts;
+ __u32 len;
+ __u32 timeout;
+ __u32 sequence;
+ __u32 flags;
+ __u8 msg[CEC_MAX_MSG_SIZE];
+ __u8 reply;
+ __u8 rx_status;
+ __u8 tx_status;
+ __u8 tx_arb_lost_cnt;
+ __u8 tx_nack_cnt;
+ __u8 tx_low_drive_cnt;
+ __u8 tx_error_cnt;
+};
+
+/**
+ * cec_msg_initiator - return the initiator's logical address.
+ * @msg: the message structure
+ */
+static inline __u8 cec_msg_initiator(const struct cec_msg *msg)
+{
+ return msg->msg[0] >> 4;
+}
+
+/**
+ * cec_msg_destination - return the destination's logical address.
+ * @msg: the message structure
+ */
+static inline __u8 cec_msg_destination(const struct cec_msg *msg)
+{
+ return msg->msg[0] & 0xf;
+}
+
+/**
+ * cec_msg_opcode - return the opcode of the message, -1 for poll
+ * @msg: the message structure
+ */
+static inline int cec_msg_opcode(const struct cec_msg *msg)
+{
+ return msg->len > 1 ? msg->msg[1] : -1;
+}
+
+/**
+ * cec_msg_is_broadcast - return true if this is a broadcast message.
+ * @msg: the message structure
+ */
+static inline bool cec_msg_is_broadcast(const struct cec_msg *msg)
+{
+ return (msg->msg[0] & 0xf) == 0xf;
+}
+
+/**
+ * cec_msg_init - initialize the message structure.
+ * @msg: the message structure
+ * @initiator: the logical address of the initiator
+ * @destination:the logical address of the destination (0xf for broadcast)
+ *
+ * The whole structure is zeroed, the len field is set to 1 (i.e. a poll
+ * message) and the initiator and destination are filled in.
+ */
+static inline void cec_msg_init(struct cec_msg *msg,
+ __u8 initiator, __u8 destination)
+{
+ memset(msg, 0, sizeof(*msg));
+ msg->msg[0] = (initiator << 4) | destination;
+ msg->len = 1;
+}
+
+/**
+ * cec_msg_set_reply_to - fill in destination/initiator in a reply message.
+ * @msg: the message structure for the reply
+ * @orig: the original message structure
+ *
+ * Set the msg destination to the orig initiator and the msg initiator to the
+ * orig destination. Note that msg and orig may be the same pointer, in which
+ * case the change is done in place.
+ */
+static inline void cec_msg_set_reply_to(struct cec_msg *msg,
+ struct cec_msg *orig)
+{
+ /* The destination becomes the initiator and vice versa */
+ msg->msg[0] = (cec_msg_destination(orig) << 4) |
+ cec_msg_initiator(orig);
+ msg->reply = msg->timeout = 0;
+}
+
+/* cec status field */
+#define CEC_TX_STATUS_OK (1 << 0)
+#define CEC_TX_STATUS_ARB_LOST (1 << 1)
+#define CEC_TX_STATUS_NACK (1 << 2)
+#define CEC_TX_STATUS_LOW_DRIVE (1 << 3)
+#define CEC_TX_STATUS_ERROR (1 << 4)
+#define CEC_TX_STATUS_MAX_RETRIES (1 << 5)
+
+#define CEC_RX_STATUS_OK (1 << 0)
+#define CEC_RX_STATUS_TIMEOUT (1 << 1)
+#define CEC_RX_STATUS_FEATURE_ABORT (1 << 2)
+
+static inline bool cec_msg_status_is_ok(const struct cec_msg *msg)
+{
+ if (msg->tx_status && !(msg->tx_status & CEC_TX_STATUS_OK))
+ return false;
+ if (msg->rx_status && !(msg->rx_status & CEC_RX_STATUS_OK))
+ return false;
+ if (!msg->tx_status && !msg->rx_status)
+ return false;
+ return !(msg->rx_status & CEC_RX_STATUS_FEATURE_ABORT);
+}
+
+#define CEC_LOG_ADDR_INVALID 0xff
+#define CEC_PHYS_ADDR_INVALID 0xffff
+
+/*
+ * The maximum number of logical addresses one device can be assigned to.
+ * The CEC 2.0 spec allows for only 2 logical addresses at the moment. The
+ * Analog Devices CEC hardware supports 3. So let's go wild and go for 4.
+ */
+#define CEC_MAX_LOG_ADDRS 4
+
+/* The logical addresses defined by CEC 2.0 */
+#define CEC_LOG_ADDR_TV 0
+#define CEC_LOG_ADDR_RECORD_1 1
+#define CEC_LOG_ADDR_RECORD_2 2
+#define CEC_LOG_ADDR_TUNER_1 3
+#define CEC_LOG_ADDR_PLAYBACK_1 4
+#define CEC_LOG_ADDR_AUDIOSYSTEM 5
+#define CEC_LOG_ADDR_TUNER_2 6
+#define CEC_LOG_ADDR_TUNER_3 7
+#define CEC_LOG_ADDR_PLAYBACK_2 8
+#define CEC_LOG_ADDR_RECORD_3 9
+#define CEC_LOG_ADDR_TUNER_4 10
+#define CEC_LOG_ADDR_PLAYBACK_3 11
+#define CEC_LOG_ADDR_BACKUP_1 12
+#define CEC_LOG_ADDR_BACKUP_2 13
+#define CEC_LOG_ADDR_SPECIFIC 14
+#define CEC_LOG_ADDR_UNREGISTERED 15 /* as initiator address */
+#define CEC_LOG_ADDR_BROADCAST 15 /* ad destination address */
+
+/* The logical address types that the CEC device wants to claim */
+#define CEC_LOG_ADDR_TYPE_TV 0
+#define CEC_LOG_ADDR_TYPE_RECORD 1
+#define CEC_LOG_ADDR_TYPE_TUNER 2
+#define CEC_LOG_ADDR_TYPE_PLAYBACK 3
+#define CEC_LOG_ADDR_TYPE_AUDIOSYSTEM 4
+#define CEC_LOG_ADDR_TYPE_SPECIFIC 5
+#define CEC_LOG_ADDR_TYPE_UNREGISTERED 6
+/*
+ * Switches should use UNREGISTERED.
+ * Processors should use SPECIFIC.
+ */
+
+#define CEC_LOG_ADDR_MASK_TV (1 << CEC_LOG_ADDR_TV)
+#define CEC_LOG_ADDR_MASK_RECORD ((1 << CEC_LOG_ADDR_RECORD_1) | \
+ (1 << CEC_LOG_ADDR_RECORD_2) | \
+ (1 << CEC_LOG_ADDR_RECORD_3))
+#define CEC_LOG_ADDR_MASK_TUNER ((1 << CEC_LOG_ADDR_TUNER_1) | \
+ (1 << CEC_LOG_ADDR_TUNER_2) | \
+ (1 << CEC_LOG_ADDR_TUNER_3) | \
+ (1 << CEC_LOG_ADDR_TUNER_4))
+#define CEC_LOG_ADDR_MASK_PLAYBACK ((1 << CEC_LOG_ADDR_PLAYBACK_1) | \
+ (1 << CEC_LOG_ADDR_PLAYBACK_2) | \
+ (1 << CEC_LOG_ADDR_PLAYBACK_3))
+#define CEC_LOG_ADDR_MASK_AUDIOSYSTEM (1 << CEC_LOG_ADDR_AUDIOSYSTEM)
+#define CEC_LOG_ADDR_MASK_BACKUP ((1 << CEC_LOG_ADDR_BACKUP_1) | \
+ (1 << CEC_LOG_ADDR_BACKUP_2))
+#define CEC_LOG_ADDR_MASK_SPECIFIC (1 << CEC_LOG_ADDR_SPECIFIC)
+#define CEC_LOG_ADDR_MASK_UNREGISTERED (1 << CEC_LOG_ADDR_UNREGISTERED)
+
+static inline bool cec_has_tv(__u16 log_addr_mask)
+{
+ return log_addr_mask & CEC_LOG_ADDR_MASK_TV;
+}
+
+static inline bool cec_has_record(__u16 log_addr_mask)
+{
+ return log_addr_mask & CEC_LOG_ADDR_MASK_RECORD;
+}
+
+static inline bool cec_has_tuner(__u16 log_addr_mask)
+{
+ return log_addr_mask & CEC_LOG_ADDR_MASK_TUNER;
+}
+
+static inline bool cec_has_playback(__u16 log_addr_mask)
+{
+ return log_addr_mask & CEC_LOG_ADDR_MASK_PLAYBACK;
+}
+
+static inline bool cec_has_audiosystem(__u16 log_addr_mask)
+{
+ return log_addr_mask & CEC_LOG_ADDR_MASK_AUDIOSYSTEM;
+}
+
+static inline bool cec_has_backup(__u16 log_addr_mask)
+{
+ return log_addr_mask & CEC_LOG_ADDR_MASK_BACKUP;
+}
+
+static inline bool cec_has_specific(__u16 log_addr_mask)
+{
+ return log_addr_mask & CEC_LOG_ADDR_MASK_SPECIFIC;
+}
+
+static inline bool cec_is_unregistered(__u16 log_addr_mask)
+{
+ return log_addr_mask & CEC_LOG_ADDR_MASK_UNREGISTERED;
+}
+
+static inline bool cec_is_unconfigured(__u16 log_addr_mask)
+{
+ return log_addr_mask == 0;
+}
+
+/*
+ * Use this if there is no vendor ID (CEC_G_VENDOR_ID) or if the vendor ID
+ * should be disabled (CEC_S_VENDOR_ID)
+ */
+#define CEC_VENDOR_ID_NONE 0xffffffff
+
+/* The message handling modes */
+/* Modes for initiator */
+#define CEC_MODE_NO_INITIATOR (0x0 << 0)
+#define CEC_MODE_INITIATOR (0x1 << 0)
+#define CEC_MODE_EXCL_INITIATOR (0x2 << 0)
+#define CEC_MODE_INITIATOR_MSK 0x0f
+
+/* Modes for follower */
+#define CEC_MODE_NO_FOLLOWER (0x0 << 4)
+#define CEC_MODE_FOLLOWER (0x1 << 4)
+#define CEC_MODE_EXCL_FOLLOWER (0x2 << 4)
+#define CEC_MODE_EXCL_FOLLOWER_PASSTHRU (0x3 << 4)
+#define CEC_MODE_MONITOR (0xe << 4)
+#define CEC_MODE_MONITOR_ALL (0xf << 4)
+#define CEC_MODE_FOLLOWER_MSK 0xf0
+
+/* Userspace has to configure the physical address */
+#define CEC_CAP_PHYS_ADDR (1 << 0)
+/* Userspace has to configure the logical addresses */
+#define CEC_CAP_LOG_ADDRS (1 << 1)
+/* Userspace can transmit messages (and thus become follower as well) */
+#define CEC_CAP_TRANSMIT (1 << 2)
+/*
+ * Passthrough all messages instead of processing them.
+ */
+#define CEC_CAP_PASSTHROUGH (1 << 3)
+/* Supports remote control */
+#define CEC_CAP_RC (1 << 4)
+/* Hardware can monitor all messages, not just directed and broadcast. */
+#define CEC_CAP_MONITOR_ALL (1 << 5)
+
+/**
+ * struct cec_caps - CEC capabilities structure.
+ * @driver: name of the CEC device driver.
+ * @name: name of the CEC device. @driver + @name must be unique.
+ * @available_log_addrs: number of available logical addresses.
+ * @capabilities: capabilities of the CEC adapter.
+ * @version: version of the CEC adapter framework.
+ */
+struct cec_caps {
+ char driver[32];
+ char name[32];
+ __u32 available_log_addrs;
+ __u32 capabilities;
+ __u32 version;
+};
+
+/**
+ * struct cec_log_addrs - CEC logical addresses structure.
+ * @log_addr: the claimed logical addresses. Set by the driver.
+ * @log_addr_mask: current logical address mask. Set by the driver.
+ * @cec_version: the CEC version that the adapter should implement. Set by the
+ * caller.
+ * @num_log_addrs: how many logical addresses should be claimed. Set by the
+ * caller.
+ * @vendor_id: the vendor ID of the device. Set by the caller.
+ * @flags: set to 0.
+ * @osd_name: the OSD name of the device. Set by the caller.
+ * @primary_device_type: the primary device type for each logical address.
+ * Set by the caller.
+ * @log_addr_type: the logical address types. Set by the caller.
+ * @all_device_types: CEC 2.0: all device types represented by the logical
+ * address. Set by the caller.
+ * @features: CEC 2.0: The logical address features. Set by the caller.
+ */
+struct cec_log_addrs {
+ __u8 log_addr[CEC_MAX_LOG_ADDRS];
+ __u16 log_addr_mask;
+ __u8 cec_version;
+ __u8 num_log_addrs;
+ __u32 vendor_id;
+ __u32 flags;
+ char osd_name[15];
+ __u8 primary_device_type[CEC_MAX_LOG_ADDRS];
+ __u8 log_addr_type[CEC_MAX_LOG_ADDRS];
+
+ /* CEC 2.0 */
+ __u8 all_device_types[CEC_MAX_LOG_ADDRS];
+ __u8 features[CEC_MAX_LOG_ADDRS][12];
+};
+
+/* Events */
+
+/* Event that occurs when the adapter state changes */
+#define CEC_EVENT_STATE_CHANGE 1
+/*
+ * This event is sent when messages are lost because the application
+ * didn't empty the message queue in time
+ */
+#define CEC_EVENT_LOST_MSGS 2
+
+#define CEC_EVENT_FL_INITIAL_STATE (1 << 0)
+
+/**
+ * struct cec_event_state_change - used when the CEC adapter changes state.
+ * @phys_addr: the current physical address
+ * @log_addr_mask: the current logical address mask
+ */
+struct cec_event_state_change {
+ __u16 phys_addr;
+ __u16 log_addr_mask;
+};
+
+/**
+ * struct cec_event_lost_msgs - tells you how many messages were lost due.
+ * @lost_msgs: how many messages were lost.
+ */
+struct cec_event_lost_msgs {
+ __u32 lost_msgs;
+};
+
+/**
+ * struct cec_event - CEC event structure
+ * @ts: the timestamp of when the event was sent.
+ * @event: the event.
+ * array.
+ * @state_change: the event payload for CEC_EVENT_STATE_CHANGE.
+ * @lost_msgs: the event payload for CEC_EVENT_LOST_MSGS.
+ * @raw: array to pad the union.
+ */
+struct cec_event {
+ __u64 ts;
+ __u32 event;
+ __u32 flags;
+ union {
+ struct cec_event_state_change state_change;
+ struct cec_event_lost_msgs lost_msgs;
+ __u32 raw[16];
+ };
+};
+
+/* ioctls */
+
+/* Adapter capabilities */
+#define CEC_ADAP_G_CAPS _IOWR('a', 0, struct cec_caps)
+
+/*
+ * phys_addr is either 0 (if this is the CEC root device)
+ * or a valid physical address obtained from the sink's EDID
+ * as read by this CEC device (if this is a source device)
+ * or a physical address obtained and modified from a sink
+ * EDID and used for a sink CEC device.
+ * If nothing is connected, then phys_addr is 0xffff.
+ * See HDMI 1.4b, section 8.7 (Physical Address).
+ *
+ * The CEC_ADAP_S_PHYS_ADDR ioctl may not be available if that is handled
+ * internally.
+ */
+#define CEC_ADAP_G_PHYS_ADDR _IOR('a', 1, __u16)
+#define CEC_ADAP_S_PHYS_ADDR _IOW('a', 2, __u16)
+
+/*
+ * Configure the CEC adapter. It sets the device type and which
+ * logical types it will try to claim. It will return which
+ * logical addresses it could actually claim.
+ * An error is returned if the adapter is disabled or if there
+ * is no physical address assigned.
+ */
+
+#define CEC_ADAP_G_LOG_ADDRS _IOR('a', 3, struct cec_log_addrs)
+#define CEC_ADAP_S_LOG_ADDRS _IOWR('a', 4, struct cec_log_addrs)
+
+/* Transmit/receive a CEC command */
+#define CEC_TRANSMIT _IOWR('a', 5, struct cec_msg)
+#define CEC_RECEIVE _IOWR('a', 6, struct cec_msg)
+
+/* Dequeue CEC events */
+#define CEC_DQEVENT _IOWR('a', 7, struct cec_event)
+
+/*
+ * Get and set the message handling mode for this filehandle.
+ */
+#define CEC_G_MODE _IOR('a', 8, __u32)
+#define CEC_S_MODE _IOW('a', 9, __u32)
+
+/*
+ * The remainder of this header defines all CEC messages and operands.
+ * The format matters since it the cec-ctl utility parses it to generate
+ * code for implementing all these messages.
+ *
+ * Comments ending with 'Feature' group messages for each feature.
+ * If messages are part of multiple features, then the "Has also"
+ * comment is used to list the previously defined messages that are
+ * supported by the feature.
+ *
+ * Before operands are defined a comment is added that gives the
+ * name of the operand and in brackets the variable name of the
+ * corresponding argument in the cec-funcs.h function.
+ */
+
+/* Messages */
+
+/* One Touch Play Feature */
+#define CEC_MSG_ACTIVE_SOURCE 0x82
+#define CEC_MSG_IMAGE_VIEW_ON 0x04
+#define CEC_MSG_TEXT_VIEW_ON 0x0d
+
+
+/* Routing Control Feature */
+
+/*
+ * Has also:
+ * CEC_MSG_ACTIVE_SOURCE
+ */
+
+#define CEC_MSG_INACTIVE_SOURCE 0x9d
+#define CEC_MSG_REQUEST_ACTIVE_SOURCE 0x85
+#define CEC_MSG_ROUTING_CHANGE 0x80
+#define CEC_MSG_ROUTING_INFORMATION 0x81
+#define CEC_MSG_SET_STREAM_PATH 0x86
+
+
+/* Standby Feature */
+#define CEC_MSG_STANDBY 0x36
+
+
+/* One Touch Record Feature */
+#define CEC_MSG_RECORD_OFF 0x0b
+#define CEC_MSG_RECORD_ON 0x09
+/* Record Source Type Operand (rec_src_type) */
+#define CEC_OP_RECORD_SRC_OWN 1
+#define CEC_OP_RECORD_SRC_DIGITAL 2
+#define CEC_OP_RECORD_SRC_ANALOG 3
+#define CEC_OP_RECORD_SRC_EXT_PLUG 4
+#define CEC_OP_RECORD_SRC_EXT_PHYS_ADDR 5
+/* Service Identification Method Operand (service_id_method) */
+#define CEC_OP_SERVICE_ID_METHOD_BY_DIG_ID 0
+#define CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL 1
+/* Digital Service Broadcast System Operand (dig_bcast_system) */
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_GEN 0x00
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN 0x01
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_GEN 0x02
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_BS 0x08
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_CS 0x09
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ARIB_T 0x0a
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE 0x10
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT 0x11
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T 0x12
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_C 0x18
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S 0x19
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_S2 0x1a
+#define CEC_OP_DIG_SERVICE_BCAST_SYSTEM_DVB_T 0x1b
+/* Analogue Broadcast Type Operand (ana_bcast_type) */
+#define CEC_OP_ANA_BCAST_TYPE_CABLE 0
+#define CEC_OP_ANA_BCAST_TYPE_SATELLITE 1
+#define CEC_OP_ANA_BCAST_TYPE_TERRESTRIAL 2
+/* Broadcast System Operand (bcast_system) */
+#define CEC_OP_BCAST_SYSTEM_PAL_BG 0x00
+#define CEC_OP_BCAST_SYSTEM_SECAM_LQ 0x01 /* SECAM L' */
+#define CEC_OP_BCAST_SYSTEM_PAL_M 0x02
+#define CEC_OP_BCAST_SYSTEM_NTSC_M 0x03
+#define CEC_OP_BCAST_SYSTEM_PAL_I 0x04
+#define CEC_OP_BCAST_SYSTEM_SECAM_DK 0x05
+#define CEC_OP_BCAST_SYSTEM_SECAM_BG 0x06
+#define CEC_OP_BCAST_SYSTEM_SECAM_L 0x07
+#define CEC_OP_BCAST_SYSTEM_PAL_DK 0x08
+#define CEC_OP_BCAST_SYSTEM_OTHER 0x1f
+/* Channel Number Format Operand (channel_number_fmt) */
+#define CEC_OP_CHANNEL_NUMBER_FMT_1_PART 0x01
+#define CEC_OP_CHANNEL_NUMBER_FMT_2_PART 0x02
+
+#define CEC_MSG_RECORD_STATUS 0x0a
+/* Record Status Operand (rec_status) */
+#define CEC_OP_RECORD_STATUS_CUR_SRC 0x01
+#define CEC_OP_RECORD_STATUS_DIG_SERVICE 0x02
+#define CEC_OP_RECORD_STATUS_ANA_SERVICE 0x03
+#define CEC_OP_RECORD_STATUS_EXT_INPUT 0x04
+#define CEC_OP_RECORD_STATUS_NO_DIG_SERVICE 0x05
+#define CEC_OP_RECORD_STATUS_NO_ANA_SERVICE 0x06
+#define CEC_OP_RECORD_STATUS_NO_SERVICE 0x07
+#define CEC_OP_RECORD_STATUS_INVALID_EXT_PLUG 0x09
+#define CEC_OP_RECORD_STATUS_INVALID_EXT_PHYS_ADDR 0x0a
+#define CEC_OP_RECORD_STATUS_UNSUP_CA 0x0b
+#define CEC_OP_RECORD_STATUS_NO_CA_ENTITLEMENTS 0x0c
+#define CEC_OP_RECORD_STATUS_CANT_COPY_SRC 0x0d
+#define CEC_OP_RECORD_STATUS_NO_MORE_COPIES 0x0e
+#define CEC_OP_RECORD_STATUS_NO_MEDIA 0x10
+#define CEC_OP_RECORD_STATUS_PLAYING 0x11
+#define CEC_OP_RECORD_STATUS_ALREADY_RECORDING 0x12
+#define CEC_OP_RECORD_STATUS_MEDIA_PROT 0x13
+#define CEC_OP_RECORD_STATUS_NO_SIGNAL 0x14
+#define CEC_OP_RECORD_STATUS_MEDIA_PROBLEM 0x15
+#define CEC_OP_RECORD_STATUS_NO_SPACE 0x16
+#define CEC_OP_RECORD_STATUS_PARENTAL_LOCK 0x17
+#define CEC_OP_RECORD_STATUS_TERMINATED_OK 0x1a
+#define CEC_OP_RECORD_STATUS_ALREADY_TERM 0x1b
+#define CEC_OP_RECORD_STATUS_OTHER 0x1f
+
+#define CEC_MSG_RECORD_TV_SCREEN 0x0f
+
+
+/* Timer Programming Feature */
+#define CEC_MSG_CLEAR_ANALOGUE_TIMER 0x33
+/* Recording Sequence Operand (recording_seq) */
+#define CEC_OP_REC_SEQ_SUNDAY 0x01
+#define CEC_OP_REC_SEQ_MONDAY 0x02
+#define CEC_OP_REC_SEQ_TUESDAY 0x04
+#define CEC_OP_REC_SEQ_WEDNESDAY 0x08
+#define CEC_OP_REC_SEQ_THURSDAY 0x10
+#define CEC_OP_REC_SEQ_FRIDAY 0x20
+#define CEC_OP_REC_SEQ_SATERDAY 0x40
+#define CEC_OP_REC_SEQ_ONCE_ONLY 0x00
+
+#define CEC_MSG_CLEAR_DIGITAL_TIMER 0x99
+
+#define CEC_MSG_CLEAR_EXT_TIMER 0xa1
+/* External Source Specifier Operand (ext_src_spec) */
+#define CEC_OP_EXT_SRC_PLUG 0x04
+#define CEC_OP_EXT_SRC_PHYS_ADDR 0x05
+
+#define CEC_MSG_SET_ANALOGUE_TIMER 0x34
+#define CEC_MSG_SET_DIGITAL_TIMER 0x97
+#define CEC_MSG_SET_EXT_TIMER 0xa2
+
+#define CEC_MSG_SET_TIMER_PROGRAM_TITLE 0x67
+#define CEC_MSG_TIMER_CLEARED_STATUS 0x43
+/* Timer Cleared Status Data Operand (timer_cleared_status) */
+#define CEC_OP_TIMER_CLR_STAT_RECORDING 0x00
+#define CEC_OP_TIMER_CLR_STAT_NO_MATCHING 0x01
+#define CEC_OP_TIMER_CLR_STAT_NO_INFO 0x02
+#define CEC_OP_TIMER_CLR_STAT_CLEARED 0x80
+
+#define CEC_MSG_TIMER_STATUS 0x35
+/* Timer Overlap Warning Operand (timer_overlap_warning) */
+#define CEC_OP_TIMER_OVERLAP_WARNING_NO_OVERLAP 0
+#define CEC_OP_TIMER_OVERLAP_WARNING_OVERLAP 1
+/* Media Info Operand (media_info) */
+#define CEC_OP_MEDIA_INFO_UNPROT_MEDIA 0
+#define CEC_OP_MEDIA_INFO_PROT_MEDIA 1
+#define CEC_OP_MEDIA_INFO_NO_MEDIA 2
+/* Programmed Indicator Operand (prog_indicator) */
+#define CEC_OP_PROG_IND_NOT_PROGRAMMED 0
+#define CEC_OP_PROG_IND_PROGRAMMED 1
+/* Programmed Info Operand (prog_info) */
+#define CEC_OP_PROG_INFO_ENOUGH_SPACE 0x08
+#define CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE 0x09
+#define CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE 0x0b
+#define CEC_OP_PROG_INFO_NONE_AVAILABLE 0x0a
+/* Not Programmed Error Info Operand (prog_error) */
+#define CEC_OP_PROG_ERROR_NO_FREE_TIMER 0x01
+#define CEC_OP_PROG_ERROR_DATE_OUT_OF_RANGE 0x02
+#define CEC_OP_PROG_ERROR_REC_SEQ_ERROR 0x03
+#define CEC_OP_PROG_ERROR_INV_EXT_PLUG 0x04
+#define CEC_OP_PROG_ERROR_INV_EXT_PHYS_ADDR 0x05
+#define CEC_OP_PROG_ERROR_CA_UNSUPP 0x06
+#define CEC_OP_PROG_ERROR_INSUF_CA_ENTITLEMENTS 0x07
+#define CEC_OP_PROG_ERROR_RESOLUTION_UNSUPP 0x08
+#define CEC_OP_PROG_ERROR_PARENTAL_LOCK 0x09
+#define CEC_OP_PROG_ERROR_CLOCK_FAILURE 0x0a
+#define CEC_OP_PROG_ERROR_DUPLICATE 0x0e
+
+
+/* System Information Feature */
+#define CEC_MSG_CEC_VERSION 0x9e
+/* CEC Version Operand (cec_version) */
+#define CEC_OP_CEC_VERSION_1_3A 4
+#define CEC_OP_CEC_VERSION_1_4 5
+#define CEC_OP_CEC_VERSION_2_0 6
+
+#define CEC_MSG_GET_CEC_VERSION 0x9f
+#define CEC_MSG_GIVE_PHYSICAL_ADDR 0x83
+#define CEC_MSG_GET_MENU_LANGUAGE 0x91
+#define CEC_MSG_REPORT_PHYSICAL_ADDR 0x84
+/* Primary Device Type Operand (prim_devtype) */
+#define CEC_OP_PRIM_DEVTYPE_TV 0
+#define CEC_OP_PRIM_DEVTYPE_RECORD 1
+#define CEC_OP_PRIM_DEVTYPE_TUNER 3
+#define CEC_OP_PRIM_DEVTYPE_PLAYBACK 4
+#define CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM 5
+#define CEC_OP_PRIM_DEVTYPE_SWITCH 6
+#define CEC_OP_PRIM_DEVTYPE_PROCESSOR 7
+
+#define CEC_MSG_SET_MENU_LANGUAGE 0x32
+#define CEC_MSG_REPORT_FEATURES 0xa6 /* HDMI 2.0 */
+/* All Device Types Operand (all_device_types) */
+#define CEC_OP_ALL_DEVTYPE_TV 0x80
+#define CEC_OP_ALL_DEVTYPE_RECORD 0x40
+#define CEC_OP_ALL_DEVTYPE_TUNER 0x20
+#define CEC_OP_ALL_DEVTYPE_PLAYBACK 0x10
+#define CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM 0x08
+#define CEC_OP_ALL_DEVTYPE_SWITCH 0x04
+/*
+ * And if you wondering what happened to PROCESSOR devices: those should
+ * be mapped to a SWITCH.
+ */
+
+/* Valid for RC Profile and Device Feature operands */
+#define CEC_OP_FEAT_EXT 0x80 /* Extension bit */
+/* RC Profile Operand (rc_profile) */
+#define CEC_OP_FEAT_RC_TV_PROFILE_NONE 0x00
+#define CEC_OP_FEAT_RC_TV_PROFILE_1 0x02
+#define CEC_OP_FEAT_RC_TV_PROFILE_2 0x06
+#define CEC_OP_FEAT_RC_TV_PROFILE_3 0x0a
+#define CEC_OP_FEAT_RC_TV_PROFILE_4 0x0e
+#define CEC_OP_FEAT_RC_SRC_HAS_DEV_ROOT_MENU 0x50
+#define CEC_OP_FEAT_RC_SRC_HAS_DEV_SETUP_MENU 0x48
+#define CEC_OP_FEAT_RC_SRC_HAS_CONTENTS_MENU 0x44
+#define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_TOP_MENU 0x42
+#define CEC_OP_FEAT_RC_SRC_HAS_MEDIA_CONTEXT_MENU 0x41
+/* Device Feature Operand (dev_features) */
+#define CEC_OP_FEAT_DEV_HAS_RECORD_TV_SCREEN 0x40
+#define CEC_OP_FEAT_DEV_HAS_SET_OSD_STRING 0x20
+#define CEC_OP_FEAT_DEV_HAS_DECK_CONTROL 0x10
+#define CEC_OP_FEAT_DEV_HAS_SET_AUDIO_RATE 0x08
+#define CEC_OP_FEAT_DEV_SINK_HAS_ARC_TX 0x04
+#define CEC_OP_FEAT_DEV_SOURCE_HAS_ARC_RX 0x02
+
+#define CEC_MSG_GIVE_FEATURES 0xa5 /* HDMI 2.0 */
+
+
+/* Deck Control Feature */
+#define CEC_MSG_DECK_CONTROL 0x42
+/* Deck Control Mode Operand (deck_control_mode) */
+#define CEC_OP_DECK_CTL_MODE_SKIP_FWD 1
+#define CEC_OP_DECK_CTL_MODE_SKIP_REV 2
+#define CEC_OP_DECK_CTL_MODE_STOP 3
+#define CEC_OP_DECK_CTL_MODE_EJECT 4
+
+#define CEC_MSG_DECK_STATUS 0x1b
+/* Deck Info Operand (deck_info) */
+#define CEC_OP_DECK_INFO_PLAY 0x11
+#define CEC_OP_DECK_INFO_RECORD 0x12
+#define CEC_OP_DECK_INFO_PLAY_REV 0x13
+#define CEC_OP_DECK_INFO_STILL 0x14
+#define CEC_OP_DECK_INFO_SLOW 0x15
+#define CEC_OP_DECK_INFO_SLOW_REV 0x16
+#define CEC_OP_DECK_INFO_FAST_FWD 0x17
+#define CEC_OP_DECK_INFO_FAST_REV 0x18
+#define CEC_OP_DECK_INFO_NO_MEDIA 0x19
+#define CEC_OP_DECK_INFO_STOP 0x1a
+#define CEC_OP_DECK_INFO_SKIP_FWD 0x1b
+#define CEC_OP_DECK_INFO_SKIP_REV 0x1c
+#define CEC_OP_DECK_INFO_INDEX_SEARCH_FWD 0x1d
+#define CEC_OP_DECK_INFO_INDEX_SEARCH_REV 0x1e
+#define CEC_OP_DECK_INFO_OTHER 0x1f
+
+#define CEC_MSG_GIVE_DECK_STATUS 0x1a
+/* Status Request Operand (status_req) */
+#define CEC_OP_STATUS_REQ_ON 1
+#define CEC_OP_STATUS_REQ_OFF 2
+#define CEC_OP_STATUS_REQ_ONCE 3
+
+#define CEC_MSG_PLAY 0x41
+/* Play Mode Operand (play_mode) */
+#define CEC_OP_PLAY_MODE_PLAY_FWD 0x24
+#define CEC_OP_PLAY_MODE_PLAY_REV 0x20
+#define CEC_OP_PLAY_MODE_PLAY_STILL 0x25
+#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MIN 0x05
+#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MED 0x06
+#define CEC_OP_PLAY_MODE_PLAY_FAST_FWD_MAX 0x07
+#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MIN 0x09
+#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MED 0x0a
+#define CEC_OP_PLAY_MODE_PLAY_FAST_REV_MAX 0x0b
+#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MIN 0x15
+#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MED 0x16
+#define CEC_OP_PLAY_MODE_PLAY_SLOW_FWD_MAX 0x17
+#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MIN 0x19
+#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MED 0x1a
+#define CEC_OP_PLAY_MODE_PLAY_SLOW_REV_MAX 0x1b
+
+
+/* Tuner Control Feature */
+#define CEC_MSG_GIVE_TUNER_DEVICE_STATUS 0x08
+#define CEC_MSG_SELECT_ANALOGUE_SERVICE 0x92
+#define CEC_MSG_SELECT_DIGITAL_SERVICE 0x93
+#define CEC_MSG_TUNER_DEVICE_STATUS 0x07
+/* Recording Flag Operand (rec_flag) */
+#define CEC_OP_REC_FLAG_USED 0
+#define CEC_OP_REC_FLAG_NOT_USED 1
+/* Tuner Display Info Operand (tuner_display_info) */
+#define CEC_OP_TUNER_DISPLAY_INFO_DIGITAL 0
+#define CEC_OP_TUNER_DISPLAY_INFO_NONE 1
+#define CEC_OP_TUNER_DISPLAY_INFO_ANALOGUE 2
+
+#define CEC_MSG_TUNER_STEP_DECREMENT 0x06
+#define CEC_MSG_TUNER_STEP_INCREMENT 0x05
+
+
+/* Vendor Specific Commands Feature */
+
+/*
+ * Has also:
+ * CEC_MSG_CEC_VERSION
+ * CEC_MSG_GET_CEC_VERSION
+ */
+#define CEC_MSG_DEVICE_VENDOR_ID 0x87
+#define CEC_MSG_GIVE_DEVICE_VENDOR_ID 0x8c
+#define CEC_MSG_VENDOR_COMMAND 0x89
+#define CEC_MSG_VENDOR_COMMAND_WITH_ID 0xa0
+#define CEC_MSG_VENDOR_REMOTE_BUTTON_DOWN 0x8a
+#define CEC_MSG_VENDOR_REMOTE_BUTTON_UP 0x8b
+
+
+/* OSD Display Feature */
+#define CEC_MSG_SET_OSD_STRING 0x64
+/* Display Control Operand (disp_ctl) */
+#define CEC_OP_DISP_CTL_DEFAULT 0x00
+#define CEC_OP_DISP_CTL_UNTIL_CLEARED 0x40
+#define CEC_OP_DISP_CTL_CLEAR 0x80
+
+
+/* Device OSD Transfer Feature */
+#define CEC_MSG_GIVE_OSD_NAME 0x46
+#define CEC_MSG_SET_OSD_NAME 0x47
+
+
+/* Device Menu Control Feature */
+#define CEC_MSG_MENU_REQUEST 0x8d
+/* Menu Request Type Operand (menu_req) */
+#define CEC_OP_MENU_REQUEST_ACTIVATE 0x00
+#define CEC_OP_MENU_REQUEST_DEACTIVATE 0x01
+#define CEC_OP_MENU_REQUEST_QUERY 0x02
+
+#define CEC_MSG_MENU_STATUS 0x8e
+/* Menu State Operand (menu_state) */
+#define CEC_OP_MENU_STATE_ACTIVATED 0x00
+#define CEC_OP_MENU_STATE_DEACTIVATED 0x01
+
+#define CEC_MSG_USER_CONTROL_PRESSED 0x44
+/* UI Broadcast Type Operand (ui_bcast_type) */
+#define CEC_OP_UI_BCAST_TYPE_TOGGLE_ALL 0x00
+#define CEC_OP_UI_BCAST_TYPE_TOGGLE_DIG_ANA 0x01
+#define CEC_OP_UI_BCAST_TYPE_ANALOGUE 0x10
+#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_T 0x20
+#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_CABLE 0x30
+#define CEC_OP_UI_BCAST_TYPE_ANALOGUE_SAT 0x40
+#define CEC_OP_UI_BCAST_TYPE_DIGITAL 0x50
+#define CEC_OP_UI_BCAST_TYPE_DIGITAL_T 0x60
+#define CEC_OP_UI_BCAST_TYPE_DIGITAL_CABLE 0x70
+#define CEC_OP_UI_BCAST_TYPE_DIGITAL_SAT 0x80
+#define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT 0x90
+#define CEC_OP_UI_BCAST_TYPE_DIGITAL_COM_SAT2 0x91
+#define CEC_OP_UI_BCAST_TYPE_IP 0xa0
+/* UI Sound Presentation Control Operand (ui_snd_pres_ctl) */
+#define CEC_OP_UI_SND_PRES_CTL_DUAL_MONO 0x10
+#define CEC_OP_UI_SND_PRES_CTL_KARAOKE 0x20
+#define CEC_OP_UI_SND_PRES_CTL_DOWNMIX 0x80
+#define CEC_OP_UI_SND_PRES_CTL_REVERB 0x90
+#define CEC_OP_UI_SND_PRES_CTL_EQUALIZER 0xa0
+#define CEC_OP_UI_SND_PRES_CTL_BASS_UP 0xb1
+#define CEC_OP_UI_SND_PRES_CTL_BASS_NEUTRAL 0xb2
+#define CEC_OP_UI_SND_PRES_CTL_BASS_DOWN 0xb3
+#define CEC_OP_UI_SND_PRES_CTL_TREBLE_UP 0xc1
+#define CEC_OP_UI_SND_PRES_CTL_TREBLE_NEUTRAL 0xc2
+#define CEC_OP_UI_SND_PRES_CTL_TREBLE_DOWN 0xc3
+
+#define CEC_MSG_USER_CONTROL_RELEASED 0x45
+
+
+/* Remote Control Passthrough Feature */
+
+/*
+ * Has also:
+ * CEC_MSG_USER_CONTROL_PRESSED
+ * CEC_MSG_USER_CONTROL_RELEASED
+ */
+
+
+/* Power Status Feature */
+#define CEC_MSG_GIVE_DEVICE_POWER_STATUS 0x8f
+#define CEC_MSG_REPORT_POWER_STATUS 0x90
+/* Power Status Operand (pwr_state) */
+#define CEC_OP_POWER_STATUS_ON 0
+#define CEC_OP_POWER_STATUS_STANDBY 1
+#define CEC_OP_POWER_STATUS_TO_ON 2
+#define CEC_OP_POWER_STATUS_TO_STANDBY 3
+
+
+/* General Protocol Messages */
+#define CEC_MSG_FEATURE_ABORT 0x00
+/* Abort Reason Operand (reason) */
+#define CEC_OP_ABORT_UNRECOGNIZED_OP 0
+#define CEC_OP_ABORT_INCORRECT_MODE 1
+#define CEC_OP_ABORT_NO_SOURCE 2
+#define CEC_OP_ABORT_INVALID_OP 3
+#define CEC_OP_ABORT_REFUSED 4
+#define CEC_OP_ABORT_UNDETERMINED 5
+
+#define CEC_MSG_ABORT 0xff
+
+
+/* System Audio Control Feature */
+
+/*
+ * Has also:
+ * CEC_MSG_USER_CONTROL_PRESSED
+ * CEC_MSG_USER_CONTROL_RELEASED
+ */
+#define CEC_MSG_GIVE_AUDIO_STATUS 0x71
+#define CEC_MSG_GIVE_SYSTEM_AUDIO_MODE_STATUS 0x7d
+#define CEC_MSG_REPORT_AUDIO_STATUS 0x7a
+/* Audio Mute Status Operand (aud_mute_status) */
+#define CEC_OP_AUD_MUTE_STATUS_OFF 0
+#define CEC_OP_AUD_MUTE_STATUS_ON 1
+
+#define CEC_MSG_REPORT_SHORT_AUDIO_DESCRIPTOR 0xa3
+#define CEC_MSG_REQUEST_SHORT_AUDIO_DESCRIPTOR 0xa4
+#define CEC_MSG_SET_SYSTEM_AUDIO_MODE 0x72
+/* System Audio Status Operand (sys_aud_status) */
+#define CEC_OP_SYS_AUD_STATUS_OFF 0
+#define CEC_OP_SYS_AUD_STATUS_ON 1
+
+#define CEC_MSG_SYSTEM_AUDIO_MODE_REQUEST 0x70
+#define CEC_MSG_SYSTEM_AUDIO_MODE_STATUS 0x7e
+/* Audio Format ID Operand (audio_format_id) */
+#define CEC_OP_AUD_FMT_ID_CEA861 0
+#define CEC_OP_AUD_FMT_ID_CEA861_CXT 1
+
+
+/* Audio Rate Control Feature */
+#define CEC_MSG_SET_AUDIO_RATE 0x9a
+/* Audio Rate Operand (audio_rate) */
+#define CEC_OP_AUD_RATE_OFF 0
+#define CEC_OP_AUD_RATE_WIDE_STD 1
+#define CEC_OP_AUD_RATE_WIDE_FAST 2
+#define CEC_OP_AUD_RATE_WIDE_SLOW 3
+#define CEC_OP_AUD_RATE_NARROW_STD 4
+#define CEC_OP_AUD_RATE_NARROW_FAST 5
+#define CEC_OP_AUD_RATE_NARROW_SLOW 6
+
+
+/* Audio Return Channel Control Feature */
+#define CEC_MSG_INITIATE_ARC 0xc0
+#define CEC_MSG_REPORT_ARC_INITIATED 0xc1
+#define CEC_MSG_REPORT_ARC_TERMINATED 0xc2
+#define CEC_MSG_REQUEST_ARC_INITIATION 0xc3
+#define CEC_MSG_REQUEST_ARC_TERMINATION 0xc4
+#define CEC_MSG_TERMINATE_ARC 0xc5
+
+
+/* Dynamic Audio Lipsync Feature */
+/* Only for CEC 2.0 and up */
+#define CEC_MSG_REQUEST_CURRENT_LATENCY 0xa7
+#define CEC_MSG_REPORT_CURRENT_LATENCY 0xa8
+/* Low Latency Mode Operand (low_latency_mode) */
+#define CEC_OP_LOW_LATENCY_MODE_OFF 0
+#define CEC_OP_LOW_LATENCY_MODE_ON 1
+/* Audio Output Compensated Operand (audio_out_compensated) */
+#define CEC_OP_AUD_OUT_COMPENSATED_NA 0
+#define CEC_OP_AUD_OUT_COMPENSATED_DELAY 1
+#define CEC_OP_AUD_OUT_COMPENSATED_NO_DELAY 2
+#define CEC_OP_AUD_OUT_COMPENSATED_PARTIAL_DELAY 3
+
+
+/* Capability Discovery and Control Feature */
+#define CEC_MSG_CDC_MESSAGE 0xf8
+/* Ethernet-over-HDMI: nobody ever does this... */
+#define CEC_MSG_CDC_HEC_INQUIRE_STATE 0x00
+#define CEC_MSG_CDC_HEC_REPORT_STATE 0x01
+/* HEC Functionality State Operand (hec_func_state) */
+#define CEC_OP_HEC_FUNC_STATE_NOT_SUPPORTED 0
+#define CEC_OP_HEC_FUNC_STATE_INACTIVE 1
+#define CEC_OP_HEC_FUNC_STATE_ACTIVE 2
+#define CEC_OP_HEC_FUNC_STATE_ACTIVATION_FIELD 3
+/* Host Functionality State Operand (host_func_state) */
+#define CEC_OP_HOST_FUNC_STATE_NOT_SUPPORTED 0
+#define CEC_OP_HOST_FUNC_STATE_INACTIVE 1
+#define CEC_OP_HOST_FUNC_STATE_ACTIVE 2
+/* ENC Functionality State Operand (enc_func_state) */
+#define CEC_OP_ENC_FUNC_STATE_EXT_CON_NOT_SUPPORTED 0
+#define CEC_OP_ENC_FUNC_STATE_EXT_CON_INACTIVE 1
+#define CEC_OP_ENC_FUNC_STATE_EXT_CON_ACTIVE 2
+/* CDC Error Code Operand (cdc_errcode) */
+#define CEC_OP_CDC_ERROR_CODE_NONE 0
+#define CEC_OP_CDC_ERROR_CODE_CAP_UNSUPPORTED 1
+#define CEC_OP_CDC_ERROR_CODE_WRONG_STATE 2
+#define CEC_OP_CDC_ERROR_CODE_OTHER 3
+/* HEC Support Operand (hec_support) */
+#define CEC_OP_HEC_SUPPORT_NO 0
+#define CEC_OP_HEC_SUPPORT_YES 1
+/* HEC Activation Operand (hec_activation) */
+#define CEC_OP_HEC_ACTIVATION_ON 0
+#define CEC_OP_HEC_ACTIVATION_OFF 1
+
+#define CEC_MSG_CDC_HEC_SET_STATE_ADJACENT 0x02
+#define CEC_MSG_CDC_HEC_SET_STATE 0x03
+/* HEC Set State Operand (hec_set_state) */
+#define CEC_OP_HEC_SET_STATE_DEACTIVATE 0
+#define CEC_OP_HEC_SET_STATE_ACTIVATE 1
+
+#define CEC_MSG_CDC_HEC_REQUEST_DEACTIVATION 0x04
+#define CEC_MSG_CDC_HEC_NOTIFY_ALIVE 0x05
+#define CEC_MSG_CDC_HEC_DISCOVER 0x06
+/* Hotplug Detect messages */
+#define CEC_MSG_CDC_HPD_SET_STATE 0x10
+/* HPD State Operand (hpd_state) */
+#define CEC_OP_HPD_STATE_CP_EDID_DISABLE 0
+#define CEC_OP_HPD_STATE_CP_EDID_ENABLE 1
+#define CEC_OP_HPD_STATE_CP_EDID_DISABLE_ENABLE 2
+#define CEC_OP_HPD_STATE_EDID_DISABLE 3
+#define CEC_OP_HPD_STATE_EDID_ENABLE 4
+#define CEC_OP_HPD_STATE_EDID_DISABLE_ENABLE 5
+#define CEC_MSG_CDC_HPD_REPORT_STATE 0x11
+/* HPD Error Code Operand (hpd_error) */
+#define CEC_OP_HPD_ERROR_NONE 0
+#define CEC_OP_HPD_ERROR_INITIATOR_NOT_CAPABLE 1
+#define CEC_OP_HPD_ERROR_INITIATOR_WRONG_STATE 2
+#define CEC_OP_HPD_ERROR_OTHER 3
+#define CEC_OP_HPD_ERROR_NONE_NO_VIDEO 4
+
+#endif
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index a20320c666fd..984f73b719a9 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -87,6 +87,7 @@ struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry,
struct cgroup_subsys *ss);
struct cgroup *cgroup_get_from_path(const char *path);
+struct cgroup *cgroup_get_from_fd(int fd);
int cgroup_attach_task_all(struct task_struct *from, struct task_struct *);
int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 0df4a51e1a78..834179f3fa72 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -461,6 +461,10 @@ static inline struct clk *clk_get_parent(struct clk *clk)
return NULL;
}
+static inline struct clk *clk_get_sys(const char *dev_id, const char *con_id)
+{
+ return NULL;
+}
#endif
/* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 44a1aff22566..08398182f56e 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -244,7 +244,7 @@ extern int clocksource_mmio_init(void __iomem *, const char *,
extern int clocksource_i8253_init(void);
#define CLOCKSOURCE_OF_DECLARE(name, compat, fn) \
- OF_DECLARE_1(clksrc, name, compat, fn)
+ OF_DECLARE_1_RET(clksrc, name, compat, fn)
#ifdef CONFIG_CLKSRC_PROBE
extern void clocksource_probe(void);
diff --git a/include/linux/compaction.h b/include/linux/compaction.h
index a58c852a268f..d4e106b5dc27 100644
--- a/include/linux/compaction.h
+++ b/include/linux/compaction.h
@@ -1,6 +1,18 @@
#ifndef _LINUX_COMPACTION_H
#define _LINUX_COMPACTION_H
+/*
+ * Determines how hard direct compaction should try to succeed.
+ * Lower value means higher priority, analogically to reclaim priority.
+ */
+enum compact_priority {
+ COMPACT_PRIO_SYNC_LIGHT,
+ MIN_COMPACT_PRIORITY = COMPACT_PRIO_SYNC_LIGHT,
+ DEF_COMPACT_PRIORITY = COMPACT_PRIO_SYNC_LIGHT,
+ COMPACT_PRIO_ASYNC,
+ INIT_COMPACT_PRIORITY = COMPACT_PRIO_ASYNC
+};
+
/* Return values for compact_zone() and try_to_compact_pages() */
/* When adding new states, please adjust include/trace/events/compaction.h */
enum compact_result {
@@ -43,14 +55,6 @@ enum compact_result {
COMPACT_PARTIAL,
};
-/* Used to signal whether compaction detected need_sched() or lock contention */
-/* No contention detected */
-#define COMPACT_CONTENDED_NONE 0
-/* Either need_sched() was true or fatal signal pending */
-#define COMPACT_CONTENDED_SCHED 1
-/* Zone lock or lru_lock was contended in async compaction */
-#define COMPACT_CONTENDED_LOCK 2
-
struct alloc_context; /* in mm/internal.h */
#ifdef CONFIG_COMPACTION
@@ -64,9 +68,8 @@ extern int sysctl_compact_unevictable_allowed;
extern int fragmentation_index(struct zone *zone, unsigned int order);
extern enum compact_result try_to_compact_pages(gfp_t gfp_mask,
- unsigned int order,
- unsigned int alloc_flags, const struct alloc_context *ac,
- enum migrate_mode mode, int *contended);
+ unsigned int order, unsigned int alloc_flags,
+ const struct alloc_context *ac, enum compact_priority prio);
extern void compact_pgdat(pg_data_t *pgdat, int order);
extern void reset_isolation_suitable(pg_data_t *pgdat);
extern enum compact_result compaction_suitable(struct zone *zone, int order,
@@ -151,14 +154,6 @@ extern void kcompactd_stop(int nid);
extern void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_idx);
#else
-static inline enum compact_result try_to_compact_pages(gfp_t gfp_mask,
- unsigned int order, int alloc_flags,
- const struct alloc_context *ac,
- enum migrate_mode mode, int *contended)
-{
- return COMPACT_CONTINUE;
-}
-
static inline void compact_pgdat(pg_data_t *pgdat, int order)
{
}
@@ -212,6 +207,7 @@ static inline void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_i
#endif /* CONFIG_COMPACTION */
#if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA)
+struct node;
extern int compaction_register_node(struct node *node);
extern void compaction_unregister_node(struct node *node);
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 793c0829e3a3..1bb954842725 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -17,7 +17,6 @@
# define __release(x) __context__(x,-1)
# define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0)
# define __percpu __attribute__((noderef, address_space(3)))
-# define __pmem __attribute__((noderef, address_space(5)))
#ifdef CONFIG_SPARSE_RCU_POINTER
# define __rcu __attribute__((noderef, address_space(4)))
#else /* CONFIG_SPARSE_RCU_POINTER */
@@ -45,7 +44,6 @@ extern void __chk_io_ptr(const volatile void __iomem *);
# define __cond_lock(x,c) (c)
# define __percpu
# define __rcu
-# define __pmem
# define __private
# define ACCESS_PRIVATE(p, member) ((p)->member)
#endif /* __CHECKER__ */
@@ -304,23 +302,6 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
__u.__val; \
})
-/**
- * smp_cond_acquire() - Spin wait for cond with ACQUIRE ordering
- * @cond: boolean expression to wait for
- *
- * Equivalent to using smp_load_acquire() on the condition variable but employs
- * the control dependency of the wait to reduce the barrier on many platforms.
- *
- * The control dependency provides a LOAD->STORE order, the additional RMB
- * provides LOAD->LOAD order, together they provide LOAD->{LOAD,STORE} order,
- * aka. ACQUIRE.
- */
-#define smp_cond_acquire(cond) do { \
- while (!(cond)) \
- cpu_relax(); \
- smp_rmb(); /* ctrl + rmb := acquire */ \
-} while (0)
-
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
@@ -545,10 +526,14 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
* Similar to rcu_dereference(), but for situations where the pointed-to
* object's lifetime is managed by something other than RCU. That
* "something other" might be reference counting or simple immortality.
+ *
+ * The seemingly unused void * variable is to validate @p is indeed a pointer
+ * type. All pointer types silently cast to void *.
*/
#define lockless_dereference(p) \
({ \
typeof(p) _________p1 = READ_ONCE(p); \
+ __maybe_unused const void * const _________p2 = _________p1; \
smp_read_barrier_depends(); /* Dependency order vs. p above. */ \
(_________p1); \
})
diff --git a/include/linux/console.h b/include/linux/console.h
index 98c8615dc300..d530c4627e54 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -28,6 +28,13 @@ struct tty_struct;
#define VT100ID "\033[?1;2c"
#define VT102ID "\033[?6c"
+/**
+ * struct consw - callbacks for consoles
+ *
+ * @con_set_palette: sets the palette of the console to @table (optional)
+ * @con_scrolldelta: the contents of the console should be scrolled by @lines.
+ * Invoked by user. (optional)
+ */
struct consw {
struct module *owner;
const char *(*con_startup)(void);
@@ -38,7 +45,6 @@ struct consw {
void (*con_putcs)(struct vc_data *, const unsigned short *, int, int, int);
void (*con_cursor)(struct vc_data *, int);
int (*con_scroll)(struct vc_data *, int, int, int, int);
- void (*con_bmove)(struct vc_data *, int, int, int, int, int, int);
int (*con_switch)(struct vc_data *);
int (*con_blank)(struct vc_data *, int, int);
int (*con_font_set)(struct vc_data *, struct console_font *, unsigned);
@@ -47,8 +53,9 @@ struct consw {
int (*con_font_copy)(struct vc_data *, int);
int (*con_resize)(struct vc_data *, unsigned int, unsigned int,
unsigned int);
- int (*con_set_palette)(struct vc_data *, const unsigned char *);
- int (*con_scrolldelta)(struct vc_data *, int);
+ void (*con_set_palette)(struct vc_data *,
+ const unsigned char *table);
+ void (*con_scrolldelta)(struct vc_data *, int lines);
int (*con_set_origin)(struct vc_data *);
void (*con_save_screen)(struct vc_data *);
u8 (*con_build_attr)(struct vc_data *, u8, u8, u8, u8, u8, u8);
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index e329ee2667e1..6fd3c908a340 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -21,6 +21,38 @@ struct uni_pagedir;
#define NPAR 16
+/*
+ * Example: vc_data of a console that was scrolled 3 lines down.
+ *
+ * Console buffer
+ * vc_screenbuf ---------> +----------------------+-.
+ * | initializing W | \
+ * | initializing X | |
+ * | initializing Y | > scroll-back area
+ * | initializing Z | |
+ * | | /
+ * vc_visible_origin ---> ^+----------------------+-:
+ * (changes by scroll) || Welcome to linux | \
+ * || | |
+ * vc_rows --->< | login: root | | visible on console
+ * || password: | > (vc_screenbuf_size is
+ * vc_origin -----------> || | | vc_size_row * vc_rows)
+ * (start when no scroll) || Last login: 12:28 | /
+ * v+----------------------+-:
+ * | Have a lot of fun... | \
+ * vc_pos -----------------|--------v | > scroll-front area
+ * | ~ # cat_ | /
+ * vc_scr_end -----------> +----------------------+-:
+ * (vc_origin + | | \ EMPTY, to be filled by
+ * vc_screenbuf_size) | | / vc_video_erase_char
+ * +----------------------+-'
+ * <---- 2 * vc_cols ----->
+ * <---- vc_size_row ----->
+ *
+ * Note that every character in the console buffer is accompanied with an
+ * attribute in the buffer right after the character. This is not depicted
+ * in the figure.
+ */
struct vc_data {
struct tty_port port; /* Upper level data */
@@ -74,7 +106,6 @@ struct vc_data {
unsigned int vc_decawm : 1; /* Autowrap Mode */
unsigned int vc_deccm : 1; /* Cursor Visible */
unsigned int vc_decim : 1; /* Insert Mode */
- unsigned int vc_deccolm : 1; /* 80/132 Column Mode */
/* attribute flags */
unsigned int vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */
unsigned int vc_italic:1;
@@ -136,6 +167,9 @@ extern void vc_SAK(struct work_struct *work);
#define CUR_DEFAULT CUR_UNDERLINE
-#define CON_IS_VISIBLE(conp) (*conp->vc_display_fg == conp)
+static inline bool con_is_visible(const struct vc_data *vc)
+{
+ return *vc->vc_display_fg == vc;
+}
#endif /* _LINUX_CONSOLE_STRUCT_H */
diff --git a/include/linux/context_tracking.h b/include/linux/context_tracking.h
index d259274238db..d9aef2a0ec8e 100644
--- a/include/linux/context_tracking.h
+++ b/include/linux/context_tracking.h
@@ -31,6 +31,19 @@ static inline void user_exit(void)
context_tracking_exit(CONTEXT_USER);
}
+/* Called with interrupts disabled. */
+static inline void user_enter_irqoff(void)
+{
+ if (context_tracking_is_enabled())
+ __context_tracking_enter(CONTEXT_USER);
+
+}
+static inline void user_exit_irqoff(void)
+{
+ if (context_tracking_is_enabled())
+ __context_tracking_exit(CONTEXT_USER);
+}
+
static inline enum ctx_state exception_enter(void)
{
enum ctx_state prev_ctx;
@@ -69,6 +82,8 @@ static inline enum ctx_state ct_state(void)
#else
static inline void user_enter(void) { }
static inline void user_exit(void) { }
+static inline void user_enter_irqoff(void) { }
+static inline void user_exit_irqoff(void) { }
static inline enum ctx_state exception_enter(void) { return 0; }
static inline void exception_exit(enum ctx_state prev_ctx) { }
static inline enum ctx_state ct_state(void) { return CONTEXT_DISABLED; }
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 4e81e08db752..631ba33bbe9f 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -36,6 +36,12 @@
struct cpufreq_governor;
+enum cpufreq_table_sorting {
+ CPUFREQ_TABLE_UNSORTED,
+ CPUFREQ_TABLE_SORTED_ASCENDING,
+ CPUFREQ_TABLE_SORTED_DESCENDING
+};
+
struct cpufreq_freqs {
unsigned int cpu; /* cpu nr */
unsigned int old;
@@ -87,6 +93,7 @@ struct cpufreq_policy {
struct cpufreq_user_policy user_policy;
struct cpufreq_frequency_table *freq_table;
+ enum cpufreq_table_sorting freq_table_sorted;
struct list_head policy_list;
struct kobject kobj;
@@ -113,6 +120,10 @@ struct cpufreq_policy {
bool fast_switch_possible;
bool fast_switch_enabled;
+ /* Cached frequency lookup from cpufreq_driver_resolve_freq. */
+ unsigned int cached_target_freq;
+ int cached_resolved_idx;
+
/* Synchronization for frequency transitions */
bool transition_ongoing; /* Tracks transition status */
spinlock_t transition_lock;
@@ -185,6 +196,18 @@ static inline unsigned int cpufreq_quick_get_max(unsigned int cpu)
static inline void disable_cpufreq(void) { }
#endif
+#ifdef CONFIG_CPU_FREQ_STAT
+void cpufreq_stats_create_table(struct cpufreq_policy *policy);
+void cpufreq_stats_free_table(struct cpufreq_policy *policy);
+void cpufreq_stats_record_transition(struct cpufreq_policy *policy,
+ unsigned int new_freq);
+#else
+static inline void cpufreq_stats_create_table(struct cpufreq_policy *policy) { }
+static inline void cpufreq_stats_free_table(struct cpufreq_policy *policy) { }
+static inline void cpufreq_stats_record_transition(struct cpufreq_policy *policy,
+ unsigned int new_freq) { }
+#endif /* CONFIG_CPU_FREQ_STAT */
+
/*********************************************************************
* CPUFREQ DRIVER INTERFACE *
*********************************************************************/
@@ -251,6 +274,16 @@ struct cpufreq_driver {
unsigned int index);
unsigned int (*fast_switch)(struct cpufreq_policy *policy,
unsigned int target_freq);
+
+ /*
+ * Caches and returns the lowest driver-supported frequency greater than
+ * or equal to the target frequency, subject to any driver limitations.
+ * Does not set the frequency. Only to be implemented for drivers with
+ * target().
+ */
+ unsigned int (*resolve_freq)(struct cpufreq_policy *policy,
+ unsigned int target_freq);
+
/*
* Only for drivers with target_index() and CPUFREQ_ASYNC_NOTIFICATION
* unset.
@@ -455,18 +488,13 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div,
#define MIN_LATENCY_MULTIPLIER (20)
#define TRANSITION_LATENCY_LIMIT (10 * 1000 * 1000)
-/* Governor Events */
-#define CPUFREQ_GOV_START 1
-#define CPUFREQ_GOV_STOP 2
-#define CPUFREQ_GOV_LIMITS 3
-#define CPUFREQ_GOV_POLICY_INIT 4
-#define CPUFREQ_GOV_POLICY_EXIT 5
-
struct cpufreq_governor {
char name[CPUFREQ_NAME_LEN];
- int initialized;
- int (*governor) (struct cpufreq_policy *policy,
- unsigned int event);
+ int (*init)(struct cpufreq_policy *policy);
+ void (*exit)(struct cpufreq_policy *policy);
+ int (*start)(struct cpufreq_policy *policy);
+ void (*stop)(struct cpufreq_policy *policy);
+ void (*limits)(struct cpufreq_policy *policy);
ssize_t (*show_setspeed) (struct cpufreq_policy *policy,
char *buf);
int (*store_setspeed) (struct cpufreq_policy *policy,
@@ -487,12 +515,22 @@ int cpufreq_driver_target(struct cpufreq_policy *policy,
int __cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation);
+unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy,
+ unsigned int target_freq);
int cpufreq_register_governor(struct cpufreq_governor *governor);
void cpufreq_unregister_governor(struct cpufreq_governor *governor);
struct cpufreq_governor *cpufreq_default_governor(void);
struct cpufreq_governor *cpufreq_fallback_governor(void);
+static inline void cpufreq_policy_apply_limits(struct cpufreq_policy *policy)
+{
+ if (policy->max < policy->cur)
+ __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H);
+ else if (policy->min > policy->cur)
+ __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L);
+}
+
/* Governor attribute set */
struct gov_attr_set {
struct kobject kobj;
@@ -582,11 +620,9 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table);
int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy);
-int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
- struct cpufreq_frequency_table *table,
- unsigned int target_freq,
- unsigned int relation,
- unsigned int *index);
+int cpufreq_table_index_unsorted(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation);
int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy,
unsigned int freq);
@@ -597,6 +633,227 @@ int cpufreq_boost_trigger_state(int state);
int cpufreq_boost_enabled(void);
int cpufreq_enable_boost_support(void);
bool policy_has_boost_freq(struct cpufreq_policy *policy);
+
+/* Find lowest freq at or above target in a table in ascending order */
+static inline int cpufreq_table_find_index_al(struct cpufreq_policy *policy,
+ unsigned int target_freq)
+{
+ struct cpufreq_frequency_table *table = policy->freq_table;
+ unsigned int freq;
+ int i, best = -1;
+
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ freq = table[i].frequency;
+
+ if (freq >= target_freq)
+ return i;
+
+ best = i;
+ }
+
+ return best;
+}
+
+/* Find lowest freq at or above target in a table in descending order */
+static inline int cpufreq_table_find_index_dl(struct cpufreq_policy *policy,
+ unsigned int target_freq)
+{
+ struct cpufreq_frequency_table *table = policy->freq_table;
+ unsigned int freq;
+ int i, best = -1;
+
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ freq = table[i].frequency;
+
+ if (freq == target_freq)
+ return i;
+
+ if (freq > target_freq) {
+ best = i;
+ continue;
+ }
+
+ /* No freq found above target_freq */
+ if (best == -1)
+ return i;
+
+ return best;
+ }
+
+ return best;
+}
+
+/* Works only on sorted freq-tables */
+static inline int cpufreq_table_find_index_l(struct cpufreq_policy *policy,
+ unsigned int target_freq)
+{
+ target_freq = clamp_val(target_freq, policy->min, policy->max);
+
+ if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING)
+ return cpufreq_table_find_index_al(policy, target_freq);
+ else
+ return cpufreq_table_find_index_dl(policy, target_freq);
+}
+
+/* Find highest freq at or below target in a table in ascending order */
+static inline int cpufreq_table_find_index_ah(struct cpufreq_policy *policy,
+ unsigned int target_freq)
+{
+ struct cpufreq_frequency_table *table = policy->freq_table;
+ unsigned int freq;
+ int i, best = -1;
+
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ freq = table[i].frequency;
+
+ if (freq == target_freq)
+ return i;
+
+ if (freq < target_freq) {
+ best = i;
+ continue;
+ }
+
+ /* No freq found below target_freq */
+ if (best == -1)
+ return i;
+
+ return best;
+ }
+
+ return best;
+}
+
+/* Find highest freq at or below target in a table in descending order */
+static inline int cpufreq_table_find_index_dh(struct cpufreq_policy *policy,
+ unsigned int target_freq)
+{
+ struct cpufreq_frequency_table *table = policy->freq_table;
+ unsigned int freq;
+ int i, best = -1;
+
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ freq = table[i].frequency;
+
+ if (freq <= target_freq)
+ return i;
+
+ best = i;
+ }
+
+ return best;
+}
+
+/* Works only on sorted freq-tables */
+static inline int cpufreq_table_find_index_h(struct cpufreq_policy *policy,
+ unsigned int target_freq)
+{
+ target_freq = clamp_val(target_freq, policy->min, policy->max);
+
+ if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING)
+ return cpufreq_table_find_index_ah(policy, target_freq);
+ else
+ return cpufreq_table_find_index_dh(policy, target_freq);
+}
+
+/* Find closest freq to target in a table in ascending order */
+static inline int cpufreq_table_find_index_ac(struct cpufreq_policy *policy,
+ unsigned int target_freq)
+{
+ struct cpufreq_frequency_table *table = policy->freq_table;
+ unsigned int freq;
+ int i, best = -1;
+
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ freq = table[i].frequency;
+
+ if (freq == target_freq)
+ return i;
+
+ if (freq < target_freq) {
+ best = i;
+ continue;
+ }
+
+ /* No freq found below target_freq */
+ if (best == -1)
+ return i;
+
+ /* Choose the closest freq */
+ if (target_freq - table[best].frequency > freq - target_freq)
+ return i;
+
+ return best;
+ }
+
+ return best;
+}
+
+/* Find closest freq to target in a table in descending order */
+static inline int cpufreq_table_find_index_dc(struct cpufreq_policy *policy,
+ unsigned int target_freq)
+{
+ struct cpufreq_frequency_table *table = policy->freq_table;
+ unsigned int freq;
+ int i, best = -1;
+
+ for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+ freq = table[i].frequency;
+
+ if (freq == target_freq)
+ return i;
+
+ if (freq > target_freq) {
+ best = i;
+ continue;
+ }
+
+ /* No freq found above target_freq */
+ if (best == -1)
+ return i;
+
+ /* Choose the closest freq */
+ if (table[best].frequency - target_freq > target_freq - freq)
+ return i;
+
+ return best;
+ }
+
+ return best;
+}
+
+/* Works only on sorted freq-tables */
+static inline int cpufreq_table_find_index_c(struct cpufreq_policy *policy,
+ unsigned int target_freq)
+{
+ target_freq = clamp_val(target_freq, policy->min, policy->max);
+
+ if (policy->freq_table_sorted == CPUFREQ_TABLE_SORTED_ASCENDING)
+ return cpufreq_table_find_index_ac(policy, target_freq);
+ else
+ return cpufreq_table_find_index_dc(policy, target_freq);
+}
+
+static inline int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ if (unlikely(policy->freq_table_sorted == CPUFREQ_TABLE_UNSORTED))
+ return cpufreq_table_index_unsorted(policy, target_freq,
+ relation);
+
+ switch (relation) {
+ case CPUFREQ_RELATION_L:
+ return cpufreq_table_find_index_l(policy, target_freq);
+ case CPUFREQ_RELATION_H:
+ return cpufreq_table_find_index_h(policy, target_freq);
+ case CPUFREQ_RELATION_C:
+ return cpufreq_table_find_index_c(policy, target_freq);
+ default:
+ pr_err("%s: Invalid relation: %d\n", __func__, relation);
+ return -EINVAL;
+ }
+}
#else
static inline int cpufreq_boost_trigger_state(int state)
{
@@ -617,8 +874,6 @@ static inline bool policy_has_boost_freq(struct cpufreq_policy *policy)
return false;
}
#endif
-/* the following funtion is for cpufreq core use only */
-struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu);
/* the following are really really optional */
extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 07b83d32f66c..bb31373c3478 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -252,4 +252,22 @@ static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
#define CPUIDLE_DRIVER_STATE_START 0
#endif
+#define CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx) \
+({ \
+ int __ret; \
+ \
+ if (!idx) { \
+ cpu_do_idle(); \
+ return idx; \
+ } \
+ \
+ __ret = cpu_pm_enter(); \
+ if (!__ret) { \
+ __ret = low_level_idle_enter(idx); \
+ cpu_pm_exit(); \
+ } \
+ \
+ __ret ? -1 : idx; \
+})
+
#endif /* _LINUX_CPUIDLE_H */
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 6e28c895c376..7cee5551625b 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -47,16 +47,18 @@
#define CRYPTO_ALG_TYPE_AEAD 0x00000003
#define CRYPTO_ALG_TYPE_BLKCIPHER 0x00000004
#define CRYPTO_ALG_TYPE_ABLKCIPHER 0x00000005
+#define CRYPTO_ALG_TYPE_SKCIPHER 0x00000005
#define CRYPTO_ALG_TYPE_GIVCIPHER 0x00000006
-#define CRYPTO_ALG_TYPE_DIGEST 0x00000008
-#define CRYPTO_ALG_TYPE_HASH 0x00000008
-#define CRYPTO_ALG_TYPE_SHASH 0x00000009
-#define CRYPTO_ALG_TYPE_AHASH 0x0000000a
+#define CRYPTO_ALG_TYPE_KPP 0x00000008
#define CRYPTO_ALG_TYPE_RNG 0x0000000c
#define CRYPTO_ALG_TYPE_AKCIPHER 0x0000000d
+#define CRYPTO_ALG_TYPE_DIGEST 0x0000000e
+#define CRYPTO_ALG_TYPE_HASH 0x0000000e
+#define CRYPTO_ALG_TYPE_SHASH 0x0000000e
+#define CRYPTO_ALG_TYPE_AHASH 0x0000000f
#define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e
-#define CRYPTO_ALG_TYPE_AHASH_MASK 0x0000000c
+#define CRYPTO_ALG_TYPE_AHASH_MASK 0x0000000e
#define CRYPTO_ALG_TYPE_BLKCIPHER_MASK 0x0000000c
#define CRYPTO_ALG_LARVAL 0x00000010
@@ -486,8 +488,6 @@ struct ablkcipher_tfm {
unsigned int keylen);
int (*encrypt)(struct ablkcipher_request *req);
int (*decrypt)(struct ablkcipher_request *req);
- int (*givencrypt)(struct skcipher_givcrypt_request *req);
- int (*givdecrypt)(struct skcipher_givcrypt_request *req);
struct crypto_ablkcipher *base;
@@ -712,23 +712,6 @@ static inline u32 crypto_skcipher_mask(u32 mask)
* state information is unused by the kernel crypto API.
*/
-/**
- * crypto_alloc_ablkcipher() - allocate asynchronous block cipher handle
- * @alg_name: is the cra_name / name or cra_driver_name / driver name of the
- * ablkcipher cipher
- * @type: specifies the type of the cipher
- * @mask: specifies the mask for the cipher
- *
- * Allocate a cipher handle for an ablkcipher. The returned struct
- * crypto_ablkcipher is the cipher handle that is required for any subsequent
- * API invocation for that ablkcipher.
- *
- * Return: allocated cipher handle in case of success; IS_ERR() is true in case
- * of an error, PTR_ERR() returns the error code.
- */
-struct crypto_ablkcipher *crypto_alloc_ablkcipher(const char *alg_name,
- u32 type, u32 mask);
-
static inline struct crypto_tfm *crypto_ablkcipher_tfm(
struct crypto_ablkcipher *tfm)
{
diff --git a/include/linux/dax.h b/include/linux/dax.h
index 43d5f0b799c7..9c6dc7704043 100644
--- a/include/linux/dax.h
+++ b/include/linux/dax.h
@@ -14,7 +14,6 @@ ssize_t dax_do_io(struct kiocb *, struct inode *, struct iov_iter *,
int dax_zero_page_range(struct inode *, loff_t from, unsigned len, get_block_t);
int dax_truncate_page(struct inode *, loff_t from, get_block_t);
int dax_fault(struct vm_area_struct *, struct vm_fault *, get_block_t);
-int __dax_fault(struct vm_area_struct *, struct vm_fault *, get_block_t);
int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index);
void dax_wake_mapping_entry_waiter(struct address_space *mapping,
pgoff_t index, bool wake_all);
@@ -46,19 +45,15 @@ static inline int __dax_zero_page_range(struct block_device *bdev,
#if defined(CONFIG_TRANSPARENT_HUGEPAGE)
int dax_pmd_fault(struct vm_area_struct *, unsigned long addr, pmd_t *,
unsigned int flags, get_block_t);
-int __dax_pmd_fault(struct vm_area_struct *, unsigned long addr, pmd_t *,
- unsigned int flags, get_block_t);
#else
static inline int dax_pmd_fault(struct vm_area_struct *vma, unsigned long addr,
pmd_t *pmd, unsigned int flags, get_block_t gb)
{
return VM_FAULT_FALLBACK;
}
-#define __dax_pmd_fault dax_pmd_fault
#endif
int dax_pfn_mkwrite(struct vm_area_struct *, struct vm_fault *);
#define dax_mkwrite(vma, vmf, gb) dax_fault(vma, vmf, gb)
-#define __dax_mkwrite(vma, vmf, gb) __dax_fault(vma, vmf, gb)
static inline bool vma_is_dax(struct vm_area_struct *vma)
{
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 14df83609c7f..98044a8d1487 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -133,6 +133,7 @@ struct dentry_operations {
int (*d_compare)(const struct dentry *, const struct dentry *,
unsigned int, const char *, const struct qstr *);
int (*d_delete)(const struct dentry *);
+ int (*d_init)(struct dentry *);
void (*d_release)(struct dentry *);
void (*d_prune)(struct dentry *);
void (*d_iput)(struct dentry *, struct inode *);
diff --git a/include/linux/debugobjects.h b/include/linux/debugobjects.h
index 46056cb161fc..d82bf1994485 100644
--- a/include/linux/debugobjects.h
+++ b/include/linux/debugobjects.h
@@ -38,7 +38,7 @@ struct debug_obj {
* @name: name of the object typee
* @debug_hint: function returning address, which have associated
* kernel symbol, to allow identify the object
- * @is_static_object return true if the obj is static, otherwise return false
+ * @is_static_object: return true if the obj is static, otherwise return false
* @fixup_init: fixup function, which is called when the init check
* fails. All fixup functions must return true if fixup
* was successful, otherwise return false
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 0830c9e86f0d..91acfce74a22 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -19,6 +19,15 @@ struct dm_table;
struct mapped_device;
struct bio_vec;
+/*
+ * Type of table, mapped_device's mempool and request_queue
+ */
+#define DM_TYPE_NONE 0
+#define DM_TYPE_BIO_BASED 1
+#define DM_TYPE_REQUEST_BASED 2
+#define DM_TYPE_MQ_REQUEST_BASED 3
+#define DM_TYPE_DAX_BIO_BASED 4
+
typedef enum { STATUSTYPE_INFO, STATUSTYPE_TABLE } status_type_t;
union map_info {
@@ -116,6 +125,14 @@ typedef void (*dm_io_hints_fn) (struct dm_target *ti,
*/
typedef int (*dm_busy_fn) (struct dm_target *ti);
+/*
+ * Returns:
+ * < 0 : error
+ * >= 0 : the number of bytes accessible at the address
+ */
+typedef long (*dm_direct_access_fn) (struct dm_target *ti, sector_t sector,
+ void **kaddr, pfn_t *pfn, long size);
+
void dm_error(const char *message);
struct dm_dev {
@@ -162,6 +179,7 @@ struct target_type {
dm_busy_fn busy;
dm_iterate_devices_fn iterate_devices;
dm_io_hints_fn io_hints;
+ dm_direct_access_fn direct_access;
/* For internal device-mapper use. */
struct list_head list;
@@ -444,6 +462,14 @@ int dm_table_add_target(struct dm_table *t, const char *type,
void dm_table_add_target_callbacks(struct dm_table *t, struct dm_target_callbacks *cb);
/*
+ * Target can use this to set the table's type.
+ * Can only ever be called from a target's ctr.
+ * Useful for "hybrid" target (supports both bio-based
+ * and request-based).
+ */
+void dm_table_set_type(struct dm_table *t, unsigned type);
+
+/*
* Finally call this to make the table ready for use.
*/
int dm_table_complete(struct dm_table *t);
diff --git a/include/linux/dm-io.h b/include/linux/dm-io.h
index a68cbe59e6ad..b91b023deffb 100644
--- a/include/linux/dm-io.h
+++ b/include/linux/dm-io.h
@@ -57,7 +57,8 @@ struct dm_io_notify {
*/
struct dm_io_client;
struct dm_io_request {
- int bi_rw; /* READ|WRITE - not READA */
+ int bi_op; /* REQ_OP */
+ int bi_op_flags; /* rq_flag_bits */
struct dm_io_memory mem; /* Memory to use for io */
struct dm_io_notify notify; /* Synchronous if notify.fn is NULL */
struct dm_io_client *client; /* Client memory handler */
diff --git a/include/linux/dma/hsu.h b/include/linux/dma/hsu.h
index 79df69dc629c..aaff68efba5d 100644
--- a/include/linux/dma/hsu.h
+++ b/include/linux/dma/hsu.h
@@ -39,14 +39,22 @@ struct hsu_dma_chip {
#if IS_ENABLED(CONFIG_HSU_DMA)
/* Export to the internal users */
-irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr);
+int hsu_dma_get_status(struct hsu_dma_chip *chip, unsigned short nr,
+ u32 *status);
+irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip, unsigned short nr,
+ u32 status);
/* Export to the platform drivers */
int hsu_dma_probe(struct hsu_dma_chip *chip);
int hsu_dma_remove(struct hsu_dma_chip *chip);
#else
-static inline irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip,
- unsigned short nr)
+static inline int hsu_dma_get_status(struct hsu_dma_chip *chip,
+ unsigned short nr, u32 *status)
+{
+ return 0;
+}
+static inline irqreturn_t hsu_dma_do_irq(struct hsu_dma_chip *chip,
+ unsigned short nr, u32 status)
{
return IRQ_NONE;
}
diff --git a/include/linux/drbd.h b/include/linux/drbd.h
index d6b3c9943a2c..002611c85318 100644
--- a/include/linux/drbd.h
+++ b/include/linux/drbd.h
@@ -51,7 +51,7 @@
#endif
extern const char *drbd_buildtag(void);
-#define REL_VERSION "8.4.6"
+#define REL_VERSION "8.4.7"
#define API_VERSION 1
#define PRO_VERSION_MIN 86
#define PRO_VERSION_MAX 101
@@ -370,6 +370,14 @@ enum drbd_notification_type {
NOTIFY_FLAGS = NOTIFY_CONTINUES,
};
+enum drbd_peer_state {
+ P_INCONSISTENT = 3,
+ P_OUTDATED = 4,
+ P_DOWN = 5,
+ P_PRIMARY = 6,
+ P_FENCING = 7,
+};
+
#define UUID_JUST_CREATED ((__u64)4)
enum write_ordering_e {
diff --git a/include/linux/drbd_genl.h b/include/linux/drbd_genl.h
index 2d0e5ad5de9d..c934d3a96b5e 100644
--- a/include/linux/drbd_genl.h
+++ b/include/linux/drbd_genl.h
@@ -123,15 +123,16 @@ GENL_struct(DRBD_NLA_DISK_CONF, 3, disk_conf,
__u32_field_def(13, DRBD_GENLA_F_MANDATORY, c_fill_target, DRBD_C_FILL_TARGET_DEF)
__u32_field_def(14, DRBD_GENLA_F_MANDATORY, c_max_rate, DRBD_C_MAX_RATE_DEF)
__u32_field_def(15, DRBD_GENLA_F_MANDATORY, c_min_rate, DRBD_C_MIN_RATE_DEF)
+ __u32_field_def(20, DRBD_GENLA_F_MANDATORY, disk_timeout, DRBD_DISK_TIMEOUT_DEF)
+ __u32_field_def(21, 0 /* OPTIONAL */, read_balancing, DRBD_READ_BALANCING_DEF)
+ __u32_field_def(25, 0 /* OPTIONAL */, rs_discard_granularity, DRBD_RS_DISCARD_GRANULARITY_DEF)
__flg_field_def(16, DRBD_GENLA_F_MANDATORY, disk_barrier, DRBD_DISK_BARRIER_DEF)
__flg_field_def(17, DRBD_GENLA_F_MANDATORY, disk_flushes, DRBD_DISK_FLUSHES_DEF)
__flg_field_def(18, DRBD_GENLA_F_MANDATORY, disk_drain, DRBD_DISK_DRAIN_DEF)
__flg_field_def(19, DRBD_GENLA_F_MANDATORY, md_flushes, DRBD_MD_FLUSHES_DEF)
- __u32_field_def(20, DRBD_GENLA_F_MANDATORY, disk_timeout, DRBD_DISK_TIMEOUT_DEF)
- __u32_field_def(21, 0 /* OPTIONAL */, read_balancing, DRBD_READ_BALANCING_DEF)
- /* 9: __u32_field_def(22, DRBD_GENLA_F_MANDATORY, unplug_watermark, DRBD_UNPLUG_WATERMARK_DEF) */
__flg_field_def(23, 0 /* OPTIONAL */, al_updates, DRBD_AL_UPDATES_DEF)
+ __flg_field_def(24, 0 /* OPTIONAL */, discard_zeroes_if_aligned, DRBD_DISCARD_ZEROES_IF_ALIGNED)
)
GENL_struct(DRBD_NLA_RESOURCE_OPTS, 4, res_opts,
diff --git a/include/linux/drbd_limits.h b/include/linux/drbd_limits.h
index 8ac8c5d9a3ad..ddac68422a96 100644
--- a/include/linux/drbd_limits.h
+++ b/include/linux/drbd_limits.h
@@ -126,8 +126,7 @@
#define DRBD_RESYNC_RATE_DEF 250
#define DRBD_RESYNC_RATE_SCALE 'k' /* kilobytes */
- /* less than 7 would hit performance unnecessarily. */
-#define DRBD_AL_EXTENTS_MIN 7
+#define DRBD_AL_EXTENTS_MIN 67
/* we use u16 as "slot number", (u16)~0 is "FREE".
* If you use >= 292 kB on-disk ring buffer,
* this is the maximum you can use: */
@@ -210,6 +209,12 @@
#define DRBD_MD_FLUSHES_DEF 1
#define DRBD_TCP_CORK_DEF 1
#define DRBD_AL_UPDATES_DEF 1
+/* We used to ignore the discard_zeroes_data setting.
+ * To not change established (and expected) behaviour,
+ * by default assume that, for discard_zeroes_data=0,
+ * we can make that an effective discard_zeroes_data=1,
+ * if we only explicitly zero-out unaligned partial chunks. */
+#define DRBD_DISCARD_ZEROES_IF_ALIGNED 1
#define DRBD_ALLOW_TWO_PRIMARIES_DEF 0
#define DRBD_ALWAYS_ASBP_DEF 0
@@ -230,4 +235,10 @@
#define DRBD_SOCKET_CHECK_TIMEO_MAX DRBD_PING_TIMEO_MAX
#define DRBD_SOCKET_CHECK_TIMEO_DEF 0
#define DRBD_SOCKET_CHECK_TIMEO_SCALE '1'
+
+#define DRBD_RS_DISCARD_GRANULARITY_MIN 0
+#define DRBD_RS_DISCARD_GRANULARITY_MAX (1<<20) /* 1MiByte */
+#define DRBD_RS_DISCARD_GRANULARITY_DEF 0 /* disabled by default */
+#define DRBD_RS_DISCARD_GRANULARITY_SCALE '1' /* bytes */
+
#endif
diff --git a/include/linux/efi.h b/include/linux/efi.h
index f196dd0b0f2f..7f80a75ee9e3 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -536,116 +536,58 @@ typedef efi_status_t efi_query_variable_store_t(u32 attributes,
void efi_native_runtime_setup(void);
/*
- * EFI Configuration Table and GUID definitions
+ * EFI Configuration Table and GUID definitions
+ *
+ * These are all defined in a single line to make them easier to
+ * grep for and to see them at a glance - while still having a
+ * similar structure to the definitions in the spec.
+ *
+ * Here's how they are structured:
+ *
+ * GUID: 12345678-1234-1234-1234-123456789012
+ * Spec:
+ * #define EFI_SOME_PROTOCOL_GUID \
+ * {0x12345678,0x1234,0x1234,\
+ * {0x12,0x34,0x12,0x34,0x56,0x78,0x90,0x12}}
+ * Here:
+ * #define SOME_PROTOCOL_GUID EFI_GUID(0x12345678, 0x1234, 0x1234, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12)
+ * ^ tabs ^extra space
+ *
+ * Note that the 'extra space' separates the values at the same place
+ * where the UEFI SPEC breaks the line.
*/
-#define NULL_GUID \
- EFI_GUID(0x00000000, 0x0000, 0x0000, \
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
-
-#define MPS_TABLE_GUID \
- EFI_GUID(0xeb9d2d2f, 0x2d88, 0x11d3, \
- 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
-
-#define ACPI_TABLE_GUID \
- EFI_GUID(0xeb9d2d30, 0x2d88, 0x11d3, \
- 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
-
-#define ACPI_20_TABLE_GUID \
- EFI_GUID(0x8868e871, 0xe4f1, 0x11d3, \
- 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81)
-
-#define SMBIOS_TABLE_GUID \
- EFI_GUID(0xeb9d2d31, 0x2d88, 0x11d3, \
- 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
-
-#define SMBIOS3_TABLE_GUID \
- EFI_GUID(0xf2fd1544, 0x9794, 0x4a2c, \
- 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94)
-
-#define SAL_SYSTEM_TABLE_GUID \
- EFI_GUID(0xeb9d2d32, 0x2d88, 0x11d3, \
- 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
-
-#define HCDP_TABLE_GUID \
- EFI_GUID(0xf951938d, 0x620b, 0x42ef, \
- 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98)
-
-#define UGA_IO_PROTOCOL_GUID \
- EFI_GUID(0x61a4d49e, 0x6f68, 0x4f1b, \
- 0xb9, 0x22, 0xa8, 0x6e, 0xed, 0x0b, 0x07, 0xa2)
-
-#define EFI_GLOBAL_VARIABLE_GUID \
- EFI_GUID(0x8be4df61, 0x93ca, 0x11d2, \
- 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c)
-
-#define UV_SYSTEM_TABLE_GUID \
- EFI_GUID(0x3b13a7d4, 0x633e, 0x11dd, \
- 0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93)
-
-#define LINUX_EFI_CRASH_GUID \
- EFI_GUID(0xcfc8fc79, 0xbe2e, 0x4ddc, \
- 0x97, 0xf0, 0x9f, 0x98, 0xbf, 0xe2, 0x98, 0xa0)
-
-#define LOADED_IMAGE_PROTOCOL_GUID \
- EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, \
- 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
-
-#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
- EFI_GUID(0x9042a9de, 0x23dc, 0x4a38, \
- 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a)
-
-#define EFI_UGA_PROTOCOL_GUID \
- EFI_GUID(0x982c298b, 0xf4fa, 0x41cb, \
- 0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39)
-
-#define EFI_PCI_IO_PROTOCOL_GUID \
- EFI_GUID(0x4cf5b200, 0x68b8, 0x4ca5, \
- 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x02, 0x9a)
-
-#define EFI_FILE_INFO_ID \
- EFI_GUID(0x9576e92, 0x6d3f, 0x11d2, \
- 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
-
-#define EFI_SYSTEM_RESOURCE_TABLE_GUID \
- EFI_GUID(0xb122a263, 0x3661, 0x4f68, \
- 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80)
-
-#define EFI_FILE_SYSTEM_GUID \
- EFI_GUID(0x964e5b22, 0x6459, 0x11d2, \
- 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
-
-#define DEVICE_TREE_GUID \
- EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5, \
- 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
-
-#define EFI_PROPERTIES_TABLE_GUID \
- EFI_GUID(0x880aaca3, 0x4adc, 0x4a04, \
- 0x90, 0x79, 0xb7, 0x47, 0x34, 0x08, 0x25, 0xe5)
-
-#define EFI_RNG_PROTOCOL_GUID \
- EFI_GUID(0x3152bca5, 0xeade, 0x433d, \
- 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44)
-
-#define EFI_MEMORY_ATTRIBUTES_TABLE_GUID \
- EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, \
- 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20)
-
-#define EFI_CONSOLE_OUT_DEVICE_GUID \
- EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, \
- 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+#define NULL_GUID EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
+#define MPS_TABLE_GUID EFI_GUID(0xeb9d2d2f, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+#define ACPI_TABLE_GUID EFI_GUID(0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+#define ACPI_20_TABLE_GUID EFI_GUID(0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81)
+#define SMBIOS_TABLE_GUID EFI_GUID(0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+#define SMBIOS3_TABLE_GUID EFI_GUID(0xf2fd1544, 0x9794, 0x4a2c, 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94)
+#define SAL_SYSTEM_TABLE_GUID EFI_GUID(0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
+#define HCDP_TABLE_GUID EFI_GUID(0xf951938d, 0x620b, 0x42ef, 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98)
+#define UGA_IO_PROTOCOL_GUID EFI_GUID(0x61a4d49e, 0x6f68, 0x4f1b, 0xb9, 0x22, 0xa8, 0x6e, 0xed, 0x0b, 0x07, 0xa2)
+#define EFI_GLOBAL_VARIABLE_GUID EFI_GUID(0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c)
+#define UV_SYSTEM_TABLE_GUID EFI_GUID(0x3b13a7d4, 0x633e, 0x11dd, 0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93)
+#define LINUX_EFI_CRASH_GUID EFI_GUID(0xcfc8fc79, 0xbe2e, 0x4ddc, 0x97, 0xf0, 0x9f, 0x98, 0xbf, 0xe2, 0x98, 0xa0)
+#define LOADED_IMAGE_PROTOCOL_GUID EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID EFI_GUID(0x9042a9de, 0x23dc, 0x4a38, 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a)
+#define EFI_UGA_PROTOCOL_GUID EFI_GUID(0x982c298b, 0xf4fa, 0x41cb, 0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39)
+#define EFI_PCI_IO_PROTOCOL_GUID EFI_GUID(0x4cf5b200, 0x68b8, 0x4ca5, 0x9e, 0xec, 0xb2, 0x3e, 0x3f, 0x50, 0x02, 0x9a)
+#define EFI_FILE_INFO_ID EFI_GUID(0x09576e92, 0x6d3f, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+#define EFI_SYSTEM_RESOURCE_TABLE_GUID EFI_GUID(0xb122a263, 0x3661, 0x4f68, 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80)
+#define EFI_FILE_SYSTEM_GUID EFI_GUID(0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+#define DEVICE_TREE_GUID EFI_GUID(0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0)
+#define EFI_PROPERTIES_TABLE_GUID EFI_GUID(0x880aaca3, 0x4adc, 0x4a04, 0x90, 0x79, 0xb7, 0x47, 0x34, 0x08, 0x25, 0xe5)
+#define EFI_RNG_PROTOCOL_GUID EFI_GUID(0x3152bca5, 0xeade, 0x433d, 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44)
+#define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20)
+#define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
/*
* This GUID is used to pass to the kernel proper the struct screen_info
* structure that was populated by the stub based on the GOP protocol instance
* associated with ConOut
*/
-#define LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID \
- EFI_GUID(0xe03fc20a, 0x85dc, 0x406e, \
- 0xb9, 0xe, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95)
-
-#define LINUX_EFI_LOADER_ENTRY_GUID \
- EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, \
- 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f)
+#define LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID EFI_GUID(0xe03fc20a, 0x85dc, 0x406e, 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95)
+#define LINUX_EFI_LOADER_ENTRY_GUID EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f)
typedef struct {
efi_guid_t guid;
@@ -975,7 +917,6 @@ extern u64 efi_mem_desc_end(efi_memory_desc_t *md);
extern int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md);
extern void efi_initialize_iomem_resources(struct resource *code_resource,
struct resource *data_resource, struct resource *bss_resource);
-extern void efi_get_time(struct timespec *now);
extern void efi_reserve_boot_services(void);
extern int efi_get_fdt_params(struct efi_fdt_params *params);
extern struct kobject *efi_kobj;
@@ -1465,4 +1406,55 @@ efi_status_t efi_setup_gop(efi_system_table_t *sys_table_arg,
unsigned long size);
bool efi_runtime_disabled(void);
+extern void efi_call_virt_check_flags(unsigned long flags, const char *call);
+
+/*
+ * Arch code can implement the following three template macros, avoiding
+ * reptition for the void/non-void return cases of {__,}efi_call_virt():
+ *
+ * * arch_efi_call_virt_setup()
+ *
+ * Sets up the environment for the call (e.g. switching page tables,
+ * allowing kernel-mode use of floating point, if required).
+ *
+ * * arch_efi_call_virt()
+ *
+ * Performs the call. The last expression in the macro must be the call
+ * itself, allowing the logic to be shared by the void and non-void
+ * cases.
+ *
+ * * arch_efi_call_virt_teardown()
+ *
+ * Restores the usual kernel environment once the call has returned.
+ */
+
+#define efi_call_virt_pointer(p, f, args...) \
+({ \
+ efi_status_t __s; \
+ unsigned long __flags; \
+ \
+ arch_efi_call_virt_setup(); \
+ \
+ local_save_flags(__flags); \
+ __s = arch_efi_call_virt(p, f, args); \
+ efi_call_virt_check_flags(__flags, __stringify(f)); \
+ \
+ arch_efi_call_virt_teardown(); \
+ \
+ __s; \
+})
+
+#define __efi_call_virt_pointer(p, f, args...) \
+({ \
+ unsigned long __flags; \
+ \
+ arch_efi_call_virt_setup(); \
+ \
+ local_save_flags(__flags); \
+ arch_efi_call_virt(p, f, args); \
+ efi_call_virt_check_flags(__flags, __stringify(f)); \
+ \
+ arch_efi_call_virt_teardown(); \
+})
+
#endif /* _LINUX_EFI_H */
diff --git a/include/linux/elevator.h b/include/linux/elevator.h
index 638b324f0291..e7f358d2e5fc 100644
--- a/include/linux/elevator.h
+++ b/include/linux/elevator.h
@@ -16,7 +16,11 @@ typedef void (elevator_merge_req_fn) (struct request_queue *, struct request *,
typedef void (elevator_merged_fn) (struct request_queue *, struct request *, int);
-typedef int (elevator_allow_merge_fn) (struct request_queue *, struct request *, struct bio *);
+typedef int (elevator_allow_bio_merge_fn) (struct request_queue *,
+ struct request *, struct bio *);
+
+typedef int (elevator_allow_rq_merge_fn) (struct request_queue *,
+ struct request *, struct request *);
typedef void (elevator_bio_merged_fn) (struct request_queue *,
struct request *, struct bio *);
@@ -26,7 +30,7 @@ typedef int (elevator_dispatch_fn) (struct request_queue *, int);
typedef void (elevator_add_req_fn) (struct request_queue *, struct request *);
typedef struct request *(elevator_request_list_fn) (struct request_queue *, struct request *);
typedef void (elevator_completed_req_fn) (struct request_queue *, struct request *);
-typedef int (elevator_may_queue_fn) (struct request_queue *, int);
+typedef int (elevator_may_queue_fn) (struct request_queue *, int, int);
typedef void (elevator_init_icq_fn) (struct io_cq *);
typedef void (elevator_exit_icq_fn) (struct io_cq *);
@@ -46,7 +50,8 @@ struct elevator_ops
elevator_merge_fn *elevator_merge_fn;
elevator_merged_fn *elevator_merged_fn;
elevator_merge_req_fn *elevator_merge_req_fn;
- elevator_allow_merge_fn *elevator_allow_merge_fn;
+ elevator_allow_bio_merge_fn *elevator_allow_bio_merge_fn;
+ elevator_allow_rq_merge_fn *elevator_allow_rq_merge_fn;
elevator_bio_merged_fn *elevator_bio_merged_fn;
elevator_dispatch_fn *elevator_dispatch_fn;
@@ -134,7 +139,7 @@ extern struct request *elv_former_request(struct request_queue *, struct request
extern struct request *elv_latter_request(struct request_queue *, struct request *);
extern int elv_register_queue(struct request_queue *q);
extern void elv_unregister_queue(struct request_queue *q);
-extern int elv_may_queue(struct request_queue *, int);
+extern int elv_may_queue(struct request_queue *, int, int);
extern void elv_completed_request(struct request_queue *, struct request *);
extern int elv_set_request(struct request_queue *q, struct request *rq,
struct bio *bio, gfp_t gfp_mask);
@@ -157,7 +162,7 @@ extern ssize_t elv_iosched_store(struct request_queue *, const char *, size_t);
extern int elevator_init(struct request_queue *, char *);
extern void elevator_exit(struct elevator_queue *);
extern int elevator_change(struct request_queue *, const char *);
-extern bool elv_rq_merge_ok(struct request *, struct bio *);
+extern bool elv_bio_merge_ok(struct request *, struct bio *);
extern struct elevator_queue *elevator_alloc(struct request_queue *,
struct elevator_type *);
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
index 37ff4a6faa9a..6fec9e81bd70 100644
--- a/include/linux/etherdevice.h
+++ b/include/linux/etherdevice.h
@@ -374,6 +374,29 @@ static inline bool ether_addr_equal_unaligned(const u8 *addr1, const u8 *addr2)
}
/**
+ * ether_addr_equal_masked - Compare two Ethernet addresses with a mask
+ * @addr1: Pointer to a six-byte array containing the 1st Ethernet address
+ * @addr2: Pointer to a six-byte array containing the 2nd Ethernet address
+ * @mask: Pointer to a six-byte array containing the Ethernet address bitmask
+ *
+ * Compare two Ethernet addresses with a mask, returns true if for every bit
+ * set in the bitmask the equivalent bits in the ethernet addresses are equal.
+ * Using a mask with all bits set is a slower ether_addr_equal.
+ */
+static inline bool ether_addr_equal_masked(const u8 *addr1, const u8 *addr2,
+ const u8 *mask)
+{
+ int i;
+
+ for (i = 0; i < ETH_ALEN; i++) {
+ if ((addr1[i] ^ addr2[i]) & mask[i])
+ return false;
+ }
+
+ return true;
+}
+
+/**
* is_etherdev_addr - Tell if given Ethernet address belongs to the device.
* @dev: Pointer to a device structure
* @addr: Pointer to a six-byte array containing the Ethernet address
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
index d8414502edb4..b03c0625fa6e 100644
--- a/include/linux/exportfs.h
+++ b/include/linux/exportfs.h
@@ -6,6 +6,7 @@
struct dentry;
struct iattr;
struct inode;
+struct iomap;
struct super_block;
struct vfsmount;
@@ -187,21 +188,6 @@ struct fid {
* get_name is not (which is possibly inconsistent)
*/
-/* types of block ranges for multipage write mappings. */
-#define IOMAP_HOLE 0x01 /* no blocks allocated, need allocation */
-#define IOMAP_DELALLOC 0x02 /* delayed allocation blocks */
-#define IOMAP_MAPPED 0x03 /* blocks allocated @blkno */
-#define IOMAP_UNWRITTEN 0x04 /* blocks allocated @blkno in unwritten state */
-
-#define IOMAP_NULL_BLOCK -1LL /* blkno is not valid */
-
-struct iomap {
- sector_t blkno; /* first sector of mapping */
- loff_t offset; /* file offset of mapping, bytes */
- u64 length; /* length of mapping, bytes */
- int type; /* type of mapping */
-};
-
struct export_operations {
int (*encode_fh)(struct inode *inode, __u32 *fh, int *max_len,
struct inode *parent);
diff --git a/include/linux/extcon.h b/include/linux/extcon.h
index 7abf674c388c..61004413dc64 100644
--- a/include/linux/extcon.h
+++ b/include/linux/extcon.h
@@ -126,42 +126,6 @@ struct extcon_dev {
struct device_attribute *d_attrs_muex;
};
-/**
- * struct extcon_cable - An internal data for each cable of extcon device.
- * @edev: The extcon device
- * @cable_index: Index of this cable in the edev
- * @attr_g: Attribute group for the cable
- * @attr_name: "name" sysfs entry
- * @attr_state: "state" sysfs entry
- * @attrs: Array pointing to attr_name and attr_state for attr_g
- */
-struct extcon_cable {
- struct extcon_dev *edev;
- int cable_index;
-
- struct attribute_group attr_g;
- struct device_attribute attr_name;
- struct device_attribute attr_state;
-
- struct attribute *attrs[3]; /* to be fed to attr_g.attrs */
-};
-
-/**
- * struct extcon_specific_cable_nb - An internal data for
- * extcon_register_interest().
- * @user_nb: user provided notifier block for events from
- * a specific cable.
- * @cable_index: the target cable.
- * @edev: the target extcon device.
- * @previous_value: the saved previous event value.
- */
-struct extcon_specific_cable_nb {
- struct notifier_block *user_nb;
- int cable_index;
- struct extcon_dev *edev;
- unsigned long previous_value;
-};
-
#if IS_ENABLED(CONFIG_EXTCON)
/*
@@ -201,29 +165,12 @@ extern int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state);
/*
* get/set_cable_state access each bit of the 32b encoded state value.
- * They are used to access the status of each cable based on the cable_name.
+ * They are used to access the status of each cable based on the cable id.
*/
extern int extcon_get_cable_state_(struct extcon_dev *edev, unsigned int id);
extern int extcon_set_cable_state_(struct extcon_dev *edev, unsigned int id,
bool cable_state);
-extern int extcon_get_cable_state(struct extcon_dev *edev,
- const char *cable_name);
-extern int extcon_set_cable_state(struct extcon_dev *edev,
- const char *cable_name, bool cable_state);
-
-/*
- * Following APIs are for notifiees (those who want to be notified)
- * to register a callback for events from a specific cable of the extcon.
- * Notifiees are the connected device drivers wanting to get notified by
- * a specific external port of a connection device.
- */
-extern int extcon_register_interest(struct extcon_specific_cable_nb *obj,
- const char *extcon_name,
- const char *cable_name,
- struct notifier_block *nb);
-extern int extcon_unregister_interest(struct extcon_specific_cable_nb *nb);
-
/*
* Following APIs are to monitor every action of a notifier.
* Registrar gets notified for every external port of a connection device.
@@ -235,6 +182,12 @@ extern int extcon_register_notifier(struct extcon_dev *edev, unsigned int id,
struct notifier_block *nb);
extern int extcon_unregister_notifier(struct extcon_dev *edev, unsigned int id,
struct notifier_block *nb);
+extern int devm_extcon_register_notifier(struct device *dev,
+ struct extcon_dev *edev, unsigned int id,
+ struct notifier_block *nb);
+extern void devm_extcon_unregister_notifier(struct device *dev,
+ struct extcon_dev *edev, unsigned int id,
+ struct notifier_block *nb);
/*
* Following API get the extcon device from devicetree.
@@ -246,6 +199,7 @@ extern struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev,
/* Following API to get information of extcon device */
extern const char *extcon_get_edev_name(struct extcon_dev *edev);
+
#else /* CONFIG_EXTCON */
static inline int extcon_dev_register(struct extcon_dev *edev)
{
@@ -306,18 +260,6 @@ static inline int extcon_set_cable_state_(struct extcon_dev *edev,
return 0;
}
-static inline int extcon_get_cable_state(struct extcon_dev *edev,
- const char *cable_name)
-{
- return 0;
-}
-
-static inline int extcon_set_cable_state(struct extcon_dev *edev,
- const char *cable_name, int state)
-{
- return 0;
-}
-
static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name)
{
return NULL;
@@ -337,19 +279,16 @@ static inline int extcon_unregister_notifier(struct extcon_dev *edev,
return 0;
}
-static inline int extcon_register_interest(struct extcon_specific_cable_nb *obj,
- const char *extcon_name,
- const char *cable_name,
- struct notifier_block *nb)
+static inline int devm_extcon_register_notifier(struct device *dev,
+ struct extcon_dev *edev, unsigned int id,
+ struct notifier_block *nb)
{
- return 0;
+ return -ENOSYS;
}
-static inline int extcon_unregister_interest(struct extcon_specific_cable_nb
- *obj)
-{
- return 0;
-}
+static inline void devm_extcon_unregister_notifier(struct device *dev,
+ struct extcon_dev *edev, unsigned int id,
+ struct notifier_block *nb) { }
static inline struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev,
int index)
@@ -357,4 +296,28 @@ static inline struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev,
return ERR_PTR(-ENODEV);
}
#endif /* CONFIG_EXTCON */
+
+/*
+ * Following structure and API are deprecated. EXTCON remains the function
+ * definition to prevent the build break.
+ */
+struct extcon_specific_cable_nb {
+ struct notifier_block *user_nb;
+ int cable_index;
+ struct extcon_dev *edev;
+ unsigned long previous_value;
+};
+
+static inline int extcon_register_interest(struct extcon_specific_cable_nb *obj,
+ const char *extcon_name, const char *cable_name,
+ struct notifier_block *nb)
+{
+ return -EINVAL;
+}
+
+static inline int extcon_unregister_interest(struct extcon_specific_cable_nb
+ *obj)
+{
+ return -EINVAL;
+}
#endif /* __LINUX_EXTCON_H__ */
diff --git a/include/linux/extcon/extcon-adc-jack.h b/include/linux/extcon/extcon-adc-jack.h
index 53c60806bcfb..ac85f2061351 100644
--- a/include/linux/extcon/extcon-adc-jack.h
+++ b/include/linux/extcon/extcon-adc-jack.h
@@ -53,6 +53,7 @@ struct adc_jack_cond {
* milli-seconds after the interrupt occurs. You may
* describe such delays with @handling_delay_ms, which
* is rounded-off by jiffies.
+ * @wakeup_source: flag to wake up the system for extcon events.
*/
struct adc_jack_pdata {
const char *name;
@@ -65,6 +66,7 @@ struct adc_jack_pdata {
unsigned long irq_flags;
unsigned long handling_delay_ms; /* in ms */
+ bool wakeup_source;
};
#endif /* _EXTCON_ADC_JACK_H */
diff --git a/include/linux/fence.h b/include/linux/fence.h
index 2056e9fd0138..1de1b3f6fb76 100644
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -81,8 +81,6 @@ struct fence {
unsigned long flags;
ktime_t timestamp;
int status;
- struct list_head child_list;
- struct list_head active_list;
};
enum fence_flag_bits {
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 8f74f3d61894..a16439b99fd9 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -368,6 +368,11 @@ struct bpf_skb_data_end {
void *data_end;
};
+struct xdp_buff {
+ void *data;
+ void *data_end;
+};
+
/* compute the linear packet data range [data, data_end) which
* will be accessed by cls_bpf and act_bpf programs
*/
@@ -429,6 +434,18 @@ static inline u32 bpf_prog_run_clear_cb(const struct bpf_prog *prog,
return BPF_PROG_RUN(prog, skb);
}
+static inline u32 bpf_prog_run_xdp(const struct bpf_prog *prog,
+ struct xdp_buff *xdp)
+{
+ u32 ret;
+
+ rcu_read_lock();
+ ret = BPF_PROG_RUN(prog, (void *)xdp);
+ rcu_read_unlock();
+
+ return ret;
+}
+
static inline unsigned int bpf_prog_size(unsigned int proglen)
{
return max(sizeof(struct bpf_prog),
@@ -513,6 +530,7 @@ bool bpf_helper_changes_skb_data(void *func);
struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
const struct bpf_insn *patch, u32 len);
+void bpf_warn_invalid_xdp_action(u32 act);
#ifdef CONFIG_BPF_JIT
extern int bpf_jit_enable;
diff --git a/include/linux/frontswap.h b/include/linux/frontswap.h
index e65ef959546c..c46d2aa16d81 100644
--- a/include/linux/frontswap.h
+++ b/include/linux/frontswap.h
@@ -4,6 +4,7 @@
#include <linux/swap.h>
#include <linux/mm.h>
#include <linux/bitops.h>
+#include <linux/jump_label.h>
struct frontswap_ops {
void (*init)(unsigned); /* this swap type was just swapon'ed */
@@ -14,7 +15,6 @@ struct frontswap_ops {
struct frontswap_ops *next; /* private pointer to next ops */
};
-extern bool frontswap_enabled;
extern void frontswap_register_ops(struct frontswap_ops *ops);
extern void frontswap_shrink(unsigned long);
extern unsigned long frontswap_curr_pages(void);
@@ -30,7 +30,12 @@ extern void __frontswap_invalidate_page(unsigned, pgoff_t);
extern void __frontswap_invalidate_area(unsigned);
#ifdef CONFIG_FRONTSWAP
-#define frontswap_enabled (1)
+extern struct static_key_false frontswap_enabled_key;
+
+static inline bool frontswap_enabled(void)
+{
+ return static_branch_unlikely(&frontswap_enabled_key);
+}
static inline bool frontswap_test(struct swap_info_struct *sis, pgoff_t offset)
{
@@ -50,7 +55,10 @@ static inline unsigned long *frontswap_map_get(struct swap_info_struct *p)
#else
/* all inline routines become no-ops and all externs are ignored */
-#define frontswap_enabled (0)
+static inline bool frontswap_enabled(void)
+{
+ return false;
+}
static inline bool frontswap_test(struct swap_info_struct *sis, pgoff_t offset)
{
@@ -70,37 +78,35 @@ static inline unsigned long *frontswap_map_get(struct swap_info_struct *p)
static inline int frontswap_store(struct page *page)
{
- int ret = -1;
+ if (frontswap_enabled())
+ return __frontswap_store(page);
- if (frontswap_enabled)
- ret = __frontswap_store(page);
- return ret;
+ return -1;
}
static inline int frontswap_load(struct page *page)
{
- int ret = -1;
+ if (frontswap_enabled())
+ return __frontswap_load(page);
- if (frontswap_enabled)
- ret = __frontswap_load(page);
- return ret;
+ return -1;
}
static inline void frontswap_invalidate_page(unsigned type, pgoff_t offset)
{
- if (frontswap_enabled)
+ if (frontswap_enabled())
__frontswap_invalidate_page(type, offset);
}
static inline void frontswap_invalidate_area(unsigned type)
{
- if (frontswap_enabled)
+ if (frontswap_enabled())
__frontswap_invalidate_area(type);
}
static inline void frontswap_init(unsigned type, unsigned long *map)
{
- if (frontswap_enabled)
+ if (frontswap_enabled())
__frontswap_init(type, map);
}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index bacc0733663c..50ccf845b56c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -152,9 +152,10 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
#define CHECK_IOVEC_ONLY -1
/*
- * The below are the various read and write types that we support. Some of
+ * The below are the various read and write flags that we support. Some of
* them include behavioral modifiers that send information down to the
- * block layer and IO scheduler. Terminology:
+ * block layer and IO scheduler. They should be used along with a req_op.
+ * Terminology:
*
* The block layer uses device plugging to defer IO a little bit, in
* the hope that we will see more IO very shortly. This increases
@@ -177,9 +178,6 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
* READ_SYNC A synchronous read. Device is not plugged, caller can
* immediately wait on this read without caring about
* unplugging.
- * READA Used for read-ahead operations. Lower priority, and the
- * block layer could (in theory) choose to ignore this
- * request if it runs into resource problems.
* WRITE A normal async write. Device will be plugged.
* WRITE_SYNC Synchronous write. Identical to WRITE, but passes down
* the hint that someone will be waiting on this IO
@@ -193,19 +191,17 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
* non-volatile media on completion.
*
*/
-#define RW_MASK REQ_WRITE
-#define RWA_MASK REQ_RAHEAD
+#define RW_MASK REQ_OP_WRITE
-#define READ 0
-#define WRITE RW_MASK
-#define READA RWA_MASK
+#define READ REQ_OP_READ
+#define WRITE REQ_OP_WRITE
-#define READ_SYNC (READ | REQ_SYNC)
-#define WRITE_SYNC (WRITE | REQ_SYNC | REQ_NOIDLE)
-#define WRITE_ODIRECT (WRITE | REQ_SYNC)
-#define WRITE_FLUSH (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FLUSH)
-#define WRITE_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FUA)
-#define WRITE_FLUSH_FUA (WRITE | REQ_SYNC | REQ_NOIDLE | REQ_FLUSH | REQ_FUA)
+#define READ_SYNC REQ_SYNC
+#define WRITE_SYNC (REQ_SYNC | REQ_NOIDLE)
+#define WRITE_ODIRECT REQ_SYNC
+#define WRITE_FLUSH (REQ_SYNC | REQ_NOIDLE | REQ_PREFLUSH)
+#define WRITE_FUA (REQ_SYNC | REQ_NOIDLE | REQ_FUA)
+#define WRITE_FLUSH_FUA (REQ_SYNC | REQ_NOIDLE | REQ_PREFLUSH | REQ_FUA)
/*
* Attribute flags. These should be or-ed together to figure out what
@@ -402,6 +398,8 @@ struct address_space_operations {
*/
int (*migratepage) (struct address_space *,
struct page *, struct page *, enum migrate_mode);
+ bool (*isolate_page)(struct page *, isolate_mode_t);
+ void (*putback_page)(struct page *);
int (*launder_page) (struct page *);
int (*is_partially_uptodate) (struct page *, unsigned long,
unsigned long);
@@ -459,7 +457,6 @@ struct block_device {
struct inode * bd_inode; /* will die */
struct super_block * bd_super;
struct mutex bd_mutex; /* open/close mutex */
- struct list_head bd_inodes;
void * bd_claiming;
void * bd_holder;
int bd_holders;
@@ -665,6 +662,7 @@ struct inode {
#endif
struct list_head i_lru; /* inode LRU list */
struct list_head i_sb_list;
+ struct list_head i_wb_list; /* backing dev writeback list */
union {
struct hlist_head i_dentry;
struct rcu_head i_rcu;
@@ -1443,6 +1441,9 @@ struct super_block {
/* s_inode_list_lock protects s_inodes */
spinlock_t s_inode_list_lock ____cacheline_aligned_in_smp;
struct list_head s_inodes; /* all inodes */
+
+ spinlock_t s_inode_wblist_lock;
+ struct list_head s_inodes_wb; /* writeback inodes */
};
extern struct timespec current_fs_time(struct super_block *sb);
@@ -2459,15 +2460,18 @@ extern void make_bad_inode(struct inode *);
extern bool is_bad_inode(struct inode *);
#ifdef CONFIG_BLOCK
-/*
- * return READ, READA, or WRITE
- */
-#define bio_rw(bio) ((bio)->bi_rw & (RW_MASK | RWA_MASK))
+static inline bool op_is_write(unsigned int op)
+{
+ return op == REQ_OP_READ ? false : true;
+}
/*
* return data direction, READ or WRITE
*/
-#define bio_data_dir(bio) ((bio)->bi_rw & 1)
+static inline int bio_data_dir(struct bio *bio)
+{
+ return op_is_write(bio_op(bio)) ? WRITE : READ;
+}
extern void check_disk_size_change(struct gendisk *disk,
struct block_device *bdev);
@@ -2742,7 +2746,7 @@ static inline void remove_inode_hash(struct inode *inode)
extern void inode_sb_list_add(struct inode *inode);
#ifdef CONFIG_BLOCK
-extern blk_qc_t submit_bio(int, struct bio *);
+extern blk_qc_t submit_bio(struct bio *);
extern int bdev_read_only(struct block_device *);
#endif
extern int set_blocksize(struct block_device *, int);
@@ -2797,7 +2801,7 @@ extern int generic_file_open(struct inode * inode, struct file * filp);
extern int nonseekable_open(struct inode * inode, struct file * filp);
#ifdef CONFIG_BLOCK
-typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
+typedef void (dio_submit_t)(struct bio *bio, struct inode *inode,
loff_t file_offset);
enum {
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index 0141f257d67b..eed9e853a06f 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -52,18 +52,6 @@ static inline int fsnotify_perm(struct file *file, int mask)
}
/*
- * fsnotify_d_move - dentry has been moved
- */
-static inline void fsnotify_d_move(struct dentry *dentry)
-{
- /*
- * On move we need to update dentry->d_flags to indicate if the new parent
- * cares about events from this dentry.
- */
- __fsnotify_update_dcache_flags(dentry);
-}
-
-/*
* fsnotify_link_count - inode's link count changed
*/
static inline void fsnotify_link_count(struct inode *inode)
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 29f917517299..58205f33af02 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -267,10 +267,8 @@ static inline int fsnotify_inode_watches_children(struct inode *inode)
* Update the dentry with a flag indicating the interest of its parent to receive
* filesystem events when those events happens to this dentry->d_inode.
*/
-static inline void __fsnotify_update_dcache_flags(struct dentry *dentry)
+static inline void fsnotify_update_flags(struct dentry *dentry)
{
- struct dentry *parent;
-
assert_spin_locked(&dentry->d_lock);
/*
@@ -280,21 +278,12 @@ static inline void __fsnotify_update_dcache_flags(struct dentry *dentry)
* find our entry, so it will spin until we complete here, and update
* us with the new state.
*/
- parent = dentry->d_parent;
- if (parent->d_inode && fsnotify_inode_watches_children(parent->d_inode))
+ if (fsnotify_inode_watches_children(dentry->d_parent->d_inode))
dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED;
else
dentry->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED;
}
-/*
- * fsnotify_d_instantiate - instantiate a dentry for inode
- */
-static inline void __fsnotify_d_instantiate(struct dentry *dentry)
-{
- __fsnotify_update_dcache_flags(dentry);
-}
-
/* called from fsnotify listeners, such as fanotify or dnotify */
/* create a new group */
@@ -386,10 +375,7 @@ static inline void __fsnotify_inode_delete(struct inode *inode)
static inline void __fsnotify_vfsmount_delete(struct vfsmount *mnt)
{}
-static inline void __fsnotify_update_dcache_flags(struct dentry *dentry)
-{}
-
-static inline void __fsnotify_d_instantiate(struct dentry *dentry)
+static inline void fsnotify_update_flags(struct dentry *dentry)
{}
static inline u32 fsnotify_get_cookie(void)
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 66a36a815f0a..7d565afe35d2 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -754,23 +754,27 @@ static inline void ftrace_init(void) { }
/*
* Structure that defines an entry function trace.
+ * It's already packed but the attribute "packed" is needed
+ * to remove extra padding at the end.
*/
struct ftrace_graph_ent {
unsigned long func; /* Current function */
int depth;
-};
+} __packed;
/*
* Structure that defines a return function trace.
+ * It's already packed but the attribute "packed" is needed
+ * to remove extra padding at the end.
*/
struct ftrace_graph_ret {
unsigned long func; /* Current function */
- unsigned long long calltime;
- unsigned long long rettime;
/* Number of functions that overran the depth limit for current task */
unsigned long overrun;
+ unsigned long long calltime;
+ unsigned long long rettime;
int depth;
-};
+} __packed;
/* Type of the callback handlers for tracing function graph*/
typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *); /* return */
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 359a8e4bd44d..1dbf52f9c24b 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -205,7 +205,6 @@ struct gendisk {
void *private_data;
int flags;
- struct device *driverfs_dev; // FIXME: remove
struct kobject *slave_dir;
struct timer_rand_state *random;
@@ -414,7 +413,12 @@ static inline void free_part_info(struct hd_struct *part)
extern void part_round_stats(int cpu, struct hd_struct *part);
/* block/genhd.c */
-extern void add_disk(struct gendisk *disk);
+extern void device_add_disk(struct device *parent, struct gendisk *disk);
+static inline void add_disk(struct gendisk *disk)
+{
+ device_add_disk(NULL, disk);
+}
+
extern void del_gendisk(struct gendisk *gp);
extern struct gendisk *get_gendisk(dev_t dev, int *partno);
extern struct block_device *bdget_disk(struct gendisk *disk, int partno);
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 570383a41853..f8041f9de31e 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -78,8 +78,7 @@ struct vm_area_struct;
* __GFP_THISNODE forces the allocation to be satisified from the requested
* node with no fallbacks or placement policy enforcements.
*
- * __GFP_ACCOUNT causes the allocation to be accounted to kmemcg (only relevant
- * to kmem allocations).
+ * __GFP_ACCOUNT causes the allocation to be accounted to kmemcg.
*/
#define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE)
#define __GFP_WRITE ((__force gfp_t)___GFP_WRITE)
@@ -238,9 +237,11 @@ struct vm_area_struct;
* are expected to be movable via page reclaim or page migration. Typically,
* pages on the LRU would also be allocated with GFP_HIGHUSER_MOVABLE.
*
- * GFP_TRANSHUGE is used for THP allocations. They are compound allocations
- * that will fail quickly if memory is not available and will not wake
- * kswapd on failure.
+ * GFP_TRANSHUGE and GFP_TRANSHUGE_LIGHT are used for THP allocations. They are
+ * compound allocations that will generally fail quickly if memory is not
+ * available and will not wake kswapd/kcompactd on failure. The _LIGHT
+ * version does not attempt reclaim/compaction at all and is by default used
+ * in page fault path, while the non-light is used by khugepaged.
*/
#define GFP_ATOMIC (__GFP_HIGH|__GFP_ATOMIC|__GFP_KSWAPD_RECLAIM)
#define GFP_KERNEL (__GFP_RECLAIM | __GFP_IO | __GFP_FS)
@@ -255,9 +256,9 @@ struct vm_area_struct;
#define GFP_DMA32 __GFP_DMA32
#define GFP_HIGHUSER (GFP_USER | __GFP_HIGHMEM)
#define GFP_HIGHUSER_MOVABLE (GFP_HIGHUSER | __GFP_MOVABLE)
-#define GFP_TRANSHUGE ((GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
- __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN) & \
- ~__GFP_RECLAIM)
+#define GFP_TRANSHUGE_LIGHT ((GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
+ __GFP_NOMEMALLOC | __GFP_NOWARN) & ~__GFP_RECLAIM)
+#define GFP_TRANSHUGE (GFP_TRANSHUGE_LIGHT | __GFP_DIRECT_RECLAIM)
/* Convert GFP flags to their corresponding migrate type */
#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE)
@@ -486,10 +487,6 @@ extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order,
#define alloc_page_vma_node(gfp_mask, vma, addr, node) \
alloc_pages_vma(gfp_mask, 0, vma, addr, node, false)
-extern struct page *alloc_kmem_pages(gfp_t gfp_mask, unsigned int order);
-extern struct page *alloc_kmem_pages_node(int nid, gfp_t gfp_mask,
- unsigned int order);
-
extern unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order);
extern unsigned long get_zeroed_page(gfp_t gfp_mask);
@@ -513,9 +510,6 @@ extern void *__alloc_page_frag(struct page_frag_cache *nc,
unsigned int fragsz, gfp_t gfp_mask);
extern void __free_page_frag(void *addr);
-extern void __free_kmem_pages(struct page *page, unsigned int order);
-extern void free_kmem_pages(unsigned long addr, unsigned int order);
-
#define __free_page(page) __free_pages((page), 0)
#define free_page(addr) free_pages((addr), 0)
diff --git a/include/linux/hsi/hsi.h b/include/linux/hsi/hsi.h
index 2790591c77cf..57402544b53f 100644
--- a/include/linux/hsi/hsi.h
+++ b/include/linux/hsi/hsi.h
@@ -246,7 +246,7 @@ struct hsi_port {
int (*stop_tx)(struct hsi_client *cl);
int (*release)(struct hsi_client *cl);
/* private */
- struct atomic_notifier_head n_head;
+ struct blocking_notifier_head n_head;
};
#define to_hsi_port(dev) container_of(dev, struct hsi_port, device)
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index f0a7a0320300..6f14de45b5ce 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -1,25 +1,17 @@
#ifndef _LINUX_HUGE_MM_H
#define _LINUX_HUGE_MM_H
-extern int do_huge_pmd_anonymous_page(struct mm_struct *mm,
- struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmd,
- unsigned int flags);
+extern int do_huge_pmd_anonymous_page(struct fault_env *fe);
extern int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long addr,
struct vm_area_struct *vma);
-extern void huge_pmd_set_accessed(struct mm_struct *mm,
- struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmd,
- pmd_t orig_pmd, int dirty);
-extern int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long address, pmd_t *pmd,
- pmd_t orig_pmd);
+extern void huge_pmd_set_accessed(struct fault_env *fe, pmd_t orig_pmd);
+extern int do_huge_pmd_wp_page(struct fault_env *fe, pmd_t orig_pmd);
extern struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
unsigned long addr,
pmd_t *pmd,
unsigned int flags);
-extern int madvise_free_huge_pmd(struct mmu_gather *tlb,
+extern bool madvise_free_huge_pmd(struct mmu_gather *tlb,
struct vm_area_struct *vma,
pmd_t *pmd, unsigned long addr, unsigned long next);
extern int zap_huge_pmd(struct mmu_gather *tlb,
@@ -49,6 +41,18 @@ enum transparent_hugepage_flag {
#endif
};
+struct kobject;
+struct kobj_attribute;
+
+extern ssize_t single_hugepage_flag_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count,
+ enum transparent_hugepage_flag flag);
+extern ssize_t single_hugepage_flag_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf,
+ enum transparent_hugepage_flag flag);
+extern struct kobj_attribute shmem_enabled_attr;
+
#define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
#define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
@@ -134,8 +138,7 @@ static inline int hpage_nr_pages(struct page *page)
return 1;
}
-extern int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long addr, pmd_t pmd, pmd_t *pmdp);
+extern int do_huge_pmd_numa_page(struct fault_env *fe, pmd_t orig_pmd);
extern struct page *huge_zero_page;
@@ -152,6 +155,8 @@ static inline bool is_huge_zero_pmd(pmd_t pmd)
struct page *get_huge_zero_page(void);
void put_huge_zero_page(void);
+#define mk_huge_pmd(page, prot) pmd_mkhuge(mk_pmd(page, prot))
+
#else /* CONFIG_TRANSPARENT_HUGEPAGE */
#define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
#define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; })
@@ -161,6 +166,8 @@ void put_huge_zero_page(void);
#define transparent_hugepage_enabled(__vma) 0
+static inline void prep_transhuge_page(struct page *page) {}
+
#define transparent_hugepage_flags 0UL
static inline int
split_huge_page_to_list(struct page *page, struct list_head *list)
@@ -196,8 +203,7 @@ static inline spinlock_t *pmd_trans_huge_lock(pmd_t *pmd,
return NULL;
}
-static inline int do_huge_pmd_numa_page(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long addr, pmd_t pmd, pmd_t *pmdp)
+static inline int do_huge_pmd_numa_page(struct fault_env *fe, pmd_t orig_pmd)
{
return 0;
}
diff --git a/include/linux/i2c-smbus.h b/include/linux/i2c-smbus.h
index 8f1b086ca5bc..c2e3324f9468 100644
--- a/include/linux/i2c-smbus.h
+++ b/include/linux/i2c-smbus.h
@@ -23,6 +23,8 @@
#define _LINUX_I2C_SMBUS_H
#include <linux/i2c.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
/**
@@ -48,4 +50,31 @@ struct i2c_client *i2c_setup_smbus_alert(struct i2c_adapter *adapter,
struct i2c_smbus_alert_setup *setup);
int i2c_handle_smbus_alert(struct i2c_client *ara);
+/**
+ * smbus_host_notify - internal structure used by the Host Notify mechanism.
+ * @adapter: the I2C adapter associated with this struct
+ * @work: worker used to schedule the IRQ in the slave device
+ * @lock: spinlock to check if a notification is already pending
+ * @pending: flag set when a notification is pending (any new notification will
+ * be rejected if pending is true)
+ * @payload: the actual payload of the Host Notify event
+ * @addr: the address of the slave device which raised the notification
+ *
+ * This struct needs to be allocated by i2c_setup_smbus_host_notify() and does
+ * not need to be freed. Internally, i2c_setup_smbus_host_notify() uses a
+ * managed resource to clean this up when the adapter get released.
+ */
+struct smbus_host_notify {
+ struct i2c_adapter *adapter;
+ struct work_struct work;
+ spinlock_t lock;
+ bool pending;
+ u16 payload;
+ u8 addr;
+};
+
+struct smbus_host_notify *i2c_setup_smbus_host_notify(struct i2c_adapter *adap);
+int i2c_handle_smbus_host_notify(struct smbus_host_notify *host_notify,
+ unsigned short addr, unsigned int data);
+
#endif /* _LINUX_I2C_SMBUS_H */
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 96a25ae14494..fffdc270ca18 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -126,6 +126,11 @@ i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client,
u8 command, u8 length, u8 *values);
#endif /* I2C */
+enum i2c_alert_protocol {
+ I2C_PROTOCOL_SMBUS_ALERT,
+ I2C_PROTOCOL_SMBUS_HOST_NOTIFY,
+};
+
/**
* struct i2c_driver - represent an I2C device driver
* @class: What kind of i2c device we instantiate (for detect)
@@ -180,8 +185,11 @@ struct i2c_driver {
* The format and meaning of the data value depends on the protocol.
* For the SMBus alert protocol, there is a single bit of data passed
* as the alert response's low bit ("event flag").
+ * For the SMBus Host Notify protocol, the data corresponds to the
+ * 16-bit payload data reported by the slave device acting as master.
*/
- void (*alert)(struct i2c_client *, unsigned int data);
+ void (*alert)(struct i2c_client *, enum i2c_alert_protocol protocol,
+ unsigned int data);
/* a ioctl like command that can be used to perform specific functions
* with the device.
@@ -349,6 +357,11 @@ extern int i2c_probe_func_quick_read(struct i2c_adapter *, unsigned short addr);
extern struct i2c_client *
i2c_new_dummy(struct i2c_adapter *adap, u16 address);
+extern struct i2c_client *
+i2c_new_secondary_device(struct i2c_client *client,
+ const char *name,
+ u16 default_addr);
+
extern void i2c_unregister_device(struct i2c_client *);
#endif /* I2C */
diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index 630f45335c73..57086e9fc64c 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -14,9 +14,12 @@ static inline struct icmp6hdr *icmp6_hdr(const struct sk_buff *skb)
#if IS_ENABLED(CONFIG_IPV6)
extern void icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info);
-typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info);
+typedef void ip6_icmp_send_t(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+ const struct in6_addr *force_saddr);
extern int inet6_register_icmp_sender(ip6_icmp_send_t *fn);
extern int inet6_unregister_icmp_sender(ip6_icmp_send_t *fn);
+int ip6_err_gen_icmpv6_unreach(struct sk_buff *skb, int nhs, int type,
+ unsigned int data_len);
#else
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index b118744d3382..a80516fd65c8 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -19,6 +19,7 @@
#include <linux/types.h>
#include <linux/if_ether.h>
+#include <linux/etherdevice.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
@@ -2464,7 +2465,7 @@ static inline bool _ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
*/
static inline bool ieee80211_is_robust_mgmt_frame(struct sk_buff *skb)
{
- if (skb->len < 25)
+ if (skb->len < IEEE80211_MIN_ACTION_SIZE)
return false;
return _ieee80211_is_robust_mgmt_frame((void *)skb->data);
}
@@ -2487,6 +2488,35 @@ static inline bool ieee80211_is_public_action(struct ieee80211_hdr *hdr,
}
/**
+ * _ieee80211_is_group_privacy_action - check if frame is a group addressed
+ * privacy action frame
+ * @hdr: the frame
+ */
+static inline bool _ieee80211_is_group_privacy_action(struct ieee80211_hdr *hdr)
+{
+ struct ieee80211_mgmt *mgmt = (void *)hdr;
+
+ if (!ieee80211_is_action(hdr->frame_control) ||
+ !is_multicast_ether_addr(hdr->addr1))
+ return false;
+
+ return mgmt->u.action.category == WLAN_CATEGORY_MESH_ACTION ||
+ mgmt->u.action.category == WLAN_CATEGORY_MULTIHOP_ACTION;
+}
+
+/**
+ * ieee80211_is_group_privacy_action - check if frame is a group addressed
+ * privacy action frame
+ * @skb: the skb containing the frame, length will be checked
+ */
+static inline bool ieee80211_is_group_privacy_action(struct sk_buff *skb)
+{
+ if (skb->len < IEEE80211_MIN_ACTION_SIZE)
+ return false;
+ return _ieee80211_is_group_privacy_action((void *)skb->data);
+}
+
+/**
* ieee80211_tu_to_usec - convert time units (TU) to microseconds
* @tu: the TUs
*/
diff --git a/include/linux/ieee802154.h b/include/linux/ieee802154.h
index acedbb68a5a3..ddb890174a0e 100644
--- a/include/linux/ieee802154.h
+++ b/include/linux/ieee802154.h
@@ -31,6 +31,8 @@
#define IEEE802154_MIN_PSDU_LEN 9
#define IEEE802154_FCS_LEN 2
#define IEEE802154_MAX_AUTH_TAG_LEN 16
+#define IEEE802154_FC_LEN 2
+#define IEEE802154_SEQ_LEN 1
/* General MAC frame format:
* 2 bytes: Frame Control
@@ -48,6 +50,7 @@
#define IEEE802154_EXTENDED_ADDR_LEN 8
#define IEEE802154_SHORT_ADDR_LEN 2
+#define IEEE802154_PAN_ID_LEN 2
#define IEEE802154_LIFS_PERIOD 40
#define IEEE802154_SIFS_PERIOD 12
@@ -221,9 +224,17 @@ enum {
#define IEEE802154_FCTL_ACKREQ 0x0020
#define IEEE802154_FCTL_SECEN 0x0004
#define IEEE802154_FCTL_INTRA_PAN 0x0040
+#define IEEE802154_FCTL_DADDR 0x0c00
+#define IEEE802154_FCTL_SADDR 0xc000
#define IEEE802154_FTYPE_DATA 0x0001
+#define IEEE802154_FCTL_ADDR_NONE 0x0000
+#define IEEE802154_FCTL_DADDR_SHORT 0x0800
+#define IEEE802154_FCTL_DADDR_EXTENDED 0x0c00
+#define IEEE802154_FCTL_SADDR_SHORT 0x8000
+#define IEEE802154_FCTL_SADDR_EXTENDED 0xc000
+
/*
* ieee802154_is_data - check if type is IEEE802154_FTYPE_DATA
* @fc: frame control bytes in little-endian byteorder
@@ -261,6 +272,24 @@ static inline bool ieee802154_is_intra_pan(__le16 fc)
return fc & cpu_to_le16(IEEE802154_FCTL_INTRA_PAN);
}
+/*
+ * ieee802154_daddr_mode - get daddr mode from fc
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline __le16 ieee802154_daddr_mode(__le16 fc)
+{
+ return fc & cpu_to_le16(IEEE802154_FCTL_DADDR);
+}
+
+/*
+ * ieee802154_saddr_mode - get saddr mode from fc
+ * @fc: frame control bytes in little-endian byteorder
+ */
+static inline __le16 ieee802154_saddr_mode(__le16 fc)
+{
+ return fc & cpu_to_le16(IEEE802154_FCTL_SADDR);
+}
+
/**
* ieee802154_is_valid_psdu_len - check if psdu len is valid
* available lengths:
diff --git a/include/linux/iio/common/st_sensors.h b/include/linux/iio/common/st_sensors.h
index 99403b19092f..228bd44efa4c 100644
--- a/include/linux/iio/common/st_sensors.h
+++ b/include/linux/iio/common/st_sensors.h
@@ -223,6 +223,7 @@ struct st_sensor_settings {
* @get_irq_data_ready: Function to get the IRQ used for data ready signal.
* @tf: Transfer function structure used by I/O operations.
* @tb: Transfer buffers and mutex used by I/O operations.
+ * @edge_irq: the IRQ triggers on edges and need special handling.
* @hw_irq_trigger: if we're using the hardware interrupt on the sensor.
* @hw_timestamp: Latest timestamp from the interrupt handler, when in use.
*/
@@ -250,14 +251,13 @@ struct st_sensor_data {
const struct st_sensor_transfer_function *tf;
struct st_sensor_transfer_buffer tb;
+ bool edge_irq;
bool hw_irq_trigger;
s64 hw_timestamp;
};
#ifdef CONFIG_IIO_BUFFER
irqreturn_t st_sensors_trigger_handler(int irq, void *p);
-
-int st_sensors_get_buffer_element(struct iio_dev *indio_dev, u8 *buf);
#endif
#ifdef CONFIG_IIO_TRIGGER
@@ -287,7 +287,7 @@ int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable);
int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable);
-void st_sensors_power_enable(struct iio_dev *indio_dev);
+int st_sensors_power_enable(struct iio_dev *indio_dev);
void st_sensors_power_disable(struct iio_dev *indio_dev);
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 7c29cb0124ae..854e2dad1e0d 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -312,13 +312,8 @@ static inline bool iio_channel_has_info(const struct iio_chan_spec *chan,
}, \
}
-/**
- * iio_get_time_ns() - utility function to get a time stamp for events etc
- **/
-static inline s64 iio_get_time_ns(void)
-{
- return ktime_get_real_ns();
-}
+s64 iio_get_time_ns(const struct iio_dev *indio_dev);
+unsigned int iio_get_time_res(const struct iio_dev *indio_dev);
/* Device operating modes */
#define INDIO_DIRECT_MODE 0x01
@@ -497,6 +492,7 @@ struct iio_buffer_setup_ops {
* @chan_attr_group: [INTERN] group for all attrs in base directory
* @name: [DRIVER] name of the device.
* @info: [DRIVER] callbacks and constant info from driver
+ * @clock_id: [INTERN] timestamping clock posix identifier
* @info_exist_lock: [INTERN] lock to prevent use during removal
* @setup_ops: [DRIVER] callbacks to call before and after buffer
* enable/disable
@@ -537,6 +533,7 @@ struct iio_dev {
struct attribute_group chan_attr_group;
const char *name;
const struct iio_info *info;
+ clockid_t clock_id;
struct mutex info_exist_lock;
const struct iio_buffer_setup_ops *setup_ops;
struct cdev chrdev;
@@ -565,7 +562,7 @@ extern struct bus_type iio_bus_type;
/**
* iio_device_put() - reference counted deallocation of struct device
- * @indio_dev: IIO device structure containing the device
+ * @indio_dev: IIO device structure containing the device
**/
static inline void iio_device_put(struct iio_dev *indio_dev)
{
@@ -574,6 +571,15 @@ static inline void iio_device_put(struct iio_dev *indio_dev)
}
/**
+ * iio_device_get_clock() - Retrieve current timestamping clock for the device
+ * @indio_dev: IIO device structure containing the device
+ */
+static inline clockid_t iio_device_get_clock(const struct iio_dev *indio_dev)
+{
+ return indio_dev->clock_id;
+}
+
+/**
* dev_to_iio_dev() - Get IIO device struct from a device struct
* @dev: The device embedded in the IIO device
*
diff --git a/include/linux/iio/sw_device.h b/include/linux/iio/sw_device.h
new file mode 100644
index 000000000000..23ca41515527
--- /dev/null
+++ b/include/linux/iio/sw_device.h
@@ -0,0 +1,70 @@
+/*
+ * Industrial I/O software device interface
+ *
+ * Copyright (c) 2016 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#ifndef __IIO_SW_DEVICE
+#define __IIO_SW_DEVICE
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/iio/iio.h>
+#include <linux/configfs.h>
+
+#define module_iio_sw_device_driver(__iio_sw_device_type) \
+ module_driver(__iio_sw_device_type, iio_register_sw_device_type, \
+ iio_unregister_sw_device_type)
+
+struct iio_sw_device_ops;
+
+struct iio_sw_device_type {
+ const char *name;
+ struct module *owner;
+ const struct iio_sw_device_ops *ops;
+ struct list_head list;
+ struct config_group *group;
+};
+
+struct iio_sw_device {
+ struct iio_dev *device;
+ struct iio_sw_device_type *device_type;
+ struct config_group group;
+};
+
+struct iio_sw_device_ops {
+ struct iio_sw_device* (*probe)(const char *);
+ int (*remove)(struct iio_sw_device *);
+};
+
+static inline
+struct iio_sw_device *to_iio_sw_device(struct config_item *item)
+{
+ return container_of(to_config_group(item), struct iio_sw_device,
+ group);
+}
+
+int iio_register_sw_device_type(struct iio_sw_device_type *dt);
+void iio_unregister_sw_device_type(struct iio_sw_device_type *dt);
+
+struct iio_sw_device *iio_sw_device_create(const char *, const char *);
+void iio_sw_device_destroy(struct iio_sw_device *);
+
+int iio_sw_device_type_configfs_register(struct iio_sw_device_type *dt);
+void iio_sw_device_type_configfs_unregister(struct iio_sw_device_type *dt);
+
+static inline
+void iio_swd_group_init_type_name(struct iio_sw_device *d,
+ const char *name,
+ struct config_item_type *type)
+{
+#ifdef CONFIG_CONFIGFS_FS
+ config_group_init_type_name(&d->group, name, type);
+#endif
+}
+
+#endif /* __IIO_SW_DEVICE */
diff --git a/include/linux/input.h b/include/linux/input.h
index 1e967694e9a5..a65e3b24fb18 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -95,7 +95,7 @@ struct input_value {
* @grab: input handle that currently has the device grabbed (via
* EVIOCGRAB ioctl). When a handle grabs a device it becomes sole
* recipient for all input events coming from the device
- * @event_lock: this spinlock is is taken when input core receives
+ * @event_lock: this spinlock is taken when input core receives
* and processes a new event for the device (in input_event()).
* Code that accesses and/or modifies parameters of a device
* (such as keymap or absmin, absmax, absfuzz, etc.) after device
diff --git a/include/linux/input/touchscreen.h b/include/linux/input/touchscreen.h
index c91e1376132b..09d22ccb9e41 100644
--- a/include/linux/input/touchscreen.h
+++ b/include/linux/input/touchscreen.h
@@ -10,7 +10,26 @@
#define _TOUCHSCREEN_H
struct input_dev;
+struct input_mt_pos;
-void touchscreen_parse_properties(struct input_dev *dev, bool multitouch);
+struct touchscreen_properties {
+ unsigned int max_x;
+ unsigned int max_y;
+ bool invert_x;
+ bool invert_y;
+ bool swap_x_y;
+};
+
+void touchscreen_parse_properties(struct input_dev *input, bool multitouch,
+ struct touchscreen_properties *prop);
+
+void touchscreen_set_mt_pos(struct input_mt_pos *pos,
+ const struct touchscreen_properties *prop,
+ unsigned int x, unsigned int y);
+
+void touchscreen_report_pos(struct input_dev *input,
+ const struct touchscreen_properties *prop,
+ unsigned int x, unsigned int y,
+ bool multitouch);
#endif
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 9fcabeb07787..b6683f0ffc9f 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -278,6 +278,8 @@ extern int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m);
extern int
irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify);
+struct cpumask *irq_create_affinity_mask(unsigned int *nr_vecs);
+
#else /* CONFIG_SMP */
static inline int irq_set_affinity(unsigned int irq, const struct cpumask *m)
@@ -308,6 +310,12 @@ irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify)
{
return 0;
}
+
+static inline struct cpumask *irq_create_affinity_mask(unsigned int *nr_vecs)
+{
+ *nr_vecs = 1;
+ return NULL;
+}
#endif /* CONFIG_SMP */
/*
diff --git a/include/linux/iomap.h b/include/linux/iomap.h
new file mode 100644
index 000000000000..3267df461012
--- /dev/null
+++ b/include/linux/iomap.h
@@ -0,0 +1,70 @@
+#ifndef LINUX_IOMAP_H
+#define LINUX_IOMAP_H 1
+
+#include <linux/types.h>
+
+struct fiemap_extent_info;
+struct inode;
+struct iov_iter;
+struct kiocb;
+struct vm_area_struct;
+struct vm_fault;
+
+/*
+ * Types of block ranges for iomap mappings:
+ */
+#define IOMAP_HOLE 0x01 /* no blocks allocated, need allocation */
+#define IOMAP_DELALLOC 0x02 /* delayed allocation blocks */
+#define IOMAP_MAPPED 0x03 /* blocks allocated @blkno */
+#define IOMAP_UNWRITTEN 0x04 /* blocks allocated @blkno in unwritten state */
+
+/*
+ * Magic value for blkno:
+ */
+#define IOMAP_NULL_BLOCK -1LL /* blkno is not valid */
+
+struct iomap {
+ sector_t blkno; /* 1st sector of mapping, 512b units */
+ loff_t offset; /* file offset of mapping, bytes */
+ u64 length; /* length of mapping, bytes */
+ int type; /* type of mapping */
+ struct block_device *bdev; /* block device for I/O */
+};
+
+/*
+ * Flags for iomap_begin / iomap_end. No flag implies a read.
+ */
+#define IOMAP_WRITE (1 << 0)
+#define IOMAP_ZERO (1 << 1)
+
+struct iomap_ops {
+ /*
+ * Return the existing mapping at pos, or reserve space starting at
+ * pos for up to length, as long as we can do it as a single mapping.
+ * The actual length is returned in iomap->length.
+ */
+ int (*iomap_begin)(struct inode *inode, loff_t pos, loff_t length,
+ unsigned flags, struct iomap *iomap);
+
+ /*
+ * Commit and/or unreserve space previous allocated using iomap_begin.
+ * Written indicates the length of the successful write operation which
+ * needs to be commited, while the rest needs to be unreserved.
+ * Written might be zero if no data was written.
+ */
+ int (*iomap_end)(struct inode *inode, loff_t pos, loff_t length,
+ ssize_t written, unsigned flags, struct iomap *iomap);
+};
+
+ssize_t iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *from,
+ struct iomap_ops *ops);
+int iomap_zero_range(struct inode *inode, loff_t pos, loff_t len,
+ bool *did_zero, struct iomap_ops *ops);
+int iomap_truncate_page(struct inode *inode, loff_t pos, bool *did_zero,
+ struct iomap_ops *ops);
+int iomap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
+ struct iomap_ops *ops);
+int iomap_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+ loff_t start, loff_t len, struct iomap_ops *ops);
+
+#endif /* LINUX_IOMAP_H */
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
index 838dbfa3c331..78c5d5ae3857 100644
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -277,7 +277,7 @@ int ipmi_validate_addr(struct ipmi_addr *addr, int len);
*/
enum ipmi_addr_src {
SI_INVALID = 0, SI_HOTMOD, SI_HARDCODED, SI_SPMI, SI_ACPI, SI_SMBIOS,
- SI_PCI, SI_DEVICETREE, SI_DEFAULT
+ SI_PCI, SI_DEVICETREE, SI_LAST
};
const char *ipmi_addr_src_to_str(enum ipmi_addr_src src);
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 5c91b0b055d4..c6dbcd84a2c7 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -283,6 +283,8 @@ struct tcp6_timewait_sock {
};
#if IS_ENABLED(CONFIG_IPV6)
+bool ipv6_mod_enabled(void);
+
static inline struct ipv6_pinfo *inet6_sk(const struct sock *__sk)
{
return sk_fullsock(__sk) ? inet_sk(__sk)->pinet6 : NULL;
@@ -326,6 +328,11 @@ static inline int inet_v6_ipv6only(const struct sock *sk)
#define ipv6_only_sock(sk) 0
#define ipv6_sk_rxinfo(sk) 0
+static inline bool ipv6_mod_enabled(void)
+{
+ return false;
+}
+
static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk)
{
return NULL;
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 4d758a7c604a..b52424eaa0ed 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -197,6 +197,7 @@ struct irq_data {
* IRQD_IRQ_INPROGRESS - In progress state of the interrupt
* IRQD_WAKEUP_ARMED - Wakeup mode armed
* IRQD_FORWARDED_TO_VCPU - The interrupt is forwarded to a VCPU
+ * IRQD_AFFINITY_MANAGED - Affinity is auto-managed by the kernel
*/
enum {
IRQD_TRIGGER_MASK = 0xf,
@@ -212,6 +213,7 @@ enum {
IRQD_IRQ_INPROGRESS = (1 << 18),
IRQD_WAKEUP_ARMED = (1 << 19),
IRQD_FORWARDED_TO_VCPU = (1 << 20),
+ IRQD_AFFINITY_MANAGED = (1 << 21),
};
#define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors)
@@ -305,6 +307,11 @@ static inline void irqd_clr_forwarded_to_vcpu(struct irq_data *d)
__irqd_to_state(d) &= ~IRQD_FORWARDED_TO_VCPU;
}
+static inline bool irqd_affinity_is_managed(struct irq_data *d)
+{
+ return __irqd_to_state(d) & IRQD_AFFINITY_MANAGED;
+}
+
#undef __irqd_to_state
static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
@@ -315,6 +322,7 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
/**
* struct irq_chip - hardware interrupt chip descriptor
*
+ * @parent_device: pointer to parent device for irqchip
* @name: name for /proc/interrupts
* @irq_startup: start up the interrupt (defaults to ->enable if NULL)
* @irq_shutdown: shut down the interrupt (defaults to ->disable if NULL)
@@ -354,6 +362,7 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
* @flags: chip specific flags
*/
struct irq_chip {
+ struct device *parent_device;
const char *name;
unsigned int (*irq_startup)(struct irq_data *data);
void (*irq_shutdown)(struct irq_data *data);
@@ -482,12 +491,15 @@ extern void handle_fasteoi_irq(struct irq_desc *desc);
extern void handle_edge_irq(struct irq_desc *desc);
extern void handle_edge_eoi_irq(struct irq_desc *desc);
extern void handle_simple_irq(struct irq_desc *desc);
+extern void handle_untracked_irq(struct irq_desc *desc);
extern void handle_percpu_irq(struct irq_desc *desc);
extern void handle_percpu_devid_irq(struct irq_desc *desc);
extern void handle_bad_irq(struct irq_desc *desc);
extern void handle_nested_irq(unsigned int irq);
extern int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg);
+extern int irq_chip_pm_get(struct irq_data *data);
+extern int irq_chip_pm_put(struct irq_data *data);
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
extern void irq_chip_enable_parent(struct irq_data *data);
extern void irq_chip_disable_parent(struct irq_data *data);
@@ -701,11 +713,11 @@ static inline struct cpumask *irq_data_get_affinity_mask(struct irq_data *d)
unsigned int arch_dynirq_lower_bound(unsigned int from);
int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
- struct module *owner);
+ struct module *owner, const struct cpumask *affinity);
/* use macros to avoid needing export.h for THIS_MODULE */
#define irq_alloc_descs(irq, from, cnt, node) \
- __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE)
+ __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE, NULL)
#define irq_alloc_desc(node) \
irq_alloc_descs(-1, 0, 1, node)
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index dc493e0f0ff7..107eed475b94 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -204,6 +204,7 @@
#define GITS_BASER_NR_REGS 8
#define GITS_BASER_VALID (1UL << 63)
+#define GITS_BASER_INDIRECT (1UL << 62)
#define GITS_BASER_nCnB (0UL << 59)
#define GITS_BASER_nC (1UL << 59)
#define GITS_BASER_RaWt (2UL << 59)
@@ -228,6 +229,7 @@
#define GITS_BASER_PAGE_SIZE_64K (2UL << GITS_BASER_PAGE_SIZE_SHIFT)
#define GITS_BASER_PAGE_SIZE_MASK (3UL << GITS_BASER_PAGE_SIZE_SHIFT)
#define GITS_BASER_PAGES_MAX 256
+#define GITS_BASER_PAGES_SHIFT (0)
#define GITS_BASER_TYPE_NONE 0
#define GITS_BASER_TYPE_DEVICE 1
@@ -238,6 +240,8 @@
#define GITS_BASER_TYPE_RESERVED6 6
#define GITS_BASER_TYPE_RESERVED7 7
+#define GITS_LVL1_ENTRY_SIZE (8UL)
+
/*
* ITS commands
*/
diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h
index fd051855539b..eafc965b3eb8 100644
--- a/include/linux/irqchip/arm-gic.h
+++ b/include/linux/irqchip/arm-gic.h
@@ -101,9 +101,14 @@
#include <linux/irqdomain.h>
struct device_node;
+struct gic_chip_data;
void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
int gic_cpu_if_down(unsigned int gic_nr);
+void gic_cpu_save(struct gic_chip_data *gic);
+void gic_cpu_restore(struct gic_chip_data *gic);
+void gic_dist_save(struct gic_chip_data *gic);
+void gic_dist_restore(struct gic_chip_data *gic);
/*
* Subdrivers that need some preparatory work can initialize their
@@ -112,6 +117,12 @@ int gic_cpu_if_down(unsigned int gic_nr);
int gic_of_init(struct device_node *node, struct device_node *parent);
/*
+ * Initialises and registers a non-root or child GIC chip. Memory for
+ * the gic_chip_data structure is dynamically allocated.
+ */
+int gic_of_init_child(struct device *dev, struct gic_chip_data **gic, int irq);
+
+/*
* Legacy platforms not converted to DT yet must use this to init
* their GIC
*/
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index f1f36e04d885..ffb84604c1de 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -39,6 +39,7 @@ struct irq_domain;
struct of_device_id;
struct irq_chip;
struct irq_data;
+struct cpumask;
/* Number of irqs reserved for a legacy isa controller */
#define NUM_ISA_INTERRUPTS 16
@@ -217,7 +218,8 @@ extern struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec,
enum irq_domain_bus_token bus_token);
extern void irq_set_default_host(struct irq_domain *host);
extern int irq_domain_alloc_descs(int virq, unsigned int nr_irqs,
- irq_hw_number_t hwirq, int node);
+ irq_hw_number_t hwirq, int node,
+ const struct cpumask *affinity);
static inline struct fwnode_handle *of_node_to_fwnode(struct device_node *node)
{
@@ -389,7 +391,7 @@ static inline struct irq_domain *irq_domain_add_hierarchy(struct irq_domain *par
extern int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
unsigned int nr_irqs, int node, void *arg,
- bool realloc);
+ bool realloc, const struct cpumask *affinity);
extern void irq_domain_free_irqs(unsigned int virq, unsigned int nr_irqs);
extern void irq_domain_activate_irq(struct irq_data *irq_data);
extern void irq_domain_deactivate_irq(struct irq_data *irq_data);
@@ -397,7 +399,8 @@ extern void irq_domain_deactivate_irq(struct irq_data *irq_data);
static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
unsigned int nr_irqs, int node, void *arg)
{
- return __irq_domain_alloc_irqs(domain, -1, nr_irqs, node, arg, false);
+ return __irq_domain_alloc_irqs(domain, -1, nr_irqs, node, arg, false,
+ NULL);
}
extern int irq_domain_alloc_irqs_recursive(struct irq_domain *domain,
@@ -452,6 +455,9 @@ static inline int irq_domain_alloc_irqs(struct irq_domain *domain,
return -1;
}
+static inline void irq_domain_free_irqs(unsigned int virq,
+ unsigned int nr_irqs) { }
+
static inline bool irq_domain_is_hierarchy(struct irq_domain *domain)
{
return false;
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index efb232c5f668..dfaa1f4dcb0c 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -491,10 +491,6 @@ struct jbd2_journal_handle
unsigned long h_start_jiffies;
unsigned int h_requested_credits;
-
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
- struct lockdep_map h_lockdep_map;
-#endif
};
@@ -793,6 +789,7 @@ jbd2_time_diff(unsigned long start, unsigned long end)
* @j_proc_entry: procfs entry for the jbd statistics directory
* @j_stats: Overall statistics
* @j_private: An opaque pointer to fs-private information.
+ * @j_trans_commit_map: Lockdep entity to track transaction commit dependencies
*/
struct journal_s
@@ -1035,8 +1032,26 @@ struct journal_s
/* Precomputed journal UUID checksum for seeding other checksums */
__u32 j_csum_seed;
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ /*
+ * Lockdep entity to track transaction commit dependencies. Handles
+ * hold this "lock" for read, when we wait for commit, we acquire the
+ * "lock" for writing. This matches the properties of jbd2 journalling
+ * where the running transaction has to wait for all handles to be
+ * dropped to commit that transaction and also acquiring a handle may
+ * require transaction commit to finish.
+ */
+ struct lockdep_map j_trans_commit_map;
+#endif
};
+#define jbd2_might_wait_for_commit(j) \
+ do { \
+ rwsem_acquire(&j->j_trans_commit_map, 0, 0, _THIS_IP_); \
+ rwsem_release(&j->j_trans_commit_map, 1, _THIS_IP_); \
+ } while (0)
+
/* journal feature predicate functions */
#define JBD2_FEATURE_COMPAT_FUNCS(name, flagname) \
static inline bool jbd2_has_feature_##name(journal_t *j) \
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index ac4b3c46a84d..c9cf374445d8 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -77,6 +77,7 @@ void kasan_free_shadow(const struct vm_struct *vm);
size_t ksize(const void *);
static inline void kasan_unpoison_slab(const void *ptr) { ksize(ptr); }
+size_t kasan_metadata_size(struct kmem_cache *cache);
#else /* CONFIG_KASAN */
@@ -121,6 +122,7 @@ static inline int kasan_module_alloc(void *addr, size_t size) { return 0; }
static inline void kasan_free_shadow(const struct vm_struct *vm) {}
static inline void kasan_unpoison_slab(const void *ptr) { }
+static inline size_t kasan_metadata_size(struct kmem_cache *cache) { return 0; }
#endif /* CONFIG_KASAN */
diff --git a/include/linux/kdb.h b/include/linux/kdb.h
index a19bcf9e762e..410decacff8f 100644
--- a/include/linux/kdb.h
+++ b/include/linux/kdb.h
@@ -177,7 +177,7 @@ extern int kdb_get_kbd_char(void);
static inline
int kdb_process_cpu(const struct task_struct *p)
{
- unsigned int cpu = task_thread_info(p)->cpu;
+ unsigned int cpu = task_cpu(p);
if (cpu > num_possible_cpus())
cpu = 0;
return cpu;
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 94aa10ffe156..c42082112ec8 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -451,6 +451,7 @@ extern int panic_on_oops;
extern int panic_on_unrecovered_nmi;
extern int panic_on_io_nmi;
extern int panic_on_warn;
+extern int sysctl_panic_on_rcu_stall;
extern int sysctl_panic_on_stackoverflow;
extern bool crash_kexec_post_notifiers;
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index 25a822f6f000..44fda64ad434 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -92,7 +92,6 @@ static inline void account_process_tick(struct task_struct *tsk, int user)
extern void account_process_tick(struct task_struct *, int user);
#endif
-extern void account_steal_ticks(unsigned long ticks);
extern void account_idle_ticks(unsigned long ticks);
#endif /* _LINUX_KERNEL_STAT_H */
diff --git a/include/linux/khugepaged.h b/include/linux/khugepaged.h
index eeb307985715..1e032a1ddb3e 100644
--- a/include/linux/khugepaged.h
+++ b/include/linux/khugepaged.h
@@ -4,6 +4,11 @@
#include <linux/sched.h> /* MMF_VM_HUGEPAGE */
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern struct attribute_group khugepaged_attr_group;
+
+extern int khugepaged_init(void);
+extern void khugepaged_destroy(void);
+extern int start_stop_khugepaged(void);
extern int __khugepaged_enter(struct mm_struct *mm);
extern void __khugepaged_exit(struct mm_struct *mm);
extern int khugepaged_enter_vma_merge(struct vm_area_struct *vma,
diff --git a/include/linux/ksm.h b/include/linux/ksm.h
index 7ae216a39c9e..481c8c4627ca 100644
--- a/include/linux/ksm.h
+++ b/include/linux/ksm.h
@@ -43,8 +43,7 @@ static inline struct stable_node *page_stable_node(struct page *page)
static inline void set_page_stable_node(struct page *page,
struct stable_node *stable_node)
{
- page->mapping = (void *)stable_node +
- (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM);
+ page->mapping = (void *)((unsigned long)stable_node | PAGE_MAPPING_KSM);
}
/*
diff --git a/include/linux/leds-lp3952.h b/include/linux/leds-lp3952.h
new file mode 100644
index 000000000000..49b37ed8d456
--- /dev/null
+++ b/include/linux/leds-lp3952.h
@@ -0,0 +1,125 @@
+/*
+ * LED driver for TI lp3952 controller
+ *
+ * Copyright (C) 2016, DAQRI, LLC.
+ * Author: Tony Makkiel <tony.makkiel@daqri.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef LEDS_LP3952_H_
+#define LEDS_LP3952_H_
+
+#define LP3952_NAME "lp3952"
+#define LP3952_CMD_REG_COUNT 8
+#define LP3952_BRIGHT_MAX 4
+#define LP3952_LABEL_MAX_LEN 15
+
+#define LP3952_REG_LED_CTRL 0x00
+#define LP3952_REG_R1_BLNK_TIME_CTRL 0x01
+#define LP3952_REG_R1_BLNK_CYCLE_CTRL 0x02
+#define LP3952_REG_G1_BLNK_TIME_CTRL 0x03
+#define LP3952_REG_G1_BLNK_CYCLE_CTRL 0x04
+#define LP3952_REG_B1_BLNK_TIME_CTRL 0x05
+#define LP3952_REG_B1_BLNK_CYCLE_CTRL 0x06
+#define LP3952_REG_ENABLES 0x0B
+#define LP3952_REG_PAT_GEN_CTRL 0x11
+#define LP3952_REG_RGB1_MAX_I_CTRL 0x12
+#define LP3952_REG_RGB2_MAX_I_CTRL 0x13
+#define LP3952_REG_CMD_0 0x50
+#define LP3952_REG_RESET 0x60
+#define REG_MAX LP3952_REG_RESET
+
+#define LP3952_PATRN_LOOP BIT(1)
+#define LP3952_PATRN_GEN_EN BIT(2)
+#define LP3952_INT_B00ST_LDR BIT(2)
+#define LP3952_ACTIVE_MODE BIT(6)
+#define LP3952_LED_MASK_ALL 0x3f
+
+/* Transition Time in ms */
+enum lp3952_tt {
+ TT0,
+ TT55,
+ TT110,
+ TT221,
+ TT422,
+ TT885,
+ TT1770,
+ TT3539
+};
+
+/* Command Execution Time in ms */
+enum lp3952_cet {
+ CET197,
+ CET393,
+ CET590,
+ CET786,
+ CET1180,
+ CET1376,
+ CET1573,
+ CET1769,
+ CET1966,
+ CET2163,
+ CET2359,
+ CET2556,
+ CET2763,
+ CET2949,
+ CET3146
+};
+
+/* Max Current in % */
+enum lp3952_colour_I_log_0 {
+ I0,
+ I7,
+ I14,
+ I21,
+ I32,
+ I46,
+ I71,
+ I100
+};
+
+enum lp3952_leds {
+ LP3952_BLUE_2,
+ LP3952_GREEN_2,
+ LP3952_RED_2,
+ LP3952_BLUE_1,
+ LP3952_GREEN_1,
+ LP3952_RED_1,
+ LP3952_LED_ALL
+};
+
+struct lp3952_ctrl_hdl {
+ struct led_classdev cdev;
+ char name[LP3952_LABEL_MAX_LEN];
+ enum lp3952_leds channel;
+ void *priv;
+};
+
+struct ptrn_gen_cmd {
+ union {
+ struct {
+ u16 tt:3;
+ u16 b:3;
+ u16 cet:4;
+ u16 g:3;
+ u16 r:3;
+ };
+ struct {
+ u8 lsb;
+ u8 msb;
+ } bytes;
+ };
+} __packed;
+
+struct lp3952_led_array {
+ struct regmap *regmap;
+ struct i2c_client *client;
+ struct gpio_desc *enable_gpio;
+ struct lp3952_ctrl_hdl leds[LP3952_LED_ALL];
+};
+
+#endif /* LEDS_LP3952_H_ */
diff --git a/include/linux/leds-pca9532.h b/include/linux/leds-pca9532.h
index b8d6fffed4d8..d215b4561180 100644
--- a/include/linux/leds-pca9532.h
+++ b/include/linux/leds-pca9532.h
@@ -16,6 +16,7 @@
#include <linux/leds.h>
#include <linux/workqueue.h>
+#include <dt-bindings/leds/leds-pca9532.h>
enum pca9532_state {
PCA9532_OFF = 0x0,
@@ -24,16 +25,14 @@ enum pca9532_state {
PCA9532_PWM1 = 0x3
};
-enum pca9532_type { PCA9532_TYPE_NONE, PCA9532_TYPE_LED,
- PCA9532_TYPE_N2100_BEEP, PCA9532_TYPE_GPIO };
-
struct pca9532_led {
u8 id;
struct i2c_client *client;
- char *name;
+ const char *name;
+ const char *default_trigger;
struct led_classdev ldev;
struct work_struct work;
- enum pca9532_type type;
+ u32 type;
enum pca9532_state state;
};
diff --git a/include/linux/leds.h b/include/linux/leds.h
index e5e7f2e80a54..8a3b5d29602f 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -325,10 +325,10 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev)
#endif /* CONFIG_LEDS_TRIGGERS */
/* Trigger specific functions */
-#ifdef CONFIG_LEDS_TRIGGER_IDE_DISK
-extern void ledtrig_ide_activity(void);
+#ifdef CONFIG_LEDS_TRIGGER_DISK
+extern void ledtrig_disk_activity(void);
#else
-static inline void ledtrig_ide_activity(void) {}
+static inline void ledtrig_disk_activity(void) {}
#endif
#ifdef CONFIG_LEDS_TRIGGER_MTD
@@ -387,8 +387,16 @@ struct gpio_led_platform_data {
unsigned long *delay_off);
};
+#ifdef CONFIG_NEW_LEDS
struct platform_device *gpio_led_register_device(
int id, const struct gpio_led_platform_data *pdata);
+#else
+static inline struct platform_device *gpio_led_register_device(
+ int id, const struct gpio_led_platform_data *pdata)
+{
+ return 0;
+}
+#endif
enum cpu_led_event {
CPU_LED_IDLE_START, /* CPU enters idle */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index d15c19e331d1..e37d4f99f510 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -146,13 +146,6 @@ enum {
ATA_TFLAG_FUA = (1 << 5), /* enable FUA */
ATA_TFLAG_POLLING = (1 << 6), /* set nIEN to 1 and use polling */
- /* protocol flags */
- ATA_PROT_FLAG_PIO = (1 << 0), /* is PIO */
- ATA_PROT_FLAG_DMA = (1 << 1), /* is DMA */
- ATA_PROT_FLAG_DATA = ATA_PROT_FLAG_PIO | ATA_PROT_FLAG_DMA,
- ATA_PROT_FLAG_NCQ = (1 << 2), /* is NCQ */
- ATA_PROT_FLAG_ATAPI = (1 << 3), /* is ATAPI */
-
/* struct ata_device stuff */
ATA_DFLAG_LBA = (1 << 0), /* device supports LBA */
ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */
@@ -1039,58 +1032,29 @@ extern const unsigned long sata_deb_timing_long[];
extern struct ata_port_operations ata_dummy_port_ops;
extern const struct ata_port_info ata_dummy_port_info;
-/*
- * protocol tests
- */
-static inline unsigned int ata_prot_flags(u8 prot)
-{
- switch (prot) {
- case ATA_PROT_NODATA:
- return 0;
- case ATA_PROT_PIO:
- return ATA_PROT_FLAG_PIO;
- case ATA_PROT_DMA:
- return ATA_PROT_FLAG_DMA;
- case ATA_PROT_NCQ:
- return ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ;
- case ATAPI_PROT_NODATA:
- return ATA_PROT_FLAG_ATAPI;
- case ATAPI_PROT_PIO:
- return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO;
- case ATAPI_PROT_DMA:
- return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA;
- }
- return 0;
-}
-
-static inline int ata_is_atapi(u8 prot)
-{
- return ata_prot_flags(prot) & ATA_PROT_FLAG_ATAPI;
-}
-
-static inline int ata_is_nodata(u8 prot)
+static inline bool ata_is_atapi(u8 prot)
{
- return !(ata_prot_flags(prot) & ATA_PROT_FLAG_DATA);
+ return prot & ATA_PROT_FLAG_ATAPI;
}
-static inline int ata_is_pio(u8 prot)
+static inline bool ata_is_pio(u8 prot)
{
- return ata_prot_flags(prot) & ATA_PROT_FLAG_PIO;
+ return prot & ATA_PROT_FLAG_PIO;
}
-static inline int ata_is_dma(u8 prot)
+static inline bool ata_is_dma(u8 prot)
{
- return ata_prot_flags(prot) & ATA_PROT_FLAG_DMA;
+ return prot & ATA_PROT_FLAG_DMA;
}
-static inline int ata_is_ncq(u8 prot)
+static inline bool ata_is_ncq(u8 prot)
{
- return ata_prot_flags(prot) & ATA_PROT_FLAG_NCQ;
+ return prot & ATA_PROT_FLAG_NCQ;
}
-static inline int ata_is_data(u8 prot)
+static inline bool ata_is_data(u8 prot)
{
- return ata_prot_flags(prot) & ATA_PROT_FLAG_DATA;
+ return prot & (ATA_PROT_FLAG_PIO | ATA_PROT_FLAG_DMA);
}
static inline int is_multi_taskfile(struct ata_taskfile *tf)
@@ -1407,7 +1371,7 @@ static inline bool sata_pmp_attached(struct ata_port *ap)
return ap->nr_pmp_links != 0;
}
-static inline int ata_is_host_link(const struct ata_link *link)
+static inline bool ata_is_host_link(const struct ata_link *link)
{
return link == &link->ap->link || link == link->ap->slave_link;
}
@@ -1422,7 +1386,7 @@ static inline bool sata_pmp_attached(struct ata_port *ap)
return false;
}
-static inline int ata_is_host_link(const struct ata_link *link)
+static inline bool ata_is_host_link(const struct ata_link *link)
{
return 1;
}
diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
index 0c3c30cbbea5..b519e137b9b7 100644
--- a/include/linux/libnvdimm.h
+++ b/include/linux/libnvdimm.h
@@ -52,6 +52,7 @@ typedef int (*ndctl_fn)(struct nvdimm_bus_descriptor *nd_desc,
struct nd_namespace_label;
struct nvdimm_drvdata;
+
struct nd_mapping {
struct nvdimm *nvdimm;
struct nd_namespace_label **labels;
@@ -69,6 +70,7 @@ struct nd_mapping {
struct nvdimm_bus_descriptor {
const struct attribute_group **attr_groups;
unsigned long cmd_mask;
+ struct module *module;
char *provider_name;
ndctl_fn ndctl;
int (*flush_probe)(struct nvdimm_bus_descriptor *nd_desc);
@@ -99,13 +101,21 @@ struct nd_region_desc {
unsigned long flags;
};
+struct device;
+void *devm_nvdimm_memremap(struct device *dev, resource_size_t offset,
+ size_t size, unsigned long flags);
+static inline void __iomem *devm_nvdimm_ioremap(struct device *dev,
+ resource_size_t offset, size_t size)
+{
+ return (void __iomem *) devm_nvdimm_memremap(dev, offset, size, 0);
+}
+
struct nvdimm_bus;
struct module;
struct device;
struct nd_blk_region;
struct nd_blk_region_desc {
int (*enable)(struct nvdimm_bus *nvdimm_bus, struct device *dev);
- void (*disable)(struct nvdimm_bus *nvdimm_bus, struct device *dev);
int (*do_io)(struct nd_blk_region *ndbr, resource_size_t dpa,
void *iobuf, u64 len, int rw);
struct nd_region_desc ndr_desc;
@@ -119,22 +129,22 @@ static inline struct nd_blk_region_desc *to_blk_region_desc(
}
int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length);
-struct nvdimm_bus *__nvdimm_bus_register(struct device *parent,
- struct nvdimm_bus_descriptor *nfit_desc, struct module *module);
-#define nvdimm_bus_register(parent, desc) \
- __nvdimm_bus_register(parent, desc, THIS_MODULE)
+struct nvdimm_bus *nvdimm_bus_register(struct device *parent,
+ struct nvdimm_bus_descriptor *nfit_desc);
void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus);
struct nvdimm_bus *to_nvdimm_bus(struct device *dev);
struct nvdimm *to_nvdimm(struct device *dev);
struct nd_region *to_nd_region(struct device *dev);
struct nd_blk_region *to_nd_blk_region(struct device *dev);
struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus);
+struct device *to_nvdimm_bus_dev(struct nvdimm_bus *nvdimm_bus);
const char *nvdimm_name(struct nvdimm *nvdimm);
unsigned long nvdimm_cmd_mask(struct nvdimm *nvdimm);
void *nvdimm_provider_data(struct nvdimm *nvdimm);
struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data,
const struct attribute_group **groups, unsigned long flags,
- unsigned long cmd_mask);
+ unsigned long cmd_mask, int num_flush,
+ struct resource *flush_wpq);
const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd);
const struct nd_cmd_desc *nd_cmd_bus_desc(int cmd);
u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd,
@@ -156,4 +166,6 @@ struct nvdimm *nd_blk_region_to_dimm(struct nd_blk_region *ndbr);
unsigned int nd_region_acquire_lane(struct nd_region *nd_region);
void nd_region_release_lane(struct nd_region *nd_region, unsigned int lane);
u64 nd_fletcher64(void *addr, size_t len, bool le);
+void nvdimm_flush(struct nd_region *nd_region);
+int nvdimm_has_flush(struct nd_region *nd_region);
#endif /* __LIBNVDIMM_H__ */
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
index ef2c7d2e76c4..ba78b8306674 100644
--- a/include/linux/lightnvm.h
+++ b/include/linux/lightnvm.h
@@ -1,7 +1,9 @@
#ifndef NVM_H
#define NVM_H
+#include <linux/blkdev.h>
#include <linux/types.h>
+#include <uapi/linux/lightnvm.h>
enum {
NVM_IO_OK = 0,
@@ -269,24 +271,15 @@ struct nvm_lun {
int lun_id;
int chnl_id;
- /* It is up to the target to mark blocks as closed. If the target does
- * not do it, all blocks are marked as open, and nr_open_blocks
- * represents the number of blocks in use
- */
- unsigned int nr_open_blocks; /* Number of used, writable blocks */
- unsigned int nr_closed_blocks; /* Number of used, read-only blocks */
- unsigned int nr_free_blocks; /* Number of unused blocks */
- unsigned int nr_bad_blocks; /* Number of bad blocks */
-
spinlock_t lock;
+ unsigned int nr_free_blocks; /* Number of unused blocks */
struct nvm_block *blocks;
};
enum {
NVM_BLK_ST_FREE = 0x1, /* Free block */
- NVM_BLK_ST_OPEN = 0x2, /* Open block - read-write */
- NVM_BLK_ST_CLOSED = 0x4, /* Closed block - read-only */
+ NVM_BLK_ST_TGT = 0x2, /* Block in use by target */
NVM_BLK_ST_BAD = 0x8, /* Bad block */
};
@@ -385,6 +378,7 @@ static inline struct ppa_addr dev_to_generic_addr(struct nvm_dev *dev,
{
struct ppa_addr l;
+ l.ppa = 0;
/*
* (r.ppa << X offset) & X len bitmask. X eq. blk, pg, etc.
*/
@@ -455,6 +449,8 @@ struct nvm_tgt_type {
struct list_head list;
};
+extern struct nvm_tgt_type *nvm_find_target_type(const char *, int);
+
extern int nvm_register_tgt_type(struct nvm_tgt_type *);
extern void nvm_unregister_tgt_type(struct nvm_tgt_type *);
@@ -463,6 +459,9 @@ extern void nvm_dev_dma_free(struct nvm_dev *, void *, dma_addr_t);
typedef int (nvmm_register_fn)(struct nvm_dev *);
typedef void (nvmm_unregister_fn)(struct nvm_dev *);
+
+typedef int (nvmm_create_tgt_fn)(struct nvm_dev *, struct nvm_ioctl_create *);
+typedef int (nvmm_remove_tgt_fn)(struct nvm_dev *, struct nvm_ioctl_remove *);
typedef struct nvm_block *(nvmm_get_blk_fn)(struct nvm_dev *,
struct nvm_lun *, unsigned long);
typedef void (nvmm_put_blk_fn)(struct nvm_dev *, struct nvm_block *);
@@ -488,9 +487,10 @@ struct nvmm_type {
nvmm_register_fn *register_mgr;
nvmm_unregister_fn *unregister_mgr;
+ nvmm_create_tgt_fn *create_tgt;
+ nvmm_remove_tgt_fn *remove_tgt;
+
/* Block administration callbacks */
- nvmm_get_blk_fn *get_blk_unlocked;
- nvmm_put_blk_fn *put_blk_unlocked;
nvmm_get_blk_fn *get_blk;
nvmm_put_blk_fn *put_blk;
nvmm_open_blk_fn *open_blk;
@@ -520,10 +520,6 @@ struct nvmm_type {
extern int nvm_register_mgr(struct nvmm_type *);
extern void nvm_unregister_mgr(struct nvmm_type *);
-extern struct nvm_block *nvm_get_blk_unlocked(struct nvm_dev *,
- struct nvm_lun *, unsigned long);
-extern void nvm_put_blk_unlocked(struct nvm_dev *, struct nvm_block *);
-
extern struct nvm_block *nvm_get_blk(struct nvm_dev *, struct nvm_lun *,
unsigned long);
extern void nvm_put_blk(struct nvm_dev *, struct nvm_block *);
@@ -532,11 +528,13 @@ extern int nvm_register(struct request_queue *, char *,
struct nvm_dev_ops *);
extern void nvm_unregister(char *);
+void nvm_mark_blk(struct nvm_dev *dev, struct ppa_addr ppa, int type);
+
extern int nvm_submit_io(struct nvm_dev *, struct nvm_rq *);
extern void nvm_generic_to_addr_mode(struct nvm_dev *, struct nvm_rq *);
extern void nvm_addr_to_generic_mode(struct nvm_dev *, struct nvm_rq *);
extern int nvm_set_rqd_ppalist(struct nvm_dev *, struct nvm_rq *,
- struct ppa_addr *, int, int);
+ const struct ppa_addr *, int, int);
extern void nvm_free_rqd_ppalist(struct nvm_dev *, struct nvm_rq *);
extern int nvm_erase_ppa(struct nvm_dev *, struct ppa_addr *, int);
extern int nvm_erase_blk(struct nvm_dev *, struct nvm_block *);
diff --git a/include/linux/list.h b/include/linux/list.h
index 5356f4d661a7..5183138aa932 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -679,6 +679,16 @@ static inline bool hlist_fake(struct hlist_node *h)
}
/*
+ * Check whether the node is the only node of the head without
+ * accessing head:
+ */
+static inline bool
+hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h)
+{
+ return !n->next && n->pprev == &h->first;
+}
+
+/*
* Move a list from one list head to another. Fixup the pprev
* reference of the first entry if it exists.
*/
diff --git a/include/linux/mdio-mux.h b/include/linux/mdio-mux.h
index a243dbba8659..61f5b21b31c7 100644
--- a/include/linux/mdio-mux.h
+++ b/include/linux/mdio-mux.h
@@ -10,11 +10,13 @@
#ifndef __LINUX_MDIO_MUX_H
#define __LINUX_MDIO_MUX_H
#include <linux/device.h>
+#include <linux/phy.h>
int mdio_mux_init(struct device *dev,
int (*switch_fn) (int cur, int desired, void *data),
void **mux_handle,
- void *data);
+ void *data,
+ struct mii_bus *mux_bus);
void mdio_mux_uninit(void *mux_handle);
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 3106ac1c895e..2925da23505d 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -73,8 +73,8 @@ extern bool movable_node_enabled;
if (memblock_debug) printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
phys_addr_t memblock_find_in_range_node(phys_addr_t size, phys_addr_t align,
- phys_addr_t start, phys_addr_t end,
- int nid, ulong flags);
+ phys_addr_t start, phys_addr_t end,
+ int nid, ulong flags);
phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
phys_addr_t size, phys_addr_t align);
phys_addr_t get_allocated_memblock_reserved_regions_info(phys_addr_t *addr);
@@ -110,7 +110,7 @@ void __next_mem_range_rev(u64 *idx, int nid, ulong flags,
phys_addr_t *out_end, int *out_nid);
void __next_reserved_mem_region(u64 *idx, phys_addr_t *out_start,
- phys_addr_t *out_end);
+ phys_addr_t *out_end);
/**
* for_each_mem_range - iterate through memblock areas from type_a and not
@@ -148,7 +148,7 @@ void __next_reserved_mem_region(u64 *idx, phys_addr_t *out_start,
p_start, p_end, p_nid) \
for (i = (u64)ULLONG_MAX, \
__next_mem_range_rev(&i, nid, flags, type_a, type_b,\
- p_start, p_end, p_nid); \
+ p_start, p_end, p_nid); \
i != (u64)ULLONG_MAX; \
__next_mem_range_rev(&i, nid, flags, type_a, type_b, \
p_start, p_end, p_nid))
@@ -163,8 +163,7 @@ void __next_reserved_mem_region(u64 *idx, phys_addr_t *out_start,
* is initialized.
*/
#define for_each_reserved_mem_region(i, p_start, p_end) \
- for (i = 0UL, \
- __next_reserved_mem_region(&i, p_start, p_end); \
+ for (i = 0UL, __next_reserved_mem_region(&i, p_start, p_end); \
i != (u64)ULLONG_MAX; \
__next_reserved_mem_region(&i, p_start, p_end))
@@ -333,6 +332,7 @@ phys_addr_t memblock_mem_size(unsigned long limit_pfn);
phys_addr_t memblock_start_of_DRAM(void);
phys_addr_t memblock_end_of_DRAM(void);
void memblock_enforce_memory_limit(phys_addr_t memory_limit);
+void memblock_mem_limit_remove_map(phys_addr_t limit);
bool memblock_is_memory(phys_addr_t addr);
int memblock_is_map_memory(phys_addr_t addr);
int memblock_is_region_memory(phys_addr_t base, phys_addr_t size);
@@ -403,15 +403,14 @@ static inline unsigned long memblock_region_reserved_end_pfn(const struct memblo
}
#define for_each_memblock(memblock_type, region) \
- for (region = memblock.memblock_type.regions; \
+ for (region = memblock.memblock_type.regions; \
region < (memblock.memblock_type.regions + memblock.memblock_type.cnt); \
region++)
#define for_each_memblock_type(memblock_type, rgn) \
- idx = 0; \
- rgn = &memblock_type->regions[idx]; \
- for (idx = 0; idx < memblock_type->cnt; \
- idx++,rgn = &memblock_type->regions[idx])
+ for (idx = 0, rgn = &memblock_type->regions[0]; \
+ idx < memblock_type->cnt; \
+ idx++, rgn = &memblock_type->regions[idx])
#ifdef CONFIG_MEMTEST
extern void early_memtest(phys_addr_t start, phys_addr_t end);
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 56e6069d2452..5d8ca6e02e39 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -52,7 +52,7 @@ enum mem_cgroup_stat_index {
MEM_CGROUP_STAT_SWAP, /* # of pages, swapped out */
MEM_CGROUP_STAT_NSTATS,
/* default hierarchy stats */
- MEMCG_KERNEL_STACK = MEM_CGROUP_STAT_NSTATS,
+ MEMCG_KERNEL_STACK_KB = MEM_CGROUP_STAT_NSTATS,
MEMCG_SLAB_RECLAIMABLE,
MEMCG_SLAB_UNRECLAIMABLE,
MEMCG_SOCK,
@@ -60,7 +60,7 @@ enum mem_cgroup_stat_index {
};
struct mem_cgroup_reclaim_cookie {
- struct zone *zone;
+ pg_data_t *pgdat;
int priority;
unsigned int generation;
};
@@ -118,7 +118,7 @@ struct mem_cgroup_reclaim_iter {
/*
* per-zone information in memory controller.
*/
-struct mem_cgroup_per_zone {
+struct mem_cgroup_per_node {
struct lruvec lruvec;
unsigned long lru_size[NR_LRU_LISTS];
@@ -132,10 +132,6 @@ struct mem_cgroup_per_zone {
/* use container_of */
};
-struct mem_cgroup_per_node {
- struct mem_cgroup_per_zone zoneinfo[MAX_NR_ZONES];
-};
-
struct mem_cgroup_threshold {
struct eventfd_ctx *eventfd;
unsigned long threshold;
@@ -314,8 +310,46 @@ void mem_cgroup_uncharge_list(struct list_head *page_list);
void mem_cgroup_migrate(struct page *oldpage, struct page *newpage);
-struct lruvec *mem_cgroup_zone_lruvec(struct zone *, struct mem_cgroup *);
-struct lruvec *mem_cgroup_page_lruvec(struct page *, struct zone *);
+static struct mem_cgroup_per_node *
+mem_cgroup_nodeinfo(struct mem_cgroup *memcg, int nid)
+{
+ return memcg->nodeinfo[nid];
+}
+
+/**
+ * mem_cgroup_lruvec - get the lru list vector for a node or a memcg zone
+ * @node: node of the wanted lruvec
+ * @memcg: memcg of the wanted lruvec
+ *
+ * Returns the lru list vector holding pages for a given @node or a given
+ * @memcg and @zone. This can be the node lruvec, if the memory controller
+ * is disabled.
+ */
+static inline struct lruvec *mem_cgroup_lruvec(struct pglist_data *pgdat,
+ struct mem_cgroup *memcg)
+{
+ struct mem_cgroup_per_node *mz;
+ struct lruvec *lruvec;
+
+ if (mem_cgroup_disabled()) {
+ lruvec = node_lruvec(pgdat);
+ goto out;
+ }
+
+ mz = mem_cgroup_nodeinfo(memcg, pgdat->node_id);
+ lruvec = &mz->lruvec;
+out:
+ /*
+ * Since a node can be onlined after the mem_cgroup was created,
+ * we have to be prepared to initialize lruvec->pgdat here;
+ * and if offlined then reonlined, we need to reinitialize it.
+ */
+ if (unlikely(lruvec->pgdat != pgdat))
+ lruvec->pgdat = pgdat;
+ return lruvec;
+}
+
+struct lruvec *mem_cgroup_page_lruvec(struct page *, struct pglist_data *);
bool task_in_mem_cgroup(struct task_struct *task, struct mem_cgroup *memcg);
struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p);
@@ -404,9 +438,9 @@ unsigned long mem_cgroup_node_nr_lru_pages(struct mem_cgroup *memcg,
static inline
unsigned long mem_cgroup_get_lru_size(struct lruvec *lruvec, enum lru_list lru)
{
- struct mem_cgroup_per_zone *mz;
+ struct mem_cgroup_per_node *mz;
- mz = container_of(lruvec, struct mem_cgroup_per_zone, lruvec);
+ mz = container_of(lruvec, struct mem_cgroup_per_node, lruvec);
return mz->lru_size[lru];
}
@@ -477,7 +511,7 @@ static inline void mem_cgroup_dec_page_stat(struct page *page,
mem_cgroup_update_page_stat(page, idx, -1);
}
-unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
+unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order,
gfp_t gfp_mask,
unsigned long *total_scanned);
@@ -568,16 +602,16 @@ static inline void mem_cgroup_migrate(struct page *old, struct page *new)
{
}
-static inline struct lruvec *mem_cgroup_zone_lruvec(struct zone *zone,
- struct mem_cgroup *memcg)
+static inline struct lruvec *mem_cgroup_lruvec(struct pglist_data *pgdat,
+ struct mem_cgroup *memcg)
{
- return &zone->lruvec;
+ return node_lruvec(pgdat);
}
static inline struct lruvec *mem_cgroup_page_lruvec(struct page *page,
- struct zone *zone)
+ struct pglist_data *pgdat)
{
- return &zone->lruvec;
+ return &pgdat->lruvec;
}
static inline bool mm_match_cgroup(struct mm_struct *mm,
@@ -681,7 +715,7 @@ static inline void mem_cgroup_dec_page_stat(struct page *page,
}
static inline
-unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
+unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order,
gfp_t gfp_mask,
unsigned long *total_scanned)
{
@@ -749,6 +783,13 @@ static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg)
}
#endif
+struct kmem_cache *memcg_kmem_get_cache(struct kmem_cache *cachep);
+void memcg_kmem_put_cache(struct kmem_cache *cachep);
+int memcg_kmem_charge_memcg(struct page *page, gfp_t gfp, int order,
+ struct mem_cgroup *memcg);
+int memcg_kmem_charge(struct page *page, gfp_t gfp, int order);
+void memcg_kmem_uncharge(struct page *page, int order);
+
#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
extern struct static_key_false memcg_kmem_enabled_key;
@@ -770,22 +811,6 @@ static inline bool memcg_kmem_enabled(void)
}
/*
- * In general, we'll do everything in our power to not incur in any overhead
- * for non-memcg users for the kmem functions. Not even a function call, if we
- * can avoid it.
- *
- * Therefore, we'll inline all those functions so that in the best case, we'll
- * see that kmemcg is off for everybody and proceed quickly. If it is on,
- * we'll still do most of the flag checking inline. We check a lot of
- * conditions, but because they are pretty simple, they are expected to be
- * fast.
- */
-int __memcg_kmem_charge_memcg(struct page *page, gfp_t gfp, int order,
- struct mem_cgroup *memcg);
-int __memcg_kmem_charge(struct page *page, gfp_t gfp, int order);
-void __memcg_kmem_uncharge(struct page *page, int order);
-
-/*
* helper for accessing a memcg's index. It will be used as an index in the
* child cache array in kmem_cache, and also to derive its name. This function
* will return -1 when this is not a kmem-limited memcg.
@@ -795,67 +820,6 @@ static inline int memcg_cache_id(struct mem_cgroup *memcg)
return memcg ? memcg->kmemcg_id : -1;
}
-struct kmem_cache *__memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp);
-void __memcg_kmem_put_cache(struct kmem_cache *cachep);
-
-static inline bool __memcg_kmem_bypass(void)
-{
- if (!memcg_kmem_enabled())
- return true;
- if (in_interrupt() || (!current->mm) || (current->flags & PF_KTHREAD))
- return true;
- return false;
-}
-
-/**
- * memcg_kmem_charge: charge a kmem page
- * @page: page to charge
- * @gfp: reclaim mode
- * @order: allocation order
- *
- * Returns 0 on success, an error code on failure.
- */
-static __always_inline int memcg_kmem_charge(struct page *page,
- gfp_t gfp, int order)
-{
- if (__memcg_kmem_bypass())
- return 0;
- if (!(gfp & __GFP_ACCOUNT))
- return 0;
- return __memcg_kmem_charge(page, gfp, order);
-}
-
-/**
- * memcg_kmem_uncharge: uncharge a kmem page
- * @page: page to uncharge
- * @order: allocation order
- */
-static __always_inline void memcg_kmem_uncharge(struct page *page, int order)
-{
- if (memcg_kmem_enabled())
- __memcg_kmem_uncharge(page, order);
-}
-
-/**
- * memcg_kmem_get_cache: selects the correct per-memcg cache for allocation
- * @cachep: the original global kmem cache
- *
- * All memory allocated from a per-memcg cache is charged to the owner memcg.
- */
-static __always_inline struct kmem_cache *
-memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp)
-{
- if (__memcg_kmem_bypass())
- return cachep;
- return __memcg_kmem_get_cache(cachep, gfp);
-}
-
-static __always_inline void memcg_kmem_put_cache(struct kmem_cache *cachep)
-{
- if (memcg_kmem_enabled())
- __memcg_kmem_put_cache(cachep);
-}
-
/**
* memcg_kmem_update_page_stat - update kmem page state statistics
* @page: the page
@@ -878,15 +842,6 @@ static inline bool memcg_kmem_enabled(void)
return false;
}
-static inline int memcg_kmem_charge(struct page *page, gfp_t gfp, int order)
-{
- return 0;
-}
-
-static inline void memcg_kmem_uncharge(struct page *page, int order)
-{
-}
-
static inline int memcg_cache_id(struct mem_cgroup *memcg)
{
return -1;
@@ -900,16 +855,6 @@ static inline void memcg_put_cache_ids(void)
{
}
-static inline struct kmem_cache *
-memcg_kmem_get_cache(struct kmem_cache *cachep, gfp_t gfp)
-{
- return cachep;
-}
-
-static inline void memcg_kmem_put_cache(struct kmem_cache *cachep)
-{
-}
-
static inline void memcg_kmem_update_page_stat(struct page *page,
enum mem_cgroup_stat_index idx, int val)
{
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 5145620ba48a..01033fadea47 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -284,5 +284,7 @@ extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms,
unsigned long map_offset);
extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map,
unsigned long pnum);
+extern int zone_can_shift(unsigned long pfn, unsigned long nr_pages,
+ enum zone_type target);
#endif /* __LINUX_MEMORY_HOTPLUG_H */
diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index bcaa634139a9..93416196ba64 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -26,7 +26,7 @@ struct vmem_altmap {
unsigned long vmem_altmap_offset(struct vmem_altmap *altmap);
void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns);
-#if defined(CONFIG_SPARSEMEM_VMEMMAP) && defined(CONFIG_ZONE_DEVICE)
+#ifdef CONFIG_ZONE_DEVICE
struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start);
#else
static inline struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start)
diff --git a/include/linux/mfd/rn5t618.h b/include/linux/mfd/rn5t618.h
index c72d5344f3b3..cadc6543909d 100644
--- a/include/linux/mfd/rn5t618.h
+++ b/include/linux/mfd/rn5t618.h
@@ -20,6 +20,7 @@
#define RN5T618_OTPVER 0x01
#define RN5T618_IODAC 0x02
#define RN5T618_VINDAC 0x03
+#define RN5T618_OUT32KEN 0x05
#define RN5T618_CPUCNT 0x06
#define RN5T618_PSWR 0x07
#define RN5T618_PONHIS 0x09
@@ -38,6 +39,7 @@
#define RN5T618_DC1_SLOT 0x16
#define RN5T618_DC2_SLOT 0x17
#define RN5T618_DC3_SLOT 0x18
+#define RN5T618_DC4_SLOT 0x19
#define RN5T618_LDO1_SLOT 0x1b
#define RN5T618_LDO2_SLOT 0x1c
#define RN5T618_LDO3_SLOT 0x1d
@@ -54,12 +56,16 @@
#define RN5T618_DC2CTL2 0x2f
#define RN5T618_DC3CTL 0x30
#define RN5T618_DC3CTL2 0x31
+#define RN5T618_DC4CTL 0x32
+#define RN5T618_DC4CTL2 0x33
#define RN5T618_DC1DAC 0x36
#define RN5T618_DC2DAC 0x37
#define RN5T618_DC3DAC 0x38
+#define RN5T618_DC4DAC 0x39
#define RN5T618_DC1DAC_SLP 0x3b
#define RN5T618_DC2DAC_SLP 0x3c
#define RN5T618_DC3DAC_SLP 0x3d
+#define RN5T618_DC4DAC_SLP 0x3e
#define RN5T618_DCIREN 0x40
#define RN5T618_DCIRQ 0x41
#define RN5T618_DCIRMON 0x42
@@ -211,6 +217,7 @@ enum {
RN5T618_DCDC1,
RN5T618_DCDC2,
RN5T618_DCDC3,
+ RN5T618_DCDC4,
RN5T618_LDO1,
RN5T618_LDO2,
RN5T618_LDO3,
@@ -221,8 +228,14 @@ enum {
RN5T618_REG_NUM,
};
+enum {
+ RN5T567 = 0,
+ RN5T618,
+};
+
struct rn5t618 {
struct regmap *regmap;
+ long variant;
};
#endif /* __LINUX_MFD_RN5T618_H */
diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h
index ac7fba44d7e4..1c88231496d3 100644
--- a/include/linux/mfd/tps65217.h
+++ b/include/linux/mfd/tps65217.h
@@ -257,6 +257,7 @@ struct tps65217 {
unsigned long id;
struct regulator_desc desc[TPS65217_NUM_REGULATOR];
struct regmap *regmap;
+ u8 *strobes;
};
static inline struct tps65217 *dev_to_tps65217(struct device *dev)
diff --git a/include/linux/mfd/tps65218.h b/include/linux/mfd/tps65218.h
index d58f3b5f585a..7fdf5326f34e 100644
--- a/include/linux/mfd/tps65218.h
+++ b/include/linux/mfd/tps65218.h
@@ -246,6 +246,7 @@ enum tps65218_irqs {
* @name: Voltage regulator name
* @min_uV: minimum micro volts
* @max_uV: minimum micro volts
+ * @strobe: sequencing strobe value for the regulator
*
* This data is used to check the regualtor voltage limits while setting.
*/
@@ -254,6 +255,7 @@ struct tps_info {
const char *name;
int min_uV;
int max_uV;
+ int strobe;
};
/**
diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
index 2e5b194b9b19..257173e0095e 100644
--- a/include/linux/micrel_phy.h
+++ b/include/linux/micrel_phy.h
@@ -37,6 +37,7 @@
/* struct phy_device dev_flags definitions */
#define MICREL_PHY_50MHZ_CLK 0x00000001
+#define MICREL_PHY_FXEN 0x00000002
#define MICREL_KSZ9021_EXTREG_CTRL 0xB
#define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 9b50325e4ddf..ae8d475a9385 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -37,6 +37,8 @@ extern int migrate_page(struct address_space *,
struct page *, struct page *, enum migrate_mode);
extern int migrate_pages(struct list_head *l, new_page_t new, free_page_t free,
unsigned long private, enum migrate_mode mode, int reason);
+extern bool isolate_movable_page(struct page *page, isolate_mode_t mode);
+extern void putback_movable_page(struct page *page);
extern int migrate_prep(void);
extern int migrate_prep_local(void);
@@ -69,6 +71,21 @@ static inline int migrate_huge_page_move_mapping(struct address_space *mapping,
#endif /* CONFIG_MIGRATION */
+#ifdef CONFIG_COMPACTION
+extern int PageMovable(struct page *page);
+extern void __SetPageMovable(struct page *page, struct address_space *mapping);
+extern void __ClearPageMovable(struct page *page);
+#else
+static inline int PageMovable(struct page *page) { return 0; };
+static inline void __SetPageMovable(struct page *page,
+ struct address_space *mapping)
+{
+}
+static inline void __ClearPageMovable(struct page *page)
+{
+}
+#endif
+
#ifdef CONFIG_NUMA_BALANCING
extern bool pmd_trans_migrating(pmd_t pmd);
extern int migrate_misplaced_page(struct page *page,
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index d46a0e7f144d..e6f6910278f3 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -536,6 +536,7 @@ struct mlx4_caps {
int max_rq_desc_sz;
int max_qp_init_rdma;
int max_qp_dest_rdma;
+ int max_tc_eth;
u32 *qp0_qkey;
u32 *qp0_proxy;
u32 *qp1_proxy;
@@ -1495,6 +1496,7 @@ int mlx4_mr_rereg_mem_write(struct mlx4_dev *dev, struct mlx4_mr *mr,
int mlx4_get_module_info(struct mlx4_dev *dev, u8 port,
u16 offset, u16 size, u8 *data);
+int mlx4_max_tc(struct mlx4_dev *dev);
/* Returns true if running in low memory profile (kdump kernel) */
static inline bool mlx4_low_memory_profile(void)
diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h
index 587cdf943b52..deaa2217214d 100644
--- a/include/linux/mlx4/qp.h
+++ b/include/linux/mlx4/qp.h
@@ -291,16 +291,18 @@ enum {
MLX4_WQE_CTRL_FORCE_LOOPBACK = 1 << 0,
};
+union mlx4_wqe_qpn_vlan {
+ struct {
+ __be16 vlan_tag;
+ u8 ins_vlan;
+ u8 fence_size;
+ };
+ __be32 bf_qpn;
+};
+
struct mlx4_wqe_ctrl_seg {
__be32 owner_opcode;
- union {
- struct {
- __be16 vlan_tag;
- u8 ins_vlan;
- u8 fence_size;
- };
- __be32 bf_qpn;
- };
+ union mlx4_wqe_qpn_vlan qpn_vlan;
/*
* High 24 bits are SRC remote buffer; low 8 bits are flags:
* [7] SO (strong ordering)
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index 73a48479892d..0b6d15cddb2f 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -129,6 +129,13 @@ __mlx5_mask(typ, fld))
tmp; \
})
+enum mlx5_inline_modes {
+ MLX5_INLINE_MODE_NONE,
+ MLX5_INLINE_MODE_L2,
+ MLX5_INLINE_MODE_IP,
+ MLX5_INLINE_MODE_TCP_UDP,
+};
+
enum {
MLX5_MAX_COMMANDS = 32,
MLX5_CMD_DATA_BLOCK_SIZE = 512,
@@ -1330,6 +1337,7 @@ enum mlx5_cap_type {
MLX5_CAP_ESWITCH,
MLX5_CAP_RESERVED,
MLX5_CAP_VECTOR_CALC,
+ MLX5_CAP_QOS,
/* NUM OF CAP Types */
MLX5_CAP_NUM
};
@@ -1414,6 +1422,9 @@ enum mlx5_cap_type {
MLX5_GET(vector_calc_cap, \
mdev->hca_caps_cur[MLX5_CAP_VECTOR_CALC], cap)
+#define MLX5_CAP_QOS(mdev, cap)\
+ MLX5_GET(qos_cap, mdev->hca_caps_cur[MLX5_CAP_QOS], cap)
+
enum {
MLX5_CMD_STAT_OK = 0x0,
MLX5_CMD_STAT_INT_ERR = 0x1,
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index fd72ecf0ce9f..a041b99fceac 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -469,7 +469,7 @@ struct mlx5_irq_info {
};
struct mlx5_fc_stats {
- struct list_head list;
+ struct rb_root counters;
struct list_head addlist;
/* protect addlist add/splice operations */
spinlock_t addlist_lock;
@@ -481,6 +481,21 @@ struct mlx5_fc_stats {
struct mlx5_eswitch;
+struct mlx5_rl_entry {
+ u32 rate;
+ u16 index;
+ u16 refcount;
+};
+
+struct mlx5_rl_table {
+ /* protect rate limit table */
+ struct mutex rl_lock;
+ u16 max_size;
+ u32 max_rate;
+ u32 min_rate;
+ struct mlx5_rl_entry *rl_entry;
+};
+
struct mlx5_priv {
char name[MLX5_MAX_NAME_LEN];
struct mlx5_eq_table eq_table;
@@ -535,15 +550,12 @@ struct mlx5_priv {
struct list_head ctx_list;
spinlock_t ctx_lock;
+ struct mlx5_flow_steering *steering;
struct mlx5_eswitch *eswitch;
struct mlx5_core_sriov sriov;
unsigned long pci_dev_data;
- struct mlx5_flow_root_namespace *root_ns;
- struct mlx5_flow_root_namespace *fdb_root_ns;
- struct mlx5_flow_root_namespace *esw_egress_root_ns;
- struct mlx5_flow_root_namespace *esw_ingress_root_ns;
-
struct mlx5_fc_stats fc_stats;
+ struct mlx5_rl_table rl_table;
};
enum mlx5_device_state {
@@ -562,6 +574,18 @@ enum mlx5_pci_status {
MLX5_PCI_STATUS_ENABLED,
};
+struct mlx5_td {
+ struct list_head tirs_list;
+ u32 tdn;
+};
+
+struct mlx5e_resources {
+ struct mlx5_uar cq_uar;
+ u32 pdn;
+ struct mlx5_td td;
+ struct mlx5_core_mkey mkey;
+};
+
struct mlx5_core_dev {
struct pci_dev *pdev;
/* sync pci state */
@@ -586,6 +610,7 @@ struct mlx5_core_dev {
struct mlx5_profile *profile;
atomic_t num_qps;
u32 issi;
+ struct mlx5e_resources mlx5e_res;
#ifdef CONFIG_RFS_ACCEL
struct cpu_rmap *rmap;
#endif
@@ -862,6 +887,12 @@ int mlx5_query_odp_caps(struct mlx5_core_dev *dev,
int mlx5_core_query_ib_ppcnt(struct mlx5_core_dev *dev,
u8 port_num, void *out, size_t sz);
+int mlx5_init_rl_table(struct mlx5_core_dev *dev);
+void mlx5_cleanup_rl_table(struct mlx5_core_dev *dev);
+int mlx5_rl_add_rate(struct mlx5_core_dev *dev, u32 rate, u16 *index);
+void mlx5_rl_remove_rate(struct mlx5_core_dev *dev, u32 rate);
+bool mlx5_rl_is_in_range(struct mlx5_core_dev *dev, u32 rate);
+
static inline int fw_initializing(struct mlx5_core_dev *dev)
{
return ioread32be(&dev->iseg->initializing) >> 31;
@@ -939,6 +970,11 @@ static inline int mlx5_get_gid_table_len(u16 param)
return 8 * (1 << param);
}
+static inline bool mlx5_rl_is_supported(struct mlx5_core_dev *dev)
+{
+ return !!(dev->priv.rl_table.max_size);
+}
+
enum {
MLX5_TRIGGERED_CMD_COMP = (u64)1 << 32,
};
diff --git a/include/linux/mlx5/fs.h b/include/linux/mlx5/fs.h
index 4b7a107d9c19..e036d6030867 100644
--- a/include/linux/mlx5/fs.h
+++ b/include/linux/mlx5/fs.h
@@ -54,6 +54,8 @@ static inline void build_leftovers_ft_param(int *priority,
enum mlx5_flow_namespace_type {
MLX5_FLOW_NAMESPACE_BYPASS,
+ MLX5_FLOW_NAMESPACE_OFFLOADS,
+ MLX5_FLOW_NAMESPACE_ETHTOOL,
MLX5_FLOW_NAMESPACE_KERNEL,
MLX5_FLOW_NAMESPACE_LEFTOVERS,
MLX5_FLOW_NAMESPACE_ANCHOR,
@@ -67,6 +69,12 @@ struct mlx5_flow_group;
struct mlx5_flow_rule;
struct mlx5_flow_namespace;
+struct mlx5_flow_spec {
+ u8 match_criteria_enable;
+ u32 match_criteria[MLX5_ST_SZ_DW(fte_match_param)];
+ u32 match_value[MLX5_ST_SZ_DW(fte_match_param)];
+};
+
struct mlx5_flow_destination {
enum mlx5_flow_destination_type type;
union {
@@ -115,9 +123,7 @@ void mlx5_destroy_flow_group(struct mlx5_flow_group *fg);
*/
struct mlx5_flow_rule *
mlx5_add_flow_rule(struct mlx5_flow_table *ft,
- u8 match_criteria_enable,
- u32 *match_criteria,
- u32 *match_value,
+ struct mlx5_flow_spec *spec,
u32 action,
u32 flow_tag,
struct mlx5_flow_destination *dest);
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index e955a2859009..21bc4557b67a 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -123,6 +123,10 @@ enum {
MLX5_CMD_OP_DRAIN_DCT = 0x712,
MLX5_CMD_OP_QUERY_DCT = 0x713,
MLX5_CMD_OP_ARM_DCT_FOR_KEY_VIOLATION = 0x714,
+ MLX5_CMD_OP_CREATE_XRQ = 0x717,
+ MLX5_CMD_OP_DESTROY_XRQ = 0x718,
+ MLX5_CMD_OP_QUERY_XRQ = 0x719,
+ MLX5_CMD_OP_ARM_XRQ = 0x71a,
MLX5_CMD_OP_QUERY_VPORT_STATE = 0x750,
MLX5_CMD_OP_MODIFY_VPORT_STATE = 0x751,
MLX5_CMD_OP_QUERY_ESW_VPORT_CONTEXT = 0x752,
@@ -139,6 +143,8 @@ enum {
MLX5_CMD_OP_ALLOC_Q_COUNTER = 0x771,
MLX5_CMD_OP_DEALLOC_Q_COUNTER = 0x772,
MLX5_CMD_OP_QUERY_Q_COUNTER = 0x773,
+ MLX5_CMD_OP_SET_RATE_LIMIT = 0x780,
+ MLX5_CMD_OP_QUERY_RATE_LIMIT = 0x781,
MLX5_CMD_OP_ALLOC_PD = 0x800,
MLX5_CMD_OP_DEALLOC_PD = 0x801,
MLX5_CMD_OP_ALLOC_UAR = 0x802,
@@ -362,7 +368,8 @@ struct mlx5_ifc_fte_match_set_lyr_2_4_bits {
};
struct mlx5_ifc_fte_match_set_misc_bits {
- u8 reserved_at_0[0x20];
+ u8 reserved_at_0[0x8];
+ u8 source_sqn[0x18];
u8 reserved_at_20[0x10];
u8 source_port[0x10];
@@ -508,6 +515,17 @@ struct mlx5_ifc_e_switch_cap_bits {
u8 reserved_at_20[0x7e0];
};
+struct mlx5_ifc_qos_cap_bits {
+ u8 packet_pacing[0x1];
+ u8 reserved_0[0x1f];
+ u8 reserved_1[0x20];
+ u8 packet_pacing_max_rate[0x20];
+ u8 packet_pacing_min_rate[0x20];
+ u8 reserved_2[0x10];
+ u8 packet_pacing_rate_table_size[0x10];
+ u8 reserved_3[0x760];
+};
+
struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
u8 csum_cap[0x1];
u8 vlan_cap[0x1];
@@ -518,7 +536,8 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
u8 self_lb_en_modifiable[0x1];
u8 reserved_at_9[0x2];
u8 max_lso_cap[0x5];
- u8 reserved_at_10[0x4];
+ u8 reserved_at_10[0x2];
+ u8 wqe_inline_mode[0x2];
u8 rss_ind_tbl_cap[0x4];
u8 reg_umr_sq[0x1];
u8 scatter_fcs[0x1];
@@ -747,7 +766,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 out_of_seq_cnt[0x1];
u8 vport_counters[0x1];
- u8 reserved_at_182[0x4];
+ u8 retransmission_q_counters[0x1];
+ u8 reserved_at_183[0x3];
u8 max_qp_cnt[0xa];
u8 pkey_table_size[0x10];
@@ -774,7 +794,9 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 log_max_msg[0x5];
u8 reserved_at_1c8[0x4];
u8 max_tc[0x4];
- u8 reserved_at_1d0[0x6];
+ u8 reserved_at_1d0[0x1];
+ u8 dcbx[0x1];
+ u8 reserved_at_1d2[0x4];
u8 rol_s[0x1];
u8 rol_g[0x1];
u8 reserved_at_1d8[0x1];
@@ -806,7 +828,7 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 tph[0x1];
u8 rf[0x1];
u8 dct[0x1];
- u8 reserved_at_21b[0x1];
+ u8 qos[0x1];
u8 eth_net_offloads[0x1];
u8 roce[0x1];
u8 atomic[0x1];
@@ -872,7 +894,10 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 reserved_at_330[0xb];
u8 log_max_xrcd[0x5];
- u8 reserved_at_340[0x20];
+ u8 reserved_at_340[0x8];
+ u8 log_max_flow_counter_bulk[0x8];
+ u8 max_flow_counter[0x10];
+
u8 reserved_at_360[0x3];
u8 log_max_rq[0x5];
@@ -932,7 +957,15 @@ struct mlx5_ifc_cmd_hca_cap_bits {
u8 cqe_compression_timeout[0x10];
u8 cqe_compression_max_num[0x10];
- u8 reserved_at_5e0[0x220];
+ u8 reserved_at_5e0[0x10];
+ u8 tag_matching[0x1];
+ u8 rndv_offload_rc[0x1];
+ u8 rndv_offload_dc[0x1];
+ u8 log_tag_matching_list_sz[0x5];
+ u8 reserved_at_5e8[0x3];
+ u8 log_max_xrq[0x5];
+
+ u8 reserved_at_5f0[0x200];
};
enum mlx5_flow_destination_type {
@@ -951,7 +984,8 @@ struct mlx5_ifc_dest_format_struct_bits {
};
struct mlx5_ifc_flow_counter_list_bits {
- u8 reserved_at_0[0x10];
+ u8 clear[0x1];
+ u8 num_of_counters[0xf];
u8 flow_counter_id[0x10];
u8 reserved_at_20[0x20];
@@ -1970,7 +2004,7 @@ struct mlx5_ifc_qpc_bits {
u8 reserved_at_560[0x5];
u8 rq_type[0x3];
- u8 srqn_rmpn[0x18];
+ u8 srqn_rmpn_xrqn[0x18];
u8 reserved_at_580[0x8];
u8 rmsn[0x18];
@@ -2021,6 +2055,7 @@ union mlx5_ifc_hca_cap_union_bits {
struct mlx5_ifc_flow_table_eswitch_cap_bits flow_table_eswitch_cap;
struct mlx5_ifc_e_switch_cap_bits e_switch_cap;
struct mlx5_ifc_vector_calc_cap_bits vector_calc_cap;
+ struct mlx5_ifc_qos_cap_bits qos_cap;
u8 reserved_at_0[0x8000];
};
@@ -2236,7 +2271,8 @@ struct mlx5_ifc_sqc_bits {
u8 cd_master[0x1];
u8 fre[0x1];
u8 flush_in_error_en[0x1];
- u8 reserved_at_4[0x4];
+ u8 reserved_at_4[0x1];
+ u8 min_wqe_inline_mode[0x3];
u8 state[0x4];
u8 reg_umr[0x1];
u8 reserved_at_d[0x13];
@@ -2247,8 +2283,9 @@ struct mlx5_ifc_sqc_bits {
u8 reserved_at_40[0x8];
u8 cqn[0x18];
- u8 reserved_at_60[0xa0];
+ u8 reserved_at_60[0x90];
+ u8 packet_pacing_rate_limit_index[0x10];
u8 tis_lst_sz[0x10];
u8 reserved_at_110[0x10];
@@ -2332,7 +2369,9 @@ struct mlx5_ifc_rmpc_bits {
};
struct mlx5_ifc_nic_vport_context_bits {
- u8 reserved_at_0[0x1f];
+ u8 reserved_at_0[0x5];
+ u8 min_wqe_inline_mode[0x3];
+ u8 reserved_at_8[0x17];
u8 roce_en[0x1];
u8 arm_change_event[0x1];
@@ -2596,7 +2635,7 @@ struct mlx5_ifc_dctc_bits {
u8 reserved_at_98[0x8];
u8 reserved_at_a0[0x8];
- u8 srqn[0x18];
+ u8 srqn_xrqn[0x18];
u8 reserved_at_c0[0x8];
u8 pd[0x18];
@@ -2648,6 +2687,7 @@ enum {
enum {
MLX5_CQ_PERIOD_MODE_START_FROM_EQE = 0x0,
MLX5_CQ_PERIOD_MODE_START_FROM_CQE = 0x1,
+ MLX5_CQ_PERIOD_NUM_MODES
};
struct mlx5_ifc_cqc_bits {
@@ -2725,6 +2765,54 @@ struct mlx5_ifc_query_adapter_param_block_bits {
u8 vsd_contd_psid[16][0x8];
};
+enum {
+ MLX5_XRQC_STATE_GOOD = 0x0,
+ MLX5_XRQC_STATE_ERROR = 0x1,
+};
+
+enum {
+ MLX5_XRQC_TOPOLOGY_NO_SPECIAL_TOPOLOGY = 0x0,
+ MLX5_XRQC_TOPOLOGY_TAG_MATCHING = 0x1,
+};
+
+enum {
+ MLX5_XRQC_OFFLOAD_RNDV = 0x1,
+};
+
+struct mlx5_ifc_tag_matching_topology_context_bits {
+ u8 log_matching_list_sz[0x4];
+ u8 reserved_at_4[0xc];
+ u8 append_next_index[0x10];
+
+ u8 sw_phase_cnt[0x10];
+ u8 hw_phase_cnt[0x10];
+
+ u8 reserved_at_40[0x40];
+};
+
+struct mlx5_ifc_xrqc_bits {
+ u8 state[0x4];
+ u8 rlkey[0x1];
+ u8 reserved_at_5[0xf];
+ u8 topology[0x4];
+ u8 reserved_at_18[0x4];
+ u8 offload[0x4];
+
+ u8 reserved_at_20[0x8];
+ u8 user_index[0x18];
+
+ u8 reserved_at_40[0x8];
+ u8 cqn[0x18];
+
+ u8 reserved_at_60[0xa0];
+
+ struct mlx5_ifc_tag_matching_topology_context_bits tag_matching_topology_context;
+
+ u8 reserved_at_180[0x180];
+
+ struct mlx5_ifc_wq_bits wq;
+};
+
union mlx5_ifc_modify_field_select_resize_field_select_auto_bits {
struct mlx5_ifc_modify_field_select_bits modify_field_select;
struct mlx5_ifc_resize_field_select_bits resize_field_select;
@@ -3147,6 +3235,30 @@ struct mlx5_ifc_rst2init_qp_in_bits {
u8 reserved_at_800[0x80];
};
+struct mlx5_ifc_query_xrq_out_bits {
+ u8 status[0x8];
+ u8 reserved_at_8[0x18];
+
+ u8 syndrome[0x20];
+
+ u8 reserved_at_40[0x40];
+
+ struct mlx5_ifc_xrqc_bits xrq_context;
+};
+
+struct mlx5_ifc_query_xrq_in_bits {
+ u8 opcode[0x10];
+ u8 reserved_at_10[0x10];
+
+ u8 reserved_at_20[0x10];
+ u8 op_mod[0x10];
+
+ u8 reserved_at_40[0x8];
+ u8 xrqn[0x18];
+
+ u8 reserved_at_60[0x20];
+};
+
struct mlx5_ifc_query_xrc_srq_out_bits {
u8 status[0x8];
u8 reserved_at_8[0x18];
@@ -3550,7 +3662,27 @@ struct mlx5_ifc_query_q_counter_out_bits {
u8 out_of_sequence[0x20];
- u8 reserved_at_1e0[0x620];
+ u8 reserved_at_1e0[0x20];
+
+ u8 duplicate_request[0x20];
+
+ u8 reserved_at_220[0x20];
+
+ u8 rnr_nak_retry_err[0x20];
+
+ u8 reserved_at_260[0x20];
+
+ u8 packet_seq_err[0x20];
+
+ u8 reserved_at_2a0[0x20];
+
+ u8 implied_nak_seq_err[0x20];
+
+ u8 reserved_at_2e0[0x20];
+
+ u8 local_ack_timeout_err[0x20];
+
+ u8 reserved_at_320[0x4e0];
};
struct mlx5_ifc_query_q_counter_in_bits {
@@ -5004,6 +5136,28 @@ struct mlx5_ifc_detach_from_mcg_in_bits {
u8 multicast_gid[16][0x8];
};
+struct mlx5_ifc_destroy_xrq_out_bits {
+ u8 status[0x8];
+ u8 reserved_at_8[0x18];
+
+ u8 syndrome[0x20];
+
+ u8 reserved_at_40[0x40];
+};
+
+struct mlx5_ifc_destroy_xrq_in_bits {
+ u8 opcode[0x10];
+ u8 reserved_at_10[0x10];
+
+ u8 reserved_at_20[0x10];
+ u8 op_mod[0x10];
+
+ u8 reserved_at_40[0x8];
+ u8 xrqn[0x18];
+
+ u8 reserved_at_60[0x20];
+};
+
struct mlx5_ifc_destroy_xrc_srq_out_bits {
u8 status[0x8];
u8 reserved_at_8[0x18];
@@ -5589,6 +5743,30 @@ struct mlx5_ifc_dealloc_flow_counter_in_bits {
u8 reserved_at_60[0x20];
};
+struct mlx5_ifc_create_xrq_out_bits {
+ u8 status[0x8];
+ u8 reserved_at_8[0x18];
+
+ u8 syndrome[0x20];
+
+ u8 reserved_at_40[0x8];
+ u8 xrqn[0x18];
+
+ u8 reserved_at_60[0x20];
+};
+
+struct mlx5_ifc_create_xrq_in_bits {
+ u8 opcode[0x10];
+ u8 reserved_at_10[0x10];
+
+ u8 reserved_at_20[0x10];
+ u8 op_mod[0x10];
+
+ u8 reserved_at_40[0x40];
+
+ struct mlx5_ifc_xrqc_bits xrq_context;
+};
+
struct mlx5_ifc_create_xrc_srq_out_bits {
u8 status[0x8];
u8 reserved_at_8[0x18];
@@ -6130,6 +6308,29 @@ struct mlx5_ifc_attach_to_mcg_in_bits {
u8 multicast_gid[16][0x8];
};
+struct mlx5_ifc_arm_xrq_out_bits {
+ u8 status[0x8];
+ u8 reserved_at_8[0x18];
+
+ u8 syndrome[0x20];
+
+ u8 reserved_at_40[0x40];
+};
+
+struct mlx5_ifc_arm_xrq_in_bits {
+ u8 opcode[0x10];
+ u8 reserved_at_10[0x10];
+
+ u8 reserved_at_20[0x10];
+ u8 op_mod[0x10];
+
+ u8 reserved_at_40[0x8];
+ u8 xrqn[0x18];
+
+ u8 reserved_at_60[0x10];
+ u8 lwm[0x10];
+};
+
struct mlx5_ifc_arm_xrc_srq_out_bits {
u8 status[0x8];
u8 reserved_at_8[0x18];
@@ -6167,7 +6368,8 @@ struct mlx5_ifc_arm_rq_out_bits {
};
enum {
- MLX5_ARM_RQ_IN_OP_MOD_SRQ_ = 0x1,
+ MLX5_ARM_RQ_IN_OP_MOD_SRQ = 0x1,
+ MLX5_ARM_RQ_IN_OP_MOD_XRQ = 0x2,
};
struct mlx5_ifc_arm_rq_in_bits {
@@ -6360,6 +6562,30 @@ struct mlx5_ifc_add_vxlan_udp_dport_in_bits {
u8 vxlan_udp_port[0x10];
};
+struct mlx5_ifc_set_rate_limit_out_bits {
+ u8 status[0x8];
+ u8 reserved_at_8[0x18];
+
+ u8 syndrome[0x20];
+
+ u8 reserved_at_40[0x40];
+};
+
+struct mlx5_ifc_set_rate_limit_in_bits {
+ u8 opcode[0x10];
+ u8 reserved_at_10[0x10];
+
+ u8 reserved_at_20[0x10];
+ u8 op_mod[0x10];
+
+ u8 reserved_at_40[0x10];
+ u8 rate_limit_index[0x10];
+
+ u8 reserved_at_60[0x20];
+
+ u8 rate_limit[0x20];
+};
+
struct mlx5_ifc_access_register_out_bits {
u8 status[0x8];
u8 reserved_at_8[0x18];
@@ -6484,12 +6710,15 @@ struct mlx5_ifc_pude_reg_bits {
};
struct mlx5_ifc_ptys_reg_bits {
- u8 reserved_at_0[0x8];
+ u8 an_disable_cap[0x1];
+ u8 an_disable_admin[0x1];
+ u8 reserved_at_2[0x6];
u8 local_port[0x8];
u8 reserved_at_10[0xd];
u8 proto_mask[0x3];
- u8 reserved_at_20[0x40];
+ u8 an_status[0x4];
+ u8 reserved_at_24[0x3c];
u8 eth_proto_capability[0x20];
@@ -7450,4 +7679,34 @@ struct mlx5_ifc_mcia_reg_bits {
u8 dword_11[0x20];
};
+struct mlx5_ifc_dcbx_param_bits {
+ u8 dcbx_cee_cap[0x1];
+ u8 dcbx_ieee_cap[0x1];
+ u8 dcbx_standby_cap[0x1];
+ u8 reserved_at_0[0x5];
+ u8 port_number[0x8];
+ u8 reserved_at_10[0xa];
+ u8 max_application_table_size[6];
+ u8 reserved_at_20[0x15];
+ u8 version_oper[0x3];
+ u8 reserved_at_38[5];
+ u8 version_admin[0x3];
+ u8 willing_admin[0x1];
+ u8 reserved_at_41[0x3];
+ u8 pfc_cap_oper[0x4];
+ u8 reserved_at_48[0x4];
+ u8 pfc_cap_admin[0x4];
+ u8 reserved_at_50[0x4];
+ u8 num_of_tc_oper[0x4];
+ u8 reserved_at_58[0x4];
+ u8 num_of_tc_admin[0x4];
+ u8 remote_willing[0x1];
+ u8 reserved_at_61[3];
+ u8 remote_pfc_cap[4];
+ u8 reserved_at_68[0x14];
+ u8 remote_num_of_tc[0x4];
+ u8 reserved_at_80[0x18];
+ u8 error[0x8];
+ u8 reserved_at_a0[0x160];
+};
#endif /* MLX5_IFC_H */
diff --git a/include/linux/mlx5/port.h b/include/linux/mlx5/port.h
index 9851862c0ec5..e3012cc64b8a 100644
--- a/include/linux/mlx5/port.h
+++ b/include/linux/mlx5/port.h
@@ -47,6 +47,14 @@ enum mlx5_module_id {
MLX5_MODULE_ID_QSFP28 = 0x11,
};
+enum mlx5_an_status {
+ MLX5_AN_UNAVAILABLE = 0,
+ MLX5_AN_COMPLETE = 1,
+ MLX5_AN_FAILED = 2,
+ MLX5_AN_LINK_UP = 3,
+ MLX5_AN_LINK_DOWN = 4,
+};
+
#define MLX5_EEPROM_MAX_BYTES 32
#define MLX5_EEPROM_IDENTIFIER_BYTE_MASK 0x000000ff
#define MLX5_I2C_ADDR_LOW 0x50
@@ -65,13 +73,17 @@ int mlx5_query_port_link_width_oper(struct mlx5_core_dev *dev,
int mlx5_query_port_proto_oper(struct mlx5_core_dev *dev,
u8 *proto_oper, int proto_mask,
u8 local_port);
-int mlx5_set_port_proto(struct mlx5_core_dev *dev, u32 proto_admin,
- int proto_mask);
+int mlx5_set_port_ptys(struct mlx5_core_dev *dev, bool an_disable,
+ u32 proto_admin, int proto_mask);
+void mlx5_toggle_port_link(struct mlx5_core_dev *dev);
int mlx5_set_port_admin_status(struct mlx5_core_dev *dev,
enum mlx5_port_status status);
int mlx5_query_port_admin_status(struct mlx5_core_dev *dev,
enum mlx5_port_status *status);
int mlx5_set_port_beacon(struct mlx5_core_dev *dev, u16 beacon_duration);
+void mlx5_query_port_autoneg(struct mlx5_core_dev *dev, int proto_mask,
+ u8 *an_status,
+ u8 *an_disable_cap, u8 *an_disable_admin);
int mlx5_set_port_mtu(struct mlx5_core_dev *dev, u16 mtu, u8 port);
void mlx5_query_port_max_mtu(struct mlx5_core_dev *dev, u16 *max_mtu, u8 port);
diff --git a/include/linux/mlx5/vport.h b/include/linux/mlx5/vport.h
index 6c16c198f680..e087b7d047ac 100644
--- a/include/linux/mlx5/vport.h
+++ b/include/linux/mlx5/vport.h
@@ -43,6 +43,8 @@ int mlx5_modify_vport_admin_state(struct mlx5_core_dev *mdev, u8 opmod,
u16 vport, u8 state);
int mlx5_query_nic_vport_mac_address(struct mlx5_core_dev *mdev,
u16 vport, u8 *addr);
+void mlx5_query_nic_vport_min_inline(struct mlx5_core_dev *mdev,
+ u8 *min_inline);
int mlx5_modify_nic_vport_mac_address(struct mlx5_core_dev *dev,
u16 vport, u8 *addr);
int mlx5_query_nic_vport_mtu(struct mlx5_core_dev *mdev, u16 *mtu);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index ece042dfe23c..08ed53eeedd5 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -309,10 +309,34 @@ struct vm_fault {
* VM_FAULT_DAX_LOCKED and fill in
* entry here.
*/
- /* for ->map_pages() only */
- pgoff_t max_pgoff; /* map pages for offset from pgoff till
- * max_pgoff inclusive */
- pte_t *pte; /* pte entry associated with ->pgoff */
+};
+
+/*
+ * Page fault context: passes though page fault handler instead of endless list
+ * of function arguments.
+ */
+struct fault_env {
+ struct vm_area_struct *vma; /* Target VMA */
+ unsigned long address; /* Faulting virtual address */
+ unsigned int flags; /* FAULT_FLAG_xxx flags */
+ pmd_t *pmd; /* Pointer to pmd entry matching
+ * the 'address'
+ */
+ pte_t *pte; /* Pointer to pte entry matching
+ * the 'address'. NULL if the page
+ * table hasn't been allocated.
+ */
+ spinlock_t *ptl; /* Page table lock.
+ * Protects pte page table if 'pte'
+ * is not NULL, otherwise pmd.
+ */
+ pgtable_t prealloc_pte; /* Pre-allocated pte page table.
+ * vm_ops->map_pages() calls
+ * alloc_set_pte() from atomic context.
+ * do_fault_around() pre-allocates
+ * page table to avoid allocation from
+ * atomic context.
+ */
};
/*
@@ -327,7 +351,8 @@ struct vm_operations_struct {
int (*fault)(struct vm_area_struct *vma, struct vm_fault *vmf);
int (*pmd_fault)(struct vm_area_struct *, unsigned long address,
pmd_t *, unsigned int flags);
- void (*map_pages)(struct vm_area_struct *vma, struct vm_fault *vmf);
+ void (*map_pages)(struct fault_env *fe,
+ pgoff_t start_pgoff, pgoff_t end_pgoff);
/* notification that a previously read-only page is about to become
* writable, if an error is returned it will cause a SIGBUS */
@@ -537,7 +562,6 @@ void __put_page(struct page *page);
void put_pages_list(struct list_head *pages);
void split_page(struct page *page, unsigned int order);
-int split_free_page(struct page *page);
/*
* Compound pages have a destructor function. Provide a
@@ -601,8 +625,8 @@ static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma)
return pte;
}
-void do_set_pte(struct vm_area_struct *vma, unsigned long address,
- struct page *page, pte_t *pte, bool write, bool anon);
+int alloc_set_pte(struct fault_env *fe, struct mem_cgroup *memcg,
+ struct page *page);
#endif
/*
@@ -909,6 +933,11 @@ static inline struct zone *page_zone(const struct page *page)
return &NODE_DATA(page_to_nid(page))->node_zones[page_zonenum(page)];
}
+static inline pg_data_t *page_pgdat(const struct page *page)
+{
+ return NODE_DATA(page_to_nid(page));
+}
+
#ifdef SECTION_IN_PAGE_FLAGS
static inline void set_page_section(struct page *page, unsigned long section)
{
@@ -949,11 +978,21 @@ static inline struct mem_cgroup *page_memcg(struct page *page)
{
return page->mem_cgroup;
}
+static inline struct mem_cgroup *page_memcg_rcu(struct page *page)
+{
+ WARN_ON_ONCE(!rcu_read_lock_held());
+ return READ_ONCE(page->mem_cgroup);
+}
#else
static inline struct mem_cgroup *page_memcg(struct page *page)
{
return NULL;
}
+static inline struct mem_cgroup *page_memcg_rcu(struct page *page)
+{
+ WARN_ON_ONCE(!rcu_read_lock_held());
+ return NULL;
+}
#endif
/*
@@ -1035,6 +1074,7 @@ static inline pgoff_t page_file_index(struct page *page)
}
bool page_mapped(struct page *page);
+struct address_space *page_mapping(struct page *page);
/*
* Return true only if the page has been allocated with
@@ -1215,15 +1255,14 @@ int generic_error_remove_page(struct address_space *mapping, struct page *page);
int invalidate_inode_page(struct page *page);
#ifdef CONFIG_MMU
-extern int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long address, unsigned int flags);
+extern int handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
+ unsigned int flags);
extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
unsigned long address, unsigned int fault_flags,
bool *unlocked);
#else
-static inline int handle_mm_fault(struct mm_struct *mm,
- struct vm_area_struct *vma, unsigned long address,
- unsigned int flags)
+static inline int handle_mm_fault(struct vm_area_struct *vma,
+ unsigned long address, unsigned int flags)
{
/* should never happen if there's no MMU */
BUG();
@@ -2063,7 +2102,8 @@ extern void truncate_inode_pages_final(struct address_space *);
/* generic vm_area_ops exported for stackable file systems */
extern int filemap_fault(struct vm_area_struct *, struct vm_fault *);
-extern void filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf);
+extern void filemap_map_pages(struct fault_env *fe,
+ pgoff_t start_pgoff, pgoff_t end_pgoff);
extern int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
/* mm/page-writeback.c */
@@ -2259,6 +2299,8 @@ static inline int in_gate_area(struct mm_struct *mm, unsigned long addr)
}
#endif /* __HAVE_ARCH_GATE_AREA */
+extern bool process_shares_mm(struct task_struct *p, struct mm_struct *mm);
+
#ifdef CONFIG_SYSCTL
extern int sysctl_drop_caches;
int drop_caches_sysctl_handler(struct ctl_table *, int,
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index 5bd29ba4f174..71613e8a720f 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -23,25 +23,30 @@ static inline int page_is_file_cache(struct page *page)
}
static __always_inline void __update_lru_size(struct lruvec *lruvec,
- enum lru_list lru, int nr_pages)
+ enum lru_list lru, enum zone_type zid,
+ int nr_pages)
{
- __mod_zone_page_state(lruvec_zone(lruvec), NR_LRU_BASE + lru, nr_pages);
+ struct pglist_data *pgdat = lruvec_pgdat(lruvec);
+
+ __mod_node_page_state(pgdat, NR_LRU_BASE + lru, nr_pages);
+ __mod_zone_page_state(&pgdat->node_zones[zid],
+ NR_ZONE_LRU_BASE + lru, nr_pages);
}
static __always_inline void update_lru_size(struct lruvec *lruvec,
- enum lru_list lru, int nr_pages)
+ enum lru_list lru, enum zone_type zid,
+ int nr_pages)
{
+ __update_lru_size(lruvec, lru, zid, nr_pages);
#ifdef CONFIG_MEMCG
mem_cgroup_update_lru_size(lruvec, lru, nr_pages);
-#else
- __update_lru_size(lruvec, lru, nr_pages);
#endif
}
static __always_inline void add_page_to_lru_list(struct page *page,
struct lruvec *lruvec, enum lru_list lru)
{
- update_lru_size(lruvec, lru, hpage_nr_pages(page));
+ update_lru_size(lruvec, lru, page_zonenum(page), hpage_nr_pages(page));
list_add(&page->lru, &lruvec->lists[lru]);
}
@@ -49,7 +54,7 @@ static __always_inline void del_page_from_lru_list(struct page *page,
struct lruvec *lruvec, enum lru_list lru)
{
list_del(&page->lru);
- update_lru_size(lruvec, lru, -hpage_nr_pages(page));
+ update_lru_size(lruvec, lru, page_zonenum(page), -hpage_nr_pages(page));
}
/**
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index ca3e517980a0..903200f4ec41 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -60,51 +60,52 @@ struct page {
};
/* Second double word */
- struct {
- union {
- pgoff_t index; /* Our offset within mapping. */
- void *freelist; /* sl[aou]b first free object */
- /* page_deferred_list().prev -- second tail page */
- };
+ union {
+ pgoff_t index; /* Our offset within mapping. */
+ void *freelist; /* sl[aou]b first free object */
+ /* page_deferred_list().prev -- second tail page */
+ };
- union {
+ union {
#if defined(CONFIG_HAVE_CMPXCHG_DOUBLE) && \
defined(CONFIG_HAVE_ALIGNED_STRUCT_PAGE)
- /* Used for cmpxchg_double in slub */
- unsigned long counters;
+ /* Used for cmpxchg_double in slub */
+ unsigned long counters;
#else
- /*
- * Keep _refcount separate from slub cmpxchg_double
- * data. As the rest of the double word is protected by
- * slab_lock but _refcount is not.
- */
- unsigned counters;
+ /*
+ * Keep _refcount separate from slub cmpxchg_double data.
+ * As the rest of the double word is protected by slab_lock
+ * but _refcount is not.
+ */
+ unsigned counters;
#endif
+ struct {
- struct {
-
- union {
- /*
- * Count of ptes mapped in mms, to show
- * when page is mapped & limit reverse
- * map searches.
- */
- atomic_t _mapcount;
-
- struct { /* SLUB */
- unsigned inuse:16;
- unsigned objects:15;
- unsigned frozen:1;
- };
- int units; /* SLOB */
- };
+ union {
/*
- * Usage count, *USE WRAPPER FUNCTION*
- * when manual accounting. See page_ref.h
+ * Count of ptes mapped in mms, to show when
+ * page is mapped & limit reverse map searches.
+ *
+ * Extra information about page type may be
+ * stored here for pages that are never mapped,
+ * in which case the value MUST BE <= -2.
+ * See page-flags.h for more details.
*/
- atomic_t _refcount;
+ atomic_t _mapcount;
+
+ unsigned int active; /* SLAB */
+ struct { /* SLUB */
+ unsigned inuse:16;
+ unsigned objects:15;
+ unsigned frozen:1;
+ };
+ int units; /* SLOB */
};
- unsigned int active; /* SLAB */
+ /*
+ * Usage count, *USE WRAPPER FUNCTION* when manual
+ * accounting. See page_ref.h
+ */
+ atomic_t _refcount;
};
};
@@ -117,7 +118,7 @@ struct page {
*/
union {
struct list_head lru; /* Pageout list, eg. active_list
- * protected by zone->lru_lock !
+ * protected by zone_lru_lock !
* Can be used as a generic list
* by the page owner.
*/
@@ -594,6 +595,9 @@ struct vm_special_mapping {
int (*fault)(const struct vm_special_mapping *sm,
struct vm_area_struct *vma,
struct vm_fault *vmf);
+
+ int (*mremap)(const struct vm_special_mapping *sm,
+ struct vm_area_struct *new_vma);
};
enum tlb_flush_reason {
diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h
index de7be78c6f0e..451a811f48f2 100644
--- a/include/linux/mmdebug.h
+++ b/include/linux/mmdebug.h
@@ -39,6 +39,7 @@ void dump_mm(const struct mm_struct *mm);
#define VM_WARN_ON(cond) WARN_ON(cond)
#define VM_WARN_ON_ONCE(cond) WARN_ON_ONCE(cond)
#define VM_WARN_ONCE(cond, format...) WARN_ONCE(cond, format)
+#define VM_WARN(cond, format...) WARN(cond, format)
#else
#define VM_BUG_ON(cond) BUILD_BUG_ON_INVALID(cond)
#define VM_BUG_ON_PAGE(cond, page) VM_BUG_ON(cond)
@@ -47,6 +48,7 @@ void dump_mm(const struct mm_struct *mm);
#define VM_WARN_ON(cond) BUILD_BUG_ON_INVALID(cond)
#define VM_WARN_ON_ONCE(cond) BUILD_BUG_ON_INVALID(cond)
#define VM_WARN_ONCE(cond, format...) BUILD_BUG_ON_INVALID(cond)
+#define VM_WARN(cond, format...) BUILD_BUG_ON_INVALID(cond)
#endif
#ifdef CONFIG_DEBUG_VIRTUAL
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 02069c23486d..f2e4e90621ec 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -93,7 +93,7 @@ struct free_area {
struct pglist_data;
/*
- * zone->lock and zone->lru_lock are two of the hottest locks in the kernel.
+ * zone->lock and the zone lru_lock are two of the hottest locks in the kernel.
* So add a wild amount of padding here to ensure that they fall into separate
* cachelines. There are very few zone structures in the machine, so space
* consumption is not a concern here.
@@ -110,36 +110,23 @@ struct zone_padding {
enum zone_stat_item {
/* First 128 byte cacheline (assuming 64 bit words) */
NR_FREE_PAGES,
- NR_ALLOC_BATCH,
- NR_LRU_BASE,
- NR_INACTIVE_ANON = NR_LRU_BASE, /* must match order of LRU_[IN]ACTIVE */
- NR_ACTIVE_ANON, /* " " " " " */
- NR_INACTIVE_FILE, /* " " " " " */
- NR_ACTIVE_FILE, /* " " " " " */
- NR_UNEVICTABLE, /* " " " " " */
+ NR_ZONE_LRU_BASE, /* Used only for compaction and reclaim retry */
+ NR_ZONE_INACTIVE_ANON = NR_ZONE_LRU_BASE,
+ NR_ZONE_ACTIVE_ANON,
+ NR_ZONE_INACTIVE_FILE,
+ NR_ZONE_ACTIVE_FILE,
+ NR_ZONE_UNEVICTABLE,
+ NR_ZONE_WRITE_PENDING, /* Count of dirty, writeback and unstable pages */
NR_MLOCK, /* mlock()ed pages found and moved off LRU */
- NR_ANON_PAGES, /* Mapped anonymous pages */
- NR_FILE_MAPPED, /* pagecache pages mapped into pagetables.
- only modified from process context */
- NR_FILE_PAGES,
- NR_FILE_DIRTY,
- NR_WRITEBACK,
NR_SLAB_RECLAIMABLE,
NR_SLAB_UNRECLAIMABLE,
NR_PAGETABLE, /* used for pagetables */
- NR_KERNEL_STACK,
+ NR_KERNEL_STACK_KB, /* measured in KiB */
/* Second 128 byte cacheline */
- NR_UNSTABLE_NFS, /* NFS unstable pages */
NR_BOUNCE,
- NR_VMSCAN_WRITE,
- NR_VMSCAN_IMMEDIATE, /* Prioritise for reclaim when writeback ends */
- NR_WRITEBACK_TEMP, /* Writeback using temporary buffers */
- NR_ISOLATED_ANON, /* Temporary isolated pages from anon lru */
- NR_ISOLATED_FILE, /* Temporary isolated pages from file lru */
- NR_SHMEM, /* shmem pages (included tmpfs/GEM pages) */
- NR_DIRTIED, /* page dirtyings since bootup */
- NR_WRITTEN, /* page writings since bootup */
- NR_PAGES_SCANNED, /* pages scanned since last reclaim */
+#if IS_ENABLED(CONFIG_ZSMALLOC)
+ NR_ZSPAGES, /* allocated in zsmalloc */
+#endif
#ifdef CONFIG_NUMA
NUMA_HIT, /* allocated in intended node */
NUMA_MISS, /* allocated in non intended node */
@@ -148,12 +135,40 @@ enum zone_stat_item {
NUMA_LOCAL, /* allocation from local node */
NUMA_OTHER, /* allocation from other node */
#endif
+ NR_FREE_CMA_PAGES,
+ NR_VM_ZONE_STAT_ITEMS };
+
+enum node_stat_item {
+ NR_LRU_BASE,
+ NR_INACTIVE_ANON = NR_LRU_BASE, /* must match order of LRU_[IN]ACTIVE */
+ NR_ACTIVE_ANON, /* " " " " " */
+ NR_INACTIVE_FILE, /* " " " " " */
+ NR_ACTIVE_FILE, /* " " " " " */
+ NR_UNEVICTABLE, /* " " " " " */
+ NR_ISOLATED_ANON, /* Temporary isolated pages from anon lru */
+ NR_ISOLATED_FILE, /* Temporary isolated pages from file lru */
+ NR_PAGES_SCANNED, /* pages scanned since last reclaim */
WORKINGSET_REFAULT,
WORKINGSET_ACTIVATE,
WORKINGSET_NODERECLAIM,
- NR_ANON_TRANSPARENT_HUGEPAGES,
- NR_FREE_CMA_PAGES,
- NR_VM_ZONE_STAT_ITEMS };
+ NR_ANON_MAPPED, /* Mapped anonymous pages */
+ NR_FILE_MAPPED, /* pagecache pages mapped into pagetables.
+ only modified from process context */
+ NR_FILE_PAGES,
+ NR_FILE_DIRTY,
+ NR_WRITEBACK,
+ NR_WRITEBACK_TEMP, /* Writeback using temporary buffers */
+ NR_SHMEM, /* shmem pages (included tmpfs/GEM pages) */
+ NR_SHMEM_THPS,
+ NR_SHMEM_PMDMAPPED,
+ NR_ANON_THPS,
+ NR_UNSTABLE_NFS, /* NFS unstable pages */
+ NR_VMSCAN_WRITE,
+ NR_VMSCAN_IMMEDIATE, /* Prioritise for reclaim when writeback ends */
+ NR_DIRTIED, /* page dirtyings since bootup */
+ NR_WRITTEN, /* page writings since bootup */
+ NR_VM_NODE_STAT_ITEMS
+};
/*
* We do arithmetic on the LRU lists in various places in the code,
@@ -210,7 +225,7 @@ struct lruvec {
/* Evictions & activations on the inactive file list */
atomic_long_t inactive_age;
#ifdef CONFIG_MEMCG
- struct zone *zone;
+ struct pglist_data *pgdat;
#endif
};
@@ -262,6 +277,11 @@ struct per_cpu_pageset {
#endif
};
+struct per_cpu_nodestat {
+ s8 stat_threshold;
+ s8 vm_node_stat_diff[NR_VM_NODE_STAT_ITEMS];
+};
+
#endif /* !__GENERATING_BOUNDS.H */
enum zone_type {
@@ -343,22 +363,9 @@ struct zone {
#ifdef CONFIG_NUMA
int node;
#endif
-
- /*
- * The target ratio of ACTIVE_ANON to INACTIVE_ANON pages on
- * this zone's LRU. Maintained by the pageout code.
- */
- unsigned int inactive_ratio;
-
struct pglist_data *zone_pgdat;
struct per_cpu_pageset __percpu *pageset;
- /*
- * This is a per-zone reserve of pages that are not available
- * to userspace allocations.
- */
- unsigned long totalreserve_pages;
-
#ifndef CONFIG_SPARSEMEM
/*
* Flags for a pageblock_nr_pages block. See pageblock-flags.h.
@@ -367,14 +374,6 @@ struct zone {
unsigned long *pageblock_flags;
#endif /* CONFIG_SPARSEMEM */
-#ifdef CONFIG_NUMA
- /*
- * zone reclaim becomes active if more unmapped pages exist.
- */
- unsigned long min_unmapped_pages;
- unsigned long min_slab_pages;
-#endif /* CONFIG_NUMA */
-
/* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
unsigned long zone_start_pfn;
@@ -467,24 +466,21 @@ struct zone {
unsigned long wait_table_hash_nr_entries;
unsigned long wait_table_bits;
+ /* Write-intensive fields used from the page allocator */
ZONE_PADDING(_pad1_)
+
/* free areas of different sizes */
struct free_area free_area[MAX_ORDER];
/* zone flags, see below */
unsigned long flags;
- /* Write-intensive fields used from the page allocator */
+ /* Primarily protects free_area */
spinlock_t lock;
+ /* Write-intensive fields used by compaction and vmstats. */
ZONE_PADDING(_pad2_)
- /* Write-intensive fields used by page reclaim */
-
- /* Fields commonly accessed by the page reclaim scanner */
- spinlock_t lru_lock;
- struct lruvec lruvec;
-
/*
* When free pages are below this point, additional steps are taken
* when reading the number of free pages to avoid per-cpu counter
@@ -522,20 +518,18 @@ struct zone {
atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
} ____cacheline_internodealigned_in_smp;
-enum zone_flags {
- ZONE_RECLAIM_LOCKED, /* prevents concurrent reclaim */
- ZONE_OOM_LOCKED, /* zone is in OOM killer zonelist */
- ZONE_CONGESTED, /* zone has many dirty pages backed by
+enum pgdat_flags {
+ PGDAT_CONGESTED, /* pgdat has many dirty pages backed by
* a congested BDI
*/
- ZONE_DIRTY, /* reclaim scanning has recently found
+ PGDAT_DIRTY, /* reclaim scanning has recently found
* many dirty file pages at the tail
* of the LRU.
*/
- ZONE_WRITEBACK, /* reclaim scanning has recently found
+ PGDAT_WRITEBACK, /* reclaim scanning has recently found
* many pages under writeback
*/
- ZONE_FAIR_DEPLETED, /* fair zone policy batch depleted */
+ PGDAT_RECLAIM_LOCKED, /* prevents concurrent reclaim */
};
static inline unsigned long zone_end_pfn(const struct zone *zone)
@@ -659,8 +653,9 @@ typedef struct pglist_data {
wait_queue_head_t pfmemalloc_wait;
struct task_struct *kswapd; /* Protected by
mem_hotplug_begin/end() */
- int kswapd_max_order;
- enum zone_type classzone_idx;
+ int kswapd_order;
+ enum zone_type kswapd_classzone_idx;
+
#ifdef CONFIG_COMPACTION
int kcompactd_max_order;
enum zone_type kcompactd_classzone_idx;
@@ -677,6 +672,23 @@ typedef struct pglist_data {
/* Number of pages migrated during the rate limiting time interval */
unsigned long numabalancing_migrate_nr_pages;
#endif
+ /*
+ * This is a per-node reserve of pages that are not available
+ * to userspace allocations.
+ */
+ unsigned long totalreserve_pages;
+
+#ifdef CONFIG_NUMA
+ /*
+ * zone reclaim becomes active if more unmapped pages exist.
+ */
+ unsigned long min_unmapped_pages;
+ unsigned long min_slab_pages;
+#endif /* CONFIG_NUMA */
+
+ /* Write-intensive fields used by page reclaim */
+ ZONE_PADDING(_pad1_)
+ spinlock_t lru_lock;
#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
/*
@@ -691,6 +703,23 @@ typedef struct pglist_data {
struct list_head split_queue;
unsigned long split_queue_len;
#endif
+
+ /* Fields commonly accessed by the page reclaim scanner */
+ struct lruvec lruvec;
+
+ /*
+ * The target ratio of ACTIVE_ANON to INACTIVE_ANON pages on
+ * this node's LRU. Maintained by the pageout code.
+ */
+ unsigned int inactive_ratio;
+
+ unsigned long flags;
+
+ ZONE_PADDING(_pad2_)
+
+ /* Per-node vmstats */
+ struct per_cpu_nodestat __percpu *per_cpu_nodestats;
+ atomic_long_t vm_stat[NR_VM_NODE_STAT_ITEMS];
} pg_data_t;
#define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages)
@@ -704,6 +733,15 @@ typedef struct pglist_data {
#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
#define node_end_pfn(nid) pgdat_end_pfn(NODE_DATA(nid))
+static inline spinlock_t *zone_lru_lock(struct zone *zone)
+{
+ return &zone->zone_pgdat->lru_lock;
+}
+
+static inline struct lruvec *node_lruvec(struct pglist_data *pgdat)
+{
+ return &pgdat->lruvec;
+}
static inline unsigned long pgdat_end_pfn(pg_data_t *pgdat)
{
@@ -756,12 +794,12 @@ extern int init_currently_empty_zone(struct zone *zone, unsigned long start_pfn,
extern void lruvec_init(struct lruvec *lruvec);
-static inline struct zone *lruvec_zone(struct lruvec *lruvec)
+static inline struct pglist_data *lruvec_pgdat(struct lruvec *lruvec)
{
#ifdef CONFIG_MEMCG
- return lruvec->zone;
+ return lruvec->pgdat;
#else
- return container_of(lruvec, struct zone, lruvec);
+ return container_of(lruvec, struct pglist_data, lruvec);
#endif
}
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 6e4c645e1c0d..ed84c07f6a51 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -657,4 +657,20 @@ struct ulpi_device_id {
kernel_ulong_t driver_data;
};
+/**
+ * struct fsl_mc_device_id - MC object device identifier
+ * @vendor: vendor ID
+ * @obj_type: MC object type
+ * @ver_major: MC object version major number
+ * @ver_minor: MC object version minor number
+ *
+ * Type of entries in the "device Id" table for MC object devices supported by
+ * a MC object device driver. The last entry of the table has vendor set to 0x0
+ */
+struct fsl_mc_device_id {
+ __u16 vendor;
+ const char obj_type[16];
+};
+
+
#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/mpi.h b/include/linux/mpi.h
index 3a5abe95affd..1cc5ffb769af 100644
--- a/include/linux/mpi.h
+++ b/include/linux/mpi.h
@@ -80,8 +80,7 @@ void *mpi_get_buffer(MPI a, unsigned *nbytes, int *sign);
int mpi_read_buffer(MPI a, uint8_t *buf, unsigned buf_len, unsigned *nbytes,
int *sign);
void *mpi_get_secure_buffer(MPI a, unsigned *nbytes, int *sign);
-int mpi_set_buffer(MPI a, const void *buffer, unsigned nbytes, int sign);
-int mpi_write_to_sgl(MPI a, struct scatterlist *sg, unsigned *nbytes,
+int mpi_write_to_sgl(MPI a, struct scatterlist *sg, unsigned nbytes,
int *sign);
#define log_mpidump g10_log_mpidump
diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index bf9b322cb0b0..d351fd3e1049 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -104,6 +104,7 @@ struct mfc_cache {
unsigned long bytes;
unsigned long pkt;
unsigned long wrong_if;
+ unsigned long lastuse;
unsigned char ttls[MAXVIFS]; /* TTL thresholds */
} res;
} mfc_un;
diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h
index 66982e764051..3987b64040c5 100644
--- a/include/linux/mroute6.h
+++ b/include/linux/mroute6.h
@@ -92,6 +92,7 @@ struct mfc6_cache {
unsigned long bytes;
unsigned long pkt;
unsigned long wrong_if;
+ unsigned long lastuse;
unsigned char ttls[MAXMIFS]; /* TTL thresholds */
} res;
} mfc_un;
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 8b425c66305a..4f0bfe5912b2 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -47,6 +47,7 @@ struct fsl_mc_msi_desc {
* @nvec_used: The number of vectors used
* @dev: Pointer to the device which uses this descriptor
* @msg: The last set MSI message cached for reuse
+ * @affinity: Optional pointer to a cpu affinity mask for this descriptor
*
* @masked: [PCI MSI/X] Mask bits
* @is_msix: [PCI MSI/X] True if MSI-X
@@ -67,6 +68,7 @@ struct msi_desc {
unsigned int nvec_used;
struct device *dev;
struct msi_msg msg;
+ const struct cpumask *affinity;
union {
/* PCI MSI/X specific data */
@@ -264,12 +266,10 @@ enum {
* callbacks.
*/
MSI_FLAG_USE_DEF_CHIP_OPS = (1 << 1),
- /* Build identity map between hwirq and irq */
- MSI_FLAG_IDENTITY_MAP = (1 << 2),
/* Support multiple PCI MSI interrupts */
- MSI_FLAG_MULTI_PCI_MSI = (1 << 3),
+ MSI_FLAG_MULTI_PCI_MSI = (1 << 2),
/* Support PCI MSIX interrupts */
- MSI_FLAG_PCI_MSIX = (1 << 4),
+ MSI_FLAG_PCI_MSIX = (1 << 3),
};
int msi_domain_set_affinity(struct irq_data *data, const struct cpumask *mask,
diff --git a/include/linux/nd.h b/include/linux/nd.h
index aee2761d294c..f1ea426d6a5e 100644
--- a/include/linux/nd.h
+++ b/include/linux/nd.h
@@ -26,6 +26,7 @@ struct nd_device_driver {
unsigned long type;
int (*probe)(struct device *dev);
int (*remove)(struct device *dev);
+ void (*shutdown)(struct device *dev);
void (*notify)(struct device *dev, enum nvdimm_event event);
};
@@ -67,7 +68,7 @@ struct nd_namespace_io {
struct nd_namespace_common common;
struct resource res;
resource_size_t size;
- void __pmem *addr;
+ void *addr;
struct badblocks bb;
};
diff --git a/include/linux/net.h b/include/linux/net.h
index 25aa03b51c4e..b9f0ff4d489c 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -185,6 +185,7 @@ struct proto_ops {
ssize_t (*splice_read)(struct socket *sock, loff_t *ppos,
struct pipe_inode_info *pipe, size_t len, unsigned int flags);
int (*set_peek_off)(struct sock *sk, int val);
+ int (*peek_len)(struct socket *sock);
};
#define DECLARE_SOCKADDR(type, dst, src) \
diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
index aa7b2400f98c..9c6c8ef2e9e7 100644
--- a/include/linux/netdev_features.h
+++ b/include/linux/netdev_features.h
@@ -53,8 +53,9 @@ enum {
* headers in software.
*/
NETIF_F_GSO_TUNNEL_REMCSUM_BIT, /* ... TUNNEL with TSO & REMCSUM */
+ NETIF_F_GSO_SCTP_BIT, /* ... SCTP fragmentation */
/**/NETIF_F_GSO_LAST = /* last bit, see GSO_MASK */
- NETIF_F_GSO_TUNNEL_REMCSUM_BIT,
+ NETIF_F_GSO_SCTP_BIT,
NETIF_F_FCOE_CRC_BIT, /* FCoE CRC32 */
NETIF_F_SCTP_CRC_BIT, /* SCTP checksum offload */
@@ -128,6 +129,7 @@ enum {
#define NETIF_F_TSO_MANGLEID __NETIF_F(TSO_MANGLEID)
#define NETIF_F_GSO_PARTIAL __NETIF_F(GSO_PARTIAL)
#define NETIF_F_GSO_TUNNEL_REMCSUM __NETIF_F(GSO_TUNNEL_REMCSUM)
+#define NETIF_F_GSO_SCTP __NETIF_F(GSO_SCTP)
#define NETIF_F_HW_VLAN_STAG_FILTER __NETIF_F(HW_VLAN_STAG_FILTER)
#define NETIF_F_HW_VLAN_STAG_RX __NETIF_F(HW_VLAN_STAG_RX)
#define NETIF_F_HW_VLAN_STAG_TX __NETIF_F(HW_VLAN_STAG_TX)
@@ -166,7 +168,8 @@ enum {
NETIF_F_FSO)
/* List of features with software fallbacks. */
-#define NETIF_F_GSO_SOFTWARE (NETIF_F_ALL_TSO | NETIF_F_UFO)
+#define NETIF_F_GSO_SOFTWARE (NETIF_F_ALL_TSO | NETIF_F_UFO | \
+ NETIF_F_GSO_SCTP)
/*
* If one device supports one of these features, then enable them
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index da4b33bea982..076df5360ba5 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -61,6 +61,9 @@ struct wireless_dev;
/* 802.15.4 specific */
struct wpan_dev;
struct mpls_dev;
+/* UDP Tunnel offloads */
+struct udp_tunnel_info;
+struct bpf_prog;
void netdev_set_default_ethtool_ops(struct net_device *dev,
const struct ethtool_ops *ops);
@@ -90,7 +93,6 @@ void netdev_set_default_ethtool_ops(struct net_device *dev,
#define NET_XMIT_SUCCESS 0x00
#define NET_XMIT_DROP 0x01 /* skb dropped */
#define NET_XMIT_CN 0x02 /* congestion notification */
-#define NET_XMIT_POLICED 0x03 /* skb is shot by police */
#define NET_XMIT_MASK 0x0f /* qdisc flags in net/sch_generic.h */
/* NET_XMIT_CN is special. It does not guarantee that this packet is lost. It
@@ -785,6 +787,7 @@ enum {
TC_SETUP_MQPRIO,
TC_SETUP_CLSU32,
TC_SETUP_CLSFLOWER,
+ TC_SETUP_MATCHALL,
};
struct tc_cls_u32_offload;
@@ -795,9 +798,37 @@ struct tc_to_netdev {
u8 tc;
struct tc_cls_u32_offload *cls_u32;
struct tc_cls_flower_offload *cls_flower;
+ struct tc_cls_matchall_offload *cls_mall;
};
};
+/* These structures hold the attributes of xdp state that are being passed
+ * to the netdevice through the xdp op.
+ */
+enum xdp_netdev_command {
+ /* Set or clear a bpf program used in the earliest stages of packet
+ * rx. The prog will have been loaded as BPF_PROG_TYPE_XDP. The callee
+ * is responsible for calling bpf_prog_put on any old progs that are
+ * stored. In case of error, the callee need not release the new prog
+ * reference, but on success it takes ownership and must bpf_prog_put
+ * when it is no longer used.
+ */
+ XDP_SETUP_PROG,
+ /* Check if a bpf program is set on the device. The callee should
+ * return true if a program is currently attached and running.
+ */
+ XDP_QUERY_PROG,
+};
+
+struct netdev_xdp {
+ enum xdp_netdev_command command;
+ union {
+ /* XDP_SETUP_PROG */
+ struct bpf_prog *prog;
+ /* XDP_QUERY_PROG */
+ bool prog_attached;
+ };
+};
/*
* This structure defines the management hooks for network devices.
@@ -1025,31 +1056,18 @@ struct tc_to_netdev {
* not implement this, it is assumed that the hw is not able to have
* multiple net devices on single physical port.
*
- * void (*ndo_add_vxlan_port)(struct net_device *dev,
- * sa_family_t sa_family, __be16 port);
- * Called by vxlan to notify a driver about the UDP port and socket
- * address family that vxlan is listening to. It is called only when
- * a new port starts listening. The operation is protected by the
- * vxlan_net->sock_lock.
- *
- * void (*ndo_add_geneve_port)(struct net_device *dev,
- * sa_family_t sa_family, __be16 port);
- * Called by geneve to notify a driver about the UDP port and socket
- * address family that geneve is listnening to. It is called only when
- * a new port starts listening. The operation is protected by the
- * geneve_net->sock_lock.
- *
- * void (*ndo_del_geneve_port)(struct net_device *dev,
- * sa_family_t sa_family, __be16 port);
- * Called by geneve to notify the driver about a UDP port and socket
- * address family that geneve is not listening to anymore. The operation
- * is protected by the geneve_net->sock_lock.
- *
- * void (*ndo_del_vxlan_port)(struct net_device *dev,
- * sa_family_t sa_family, __be16 port);
- * Called by vxlan to notify the driver about a UDP port and socket
- * address family that vxlan is not listening to anymore. The operation
- * is protected by the vxlan_net->sock_lock.
+ * void (*ndo_udp_tunnel_add)(struct net_device *dev,
+ * struct udp_tunnel_info *ti);
+ * Called by UDP tunnel to notify a driver about the UDP port and socket
+ * address family that a UDP tunnel is listnening to. It is called only
+ * when a new port starts listening. The operation is protected by the
+ * RTNL.
+ *
+ * void (*ndo_udp_tunnel_del)(struct net_device *dev,
+ * struct udp_tunnel_info *ti);
+ * Called by UDP tunnel to notify the driver about a UDP port and socket
+ * address family that the UDP tunnel is not listening to anymore. The
+ * operation is protected by the RTNL.
*
* void* (*ndo_dfwd_add_station)(struct net_device *pdev,
* struct net_device *dev)
@@ -1099,6 +1117,9 @@ struct tc_to_netdev {
* appropriate rx headroom value allows avoiding skb head copy on
* forward. Setting a negative value resets the rx headroom to the
* default value.
+ * int (*ndo_xdp)(struct net_device *dev, struct netdev_xdp *xdp);
+ * This function is used to set or query state related to XDP on the
+ * netdevice. See definition of enum xdp_netdev_command for details.
*
*/
struct net_device_ops {
@@ -1221,8 +1242,10 @@ struct net_device_ops {
netdev_features_t features);
int (*ndo_set_features)(struct net_device *dev,
netdev_features_t features);
- int (*ndo_neigh_construct)(struct neighbour *n);
- void (*ndo_neigh_destroy)(struct neighbour *n);
+ int (*ndo_neigh_construct)(struct net_device *dev,
+ struct neighbour *n);
+ void (*ndo_neigh_destroy)(struct net_device *dev,
+ struct neighbour *n);
int (*ndo_fdb_add)(struct ndmsg *ndm,
struct nlattr *tb[],
@@ -1258,18 +1281,10 @@ struct net_device_ops {
struct netdev_phys_item_id *ppid);
int (*ndo_get_phys_port_name)(struct net_device *dev,
char *name, size_t len);
- void (*ndo_add_vxlan_port)(struct net_device *dev,
- sa_family_t sa_family,
- __be16 port);
- void (*ndo_del_vxlan_port)(struct net_device *dev,
- sa_family_t sa_family,
- __be16 port);
- void (*ndo_add_geneve_port)(struct net_device *dev,
- sa_family_t sa_family,
- __be16 port);
- void (*ndo_del_geneve_port)(struct net_device *dev,
- sa_family_t sa_family,
- __be16 port);
+ void (*ndo_udp_tunnel_add)(struct net_device *dev,
+ struct udp_tunnel_info *ti);
+ void (*ndo_udp_tunnel_del)(struct net_device *dev,
+ struct udp_tunnel_info *ti);
void* (*ndo_dfwd_add_station)(struct net_device *pdev,
struct net_device *dev);
void (*ndo_dfwd_del_station)(struct net_device *pdev,
@@ -1289,6 +1304,8 @@ struct net_device_ops {
struct sk_buff *skb);
void (*ndo_set_rx_headroom)(struct net_device *dev,
int needed_headroom);
+ int (*ndo_xdp)(struct net_device *dev,
+ struct netdev_xdp *xdp);
};
/**
@@ -1457,6 +1474,8 @@ enum netdev_priv_flags {
* @netdev_ops: Includes several pointers to callbacks,
* if one wants to override the ndo_*() functions
* @ethtool_ops: Management operations
+ * @ndisc_ops: Includes callbacks for different IPv6 neighbour
+ * discovery handling. Necessary for e.g. 6LoWPAN.
* @header_ops: Includes callbacks for creating,parsing,caching,etc
* of Layer 2 headers.
*
@@ -1484,8 +1503,7 @@ enum netdev_priv_flags {
* @perm_addr: Permanent hw address
* @addr_assign_type: Hw address assignment type
* @addr_len: Hardware address length
- * @neigh_priv_len; Used in neigh_alloc(),
- * initialized only in atm/clip.c
+ * @neigh_priv_len: Used in neigh_alloc()
* @dev_id: Used to differentiate devices that share
* the same link layer address
* @dev_port: Used to differentiate devices that share
@@ -1594,7 +1612,8 @@ enum netdev_priv_flags {
* @phydev: Physical device may attach itself
* for hardware timestamping
*
- * @qdisc_tx_busylock: XXX: need comments on this one
+ * @qdisc_tx_busylock: lockdep class annotating Qdisc->busylock spinlock
+ * @qdisc_running_key: lockdep class annotating Qdisc->running seqcount
*
* @proto_down: protocol port state information can be sent to the
* switch driver and used to set the phys state of the
@@ -1673,6 +1692,9 @@ struct net_device {
#ifdef CONFIG_NET_L3_MASTER_DEV
const struct l3mdev_ops *l3mdev_ops;
#endif
+#if IS_ENABLED(CONFIG_IPV6)
+ const struct ndisc_ops *ndisc_ops;
+#endif
const struct header_ops *header_ops;
@@ -1862,6 +1884,7 @@ struct net_device {
#endif
struct phy_device *phydev;
struct lock_class_key *qdisc_tx_busylock;
+ struct lock_class_key *qdisc_running_key;
bool proto_down;
};
#define to_net_dev(d) container_of(d, struct net_device, dev)
@@ -1944,6 +1967,23 @@ static inline void netdev_for_each_tx_queue(struct net_device *dev,
f(dev, &dev->_tx[i], arg);
}
+#define netdev_lockdep_set_classes(dev) \
+{ \
+ static struct lock_class_key qdisc_tx_busylock_key; \
+ static struct lock_class_key qdisc_running_key; \
+ static struct lock_class_key qdisc_xmit_lock_key; \
+ static struct lock_class_key dev_addr_list_lock_key; \
+ unsigned int i; \
+ \
+ (dev)->qdisc_tx_busylock = &qdisc_tx_busylock_key; \
+ (dev)->qdisc_running_key = &qdisc_running_key; \
+ lockdep_set_class(&(dev)->addr_list_lock, \
+ &dev_addr_list_lock_key); \
+ for (i = 0; i < (dev)->num_tx_queues; i++) \
+ lockdep_set_class(&(dev)->_tx[i]._xmit_lock, \
+ &qdisc_xmit_lock_key); \
+}
+
struct netdev_queue *netdev_pick_tx(struct net_device *dev,
struct sk_buff *skb,
void *accel_priv);
@@ -2233,8 +2273,8 @@ struct netdev_lag_lower_state_info {
#define NETDEV_BONDING_INFO 0x0019
#define NETDEV_PRECHANGEUPPER 0x001A
#define NETDEV_CHANGELOWERSTATE 0x001B
-#define NETDEV_OFFLOAD_PUSH_VXLAN 0x001C
-#define NETDEV_OFFLOAD_PUSH_GENEVE 0x001D
+#define NETDEV_UDP_TUNNEL_PUSH_INFO 0x001C
+#define NETDEV_CHANGE_TX_QUEUE_LEN 0x001E
int register_netdevice_notifier(struct notifier_block *nb);
int unregister_netdevice_notifier(struct notifier_block *nb);
@@ -2370,6 +2410,8 @@ void synchronize_net(void);
int init_dummy_netdev(struct net_device *dev);
DECLARE_PER_CPU(int, xmit_recursion);
+#define XMIT_RECURSION_LIMIT 10
+
static inline int dev_recursion_level(void)
{
return this_cpu_read(xmit_recursion);
@@ -3250,6 +3292,7 @@ int dev_get_phys_port_id(struct net_device *dev,
int dev_get_phys_port_name(struct net_device *dev,
char *name, size_t len);
int dev_change_proto_down(struct net_device *dev, bool proto_down);
+int dev_change_xdp_fd(struct net_device *dev, int fd);
struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev);
struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
struct netdev_queue *txq, int *ret);
@@ -3799,12 +3842,30 @@ void *netdev_lower_get_next_private_rcu(struct net_device *dev,
void *netdev_lower_get_next(struct net_device *dev,
struct list_head **iter);
+
#define netdev_for_each_lower_dev(dev, ldev, iter) \
for (iter = (dev)->adj_list.lower.next, \
ldev = netdev_lower_get_next(dev, &(iter)); \
ldev; \
ldev = netdev_lower_get_next(dev, &(iter)))
+struct net_device *netdev_all_lower_get_next(struct net_device *dev,
+ struct list_head **iter);
+struct net_device *netdev_all_lower_get_next_rcu(struct net_device *dev,
+ struct list_head **iter);
+
+#define netdev_for_each_all_lower_dev(dev, ldev, iter) \
+ for (iter = (dev)->all_adj_list.lower.next, \
+ ldev = netdev_all_lower_get_next(dev, &(iter)); \
+ ldev; \
+ ldev = netdev_all_lower_get_next(dev, &(iter)))
+
+#define netdev_for_each_all_lower_dev_rcu(dev, ldev, iter) \
+ for (iter = (dev)->all_adj_list.lower.next, \
+ ldev = netdev_all_lower_get_next_rcu(dev, &(iter)); \
+ ldev; \
+ ldev = netdev_all_lower_get_next_rcu(dev, &(iter)))
+
void *netdev_adjacent_get_private(struct list_head *adj_list);
void *netdev_lower_get_first_private_rcu(struct net_device *dev);
struct net_device *netdev_master_upper_dev_get(struct net_device *dev);
@@ -3820,6 +3881,10 @@ void *netdev_lower_dev_get_private(struct net_device *dev,
struct net_device *lower_dev);
void netdev_lower_state_changed(struct net_device *lower_dev,
void *lower_state_info);
+int netdev_default_l2upper_neigh_construct(struct net_device *dev,
+ struct neighbour *n);
+void netdev_default_l2upper_neigh_destroy(struct net_device *dev,
+ struct neighbour *n);
/* RSS keys are 40 or 52 bytes long */
#define NETDEV_RSS_KEY_LEN 52
@@ -4012,6 +4077,7 @@ static inline bool net_gso_ok(netdev_features_t features, int gso_type)
BUILD_BUG_ON(SKB_GSO_UDP_TUNNEL_CSUM != (NETIF_F_GSO_UDP_TUNNEL_CSUM >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_PARTIAL != (NETIF_F_GSO_PARTIAL >> NETIF_F_GSO_SHIFT));
BUILD_BUG_ON(SKB_GSO_TUNNEL_REMCSUM != (NETIF_F_GSO_TUNNEL_REMCSUM >> NETIF_F_GSO_SHIFT));
+ BUILD_BUG_ON(SKB_GSO_SCTP != (NETIF_F_GSO_SCTP >> NETIF_F_GSO_SHIFT));
return (features & feature) == feature;
}
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index dc4f58a3cdcc..2ad1a2b289b5 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -6,6 +6,10 @@
#include <linux/static_key.h>
#include <uapi/linux/netfilter/x_tables.h>
+/* Test a struct->invflags and a boolean for inequality */
+#define NF_INVF(ptr, flag, boolean) \
+ ((boolean) ^ !!((ptr)->invflags & (flag)))
+
/**
* struct xt_action_param - parameters for matches/targets
*
@@ -246,6 +250,10 @@ int xt_check_entry_offsets(const void *base, const char *elems,
unsigned int target_offset,
unsigned int next_offset);
+unsigned int *xt_alloc_entry_offsets(unsigned int size);
+bool xt_find_jump_offset(const unsigned int *offsets,
+ unsigned int target, unsigned int size);
+
int xt_check_match(struct xt_mtchk_param *, unsigned int size, u_int8_t proto,
bool inv_proto);
int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t proto,
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
index 2ea517c7c6b9..984b2112c77b 100644
--- a/include/linux/netfilter_bridge/ebtables.h
+++ b/include/linux/netfilter_bridge/ebtables.h
@@ -115,8 +115,6 @@ extern unsigned int ebt_do_table(struct sk_buff *skb,
const struct nf_hook_state *state,
struct ebt_table *table);
-/* Used in the kernel match() functions */
-#define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg))
/* True if the hook mask denotes that the rule is in a base chain,
* used in the check() functions */
#define BASE_CHAIN (par->hook_mask & (1 << NF_BR_NUMHOOKS))
diff --git a/include/linux/nvme-rdma.h b/include/linux/nvme-rdma.h
new file mode 100644
index 000000000000..bf240a3cbf99
--- /dev/null
+++ b/include/linux/nvme-rdma.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2015 Mellanox Technologies. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ */
+
+#ifndef _LINUX_NVME_RDMA_H
+#define _LINUX_NVME_RDMA_H
+
+enum nvme_rdma_cm_fmt {
+ NVME_RDMA_CM_FMT_1_0 = 0x0,
+};
+
+enum nvme_rdma_cm_status {
+ NVME_RDMA_CM_INVALID_LEN = 0x01,
+ NVME_RDMA_CM_INVALID_RECFMT = 0x02,
+ NVME_RDMA_CM_INVALID_QID = 0x03,
+ NVME_RDMA_CM_INVALID_HSQSIZE = 0x04,
+ NVME_RDMA_CM_INVALID_HRQSIZE = 0x05,
+ NVME_RDMA_CM_NO_RSC = 0x06,
+ NVME_RDMA_CM_INVALID_IRD = 0x07,
+ NVME_RDMA_CM_INVALID_ORD = 0x08,
+};
+
+/**
+ * struct nvme_rdma_cm_req - rdma connect request
+ *
+ * @recfmt: format of the RDMA Private Data
+ * @qid: queue Identifier for the Admin or I/O Queue
+ * @hrqsize: host receive queue size to be created
+ * @hsqsize: host send queue size to be created
+ */
+struct nvme_rdma_cm_req {
+ __le16 recfmt;
+ __le16 qid;
+ __le16 hrqsize;
+ __le16 hsqsize;
+ u8 rsvd[24];
+};
+
+/**
+ * struct nvme_rdma_cm_rep - rdma connect reply
+ *
+ * @recfmt: format of the RDMA Private Data
+ * @crqsize: controller receive queue size
+ */
+struct nvme_rdma_cm_rep {
+ __le16 recfmt;
+ __le16 crqsize;
+ u8 rsvd[28];
+};
+
+/**
+ * struct nvme_rdma_cm_rej - rdma connect reject
+ *
+ * @recfmt: format of the RDMA Private Data
+ * @fsts: error status for the associated connect request
+ */
+struct nvme_rdma_cm_rej {
+ __le16 recfmt;
+ __le16 sts;
+};
+
+#endif /* _LINUX_NVME_RDMA_H */
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index 7d51b2904cb7..d8b37bab2887 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -16,6 +16,78 @@
#define _LINUX_NVME_H
#include <linux/types.h>
+#include <linux/uuid.h>
+
+/* NQN names in commands fields specified one size */
+#define NVMF_NQN_FIELD_LEN 256
+
+/* However the max length of a qualified name is another size */
+#define NVMF_NQN_SIZE 223
+
+#define NVMF_TRSVCID_SIZE 32
+#define NVMF_TRADDR_SIZE 256
+#define NVMF_TSAS_SIZE 256
+
+#define NVME_DISC_SUBSYS_NAME "nqn.2014-08.org.nvmexpress.discovery"
+
+#define NVME_RDMA_IP_PORT 4420
+
+enum nvme_subsys_type {
+ NVME_NQN_DISC = 1, /* Discovery type target subsystem */
+ NVME_NQN_NVME = 2, /* NVME type target subsystem */
+};
+
+/* Address Family codes for Discovery Log Page entry ADRFAM field */
+enum {
+ NVMF_ADDR_FAMILY_PCI = 0, /* PCIe */
+ NVMF_ADDR_FAMILY_IP4 = 1, /* IP4 */
+ NVMF_ADDR_FAMILY_IP6 = 2, /* IP6 */
+ NVMF_ADDR_FAMILY_IB = 3, /* InfiniBand */
+ NVMF_ADDR_FAMILY_FC = 4, /* Fibre Channel */
+};
+
+/* Transport Type codes for Discovery Log Page entry TRTYPE field */
+enum {
+ NVMF_TRTYPE_RDMA = 1, /* RDMA */
+ NVMF_TRTYPE_FC = 2, /* Fibre Channel */
+ NVMF_TRTYPE_LOOP = 254, /* Reserved for host usage */
+ NVMF_TRTYPE_MAX,
+};
+
+/* Transport Requirements codes for Discovery Log Page entry TREQ field */
+enum {
+ NVMF_TREQ_NOT_SPECIFIED = 0, /* Not specified */
+ NVMF_TREQ_REQUIRED = 1, /* Required */
+ NVMF_TREQ_NOT_REQUIRED = 2, /* Not Required */
+};
+
+/* RDMA QP Service Type codes for Discovery Log Page entry TSAS
+ * RDMA_QPTYPE field
+ */
+enum {
+ NVMF_RDMA_QPTYPE_CONNECTED = 0, /* Reliable Connected */
+ NVMF_RDMA_QPTYPE_DATAGRAM = 1, /* Reliable Datagram */
+};
+
+/* RDMA QP Service Type codes for Discovery Log Page entry TSAS
+ * RDMA_QPTYPE field
+ */
+enum {
+ NVMF_RDMA_PRTYPE_NOT_SPECIFIED = 0, /* No Provider Specified */
+ NVMF_RDMA_PRTYPE_IB = 1, /* InfiniBand */
+ NVMF_RDMA_PRTYPE_ROCE = 2, /* InfiniBand RoCE */
+ NVMF_RDMA_PRTYPE_ROCEV2 = 3, /* InfiniBand RoCEV2 */
+ NVMF_RDMA_PRTYPE_IWARP = 4, /* IWARP */
+};
+
+/* RDMA Connection Management Service Type codes for Discovery Log Page
+ * entry TSAS RDMA_CMS field
+ */
+enum {
+ NVMF_RDMA_CMS_RDMA_CM = 0, /* Sockets based enpoint addressing */
+};
+
+#define NVMF_AQ_DEPTH 32
enum {
NVME_REG_CAP = 0x0000, /* Controller Capabilities */
@@ -50,6 +122,13 @@ enum {
#define NVME_CMB_CQS(cmbsz) ((cmbsz) & 0x2)
#define NVME_CMB_SQS(cmbsz) ((cmbsz) & 0x1)
+/*
+ * Submission and Completion Queue Entry Sizes for the NVM command set.
+ * (In bytes and specified as a power of two (2^n)).
+ */
+#define NVME_NVM_IOSQES 6
+#define NVME_NVM_IOCQES 4
+
enum {
NVME_CC_ENABLE = 1 << 0,
NVME_CC_CSS_NVM = 0 << 4,
@@ -61,8 +140,8 @@ enum {
NVME_CC_SHN_NORMAL = 1 << 14,
NVME_CC_SHN_ABRUPT = 2 << 14,
NVME_CC_SHN_MASK = 3 << 14,
- NVME_CC_IOSQES = 6 << 16,
- NVME_CC_IOCQES = 4 << 20,
+ NVME_CC_IOSQES = NVME_NVM_IOSQES << 16,
+ NVME_CC_IOCQES = NVME_NVM_IOCQES << 20,
NVME_CSTS_RDY = 1 << 0,
NVME_CSTS_CFS = 1 << 1,
NVME_CSTS_NSSRO = 1 << 4,
@@ -107,7 +186,11 @@ struct nvme_id_ctrl {
__u8 mdts;
__le16 cntlid;
__le32 ver;
- __u8 rsvd84[172];
+ __le32 rtd3r;
+ __le32 rtd3e;
+ __le32 oaes;
+ __le32 ctratt;
+ __u8 rsvd100[156];
__le16 oacs;
__u8 acl;
__u8 aerl;
@@ -119,10 +202,12 @@ struct nvme_id_ctrl {
__u8 apsta;
__le16 wctemp;
__le16 cctemp;
- __u8 rsvd270[242];
+ __u8 rsvd270[50];
+ __le16 kas;
+ __u8 rsvd322[190];
__u8 sqes;
__u8 cqes;
- __u8 rsvd514[2];
+ __le16 maxcmd;
__le32 nn;
__le16 oncs;
__le16 fuses;
@@ -135,7 +220,15 @@ struct nvme_id_ctrl {
__le16 acwu;
__u8 rsvd534[2];
__le32 sgls;
- __u8 rsvd540[1508];
+ __u8 rsvd540[228];
+ char subnqn[256];
+ __u8 rsvd1024[768];
+ __le32 ioccsz;
+ __le32 iorcsz;
+ __le16 icdoff;
+ __u8 ctrattr;
+ __u8 msdbd;
+ __u8 rsvd1804[244];
struct nvme_id_power_state psd[32];
__u8 vs[1024];
};
@@ -274,6 +367,12 @@ struct nvme_reservation_status {
} regctl_ds[];
};
+enum nvme_async_event_type {
+ NVME_AER_TYPE_ERROR = 0,
+ NVME_AER_TYPE_SMART = 1,
+ NVME_AER_TYPE_NOTICE = 2,
+};
+
/* I/O commands */
enum nvme_opcode {
@@ -290,6 +389,84 @@ enum nvme_opcode {
nvme_cmd_resv_release = 0x15,
};
+/*
+ * Descriptor subtype - lower 4 bits of nvme_(keyed_)sgl_desc identifier
+ *
+ * @NVME_SGL_FMT_ADDRESS: absolute address of the data block
+ * @NVME_SGL_FMT_OFFSET: relative offset of the in-capsule data block
+ * @NVME_SGL_FMT_INVALIDATE: RDMA transport specific remote invalidation
+ * request subtype
+ */
+enum {
+ NVME_SGL_FMT_ADDRESS = 0x00,
+ NVME_SGL_FMT_OFFSET = 0x01,
+ NVME_SGL_FMT_INVALIDATE = 0x0f,
+};
+
+/*
+ * Descriptor type - upper 4 bits of nvme_(keyed_)sgl_desc identifier
+ *
+ * For struct nvme_sgl_desc:
+ * @NVME_SGL_FMT_DATA_DESC: data block descriptor
+ * @NVME_SGL_FMT_SEG_DESC: sgl segment descriptor
+ * @NVME_SGL_FMT_LAST_SEG_DESC: last sgl segment descriptor
+ *
+ * For struct nvme_keyed_sgl_desc:
+ * @NVME_KEY_SGL_FMT_DATA_DESC: keyed data block descriptor
+ */
+enum {
+ NVME_SGL_FMT_DATA_DESC = 0x00,
+ NVME_SGL_FMT_SEG_DESC = 0x02,
+ NVME_SGL_FMT_LAST_SEG_DESC = 0x03,
+ NVME_KEY_SGL_FMT_DATA_DESC = 0x04,
+};
+
+struct nvme_sgl_desc {
+ __le64 addr;
+ __le32 length;
+ __u8 rsvd[3];
+ __u8 type;
+};
+
+struct nvme_keyed_sgl_desc {
+ __le64 addr;
+ __u8 length[3];
+ __u8 key[4];
+ __u8 type;
+};
+
+union nvme_data_ptr {
+ struct {
+ __le64 prp1;
+ __le64 prp2;
+ };
+ struct nvme_sgl_desc sgl;
+ struct nvme_keyed_sgl_desc ksgl;
+};
+
+/*
+ * Lowest two bits of our flags field (FUSE field in the spec):
+ *
+ * @NVME_CMD_FUSE_FIRST: Fused Operation, first command
+ * @NVME_CMD_FUSE_SECOND: Fused Operation, second command
+ *
+ * Highest two bits in our flags field (PSDT field in the spec):
+ *
+ * @NVME_CMD_PSDT_SGL_METABUF: Use SGLS for this transfer,
+ * If used, MPTR contains addr of single physical buffer (byte aligned).
+ * @NVME_CMD_PSDT_SGL_METASEG: Use SGLS for this transfer,
+ * If used, MPTR contains an address of an SGL segment containing
+ * exactly 1 SGL descriptor (qword aligned).
+ */
+enum {
+ NVME_CMD_FUSE_FIRST = (1 << 0),
+ NVME_CMD_FUSE_SECOND = (1 << 1),
+
+ NVME_CMD_SGL_METABUF = (1 << 6),
+ NVME_CMD_SGL_METASEG = (1 << 7),
+ NVME_CMD_SGL_ALL = NVME_CMD_SGL_METABUF | NVME_CMD_SGL_METASEG,
+};
+
struct nvme_common_command {
__u8 opcode;
__u8 flags;
@@ -297,8 +474,7 @@ struct nvme_common_command {
__le32 nsid;
__le32 cdw2[2];
__le64 metadata;
- __le64 prp1;
- __le64 prp2;
+ union nvme_data_ptr dptr;
__le32 cdw10[6];
};
@@ -309,8 +485,7 @@ struct nvme_rw_command {
__le32 nsid;
__u64 rsvd2;
__le64 metadata;
- __le64 prp1;
- __le64 prp2;
+ union nvme_data_ptr dptr;
__le64 slba;
__le16 length;
__le16 control;
@@ -350,8 +525,7 @@ struct nvme_dsm_cmd {
__u16 command_id;
__le32 nsid;
__u64 rsvd2[2];
- __le64 prp1;
- __le64 prp2;
+ union nvme_data_ptr dptr;
__le32 nr;
__le32 attributes;
__u32 rsvd12[4];
@@ -384,6 +558,7 @@ enum nvme_admin_opcode {
nvme_admin_async_event = 0x0c,
nvme_admin_activate_fw = 0x10,
nvme_admin_download_fw = 0x11,
+ nvme_admin_keep_alive = 0x18,
nvme_admin_format_nvm = 0x80,
nvme_admin_security_send = 0x81,
nvme_admin_security_recv = 0x82,
@@ -408,6 +583,7 @@ enum {
NVME_FEAT_WRITE_ATOMIC = 0x0a,
NVME_FEAT_ASYNC_EVENT = 0x0b,
NVME_FEAT_AUTO_PST = 0x0c,
+ NVME_FEAT_KATO = 0x0f,
NVME_FEAT_SW_PROGRESS = 0x80,
NVME_FEAT_HOST_ID = 0x81,
NVME_FEAT_RESV_MASK = 0x82,
@@ -415,6 +591,7 @@ enum {
NVME_LOG_ERROR = 0x01,
NVME_LOG_SMART = 0x02,
NVME_LOG_FW_SLOT = 0x03,
+ NVME_LOG_DISC = 0x70,
NVME_LOG_RESERVATION = 0x80,
NVME_FWACT_REPL = (0 << 3),
NVME_FWACT_REPL_ACTV = (1 << 3),
@@ -427,8 +604,7 @@ struct nvme_identify {
__u16 command_id;
__le32 nsid;
__u64 rsvd2[2];
- __le64 prp1;
- __le64 prp2;
+ union nvme_data_ptr dptr;
__le32 cns;
__u32 rsvd11[5];
};
@@ -439,8 +615,7 @@ struct nvme_features {
__u16 command_id;
__le32 nsid;
__u64 rsvd2[2];
- __le64 prp1;
- __le64 prp2;
+ union nvme_data_ptr dptr;
__le32 fid;
__le32 dword11;
__u32 rsvd12[4];
@@ -499,8 +674,7 @@ struct nvme_download_firmware {
__u8 flags;
__u16 command_id;
__u32 rsvd1[5];
- __le64 prp1;
- __le64 prp2;
+ union nvme_data_ptr dptr;
__le32 numd;
__le32 offset;
__u32 rsvd12[4];
@@ -516,6 +690,143 @@ struct nvme_format_cmd {
__u32 rsvd11[5];
};
+struct nvme_get_log_page_command {
+ __u8 opcode;
+ __u8 flags;
+ __u16 command_id;
+ __le32 nsid;
+ __u64 rsvd2[2];
+ union nvme_data_ptr dptr;
+ __u8 lid;
+ __u8 rsvd10;
+ __le16 numdl;
+ __le16 numdu;
+ __u16 rsvd11;
+ __le32 lpol;
+ __le32 lpou;
+ __u32 rsvd14[2];
+};
+
+/*
+ * Fabrics subcommands.
+ */
+enum nvmf_fabrics_opcode {
+ nvme_fabrics_command = 0x7f,
+};
+
+enum nvmf_capsule_command {
+ nvme_fabrics_type_property_set = 0x00,
+ nvme_fabrics_type_connect = 0x01,
+ nvme_fabrics_type_property_get = 0x04,
+};
+
+struct nvmf_common_command {
+ __u8 opcode;
+ __u8 resv1;
+ __u16 command_id;
+ __u8 fctype;
+ __u8 resv2[35];
+ __u8 ts[24];
+};
+
+/*
+ * The legal cntlid range a NVMe Target will provide.
+ * Note that cntlid of value 0 is considered illegal in the fabrics world.
+ * Devices based on earlier specs did not have the subsystem concept;
+ * therefore, those devices had their cntlid value set to 0 as a result.
+ */
+#define NVME_CNTLID_MIN 1
+#define NVME_CNTLID_MAX 0xffef
+#define NVME_CNTLID_DYNAMIC 0xffff
+
+#define MAX_DISC_LOGS 255
+
+/* Discovery log page entry */
+struct nvmf_disc_rsp_page_entry {
+ __u8 trtype;
+ __u8 adrfam;
+ __u8 nqntype;
+ __u8 treq;
+ __le16 portid;
+ __le16 cntlid;
+ __le16 asqsz;
+ __u8 resv8[22];
+ char trsvcid[NVMF_TRSVCID_SIZE];
+ __u8 resv64[192];
+ char subnqn[NVMF_NQN_FIELD_LEN];
+ char traddr[NVMF_TRADDR_SIZE];
+ union tsas {
+ char common[NVMF_TSAS_SIZE];
+ struct rdma {
+ __u8 qptype;
+ __u8 prtype;
+ __u8 cms;
+ __u8 resv3[5];
+ __u16 pkey;
+ __u8 resv10[246];
+ } rdma;
+ } tsas;
+};
+
+/* Discovery log page header */
+struct nvmf_disc_rsp_page_hdr {
+ __le64 genctr;
+ __le64 numrec;
+ __le16 recfmt;
+ __u8 resv14[1006];
+ struct nvmf_disc_rsp_page_entry entries[0];
+};
+
+struct nvmf_connect_command {
+ __u8 opcode;
+ __u8 resv1;
+ __u16 command_id;
+ __u8 fctype;
+ __u8 resv2[19];
+ union nvme_data_ptr dptr;
+ __le16 recfmt;
+ __le16 qid;
+ __le16 sqsize;
+ __u8 cattr;
+ __u8 resv3;
+ __le32 kato;
+ __u8 resv4[12];
+};
+
+struct nvmf_connect_data {
+ uuid_le hostid;
+ __le16 cntlid;
+ char resv4[238];
+ char subsysnqn[NVMF_NQN_FIELD_LEN];
+ char hostnqn[NVMF_NQN_FIELD_LEN];
+ char resv5[256];
+};
+
+struct nvmf_property_set_command {
+ __u8 opcode;
+ __u8 resv1;
+ __u16 command_id;
+ __u8 fctype;
+ __u8 resv2[35];
+ __u8 attrib;
+ __u8 resv3[3];
+ __le32 offset;
+ __le64 value;
+ __u8 resv4[8];
+};
+
+struct nvmf_property_get_command {
+ __u8 opcode;
+ __u8 resv1;
+ __u16 command_id;
+ __u8 fctype;
+ __u8 resv2[35];
+ __u8 attrib;
+ __u8 resv3[3];
+ __le32 offset;
+ __u8 resv4[16];
+};
+
struct nvme_command {
union {
struct nvme_common_command common;
@@ -529,10 +840,30 @@ struct nvme_command {
struct nvme_format_cmd format;
struct nvme_dsm_cmd dsm;
struct nvme_abort_cmd abort;
+ struct nvme_get_log_page_command get_log_page;
+ struct nvmf_common_command fabrics;
+ struct nvmf_connect_command connect;
+ struct nvmf_property_set_command prop_set;
+ struct nvmf_property_get_command prop_get;
};
};
+static inline bool nvme_is_write(struct nvme_command *cmd)
+{
+ /*
+ * What a mess...
+ *
+ * Why can't we simply have a Fabrics In and Fabrics out command?
+ */
+ if (unlikely(cmd->common.opcode == nvme_fabrics_command))
+ return cmd->fabrics.opcode & 1;
+ return cmd->common.opcode & 1;
+}
+
enum {
+ /*
+ * Generic Command Status:
+ */
NVME_SC_SUCCESS = 0x0,
NVME_SC_INVALID_OPCODE = 0x1,
NVME_SC_INVALID_FIELD = 0x2,
@@ -551,10 +882,18 @@ enum {
NVME_SC_SGL_INVALID_DATA = 0xf,
NVME_SC_SGL_INVALID_METADATA = 0x10,
NVME_SC_SGL_INVALID_TYPE = 0x11,
+
+ NVME_SC_SGL_INVALID_OFFSET = 0x16,
+ NVME_SC_SGL_INVALID_SUBTYPE = 0x17,
+
NVME_SC_LBA_RANGE = 0x80,
NVME_SC_CAP_EXCEEDED = 0x81,
NVME_SC_NS_NOT_READY = 0x82,
NVME_SC_RESERVATION_CONFLICT = 0x83,
+
+ /*
+ * Command Specific Status:
+ */
NVME_SC_CQ_INVALID = 0x100,
NVME_SC_QID_INVALID = 0x101,
NVME_SC_QUEUE_SIZE = 0x102,
@@ -572,9 +911,29 @@ enum {
NVME_SC_FEATURE_NOT_CHANGEABLE = 0x10e,
NVME_SC_FEATURE_NOT_PER_NS = 0x10f,
NVME_SC_FW_NEEDS_RESET_SUBSYS = 0x110,
+
+ /*
+ * I/O Command Set Specific - NVM commands:
+ */
NVME_SC_BAD_ATTRIBUTES = 0x180,
NVME_SC_INVALID_PI = 0x181,
NVME_SC_READ_ONLY = 0x182,
+
+ /*
+ * I/O Command Set Specific - Fabrics commands:
+ */
+ NVME_SC_CONNECT_FORMAT = 0x180,
+ NVME_SC_CONNECT_CTRL_BUSY = 0x181,
+ NVME_SC_CONNECT_INVALID_PARAM = 0x182,
+ NVME_SC_CONNECT_RESTART_DISC = 0x183,
+ NVME_SC_CONNECT_INVALID_HOST = 0x184,
+
+ NVME_SC_DISCOVERY_RESTART = 0x190,
+ NVME_SC_AUTH_REQUIRED = 0x191,
+
+ /*
+ * Media and Data Integrity Errors:
+ */
NVME_SC_WRITE_FAULT = 0x280,
NVME_SC_READ_ERROR = 0x281,
NVME_SC_GUARD_CHECK = 0x282,
@@ -582,12 +941,19 @@ enum {
NVME_SC_REFTAG_CHECK = 0x284,
NVME_SC_COMPARE_FAILED = 0x285,
NVME_SC_ACCESS_DENIED = 0x286,
+
NVME_SC_DNR = 0x4000,
};
struct nvme_completion {
- __le32 result; /* Used by admin commands to return data */
- __u32 rsvd;
+ /*
+ * Used by Admin and Fabrics commands to return data:
+ */
+ union {
+ __le16 result16;
+ __le32 result;
+ __le64 result64;
+ };
__le16 sq_head; /* how much of this queue may be reclaimed */
__le16 sq_id; /* submission queue that generated this entry */
__u16 command_id; /* of the command which completed */
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
index 9bb77d3ed6e0..c2256d746543 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -74,7 +74,7 @@ static inline void nvmem_cell_put(struct nvmem_cell *cell)
{
}
-static inline char *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
+static inline void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len)
{
return ERR_PTR(-ENOSYS);
}
diff --git a/include/linux/of.h b/include/linux/of.h
index 74eb28cadbef..15c43f076b23 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -1009,10 +1009,13 @@ static inline int of_get_available_child_count(const struct device_node *np)
#endif
typedef int (*of_init_fn_2)(struct device_node *, struct device_node *);
+typedef int (*of_init_fn_1_ret)(struct device_node *);
typedef void (*of_init_fn_1)(struct device_node *);
#define OF_DECLARE_1(table, name, compat, fn) \
_OF_DECLARE(table, name, compat, fn, of_init_fn_1)
+#define OF_DECLARE_1_RET(table, name, compat, fn) \
+ _OF_DECLARE(table, name, compat, fn, of_init_fn_1_ret)
#define OF_DECLARE_2(table, name, compat, fn) \
_OF_DECLARE(table, name, compat, fn, of_init_fn_2)
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index 901ec01c9fba..26c3302ae58f 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -53,6 +53,8 @@ extern char __dtb_end[];
extern int of_scan_flat_dt(int (*it)(unsigned long node, const char *uname,
int depth, void *data),
void *data);
+extern int of_get_flat_dt_subnode_by_name(unsigned long node,
+ const char *uname);
extern const void *of_get_flat_dt_prop(unsigned long node, const char *name,
int *size);
extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h
index 8f2237eb3485..2ab233661ae5 100644
--- a/include/linux/of_mdio.h
+++ b/include/linux/of_mdio.h
@@ -19,12 +19,17 @@ extern struct phy_device *of_phy_connect(struct net_device *dev,
struct device_node *phy_np,
void (*hndlr)(struct net_device *),
u32 flags, phy_interface_t iface);
+extern struct phy_device *
+of_phy_get_and_connect(struct net_device *dev, struct device_node *np,
+ void (*hndlr)(struct net_device *));
struct phy_device *of_phy_attach(struct net_device *dev,
struct device_node *phy_np, u32 flags,
phy_interface_t iface);
extern struct mii_bus *of_mdio_find_bus(struct device_node *mdio_np);
extern int of_mdio_parse_addr(struct device *dev, const struct device_node *np);
+extern int of_phy_register_fixed_link(struct device_node *np);
+extern bool of_phy_is_fixed_link(struct device_node *np);
#else /* CONFIG_OF */
static inline int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
@@ -50,6 +55,13 @@ static inline struct phy_device *of_phy_connect(struct net_device *dev,
return NULL;
}
+static inline struct phy_device *
+of_phy_get_and_connect(struct net_device *dev, struct device_node *np,
+ void (*hndlr)(struct net_device *))
+{
+ return NULL;
+}
+
static inline struct phy_device *of_phy_attach(struct net_device *dev,
struct device_node *phy_np,
u32 flags, phy_interface_t iface)
@@ -67,12 +79,6 @@ static inline int of_mdio_parse_addr(struct device *dev,
{
return -ENOSYS;
}
-#endif /* CONFIG_OF */
-
-#if defined(CONFIG_OF) && defined(CONFIG_FIXED_PHY)
-extern int of_phy_register_fixed_link(struct device_node *np);
-extern bool of_phy_is_fixed_link(struct device_node *np);
-#else
static inline int of_phy_register_fixed_link(struct device_node *np)
{
return -ENOSYS;
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index c201060e0c6d..f8e1992d6423 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -1,7 +1,8 @@
#ifndef __OF_RESERVED_MEM_H
#define __OF_RESERVED_MEM_H
-struct device;
+#include <linux/device.h>
+
struct of_phandle_args;
struct reserved_mem_ops;
@@ -28,7 +29,9 @@ typedef int (*reservedmem_of_init_fn)(struct reserved_mem *rmem);
_OF_DECLARE(reservedmem, name, compat, init, reservedmem_of_init_fn)
#ifdef CONFIG_OF_RESERVED_MEM
-int of_reserved_mem_device_init(struct device *dev);
+
+int of_reserved_mem_device_init_by_idx(struct device *dev,
+ struct device_node *np, int idx);
void of_reserved_mem_device_release(struct device *dev);
int early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
@@ -42,7 +45,8 @@ void fdt_init_reserved_mem(void);
void fdt_reserved_mem_save_node(unsigned long node, const char *uname,
phys_addr_t base, phys_addr_t size);
#else
-static inline int of_reserved_mem_device_init(struct device *dev)
+static inline int of_reserved_mem_device_init_by_idx(struct device *dev,
+ struct device_node *np, int idx)
{
return -ENOSYS;
}
@@ -53,4 +57,19 @@ static inline void fdt_reserved_mem_save_node(unsigned long node,
const char *uname, phys_addr_t base, phys_addr_t size) { }
#endif
+/**
+ * of_reserved_mem_device_init() - assign reserved memory region to given device
+ * @dev: Pointer to the device to configure
+ *
+ * This function assigns respective DMA-mapping operations based on the first
+ * reserved memory region specified by 'memory-region' property in device tree
+ * node of the given device.
+ *
+ * Returns error code or zero on success.
+ */
+static inline int of_reserved_mem_device_init(struct device *dev)
+{
+ return of_reserved_mem_device_init_by_idx(dev, dev->of_node, 0);
+}
+
#endif /* __OF_RESERVED_MEM_H */
diff --git a/include/linux/oom.h b/include/linux/oom.h
index 83469522690a..5bc0457ee3a8 100644
--- a/include/linux/oom.h
+++ b/include/linux/oom.h
@@ -23,6 +23,9 @@ struct oom_control {
/* Used to determine mempolicy */
nodemask_t *nodemask;
+ /* Memory cgroup in which oom is invoked, or NULL for global oom */
+ struct mem_cgroup *memcg;
+
/* Used to determine cpuset and node locality requirement */
const gfp_t gfp_mask;
@@ -70,9 +73,9 @@ static inline bool oom_task_origin(const struct task_struct *p)
extern void mark_oom_victim(struct task_struct *tsk);
#ifdef CONFIG_MMU
-extern void try_oom_reaper(struct task_struct *tsk);
+extern void wake_oom_reaper(struct task_struct *tsk);
#else
-static inline void try_oom_reaper(struct task_struct *tsk)
+static inline void wake_oom_reaper(struct task_struct *tsk)
{
}
#endif
@@ -83,14 +86,13 @@ extern unsigned long oom_badness(struct task_struct *p,
extern void oom_kill_process(struct oom_control *oc, struct task_struct *p,
unsigned int points, unsigned long totalpages,
- struct mem_cgroup *memcg, const char *message);
+ const char *message);
extern void check_panic_on_oom(struct oom_control *oc,
- enum oom_constraint constraint,
- struct mem_cgroup *memcg);
+ enum oom_constraint constraint);
extern enum oom_scan_t oom_scan_process_thread(struct oom_control *oc,
- struct task_struct *task, unsigned long totalpages);
+ struct task_struct *task);
extern bool out_of_memory(struct oom_control *oc);
@@ -105,27 +107,7 @@ extern void oom_killer_enable(void);
extern struct task_struct *find_lock_task_mm(struct task_struct *p);
-static inline bool task_will_free_mem(struct task_struct *task)
-{
- struct signal_struct *sig = task->signal;
-
- /*
- * A coredumping process may sleep for an extended period in exit_mm(),
- * so the oom killer cannot assume that the process will promptly exit
- * and release memory.
- */
- if (sig->flags & SIGNAL_GROUP_COREDUMP)
- return false;
-
- if (!(task->flags & PF_EXITING))
- return false;
-
- /* Make sure that the whole thread group is going down */
- if (!thread_group_empty(task) && !(sig->flags & SIGNAL_GROUP_EXIT))
- return false;
-
- return true;
-}
+bool task_will_free_mem(struct task_struct *task);
/* sysctls */
extern int sysctl_oom_dump_tasks;
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index e5a32445f930..74e4dda91238 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -129,6 +129,9 @@ enum pageflags {
/* Compound pages. Stored in first tail page's flags */
PG_double_map = PG_private_2,
+
+ /* non-lru isolated movable page */
+ PG_isolated = PG_reclaim,
};
#ifndef __GENERATING_BOUNDS_H
@@ -292,11 +295,11 @@ PAGEFLAG(OwnerPriv1, owner_priv_1, PF_ANY)
*/
TESTPAGEFLAG(Writeback, writeback, PF_NO_COMPOUND)
TESTSCFLAG(Writeback, writeback, PF_NO_COMPOUND)
-PAGEFLAG(MappedToDisk, mappedtodisk, PF_NO_COMPOUND)
+PAGEFLAG(MappedToDisk, mappedtodisk, PF_NO_TAIL)
/* PG_readahead is only used for reads; PG_reclaim is only for writes */
-PAGEFLAG(Reclaim, reclaim, PF_NO_COMPOUND)
- TESTCLEARFLAG(Reclaim, reclaim, PF_NO_COMPOUND)
+PAGEFLAG(Reclaim, reclaim, PF_NO_TAIL)
+ TESTCLEARFLAG(Reclaim, reclaim, PF_NO_TAIL)
PAGEFLAG(Readahead, reclaim, PF_NO_COMPOUND)
TESTCLEARFLAG(Readahead, reclaim, PF_NO_COMPOUND)
@@ -357,29 +360,37 @@ PAGEFLAG(Idle, idle, PF_ANY)
* with the PAGE_MAPPING_ANON bit set to distinguish it. See rmap.h.
*
* On an anonymous page in a VM_MERGEABLE area, if CONFIG_KSM is enabled,
- * the PAGE_MAPPING_KSM bit may be set along with the PAGE_MAPPING_ANON bit;
- * and then page->mapping points, not to an anon_vma, but to a private
+ * the PAGE_MAPPING_MOVABLE bit may be set along with the PAGE_MAPPING_ANON
+ * bit; and then page->mapping points, not to an anon_vma, but to a private
* structure which KSM associates with that merged page. See ksm.h.
*
- * PAGE_MAPPING_KSM without PAGE_MAPPING_ANON is currently never used.
+ * PAGE_MAPPING_KSM without PAGE_MAPPING_ANON is used for non-lru movable
+ * page and then page->mapping points a struct address_space.
*
* Please note that, confusingly, "page_mapping" refers to the inode
* address_space which maps the page from disk; whereas "page_mapped"
* refers to user virtual address space into which the page is mapped.
*/
-#define PAGE_MAPPING_ANON 1
-#define PAGE_MAPPING_KSM 2
-#define PAGE_MAPPING_FLAGS (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM)
+#define PAGE_MAPPING_ANON 0x1
+#define PAGE_MAPPING_MOVABLE 0x2
+#define PAGE_MAPPING_KSM (PAGE_MAPPING_ANON | PAGE_MAPPING_MOVABLE)
+#define PAGE_MAPPING_FLAGS (PAGE_MAPPING_ANON | PAGE_MAPPING_MOVABLE)
-static __always_inline int PageAnonHead(struct page *page)
+static __always_inline int PageMappingFlags(struct page *page)
{
- return ((unsigned long)page->mapping & PAGE_MAPPING_ANON) != 0;
+ return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) != 0;
}
static __always_inline int PageAnon(struct page *page)
{
page = compound_head(page);
- return PageAnonHead(page);
+ return ((unsigned long)page->mapping & PAGE_MAPPING_ANON) != 0;
+}
+
+static __always_inline int __PageMovable(struct page *page)
+{
+ return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) ==
+ PAGE_MAPPING_MOVABLE;
}
#ifdef CONFIG_KSM
@@ -393,7 +404,7 @@ static __always_inline int PageKsm(struct page *page)
{
page = compound_head(page);
return ((unsigned long)page->mapping & PAGE_MAPPING_FLAGS) ==
- (PAGE_MAPPING_ANON | PAGE_MAPPING_KSM);
+ PAGE_MAPPING_KSM;
}
#else
TESTPAGEFLAG_FALSE(Ksm)
@@ -570,6 +581,17 @@ static inline int PageDoubleMap(struct page *page)
return PageHead(page) && test_bit(PG_double_map, &page[1].flags);
}
+static inline void SetPageDoubleMap(struct page *page)
+{
+ VM_BUG_ON_PAGE(!PageHead(page), page);
+ set_bit(PG_double_map, &page[1].flags);
+}
+
+static inline void ClearPageDoubleMap(struct page *page)
+{
+ VM_BUG_ON_PAGE(!PageHead(page), page);
+ clear_bit(PG_double_map, &page[1].flags);
+}
static inline int TestSetPageDoubleMap(struct page *page)
{
VM_BUG_ON_PAGE(!PageHead(page), page);
@@ -587,59 +609,59 @@ TESTPAGEFLAG_FALSE(TransHuge)
TESTPAGEFLAG_FALSE(TransCompound)
TESTPAGEFLAG_FALSE(TransCompoundMap)
TESTPAGEFLAG_FALSE(TransTail)
-TESTPAGEFLAG_FALSE(DoubleMap)
+PAGEFLAG_FALSE(DoubleMap)
TESTSETFLAG_FALSE(DoubleMap)
TESTCLEARFLAG_FALSE(DoubleMap)
#endif
/*
+ * For pages that are never mapped to userspace, page->mapcount may be
+ * used for storing extra information about page type. Any value used
+ * for this purpose must be <= -2, but it's better start not too close
+ * to -2 so that an underflow of the page_mapcount() won't be mistaken
+ * for a special page.
+ */
+#define PAGE_MAPCOUNT_OPS(uname, lname) \
+static __always_inline int Page##uname(struct page *page) \
+{ \
+ return atomic_read(&page->_mapcount) == \
+ PAGE_##lname##_MAPCOUNT_VALUE; \
+} \
+static __always_inline void __SetPage##uname(struct page *page) \
+{ \
+ VM_BUG_ON_PAGE(atomic_read(&page->_mapcount) != -1, page); \
+ atomic_set(&page->_mapcount, PAGE_##lname##_MAPCOUNT_VALUE); \
+} \
+static __always_inline void __ClearPage##uname(struct page *page) \
+{ \
+ VM_BUG_ON_PAGE(!Page##uname(page), page); \
+ atomic_set(&page->_mapcount, -1); \
+}
+
+/*
* PageBuddy() indicate that the page is free and in the buddy system
* (see mm/page_alloc.c).
- *
- * PAGE_BUDDY_MAPCOUNT_VALUE must be <= -2 but better not too close to
- * -2 so that an underflow of the page_mapcount() won't be mistaken
- * for a genuine PAGE_BUDDY_MAPCOUNT_VALUE. -128 can be created very
- * efficiently by most CPU architectures.
*/
-#define PAGE_BUDDY_MAPCOUNT_VALUE (-128)
-
-static inline int PageBuddy(struct page *page)
-{
- return atomic_read(&page->_mapcount) == PAGE_BUDDY_MAPCOUNT_VALUE;
-}
+#define PAGE_BUDDY_MAPCOUNT_VALUE (-128)
+PAGE_MAPCOUNT_OPS(Buddy, BUDDY)
-static inline void __SetPageBuddy(struct page *page)
-{
- VM_BUG_ON_PAGE(atomic_read(&page->_mapcount) != -1, page);
- atomic_set(&page->_mapcount, PAGE_BUDDY_MAPCOUNT_VALUE);
-}
+/*
+ * PageBalloon() is set on pages that are on the balloon page list
+ * (see mm/balloon_compaction.c).
+ */
+#define PAGE_BALLOON_MAPCOUNT_VALUE (-256)
+PAGE_MAPCOUNT_OPS(Balloon, BALLOON)
-static inline void __ClearPageBuddy(struct page *page)
-{
- VM_BUG_ON_PAGE(!PageBuddy(page), page);
- atomic_set(&page->_mapcount, -1);
-}
+/*
+ * If kmemcg is enabled, the buddy allocator will set PageKmemcg() on
+ * pages allocated with __GFP_ACCOUNT. It gets cleared on page free.
+ */
+#define PAGE_KMEMCG_MAPCOUNT_VALUE (-512)
+PAGE_MAPCOUNT_OPS(Kmemcg, KMEMCG)
extern bool is_free_buddy_page(struct page *page);
-#define PAGE_BALLOON_MAPCOUNT_VALUE (-256)
-
-static inline int PageBalloon(struct page *page)
-{
- return atomic_read(&page->_mapcount) == PAGE_BALLOON_MAPCOUNT_VALUE;
-}
-
-static inline void __SetPageBalloon(struct page *page)
-{
- VM_BUG_ON_PAGE(atomic_read(&page->_mapcount) != -1, page);
- atomic_set(&page->_mapcount, PAGE_BALLOON_MAPCOUNT_VALUE);
-}
-
-static inline void __ClearPageBalloon(struct page *page)
-{
- VM_BUG_ON_PAGE(!PageBalloon(page), page);
- atomic_set(&page->_mapcount, -1);
-}
+__PAGEFLAG(Isolated, isolated, PF_ANY);
/*
* If network-based swap is enabled, sl*b must keep track of whether pages
diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h
index e1fe7cf5bddf..03f2a3e7d76d 100644
--- a/include/linux/page_ext.h
+++ b/include/linux/page_ext.h
@@ -3,6 +3,7 @@
#include <linux/types.h>
#include <linux/stacktrace.h>
+#include <linux/stackdepot.h>
struct pglist_data;
struct page_ext_operations {
@@ -44,9 +45,8 @@ struct page_ext {
#ifdef CONFIG_PAGE_OWNER
unsigned int order;
gfp_t gfp_mask;
- unsigned int nr_entries;
int last_migrate_reason;
- unsigned long trace_entries[8];
+ depot_stack_handle_t handle;
#endif
};
diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h
index 46f1b939948c..30583ab0ffb1 100644
--- a/include/linux/page_owner.h
+++ b/include/linux/page_owner.h
@@ -10,7 +10,7 @@ extern struct page_ext_operations page_owner_ops;
extern void __reset_page_owner(struct page *page, unsigned int order);
extern void __set_page_owner(struct page *page,
unsigned int order, gfp_t gfp_mask);
-extern gfp_t __get_page_owner_gfp(struct page *page);
+extern void __split_page_owner(struct page *page, unsigned int order);
extern void __copy_page_owner(struct page *oldpage, struct page *newpage);
extern void __set_page_owner_migrate_reason(struct page *page, int reason);
extern void __dump_page_owner(struct page *page);
@@ -28,12 +28,10 @@ static inline void set_page_owner(struct page *page,
__set_page_owner(page, order, gfp_mask);
}
-static inline gfp_t get_page_owner_gfp(struct page *page)
+static inline void split_page_owner(struct page *page, unsigned int order)
{
if (static_branch_unlikely(&page_owner_inited))
- return __get_page_owner_gfp(page);
- else
- return 0;
+ __split_page_owner(page, order);
}
static inline void copy_page_owner(struct page *oldpage, struct page *newpage)
{
@@ -58,9 +56,9 @@ static inline void set_page_owner(struct page *page,
unsigned int order, gfp_t gfp_mask)
{
}
-static inline gfp_t get_page_owner_gfp(struct page *page)
+static inline void split_page_owner(struct page *page,
+ unsigned int order)
{
- return 0;
}
static inline void copy_page_owner(struct page *oldpage, struct page *newpage)
{
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 97354102794d..81363b834900 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -209,10 +209,10 @@ static inline struct page *page_cache_alloc_cold(struct address_space *x)
return __page_cache_alloc(mapping_gfp_mask(x)|__GFP_COLD);
}
-static inline struct page *page_cache_alloc_readahead(struct address_space *x)
+static inline gfp_t readahead_gfp_mask(struct address_space *x)
{
- return __page_cache_alloc(mapping_gfp_mask(x) |
- __GFP_COLD | __GFP_NORETRY | __GFP_NOWARN);
+ return mapping_gfp_mask(x) |
+ __GFP_COLD | __GFP_NORETRY | __GFP_NOWARN;
}
typedef int filler_t(void *, struct page *);
diff --git a/include/linux/percpu-refcount.h b/include/linux/percpu-refcount.h
index 84f542df7ff5..1c7eec09e5eb 100644
--- a/include/linux/percpu-refcount.h
+++ b/include/linux/percpu-refcount.h
@@ -136,14 +136,12 @@ static inline bool __ref_is_percpu(struct percpu_ref *ref,
* used as a pointer. If the compiler generates a separate fetch
* when using it as a pointer, __PERCPU_REF_ATOMIC may be set in
* between contaminating the pointer value, meaning that
- * ACCESS_ONCE() is required when fetching it.
- *
- * Also, we need a data dependency barrier to be paired with
- * smp_store_release() in __percpu_ref_switch_to_percpu().
- *
- * Use lockless deref which contains both.
+ * READ_ONCE() is required when fetching it.
*/
- percpu_ptr = lockless_dereference(ref->percpu_count_ptr);
+ percpu_ptr = READ_ONCE(ref->percpu_count_ptr);
+
+ /* paired with smp_store_release() in __percpu_ref_switch_to_percpu() */
+ smp_read_barrier_depends();
/*
* Theoretically, the following could test just ATOMIC; however,
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 1a827cecd62f..e1f921c2e4e0 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -69,9 +69,22 @@ struct perf_callchain_entry_ctx {
bool contexts_maxed;
};
+typedef unsigned long (*perf_copy_f)(void *dst, const void *src,
+ unsigned long off, unsigned long len);
+
+struct perf_raw_frag {
+ union {
+ struct perf_raw_frag *next;
+ unsigned long pad;
+ };
+ perf_copy_f copy;
+ void *data;
+ u32 size;
+} __packed;
+
struct perf_raw_record {
+ struct perf_raw_frag frag;
u32 size;
- void *data;
};
/*
@@ -517,6 +530,11 @@ struct swevent_hlist {
struct perf_cgroup;
struct ring_buffer;
+struct pmu_event_list {
+ raw_spinlock_t lock;
+ struct list_head list;
+};
+
/**
* struct perf_event - performance event kernel representation:
*/
@@ -675,6 +693,7 @@ struct perf_event {
int cgrp_defer_enabled;
#endif
+ struct list_head sb_list;
#endif /* CONFIG_PERF_EVENTS */
};
@@ -1074,7 +1093,7 @@ extern void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct
extern struct perf_callchain_entry *
get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user,
u32 max_stack, bool crosstask, bool add_mark);
-extern int get_callchain_buffers(void);
+extern int get_callchain_buffers(int max_stack);
extern void put_callchain_buffers(void);
extern int sysctl_perf_event_max_stack;
@@ -1283,6 +1302,11 @@ extern void perf_restore_debug_store(void);
static inline void perf_restore_debug_store(void) { }
#endif
+static __always_inline bool perf_raw_frag_last(const struct perf_raw_frag *frag)
+{
+ return frag->pad < sizeof(u64);
+}
+
#define perf_output_put(handle, x) perf_output_copy((handle), &(x), sizeof(x))
/*
@@ -1326,6 +1350,13 @@ struct perf_pmu_events_attr {
const char *event_str;
};
+struct perf_pmu_events_ht_attr {
+ struct device_attribute attr;
+ u64 id;
+ const char *event_str_ht;
+ const char *event_str_noht;
+};
+
ssize_t perf_event_sysfs_show(struct device *dev, struct device_attribute *attr,
char *page);
diff --git a/include/linux/pfn_t.h b/include/linux/pfn_t.h
index 94994810c7c0..a3d90b9da18d 100644
--- a/include/linux/pfn_t.h
+++ b/include/linux/pfn_t.h
@@ -28,7 +28,10 @@ static inline pfn_t pfn_to_pfn_t(unsigned long pfn)
return __pfn_to_pfn_t(pfn, 0);
}
-extern pfn_t phys_to_pfn_t(phys_addr_t addr, u64 flags);
+static inline pfn_t phys_to_pfn_t(phys_addr_t addr, u64 flags)
+{
+ return __pfn_to_pfn_t(addr >> PAGE_SHIFT, flags);
+}
static inline bool pfn_t_has_page(pfn_t pfn)
{
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index a810f2a18842..f08b67238b58 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -22,12 +22,20 @@
struct phy;
+enum phy_mode {
+ PHY_MODE_INVALID,
+ PHY_MODE_USB_HOST,
+ PHY_MODE_USB_DEVICE,
+ PHY_MODE_USB_OTG,
+};
+
/**
* struct phy_ops - set of function pointers for performing phy operations
* @init: operation to be performed for initializing phy
* @exit: operation to be performed while exiting
* @power_on: powering on the phy
* @power_off: powering off the phy
+ * @set_mode: set the mode of the phy
* @owner: the module owner containing the ops
*/
struct phy_ops {
@@ -35,6 +43,7 @@ struct phy_ops {
int (*exit)(struct phy *phy);
int (*power_on)(struct phy *phy);
int (*power_off)(struct phy *phy);
+ int (*set_mode)(struct phy *phy, enum phy_mode mode);
struct module *owner;
};
@@ -126,6 +135,7 @@ int phy_init(struct phy *phy);
int phy_exit(struct phy *phy);
int phy_power_on(struct phy *phy);
int phy_power_off(struct phy *phy);
+int phy_set_mode(struct phy *phy, enum phy_mode mode);
static inline int phy_get_bus_width(struct phy *phy)
{
return phy->attrs.bus_width;
@@ -233,6 +243,13 @@ static inline int phy_power_off(struct phy *phy)
return -ENOSYS;
}
+static inline int phy_set_mode(struct phy *phy, enum phy_mode mode)
+{
+ if (!phy)
+ return 0;
+ return -ENOSYS;
+}
+
static inline int phy_get_bus_width(struct phy *phy)
{
return -ENOSYS;
diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h
index d921afd5f109..12343caa114e 100644
--- a/include/linux/pinctrl/pinconf-generic.h
+++ b/include/linux/pinctrl/pinconf-generic.h
@@ -175,6 +175,8 @@ int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev,
int pinconf_generic_dt_node_to_map(struct pinctrl_dev *pctldev,
struct device_node *np_config, struct pinctrl_map **map,
unsigned *num_maps, enum pinctrl_map_type type);
+void pinconf_generic_dt_free_map(struct pinctrl_dev *pctldev,
+ struct pinctrl_map *map, unsigned num_maps);
static inline int pinconf_generic_dt_node_to_map_group(
struct pinctrl_dev *pctldev, struct device_node *np_config,
diff --git a/include/linux/platform_data/at24.h b/include/linux/platform_data/at24.h
index be830b141d83..271a4e25af67 100644
--- a/include/linux/platform_data/at24.h
+++ b/include/linux/platform_data/at24.h
@@ -10,6 +10,7 @@
#include <linux/types.h>
#include <linux/nvmem-consumer.h>
+#include <linux/bitops.h>
/**
* struct at24_platform_data - data to set up at24 (generic eeprom) driver
@@ -43,10 +44,12 @@ struct at24_platform_data {
u32 byte_len; /* size (sum of all addr) */
u16 page_size; /* for writes */
u8 flags;
-#define AT24_FLAG_ADDR16 0x80 /* address pointer is 16 bit */
-#define AT24_FLAG_READONLY 0x40 /* sysfs-entry will be read-only */
-#define AT24_FLAG_IRUGO 0x20 /* sysfs-entry will be world-readable */
-#define AT24_FLAG_TAKE8ADDR 0x10 /* take always 8 addresses (24c00) */
+#define AT24_FLAG_ADDR16 BIT(7) /* address pointer is 16 bit */
+#define AT24_FLAG_READONLY BIT(6) /* sysfs-entry will be read-only */
+#define AT24_FLAG_IRUGO BIT(5) /* sysfs-entry will be world-readable */
+#define AT24_FLAG_TAKE8ADDR BIT(4) /* take always 8 addresses (24c00) */
+#define AT24_FLAG_SERIAL BIT(3) /* factory-programmed serial number */
+#define AT24_FLAG_MAC BIT(2) /* factory-programmed mac address */
void (*setup)(struct nvmem_device *nvmem, void *context);
void *context;
diff --git a/include/linux/platform_data/b53.h b/include/linux/platform_data/b53.h
new file mode 100644
index 000000000000..69d279c0da96
--- /dev/null
+++ b/include/linux/platform_data/b53.h
@@ -0,0 +1,33 @@
+/*
+ * B53 platform data
+ *
+ * Copyright (C) 2013 Jonas Gorski <jogo@openwrt.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __B53_H
+#define __B53_H
+
+#include <linux/kernel.h>
+
+struct b53_platform_data {
+ u32 chip_id;
+ u16 enabled_ports;
+
+ /* only used by MMAP'd driver */
+ unsigned big_endian:1;
+ void __iomem *regs;
+};
+
+#endif
diff --git a/include/linux/platform_data/sht3x.h b/include/linux/platform_data/sht3x.h
new file mode 100644
index 000000000000..2e5eea358194
--- /dev/null
+++ b/include/linux/platform_data/sht3x.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 Sensirion AG, Switzerland
+ * Author: David Frey <david.frey@sensirion.com>
+ * Author: Pascal Sachs <pascal.sachs@sensirion.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __SHT3X_H_
+#define __SHT3X_H_
+
+struct sht3x_platform_data {
+ bool blocking_io;
+ bool high_precision;
+};
+#endif /* __SHT3X_H_ */
diff --git a/include/linux/platform_data/spi-s3c64xx.h b/include/linux/platform_data/spi-s3c64xx.h
index fb5625bcca9a..5c1e21c87270 100644
--- a/include/linux/platform_data/spi-s3c64xx.h
+++ b/include/linux/platform_data/spi-s3c64xx.h
@@ -38,6 +38,7 @@ struct s3c64xx_spi_csinfo {
struct s3c64xx_spi_info {
int src_clk_nr;
int num_cs;
+ bool no_cs;
int (*cfg_gpio)(void);
dma_filter_fn filter;
void *dma_tx;
diff --git a/include/linux/pm_clock.h b/include/linux/pm_clock.h
index 308d6044f153..09779b0ae720 100644
--- a/include/linux/pm_clock.h
+++ b/include/linux/pm_clock.h
@@ -42,6 +42,7 @@ extern int pm_clk_create(struct device *dev);
extern void pm_clk_destroy(struct device *dev);
extern int pm_clk_add(struct device *dev, const char *con_id);
extern int pm_clk_add_clk(struct device *dev, struct clk *clk);
+extern int of_pm_clk_add_clk(struct device *dev, const char *name);
extern int of_pm_clk_add_clks(struct device *dev);
extern void pm_clk_remove(struct device *dev, const char *con_id);
extern void pm_clk_remove_clk(struct device *dev, struct clk *clk);
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h
index 39285c7bd3f5..31fec858088c 100644
--- a/include/linux/pm_domain.h
+++ b/include/linux/pm_domain.h
@@ -57,7 +57,6 @@ struct generic_pm_domain {
unsigned int device_count; /* Number of devices */
unsigned int suspended_count; /* System suspend device counter */
unsigned int prepared_count; /* Suspend counter of prepared devices */
- bool suspend_power_off; /* Power status before system suspend */
int (*power_off)(struct generic_pm_domain *domain);
int (*power_on)(struct generic_pm_domain *domain);
struct gpd_dev_ops dev_ops;
@@ -128,8 +127,8 @@ extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd,
struct generic_pm_domain *new_subdomain);
extern int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
struct generic_pm_domain *target);
-extern void pm_genpd_init(struct generic_pm_domain *genpd,
- struct dev_power_governor *gov, bool is_off);
+extern int pm_genpd_init(struct generic_pm_domain *genpd,
+ struct dev_power_governor *gov, bool is_off);
extern struct dev_power_governor simple_qos_governor;
extern struct dev_power_governor pm_domain_always_on_gov;
@@ -164,9 +163,10 @@ static inline int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd,
{
return -ENOSYS;
}
-static inline void pm_genpd_init(struct generic_pm_domain *genpd,
- struct dev_power_governor *gov, bool is_off)
+static inline int pm_genpd_init(struct generic_pm_domain *genpd,
+ struct dev_power_governor *gov, bool is_off)
{
+ return -ENOSYS;
}
#endif
diff --git a/include/linux/pmem.h b/include/linux/pmem.h
index 57d146fe44dd..e856c2cb0fe8 100644
--- a/include/linux/pmem.h
+++ b/include/linux/pmem.h
@@ -26,47 +26,35 @@
* calling these symbols with arch_has_pmem_api() and redirect to the
* implementation in asm/pmem.h.
*/
-static inline bool __arch_has_wmb_pmem(void)
-{
- return false;
-}
-
-static inline void arch_wmb_pmem(void)
-{
- BUG();
-}
-
-static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src,
- size_t n)
+static inline void arch_memcpy_to_pmem(void *dst, const void *src, size_t n)
{
BUG();
}
-static inline int arch_memcpy_from_pmem(void *dst, const void __pmem *src,
- size_t n)
+static inline int arch_memcpy_from_pmem(void *dst, const void *src, size_t n)
{
BUG();
return -EFAULT;
}
-static inline size_t arch_copy_from_iter_pmem(void __pmem *addr, size_t bytes,
+static inline size_t arch_copy_from_iter_pmem(void *addr, size_t bytes,
struct iov_iter *i)
{
BUG();
return 0;
}
-static inline void arch_clear_pmem(void __pmem *addr, size_t size)
+static inline void arch_clear_pmem(void *addr, size_t size)
{
BUG();
}
-static inline void arch_wb_cache_pmem(void __pmem *addr, size_t size)
+static inline void arch_wb_cache_pmem(void *addr, size_t size)
{
BUG();
}
-static inline void arch_invalidate_pmem(void __pmem *addr, size_t size)
+static inline void arch_invalidate_pmem(void *addr, size_t size)
{
BUG();
}
@@ -77,13 +65,6 @@ static inline bool arch_has_pmem_api(void)
return IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API);
}
-static inline int default_memcpy_from_pmem(void *dst, void __pmem const *src,
- size_t size)
-{
- memcpy(dst, (void __force *) src, size);
- return 0;
-}
-
/*
* memcpy_from_pmem - read from persistent memory with error handling
* @dst: destination buffer
@@ -92,54 +73,13 @@ static inline int default_memcpy_from_pmem(void *dst, void __pmem const *src,
*
* Returns 0 on success negative error code on failure.
*/
-static inline int memcpy_from_pmem(void *dst, void __pmem const *src,
- size_t size)
+static inline int memcpy_from_pmem(void *dst, void const *src, size_t size)
{
if (arch_has_pmem_api())
return arch_memcpy_from_pmem(dst, src, size);
else
- return default_memcpy_from_pmem(dst, src, size);
-}
-
-/**
- * arch_has_wmb_pmem - true if wmb_pmem() ensures durability
- *
- * For a given cpu implementation within an architecture it is possible
- * that wmb_pmem() resolves to a nop. In the case this returns
- * false, pmem api users are unable to ensure durability and may want to
- * fall back to a different data consistency model, or otherwise notify
- * the user.
- */
-static inline bool arch_has_wmb_pmem(void)
-{
- return arch_has_pmem_api() && __arch_has_wmb_pmem();
-}
-
-/*
- * These defaults seek to offer decent performance and minimize the
- * window between i/o completion and writes being durable on media.
- * However, it is undefined / architecture specific whether
- * ARCH_MEMREMAP_PMEM + default_memcpy_to_pmem is sufficient for
- * making data durable relative to i/o completion.
- */
-static inline void default_memcpy_to_pmem(void __pmem *dst, const void *src,
- size_t size)
-{
- memcpy((void __force *) dst, src, size);
-}
-
-static inline size_t default_copy_from_iter_pmem(void __pmem *addr,
- size_t bytes, struct iov_iter *i)
-{
- return copy_from_iter_nocache((void __force *)addr, bytes, i);
-}
-
-static inline void default_clear_pmem(void __pmem *addr, size_t size)
-{
- if (size == PAGE_SIZE && ((unsigned long)addr & ~PAGE_MASK) == 0)
- clear_page((void __force *)addr);
- else
- memset((void __force *)addr, 0, size);
+ memcpy(dst, src, size);
+ return 0;
}
/**
@@ -152,29 +92,14 @@ static inline void default_clear_pmem(void __pmem *addr, size_t size)
* being effectively evicted from, or never written to, the processor
* cache hierarchy after the copy completes. After memcpy_to_pmem()
* data may still reside in cpu or platform buffers, so this operation
- * must be followed by a wmb_pmem().
+ * must be followed by a blkdev_issue_flush() on the pmem block device.
*/
-static inline void memcpy_to_pmem(void __pmem *dst, const void *src, size_t n)
+static inline void memcpy_to_pmem(void *dst, const void *src, size_t n)
{
if (arch_has_pmem_api())
arch_memcpy_to_pmem(dst, src, n);
else
- default_memcpy_to_pmem(dst, src, n);
-}
-
-/**
- * wmb_pmem - synchronize writes to persistent memory
- *
- * After a series of memcpy_to_pmem() operations this drains data from
- * cpu write buffers and any platform (memory controller) buffers to
- * ensure that written data is durable on persistent memory media.
- */
-static inline void wmb_pmem(void)
-{
- if (arch_has_wmb_pmem())
- arch_wmb_pmem();
- else
- wmb();
+ memcpy(dst, src, n);
}
/**
@@ -184,14 +109,14 @@ static inline void wmb_pmem(void)
* @i: iterator with source data
*
* Copy data from the iterator 'i' to the PMEM buffer starting at 'addr'.
- * This function requires explicit ordering with a wmb_pmem() call.
+ * See blkdev_issue_flush() note for memcpy_to_pmem().
*/
-static inline size_t copy_from_iter_pmem(void __pmem *addr, size_t bytes,
+static inline size_t copy_from_iter_pmem(void *addr, size_t bytes,
struct iov_iter *i)
{
if (arch_has_pmem_api())
return arch_copy_from_iter_pmem(addr, bytes, i);
- return default_copy_from_iter_pmem(addr, bytes, i);
+ return copy_from_iter_nocache(addr, bytes, i);
}
/**
@@ -200,14 +125,14 @@ static inline size_t copy_from_iter_pmem(void __pmem *addr, size_t bytes,
* @size: number of bytes to zero
*
* Write zeros into the memory range starting at 'addr' for 'size' bytes.
- * This function requires explicit ordering with a wmb_pmem() call.
+ * See blkdev_issue_flush() note for memcpy_to_pmem().
*/
-static inline void clear_pmem(void __pmem *addr, size_t size)
+static inline void clear_pmem(void *addr, size_t size)
{
if (arch_has_pmem_api())
arch_clear_pmem(addr, size);
else
- default_clear_pmem(addr, size);
+ memset(addr, 0, size);
}
/**
@@ -218,7 +143,7 @@ static inline void clear_pmem(void __pmem *addr, size_t size)
* For platforms that support clearing poison this flushes any poisoned
* ranges out of the cache
*/
-static inline void invalidate_pmem(void __pmem *addr, size_t size)
+static inline void invalidate_pmem(void *addr, size_t size)
{
if (arch_has_pmem_api())
arch_invalidate_pmem(addr, size);
@@ -230,9 +155,9 @@ static inline void invalidate_pmem(void __pmem *addr, size_t size)
* @size: number of bytes to write back
*
* Write back the processor cache range starting at 'addr' for 'size' bytes.
- * This function requires explicit ordering with a wmb_pmem() call.
+ * See blkdev_issue_flush() note for memcpy_to_pmem().
*/
-static inline void wb_cache_pmem(void __pmem *addr, size_t size)
+static inline void wb_cache_pmem(void *addr, size_t size)
{
if (arch_has_pmem_api())
arch_wb_cache_pmem(addr, size);
diff --git a/include/linux/power/max8903_charger.h b/include/linux/power/max8903_charger.h
index 24f51db8a83f..89d3f1cb3433 100644
--- a/include/linux/power/max8903_charger.h
+++ b/include/linux/power/max8903_charger.h
@@ -26,8 +26,8 @@
struct max8903_pdata {
/*
* GPIOs
- * cen, chg, flt, and usus are optional.
- * dok, dcm, and uok are not optional depending on the status of
+ * cen, chg, flt, dcm and usus are optional.
+ * dok and uok are not optional depending on the status of
* dc_valid and usb_valid.
*/
int cen; /* Charger Enable input */
@@ -41,7 +41,7 @@ struct max8903_pdata {
/*
* DC(Adapter/TA) is wired
* When dc_valid is true,
- * dok and dcm should be valid.
+ * dok should be valid.
*
* At least one of dc_valid or usb_valid should be true.
*/
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 751061790626..3965503315ef 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -248,6 +248,7 @@ struct power_supply {
struct delayed_work deferred_register_work;
spinlock_t changed_lock;
bool changed;
+ bool initialized;
atomic_t use_cnt;
#ifdef CONFIG_THERMAL
struct thermal_zone_device *tzd;
diff --git a/include/linux/printk.h b/include/linux/printk.h
index f4da695fd615..f136b22c7772 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -108,11 +108,14 @@ struct va_format {
* Dummy printk for disabled debugging statements to use whilst maintaining
* gcc's format checking.
*/
-#define no_printk(fmt, ...) \
-do { \
- if (0) \
- printk(fmt, ##__VA_ARGS__); \
-} while (0)
+#define no_printk(fmt, ...) \
+({ \
+ do { \
+ if (0) \
+ printk(fmt, ##__VA_ARGS__); \
+ } while (0); \
+ 0; \
+})
#ifdef CONFIG_EARLY_PRINTK
extern asmlinkage __printf(1, 2)
@@ -309,20 +312,24 @@ extern asmlinkage void dump_stack(void) __cold;
#define printk_once(fmt, ...) \
({ \
static bool __print_once __read_mostly; \
+ bool __ret_print_once = !__print_once; \
\
if (!__print_once) { \
__print_once = true; \
printk(fmt, ##__VA_ARGS__); \
} \
+ unlikely(__ret_print_once); \
})
#define printk_deferred_once(fmt, ...) \
({ \
static bool __print_once __read_mostly; \
+ bool __ret_print_once = !__print_once; \
\
if (!__print_once) { \
__print_once = true; \
printk_deferred(fmt, ##__VA_ARGS__); \
} \
+ unlikely(__ret_print_once); \
})
#else
#define printk_once(fmt, ...) \
diff --git a/include/linux/pstore.h b/include/linux/pstore.h
index 831479f8df8f..899e95e84400 100644
--- a/include/linux/pstore.h
+++ b/include/linux/pstore.h
@@ -58,7 +58,8 @@ struct pstore_info {
int (*close)(struct pstore_info *psi);
ssize_t (*read)(u64 *id, enum pstore_type_id *type,
int *count, struct timespec *time, char **buf,
- bool *compressed, struct pstore_info *psi);
+ bool *compressed, ssize_t *ecc_notice_size,
+ struct pstore_info *psi);
int (*write)(enum pstore_type_id type,
enum kmsg_dump_reason reason, u64 *id,
unsigned int part, int count, bool compressed,
diff --git a/include/linux/ptr_ring.h b/include/linux/ptr_ring.h
new file mode 100644
index 000000000000..2052011bf9fb
--- /dev/null
+++ b/include/linux/ptr_ring.h
@@ -0,0 +1,448 @@
+/*
+ * Definitions for the 'struct ptr_ring' datastructure.
+ *
+ * Author:
+ * Michael S. Tsirkin <mst@redhat.com>
+ *
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This is a limited-size FIFO maintaining pointers in FIFO order, with
+ * one CPU producing entries and another consuming entries from a FIFO.
+ *
+ * This implementation tries to minimize cache-contention when there is a
+ * single producer and a single consumer CPU.
+ */
+
+#ifndef _LINUX_PTR_RING_H
+#define _LINUX_PTR_RING_H 1
+
+#ifdef __KERNEL__
+#include <linux/spinlock.h>
+#include <linux/cache.h>
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/cache.h>
+#include <linux/slab.h>
+#include <asm/errno.h>
+#endif
+
+struct ptr_ring {
+ int producer ____cacheline_aligned_in_smp;
+ spinlock_t producer_lock;
+ int consumer ____cacheline_aligned_in_smp;
+ spinlock_t consumer_lock;
+ /* Shared consumer/producer data */
+ /* Read-only by both the producer and the consumer */
+ int size ____cacheline_aligned_in_smp; /* max entries in queue */
+ void **queue;
+};
+
+/* Note: callers invoking this in a loop must use a compiler barrier,
+ * for example cpu_relax(). If ring is ever resized, callers must hold
+ * producer_lock - see e.g. ptr_ring_full. Otherwise, if callers don't hold
+ * producer_lock, the next call to __ptr_ring_produce may fail.
+ */
+static inline bool __ptr_ring_full(struct ptr_ring *r)
+{
+ return r->queue[r->producer];
+}
+
+static inline bool ptr_ring_full(struct ptr_ring *r)
+{
+ bool ret;
+
+ spin_lock(&r->producer_lock);
+ ret = __ptr_ring_full(r);
+ spin_unlock(&r->producer_lock);
+
+ return ret;
+}
+
+static inline bool ptr_ring_full_irq(struct ptr_ring *r)
+{
+ bool ret;
+
+ spin_lock_irq(&r->producer_lock);
+ ret = __ptr_ring_full(r);
+ spin_unlock_irq(&r->producer_lock);
+
+ return ret;
+}
+
+static inline bool ptr_ring_full_any(struct ptr_ring *r)
+{
+ unsigned long flags;
+ bool ret;
+
+ spin_lock_irqsave(&r->producer_lock, flags);
+ ret = __ptr_ring_full(r);
+ spin_unlock_irqrestore(&r->producer_lock, flags);
+
+ return ret;
+}
+
+static inline bool ptr_ring_full_bh(struct ptr_ring *r)
+{
+ bool ret;
+
+ spin_lock_bh(&r->producer_lock);
+ ret = __ptr_ring_full(r);
+ spin_unlock_bh(&r->producer_lock);
+
+ return ret;
+}
+
+/* Note: callers invoking this in a loop must use a compiler barrier,
+ * for example cpu_relax(). Callers must hold producer_lock.
+ */
+static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr)
+{
+ if (unlikely(!r->size) || r->queue[r->producer])
+ return -ENOSPC;
+
+ r->queue[r->producer++] = ptr;
+ if (unlikely(r->producer >= r->size))
+ r->producer = 0;
+ return 0;
+}
+
+static inline int ptr_ring_produce(struct ptr_ring *r, void *ptr)
+{
+ int ret;
+
+ spin_lock(&r->producer_lock);
+ ret = __ptr_ring_produce(r, ptr);
+ spin_unlock(&r->producer_lock);
+
+ return ret;
+}
+
+static inline int ptr_ring_produce_irq(struct ptr_ring *r, void *ptr)
+{
+ int ret;
+
+ spin_lock_irq(&r->producer_lock);
+ ret = __ptr_ring_produce(r, ptr);
+ spin_unlock_irq(&r->producer_lock);
+
+ return ret;
+}
+
+static inline int ptr_ring_produce_any(struct ptr_ring *r, void *ptr)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&r->producer_lock, flags);
+ ret = __ptr_ring_produce(r, ptr);
+ spin_unlock_irqrestore(&r->producer_lock, flags);
+
+ return ret;
+}
+
+static inline int ptr_ring_produce_bh(struct ptr_ring *r, void *ptr)
+{
+ int ret;
+
+ spin_lock_bh(&r->producer_lock);
+ ret = __ptr_ring_produce(r, ptr);
+ spin_unlock_bh(&r->producer_lock);
+
+ return ret;
+}
+
+/* Note: callers invoking this in a loop must use a compiler barrier,
+ * for example cpu_relax(). Callers must take consumer_lock
+ * if they dereference the pointer - see e.g. PTR_RING_PEEK_CALL.
+ * If ring is never resized, and if the pointer is merely
+ * tested, there's no need to take the lock - see e.g. __ptr_ring_empty.
+ */
+static inline void *__ptr_ring_peek(struct ptr_ring *r)
+{
+ if (likely(r->size))
+ return r->queue[r->consumer];
+ return NULL;
+}
+
+/* Note: callers invoking this in a loop must use a compiler barrier,
+ * for example cpu_relax(). Callers must take consumer_lock
+ * if the ring is ever resized - see e.g. ptr_ring_empty.
+ */
+static inline bool __ptr_ring_empty(struct ptr_ring *r)
+{
+ return !__ptr_ring_peek(r);
+}
+
+static inline bool ptr_ring_empty(struct ptr_ring *r)
+{
+ bool ret;
+
+ spin_lock(&r->consumer_lock);
+ ret = __ptr_ring_empty(r);
+ spin_unlock(&r->consumer_lock);
+
+ return ret;
+}
+
+static inline bool ptr_ring_empty_irq(struct ptr_ring *r)
+{
+ bool ret;
+
+ spin_lock_irq(&r->consumer_lock);
+ ret = __ptr_ring_empty(r);
+ spin_unlock_irq(&r->consumer_lock);
+
+ return ret;
+}
+
+static inline bool ptr_ring_empty_any(struct ptr_ring *r)
+{
+ unsigned long flags;
+ bool ret;
+
+ spin_lock_irqsave(&r->consumer_lock, flags);
+ ret = __ptr_ring_empty(r);
+ spin_unlock_irqrestore(&r->consumer_lock, flags);
+
+ return ret;
+}
+
+static inline bool ptr_ring_empty_bh(struct ptr_ring *r)
+{
+ bool ret;
+
+ spin_lock_bh(&r->consumer_lock);
+ ret = __ptr_ring_empty(r);
+ spin_unlock_bh(&r->consumer_lock);
+
+ return ret;
+}
+
+/* Must only be called after __ptr_ring_peek returned !NULL */
+static inline void __ptr_ring_discard_one(struct ptr_ring *r)
+{
+ r->queue[r->consumer++] = NULL;
+ if (unlikely(r->consumer >= r->size))
+ r->consumer = 0;
+}
+
+static inline void *__ptr_ring_consume(struct ptr_ring *r)
+{
+ void *ptr;
+
+ ptr = __ptr_ring_peek(r);
+ if (ptr)
+ __ptr_ring_discard_one(r);
+
+ return ptr;
+}
+
+static inline void *ptr_ring_consume(struct ptr_ring *r)
+{
+ void *ptr;
+
+ spin_lock(&r->consumer_lock);
+ ptr = __ptr_ring_consume(r);
+ spin_unlock(&r->consumer_lock);
+
+ return ptr;
+}
+
+static inline void *ptr_ring_consume_irq(struct ptr_ring *r)
+{
+ void *ptr;
+
+ spin_lock_irq(&r->consumer_lock);
+ ptr = __ptr_ring_consume(r);
+ spin_unlock_irq(&r->consumer_lock);
+
+ return ptr;
+}
+
+static inline void *ptr_ring_consume_any(struct ptr_ring *r)
+{
+ unsigned long flags;
+ void *ptr;
+
+ spin_lock_irqsave(&r->consumer_lock, flags);
+ ptr = __ptr_ring_consume(r);
+ spin_unlock_irqrestore(&r->consumer_lock, flags);
+
+ return ptr;
+}
+
+static inline void *ptr_ring_consume_bh(struct ptr_ring *r)
+{
+ void *ptr;
+
+ spin_lock_bh(&r->consumer_lock);
+ ptr = __ptr_ring_consume(r);
+ spin_unlock_bh(&r->consumer_lock);
+
+ return ptr;
+}
+
+/* Cast to structure type and call a function without discarding from FIFO.
+ * Function must return a value.
+ * Callers must take consumer_lock.
+ */
+#define __PTR_RING_PEEK_CALL(r, f) ((f)(__ptr_ring_peek(r)))
+
+#define PTR_RING_PEEK_CALL(r, f) ({ \
+ typeof((f)(NULL)) __PTR_RING_PEEK_CALL_v; \
+ \
+ spin_lock(&(r)->consumer_lock); \
+ __PTR_RING_PEEK_CALL_v = __PTR_RING_PEEK_CALL(r, f); \
+ spin_unlock(&(r)->consumer_lock); \
+ __PTR_RING_PEEK_CALL_v; \
+})
+
+#define PTR_RING_PEEK_CALL_IRQ(r, f) ({ \
+ typeof((f)(NULL)) __PTR_RING_PEEK_CALL_v; \
+ \
+ spin_lock_irq(&(r)->consumer_lock); \
+ __PTR_RING_PEEK_CALL_v = __PTR_RING_PEEK_CALL(r, f); \
+ spin_unlock_irq(&(r)->consumer_lock); \
+ __PTR_RING_PEEK_CALL_v; \
+})
+
+#define PTR_RING_PEEK_CALL_BH(r, f) ({ \
+ typeof((f)(NULL)) __PTR_RING_PEEK_CALL_v; \
+ \
+ spin_lock_bh(&(r)->consumer_lock); \
+ __PTR_RING_PEEK_CALL_v = __PTR_RING_PEEK_CALL(r, f); \
+ spin_unlock_bh(&(r)->consumer_lock); \
+ __PTR_RING_PEEK_CALL_v; \
+})
+
+#define PTR_RING_PEEK_CALL_ANY(r, f) ({ \
+ typeof((f)(NULL)) __PTR_RING_PEEK_CALL_v; \
+ unsigned long __PTR_RING_PEEK_CALL_f;\
+ \
+ spin_lock_irqsave(&(r)->consumer_lock, __PTR_RING_PEEK_CALL_f); \
+ __PTR_RING_PEEK_CALL_v = __PTR_RING_PEEK_CALL(r, f); \
+ spin_unlock_irqrestore(&(r)->consumer_lock, __PTR_RING_PEEK_CALL_f); \
+ __PTR_RING_PEEK_CALL_v; \
+})
+
+static inline void **__ptr_ring_init_queue_alloc(int size, gfp_t gfp)
+{
+ return kzalloc(ALIGN(size * sizeof(void *), SMP_CACHE_BYTES), gfp);
+}
+
+static inline int ptr_ring_init(struct ptr_ring *r, int size, gfp_t gfp)
+{
+ r->queue = __ptr_ring_init_queue_alloc(size, gfp);
+ if (!r->queue)
+ return -ENOMEM;
+
+ r->size = size;
+ r->producer = r->consumer = 0;
+ spin_lock_init(&r->producer_lock);
+ spin_lock_init(&r->consumer_lock);
+
+ return 0;
+}
+
+static inline void **__ptr_ring_swap_queue(struct ptr_ring *r, void **queue,
+ int size, gfp_t gfp,
+ void (*destroy)(void *))
+{
+ int producer = 0;
+ void **old;
+ void *ptr;
+
+ while ((ptr = ptr_ring_consume(r)))
+ if (producer < size)
+ queue[producer++] = ptr;
+ else if (destroy)
+ destroy(ptr);
+
+ r->size = size;
+ r->producer = producer;
+ r->consumer = 0;
+ old = r->queue;
+ r->queue = queue;
+
+ return old;
+}
+
+static inline int ptr_ring_resize(struct ptr_ring *r, int size, gfp_t gfp,
+ void (*destroy)(void *))
+{
+ unsigned long flags;
+ void **queue = __ptr_ring_init_queue_alloc(size, gfp);
+ void **old;
+
+ if (!queue)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&(r)->producer_lock, flags);
+
+ old = __ptr_ring_swap_queue(r, queue, size, gfp, destroy);
+
+ spin_unlock_irqrestore(&(r)->producer_lock, flags);
+
+ kfree(old);
+
+ return 0;
+}
+
+static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, int nrings,
+ int size,
+ gfp_t gfp, void (*destroy)(void *))
+{
+ unsigned long flags;
+ void ***queues;
+ int i;
+
+ queues = kmalloc(nrings * sizeof *queues, gfp);
+ if (!queues)
+ goto noqueues;
+
+ for (i = 0; i < nrings; ++i) {
+ queues[i] = __ptr_ring_init_queue_alloc(size, gfp);
+ if (!queues[i])
+ goto nomem;
+ }
+
+ for (i = 0; i < nrings; ++i) {
+ spin_lock_irqsave(&(rings[i])->producer_lock, flags);
+ queues[i] = __ptr_ring_swap_queue(rings[i], queues[i],
+ size, gfp, destroy);
+ spin_unlock_irqrestore(&(rings[i])->producer_lock, flags);
+ }
+
+ for (i = 0; i < nrings; ++i)
+ kfree(queues[i]);
+
+ kfree(queues);
+
+ return 0;
+
+nomem:
+ while (--i >= 0)
+ kfree(queues[i]);
+
+ kfree(queues);
+
+noqueues:
+ return -ENOMEM;
+}
+
+static inline void ptr_ring_cleanup(struct ptr_ring *r, void (*destroy)(void *))
+{
+ void *ptr;
+
+ if (destroy)
+ while ((ptr = ptr_ring_consume(r)))
+ destroy(ptr);
+ kfree(r->queue);
+}
+
+#endif /* _LINUX_PTR_RING_H */
diff --git a/include/linux/qed/common_hsi.h b/include/linux/qed/common_hsi.h
index 3f14c7efe68f..40c0ada01806 100644
--- a/include/linux/qed/common_hsi.h
+++ b/include/linux/qed/common_hsi.h
@@ -12,10 +12,21 @@
#define CORE_SPQE_PAGE_SIZE_BYTES 4096
#define X_FINAL_CLEANUP_AGG_INT 1
+#define NUM_OF_GLOBAL_QUEUES 128
+
+/* Queue Zone sizes in bytes */
+#define TSTORM_QZONE_SIZE 8
+#define MSTORM_QZONE_SIZE 0
+#define USTORM_QZONE_SIZE 8
+#define XSTORM_QZONE_SIZE 8
+#define YSTORM_QZONE_SIZE 0
+#define PSTORM_QZONE_SIZE 0
+
+#define ETH_MAX_NUM_RX_QUEUES_PER_VF 16
#define FW_MAJOR_VERSION 8
-#define FW_MINOR_VERSION 7
-#define FW_REVISION_VERSION 3
+#define FW_MINOR_VERSION 10
+#define FW_REVISION_VERSION 5
#define FW_ENGINEERING_VERSION 0
/***********************/
@@ -97,45 +108,86 @@
#define DQ_XCM_AGG_VAL_SEL_REG6 7
/* XCM agg val selection */
-#define DQ_XCM_ETH_EDPM_NUM_BDS_CMD \
- DQ_XCM_AGG_VAL_SEL_WORD2
-#define DQ_XCM_ETH_TX_BD_CONS_CMD \
- DQ_XCM_AGG_VAL_SEL_WORD3
-#define DQ_XCM_CORE_TX_BD_CONS_CMD \
- DQ_XCM_AGG_VAL_SEL_WORD3
-#define DQ_XCM_ETH_TX_BD_PROD_CMD \
- DQ_XCM_AGG_VAL_SEL_WORD4
-#define DQ_XCM_CORE_TX_BD_PROD_CMD \
- DQ_XCM_AGG_VAL_SEL_WORD4
-#define DQ_XCM_CORE_SPQ_PROD_CMD \
- DQ_XCM_AGG_VAL_SEL_WORD4
-#define DQ_XCM_ETH_GO_TO_BD_CONS_CMD DQ_XCM_AGG_VAL_SEL_WORD5
+#define DQ_XCM_CORE_TX_BD_CONS_CMD DQ_XCM_AGG_VAL_SEL_WORD3
+#define DQ_XCM_CORE_TX_BD_PROD_CMD DQ_XCM_AGG_VAL_SEL_WORD4
+#define DQ_XCM_CORE_SPQ_PROD_CMD DQ_XCM_AGG_VAL_SEL_WORD4
+#define DQ_XCM_ETH_EDPM_NUM_BDS_CMD DQ_XCM_AGG_VAL_SEL_WORD2
+#define DQ_XCM_ETH_TX_BD_CONS_CMD DQ_XCM_AGG_VAL_SEL_WORD3
+#define DQ_XCM_ETH_TX_BD_PROD_CMD DQ_XCM_AGG_VAL_SEL_WORD4
+#define DQ_XCM_ETH_GO_TO_BD_CONS_CMD DQ_XCM_AGG_VAL_SEL_WORD5
+
+/* UCM agg val selection (HW) */
+#define DQ_UCM_AGG_VAL_SEL_WORD0 0
+#define DQ_UCM_AGG_VAL_SEL_WORD1 1
+#define DQ_UCM_AGG_VAL_SEL_WORD2 2
+#define DQ_UCM_AGG_VAL_SEL_WORD3 3
+#define DQ_UCM_AGG_VAL_SEL_REG0 4
+#define DQ_UCM_AGG_VAL_SEL_REG1 5
+#define DQ_UCM_AGG_VAL_SEL_REG2 6
+#define DQ_UCM_AGG_VAL_SEL_REG3 7
+
+/* UCM agg val selection (FW) */
+#define DQ_UCM_ETH_PMD_TX_CONS_CMD DQ_UCM_AGG_VAL_SEL_WORD2
+#define DQ_UCM_ETH_PMD_RX_CONS_CMD DQ_UCM_AGG_VAL_SEL_WORD3
+#define DQ_UCM_ROCE_CQ_CONS_CMD DQ_UCM_AGG_VAL_SEL_REG0
+#define DQ_UCM_ROCE_CQ_PROD_CMD DQ_UCM_AGG_VAL_SEL_REG2
+
+/* TCM agg val selection (HW) */
+#define DQ_TCM_AGG_VAL_SEL_WORD0 0
+#define DQ_TCM_AGG_VAL_SEL_WORD1 1
+#define DQ_TCM_AGG_VAL_SEL_WORD2 2
+#define DQ_TCM_AGG_VAL_SEL_WORD3 3
+#define DQ_TCM_AGG_VAL_SEL_REG1 4
+#define DQ_TCM_AGG_VAL_SEL_REG2 5
+#define DQ_TCM_AGG_VAL_SEL_REG6 6
+#define DQ_TCM_AGG_VAL_SEL_REG9 7
+
+/* TCM agg val selection (FW) */
+#define DQ_TCM_L2B_BD_PROD_CMD \
+ DQ_TCM_AGG_VAL_SEL_WORD1
+#define DQ_TCM_ROCE_RQ_PROD_CMD \
+ DQ_TCM_AGG_VAL_SEL_WORD0
/* XCM agg counter flag selection */
-#define DQ_XCM_AGG_FLG_SHIFT_BIT14 0
-#define DQ_XCM_AGG_FLG_SHIFT_BIT15 1
-#define DQ_XCM_AGG_FLG_SHIFT_CF12 2
-#define DQ_XCM_AGG_FLG_SHIFT_CF13 3
-#define DQ_XCM_AGG_FLG_SHIFT_CF18 4
-#define DQ_XCM_AGG_FLG_SHIFT_CF19 5
-#define DQ_XCM_AGG_FLG_SHIFT_CF22 6
-#define DQ_XCM_AGG_FLG_SHIFT_CF23 7
+#define DQ_XCM_AGG_FLG_SHIFT_BIT14 0
+#define DQ_XCM_AGG_FLG_SHIFT_BIT15 1
+#define DQ_XCM_AGG_FLG_SHIFT_CF12 2
+#define DQ_XCM_AGG_FLG_SHIFT_CF13 3
+#define DQ_XCM_AGG_FLG_SHIFT_CF18 4
+#define DQ_XCM_AGG_FLG_SHIFT_CF19 5
+#define DQ_XCM_AGG_FLG_SHIFT_CF22 6
+#define DQ_XCM_AGG_FLG_SHIFT_CF23 7
/* XCM agg counter flag selection */
-#define DQ_XCM_ETH_DQ_CF_CMD (1 << \
- DQ_XCM_AGG_FLG_SHIFT_CF18)
-#define DQ_XCM_CORE_DQ_CF_CMD (1 << \
- DQ_XCM_AGG_FLG_SHIFT_CF18)
-#define DQ_XCM_ETH_TERMINATE_CMD (1 << \
- DQ_XCM_AGG_FLG_SHIFT_CF19)
-#define DQ_XCM_CORE_TERMINATE_CMD (1 << \
- DQ_XCM_AGG_FLG_SHIFT_CF19)
-#define DQ_XCM_ETH_SLOW_PATH_CMD (1 << \
- DQ_XCM_AGG_FLG_SHIFT_CF22)
-#define DQ_XCM_CORE_SLOW_PATH_CMD (1 << \
- DQ_XCM_AGG_FLG_SHIFT_CF22)
-#define DQ_XCM_ETH_TPH_EN_CMD (1 << \
- DQ_XCM_AGG_FLG_SHIFT_CF23)
+#define DQ_XCM_CORE_DQ_CF_CMD (1 << DQ_XCM_AGG_FLG_SHIFT_CF18)
+#define DQ_XCM_CORE_TERMINATE_CMD (1 << DQ_XCM_AGG_FLG_SHIFT_CF19)
+#define DQ_XCM_CORE_SLOW_PATH_CMD (1 << DQ_XCM_AGG_FLG_SHIFT_CF22)
+#define DQ_XCM_ETH_DQ_CF_CMD (1 << DQ_XCM_AGG_FLG_SHIFT_CF18)
+#define DQ_XCM_ETH_TERMINATE_CMD (1 << DQ_XCM_AGG_FLG_SHIFT_CF19)
+#define DQ_XCM_ETH_SLOW_PATH_CMD (1 << DQ_XCM_AGG_FLG_SHIFT_CF22)
+#define DQ_XCM_ETH_TPH_EN_CMD (1 << DQ_XCM_AGG_FLG_SHIFT_CF23)
+
+/* UCM agg counter flag selection (HW) */
+#define DQ_UCM_AGG_FLG_SHIFT_CF0 0
+#define DQ_UCM_AGG_FLG_SHIFT_CF1 1
+#define DQ_UCM_AGG_FLG_SHIFT_CF3 2
+#define DQ_UCM_AGG_FLG_SHIFT_CF4 3
+#define DQ_UCM_AGG_FLG_SHIFT_CF5 4
+#define DQ_UCM_AGG_FLG_SHIFT_CF6 5
+#define DQ_UCM_AGG_FLG_SHIFT_RULE0EN 6
+#define DQ_UCM_AGG_FLG_SHIFT_RULE1EN 7
+
+/* UCM agg counter flag selection (FW) */
+#define DQ_UCM_ETH_PMD_TX_ARM_CMD (1 << DQ_UCM_AGG_FLG_SHIFT_CF4)
+#define DQ_UCM_ETH_PMD_RX_ARM_CMD (1 << DQ_UCM_AGG_FLG_SHIFT_CF5)
+
+#define DQ_REGION_SHIFT (12)
+
+/* DPM */
+#define DQ_DPM_WQE_BUFF_SIZE (320)
+
+/* Conn type ranges */
+#define DQ_CONN_TYPE_RANGE_SHIFT (4)
/*****************/
/* QM CONSTANTS */
@@ -282,8 +334,6 @@
(PXP_EXTERNAL_BAR_GLOBAL_WINDOW_START + \
PXP_EXTERNAL_BAR_GLOBAL_WINDOW_LENGTH - 1)
-#define PXP_ILT_PAGE_SIZE_NUM_BITS_MIN 12
-#define PXP_ILT_BLOCK_FACTOR_MULTIPLIER 1024
#define PXP_VF_BAR0_START_IGU 0
#define PXP_VF_BAR0_IGU_LENGTH 0x3000
@@ -342,6 +392,9 @@
#define PXP_VF_BAR0_GRC_WINDOW_LENGTH 32
+#define PXP_ILT_PAGE_SIZE_NUM_BITS_MIN 12
+#define PXP_ILT_BLOCK_FACTOR_MULTIPLIER 1024
+
/* ILT Records */
#define PXP_NUM_ILT_RECORDS_BB 7600
#define PXP_NUM_ILT_RECORDS_K2 11000
@@ -379,6 +432,38 @@ struct async_data {
u8 fw_debug_param;
};
+struct coalescing_timeset {
+ u8 value;
+#define COALESCING_TIMESET_TIMESET_MASK 0x7F
+#define COALESCING_TIMESET_TIMESET_SHIFT 0
+#define COALESCING_TIMESET_VALID_MASK 0x1
+#define COALESCING_TIMESET_VALID_SHIFT 7
+};
+
+struct common_prs_pf_msg_info {
+ __le32 value;
+#define COMMON_PRS_PF_MSG_INFO_NPAR_DEFAULT_PF_MASK 0x1
+#define COMMON_PRS_PF_MSG_INFO_NPAR_DEFAULT_PF_SHIFT 0
+#define COMMON_PRS_PF_MSG_INFO_FW_DEBUG_1_MASK 0x1
+#define COMMON_PRS_PF_MSG_INFO_FW_DEBUG_1_SHIFT 1
+#define COMMON_PRS_PF_MSG_INFO_FW_DEBUG_2_MASK 0x1
+#define COMMON_PRS_PF_MSG_INFO_FW_DEBUG_2_SHIFT 2
+#define COMMON_PRS_PF_MSG_INFO_FW_DEBUG_3_MASK 0x1
+#define COMMON_PRS_PF_MSG_INFO_FW_DEBUG_3_SHIFT 3
+#define COMMON_PRS_PF_MSG_INFO_RESERVED_MASK 0xFFFFFFF
+#define COMMON_PRS_PF_MSG_INFO_RESERVED_SHIFT 4
+};
+
+struct common_queue_zone {
+ __le16 ring_drv_data_consumer;
+ __le16 reserved;
+};
+
+struct eth_rx_prod_data {
+ __le16 bd_prod;
+ __le16 cqe_prod;
+};
+
struct regpair {
__le32 lo;
__le32 hi;
@@ -388,11 +473,23 @@ struct vf_pf_channel_eqe_data {
struct regpair msg_addr;
};
+struct malicious_vf_eqe_data {
+ u8 vf_id;
+ u8 err_id;
+ __le16 reserved[3];
+};
+
+struct initial_cleanup_eqe_data {
+ u8 vf_id;
+ u8 reserved[7];
+};
+
/* Event Data Union */
union event_ring_data {
- u8 bytes[8];
- struct vf_pf_channel_eqe_data vf_pf_channel;
- struct async_data async_info;
+ u8 bytes[8];
+ struct vf_pf_channel_eqe_data vf_pf_channel;
+ struct malicious_vf_eqe_data malicious_vf;
+ struct initial_cleanup_eqe_data vf_init_cleanup;
};
/* Event Ring Entry */
@@ -420,9 +517,9 @@ enum mf_mode {
/* Per-protocol connection types */
enum protocol_type {
- PROTOCOLID_RESERVED1,
+ PROTOCOLID_ISCSI,
PROTOCOLID_RESERVED2,
- PROTOCOLID_RESERVED3,
+ PROTOCOLID_ROCE,
PROTOCOLID_CORE,
PROTOCOLID_ETH,
PROTOCOLID_RESERVED4,
@@ -433,6 +530,16 @@ enum protocol_type {
MAX_PROTOCOL_TYPE
};
+struct ustorm_eth_queue_zone {
+ struct coalescing_timeset int_coalescing_timeset;
+ u8 reserved[3];
+};
+
+struct ustorm_queue_zone {
+ struct ustorm_eth_queue_zone eth;
+ struct common_queue_zone common;
+};
+
/* status block structure */
struct cau_pi_entry {
u32 prod;
@@ -588,7 +695,10 @@ struct parsing_and_err_flags {
#define PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMERROR_SHIFT 15
};
-/* Concrete Function ID. */
+struct pb_context {
+ __le32 crc[4];
+};
+
struct pxp_concrete_fid {
__le16 fid;
#define PXP_CONCRETE_FID_PFID_MASK 0xF
@@ -655,6 +765,72 @@ struct pxp_ptt_entry {
};
/* RSS hash type */
+struct rdif_task_context {
+ __le32 initial_ref_tag;
+ __le16 app_tag_value;
+ __le16 app_tag_mask;
+ u8 flags0;
+#define RDIF_TASK_CONTEXT_IGNOREAPPTAG_MASK 0x1
+#define RDIF_TASK_CONTEXT_IGNOREAPPTAG_SHIFT 0
+#define RDIF_TASK_CONTEXT_INITIALREFTAGVALID_MASK 0x1
+#define RDIF_TASK_CONTEXT_INITIALREFTAGVALID_SHIFT 1
+#define RDIF_TASK_CONTEXT_HOSTGUARDTYPE_MASK 0x1
+#define RDIF_TASK_CONTEXT_HOSTGUARDTYPE_SHIFT 2
+#define RDIF_TASK_CONTEXT_SETERRORWITHEOP_MASK 0x1
+#define RDIF_TASK_CONTEXT_SETERRORWITHEOP_SHIFT 3
+#define RDIF_TASK_CONTEXT_PROTECTIONTYPE_MASK 0x3
+#define RDIF_TASK_CONTEXT_PROTECTIONTYPE_SHIFT 4
+#define RDIF_TASK_CONTEXT_CRC_SEED_MASK 0x1
+#define RDIF_TASK_CONTEXT_CRC_SEED_SHIFT 6
+#define RDIF_TASK_CONTEXT_KEEPREFTAGCONST_MASK 0x1
+#define RDIF_TASK_CONTEXT_KEEPREFTAGCONST_SHIFT 7
+ u8 partial_dif_data[7];
+ __le16 partial_crc_value;
+ __le16 partial_checksum_value;
+ __le32 offset_in_io;
+ __le16 flags1;
+#define RDIF_TASK_CONTEXT_VALIDATEGUARD_MASK 0x1
+#define RDIF_TASK_CONTEXT_VALIDATEGUARD_SHIFT 0
+#define RDIF_TASK_CONTEXT_VALIDATEAPPTAG_MASK 0x1
+#define RDIF_TASK_CONTEXT_VALIDATEAPPTAG_SHIFT 1
+#define RDIF_TASK_CONTEXT_VALIDATEREFTAG_MASK 0x1
+#define RDIF_TASK_CONTEXT_VALIDATEREFTAG_SHIFT 2
+#define RDIF_TASK_CONTEXT_FORWARDGUARD_MASK 0x1
+#define RDIF_TASK_CONTEXT_FORWARDGUARD_SHIFT 3
+#define RDIF_TASK_CONTEXT_FORWARDAPPTAG_MASK 0x1
+#define RDIF_TASK_CONTEXT_FORWARDAPPTAG_SHIFT 4
+#define RDIF_TASK_CONTEXT_FORWARDREFTAG_MASK 0x1
+#define RDIF_TASK_CONTEXT_FORWARDREFTAG_SHIFT 5
+#define RDIF_TASK_CONTEXT_INTERVALSIZE_MASK 0x7
+#define RDIF_TASK_CONTEXT_INTERVALSIZE_SHIFT 6
+#define RDIF_TASK_CONTEXT_HOSTINTERFACE_MASK 0x3
+#define RDIF_TASK_CONTEXT_HOSTINTERFACE_SHIFT 9
+#define RDIF_TASK_CONTEXT_DIFBEFOREDATA_MASK 0x1
+#define RDIF_TASK_CONTEXT_DIFBEFOREDATA_SHIFT 11
+#define RDIF_TASK_CONTEXT_RESERVED0_MASK 0x1
+#define RDIF_TASK_CONTEXT_RESERVED0_SHIFT 12
+#define RDIF_TASK_CONTEXT_NETWORKINTERFACE_MASK 0x1
+#define RDIF_TASK_CONTEXT_NETWORKINTERFACE_SHIFT 13
+#define RDIF_TASK_CONTEXT_FORWARDAPPTAGWITHMASK_MASK 0x1
+#define RDIF_TASK_CONTEXT_FORWARDAPPTAGWITHMASK_SHIFT 14
+#define RDIF_TASK_CONTEXT_FORWARDREFTAGWITHMASK_MASK 0x1
+#define RDIF_TASK_CONTEXT_FORWARDREFTAGWITHMASK_SHIFT 15
+ __le16 state;
+#define RDIF_TASK_CONTEXT_RECEIVEDDIFBYTESLEFT_MASK 0xF
+#define RDIF_TASK_CONTEXT_RECEIVEDDIFBYTESLEFT_SHIFT 0
+#define RDIF_TASK_CONTEXT_TRANSMITEDDIFBYTESLEFT_MASK 0xF
+#define RDIF_TASK_CONTEXT_TRANSMITEDDIFBYTESLEFT_SHIFT 4
+#define RDIF_TASK_CONTEXT_ERRORINIO_MASK 0x1
+#define RDIF_TASK_CONTEXT_ERRORINIO_SHIFT 8
+#define RDIF_TASK_CONTEXT_CHECKSUMOVERFLOW_MASK 0x1
+#define RDIF_TASK_CONTEXT_CHECKSUMOVERFLOW_SHIFT 9
+#define RDIF_TASK_CONTEXT_REFTAGMASK_MASK 0xF
+#define RDIF_TASK_CONTEXT_REFTAGMASK_SHIFT 10
+#define RDIF_TASK_CONTEXT_RESERVED1_MASK 0x3
+#define RDIF_TASK_CONTEXT_RESERVED1_SHIFT 14
+ __le32 reserved2;
+};
+
enum rss_hash_type {
RSS_HASH_TYPE_DEFAULT = 0,
RSS_HASH_TYPE_IPV4 = 1,
@@ -683,19 +859,122 @@ struct status_block {
#define STATUS_BLOCK_ZERO_PAD3_SHIFT 24
};
-struct tunnel_parsing_flags {
- u8 flags;
-#define TUNNEL_PARSING_FLAGS_TYPE_MASK 0x3
-#define TUNNEL_PARSING_FLAGS_TYPE_SHIFT 0
-#define TUNNEL_PARSING_FLAGS_TENNANT_ID_EXIST_MASK 0x1
-#define TUNNEL_PARSING_FLAGS_TENNANT_ID_EXIST_SHIFT 2
-#define TUNNEL_PARSING_FLAGS_NEXT_PROTOCOL_MASK 0x3
-#define TUNNEL_PARSING_FLAGS_NEXT_PROTOCOL_SHIFT 3
-#define TUNNEL_PARSING_FLAGS_FIRSTHDRIPMATCH_MASK 0x1
-#define TUNNEL_PARSING_FLAGS_FIRSTHDRIPMATCH_SHIFT 5
-#define TUNNEL_PARSING_FLAGS_IPV4_FRAGMENT_MASK 0x1
-#define TUNNEL_PARSING_FLAGS_IPV4_FRAGMENT_SHIFT 6
-#define TUNNEL_PARSING_FLAGS_IPV4_OPTIONS_MASK 0x1
-#define TUNNEL_PARSING_FLAGS_IPV4_OPTIONS_SHIFT 7
+struct tdif_task_context {
+ __le32 initial_ref_tag;
+ __le16 app_tag_value;
+ __le16 app_tag_mask;
+ __le16 partial_crc_valueB;
+ __le16 partial_checksum_valueB;
+ __le16 stateB;
+#define TDIF_TASK_CONTEXT_RECEIVEDDIFBYTESLEFTB_MASK 0xF
+#define TDIF_TASK_CONTEXT_RECEIVEDDIFBYTESLEFTB_SHIFT 0
+#define TDIF_TASK_CONTEXT_TRANSMITEDDIFBYTESLEFTB_MASK 0xF
+#define TDIF_TASK_CONTEXT_TRANSMITEDDIFBYTESLEFTB_SHIFT 4
+#define TDIF_TASK_CONTEXT_ERRORINIOB_MASK 0x1
+#define TDIF_TASK_CONTEXT_ERRORINIOB_SHIFT 8
+#define TDIF_TASK_CONTEXT_CHECKSUMOVERFLOW_MASK 0x1
+#define TDIF_TASK_CONTEXT_CHECKSUMOVERFLOW_SHIFT 9
+#define TDIF_TASK_CONTEXT_RESERVED0_MASK 0x3F
+#define TDIF_TASK_CONTEXT_RESERVED0_SHIFT 10
+ u8 reserved1;
+ u8 flags0;
+#define TDIF_TASK_CONTEXT_IGNOREAPPTAG_MASK 0x1
+#define TDIF_TASK_CONTEXT_IGNOREAPPTAG_SHIFT 0
+#define TDIF_TASK_CONTEXT_INITIALREFTAGVALID_MASK 0x1
+#define TDIF_TASK_CONTEXT_INITIALREFTAGVALID_SHIFT 1
+#define TDIF_TASK_CONTEXT_HOSTGUARDTYPE_MASK 0x1
+#define TDIF_TASK_CONTEXT_HOSTGUARDTYPE_SHIFT 2
+#define TDIF_TASK_CONTEXT_SETERRORWITHEOP_MASK 0x1
+#define TDIF_TASK_CONTEXT_SETERRORWITHEOP_SHIFT 3
+#define TDIF_TASK_CONTEXT_PROTECTIONTYPE_MASK 0x3
+#define TDIF_TASK_CONTEXT_PROTECTIONTYPE_SHIFT 4
+#define TDIF_TASK_CONTEXT_CRC_SEED_MASK 0x1
+#define TDIF_TASK_CONTEXT_CRC_SEED_SHIFT 6
+#define TDIF_TASK_CONTEXT_RESERVED2_MASK 0x1
+#define TDIF_TASK_CONTEXT_RESERVED2_SHIFT 7
+ __le32 flags1;
+#define TDIF_TASK_CONTEXT_VALIDATEGUARD_MASK 0x1
+#define TDIF_TASK_CONTEXT_VALIDATEGUARD_SHIFT 0
+#define TDIF_TASK_CONTEXT_VALIDATEAPPTAG_MASK 0x1
+#define TDIF_TASK_CONTEXT_VALIDATEAPPTAG_SHIFT 1
+#define TDIF_TASK_CONTEXT_VALIDATEREFTAG_MASK 0x1
+#define TDIF_TASK_CONTEXT_VALIDATEREFTAG_SHIFT 2
+#define TDIF_TASK_CONTEXT_FORWARDGUARD_MASK 0x1
+#define TDIF_TASK_CONTEXT_FORWARDGUARD_SHIFT 3
+#define TDIF_TASK_CONTEXT_FORWARDAPPTAG_MASK 0x1
+#define TDIF_TASK_CONTEXT_FORWARDAPPTAG_SHIFT 4
+#define TDIF_TASK_CONTEXT_FORWARDREFTAG_MASK 0x1
+#define TDIF_TASK_CONTEXT_FORWARDREFTAG_SHIFT 5
+#define TDIF_TASK_CONTEXT_INTERVALSIZE_MASK 0x7
+#define TDIF_TASK_CONTEXT_INTERVALSIZE_SHIFT 6
+#define TDIF_TASK_CONTEXT_HOSTINTERFACE_MASK 0x3
+#define TDIF_TASK_CONTEXT_HOSTINTERFACE_SHIFT 9
+#define TDIF_TASK_CONTEXT_DIFBEFOREDATA_MASK 0x1
+#define TDIF_TASK_CONTEXT_DIFBEFOREDATA_SHIFT 11
+#define TDIF_TASK_CONTEXT_RESERVED3_MASK 0x1
+#define TDIF_TASK_CONTEXT_RESERVED3_SHIFT 12
+#define TDIF_TASK_CONTEXT_NETWORKINTERFACE_MASK 0x1
+#define TDIF_TASK_CONTEXT_NETWORKINTERFACE_SHIFT 13
+#define TDIF_TASK_CONTEXT_RECEIVEDDIFBYTESLEFTA_MASK 0xF
+#define TDIF_TASK_CONTEXT_RECEIVEDDIFBYTESLEFTA_SHIFT 14
+#define TDIF_TASK_CONTEXT_TRANSMITEDDIFBYTESLEFTA_MASK 0xF
+#define TDIF_TASK_CONTEXT_TRANSMITEDDIFBYTESLEFTA_SHIFT 18
+#define TDIF_TASK_CONTEXT_ERRORINIOA_MASK 0x1
+#define TDIF_TASK_CONTEXT_ERRORINIOA_SHIFT 22
+#define TDIF_TASK_CONTEXT_CHECKSUMOVERFLOWA_MASK 0x1
+#define TDIF_TASK_CONTEXT_CHECKSUMOVERFLOWA_SHIFT 23
+#define TDIF_TASK_CONTEXT_REFTAGMASK_MASK 0xF
+#define TDIF_TASK_CONTEXT_REFTAGMASK_SHIFT 24
+#define TDIF_TASK_CONTEXT_FORWARDAPPTAGWITHMASK_MASK 0x1
+#define TDIF_TASK_CONTEXT_FORWARDAPPTAGWITHMASK_SHIFT 28
+#define TDIF_TASK_CONTEXT_FORWARDREFTAGWITHMASK_MASK 0x1
+#define TDIF_TASK_CONTEXT_FORWARDREFTAGWITHMASK_SHIFT 29
+#define TDIF_TASK_CONTEXT_KEEPREFTAGCONST_MASK 0x1
+#define TDIF_TASK_CONTEXT_KEEPREFTAGCONST_SHIFT 30
+#define TDIF_TASK_CONTEXT_RESERVED4_MASK 0x1
+#define TDIF_TASK_CONTEXT_RESERVED4_SHIFT 31
+ __le32 offset_in_iob;
+ __le16 partial_crc_value_a;
+ __le16 partial_checksum_valuea_;
+ __le32 offset_in_ioa;
+ u8 partial_dif_data_a[8];
+ u8 partial_dif_data_b[8];
+};
+
+struct timers_context {
+ __le32 logical_client0;
+#define TIMERS_CONTEXT_EXPIRATIONTIMELC0_MASK 0xFFFFFFF
+#define TIMERS_CONTEXT_EXPIRATIONTIMELC0_SHIFT 0
+#define TIMERS_CONTEXT_VALIDLC0_MASK 0x1
+#define TIMERS_CONTEXT_VALIDLC0_SHIFT 28
+#define TIMERS_CONTEXT_ACTIVELC0_MASK 0x1
+#define TIMERS_CONTEXT_ACTIVELC0_SHIFT 29
+#define TIMERS_CONTEXT_RESERVED0_MASK 0x3
+#define TIMERS_CONTEXT_RESERVED0_SHIFT 30
+ __le32 logical_client1;
+#define TIMERS_CONTEXT_EXPIRATIONTIMELC1_MASK 0xFFFFFFF
+#define TIMERS_CONTEXT_EXPIRATIONTIMELC1_SHIFT 0
+#define TIMERS_CONTEXT_VALIDLC1_MASK 0x1
+#define TIMERS_CONTEXT_VALIDLC1_SHIFT 28
+#define TIMERS_CONTEXT_ACTIVELC1_MASK 0x1
+#define TIMERS_CONTEXT_ACTIVELC1_SHIFT 29
+#define TIMERS_CONTEXT_RESERVED1_MASK 0x3
+#define TIMERS_CONTEXT_RESERVED1_SHIFT 30
+ __le32 logical_client2;
+#define TIMERS_CONTEXT_EXPIRATIONTIMELC2_MASK 0xFFFFFFF
+#define TIMERS_CONTEXT_EXPIRATIONTIMELC2_SHIFT 0
+#define TIMERS_CONTEXT_VALIDLC2_MASK 0x1
+#define TIMERS_CONTEXT_VALIDLC2_SHIFT 28
+#define TIMERS_CONTEXT_ACTIVELC2_MASK 0x1
+#define TIMERS_CONTEXT_ACTIVELC2_SHIFT 29
+#define TIMERS_CONTEXT_RESERVED2_MASK 0x3
+#define TIMERS_CONTEXT_RESERVED2_SHIFT 30
+ __le32 host_expiration_fields;
+#define TIMERS_CONTEXT_HOSTEXPRIRATIONVALUE_MASK 0xFFFFFFF
+#define TIMERS_CONTEXT_HOSTEXPRIRATIONVALUE_SHIFT 0
+#define TIMERS_CONTEXT_HOSTEXPRIRATIONVALID_MASK 0x1
+#define TIMERS_CONTEXT_HOSTEXPRIRATIONVALID_SHIFT 28
+#define TIMERS_CONTEXT_RESERVED3_MASK 0x7
+#define TIMERS_CONTEXT_RESERVED3_SHIFT 29
};
#endif /* __COMMON_HSI__ */
diff --git a/include/linux/qed/eth_common.h b/include/linux/qed/eth_common.h
index 092cb0c1afcb..b5ebc697d05f 100644
--- a/include/linux/qed/eth_common.h
+++ b/include/linux/qed/eth_common.h
@@ -12,6 +12,8 @@
/********************/
/* ETH FW CONSTANTS */
/********************/
+#define ETH_HSI_VER_MAJOR 3
+#define ETH_HSI_VER_MINOR 0
#define ETH_CACHE_LINE_SIZE 64
#define ETH_MAX_RAMROD_PER_CON 8
@@ -57,19 +59,6 @@
#define ETH_TPA_CQE_CONT_LEN_LIST_SIZE 6
#define ETH_TPA_CQE_END_LEN_LIST_SIZE 4
-/* Queue Zone sizes */
-#define TSTORM_QZONE_SIZE 0
-#define MSTORM_QZONE_SIZE sizeof(struct mstorm_eth_queue_zone)
-#define USTORM_QZONE_SIZE sizeof(struct ustorm_eth_queue_zone)
-#define XSTORM_QZONE_SIZE 0
-#define YSTORM_QZONE_SIZE sizeof(struct ystorm_eth_queue_zone)
-#define PSTORM_QZONE_SIZE 0
-
-/* Interrupt coalescing TimeSet */
-struct coalescing_timeset {
- u8 timeset;
- u8 valid;
-};
struct eth_tx_1st_bd_flags {
u8 bitfields;
@@ -97,12 +86,12 @@ struct eth_tx_data_1st_bd {
u8 nbds;
struct eth_tx_1st_bd_flags bd_flags;
__le16 bitfields;
-#define ETH_TX_DATA_1ST_BD_TUNN_CFG_OVERRIDE_MASK 0x1
-#define ETH_TX_DATA_1ST_BD_TUNN_CFG_OVERRIDE_SHIFT 0
+#define ETH_TX_DATA_1ST_BD_TUNN_FLAG_MASK 0x1
+#define ETH_TX_DATA_1ST_BD_TUNN_FLAG_SHIFT 0
#define ETH_TX_DATA_1ST_BD_RESERVED0_MASK 0x1
#define ETH_TX_DATA_1ST_BD_RESERVED0_SHIFT 1
-#define ETH_TX_DATA_1ST_BD_FW_USE_ONLY_MASK 0x3FFF
-#define ETH_TX_DATA_1ST_BD_FW_USE_ONLY_SHIFT 2
+#define ETH_TX_DATA_1ST_BD_PKT_LEN_MASK 0x3FFF
+#define ETH_TX_DATA_1ST_BD_PKT_LEN_SHIFT 2
};
/* The parsing information data for the second tx bd of a given packet. */
@@ -136,28 +125,51 @@ struct eth_tx_data_2nd_bd {
#define ETH_TX_DATA_2ND_BD_RESERVED0_SHIFT 13
};
+struct eth_fast_path_cqe_fw_debug {
+ u8 reserved0;
+ u8 reserved1;
+ __le16 reserved2;
+};
+
+/* tunneling parsing flags */
+struct eth_tunnel_parsing_flags {
+ u8 flags;
+#define ETH_TUNNEL_PARSING_FLAGS_TYPE_MASK 0x3
+#define ETH_TUNNEL_PARSING_FLAGS_TYPE_SHIFT 0
+#define ETH_TUNNEL_PARSING_FLAGS_TENNANT_ID_EXIST_MASK 0x1
+#define ETH_TUNNEL_PARSING_FLAGS_TENNANT_ID_EXIST_SHIFT 2
+#define ETH_TUNNEL_PARSING_FLAGS_NEXT_PROTOCOL_MASK 0x3
+#define ETH_TUNNEL_PARSING_FLAGS_NEXT_PROTOCOL_SHIFT 3
+#define ETH_TUNNEL_PARSING_FLAGS_FIRSTHDRIPMATCH_MASK 0x1
+#define ETH_TUNNEL_PARSING_FLAGS_FIRSTHDRIPMATCH_SHIFT 5
+#define ETH_TUNNEL_PARSING_FLAGS_IPV4_FRAGMENT_MASK 0x1
+#define ETH_TUNNEL_PARSING_FLAGS_IPV4_FRAGMENT_SHIFT 6
+#define ETH_TUNNEL_PARSING_FLAGS_IPV4_OPTIONS_MASK 0x1
+#define ETH_TUNNEL_PARSING_FLAGS_IPV4_OPTIONS_SHIFT 7
+};
+
/* Regular ETH Rx FP CQE. */
struct eth_fast_path_rx_reg_cqe {
- u8 type;
- u8 bitfields;
+ u8 type;
+ u8 bitfields;
#define ETH_FAST_PATH_RX_REG_CQE_RSS_HASH_TYPE_MASK 0x7
#define ETH_FAST_PATH_RX_REG_CQE_RSS_HASH_TYPE_SHIFT 0
#define ETH_FAST_PATH_RX_REG_CQE_TC_MASK 0xF
#define ETH_FAST_PATH_RX_REG_CQE_TC_SHIFT 3
#define ETH_FAST_PATH_RX_REG_CQE_RESERVED0_MASK 0x1
#define ETH_FAST_PATH_RX_REG_CQE_RESERVED0_SHIFT 7
- __le16 pkt_len;
- struct parsing_and_err_flags pars_flags;
- __le16 vlan_tag;
- __le32 rss_hash;
- __le16 len_on_first_bd;
- u8 placement_offset;
- struct tunnel_parsing_flags tunnel_pars_flags;
- u8 bd_num;
- u8 reserved[7];
- u32 fw_debug;
- u8 reserved1[3];
- u8 flags;
+ __le16 pkt_len;
+ struct parsing_and_err_flags pars_flags;
+ __le16 vlan_tag;
+ __le32 rss_hash;
+ __le16 len_on_first_bd;
+ u8 placement_offset;
+ struct eth_tunnel_parsing_flags tunnel_pars_flags;
+ u8 bd_num;
+ u8 reserved[7];
+ struct eth_fast_path_cqe_fw_debug fw_debug;
+ u8 reserved1[3];
+ u8 flags;
#define ETH_FAST_PATH_RX_REG_CQE_VALID_MASK 0x1
#define ETH_FAST_PATH_RX_REG_CQE_VALID_SHIFT 0
#define ETH_FAST_PATH_RX_REG_CQE_VALID_TOGGLE_MASK 0x1
@@ -207,11 +219,11 @@ struct eth_fast_path_rx_tpa_start_cqe {
__le32 rss_hash;
__le16 len_on_first_bd;
u8 placement_offset;
- struct tunnel_parsing_flags tunnel_pars_flags;
+ struct eth_tunnel_parsing_flags tunnel_pars_flags;
u8 tpa_agg_index;
u8 header_len;
__le16 ext_bd_len_list[ETH_TPA_CQE_START_LEN_LIST_SIZE];
- u32 fw_debug;
+ struct eth_fast_path_cqe_fw_debug fw_debug;
};
/* The L4 pseudo checksum mode for Ethernet */
@@ -264,12 +276,25 @@ enum eth_rx_cqe_type {
MAX_ETH_RX_CQE_TYPE
};
-/* ETH Rx producers data */
-struct eth_rx_prod_data {
- __le16 bd_prod;
- __le16 cqe_prod;
- __le16 reserved;
- __le16 reserved1;
+enum eth_rx_tunn_type {
+ ETH_RX_NO_TUNN,
+ ETH_RX_TUNN_GENEVE,
+ ETH_RX_TUNN_GRE,
+ ETH_RX_TUNN_VXLAN,
+ MAX_ETH_RX_TUNN_TYPE
+};
+
+/* Aggregation end reason. */
+enum eth_tpa_end_reason {
+ ETH_AGG_END_UNUSED,
+ ETH_AGG_END_SP_UPDATE,
+ ETH_AGG_END_MAX_LEN,
+ ETH_AGG_END_LAST_SEG,
+ ETH_AGG_END_TIMEOUT,
+ ETH_AGG_END_NOT_CONSISTENT,
+ ETH_AGG_END_OUT_OF_ORDER,
+ ETH_AGG_END_NON_TPA_SEG,
+ MAX_ETH_TPA_END_REASON
};
/* The first tx bd of a given packet */
@@ -337,21 +362,18 @@ union eth_tx_bd_types {
};
/* Mstorm Queue Zone */
-struct mstorm_eth_queue_zone {
- struct eth_rx_prod_data rx_producers;
- __le32 reserved[2];
-};
-
-/* Ustorm Queue Zone */
-struct ustorm_eth_queue_zone {
- struct coalescing_timeset int_coalescing_timeset;
- __le16 reserved[3];
+enum eth_tx_tunn_type {
+ ETH_TX_TUNN_GENEVE,
+ ETH_TX_TUNN_TTAG,
+ ETH_TX_TUNN_GRE,
+ ETH_TX_TUNN_VXLAN,
+ MAX_ETH_TX_TUNN_TYPE
};
/* Ystorm Queue Zone */
-struct ystorm_eth_queue_zone {
- struct coalescing_timeset int_coalescing_timeset;
- __le16 reserved[3];
+struct xstorm_eth_queue_zone {
+ struct coalescing_timeset int_coalescing_timeset;
+ u8 reserved[7];
};
/* ETH doorbell data */
diff --git a/include/linux/qed/iscsi_common.h b/include/linux/qed/iscsi_common.h
new file mode 100644
index 000000000000..b3c0feb15ae9
--- /dev/null
+++ b/include/linux/qed/iscsi_common.h
@@ -0,0 +1,1439 @@
+/* QLogic qed NIC Driver
+ * Copyright (c) 2015 QLogic Corporation
+ *
+ * This software is available under the terms of the GNU General Public License
+ * (GPL) Version 2, available from the file COPYING in the main directory of
+ * this source tree.
+ */
+
+#ifndef __ISCSI_COMMON__
+#define __ISCSI_COMMON__
+/**********************/
+/* ISCSI FW CONSTANTS */
+/**********************/
+
+/* iSCSI HSI constants */
+#define ISCSI_DEFAULT_MTU (1500)
+
+/* Current iSCSI HSI version number composed of two fields (16 bit) */
+#define ISCSI_HSI_MAJOR_VERSION (0)
+#define ISCSI_HSI_MINOR_VERSION (0)
+
+/* KWQ (kernel work queue) layer codes */
+#define ISCSI_SLOW_PATH_LAYER_CODE (6)
+
+/* CQE completion status */
+#define ISCSI_EQE_COMPLETION_SUCCESS (0x0)
+#define ISCSI_EQE_RST_CONN_RCVD (0x1)
+
+/* iSCSI parameter defaults */
+#define ISCSI_DEFAULT_HEADER_DIGEST (0)
+#define ISCSI_DEFAULT_DATA_DIGEST (0)
+#define ISCSI_DEFAULT_INITIAL_R2T (1)
+#define ISCSI_DEFAULT_IMMEDIATE_DATA (1)
+#define ISCSI_DEFAULT_MAX_PDU_LENGTH (0x2000)
+#define ISCSI_DEFAULT_FIRST_BURST_LENGTH (0x10000)
+#define ISCSI_DEFAULT_MAX_BURST_LENGTH (0x40000)
+#define ISCSI_DEFAULT_MAX_OUTSTANDING_R2T (1)
+
+/* iSCSI parameter limits */
+#define ISCSI_MIN_VAL_MAX_PDU_LENGTH (0x200)
+#define ISCSI_MAX_VAL_MAX_PDU_LENGTH (0xffffff)
+#define ISCSI_MIN_VAL_BURST_LENGTH (0x200)
+#define ISCSI_MAX_VAL_BURST_LENGTH (0xffffff)
+#define ISCSI_MIN_VAL_MAX_OUTSTANDING_R2T (1)
+#define ISCSI_MAX_VAL_MAX_OUTSTANDING_R2T (0xff)
+
+/* iSCSI reserved params */
+#define ISCSI_ITT_ALL_ONES (0xffffffff)
+#define ISCSI_TTT_ALL_ONES (0xffffffff)
+
+#define ISCSI_OPTION_1_OFF_CHIP_TCP 1
+#define ISCSI_OPTION_2_ON_CHIP_TCP 2
+
+#define ISCSI_INITIATOR_MODE 0
+#define ISCSI_TARGET_MODE 1
+
+/* iSCSI request op codes */
+#define ISCSI_OPCODE_NOP_OUT_NO_IMM (0)
+#define ISCSI_OPCODE_NOP_OUT ( \
+ ISCSI_OPCODE_NOP_OUT_NO_IMM | 0x40)
+#define ISCSI_OPCODE_SCSI_CMD_NO_IMM (1)
+#define ISCSI_OPCODE_SCSI_CMD ( \
+ ISCSI_OPCODE_SCSI_CMD_NO_IMM | 0x40)
+#define ISCSI_OPCODE_TMF_REQUEST_NO_IMM (2)
+#define ISCSI_OPCODE_TMF_REQUEST ( \
+ ISCSI_OPCODE_TMF_REQUEST_NO_IMM | 0x40)
+#define ISCSI_OPCODE_LOGIN_REQUEST_NO_IMM (3)
+#define ISCSI_OPCODE_LOGIN_REQUEST ( \
+ ISCSI_OPCODE_LOGIN_REQUEST_NO_IMM | 0x40)
+#define ISCSI_OPCODE_TEXT_REQUEST_NO_IMM (4)
+#define ISCSI_OPCODE_TEXT_REQUEST ( \
+ ISCSI_OPCODE_TEXT_REQUEST_NO_IMM | 0x40)
+#define ISCSI_OPCODE_DATA_OUT (5)
+#define ISCSI_OPCODE_LOGOUT_REQUEST_NO_IMM (6)
+#define ISCSI_OPCODE_LOGOUT_REQUEST ( \
+ ISCSI_OPCODE_LOGOUT_REQUEST_NO_IMM | 0x40)
+
+/* iSCSI response/messages op codes */
+#define ISCSI_OPCODE_NOP_IN (0x20)
+#define ISCSI_OPCODE_SCSI_RESPONSE (0x21)
+#define ISCSI_OPCODE_TMF_RESPONSE (0x22)
+#define ISCSI_OPCODE_LOGIN_RESPONSE (0x23)
+#define ISCSI_OPCODE_TEXT_RESPONSE (0x24)
+#define ISCSI_OPCODE_DATA_IN (0x25)
+#define ISCSI_OPCODE_LOGOUT_RESPONSE (0x26)
+#define ISCSI_OPCODE_R2T (0x31)
+#define ISCSI_OPCODE_ASYNC_MSG (0x32)
+#define ISCSI_OPCODE_REJECT (0x3f)
+
+/* iSCSI stages */
+#define ISCSI_STAGE_SECURITY_NEGOTIATION (0)
+#define ISCSI_STAGE_LOGIN_OPERATIONAL_NEGOTIATION (1)
+#define ISCSI_STAGE_FULL_FEATURE_PHASE (3)
+
+/* iSCSI CQE errors */
+#define CQE_ERROR_BITMAP_DATA_DIGEST (0x08)
+#define CQE_ERROR_BITMAP_RCV_ON_INVALID_CONN (0x10)
+#define CQE_ERROR_BITMAP_DATA_TRUNCATED (0x20)
+
+struct cqe_error_bitmap {
+ u8 cqe_error_status_bits;
+#define CQE_ERROR_BITMAP_DIF_ERR_BITS_MASK 0x7
+#define CQE_ERROR_BITMAP_DIF_ERR_BITS_SHIFT 0
+#define CQE_ERROR_BITMAP_DATA_DIGEST_ERR_MASK 0x1
+#define CQE_ERROR_BITMAP_DATA_DIGEST_ERR_SHIFT 3
+#define CQE_ERROR_BITMAP_RCV_ON_INVALID_CONN_MASK 0x1
+#define CQE_ERROR_BITMAP_RCV_ON_INVALID_CONN_SHIFT 4
+#define CQE_ERROR_BITMAP_DATA_TRUNCATED_ERR_MASK 0x1
+#define CQE_ERROR_BITMAP_DATA_TRUNCATED_ERR_SHIFT 5
+#define CQE_ERROR_BITMAP_UNDER_RUN_ERR_MASK 0x1
+#define CQE_ERROR_BITMAP_UNDER_RUN_ERR_SHIFT 6
+#define CQE_ERROR_BITMAP_RESERVED2_MASK 0x1
+#define CQE_ERROR_BITMAP_RESERVED2_SHIFT 7
+};
+
+union cqe_error_status {
+ u8 error_status;
+ struct cqe_error_bitmap error_bits;
+};
+
+struct data_hdr {
+ __le32 data[12];
+};
+
+struct iscsi_async_msg_hdr {
+ __le16 reserved0;
+ u8 flags_attr;
+#define ISCSI_ASYNC_MSG_HDR_RSRV_MASK 0x7F
+#define ISCSI_ASYNC_MSG_HDR_RSRV_SHIFT 0
+#define ISCSI_ASYNC_MSG_HDR_CONST1_MASK 0x1
+#define ISCSI_ASYNC_MSG_HDR_CONST1_SHIFT 7
+ u8 opcode;
+ __le32 hdr_second_dword;
+#define ISCSI_ASYNC_MSG_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_ASYNC_MSG_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_ASYNC_MSG_HDR_TOTAL_AHS_LEN_MASK 0xFF
+#define ISCSI_ASYNC_MSG_HDR_TOTAL_AHS_LEN_SHIFT 24
+ struct regpair lun;
+ __le32 all_ones;
+ __le32 reserved1;
+ __le32 stat_sn;
+ __le32 exp_cmd_sn;
+ __le32 max_cmd_sn;
+ __le16 param1_rsrv;
+ u8 async_vcode;
+ u8 async_event;
+ __le16 param3_rsrv;
+ __le16 param2_rsrv;
+ __le32 reserved7;
+};
+
+struct iscsi_sge {
+ struct regpair sge_addr;
+ __le16 sge_len;
+ __le16 reserved0;
+ __le32 reserved1;
+};
+
+struct iscsi_cached_sge_ctx {
+ struct iscsi_sge sge;
+ struct regpair reserved;
+ __le32 dsgl_curr_offset[2];
+};
+
+struct iscsi_cmd_hdr {
+ __le16 reserved1;
+ u8 flags_attr;
+#define ISCSI_CMD_HDR_ATTR_MASK 0x7
+#define ISCSI_CMD_HDR_ATTR_SHIFT 0
+#define ISCSI_CMD_HDR_RSRV_MASK 0x3
+#define ISCSI_CMD_HDR_RSRV_SHIFT 3
+#define ISCSI_CMD_HDR_WRITE_MASK 0x1
+#define ISCSI_CMD_HDR_WRITE_SHIFT 5
+#define ISCSI_CMD_HDR_READ_MASK 0x1
+#define ISCSI_CMD_HDR_READ_SHIFT 6
+#define ISCSI_CMD_HDR_FINAL_MASK 0x1
+#define ISCSI_CMD_HDR_FINAL_SHIFT 7
+ u8 opcode;
+ __le32 hdr_second_dword;
+#define ISCSI_CMD_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_CMD_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_CMD_HDR_TOTAL_AHS_LEN_MASK 0xFF
+#define ISCSI_CMD_HDR_TOTAL_AHS_LEN_SHIFT 24
+ struct regpair lun;
+ __le32 itt;
+ __le32 expected_transfer_length;
+ __le32 cmd_sn;
+ __le32 exp_stat_sn;
+ __le32 cdb[4];
+};
+
+struct iscsi_common_hdr {
+ u8 hdr_status;
+ u8 hdr_response;
+ u8 hdr_flags;
+ u8 hdr_first_byte;
+#define ISCSI_COMMON_HDR_OPCODE_MASK 0x3F
+#define ISCSI_COMMON_HDR_OPCODE_SHIFT 0
+#define ISCSI_COMMON_HDR_IMM_MASK 0x1
+#define ISCSI_COMMON_HDR_IMM_SHIFT 6
+#define ISCSI_COMMON_HDR_RSRV_MASK 0x1
+#define ISCSI_COMMON_HDR_RSRV_SHIFT 7
+ __le32 hdr_second_dword;
+#define ISCSI_COMMON_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_COMMON_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_COMMON_HDR_TOTAL_AHS_LEN_MASK 0xFF
+#define ISCSI_COMMON_HDR_TOTAL_AHS_LEN_SHIFT 24
+ __le32 lun_reserved[4];
+ __le32 data[6];
+};
+
+struct iscsi_conn_offload_params {
+ struct regpair sq_pbl_addr;
+ struct regpair r2tq_pbl_addr;
+ struct regpair xhq_pbl_addr;
+ struct regpair uhq_pbl_addr;
+ __le32 initial_ack;
+ __le16 physical_q0;
+ __le16 physical_q1;
+ u8 flags;
+#define ISCSI_CONN_OFFLOAD_PARAMS_TCP_ON_CHIP_1B_MASK 0x1
+#define ISCSI_CONN_OFFLOAD_PARAMS_TCP_ON_CHIP_1B_SHIFT 0
+#define ISCSI_CONN_OFFLOAD_PARAMS_TARGET_MODE_MASK 0x1
+#define ISCSI_CONN_OFFLOAD_PARAMS_TARGET_MODE_SHIFT 1
+#define ISCSI_CONN_OFFLOAD_PARAMS_RESERVED1_MASK 0x3F
+#define ISCSI_CONN_OFFLOAD_PARAMS_RESERVED1_SHIFT 2
+ u8 pbl_page_size_log;
+ u8 pbe_page_size_log;
+ u8 default_cq;
+ __le32 stat_sn;
+};
+
+struct iscsi_slow_path_hdr {
+ u8 op_code;
+ u8 flags;
+#define ISCSI_SLOW_PATH_HDR_RESERVED0_MASK 0xF
+#define ISCSI_SLOW_PATH_HDR_RESERVED0_SHIFT 0
+#define ISCSI_SLOW_PATH_HDR_LAYER_CODE_MASK 0x7
+#define ISCSI_SLOW_PATH_HDR_LAYER_CODE_SHIFT 4
+#define ISCSI_SLOW_PATH_HDR_RESERVED1_MASK 0x1
+#define ISCSI_SLOW_PATH_HDR_RESERVED1_SHIFT 7
+};
+
+struct iscsi_conn_update_ramrod_params {
+ struct iscsi_slow_path_hdr hdr;
+ __le16 conn_id;
+ __le32 fw_cid;
+ u8 flags;
+#define ISCSI_CONN_UPDATE_RAMROD_PARAMS_HD_EN_MASK 0x1
+#define ISCSI_CONN_UPDATE_RAMROD_PARAMS_HD_EN_SHIFT 0
+#define ISCSI_CONN_UPDATE_RAMROD_PARAMS_DD_EN_MASK 0x1
+#define ISCSI_CONN_UPDATE_RAMROD_PARAMS_DD_EN_SHIFT 1
+#define ISCSI_CONN_UPDATE_RAMROD_PARAMS_INITIAL_R2T_MASK 0x1
+#define ISCSI_CONN_UPDATE_RAMROD_PARAMS_INITIAL_R2T_SHIFT 2
+#define ISCSI_CONN_UPDATE_RAMROD_PARAMS_IMMEDIATE_DATA_MASK 0x1
+#define ISCSI_CONN_UPDATE_RAMROD_PARAMS_IMMEDIATE_DATA_SHIFT 3
+#define ISCSI_CONN_UPDATE_RAMROD_PARAMS_RESERVED1_MASK 0xF
+#define ISCSI_CONN_UPDATE_RAMROD_PARAMS_RESERVED1_SHIFT 4
+ u8 reserved0[3];
+ __le32 max_seq_size;
+ __le32 max_send_pdu_length;
+ __le32 max_recv_pdu_length;
+ __le32 first_seq_length;
+ __le32 exp_stat_sn;
+};
+
+struct iscsi_ext_cdb_cmd_hdr {
+ __le16 reserved1;
+ u8 flags_attr;
+#define ISCSI_EXT_CDB_CMD_HDR_ATTR_MASK 0x7
+#define ISCSI_EXT_CDB_CMD_HDR_ATTR_SHIFT 0
+#define ISCSI_EXT_CDB_CMD_HDR_RSRV_MASK 0x3
+#define ISCSI_EXT_CDB_CMD_HDR_RSRV_SHIFT 3
+#define ISCSI_EXT_CDB_CMD_HDR_WRITE_MASK 0x1
+#define ISCSI_EXT_CDB_CMD_HDR_WRITE_SHIFT 5
+#define ISCSI_EXT_CDB_CMD_HDR_READ_MASK 0x1
+#define ISCSI_EXT_CDB_CMD_HDR_READ_SHIFT 6
+#define ISCSI_EXT_CDB_CMD_HDR_FINAL_MASK 0x1
+#define ISCSI_EXT_CDB_CMD_HDR_FINAL_SHIFT 7
+ u8 opcode;
+ __le32 hdr_second_dword;
+#define ISCSI_EXT_CDB_CMD_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_EXT_CDB_CMD_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_EXT_CDB_CMD_HDR_CDB_SIZE_MASK 0xFF
+#define ISCSI_EXT_CDB_CMD_HDR_CDB_SIZE_SHIFT 24
+ struct regpair lun;
+ __le32 itt;
+ __le32 expected_transfer_length;
+ __le32 cmd_sn;
+ __le32 exp_stat_sn;
+ struct iscsi_sge cdb_sge;
+};
+
+struct iscsi_login_req_hdr {
+ u8 version_min;
+ u8 version_max;
+ u8 flags_attr;
+#define ISCSI_LOGIN_REQ_HDR_NSG_MASK 0x3
+#define ISCSI_LOGIN_REQ_HDR_NSG_SHIFT 0
+#define ISCSI_LOGIN_REQ_HDR_CSG_MASK 0x3
+#define ISCSI_LOGIN_REQ_HDR_CSG_SHIFT 2
+#define ISCSI_LOGIN_REQ_HDR_RSRV_MASK 0x3
+#define ISCSI_LOGIN_REQ_HDR_RSRV_SHIFT 4
+#define ISCSI_LOGIN_REQ_HDR_C_MASK 0x1
+#define ISCSI_LOGIN_REQ_HDR_C_SHIFT 6
+#define ISCSI_LOGIN_REQ_HDR_T_MASK 0x1
+#define ISCSI_LOGIN_REQ_HDR_T_SHIFT 7
+ u8 opcode;
+ __le32 hdr_second_dword;
+#define ISCSI_LOGIN_REQ_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_LOGIN_REQ_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_LOGIN_REQ_HDR_TOTAL_AHS_LEN_MASK 0xFF
+#define ISCSI_LOGIN_REQ_HDR_TOTAL_AHS_LEN_SHIFT 24
+ __le32 isid_TABC;
+ __le16 tsih;
+ __le16 isid_d;
+ __le32 itt;
+ __le16 reserved1;
+ __le16 cid;
+ __le32 cmd_sn;
+ __le32 exp_stat_sn;
+ __le32 reserved2[4];
+};
+
+struct iscsi_logout_req_hdr {
+ __le16 reserved0;
+ u8 reason_code;
+ u8 opcode;
+ __le32 reserved1;
+ __le32 reserved2[2];
+ __le32 itt;
+ __le16 reserved3;
+ __le16 cid;
+ __le32 cmd_sn;
+ __le32 exp_stat_sn;
+ __le32 reserved4[4];
+};
+
+struct iscsi_data_out_hdr {
+ __le16 reserved1;
+ u8 flags_attr;
+#define ISCSI_DATA_OUT_HDR_RSRV_MASK 0x7F
+#define ISCSI_DATA_OUT_HDR_RSRV_SHIFT 0
+#define ISCSI_DATA_OUT_HDR_FINAL_MASK 0x1
+#define ISCSI_DATA_OUT_HDR_FINAL_SHIFT 7
+ u8 opcode;
+ __le32 reserved2;
+ struct regpair lun;
+ __le32 itt;
+ __le32 ttt;
+ __le32 reserved3;
+ __le32 exp_stat_sn;
+ __le32 reserved4;
+ __le32 data_sn;
+ __le32 buffer_offset;
+ __le32 reserved5;
+};
+
+struct iscsi_data_in_hdr {
+ u8 status_rsvd;
+ u8 reserved1;
+ u8 flags;
+#define ISCSI_DATA_IN_HDR_STATUS_MASK 0x1
+#define ISCSI_DATA_IN_HDR_STATUS_SHIFT 0
+#define ISCSI_DATA_IN_HDR_UNDERFLOW_MASK 0x1
+#define ISCSI_DATA_IN_HDR_UNDERFLOW_SHIFT 1
+#define ISCSI_DATA_IN_HDR_OVERFLOW_MASK 0x1
+#define ISCSI_DATA_IN_HDR_OVERFLOW_SHIFT 2
+#define ISCSI_DATA_IN_HDR_RSRV_MASK 0x7
+#define ISCSI_DATA_IN_HDR_RSRV_SHIFT 3
+#define ISCSI_DATA_IN_HDR_ACK_MASK 0x1
+#define ISCSI_DATA_IN_HDR_ACK_SHIFT 6
+#define ISCSI_DATA_IN_HDR_FINAL_MASK 0x1
+#define ISCSI_DATA_IN_HDR_FINAL_SHIFT 7
+ u8 opcode;
+ __le32 reserved2;
+ struct regpair lun;
+ __le32 itt;
+ __le32 ttt;
+ __le32 stat_sn;
+ __le32 exp_cmd_sn;
+ __le32 max_cmd_sn;
+ __le32 data_sn;
+ __le32 buffer_offset;
+ __le32 residual_count;
+};
+
+struct iscsi_r2t_hdr {
+ u8 reserved0[3];
+ u8 opcode;
+ __le32 reserved2;
+ struct regpair lun;
+ __le32 itt;
+ __le32 ttt;
+ __le32 stat_sn;
+ __le32 exp_cmd_sn;
+ __le32 max_cmd_sn;
+ __le32 r2t_sn;
+ __le32 buffer_offset;
+ __le32 desired_data_trns_len;
+};
+
+struct iscsi_nop_out_hdr {
+ __le16 reserved1;
+ u8 flags_attr;
+#define ISCSI_NOP_OUT_HDR_RSRV_MASK 0x7F
+#define ISCSI_NOP_OUT_HDR_RSRV_SHIFT 0
+#define ISCSI_NOP_OUT_HDR_CONST1_MASK 0x1
+#define ISCSI_NOP_OUT_HDR_CONST1_SHIFT 7
+ u8 opcode;
+ __le32 reserved2;
+ struct regpair lun;
+ __le32 itt;
+ __le32 ttt;
+ __le32 cmd_sn;
+ __le32 exp_stat_sn;
+ __le32 reserved3;
+ __le32 reserved4;
+ __le32 reserved5;
+ __le32 reserved6;
+};
+
+struct iscsi_nop_in_hdr {
+ __le16 reserved0;
+ u8 flags_attr;
+#define ISCSI_NOP_IN_HDR_RSRV_MASK 0x7F
+#define ISCSI_NOP_IN_HDR_RSRV_SHIFT 0
+#define ISCSI_NOP_IN_HDR_CONST1_MASK 0x1
+#define ISCSI_NOP_IN_HDR_CONST1_SHIFT 7
+ u8 opcode;
+ __le32 hdr_second_dword;
+#define ISCSI_NOP_IN_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_NOP_IN_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_NOP_IN_HDR_TOTAL_AHS_LEN_MASK 0xFF
+#define ISCSI_NOP_IN_HDR_TOTAL_AHS_LEN_SHIFT 24
+ struct regpair lun;
+ __le32 itt;
+ __le32 ttt;
+ __le32 stat_sn;
+ __le32 exp_cmd_sn;
+ __le32 max_cmd_sn;
+ __le32 reserved5;
+ __le32 reserved6;
+ __le32 reserved7;
+};
+
+struct iscsi_login_response_hdr {
+ u8 version_active;
+ u8 version_max;
+ u8 flags_attr;
+#define ISCSI_LOGIN_RESPONSE_HDR_NSG_MASK 0x3
+#define ISCSI_LOGIN_RESPONSE_HDR_NSG_SHIFT 0
+#define ISCSI_LOGIN_RESPONSE_HDR_CSG_MASK 0x3
+#define ISCSI_LOGIN_RESPONSE_HDR_CSG_SHIFT 2
+#define ISCSI_LOGIN_RESPONSE_HDR_RSRV_MASK 0x3
+#define ISCSI_LOGIN_RESPONSE_HDR_RSRV_SHIFT 4
+#define ISCSI_LOGIN_RESPONSE_HDR_C_MASK 0x1
+#define ISCSI_LOGIN_RESPONSE_HDR_C_SHIFT 6
+#define ISCSI_LOGIN_RESPONSE_HDR_T_MASK 0x1
+#define ISCSI_LOGIN_RESPONSE_HDR_T_SHIFT 7
+ u8 opcode;
+ __le32 hdr_second_dword;
+#define ISCSI_LOGIN_RESPONSE_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_LOGIN_RESPONSE_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_LOGIN_RESPONSE_HDR_TOTAL_AHS_LEN_MASK 0xFF
+#define ISCSI_LOGIN_RESPONSE_HDR_TOTAL_AHS_LEN_SHIFT 24
+ __le32 isid_TABC;
+ __le16 tsih;
+ __le16 isid_d;
+ __le32 itt;
+ __le32 reserved1;
+ __le32 stat_sn;
+ __le32 exp_cmd_sn;
+ __le32 max_cmd_sn;
+ __le16 reserved2;
+ u8 status_detail;
+ u8 status_class;
+ __le32 reserved4[2];
+};
+
+struct iscsi_logout_response_hdr {
+ u8 reserved1;
+ u8 response;
+ u8 flags;
+ u8 opcode;
+ __le32 hdr_second_dword;
+#define ISCSI_LOGOUT_RESPONSE_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_LOGOUT_RESPONSE_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_LOGOUT_RESPONSE_HDR_TOTAL_AHS_LEN_MASK 0xFF
+#define ISCSI_LOGOUT_RESPONSE_HDR_TOTAL_AHS_LEN_SHIFT 24
+ __le32 reserved2[2];
+ __le32 itt;
+ __le32 reserved3;
+ __le32 stat_sn;
+ __le32 exp_cmd_sn;
+ __le32 max_cmd_sn;
+ __le32 reserved4;
+ __le16 time2retain;
+ __le16 time2wait;
+ __le32 reserved5[1];
+};
+
+struct iscsi_text_request_hdr {
+ __le16 reserved0;
+ u8 flags_attr;
+#define ISCSI_TEXT_REQUEST_HDR_RSRV_MASK 0x3F
+#define ISCSI_TEXT_REQUEST_HDR_RSRV_SHIFT 0
+#define ISCSI_TEXT_REQUEST_HDR_C_MASK 0x1
+#define ISCSI_TEXT_REQUEST_HDR_C_SHIFT 6
+#define ISCSI_TEXT_REQUEST_HDR_F_MASK 0x1
+#define ISCSI_TEXT_REQUEST_HDR_F_SHIFT 7
+ u8 opcode;
+ __le32 hdr_second_dword;
+#define ISCSI_TEXT_REQUEST_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_TEXT_REQUEST_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_TEXT_REQUEST_HDR_TOTAL_AHS_LEN_MASK 0xFF
+#define ISCSI_TEXT_REQUEST_HDR_TOTAL_AHS_LEN_SHIFT 24
+ struct regpair lun;
+ __le32 itt;
+ __le32 ttt;
+ __le32 cmd_sn;
+ __le32 exp_stat_sn;
+ __le32 reserved4[4];
+};
+
+struct iscsi_text_response_hdr {
+ __le16 reserved1;
+ u8 flags;
+#define ISCSI_TEXT_RESPONSE_HDR_RSRV_MASK 0x3F
+#define ISCSI_TEXT_RESPONSE_HDR_RSRV_SHIFT 0
+#define ISCSI_TEXT_RESPONSE_HDR_C_MASK 0x1
+#define ISCSI_TEXT_RESPONSE_HDR_C_SHIFT 6
+#define ISCSI_TEXT_RESPONSE_HDR_F_MASK 0x1
+#define ISCSI_TEXT_RESPONSE_HDR_F_SHIFT 7
+ u8 opcode;
+ __le32 hdr_second_dword;
+#define ISCSI_TEXT_RESPONSE_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_TEXT_RESPONSE_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_TEXT_RESPONSE_HDR_TOTAL_AHS_LEN_MASK 0xFF
+#define ISCSI_TEXT_RESPONSE_HDR_TOTAL_AHS_LEN_SHIFT 24
+ struct regpair lun;
+ __le32 itt;
+ __le32 ttt;
+ __le32 stat_sn;
+ __le32 exp_cmd_sn;
+ __le32 max_cmd_sn;
+ __le32 reserved4[3];
+};
+
+struct iscsi_tmf_request_hdr {
+ __le16 reserved0;
+ u8 function;
+ u8 opcode;
+ __le32 hdr_second_dword;
+#define ISCSI_TMF_REQUEST_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_TMF_REQUEST_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_TMF_REQUEST_HDR_TOTAL_AHS_LEN_MASK 0xFF
+#define ISCSI_TMF_REQUEST_HDR_TOTAL_AHS_LEN_SHIFT 24
+ struct regpair lun;
+ __le32 itt;
+ __le32 rtt;
+ __le32 cmd_sn;
+ __le32 exp_stat_sn;
+ __le32 ref_cmd_sn;
+ __le32 exp_data_sn;
+ __le32 reserved4[2];
+};
+
+struct iscsi_tmf_response_hdr {
+ u8 reserved2;
+ u8 hdr_response;
+ u8 hdr_flags;
+ u8 opcode;
+ __le32 hdr_second_dword;
+#define ISCSI_TMF_RESPONSE_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_TMF_RESPONSE_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_TMF_RESPONSE_HDR_TOTAL_AHS_LEN_MASK 0xFF
+#define ISCSI_TMF_RESPONSE_HDR_TOTAL_AHS_LEN_SHIFT 24
+ struct regpair reserved0;
+ __le32 itt;
+ __le32 rtt;
+ __le32 stat_sn;
+ __le32 exp_cmd_sn;
+ __le32 max_cmd_sn;
+ __le32 reserved4[3];
+};
+
+struct iscsi_response_hdr {
+ u8 hdr_status;
+ u8 hdr_response;
+ u8 hdr_flags;
+ u8 opcode;
+ __le32 hdr_second_dword;
+#define ISCSI_RESPONSE_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_RESPONSE_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_RESPONSE_HDR_TOTAL_AHS_LEN_MASK 0xFF
+#define ISCSI_RESPONSE_HDR_TOTAL_AHS_LEN_SHIFT 24
+ struct regpair lun;
+ __le32 itt;
+ __le32 snack_tag;
+ __le32 stat_sn;
+ __le32 exp_cmd_sn;
+ __le32 max_cmd_sn;
+ __le32 exp_data_sn;
+ __le32 bi_residual_count;
+ __le32 residual_count;
+};
+
+struct iscsi_reject_hdr {
+ u8 reserved4;
+ u8 hdr_reason;
+ u8 hdr_flags;
+ u8 opcode;
+ __le32 hdr_second_dword;
+#define ISCSI_REJECT_HDR_DATA_SEG_LEN_MASK 0xFFFFFF
+#define ISCSI_REJECT_HDR_DATA_SEG_LEN_SHIFT 0
+#define ISCSI_REJECT_HDR_TOTAL_AHS_LEN_MASK 0xFF
+#define ISCSI_REJECT_HDR_TOTAL_AHS_LEN_SHIFT 24
+ struct regpair reserved0;
+ __le32 reserved1;
+ __le32 reserved2;
+ __le32 stat_sn;
+ __le32 exp_cmd_sn;
+ __le32 max_cmd_sn;
+ __le32 data_sn;
+ __le32 reserved3[2];
+};
+
+union iscsi_task_hdr {
+ struct iscsi_common_hdr common;
+ struct data_hdr data;
+ struct iscsi_cmd_hdr cmd;
+ struct iscsi_ext_cdb_cmd_hdr ext_cdb_cmd;
+ struct iscsi_login_req_hdr login_req;
+ struct iscsi_logout_req_hdr logout_req;
+ struct iscsi_data_out_hdr data_out;
+ struct iscsi_data_in_hdr data_in;
+ struct iscsi_r2t_hdr r2t;
+ struct iscsi_nop_out_hdr nop_out;
+ struct iscsi_nop_in_hdr nop_in;
+ struct iscsi_login_response_hdr login_response;
+ struct iscsi_logout_response_hdr logout_response;
+ struct iscsi_text_request_hdr text_request;
+ struct iscsi_text_response_hdr text_response;
+ struct iscsi_tmf_request_hdr tmf_request;
+ struct iscsi_tmf_response_hdr tmf_response;
+ struct iscsi_response_hdr response;
+ struct iscsi_reject_hdr reject;
+ struct iscsi_async_msg_hdr async_msg;
+};
+
+struct iscsi_cqe_common {
+ __le16 conn_id;
+ u8 cqe_type;
+ union cqe_error_status error_bitmap;
+ __le32 reserved[3];
+ union iscsi_task_hdr iscsi_hdr;
+};
+
+struct iscsi_cqe_solicited {
+ __le16 conn_id;
+ u8 cqe_type;
+ union cqe_error_status error_bitmap;
+ __le16 itid;
+ u8 task_type;
+ u8 fw_dbg_field;
+ __le32 reserved1[2];
+ union iscsi_task_hdr iscsi_hdr;
+};
+
+struct iscsi_cqe_unsolicited {
+ __le16 conn_id;
+ u8 cqe_type;
+ union cqe_error_status error_bitmap;
+ __le16 reserved0;
+ u8 reserved1;
+ u8 unsol_cqe_type;
+ struct regpair rqe_opaque;
+ union iscsi_task_hdr iscsi_hdr;
+};
+
+union iscsi_cqe {
+ struct iscsi_cqe_common cqe_common;
+ struct iscsi_cqe_solicited cqe_solicited;
+ struct iscsi_cqe_unsolicited cqe_unsolicited;
+};
+
+enum iscsi_cqes_type {
+ ISCSI_CQE_TYPE_SOLICITED = 1,
+ ISCSI_CQE_TYPE_UNSOLICITED,
+ ISCSI_CQE_TYPE_SOLICITED_WITH_SENSE
+ ,
+ ISCSI_CQE_TYPE_TASK_CLEANUP,
+ ISCSI_CQE_TYPE_DUMMY,
+ MAX_ISCSI_CQES_TYPE
+};
+
+enum iscsi_cqe_unsolicited_type {
+ ISCSI_CQE_UNSOLICITED_NONE,
+ ISCSI_CQE_UNSOLICITED_SINGLE,
+ ISCSI_CQE_UNSOLICITED_FIRST,
+ ISCSI_CQE_UNSOLICITED_MIDDLE,
+ ISCSI_CQE_UNSOLICITED_LAST,
+ MAX_ISCSI_CQE_UNSOLICITED_TYPE
+};
+
+struct iscsi_virt_sgl_ctx {
+ struct regpair sgl_base;
+ struct regpair dsgl_base;
+ __le32 sgl_initial_offset;
+ __le32 dsgl_initial_offset;
+ __le32 dsgl_curr_offset[2];
+};
+
+struct iscsi_sgl_var_params {
+ u8 sgl_ptr;
+ u8 dsgl_ptr;
+ __le16 sge_offset;
+ __le16 dsge_offset;
+};
+
+struct iscsi_phys_sgl_ctx {
+ struct regpair sgl_base;
+ struct regpair dsgl_base;
+ u8 sgl_size;
+ u8 dsgl_size;
+ __le16 reserved;
+ struct iscsi_sgl_var_params var_params[2];
+};
+
+union iscsi_data_desc_ctx {
+ struct iscsi_virt_sgl_ctx virt_sgl;
+ struct iscsi_phys_sgl_ctx phys_sgl;
+ struct iscsi_cached_sge_ctx cached_sge;
+};
+
+struct iscsi_debug_modes {
+ u8 flags;
+#define ISCSI_DEBUG_MODES_ASSERT_IF_RX_CONN_ERROR_MASK 0x1
+#define ISCSI_DEBUG_MODES_ASSERT_IF_RX_CONN_ERROR_SHIFT 0
+#define ISCSI_DEBUG_MODES_ASSERT_IF_RECV_RESET_MASK 0x1
+#define ISCSI_DEBUG_MODES_ASSERT_IF_RECV_RESET_SHIFT 1
+#define ISCSI_DEBUG_MODES_ASSERT_IF_RECV_FIN_MASK 0x1
+#define ISCSI_DEBUG_MODES_ASSERT_IF_RECV_FIN_SHIFT 2
+#define ISCSI_DEBUG_MODES_ASSERT_IF_RECV_CLEANUP_MASK 0x1
+#define ISCSI_DEBUG_MODES_ASSERT_IF_RECV_CLEANUP_SHIFT 3
+#define ISCSI_DEBUG_MODES_ASSERT_IF_RECV_REJECT_OR_ASYNC_MASK 0x1
+#define ISCSI_DEBUG_MODES_ASSERT_IF_RECV_REJECT_OR_ASYNC_SHIFT 4
+#define ISCSI_DEBUG_MODES_ASSERT_IF_RECV_NOP_MASK 0x1
+#define ISCSI_DEBUG_MODES_ASSERT_IF_RECV_NOP_SHIFT 5
+#define ISCSI_DEBUG_MODES_RESERVED0_MASK 0x3
+#define ISCSI_DEBUG_MODES_RESERVED0_SHIFT 6
+};
+
+struct iscsi_dif_flags {
+ u8 flags;
+#define ISCSI_DIF_FLAGS_PROT_INTERVAL_SIZE_LOG_MASK 0xF
+#define ISCSI_DIF_FLAGS_PROT_INTERVAL_SIZE_LOG_SHIFT 0
+#define ISCSI_DIF_FLAGS_DIF_TO_PEER_MASK 0x1
+#define ISCSI_DIF_FLAGS_DIF_TO_PEER_SHIFT 4
+#define ISCSI_DIF_FLAGS_HOST_INTERFACE_MASK 0x7
+#define ISCSI_DIF_FLAGS_HOST_INTERFACE_SHIFT 5
+};
+
+enum iscsi_eqe_opcode {
+ ISCSI_EVENT_TYPE_INIT_FUNC = 0,
+ ISCSI_EVENT_TYPE_DESTROY_FUNC,
+ ISCSI_EVENT_TYPE_OFFLOAD_CONN,
+ ISCSI_EVENT_TYPE_UPDATE_CONN,
+ ISCSI_EVENT_TYPE_CLEAR_SQ,
+ ISCSI_EVENT_TYPE_TERMINATE_CONN,
+ ISCSI_EVENT_TYPE_ASYN_CONNECT_COMPLETE,
+ ISCSI_EVENT_TYPE_ASYN_TERMINATE_DONE,
+ RESERVED8,
+ RESERVED9,
+ ISCSI_EVENT_TYPE_START_OF_ERROR_TYPES = 10,
+ ISCSI_EVENT_TYPE_ASYN_ABORT_RCVD,
+ ISCSI_EVENT_TYPE_ASYN_CLOSE_RCVD,
+ ISCSI_EVENT_TYPE_ASYN_SYN_RCVD,
+ ISCSI_EVENT_TYPE_ASYN_MAX_RT_TIME,
+ ISCSI_EVENT_TYPE_ASYN_MAX_RT_CNT,
+ ISCSI_EVENT_TYPE_ASYN_MAX_KA_PROBES_CNT,
+ ISCSI_EVENT_TYPE_ASYN_FIN_WAIT2,
+ ISCSI_EVENT_TYPE_ISCSI_CONN_ERROR,
+ ISCSI_EVENT_TYPE_TCP_CONN_ERROR,
+ ISCSI_EVENT_TYPE_ASYN_DELETE_OOO_ISLES,
+ MAX_ISCSI_EQE_OPCODE
+};
+
+enum iscsi_error_types {
+ ISCSI_STATUS_NONE = 0,
+ ISCSI_CQE_ERROR_UNSOLICITED_RCV_ON_INVALID_CONN = 1,
+ ISCSI_CONN_ERROR_TASK_CID_MISMATCH,
+ ISCSI_CONN_ERROR_TASK_NOT_VALID,
+ ISCSI_CONN_ERROR_RQ_RING_IS_FULL,
+ ISCSI_CONN_ERROR_CMDQ_RING_IS_FULL,
+ ISCSI_CONN_ERROR_HQE_CACHING_FAILED,
+ ISCSI_CONN_ERROR_HEADER_DIGEST_ERROR,
+ ISCSI_CONN_ERROR_LOCAL_COMPLETION_ERROR,
+ ISCSI_CONN_ERROR_DATA_OVERRUN,
+ ISCSI_CONN_ERROR_OUT_OF_SGES_ERROR,
+ ISCSI_CONN_ERROR_TCP_SEG_PROC_URG_ERROR,
+ ISCSI_CONN_ERROR_TCP_SEG_PROC_IP_OPTIONS_ERROR,
+ ISCSI_CONN_ERROR_TCP_SEG_PROC_CONNECT_INVALID_WS_OPTION,
+ ISCSI_CONN_ERROR_TCP_IP_FRAGMENT_ERROR,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_AHS_LEN,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_AHS_TYPE,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_ITT_OUT_OF_RANGE,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_TTT_OUT_OF_RANGE,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_DATA_SEG_LEN_EXCEEDS_PDU_SIZE,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_INVALID_OPCODE,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_INVALID_OPCODE_BEFORE_UPDATE,
+ ISCSI_CONN_ERROR_UNVALID_NOPIN_DSL,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_R2T_CARRIES_NO_DATA,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_DATA_SN,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_DATA_IN_TTT,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_DATA_OUT_ITT,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_R2T_TTT,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_R2T_BUFFER_OFFSET,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_BUFFER_OFFSET_OOO,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_R2T_SN,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_DESIRED_DATA_TRNS_LEN_0,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_DESIRED_DATA_TRNS_LEN_1,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_DESIRED_DATA_TRNS_LEN_2,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_LUN,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_F_BIT_ZERO,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_F_BIT_ZERO_S_BIT_ONE,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_EXP_STAT_SN,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_DSL_NOT_ZERO,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_INVALID_DSL,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_DATA_SEG_LEN_TOO_BIG,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_OUTSTANDING_R2T_COUNT,
+ ISCSI_CONN_ERROR_PROTOCOL_ERR_DIF_TX,
+ ISCSI_CONN_ERROR_SENSE_DATA_LENGTH,
+ ISCSI_CONN_ERROR_DATA_PLACEMENT_ERROR,
+ ISCSI_ERROR_UNKNOWN,
+ MAX_ISCSI_ERROR_TYPES
+};
+
+struct iscsi_mflags {
+ u8 mflags;
+#define ISCSI_MFLAGS_SLOW_IO_MASK 0x1
+#define ISCSI_MFLAGS_SLOW_IO_SHIFT 0
+#define ISCSI_MFLAGS_SINGLE_SGE_MASK 0x1
+#define ISCSI_MFLAGS_SINGLE_SGE_SHIFT 1
+#define ISCSI_MFLAGS_RESERVED_MASK 0x3F
+#define ISCSI_MFLAGS_RESERVED_SHIFT 2
+};
+
+struct iscsi_sgl {
+ struct regpair sgl_addr;
+ __le16 updated_sge_size;
+ __le16 updated_sge_offset;
+ __le32 byte_offset;
+};
+
+union iscsi_mstorm_sgl {
+ struct iscsi_sgl sgl_struct;
+ struct iscsi_sge single_sge;
+};
+
+enum iscsi_ramrod_cmd_id {
+ ISCSI_RAMROD_CMD_ID_UNUSED = 0,
+ ISCSI_RAMROD_CMD_ID_INIT_FUNC = 1,
+ ISCSI_RAMROD_CMD_ID_DESTROY_FUNC = 2,
+ ISCSI_RAMROD_CMD_ID_OFFLOAD_CONN = 3,
+ ISCSI_RAMROD_CMD_ID_UPDATE_CONN = 4,
+ ISCSI_RAMROD_CMD_ID_TERMINATION_CONN = 5,
+ ISCSI_RAMROD_CMD_ID_CLEAR_SQ = 6,
+ MAX_ISCSI_RAMROD_CMD_ID
+};
+
+struct iscsi_reg1 {
+ __le32 reg1_map;
+#define ISCSI_REG1_NUM_FAST_SGES_MASK 0x7
+#define ISCSI_REG1_NUM_FAST_SGES_SHIFT 0
+#define ISCSI_REG1_RESERVED1_MASK 0x1FFFFFFF
+#define ISCSI_REG1_RESERVED1_SHIFT 3
+};
+
+union iscsi_seq_num {
+ __le16 data_sn;
+ __le16 r2t_sn;
+};
+
+struct iscsi_spe_conn_offload {
+ struct iscsi_slow_path_hdr hdr;
+ __le16 conn_id;
+ __le32 fw_cid;
+ struct iscsi_conn_offload_params iscsi;
+ struct tcp_offload_params tcp;
+};
+
+struct iscsi_spe_conn_offload_option2 {
+ struct iscsi_slow_path_hdr hdr;
+ __le16 conn_id;
+ __le32 fw_cid;
+ struct iscsi_conn_offload_params iscsi;
+ struct tcp_offload_params_opt2 tcp;
+};
+
+struct iscsi_spe_conn_termination {
+ struct iscsi_slow_path_hdr hdr;
+ __le16 conn_id;
+ __le32 fw_cid;
+ u8 abortive;
+ u8 reserved0[7];
+ struct regpair queue_cnts_addr;
+ struct regpair query_params_addr;
+};
+
+struct iscsi_spe_func_dstry {
+ struct iscsi_slow_path_hdr hdr;
+ __le16 reserved0;
+ __le32 reserved1;
+};
+
+struct iscsi_spe_func_init {
+ struct iscsi_slow_path_hdr hdr;
+ __le16 half_way_close_timeout;
+ u8 num_sq_pages_in_ring;
+ u8 num_r2tq_pages_in_ring;
+ u8 num_uhq_pages_in_ring;
+ u8 ll2_rx_queue_id;
+ u8 ooo_enable;
+ struct iscsi_debug_modes debug_mode;
+ __le16 reserved1;
+ __le32 reserved2;
+ __le32 reserved3;
+ __le32 reserved4;
+ struct scsi_init_func_params func_params;
+ struct scsi_init_func_queues q_params;
+};
+
+struct ystorm_iscsi_task_state {
+ union iscsi_data_desc_ctx sgl_ctx_union;
+ __le32 buffer_offset[2];
+ __le16 bytes_nxt_dif;
+ __le16 rxmit_bytes_nxt_dif;
+ union iscsi_seq_num seq_num_union;
+ u8 dif_bytes_leftover;
+ u8 rxmit_dif_bytes_leftover;
+ __le16 reuse_count;
+ struct iscsi_dif_flags dif_flags;
+ u8 local_comp;
+ __le32 exp_r2t_sn;
+ __le32 sgl_offset[2];
+};
+
+struct ystorm_iscsi_task_st_ctx {
+ struct ystorm_iscsi_task_state state;
+ union iscsi_task_hdr pdu_hdr;
+};
+
+struct ystorm_iscsi_task_ag_ctx {
+ u8 reserved;
+ u8 byte1;
+ __le16 word0;
+ u8 flags0;
+#define YSTORM_ISCSI_TASK_AG_CTX_NIBBLE0_MASK 0xF
+#define YSTORM_ISCSI_TASK_AG_CTX_NIBBLE0_SHIFT 0
+#define YSTORM_ISCSI_TASK_AG_CTX_BIT0_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_BIT0_SHIFT 4
+#define YSTORM_ISCSI_TASK_AG_CTX_BIT1_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_BIT1_SHIFT 5
+#define YSTORM_ISCSI_TASK_AG_CTX_VALID_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_VALID_SHIFT 6
+#define YSTORM_ISCSI_TASK_AG_CTX_BIT3_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_BIT3_SHIFT 7
+ u8 flags1;
+#define YSTORM_ISCSI_TASK_AG_CTX_CF0_MASK 0x3
+#define YSTORM_ISCSI_TASK_AG_CTX_CF0_SHIFT 0
+#define YSTORM_ISCSI_TASK_AG_CTX_CF1_MASK 0x3
+#define YSTORM_ISCSI_TASK_AG_CTX_CF1_SHIFT 2
+#define YSTORM_ISCSI_TASK_AG_CTX_CF2SPECIAL_MASK 0x3
+#define YSTORM_ISCSI_TASK_AG_CTX_CF2SPECIAL_SHIFT 4
+#define YSTORM_ISCSI_TASK_AG_CTX_CF0EN_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_CF0EN_SHIFT 6
+#define YSTORM_ISCSI_TASK_AG_CTX_CF1EN_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_CF1EN_SHIFT 7
+ u8 flags2;
+#define YSTORM_ISCSI_TASK_AG_CTX_BIT4_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_BIT4_SHIFT 0
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE0EN_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE0EN_SHIFT 1
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE1EN_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE1EN_SHIFT 2
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE2EN_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE2EN_SHIFT 3
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE3EN_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE3EN_SHIFT 4
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE4EN_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE4EN_SHIFT 5
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE5EN_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE5EN_SHIFT 6
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE6EN_MASK 0x1
+#define YSTORM_ISCSI_TASK_AG_CTX_RULE6EN_SHIFT 7
+ u8 byte2;
+ __le32 TTT;
+ u8 byte3;
+ u8 byte4;
+ __le16 word1;
+};
+
+struct mstorm_iscsi_task_ag_ctx {
+ u8 cdu_validation;
+ u8 byte1;
+ __le16 task_cid;
+ u8 flags0;
+#define MSTORM_ISCSI_TASK_AG_CTX_CONNECTION_TYPE_MASK 0xF
+#define MSTORM_ISCSI_TASK_AG_CTX_CONNECTION_TYPE_SHIFT 0
+#define MSTORM_ISCSI_TASK_AG_CTX_EXIST_IN_QM0_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_EXIST_IN_QM0_SHIFT 4
+#define MSTORM_ISCSI_TASK_AG_CTX_BIT1_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_BIT1_SHIFT 5
+#define MSTORM_ISCSI_TASK_AG_CTX_VALID_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_VALID_SHIFT 6
+#define MSTORM_ISCSI_TASK_AG_CTX_TASK_CLEANUP_FLAG_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_TASK_CLEANUP_FLAG_SHIFT 7
+ u8 flags1;
+#define MSTORM_ISCSI_TASK_AG_CTX_TASK_CLEANUP_CF_MASK 0x3
+#define MSTORM_ISCSI_TASK_AG_CTX_TASK_CLEANUP_CF_SHIFT 0
+#define MSTORM_ISCSI_TASK_AG_CTX_CF1_MASK 0x3
+#define MSTORM_ISCSI_TASK_AG_CTX_CF1_SHIFT 2
+#define MSTORM_ISCSI_TASK_AG_CTX_CF2_MASK 0x3
+#define MSTORM_ISCSI_TASK_AG_CTX_CF2_SHIFT 4
+#define MSTORM_ISCSI_TASK_AG_CTX_TASK_CLEANUP_CF_EN_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_TASK_CLEANUP_CF_EN_SHIFT 6
+#define MSTORM_ISCSI_TASK_AG_CTX_CF1EN_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_CF1EN_SHIFT 7
+ u8 flags2;
+#define MSTORM_ISCSI_TASK_AG_CTX_CF2EN_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_CF2EN_SHIFT 0
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE0EN_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE0EN_SHIFT 1
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE1EN_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE1EN_SHIFT 2
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE2EN_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE2EN_SHIFT 3
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE3EN_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE3EN_SHIFT 4
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE4EN_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE4EN_SHIFT 5
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE5EN_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE5EN_SHIFT 6
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE6EN_MASK 0x1
+#define MSTORM_ISCSI_TASK_AG_CTX_RULE6EN_SHIFT 7
+ u8 byte2;
+ __le32 reg0;
+ u8 byte3;
+ u8 byte4;
+ __le16 word1;
+};
+
+struct ustorm_iscsi_task_ag_ctx {
+ u8 reserved;
+ u8 state;
+ __le16 icid;
+ u8 flags0;
+#define USTORM_ISCSI_TASK_AG_CTX_CONNECTION_TYPE_MASK 0xF
+#define USTORM_ISCSI_TASK_AG_CTX_CONNECTION_TYPE_SHIFT 0
+#define USTORM_ISCSI_TASK_AG_CTX_EXIST_IN_QM0_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_EXIST_IN_QM0_SHIFT 4
+#define USTORM_ISCSI_TASK_AG_CTX_BIT1_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_BIT1_SHIFT 5
+#define USTORM_ISCSI_TASK_AG_CTX_HQ_SCANNED_CF_MASK 0x3
+#define USTORM_ISCSI_TASK_AG_CTX_HQ_SCANNED_CF_SHIFT 6
+ u8 flags1;
+#define USTORM_ISCSI_TASK_AG_CTX_RESERVED1_MASK 0x3
+#define USTORM_ISCSI_TASK_AG_CTX_RESERVED1_SHIFT 0
+#define USTORM_ISCSI_TASK_AG_CTX_R2T2RECV_MASK 0x3
+#define USTORM_ISCSI_TASK_AG_CTX_R2T2RECV_SHIFT 2
+#define USTORM_ISCSI_TASK_AG_CTX_CF3_MASK 0x3
+#define USTORM_ISCSI_TASK_AG_CTX_CF3_SHIFT 4
+#define USTORM_ISCSI_TASK_AG_CTX_DIF_ERROR_CF_MASK 0x3
+#define USTORM_ISCSI_TASK_AG_CTX_DIF_ERROR_CF_SHIFT 6
+ u8 flags2;
+#define USTORM_ISCSI_TASK_AG_CTX_HQ_SCANNED_CF_EN_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_HQ_SCANNED_CF_EN_SHIFT 0
+#define USTORM_ISCSI_TASK_AG_CTX_DISABLE_DATA_ACKED_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_DISABLE_DATA_ACKED_SHIFT 1
+#define USTORM_ISCSI_TASK_AG_CTX_R2T2RECV_EN_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_R2T2RECV_EN_SHIFT 2
+#define USTORM_ISCSI_TASK_AG_CTX_CF3EN_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_CF3EN_SHIFT 3
+#define USTORM_ISCSI_TASK_AG_CTX_DIF_ERROR_CF_EN_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_DIF_ERROR_CF_EN_SHIFT 4
+#define USTORM_ISCSI_TASK_AG_CTX_CMP_DATA_TOTAL_EXP_EN_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_CMP_DATA_TOTAL_EXP_EN_SHIFT 5
+#define USTORM_ISCSI_TASK_AG_CTX_RULE1EN_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_RULE1EN_SHIFT 6
+#define USTORM_ISCSI_TASK_AG_CTX_CMP_CONT_RCV_EXP_EN_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_CMP_CONT_RCV_EXP_EN_SHIFT 7
+ u8 flags3;
+#define USTORM_ISCSI_TASK_AG_CTX_RULE3EN_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_RULE3EN_SHIFT 0
+#define USTORM_ISCSI_TASK_AG_CTX_RULE4EN_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_RULE4EN_SHIFT 1
+#define USTORM_ISCSI_TASK_AG_CTX_RULE5EN_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_RULE5EN_SHIFT 2
+#define USTORM_ISCSI_TASK_AG_CTX_RULE6EN_MASK 0x1
+#define USTORM_ISCSI_TASK_AG_CTX_RULE6EN_SHIFT 3
+#define USTORM_ISCSI_TASK_AG_CTX_DIF_ERROR_TYPE_MASK 0xF
+#define USTORM_ISCSI_TASK_AG_CTX_DIF_ERROR_TYPE_SHIFT 4
+ __le32 dif_err_intervals;
+ __le32 dif_error_1st_interval;
+ __le32 rcv_cont_len;
+ __le32 exp_cont_len;
+ __le32 total_data_acked;
+ __le32 exp_data_acked;
+ u8 next_tid_valid;
+ u8 byte3;
+ __le16 word1;
+ __le16 next_tid;
+ __le16 word3;
+ __le32 hdr_residual_count;
+ __le32 exp_r2t_sn;
+};
+
+struct mstorm_iscsi_task_st_ctx {
+ union iscsi_mstorm_sgl sgl_union;
+ struct iscsi_dif_flags dif_flags;
+ struct iscsi_mflags flags;
+ u8 sgl_size;
+ u8 host_sge_index;
+ __le16 dix_cur_sge_offset;
+ __le16 dix_cur_sge_size;
+ __le32 data_offset_rtid;
+ u8 dif_offset;
+ u8 dix_sgl_size;
+ u8 dix_sge_index;
+ u8 task_type;
+ struct regpair sense_db;
+ struct regpair dix_sgl_cur_sge;
+ __le32 rem_task_size;
+ __le16 reuse_count;
+ __le16 dif_data_residue;
+ u8 reserved0[4];
+ __le32 reserved1[1];
+};
+
+struct ustorm_iscsi_task_st_ctx {
+ __le32 rem_rcv_len;
+ __le32 exp_data_transfer_len;
+ __le32 exp_data_sn;
+ struct regpair lun;
+ struct iscsi_reg1 reg1;
+ u8 flags2;
+#define USTORM_ISCSI_TASK_ST_CTX_AHS_EXIST_MASK 0x1
+#define USTORM_ISCSI_TASK_ST_CTX_AHS_EXIST_SHIFT 0
+#define USTORM_ISCSI_TASK_ST_CTX_RESERVED1_MASK 0x7F
+#define USTORM_ISCSI_TASK_ST_CTX_RESERVED1_SHIFT 1
+ u8 reserved2;
+ __le16 reserved3;
+ __le32 reserved4;
+ __le32 reserved5;
+ __le32 reserved6;
+ __le32 reserved7;
+ u8 task_type;
+ u8 error_flags;
+#define USTORM_ISCSI_TASK_ST_CTX_DATA_DIGEST_ERROR_MASK 0x1
+#define USTORM_ISCSI_TASK_ST_CTX_DATA_DIGEST_ERROR_SHIFT 0
+#define USTORM_ISCSI_TASK_ST_CTX_DATA_TRUNCATED_ERROR_MASK 0x1
+#define USTORM_ISCSI_TASK_ST_CTX_DATA_TRUNCATED_ERROR_SHIFT 1
+#define USTORM_ISCSI_TASK_ST_CTX_UNDER_RUN_ERROR_MASK 0x1
+#define USTORM_ISCSI_TASK_ST_CTX_UNDER_RUN_ERROR_SHIFT 2
+#define USTORM_ISCSI_TASK_ST_CTX_RESERVED8_MASK 0x1F
+#define USTORM_ISCSI_TASK_ST_CTX_RESERVED8_SHIFT 3
+ u8 flags;
+#define USTORM_ISCSI_TASK_ST_CTX_CQE_WRITE_MASK 0x3
+#define USTORM_ISCSI_TASK_ST_CTX_CQE_WRITE_SHIFT 0
+#define USTORM_ISCSI_TASK_ST_CTX_LOCAL_COMP_MASK 0x1
+#define USTORM_ISCSI_TASK_ST_CTX_LOCAL_COMP_SHIFT 2
+#define USTORM_ISCSI_TASK_ST_CTX_Q0_R2TQE_WRITE_MASK 0x1
+#define USTORM_ISCSI_TASK_ST_CTX_Q0_R2TQE_WRITE_SHIFT 3
+#define USTORM_ISCSI_TASK_ST_CTX_TOTALDATAACKED_DONE_MASK 0x1
+#define USTORM_ISCSI_TASK_ST_CTX_TOTALDATAACKED_DONE_SHIFT 4
+#define USTORM_ISCSI_TASK_ST_CTX_HQSCANNED_DONE_MASK 0x1
+#define USTORM_ISCSI_TASK_ST_CTX_HQSCANNED_DONE_SHIFT 5
+#define USTORM_ISCSI_TASK_ST_CTX_R2T2RECV_DONE_MASK 0x1
+#define USTORM_ISCSI_TASK_ST_CTX_R2T2RECV_DONE_SHIFT 6
+#define USTORM_ISCSI_TASK_ST_CTX_RESERVED0_MASK 0x1
+#define USTORM_ISCSI_TASK_ST_CTX_RESERVED0_SHIFT 7
+ u8 cq_rss_number;
+};
+
+struct iscsi_task_context {
+ struct ystorm_iscsi_task_st_ctx ystorm_st_context;
+ struct regpair ystorm_st_padding[2];
+ struct ystorm_iscsi_task_ag_ctx ystorm_ag_context;
+ struct regpair ystorm_ag_padding[2];
+ struct tdif_task_context tdif_context;
+ struct mstorm_iscsi_task_ag_ctx mstorm_ag_context;
+ struct regpair mstorm_ag_padding[2];
+ struct ustorm_iscsi_task_ag_ctx ustorm_ag_context;
+ struct mstorm_iscsi_task_st_ctx mstorm_st_context;
+ struct ustorm_iscsi_task_st_ctx ustorm_st_context;
+ struct rdif_task_context rdif_context;
+};
+
+enum iscsi_task_type {
+ ISCSI_TASK_TYPE_INITIATOR_WRITE,
+ ISCSI_TASK_TYPE_INITIATOR_READ,
+ ISCSI_TASK_TYPE_MIDPATH,
+ ISCSI_TASK_TYPE_UNSOLIC,
+ ISCSI_TASK_TYPE_EXCHCLEANUP,
+ ISCSI_TASK_TYPE_IRRELEVANT,
+ ISCSI_TASK_TYPE_TARGET_WRITE,
+ ISCSI_TASK_TYPE_TARGET_READ,
+ ISCSI_TASK_TYPE_TARGET_RESPONSE,
+ ISCSI_TASK_TYPE_LOGIN_RESPONSE,
+ MAX_ISCSI_TASK_TYPE
+};
+
+union iscsi_ttt_txlen_union {
+ __le32 desired_tx_len;
+ __le32 ttt;
+};
+
+struct iscsi_uhqe {
+ __le32 reg1;
+#define ISCSI_UHQE_PDU_PAYLOAD_LEN_MASK 0xFFFFF
+#define ISCSI_UHQE_PDU_PAYLOAD_LEN_SHIFT 0
+#define ISCSI_UHQE_LOCAL_COMP_MASK 0x1
+#define ISCSI_UHQE_LOCAL_COMP_SHIFT 20
+#define ISCSI_UHQE_TOGGLE_BIT_MASK 0x1
+#define ISCSI_UHQE_TOGGLE_BIT_SHIFT 21
+#define ISCSI_UHQE_PURE_PAYLOAD_MASK 0x1
+#define ISCSI_UHQE_PURE_PAYLOAD_SHIFT 22
+#define ISCSI_UHQE_LOGIN_RESPONSE_PDU_MASK 0x1
+#define ISCSI_UHQE_LOGIN_RESPONSE_PDU_SHIFT 23
+#define ISCSI_UHQE_TASK_ID_HI_MASK 0xFF
+#define ISCSI_UHQE_TASK_ID_HI_SHIFT 24
+ __le32 reg2;
+#define ISCSI_UHQE_BUFFER_OFFSET_MASK 0xFFFFFF
+#define ISCSI_UHQE_BUFFER_OFFSET_SHIFT 0
+#define ISCSI_UHQE_TASK_ID_LO_MASK 0xFF
+#define ISCSI_UHQE_TASK_ID_LO_SHIFT 24
+};
+
+struct iscsi_wqe_field {
+ __le32 contlen_cdbsize_field;
+#define ISCSI_WQE_FIELD_CONT_LEN_MASK 0xFFFFFF
+#define ISCSI_WQE_FIELD_CONT_LEN_SHIFT 0
+#define ISCSI_WQE_FIELD_CDB_SIZE_MASK 0xFF
+#define ISCSI_WQE_FIELD_CDB_SIZE_SHIFT 24
+};
+
+union iscsi_wqe_field_union {
+ struct iscsi_wqe_field cont_field;
+ __le32 prev_tid;
+};
+
+struct iscsi_wqe {
+ __le16 task_id;
+ u8 flags;
+#define ISCSI_WQE_WQE_TYPE_MASK 0x7
+#define ISCSI_WQE_WQE_TYPE_SHIFT 0
+#define ISCSI_WQE_NUM_FAST_SGES_MASK 0x7
+#define ISCSI_WQE_NUM_FAST_SGES_SHIFT 3
+#define ISCSI_WQE_PTU_INVALIDATE_MASK 0x1
+#define ISCSI_WQE_PTU_INVALIDATE_SHIFT 6
+#define ISCSI_WQE_RESPONSE_MASK 0x1
+#define ISCSI_WQE_RESPONSE_SHIFT 7
+ struct iscsi_dif_flags prot_flags;
+ union iscsi_wqe_field_union cont_prevtid_union;
+};
+
+enum iscsi_wqe_type {
+ ISCSI_WQE_TYPE_NORMAL,
+ ISCSI_WQE_TYPE_TASK_CLEANUP,
+ ISCSI_WQE_TYPE_MIDDLE_PATH,
+ ISCSI_WQE_TYPE_LOGIN,
+ ISCSI_WQE_TYPE_FIRST_R2T_CONT,
+ ISCSI_WQE_TYPE_NONFIRST_R2T_CONT,
+ ISCSI_WQE_TYPE_RESPONSE,
+ MAX_ISCSI_WQE_TYPE
+};
+
+struct iscsi_xhqe {
+ union iscsi_ttt_txlen_union ttt_or_txlen;
+ __le32 exp_stat_sn;
+ struct iscsi_dif_flags prot_flags;
+ u8 total_ahs_length;
+ u8 opcode;
+ u8 flags;
+#define ISCSI_XHQE_NUM_FAST_SGES_MASK 0x7
+#define ISCSI_XHQE_NUM_FAST_SGES_SHIFT 0
+#define ISCSI_XHQE_FINAL_MASK 0x1
+#define ISCSI_XHQE_FINAL_SHIFT 3
+#define ISCSI_XHQE_SUPER_IO_MASK 0x1
+#define ISCSI_XHQE_SUPER_IO_SHIFT 4
+#define ISCSI_XHQE_STATUS_BIT_MASK 0x1
+#define ISCSI_XHQE_STATUS_BIT_SHIFT 5
+#define ISCSI_XHQE_RESERVED_MASK 0x3
+#define ISCSI_XHQE_RESERVED_SHIFT 6
+ union iscsi_seq_num seq_num_union;
+ __le16 reserved1;
+};
+
+struct mstorm_iscsi_stats_drv {
+ struct regpair iscsi_rx_dropped_pdus_task_not_valid;
+};
+
+struct ooo_opaque {
+ __le32 cid;
+ u8 drop_isle;
+ u8 drop_size;
+ u8 ooo_opcode;
+ u8 ooo_isle;
+};
+
+struct pstorm_iscsi_stats_drv {
+ struct regpair iscsi_tx_bytes_cnt;
+ struct regpair iscsi_tx_packet_cnt;
+};
+
+struct tstorm_iscsi_stats_drv {
+ struct regpair iscsi_rx_bytes_cnt;
+ struct regpair iscsi_rx_packet_cnt;
+ struct regpair iscsi_rx_new_ooo_isle_events_cnt;
+ __le32 iscsi_cmdq_threshold_cnt;
+ __le32 iscsi_rq_threshold_cnt;
+ __le32 iscsi_immq_threshold_cnt;
+};
+
+struct ustorm_iscsi_stats_drv {
+ struct regpair iscsi_rx_data_pdu_cnt;
+ struct regpair iscsi_rx_r2t_pdu_cnt;
+ struct regpair iscsi_rx_total_pdu_cnt;
+};
+
+struct xstorm_iscsi_stats_drv {
+ struct regpair iscsi_tx_go_to_slow_start_event_cnt;
+ struct regpair iscsi_tx_fast_retransmit_event_cnt;
+};
+
+struct ystorm_iscsi_stats_drv {
+ struct regpair iscsi_tx_data_pdu_cnt;
+ struct regpair iscsi_tx_r2t_pdu_cnt;
+ struct regpair iscsi_tx_total_pdu_cnt;
+};
+
+struct iscsi_db_data {
+ u8 params;
+#define ISCSI_DB_DATA_DEST_MASK 0x3
+#define ISCSI_DB_DATA_DEST_SHIFT 0
+#define ISCSI_DB_DATA_AGG_CMD_MASK 0x3
+#define ISCSI_DB_DATA_AGG_CMD_SHIFT 2
+#define ISCSI_DB_DATA_BYPASS_EN_MASK 0x1
+#define ISCSI_DB_DATA_BYPASS_EN_SHIFT 4
+#define ISCSI_DB_DATA_RESERVED_MASK 0x1
+#define ISCSI_DB_DATA_RESERVED_SHIFT 5
+#define ISCSI_DB_DATA_AGG_VAL_SEL_MASK 0x3
+#define ISCSI_DB_DATA_AGG_VAL_SEL_SHIFT 6
+ u8 agg_flags;
+ __le16 sq_prod;
+};
+
+struct tstorm_iscsi_task_ag_ctx {
+ u8 byte0;
+ u8 byte1;
+ __le16 word0;
+ u8 flags0;
+#define TSTORM_ISCSI_TASK_AG_CTX_NIBBLE0_MASK 0xF
+#define TSTORM_ISCSI_TASK_AG_CTX_NIBBLE0_SHIFT 0
+#define TSTORM_ISCSI_TASK_AG_CTX_BIT0_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_BIT0_SHIFT 4
+#define TSTORM_ISCSI_TASK_AG_CTX_BIT1_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_BIT1_SHIFT 5
+#define TSTORM_ISCSI_TASK_AG_CTX_BIT2_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_BIT2_SHIFT 6
+#define TSTORM_ISCSI_TASK_AG_CTX_BIT3_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_BIT3_SHIFT 7
+ u8 flags1;
+#define TSTORM_ISCSI_TASK_AG_CTX_BIT4_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_BIT4_SHIFT 0
+#define TSTORM_ISCSI_TASK_AG_CTX_BIT5_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_BIT5_SHIFT 1
+#define TSTORM_ISCSI_TASK_AG_CTX_CF0_MASK 0x3
+#define TSTORM_ISCSI_TASK_AG_CTX_CF0_SHIFT 2
+#define TSTORM_ISCSI_TASK_AG_CTX_CF1_MASK 0x3
+#define TSTORM_ISCSI_TASK_AG_CTX_CF1_SHIFT 4
+#define TSTORM_ISCSI_TASK_AG_CTX_CF2_MASK 0x3
+#define TSTORM_ISCSI_TASK_AG_CTX_CF2_SHIFT 6
+ u8 flags2;
+#define TSTORM_ISCSI_TASK_AG_CTX_CF3_MASK 0x3
+#define TSTORM_ISCSI_TASK_AG_CTX_CF3_SHIFT 0
+#define TSTORM_ISCSI_TASK_AG_CTX_CF4_MASK 0x3
+#define TSTORM_ISCSI_TASK_AG_CTX_CF4_SHIFT 2
+#define TSTORM_ISCSI_TASK_AG_CTX_CF5_MASK 0x3
+#define TSTORM_ISCSI_TASK_AG_CTX_CF5_SHIFT 4
+#define TSTORM_ISCSI_TASK_AG_CTX_CF6_MASK 0x3
+#define TSTORM_ISCSI_TASK_AG_CTX_CF6_SHIFT 6
+ u8 flags3;
+#define TSTORM_ISCSI_TASK_AG_CTX_CF7_MASK 0x3
+#define TSTORM_ISCSI_TASK_AG_CTX_CF7_SHIFT 0
+#define TSTORM_ISCSI_TASK_AG_CTX_CF0EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_CF0EN_SHIFT 2
+#define TSTORM_ISCSI_TASK_AG_CTX_CF1EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_CF1EN_SHIFT 3
+#define TSTORM_ISCSI_TASK_AG_CTX_CF2EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_CF2EN_SHIFT 4
+#define TSTORM_ISCSI_TASK_AG_CTX_CF3EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_CF3EN_SHIFT 5
+#define TSTORM_ISCSI_TASK_AG_CTX_CF4EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_CF4EN_SHIFT 6
+#define TSTORM_ISCSI_TASK_AG_CTX_CF5EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_CF5EN_SHIFT 7
+ u8 flags4;
+#define TSTORM_ISCSI_TASK_AG_CTX_CF6EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_CF6EN_SHIFT 0
+#define TSTORM_ISCSI_TASK_AG_CTX_CF7EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_CF7EN_SHIFT 1
+#define TSTORM_ISCSI_TASK_AG_CTX_RULE0EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_RULE0EN_SHIFT 2
+#define TSTORM_ISCSI_TASK_AG_CTX_RULE1EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_RULE1EN_SHIFT 3
+#define TSTORM_ISCSI_TASK_AG_CTX_RULE2EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_RULE2EN_SHIFT 4
+#define TSTORM_ISCSI_TASK_AG_CTX_RULE3EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_RULE3EN_SHIFT 5
+#define TSTORM_ISCSI_TASK_AG_CTX_RULE4EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_RULE4EN_SHIFT 6
+#define TSTORM_ISCSI_TASK_AG_CTX_RULE5EN_MASK 0x1
+#define TSTORM_ISCSI_TASK_AG_CTX_RULE5EN_SHIFT 7
+ u8 byte2;
+ __le16 word1;
+ __le32 reg0;
+ u8 byte3;
+ u8 byte4;
+ __le16 word2;
+ __le16 word3;
+ __le16 word4;
+ __le32 reg1;
+ __le32 reg2;
+};
+
+#endif /* __ISCSI_COMMON__ */
diff --git a/include/linux/qed/qed_chain.h b/include/linux/qed/qed_chain.h
index 5f8fcaaa6504..7e441bdeabdc 100644
--- a/include/linux/qed/qed_chain.h
+++ b/include/linux/qed/qed_chain.h
@@ -25,10 +25,9 @@
} while (0)
#define HILO_GEN(hi, lo, type) ((((type)(hi)) << 32) + (lo))
-#define HILO_DMA(hi, lo) HILO_GEN(hi, lo, dma_addr_t)
#define HILO_64(hi, lo) HILO_GEN((le32_to_cpu(hi)), (le32_to_cpu(lo)), u64)
-#define HILO_DMA_REGPAIR(regpair) (HILO_DMA(regpair.hi, regpair.lo))
#define HILO_64_REGPAIR(regpair) (HILO_64(regpair.hi, regpair.lo))
+#define HILO_DMA_REGPAIR(regpair) ((dma_addr_t)HILO_64_REGPAIR(regpair))
enum qed_chain_mode {
/* Each Page contains a next pointer at its end */
@@ -47,16 +46,56 @@ enum qed_chain_use_mode {
QED_CHAIN_USE_TO_CONSUME_PRODUCE, /* Chain starts empty */
};
+enum qed_chain_cnt_type {
+ /* The chain's size/prod/cons are kept in 16-bit variables */
+ QED_CHAIN_CNT_TYPE_U16,
+
+ /* The chain's size/prod/cons are kept in 32-bit variables */
+ QED_CHAIN_CNT_TYPE_U32,
+};
+
struct qed_chain_next {
struct regpair next_phys;
void *next_virt;
};
+struct qed_chain_pbl_u16 {
+ u16 prod_page_idx;
+ u16 cons_page_idx;
+};
+
+struct qed_chain_pbl_u32 {
+ u32 prod_page_idx;
+ u32 cons_page_idx;
+};
+
struct qed_chain_pbl {
+ /* Base address of a pre-allocated buffer for pbl */
dma_addr_t p_phys_table;
void *p_virt_table;
- u16 prod_page_idx;
- u16 cons_page_idx;
+
+ /* Table for keeping the virtual addresses of the chain pages,
+ * respectively to the physical addresses in the pbl table.
+ */
+ void **pp_virt_addr_tbl;
+
+ /* Index to current used page by producer/consumer */
+ union {
+ struct qed_chain_pbl_u16 pbl16;
+ struct qed_chain_pbl_u32 pbl32;
+ } u;
+};
+
+struct qed_chain_u16 {
+ /* Cyclic index of next element to produce/consme */
+ u16 prod_idx;
+ u16 cons_idx;
+};
+
+struct qed_chain_u32 {
+ /* Cyclic index of next element to produce/consme */
+ u32 prod_idx;
+ u32 cons_idx;
};
struct qed_chain {
@@ -64,13 +103,25 @@ struct qed_chain {
dma_addr_t p_phys_addr;
void *p_prod_elem;
void *p_cons_elem;
- u16 page_cnt;
+
enum qed_chain_mode mode;
enum qed_chain_use_mode intended_use; /* used to produce/consume */
- u16 capacity; /*< number of _usable_ elements */
- u16 size; /* number of elements */
- u16 prod_idx;
- u16 cons_idx;
+ enum qed_chain_cnt_type cnt_type;
+
+ union {
+ struct qed_chain_u16 chain16;
+ struct qed_chain_u32 chain32;
+ } u;
+
+ u32 page_cnt;
+
+ /* Number of elements - capacity is for usable elements only,
+ * while size will contain total number of elements [for entire chain].
+ */
+ u32 capacity;
+ u32 size;
+
+ /* Elements information for fast calculations */
u16 elem_per_page;
u16 elem_per_page_mask;
u16 elem_unusable;
@@ -96,66 +147,69 @@ struct qed_chain {
#define QED_CHAIN_PAGE_CNT(elem_cnt, elem_size, mode) \
DIV_ROUND_UP(elem_cnt, USABLE_ELEMS_PER_PAGE(elem_size, mode))
+#define is_chain_u16(p) ((p)->cnt_type == QED_CHAIN_CNT_TYPE_U16)
+#define is_chain_u32(p) ((p)->cnt_type == QED_CHAIN_CNT_TYPE_U32)
+
/* Accessors */
static inline u16 qed_chain_get_prod_idx(struct qed_chain *p_chain)
{
- return p_chain->prod_idx;
+ return p_chain->u.chain16.prod_idx;
}
static inline u16 qed_chain_get_cons_idx(struct qed_chain *p_chain)
{
- return p_chain->cons_idx;
+ return p_chain->u.chain16.cons_idx;
+}
+
+static inline u32 qed_chain_get_cons_idx_u32(struct qed_chain *p_chain)
+{
+ return p_chain->u.chain32.cons_idx;
}
static inline u16 qed_chain_get_elem_left(struct qed_chain *p_chain)
{
u16 used;
- /* we don't need to trancate upon assignmet, as we assign u32->u16 */
- used = ((u32)0x10000u + (u32)(p_chain->prod_idx)) -
- (u32)p_chain->cons_idx;
+ used = (u16) (((u32)0x10000 +
+ (u32)p_chain->u.chain16.prod_idx) -
+ (u32)p_chain->u.chain16.cons_idx);
if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR)
- used -= p_chain->prod_idx / p_chain->elem_per_page -
- p_chain->cons_idx / p_chain->elem_per_page;
+ used -= p_chain->u.chain16.prod_idx / p_chain->elem_per_page -
+ p_chain->u.chain16.cons_idx / p_chain->elem_per_page;
- return p_chain->capacity - used;
+ return (u16)(p_chain->capacity - used);
}
-static inline u8 qed_chain_is_full(struct qed_chain *p_chain)
+static inline u32 qed_chain_get_elem_left_u32(struct qed_chain *p_chain)
{
- return qed_chain_get_elem_left(p_chain) == p_chain->capacity;
-}
+ u32 used;
-static inline u8 qed_chain_is_empty(struct qed_chain *p_chain)
-{
- return qed_chain_get_elem_left(p_chain) == 0;
-}
+ used = (u32) (((u64)0x100000000ULL +
+ (u64)p_chain->u.chain32.prod_idx) -
+ (u64)p_chain->u.chain32.cons_idx);
+ if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR)
+ used -= p_chain->u.chain32.prod_idx / p_chain->elem_per_page -
+ p_chain->u.chain32.cons_idx / p_chain->elem_per_page;
-static inline u16 qed_chain_get_elem_per_page(
- struct qed_chain *p_chain)
-{
- return p_chain->elem_per_page;
+ return p_chain->capacity - used;
}
-static inline u16 qed_chain_get_usable_per_page(
- struct qed_chain *p_chain)
+static inline u16 qed_chain_get_usable_per_page(struct qed_chain *p_chain)
{
return p_chain->usable_per_page;
}
-static inline u16 qed_chain_get_unusable_per_page(
- struct qed_chain *p_chain)
+static inline u16 qed_chain_get_unusable_per_page(struct qed_chain *p_chain)
{
return p_chain->elem_unusable;
}
-static inline u16 qed_chain_get_size(struct qed_chain *p_chain)
+static inline u32 qed_chain_get_page_cnt(struct qed_chain *p_chain)
{
- return p_chain->size;
+ return p_chain->page_cnt;
}
-static inline dma_addr_t
-qed_chain_get_pbl_phys(struct qed_chain *p_chain)
+static inline dma_addr_t qed_chain_get_pbl_phys(struct qed_chain *p_chain)
{
return p_chain->pbl.p_phys_table;
}
@@ -172,65 +226,63 @@ qed_chain_get_pbl_phys(struct qed_chain *p_chain)
*/
static inline void
qed_chain_advance_page(struct qed_chain *p_chain,
- void **p_next_elem,
- u16 *idx_to_inc,
- u16 *page_to_inc)
+ void **p_next_elem, void *idx_to_inc, void *page_to_inc)
{
+ struct qed_chain_next *p_next = NULL;
+ u32 page_index = 0;
switch (p_chain->mode) {
case QED_CHAIN_MODE_NEXT_PTR:
- {
- struct qed_chain_next *p_next = *p_next_elem;
+ p_next = *p_next_elem;
*p_next_elem = p_next->next_virt;
- *idx_to_inc += p_chain->elem_unusable;
+ if (is_chain_u16(p_chain))
+ *(u16 *)idx_to_inc += p_chain->elem_unusable;
+ else
+ *(u32 *)idx_to_inc += p_chain->elem_unusable;
break;
- }
case QED_CHAIN_MODE_SINGLE:
*p_next_elem = p_chain->p_virt_addr;
break;
case QED_CHAIN_MODE_PBL:
- /* It is assumed pages are sequential, next element needs
- * to change only when passing going back to first from last.
- */
- if (++(*page_to_inc) == p_chain->page_cnt) {
- *page_to_inc = 0;
- *p_next_elem = p_chain->p_virt_addr;
+ if (is_chain_u16(p_chain)) {
+ if (++(*(u16 *)page_to_inc) == p_chain->page_cnt)
+ *(u16 *)page_to_inc = 0;
+ page_index = *(u16 *)page_to_inc;
+ } else {
+ if (++(*(u32 *)page_to_inc) == p_chain->page_cnt)
+ *(u32 *)page_to_inc = 0;
+ page_index = *(u32 *)page_to_inc;
}
+ *p_next_elem = p_chain->pbl.pp_virt_addr_tbl[page_index];
}
}
#define is_unusable_idx(p, idx) \
- (((p)->idx & (p)->elem_per_page_mask) == (p)->usable_per_page)
+ (((p)->u.chain16.idx & (p)->elem_per_page_mask) == (p)->usable_per_page)
+
+#define is_unusable_idx_u32(p, idx) \
+ (((p)->u.chain32.idx & (p)->elem_per_page_mask) == (p)->usable_per_page)
+#define is_unusable_next_idx(p, idx) \
+ ((((p)->u.chain16.idx + 1) & (p)->elem_per_page_mask) == \
+ (p)->usable_per_page)
-#define is_unusable_next_idx(p, idx) \
- ((((p)->idx + 1) & (p)->elem_per_page_mask) == (p)->usable_per_page)
+#define is_unusable_next_idx_u32(p, idx) \
+ ((((p)->u.chain32.idx + 1) & (p)->elem_per_page_mask) == \
+ (p)->usable_per_page)
-#define test_ans_skip(p, idx) \
+#define test_and_skip(p, idx) \
do { \
- if (is_unusable_idx(p, idx)) { \
- (p)->idx += (p)->elem_unusable; \
+ if (is_chain_u16(p)) { \
+ if (is_unusable_idx(p, idx)) \
+ (p)->u.chain16.idx += (p)->elem_unusable; \
+ } else { \
+ if (is_unusable_idx_u32(p, idx)) \
+ (p)->u.chain32.idx += (p)->elem_unusable; \
} \
} while (0)
/**
- * @brief qed_chain_return_multi_produced -
- *
- * A chain in which the driver "Produces" elements should use this API
- * to indicate previous produced elements are now consumed.
- *
- * @param p_chain
- * @param num
- */
-static inline void
-qed_chain_return_multi_produced(struct qed_chain *p_chain,
- u16 num)
-{
- p_chain->cons_idx += num;
- test_ans_skip(p_chain, cons_idx);
-}
-
-/**
* @brief qed_chain_return_produced -
*
* A chain in which the driver "Produces" elements should use this API
@@ -240,8 +292,11 @@ qed_chain_return_multi_produced(struct qed_chain *p_chain,
*/
static inline void qed_chain_return_produced(struct qed_chain *p_chain)
{
- p_chain->cons_idx++;
- test_ans_skip(p_chain, cons_idx);
+ if (is_chain_u16(p_chain))
+ p_chain->u.chain16.cons_idx++;
+ else
+ p_chain->u.chain32.cons_idx++;
+ test_and_skip(p_chain, cons_idx);
}
/**
@@ -257,21 +312,33 @@ static inline void qed_chain_return_produced(struct qed_chain *p_chain)
*/
static inline void *qed_chain_produce(struct qed_chain *p_chain)
{
- void *ret = NULL;
-
- if ((p_chain->prod_idx & p_chain->elem_per_page_mask) ==
- p_chain->next_page_mask) {
- qed_chain_advance_page(p_chain, &p_chain->p_prod_elem,
- &p_chain->prod_idx,
- &p_chain->pbl.prod_page_idx);
+ void *p_ret = NULL, *p_prod_idx, *p_prod_page_idx;
+
+ if (is_chain_u16(p_chain)) {
+ if ((p_chain->u.chain16.prod_idx &
+ p_chain->elem_per_page_mask) == p_chain->next_page_mask) {
+ p_prod_idx = &p_chain->u.chain16.prod_idx;
+ p_prod_page_idx = &p_chain->pbl.u.pbl16.prod_page_idx;
+ qed_chain_advance_page(p_chain, &p_chain->p_prod_elem,
+ p_prod_idx, p_prod_page_idx);
+ }
+ p_chain->u.chain16.prod_idx++;
+ } else {
+ if ((p_chain->u.chain32.prod_idx &
+ p_chain->elem_per_page_mask) == p_chain->next_page_mask) {
+ p_prod_idx = &p_chain->u.chain32.prod_idx;
+ p_prod_page_idx = &p_chain->pbl.u.pbl32.prod_page_idx;
+ qed_chain_advance_page(p_chain, &p_chain->p_prod_elem,
+ p_prod_idx, p_prod_page_idx);
+ }
+ p_chain->u.chain32.prod_idx++;
}
- ret = p_chain->p_prod_elem;
- p_chain->prod_idx++;
+ p_ret = p_chain->p_prod_elem;
p_chain->p_prod_elem = (void *)(((u8 *)p_chain->p_prod_elem) +
p_chain->elem_size);
- return ret;
+ return p_ret;
}
/**
@@ -282,9 +349,9 @@ static inline void *qed_chain_produce(struct qed_chain *p_chain)
* @param p_chain
* @param num
*
- * @return u16, number of unusable BDs
+ * @return number of unusable BDs
*/
-static inline u16 qed_chain_get_capacity(struct qed_chain *p_chain)
+static inline u32 qed_chain_get_capacity(struct qed_chain *p_chain)
{
return p_chain->capacity;
}
@@ -297,11 +364,13 @@ static inline u16 qed_chain_get_capacity(struct qed_chain *p_chain)
*
* @param p_chain
*/
-static inline void
-qed_chain_recycle_consumed(struct qed_chain *p_chain)
+static inline void qed_chain_recycle_consumed(struct qed_chain *p_chain)
{
- test_ans_skip(p_chain, prod_idx);
- p_chain->prod_idx++;
+ test_and_skip(p_chain, prod_idx);
+ if (is_chain_u16(p_chain))
+ p_chain->u.chain16.prod_idx++;
+ else
+ p_chain->u.chain32.prod_idx++;
}
/**
@@ -316,21 +385,33 @@ qed_chain_recycle_consumed(struct qed_chain *p_chain)
*/
static inline void *qed_chain_consume(struct qed_chain *p_chain)
{
- void *ret = NULL;
-
- if ((p_chain->cons_idx & p_chain->elem_per_page_mask) ==
- p_chain->next_page_mask) {
+ void *p_ret = NULL, *p_cons_idx, *p_cons_page_idx;
+
+ if (is_chain_u16(p_chain)) {
+ if ((p_chain->u.chain16.cons_idx &
+ p_chain->elem_per_page_mask) == p_chain->next_page_mask) {
+ p_cons_idx = &p_chain->u.chain16.cons_idx;
+ p_cons_page_idx = &p_chain->pbl.u.pbl16.cons_page_idx;
+ qed_chain_advance_page(p_chain, &p_chain->p_cons_elem,
+ p_cons_idx, p_cons_page_idx);
+ }
+ p_chain->u.chain16.cons_idx++;
+ } else {
+ if ((p_chain->u.chain32.cons_idx &
+ p_chain->elem_per_page_mask) == p_chain->next_page_mask) {
+ p_cons_idx = &p_chain->u.chain32.cons_idx;
+ p_cons_page_idx = &p_chain->pbl.u.pbl32.cons_page_idx;
qed_chain_advance_page(p_chain, &p_chain->p_cons_elem,
- &p_chain->cons_idx,
- &p_chain->pbl.cons_page_idx);
+ p_cons_idx, p_cons_page_idx);
+ }
+ p_chain->u.chain32.cons_idx++;
}
- ret = p_chain->p_cons_elem;
- p_chain->cons_idx++;
+ p_ret = p_chain->p_cons_elem;
p_chain->p_cons_elem = (void *)(((u8 *)p_chain->p_cons_elem) +
p_chain->elem_size);
- return ret;
+ return p_ret;
}
/**
@@ -340,16 +421,33 @@ static inline void *qed_chain_consume(struct qed_chain *p_chain)
*/
static inline void qed_chain_reset(struct qed_chain *p_chain)
{
- int i;
-
- p_chain->prod_idx = 0;
- p_chain->cons_idx = 0;
- p_chain->p_cons_elem = p_chain->p_virt_addr;
- p_chain->p_prod_elem = p_chain->p_virt_addr;
+ u32 i;
+
+ if (is_chain_u16(p_chain)) {
+ p_chain->u.chain16.prod_idx = 0;
+ p_chain->u.chain16.cons_idx = 0;
+ } else {
+ p_chain->u.chain32.prod_idx = 0;
+ p_chain->u.chain32.cons_idx = 0;
+ }
+ p_chain->p_cons_elem = p_chain->p_virt_addr;
+ p_chain->p_prod_elem = p_chain->p_virt_addr;
if (p_chain->mode == QED_CHAIN_MODE_PBL) {
- p_chain->pbl.prod_page_idx = p_chain->page_cnt - 1;
- p_chain->pbl.cons_page_idx = p_chain->page_cnt - 1;
+ /* Use (page_cnt - 1) as a reset value for the prod/cons page's
+ * indices, to avoid unnecessary page advancing on the first
+ * call to qed_chain_produce/consume. Instead, the indices
+ * will be advanced to page_cnt and then will be wrapped to 0.
+ */
+ u32 reset_val = p_chain->page_cnt - 1;
+
+ if (is_chain_u16(p_chain)) {
+ p_chain->pbl.u.pbl16.prod_page_idx = (u16)reset_val;
+ p_chain->pbl.u.pbl16.cons_page_idx = (u16)reset_val;
+ } else {
+ p_chain->pbl.u.pbl32.prod_page_idx = reset_val;
+ p_chain->pbl.u.pbl32.cons_page_idx = reset_val;
+ }
}
switch (p_chain->intended_use) {
@@ -377,168 +475,184 @@ static inline void qed_chain_reset(struct qed_chain *p_chain)
* @param intended_use
* @param mode
*/
-static inline void qed_chain_init(struct qed_chain *p_chain,
- void *p_virt_addr,
- dma_addr_t p_phys_addr,
- u16 page_cnt,
- u8 elem_size,
- enum qed_chain_use_mode intended_use,
- enum qed_chain_mode mode)
+static inline void qed_chain_init_params(struct qed_chain *p_chain,
+ u32 page_cnt,
+ u8 elem_size,
+ enum qed_chain_use_mode intended_use,
+ enum qed_chain_mode mode,
+ enum qed_chain_cnt_type cnt_type)
{
/* chain fixed parameters */
- p_chain->p_virt_addr = p_virt_addr;
- p_chain->p_phys_addr = p_phys_addr;
+ p_chain->p_virt_addr = NULL;
+ p_chain->p_phys_addr = 0;
p_chain->elem_size = elem_size;
- p_chain->page_cnt = page_cnt;
+ p_chain->intended_use = intended_use;
p_chain->mode = mode;
+ p_chain->cnt_type = cnt_type;
- p_chain->intended_use = intended_use;
p_chain->elem_per_page = ELEMS_PER_PAGE(elem_size);
- p_chain->usable_per_page =
- USABLE_ELEMS_PER_PAGE(elem_size, mode);
- p_chain->capacity = p_chain->usable_per_page * page_cnt;
- p_chain->size = p_chain->elem_per_page * page_cnt;
+ p_chain->usable_per_page = USABLE_ELEMS_PER_PAGE(elem_size, mode);
p_chain->elem_per_page_mask = p_chain->elem_per_page - 1;
-
p_chain->elem_unusable = UNUSABLE_ELEMS_PER_PAGE(elem_size, mode);
-
p_chain->next_page_mask = (p_chain->usable_per_page &
p_chain->elem_per_page_mask);
- if (mode == QED_CHAIN_MODE_NEXT_PTR) {
- struct qed_chain_next *p_next;
- u16 i;
-
- for (i = 0; i < page_cnt - 1; i++) {
- /* Increment mem_phy to the next page. */
- p_phys_addr += QED_CHAIN_PAGE_SIZE;
-
- /* Initialize the physical address of the next page. */
- p_next = (struct qed_chain_next *)((u8 *)p_virt_addr +
- elem_size *
- p_chain->
- usable_per_page);
-
- p_next->next_phys.lo = DMA_LO_LE(p_phys_addr);
- p_next->next_phys.hi = DMA_HI_LE(p_phys_addr);
-
- /* Initialize the virtual address of the next page. */
- p_next->next_virt = (void *)((u8 *)p_virt_addr +
- QED_CHAIN_PAGE_SIZE);
-
- /* Move to the next page. */
- p_virt_addr = p_next->next_virt;
- }
-
- /* Last page's next should point to beginning of the chain */
- p_next = (struct qed_chain_next *)((u8 *)p_virt_addr +
- elem_size *
- p_chain->usable_per_page);
+ p_chain->page_cnt = page_cnt;
+ p_chain->capacity = p_chain->usable_per_page * page_cnt;
+ p_chain->size = p_chain->elem_per_page * page_cnt;
- p_next->next_phys.lo = DMA_LO_LE(p_chain->p_phys_addr);
- p_next->next_phys.hi = DMA_HI_LE(p_chain->p_phys_addr);
- p_next->next_virt = p_chain->p_virt_addr;
- }
- qed_chain_reset(p_chain);
+ p_chain->pbl.p_phys_table = 0;
+ p_chain->pbl.p_virt_table = NULL;
+ p_chain->pbl.pp_virt_addr_tbl = NULL;
}
/**
- * @brief qed_chain_pbl_init - Initalizes a basic pbl chain
- * struct
+ * @brief qed_chain_init_mem -
+ *
+ * Initalizes a basic chain struct with its chain buffers
+ *
* @param p_chain
* @param p_virt_addr virtual address of allocated buffer's beginning
* @param p_phys_addr physical address of allocated buffer's beginning
- * @param page_cnt number of pages in the allocated buffer
- * @param elem_size size of each element in the chain
- * @param use_mode
- * @param p_phys_pbl pointer to a pre-allocated side table
- * which will hold physical page addresses.
- * @param p_virt_pbl pointer to a pre allocated side table
- * which will hold virtual page addresses.
+ *
*/
-static inline void
-qed_chain_pbl_init(struct qed_chain *p_chain,
- void *p_virt_addr,
- dma_addr_t p_phys_addr,
- u16 page_cnt,
- u8 elem_size,
- enum qed_chain_use_mode use_mode,
- dma_addr_t p_phys_pbl,
- dma_addr_t *p_virt_pbl)
+static inline void qed_chain_init_mem(struct qed_chain *p_chain,
+ void *p_virt_addr, dma_addr_t p_phys_addr)
{
- dma_addr_t *p_pbl_dma = p_virt_pbl;
- int i;
-
- qed_chain_init(p_chain, p_virt_addr, p_phys_addr, page_cnt,
- elem_size, use_mode, QED_CHAIN_MODE_PBL);
+ p_chain->p_virt_addr = p_virt_addr;
+ p_chain->p_phys_addr = p_phys_addr;
+}
+/**
+ * @brief qed_chain_init_pbl_mem -
+ *
+ * Initalizes a basic chain struct with its pbl buffers
+ *
+ * @param p_chain
+ * @param p_virt_pbl pointer to a pre allocated side table which will hold
+ * virtual page addresses.
+ * @param p_phys_pbl pointer to a pre-allocated side table which will hold
+ * physical page addresses.
+ * @param pp_virt_addr_tbl
+ * pointer to a pre-allocated side table which will hold
+ * the virtual addresses of the chain pages.
+ *
+ */
+static inline void qed_chain_init_pbl_mem(struct qed_chain *p_chain,
+ void *p_virt_pbl,
+ dma_addr_t p_phys_pbl,
+ void **pp_virt_addr_tbl)
+{
p_chain->pbl.p_phys_table = p_phys_pbl;
p_chain->pbl.p_virt_table = p_virt_pbl;
-
- /* Fill the PBL with physical addresses*/
- for (i = 0; i < page_cnt; i++) {
- *p_pbl_dma = p_phys_addr;
- p_phys_addr += QED_CHAIN_PAGE_SIZE;
- p_pbl_dma++;
- }
+ p_chain->pbl.pp_virt_addr_tbl = pp_virt_addr_tbl;
}
/**
- * @brief qed_chain_set_prod - sets the prod to the given
- * value
+ * @brief qed_chain_init_next_ptr_elem -
+ *
+ * Initalizes a next pointer element
+ *
+ * @param p_chain
+ * @param p_virt_curr virtual address of a chain page of which the next
+ * pointer element is initialized
+ * @param p_virt_next virtual address of the next chain page
+ * @param p_phys_next physical address of the next chain page
*
- * @param prod_idx
- * @param p_prod_elem
*/
-static inline void qed_chain_set_prod(struct qed_chain *p_chain,
- u16 prod_idx,
- void *p_prod_elem)
+static inline void
+qed_chain_init_next_ptr_elem(struct qed_chain *p_chain,
+ void *p_virt_curr,
+ void *p_virt_next, dma_addr_t p_phys_next)
{
- p_chain->prod_idx = prod_idx;
- p_chain->p_prod_elem = p_prod_elem;
+ struct qed_chain_next *p_next;
+ u32 size;
+
+ size = p_chain->elem_size * p_chain->usable_per_page;
+ p_next = (struct qed_chain_next *)((u8 *)p_virt_curr + size);
+
+ DMA_REGPAIR_LE(p_next->next_phys, p_phys_next);
+
+ p_next->next_virt = p_virt_next;
}
/**
- * @brief qed_chain_get_elem -
+ * @brief qed_chain_get_last_elem -
*
- * get a pointer to an element represented by absolute idx
+ * Returns a pointer to the last element of the chain
*
* @param p_chain
- * @assumption p_chain->size is a power of 2
*
- * @return void*, a pointer to next element
+ * @return void*
*/
-static inline void *qed_chain_sge_get_elem(struct qed_chain *p_chain,
- u16 idx)
+static inline void *qed_chain_get_last_elem(struct qed_chain *p_chain)
{
- void *ret = NULL;
-
- if (idx >= p_chain->size)
- return NULL;
+ struct qed_chain_next *p_next = NULL;
+ void *p_virt_addr = NULL;
+ u32 size, last_page_idx;
- ret = (u8 *)p_chain->p_virt_addr + p_chain->elem_size * idx;
+ if (!p_chain->p_virt_addr)
+ goto out;
- return ret;
+ switch (p_chain->mode) {
+ case QED_CHAIN_MODE_NEXT_PTR:
+ size = p_chain->elem_size * p_chain->usable_per_page;
+ p_virt_addr = p_chain->p_virt_addr;
+ p_next = (struct qed_chain_next *)((u8 *)p_virt_addr + size);
+ while (p_next->next_virt != p_chain->p_virt_addr) {
+ p_virt_addr = p_next->next_virt;
+ p_next = (struct qed_chain_next *)((u8 *)p_virt_addr +
+ size);
+ }
+ break;
+ case QED_CHAIN_MODE_SINGLE:
+ p_virt_addr = p_chain->p_virt_addr;
+ break;
+ case QED_CHAIN_MODE_PBL:
+ last_page_idx = p_chain->page_cnt - 1;
+ p_virt_addr = p_chain->pbl.pp_virt_addr_tbl[last_page_idx];
+ break;
+ }
+ /* p_virt_addr points at this stage to the last page of the chain */
+ size = p_chain->elem_size * (p_chain->usable_per_page - 1);
+ p_virt_addr = (u8 *)p_virt_addr + size;
+out:
+ return p_virt_addr;
}
/**
- * @brief qed_chain_sge_inc_cons_prod
+ * @brief qed_chain_set_prod - sets the prod to the given value
*
- * for sge chains, producer isn't increased serially, the ring
- * is expected to be full at all times. Once elements are
- * consumed, they are immediately produced.
+ * @param prod_idx
+ * @param p_prod_elem
+ */
+static inline void qed_chain_set_prod(struct qed_chain *p_chain,
+ u32 prod_idx, void *p_prod_elem)
+{
+ if (is_chain_u16(p_chain))
+ p_chain->u.chain16.prod_idx = (u16) prod_idx;
+ else
+ p_chain->u.chain32.prod_idx = prod_idx;
+ p_chain->p_prod_elem = p_prod_elem;
+}
+
+/**
+ * @brief qed_chain_pbl_zero_mem - set chain memory to 0
*
* @param p_chain
- * @param cnt
- *
- * @return inline void
*/
-static inline void
-qed_chain_sge_inc_cons_prod(struct qed_chain *p_chain,
- u16 cnt)
+static inline void qed_chain_pbl_zero_mem(struct qed_chain *p_chain)
{
- p_chain->prod_idx += cnt;
- p_chain->cons_idx += cnt;
+ u32 i, page_cnt;
+
+ if (p_chain->mode != QED_CHAIN_MODE_PBL)
+ return;
+
+ page_cnt = qed_chain_get_page_cnt(p_chain);
+
+ for (i = 0; i < page_cnt; i++)
+ memset(p_chain->pbl.pp_virt_addr_tbl[i], 0,
+ QED_CHAIN_PAGE_SIZE);
}
#endif
diff --git a/include/linux/qed/qed_eth_if.h b/include/linux/qed/qed_eth_if.h
index 6c876a63558d..4475a9d8ae15 100644
--- a/include/linux/qed/qed_eth_if.h
+++ b/include/linux/qed/qed_eth_if.h
@@ -114,6 +114,7 @@ struct qed_queue_start_common_params {
u8 vport_id;
u16 sb;
u16 sb_idx;
+ u16 vf_qid;
};
struct qed_tunn_params {
@@ -128,11 +129,73 @@ struct qed_eth_cb_ops {
void (*force_mac) (void *dev, u8 *mac);
};
+#ifdef CONFIG_DCB
+/* Prototype declaration of qed_eth_dcbnl_ops should match with the declaration
+ * of dcbnl_rtnl_ops structure.
+ */
+struct qed_eth_dcbnl_ops {
+ /* IEEE 802.1Qaz std */
+ int (*ieee_getpfc)(struct qed_dev *cdev, struct ieee_pfc *pfc);
+ int (*ieee_setpfc)(struct qed_dev *cdev, struct ieee_pfc *pfc);
+ int (*ieee_getets)(struct qed_dev *cdev, struct ieee_ets *ets);
+ int (*ieee_setets)(struct qed_dev *cdev, struct ieee_ets *ets);
+ int (*ieee_peer_getets)(struct qed_dev *cdev, struct ieee_ets *ets);
+ int (*ieee_peer_getpfc)(struct qed_dev *cdev, struct ieee_pfc *pfc);
+ int (*ieee_getapp)(struct qed_dev *cdev, struct dcb_app *app);
+ int (*ieee_setapp)(struct qed_dev *cdev, struct dcb_app *app);
+
+ /* CEE std */
+ u8 (*getstate)(struct qed_dev *cdev);
+ u8 (*setstate)(struct qed_dev *cdev, u8 state);
+ void (*getpgtccfgtx)(struct qed_dev *cdev, int prio, u8 *prio_type,
+ u8 *pgid, u8 *bw_pct, u8 *up_map);
+ void (*getpgbwgcfgtx)(struct qed_dev *cdev, int pgid, u8 *bw_pct);
+ void (*getpgtccfgrx)(struct qed_dev *cdev, int prio, u8 *prio_type,
+ u8 *pgid, u8 *bw_pct, u8 *up_map);
+ void (*getpgbwgcfgrx)(struct qed_dev *cdev, int pgid, u8 *bw_pct);
+ void (*getpfccfg)(struct qed_dev *cdev, int prio, u8 *setting);
+ void (*setpfccfg)(struct qed_dev *cdev, int prio, u8 setting);
+ u8 (*getcap)(struct qed_dev *cdev, int capid, u8 *cap);
+ int (*getnumtcs)(struct qed_dev *cdev, int tcid, u8 *num);
+ u8 (*getpfcstate)(struct qed_dev *cdev);
+ int (*getapp)(struct qed_dev *cdev, u8 idtype, u16 id);
+ u8 (*getfeatcfg)(struct qed_dev *cdev, int featid, u8 *flags);
+
+ /* DCBX configuration */
+ u8 (*getdcbx)(struct qed_dev *cdev);
+ void (*setpgtccfgtx)(struct qed_dev *cdev, int prio,
+ u8 pri_type, u8 pgid, u8 bw_pct, u8 up_map);
+ void (*setpgtccfgrx)(struct qed_dev *cdev, int prio,
+ u8 pri_type, u8 pgid, u8 bw_pct, u8 up_map);
+ void (*setpgbwgcfgtx)(struct qed_dev *cdev, int pgid, u8 bw_pct);
+ void (*setpgbwgcfgrx)(struct qed_dev *cdev, int pgid, u8 bw_pct);
+ u8 (*setall)(struct qed_dev *cdev);
+ int (*setnumtcs)(struct qed_dev *cdev, int tcid, u8 num);
+ void (*setpfcstate)(struct qed_dev *cdev, u8 state);
+ int (*setapp)(struct qed_dev *cdev, u8 idtype, u16 idval, u8 up);
+ u8 (*setdcbx)(struct qed_dev *cdev, u8 state);
+ u8 (*setfeatcfg)(struct qed_dev *cdev, int featid, u8 flags);
+
+ /* Peer apps */
+ int (*peer_getappinfo)(struct qed_dev *cdev,
+ struct dcb_peer_app_info *info,
+ u16 *app_count);
+ int (*peer_getapptable)(struct qed_dev *cdev, struct dcb_app *table);
+
+ /* CEE peer */
+ int (*cee_peer_getpfc)(struct qed_dev *cdev, struct cee_pfc *pfc);
+ int (*cee_peer_getpg)(struct qed_dev *cdev, struct cee_pg *pg);
+};
+#endif
+
struct qed_eth_ops {
const struct qed_common_ops *common;
#ifdef CONFIG_QED_SRIOV
const struct qed_iov_hv_ops *iov;
#endif
+#ifdef CONFIG_DCB
+ const struct qed_eth_dcbnl_ops *dcb;
+#endif
int (*fill_dev_info)(struct qed_dev *cdev,
struct qed_dev_eth_info *info);
diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
index 4c29439f54bf..b1e3c57c7117 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -34,6 +34,96 @@ enum dcbx_protocol_type {
DCBX_MAX_PROTOCOL_TYPE
};
+#ifdef CONFIG_DCB
+#define QED_LLDP_CHASSIS_ID_STAT_LEN 4
+#define QED_LLDP_PORT_ID_STAT_LEN 4
+#define QED_DCBX_MAX_APP_PROTOCOL 32
+#define QED_MAX_PFC_PRIORITIES 8
+#define QED_DCBX_DSCP_SIZE 64
+
+struct qed_dcbx_lldp_remote {
+ u32 peer_chassis_id[QED_LLDP_CHASSIS_ID_STAT_LEN];
+ u32 peer_port_id[QED_LLDP_PORT_ID_STAT_LEN];
+ bool enable_rx;
+ bool enable_tx;
+ u32 tx_interval;
+ u32 max_credit;
+};
+
+struct qed_dcbx_lldp_local {
+ u32 local_chassis_id[QED_LLDP_CHASSIS_ID_STAT_LEN];
+ u32 local_port_id[QED_LLDP_PORT_ID_STAT_LEN];
+};
+
+struct qed_dcbx_app_prio {
+ u8 roce;
+ u8 roce_v2;
+ u8 fcoe;
+ u8 iscsi;
+ u8 eth;
+};
+
+struct qed_dbcx_pfc_params {
+ bool willing;
+ bool enabled;
+ u8 prio[QED_MAX_PFC_PRIORITIES];
+ u8 max_tc;
+};
+
+struct qed_app_entry {
+ bool ethtype;
+ bool enabled;
+ u8 prio;
+ u16 proto_id;
+ enum dcbx_protocol_type proto_type;
+};
+
+struct qed_dcbx_params {
+ struct qed_app_entry app_entry[QED_DCBX_MAX_APP_PROTOCOL];
+ u16 num_app_entries;
+ bool app_willing;
+ bool app_valid;
+ bool app_error;
+ bool ets_willing;
+ bool ets_enabled;
+ bool ets_cbs;
+ bool valid;
+ u8 ets_pri_tc_tbl[QED_MAX_PFC_PRIORITIES];
+ u8 ets_tc_bw_tbl[QED_MAX_PFC_PRIORITIES];
+ u8 ets_tc_tsa_tbl[QED_MAX_PFC_PRIORITIES];
+ struct qed_dbcx_pfc_params pfc;
+ u8 max_ets_tc;
+};
+
+struct qed_dcbx_admin_params {
+ struct qed_dcbx_params params;
+ bool valid;
+};
+
+struct qed_dcbx_remote_params {
+ struct qed_dcbx_params params;
+ bool valid;
+};
+
+struct qed_dcbx_operational_params {
+ struct qed_dcbx_app_prio app_prio;
+ struct qed_dcbx_params params;
+ bool valid;
+ bool enabled;
+ bool ieee;
+ bool cee;
+ u32 err;
+};
+
+struct qed_dcbx_get {
+ struct qed_dcbx_operational_params operational;
+ struct qed_dcbx_lldp_remote lldp_remote;
+ struct qed_dcbx_lldp_local lldp_local;
+ struct qed_dcbx_remote_params remote;
+ struct qed_dcbx_admin_params local;
+};
+#endif
+
enum qed_led_mode {
QED_LED_MODE_OFF,
QED_LED_MODE_ON,
@@ -58,8 +148,70 @@ struct qed_eth_pf_params {
u16 num_cons;
};
+/* Most of the the parameters below are described in the FW iSCSI / TCP HSI */
+struct qed_iscsi_pf_params {
+ u64 glbl_q_params_addr;
+ u64 bdq_pbl_base_addr[2];
+ u32 max_cwnd;
+ u16 cq_num_entries;
+ u16 cmdq_num_entries;
+ u16 dup_ack_threshold;
+ u16 tx_sws_timer;
+ u16 min_rto;
+ u16 min_rto_rt;
+ u16 max_rto;
+
+ /* The following parameters are used during HW-init
+ * and these parameters need to be passed as arguments
+ * to update_pf_params routine invoked before slowpath start
+ */
+ u16 num_cons;
+ u16 num_tasks;
+
+ /* The following parameters are used during protocol-init */
+ u16 half_way_close_timeout;
+ u16 bdq_xoff_threshold[2];
+ u16 bdq_xon_threshold[2];
+ u16 cmdq_xoff_threshold;
+ u16 cmdq_xon_threshold;
+ u16 rq_buffer_size;
+
+ u8 num_sq_pages_in_ring;
+ u8 num_r2tq_pages_in_ring;
+ u8 num_uhq_pages_in_ring;
+ u8 num_queues;
+ u8 log_page_size;
+ u8 rqe_log_size;
+ u8 max_fin_rt;
+ u8 gl_rq_pi;
+ u8 gl_cmd_pi;
+ u8 debug_mode;
+ u8 ll2_ooo_queue_id;
+ u8 ooo_enable;
+
+ u8 is_target;
+ u8 bdq_pbl_num_entries[2];
+};
+
+struct qed_rdma_pf_params {
+ /* Supplied to QED during resource allocation (may affect the ILT and
+ * the doorbell BAR).
+ */
+ u32 min_dpis; /* number of requested DPIs */
+ u32 num_mrs; /* number of requested memory regions */
+ u32 num_qps; /* number of requested Queue Pairs */
+ u32 num_srqs; /* number of requested SRQ */
+ u8 roce_edpm_mode; /* see QED_ROCE_EDPM_MODE_ENABLE */
+ u8 gl_pi; /* protocol index */
+
+ /* Will allocate rate limiters to be used with QPs */
+ u8 enable_dcqcn;
+};
+
struct qed_pf_params {
struct qed_eth_pf_params eth_pf_params;
+ struct qed_iscsi_pf_params iscsi_pf_params;
+ struct qed_rdma_pf_params rdma_pf_params;
};
enum qed_int_mode {
@@ -100,6 +252,8 @@ struct qed_dev_info {
/* MFW version */
u32 mfw_rev;
+ bool rdma_supported;
+
u32 flash_size;
u8 mf_mode;
bool tx_switching;
@@ -111,6 +265,7 @@ enum qed_sb_type {
enum qed_protocol {
QED_PROTOCOL_ETH,
+ QED_PROTOCOL_ISCSI,
};
struct qed_link_params {
@@ -325,7 +480,8 @@ struct qed_common_ops {
int (*chain_alloc)(struct qed_dev *cdev,
enum qed_chain_use_mode intended_use,
enum qed_chain_mode mode,
- u16 num_elems,
+ enum qed_chain_cnt_type cnt_type,
+ u32 num_elems,
size_t elem_size,
struct qed_chain *p_chain);
@@ -333,6 +489,30 @@ struct qed_common_ops {
struct qed_chain *p_chain);
/**
+ * @brief get_coalesce - Get coalesce parameters in usec
+ *
+ * @param cdev
+ * @param rx_coal - Rx coalesce value in usec
+ * @param tx_coal - Tx coalesce value in usec
+ *
+ */
+ void (*get_coalesce)(struct qed_dev *cdev, u16 *rx_coal, u16 *tx_coal);
+
+/**
+ * @brief set_coalesce - Configure Rx coalesce value in usec
+ *
+ * @param cdev
+ * @param rx_coal - Rx coalesce value in usec
+ * @param tx_coal - Tx coalesce value in usec
+ * @param qid - Queue index
+ * @param sb_id - Status Block Id
+ *
+ * @return 0 on success, error otherwise.
+ */
+ int (*set_coalesce)(struct qed_dev *cdev, u16 rx_coal, u16 tx_coal,
+ u8 qid, u16 sb_id);
+
+/**
* @brief set_led - Configure LED mode
*
* @param cdev
diff --git a/include/linux/qed/rdma_common.h b/include/linux/qed/rdma_common.h
new file mode 100644
index 000000000000..187991c1f439
--- /dev/null
+++ b/include/linux/qed/rdma_common.h
@@ -0,0 +1,44 @@
+/* QLogic qed NIC Driver
+ * Copyright (c) 2015 QLogic Corporation
+ *
+ * This software is available under the terms of the GNU General Public License
+ * (GPL) Version 2, available from the file COPYING in the main directory of
+ * this source tree.
+ */
+
+#ifndef __RDMA_COMMON__
+#define __RDMA_COMMON__
+/************************/
+/* RDMA FW CONSTANTS */
+/************************/
+
+#define RDMA_RESERVED_LKEY (0)
+#define RDMA_RING_PAGE_SIZE (0x1000)
+
+#define RDMA_MAX_SGE_PER_SQ_WQE (4)
+#define RDMA_MAX_SGE_PER_RQ_WQE (4)
+
+#define RDMA_MAX_DATA_SIZE_IN_WQE (0x7FFFFFFF)
+
+#define RDMA_REQ_RD_ATOMIC_ELM_SIZE (0x50)
+#define RDMA_RESP_RD_ATOMIC_ELM_SIZE (0x20)
+
+#define RDMA_MAX_CQS (64 * 1024)
+#define RDMA_MAX_TIDS (128 * 1024 - 1)
+#define RDMA_MAX_PDS (64 * 1024)
+
+#define RDMA_NUM_STATISTIC_COUNTERS MAX_NUM_VPORTS
+
+#define RDMA_TASK_TYPE (PROTOCOLID_ROCE)
+
+struct rdma_srq_id {
+ __le16 srq_idx;
+ __le16 opaque_fid;
+};
+
+struct rdma_srq_producers {
+ __le32 sge_prod;
+ __le32 wqe_prod;
+};
+
+#endif /* __RDMA_COMMON__ */
diff --git a/include/linux/qed/roce_common.h b/include/linux/qed/roce_common.h
new file mode 100644
index 000000000000..2eeaf3dc6646
--- /dev/null
+++ b/include/linux/qed/roce_common.h
@@ -0,0 +1,17 @@
+/* QLogic qed NIC Driver
+ * Copyright (c) 2015 QLogic Corporation
+ *
+ * This software is available under the terms of the GNU General Public License
+ * (GPL) Version 2, available from the file COPYING in the main directory of
+ * this source tree.
+ */
+
+#ifndef __ROCE_COMMON__
+#define __ROCE_COMMON__
+
+#define ROCE_REQ_MAX_INLINE_DATA_SIZE (256)
+#define ROCE_REQ_MAX_SINGLE_SQ_WQE_SIZE (288)
+
+#define ROCE_MAX_QPS (32 * 1024)
+
+#endif /* __ROCE_COMMON__ */
diff --git a/include/linux/qed/storage_common.h b/include/linux/qed/storage_common.h
new file mode 100644
index 000000000000..3b8e1efd9bc2
--- /dev/null
+++ b/include/linux/qed/storage_common.h
@@ -0,0 +1,91 @@
+/* QLogic qed NIC Driver
+ * Copyright (c) 2015 QLogic Corporation
+ *
+ * This software is available under the terms of the GNU General Public License
+ * (GPL) Version 2, available from the file COPYING in the main directory of
+ * this source tree.
+ */
+
+#ifndef __STORAGE_COMMON__
+#define __STORAGE_COMMON__
+
+#define NUM_OF_CMDQS_CQS (NUM_OF_GLOBAL_QUEUES / 2)
+#define BDQ_NUM_RESOURCES (4)
+
+#define BDQ_ID_RQ (0)
+#define BDQ_ID_IMM_DATA (1)
+#define BDQ_NUM_IDS (2)
+
+#define BDQ_MAX_EXTERNAL_RING_SIZE (1 << 15)
+
+struct scsi_bd {
+ struct regpair address;
+ struct regpair opaque;
+};
+
+struct scsi_bdq_ram_drv_data {
+ __le16 external_producer;
+ __le16 reserved0[3];
+};
+
+struct scsi_drv_cmdq {
+ __le16 cmdq_cons;
+ __le16 reserved0;
+ __le32 reserved1;
+};
+
+struct scsi_init_func_params {
+ __le16 num_tasks;
+ u8 log_page_size;
+ u8 debug_mode;
+ u8 reserved2[12];
+};
+
+struct scsi_init_func_queues {
+ struct regpair glbl_q_params_addr;
+ __le16 rq_buffer_size;
+ __le16 cq_num_entries;
+ __le16 cmdq_num_entries;
+ u8 bdq_resource_id;
+ u8 q_validity;
+#define SCSI_INIT_FUNC_QUEUES_RQ_VALID_MASK 0x1
+#define SCSI_INIT_FUNC_QUEUES_RQ_VALID_SHIFT 0
+#define SCSI_INIT_FUNC_QUEUES_IMM_DATA_VALID_MASK 0x1
+#define SCSI_INIT_FUNC_QUEUES_IMM_DATA_VALID_SHIFT 1
+#define SCSI_INIT_FUNC_QUEUES_CMD_VALID_MASK 0x1
+#define SCSI_INIT_FUNC_QUEUES_CMD_VALID_SHIFT 2
+#define SCSI_INIT_FUNC_QUEUES_RESERVED_VALID_MASK 0x1F
+#define SCSI_INIT_FUNC_QUEUES_RESERVED_VALID_SHIFT 3
+ u8 num_queues;
+ u8 queue_relative_offset;
+ u8 cq_sb_pi;
+ u8 cmdq_sb_pi;
+ __le16 cq_cmdq_sb_num_arr[NUM_OF_CMDQS_CQS];
+ __le16 reserved0;
+ u8 bdq_pbl_num_entries[BDQ_NUM_IDS];
+ struct regpair bdq_pbl_base_address[BDQ_NUM_IDS];
+ __le16 bdq_xoff_threshold[BDQ_NUM_IDS];
+ __le16 bdq_xon_threshold[BDQ_NUM_IDS];
+ __le16 cmdq_xoff_threshold;
+ __le16 cmdq_xon_threshold;
+ __le32 reserved1;
+};
+
+struct scsi_ram_per_bdq_resource_drv_data {
+ struct scsi_bdq_ram_drv_data drv_data_per_bdq_id[BDQ_NUM_IDS];
+};
+
+struct scsi_sge {
+ struct regpair sge_addr;
+ __le16 sge_len;
+ __le16 reserved0;
+ __le32 reserved1;
+};
+
+struct scsi_terminate_extra_params {
+ __le16 unsolicited_cq_count;
+ __le16 cmdq_count;
+ u8 reserved[4];
+};
+
+#endif /* __STORAGE_COMMON__ */
diff --git a/include/linux/qed/tcp_common.h b/include/linux/qed/tcp_common.h
new file mode 100644
index 000000000000..accba0e6b704
--- /dev/null
+++ b/include/linux/qed/tcp_common.h
@@ -0,0 +1,226 @@
+/* QLogic qed NIC Driver
+ * Copyright (c) 2015 QLogic Corporation
+ *
+ * This software is available under the terms of the GNU General Public License
+ * (GPL) Version 2, available from the file COPYING in the main directory of
+ * this source tree.
+ */
+
+#ifndef __TCP_COMMON__
+#define __TCP_COMMON__
+
+#define TCP_INVALID_TIMEOUT_VAL -1
+
+enum tcp_connect_mode {
+ TCP_CONNECT_ACTIVE,
+ TCP_CONNECT_PASSIVE,
+ MAX_TCP_CONNECT_MODE
+};
+
+struct tcp_init_params {
+ __le32 max_cwnd;
+ __le16 dup_ack_threshold;
+ __le16 tx_sws_timer;
+ __le16 min_rto;
+ __le16 min_rto_rt;
+ __le16 max_rto;
+ u8 maxfinrt;
+ u8 reserved[1];
+};
+
+enum tcp_ip_version {
+ TCP_IPV4,
+ TCP_IPV6,
+ MAX_TCP_IP_VERSION
+};
+
+struct tcp_offload_params {
+ __le16 local_mac_addr_lo;
+ __le16 local_mac_addr_mid;
+ __le16 local_mac_addr_hi;
+ __le16 remote_mac_addr_lo;
+ __le16 remote_mac_addr_mid;
+ __le16 remote_mac_addr_hi;
+ __le16 vlan_id;
+ u8 flags;
+#define TCP_OFFLOAD_PARAMS_TS_EN_MASK 0x1
+#define TCP_OFFLOAD_PARAMS_TS_EN_SHIFT 0
+#define TCP_OFFLOAD_PARAMS_DA_EN_MASK 0x1
+#define TCP_OFFLOAD_PARAMS_DA_EN_SHIFT 1
+#define TCP_OFFLOAD_PARAMS_KA_EN_MASK 0x1
+#define TCP_OFFLOAD_PARAMS_KA_EN_SHIFT 2
+#define TCP_OFFLOAD_PARAMS_NAGLE_EN_MASK 0x1
+#define TCP_OFFLOAD_PARAMS_NAGLE_EN_SHIFT 3
+#define TCP_OFFLOAD_PARAMS_DA_CNT_EN_MASK 0x1
+#define TCP_OFFLOAD_PARAMS_DA_CNT_EN_SHIFT 4
+#define TCP_OFFLOAD_PARAMS_FIN_SENT_MASK 0x1
+#define TCP_OFFLOAD_PARAMS_FIN_SENT_SHIFT 5
+#define TCP_OFFLOAD_PARAMS_FIN_RECEIVED_MASK 0x1
+#define TCP_OFFLOAD_PARAMS_FIN_RECEIVED_SHIFT 6
+#define TCP_OFFLOAD_PARAMS_RESERVED0_MASK 0x1
+#define TCP_OFFLOAD_PARAMS_RESERVED0_SHIFT 7
+ u8 ip_version;
+ __le32 remote_ip[4];
+ __le32 local_ip[4];
+ __le32 flow_label;
+ u8 ttl;
+ u8 tos_or_tc;
+ __le16 remote_port;
+ __le16 local_port;
+ __le16 mss;
+ u8 rcv_wnd_scale;
+ u8 connect_mode;
+ __le16 srtt;
+ __le32 cwnd;
+ __le32 ss_thresh;
+ __le16 reserved1;
+ u8 ka_max_probe_cnt;
+ u8 dup_ack_theshold;
+ __le32 rcv_next;
+ __le32 snd_una;
+ __le32 snd_next;
+ __le32 snd_max;
+ __le32 snd_wnd;
+ __le32 rcv_wnd;
+ __le32 snd_wl1;
+ __le32 ts_time;
+ __le32 ts_recent;
+ __le32 ts_recent_age;
+ __le32 total_rt;
+ __le32 ka_timeout_delta;
+ __le32 rt_timeout_delta;
+ u8 dup_ack_cnt;
+ u8 snd_wnd_probe_cnt;
+ u8 ka_probe_cnt;
+ u8 rt_cnt;
+ __le16 rtt_var;
+ __le16 reserved2;
+ __le32 ka_timeout;
+ __le32 ka_interval;
+ __le32 max_rt_time;
+ __le32 initial_rcv_wnd;
+ u8 snd_wnd_scale;
+ u8 ack_frequency;
+ __le16 da_timeout_value;
+ __le32 ts_ticks_per_second;
+};
+
+struct tcp_offload_params_opt2 {
+ __le16 local_mac_addr_lo;
+ __le16 local_mac_addr_mid;
+ __le16 local_mac_addr_hi;
+ __le16 remote_mac_addr_lo;
+ __le16 remote_mac_addr_mid;
+ __le16 remote_mac_addr_hi;
+ __le16 vlan_id;
+ u8 flags;
+#define TCP_OFFLOAD_PARAMS_OPT2_TS_EN_MASK 0x1
+#define TCP_OFFLOAD_PARAMS_OPT2_TS_EN_SHIFT 0
+#define TCP_OFFLOAD_PARAMS_OPT2_DA_EN_MASK 0x1
+#define TCP_OFFLOAD_PARAMS_OPT2_DA_EN_SHIFT 1
+#define TCP_OFFLOAD_PARAMS_OPT2_KA_EN_MASK 0x1
+#define TCP_OFFLOAD_PARAMS_OPT2_KA_EN_SHIFT 2
+#define TCP_OFFLOAD_PARAMS_OPT2_RESERVED0_MASK 0x1F
+#define TCP_OFFLOAD_PARAMS_OPT2_RESERVED0_SHIFT 3
+ u8 ip_version;
+ __le32 remote_ip[4];
+ __le32 local_ip[4];
+ __le32 flow_label;
+ u8 ttl;
+ u8 tos_or_tc;
+ __le16 remote_port;
+ __le16 local_port;
+ __le16 mss;
+ u8 rcv_wnd_scale;
+ u8 connect_mode;
+ __le16 syn_ip_payload_length;
+ __le32 syn_phy_addr_lo;
+ __le32 syn_phy_addr_hi;
+ __le32 reserved1[22];
+};
+
+enum tcp_seg_placement_event {
+ TCP_EVENT_ADD_PEN,
+ TCP_EVENT_ADD_NEW_ISLE,
+ TCP_EVENT_ADD_ISLE_RIGHT,
+ TCP_EVENT_ADD_ISLE_LEFT,
+ TCP_EVENT_JOIN,
+ TCP_EVENT_NOP,
+ MAX_TCP_SEG_PLACEMENT_EVENT
+};
+
+struct tcp_update_params {
+ __le16 flags;
+#define TCP_UPDATE_PARAMS_REMOTE_MAC_ADDR_CHANGED_MASK 0x1
+#define TCP_UPDATE_PARAMS_REMOTE_MAC_ADDR_CHANGED_SHIFT 0
+#define TCP_UPDATE_PARAMS_MSS_CHANGED_MASK 0x1
+#define TCP_UPDATE_PARAMS_MSS_CHANGED_SHIFT 1
+#define TCP_UPDATE_PARAMS_TTL_CHANGED_MASK 0x1
+#define TCP_UPDATE_PARAMS_TTL_CHANGED_SHIFT 2
+#define TCP_UPDATE_PARAMS_TOS_OR_TC_CHANGED_MASK 0x1
+#define TCP_UPDATE_PARAMS_TOS_OR_TC_CHANGED_SHIFT 3
+#define TCP_UPDATE_PARAMS_KA_TIMEOUT_CHANGED_MASK 0x1
+#define TCP_UPDATE_PARAMS_KA_TIMEOUT_CHANGED_SHIFT 4
+#define TCP_UPDATE_PARAMS_KA_INTERVAL_CHANGED_MASK 0x1
+#define TCP_UPDATE_PARAMS_KA_INTERVAL_CHANGED_SHIFT 5
+#define TCP_UPDATE_PARAMS_MAX_RT_TIME_CHANGED_MASK 0x1
+#define TCP_UPDATE_PARAMS_MAX_RT_TIME_CHANGED_SHIFT 6
+#define TCP_UPDATE_PARAMS_FLOW_LABEL_CHANGED_MASK 0x1
+#define TCP_UPDATE_PARAMS_FLOW_LABEL_CHANGED_SHIFT 7
+#define TCP_UPDATE_PARAMS_INITIAL_RCV_WND_CHANGED_MASK 0x1
+#define TCP_UPDATE_PARAMS_INITIAL_RCV_WND_CHANGED_SHIFT 8
+#define TCP_UPDATE_PARAMS_KA_MAX_PROBE_CNT_CHANGED_MASK 0x1
+#define TCP_UPDATE_PARAMS_KA_MAX_PROBE_CNT_CHANGED_SHIFT 9
+#define TCP_UPDATE_PARAMS_KA_EN_CHANGED_MASK 0x1
+#define TCP_UPDATE_PARAMS_KA_EN_CHANGED_SHIFT 10
+#define TCP_UPDATE_PARAMS_NAGLE_EN_CHANGED_MASK 0x1
+#define TCP_UPDATE_PARAMS_NAGLE_EN_CHANGED_SHIFT 11
+#define TCP_UPDATE_PARAMS_KA_EN_MASK 0x1
+#define TCP_UPDATE_PARAMS_KA_EN_SHIFT 12
+#define TCP_UPDATE_PARAMS_NAGLE_EN_MASK 0x1
+#define TCP_UPDATE_PARAMS_NAGLE_EN_SHIFT 13
+#define TCP_UPDATE_PARAMS_KA_RESTART_MASK 0x1
+#define TCP_UPDATE_PARAMS_KA_RESTART_SHIFT 14
+#define TCP_UPDATE_PARAMS_RETRANSMIT_RESTART_MASK 0x1
+#define TCP_UPDATE_PARAMS_RETRANSMIT_RESTART_SHIFT 15
+ __le16 remote_mac_addr_lo;
+ __le16 remote_mac_addr_mid;
+ __le16 remote_mac_addr_hi;
+ __le16 mss;
+ u8 ttl;
+ u8 tos_or_tc;
+ __le32 ka_timeout;
+ __le32 ka_interval;
+ __le32 max_rt_time;
+ __le32 flow_label;
+ __le32 initial_rcv_wnd;
+ u8 ka_max_probe_cnt;
+ u8 reserved1[7];
+};
+
+struct tcp_upload_params {
+ __le32 rcv_next;
+ __le32 snd_una;
+ __le32 snd_next;
+ __le32 snd_max;
+ __le32 snd_wnd;
+ __le32 rcv_wnd;
+ __le32 snd_wl1;
+ __le32 cwnd;
+ __le32 ss_thresh;
+ __le16 srtt;
+ __le16 rtt_var;
+ __le32 ts_time;
+ __le32 ts_recent;
+ __le32 ts_recent_age;
+ __le32 total_rt;
+ __le32 ka_timeout_delta;
+ __le32 rt_timeout_delta;
+ u8 dup_ack_cnt;
+ u8 snd_wnd_probe_cnt;
+ u8 ka_probe_cnt;
+ u8 rt_cnt;
+ __le32 reserved;
+};
+
+#endif /* __TCP_COMMON__ */
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 9dfb6bce8c9e..8486d27cf360 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -200,8 +200,8 @@ struct mem_dqblk {
qsize_t dqb_ihardlimit; /* absolute limit on allocated inodes */
qsize_t dqb_isoftlimit; /* preferred inode limit */
qsize_t dqb_curinodes; /* current # allocated inodes */
- time_t dqb_btime; /* time limit for excessive disk use */
- time_t dqb_itime; /* time limit for excessive inode use */
+ time64_t dqb_btime; /* time limit for excessive disk use */
+ time64_t dqb_itime; /* time limit for excessive inode use */
};
/*
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index eca6f626c16e..cbfee507c839 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -291,6 +291,7 @@ unsigned int radix_tree_gang_lookup_slot(struct radix_tree_root *root,
unsigned long first_index, unsigned int max_items);
int radix_tree_preload(gfp_t gfp_mask);
int radix_tree_maybe_preload(gfp_t gfp_mask);
+int radix_tree_maybe_preload_order(gfp_t gfp_mask, int order);
void radix_tree_init(void);
void *radix_tree_tag_set(struct radix_tree_root *root,
unsigned long index, unsigned int tag);
diff --git a/include/linux/random.h b/include/linux/random.h
index e47e533742b5..3d6e9815cd85 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -95,27 +95,27 @@ static inline void prandom_seed_state(struct rnd_state *state, u64 seed)
#ifdef CONFIG_ARCH_RANDOM
# include <asm/archrandom.h>
#else
-static inline int arch_get_random_long(unsigned long *v)
+static inline bool arch_get_random_long(unsigned long *v)
{
return 0;
}
-static inline int arch_get_random_int(unsigned int *v)
+static inline bool arch_get_random_int(unsigned int *v)
{
return 0;
}
-static inline int arch_has_random(void)
+static inline bool arch_has_random(void)
{
return 0;
}
-static inline int arch_get_random_seed_long(unsigned long *v)
+static inline bool arch_get_random_seed_long(unsigned long *v)
{
return 0;
}
-static inline int arch_get_random_seed_int(unsigned int *v)
+static inline bool arch_get_random_seed_int(unsigned int *v)
{
return 0;
}
-static inline int arch_has_random_seed(void)
+static inline bool arch_has_random_seed(void)
{
return 0;
}
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h
index b6900099ea81..e585018498d5 100644
--- a/include/linux/rbtree.h
+++ b/include/linux/rbtree.h
@@ -76,6 +76,8 @@ extern struct rb_node *rb_next_postorder(const struct rb_node *);
/* Fast replacement of a single node without remove/rebalance/add/rebalance */
extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
struct rb_root *root);
+extern void rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new,
+ struct rb_root *root);
static inline void rb_link_node(struct rb_node *node, struct rb_node *parent,
struct rb_node **rb_link)
diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h
index 14d7b831b63a..d076183e49be 100644
--- a/include/linux/rbtree_augmented.h
+++ b/include/linux/rbtree_augmented.h
@@ -130,6 +130,19 @@ __rb_change_child(struct rb_node *old, struct rb_node *new,
WRITE_ONCE(root->rb_node, new);
}
+static inline void
+__rb_change_child_rcu(struct rb_node *old, struct rb_node *new,
+ struct rb_node *parent, struct rb_root *root)
+{
+ if (parent) {
+ if (parent->rb_left == old)
+ rcu_assign_pointer(parent->rb_left, new);
+ else
+ rcu_assign_pointer(parent->rb_right, new);
+ } else
+ rcu_assign_pointer(root->rb_node, new);
+}
+
extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root,
void (*augment_rotate)(struct rb_node *old, struct rb_node *new));
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 5f1533e3d032..1aa62e1a761b 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -45,6 +45,7 @@
#include <linux/bug.h>
#include <linux/compiler.h>
#include <linux/ktime.h>
+#include <linux/irqflags.h>
#include <asm/barrier.h>
@@ -379,12 +380,13 @@ static inline void rcu_init_nohz(void)
* in the inner idle loop.
*
* This macro provides the way out: RCU_NONIDLE(do_something_with_RCU())
- * will tell RCU that it needs to pay attending, invoke its argument
- * (in this example, a call to the do_something_with_RCU() function),
+ * will tell RCU that it needs to pay attention, invoke its argument
+ * (in this example, calling the do_something_with_RCU() function),
* and then tell RCU to go back to ignoring this CPU. It is permissible
- * to nest RCU_NONIDLE() wrappers, but the nesting level is currently
- * quite limited. If deeper nesting is required, it will be necessary
- * to adjust DYNTICK_TASK_NESTING_VALUE accordingly.
+ * to nest RCU_NONIDLE() wrappers, but not indefinitely (but the limit is
+ * on the order of a million or so, even on 32-bit systems). It is
+ * not legal to block within RCU_NONIDLE(), nor is it permissible to
+ * transfer control either into or out of RCU_NONIDLE()'s statement.
*/
#define RCU_NONIDLE(a) \
do { \
@@ -611,6 +613,12 @@ static inline void rcu_preempt_sleep_check(void)
rcu_dereference_sparse(p, space); \
((typeof(*p) __force __kernel *)(p)); \
})
+#define rcu_dereference_raw(p) \
+({ \
+ /* Dependency order vs. p above. */ \
+ typeof(p) ________p1 = lockless_dereference(p); \
+ ((typeof(*p) __force __kernel *)(________p1)); \
+})
/**
* RCU_INITIALIZER() - statically initialize an RCU-protected global variable
@@ -649,7 +657,16 @@ static inline void rcu_preempt_sleep_check(void)
* please be careful when making changes to rcu_assign_pointer() and the
* other macros that it invokes.
*/
-#define rcu_assign_pointer(p, v) smp_store_release(&p, RCU_INITIALIZER(v))
+#define rcu_assign_pointer(p, v) \
+({ \
+ uintptr_t _r_a_p__v = (uintptr_t)(v); \
+ \
+ if (__builtin_constant_p(v) && (_r_a_p__v) == (uintptr_t)NULL) \
+ WRITE_ONCE((p), (typeof(p))(_r_a_p__v)); \
+ else \
+ smp_store_release(&p, RCU_INITIALIZER((typeof(p))_r_a_p__v)); \
+ _r_a_p__v; \
+})
/**
* rcu_access_pointer() - fetch RCU pointer with no dereferencing
@@ -729,8 +746,6 @@ static inline void rcu_preempt_sleep_check(void)
__rcu_dereference_check((p), (c) || rcu_read_lock_sched_held(), \
__rcu)
-#define rcu_dereference_raw(p) rcu_dereference_check(p, 1) /*@@@ needed? @@@*/
-
/*
* The tracing infrastructure traces RCU (we want that), but unfortunately
* some of the RCU checks causes tracing to lock up the system.
diff --git a/include/linux/regmap.h b/include/linux/regmap.h
index 3dc08ce15426..2c12cc5af744 100644
--- a/include/linux/regmap.h
+++ b/include/linux/regmap.h
@@ -95,6 +95,45 @@ struct reg_sequence {
#define regmap_fields_force_update_bits(field, id, mask, val) \
regmap_fields_update_bits_base(field, id, mask, val, NULL, false, true)
+/**
+ * regmap_read_poll_timeout - Poll until a condition is met or a timeout occurs
+ * @map: Regmap to read from
+ * @addr: Address to poll
+ * @val: Unsigned integer variable to read the value into
+ * @cond: Break condition (usually involving @val)
+ * @sleep_us: Maximum time to sleep between reads in us (0
+ * tight-loops). Should be less than ~20ms since usleep_range
+ * is used (see Documentation/timers/timers-howto.txt).
+ * @timeout_us: Timeout in us, 0 means never timeout
+ *
+ * Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_read
+ * error return value in case of a error read. In the two former cases,
+ * the last read value at @addr is stored in @val. Must not be called
+ * from atomic context if sleep_us or timeout_us are used.
+ *
+ * This is modelled after the readx_poll_timeout macros in linux/iopoll.h.
+ */
+#define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_us) \
+({ \
+ ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); \
+ int ret; \
+ might_sleep_if(sleep_us); \
+ for (;;) { \
+ ret = regmap_read((map), (addr), &(val)); \
+ if (ret) \
+ break; \
+ if (cond) \
+ break; \
+ if (timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \
+ ret = regmap_read((map), (addr), &(val)); \
+ break; \
+ } \
+ if (sleep_us) \
+ usleep_range((sleep_us >> 2) + 1, sleep_us); \
+ } \
+ ret ?: ((cond) ? 0 : -ETIMEDOUT); \
+})
+
#ifdef CONFIG_REGMAP
enum regmap_endian {
@@ -851,6 +890,12 @@ struct regmap_irq {
* @num_type_reg: Number of type registers.
* @type_reg_stride: Stride to use for chips where type registers are not
* contiguous.
+ * @handle_pre_irq: Driver specific callback to handle interrupt from device
+ * before regmap_irq_handler process the interrupts.
+ * @handle_post_irq: Driver specific callback to handle interrupt from device
+ * after handling the interrupts in regmap_irq_handler().
+ * @irq_drv_data: Driver specific IRQ data which is passed as parameter when
+ * driver specific pre/post interrupt handler is called.
*/
struct regmap_irq_chip {
const char *name;
@@ -877,6 +922,10 @@ struct regmap_irq_chip {
int num_type_reg;
unsigned int type_reg_stride;
+
+ int (*handle_pre_irq)(void *irq_drv_data);
+ int (*handle_post_irq)(void *irq_drv_data);
+ void *irq_drv_data;
};
struct regmap_irq_chip_data;
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index 48603506f8de..cae500b2c1d7 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -224,7 +224,6 @@ int regulator_bulk_force_disable(int num_consumers,
void regulator_bulk_free(int num_consumers,
struct regulator_bulk_data *consumers);
-int regulator_can_change_voltage(struct regulator *regulator);
int regulator_count_voltages(struct regulator *regulator);
int regulator_list_voltage(struct regulator *regulator, unsigned selector);
int regulator_is_supported_voltage(struct regulator *regulator,
@@ -436,11 +435,6 @@ static inline void regulator_bulk_free(int num_consumers,
{
}
-static inline int regulator_can_change_voltage(struct regulator *regulator)
-{
- return 0;
-}
-
static inline int regulator_set_voltage(struct regulator *regulator,
int min_uV, int max_uV)
{
diff --git a/include/linux/regulator/da9211.h b/include/linux/regulator/da9211.h
index a43a5ca1167b..80cb40b7c88d 100644
--- a/include/linux/regulator/da9211.h
+++ b/include/linux/regulator/da9211.h
@@ -1,5 +1,6 @@
/*
- * da9211.h - Regulator device driver for DA9211/DA9213/DA9215
+ * da9211.h - Regulator device driver for DA9211/DA9212
+ * /DA9213/DA9214/DA9215
* Copyright (C) 2015 Dialog Semiconductor Ltd.
*
* This program is free software; you can redistribute it and/or
@@ -22,7 +23,9 @@
enum da9211_chip_id {
DA9211,
+ DA9212,
DA9213,
+ DA9214,
DA9215,
};
diff --git a/include/linux/regulator/mt6323-regulator.h b/include/linux/regulator/mt6323-regulator.h
new file mode 100644
index 000000000000..67011cd1ce55
--- /dev/null
+++ b/include/linux/regulator/mt6323-regulator.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#ifndef __LINUX_REGULATOR_MT6323_H
+#define __LINUX_REGULATOR_MT6323_H
+
+enum {
+ MT6323_ID_VPROC = 0,
+ MT6323_ID_VSYS,
+ MT6323_ID_VPA,
+ MT6323_ID_VTCXO,
+ MT6323_ID_VCN28,
+ MT6323_ID_VCN33_BT,
+ MT6323_ID_VCN33_WIFI,
+ MT6323_ID_VA,
+ MT6323_ID_VCAMA,
+ MT6323_ID_VIO28 = 9,
+ MT6323_ID_VUSB,
+ MT6323_ID_VMC,
+ MT6323_ID_VMCH,
+ MT6323_ID_VEMC3V3,
+ MT6323_ID_VGP1,
+ MT6323_ID_VGP2,
+ MT6323_ID_VGP3,
+ MT6323_ID_VCN18,
+ MT6323_ID_VSIM1,
+ MT6323_ID_VSIM2,
+ MT6323_ID_VRTC,
+ MT6323_ID_VCAMAF,
+ MT6323_ID_VIBR,
+ MT6323_ID_VRF18,
+ MT6323_ID_VM,
+ MT6323_ID_VIO18,
+ MT6323_ID_VCAMD,
+ MT6323_ID_VCAMIO,
+ MT6323_ID_RG_MAX,
+};
+
+#define MT6323_MAX_REGULATOR MT6323_ID_RG_MAX
+
+#endif /* __LINUX_REGULATOR_MT6323_H */
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 2b0fad83683f..b46bb5620a76 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -165,7 +165,7 @@ void do_page_add_anon_rmap(struct page *, struct vm_area_struct *,
unsigned long, int);
void page_add_new_anon_rmap(struct page *, struct vm_area_struct *,
unsigned long, bool);
-void page_add_file_rmap(struct page *);
+void page_add_file_rmap(struct page *, bool);
void page_remove_rmap(struct page *, bool);
void hugepage_add_anon_rmap(struct page *, struct vm_area_struct *,
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index c006cc900c44..2daece8979f7 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -89,8 +89,9 @@ void net_inc_egress_queue(void);
void net_dec_egress_queue(void);
#endif
-extern void rtnetlink_init(void);
-extern void __rtnl_unlock(void);
+void rtnetlink_init(void);
+void __rtnl_unlock(void);
+void rtnl_kfree_skbs(struct sk_buff *head, struct sk_buff *tail);
#define ASSERT_RTNL() do { \
if (unlikely(!rtnl_is_locked())) { \
diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h
index d37fbb34d06f..dd1d14250340 100644
--- a/include/linux/rwsem.h
+++ b/include/linux/rwsem.h
@@ -23,10 +23,11 @@ struct rw_semaphore;
#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
#include <linux/rwsem-spinlock.h> /* use a generic implementation */
+#define __RWSEM_INIT_COUNT(name) .count = RWSEM_UNLOCKED_VALUE
#else
/* All arch specific implementations share the same struct */
struct rw_semaphore {
- long count;
+ atomic_long_t count;
struct list_head wait_list;
raw_spinlock_t wait_lock;
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
@@ -54,9 +55,10 @@ extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
/* In all implementations count != 0 means locked */
static inline int rwsem_is_locked(struct rw_semaphore *sem)
{
- return sem->count != 0;
+ return atomic_long_read(&sem->count) != 0;
}
+#define __RWSEM_INIT_COUNT(name) .count = ATOMIC_LONG_INIT(RWSEM_UNLOCKED_VALUE)
#endif
/* Common initializer macros and functions */
@@ -74,7 +76,7 @@ static inline int rwsem_is_locked(struct rw_semaphore *sem)
#endif
#define __RWSEM_INITIALIZER(name) \
- { .count = RWSEM_UNLOCKED_VALUE, \
+ { __RWSEM_INIT_COUNT(name), \
.wait_list = LIST_HEAD_INIT((name).wait_list), \
.wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock) \
__RWSEM_OPT_INIT(name) \
diff --git a/include/linux/rxrpc.h b/include/linux/rxrpc.h
index a53915cd5581..c68307bc306f 100644
--- a/include/linux/rxrpc.h
+++ b/include/linux/rxrpc.h
@@ -35,21 +35,24 @@ struct sockaddr_rxrpc {
*/
#define RXRPC_SECURITY_KEY 1 /* [clnt] set client security key */
#define RXRPC_SECURITY_KEYRING 2 /* [srvr] set ring of server security keys */
-#define RXRPC_EXCLUSIVE_CONNECTION 3 /* [clnt] use exclusive RxRPC connection */
+#define RXRPC_EXCLUSIVE_CONNECTION 3 /* Deprecated; use RXRPC_EXCLUSIVE_CALL instead */
#define RXRPC_MIN_SECURITY_LEVEL 4 /* minimum security level */
/*
* RxRPC control messages
+ * - If neither abort or accept are specified, the message is a data message.
* - terminal messages mean that a user call ID tag can be recycled
+ * - s/r/- indicate whether these are applicable to sendmsg() and/or recvmsg()
*/
-#define RXRPC_USER_CALL_ID 1 /* user call ID specifier */
-#define RXRPC_ABORT 2 /* abort request / notification [terminal] */
-#define RXRPC_ACK 3 /* [Server] RPC op final ACK received [terminal] */
-#define RXRPC_NET_ERROR 5 /* network error received [terminal] */
-#define RXRPC_BUSY 6 /* server busy received [terminal] */
-#define RXRPC_LOCAL_ERROR 7 /* local error generated [terminal] */
-#define RXRPC_NEW_CALL 8 /* [Server] new incoming call notification */
-#define RXRPC_ACCEPT 9 /* [Server] accept request */
+#define RXRPC_USER_CALL_ID 1 /* sr: user call ID specifier */
+#define RXRPC_ABORT 2 /* sr: abort request / notification [terminal] */
+#define RXRPC_ACK 3 /* -r: [Service] RPC op final ACK received [terminal] */
+#define RXRPC_NET_ERROR 5 /* -r: network error received [terminal] */
+#define RXRPC_BUSY 6 /* -r: server busy received [terminal] */
+#define RXRPC_LOCAL_ERROR 7 /* -r: local error generated [terminal] */
+#define RXRPC_NEW_CALL 8 /* -r: [Service] new incoming call notification */
+#define RXRPC_ACCEPT 9 /* s-: [Service] accept request */
+#define RXRPC_EXCLUSIVE_CALL 10 /* s-: Call should be on exclusive connection */
/*
* RxRPC security levels
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 253538f29ade..553af2923824 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -219,9 +219,10 @@ extern void proc_sched_set_task(struct task_struct *p);
#define TASK_WAKING 256
#define TASK_PARKED 512
#define TASK_NOLOAD 1024
-#define TASK_STATE_MAX 2048
+#define TASK_NEW 2048
+#define TASK_STATE_MAX 4096
-#define TASK_STATE_TO_CHAR_STR "RSDTtXZxKWPN"
+#define TASK_STATE_TO_CHAR_STR "RSDTtXZxKWPNn"
extern char ___assert_task_state[1 - 2*!!(
sizeof(TASK_STATE_TO_CHAR_STR)-1 != ilog2(TASK_STATE_MAX)+1)];
@@ -522,6 +523,7 @@ static inline int get_dumpable(struct mm_struct *mm)
#define MMF_HAS_UPROBES 19 /* has uprobes */
#define MMF_RECALC_UPROBES 20 /* MMF_HAS_UPROBES can be wrong */
#define MMF_OOM_REAPED 21 /* mm has been already reaped */
+#define MMF_OOM_NOT_REAPABLE 22 /* mm couldn't be reaped */
#define MMF_INIT_MASK (MMF_DUMPABLE_MASK | MMF_DUMP_FILTER_MASK)
@@ -1948,6 +1950,32 @@ static inline int tsk_nr_cpus_allowed(struct task_struct *p)
#define TNF_FAULT_LOCAL 0x08
#define TNF_MIGRATE_FAIL 0x10
+static inline bool in_vfork(struct task_struct *tsk)
+{
+ bool ret;
+
+ /*
+ * need RCU to access ->real_parent if CLONE_VM was used along with
+ * CLONE_PARENT.
+ *
+ * We check real_parent->mm == tsk->mm because CLONE_VFORK does not
+ * imply CLONE_VM
+ *
+ * CLONE_VFORK can be used with CLONE_PARENT/CLONE_THREAD and thus
+ * ->real_parent is not necessarily the task doing vfork(), so in
+ * theory we can't rely on task_lock() if we want to dereference it.
+ *
+ * And in this case we can't trust the real_parent->mm == tsk->mm
+ * check, it can be false negative. But we do not care, if init or
+ * another oom-unkillable task does this it should blame itself.
+ */
+ rcu_read_lock();
+ ret = tsk->vfork_done && tsk->real_parent->mm == tsk->mm;
+ rcu_read_unlock();
+
+ return ret;
+}
+
#ifdef CONFIG_NUMA_BALANCING
extern void task_numa_fault(int last_node, int node, int pages, int flags);
extern pid_t task_numa_group_id(struct task_struct *p);
@@ -2139,6 +2167,9 @@ static inline void put_task_struct(struct task_struct *t)
__put_task_struct(t);
}
+struct task_struct *task_rcu_dereference(struct task_struct **ptask);
+struct task_struct *try_get_task_struct(struct task_struct **ptask);
+
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
extern void task_cputime(struct task_struct *t,
cputime_t *utime, cputime_t *stime);
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 48ec7651989b..923266cd294a 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -111,6 +111,7 @@ struct uart_8250_port {
* if no_console_suspend
*/
unsigned char probe;
+ struct mctrl_gpios *gpios;
#define UART_PROBE_RSA (1 << 0)
/*
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index a3d7c0d4a03e..2f44e2013654 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -352,9 +352,15 @@ struct earlycon_id {
extern const struct earlycon_id __earlycon_table[];
extern const struct earlycon_id __earlycon_table_end[];
+#if defined(CONFIG_SERIAL_EARLYCON) && !defined(MODULE)
+#define EARLYCON_USED_OR_UNUSED __used
+#else
+#define EARLYCON_USED_OR_UNUSED __maybe_unused
+#endif
+
#define OF_EARLYCON_DECLARE(_name, compat, fn) \
static const struct earlycon_id __UNIQUE_ID(__earlycon_##_name) \
- __used __section(__earlycon_table) \
+ EARLYCON_USED_OR_UNUSED __section(__earlycon_table) \
= { .name = __stringify(_name), \
.compatible = compat, \
.setup = fn }
diff --git a/include/linux/sfi.h b/include/linux/sfi.h
index d9b436f09925..e0e1597ef9e6 100644
--- a/include/linux/sfi.h
+++ b/include/linux/sfi.h
@@ -156,6 +156,7 @@ struct sfi_device_table_entry {
#define SFI_DEV_TYPE_UART 2
#define SFI_DEV_TYPE_HSI 3
#define SFI_DEV_TYPE_IPC 4
+#define SFI_DEV_TYPE_SD 5
u8 host_num; /* attached to host 0, 1...*/
u16 addr;
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index 4d4780c00d34..ff078e7043b6 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -16,8 +16,9 @@ struct shmem_inode_info {
unsigned long flags;
unsigned long alloced; /* data pages alloced to file */
unsigned long swapped; /* subtotal assigned to swap */
- struct shared_policy policy; /* NUMA memory alloc policy */
+ struct list_head shrinklist; /* shrinkable hpage inodes */
struct list_head swaplist; /* chain of maybes on swap */
+ struct shared_policy policy; /* NUMA memory alloc policy */
struct simple_xattrs xattrs; /* list of xattrs */
struct inode vfs_inode;
};
@@ -28,10 +29,14 @@ struct shmem_sb_info {
unsigned long max_inodes; /* How many inodes are allowed */
unsigned long free_inodes; /* How many are left for allocation */
spinlock_t stat_lock; /* Serialize shmem_sb_info changes */
+ umode_t mode; /* Mount mode for root directory */
+ unsigned char huge; /* Whether to try for hugepages */
kuid_t uid; /* Mount uid for root directory */
kgid_t gid; /* Mount gid for root directory */
- umode_t mode; /* Mount mode for root directory */
struct mempolicy *mpol; /* default memory policy for mappings */
+ spinlock_t shrinklist_lock; /* Protects shrinklist */
+ struct list_head shrinklist; /* List of shinkable inodes */
+ unsigned long shrinklist_len; /* Length of shrinklist */
};
static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
@@ -49,6 +54,8 @@ extern struct file *shmem_file_setup(const char *name,
extern struct file *shmem_kernel_file_setup(const char *name, loff_t size,
unsigned long flags);
extern int shmem_zero_setup(struct vm_area_struct *);
+extern unsigned long shmem_get_unmapped_area(struct file *, unsigned long addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags);
extern int shmem_lock(struct file *file, int lock, struct user_struct *user);
extern bool shmem_mapping(struct address_space *mapping);
extern void shmem_unlock_mapping(struct address_space *mapping);
@@ -61,6 +68,19 @@ extern unsigned long shmem_swap_usage(struct vm_area_struct *vma);
extern unsigned long shmem_partial_swap_usage(struct address_space *mapping,
pgoff_t start, pgoff_t end);
+/* Flag allocation requirements to shmem_getpage */
+enum sgp_type {
+ SGP_READ, /* don't exceed i_size, don't allocate page */
+ SGP_CACHE, /* don't exceed i_size, may allocate page */
+ SGP_NOHUGE, /* like SGP_CACHE, but no huge pages */
+ SGP_HUGE, /* like SGP_CACHE, huge pages preferred */
+ SGP_WRITE, /* may exceed i_size, may allocate !Uptodate page */
+ SGP_FALLOC, /* like SGP_WRITE, but make existing page Uptodate */
+};
+
+extern int shmem_getpage(struct inode *inode, pgoff_t index,
+ struct page **pagep, enum sgp_type sgp);
+
static inline struct page *shmem_read_mapping_page(
struct address_space *mapping, pgoff_t index)
{
@@ -68,6 +88,18 @@ static inline struct page *shmem_read_mapping_page(
mapping_gfp_mask(mapping));
}
+static inline bool shmem_file(struct file *file)
+{
+ if (!IS_ENABLED(CONFIG_SHMEM))
+ return false;
+ if (!file || !file->f_mapping)
+ return false;
+ return shmem_mapping(file->f_mapping);
+}
+
+extern bool shmem_charge(struct inode *inode, long pages);
+extern void shmem_uncharge(struct inode *inode, long pages);
+
#ifdef CONFIG_TMPFS
extern int shmem_add_seals(struct file *file, unsigned int seals);
@@ -83,4 +115,13 @@ static inline long shmem_fcntl(struct file *f, unsigned int c, unsigned long a)
#endif
+#ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE
+extern bool shmem_huge_enabled(struct vm_area_struct *vma);
+#else
+static inline bool shmem_huge_enabled(struct vm_area_struct *vma)
+{
+ return false;
+}
+#endif
+
#endif
diff --git a/include/linux/skb_array.h b/include/linux/skb_array.h
new file mode 100644
index 000000000000..f4dfade428f0
--- /dev/null
+++ b/include/linux/skb_array.h
@@ -0,0 +1,178 @@
+/*
+ * Definitions for the 'struct skb_array' datastructure.
+ *
+ * Author:
+ * Michael S. Tsirkin <mst@redhat.com>
+ *
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Limited-size FIFO of skbs. Can be used more or less whenever
+ * sk_buff_head can be used, except you need to know the queue size in
+ * advance.
+ * Implemented as a type-safe wrapper around ptr_ring.
+ */
+
+#ifndef _LINUX_SKB_ARRAY_H
+#define _LINUX_SKB_ARRAY_H 1
+
+#ifdef __KERNEL__
+#include <linux/ptr_ring.h>
+#include <linux/skbuff.h>
+#include <linux/if_vlan.h>
+#endif
+
+struct skb_array {
+ struct ptr_ring ring;
+};
+
+/* Might be slightly faster than skb_array_full below, but callers invoking
+ * this in a loop must use a compiler barrier, for example cpu_relax().
+ */
+static inline bool __skb_array_full(struct skb_array *a)
+{
+ return __ptr_ring_full(&a->ring);
+}
+
+static inline bool skb_array_full(struct skb_array *a)
+{
+ return ptr_ring_full(&a->ring);
+}
+
+static inline int skb_array_produce(struct skb_array *a, struct sk_buff *skb)
+{
+ return ptr_ring_produce(&a->ring, skb);
+}
+
+static inline int skb_array_produce_irq(struct skb_array *a, struct sk_buff *skb)
+{
+ return ptr_ring_produce_irq(&a->ring, skb);
+}
+
+static inline int skb_array_produce_bh(struct skb_array *a, struct sk_buff *skb)
+{
+ return ptr_ring_produce_bh(&a->ring, skb);
+}
+
+static inline int skb_array_produce_any(struct skb_array *a, struct sk_buff *skb)
+{
+ return ptr_ring_produce_any(&a->ring, skb);
+}
+
+/* Might be slightly faster than skb_array_empty below, but only safe if the
+ * array is never resized. Also, callers invoking this in a loop must take care
+ * to use a compiler barrier, for example cpu_relax().
+ */
+static inline bool __skb_array_empty(struct skb_array *a)
+{
+ return !__ptr_ring_peek(&a->ring);
+}
+
+static inline bool skb_array_empty(struct skb_array *a)
+{
+ return ptr_ring_empty(&a->ring);
+}
+
+static inline bool skb_array_empty_bh(struct skb_array *a)
+{
+ return ptr_ring_empty_bh(&a->ring);
+}
+
+static inline bool skb_array_empty_irq(struct skb_array *a)
+{
+ return ptr_ring_empty_irq(&a->ring);
+}
+
+static inline bool skb_array_empty_any(struct skb_array *a)
+{
+ return ptr_ring_empty_any(&a->ring);
+}
+
+static inline struct sk_buff *skb_array_consume(struct skb_array *a)
+{
+ return ptr_ring_consume(&a->ring);
+}
+
+static inline struct sk_buff *skb_array_consume_irq(struct skb_array *a)
+{
+ return ptr_ring_consume_irq(&a->ring);
+}
+
+static inline struct sk_buff *skb_array_consume_any(struct skb_array *a)
+{
+ return ptr_ring_consume_any(&a->ring);
+}
+
+static inline struct sk_buff *skb_array_consume_bh(struct skb_array *a)
+{
+ return ptr_ring_consume_bh(&a->ring);
+}
+
+static inline int __skb_array_len_with_tag(struct sk_buff *skb)
+{
+ if (likely(skb)) {
+ int len = skb->len;
+
+ if (skb_vlan_tag_present(skb))
+ len += VLAN_HLEN;
+
+ return len;
+ } else {
+ return 0;
+ }
+}
+
+static inline int skb_array_peek_len(struct skb_array *a)
+{
+ return PTR_RING_PEEK_CALL(&a->ring, __skb_array_len_with_tag);
+}
+
+static inline int skb_array_peek_len_irq(struct skb_array *a)
+{
+ return PTR_RING_PEEK_CALL_IRQ(&a->ring, __skb_array_len_with_tag);
+}
+
+static inline int skb_array_peek_len_bh(struct skb_array *a)
+{
+ return PTR_RING_PEEK_CALL_BH(&a->ring, __skb_array_len_with_tag);
+}
+
+static inline int skb_array_peek_len_any(struct skb_array *a)
+{
+ return PTR_RING_PEEK_CALL_ANY(&a->ring, __skb_array_len_with_tag);
+}
+
+static inline int skb_array_init(struct skb_array *a, int size, gfp_t gfp)
+{
+ return ptr_ring_init(&a->ring, size, gfp);
+}
+
+static void __skb_array_destroy_skb(void *ptr)
+{
+ kfree_skb(ptr);
+}
+
+static inline int skb_array_resize(struct skb_array *a, int size, gfp_t gfp)
+{
+ return ptr_ring_resize(&a->ring, size, gfp, __skb_array_destroy_skb);
+}
+
+static inline int skb_array_resize_multiple(struct skb_array **rings,
+ int nrings, int size, gfp_t gfp)
+{
+ BUILD_BUG_ON(offsetof(struct skb_array, ring));
+ return ptr_ring_resize_multiple((struct ptr_ring **)rings,
+ nrings, size, gfp,
+ __skb_array_destroy_skb);
+}
+
+static inline void skb_array_cleanup(struct skb_array *a)
+{
+ ptr_ring_cleanup(&a->ring, __skb_array_destroy_skb);
+}
+
+#endif /* _LINUX_SKB_ARRAY_H */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index f39b37180c41..6f0b3e0adc73 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -37,6 +37,7 @@
#include <net/flow_dissector.h>
#include <linux/splice.h>
#include <linux/in6.h>
+#include <linux/if_packet.h>
#include <net/flow.h>
/* The interface for checksum offload between the stack and networking drivers
@@ -301,6 +302,11 @@ struct sk_buff;
#endif
extern int sysctl_max_skb_frags;
+/* Set skb_shinfo(skb)->gso_size to this in case you want skb_segment to
+ * segment using its current segmentation instead.
+ */
+#define GSO_BY_FRAGS 0xFFFF
+
typedef struct skb_frag_struct skb_frag_t;
struct skb_frag_struct {
@@ -482,6 +488,8 @@ enum {
SKB_GSO_PARTIAL = 1 << 13,
SKB_GSO_TUNNEL_REMCSUM = 1 << 14,
+
+ SKB_GSO_SCTP = 1 << 15,
};
#if BITS_PER_LONG > 32
@@ -874,6 +882,15 @@ static inline struct rtable *skb_rtable(const struct sk_buff *skb)
return (struct rtable *)skb_dst(skb);
}
+/* For mangling skb->pkt_type from user space side from applications
+ * such as nft, tc, etc, we only allow a conservative subset of
+ * possible pkt_types to be set.
+*/
+static inline bool skb_pkt_type_ok(u32 ptype)
+{
+ return ptype <= PACKET_OTHERHOST;
+}
+
void kfree_skb(struct sk_buff *skb);
void kfree_skb_list(struct sk_buff *segs);
void skb_tx_error(struct sk_buff *skb);
@@ -3007,6 +3024,7 @@ void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len);
int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen);
void skb_scrub_packet(struct sk_buff *skb, bool xnet);
unsigned int skb_gso_transport_seglen(const struct sk_buff *skb);
+bool skb_gso_validate_mtu(const struct sk_buff *skb, unsigned int mtu);
struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features);
struct sk_buff *skb_vlan_untag(struct sk_buff *skb);
int skb_ensure_writable(struct sk_buff *skb, int write_len);
diff --git a/include/linux/slab.h b/include/linux/slab.h
index aeb3e6d00a66..1a4ea551aae5 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -565,6 +565,8 @@ static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags)
{
if (size != 0 && n > SIZE_MAX / size)
return NULL;
+ if (__builtin_constant_p(n) && __builtin_constant_p(size))
+ return kmalloc(n * size, flags);
return __kmalloc(n * size, flags);
}
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
index 8694f7a5d92b..4ad2c5a26399 100644
--- a/include/linux/slab_def.h
+++ b/include/linux/slab_def.h
@@ -81,14 +81,15 @@ struct kmem_cache {
#endif
#ifdef CONFIG_SLAB_FREELIST_RANDOM
- void *random_seq;
+ unsigned int *random_seq;
#endif
struct kmem_cache_node *node[MAX_NUMNODES];
};
static inline void *nearest_obj(struct kmem_cache *cache, struct page *page,
- void *x) {
+ void *x)
+{
void *object = x - (x - page->s_mem) % cache->size;
void *last_object = page->s_mem + (cache->num - 1) * cache->size;
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index d1faa019c02a..75f56c2ef2d4 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -99,6 +99,15 @@ struct kmem_cache {
*/
int remote_node_defrag_ratio;
#endif
+
+#ifdef CONFIG_SLAB_FREELIST_RANDOM
+ unsigned int *random_seq;
+#endif
+
+#ifdef CONFIG_KASAN
+ struct kasan_cache kasan_info;
+#endif
+
struct kmem_cache_node *node[MAX_NUMNODES];
};
@@ -114,15 +123,17 @@ static inline void sysfs_slab_remove(struct kmem_cache *s)
void object_err(struct kmem_cache *s, struct page *page,
u8 *object, char *reason);
+void *fixup_red_left(struct kmem_cache *s, void *p);
+
static inline void *nearest_obj(struct kmem_cache *cache, struct page *page,
void *x) {
void *object = x - (x - page_address(page)) % cache->size;
void *last_object = page_address(page) +
(page->objects - 1) * cache->size;
- if (unlikely(object > last_object))
- return last_object;
- else
- return object;
+ void *result = (unlikely(object > last_object)) ? last_object : object;
+
+ result = fixup_red_left(cache, result);
+ return result;
}
#endif /* _LINUX_SLUB_DEF_H */
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 1f03483f61e5..072cb2aa2413 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -312,8 +312,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
* @flags: other constraints relevant to this driver
* @max_transfer_size: function that returns the max transfer size for
* a &spi_device; may be %NULL, so the default %SIZE_MAX will be used.
+ * @io_mutex: mutex for physical bus access
* @bus_lock_spinlock: spinlock for SPI bus locking
- * @bus_lock_mutex: mutex for SPI bus locking
+ * @bus_lock_mutex: mutex for exclusion of multiple callers
* @bus_lock_flag: indicates that the SPI bus is locked for exclusive use
* @setup: updates the device mode and clocking records used by a
* device's SPI controller; protocol code may call this. This
@@ -446,6 +447,9 @@ struct spi_master {
*/
size_t (*max_transfer_size)(struct spi_device *spi);
+ /* I/O mutex */
+ struct mutex io_mutex;
+
/* lock and mutex for SPI bus locking */
spinlock_t bus_lock_spinlock;
struct mutex bus_lock_mutex;
@@ -1143,6 +1147,8 @@ static inline ssize_t spi_w8r16be(struct spi_device *spi, u8 cmd)
* @opcode_nbits: number of lines to send opcode
* @addr_nbits: number of lines to send address
* @data_nbits: number of lines for data
+ * @rx_sg: Scatterlist for receive data read from flash
+ * @cur_msg_mapped: message has been mapped for DMA
*/
struct spi_flash_read_message {
void *buf;
@@ -1155,6 +1161,8 @@ struct spi_flash_read_message {
u8 opcode_nbits;
u8 addr_nbits;
u8 data_nbits;
+ struct sg_table rx_sg;
+ bool cur_msg_mapped;
};
/* SPI core interface for flash read support */
diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h
index 8b3ac0d718eb..0d9848de677d 100644
--- a/include/linux/spinlock_up.h
+++ b/include/linux/spinlock_up.h
@@ -6,6 +6,7 @@
#endif
#include <asm/processor.h> /* for cpu_relax() */
+#include <asm/barrier.h>
/*
* include/linux/spinlock_up.h - UP-debug version of spinlocks.
@@ -25,6 +26,11 @@
#ifdef CONFIG_DEBUG_SPINLOCK
#define arch_spin_is_locked(x) ((x)->slock == 0)
+static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
+{
+ smp_cond_load_acquire(&lock->slock, VAL);
+}
+
static inline void arch_spin_lock(arch_spinlock_t *lock)
{
lock->slock = 0;
@@ -67,6 +73,7 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
#else /* DEBUG_SPINLOCK */
#define arch_spin_is_locked(lock) ((void)(lock), 0)
+#define arch_spin_unlock_wait(lock) do { barrier(); (void)(lock); } while (0)
/* for sched/core.c and kernel_lock.c: */
# define arch_spin_lock(lock) do { barrier(); (void)(lock); } while (0)
# define arch_spin_lock_flags(lock, flags) do { barrier(); (void)(lock); } while (0)
@@ -79,7 +86,4 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
#define arch_read_can_lock(lock) (((void)(lock), 1))
#define arch_write_can_lock(lock) (((void)(lock), 1))
-#define arch_spin_unlock_wait(lock) \
- do { cpu_relax(); } while (arch_spin_is_locked(lock))
-
#endif /* __LINUX_SPINLOCK_UP_H */
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index ffdaca9c01af..705840e0438f 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -135,9 +135,12 @@ struct plat_stmmacenet_data {
void (*bus_setup)(void __iomem *ioaddr);
int (*init)(struct platform_device *pdev, void *priv);
void (*exit)(struct platform_device *pdev, void *priv);
+ void (*suspend)(struct platform_device *pdev, void *priv);
+ void (*resume)(struct platform_device *pdev, void *priv);
void *bsp_priv;
struct stmmac_axi *axi;
int has_gmac4;
bool tso_en;
+ int mac_port_sel_speed;
};
#endif
diff --git a/include/linux/stringhash.h b/include/linux/stringhash.h
index 451771d9b9c0..7c2d95170d01 100644
--- a/include/linux/stringhash.h
+++ b/include/linux/stringhash.h
@@ -3,6 +3,7 @@
#include <linux/compiler.h> /* For __pure */
#include <linux/types.h> /* For u32, u64 */
+#include <linux/hash.h>
/*
* Routines for hashing strings of bytes to a 32-bit hash value.
@@ -34,7 +35,7 @@
*/
/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */
-#define init_name_hash() 0
+#define init_name_hash(salt) (unsigned long)(salt)
/* partial hash update function. Assume roughly 4 bits per character */
static inline unsigned long
@@ -45,11 +46,12 @@ partial_name_hash(unsigned long c, unsigned long prevhash)
/*
* Finally: cut down the number of bits to a int value (and try to avoid
- * losing bits)
+ * losing bits). This also has the property (wanted by the dcache)
+ * that the msbits make a good hash table index.
*/
static inline unsigned long end_name_hash(unsigned long hash)
{
- return (unsigned int)hash;
+ return __hash_32((unsigned int)hash);
}
/*
@@ -60,7 +62,7 @@ static inline unsigned long end_name_hash(unsigned long hash)
*
* If not set, this falls back to a wrapper around the preceding.
*/
-extern unsigned int __pure full_name_hash(const char *, unsigned int);
+extern unsigned int __pure full_name_hash(const void *salt, const char *, unsigned int);
/*
* A hash_len is a u64 with the hash of a string in the low
@@ -71,6 +73,6 @@ extern unsigned int __pure full_name_hash(const char *, unsigned int);
#define hashlen_create(hash, len) ((u64)(len)<<32 | (u32)(hash))
/* Return the "hash_len" (hash and length) of a null-terminated string */
-extern u64 __pure hashlen_string(const char *name);
+extern u64 __pure hashlen_string(const void *salt, const char *name);
#endif /* __LINUX_STRINGHASH_H */
diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h
index 91d5a5d6f52b..d03932055328 100644
--- a/include/linux/sunrpc/svcauth.h
+++ b/include/linux/sunrpc/svcauth.h
@@ -172,12 +172,12 @@ extern void unix_gid_cache_destroy(struct net *net);
*/
static inline unsigned long hash_str(char const *name, int bits)
{
- return hashlen_hash(hashlen_string(name)) >> (32 - bits);
+ return hashlen_hash(hashlen_string(NULL, name)) >> (32 - bits);
}
static inline unsigned long hash_mem(char const *buf, int length, int bits)
{
- return full_name_hash(buf, length) >> (32 - bits);
+ return full_name_hash(NULL, buf, length) >> (32 - bits);
}
#endif /* __KERNEL__ */
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 8b6ec7ef0854..7693e39b14fe 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -18,12 +18,11 @@ static inline void pm_set_vt_switch(int do_switch)
#endif
#ifdef CONFIG_VT_CONSOLE_SLEEP
-extern int pm_prepare_console(void);
+extern void pm_prepare_console(void);
extern void pm_restore_console(void);
#else
-static inline int pm_prepare_console(void)
+static inline void pm_prepare_console(void)
{
- return 0;
}
static inline void pm_restore_console(void)
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 0af2bb2028fd..b17cc4830fa6 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -157,15 +157,6 @@ enum {
#define SWAP_CLUSTER_MAX 32UL
#define COMPACT_CLUSTER_MAX SWAP_CLUSTER_MAX
-/*
- * Ratio between zone->managed_pages and the "gap" that above the per-zone
- * "high_wmark". While balancing nodes, We allow kswapd to shrink zones that
- * do not meet the (high_wmark + gap) watermark, even which already met the
- * high_wmark, in order to provide better per-zone lru behavior. We are ok to
- * spend not more than 1% of the memory for this zone balancing "gap".
- */
-#define KSWAPD_ZONE_BALANCE_GAP_RATIO 100
-
#define SWAP_MAP_MAX 0x3e /* Max duplication count, in first swap_map */
#define SWAP_MAP_BAD 0x3f /* Note pageblock is bad, in first swap_map */
#define SWAP_HAS_CACHE 0x40 /* Flag page is cached, in first swap_map */
@@ -317,6 +308,7 @@ extern void lru_cache_add_active_or_unevictable(struct page *page,
/* linux/mm/vmscan.c */
extern unsigned long zone_reclaimable_pages(struct zone *zone);
+extern unsigned long pgdat_reclaimable_pages(struct pglist_data *pgdat);
extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
gfp_t gfp_mask, nodemask_t *mask);
extern int __isolate_lru_page(struct page *page, isolate_mode_t mode);
@@ -324,9 +316,9 @@ extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
unsigned long nr_pages,
gfp_t gfp_mask,
bool may_swap);
-extern unsigned long mem_cgroup_shrink_node_zone(struct mem_cgroup *mem,
+extern unsigned long mem_cgroup_shrink_node(struct mem_cgroup *mem,
gfp_t gfp_mask, bool noswap,
- struct zone *zone,
+ pg_data_t *pgdat,
unsigned long *nr_scanned);
extern unsigned long shrink_all_memory(unsigned long nr_pages);
extern int vm_swappiness;
@@ -334,13 +326,14 @@ extern int remove_mapping(struct address_space *mapping, struct page *page);
extern unsigned long vm_total_pages;
#ifdef CONFIG_NUMA
-extern int zone_reclaim_mode;
+extern int node_reclaim_mode;
extern int sysctl_min_unmapped_ratio;
extern int sysctl_min_slab_ratio;
-extern int zone_reclaim(struct zone *, gfp_t, unsigned int);
+extern int node_reclaim(struct pglist_data *, gfp_t, unsigned int);
#else
-#define zone_reclaim_mode 0
-static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order)
+#define node_reclaim_mode 0
+static inline int node_reclaim(struct pglist_data *pgdat, gfp_t mask,
+ unsigned int order)
{
return 0;
}
diff --git a/include/linux/ti_wilink_st.h b/include/linux/ti_wilink_st.h
index 0a0d56834c8e..f2293028ab9d 100644
--- a/include/linux/ti_wilink_st.h
+++ b/include/linux/ti_wilink_st.h
@@ -71,7 +71,7 @@ struct st_proto_s {
enum proto_type type;
long (*recv) (void *, struct sk_buff *);
unsigned char (*match_packet) (const unsigned char *data);
- void (*reg_complete_cb) (void *, char data);
+ void (*reg_complete_cb) (void *, int data);
long (*write) (struct sk_buff *skb);
void *priv_data;
diff --git a/include/linux/time.h b/include/linux/time.h
index 297f09f23896..4cea09d94208 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -205,7 +205,20 @@ struct tm {
int tm_yday;
};
-void time_to_tm(time_t totalsecs, int offset, struct tm *result);
+void time64_to_tm(time64_t totalsecs, int offset, struct tm *result);
+
+/**
+ * time_to_tm - converts the calendar time to local broken-down time
+ *
+ * @totalsecs the number of seconds elapsed since 00:00:00 on January 1, 1970,
+ * Coordinated Universal Time (UTC).
+ * @offset offset seconds adding to totalsecs.
+ * @result pointer to struct tm variable to receive broken-down time
+ */
+static inline void time_to_tm(time_t totalsecs, int offset, struct tm *result)
+{
+ time64_to_tm(totalsecs, offset, result);
+}
/**
* timespec_to_ns - Convert timespec to nanoseconds
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 20ac746f3eb3..4419506b564e 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -19,7 +19,6 @@ struct timer_list {
void (*function)(unsigned long);
unsigned long data;
u32 flags;
- int slack;
#ifdef CONFIG_TIMER_STATS
int start_pid;
@@ -58,11 +57,14 @@ struct timer_list {
* workqueue locking issues. It's not meant for executing random crap
* with interrupts disabled. Abuse is monitored!
*/
-#define TIMER_CPUMASK 0x0007FFFF
-#define TIMER_MIGRATING 0x00080000
+#define TIMER_CPUMASK 0x0003FFFF
+#define TIMER_MIGRATING 0x00040000
#define TIMER_BASEMASK (TIMER_CPUMASK | TIMER_MIGRATING)
-#define TIMER_DEFERRABLE 0x00100000
+#define TIMER_DEFERRABLE 0x00080000
+#define TIMER_PINNED 0x00100000
#define TIMER_IRQSAFE 0x00200000
+#define TIMER_ARRAYSHIFT 22
+#define TIMER_ARRAYMASK 0xFFC00000
#define __TIMER_INITIALIZER(_function, _expires, _data, _flags) { \
.entry = { .next = TIMER_ENTRY_STATIC }, \
@@ -70,7 +72,6 @@ struct timer_list {
.expires = (_expires), \
.data = (_data), \
.flags = (_flags), \
- .slack = -1, \
__TIMER_LOCKDEP_MAP_INITIALIZER( \
__FILE__ ":" __stringify(__LINE__)) \
}
@@ -78,9 +79,15 @@ struct timer_list {
#define TIMER_INITIALIZER(_function, _expires, _data) \
__TIMER_INITIALIZER((_function), (_expires), (_data), 0)
+#define TIMER_PINNED_INITIALIZER(_function, _expires, _data) \
+ __TIMER_INITIALIZER((_function), (_expires), (_data), TIMER_PINNED)
+
#define TIMER_DEFERRED_INITIALIZER(_function, _expires, _data) \
__TIMER_INITIALIZER((_function), (_expires), (_data), TIMER_DEFERRABLE)
+#define TIMER_PINNED_DEFERRED_INITIALIZER(_function, _expires, _data) \
+ __TIMER_INITIALIZER((_function), (_expires), (_data), TIMER_DEFERRABLE | TIMER_PINNED)
+
#define DEFINE_TIMER(_name, _function, _expires, _data) \
struct timer_list _name = \
TIMER_INITIALIZER(_function, _expires, _data)
@@ -124,8 +131,12 @@ static inline void init_timer_on_stack_key(struct timer_list *timer,
#define init_timer(timer) \
__init_timer((timer), 0)
+#define init_timer_pinned(timer) \
+ __init_timer((timer), TIMER_PINNED)
#define init_timer_deferrable(timer) \
__init_timer((timer), TIMER_DEFERRABLE)
+#define init_timer_pinned_deferrable(timer) \
+ __init_timer((timer), TIMER_DEFERRABLE | TIMER_PINNED)
#define init_timer_on_stack(timer) \
__init_timer_on_stack((timer), 0)
@@ -145,12 +156,20 @@ static inline void init_timer_on_stack_key(struct timer_list *timer,
#define setup_timer(timer, fn, data) \
__setup_timer((timer), (fn), (data), 0)
+#define setup_pinned_timer(timer, fn, data) \
+ __setup_timer((timer), (fn), (data), TIMER_PINNED)
#define setup_deferrable_timer(timer, fn, data) \
__setup_timer((timer), (fn), (data), TIMER_DEFERRABLE)
+#define setup_pinned_deferrable_timer(timer, fn, data) \
+ __setup_timer((timer), (fn), (data), TIMER_DEFERRABLE | TIMER_PINNED)
#define setup_timer_on_stack(timer, fn, data) \
__setup_timer_on_stack((timer), (fn), (data), 0)
+#define setup_pinned_timer_on_stack(timer, fn, data) \
+ __setup_timer_on_stack((timer), (fn), (data), TIMER_PINNED)
#define setup_deferrable_timer_on_stack(timer, fn, data) \
__setup_timer_on_stack((timer), (fn), (data), TIMER_DEFERRABLE)
+#define setup_pinned_deferrable_timer_on_stack(timer, fn, data) \
+ __setup_timer_on_stack((timer), (fn), (data), TIMER_DEFERRABLE | TIMER_PINNED)
/**
* timer_pending - is a timer pending?
@@ -171,12 +190,7 @@ extern void add_timer_on(struct timer_list *timer, int cpu);
extern int del_timer(struct timer_list * timer);
extern int mod_timer(struct timer_list *timer, unsigned long expires);
extern int mod_timer_pending(struct timer_list *timer, unsigned long expires);
-extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires);
-
-extern void set_timer_slack(struct timer_list *time, int slack_hz);
-#define TIMER_NOT_PINNED 0
-#define TIMER_PINNED 1
/*
* The jiffies value which is added to now, when there is no timer
* in the timer wheel:
diff --git a/include/linux/topology.h b/include/linux/topology.h
index afce69296ac0..cb0775e1ee4b 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -54,7 +54,7 @@ int arch_update_cpu_topology(void);
/*
* If the distance between nodes in a system is larger than RECLAIM_DISTANCE
* (in whatever arch specific measurement units returned by node_distance())
- * and zone_reclaim_mode is enabled then the VM will only call zone_reclaim()
+ * and node_reclaim_mode is enabled then the VM will only call node_reclaim()
* on nodes within this distance.
*/
#define RECLAIM_DISTANCE 30
diff --git a/include/linux/torture.h b/include/linux/torture.h
index 7759fc3c622d..6685a73736a2 100644
--- a/include/linux/torture.h
+++ b/include/linux/torture.h
@@ -50,6 +50,10 @@
do { if (verbose) pr_alert("%s" TORTURE_FLAG "!!! %s\n", torture_type, s); } while (0)
/* Definitions for online/offline exerciser. */
+bool torture_offline(int cpu, long *n_onl_attempts, long *n_onl_successes,
+ unsigned long *sum_offl, int *min_onl, int *max_onl);
+bool torture_online(int cpu, long *n_onl_attempts, long *n_onl_successes,
+ unsigned long *sum_onl, int *min_onl, int *max_onl);
int torture_onoff_init(long ooholdoff, long oointerval);
void torture_onoff_stats(void);
bool torture_onoff_failures(void);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index fefe8b06a63d..612dbdfa388e 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -25,6 +25,8 @@
#include <linux/workqueue.h>
#include <linux/usb/ch9.h>
+#define UDC_TRACE_STR_MAX 512
+
struct usb_ep;
/**
@@ -228,307 +230,49 @@ struct usb_ep {
/*-------------------------------------------------------------------------*/
-/**
- * usb_ep_set_maxpacket_limit - set maximum packet size limit for endpoint
- * @ep:the endpoint being configured
- * @maxpacket_limit:value of maximum packet size limit
- *
- * This function should be used only in UDC drivers to initialize endpoint
- * (usually in probe function).
- */
+#if IS_ENABLED(CONFIG_USB_GADGET)
+void usb_ep_set_maxpacket_limit(struct usb_ep *ep, unsigned maxpacket_limit);
+int usb_ep_enable(struct usb_ep *ep);
+int usb_ep_disable(struct usb_ep *ep);
+struct usb_request *usb_ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags);
+void usb_ep_free_request(struct usb_ep *ep, struct usb_request *req);
+int usb_ep_queue(struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags);
+int usb_ep_dequeue(struct usb_ep *ep, struct usb_request *req);
+int usb_ep_set_halt(struct usb_ep *ep);
+int usb_ep_clear_halt(struct usb_ep *ep);
+int usb_ep_set_wedge(struct usb_ep *ep);
+int usb_ep_fifo_status(struct usb_ep *ep);
+void usb_ep_fifo_flush(struct usb_ep *ep);
+#else
static inline void usb_ep_set_maxpacket_limit(struct usb_ep *ep,
- unsigned maxpacket_limit)
-{
- ep->maxpacket_limit = maxpacket_limit;
- ep->maxpacket = maxpacket_limit;
-}
-
-/**
- * usb_ep_enable - configure endpoint, making it usable
- * @ep:the endpoint being configured. may not be the endpoint named "ep0".
- * drivers discover endpoints through the ep_list of a usb_gadget.
- *
- * When configurations are set, or when interface settings change, the driver
- * will enable or disable the relevant endpoints. while it is enabled, an
- * endpoint may be used for i/o until the driver receives a disconnect() from
- * the host or until the endpoint is disabled.
- *
- * the ep0 implementation (which calls this routine) must ensure that the
- * hardware capabilities of each endpoint match the descriptor provided
- * for it. for example, an endpoint named "ep2in-bulk" would be usable
- * for interrupt transfers as well as bulk, but it likely couldn't be used
- * for iso transfers or for endpoint 14. some endpoints are fully
- * configurable, with more generic names like "ep-a". (remember that for
- * USB, "in" means "towards the USB master".)
- *
- * returns zero, or a negative error code.
- */
+ unsigned maxpacket_limit)
+{ }
static inline int usb_ep_enable(struct usb_ep *ep)
-{
- int ret;
-
- if (ep->enabled)
- return 0;
-
- ret = ep->ops->enable(ep, ep->desc);
- if (ret)
- return ret;
-
- ep->enabled = true;
-
- return 0;
-}
-
-/**
- * usb_ep_disable - endpoint is no longer usable
- * @ep:the endpoint being unconfigured. may not be the endpoint named "ep0".
- *
- * no other task may be using this endpoint when this is called.
- * any pending and uncompleted requests will complete with status
- * indicating disconnect (-ESHUTDOWN) before this call returns.
- * gadget drivers must call usb_ep_enable() again before queueing
- * requests to the endpoint.
- *
- * returns zero, or a negative error code.
- */
+{ return 0; }
static inline int usb_ep_disable(struct usb_ep *ep)
-{
- int ret;
-
- if (!ep->enabled)
- return 0;
-
- ret = ep->ops->disable(ep);
- if (ret)
- return ret;
-
- ep->enabled = false;
-
- return 0;
-}
-
-/**
- * usb_ep_alloc_request - allocate a request object to use with this endpoint
- * @ep:the endpoint to be used with with the request
- * @gfp_flags:GFP_* flags to use
- *
- * Request objects must be allocated with this call, since they normally
- * need controller-specific setup and may even need endpoint-specific
- * resources such as allocation of DMA descriptors.
- * Requests may be submitted with usb_ep_queue(), and receive a single
- * completion callback. Free requests with usb_ep_free_request(), when
- * they are no longer needed.
- *
- * Returns the request, or null if one could not be allocated.
- */
+{ return 0; }
static inline struct usb_request *usb_ep_alloc_request(struct usb_ep *ep,
- gfp_t gfp_flags)
-{
- return ep->ops->alloc_request(ep, gfp_flags);
-}
-
-/**
- * usb_ep_free_request - frees a request object
- * @ep:the endpoint associated with the request
- * @req:the request being freed
- *
- * Reverses the effect of usb_ep_alloc_request().
- * Caller guarantees the request is not queued, and that it will
- * no longer be requeued (or otherwise used).
- */
+ gfp_t gfp_flags)
+{ return NULL; }
static inline void usb_ep_free_request(struct usb_ep *ep,
- struct usb_request *req)
-{
- ep->ops->free_request(ep, req);
-}
-
-/**
- * usb_ep_queue - queues (submits) an I/O request to an endpoint.
- * @ep:the endpoint associated with the request
- * @req:the request being submitted
- * @gfp_flags: GFP_* flags to use in case the lower level driver couldn't
- * pre-allocate all necessary memory with the request.
- *
- * This tells the device controller to perform the specified request through
- * that endpoint (reading or writing a buffer). When the request completes,
- * including being canceled by usb_ep_dequeue(), the request's completion
- * routine is called to return the request to the driver. Any endpoint
- * (except control endpoints like ep0) may have more than one transfer
- * request queued; they complete in FIFO order. Once a gadget driver
- * submits a request, that request may not be examined or modified until it
- * is given back to that driver through the completion callback.
- *
- * Each request is turned into one or more packets. The controller driver
- * never merges adjacent requests into the same packet. OUT transfers
- * will sometimes use data that's already buffered in the hardware.
- * Drivers can rely on the fact that the first byte of the request's buffer
- * always corresponds to the first byte of some USB packet, for both
- * IN and OUT transfers.
- *
- * Bulk endpoints can queue any amount of data; the transfer is packetized
- * automatically. The last packet will be short if the request doesn't fill it
- * out completely. Zero length packets (ZLPs) should be avoided in portable
- * protocols since not all usb hardware can successfully handle zero length
- * packets. (ZLPs may be explicitly written, and may be implicitly written if
- * the request 'zero' flag is set.) Bulk endpoints may also be used
- * for interrupt transfers; but the reverse is not true, and some endpoints
- * won't support every interrupt transfer. (Such as 768 byte packets.)
- *
- * Interrupt-only endpoints are less functional than bulk endpoints, for
- * example by not supporting queueing or not handling buffers that are
- * larger than the endpoint's maxpacket size. They may also treat data
- * toggle differently.
- *
- * Control endpoints ... after getting a setup() callback, the driver queues
- * one response (even if it would be zero length). That enables the
- * status ack, after transferring data as specified in the response. Setup
- * functions may return negative error codes to generate protocol stalls.
- * (Note that some USB device controllers disallow protocol stall responses
- * in some cases.) When control responses are deferred (the response is
- * written after the setup callback returns), then usb_ep_set_halt() may be
- * used on ep0 to trigger protocol stalls. Depending on the controller,
- * it may not be possible to trigger a status-stage protocol stall when the
- * data stage is over, that is, from within the response's completion
- * routine.
- *
- * For periodic endpoints, like interrupt or isochronous ones, the usb host
- * arranges to poll once per interval, and the gadget driver usually will
- * have queued some data to transfer at that time.
- *
- * Returns zero, or a negative error code. Endpoints that are not enabled
- * report errors; errors will also be
- * reported when the usb peripheral is disconnected.
- */
-static inline int usb_ep_queue(struct usb_ep *ep,
- struct usb_request *req, gfp_t gfp_flags)
-{
- if (WARN_ON_ONCE(!ep->enabled && ep->address))
- return -ESHUTDOWN;
-
- return ep->ops->queue(ep, req, gfp_flags);
-}
-
-/**
- * usb_ep_dequeue - dequeues (cancels, unlinks) an I/O request from an endpoint
- * @ep:the endpoint associated with the request
- * @req:the request being canceled
- *
- * If the request is still active on the endpoint, it is dequeued and its
- * completion routine is called (with status -ECONNRESET); else a negative
- * error code is returned. This is guaranteed to happen before the call to
- * usb_ep_dequeue() returns.
- *
- * Note that some hardware can't clear out write fifos (to unlink the request
- * at the head of the queue) except as part of disconnecting from usb. Such
- * restrictions prevent drivers from supporting configuration changes,
- * even to configuration zero (a "chapter 9" requirement).
- */
+ struct usb_request *req)
+{ }
+static inline int usb_ep_queue(struct usb_ep *ep, struct usb_request *req,
+ gfp_t gfp_flags)
+{ return 0; }
static inline int usb_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
-{
- return ep->ops->dequeue(ep, req);
-}
-
-/**
- * usb_ep_set_halt - sets the endpoint halt feature.
- * @ep: the non-isochronous endpoint being stalled
- *
- * Use this to stall an endpoint, perhaps as an error report.
- * Except for control endpoints,
- * the endpoint stays halted (will not stream any data) until the host
- * clears this feature; drivers may need to empty the endpoint's request
- * queue first, to make sure no inappropriate transfers happen.
- *
- * Note that while an endpoint CLEAR_FEATURE will be invisible to the
- * gadget driver, a SET_INTERFACE will not be. To reset endpoints for the
- * current altsetting, see usb_ep_clear_halt(). When switching altsettings,
- * it's simplest to use usb_ep_enable() or usb_ep_disable() for the endpoints.
- *
- * Returns zero, or a negative error code. On success, this call sets
- * underlying hardware state that blocks data transfers.
- * Attempts to halt IN endpoints will fail (returning -EAGAIN) if any
- * transfer requests are still queued, or if the controller hardware
- * (usually a FIFO) still holds bytes that the host hasn't collected.
- */
+{ return 0; }
static inline int usb_ep_set_halt(struct usb_ep *ep)
-{
- return ep->ops->set_halt(ep, 1);
-}
-
-/**
- * usb_ep_clear_halt - clears endpoint halt, and resets toggle
- * @ep:the bulk or interrupt endpoint being reset
- *
- * Use this when responding to the standard usb "set interface" request,
- * for endpoints that aren't reconfigured, after clearing any other state
- * in the endpoint's i/o queue.
- *
- * Returns zero, or a negative error code. On success, this call clears
- * the underlying hardware state reflecting endpoint halt and data toggle.
- * Note that some hardware can't support this request (like pxa2xx_udc),
- * and accordingly can't correctly implement interface altsettings.
- */
+{ return 0; }
static inline int usb_ep_clear_halt(struct usb_ep *ep)
-{
- return ep->ops->set_halt(ep, 0);
-}
-
-/**
- * usb_ep_set_wedge - sets the halt feature and ignores clear requests
- * @ep: the endpoint being wedged
- *
- * Use this to stall an endpoint and ignore CLEAR_FEATURE(HALT_ENDPOINT)
- * requests. If the gadget driver clears the halt status, it will
- * automatically unwedge the endpoint.
- *
- * Returns zero on success, else negative errno.
- */
-static inline int
-usb_ep_set_wedge(struct usb_ep *ep)
-{
- if (ep->ops->set_wedge)
- return ep->ops->set_wedge(ep);
- else
- return ep->ops->set_halt(ep, 1);
-}
-
-/**
- * usb_ep_fifo_status - returns number of bytes in fifo, or error
- * @ep: the endpoint whose fifo status is being checked.
- *
- * FIFO endpoints may have "unclaimed data" in them in certain cases,
- * such as after aborted transfers. Hosts may not have collected all
- * the IN data written by the gadget driver (and reported by a request
- * completion). The gadget driver may not have collected all the data
- * written OUT to it by the host. Drivers that need precise handling for
- * fault reporting or recovery may need to use this call.
- *
- * This returns the number of such bytes in the fifo, or a negative
- * errno if the endpoint doesn't use a FIFO or doesn't support such
- * precise handling.
- */
+{ return 0; }
+static inline int usb_ep_set_wedge(struct usb_ep *ep)
+{ return 0; }
static inline int usb_ep_fifo_status(struct usb_ep *ep)
-{
- if (ep->ops->fifo_status)
- return ep->ops->fifo_status(ep);
- else
- return -EOPNOTSUPP;
-}
-
-/**
- * usb_ep_fifo_flush - flushes contents of a fifo
- * @ep: the endpoint whose fifo is being flushed.
- *
- * This call may be used to flush the "unclaimed data" that may exist in
- * an endpoint fifo after abnormal transaction terminations. The call
- * must never be used except when endpoint is not being used for any
- * protocol translation.
- */
+{ return 0; }
static inline void usb_ep_fifo_flush(struct usb_ep *ep)
-{
- if (ep->ops->fifo_flush)
- ep->ops->fifo_flush(ep);
-}
-
+{ }
+#endif /* USB_GADGET */
/*-------------------------------------------------------------------------*/
@@ -582,6 +326,7 @@ struct usb_gadget_ops {
* @dev: Driver model state for this abstract device.
* @out_epnum: last used out ep number
* @in_epnum: last used in ep number
+ * @mA: last set mA value
* @otg_caps: OTG capabilities of this gadget.
* @sg_supported: true if we can handle scatter-gather
* @is_otg: True if the USB device port uses a Mini-AB jack, so that the
@@ -638,6 +383,7 @@ struct usb_gadget {
struct device dev;
unsigned out_epnum;
unsigned in_epnum;
+ unsigned mA;
struct usb_otg_caps *otg_caps;
unsigned sg_supported:1;
@@ -760,251 +506,44 @@ static inline int gadget_is_otg(struct usb_gadget *g)
#endif
}
-/**
- * usb_gadget_frame_number - returns the current frame number
- * @gadget: controller that reports the frame number
- *
- * Returns the usb frame number, normally eleven bits from a SOF packet,
- * or negative errno if this device doesn't support this capability.
- */
-static inline int usb_gadget_frame_number(struct usb_gadget *gadget)
-{
- return gadget->ops->get_frame(gadget);
-}
+/*-------------------------------------------------------------------------*/
-/**
- * usb_gadget_wakeup - tries to wake up the host connected to this gadget
- * @gadget: controller used to wake up the host
- *
- * Returns zero on success, else negative error code if the hardware
- * doesn't support such attempts, or its support has not been enabled
- * by the usb host. Drivers must return device descriptors that report
- * their ability to support this, or hosts won't enable it.
- *
- * This may also try to use SRP to wake the host and start enumeration,
- * even if OTG isn't otherwise in use. OTG devices may also start
- * remote wakeup even when hosts don't explicitly enable it.
- */
+#if IS_ENABLED(CONFIG_USB_GADGET)
+int usb_gadget_frame_number(struct usb_gadget *gadget);
+int usb_gadget_wakeup(struct usb_gadget *gadget);
+int usb_gadget_set_selfpowered(struct usb_gadget *gadget);
+int usb_gadget_clear_selfpowered(struct usb_gadget *gadget);
+int usb_gadget_vbus_connect(struct usb_gadget *gadget);
+int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA);
+int usb_gadget_vbus_disconnect(struct usb_gadget *gadget);
+int usb_gadget_connect(struct usb_gadget *gadget);
+int usb_gadget_disconnect(struct usb_gadget *gadget);
+int usb_gadget_deactivate(struct usb_gadget *gadget);
+int usb_gadget_activate(struct usb_gadget *gadget);
+#else
+static inline int usb_gadget_frame_number(struct usb_gadget *gadget)
+{ return 0; }
static inline int usb_gadget_wakeup(struct usb_gadget *gadget)
-{
- if (!gadget->ops->wakeup)
- return -EOPNOTSUPP;
- return gadget->ops->wakeup(gadget);
-}
-
-/**
- * usb_gadget_set_selfpowered - sets the device selfpowered feature.
- * @gadget:the device being declared as self-powered
- *
- * this affects the device status reported by the hardware driver
- * to reflect that it now has a local power supply.
- *
- * returns zero on success, else negative errno.
- */
+{ return 0; }
static inline int usb_gadget_set_selfpowered(struct usb_gadget *gadget)
-{
- if (!gadget->ops->set_selfpowered)
- return -EOPNOTSUPP;
- return gadget->ops->set_selfpowered(gadget, 1);
-}
-
-/**
- * usb_gadget_clear_selfpowered - clear the device selfpowered feature.
- * @gadget:the device being declared as bus-powered
- *
- * this affects the device status reported by the hardware driver.
- * some hardware may not support bus-powered operation, in which
- * case this feature's value can never change.
- *
- * returns zero on success, else negative errno.
- */
+{ return 0; }
static inline int usb_gadget_clear_selfpowered(struct usb_gadget *gadget)
-{
- if (!gadget->ops->set_selfpowered)
- return -EOPNOTSUPP;
- return gadget->ops->set_selfpowered(gadget, 0);
-}
-
-/**
- * usb_gadget_vbus_connect - Notify controller that VBUS is powered
- * @gadget:The device which now has VBUS power.
- * Context: can sleep
- *
- * This call is used by a driver for an external transceiver (or GPIO)
- * that detects a VBUS power session starting. Common responses include
- * resuming the controller, activating the D+ (or D-) pullup to let the
- * host detect that a USB device is attached, and starting to draw power
- * (8mA or possibly more, especially after SET_CONFIGURATION).
- *
- * Returns zero on success, else negative errno.
- */
+{ return 0; }
static inline int usb_gadget_vbus_connect(struct usb_gadget *gadget)
-{
- if (!gadget->ops->vbus_session)
- return -EOPNOTSUPP;
- return gadget->ops->vbus_session(gadget, 1);
-}
-
-/**
- * usb_gadget_vbus_draw - constrain controller's VBUS power usage
- * @gadget:The device whose VBUS usage is being described
- * @mA:How much current to draw, in milliAmperes. This should be twice
- * the value listed in the configuration descriptor bMaxPower field.
- *
- * This call is used by gadget drivers during SET_CONFIGURATION calls,
- * reporting how much power the device may consume. For example, this
- * could affect how quickly batteries are recharged.
- *
- * Returns zero on success, else negative errno.
- */
+{ return 0; }
static inline int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
-{
- if (!gadget->ops->vbus_draw)
- return -EOPNOTSUPP;
- return gadget->ops->vbus_draw(gadget, mA);
-}
-
-/**
- * usb_gadget_vbus_disconnect - notify controller about VBUS session end
- * @gadget:the device whose VBUS supply is being described
- * Context: can sleep
- *
- * This call is used by a driver for an external transceiver (or GPIO)
- * that detects a VBUS power session ending. Common responses include
- * reversing everything done in usb_gadget_vbus_connect().
- *
- * Returns zero on success, else negative errno.
- */
+{ return 0; }
static inline int usb_gadget_vbus_disconnect(struct usb_gadget *gadget)
-{
- if (!gadget->ops->vbus_session)
- return -EOPNOTSUPP;
- return gadget->ops->vbus_session(gadget, 0);
-}
-
-/**
- * usb_gadget_connect - software-controlled connect to USB host
- * @gadget:the peripheral being connected
- *
- * Enables the D+ (or potentially D-) pullup. The host will start
- * enumerating this gadget when the pullup is active and a VBUS session
- * is active (the link is powered). This pullup is always enabled unless
- * usb_gadget_disconnect() has been used to disable it.
- *
- * Returns zero on success, else negative errno.
- */
+{ return 0; }
static inline int usb_gadget_connect(struct usb_gadget *gadget)
-{
- int ret;
-
- if (!gadget->ops->pullup)
- return -EOPNOTSUPP;
-
- if (gadget->deactivated) {
- /*
- * If gadget is deactivated we only save new state.
- * Gadget will be connected automatically after activation.
- */
- gadget->connected = true;
- return 0;
- }
-
- ret = gadget->ops->pullup(gadget, 1);
- if (!ret)
- gadget->connected = 1;
- return ret;
-}
-
-/**
- * usb_gadget_disconnect - software-controlled disconnect from USB host
- * @gadget:the peripheral being disconnected
- *
- * Disables the D+ (or potentially D-) pullup, which the host may see
- * as a disconnect (when a VBUS session is active). Not all systems
- * support software pullup controls.
- *
- * Returns zero on success, else negative errno.
- */
+{ return 0; }
static inline int usb_gadget_disconnect(struct usb_gadget *gadget)
-{
- int ret;
-
- if (!gadget->ops->pullup)
- return -EOPNOTSUPP;
-
- if (gadget->deactivated) {
- /*
- * If gadget is deactivated we only save new state.
- * Gadget will stay disconnected after activation.
- */
- gadget->connected = false;
- return 0;
- }
-
- ret = gadget->ops->pullup(gadget, 0);
- if (!ret)
- gadget->connected = 0;
- return ret;
-}
-
-/**
- * usb_gadget_deactivate - deactivate function which is not ready to work
- * @gadget: the peripheral being deactivated
- *
- * This routine may be used during the gadget driver bind() call to prevent
- * the peripheral from ever being visible to the USB host, unless later
- * usb_gadget_activate() is called. For example, user mode components may
- * need to be activated before the system can talk to hosts.
- *
- * Returns zero on success, else negative errno.
- */
+{ return 0; }
static inline int usb_gadget_deactivate(struct usb_gadget *gadget)
-{
- int ret;
-
- if (gadget->deactivated)
- return 0;
-
- if (gadget->connected) {
- ret = usb_gadget_disconnect(gadget);
- if (ret)
- return ret;
- /*
- * If gadget was being connected before deactivation, we want
- * to reconnect it in usb_gadget_activate().
- */
- gadget->connected = true;
- }
- gadget->deactivated = true;
-
- return 0;
-}
-
-/**
- * usb_gadget_activate - activate function which is not ready to work
- * @gadget: the peripheral being activated
- *
- * This routine activates gadget which was previously deactivated with
- * usb_gadget_deactivate() call. It calls usb_gadget_connect() if needed.
- *
- * Returns zero on success, else negative errno.
- */
+{ return 0; }
static inline int usb_gadget_activate(struct usb_gadget *gadget)
-{
- if (!gadget->deactivated)
- return 0;
-
- gadget->deactivated = false;
-
- /*
- * If gadget has been connected before deactivation, or became connected
- * while it was being deactivated, we call usb_gadget_connect().
- */
- if (gadget->connected)
- return usb_gadget_connect(gadget);
-
- return 0;
-}
+{ return 0; }
+#endif /* CONFIG_USB_GADGET */
/*-------------------------------------------------------------------------*/
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
deleted file mode 100644
index 8c8f6854c993..000000000000
--- a/include/linux/usb/msm_hsusb.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* linux/include/asm-arm/arch-msm/hsusb.h
- *
- * Copyright (C) 2008 Google, Inc.
- * Author: Brian Swetland <swetland@google.com>
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
-
-#ifndef __ASM_ARCH_MSM_HSUSB_H
-#define __ASM_ARCH_MSM_HSUSB_H
-
-#include <linux/extcon.h>
-#include <linux/types.h>
-#include <linux/usb/otg.h>
-#include <linux/clk.h>
-
-/**
- * OTG control
- *
- * OTG_NO_CONTROL Id/VBUS notifications not required. Useful in host
- * only configuration.
- * OTG_PHY_CONTROL Id/VBUS notifications comes form USB PHY.
- * OTG_PMIC_CONTROL Id/VBUS notifications comes from PMIC hardware.
- * OTG_USER_CONTROL Id/VBUS notifcations comes from User via sysfs.
- *
- */
-enum otg_control_type {
- OTG_NO_CONTROL = 0,
- OTG_PHY_CONTROL,
- OTG_PMIC_CONTROL,
- OTG_USER_CONTROL,
-};
-
-/**
- * PHY used in
- *
- * INVALID_PHY Unsupported PHY
- * CI_45NM_INTEGRATED_PHY Chipidea 45nm integrated PHY
- * SNPS_28NM_INTEGRATED_PHY Synopsis 28nm integrated PHY
- *
- */
-enum msm_usb_phy_type {
- INVALID_PHY = 0,
- CI_45NM_INTEGRATED_PHY,
- SNPS_28NM_INTEGRATED_PHY,
-};
-
-#define IDEV_CHG_MAX 1500
-#define IUNIT 100
-
-/**
- * Different states involved in USB charger detection.
- *
- * USB_CHG_STATE_UNDEFINED USB charger is not connected or detection
- * process is not yet started.
- * USB_CHG_STATE_WAIT_FOR_DCD Waiting for Data pins contact.
- * USB_CHG_STATE_DCD_DONE Data pin contact is detected.
- * USB_CHG_STATE_PRIMARY_DONE Primary detection is completed (Detects
- * between SDP and DCP/CDP).
- * USB_CHG_STATE_SECONDARY_DONE Secondary detection is completed (Detects
- * between DCP and CDP).
- * USB_CHG_STATE_DETECTED USB charger type is determined.
- *
- */
-enum usb_chg_state {
- USB_CHG_STATE_UNDEFINED = 0,
- USB_CHG_STATE_WAIT_FOR_DCD,
- USB_CHG_STATE_DCD_DONE,
- USB_CHG_STATE_PRIMARY_DONE,
- USB_CHG_STATE_SECONDARY_DONE,
- USB_CHG_STATE_DETECTED,
-};
-
-/**
- * USB charger types
- *
- * USB_INVALID_CHARGER Invalid USB charger.
- * USB_SDP_CHARGER Standard downstream port. Refers to a downstream port
- * on USB2.0 compliant host/hub.
- * USB_DCP_CHARGER Dedicated charger port (AC charger/ Wall charger).
- * USB_CDP_CHARGER Charging downstream port. Enumeration can happen and
- * IDEV_CHG_MAX can be drawn irrespective of USB state.
- *
- */
-enum usb_chg_type {
- USB_INVALID_CHARGER = 0,
- USB_SDP_CHARGER,
- USB_DCP_CHARGER,
- USB_CDP_CHARGER,
-};
-
-/**
- * struct msm_otg_platform_data - platform device data
- * for msm_otg driver.
- * @phy_init_seq: PHY configuration sequence values. Value of -1 is reserved as
- * "do not overwrite default vaule at this address".
- * @phy_init_sz: PHY configuration sequence size.
- * @vbus_power: VBUS power on/off routine.
- * @power_budget: VBUS power budget in mA (0 will be treated as 500mA).
- * @mode: Supported mode (OTG/peripheral/host).
- * @otg_control: OTG switch controlled by user/Id pin
- */
-struct msm_otg_platform_data {
- int *phy_init_seq;
- int phy_init_sz;
- void (*vbus_power)(bool on);
- unsigned power_budget;
- enum usb_dr_mode mode;
- enum otg_control_type otg_control;
- enum msm_usb_phy_type phy_type;
- void (*setup_gpio)(enum usb_otg_state state);
-};
-
-/**
- * struct msm_usb_cable - structure for exteternal connector cable
- * state tracking
- * @nb: hold event notification callback
- * @conn: used for notification registration
- */
-struct msm_usb_cable {
- struct notifier_block nb;
- struct extcon_dev *extcon;
-};
-
-/**
- * struct msm_otg: OTG driver data. Shared by HCD and DCD.
- * @otg: USB OTG Transceiver structure.
- * @pdata: otg device platform data.
- * @irq: IRQ number assigned for HSUSB controller.
- * @clk: clock struct of usb_hs_clk.
- * @pclk: clock struct of usb_hs_pclk.
- * @core_clk: clock struct of usb_hs_core_clk.
- * @regs: ioremapped register base address.
- * @inputs: OTG state machine inputs(Id, SessValid etc).
- * @sm_work: OTG state machine work.
- * @in_lpm: indicates low power mode (LPM) state.
- * @async_int: Async interrupt arrived.
- * @cur_power: The amount of mA available from downstream port.
- * @chg_work: Charger detection work.
- * @chg_state: The state of charger detection process.
- * @chg_type: The type of charger attached.
- * @dcd_retires: The retry count used to track Data contact
- * detection process.
- * @manual_pullup: true if VBUS is not routed to USB controller/phy
- * and controller driver therefore enables pull-up explicitly before
- * starting controller using usbcmd run/stop bit.
- * @vbus: VBUS signal state trakining, using extcon framework
- * @id: ID signal state trakining, using extcon framework
- * @switch_gpio: Descriptor for GPIO used to control external Dual
- * SPDT USB Switch.
- * @reboot: Used to inform the driver to route USB D+/D- line to Device
- * connector
- */
-struct msm_otg {
- struct usb_phy phy;
- struct msm_otg_platform_data *pdata;
- int irq;
- struct clk *clk;
- struct clk *pclk;
- struct clk *core_clk;
- void __iomem *regs;
-#define ID 0
-#define B_SESS_VLD 1
- unsigned long inputs;
- struct work_struct sm_work;
- atomic_t in_lpm;
- int async_int;
- unsigned cur_power;
- int phy_number;
- struct delayed_work chg_work;
- enum usb_chg_state chg_state;
- enum usb_chg_type chg_type;
- u8 dcd_retries;
- struct regulator *v3p3;
- struct regulator *v1p8;
- struct regulator *vddcx;
-
- struct reset_control *phy_rst;
- struct reset_control *link_rst;
- int vdd_levels[3];
-
- bool manual_pullup;
-
- struct msm_usb_cable vbus;
- struct msm_usb_cable id;
-
- struct gpio_desc *switch_gpio;
- struct notifier_block reboot;
-};
-
-#endif
diff --git a/include/linux/usb/of.h b/include/linux/usb/of.h
index de3237fce6b2..5ff9032ee1b4 100644
--- a/include/linux/usb/of.h
+++ b/include/linux/usb/of.h
@@ -12,7 +12,7 @@
#include <linux/usb/phy.h>
#if IS_ENABLED(CONFIG_OF)
-enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *phy_np);
+enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *np, int arg0);
bool of_usb_host_tpl_support(struct device_node *np);
int of_usb_update_otg_caps(struct device_node *np,
struct usb_otg_caps *otg_caps);
@@ -20,7 +20,7 @@ struct device_node *usb_of_get_child_node(struct device_node *parent,
int portnum);
#else
static inline enum usb_dr_mode
-of_usb_get_dr_mode_by_phy(struct device_node *phy_np)
+of_usb_get_dr_mode_by_phy(struct device_node *np, int arg0)
{
return USB_DR_MODE_UNKNOWN;
}
diff --git a/include/linux/usb/xhci_pdriver.h b/include/linux/usb/xhci_pdriver.h
deleted file mode 100644
index 376654b5b0f7..000000000000
--- a/include/linux/usb/xhci_pdriver.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * 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.
- *
- */
-
-#ifndef __USB_CORE_XHCI_PDRIVER_H
-#define __USB_CORE_XHCI_PDRIVER_H
-
-/**
- * struct usb_xhci_pdata - platform_data for generic xhci platform driver
- *
- * @usb3_lpm_capable: determines if this xhci platform supports USB3
- * LPM capability
- *
- */
-struct usb_xhci_pdata {
- unsigned usb3_lpm_capable:1;
-};
-
-#endif /* __USB_CORE_XHCI_PDRIVER_H */
diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h
index 587480ad41b7..dd66a952e8cd 100644
--- a/include/linux/userfaultfd_k.h
+++ b/include/linux/userfaultfd_k.h
@@ -27,8 +27,7 @@
#define UFFD_SHARED_FCNTL_FLAGS (O_CLOEXEC | O_NONBLOCK)
#define UFFD_FLAGS_SET (EFD_SHARED_FCNTL_FLAGS)
-extern int handle_userfault(struct vm_area_struct *vma, unsigned long address,
- unsigned int flags, unsigned long reason);
+extern int handle_userfault(struct fault_env *fe, unsigned long reason);
extern ssize_t mcopy_atomic(struct mm_struct *dst_mm, unsigned long dst_start,
unsigned long src_start, unsigned long len);
@@ -56,10 +55,7 @@ static inline bool userfaultfd_armed(struct vm_area_struct *vma)
#else /* CONFIG_USERFAULTFD */
/* mm helpers */
-static inline int handle_userfault(struct vm_area_struct *vma,
- unsigned long address,
- unsigned int flags,
- unsigned long reason)
+static inline int handle_userfault(struct fault_env *fe, unsigned long reason)
{
return VM_FAULT_SIGBUS;
}
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
new file mode 100644
index 000000000000..1c912f85e041
--- /dev/null
+++ b/include/linux/virtio_net.h
@@ -0,0 +1,101 @@
+#ifndef _LINUX_VIRTIO_NET_H
+#define _LINUX_VIRTIO_NET_H
+
+#include <linux/if_vlan.h>
+#include <uapi/linux/virtio_net.h>
+
+static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
+ const struct virtio_net_hdr *hdr,
+ bool little_endian)
+{
+ unsigned short gso_type = 0;
+
+ if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+ switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+ case VIRTIO_NET_HDR_GSO_TCPV4:
+ gso_type = SKB_GSO_TCPV4;
+ break;
+ case VIRTIO_NET_HDR_GSO_TCPV6:
+ gso_type = SKB_GSO_TCPV6;
+ break;
+ case VIRTIO_NET_HDR_GSO_UDP:
+ gso_type = SKB_GSO_UDP;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (hdr->gso_type & VIRTIO_NET_HDR_GSO_ECN)
+ gso_type |= SKB_GSO_TCP_ECN;
+
+ if (hdr->gso_size == 0)
+ return -EINVAL;
+ }
+
+ if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+ u16 start = __virtio16_to_cpu(little_endian, hdr->csum_start);
+ u16 off = __virtio16_to_cpu(little_endian, hdr->csum_offset);
+
+ if (!skb_partial_csum_set(skb, start, off))
+ return -EINVAL;
+ }
+
+ if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+ u16 gso_size = __virtio16_to_cpu(little_endian, hdr->gso_size);
+
+ skb_shinfo(skb)->gso_size = gso_size;
+ skb_shinfo(skb)->gso_type = gso_type;
+
+ /* Header must be checked, and gso_segs computed. */
+ skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
+ skb_shinfo(skb)->gso_segs = 0;
+ }
+
+ return 0;
+}
+
+static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb,
+ struct virtio_net_hdr *hdr,
+ bool little_endian)
+{
+ memset(hdr, 0, sizeof(*hdr));
+
+ if (skb_is_gso(skb)) {
+ struct skb_shared_info *sinfo = skb_shinfo(skb);
+
+ /* This is a hint as to how much should be linear. */
+ hdr->hdr_len = __cpu_to_virtio16(little_endian,
+ skb_headlen(skb));
+ hdr->gso_size = __cpu_to_virtio16(little_endian,
+ sinfo->gso_size);
+ if (sinfo->gso_type & SKB_GSO_TCPV4)
+ hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+ else if (sinfo->gso_type & SKB_GSO_TCPV6)
+ hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+ else if (sinfo->gso_type & SKB_GSO_UDP)
+ hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
+ else
+ return -EINVAL;
+ if (sinfo->gso_type & SKB_GSO_TCP_ECN)
+ hdr->gso_type |= VIRTIO_NET_HDR_GSO_ECN;
+ } else
+ hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+ if (skb_vlan_tag_present(skb))
+ hdr->csum_start = __cpu_to_virtio16(little_endian,
+ skb_checksum_start_offset(skb) + VLAN_HLEN);
+ else
+ hdr->csum_start = __cpu_to_virtio16(little_endian,
+ skb_checksum_start_offset(skb));
+ hdr->csum_offset = __cpu_to_virtio16(little_endian,
+ skb->csum_offset);
+ } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ hdr->flags = VIRTIO_NET_HDR_F_DATA_VALID;
+ } /* else everything is zero */
+
+ return 0;
+}
+
+#endif /* _LINUX_VIRTIO_BYTEORDER */
diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
index ec084321fe09..4d6ec58a8d45 100644
--- a/include/linux/vm_event_item.h
+++ b/include/linux/vm_event_item.h
@@ -23,21 +23,23 @@
enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
FOR_ALL_ZONES(PGALLOC),
+ FOR_ALL_ZONES(ALLOCSTALL),
+ FOR_ALL_ZONES(PGSCAN_SKIP),
PGFREE, PGACTIVATE, PGDEACTIVATE,
PGFAULT, PGMAJFAULT,
PGLAZYFREED,
- FOR_ALL_ZONES(PGREFILL),
- FOR_ALL_ZONES(PGSTEAL_KSWAPD),
- FOR_ALL_ZONES(PGSTEAL_DIRECT),
- FOR_ALL_ZONES(PGSCAN_KSWAPD),
- FOR_ALL_ZONES(PGSCAN_DIRECT),
+ PGREFILL,
+ PGSTEAL_KSWAPD,
+ PGSTEAL_DIRECT,
+ PGSCAN_KSWAPD,
+ PGSCAN_DIRECT,
PGSCAN_DIRECT_THROTTLE,
#ifdef CONFIG_NUMA
PGSCAN_ZONE_RECLAIM_FAILED,
#endif
PGINODESTEAL, SLABS_SCANNED, KSWAPD_INODESTEAL,
KSWAPD_LOW_WMARK_HIT_QUICKLY, KSWAPD_HIGH_WMARK_HIT_QUICKLY,
- PAGEOUTRUN, ALLOCSTALL, PGROTATED,
+ PAGEOUTRUN, PGROTATED,
DROP_PAGECACHE, DROP_SLAB,
#ifdef CONFIG_NUMA_BALANCING
NUMA_PTE_UPDATES,
@@ -70,6 +72,8 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
THP_FAULT_FALLBACK,
THP_COLLAPSE_ALLOC,
THP_COLLAPSE_ALLOC_FAILED,
+ THP_FILE_ALLOC,
+ THP_FILE_MAPPED,
THP_SPLIT_PAGE,
THP_SPLIT_PAGE_FAILED,
THP_DEFERRED_SPLIT_PAGE,
@@ -100,4 +104,9 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
NR_VM_EVENT_ITEMS
};
+#ifndef CONFIG_TRANSPARENT_HUGEPAGE
+#define THP_FILE_ALLOC ({ BUILD_BUG(); 0; })
+#define THP_FILE_MAPPED ({ BUILD_BUG(); 0; })
+#endif
+
#endif /* VM_EVENT_ITEM_H_INCLUDED */
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index d2da8e053210..613771909b6e 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -101,25 +101,42 @@ static inline void vm_events_fold_cpu(int cpu)
#define count_vm_vmacache_event(x) do {} while (0)
#endif
-#define __count_zone_vm_events(item, zone, delta) \
- __count_vm_events(item##_NORMAL - ZONE_NORMAL + \
- zone_idx(zone), delta)
+#define __count_zid_vm_events(item, zid, delta) \
+ __count_vm_events(item##_NORMAL - ZONE_NORMAL + zid, delta)
/*
- * Zone based page accounting with per cpu differentials.
+ * Zone and node-based page accounting with per cpu differentials.
*/
-extern atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS];
+extern atomic_long_t vm_zone_stat[NR_VM_ZONE_STAT_ITEMS];
+extern atomic_long_t vm_node_stat[NR_VM_NODE_STAT_ITEMS];
static inline void zone_page_state_add(long x, struct zone *zone,
enum zone_stat_item item)
{
atomic_long_add(x, &zone->vm_stat[item]);
- atomic_long_add(x, &vm_stat[item]);
+ atomic_long_add(x, &vm_zone_stat[item]);
+}
+
+static inline void node_page_state_add(long x, struct pglist_data *pgdat,
+ enum node_stat_item item)
+{
+ atomic_long_add(x, &pgdat->vm_stat[item]);
+ atomic_long_add(x, &vm_node_stat[item]);
}
static inline unsigned long global_page_state(enum zone_stat_item item)
{
- long x = atomic_long_read(&vm_stat[item]);
+ long x = atomic_long_read(&vm_zone_stat[item]);
+#ifdef CONFIG_SMP
+ if (x < 0)
+ x = 0;
+#endif
+ return x;
+}
+
+static inline unsigned long global_node_page_state(enum node_stat_item item)
+{
+ long x = atomic_long_read(&vm_node_stat[item]);
#ifdef CONFIG_SMP
if (x < 0)
x = 0;
@@ -160,32 +177,61 @@ static inline unsigned long zone_page_state_snapshot(struct zone *zone,
return x;
}
-#ifdef CONFIG_NUMA
+static inline unsigned long node_page_state_snapshot(pg_data_t *pgdat,
+ enum node_stat_item item)
+{
+ long x = atomic_long_read(&pgdat->vm_stat[item]);
-extern unsigned long node_page_state(int node, enum zone_stat_item item);
+#ifdef CONFIG_SMP
+ int cpu;
+ for_each_online_cpu(cpu)
+ x += per_cpu_ptr(pgdat->per_cpu_nodestats, cpu)->vm_node_stat_diff[item];
-#else
+ if (x < 0)
+ x = 0;
+#endif
+ return x;
+}
-#define node_page_state(node, item) global_page_state(item)
+#ifdef CONFIG_NUMA
+extern unsigned long sum_zone_node_page_state(int node,
+ enum zone_stat_item item);
+extern unsigned long node_page_state(struct pglist_data *pgdat,
+ enum node_stat_item item);
+#else
+#define sum_zone_node_page_state(node, item) global_page_state(item)
+#define node_page_state(node, item) global_node_page_state(item)
#endif /* CONFIG_NUMA */
#define add_zone_page_state(__z, __i, __d) mod_zone_page_state(__z, __i, __d)
#define sub_zone_page_state(__z, __i, __d) mod_zone_page_state(__z, __i, -(__d))
+#define add_node_page_state(__p, __i, __d) mod_node_page_state(__p, __i, __d)
+#define sub_node_page_state(__p, __i, __d) mod_node_page_state(__p, __i, -(__d))
#ifdef CONFIG_SMP
void __mod_zone_page_state(struct zone *, enum zone_stat_item item, long);
void __inc_zone_page_state(struct page *, enum zone_stat_item);
void __dec_zone_page_state(struct page *, enum zone_stat_item);
+void __mod_node_page_state(struct pglist_data *, enum node_stat_item item, long);
+void __inc_node_page_state(struct page *, enum node_stat_item);
+void __dec_node_page_state(struct page *, enum node_stat_item);
+
void mod_zone_page_state(struct zone *, enum zone_stat_item, long);
void inc_zone_page_state(struct page *, enum zone_stat_item);
void dec_zone_page_state(struct page *, enum zone_stat_item);
-extern void inc_zone_state(struct zone *, enum zone_stat_item);
+void mod_node_page_state(struct pglist_data *, enum node_stat_item, long);
+void inc_node_page_state(struct page *, enum node_stat_item);
+void dec_node_page_state(struct page *, enum node_stat_item);
+
+extern void inc_node_state(struct pglist_data *, enum node_stat_item);
extern void __inc_zone_state(struct zone *, enum zone_stat_item);
+extern void __inc_node_state(struct pglist_data *, enum node_stat_item);
extern void dec_zone_state(struct zone *, enum zone_stat_item);
extern void __dec_zone_state(struct zone *, enum zone_stat_item);
+extern void __dec_node_state(struct pglist_data *, enum node_stat_item);
void quiet_vmstat(void);
void cpu_vm_stats_fold(int cpu);
@@ -213,16 +259,34 @@ static inline void __mod_zone_page_state(struct zone *zone,
zone_page_state_add(delta, zone, item);
}
+static inline void __mod_node_page_state(struct pglist_data *pgdat,
+ enum node_stat_item item, int delta)
+{
+ node_page_state_add(delta, pgdat, item);
+}
+
static inline void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
{
atomic_long_inc(&zone->vm_stat[item]);
- atomic_long_inc(&vm_stat[item]);
+ atomic_long_inc(&vm_zone_stat[item]);
+}
+
+static inline void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item)
+{
+ atomic_long_inc(&pgdat->vm_stat[item]);
+ atomic_long_inc(&vm_node_stat[item]);
}
static inline void __dec_zone_state(struct zone *zone, enum zone_stat_item item)
{
atomic_long_dec(&zone->vm_stat[item]);
- atomic_long_dec(&vm_stat[item]);
+ atomic_long_dec(&vm_zone_stat[item]);
+}
+
+static inline void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item)
+{
+ atomic_long_dec(&pgdat->vm_stat[item]);
+ atomic_long_dec(&vm_node_stat[item]);
}
static inline void __inc_zone_page_state(struct page *page,
@@ -231,12 +295,26 @@ static inline void __inc_zone_page_state(struct page *page,
__inc_zone_state(page_zone(page), item);
}
+static inline void __inc_node_page_state(struct page *page,
+ enum node_stat_item item)
+{
+ __inc_node_state(page_pgdat(page), item);
+}
+
+
static inline void __dec_zone_page_state(struct page *page,
enum zone_stat_item item)
{
__dec_zone_state(page_zone(page), item);
}
+static inline void __dec_node_page_state(struct page *page,
+ enum node_stat_item item)
+{
+ __dec_node_state(page_pgdat(page), item);
+}
+
+
/*
* We only use atomic operations to update counters. So there is no need to
* disable interrupts.
@@ -245,7 +323,12 @@ static inline void __dec_zone_page_state(struct page *page,
#define dec_zone_page_state __dec_zone_page_state
#define mod_zone_page_state __mod_zone_page_state
+#define inc_node_page_state __inc_node_page_state
+#define dec_node_page_state __dec_node_page_state
+#define mod_node_page_state __mod_node_page_state
+
#define inc_zone_state __inc_zone_state
+#define inc_node_state __inc_node_state
#define dec_zone_state __dec_zone_state
#define set_pgdat_percpu_threshold(pgdat, callback) { }
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 8d7634247fb4..6abd24f258bc 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -45,7 +45,7 @@ void poke_blanked_console(void);
int con_font_op(struct vc_data *vc, struct console_font_op *op);
int con_set_cmap(unsigned char __user *cmap);
int con_get_cmap(unsigned char __user *cmap);
-void scrollback(struct vc_data *vc, int lines);
+void scrollback(struct vc_data *vc);
void scrollfront(struct vc_data *vc, int lines);
void clear_buffer_attributes(struct vc_data *vc);
void update_region(struct vc_data *vc, unsigned long start, int count);
@@ -59,14 +59,13 @@ int tioclinux(struct tty_struct *tty, unsigned long arg);
#ifdef CONFIG_CONSOLE_TRANSLATIONS
/* consolemap.c */
-struct unimapinit;
struct unipair;
int con_set_trans_old(unsigned char __user * table);
int con_get_trans_old(unsigned char __user * table);
int con_set_trans_new(unsigned short __user * table);
int con_get_trans_new(unsigned short __user * table);
-int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui);
+int con_clear_unimap(struct vc_data *vc);
int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list);
int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list);
int con_set_default_unimap(struct vc_data *vc);
@@ -92,7 +91,7 @@ static inline int con_get_trans_new(unsigned short __user *table)
{
return -EINVAL;
}
-static inline int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
+static inline int con_clear_unimap(struct vc_data *vc)
{
return 0;
}
diff --git a/include/linux/vtime.h b/include/linux/vtime.h
index fa2196990f84..aa9bfea8804a 100644
--- a/include/linux/vtime.h
+++ b/include/linux/vtime.h
@@ -12,11 +12,9 @@ struct task_struct;
/*
* vtime_accounting_cpu_enabled() definitions/declarations
*/
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+#if defined(CONFIG_VIRT_CPU_ACCOUNTING_NATIVE)
static inline bool vtime_accounting_cpu_enabled(void) { return true; }
-#endif /* CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
-
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
+#elif defined(CONFIG_VIRT_CPU_ACCOUNTING_GEN)
/*
* Checks if vtime is enabled on some CPU. Cputime readers want to be careful
* in that case and compute the tickless cputime.
@@ -37,11 +35,9 @@ static inline bool vtime_accounting_cpu_enabled(void)
return false;
}
-#endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */
-
-#ifndef CONFIG_VIRT_CPU_ACCOUNTING
+#else /* !CONFIG_VIRT_CPU_ACCOUNTING */
static inline bool vtime_accounting_cpu_enabled(void) { return false; }
-#endif /* !CONFIG_VIRT_CPU_ACCOUNTING */
+#endif
/*
@@ -64,35 +60,15 @@ extern void vtime_account_system(struct task_struct *tsk);
extern void vtime_account_idle(struct task_struct *tsk);
extern void vtime_account_user(struct task_struct *tsk);
-#ifdef __ARCH_HAS_VTIME_ACCOUNT
-extern void vtime_account_irq_enter(struct task_struct *tsk);
-#else
-extern void vtime_common_account_irq_enter(struct task_struct *tsk);
-static inline void vtime_account_irq_enter(struct task_struct *tsk)
-{
- if (vtime_accounting_cpu_enabled())
- vtime_common_account_irq_enter(tsk);
-}
-#endif /* __ARCH_HAS_VTIME_ACCOUNT */
-
#else /* !CONFIG_VIRT_CPU_ACCOUNTING */
static inline void vtime_task_switch(struct task_struct *prev) { }
static inline void vtime_account_system(struct task_struct *tsk) { }
static inline void vtime_account_user(struct task_struct *tsk) { }
-static inline void vtime_account_irq_enter(struct task_struct *tsk) { }
#endif /* !CONFIG_VIRT_CPU_ACCOUNTING */
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
extern void arch_vtime_task_switch(struct task_struct *tsk);
-extern void vtime_gen_account_irq_exit(struct task_struct *tsk);
-
-static inline void vtime_account_irq_exit(struct task_struct *tsk)
-{
- if (vtime_accounting_cpu_enabled())
- vtime_gen_account_irq_exit(tsk);
-}
-
extern void vtime_user_enter(struct task_struct *tsk);
static inline void vtime_user_exit(struct task_struct *tsk)
@@ -103,11 +79,6 @@ extern void vtime_guest_enter(struct task_struct *tsk);
extern void vtime_guest_exit(struct task_struct *tsk);
extern void vtime_init_idle(struct task_struct *tsk, int cpu);
#else /* !CONFIG_VIRT_CPU_ACCOUNTING_GEN */
-static inline void vtime_account_irq_exit(struct task_struct *tsk)
-{
- /* On hard|softirq exit we always account to hard|softirq cputime */
- vtime_account_system(tsk);
-}
static inline void vtime_user_enter(struct task_struct *tsk) { }
static inline void vtime_user_exit(struct task_struct *tsk) { }
static inline void vtime_guest_enter(struct task_struct *tsk) { }
@@ -115,6 +86,19 @@ static inline void vtime_guest_exit(struct task_struct *tsk) { }
static inline void vtime_init_idle(struct task_struct *tsk, int cpu) { }
#endif
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
+extern void vtime_account_irq_enter(struct task_struct *tsk);
+static inline void vtime_account_irq_exit(struct task_struct *tsk)
+{
+ /* On hard|softirq exit we always account to hard|softirq cputime */
+ vtime_account_system(tsk);
+}
+#else /* !CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
+static inline void vtime_account_irq_enter(struct task_struct *tsk) { }
+static inline void vtime_account_irq_exit(struct task_struct *tsk) { }
+#endif
+
+
#ifdef CONFIG_IRQ_TIME_ACCOUNTING
extern void irqtime_account_irq(struct task_struct *tsk);
#else
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index d0b5ca5d4e08..fc1e16c25a29 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -320,7 +320,7 @@ void laptop_mode_timer_fn(unsigned long data);
static inline void laptop_sync_completion(void) { }
#endif
void throttle_vm_writeout(gfp_t gfp_mask);
-bool zone_dirty_ok(struct zone *zone);
+bool node_dirty_ok(struct pglist_data *pgdat);
int wb_domain_init(struct wb_domain *dom, gfp_t gfp);
#ifdef CONFIG_CGROUP_WRITEBACK
void wb_domain_exit(struct wb_domain *dom);
@@ -384,4 +384,7 @@ void tag_pages_for_writeback(struct address_space *mapping,
void account_page_redirty(struct page *page);
+void sb_mark_inode_writeback(struct inode *inode);
+void sb_clear_inode_writeback(struct inode *inode);
+
#endif /* WRITEBACK_H */
diff --git a/include/media/cec-edid.h b/include/media/cec-edid.h
new file mode 100644
index 000000000000..bdf731ecba1a
--- /dev/null
+++ b/include/media/cec-edid.h
@@ -0,0 +1,104 @@
+/*
+ * cec-edid - HDMI Consumer Electronics Control & EDID helpers
+ *
+ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _MEDIA_CEC_EDID_H
+#define _MEDIA_CEC_EDID_H
+
+#include <linux/types.h>
+
+#define CEC_PHYS_ADDR_INVALID 0xffff
+#define cec_phys_addr_exp(pa) \
+ ((pa) >> 12), ((pa) >> 8) & 0xf, ((pa) >> 4) & 0xf, (pa) & 0xf
+
+/**
+ * cec_get_edid_phys_addr() - find and return the physical address
+ *
+ * @edid: pointer to the EDID data
+ * @size: size in bytes of the EDID data
+ * @offset: If not %NULL then the location of the physical address
+ * bytes in the EDID will be returned here. This is set to 0
+ * if there is no physical address found.
+ *
+ * Return: the physical address or CEC_PHYS_ADDR_INVALID if there is none.
+ */
+u16 cec_get_edid_phys_addr(const u8 *edid, unsigned int size,
+ unsigned int *offset);
+
+/**
+ * cec_set_edid_phys_addr() - find and set the physical address
+ *
+ * @edid: pointer to the EDID data
+ * @size: size in bytes of the EDID data
+ * @phys_addr: the new physical address
+ *
+ * This function finds the location of the physical address in the EDID
+ * and fills in the given physical address and updates the checksum
+ * at the end of the EDID block. It does nothing if the EDID doesn't
+ * contain a physical address.
+ */
+void cec_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr);
+
+/**
+ * cec_phys_addr_for_input() - calculate the PA for an input
+ *
+ * @phys_addr: the physical address of the parent
+ * @input: the number of the input port, must be between 1 and 15
+ *
+ * This function calculates a new physical address based on the input
+ * port number. For example:
+ *
+ * PA = 0.0.0.0 and input = 2 becomes 2.0.0.0
+ *
+ * PA = 3.0.0.0 and input = 1 becomes 3.1.0.0
+ *
+ * PA = 3.2.1.0 and input = 5 becomes 3.2.1.5
+ *
+ * PA = 3.2.1.3 and input = 5 becomes f.f.f.f since it maxed out the depth.
+ *
+ * Return: the new physical address or CEC_PHYS_ADDR_INVALID.
+ */
+u16 cec_phys_addr_for_input(u16 phys_addr, u8 input);
+
+/**
+ * cec_phys_addr_validate() - validate a physical address from an EDID
+ *
+ * @phys_addr: the physical address to validate
+ * @parent: if not %NULL, then this is filled with the parents PA.
+ * @port: if not %NULL, then this is filled with the input port.
+ *
+ * This validates a physical address as read from an EDID. If the
+ * PA is invalid (such as 1.0.1.0 since '0' is only allowed at the end),
+ * then it will return -EINVAL.
+ *
+ * The parent PA is passed into %parent and the input port is passed into
+ * %port. For example:
+ *
+ * PA = 0.0.0.0: has parent 0.0.0.0 and input port 0.
+ *
+ * PA = 1.0.0.0: has parent 0.0.0.0 and input port 1.
+ *
+ * PA = 3.2.0.0: has parent 3.0.0.0 and input port 2.
+ *
+ * PA = f.f.f.f: has parent f.f.f.f and input port 0.
+ *
+ * Return: 0 if the PA is valid, -EINVAL if not.
+ */
+int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port);
+
+#endif /* _MEDIA_CEC_EDID_H */
diff --git a/include/media/cec.h b/include/media/cec.h
new file mode 100644
index 000000000000..dc7854b855f3
--- /dev/null
+++ b/include/media/cec.h
@@ -0,0 +1,241 @@
+/*
+ * cec - HDMI Consumer Electronics Control support header
+ *
+ * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef _MEDIA_CEC_H
+#define _MEDIA_CEC_H
+
+#include <linux/poll.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/kthread.h>
+#include <linux/timer.h>
+#include <linux/cec-funcs.h>
+#include <media/rc-core.h>
+#include <media/cec-edid.h>
+
+/**
+ * struct cec_devnode - cec device node
+ * @dev: cec device
+ * @cdev: cec character device
+ * @parent: parent device
+ * @minor: device node minor number
+ * @registered: the device was correctly registered
+ * @unregistered: the device was unregistered
+ * @fhs_lock: lock to control access to the filehandle list
+ * @fhs: the list of open filehandles (cec_fh)
+ *
+ * This structure represents a cec-related device node.
+ *
+ * The @parent is a physical device. It must be set by core or device drivers
+ * before registering the node.
+ */
+struct cec_devnode {
+ /* sysfs */
+ struct device dev;
+ struct cdev cdev;
+ struct device *parent;
+
+ /* device info */
+ int minor;
+ bool registered;
+ bool unregistered;
+ struct mutex fhs_lock;
+ struct list_head fhs;
+};
+
+struct cec_adapter;
+struct cec_data;
+
+struct cec_data {
+ struct list_head list;
+ struct list_head xfer_list;
+ struct cec_adapter *adap;
+ struct cec_msg msg;
+ struct cec_fh *fh;
+ struct delayed_work work;
+ struct completion c;
+ u8 attempts;
+ bool new_initiator;
+ bool blocking;
+ bool completed;
+};
+
+struct cec_msg_entry {
+ struct list_head list;
+ struct cec_msg msg;
+};
+
+#define CEC_NUM_EVENTS CEC_EVENT_LOST_MSGS
+
+struct cec_fh {
+ struct list_head list;
+ struct list_head xfer_list;
+ struct cec_adapter *adap;
+ u8 mode_initiator;
+ u8 mode_follower;
+
+ /* Events */
+ wait_queue_head_t wait;
+ unsigned int pending_events;
+ struct cec_event events[CEC_NUM_EVENTS];
+ struct mutex lock;
+ struct list_head msgs; /* queued messages */
+ unsigned int queued_msgs;
+};
+
+#define CEC_SIGNAL_FREE_TIME_RETRY 3
+#define CEC_SIGNAL_FREE_TIME_NEW_INITIATOR 5
+#define CEC_SIGNAL_FREE_TIME_NEXT_XFER 7
+
+/* The nominal data bit period is 2.4 ms */
+#define CEC_FREE_TIME_TO_USEC(ft) ((ft) * 2400)
+
+struct cec_adap_ops {
+ /* Low-level callbacks */
+ int (*adap_enable)(struct cec_adapter *adap, bool enable);
+ int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
+ int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
+ int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
+ u32 signal_free_time, struct cec_msg *msg);
+ void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
+
+ /* High-level CEC message callback */
+ int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
+};
+
+/*
+ * The minimum message length you can receive (excepting poll messages) is 2.
+ * With a transfer rate of at most 36 bytes per second this makes 18 messages
+ * per second worst case.
+ *
+ * We queue at most 3 seconds worth of received messages. The CEC specification
+ * requires that messages are replied to within a second, so 3 seconds should
+ * give more than enough margin. Since most messages are actually more than 2
+ * bytes, this is in practice a lot more than 3 seconds.
+ */
+#define CEC_MAX_MSG_RX_QUEUE_SZ (18 * 3)
+
+/*
+ * The transmit queue is limited to 1 second worth of messages (worst case).
+ * Messages can be transmitted by userspace and kernel space. But for both it
+ * makes no sense to have a lot of messages queued up. One second seems
+ * reasonable.
+ */
+#define CEC_MAX_MSG_TX_QUEUE_SZ (18 * 1)
+
+struct cec_adapter {
+ struct module *owner;
+ char name[32];
+ struct cec_devnode devnode;
+ struct mutex lock;
+ struct rc_dev *rc;
+
+ struct list_head transmit_queue;
+ unsigned int transmit_queue_sz;
+ struct list_head wait_queue;
+ struct cec_data *transmitting;
+
+ struct task_struct *kthread_config;
+ struct completion config_completion;
+
+ struct task_struct *kthread;
+ wait_queue_head_t kthread_waitq;
+ wait_queue_head_t waitq;
+
+ const struct cec_adap_ops *ops;
+ void *priv;
+ u32 capabilities;
+ u8 available_log_addrs;
+
+ u16 phys_addr;
+ bool is_configuring;
+ bool is_configured;
+ u32 monitor_all_cnt;
+ u32 follower_cnt;
+ struct cec_fh *cec_follower;
+ struct cec_fh *cec_initiator;
+ bool passthrough;
+ struct cec_log_addrs log_addrs;
+
+ struct dentry *cec_dir;
+ struct dentry *status_file;
+
+ u16 phys_addrs[15];
+ u32 sequence;
+
+ char input_name[32];
+ char input_phys[32];
+ char input_drv[32];
+};
+
+static inline bool cec_has_log_addr(const struct cec_adapter *adap, u8 log_addr)
+{
+ return adap->log_addrs.log_addr_mask & (1 << log_addr);
+}
+
+static inline bool cec_is_sink(const struct cec_adapter *adap)
+{
+ return adap->phys_addr == 0;
+}
+
+#if IS_ENABLED(CONFIG_MEDIA_CEC)
+struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
+ void *priv, const char *name, u32 caps, u8 available_las,
+ struct device *parent);
+int cec_register_adapter(struct cec_adapter *adap);
+void cec_unregister_adapter(struct cec_adapter *adap);
+void cec_delete_adapter(struct cec_adapter *adap);
+
+int cec_s_log_addrs(struct cec_adapter *adap, struct cec_log_addrs *log_addrs,
+ bool block);
+void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
+ bool block);
+int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg,
+ bool block);
+
+/* Called by the adapter */
+void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
+ u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt);
+void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg);
+
+#else
+
+static inline int cec_register_adapter(struct cec_adapter *adap)
+{
+ return 0;
+}
+
+static inline void cec_unregister_adapter(struct cec_adapter *adap)
+{
+}
+
+static inline void cec_delete_adapter(struct cec_adapter *adap)
+{
+}
+
+static inline void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
+ bool block)
+{
+}
+
+#endif
+
+#endif /* _MEDIA_CEC_H */
diff --git a/include/media/davinci/vpbe_display.h b/include/media/davinci/vpbe_display.h
index e14a9370b67e..12783fd823f8 100644
--- a/include/media/davinci/vpbe_display.h
+++ b/include/media/davinci/vpbe_display.h
@@ -81,8 +81,6 @@ struct vpbe_layer {
* Buffer queue used in video-buf
*/
struct vb2_queue buffer_queue;
- /* allocator-specific contexts for each plane */
- struct vb2_alloc_ctx *alloc_ctx;
/* Queue of filled frames */
struct list_head dma_queue;
/* Used in video-buf */
diff --git a/include/media/i2c/adv7511.h b/include/media/i2c/adv7511.h
index d83b91d80764..61c3d711cc69 100644
--- a/include/media/i2c/adv7511.h
+++ b/include/media/i2c/adv7511.h
@@ -32,11 +32,7 @@ struct adv7511_monitor_detect {
struct adv7511_edid_detect {
int present;
int segment;
-};
-
-struct adv7511_cec_arg {
- void *arg;
- u32 f_flags;
+ uint16_t phys_addr;
};
struct adv7511_platform_data {
diff --git a/include/media/i2c/adv7604.h b/include/media/i2c/adv7604.h
index a913859bfd30..2e6857dee0cc 100644
--- a/include/media/i2c/adv7604.h
+++ b/include/media/i2c/adv7604.h
@@ -121,8 +121,6 @@ struct adv76xx_platform_data {
/* IO register 0x02 */
unsigned alt_gamma:1;
- unsigned op_656_range:1;
- unsigned alt_data_sat:1;
/* IO register 0x05 */
unsigned blank_data:1;
diff --git a/include/media/i2c/adv7842.h b/include/media/i2c/adv7842.h
index bc249709bf35..7f53ada9bdf1 100644
--- a/include/media/i2c/adv7842.h
+++ b/include/media/i2c/adv7842.h
@@ -165,8 +165,6 @@ struct adv7842_platform_data {
/* IO register 0x02 */
unsigned alt_gamma:1;
- unsigned op_656_range:1;
- unsigned alt_data_sat:1;
/* IO register 0x05 */
unsigned blank_data:1;
diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h
index 0ab59a571fee..cec7d35602d1 100644
--- a/include/media/lirc_dev.h
+++ b/include/media/lirc_dev.h
@@ -140,7 +140,7 @@ static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf,
* second.
*
* @features: lirc compatible hardware features, like LIRC_MODE_RAW,
- * LIRC_CAN_*, as defined at include/media/lirc.h.
+ * LIRC_CAN\_\*, as defined at include/media/lirc.h.
*
* @chunk_size: Size of each FIFO buffer.
*
diff --git a/include/media/media-device.h b/include/media/media-device.h
index a9b33c47310d..28195242386c 100644
--- a/include/media/media-device.h
+++ b/include/media/media-device.h
@@ -29,237 +29,6 @@
#include <media/media-devnode.h>
#include <media/media-entity.h>
-/**
- * DOC: Media Controller
- *
- * The media controller userspace API is documented in DocBook format in
- * Documentation/DocBook/media/v4l/media-controller.xml. This document focus
- * on the kernel-side implementation of the media framework.
- *
- * * Abstract media device model:
- *
- * Discovering a device internal topology, and configuring it at runtime, is one
- * of the goals of the media framework. To achieve this, hardware devices are
- * modelled as an oriented graph of building blocks called entities connected
- * through pads.
- *
- * An entity is a basic media hardware building block. It can correspond to
- * a large variety of logical blocks such as physical hardware devices
- * (CMOS sensor for instance), logical hardware devices (a building block
- * in a System-on-Chip image processing pipeline), DMA channels or physical
- * connectors.
- *
- * A pad is a connection endpoint through which an entity can interact with
- * other entities. Data (not restricted to video) produced by an entity
- * flows from the entity's output to one or more entity inputs. Pads should
- * not be confused with physical pins at chip boundaries.
- *
- * A link is a point-to-point oriented connection between two pads, either
- * on the same entity or on different entities. Data flows from a source
- * pad to a sink pad.
- *
- *
- * * Media device:
- *
- * A media device is represented by a struct &media_device instance, defined in
- * include/media/media-device.h. Allocation of the structure is handled by the
- * media device driver, usually by embedding the &media_device instance in a
- * larger driver-specific structure.
- *
- * Drivers register media device instances by calling
- * __media_device_register() via the macro media_device_register()
- * and unregistered by calling
- * media_device_unregister().
- *
- * * Entities, pads and links:
- *
- * - Entities
- *
- * Entities are represented by a struct &media_entity instance, defined in
- * include/media/media-entity.h. The structure is usually embedded into a
- * higher-level structure, such as a v4l2_subdev or video_device instance,
- * although drivers can allocate entities directly.
- *
- * Drivers initialize entity pads by calling
- * media_entity_pads_init().
- *
- * Drivers register entities with a media device by calling
- * media_device_register_entity()
- * and unregistred by calling
- * media_device_unregister_entity().
- *
- * - Interfaces
- *
- * Interfaces are represented by a struct &media_interface instance, defined in
- * include/media/media-entity.h. Currently, only one type of interface is
- * defined: a device node. Such interfaces are represented by a struct
- * &media_intf_devnode.
- *
- * Drivers initialize and create device node interfaces by calling
- * media_devnode_create()
- * and remove them by calling:
- * media_devnode_remove().
- *
- * - Pads
- *
- * Pads are represented by a struct &media_pad instance, defined in
- * include/media/media-entity.h. Each entity stores its pads in a pads array
- * managed by the entity driver. Drivers usually embed the array in a
- * driver-specific structure.
- *
- * Pads are identified by their entity and their 0-based index in the pads
- * array.
- * Both information are stored in the &media_pad structure, making the
- * &media_pad pointer the canonical way to store and pass link references.
- *
- * Pads have flags that describe the pad capabilities and state.
- *
- * %MEDIA_PAD_FL_SINK indicates that the pad supports sinking data.
- * %MEDIA_PAD_FL_SOURCE indicates that the pad supports sourcing data.
- *
- * NOTE: One and only one of %MEDIA_PAD_FL_SINK and %MEDIA_PAD_FL_SOURCE must
- * be set for each pad.
- *
- * - Links
- *
- * Links are represented by a struct &media_link instance, defined in
- * include/media/media-entity.h. There are two types of links:
- *
- * 1. pad to pad links:
- *
- * Associate two entities via their PADs. Each entity has a list that points
- * to all links originating at or targeting any of its pads.
- * A given link is thus stored twice, once in the source entity and once in
- * the target entity.
- *
- * Drivers create pad to pad links by calling:
- * media_create_pad_link() and remove with media_entity_remove_links().
- *
- * 2. interface to entity links:
- *
- * Associate one interface to a Link.
- *
- * Drivers create interface to entity links by calling:
- * media_create_intf_link() and remove with media_remove_intf_links().
- *
- * NOTE:
- *
- * Links can only be created after having both ends already created.
- *
- * Links have flags that describe the link capabilities and state. The
- * valid values are described at media_create_pad_link() and
- * media_create_intf_link().
- *
- * Graph traversal:
- *
- * The media framework provides APIs to iterate over entities in a graph.
- *
- * To iterate over all entities belonging to a media device, drivers can use
- * the media_device_for_each_entity macro, defined in
- * include/media/media-device.h.
- *
- * struct media_entity *entity;
- *
- * media_device_for_each_entity(entity, mdev) {
- * // entity will point to each entity in turn
- * ...
- * }
- *
- * Drivers might also need to iterate over all entities in a graph that can be
- * reached only through enabled links starting at a given entity. The media
- * framework provides a depth-first graph traversal API for that purpose.
- *
- * Note that graphs with cycles (whether directed or undirected) are *NOT*
- * supported by the graph traversal API. To prevent infinite loops, the graph
- * traversal code limits the maximum depth to MEDIA_ENTITY_ENUM_MAX_DEPTH,
- * currently defined as 16.
- *
- * Drivers initiate a graph traversal by calling
- * media_entity_graph_walk_start()
- *
- * The graph structure, provided by the caller, is initialized to start graph
- * traversal at the given entity.
- *
- * Drivers can then retrieve the next entity by calling
- * media_entity_graph_walk_next()
- *
- * When the graph traversal is complete the function will return NULL.
- *
- * Graph traversal can be interrupted at any moment. No cleanup function call
- * is required and the graph structure can be freed normally.
- *
- * Helper functions can be used to find a link between two given pads, or a pad
- * connected to another pad through an enabled link
- * media_entity_find_link() and media_entity_remote_pad()
- *
- * Use count and power handling:
- *
- * Due to the wide differences between drivers regarding power management
- * needs, the media controller does not implement power management. However,
- * the &media_entity structure includes a use_count field that media drivers
- * can use to track the number of users of every entity for power management
- * needs.
- *
- * The &media_entity.@use_count field is owned by media drivers and must not be
- * touched by entity drivers. Access to the field must be protected by the
- * &media_device.@graph_mutex lock.
- *
- * Links setup:
- *
- * Link properties can be modified at runtime by calling
- * media_entity_setup_link()
- *
- * Pipelines and media streams:
- *
- * When starting streaming, drivers must notify all entities in the pipeline to
- * prevent link states from being modified during streaming by calling
- * media_entity_pipeline_start().
- *
- * The function will mark all entities connected to the given entity through
- * enabled links, either directly or indirectly, as streaming.
- *
- * The &media_pipeline instance pointed to by the pipe argument will be stored
- * in every entity in the pipeline. Drivers should embed the &media_pipeline
- * structure in higher-level pipeline structures and can then access the
- * pipeline through the &media_entity pipe field.
- *
- * Calls to media_entity_pipeline_start() can be nested. The pipeline pointer
- * must be identical for all nested calls to the function.
- *
- * media_entity_pipeline_start() may return an error. In that case, it will
- * clean up any of the changes it did by itself.
- *
- * When stopping the stream, drivers must notify the entities with
- * media_entity_pipeline_stop().
- *
- * If multiple calls to media_entity_pipeline_start() have been made the same
- * number of media_entity_pipeline_stop() calls are required to stop streaming.
- * The &media_entity pipe field is reset to NULL on the last nested stop call.
- *
- * Link configuration will fail with -%EBUSY by default if either end of the
- * link is a streaming entity. Links that can be modified while streaming must
- * be marked with the %MEDIA_LNK_FL_DYNAMIC flag.
- *
- * If other operations need to be disallowed on streaming entities (such as
- * changing entities configuration parameters) drivers can explicitly check the
- * media_entity stream_count field to find out if an entity is streaming. This
- * operation must be done with the media_device graph_mutex held.
- *
- * Link validation:
- *
- * Link validation is performed by media_entity_pipeline_start() for any
- * entity which has sink pads in the pipeline. The
- * &media_entity.@link_validate() callback is used for that purpose. In
- * @link_validate() callback, entity driver should check that the properties of
- * the source pad of the connected entity and its own sink pad match. It is up
- * to the type of the entity (and in the end, the properties of the hardware)
- * what matching actually means.
- *
- * Subsystems should facilitate link validation by providing subsystem specific
- * helper functions to provide easy access for commonly needed information, and
- * in the end provide a way to use driver-specific callbacks.
- */
-
struct ida;
struct device;
@@ -347,7 +116,7 @@ struct media_entity_notify {
struct media_device {
/* dev->driver_data points to this struct. */
struct device *dev;
- struct media_devnode devnode;
+ struct media_devnode *devnode;
char model[32];
char driver_name[32];
@@ -393,9 +162,6 @@ struct usb_device;
#define MEDIA_DEV_NOTIFY_PRE_LINK_CH 0
#define MEDIA_DEV_NOTIFY_POST_LINK_CH 1
-/* media_devnode to media_device */
-#define to_media_device(node) container_of(node, struct media_device, devnode)
-
/**
* media_entity_enum_init - Initialise an entity enumeration
*
@@ -476,13 +242,11 @@ void media_device_cleanup(struct media_device *mdev);
* without breaking binary compatibility. The version major must be
* incremented when binary compatibility is broken.
*
- * Notes:
+ * .. note::
*
- * Upon successful registration a character device named media[0-9]+ is created.
- * The device major and minor numbers are dynamic. The model name is exported as
- * a sysfs attribute.
+ * #) Upon successful registration a character device named media[0-9]+ is created. The device major and minor numbers are dynamic. The model name is exported as a sysfs attribute.
*
- * Unregistering a media device that hasn't been registered is *NOT* safe.
+ * #) Unregistering a media device that hasn't been registered is **NOT** safe.
*
* Return: returns zero on success or a negative error code.
*/
@@ -530,14 +294,16 @@ void media_device_unregister(struct media_device *mdev);
* This can be used to report the default audio and video devices or the
* default camera sensor.
*
- * NOTE: Drivers should set the entity function before calling this function.
- * Please notice that the values %MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN and
- * %MEDIA_ENT_F_UNKNOWN should not be used by the drivers.
+ * .. note::
+ *
+ * Drivers should set the entity function before calling this function.
+ * Please notice that the values %MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN and
+ * %MEDIA_ENT_F_UNKNOWN should not be used by the drivers.
*/
int __must_check media_device_register_entity(struct media_device *mdev,
struct media_entity *entity);
-/*
+/**
* media_device_unregister_entity() - unregisters a media entity.
*
* @entity: pointer to struct &media_entity to be unregistered
@@ -551,8 +317,10 @@ int __must_check media_device_register_entity(struct media_device *mdev,
* When a media device is unregistered, all its entities are unregistered
* automatically. No manual entities unregistration is then required.
*
- * Note: the media_entity instance itself must be freed explicitly by
- * the driver if required.
+ * .. note::
+ *
+ * The media_entity instance itself must be freed explicitly by
+ * the driver if required.
*/
void media_device_unregister_entity(struct media_entity *entity);
diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h
index fe42f08e72bd..37d494805944 100644
--- a/include/media/media-devnode.h
+++ b/include/media/media-devnode.h
@@ -33,6 +33,8 @@
#include <linux/device.h>
#include <linux/cdev.h>
+struct media_device;
+
/*
* Flag to mark the media_devnode struct as registered. Drivers must not touch
* this flag directly, it will be set and cleared by media_devnode_register and
@@ -67,8 +69,9 @@ struct media_file_operations {
/**
* struct media_devnode - Media device node
+ * @media_dev: pointer to struct &media_device
* @fops: pointer to struct &media_file_operations with media device ops
- * @dev: struct device pointer for the media controller device
+ * @dev: pointer to struct &device containing the media controller device
* @cdev: struct cdev pointer character device
* @parent: parent device
* @minor: device node minor number
@@ -81,6 +84,8 @@ struct media_file_operations {
* before registering the node.
*/
struct media_devnode {
+ struct media_device *media_dev;
+
/* device ops */
const struct media_file_operations *fops;
@@ -94,7 +99,7 @@ struct media_devnode {
unsigned long flags; /* Use bitops to access flags */
/* callbacks */
- void (*release)(struct media_devnode *mdev);
+ void (*release)(struct media_devnode *devnode);
};
/* dev to media_devnode */
@@ -103,7 +108,8 @@ struct media_devnode {
/**
* media_devnode_register - register a media device node
*
- * @mdev: media device node structure we want to register
+ * @mdev: struct media_device we want to register a device node
+ * @devnode: media device node structure we want to register
* @owner: should be filled with %THIS_MODULE
*
* The registration code assigns minor numbers and registers the new device node
@@ -116,20 +122,33 @@ struct media_devnode {
* the media_devnode structure is *not* called, so the caller is responsible for
* freeing any data.
*/
-int __must_check media_devnode_register(struct media_devnode *mdev,
+int __must_check media_devnode_register(struct media_device *mdev,
+ struct media_devnode *devnode,
struct module *owner);
/**
+ * media_devnode_unregister_prepare - clear the media device node register bit
+ * @devnode: the device node to prepare for unregister
+ *
+ * This clears the passed device register bit. Future open calls will be met
+ * with errors. Should be called before media_devnode_unregister() to avoid
+ * races with unregister and device file open calls.
+ *
+ * This function can safely be called if the device node has never been
+ * registered or has already been unregistered.
+ */
+void media_devnode_unregister_prepare(struct media_devnode *devnode);
+
+/**
* media_devnode_unregister - unregister a media device node
- * @mdev: the device node to unregister
+ * @devnode: the device node to unregister
*
* This unregisters the passed device. Future open calls will be met with
* errors.
*
- * This function can safely be called if the device node has never been
- * registered or has already been unregistered.
+ * Should be called after media_devnode_unregister_prepare()
*/
-void media_devnode_unregister(struct media_devnode *mdev);
+void media_devnode_unregister(struct media_devnode *devnode);
/**
* media_devnode_data - returns a pointer to the &media_devnode
@@ -145,11 +164,16 @@ static inline struct media_devnode *media_devnode_data(struct file *filp)
* media_devnode_is_registered - returns true if &media_devnode is registered;
* false otherwise.
*
- * @mdev: pointer to struct &media_devnode.
+ * @devnode: pointer to struct &media_devnode.
+ *
+ * Note: If mdev is NULL, it also returns false.
*/
-static inline int media_devnode_is_registered(struct media_devnode *mdev)
+static inline int media_devnode_is_registered(struct media_devnode *devnode)
{
- return test_bit(MEDIA_FLAG_REGISTERED, &mdev->flags);
+ if (!devnode)
+ return false;
+
+ return test_bit(MEDIA_FLAG_REGISTERED, &devnode->flags);
}
#endif /* _MEDIA_DEVNODE_H */
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index cbb266f7f2b5..09b03c17784d 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -104,7 +104,7 @@ struct media_entity_graph {
int top;
};
-/*
+/**
* struct media_pipeline - Media pipeline related information
*
* @streaming_count: Streaming start count - streaming stop count
@@ -180,8 +180,10 @@ struct media_pad {
* view. The media_entity_pipeline_start() function
* validates all links by calling this operation. Optional.
*
- * Note: Those these callbacks are called with struct media_device.@graph_mutex
- * mutex held.
+ * .. note::
+ *
+ * Those these callbacks are called with struct media_device.@graph_mutex
+ * mutex held.
*/
struct media_entity_operations {
int (*link_setup)(struct media_entity *entity,
@@ -538,7 +540,7 @@ static inline bool media_entity_enum_intersects(
* @gobj: Pointer to the graph object
*
* This routine initializes the embedded struct media_gobj inside a
- * media graph object. It is called automatically if media_*_create()
+ * media graph object. It is called automatically if media_*_create\(\)
* calls are used. However, if the object (entity, link, pad, interface)
* is embedded on some other object, this function should be called before
* registering the object at the media controller.
@@ -602,19 +604,20 @@ static inline void media_entity_cleanup(struct media_entity *entity) {};
* @flags: Link flags, as defined in include/uapi/linux/media.h.
*
* Valid values for flags:
- * A %MEDIA_LNK_FL_ENABLED flag indicates that the link is enabled and can be
- * used to transfer media data. When two or more links target a sink pad,
- * only one of them can be enabled at a time.
*
- * A %MEDIA_LNK_FL_IMMUTABLE flag indicates that the link enabled state can't
- * be modified at runtime. If %MEDIA_LNK_FL_IMMUTABLE is set, then
- * %MEDIA_LNK_FL_ENABLED must also be set since an immutable link is
- * always enabled.
+ * - A %MEDIA_LNK_FL_ENABLED flag indicates that the link is enabled and can
+ * be used to transfer media data. When two or more links target a sink pad,
+ * only one of them can be enabled at a time.
+ *
+ * - A %MEDIA_LNK_FL_IMMUTABLE flag indicates that the link enabled state can't
+ * be modified at runtime. If %MEDIA_LNK_FL_IMMUTABLE is set, then
+ * %MEDIA_LNK_FL_ENABLED must also be set since an immutable link is
+ * always enabled.
*
- * NOTE:
+ * .. note::
*
- * Before calling this function, media_entity_pads_init() and
- * media_device_register_entity() should be called previously for both ends.
+ * Before calling this function, media_entity_pads_init() and
+ * media_device_register_entity() should be called previously for both ends.
*/
__must_check int media_create_pad_link(struct media_entity *source,
u16 source_pad, struct media_entity *sink,
@@ -641,6 +644,7 @@ __must_check int media_create_pad_link(struct media_entity *source,
* and @sink are NULL.
*
* Valid values for flags:
+ *
* A %MEDIA_LNK_FL_ENABLED flag indicates that the link is enabled and can be
* used to transfer media data. If multiple links are created and this
* flag is passed as an argument, only the first created link will have
@@ -677,8 +681,10 @@ void __media_entity_remove_links(struct media_entity *entity);
*
* @entity: pointer to &media_entity
*
- * Note: this is called automatically when an entity is unregistered via
- * media_device_register_entity().
+ * .. note::
+ *
+ * This is called automatically when an entity is unregistered via
+ * media_device_register_entity().
*/
void media_entity_remove_links(struct media_entity *entity);
@@ -728,9 +734,11 @@ int __media_entity_setup_link(struct media_link *link, u32 flags);
* being enabled, the link_setup operation must return -EBUSY and can't
* implicitly disable the first enabled link.
*
- * NOTE: the valid values of the flags for the link is the same as described
- * on media_create_pad_link(), for pad to pad links or the same as described
- * on media_create_intf_link(), for interface to entity links.
+ * .. note::
+ *
+ * The valid values of the flags for the link is the same as described
+ * on media_create_pad_link(), for pad to pad links or the same as described
+ * on media_create_intf_link(), for interface to entity links.
*/
int media_entity_setup_link(struct media_link *link, u32 flags);
@@ -844,7 +852,7 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity,
* @entity: Starting entity
* @pipe: Media pipeline to be assigned to all entities in the pipeline.
*
- * Note: This is the non-locking version of media_entity_pipeline_start()
+ * ..note:: This is the non-locking version of media_entity_pipeline_start()
*/
__must_check int __media_entity_pipeline_start(struct media_entity *entity,
struct media_pipeline *pipe);
@@ -868,7 +876,7 @@ void media_entity_pipeline_stop(struct media_entity *entity);
*
* @entity: Starting entity
*
- * Note: This is the non-locking version of media_entity_pipeline_stop()
+ * .. note:: This is the non-locking version of media_entity_pipeline_stop()
*/
void __media_entity_pipeline_stop(struct media_entity *entity);
@@ -909,20 +917,21 @@ struct media_link *
*
*
* Valid values for flags:
- * The %MEDIA_LNK_FL_ENABLED flag indicates that the interface is connected to
- * the entity hardware. That's the default value for interfaces. An
- * interface may be disabled if the hardware is busy due to the usage
- * of some other interface that it is currently controlling the hardware.
- * A typical example is an hybrid TV device that handle only one type of
- * stream on a given time. So, when the digital TV is streaming,
- * the V4L2 interfaces won't be enabled, as such device is not able to
- * also stream analog TV or radio.
*
- * Note:
+ * - The %MEDIA_LNK_FL_ENABLED flag indicates that the interface is connected to
+ * the entity hardware. That's the default value for interfaces. An
+ * interface may be disabled if the hardware is busy due to the usage
+ * of some other interface that it is currently controlling the hardware.
+ * A typical example is an hybrid TV device that handle only one type of
+ * stream on a given time. So, when the digital TV is streaming,
+ * the V4L2 interfaces won't be enabled, as such device is not able to
+ * also stream analog TV or radio.
+ *
+ * .. note::
*
- * Before calling this function, media_devnode_create() should be called for
- * the interface and media_device_register_entity() should be called for the
- * interface that will be part of the link.
+ * Before calling this function, media_devnode_create() should be called for
+ * the interface and media_device_register_entity() should be called for the
+ * interface that will be part of the link.
*/
__must_check media_create_intf_link(struct media_entity *entity,
struct media_interface *intf,
@@ -932,7 +941,7 @@ __must_check media_create_intf_link(struct media_entity *entity,
*
* @link: pointer to &media_link.
*
- * Note: this is an unlocked version of media_remove_intf_link()
+ * .. note:: This is an unlocked version of media_remove_intf_link()
*/
void __media_remove_intf_link(struct media_link *link);
@@ -941,7 +950,7 @@ void __media_remove_intf_link(struct media_link *link);
*
* @link: pointer to &media_link.
*
- * Note: prefer to use this one, instead of __media_remove_intf_link()
+ * .. note:: Prefer to use this one, instead of __media_remove_intf_link()
*/
void media_remove_intf_link(struct media_link *link);
@@ -950,7 +959,7 @@ void media_remove_intf_link(struct media_link *link);
*
* @intf: pointer to &media_interface
*
- * Note: this is an unlocked version of media_remove_intf_links().
+ * .. note:: This is an unlocked version of media_remove_intf_links().
*/
void __media_remove_intf_links(struct media_interface *intf);
@@ -959,12 +968,12 @@ void __media_remove_intf_links(struct media_interface *intf);
*
* @intf: pointer to &media_interface
*
- * Notes:
+ * .. note::
*
- * this is called automatically when an entity is unregistered via
- * media_device_register_entity() and by media_devnode_remove().
+ * #) This is called automatically when an entity is unregistered via
+ * media_device_register_entity() and by media_devnode_remove().
*
- * Prefer to use this one, instead of __media_remove_intf_links().
+ * #) Prefer to use this one, instead of __media_remove_intf_links().
*/
void media_remove_intf_links(struct media_interface *intf);
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index b6586a91129c..10908e356b23 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -29,9 +29,16 @@ do { \
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
+/**
+ * enum rc_driver_type - type of the RC output
+ *
+ * @RC_DRIVER_SCANCODE: Driver or hardware generates a scancode
+ * @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences.
+ * It needs a Infra-Red pulse/space decoder
+ */
enum rc_driver_type {
- RC_DRIVER_SCANCODE = 0, /* Driver or hardware generates a scancode */
- RC_DRIVER_IR_RAW, /* Needs a Infra-Red pulse/space decoder */
+ RC_DRIVER_SCANCODE = 0,
+ RC_DRIVER_IR_RAW,
};
/**
@@ -119,6 +126,7 @@ enum rc_filter_type {
* @s_carrier_report: enable carrier reports
* @s_filter: set the scancode filter
* @s_wakeup_filter: set the wakeup scancode filter
+ * @s_timeout: set hardware timeout in ns
*/
struct rc_dev {
struct device dev;
@@ -174,6 +182,8 @@ struct rc_dev {
struct rc_scancode_filter *filter);
int (*s_wakeup_filter)(struct rc_dev *dev,
struct rc_scancode_filter *filter);
+ int (*s_timeout)(struct rc_dev *dev,
+ unsigned int timeout);
};
#define to_rc_dev(d) container_of(d, struct rc_dev, dev)
@@ -185,12 +195,46 @@ struct rc_dev {
* Remote Controller, at sys/class/rc.
*/
+/**
+ * rc_allocate_device - Allocates a RC device
+ *
+ * returns a pointer to struct rc_dev.
+ */
struct rc_dev *rc_allocate_device(void);
+
+/**
+ * rc_free_device - Frees a RC device
+ *
+ * @dev: pointer to struct rc_dev.
+ */
void rc_free_device(struct rc_dev *dev);
+
+/**
+ * rc_register_device - Registers a RC device
+ *
+ * @dev: pointer to struct rc_dev.
+ */
int rc_register_device(struct rc_dev *dev);
+
+/**
+ * rc_unregister_device - Unregisters a RC device
+ *
+ * @dev: pointer to struct rc_dev.
+ */
void rc_unregister_device(struct rc_dev *dev);
+/**
+ * rc_open - Opens a RC device
+ *
+ * @rdev: pointer to struct rc_dev.
+ */
int rc_open(struct rc_dev *rdev);
+
+/**
+ * rc_open - Closes a RC device
+ *
+ * @rdev: pointer to struct rc_dev.
+ */
void rc_close(struct rc_dev *rdev);
void rc_repeat(struct rc_dev *dev);
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 7844e9879497..daa75fcc1ff1 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -31,6 +31,7 @@ enum rc_type {
RC_TYPE_RC6_MCE = 16, /* MCE (Philips RC6-6A-32 subtype) protocol */
RC_TYPE_SHARP = 17, /* Sharp protocol */
RC_TYPE_XMP = 18, /* XMP protocol */
+ RC_TYPE_CEC = 19, /* CEC protocol */
};
#define RC_BIT_NONE 0ULL
@@ -53,6 +54,7 @@ enum rc_type {
#define RC_BIT_RC6_MCE (1ULL << RC_TYPE_RC6_MCE)
#define RC_BIT_SHARP (1ULL << RC_TYPE_SHARP)
#define RC_BIT_XMP (1ULL << RC_TYPE_XMP)
+#define RC_BIT_CEC (1ULL << RC_TYPE_CEC)
#define RC_BIT_ALL (RC_BIT_UNKNOWN | RC_BIT_OTHER | \
RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ | \
@@ -61,7 +63,7 @@ enum rc_type {
RC_BIT_NEC | RC_BIT_SANYO | RC_BIT_MCE_KBD | \
RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \
RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | RC_BIT_SHARP | \
- RC_BIT_XMP)
+ RC_BIT_XMP | RC_BIT_CEC)
#define RC_SCANCODE_UNKNOWN(x) (x)
@@ -96,10 +98,25 @@ struct rc_map_list {
/* Routines from rc-map.c */
+/**
+ * rc_map_register() - Registers a Remote Controler scancode map
+ *
+ * @map: pointer to struct rc_map_list
+ */
int rc_map_register(struct rc_map_list *map);
+
+/**
+ * rc_map_unregister() - Unregisters a Remote Controler scancode map
+ *
+ * @map: pointer to struct rc_map_list
+ */
void rc_map_unregister(struct rc_map_list *map);
+
+/**
+ * rc_map_get - gets an RC map from its name
+ * @name: name of the RC scancode map
+ */
struct rc_map *rc_map_get(const char *name);
-void rc_map_init(void);
/* Names of the several keytables defined in-kernel */
@@ -123,6 +140,7 @@ void rc_map_init(void);
#define RC_MAP_BEHOLD_COLUMBUS "rc-behold-columbus"
#define RC_MAP_BEHOLD "rc-behold"
#define RC_MAP_BUDGET_CI_OLD "rc-budget-ci-old"
+#define RC_MAP_CEC "rc-cec"
#define RC_MAP_CINERGY_1400 "rc-cinergy-1400"
#define RC_MAP_CINERGY "rc-cinergy"
#define RC_MAP_DELOCK_61959 "rc-delock-61959"
@@ -133,6 +151,7 @@ void rc_map_init(void);
#define RC_MAP_DM1105_NEC "rc-dm1105-nec"
#define RC_MAP_DNTV_LIVE_DVBT_PRO "rc-dntv-live-dvbt-pro"
#define RC_MAP_DNTV_LIVE_DVB_T "rc-dntv-live-dvb-t"
+#define RC_MAP_DTT200U "rc-dtt200u"
#define RC_MAP_DVBSKY "rc-dvbsky"
#define RC_MAP_EMPTY "rc-empty"
#define RC_MAP_EM_TERRATEC "rc-em-terratec"
diff --git a/include/media/rcar-fcp.h b/include/media/rcar-fcp.h
new file mode 100644
index 000000000000..4c7fc77eaf29
--- /dev/null
+++ b/include/media/rcar-fcp.h
@@ -0,0 +1,37 @@
+/*
+ * rcar-fcp.h -- R-Car Frame Compression Processor Driver
+ *
+ * Copyright (C) 2016 Renesas Electronics Corporation
+ *
+ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __MEDIA_RCAR_FCP_H__
+#define __MEDIA_RCAR_FCP_H__
+
+struct device_node;
+struct rcar_fcp_device;
+
+#if IS_ENABLED(CONFIG_VIDEO_RENESAS_FCP)
+struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np);
+void rcar_fcp_put(struct rcar_fcp_device *fcp);
+int rcar_fcp_enable(struct rcar_fcp_device *fcp);
+void rcar_fcp_disable(struct rcar_fcp_device *fcp);
+#else
+static inline struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
+{
+ return ERR_PTR(-ENOENT);
+}
+static inline void rcar_fcp_put(struct rcar_fcp_device *fcp) { }
+static inline int rcar_fcp_enable(struct rcar_fcp_device *fcp)
+{
+ return -ENOSYS;
+}
+static inline void rcar_fcp_disable(struct rcar_fcp_device *fcp) { }
+#endif
+
+#endif /* __MEDIA_RCAR_FCP_H__ */
diff --git a/include/media/tuner-types.h b/include/media/tuner-types.h
index 094e112cc325..aed539068d2d 100644
--- a/include/media/tuner-types.h
+++ b/include/media/tuner-types.h
@@ -35,8 +35,12 @@ enum param_type {
* those ranges, as they're defined inside the driver. This is used by
* analog tuners that are compatible with the "Philips way" to setup the
* tuners. On those devices, the tuner set is done via 4 bytes:
- * divider byte1 (DB1), divider byte 2 (DB2), Control byte (CB) and
- * band switch byte (BB).
+ *
+ * #) divider byte1 (DB1)
+ * #) divider byte 2 (DB2)
+ * #) Control byte (CB)
+ * #) band switch byte (BB)
+ *
* Some tuners also have an additional optional Auxiliary byte (AB).
*/
struct tuner_range {
diff --git a/include/media/tveeprom.h b/include/media/tveeprom.h
index 8be898739e0c..c56501ee0484 100644
--- a/include/media/tveeprom.h
+++ b/include/media/tveeprom.h
@@ -27,31 +27,43 @@ enum tveeprom_audio_processor {
* struct tveeprom - Contains the fields parsed from Hauppauge eeproms
*
* @has_radio: 1 if the device has radio; 0 otherwise.
+ *
* @has_ir: If has_ir == 0, then it is unknown what the IR
* capabilities are. Otherwise:
- * bit 0) 1 (= IR capabilities are known);
- * bit 1) IR receiver present;
- * bit 2) IR transmitter (blaster) present.
+ * bit 0) 1 (= IR capabilities are known);
+ * bit 1) IR receiver present;
+ * bit 2) IR transmitter (blaster) present.
+ *
* @has_MAC_address: 0: no MAC, 1: MAC present, 2: unknown.
* @tuner_type: type of the tuner (TUNER_*, as defined at
* include/media/tuner.h).
+ *
* @tuner_formats: Supported analog TV standards (V4L2_STD_*).
* @tuner_hauppauge_model: Hauppauge's code for the device model number.
* @tuner2_type: type of the second tuner (TUNER_*, as defined
* at include/media/tuner.h).
+ *
* @tuner2_formats: Tuner 2 supported analog TV standards
* (V4L2_STD_*).
+ *
* @tuner2_hauppauge_model: tuner 2 Hauppauge's code for the device model
* number.
+ *
* @audio_processor: analog audio decoder, as defined by enum
* tveeprom_audio_processor.
+ *
* @decoder_processor: Hauppauge's code for the decoder chipset.
* Unused by the drivers, as they probe the
* decoder based on the PCI or USB ID.
+ *
* @model: Hauppauge's model number
+ *
* @revision: Card revision number
+ *
* @serial_number: Card's serial number
+ *
* @rev_str: Card revision converted to number
+ *
* @MAC_address: MAC address for the network interface
*/
struct tveeprom {
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 1d6d7da4c45d..8e2a236a4d03 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -23,6 +23,19 @@ struct v4l2_async_notifier;
/* A random max subdevice number, used to allocate an array on stack */
#define V4L2_MAX_SUBDEVS 128U
+/**
+ * enum v4l2_async_match_type - type of asynchronous subdevice logic to be used
+ * in order to identify a match
+ *
+ * @V4L2_ASYNC_MATCH_CUSTOM: Match will use the logic provided by &struct
+ * v4l2_async_subdev.match ops
+ * @V4L2_ASYNC_MATCH_DEVNAME: Match will use the device name
+ * @V4L2_ASYNC_MATCH_I2C: Match will check for I2C adapter ID and address
+ * @V4L2_ASYNC_MATCH_OF: Match will use OF node
+ *
+ * This enum is used by the asyncrhronous sub-device logic to define the
+ * algorithm that will be used to match an asynchronous device.
+ */
enum v4l2_async_match_type {
V4L2_ASYNC_MATCH_CUSTOM,
V4L2_ASYNC_MATCH_DEVNAME,
@@ -91,9 +104,35 @@ struct v4l2_async_notifier {
struct v4l2_async_subdev *asd);
};
+/**
+ * v4l2_async_notifier_register - registers a subdevice asynchronous notifier
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @notifier: pointer to &struct v4l2_async_notifier
+ */
int v4l2_async_notifier_register(struct v4l2_device *v4l2_dev,
struct v4l2_async_notifier *notifier);
+
+/**
+ * v4l2_async_notifier_unregister - unregisters a subdevice asynchronous notifier
+ *
+ * @notifier: pointer to &struct v4l2_async_notifier
+ */
void v4l2_async_notifier_unregister(struct v4l2_async_notifier *notifier);
+
+/**
+ * v4l2_async_register_subdev - registers a sub-device to the asynchronous
+ * subdevice framework
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ */
int v4l2_async_register_subdev(struct v4l2_subdev *sd);
+
+/**
+ * v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous
+ * subdevice framework
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ */
void v4l2_async_unregister_subdev(struct v4l2_subdev *sd);
#endif
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 1cc0c5ba16b3..350cbf9fb10e 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -78,11 +78,26 @@
v4l2_printk(KERN_DEBUG, dev, fmt , ## arg); \
} while (0)
-/* ------------------------------------------------------------------------- */
-
-/* Control helper function */
+/**
+ * v4l2_ctrl_query_fill- Fill in a struct v4l2_queryctrl
+ *
+ * @qctrl: pointer to the &struct v4l2_queryctrl to be filled
+ * @min: minimum value for the control
+ * @max: maximum value for the control
+ * @step: control step
+ * @def: default value for the control
+ *
+ * Fills the &struct v4l2_queryctrl fields for the query control.
+ *
+ * .. note::
+ *
+ * This function assumes that the @qctrl->id field is filled.
+ *
+ * Returns -EINVAL if the control is not known by the V4L2 core, 0 on success.
+ */
-int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def);
+int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl,
+ s32 min, s32 max, s32 step, s32 def);
/* ------------------------------------------------------------------------- */
@@ -96,23 +111,60 @@ struct v4l2_device;
struct v4l2_subdev;
struct v4l2_subdev_ops;
-
-/* Load an i2c module and return an initialized v4l2_subdev struct.
- The client_type argument is the name of the chip that's on the adapter. */
+/**
+ * v4l2_i2c_new_subdev - Load an i2c module and return an initialized
+ * &struct v4l2_subdev.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @adapter: pointer to struct i2c_adapter
+ * @client_type: name of the chip that's on the adapter.
+ * @addr: I2C address. If zero, it will use @probe_addrs
+ * @probe_addrs: array with a list of address. The last entry at such
+ * array should be %I2C_CLIENT_END.
+ *
+ * returns a &struct v4l2_subdev pointer.
+ */
struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
struct i2c_adapter *adapter, const char *client_type,
u8 addr, const unsigned short *probe_addrs);
struct i2c_board_info;
+/**
+ * v4l2_i2c_new_subdev_board - Load an i2c module and return an initialized
+ * &struct v4l2_subdev.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @adapter: pointer to struct i2c_adapter
+ * @info: pointer to struct i2c_board_info used to replace the irq,
+ * platform_data and addr arguments.
+ * @probe_addrs: array with a list of address. The last entry at such
+ * array should be %I2C_CLIENT_END.
+ *
+ * returns a &struct v4l2_subdev pointer.
+ */
struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
struct i2c_adapter *adapter, struct i2c_board_info *info,
const unsigned short *probe_addrs);
-/* Initialize a v4l2_subdev with data from an i2c_client struct */
+/**
+ * v4l2_i2c_subdev_init - Initializes a &struct v4l2_subdev with data from
+ * an i2c_client struct.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @client: pointer to struct i2c_client
+ * @ops: pointer to &struct v4l2_subdev_ops
+ */
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
const struct v4l2_subdev_ops *ops);
-/* Return i2c client address of v4l2_subdev. */
+
+/**
+ * v4l2_i2c_subdev_addr - returns i2c client address of &struct v4l2_subdev.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ *
+ * Returns the address of an I2C sub-device
+ */
unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd);
enum v4l2_i2c_tuner_type {
@@ -137,12 +189,28 @@ const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type);
struct spi_device;
-/* Load an spi module and return an initialized v4l2_subdev struct.
- The client_type argument is the name of the chip that's on the adapter. */
+/**
+ * v4l2_spi_new_subdev - Load an spi module and return an initialized
+ * &struct v4l2_subdev.
+ *
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device.
+ * @master: pointer to struct spi_master.
+ * @info: pointer to struct spi_board_info.
+ *
+ * returns a &struct v4l2_subdev pointer.
+ */
struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
struct spi_master *master, struct spi_board_info *info);
-/* Initialize a v4l2_subdev with data from an spi_device struct */
+/**
+ * v4l2_spi_subdev_init - Initialize a v4l2_subdev with data from an
+ * spi_device struct.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @spi: pointer to struct spi_device.
+ * @ops: pointer to &struct v4l2_subdev_ops
+ */
void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
const struct v4l2_subdev_ops *ops);
#endif
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 0bc9b35b8f3e..178a88d45aea 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -1,21 +1,17 @@
/*
- V4L2 controls support header.
-
- Copyright (C) 2010 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * V4L2 controls support header.
+ *
+ * Copyright (C) 2010 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
*/
#ifndef _V4L2_CTRLS_H
@@ -58,6 +54,7 @@ union v4l2_ctrl_ptr {
/**
* struct v4l2_ctrl_ops - The control operations that the driver has to provide.
+ *
* @g_volatile_ctrl: Get a new value for this control. Generally only relevant
* for volatile (and usually read-only) controls such as a control
* that returns the current signal strength which changes
@@ -77,12 +74,13 @@ struct v4l2_ctrl_ops {
/**
* struct v4l2_ctrl_type_ops - The control type operations that the driver
- * has to provide.
+ * has to provide.
*
* @equal: return true if both values are equal.
* @init: initialize the value.
* @log: log the value.
- * @validate: validate the value. Return 0 on success and a negative value otherwise.
+ * @validate: validate the value. Return 0 on success and a negative value
+ * otherwise.
*/
struct v4l2_ctrl_type_ops {
bool (*equal)(const struct v4l2_ctrl *ctrl, u32 idx,
@@ -99,6 +97,7 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
/**
* struct v4l2_ctrl - The control structure.
+ *
* @node: The list node.
* @ev_subs: The list of control event subscriptions.
* @handler: The handler that owns the control.
@@ -106,7 +105,7 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
* @ncontrols: Number of controls in cluster array.
* @done: Internal flag: set for each processed control.
* @is_new: Set when the user specified a new value for this control. It
- * is also set when called from v4l2_ctrl_handler_setup. Drivers
+ * is also set when called from v4l2_ctrl_handler_setup(). Drivers
* should never set this flag.
* @has_changed: Set when the current value differs from the new value. Drivers
* should never use this flag.
@@ -119,9 +118,10 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
* set this flag directly.
* @is_int: If set, then this control has a simple integer value (i.e. it
* uses ctrl->val).
- * @is_string: If set, then this control has type V4L2_CTRL_TYPE_STRING.
- * @is_ptr: If set, then this control is an array and/or has type >= V4L2_CTRL_COMPOUND_TYPES
- * and/or has type V4L2_CTRL_TYPE_STRING. In other words, struct
+ * @is_string: If set, then this control has type %V4L2_CTRL_TYPE_STRING.
+ * @is_ptr: If set, then this control is an array and/or has type >=
+ * %V4L2_CTRL_COMPOUND_TYPES
+ * and/or has type %V4L2_CTRL_TYPE_STRING. In other words, &struct
* v4l2_ext_control uses field p to point to the data.
* @is_array: If set, then this control contains an N-dimensional array.
* @has_volatiles: If set, then one or more members of the cluster are volatile.
@@ -177,7 +177,8 @@ struct v4l2_ctrl {
struct list_head ev_subs;
struct v4l2_ctrl_handler *handler;
struct v4l2_ctrl **cluster;
- unsigned ncontrols;
+ unsigned int ncontrols;
+
unsigned int done:1;
unsigned int is_new:1;
@@ -223,10 +224,12 @@ struct v4l2_ctrl {
/**
* struct v4l2_ctrl_ref - The control reference.
+ *
* @node: List node for the sorted list.
* @next: Single-link list node for the hash.
* @ctrl: The actual control information.
- * @helper: Pointer to helper struct. Used internally in prepare_ext_ctrls().
+ * @helper: Pointer to helper struct. Used internally in
+ * prepare_ext_ctrls().
*
* Each control handler has a list of these refs. The list_head is used to
* keep a sorted-by-control-ID list of all controls, while the next pointer
@@ -241,8 +244,9 @@ struct v4l2_ctrl_ref {
/**
* struct v4l2_ctrl_handler - The control handler keeps track of all the
- * controls: both the controls owned by the handler and those inherited
- * from other handlers.
+ * controls: both the controls owned by the handler and those inherited
+ * from other handlers.
+ *
* @_lock: Default for "lock".
* @lock: Lock to control access to this handler and its controls.
* May be replaced by the user right after init.
@@ -252,7 +256,8 @@ struct v4l2_ctrl_ref {
* control is needed multiple times, so this is a simple
* optimization.
* @buckets: Buckets for the hashing. Allows for quick control lookup.
- * @notify: A notify callback that is called whenever the control changes value.
+ * @notify: A notify callback that is called whenever the control changes
+ * value.
* Note that the handler's lock is held when the notify function
* is called!
* @notify_priv: Passed as argument to the v4l2_ctrl notify callback.
@@ -274,6 +279,7 @@ struct v4l2_ctrl_handler {
/**
* struct v4l2_ctrl_config - Control configuration structure.
+ *
* @ops: The control ops.
* @type_ops: The control type ops. Only needed for compound controls.
* @id: The control ID.
@@ -282,7 +288,7 @@ struct v4l2_ctrl_handler {
* @min: The control's minimum value.
* @max: The control's maximum value.
* @step: The control's step value for non-menu controls.
- * @def: The control's default value.
+ * @def: The control's default value.
* @dims: The size of each dimension.
* @elem_size: The size in bytes of the control.
* @flags: The control's flags.
@@ -297,7 +303,7 @@ struct v4l2_ctrl_handler {
* is in addition to the menu_skip_mask above). The last entry
* must be NULL.
* @qmenu_int: A const s64 integer array for all menu items of the type
- * V4L2_CTRL_TYPE_INTEGER_MENU.
+ * V4L2_CTRL_TYPE_INTEGER_MENU.
* @is_private: If set, then this control is private to its handler and it
* will not be added to any other handlers.
*/
@@ -320,20 +326,31 @@ struct v4l2_ctrl_config {
unsigned int is_private:1;
};
-/*
- * v4l2_ctrl_fill() - Fill in the control fields based on the control ID.
+/**
+ * v4l2_ctrl_fill - Fill in the control fields based on the control ID.
+ *
+ * @id: ID of the control
+ * @name: name of the control
+ * @type: type of the control
+ * @min: minimum value for the control
+ * @max: maximum value for the control
+ * @step: control step
+ * @def: default value for the control
+ * @flags: flags to be used on the control
*
* This works for all standard V4L2 controls.
* For non-standard controls it will only fill in the given arguments
- * and @name will be NULL.
+ * and @name will be %NULL.
*
* This function will overwrite the contents of @name, @type and @flags.
* The contents of @min, @max, @step and @def may be modified depending on
* the type.
*
- * Do not use in drivers! It is used internally for backwards compatibility
- * control handling only. Once all drivers are converted to use the new
- * control framework this function will no longer be exported.
+ * .. note::
+ *
+ * Do not use in drivers! It is used internally for backwards compatibility
+ * control handling only. Once all drivers are converted to use the new
+ * control framework this function will no longer be exported.
*/
void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
s64 *min, s64 *max, u64 *step, s64 *def, u32 *flags);
@@ -359,7 +376,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
* macro that hides the @key and @name arguments.
*/
int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl,
- unsigned nr_of_controls_hint,
+ unsigned int nr_of_controls_hint,
struct lock_class_key *key, const char *name);
#ifdef CONFIG_LOCKDEP
@@ -436,7 +453,8 @@ void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
/**
* v4l2_ctrl_new_custom() - Allocate and initialize a new custom V4L2
- * control.
+ * control.
+ *
* @hdl: The control handler.
* @cfg: The control's configuration data.
* @priv: The control's driver-specific private data.
@@ -445,17 +463,20 @@ void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
* and @hdl->error is set to the error code (if it wasn't set already).
*/
struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
- const struct v4l2_ctrl_config *cfg, void *priv);
+ const struct v4l2_ctrl_config *cfg,
+ void *priv);
/**
- * v4l2_ctrl_new_std() - Allocate and initialize a new standard V4L2 non-menu control.
+ * v4l2_ctrl_new_std() - Allocate and initialize a new standard V4L2 non-menu
+ * control.
+ *
* @hdl: The control handler.
* @ops: The control ops.
- * @id: The control ID.
+ * @id: The control ID.
* @min: The control's minimum value.
* @max: The control's maximum value.
* @step: The control's step value
- * @def: The control's default value.
+ * @def: The control's default value.
*
* If the &v4l2_ctrl struct could not be allocated, or the control
* ID is not known, then NULL is returned and @hdl->error is set to the
@@ -466,22 +487,25 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
* Use v4l2_ctrl_new_std_menu() when adding menu controls.
*/
struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
- const struct v4l2_ctrl_ops *ops,
- u32 id, s64 min, s64 max, u64 step, s64 def);
+ const struct v4l2_ctrl_ops *ops,
+ u32 id, s64 min, s64 max, u64 step,
+ s64 def);
/**
- * v4l2_ctrl_new_std_menu() - Allocate and initialize a new standard V4L2 menu control.
+ * v4l2_ctrl_new_std_menu() - Allocate and initialize a new standard V4L2
+ * menu control.
+ *
* @hdl: The control handler.
* @ops: The control ops.
- * @id: The control ID.
+ * @id: The control ID.
* @max: The control's maximum value.
- * @mask: The control's skip mask for menu controls. This makes it
+ * @mask: The control's skip mask for menu controls. This makes it
* easy to skip menu items that are not valid. If bit X is set,
* then menu item X is skipped. Of course, this only works for
* menus with <= 64 menu items. There are no menus that come
* close to that number, so this is OK. Should we ever need more,
* then this will have to be extended to a bit array.
- * @def: The control's default value.
+ * @def: The control's default value.
*
* Same as v4l2_ctrl_new_std(), but @min is set to 0 and the @mask value
* determines which menu items are to be skipped.
@@ -489,12 +513,13 @@ struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
* If @id refers to a non-menu control, then this function will return NULL.
*/
struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
- const struct v4l2_ctrl_ops *ops,
- u32 id, u8 max, u64 mask, u8 def);
+ const struct v4l2_ctrl_ops *ops,
+ u32 id, u8 max, u64 mask, u8 def);
/**
* v4l2_ctrl_new_std_menu_items() - Create a new standard V4L2 menu control
- * with driver specific menu.
+ * with driver specific menu.
+ *
* @hdl: The control handler.
* @ops: The control ops.
* @id: The control ID.
@@ -513,11 +538,14 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
*
*/
struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
- const struct v4l2_ctrl_ops *ops, u32 id, u8 max,
- u64 mask, u8 def, const char * const *qmenu);
+ const struct v4l2_ctrl_ops *ops,
+ u32 id, u8 max,
+ u64 mask, u8 def,
+ const char * const *qmenu);
/**
* v4l2_ctrl_new_int_menu() - Create a new standard V4L2 integer menu control.
+ *
* @hdl: The control handler.
* @ops: The control ops.
* @id: The control ID.
@@ -528,15 +556,20 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items(struct v4l2_ctrl_handler *hdl,
* Same as v4l2_ctrl_new_std_menu(), but @mask is set to 0 and it additionaly
* takes as an argument an array of integers determining the menu items.
*
- * If @id refers to a non-integer-menu control, then this function will return NULL.
+ * If @id refers to a non-integer-menu control, then this function will
+ * return %NULL.
*/
struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
- const struct v4l2_ctrl_ops *ops,
- u32 id, u8 max, u8 def, const s64 *qmenu_int);
+ const struct v4l2_ctrl_ops *ops,
+ u32 id, u8 max, u8 def,
+ const s64 *qmenu_int);
+
+typedef bool (*v4l2_ctrl_filter)(const struct v4l2_ctrl *ctrl);
/**
* v4l2_ctrl_add_handler() - Add all controls from handler @add to
- * handler @hdl.
+ * handler @hdl.
+ *
* @hdl: The control handler.
* @add: The control handler whose controls you want to add to
* the @hdl control handler.
@@ -550,10 +583,11 @@ struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl,
*/
int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
struct v4l2_ctrl_handler *add,
- bool (*filter)(const struct v4l2_ctrl *ctrl));
+ v4l2_ctrl_filter filter);
/**
* v4l2_ctrl_radio_filter() - Standard filter for radio controls.
+ *
* @ctrl: The control that is filtered.
*
* This will return true for any controls that are valid for radio device
@@ -565,16 +599,19 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
bool v4l2_ctrl_radio_filter(const struct v4l2_ctrl *ctrl);
/**
- * v4l2_ctrl_cluster() - Mark all controls in the cluster as belonging to that cluster.
+ * v4l2_ctrl_cluster() - Mark all controls in the cluster as belonging
+ * to that cluster.
+ *
* @ncontrols: The number of controls in this cluster.
- * @controls: The cluster control array of size @ncontrols.
+ * @controls: The cluster control array of size @ncontrols.
*/
-void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls);
+void v4l2_ctrl_cluster(unsigned int ncontrols, struct v4l2_ctrl **controls);
/**
- * v4l2_ctrl_auto_cluster() - Mark all controls in the cluster as belonging to
- * that cluster and set it up for autofoo/foo-type handling.
+ * v4l2_ctrl_auto_cluster() - Mark all controls in the cluster as belonging
+ * to that cluster and set it up for autofoo/foo-type handling.
+ *
* @ncontrols: The number of controls in this cluster.
* @controls: The cluster control array of size @ncontrols. The first control
* must be the 'auto' control (e.g. autogain, autoexposure, etc.)
@@ -602,12 +639,14 @@ void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls);
* on the autofoo control and V4L2_CTRL_FLAG_INACTIVE on the foo control(s)
* if autofoo is in auto mode.
*/
-void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls,
- u8 manual_val, bool set_volatile);
+void v4l2_ctrl_auto_cluster(unsigned int ncontrols,
+ struct v4l2_ctrl **controls,
+ u8 manual_val, bool set_volatile);
/**
* v4l2_ctrl_find() - Find a control with the given ID.
+ *
* @hdl: The control handler.
* @id: The control ID to find.
*
@@ -632,6 +671,7 @@ void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active);
/**
* v4l2_ctrl_grab() - Mark the control as grabbed or not grabbed.
+ *
* @ctrl: The control to (de)activate.
* @grabbed: True if the control should become grabbed.
*
@@ -671,6 +711,7 @@ int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
/**
* v4l2_ctrl_modify_range() - Update the range of a control.
+ *
* @ctrl: The control to update.
* @min: The control's minimum value.
* @max: The control's maximum value.
@@ -701,6 +742,7 @@ static inline int v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
/**
* v4l2_ctrl_notify() - Function to set a notify callback for a control.
+ *
* @ctrl: The control.
* @notify: The callback function.
* @priv: The callback private handle, passed as argument to the callback.
@@ -712,10 +754,12 @@ static inline int v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
* There can be only one notify. If another already exists, then a WARN_ON
* will be issued and the function will do nothing.
*/
-void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void *priv);
+void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify,
+ void *priv);
/**
* v4l2_ctrl_get_name() - Get the name of the control
+ *
* @id: The control ID.
*
* This function returns the name of the given control ID or NULL if it isn't
@@ -725,6 +769,7 @@ const char *v4l2_ctrl_get_name(u32 id);
/**
* v4l2_ctrl_get_menu() - Get the menu string array of the control
+ *
* @id: The control ID.
*
* This function returns the NULL-terminated menu string array name of the
@@ -734,6 +779,7 @@ const char * const *v4l2_ctrl_get_menu(u32 id);
/**
* v4l2_ctrl_get_int_menu() - Get the integer menu array of the control
+ *
* @id: The control ID.
* @len: The size of the integer array.
*
@@ -743,7 +789,9 @@ const char * const *v4l2_ctrl_get_menu(u32 id);
const s64 *v4l2_ctrl_get_int_menu(u32 id, u32 *len);
/**
- * v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver.
+ * v4l2_ctrl_g_ctrl() - Helper function to get the control's value from
+ * within a driver.
+ *
* @ctrl: The control.
*
* This returns the control's value safely by going through the control
@@ -756,22 +804,25 @@ s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl);
/**
* __v4l2_ctrl_s_ctrl() - Unlocked variant of v4l2_ctrl_s_ctrl().
+ *
* @ctrl: The control.
- * @val: The new value.
+ * @val: TheControls name new value.
*
- * This set the control's new value safely by going through the control
- * framework. This function will lock the control's handler, so it cannot be
- * used from within the &v4l2_ctrl_ops functions.
+ * This sets the control's new value safely by going through the control
+ * framework. This function assumes the control's handler is already locked,
+ * allowing it to be used from within the &v4l2_ctrl_ops functions.
*
* This function is for integer type controls only.
*/
int __v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val);
-/** v4l2_ctrl_s_ctrl() - Helper function to set the control's value from within a driver.
+/**
+ * v4l2_ctrl_s_ctrl() - Helper function to set the control's value from
+ * within a driver.
* @ctrl: The control.
* @val: The new value.
*
- * This set the control's new value safely by going through the control
+ * This sets the control's new value safely by going through the control
* framework. This function will lock the control's handler, so it cannot be
* used from within the &v4l2_ctrl_ops functions.
*
@@ -791,6 +842,7 @@ static inline int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val)
/**
* v4l2_ctrl_g_ctrl_int64() - Helper function to get a 64-bit control's value
* from within a driver.
+ *
* @ctrl: The control.
*
* This returns the control's value safely by going through the control
@@ -807,21 +859,22 @@ s64 v4l2_ctrl_g_ctrl_int64(struct v4l2_ctrl *ctrl);
* @ctrl: The control.
* @val: The new value.
*
- * This set the control's new value safely by going through the control
- * framework. This function will lock the control's handler, so it cannot be
- * used from within the &v4l2_ctrl_ops functions.
+ * This sets the control's new value safely by going through the control
+ * framework. This function assumes the control's handler is already locked,
+ * allowing it to be used from within the &v4l2_ctrl_ops functions.
*
* This function is for 64-bit integer type controls only.
*/
int __v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val);
-/** v4l2_ctrl_s_ctrl_int64() - Helper function to set a 64-bit control's value
+/**
+ * v4l2_ctrl_s_ctrl_int64() - Helper function to set a 64-bit control's value
* from within a driver.
*
* @ctrl: The control.
* @val: The new value.
*
- * This set the control's new value safely by going through the control
+ * This sets the control's new value safely by going through the control
* framework. This function will lock the control's handler, so it cannot be
* used from within the &v4l2_ctrl_ops functions.
*
@@ -838,26 +891,28 @@ static inline int v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val)
return rval;
}
-/** __v4l2_ctrl_s_ctrl_string() - Unlocked variant of v4l2_ctrl_s_ctrl_string().
+/**
+ * __v4l2_ctrl_s_ctrl_string() - Unlocked variant of v4l2_ctrl_s_ctrl_string().
*
* @ctrl: The control.
* @s: The new string.
*
- * This set the control's new string safely by going through the control
- * framework. This function will lock the control's handler, so it cannot be
- * used from within the &v4l2_ctrl_ops functions.
+ * This sets the control's new string safely by going through the control
+ * framework. This function assumes the control's handler is already locked,
+ * allowing it to be used from within the &v4l2_ctrl_ops functions.
*
* This function is for string type controls only.
*/
int __v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s);
-/** v4l2_ctrl_s_ctrl_string() - Helper function to set a control's string value
+/**
+ * v4l2_ctrl_s_ctrl_string() - Helper function to set a control's string value
* from within a driver.
*
* @ctrl: The control.
* @s: The new string.
- *
- * This set the control's new string safely by going through the control
+ *Controls name
+ * This sets the control's new string safely by going through the control
* framework. This function will lock the control's handler, so it cannot be
* used from within the &v4l2_ctrl_ops functions.
*
@@ -876,49 +931,179 @@ static inline int v4l2_ctrl_s_ctrl_string(struct v4l2_ctrl *ctrl, const char *s)
/* Internal helper functions that deal with control events. */
extern const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops;
+
+/**
+ * v4l2_ctrl_replace - Function to be used as a callback to
+ * &struct v4l2_subscribed_event_ops replace\(\)
+ *
+ * @old: pointer to :ref:`struct v4l2_event <v4l2-event>` with the reported
+ * event;
+ * @new: pointer to :ref:`struct v4l2_event <v4l2-event>` with the modified
+ * event;
+ */
void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new);
+
+/**
+ * v4l2_ctrl_merge - Function to be used as a callback to
+ * &struct v4l2_subscribed_event_ops merge(\)
+ *
+ * @old: pointer to :ref:`struct v4l2_event <v4l2-event>` with the reported
+ * event;
+ * @new: pointer to :ref:`struct v4l2_event <v4l2-event>` with the merged
+ * event;
+ */
void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new);
-/* Can be used as a vidioc_log_status function that just dumps all controls
- associated with the filehandle. */
+/**
+ * v4l2_ctrl_log_status - helper function to implement %VIDIOC_LOG_STATUS ioctl
+ *
+ * @file: pointer to struct file
+ * @fh: unused. Kept just to be compatible to the arguments expected by
+ * &struct v4l2_ioctl_ops.vidioc_log_status.
+ *
+ * Can be used as a vidioc_log_status function that just dumps all controls
+ * associated with the filehandle.
+ */
int v4l2_ctrl_log_status(struct file *file, void *fh);
-/* Can be used as a vidioc_subscribe_event function that just subscribes
- control events. */
+/**
+ * v4l2_ctrl_subscribe_event - Subscribes to an event
+ *
+ *
+ * @fh: pointer to struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ *
+ * Can be used as a vidioc_subscribe_event function that just subscribes
+ * control events.
+ */
int v4l2_ctrl_subscribe_event(struct v4l2_fh *fh,
const struct v4l2_event_subscription *sub);
-/* Can be used as a poll function that just polls for control events. */
+/**
+ * v4l2_ctrl_poll - function to be used as a callback to the poll()
+ * That just polls for control events.
+ *
+ * @file: pointer to struct file
+ * @wait: pointer to struct poll_table_struct
+ */
unsigned int v4l2_ctrl_poll(struct file *file, struct poll_table_struct *wait);
-/* Helpers for ioctl_ops. If hdl == NULL then they will all return -EINVAL. */
+/* Helpers for ioctl_ops */
+
+/**
+ * v4l2_queryctrl - Helper function to implement
+ * :ref:`VIDIOC_QUERYCTRL <vidioc_queryctrl>` ioctl
+ *
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @qc: pointer to &struct v4l2_queryctrl
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc);
-int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_query_ext_ctrl *qc);
+
+/**
+ * v4l2_query_ext_ctrl - Helper function to implement
+ * :ref:`VIDIOC_QUERY_EXT_CTRL <vidioc_queryctrl>` ioctl
+ *
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @qc: pointer to &struct v4l2_query_ext_ctrl
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
+int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl,
+ struct v4l2_query_ext_ctrl *qc);
+
+/**
+ * v4l2_querymenu - Helper function to implement
+ * :ref:`VIDIOC_QUERYMENU <vidioc_queryctrl>` ioctl
+ *
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @qm: pointer to &struct v4l2_querymenu
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm);
+
+/**
+ * v4l2_g_ctrl - Helper function to implement
+ * :ref:`VIDIOC_G_CTRL <vidioc_g_ctrl>` ioctl
+ *
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @ctrl: pointer to &struct v4l2_control
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *ctrl);
+
+/**
+ * v4l2_s_ctrl - Helper function to implement
+ * :ref:`VIDIOC_S_CTRL <vidioc_g_ctrl>` ioctl
+ *
+ * @fh: pointer to &struct v4l2_fh
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ *
+ * @ctrl: pointer to &struct v4l2_control
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
- struct v4l2_control *ctrl);
-int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *c);
-int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *c);
+ struct v4l2_control *ctrl);
+
+/**
+ * v4l2_g_ext_ctrls - Helper function to implement
+ * :ref:`VIDIOC_G_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
+ *
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @c: pointer to &struct v4l2_ext_controls
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
+int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl,
+ struct v4l2_ext_controls *c);
+
+/**
+ * v4l2_try_ext_ctrls - Helper function to implement
+ * :ref:`VIDIOC_TRY_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
+ *
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @c: pointer to &struct v4l2_ext_controls
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
+int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl,
+ struct v4l2_ext_controls *c);
+
+/**
+ * v4l2_s_ext_ctrls - Helper function to implement
+ * :ref:`VIDIOC_S_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
+ *
+ * @fh: pointer to &struct v4l2_fh
+ * @hdl: pointer to &struct v4l2_ctrl_handler
+ * @c: pointer to &struct v4l2_ext_controls
+ *
+ * If hdl == NULL then they will all return -EINVAL.
+ */
int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
- struct v4l2_ext_controls *c);
-
-/* Helpers for subdevices. If the associated ctrl_handler == NULL then they
- will all return -EINVAL. */
-int v4l2_subdev_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc);
-int v4l2_subdev_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm);
-int v4l2_subdev_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs);
-int v4l2_subdev_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs);
-int v4l2_subdev_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs);
-int v4l2_subdev_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
-int v4l2_subdev_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
-
-/* Can be used as a subscribe_event function that just subscribes control
- events. */
+ struct v4l2_ext_controls *c);
+
+/**
+ * v4l2_ctrl_subdev_subscribe_event - Helper function to implement
+ * as a &struct v4l2_subdev_core_ops subscribe_event function
+ * that just subscribes control events.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @fh: pointer to &struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ */
int v4l2_ctrl_subdev_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
struct v4l2_event_subscription *sub);
-/* Log all controls owned by subdev's control handler. */
+/**
+ * v4l2_ctrl_subdev_log_status - Log all controls owned by subdev's control
+ * handler.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ */
int v4l2_ctrl_subdev_log_status(struct v4l2_subdev *sd);
#endif
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 25a3190308fb..a122b1bd40f9 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -47,19 +47,105 @@ struct v4l2_ctrl_handler;
/* Priority helper functions */
+/**
+ * struct v4l2_prio_state - stores the priority states
+ *
+ * @prios: array with elements to store the array priorities
+ *
+ *
+ * .. note::
+ * The size of @prios array matches the number of priority types defined
+ * by :ref:`enum v4l2_priority <v4l2-priority>`.
+ */
struct v4l2_prio_state {
atomic_t prios[4];
};
+/**
+ * v4l2_prio_init - initializes a struct v4l2_prio_state
+ *
+ * @global: pointer to &struct v4l2_prio_state
+ */
void v4l2_prio_init(struct v4l2_prio_state *global);
+
+/**
+ * v4l2_prio_change - changes the v4l2 file handler priority
+ *
+ * @global: pointer to the &struct v4l2_prio_state of the device node.
+ * @local: pointer to the desired priority, as defined by :ref:`enum v4l2_priority <v4l2-priority>`
+ * @new: Priority type requested, as defined by :ref:`enum v4l2_priority <v4l2-priority>`.
+ *
+ * .. note::
+ * This function should be used only by the V4L2 core.
+ */
int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
enum v4l2_priority new);
+
+/**
+ * v4l2_prio_open - Implements the priority logic for a file handler open
+ *
+ * @global: pointer to the &struct v4l2_prio_state of the device node.
+ * @local: pointer to the desired priority, as defined by :ref:`enum v4l2_priority <v4l2-priority>`
+ *
+ * .. note::
+ * This function should be used only by the V4L2 core.
+ */
void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
+
+/**
+ * v4l2_prio_close - Implements the priority logic for a file handler close
+ *
+ * @global: pointer to the &struct v4l2_prio_state of the device node.
+ * @local: priority to be released, as defined by :ref:`enum v4l2_priority <v4l2-priority>`
+ *
+ * .. note::
+ * This function should be used only by the V4L2 core.
+ */
void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local);
+
+/**
+ * v4l2_prio_max - Return the maximum priority, as stored at the @global array.
+ *
+ * @global: pointer to the &struct v4l2_prio_state of the device node.
+ *
+ * .. note::
+ * This function should be used only by the V4L2 core.
+ */
enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
-int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local);
+/**
+ * v4l2_prio_close - Implements the priority logic for a file handler close
+ *
+ * @global: pointer to the &struct v4l2_prio_state of the device node.
+ * @local: desired priority, as defined by :ref:`enum v4l2_priority <v4l2-priority>` local
+ *
+ * .. note::
+ * This function should be used only by the V4L2 core.
+ */
+int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local);
+/**
+ * struct v4l2_file_operations - fs operations used by a V4L2 device
+ *
+ * @owner: pointer to struct module
+ * @read: operations needed to implement the read() syscall
+ * @write: operations needed to implement the write() syscall
+ * @poll: operations needed to implement the poll() syscall
+ * @unlocked_ioctl: operations needed to implement the ioctl() syscall
+ * @compat_ioctl32: operations needed to implement the ioctl() syscall for
+ * the special case where the Kernel uses 64 bits instructions, but
+ * the userspace uses 32 bits.
+ * @get_unmapped_area: called by the mmap() syscall, used when %!CONFIG_MMU
+ * @mmap: operations needed to implement the mmap() syscall
+ * @open: operations needed to implement the open() syscall
+ * @release: operations needed to implement the release() syscall
+ *
+ * .. note::
+ *
+ * Those operations are used to implemente the fs struct file_operations
+ * at the V4L2 drivers. The V4L2 core overrides the fs ops with some
+ * extra logic needed by the subsystem.
+ */
struct v4l2_file_operations {
struct module *owner;
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
@@ -82,6 +168,47 @@ struct v4l2_file_operations {
* the common handler
*/
+/**
+ * struct video_device - Structure used to create and manage the V4L2 device
+ * nodes.
+ *
+ * @entity: &struct media_entity
+ * @intf_devnode: pointer to &struct media_intf_devnode
+ * @pipe: &struct media_pipeline
+ * @fops: pointer to &struct v4l2_file_operations for the video device
+ * @device_caps: device capabilities as used in v4l2_capabilities
+ * @dev: &struct device for the video device
+ * @cdev: character device
+ * @v4l2_dev: pointer to &struct v4l2_device parent
+ * @dev_parent: pointer to &struct device parent
+ * @ctrl_handler: Control handler associated with this device node.
+ * May be NULL.
+ * @queue: &struct vb2_queue associated with this device node. May be NULL.
+ * @prio: pointer to &struct v4l2_prio_state with device's Priority state.
+ * If NULL, then v4l2_dev->prio will be used.
+ * @name: video device name
+ * @vfl_type: V4L device type
+ * @vfl_dir: V4L receiver, transmitter or m2m
+ * @minor: device node 'minor'. It is set to -1 if the registration failed
+ * @num: number of the video device node
+ * @flags: video device flags. Use bitops to set/clear/test flags
+ * @index: attribute to differentiate multiple indices on one physical device
+ * @fh_lock: Lock for all v4l2_fhs
+ * @fh_list: List of &struct v4l2_fh
+ * @dev_debug: Internal device debug flags, not for use by drivers
+ * @tvnorms: Supported tv norms
+ *
+ * @release: video device release() callback
+ * @ioctl_ops: pointer to &struct v4l2_ioctl_ops with ioctl callbacks
+ *
+ * @valid_ioctls: bitmap with the valid ioctls for this device
+ * @disable_locking: bitmap with the ioctls that don't require locking
+ * @lock: pointer to &struct mutex serialization lock
+ *
+ * .. note::
+ * Only set @dev_parent if that can't be deduced from @v4l2_dev.
+ */
+
struct video_device
{
#if defined(CONFIG_MEDIA_CONTROLLER)
@@ -89,59 +216,45 @@ struct video_device
struct media_intf_devnode *intf_devnode;
struct media_pipeline pipe;
#endif
- /* device ops */
const struct v4l2_file_operations *fops;
- /* device capabilities as used in v4l2_capabilities */
u32 device_caps;
/* sysfs */
- struct device dev; /* v4l device */
- struct cdev *cdev; /* character device */
+ struct device dev;
+ struct cdev *cdev;
- struct v4l2_device *v4l2_dev; /* v4l2_device parent */
- /* Only set parent if that can't be deduced from v4l2_dev */
- struct device *dev_parent; /* device parent */
+ struct v4l2_device *v4l2_dev;
+ struct device *dev_parent;
- /* Control handler associated with this device node. May be NULL. */
struct v4l2_ctrl_handler *ctrl_handler;
- /* vb2_queue associated with this device node. May be NULL. */
struct vb2_queue *queue;
- /* Priority state. If NULL, then v4l2_dev->prio will be used. */
struct v4l2_prio_state *prio;
/* device info */
char name[32];
- int vfl_type; /* device type */
- int vfl_dir; /* receiver, transmitter or m2m */
- /* 'minor' is set to -1 if the registration failed */
+ int vfl_type;
+ int vfl_dir;
int minor;
u16 num;
- /* use bitops to set/clear/test flags */
unsigned long flags;
- /* attribute to differentiate multiple indices on one physical device */
int index;
/* V4L2 file handles */
- spinlock_t fh_lock; /* Lock for all v4l2_fhs */
- struct list_head fh_list; /* List of struct v4l2_fh */
+ spinlock_t fh_lock;
+ struct list_head fh_list;
- /* Internal device debug flags, not for use by drivers */
int dev_debug;
- /* Video standard vars */
- v4l2_std_id tvnorms; /* Supported tv norms */
+ v4l2_std_id tvnorms;
/* callbacks */
void (*release)(struct video_device *vdev);
-
- /* ioctl callbacks */
const struct v4l2_ioctl_ops *ioctl_ops;
DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE);
- /* serialization lock */
DECLARE_BITMAP(disable_locking, BASE_VIDIOC_PRIVATE);
struct mutex *lock;
};
@@ -151,88 +264,241 @@ struct video_device
/* dev to video-device */
#define to_video_device(cd) container_of(cd, struct video_device, dev)
+/**
+ * __video_register_device - register video4linux devices
+ *
+ * @vdev: struct video_device to register
+ * @type: type of device to register
+ * @nr: which device node number is desired:
+ * (0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
+ * @warn_if_nr_in_use: warn if the desired device node number
+ * was already in use and another number was chosen instead.
+ * @owner: module that owns the video device node
+ *
+ * The registration code assigns minor numbers and device node numbers
+ * based on the requested type and registers the new device node with
+ * the kernel.
+ *
+ * This function assumes that struct video_device was zeroed when it
+ * was allocated and does not contain any stale date.
+ *
+ * An error is returned if no free minor or device node number could be
+ * found, or if the registration of the device node failed.
+ *
+ * Returns 0 on success.
+ *
+ * Valid values for @type are:
+ *
+ * - %VFL_TYPE_GRABBER - A frame grabber
+ * - %VFL_TYPE_VBI - Vertical blank data (undecoded)
+ * - %VFL_TYPE_RADIO - A radio card
+ * - %VFL_TYPE_SUBDEV - A subdevice
+ * - %VFL_TYPE_SDR - Software Defined Radio
+ *
+ * .. note::
+ *
+ * This function is meant to be used only inside the V4L2 core.
+ * Drivers should use video_register_device() or
+ * video_register_device_no_warn().
+ */
int __must_check __video_register_device(struct video_device *vdev, int type,
int nr, int warn_if_nr_in_use, struct module *owner);
-/* Register video devices. Note that if video_register_device fails,
- the release() callback of the video_device structure is *not* called, so
- the caller is responsible for freeing any data. Usually that means that
- you call video_device_release() on failure. */
+/**
+ * video_register_device - register video4linux devices
+ *
+ * @vdev: struct video_device to register
+ * @type: type of device to register
+ * @nr: which device node number is desired:
+ * (0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
+ *
+ * Internally, it calls __video_register_device(). Please see its
+ * documentation for more details.
+ *
+ * .. note::
+ * if video_register_device fails, the release() callback of
+ * &struct video_device structure is *not* called, so the caller
+ * is responsible for freeing any data. Usually that means that
+ * you video_device_release() should be called on failure.
+ */
static inline int __must_check video_register_device(struct video_device *vdev,
int type, int nr)
{
return __video_register_device(vdev, type, nr, 1, vdev->fops->owner);
}
-/* Same as video_register_device, but no warning is issued if the desired
- device node number was already in use. */
+/**
+ * video_register_device_no_warn - register video4linux devices
+ *
+ * @vdev: struct video_device to register
+ * @type: type of device to register
+ * @nr: which device node number is desired:
+ * (0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
+ *
+ * This function is identical to video_register_device() except that no
+ * warning is issued if the desired device node number was already in use.
+ *
+ * Internally, it calls __video_register_device(). Please see its
+ * documentation for more details.
+ *
+ * .. note::
+ * if video_register_device fails, the release() callback of
+ * &struct video_device structure is *not* called, so the caller
+ * is responsible for freeing any data. Usually that means that
+ * you video_device_release() should be called on failure.
+ */
static inline int __must_check video_register_device_no_warn(
struct video_device *vdev, int type, int nr)
{
return __video_register_device(vdev, type, nr, 0, vdev->fops->owner);
}
-/* Unregister video devices. Will do nothing if vdev == NULL or
- video_is_registered() returns false. */
+/**
+ * video_unregister_device - Unregister video devices.
+ *
+ * @vdev: &struct video_device to register
+ *
+ * Does nothing if vdev == NULL or if video_is_registered() returns false.
+ */
void video_unregister_device(struct video_device *vdev);
-/* helper functions to alloc/release struct video_device, the
- latter can also be used for video_device->release(). */
+/**
+ * video_device_alloc - helper function to alloc &struct video_device
+ *
+ * Returns NULL if %-ENOMEM or a &struct video_device on success.
+ */
struct video_device * __must_check video_device_alloc(void);
-/* this release function frees the vdev pointer */
+/**
+ * video_device_release - helper function to release &struct video_device
+ *
+ * @vdev: pointer to &struct video_device
+ *
+ * Can also be used for video_device->release\(\).
+ */
void video_device_release(struct video_device *vdev);
-/* this release function does nothing, use when the video_device is a
- static global struct. Note that having a static video_device is
- a dubious construction at best. */
+/**
+ * video_device_release_empty - helper function to implement the
+ * video_device->release\(\) callback.
+ *
+ * @vdev: pointer to &struct video_device
+ *
+ * This release function does nothing.
+ *
+ * It should be used when the video_device is a static global struct.
+ *
+ * .. note::
+ * Having a static video_device is a dubious construction at best.
+ */
void video_device_release_empty(struct video_device *vdev);
-/* returns true if cmd is a known V4L2 ioctl */
+/**
+ * v4l2_is_known_ioctl - Checks if a given cmd is a known V4L ioctl
+ *
+ * @cmd: ioctl command
+ *
+ * returns true if cmd is a known V4L2 ioctl
+ */
bool v4l2_is_known_ioctl(unsigned int cmd);
-/* mark that this command shouldn't use core locking */
-static inline void v4l2_disable_ioctl_locking(struct video_device *vdev, unsigned int cmd)
+/** v4l2_disable_ioctl_locking - mark that a given command
+ * shouldn't use core locking
+ *
+ * @vdev: pointer to &struct video_device
+ * @cmd: ioctl command
+ */
+static inline void v4l2_disable_ioctl_locking(struct video_device *vdev,
+ unsigned int cmd)
{
if (_IOC_NR(cmd) < BASE_VIDIOC_PRIVATE)
set_bit(_IOC_NR(cmd), vdev->disable_locking);
}
-/* Mark that this command isn't implemented. This must be called before
- video_device_register. See also the comments in determine_valid_ioctls().
- This function allows drivers to provide just one v4l2_ioctl_ops struct, but
- disable ioctls based on the specific card that is actually found. */
-static inline void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd)
+/**
+ * v4l2_disable_ioctl- mark that a given command isn't implemented.
+ * shouldn't use core locking
+ *
+ * @vdev: pointer to &struct video_device
+ * @cmd: ioctl command
+ *
+ * This function allows drivers to provide just one v4l2_ioctl_ops struct, but
+ * disable ioctls based on the specific card that is actually found.
+ *
+ * .. note::
+ *
+ * This must be called before video_register_device.
+ * See also the comments for determine_valid_ioctls().
+ */
+static inline void v4l2_disable_ioctl(struct video_device *vdev,
+ unsigned int cmd)
{
if (_IOC_NR(cmd) < BASE_VIDIOC_PRIVATE)
set_bit(_IOC_NR(cmd), vdev->valid_ioctls);
}
-/* helper functions to access driver private data. */
+/**
+ * video_get_drvdata - gets private data from &struct video_device.
+ *
+ * @vdev: pointer to &struct video_device
+ *
+ * returns a pointer to the private data
+ */
static inline void *video_get_drvdata(struct video_device *vdev)
{
return dev_get_drvdata(&vdev->dev);
}
+/**
+ * video_set_drvdata - sets private data from &struct video_device.
+ *
+ * @vdev: pointer to &struct video_device
+ * @data: private data pointer
+ */
static inline void video_set_drvdata(struct video_device *vdev, void *data)
{
dev_set_drvdata(&vdev->dev, data);
}
+/**
+ * video_devdata - gets &struct video_device from struct file.
+ *
+ * @file: pointer to struct file
+ */
struct video_device *video_devdata(struct file *file);
-/* Combine video_get_drvdata and video_devdata as this is
- used very often. */
+/**
+ * video_drvdata - gets private data from &struct video_device using the
+ * struct file.
+ *
+ * @file: pointer to struct file
+ *
+ * This is function combines both video_get_drvdata() and video_devdata()
+ * as this is used very often.
+ */
static inline void *video_drvdata(struct file *file)
{
return video_get_drvdata(video_devdata(file));
}
+/**
+ * video_device_node_name - returns the video device name
+ *
+ * @vdev: pointer to &struct video_device
+ *
+ * Returns the device name string
+ */
static inline const char *video_device_node_name(struct video_device *vdev)
{
return dev_name(&vdev->dev);
}
+/**
+ * video_is_registered - returns true if the &struct video_device is registered.
+ *
+ *
+ * @vdev: pointer to &struct video_device
+ */
static inline int video_is_registered(struct video_device *vdev)
{
return test_bit(V4L2_FL_REGISTERED, &vdev->flags);
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index d5d45a8d3998..a9d6aa41790e 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -25,100 +25,188 @@
#include <media/v4l2-subdev.h>
#include <media/v4l2-dev.h>
-/* Each instance of a V4L2 device should create the v4l2_device struct,
- either stand-alone or embedded in a larger struct.
-
- It allows easy access to sub-devices (see v4l2-subdev.h) and provides
- basic V4L2 device-level support.
- */
-
#define V4L2_DEVICE_NAME_SIZE (20 + 16)
struct v4l2_ctrl_handler;
+/**
+ * struct v4l2_device - main struct to for V4L2 device drivers
+ *
+ * @dev: pointer to struct device.
+ * @mdev: pointer to struct media_device
+ * @subdevs: used to keep track of the registered subdevs
+ * @lock: lock this struct; can be used by the driver as well
+ * if this struct is embedded into a larger struct.
+ * @name: unique device name, by default the driver name + bus ID
+ * @notify: notify callback called by some sub-devices.
+ * @ctrl_handler: The control handler. May be NULL.
+ * @prio: Device's priority state
+ * @ref: Keep track of the references to this struct.
+ * @release: Release function that is called when the ref count
+ * goes to 0.
+ *
+ * Each instance of a V4L2 device should create the v4l2_device struct,
+ * either stand-alone or embedded in a larger struct.
+ *
+ * It allows easy access to sub-devices (see v4l2-subdev.h) and provides
+ * basic V4L2 device-level support.
+ *
+ * .. note::
+ *
+ * #) dev->driver_data points to this struct.
+ * #) dev might be NULL if there is no parent device
+ */
+
struct v4l2_device {
- /* dev->driver_data points to this struct.
- Note: dev might be NULL if there is no parent device
- as is the case with e.g. ISA devices. */
struct device *dev;
#if defined(CONFIG_MEDIA_CONTROLLER)
struct media_device *mdev;
#endif
- /* used to keep track of the registered subdevs */
struct list_head subdevs;
- /* lock this struct; can be used by the driver as well if this
- struct is embedded into a larger struct. */
spinlock_t lock;
- /* unique device name, by default the driver name + bus ID */
char name[V4L2_DEVICE_NAME_SIZE];
- /* notify callback called by some sub-devices. */
void (*notify)(struct v4l2_subdev *sd,
unsigned int notification, void *arg);
- /* The control handler. May be NULL. */
struct v4l2_ctrl_handler *ctrl_handler;
- /* Device's priority state */
struct v4l2_prio_state prio;
- /* Keep track of the references to this struct. */
struct kref ref;
- /* Release function that is called when the ref count goes to 0. */
void (*release)(struct v4l2_device *v4l2_dev);
};
+/**
+ * v4l2_device_get - gets a V4L2 device reference
+ *
+ * @v4l2_dev: pointer to struct v4l2_device
+ *
+ * This is an ancillary routine meant to increment the usage for the
+ * struct v4l2_device pointed by @v4l2_dev.
+ */
static inline void v4l2_device_get(struct v4l2_device *v4l2_dev)
{
kref_get(&v4l2_dev->ref);
}
+/**
+ * v4l2_device_put - putss a V4L2 device reference
+ *
+ * @v4l2_dev: pointer to struct v4l2_device
+ *
+ * This is an ancillary routine meant to decrement the usage for the
+ * struct v4l2_device pointed by @v4l2_dev.
+ */
int v4l2_device_put(struct v4l2_device *v4l2_dev);
-/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev.
- dev may be NULL in rare cases (ISA devices). In that case you
- must fill in the v4l2_dev->name field before calling this function. */
-int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
-
-/* Optional function to initialize the name field of struct v4l2_device using
- the driver name and a driver-global atomic_t instance.
- This function will increment the instance counter and returns the instance
- value used in the name.
-
- Example:
-
- static atomic_t drv_instance = ATOMIC_INIT(0);
-
- ...
-
- instance = v4l2_device_set_name(&v4l2_dev, "foo", &drv_instance);
-
- The first time this is called the name field will be set to foo0 and
- this function returns 0. If the name ends with a digit (e.g. cx18),
- then the name will be set to cx18-0 since cx180 looks really odd. */
+/**
+ * v4l2_device_register -Initialize v4l2_dev and make dev->driver_data
+ * point to v4l2_dev.
+ *
+ * @dev: pointer to struct device
+ * @v4l2_dev: pointer to struct v4l2_device
+ *
+ * .. note::
+ * dev may be NULL in rare cases (ISA devices).
+ * In such case the caller must fill in the v4l2_dev->name field
+ * before calling this function.
+ */
+int __must_check v4l2_device_register(struct device *dev,
+ struct v4l2_device *v4l2_dev);
+
+/**
+ * v4l2_device_set_name - Optional function to initialize the
+ * name field of struct v4l2_device
+ *
+ * @v4l2_dev: pointer to struct v4l2_device
+ * @basename: base name for the device name
+ * @instance: pointer to a static atomic_t var with the instance usage for
+ * the device driver.
+ *
+ * v4l2_device_set_name() initializes the name field of struct v4l2_device
+ * using the driver name and a driver-global atomic_t instance.
+ *
+ * This function will increment the instance counter and returns the
+ * instance value used in the name.
+ *
+ * Example:
+ *
+ * static atomic_t drv_instance = ATOMIC_INIT(0);
+ *
+ * ...
+ *
+ * instance = v4l2_device_set_name(&v4l2_dev, "foo", &drv_instance);
+ *
+ * The first time this is called the name field will be set to foo0 and
+ * this function returns 0. If the name ends with a digit (e.g. cx18),
+ * then the name will be set to cx18-0 since cx180 would look really odd.
+ */
int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
- atomic_t *instance);
-
-/* Set v4l2_dev->dev to NULL. Call when the USB parent disconnects.
- Since the parent disappears this ensures that v4l2_dev doesn't have an
- invalid parent pointer. */
+ atomic_t *instance);
+
+/**
+ * v4l2_device_disconnect - Change V4L2 device state to disconnected.
+ *
+ * @v4l2_dev: pointer to struct v4l2_device
+ *
+ * Should be called when the USB parent disconnects.
+ * Since the parent disappears, this ensures that v4l2_dev doesn't have
+ * an invalid parent pointer.
+ *
+ * .. note:: This function sets v4l2_dev->dev to NULL.
+ */
void v4l2_device_disconnect(struct v4l2_device *v4l2_dev);
-/* Unregister all sub-devices and any other resources related to v4l2_dev. */
+/**
+ * v4l2_device_unregister - Unregister all sub-devices and any other
+ * resources related to v4l2_dev.
+ *
+ * @v4l2_dev: pointer to struct v4l2_device
+ */
void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
-/* Register a subdev with a v4l2 device. While registered the subdev module
- is marked as in-use. An error is returned if the module is no longer
- loaded when you attempt to register it. */
+/**
+ * v4l2_device_register_subdev - Registers a subdev with a v4l2 device.
+ *
+ * @v4l2_dev: pointer to struct v4l2_device
+ * @sd: pointer to struct v4l2_subdev
+ *
+ * While registered, the subdev module is marked as in-use.
+ *
+ * An error is returned if the module is no longer loaded on any attempts
+ * to register it.
+ */
int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
- struct v4l2_subdev *sd);
-/* Unregister a subdev with a v4l2 device. Can also be called if the subdev
- wasn't registered. In that case it will do nothing. */
+ struct v4l2_subdev *sd);
+
+/**
+ * v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device.
+ *
+ * @sd: pointer to struct v4l2_subdev
+ *
+ * .. note ::
+ *
+ * Can also be called if the subdev wasn't registered. In such
+ * case, it will do nothing.
+ */
void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
-/* Register device nodes for all subdev of the v4l2 device that are marked with
- * the V4L2_SUBDEV_FL_HAS_DEVNODE flag.
+/**
+ * v4l2_device_register_subdev_nodes - Registers device nodes for all subdevs
+ * of the v4l2 device that are marked with
+ * the V4L2_SUBDEV_FL_HAS_DEVNODE flag.
+ *
+ * @v4l2_dev: pointer to struct v4l2_device
*/
int __must_check
v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
-/* Send a notification to v4l2_device. */
+/**
+ * v4l2_subdev_notify - Sends a notification to v4l2_device.
+ *
+ * @sd: pointer to struct v4l2_subdev
+ * @notification: type of notification. Please notice that the notification
+ * type is driver-specific.
+ * @arg: arguments for the notification. Those are specific to each
+ * notification type.
+ */
static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
unsigned int notification, void *arg)
{
diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h
index 1113c8874c26..65caadf13eec 100644
--- a/include/media/v4l2-dv-timings.h
+++ b/include/media/v4l2-dv-timings.h
@@ -28,7 +28,7 @@
*/
extern const struct v4l2_dv_timings v4l2_dv_timings_presets[];
-/**
+/*
* v4l2_check_dv_timings_fnc - timings check callback
*
* @t: the v4l2_dv_timings struct.
diff --git a/include/media/v4l2-event.h b/include/media/v4l2-event.h
index 9792f906423b..ca854203b8b9 100644
--- a/include/media/v4l2-event.h
+++ b/include/media/v4l2-event.h
@@ -73,14 +73,15 @@ struct video_device;
* @list: List node for the v4l2_fh->available list.
* @sev: Pointer to parent v4l2_subscribed_event.
* @event: The event itself.
- */
+ */
struct v4l2_kevent {
struct list_head list;
struct v4l2_subscribed_event *sev;
struct v4l2_event event;
};
-/** struct v4l2_subscribed_event_ops - Subscribed event operations.
+/**
+ * struct v4l2_subscribed_event_ops - Subscribed event operations.
*
* @add: Optional callback, called when a new listener is added
* @del: Optional callback, called when a listener stops listening
@@ -88,20 +89,23 @@ struct v4l2_kevent {
* @merge: Optional callback that can merge event 'old' into event 'new'.
*/
struct v4l2_subscribed_event_ops {
- int (*add)(struct v4l2_subscribed_event *sev, unsigned elems);
+ int (*add)(struct v4l2_subscribed_event *sev, unsigned int elems);
void (*del)(struct v4l2_subscribed_event *sev);
void (*replace)(struct v4l2_event *old, const struct v4l2_event *new);
void (*merge)(const struct v4l2_event *old, struct v4l2_event *new);
};
/**
- * struct v4l2_subscribed_event - Internal struct representing a subscribed event.
+ * struct v4l2_subscribed_event - Internal struct representing a subscribed
+ * event.
+ *
* @list: List node for the v4l2_fh->subscribed list.
* @type: Event type.
* @id: Associated object ID (e.g. control ID). 0 if there isn't any.
* @flags: Copy of v4l2_event_subscription->flags.
* @fh: Filehandle that subscribed to this event.
- * @node: List node that hooks into the object's event list (if there is one).
+ * @node: List node that hooks into the object's event list
+ * (if there is one).
* @ops: v4l2_subscribed_event_ops
* @elems: The number of elements in the events array.
* @first: The index of the events containing the oldest available event.
@@ -116,27 +120,124 @@ struct v4l2_subscribed_event {
struct v4l2_fh *fh;
struct list_head node;
const struct v4l2_subscribed_event_ops *ops;
- unsigned elems;
- unsigned first;
- unsigned in_use;
+ unsigned int elems;
+ unsigned int first;
+ unsigned int in_use;
struct v4l2_kevent events[];
};
+/**
+ * v4l2_event_dequeue - Dequeue events from video device.
+ *
+ * @fh: pointer to struct v4l2_fh
+ * @event: pointer to struct v4l2_event
+ * @nonblocking: if not zero, waits for an event to arrive
+ */
int v4l2_event_dequeue(struct v4l2_fh *fh, struct v4l2_event *event,
int nonblocking);
+
+/**
+ * v4l2_event_queue - Queue events to video device.
+ *
+ * @vdev: pointer to &struct video_device
+ * @ev: pointer to &struct v4l2_event
+ *
+ * The event will be queued for all &struct v4l2_fh file handlers.
+ *
+ * .. note::
+ * The driver's only responsibility is to fill in the type and the data
+ * fields.The other fields will be filled in by V4L2.
+ */
void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev);
+
+/**
+ * v4l2_event_queue_fh - Queue events to video device.
+ *
+ * @fh: pointer to &struct v4l2_fh
+ * @ev: pointer to &struct v4l2_event
+ *
+ *
+ * The event will be queued only for the specified &struct v4l2_fh file handler.
+ *
+ * .. note::
+ * The driver's only responsibility is to fill in the type and the data
+ * fields.The other fields will be filled in by V4L2.
+ */
void v4l2_event_queue_fh(struct v4l2_fh *fh, const struct v4l2_event *ev);
+
+/**
+ * v4l2_event_pending - Check if an event is available
+ *
+ * @fh: pointer to &struct v4l2_fh
+ *
+ * Returns the number of pending events.
+ */
int v4l2_event_pending(struct v4l2_fh *fh);
+
+/**
+ * v4l2_event_subscribe - Subscribes to an event
+ *
+ * @fh: pointer to &struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ * @elems: size of the events queue
+ * @ops: pointer to &v4l2_subscribed_event_ops
+ *
+ * .. note::
+ *
+ * if @elems is zero, the framework will fill in a default value,
+ * with is currently 1 element.
+ */
int v4l2_event_subscribe(struct v4l2_fh *fh,
- const struct v4l2_event_subscription *sub, unsigned elems,
+ const struct v4l2_event_subscription *sub,
+ unsigned int elems,
const struct v4l2_subscribed_event_ops *ops);
+/**
+ * v4l2_event_unsubscribe - Unsubscribes to an event
+ *
+ * @fh: pointer to &struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ */
int v4l2_event_unsubscribe(struct v4l2_fh *fh,
const struct v4l2_event_subscription *sub);
+/**
+ * v4l2_event_unsubscribe_all - Unsubscribes to all events
+ *
+ * @fh: pointer to &struct v4l2_fh
+ */
void v4l2_event_unsubscribe_all(struct v4l2_fh *fh);
-int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+
+/**
+ * v4l2_event_subdev_unsubscribe - Subdev variant of v4l2_event_unsubscribe()
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @fh: pointer to &struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ *
+ * .. note::
+ *
+ * This function should be used for the &struct v4l2_subdev_core_ops
+ * %unsubscribe_event field.
+ */
+int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd,
+ struct v4l2_fh *fh,
struct v4l2_event_subscription *sub);
+/**
+ * v4l2_src_change_event_subscribe -
+ *
+ * @fh: pointer to struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ */
int v4l2_src_change_event_subscribe(struct v4l2_fh *fh,
- const struct v4l2_event_subscription *sub);
+ const struct v4l2_event_subscription *sub);
+/**
+ * v4l2_src_change_event_subdev_subscribe - Variant of v4l2_event_subscribe(),
+ * meant to subscribe only events of the type %V4L2_EVENT_SOURCE_CHANGE.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @fh: pointer to &struct v4l2_fh
+ * @sub: pointer to &struct v4l2_event_subscription
+ */
int v4l2_src_change_event_subdev_subscribe(struct v4l2_subdev *sd,
- struct v4l2_fh *fh, struct v4l2_event_subscription *sub);
+ struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub);
#endif /* V4L2_EVENT_H */
diff --git a/include/media/v4l2-fh.h b/include/media/v4l2-fh.h
index 803516775162..e19e6246e21c 100644
--- a/include/media/v4l2-fh.h
+++ b/include/media/v4l2-fh.h
@@ -33,6 +33,21 @@
struct video_device;
struct v4l2_ctrl_handler;
+/**
+ * struct v4l2_fh - Describes a V4L2 file handler
+ *
+ * @list: list of file handlers
+ * @vdev: pointer to &struct video_device
+ * @ctrl_handler: pointer to &struct v4l2_ctrl_handler
+ * @prio: priority of the file handler, as defined by &enum v4l2_priority
+ *
+ * @wait: event' s wait queue
+ * @subscribed: list of subscribed events
+ * @available: list of events waiting to be dequeued
+ * @navailable: number of available events at @available list
+ * @sequence: event sequence number
+ * @m2m_ctx: pointer to &struct v4l2_m2m_ctx
+ */
struct v4l2_fh {
struct list_head list;
struct video_device *vdev;
@@ -41,8 +56,8 @@ struct v4l2_fh {
/* Events */
wait_queue_head_t wait;
- struct list_head subscribed; /* Subscribed events */
- struct list_head available; /* Dequeueable event */
+ struct list_head subscribed;
+ struct list_head available;
unsigned int navailable;
u32 sequence;
@@ -51,53 +66,102 @@ struct v4l2_fh {
#endif
};
-/*
- * Initialise the file handle. Parts of the V4L2 framework using the
+/**
+ * v4l2_fh_init - Initialise the file handle.
+ *
+ * @fh: pointer to &struct v4l2_fh
+ * @vdev: pointer to &struct video_device
+ *
+ * Parts of the V4L2 framework using the
* file handles should be initialised in this function. Must be called
- * from driver's v4l2_file_operations->open() handler if the driver
- * uses v4l2_fh.
+ * from driver's v4l2_file_operations->open\(\) handler if the driver
+ * uses &struct v4l2_fh.
*/
void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev);
-/*
- * Add the fh to the list of file handles on a video_device. The file
- * handle must be initialised first.
+
+/**
+ * v4l2_fh_add - Add the fh to the list of file handles on a video_device.
+ *
+ * @fh: pointer to &struct v4l2_fh
+ *
+ * .. note::
+ * The @fh file handle must be initialised first.
*/
void v4l2_fh_add(struct v4l2_fh *fh);
-/*
- * Can be used as the open() op of v4l2_file_operations.
- * It allocates a v4l2_fh and inits and adds it to the video_device associated
- * with the file pointer.
+
+/**
+ * v4l2_fh_open - Ancillary routine that can be used as the open\(\) op
+ * of v4l2_file_operations.
+ *
+ * @filp: pointer to struct file
+ *
+ * It allocates a v4l2_fh and inits and adds it to the &struct video_device
+ * associated with the file pointer.
*/
int v4l2_fh_open(struct file *filp);
-/*
- * Remove file handle from the list of file handles. Must be called in
- * v4l2_file_operations->release() handler if the driver uses v4l2_fh.
- * On error filp->private_data will be NULL, otherwise it will point to
- * the v4l2_fh struct.
+
+/**
+ * v4l2_fh_del - Remove file handle from the list of file handles.
+ *
+ * @fh: pointer to &struct v4l2_fh
+ *
+ * On error filp->private_data will be %NULL, otherwise it will point to
+ * the &struct v4l2_fh.
+ *
+ * .. note::
+ * Must be called in v4l2_file_operations->release\(\) handler if the driver
+ * uses &struct v4l2_fh.
*/
void v4l2_fh_del(struct v4l2_fh *fh);
-/*
- * Release resources related to a file handle. Parts of the V4L2
- * framework using the v4l2_fh must release their resources here, too.
- * Must be called in v4l2_file_operations->release() handler if the
- * driver uses v4l2_fh.
+
+/**
+ * v4l2_fh_exit - Release resources related to a file handle.
+ *
+ * @fh: pointer to &struct v4l2_fh
+ *
+ * Parts of the V4L2 framework using the v4l2_fh must release their
+ * resources here, too.
+ *
+ * .. note::
+ * Must be called in v4l2_file_operations->release\(\) handler if the
+ * driver uses &struct v4l2_fh.
*/
void v4l2_fh_exit(struct v4l2_fh *fh);
-/*
- * Can be used as the release() op of v4l2_file_operations.
+
+/**
+ * v4l2_fh_release - Ancillary routine that can be used as the release\(\) op
+ * of v4l2_file_operations.
+ *
+ * @filp: pointer to struct file
+ *
* It deletes and exits the v4l2_fh associated with the file pointer and
* frees it. It will do nothing if filp->private_data (the pointer to the
- * v4l2_fh struct) is NULL. This function always returns 0.
+ * v4l2_fh struct) is %NULL.
+ *
+ * This function always returns 0.
*/
int v4l2_fh_release(struct file *filp);
-/*
- * Returns 1 if this filehandle is the only filehandle opened for the
- * associated video_device. If fh is NULL, then it returns 0.
+
+/**
+ * v4l2_fh_is_singular - Returns 1 if this filehandle is the only filehandle
+ * opened for the associated video_device.
+ *
+ * @fh: pointer to &struct v4l2_fh
+ *
+ * If @fh is NULL, then it returns 0.
*/
int v4l2_fh_is_singular(struct v4l2_fh *fh);
-/*
- * Helper function with struct file as argument. If filp->private_data is
- * NULL, then it will return 0.
+
+/**
+ * v4l2_fh_is_singular_file - Returns 1 if this filehandle is the only
+ * filehandle opened for the associated video_device.
+ *
+ * @filp: pointer to struct file
+ *
+ * This is a helper function variant of v4l2_fh_is_singular() with uses
+ * struct file as argument.
+ *
+ * If filp->private_data is %NULL, then it will return 0.
*/
static inline int v4l2_fh_is_singular_file(struct file *filp)
{
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 017ffb2220c7..8b1d19bc9b0e 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -17,6 +17,272 @@
struct v4l2_fh;
+/**
+ * struct v4l2_ioctl_ops - describe operations for each V4L2 ioctl
+ *
+ * @vidioc_querycap: pointer to the function that implements
+ * :ref:`VIDIOC_QUERYCAP <vidioc_querycap>` ioctl
+ * @vidioc_enum_fmt_vid_cap: pointer to the function that implements
+ * :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ * for video capture in single plane mode
+ * @vidioc_enum_fmt_vid_overlay: pointer to the function that implements
+ * :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ * for video overlay
+ * @vidioc_enum_fmt_vid_out: pointer to the function that implements
+ * :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ * for video output in single plane mode
+ * @vidioc_enum_fmt_vid_cap_mplane: pointer to the function that implements
+ * :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ * for video capture in multiplane mode
+ * @vidioc_enum_fmt_vid_out_mplane: pointer to the function that implements
+ * :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ * for video output in multiplane mode
+ * @vidioc_enum_fmt_sdr_cap: pointer to the function that implements
+ * :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ * for Software Defined Radio capture
+ * @vidioc_enum_fmt_sdr_out: pointer to the function that implements
+ * :ref:`VIDIOC_ENUM_FMT <vidioc_enum_fmt>` ioctl logic
+ * for Software Defined Radio output
+ * @vidioc_g_fmt_vid_cap: pointer to the function that implements
+ * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video capture
+ * in single plane mode
+ * @vidioc_g_fmt_vid_overlay: pointer to the function that implements
+ * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video overlay
+ * @vidioc_g_fmt_vid_out: pointer to the function that implements
+ * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video out
+ * in single plane mode
+ * @vidioc_g_fmt_vid_out_overlay: pointer to the function that implements
+ * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video overlay output
+ * @vidioc_g_fmt_vbi_cap: pointer to the function that implements
+ * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for raw VBI capture
+ * @vidioc_g_fmt_vbi_out: pointer to the function that implements
+ * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for raw VBI output
+ * @vidioc_g_fmt_sliced_vbi_cap: pointer to the function that implements
+ * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for sliced VBI capture
+ * @vidioc_g_fmt_sliced_vbi_out: pointer to the function that implements
+ * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for sliced VBI output
+ * @vidioc_g_fmt_vid_cap_mplane: pointer to the function that implements
+ * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video capture
+ * in multiple plane mode
+ * @vidioc_g_fmt_vid_out_mplane: pointer to the function that implements
+ * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for video out
+ * in multiplane plane mode
+ * @vidioc_g_fmt_sdr_cap: pointer to the function that implements
+ * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for Software Defined
+ * Radio capture
+ * @vidioc_g_fmt_sdr_out: pointer to the function that implements
+ * :ref:`VIDIOC_G_FMT <vidioc_g_fmt>` ioctl logic for Software Defined
+ * Radio output
+ * @vidioc_s_fmt_vid_cap: pointer to the function that implements
+ * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video capture
+ * in single plane mode
+ * @vidioc_s_fmt_vid_overlay: pointer to the function that implements
+ * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video overlay
+ * @vidioc_s_fmt_vid_out: pointer to the function that implements
+ * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video out
+ * in single plane mode
+ * @vidioc_s_fmt_vid_out_overlay: pointer to the function that implements
+ * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video overlay output
+ * @vidioc_s_fmt_vbi_cap: pointer to the function that implements
+ * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for raw VBI capture
+ * @vidioc_s_fmt_vbi_out: pointer to the function that implements
+ * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for raw VBI output
+ * @vidioc_s_fmt_sliced_vbi_cap: pointer to the function that implements
+ * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for sliced VBI capture
+ * @vidioc_s_fmt_sliced_vbi_out: pointer to the function that implements
+ * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for sliced VBI output
+ * @vidioc_s_fmt_vid_cap_mplane: pointer to the function that implements
+ * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video capture
+ * in multiple plane mode
+ * @vidioc_s_fmt_vid_out_mplane: pointer to the function that implements
+ * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for video out
+ * in multiplane plane mode
+ * @vidioc_s_fmt_sdr_cap: pointer to the function that implements
+ * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for Software Defined
+ * Radio capture
+ * @vidioc_s_fmt_sdr_out: pointer to the function that implements
+ * :ref:`VIDIOC_S_FMT <vidioc_g_fmt>` ioctl logic for Software Defined
+ * Radio output
+ * @vidioc_try_fmt_vid_cap: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video capture
+ * in single plane mode
+ * @vidioc_try_fmt_vid_overlay: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video overlay
+ * @vidioc_try_fmt_vid_out: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video out
+ * in single plane mode
+ * @vidioc_try_fmt_vid_out_overlay: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video overlay
+ * output
+ * @vidioc_try_fmt_vbi_cap: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for raw VBI capture
+ * @vidioc_try_fmt_vbi_out: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for raw VBI output
+ * @vidioc_try_fmt_sliced_vbi_cap: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for sliced VBI
+ * capture
+ * @vidioc_try_fmt_sliced_vbi_out: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for sliced VBI output
+ * @vidioc_try_fmt_vid_cap_mplane: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video capture
+ * in multiple plane mode
+ * @vidioc_try_fmt_vid_out_mplane: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for video out
+ * in multiplane plane mode
+ * @vidioc_try_fmt_sdr_cap: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for Software Defined
+ * Radio capture
+ * @vidioc_try_fmt_sdr_out: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_FMT <vidioc_g_fmt>` ioctl logic for Software Defined
+ * Radio output
+ * @vidioc_reqbufs: pointer to the function that implements
+ * :ref:`VIDIOC_REQBUFS <vidioc_reqbufs>` ioctl
+ * @vidioc_querybuf: pointer to the function that implements
+ * :ref:`VIDIOC_QUERYBUF <vidioc_querybuf>` ioctl
+ * @vidioc_qbuf: pointer to the function that implements
+ * :ref:`VIDIOC_QBUF <vidioc_qbuf>` ioctl
+ * @vidioc_expbuf: pointer to the function that implements
+ * :ref:`VIDIOC_EXPBUF <vidioc_expbuf>` ioctl
+ * @vidioc_dqbuf: pointer to the function that implements
+ * :ref:`VIDIOC_DQBUF <vidioc_qbuf>` ioctl
+ * @vidioc_create_bufs: pointer to the function that implements
+ * :ref:`VIDIOC_CREATE_BUFS <vidioc_create_bufs>` ioctl
+ * @vidioc_prepare_buf: pointer to the function that implements
+ * :ref:`VIDIOC_PREPARE_BUF <vidioc_prepare_buf>` ioctl
+ * @vidioc_overlay: pointer to the function that implements
+ * :ref:`VIDIOC_OVERLAY <vidioc_overlay>` ioctl
+ * @vidioc_g_fbuf: pointer to the function that implements
+ * :ref:`VIDIOC_G_FBUF <vidioc_g_fbuf>` ioctl
+ * @vidioc_s_fbuf: pointer to the function that implements
+ * :ref:`VIDIOC_S_FBUF <vidioc_g_fbuf>` ioctl
+ * @vidioc_streamon: pointer to the function that implements
+ * :ref:`VIDIOC_STREAMON <vidioc_streamon>` ioctl
+ * @vidioc_streamoff: pointer to the function that implements
+ * :ref:`VIDIOC_STREAMOFF <vidioc_streamon>` ioctl
+ * @vidioc_g_std: pointer to the function that implements
+ * :ref:`VIDIOC_G_STD <vidioc_g_std>` ioctl
+ * @vidioc_s_std: pointer to the function that implements
+ * :ref:`VIDIOC_S_STD <vidioc_g_std>` ioctl
+ * @vidioc_querystd: pointer to the function that implements
+ * :ref:`VIDIOC_QUERYSTD <vidioc_querystd>` ioctl
+ * @vidioc_enum_input: pointer to the function that implements
+ * :ref:`VIDIOC_ENUM_INPUT <vidioc_g_input>` ioctl
+ * @vidioc_g_input: pointer to the function that implements
+ * :ref:`VIDIOC_G_INPUT <vidioc_g_input>` ioctl
+ * @vidioc_s_input: pointer to the function that implements
+ * :ref:`VIDIOC_S_INPUT <vidioc_g_input>` ioctl
+ * @vidioc_enum_output: pointer to the function that implements
+ * :ref:`VIDIOC_ENUM_OUTPUT <vidioc_g_output>` ioctl
+ * @vidioc_g_output: pointer to the function that implements
+ * :ref:`VIDIOC_G_OUTPUT <vidioc_g_output>` ioctl
+ * @vidioc_s_output: pointer to the function that implements
+ * :ref:`VIDIOC_S_OUTPUT <vidioc_g_output>` ioctl
+ * @vidioc_queryctrl: pointer to the function that implements
+ * :ref:`VIDIOC_QUERYCTRL <vidioc_queryctrl>` ioctl
+ * @vidioc_query_ext_ctrl: pointer to the function that implements
+ * :ref:`VIDIOC_QUERY_EXT_CTRL <vidioc_queryctrl>` ioctl
+ * @vidioc_g_ctrl: pointer to the function that implements
+ * :ref:`VIDIOC_G_CTRL <vidioc_g_ctrl>` ioctl
+ * @vidioc_s_ctrl: pointer to the function that implements
+ * :ref:`VIDIOC_S_CTRL <vidioc_g_ctrl>` ioctl
+ * @vidioc_g_ext_ctrls: pointer to the function that implements
+ * :ref:`VIDIOC_G_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
+ * @vidioc_s_ext_ctrls: pointer to the function that implements
+ * :ref:`VIDIOC_S_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
+ * @vidioc_try_ext_ctrls: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_EXT_CTRLS <vidioc_g_ext_ctrls>` ioctl
+ * @vidioc_querymenu: pointer to the function that implements
+ * :ref:`VIDIOC_QUERYMENU <vidioc_queryctrl>` ioctl
+ * @vidioc_enumaudio: pointer to the function that implements
+ * :ref:`VIDIOC_ENUMAUDIO <vidioc_enumaudio>` ioctl
+ * @vidioc_g_audio: pointer to the function that implements
+ * :ref:`VIDIOC_G_AUDIO <vidioc_g_audio>` ioctl
+ * @vidioc_s_audio: pointer to the function that implements
+ * :ref:`VIDIOC_S_AUDIO <vidioc_g_audio>` ioctl
+ * @vidioc_enumaudout: pointer to the function that implements
+ * :ref:`VIDIOC_ENUMAUDOUT <vidioc_enumaudout>` ioctl
+ * @vidioc_g_audout: pointer to the function that implements
+ * :ref:`VIDIOC_G_AUDOUT <vidioc_g_audout>` ioctl
+ * @vidioc_s_audout: pointer to the function that implements
+ * :ref:`VIDIOC_S_AUDOUT <vidioc_g_audout>` ioctl
+ * @vidioc_g_modulator: pointer to the function that implements
+ * :ref:`VIDIOC_G_MODULATOR <vidioc_g_modulator>` ioctl
+ * @vidioc_s_modulator: pointer to the function that implements
+ * :ref:`VIDIOC_S_MODULATOR <vidioc_g_modulator>` ioctl
+ * @vidioc_cropcap: pointer to the function that implements
+ * :ref:`VIDIOC_CROPCAP <vidioc_cropcap>` ioctl
+ * @vidioc_g_crop: pointer to the function that implements
+ * :ref:`VIDIOC_G_CROP <vidioc_g_crop>` ioctl
+ * @vidioc_s_crop: pointer to the function that implements
+ * :ref:`VIDIOC_S_CROP <vidioc_g_crop>` ioctl
+ * @vidioc_g_selection: pointer to the function that implements
+ * :ref:`VIDIOC_G_SELECTION <vidioc_g_selection>` ioctl
+ * @vidioc_s_selection: pointer to the function that implements
+ * :ref:`VIDIOC_S_SELECTION <vidioc_g_selection>` ioctl
+ * @vidioc_g_jpegcomp: pointer to the function that implements
+ * :ref:`VIDIOC_G_JPEGCOMP <vidioc_g_jpegcomp>` ioctl
+ * @vidioc_s_jpegcomp: pointer to the function that implements
+ * :ref:`VIDIOC_S_JPEGCOMP <vidioc_g_jpegcomp>` ioctl
+ * @vidioc_g_enc_index: pointer to the function that implements
+ * :ref:`VIDIOC_G_ENC_INDEX <vidioc_g_enc_index>` ioctl
+ * @vidioc_encoder_cmd: pointer to the function that implements
+ * :ref:`VIDIOC_ENCODER_CMD <vidioc_encoder_cmd>` ioctl
+ * @vidioc_try_encoder_cmd: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_ENCODER_CMD <vidioc_encoder_cmd>` ioctl
+ * @vidioc_decoder_cmd: pointer to the function that implements
+ * :ref:`VIDIOC_DECODER_CMD <vidioc_decoder_cmd>` ioctl
+ * @vidioc_try_decoder_cmd: pointer to the function that implements
+ * :ref:`VIDIOC_TRY_DECODER_CMD <vidioc_decoder_cmd>` ioctl
+ * @vidioc_g_parm: pointer to the function that implements
+ * :ref:`VIDIOC_G_PARM <vidioc_g_parm>` ioctl
+ * @vidioc_s_parm: pointer to the function that implements
+ * :ref:`VIDIOC_S_PARM <vidioc_g_parm>` ioctl
+ * @vidioc_g_tuner: pointer to the function that implements
+ * :ref:`VIDIOC_G_TUNER <vidioc_g_tuner>` ioctl
+ * @vidioc_s_tuner: pointer to the function that implements
+ * :ref:`VIDIOC_S_TUNER <vidioc_g_tuner>` ioctl
+ * @vidioc_g_frequency: pointer to the function that implements
+ * :ref:`VIDIOC_G_FREQUENCY <vidioc_g_frequency>` ioctl
+ * @vidioc_s_frequency: pointer to the function that implements
+ * :ref:`VIDIOC_S_FREQUENCY <vidioc_g_frequency>` ioctl
+ * @vidioc_enum_freq_bands: pointer to the function that implements
+ * :ref:`VIDIOC_ENUM_FREQ_BANDS <vidioc_enum_freq_bands>` ioctl
+ * @vidioc_g_sliced_vbi_cap: pointer to the function that implements
+ * :ref:`VIDIOC_G_SLICED_VBI_CAP <vidioc_g_sliced_vbi_cap>` ioctl
+ * @vidioc_log_status: pointer to the function that implements
+ * :ref:`VIDIOC_LOG_STATUS <vidioc_log_status>` ioctl
+ * @vidioc_s_hw_freq_seek: pointer to the function that implements
+ * :ref:`VIDIOC_S_HW_FREQ_SEEK <vidioc_s_hw_freq_seek>` ioctl
+ * @vidioc_g_register: pointer to the function that implements
+ * :ref:`VIDIOC_DBG_G_REGISTER <vidioc_dbg_g_register>` ioctl
+ * @vidioc_s_register: pointer to the function that implements
+ * :ref:`VIDIOC_DBG_S_REGISTER <vidioc_dbg_g_register>` ioctl
+ * @vidioc_g_chip_info: pointer to the function that implements
+ * :ref:`VIDIOC_DBG_G_CHIP_INFO <vidioc_dbg_g_chip_info>` ioctl
+ * @vidioc_enum_framesizes: pointer to the function that implements
+ * :ref:`VIDIOC_ENUM_FRAMESIZES <vidioc_enum_framesizes>` ioctl
+ * @vidioc_enum_frameintervals: pointer to the function that implements
+ * :ref:`VIDIOC_ENUM_FRAMEINTERVALS <vidioc_enum_frameintervals>` ioctl
+ * @vidioc_s_dv_timings: pointer to the function that implements
+ * :ref:`VIDIOC_S_DV_TIMINGS <vidioc_g_dv_timings>` ioctl
+ * @vidioc_g_dv_timings: pointer to the function that implements
+ * :ref:`VIDIOC_G_DV_TIMINGS <vidioc_g_dv_timings>` ioctl
+ * @vidioc_query_dv_timings: pointer to the function that implements
+ * :ref:`VIDIOC_QUERY_DV_TIMINGS <vidioc_query_dv_timings>` ioctl
+ * @vidioc_enum_dv_timings: pointer to the function that implements
+ * :ref:`VIDIOC_ENUM_DV_TIMINGS <vidioc_enum_dv_timings>` ioctl
+ * @vidioc_dv_timings_cap: pointer to the function that implements
+ * :ref:`VIDIOC_DV_TIMINGS_CAP <vidioc_dv_timings_cap>` ioctl
+ * @vidioc_g_edid: pointer to the function that implements
+ * :ref:`VIDIOC_G_EDID <vidioc_g_edid>` ioctl
+ * @vidioc_s_edid: pointer to the function that implements
+ * :ref:`VIDIOC_S_EDID <vidioc_g_edid>` ioctl
+ * @vidioc_subscribe_event: pointer to the function that implements
+ * :ref:`VIDIOC_SUBSCRIBE_EVENT <vidioc_subscribe_event>` ioctl
+ * @vidioc_unsubscribe_event: pointer to the function that implements
+ * :ref:`VIDIOC_UNSUBSCRIBE_EVENT <vidioc_unsubscribe_event>` ioctl
+ * @vidioc_default: pointed used to allow other ioctls
+ */
struct v4l2_ioctl_ops {
/* ioctl callbacks */
diff --git a/include/media/v4l2-mc.h b/include/media/v4l2-mc.h
index 7a8d6037a4bb..28c3f9d9c209 100644
--- a/include/media/v4l2-mc.h
+++ b/include/media/v4l2-mc.h
@@ -114,11 +114,14 @@ struct usb_device;
* Add links between the entities commonly found on PC customer's hardware at
* the V4L2 side: camera sensors, audio and video PLL-IF decoders, tuners,
* analog TV decoder and I/O entities (video, VBI and Software Defined Radio).
- * NOTE: webcams are modelled on a very simple way: the sensor is
- * connected directly to the I/O entity. All dirty details, like
- * scaler and crop HW are hidden. While such mapping is enough for v4l2
- * interface centric PC-consumer's hardware, V4L2 subdev centric camera
- * hardware should not use this routine, as it will not build the right graph.
+ *
+ * .. note::
+ *
+ * Webcams are modelled on a very simple way: the sensor is
+ * connected directly to the I/O entity. All dirty details, like
+ * scaler and crop HW are hidden. While such mapping is enough for v4l2
+ * interface centric PC-consumer's hardware, V4L2 subdev centric camera
+ * hardware should not use this routine, as it will not build the right graph.
*/
int v4l2_mc_create_media_graph(struct media_device *mdev);
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 32fc7a4beb5e..2a2240c99b30 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -1,21 +1,17 @@
/*
- V4L2 sub-device support header.
-
- Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * V4L2 sub-device support header.
+ *
+ * Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
*/
#ifndef _V4L2_SUBDEV_H
@@ -52,55 +48,64 @@ struct v4l2_subdev_fh;
struct tuner_setup;
struct v4l2_mbus_frame_desc;
-/* decode_vbi_line */
+/**
+ * struct v4l2_decode_vbi_line - used to decode_vbi_line
+ *
+ * @is_second_field: Set to 0 for the first (odd) field;
+ * set to 1 for the second (even) field.
+ * @p: Pointer to the sliced VBI data from the decoder. On exit, points to
+ * the start of the payload.
+ * @line: Line number of the sliced VBI data (1-23)
+ * @type: VBI service type (V4L2_SLICED_*). 0 if no service found
+ */
struct v4l2_decode_vbi_line {
- u32 is_second_field; /* Set to 0 for the first (odd) field,
- set to 1 for the second (even) field. */
- u8 *p; /* Pointer to the sliced VBI data from the decoder.
- On exit points to the start of the payload. */
- u32 line; /* Line number of the sliced VBI data (1-23) */
- u32 type; /* VBI service type (V4L2_SLICED_*). 0 if no service found */
+ u32 is_second_field;
+ u8 *p;
+ u32 line;
+ u32 type;
};
-/* Sub-devices are devices that are connected somehow to the main bridge
- device. These devices are usually audio/video muxers/encoders/decoders or
- sensors and webcam controllers.
-
- Usually these devices are controlled through an i2c bus, but other busses
- may also be used.
-
- The v4l2_subdev struct provides a way of accessing these devices in a
- generic manner. Most operations that these sub-devices support fall in
- a few categories: core ops, audio ops, video ops and tuner ops.
-
- More categories can be added if needed, although this should remain a
- limited set (no more than approx. 8 categories).
-
- Each category has its own set of ops that subdev drivers can implement.
-
- A subdev driver can leave the pointer to the category ops NULL if
- it does not implement them (e.g. an audio subdev will generally not
- implement the video category ops). The exception is the core category:
- this must always be present.
-
- These ops are all used internally so it is no problem to change, remove
- or add ops or move ops from one to another category. Currently these
- ops are based on the original ioctls, but since ops are not limited to
- one argument there is room for improvement here once all i2c subdev
- drivers are converted to use these ops.
+/*
+ * Sub-devices are devices that are connected somehow to the main bridge
+ * device. These devices are usually audio/video muxers/encoders/decoders or
+ * sensors and webcam controllers.
+ *
+ * Usually these devices are controlled through an i2c bus, but other busses
+ * may also be used.
+ *
+ * The v4l2_subdev struct provides a way of accessing these devices in a
+ * generic manner. Most operations that these sub-devices support fall in
+ * a few categories: core ops, audio ops, video ops and tuner ops.
+ *
+ * More categories can be added if needed, although this should remain a
+ * limited set (no more than approx. 8 categories).
+ *
+ * Each category has its own set of ops that subdev drivers can implement.
+ *
+ * A subdev driver can leave the pointer to the category ops NULL if
+ * it does not implement them (e.g. an audio subdev will generally not
+ * implement the video category ops). The exception is the core category:
+ * this must always be present.
+ *
+ * These ops are all used internally so it is no problem to change, remove
+ * or add ops or move ops from one to another category. Currently these
+ * ops are based on the original ioctls, but since ops are not limited to
+ * one argument there is room for improvement here once all i2c subdev
+ * drivers are converted to use these ops.
*/
-/* Core ops: it is highly recommended to implement at least these ops:
-
- log_status
- g_register
- s_register
-
- This provides basic debugging support.
-
- The ioctl ops is meant for generic ioctl-like commands. Depending on
- the use-case it might be better to use subdev-specific ops (currently
- not yet implemented) since ops provide proper type-checking.
+/*
+ * Core ops: it is highly recommended to implement at least these ops:
+ *
+ * log_status
+ * g_register
+ * s_register
+ *
+ * This provides basic debugging support.
+ *
+ * The ioctl ops is meant for generic ioctl-like commands. Depending on
+ * the use-case it might be better to use subdev-specific ops (currently
+ * not yet implemented) since ops provide proper type-checking.
*/
/* Subdevice external IO pin configuration */
@@ -110,18 +115,32 @@ struct v4l2_decode_vbi_line {
#define V4L2_SUBDEV_IO_PIN_SET_VALUE (1 << 3) /* Set output value */
#define V4L2_SUBDEV_IO_PIN_ACTIVE_LOW (1 << 4) /* ACTIVE HIGH assumed */
+/**
+ * struct v4l2_subdev_io_pin_config - Subdevice external IO pin configuration
+ *
+ * @flags: bitmask with flags for this pin's config:
+ * %V4L2_SUBDEV_IO_PIN_DISABLE - disables a pin config,
+ * %V4L2_SUBDEV_IO_PIN_OUTPUT - if pin is an output,
+ * %V4L2_SUBDEV_IO_PIN_INPUT - if pin is an input,
+ * %V4L2_SUBDEV_IO_PIN_SET_VALUE - to set the output value via @value
+ * and %V4L2_SUBDEV_IO_PIN_ACTIVE_LOW - if active is 0.
+ * @pin: Chip external IO pin to configure
+ * @function: Internal signal pad/function to route to IO pin
+ * @value: Initial value for pin - e.g. GPIO output value
+ * @strength: Pin drive strength
+ */
struct v4l2_subdev_io_pin_config {
- u32 flags; /* V4L2_SUBDEV_IO_PIN_* flags for this pin's config */
- u8 pin; /* Chip external IO pin to configure */
- u8 function; /* Internal signal pad/function to route to IO pin */
- u8 value; /* Initial value for pin - e.g. GPIO output value */
- u8 strength; /* Pin drive strength */
+ u32 flags;
+ u8 pin;
+ u8 function;
+ u8 value;
+ u8 strength;
};
/**
* struct v4l2_subdev_core_ops - Define core ops callbacks for subdevs
*
- * @log_status: callback for VIDIOC_LOG_STATUS ioctl handler code.
+ * @log_status: callback for %VIDIOC_LOG_STATUS ioctl handler code.
*
* @s_io_pin_config: configure one or more chip I/O pins for chips that
* multiplex different internal signal pads out to IO pins. This function
@@ -143,29 +162,15 @@ struct v4l2_subdev_io_pin_config {
* @s_gpio: set GPIO pins. Very simple right now, might need to be extended with
* a direction argument if needed.
*
- * @queryctrl: callback for VIDIOC_QUERYCTL ioctl handler code.
- *
- * @g_ctrl: callback for VIDIOC_G_CTRL ioctl handler code.
- *
- * @s_ctrl: callback for VIDIOC_S_CTRL ioctl handler code.
- *
- * @g_ext_ctrls: callback for VIDIOC_G_EXT_CTRLS ioctl handler code.
- *
- * @s_ext_ctrls: callback for VIDIOC_S_EXT_CTRLS ioctl handler code.
- *
- * @try_ext_ctrls: callback for VIDIOC_TRY_EXT_CTRLS ioctl handler code.
- *
- * @querymenu: callback for VIDIOC_QUERYMENU ioctl handler code.
- *
* @ioctl: called at the end of ioctl() syscall handler at the V4L2 core.
* used to provide support for private ioctls used on the driver.
*
* @compat_ioctl32: called when a 32 bits application uses a 64 bits Kernel,
* in order to fix data passed from/to userspace.
*
- * @g_register: callback for VIDIOC_G_REGISTER ioctl handler code.
+ * @g_register: callback for %VIDIOC_G_REGISTER ioctl handler code.
*
- * @s_register: callback for VIDIOC_G_REGISTER ioctl handler code.
+ * @s_register: callback for %VIDIOC_G_REGISTER ioctl handler code.
*
* @s_power: puts subdevice in power saving mode (on == 0) or normal operation
* mode (on == 1).
@@ -173,7 +178,7 @@ struct v4l2_subdev_io_pin_config {
* @interrupt_service_routine: Called by the bridge chip's interrupt service
* handler, when an interrupt status has be raised due to this subdev,
* so that this subdev can handle the details. It may schedule work to be
- * performed later. It must not sleep. *Called from an IRQ context*.
+ * performed later. It must not sleep. **Called from an IRQ context**.
*
* @subscribe_event: used by the drivers to request the control framework that
* for it to be warned when the value of a control changes.
@@ -190,13 +195,6 @@ struct v4l2_subdev_core_ops {
int (*load_fw)(struct v4l2_subdev *sd);
int (*reset)(struct v4l2_subdev *sd, u32 val);
int (*s_gpio)(struct v4l2_subdev *sd, u32 val);
- int (*queryctrl)(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc);
- int (*g_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
- int (*s_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
- int (*g_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);
- int (*s_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);
- int (*try_ext_ctrls)(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls);
- int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm);
long (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
#ifdef CONFIG_COMPAT
long (*compat_ioctl32)(struct v4l2_subdev *sd, unsigned int cmd,
@@ -219,25 +217,25 @@ struct v4l2_subdev_core_ops {
/**
* struct s_radio - Callbacks used when v4l device was opened in radio mode.
*
- * @s_radio: callback for VIDIOC_S_RADIO ioctl handler code.
+ * @s_radio: callback for %VIDIOC_S_RADIO ioctl handler code.
*
- * @s_frequency: callback for VIDIOC_S_FREQUENCY ioctl handler code.
+ * @s_frequency: callback for %VIDIOC_S_FREQUENCY ioctl handler code.
*
- * @g_frequency: callback for VIDIOC_G_FREQUENCY ioctl handler code.
- * freq->type must be filled in. Normally done by video_ioctl2
- * or the bridge driver.
+ * @g_frequency: callback for %VIDIOC_G_FREQUENCY ioctl handler code.
+ * freq->type must be filled in. Normally done by video_ioctl2()
+ * or the bridge driver.
*
- * @enum_freq_bands: callback for VIDIOC_ENUM_FREQ_BANDS ioctl handler code.
+ * @enum_freq_bands: callback for %VIDIOC_ENUM_FREQ_BANDS ioctl handler code.
*
- * @g_tuner: callback for VIDIOC_G_TUNER ioctl handler code.
+ * @g_tuner: callback for %VIDIOC_G_TUNER ioctl handler code.
*
- * @s_tuner: callback for VIDIOC_S_TUNER ioctl handler code. vt->type must be
+ * @s_tuner: callback for %VIDIOC_S_TUNER ioctl handler code. &vt->type must be
* filled in. Normally done by video_ioctl2 or the
- * bridge driver.
+ * bridge driver.
*
- * @g_modulator: callback for VIDIOC_G_MODULATOR ioctl handler code.
+ * @g_modulator: callback for %VIDIOC_G_MODULATOR ioctl handler code.
*
- * @s_modulator: callback for VIDIOC_S_MODULATOR ioctl handler code.
+ * @s_modulator: callback for %VIDIOC_S_MODULATOR ioctl handler code.
*
* @s_type_addr: sets tuner type and its I2C addr.
*
@@ -268,7 +266,7 @@ struct v4l2_subdev_tuner_ops {
* @s_i2s_clock_freq: sets I2S speed in bps. This is used to provide a standard
* way to select I2S clock used by driving digital audio streams at some
* board designs. Usual values for the frequency are 1024000 and 2048000.
- * If the frequency is not supported, then -EINVAL is returned.
+ * If the frequency is not supported, then %-EINVAL is returned.
*
* @s_routing: used to define the input and/or output pins of an audio chip,
* and any additional configuration data.
@@ -300,7 +298,8 @@ struct v4l2_subdev_audio_ops {
/**
* struct v4l2_mbus_frame_desc_entry - media bus frame description structure
*
- * @flags: V4L2_MBUS_FRAME_DESC_FL_* flags
+ * @flags: bitmask flags: %V4L2_MBUS_FRAME_DESC_FL_LEN_MAX and
+ * %V4L2_MBUS_FRAME_DESC_FL_BLOB.
* @pixelcode: media bus pixel code, valid if FRAME_DESC_FL_BLOB is not set
* @length: number of octets per frame, valid if V4L2_MBUS_FRAME_DESC_FL_BLOB
* is set
@@ -325,7 +324,7 @@ struct v4l2_mbus_frame_desc {
/**
* struct v4l2_subdev_video_ops - Callbacks used when v4l device was opened
- * in video mode.
+ * in video mode.
*
* @s_routing: see s_routing in audio_ops, except this version is for video
* devices.
@@ -335,9 +334,9 @@ struct v4l2_mbus_frame_desc {
* regarding clock frequency dividers, etc. If not used, then set flags
* to 0. If the frequency is not supported, then -EINVAL is returned.
*
- * @g_std: callback for VIDIOC_G_STD ioctl handler code.
+ * @g_std: callback for %VIDIOC_G_STD ioctl handler code.
*
- * @s_std: callback for VIDIOC_S_STD ioctl handler code.
+ * @s_std: callback for %VIDIOC_S_STD ioctl handler code.
*
* @s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by
* video input devices.
@@ -345,33 +344,33 @@ struct v4l2_mbus_frame_desc {
* @g_std_output: get current standard for video OUTPUT devices. This is ignored
* by video input devices.
*
- * @querystd: callback for VIDIOC_QUERYSTD ioctl handler code.
+ * @querystd: callback for %VIDIOC_QUERYSTD ioctl handler code.
*
- * @g_tvnorms: get v4l2_std_id with all standards supported by the video
+ * @g_tvnorms: get &v4l2_std_id with all standards supported by the video
* CAPTURE device. This is ignored by video output devices.
*
* @g_tvnorms_output: get v4l2_std_id with all standards supported by the video
* OUTPUT device. This is ignored by video capture devices.
*
- * @g_input_status: get input status. Same as the status field in the v4l2_input
- * struct.
+ * @g_input_status: get input status. Same as the status field in the
+ * &struct &v4l2_input
*
* @s_stream: used to notify the driver that a video stream will start or has
* stopped.
*
- * @cropcap: callback for VIDIOC_CROPCAP ioctl handler code.
+ * @cropcap: callback for %VIDIOC_CROPCAP ioctl handler code.
*
- * @g_crop: callback for VIDIOC_G_CROP ioctl handler code.
+ * @g_crop: callback for %VIDIOC_G_CROP ioctl handler code.
*
- * @s_crop: callback for VIDIOC_S_CROP ioctl handler code.
+ * @s_crop: callback for %VIDIOC_S_CROP ioctl handler code.
*
- * @g_parm: callback for VIDIOC_G_PARM ioctl handler code.
+ * @g_parm: callback for %VIDIOC_G_PARM ioctl handler code.
*
- * @s_parm: callback for VIDIOC_S_PARM ioctl handler code.
+ * @s_parm: callback for %VIDIOC_S_PARM ioctl handler code.
*
- * @g_frame_interval: callback for VIDIOC_G_FRAMEINTERVAL ioctl handler code.
+ * @g_frame_interval: callback for %VIDIOC_G_FRAMEINTERVAL ioctl handler code.
*
- * @s_frame_interval: callback for VIDIOC_S_FRAMEINTERVAL ioctl handler code.
+ * @s_frame_interval: callback for %VIDIOC_S_FRAMEINTERVAL ioctl handler code.
*
* @s_dv_timings: Set custom dv timings in the sub device. This is used
* when sub device is capable of setting detailed timing information
@@ -379,7 +378,7 @@ struct v4l2_mbus_frame_desc {
*
* @g_dv_timings: Get custom dv timings in the sub device.
*
- * @query_dv_timings: callback for VIDIOC_QUERY_DV_TIMINGS ioctl handler code.
+ * @query_dv_timings: callback for %VIDIOC_QUERY_DV_TIMINGS ioctl handler code.
*
* @g_mbus_config: get supported mediabus configurations
*
@@ -428,31 +427,31 @@ struct v4l2_subdev_video_ops {
/**
* struct v4l2_subdev_vbi_ops - Callbacks used when v4l device was opened
- * in video mode via the vbi device node.
+ * in video mode via the vbi device node.
*
* @decode_vbi_line: video decoders that support sliced VBI need to implement
- * this ioctl. Field p of the v4l2_sliced_vbi_line struct is set to the
+ * this ioctl. Field p of the &struct v4l2_sliced_vbi_line is set to the
* start of the VBI data that was generated by the decoder. The driver
* then parses the sliced VBI data and sets the other fields in the
* struct accordingly. The pointer p is updated to point to the start of
* the payload which can be copied verbatim into the data field of the
- * v4l2_sliced_vbi_data struct. If no valid VBI data was found, then the
+ * &struct v4l2_sliced_vbi_data. If no valid VBI data was found, then the
* type field is set to 0 on return.
*
* @s_vbi_data: used to generate VBI signals on a video signal.
- * v4l2_sliced_vbi_data is filled with the data packets that should be
- * output. Note that if you set the line field to 0, then that VBI signal
- * is disabled. If no valid VBI data was found, then the type field is
- * set to 0 on return.
+ * &struct v4l2_sliced_vbi_data is filled with the data packets that
+ * should be output. Note that if you set the line field to 0, then that
+ * VBI signal is disabled. If no valid VBI data was found, then the type
+ * field is set to 0 on return.
*
* @g_vbi_data: used to obtain the sliced VBI packet from a readback register.
* Not all video decoders support this. If no data is available because
- * the readback register contains invalid or erroneous data -EIO is
+ * the readback register contains invalid or erroneous data %-EIO is
* returned. Note that you must fill in the 'id' member and the 'field'
* member (to determine whether CC data from the first or second field
* should be obtained).
*
- * @g_sliced_vbi_cap: callback for VIDIOC_SLICED_VBI_CAP ioctl handler code.
+ * @g_sliced_vbi_cap: callback for %VIDIOC_SLICED_VBI_CAP ioctl handler code.
*
* @s_raw_fmt: setup the video encoder/decoder for raw VBI.
*
@@ -485,58 +484,99 @@ struct v4l2_subdev_sensor_ops {
int (*g_skip_frames)(struct v4l2_subdev *sd, u32 *frames);
};
-/*
- [rt]x_g_parameters: Get the current operating parameters and state of the
- the IR receiver or transmitter.
-
- [rt]x_s_parameters: Set the current operating parameters and state of the
- the IR receiver or transmitter. It is recommended to call
- [rt]x_g_parameters first to fill out the current state, and only change
- the fields that need to be changed. Upon return, the actual device
- operating parameters and state will be returned. Note that hardware
- limitations may prevent the actual settings from matching the requested
- settings - e.g. an actual carrier setting of 35,904 Hz when 36,000 Hz
- was requested. An exception is when the shutdown parameter is true.
- The last used operational parameters will be returned, but the actual
- state of the hardware be different to minimize power consumption and
- processing when shutdown is true.
-
- rx_read: Reads received codes or pulse width data.
- The semantics are similar to a non-blocking read() call.
-
- tx_write: Writes codes or pulse width data for transmission.
- The semantics are similar to a non-blocking write() call.
+/**
+ * enum v4l2_subdev_ir_mode- describes the type of IR supported
+ *
+ * @V4L2_SUBDEV_IR_MODE_PULSE_WIDTH: IR uses struct ir_raw_event records
*/
-
enum v4l2_subdev_ir_mode {
- V4L2_SUBDEV_IR_MODE_PULSE_WIDTH, /* uses struct ir_raw_event records */
+ V4L2_SUBDEV_IR_MODE_PULSE_WIDTH,
};
+/**
+ * struct v4l2_subdev_ir_parameters - Parameters for IR TX or TX
+ *
+ * @bytes_per_data_element: bytes per data element of data in read or
+ * write call.
+ * @mode: IR mode as defined by &enum v4l2_subdev_ir_mode.
+ * @enable: device is active if true
+ * @interrupt_enable: IR interrupts are enabled if true
+ * @shutdown: if true: set hardware to low/no power, false: normal mode
+ *
+ * @modulation: if true, it uses carrier, if false: baseband
+ * @max_pulse_width: maximum pulse width in ns, valid only for baseband signal
+ * @carrier_freq: carrier frequency in Hz, valid only for modulated signal
+ * @duty_cycle: duty cycle percentage, valid only for modulated signal
+ * @invert_level: invert signal level
+ *
+ * @invert_carrier_sense: Send 0/space as a carrier burst. used only in TX.
+ *
+ * @noise_filter_min_width: min time of a valid pulse, in ns. Used only for RX.
+ * @carrier_range_lower: Lower carrier range, in Hz, valid only for modulated
+ * signal. Used only for RX.
+ * @carrier_range_upper: Upper carrier range, in Hz, valid only for modulated
+ * signal. Used only for RX.
+ * @resolution: The receive resolution, in ns . Used only for RX.
+ */
struct v4l2_subdev_ir_parameters {
- /* Either Rx or Tx */
- unsigned int bytes_per_data_element; /* of data in read or write call */
+ unsigned int bytes_per_data_element;
enum v4l2_subdev_ir_mode mode;
bool enable;
bool interrupt_enable;
- bool shutdown; /* true: set hardware to low/no power, false: normal */
+ bool shutdown;
- bool modulation; /* true: uses carrier, false: baseband */
- u32 max_pulse_width; /* ns, valid only for baseband signal */
- unsigned int carrier_freq; /* Hz, valid only for modulated signal*/
- unsigned int duty_cycle; /* percent, valid only for modulated signal*/
- bool invert_level; /* invert signal level */
+ bool modulation;
+ u32 max_pulse_width;
+ unsigned int carrier_freq;
+ unsigned int duty_cycle;
+ bool invert_level;
/* Tx only */
- bool invert_carrier_sense; /* Send 0/space as a carrier burst */
+ bool invert_carrier_sense;
/* Rx only */
- u32 noise_filter_min_width; /* ns, min time of a valid pulse */
- unsigned int carrier_range_lower; /* Hz, valid only for modulated sig */
- unsigned int carrier_range_upper; /* Hz, valid only for modulated sig */
- u32 resolution; /* ns */
+ u32 noise_filter_min_width;
+ unsigned int carrier_range_lower;
+ unsigned int carrier_range_upper;
+ u32 resolution;
};
+/**
+ * struct v4l2_subdev_ir_ops - operations for IR subdevices
+ *
+ * @rx_read: Reads received codes or pulse width data.
+ * The semantics are similar to a non-blocking read() call.
+ * @rx_g_parameters: Get the current operating parameters and state of the
+ * the IR receiver.
+ * @rx_s_parameters: Set the current operating parameters and state of the
+ * the IR receiver. It is recommended to call
+ * [rt]x_g_parameters first to fill out the current state, and only change
+ * the fields that need to be changed. Upon return, the actual device
+ * operating parameters and state will be returned. Note that hardware
+ * limitations may prevent the actual settings from matching the requested
+ * settings - e.g. an actual carrier setting of 35,904 Hz when 36,000 Hz
+ * was requested. An exception is when the shutdown parameter is true.
+ * The last used operational parameters will be returned, but the actual
+ * state of the hardware be different to minimize power consumption and
+ * processing when shutdown is true.
+ *
+ * @tx_write: Writes codes or pulse width data for transmission.
+ * The semantics are similar to a non-blocking write() call.
+ * @tx_g_parameters: Get the current operating parameters and state of the
+ * the IR transmitter.
+ * @tx_s_parameters: Set the current operating parameters and state of the
+ * the IR transmitter. It is recommended to call
+ * [rt]x_g_parameters first to fill out the current state, and only change
+ * the fields that need to be changed. Upon return, the actual device
+ * operating parameters and state will be returned. Note that hardware
+ * limitations may prevent the actual settings from matching the requested
+ * settings - e.g. an actual carrier setting of 35,904 Hz when 36,000 Hz
+ * was requested. An exception is when the shutdown parameter is true.
+ * The last used operational parameters will be returned, but the actual
+ * state of the hardware be different to minimize power consumption and
+ * processing when shutdown is true.
+ */
struct v4l2_subdev_ir_ops {
/* Receiver */
int (*rx_read)(struct v4l2_subdev *sd, u8 *buf, size_t count,
@@ -557,11 +597,16 @@ struct v4l2_subdev_ir_ops {
struct v4l2_subdev_ir_parameters *params);
};
-/*
- * Used for storing subdev pad information. This structure only needs
- * to be passed to the pad op if the 'which' field of the main argument
- * is set to V4L2_SUBDEV_FORMAT_TRY. For V4L2_SUBDEV_FORMAT_ACTIVE it is
- * safe to pass NULL.
+/**
+ * struct v4l2_subdev_pad_config - Used for storing subdev pad information.
+ *
+ * @try_fmt: pointer to &struct v4l2_mbus_framefmt
+ * @try_crop: pointer to &struct v4l2_rect to be used for crop
+ * @try_compose: pointer to &struct v4l2_rect to be used for compose
+ *
+ * This structure only needs to be passed to the pad op if the 'which' field
+ * of the main argument is set to %V4L2_SUBDEV_FORMAT_TRY. For
+ * %V4L2_SUBDEV_FORMAT_ACTIVE it is safe to pass %NULL.
*/
struct v4l2_subdev_pad_config {
struct v4l2_mbus_framefmt try_fmt;
@@ -573,30 +618,30 @@ struct v4l2_subdev_pad_config {
* struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations
*
* @init_cfg: initialize the pad config to default values
- * @enum_mbus_code: callback for VIDIOC_SUBDEV_ENUM_MBUS_CODE ioctl handler
+ * @enum_mbus_code: callback for %VIDIOC_SUBDEV_ENUM_MBUS_CODE ioctl handler
* code.
- * @enum_frame_size: callback for VIDIOC_SUBDEV_ENUM_FRAME_SIZE ioctl handler
+ * @enum_frame_size: callback for %VIDIOC_SUBDEV_ENUM_FRAME_SIZE ioctl handler
* code.
*
- * @enum_frame_interval: callback for VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL ioctl
+ * @enum_frame_interval: callback for %VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL ioctl
* handler code.
*
- * @get_fmt: callback for VIDIOC_SUBDEV_G_FMT ioctl handler code.
+ * @get_fmt: callback for %VIDIOC_SUBDEV_G_FMT ioctl handler code.
*
- * @set_fmt: callback for VIDIOC_SUBDEV_S_FMT ioctl handler code.
+ * @set_fmt: callback for %VIDIOC_SUBDEV_S_FMT ioctl handler code.
*
- * @get_selection: callback for VIDIOC_SUBDEV_G_SELECTION ioctl handler code.
+ * @get_selection: callback for %VIDIOC_SUBDEV_G_SELECTION ioctl handler code.
*
- * @set_selection: callback for VIDIOC_SUBDEV_S_SELECTION ioctl handler code.
+ * @set_selection: callback for %VIDIOC_SUBDEV_S_SELECTION ioctl handler code.
*
- * @get_edid: callback for VIDIOC_SUBDEV_G_EDID ioctl handler code.
+ * @get_edid: callback for %VIDIOC_SUBDEV_G_EDID ioctl handler code.
*
- * @set_edid: callback for VIDIOC_SUBDEV_S_EDID ioctl handler code.
+ * @set_edid: callback for %VIDIOC_SUBDEV_S_EDID ioctl handler code.
*
- * @dv_timings_cap: callback for VIDIOC_SUBDEV_DV_TIMINGS_CAP ioctl handler
+ * @dv_timings_cap: callback for %VIDIOC_SUBDEV_DV_TIMINGS_CAP ioctl handler
* code.
*
- * @enum_dv_timings: callback for VIDIOC_SUBDEV_ENUM_DV_TIMINGS ioctl handler
+ * @enum_dv_timings: callback for %VIDIOC_SUBDEV_ENUM_DV_TIMINGS ioctl handler
* code.
*
* @link_validate: used by the media controller code to check if the links
@@ -648,6 +693,18 @@ struct v4l2_subdev_pad_ops {
struct v4l2_mbus_frame_desc *fd);
};
+/**
+ * struct v4l2_subdev_ops - Subdev operations
+ *
+ * @core: pointer to &struct v4l2_subdev_core_ops. Can be %NULL
+ * @tuner: pointer to &struct v4l2_subdev_tuner_ops. Can be %NULL
+ * @audio: pointer to &struct v4l2_subdev_audio_ops. Can be %NULL
+ * @video: pointer to &struct v4l2_subdev_video_ops. Can be %NULL
+ * @vbi: pointer to &struct v4l2_subdev_vbi_ops. Can be %NULL
+ * @ir: pointer to &struct v4l2_subdev_ir_ops. Can be %NULL
+ * @sensor: pointer to &struct v4l2_subdev_sensor_ops. Can be %NULL
+ * @pad: pointer to &struct v4l2_subdev_pad_ops. Can be %NULL
+ */
struct v4l2_subdev_ops {
const struct v4l2_subdev_core_ops *core;
const struct v4l2_subdev_tuner_ops *tuner;
@@ -659,19 +716,22 @@ struct v4l2_subdev_ops {
const struct v4l2_subdev_pad_ops *pad;
};
-/*
- * Internal ops. Never call this from drivers, only the v4l2 framework can call
- * these ops.
+/**
+ * struct v4l2_subdev_internal_ops - V4L2 subdev internal ops
*
- * registered: called when this subdev is registered. When called the v4l2_dev
+ * @registered: called when this subdev is registered. When called the v4l2_dev
* field is set to the correct v4l2_device.
*
- * unregistered: called when this subdev is unregistered. When called the
+ * @unregistered: called when this subdev is unregistered. When called the
* v4l2_dev field is still set to the correct v4l2_device.
*
- * open: called when the subdev device node is opened by an application.
+ * @open: called when the subdev device node is opened by an application.
+ *
+ * @close: called when the subdev device node is closed.
*
- * close: called when the subdev device node is closed.
+ * .. note::
+ * Never call this from drivers, only the v4l2 framework can call
+ * these ops.
*/
struct v4l2_subdev_internal_ops {
int (*registered)(struct v4l2_subdev *sd);
@@ -693,17 +753,60 @@ struct v4l2_subdev_internal_ops {
struct regulator_bulk_data;
+/**
+ * struct v4l2_subdev_platform_data - regulators config struct
+ *
+ * @regulators: Optional regulators used to power on/off the subdevice
+ * @num_regulators: Number of regululators
+ * @host_priv: Per-subdevice data, specific for a certain video host device
+ */
struct v4l2_subdev_platform_data {
- /* Optional regulators uset to power on/off the subdevice */
struct regulator_bulk_data *regulators;
int num_regulators;
- /* Per-subdevice data, specific for a certain video host device */
void *host_priv;
};
-/* Each instance of a subdev driver should create this struct, either
- stand-alone or embedded in a larger struct.
+/**
+ * struct v4l2_subdev - describes a V4L2 sub-device
+ *
+ * @entity: pointer to &struct media_entity
+ * @list: List of sub-devices
+ * @owner: The owner is the same as the driver's &struct device owner.
+ * @owner_v4l2_dev: true if the &sd->owner matches the owner of &v4l2_dev->dev
+ * ownner. Initialized by v4l2_device_register_subdev().
+ * @flags: subdev flags. Can be:
+ * %V4L2_SUBDEV_FL_IS_I2C - Set this flag if this subdev is a i2c device;
+ * %V4L2_SUBDEV_FL_IS_SPI - Set this flag if this subdev is a spi device;
+ * %V4L2_SUBDEV_FL_HAS_DEVNODE - Set this flag if this subdev needs a
+ * device node;
+ * %V4L2_SUBDEV_FL_HAS_EVENTS - Set this flag if this subdev generates
+ * events.
+ *
+ * @v4l2_dev: pointer to &struct v4l2_device
+ * @ops: pointer to &struct v4l2_subdev_ops
+ * @internal_ops: pointer to &struct v4l2_subdev_internal_ops.
+ * Never call these internal ops from within a driver!
+ * @ctrl_handler: The control handler of this subdev. May be NULL.
+ * @name: Name of the sub-device. Please notice that the name must be unique.
+ * @grp_id: can be used to group similar subdevs. Value is driver-specific
+ * @dev_priv: pointer to private data
+ * @host_priv: pointer to private data used by the device where the subdev
+ * is attached.
+ * @devnode: subdev device node
+ * @dev: pointer to the physical device, if any
+ * @of_node: The device_node of the subdev, usually the same as dev->of_node.
+ * @async_list: Links this subdev to a global subdev_list or @notifier->done
+ * list.
+ * @asd: Pointer to respective &struct v4l2_async_subdev.
+ * @notifier: Pointer to the managing notifier.
+ * @pdata: common part of subdevice platform data
+ *
+ * Each instance of a subdev driver should create this struct, either
+ * stand-alone or embedded in a larger struct.
+ *
+ * This structure should be initialized by v4l2_subdev_init() or one of
+ * its variants: v4l2_spi_subdev_init(), v4l2_i2c_subdev_init().
*/
struct v4l2_subdev {
#if defined(CONFIG_MEDIA_CONTROLLER)
@@ -715,30 +818,18 @@ struct v4l2_subdev {
u32 flags;
struct v4l2_device *v4l2_dev;
const struct v4l2_subdev_ops *ops;
- /* Never call these internal ops from within a driver! */
const struct v4l2_subdev_internal_ops *internal_ops;
- /* The control handler of this subdev. May be NULL. */
struct v4l2_ctrl_handler *ctrl_handler;
- /* name must be unique */
char name[V4L2_SUBDEV_NAME_SIZE];
- /* can be used to group similar subdevs, value is driver-specific */
u32 grp_id;
- /* pointer to private data */
void *dev_priv;
void *host_priv;
- /* subdev device node */
struct video_device *devnode;
- /* pointer to the physical device, if any */
struct device *dev;
- /* The device_node of the subdev, usually the same as dev->of_node. */
struct device_node *of_node;
- /* Links this subdev to a global subdev_list or @notifier->done list. */
struct list_head async_list;
- /* Pointer to respective struct v4l2_async_subdev. */
struct v4l2_async_subdev *asd;
- /* Pointer to the managing notifier. */
struct v4l2_async_notifier *notifier;
- /* common part of subdevice platform data */
struct v4l2_subdev_platform_data *pdata;
};
@@ -747,8 +838,11 @@ struct v4l2_subdev {
#define vdev_to_v4l2_subdev(vdev) \
((struct v4l2_subdev *)video_get_drvdata(vdev))
-/*
- * Used for storing subdev information per file handle
+/**
+ * struct v4l2_subdev_fh - Used for storing subdev information per file handle
+ *
+ * @vfh: pointer to struct v4l2_fh
+ * @pad: pointer to v4l2_subdev_pad_config
*/
struct v4l2_subdev_fh {
struct v4l2_fh vfh;
@@ -778,53 +872,132 @@ __V4L2_SUBDEV_MK_GET_TRY(v4l2_rect, v4l2_subdev_get_try_compose, try_compose)
extern const struct v4l2_file_operations v4l2_subdev_fops;
+/**
+ * v4l2_set_subdevdata - Sets V4L2 dev private device data
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @p: pointer to the private device data to be stored.
+ */
static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p)
{
sd->dev_priv = p;
}
+/**
+ * v4l2_get_subdevdata - Gets V4L2 dev private device data
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ *
+ * Returns the pointer to the private device data to be stored.
+ */
static inline void *v4l2_get_subdevdata(const struct v4l2_subdev *sd)
{
return sd->dev_priv;
}
+/**
+ * v4l2_set_subdevdata - Sets V4L2 dev private host data
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @p: pointer to the private data to be stored.
+ */
static inline void v4l2_set_subdev_hostdata(struct v4l2_subdev *sd, void *p)
{
sd->host_priv = p;
}
+/**
+ * v4l2_get_subdevdata - Gets V4L2 dev private data
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ *
+ * Returns the pointer to the private host data to be stored.
+ */
static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd)
{
return sd->host_priv;
}
#ifdef CONFIG_MEDIA_CONTROLLER
+
+/**
+ * v4l2_subdev_link_validate_default - validates a media link
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ * @link: pointer to &struct media_link
+ * @source_fmt: pointer to &struct v4l2_subdev_format
+ * @sink_fmt: pointer to &struct v4l2_subdev_format
+ *
+ * This function ensures that width, height and the media bus pixel
+ * code are equal on both source and sink of the link.
+ */
int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
struct media_link *link,
struct v4l2_subdev_format *source_fmt,
struct v4l2_subdev_format *sink_fmt);
+
+/**
+ * v4l2_subdev_link_validate - validates a media link
+ *
+ * @link: pointer to &struct media_link
+ *
+ * This function calls the subdev's link_validate ops to validate
+ * if a media link is valid for streaming. It also internally
+ * calls v4l2_subdev_link_validate_default() to ensure that
+ * width, height and the media bus pixel code are equal on both
+ * source and sink of the link.
+ */
int v4l2_subdev_link_validate(struct media_link *link);
-struct v4l2_subdev_pad_config *
-v4l2_subdev_alloc_pad_config(struct v4l2_subdev *sd);
+/**
+ * v4l2_subdev_alloc_pad_config - Allocates memory for pad config
+ *
+ * @sd: pointer to struct v4l2_subdev
+ */
+struct
+v4l2_subdev_pad_config *v4l2_subdev_alloc_pad_config(struct v4l2_subdev *sd);
+
+/**
+ * v4l2_subdev_free_pad_config - Frees memory allocated by
+ * v4l2_subdev_alloc_pad_config().
+ *
+ * @cfg: pointer to &struct v4l2_subdev_pad_config
+ */
void v4l2_subdev_free_pad_config(struct v4l2_subdev_pad_config *cfg);
#endif /* CONFIG_MEDIA_CONTROLLER */
+/**
+ * v4l2_subdev_init - initializes the sub-device struct
+ *
+ * @sd: pointer to the &struct v4l2_subdev to be initialized
+ * @ops: pointer to &struct v4l2_subdev_ops.
+ */
void v4l2_subdev_init(struct v4l2_subdev *sd,
const struct v4l2_subdev_ops *ops);
-/* Call an ops of a v4l2_subdev, doing the right checks against
- NULL pointers.
-
- Example: err = v4l2_subdev_call(sd, video, s_std, norm);
+/*
+ * Call an ops of a v4l2_subdev, doing the right checks against
+ * NULL pointers.
+ *
+ * Example: err = v4l2_subdev_call(sd, video, s_std, norm);
*/
#define v4l2_subdev_call(sd, o, f, args...) \
(!(sd) ? -ENODEV : (((sd)->ops->o && (sd)->ops->o->f) ? \
- (sd)->ops->o->f((sd) , ##args) : -ENOIOCTLCMD))
+ (sd)->ops->o->f((sd), ##args) : -ENOIOCTLCMD))
#define v4l2_subdev_has_op(sd, o, f) \
((sd)->ops->o && (sd)->ops->o->f)
+/**
+ * v4l2_subdev_notify_event() - Delivers event notification for subdevice
+ * @sd: The subdev for which to deliver the event
+ * @ev: The event to deliver
+ *
+ * Will deliver the specified event to all userspace event listeners which are
+ * subscribed to the v42l subdev event queue as well as to the bridge driver
+ * using the notify callback. The notification type for the notify callback
+ * will be %V4L2_DEVICE_NOTIFY_EVENT.
+ */
void v4l2_subdev_notify_event(struct v4l2_subdev *sd,
const struct v4l2_event *ev);
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 88e3ab496e8f..946340ce7701 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -27,7 +27,6 @@ enum vb2_memory {
VB2_MEMORY_DMABUF = 4,
};
-struct vb2_alloc_ctx;
struct vb2_fileio_data;
struct vb2_threadio_data;
@@ -57,7 +56,7 @@ struct vb2_threadio_data;
* @put_userptr: inform the allocator that a USERPTR buffer will no longer
* be used.
* @attach_dmabuf: attach a shared struct dma_buf for a hardware operation;
- * used for DMABUF memory types; alloc_ctx is the alloc context
+ * used for DMABUF memory types; dev is the alloc device
* dbuf is the shared dma_buf; returns NULL on failure;
* allocator private per-buffer structure on success;
* this needs to be used for further accesses to the buffer.
@@ -86,20 +85,26 @@ struct vb2_threadio_data;
* @mmap: setup a userspace mapping for a given memory buffer under
* the provided virtual memory region.
*
- * Required ops for USERPTR types: get_userptr, put_userptr.
- * Required ops for MMAP types: alloc, put, num_users, mmap.
- * Required ops for read/write access types: alloc, put, num_users, vaddr.
- * Required ops for DMABUF types: attach_dmabuf, detach_dmabuf, map_dmabuf,
- * unmap_dmabuf.
+ * Those operations are used by the videobuf2 core to implement the memory
+ * handling/memory allocators for each type of supported streaming I/O method.
+ *
+ * .. note::
+ * #) Required ops for USERPTR types: get_userptr, put_userptr.
+ *
+ * #) Required ops for MMAP types: alloc, put, num_users, mmap.
+ *
+ * #) Required ops for read/write access types: alloc, put, num_users, vaddr.
+ *
+ * #) Required ops for DMABUF types: attach_dmabuf, detach_dmabuf, map_dmabuf, unmap_dmabuf.
*/
struct vb2_mem_ops {
- void *(*alloc)(void *alloc_ctx, unsigned long size,
- enum dma_data_direction dma_dir,
+ void *(*alloc)(struct device *dev, const struct dma_attrs *attrs,
+ unsigned long size, enum dma_data_direction dma_dir,
gfp_t gfp_flags);
void (*put)(void *buf_priv);
struct dma_buf *(*get_dmabuf)(void *buf_priv, unsigned long flags);
- void *(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
+ void *(*get_userptr)(struct device *dev, unsigned long vaddr,
unsigned long size,
enum dma_data_direction dma_dir);
void (*put_userptr)(void *buf_priv);
@@ -107,7 +112,7 @@ struct vb2_mem_ops {
void (*prepare)(void *buf_priv);
void (*finish)(void *buf_priv);
- void *(*attach_dmabuf)(void *alloc_ctx, struct dma_buf *dbuf,
+ void *(*attach_dmabuf)(struct device *dev, struct dma_buf *dbuf,
unsigned long size,
enum dma_data_direction dma_dir);
void (*detach_dmabuf)(void *buf_priv);
@@ -272,26 +277,26 @@ struct vb2_buffer {
/**
* struct vb2_ops - driver-specific callbacks
*
- * @queue_setup: called from VIDIOC_REQBUFS and VIDIOC_CREATE_BUFS
+ * @queue_setup: called from %VIDIOC_REQBUFS and %VIDIOC_CREATE_BUFS
* handlers before memory allocation. It can be called
* twice: if the original number of requested buffers
* could not be allocated, then it will be called a
* second time with the actually allocated number of
* buffers to verify if that is OK.
* The driver should return the required number of buffers
- * in *num_buffers, the required number of planes per
- * buffer in *num_planes, the size of each plane should be
- * set in the sizes[] array and optional per-plane
- * allocator specific context in the alloc_ctxs[] array.
- * When called from VIDIOC_REQBUFS, *num_planes == 0, the
+ * in \*num_buffers, the required number of planes per
+ * buffer in \*num_planes, the size of each plane should be
+ * set in the sizes\[\] array and optional per-plane
+ * allocator specific device in the alloc_devs\[\] array.
+ * When called from %VIDIOC_REQBUFS, \*num_planes == 0, the
* driver has to use the currently configured format to
- * determine the plane sizes and *num_buffers is the total
+ * determine the plane sizes and \*num_buffers is the total
* number of buffers that are being allocated. When called
- * from VIDIOC_CREATE_BUFS, *num_planes != 0 and it
- * describes the requested number of planes and sizes[]
+ * from %VIDIOC_CREATE_BUFS, \*num_planes != 0 and it
+ * describes the requested number of planes and sizes\[\]
* contains the requested plane sizes. If either
- * *num_planes or the requested sizes are invalid callback
- * must return -EINVAL. In this case *num_buffers are
+ * \*num_planes or the requested sizes are invalid callback
+ * must return %-EINVAL. In this case \*num_buffers are
* being allocated additionally to q->num_buffers.
* @wait_prepare: release any locks taken while calling vb2 functions;
* it is called before an ioctl needs to wait for a new
@@ -306,11 +311,11 @@ struct vb2_buffer {
* initialization failure (return != 0) will prevent
* queue setup from completing successfully; optional.
* @buf_prepare: called every time the buffer is queued from userspace
- * and from the VIDIOC_PREPARE_BUF ioctl; drivers may
+ * and from the %VIDIOC_PREPARE_BUF ioctl; drivers may
* perform any initialization required before each
* hardware operation in this callback; drivers can
* access/modify the buffer here as it is still synced for
- * the CPU; drivers that support VIDIOC_CREATE_BUFS must
+ * the CPU; drivers that support %VIDIOC_CREATE_BUFS must
* also validate the buffer size; if an error is returned,
* the buffer will not be queued in driver; optional.
* @buf_finish: called before every dequeue of the buffer back to
@@ -318,23 +323,23 @@ struct vb2_buffer {
* can access/modify the buffer contents; drivers may
* perform any operations required before userspace
* accesses the buffer; optional. The buffer state can be
- * one of the following: DONE and ERROR occur while
- * streaming is in progress, and the PREPARED state occurs
+ * one of the following: %DONE and %ERROR occur while
+ * streaming is in progress, and the %PREPARED state occurs
* when the queue has been canceled and all pending
- * buffers are being returned to their default DEQUEUED
+ * buffers are being returned to their default %DEQUEUED
* state. Typically you only have to do something if the
- * state is VB2_BUF_STATE_DONE, since in all other cases
+ * state is %VB2_BUF_STATE_DONE, since in all other cases
* the buffer contents will be ignored anyway.
* @buf_cleanup: called once before the buffer is freed; drivers may
* perform any additional cleanup; optional.
* @start_streaming: called once to enter 'streaming' state; the driver may
- * receive buffers with @buf_queue callback before
- * @start_streaming is called; the driver gets the number
- * of already queued buffers in count parameter; driver
- * can return an error if hardware fails, in that case all
- * buffers that have been already given by the @buf_queue
- * callback are to be returned by the driver by calling
- * @vb2_buffer_done(VB2_BUF_STATE_QUEUED).
+ * receive buffers with @buf_queue callback
+ * before @start_streaming is called; the driver gets the
+ * number of already queued buffers in count parameter;
+ * driver can return an error if hardware fails, in that
+ * case all buffers that have been already given by
+ * the @buf_queue callback are to be returned by the driver
+ * by calling @vb2_buffer_done\(%VB2_BUF_STATE_QUEUED\).
* If you need a minimum number of buffers before you can
* start streaming, then set @min_buffers_needed in the
* vb2_queue structure. If that is non-zero then
@@ -342,21 +347,21 @@ struct vb2_buffer {
* many buffers have been queued up by userspace.
* @stop_streaming: called when 'streaming' state must be disabled; driver
* should stop any DMA transactions or wait until they
- * finish and give back all buffers it got from buf_queue()
- * callback by calling @vb2_buffer_done() with either
- * VB2_BUF_STATE_DONE or VB2_BUF_STATE_ERROR; may use
+ * finish and give back all buffers it got from &buf_queue
+ * callback by calling @vb2_buffer_done\(\) with either
+ * %VB2_BUF_STATE_DONE or %VB2_BUF_STATE_ERROR; may use
* vb2_wait_for_all_buffers() function
* @buf_queue: passes buffer vb to the driver; driver may start
* hardware operation on this buffer; driver should give
* the buffer back by calling vb2_buffer_done() function;
- * it is allways called after calling STREAMON ioctl;
+ * it is allways called after calling %VIDIOC_STREAMON ioctl;
* might be called before start_streaming callback if user
- * pre-queued buffers before calling STREAMON.
+ * pre-queued buffers before calling %VIDIOC_STREAMON.
*/
struct vb2_ops {
int (*queue_setup)(struct vb2_queue *q,
unsigned int *num_buffers, unsigned int *num_planes,
- unsigned int sizes[], void *alloc_ctxs[]);
+ unsigned int sizes[], struct device *alloc_devs[]);
void (*wait_prepare)(struct vb2_queue *q);
void (*wait_finish)(struct vb2_queue *q);
@@ -401,6 +406,9 @@ struct vb2_buf_ops {
* caller. For example, for V4L2, it should match
* the V4L2_BUF_TYPE_* in include/uapi/linux/videodev2.h
* @io_modes: supported io methods (see vb2_io_modes enum)
+ * @dev: device to use for the default allocation context if the driver
+ * doesn't fill in the @alloc_devs array.
+ * @dma_attrs: DMA attributes to use for the DMA. May be NULL.
* @fileio_read_once: report EOF after reading the first buffer
* @fileio_write_immediately: queue buffer after each write() call
* @allow_zero_bytesused: allow bytesused == 0 to be passed to the driver
@@ -447,7 +455,7 @@ struct vb2_buf_ops {
* @done_list: list of buffers ready to be dequeued to userspace
* @done_lock: lock to protect done_list list
* @done_wq: waitqueue for processes waiting for buffers ready to be dequeued
- * @alloc_ctx: memory type/allocator-specific contexts for each plane
+ * @alloc_devs: memory type/allocator-specific per-plane device
* @streaming: current streaming state
* @start_streaming_called: start_streaming() was called successfully and we
* started streaming.
@@ -467,6 +475,8 @@ struct vb2_buf_ops {
struct vb2_queue {
unsigned int type;
unsigned int io_modes;
+ struct device *dev;
+ const struct dma_attrs *dma_attrs;
unsigned fileio_read_once:1;
unsigned fileio_write_immediately:1;
unsigned allow_zero_bytesused:1;
@@ -499,7 +509,7 @@ struct vb2_queue {
spinlock_t done_lock;
wait_queue_head_t done_wq;
- void *alloc_ctx[VB2_MAX_PLANES];
+ struct device *alloc_devs[VB2_MAX_PLANES];
unsigned int streaming:1;
unsigned int start_streaming_called:1;
diff --git a/include/media/videobuf2-dma-contig.h b/include/media/videobuf2-dma-contig.h
index 2087c9a68be3..df2aabee3401 100644
--- a/include/media/videobuf2-dma-contig.h
+++ b/include/media/videobuf2-dma-contig.h
@@ -26,15 +26,8 @@ vb2_dma_contig_plane_dma_addr(struct vb2_buffer *vb, unsigned int plane_no)
return *addr;
}
-void *vb2_dma_contig_init_ctx_attrs(struct device *dev,
- struct dma_attrs *attrs);
-
-static inline void *vb2_dma_contig_init_ctx(struct device *dev)
-{
- return vb2_dma_contig_init_ctx_attrs(dev, NULL);
-}
-
-void vb2_dma_contig_cleanup_ctx(void *alloc_ctx);
+int vb2_dma_contig_set_max_seg_size(struct device *dev, unsigned int size);
+void vb2_dma_contig_clear_max_seg_size(struct device *dev);
extern const struct vb2_mem_ops vb2_dma_contig_memops;
diff --git a/include/media/videobuf2-dma-sg.h b/include/media/videobuf2-dma-sg.h
index 8d1083f83c3d..52afa0e2bb17 100644
--- a/include/media/videobuf2-dma-sg.h
+++ b/include/media/videobuf2-dma-sg.h
@@ -21,9 +21,6 @@ static inline struct sg_table *vb2_dma_sg_plane_desc(
return (struct sg_table *)vb2_plane_cookie(vb, plane_no);
}
-void *vb2_dma_sg_init_ctx(struct device *dev);
-void vb2_dma_sg_cleanup_ctx(void *alloc_ctx);
-
extern const struct vb2_mem_ops vb2_dma_sg_memops;
#endif
diff --git a/include/media/vsp1.h b/include/media/vsp1.h
index 3e654a0455bd..9322d9775fb7 100644
--- a/include/media/vsp1.h
+++ b/include/media/vsp1.h
@@ -14,31 +14,28 @@
#define __MEDIA_VSP1_H__
#include <linux/types.h>
+#include <linux/videodev2.h>
struct device;
-struct v4l2_rect;
int vsp1_du_init(struct device *dev);
int vsp1_du_setup_lif(struct device *dev, unsigned int width,
unsigned int height);
+struct vsp1_du_atomic_config {
+ u32 pixelformat;
+ unsigned int pitch;
+ dma_addr_t mem[2];
+ struct v4l2_rect src;
+ struct v4l2_rect dst;
+ unsigned int alpha;
+ unsigned int zpos;
+};
+
void vsp1_du_atomic_begin(struct device *dev);
-int vsp1_du_atomic_update_ext(struct device *dev, unsigned int rpf,
- u32 pixelformat, unsigned int pitch,
- dma_addr_t mem[2], const struct v4l2_rect *src,
- const struct v4l2_rect *dst, unsigned int alpha,
- unsigned int zpos);
+int vsp1_du_atomic_update(struct device *dev, unsigned int rpf,
+ const struct vsp1_du_atomic_config *cfg);
void vsp1_du_atomic_flush(struct device *dev);
-static inline int vsp1_du_atomic_update(struct device *dev,
- unsigned int rpf_index, u32 pixelformat,
- unsigned int pitch, dma_addr_t mem[2],
- const struct v4l2_rect *src,
- const struct v4l2_rect *dst)
-{
- return vsp1_du_atomic_update_ext(dev, rpf_index, pixelformat, pitch,
- mem, src, dst, 255, 0);
-}
-
#endif /* __MEDIA_VSP1_H__ */
diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index da84cf920b78..5ab4c9901ccc 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -141,6 +141,16 @@ struct lowpan_dev {
u8 priv[0] __aligned(sizeof(void *));
};
+struct lowpan_802154_neigh {
+ __le16 short_addr;
+};
+
+static inline
+struct lowpan_802154_neigh *lowpan_802154_neigh(void *neigh_priv)
+{
+ return neigh_priv;
+}
+
static inline
struct lowpan_dev *lowpan_dev(const struct net_device *dev)
{
@@ -244,6 +254,12 @@ static inline bool lowpan_fetch_skb(struct sk_buff *skb, void *data,
return false;
}
+static inline bool lowpan_802154_is_valid_src_short_addr(__le16 addr)
+{
+ /* First bit of addr is multicast, reserved or 802.15.4 specific */
+ return !(addr & cpu_to_le16(0x8000));
+}
+
static inline void lowpan_push_hc_data(u8 **hc_ptr, const void *data,
const size_t len)
{
diff --git a/include/net/act_api.h b/include/net/act_api.h
index 9a9a8edc138f..41e6a24a44b9 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -2,42 +2,14 @@
#define __NET_ACT_API_H
/*
- * Public police action API for classifiers/qdiscs
- */
+ * Public action API for classifiers/qdiscs
+*/
#include <net/sch_generic.h>
#include <net/pkt_sched.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
-struct tcf_common {
- struct hlist_node tcfc_head;
- u32 tcfc_index;
- int tcfc_refcnt;
- int tcfc_bindcnt;
- u32 tcfc_capab;
- int tcfc_action;
- struct tcf_t tcfc_tm;
- struct gnet_stats_basic_packed tcfc_bstats;
- struct gnet_stats_queue tcfc_qstats;
- struct gnet_stats_rate_est64 tcfc_rate_est;
- spinlock_t tcfc_lock;
- struct rcu_head tcfc_rcu;
- struct gnet_stats_basic_cpu __percpu *cpu_bstats;
- struct gnet_stats_queue __percpu *cpu_qstats;
-};
-#define tcf_head common.tcfc_head
-#define tcf_index common.tcfc_index
-#define tcf_refcnt common.tcfc_refcnt
-#define tcf_bindcnt common.tcfc_bindcnt
-#define tcf_capab common.tcfc_capab
-#define tcf_action common.tcfc_action
-#define tcf_tm common.tcfc_tm
-#define tcf_bstats common.tcfc_bstats
-#define tcf_qstats common.tcfc_qstats
-#define tcf_rate_est common.tcfc_rate_est
-#define tcf_lock common.tcfc_lock
-#define tcf_rcu common.tcfc_rcu
struct tcf_hashinfo {
struct hlist_head *htab;
@@ -46,6 +18,44 @@ struct tcf_hashinfo {
u32 index;
};
+struct tc_action_ops;
+
+struct tc_action {
+ const struct tc_action_ops *ops;
+ __u32 type; /* for backward compat(TCA_OLD_COMPAT) */
+ __u32 order;
+ struct list_head list;
+ struct tcf_hashinfo *hinfo;
+
+ struct hlist_node tcfa_head;
+ u32 tcfa_index;
+ int tcfa_refcnt;
+ int tcfa_bindcnt;
+ u32 tcfa_capab;
+ int tcfa_action;
+ struct tcf_t tcfa_tm;
+ struct gnet_stats_basic_packed tcfa_bstats;
+ struct gnet_stats_queue tcfa_qstats;
+ struct gnet_stats_rate_est64 tcfa_rate_est;
+ spinlock_t tcfa_lock;
+ struct rcu_head tcfa_rcu;
+ struct gnet_stats_basic_cpu __percpu *cpu_bstats;
+ struct gnet_stats_queue __percpu *cpu_qstats;
+};
+#define tcf_act common.tcfa_act
+#define tcf_head common.tcfa_head
+#define tcf_index common.tcfa_index
+#define tcf_refcnt common.tcfa_refcnt
+#define tcf_bindcnt common.tcfa_bindcnt
+#define tcf_capab common.tcfa_capab
+#define tcf_action common.tcfa_action
+#define tcf_tm common.tcfa_tm
+#define tcf_bstats common.tcfa_bstats
+#define tcf_qstats common.tcfa_qstats
+#define tcf_rate_est common.tcfa_rate_est
+#define tcf_lock common.tcfa_lock
+#define tcf_rcu common.tcfa_rcu
+
static inline unsigned int tcf_hash(u32 index, unsigned int hmask)
{
return index & hmask;
@@ -76,16 +86,17 @@ static inline void tcf_lastuse_update(struct tcf_t *tm)
if (tm->lastuse != now)
tm->lastuse = now;
+ if (unlikely(!tm->firstuse))
+ tm->firstuse = now;
}
-struct tc_action {
- void *priv;
- const struct tc_action_ops *ops;
- __u32 type; /* for backward compat(TCA_OLD_COMPAT) */
- __u32 order;
- struct list_head list;
- struct tcf_hashinfo *hinfo;
-};
+static inline void tcf_tm_dump(struct tcf_t *dtm, const struct tcf_t *stm)
+{
+ dtm->install = jiffies_to_clock_t(jiffies - stm->install);
+ dtm->lastuse = jiffies_to_clock_t(jiffies - stm->lastuse);
+ dtm->firstuse = jiffies_to_clock_t(jiffies - stm->firstuse);
+ dtm->expires = jiffies_to_clock_t(stm->expires);
+}
#ifdef CONFIG_NET_CLS_ACT
@@ -96,16 +107,18 @@ struct tc_action_ops {
struct list_head head;
char kind[IFNAMSIZ];
__u32 type; /* TBD to match kind */
+ size_t size;
struct module *owner;
- int (*act)(struct sk_buff *, const struct tc_action *, struct tcf_result *);
+ int (*act)(struct sk_buff *, const struct tc_action *,
+ struct tcf_result *);
int (*dump)(struct sk_buff *, struct tc_action *, int, int);
void (*cleanup)(struct tc_action *, int bind);
- int (*lookup)(struct net *, struct tc_action *, u32);
+ int (*lookup)(struct net *, struct tc_action **, u32);
int (*init)(struct net *net, struct nlattr *nla,
- struct nlattr *est, struct tc_action *act, int ovr,
+ struct nlattr *est, struct tc_action **act, int ovr,
int bind);
int (*walk)(struct net *, struct sk_buff *,
- struct netlink_callback *, int, struct tc_action *);
+ struct netlink_callback *, int, const struct tc_action_ops *);
void (*stats_update)(struct tc_action *, u64, u32, u64);
};
@@ -115,8 +128,8 @@ struct tc_action_net {
};
static inline
-int tc_action_net_init(struct tc_action_net *tn, const struct tc_action_ops *ops,
- unsigned int mask)
+int tc_action_net_init(struct tc_action_net *tn,
+ const struct tc_action_ops *ops, unsigned int mask)
{
int err = 0;
@@ -141,13 +154,14 @@ static inline void tc_action_net_exit(struct tc_action_net *tn)
int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
struct netlink_callback *cb, int type,
- struct tc_action *a);
-int tcf_hash_search(struct tc_action_net *tn, struct tc_action *a, u32 index);
+ const struct tc_action_ops *ops);
+int tcf_hash_search(struct tc_action_net *tn, struct tc_action **a, u32 index);
u32 tcf_hash_new_index(struct tc_action_net *tn);
-int tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action *a,
- int bind);
+bool tcf_hash_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
+ int bind);
int tcf_hash_create(struct tc_action_net *tn, u32 index, struct nlattr *est,
- struct tc_action *a, int size, int bind, bool cpustats);
+ struct tc_action **a, const struct tc_action_ops *ops, int bind,
+ bool cpustats);
void tcf_hash_cleanup(struct tc_action *a, struct nlattr *est);
void tcf_hash_insert(struct tc_action_net *tn, struct tc_action *a);
@@ -159,7 +173,8 @@ static inline int tcf_hash_release(struct tc_action *a, bool bind)
}
int tcf_register_action(struct tc_action_ops *a, struct pernet_operations *ops);
-int tcf_unregister_action(struct tc_action_ops *a, struct pernet_operations *ops);
+int tcf_unregister_action(struct tc_action_ops *a,
+ struct pernet_operations *ops);
int tcf_action_destroy(struct list_head *actions, int bind);
int tcf_action_exec(struct sk_buff *skb, const struct list_head *actions,
struct tcf_result *res);
@@ -180,6 +195,9 @@ int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int);
#define tc_for_each_action(_a, _exts) \
list_for_each_entry(a, &(_exts)->actions, list)
+#define tc_single_action(_exts) \
+ (list_is_singular(&(_exts)->actions))
+
static inline void tcf_action_stats_update(struct tc_action *a, u64 bytes,
u64 packets, u64 lastuse)
{
@@ -193,6 +211,7 @@ static inline void tcf_action_stats_update(struct tc_action *a, u64 bytes,
#define tc_no_actions(_exts) true
#define tc_for_each_action(_a, _exts) while ((void)(_a), 0)
+#define tc_single_action(_exts) false
#define tcf_action_stats_update(a, bytes, packets, lastuse)
#endif /* CONFIG_NET_CLS_ACT */
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 730d856683e5..9826d3a9464c 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -94,6 +94,16 @@ int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,
void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr);
void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr);
+void addrconf_add_linklocal(struct inet6_dev *idev,
+ const struct in6_addr *addr, u32 flags);
+
+int addrconf_prefix_rcv_add_addr(struct net *net, struct net_device *dev,
+ const struct prefix_info *pinfo,
+ struct inet6_dev *in6_dev,
+ const struct in6_addr *addr, int addr_type,
+ u32 addr_flags, bool sllao, bool tokenized,
+ __u32 valid_lft, u32 prefered_lft);
+
static inline int addrconf_ifid_eui48(u8 *eui, struct net_device *dev)
{
if (dev->addr_len != ETH_ALEN)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index eefcf3e96421..003b25283407 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -65,7 +65,7 @@
#define HCI_I2C 8
/* HCI controller types */
-#define HCI_BREDR 0x00
+#define HCI_PRIMARY 0x00
#define HCI_AMP 0x01
/* First BR/EDR Controller shall have ID = 0 */
@@ -445,6 +445,7 @@ enum {
/* ---- HCI Error Codes ---- */
#define HCI_ERROR_UNKNOWN_CONN_ID 0x02
#define HCI_ERROR_AUTH_FAILURE 0x05
+#define HCI_ERROR_PIN_OR_KEY_MISSING 0x06
#define HCI_ERROR_MEMORY_EXCEEDED 0x07
#define HCI_ERROR_CONNECTION_TIMEOUT 0x08
#define HCI_ERROR_REJ_LIMITED_RESOURCES 0x0d
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index dc71473462ac..ee7fc47680a1 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -372,6 +372,8 @@ struct hci_dev {
atomic_t promisc;
+ const char *hw_info;
+ const char *fw_info;
struct dentry *debugfs;
struct device dev;
@@ -654,6 +656,7 @@ enum {
HCI_CONN_PARAM_REMOVAL_PEND,
HCI_CONN_NEW_LINK_KEY,
HCI_CONN_SCANNING,
+ HCI_CONN_AUTH_FAILURE,
};
static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
@@ -1021,6 +1024,10 @@ void hci_unregister_dev(struct hci_dev *hdev);
int hci_suspend_dev(struct hci_dev *hdev);
int hci_resume_dev(struct hci_dev *hdev);
int hci_reset_dev(struct hci_dev *hdev);
+int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb);
+int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb);
+void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...);
+void hci_set_fw_info(struct hci_dev *hdev, const char *fmt, ...);
int hci_dev_open(__u16 dev);
int hci_dev_close(__u16 dev);
int hci_dev_do_close(struct hci_dev *hdev);
@@ -1097,9 +1104,6 @@ int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance);
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
-int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb);
-int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb);
-
void hci_init_sysfs(struct hci_dev *hdev);
void hci_conn_init_sysfs(struct hci_conn *conn);
void hci_conn_add_sysfs(struct hci_conn *conn);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index ea73e0826aa7..7647964b1efa 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -645,6 +645,7 @@ struct mgmt_ev_device_connected {
#define MGMT_DEV_DISCONN_TIMEOUT 0x01
#define MGMT_DEV_DISCONN_LOCAL_HOST 0x02
#define MGMT_DEV_DISCONN_REMOTE 0x03
+#define MGMT_DEV_DISCONN_AUTH_FAILURE 0x04
#define MGMT_EV_DEVICE_DISCONNECTED 0x000C
struct mgmt_ev_device_disconnected {
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 63921672bed0..9c23f4d33e06 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -330,6 +330,9 @@ struct ieee80211_supported_band {
* in a separate chapter.
*/
+#define VHT_MUMIMO_GROUPS_DATA_LEN (WLAN_MEMBERSHIP_LEN +\
+ WLAN_USER_POSITION_LEN)
+
/**
* struct vif_params - describes virtual interface parameters
* @use_4addr: use 4-address frames
@@ -339,10 +342,13 @@ struct ieee80211_supported_band {
* This feature is only fully supported by drivers that enable the
* %NL80211_FEATURE_MAC_ON_CREATE flag. Others may support creating
** only p2p devices with specified MAC.
+ * @vht_mumimo_groups: MU-MIMO groupID. used for monitoring only
+ * packets belonging to that MU-MIMO groupID.
*/
struct vif_params {
- int use_4addr;
- u8 macaddr[ETH_ALEN];
+ int use_4addr;
+ u8 macaddr[ETH_ALEN];
+ u8 vht_mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN];
};
/**
@@ -774,6 +780,7 @@ enum station_parameters_apply_mask {
* (bitmask of BIT(NL80211_STA_FLAG_...))
* @listen_interval: listen interval or -1 for no change
* @aid: AID or zero for no change
+ * @peer_aid: mesh peer AID or zero for no change
* @plink_action: plink action to take
* @plink_state: set the peer link state for a station
* @ht_capa: HT capabilities of station
@@ -805,6 +812,7 @@ struct station_parameters {
u32 sta_modify_mask;
int listen_interval;
u16 aid;
+ u16 peer_aid;
u8 supported_rates_len;
u8 plink_action;
u8 plink_state;
@@ -1418,6 +1426,21 @@ struct cfg80211_ssid {
};
/**
+ * struct cfg80211_scan_info - information about completed scan
+ * @scan_start_tsf: scan start time in terms of the TSF of the BSS that the
+ * wireless device that requested the scan is connected to. If this
+ * information is not available, this field is left zero.
+ * @tsf_bssid: the BSSID according to which %scan_start_tsf is set.
+ * @aborted: set to true if the scan was aborted for any reason,
+ * userspace will be notified of that
+ */
+struct cfg80211_scan_info {
+ u64 scan_start_tsf;
+ u8 tsf_bssid[ETH_ALEN] __aligned(2);
+ bool aborted;
+};
+
+/**
* struct cfg80211_scan_request - scan request description
*
* @ssids: SSIDs to scan for (active scan only)
@@ -1427,12 +1450,17 @@ struct cfg80211_ssid {
* @scan_width: channel width for scanning
* @ie: optional information element(s) to add into Probe Request or %NULL
* @ie_len: length of ie in octets
+ * @duration: how long to listen on each channel, in TUs. If
+ * %duration_mandatory is not set, this is the maximum dwell time and
+ * the actual dwell time may be shorter.
+ * @duration_mandatory: if set, the scan duration must be as specified by the
+ * %duration field.
* @flags: bit field of flags controlling operation
* @rates: bitmap of rates to advertise for each band
* @wiphy: the wiphy this was for
* @scan_start: time (in jiffies) when the scan started
* @wdev: the wireless device to scan for
- * @aborted: (internal) scan request was notified as aborted
+ * @info: (internal) information about completed scan
* @notified: (internal) scan request was notified as done or aborted
* @no_cck: used to send probe requests at non CCK rate in 2GHz band
* @mac_addr: MAC address used with randomisation
@@ -1448,6 +1476,8 @@ struct cfg80211_scan_request {
enum nl80211_bss_scan_width scan_width;
const u8 *ie;
size_t ie_len;
+ u16 duration;
+ bool duration_mandatory;
u32 flags;
u32 rates[NUM_NL80211_BANDS];
@@ -1461,7 +1491,8 @@ struct cfg80211_scan_request {
/* internal */
struct wiphy *wiphy;
unsigned long scan_start;
- bool aborted, notified;
+ struct cfg80211_scan_info info;
+ bool notified;
bool no_cck;
/* keep last */
@@ -1594,12 +1625,19 @@ enum cfg80211_signal_type {
* buffered on the device) and be accurate to about 10ms.
* If the frame isn't buffered, just passing the return value of
* ktime_get_boot_ns() is likely appropriate.
+ * @parent_tsf: the time at the start of reception of the first octet of the
+ * timestamp field of the frame. The time is the TSF of the BSS specified
+ * by %parent_bssid.
+ * @parent_bssid: the BSS according to which %parent_tsf is set. This is set to
+ * the BSS that requested the scan in which the beacon/probe was received.
*/
struct cfg80211_inform_bss {
struct ieee80211_channel *chan;
enum nl80211_bss_scan_width scan_width;
s32 signal;
u64 boottime_ns;
+ u64 parent_tsf;
+ u8 parent_bssid[ETH_ALEN] __aligned(2);
};
/**
@@ -2367,19 +2405,23 @@ struct cfg80211_qos_map {
* (invoked with the wireless_dev mutex held)
*
* @connect: Connect to the ESS with the specified parameters. When connected,
- * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
- * If the connection fails for some reason, call cfg80211_connect_result()
- * with the status from the AP. The driver is allowed to roam to other
- * BSSes within the ESS when the other BSS matches the connect parameters.
- * When such roaming is initiated by the driver, the driver is expected to
- * verify that the target matches the configured security parameters and
- * to use Reassociation Request frame instead of Association Request frame.
- * The connect function can also be used to request the driver to perform
- * a specific roam when connected to an ESS. In that case, the prev_bssid
+ * call cfg80211_connect_result()/cfg80211_connect_bss() with status code
+ * %WLAN_STATUS_SUCCESS. If the connection fails for some reason, call
+ * cfg80211_connect_result()/cfg80211_connect_bss() with the status code
+ * from the AP or cfg80211_connect_timeout() if no frame with status code
+ * was received.
+ * The driver is allowed to roam to other BSSes within the ESS when the
+ * other BSS matches the connect parameters. When such roaming is initiated
+ * by the driver, the driver is expected to verify that the target matches
+ * the configured security parameters and to use Reassociation Request
+ * frame instead of Association Request frame.
+ * The connect function can also be used to request the driver to perform a
+ * specific roam when connected to an ESS. In that case, the prev_bssid
* parameter is set to the BSSID of the currently associated BSS as an
- * indication of requesting reassociation. In both the driver-initiated and
- * new connect() call initiated roaming cases, the result of roaming is
- * indicated with a call to cfg80211_roamed() or cfg80211_roamed_bss().
+ * indication of requesting reassociation.
+ * In both the driver-initiated and new connect() call initiated roaming
+ * cases, the result of roaming is indicated with a call to
+ * cfg80211_roamed() or cfg80211_roamed_bss().
* (invoked with the wireless_dev mutex held)
* @disconnect: Disconnect from the BSS/ESS.
* (invoked with the wireless_dev mutex held)
@@ -3080,6 +3122,24 @@ struct wiphy_vendor_command {
};
/**
+ * struct wiphy_iftype_ext_capab - extended capabilities per interface type
+ * @iftype: interface type
+ * @extended_capabilities: extended capabilities supported by the driver,
+ * additional capabilities might be supported by userspace; these are the
+ * 802.11 extended capabilities ("Extended Capabilities element") and are
+ * in the same format as in the information element. See IEEE Std
+ * 802.11-2012 8.4.2.29 for the defined fields.
+ * @extended_capabilities_mask: mask of the valid values
+ * @extended_capabilities_len: length of the extended capabilities
+ */
+struct wiphy_iftype_ext_capab {
+ enum nl80211_iftype iftype;
+ const u8 *extended_capabilities;
+ const u8 *extended_capabilities_mask;
+ u8 extended_capabilities_len;
+};
+
+/**
* struct wiphy - wireless hardware description
* @reg_notifier: the driver's regulatory notification callback,
* note that if your driver uses wiphy_apply_custom_regulatory()
@@ -3199,9 +3259,14 @@ struct wiphy_vendor_command {
* additional capabilities might be supported by userspace; these are
* the 802.11 extended capabilities ("Extended Capabilities element")
* and are in the same format as in the information element. See
- * 802.11-2012 8.4.2.29 for the defined fields.
+ * 802.11-2012 8.4.2.29 for the defined fields. These are the default
+ * extended capabilities to be used if the capabilities are not specified
+ * for a specific interface type in iftype_ext_capab.
* @extended_capabilities_mask: mask of the valid values
* @extended_capabilities_len: length of the extended capabilities
+ * @iftype_ext_capab: array of extended capabilities per interface type
+ * @num_iftype_ext_capab: number of interface types for which extended
+ * capabilities are specified separately.
* @coalesce: packet coalescing support information
*
* @vendor_commands: array of vendor commands supported by the hardware
@@ -3301,6 +3366,9 @@ struct wiphy {
const u8 *extended_capabilities, *extended_capabilities_mask;
u8 extended_capabilities_len;
+ const struct wiphy_iftype_ext_capab *iftype_ext_capab;
+ unsigned int num_iftype_ext_capab;
+
/* If multiple wiphys are registered and you're handed e.g.
* a regular netdev with assigned ieee80211_ptr, you won't
* know whether it points to a wiphy your driver has registered
@@ -4031,10 +4099,10 @@ const char *reg_initiator_name(enum nl80211_reg_initiator initiator);
* cfg80211_scan_done - notify that scan finished
*
* @request: the corresponding scan request
- * @aborted: set to true if the scan was aborted for any reason,
- * userspace will be notified of that
+ * @info: information about the completed scan
*/
-void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted);
+void cfg80211_scan_done(struct cfg80211_scan_request *request,
+ struct cfg80211_scan_info *info);
/**
* cfg80211_sched_scan_results - notify that new scan results are available
@@ -4680,7 +4748,7 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
struct cfg80211_bss *bss, const u8 *req_ie,
size_t req_ie_len, const u8 *resp_ie,
- size_t resp_ie_len, u16 status, gfp_t gfp);
+ size_t resp_ie_len, int status, gfp_t gfp);
/**
* cfg80211_connect_result - notify cfg80211 of connection result
@@ -4710,6 +4778,29 @@ cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
}
/**
+ * cfg80211_connect_timeout - notify cfg80211 of connection timeout
+ *
+ * @dev: network device
+ * @bssid: the BSSID of the AP
+ * @req_ie: association request IEs (maybe be %NULL)
+ * @req_ie_len: association request IEs length
+ * @gfp: allocation flags
+ *
+ * It should be called by the underlying driver whenever connect() has failed
+ * in a sequence where no explicit authentication/association rejection was
+ * received from the AP. This could happen, e.g., due to not being able to send
+ * out the Authentication or Association Request frame or timing out while
+ * waiting for the response.
+ */
+static inline void
+cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid,
+ const u8 *req_ie, size_t req_ie_len, gfp_t gfp)
+{
+ cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, NULL, 0, -1,
+ gfp);
+}
+
+/**
* cfg80211_roamed - notify cfg80211 of roaming
*
* @dev: network device
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 171cd76558fb..795ca4008f72 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -219,9 +219,22 @@ struct wpan_phy {
struct device dev;
+ /* the network namespace this phy lives in currently */
+ possible_net_t _net;
+
char priv[0] __aligned(NETDEV_ALIGN);
};
+static inline struct net *wpan_phy_net(struct wpan_phy *wpan_phy)
+{
+ return read_pnet(&wpan_phy->_net);
+}
+
+static inline void wpan_phy_net_set(struct wpan_phy *wpan_phy, struct net *net)
+{
+ write_pnet(&wpan_phy->_net, net);
+}
+
struct ieee802154_addr {
u8 mode;
__le16 pan_id;
diff --git a/include/net/codel_qdisc.h b/include/net/codel_qdisc.h
index 8144d9cd2908..098630f83a55 100644
--- a/include/net/codel_qdisc.h
+++ b/include/net/codel_qdisc.h
@@ -52,6 +52,7 @@
/* Qdiscs using codel plugin must use codel_skb_cb in their own cb[] */
struct codel_skb_cb {
codel_time_t enqueue_time;
+ unsigned int mem_usage;
};
static struct codel_skb_cb *get_codel_cb(const struct sk_buff *skb)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 1d45b61cb320..c99ffe8cef3c 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -90,6 +90,9 @@ struct devlink_ops {
u16 tc_index,
enum devlink_sb_pool_type pool_type,
u32 *p_cur, u32 *p_max);
+
+ int (*eswitch_mode_get)(struct devlink *devlink, u16 *p_mode);
+ int (*eswitch_mode_set)(struct devlink *devlink, u16 mode);
};
static inline void *devlink_priv(struct devlink *devlink)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 17c3d37b6779..2217a3f817f8 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -26,11 +26,14 @@ enum dsa_tag_protocol {
DSA_TAG_PROTO_TRAILER,
DSA_TAG_PROTO_EDSA,
DSA_TAG_PROTO_BRCM,
+ DSA_TAG_LAST, /* MUST BE LAST */
};
#define DSA_MAX_SWITCHES 4
#define DSA_MAX_PORTS 12
+#define DSA_RTABLE_NONE -1
+
struct dsa_chip_data {
/*
* How to access the switch configuration registers.
@@ -58,12 +61,11 @@ struct dsa_chip_data {
struct device_node *port_dn[DSA_MAX_PORTS];
/*
- * An array (with nr_chips elements) of which element [a]
- * indicates which port on this switch should be used to
- * send packets to that are destined for switch a. Can be
- * NULL if there is only one switch chip.
+ * An array of which element [a] indicates which port on this
+ * switch should be used to send packets to that are destined
+ * for switch a. Can be NULL if there is only one switch chip.
*/
- s8 *rtable;
+ s8 rtable[DSA_MAX_SWITCHES];
};
struct dsa_platform_data {
@@ -85,6 +87,17 @@ struct dsa_platform_data {
struct packet_type;
struct dsa_switch_tree {
+ struct list_head list;
+
+ /* Tree identifier */
+ u32 tree;
+
+ /* Number of switches attached to this tree */
+ struct kref refcount;
+
+ /* Has this tree been applied to the hardware? */
+ bool applied;
+
/*
* Configuration data for the platform device that owns
* this dsa switch tree instance.
@@ -100,12 +113,12 @@ struct dsa_switch_tree {
struct net_device *dev,
struct packet_type *pt,
struct net_device *orig_dev);
- enum dsa_tag_protocol tag_protocol;
/*
* Original copy of the master netdev ethtool_ops
*/
struct ethtool_ops master_ethtool_ops;
+ const struct ethtool_ops *master_orig_ethtool_ops;
/*
* The switch and port to which the CPU is attached.
@@ -117,6 +130,18 @@ struct dsa_switch_tree {
* Data for the individual switch chips.
*/
struct dsa_switch *ds[DSA_MAX_SWITCHES];
+
+ /*
+ * Tagging protocol operations for adding and removing an
+ * encapsulation tag.
+ */
+ const struct dsa_device_ops *tag_ops;
+};
+
+struct dsa_port {
+ struct net_device *netdev;
+ struct device_node *dn;
+ unsigned int ageing_time;
};
struct dsa_switch {
@@ -144,6 +169,13 @@ struct dsa_switch {
*/
struct dsa_switch_driver *drv;
+ /*
+ * An array of which element [a] indicates which port on this
+ * switch should be used to send packets to that are destined
+ * for switch a. Can be NULL if there is only one switch chip.
+ */
+ s8 rtable[DSA_MAX_SWITCHES];
+
#ifdef CONFIG_NET_DSA_HWMON
/*
* Hardware monitoring information
@@ -153,13 +185,19 @@ struct dsa_switch {
#endif
/*
+ * The lower device this switch uses to talk to the host
+ */
+ struct net_device *master_netdev;
+
+ /*
* Slave mii_bus and devices for the individual ports.
*/
u32 dsa_port_mask;
+ u32 cpu_port_mask;
u32 enabled_port_mask;
u32 phys_mii_mask;
+ struct dsa_port ports[DSA_MAX_PORTS];
struct mii_bus *slave_mii_bus;
- struct net_device *ports[DSA_MAX_PORTS];
};
static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p)
@@ -174,7 +212,7 @@ static inline bool dsa_is_dsa_port(struct dsa_switch *ds, int p)
static inline bool dsa_is_port_initialized(struct dsa_switch *ds, int p)
{
- return ds->enabled_port_mask & (1 << p) && ds->ports[p];
+ return ds->enabled_port_mask & (1 << p) && ds->ports[p].netdev;
}
static inline u8 dsa_upstream_port(struct dsa_switch *ds)
@@ -190,7 +228,7 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds)
if (dst->cpu_switch == ds->index)
return dst->cpu_port;
else
- return ds->cd->rtable[dst->cpu_switch];
+ return ds->rtable[dst->cpu_switch];
}
struct switchdev_trans;
@@ -292,6 +330,7 @@ struct dsa_switch_driver {
/*
* Bridge integration
*/
+ int (*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs);
int (*port_bridge_join)(struct dsa_switch *ds, int port,
struct net_device *bridge);
void (*port_bridge_leave)(struct dsa_switch *ds, int port);
@@ -344,4 +383,7 @@ static inline bool dsa_uses_tagged_protocol(struct dsa_switch_tree *dst)
{
return dst->rcv != NULL;
}
+
+void dsa_unregister_switch(struct dsa_switch *ds);
+int dsa_register_switch(struct dsa_switch *ds, struct device_node *np);
#endif
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index 59160de702b6..456e4a6006ab 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -17,7 +17,8 @@ struct fib_rule {
u32 flags;
u32 table;
u8 action;
- /* 3 bytes hole, try to use */
+ u8 l3mdev;
+ /* 2 bytes hole, try to use */
u32 target;
__be64 tun_id;
struct fib_rule __rcu *ctarget;
@@ -36,6 +37,7 @@ struct fib_lookup_arg {
void *lookup_ptr;
void *result;
struct fib_rule *rule;
+ u32 table;
int flags;
#define FIB_LOOKUP_NOREF 1
#define FIB_LOOKUP_IGNORE_LINKSTATE 2
@@ -89,7 +91,8 @@ struct fib_rules_ops {
[FRA_TABLE] = { .type = NLA_U32 }, \
[FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, \
[FRA_SUPPRESS_IFGROUP] = { .type = NLA_U32 }, \
- [FRA_GOTO] = { .type = NLA_U32 }
+ [FRA_GOTO] = { .type = NLA_U32 }, \
+ [FRA_L3MDEV] = { .type = NLA_U8 }
static inline void fib_rule_get(struct fib_rule *rule)
{
@@ -102,6 +105,20 @@ static inline void fib_rule_put(struct fib_rule *rule)
kfree_rcu(rule, rcu);
}
+#ifdef CONFIG_NET_L3_MASTER_DEV
+static inline u32 fib_rule_get_table(struct fib_rule *rule,
+ struct fib_lookup_arg *arg)
+{
+ return rule->l3mdev ? arg->table : rule->table;
+}
+#else
+static inline u32 fib_rule_get_table(struct fib_rule *rule,
+ struct fib_lookup_arg *arg)
+{
+ return rule->table;
+}
+#endif
+
static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla)
{
if (nla[FRA_TABLE])
@@ -117,4 +134,7 @@ int fib_rules_lookup(struct fib_rules_ops *, struct flowi *, int flags,
struct fib_lookup_arg *);
int fib_default_rule_add(struct fib_rules_ops *, u32 pref, u32 table,
u32 flags);
+
+int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr *nlh);
+int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr *nlh);
#endif
diff --git a/include/net/gen_stats.h b/include/net/gen_stats.h
index 610cd397890e..231e121cc7d9 100644
--- a/include/net/gen_stats.h
+++ b/include/net/gen_stats.h
@@ -33,10 +33,12 @@ int gnet_stats_start_copy_compat(struct sk_buff *skb, int type,
spinlock_t *lock, struct gnet_dump *d,
int padattr);
-int gnet_stats_copy_basic(struct gnet_dump *d,
+int gnet_stats_copy_basic(const seqcount_t *running,
+ struct gnet_dump *d,
struct gnet_stats_basic_cpu __percpu *cpu,
struct gnet_stats_basic_packed *b);
-void __gnet_stats_copy_basic(struct gnet_stats_basic_packed *bstats,
+void __gnet_stats_copy_basic(const seqcount_t *running,
+ struct gnet_stats_basic_packed *bstats,
struct gnet_stats_basic_cpu __percpu *cpu,
struct gnet_stats_basic_packed *b);
int gnet_stats_copy_rate_est(struct gnet_dump *d,
@@ -52,13 +54,15 @@ int gnet_stats_finish_copy(struct gnet_dump *d);
int gen_new_estimator(struct gnet_stats_basic_packed *bstats,
struct gnet_stats_basic_cpu __percpu *cpu_bstats,
struct gnet_stats_rate_est64 *rate_est,
- spinlock_t *stats_lock, struct nlattr *opt);
+ spinlock_t *stats_lock,
+ seqcount_t *running, struct nlattr *opt);
void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,
struct gnet_stats_rate_est64 *rate_est);
int gen_replace_estimator(struct gnet_stats_basic_packed *bstats,
struct gnet_stats_basic_cpu __percpu *cpu_bstats,
struct gnet_stats_rate_est64 *rate_est,
- spinlock_t *stats_lock, struct nlattr *opt);
+ spinlock_t *stats_lock,
+ seqcount_t *running, struct nlattr *opt);
bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats,
const struct gnet_stats_rate_est64 *rate_est);
#endif
diff --git a/include/net/geneve.h b/include/net/geneve.h
index cb544a530146..ec0327d4331b 100644
--- a/include/net/geneve.h
+++ b/include/net/geneve.h
@@ -1,10 +1,7 @@
#ifndef __NET_GENEVE_H
#define __NET_GENEVE_H 1
-#ifdef CONFIG_INET
#include <net/udp_tunnel.h>
-#endif
-
/* Geneve Header:
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -62,12 +59,6 @@ struct genevehdr {
struct geneve_opt options[];
};
-static inline void geneve_get_rx_port(struct net_device *netdev)
-{
- ASSERT_RTNL();
- call_netdevice_notifiers(NETDEV_OFFLOAD_PUSH_GENEVE, netdev);
-}
-
#ifdef CONFIG_INET
struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
u8 name_assign_type, u16 dst_port);
diff --git a/include/net/gro_cells.h b/include/net/gro_cells.h
index cf6c74550baa..d15214d673b2 100644
--- a/include/net/gro_cells.h
+++ b/include/net/gro_cells.h
@@ -14,27 +14,26 @@ struct gro_cells {
struct gro_cell __percpu *cells;
};
-static inline void gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
+static inline int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
{
struct gro_cell *cell;
struct net_device *dev = skb->dev;
- if (!gcells->cells || skb_cloned(skb) || !(dev->features & NETIF_F_GRO)) {
- netif_rx(skb);
- return;
- }
+ if (!gcells->cells || skb_cloned(skb) || !(dev->features & NETIF_F_GRO))
+ return netif_rx(skb);
cell = this_cpu_ptr(gcells->cells);
if (skb_queue_len(&cell->napi_skbs) > netdev_max_backlog) {
atomic_long_inc(&dev->rx_dropped);
kfree_skb(skb);
- return;
+ return NET_RX_DROP;
}
__skb_queue_tail(&cell->napi_skbs, skb);
if (skb_queue_len(&cell->napi_skbs) == 1)
napi_schedule(&cell->napi);
+ return NET_RX_SUCCESS;
}
/* called under BH context */
diff --git a/include/net/gtp.h b/include/net/gtp.h
index 894a37b87d63..6398891b99ba 100644
--- a/include/net/gtp.h
+++ b/include/net/gtp.h
@@ -1,5 +1,5 @@
#ifndef _GTP_H_
-#define _GTP_H
+#define _GTP_H_
/* General GTP protocol related definitions. */
diff --git a/include/net/ip.h b/include/net/ip.h
index 08f36cd2b874..9742b92dc933 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -47,6 +47,7 @@ struct inet_skb_parm {
#define IPSKB_REROUTED BIT(4)
#define IPSKB_DOREDIRECT BIT(5)
#define IPSKB_FRAG_PMTU BIT(6)
+#define IPSKB_FRAG_SEGS BIT(7)
u16 frag_max_size;
};
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 54c779416eec..d97305d0e71f 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -18,6 +18,7 @@ struct route_info {
__u8 prefix[0]; /* 0,8 or 16 */
};
+#include <net/addrconf.h>
#include <net/flow.h>
#include <net/ip6_fib.h>
#include <net/sock.h>
@@ -76,6 +77,8 @@ static inline struct dst_entry *ip6_route_output(struct net *net,
struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
int flags);
+struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
+ int ifindex, struct flowi6 *fl6, int flags);
int ip6_route_init(void);
void ip6_route_cleanup(void);
@@ -86,9 +89,23 @@ int ip6_route_add(struct fib6_config *cfg);
int ip6_ins_rt(struct rt6_info *);
int ip6_del_rt(struct rt6_info *);
-int ip6_route_get_saddr(struct net *net, struct rt6_info *rt,
- const struct in6_addr *daddr, unsigned int prefs,
- struct in6_addr *saddr);
+static inline int ip6_route_get_saddr(struct net *net, struct rt6_info *rt,
+ const struct in6_addr *daddr,
+ unsigned int prefs,
+ struct in6_addr *saddr)
+{
+ struct inet6_dev *idev =
+ rt ? ip6_dst_idev((struct dst_entry *)rt) : NULL;
+ int err = 0;
+
+ if (rt && rt->rt6i_prefsrc.plen)
+ *saddr = rt->rt6i_prefsrc.addr;
+ else
+ err = ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
+ daddr, prefs, saddr);
+
+ return err;
+}
struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
const struct in6_addr *saddr, int oif, int flags);
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index dbf444428437..a5e7035fb93f 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -132,6 +132,7 @@ struct ip_tunnel {
int ip_tnl_net_id;
struct gro_cells gro_cells;
bool collect_md;
+ bool ignore_df;
};
#define TUNNEL_CSUM __cpu_to_be16(0x01)
@@ -156,6 +157,7 @@ struct tnl_ptk_info {
__be16 proto;
__be32 key;
__be32 seq;
+ int hdr_len;
};
#define PACKET_RCVD 0
diff --git a/include/net/l3mdev.h b/include/net/l3mdev.h
index 374388dc01c8..e90095091aa0 100644
--- a/include/net/l3mdev.h
+++ b/include/net/l3mdev.h
@@ -11,6 +11,8 @@
#ifndef _NET_L3MDEV_H_
#define _NET_L3MDEV_H_
+#include <net/fib_rules.h>
+
/**
* struct l3mdev_ops - l3mdev operations
*
@@ -36,11 +38,17 @@ struct l3mdev_ops {
/* IPv6 ops */
struct dst_entry * (*l3mdev_get_rt6_dst)(const struct net_device *dev,
- const struct flowi6 *fl6);
+ struct flowi6 *fl6);
+ int (*l3mdev_get_saddr6)(struct net_device *dev,
+ const struct sock *sk,
+ struct flowi6 *fl6);
};
#ifdef CONFIG_NET_L3_MASTER_DEV
+int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
+ struct fib_lookup_arg *arg);
+
int l3mdev_master_ifindex_rcu(const struct net_device *dev);
static inline int l3mdev_master_ifindex(struct net_device *dev)
{
@@ -71,6 +79,31 @@ static inline int l3mdev_master_ifindex_by_index(struct net *net, int ifindex)
return rc;
}
+static inline
+const struct net_device *l3mdev_master_dev_rcu(const struct net_device *_dev)
+{
+ /* netdev_master_upper_dev_get_rcu calls
+ * list_first_or_null_rcu to walk the upper dev list.
+ * list_first_or_null_rcu does not handle a const arg. We aren't
+ * making changes, just want the master device from that list so
+ * typecast to remove the const
+ */
+ struct net_device *dev = (struct net_device *)_dev;
+ const struct net_device *master;
+
+ if (!dev)
+ return NULL;
+
+ if (netif_is_l3_master(dev))
+ master = dev;
+ else if (netif_is_l3_slave(dev))
+ master = netdev_master_upper_dev_get_rcu(dev);
+ else
+ master = NULL;
+
+ return master;
+}
+
/* get index of an interface to use for FIB lookups. For devices
* enslaved to an L3 master device FIB lookups are based on the
* master index
@@ -134,7 +167,9 @@ static inline bool netif_index_is_l3_master(struct net *net, int ifindex)
int l3mdev_get_saddr(struct net *net, int ifindex, struct flowi4 *fl4);
-struct dst_entry *l3mdev_get_rt6_dst(struct net *net, const struct flowi6 *fl6);
+struct dst_entry *l3mdev_get_rt6_dst(struct net *net, struct flowi6 *fl6);
+int l3mdev_get_saddr6(struct net *net, const struct sock *sk,
+ struct flowi6 *fl6);
static inline
struct sk_buff *l3mdev_l3_rcv(struct sk_buff *skb, u16 proto)
@@ -180,6 +215,12 @@ static inline int l3mdev_master_ifindex_by_index(struct net *net, int ifindex)
return 0;
}
+static inline
+const struct net_device *l3mdev_master_dev_rcu(const struct net_device *dev)
+{
+ return NULL;
+}
+
static inline int l3mdev_fib_oif_rcu(struct net_device *dev)
{
return dev ? dev->ifindex : 0;
@@ -220,11 +261,17 @@ static inline int l3mdev_get_saddr(struct net *net, int ifindex,
}
static inline
-struct dst_entry *l3mdev_get_rt6_dst(struct net *net, const struct flowi6 *fl6)
+struct dst_entry *l3mdev_get_rt6_dst(struct net *net, struct flowi6 *fl6)
{
return NULL;
}
+static inline int l3mdev_get_saddr6(struct net *net, const struct sock *sk,
+ struct flowi6 *fl6)
+{
+ return 0;
+}
+
static inline
struct sk_buff *l3mdev_ip_rcv(struct sk_buff *skb)
{
@@ -236,6 +283,13 @@ struct sk_buff *l3mdev_ip6_rcv(struct sk_buff *skb)
{
return skb;
}
+
+static inline
+int l3mdev_fib_rule_match(struct net *net, struct flowi *fl,
+ struct fib_lookup_arg *arg)
+{
+ return 1;
+}
#endif
#endif /* _NET_L3MDEV_H_ */
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index be30b0549b88..b4faadbb4e01 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -21,6 +21,7 @@
#include <linux/skbuff.h>
#include <linux/ieee80211.h>
#include <net/cfg80211.h>
+#include <net/codel.h>
#include <asm/unaligned.h>
/**
@@ -895,7 +896,18 @@ struct ieee80211_tx_info {
unsigned long jiffies;
};
/* NB: vif can be NULL for injected frames */
- struct ieee80211_vif *vif;
+ union {
+ /* NB: vif can be NULL for injected frames */
+ struct ieee80211_vif *vif;
+
+ /* When packets are enqueued on txq it's easy
+ * to re-construct the vif pointer. There's no
+ * more space in tx_info so it can be used to
+ * store the necessary enqueue time for packet
+ * sojourn time computation.
+ */
+ codel_time_t enqueue_time;
+ };
struct ieee80211_key_conf *hw_key;
u32 flags;
/* 4 bytes free */
@@ -2147,9 +2159,6 @@ enum ieee80211_hw_flags {
* @n_cipher_schemes: a size of an array of cipher schemes definitions.
* @cipher_schemes: a pointer to an array of cipher scheme definitions
* supported by HW.
- *
- * @txq_ac_max_pending: maximum number of frames per AC pending in all txq
- * entries for a vif.
*/
struct ieee80211_hw {
struct ieee80211_conf conf;
@@ -2180,7 +2189,6 @@ struct ieee80211_hw {
u8 uapsd_max_sp_len;
u8 n_cipher_schemes;
const struct ieee80211_cipher_scheme *cipher_schemes;
- int txq_ac_max_pending;
};
static inline bool _ieee80211_hw_check(struct ieee80211_hw *hw,
@@ -4689,9 +4697,10 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw);
* any context, including hardirq context.
*
* @hw: the hardware that finished the scan
- * @aborted: set to true if scan was aborted
+ * @info: information about the completed scan
*/
-void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted);
+void ieee80211_scan_completed(struct ieee80211_hw *hw,
+ struct cfg80211_scan_info *info);
/**
* ieee80211_sched_scan_results - got results from scheduled scan
diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index e465c8551ac3..286824acd008 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -247,14 +247,123 @@ struct ieee802154_ops {
*/
static inline __le16 ieee802154_get_fc_from_skb(const struct sk_buff *skb)
{
+ __le16 fc;
+
/* check if we can fc at skb_mac_header of sk buffer */
- if (unlikely(!skb_mac_header_was_set(skb) ||
- (skb_tail_pointer(skb) - skb_mac_header(skb)) < 2)) {
- WARN_ON(1);
+ if (WARN_ON(!skb_mac_header_was_set(skb) ||
+ (skb_tail_pointer(skb) -
+ skb_mac_header(skb)) < IEEE802154_FC_LEN))
return cpu_to_le16(0);
+
+ memcpy(&fc, skb_mac_header(skb), IEEE802154_FC_LEN);
+ return fc;
+}
+
+/**
+ * ieee802154_skb_dst_pan - get the pointer to destination pan field
+ * @fc: mac header frame control field
+ * @skb: skb where the destination pan pointer will be get from
+ */
+static inline unsigned char *ieee802154_skb_dst_pan(__le16 fc,
+ const struct sk_buff *skb)
+{
+ unsigned char *dst_pan;
+
+ switch (ieee802154_daddr_mode(fc)) {
+ case cpu_to_le16(IEEE802154_FCTL_ADDR_NONE):
+ dst_pan = NULL;
+ break;
+ case cpu_to_le16(IEEE802154_FCTL_DADDR_SHORT):
+ case cpu_to_le16(IEEE802154_FCTL_DADDR_EXTENDED):
+ dst_pan = skb_mac_header(skb) +
+ IEEE802154_FC_LEN +
+ IEEE802154_SEQ_LEN;
+ break;
+ default:
+ WARN_ONCE(1, "invalid addr mode detected");
+ dst_pan = NULL;
+ break;
+ }
+
+ return dst_pan;
+}
+
+/**
+ * ieee802154_skb_src_pan - get the pointer to source pan field
+ * @fc: mac header frame control field
+ * @skb: skb where the source pan pointer will be get from
+ */
+static inline unsigned char *ieee802154_skb_src_pan(__le16 fc,
+ const struct sk_buff *skb)
+{
+ unsigned char *src_pan;
+
+ switch (ieee802154_saddr_mode(fc)) {
+ case cpu_to_le16(IEEE802154_FCTL_ADDR_NONE):
+ src_pan = NULL;
+ break;
+ case cpu_to_le16(IEEE802154_FCTL_SADDR_SHORT):
+ case cpu_to_le16(IEEE802154_FCTL_SADDR_EXTENDED):
+ /* if intra-pan and source addr mode is non none,
+ * then source pan id is equal destination pan id.
+ */
+ if (ieee802154_is_intra_pan(fc)) {
+ src_pan = ieee802154_skb_dst_pan(fc, skb);
+ break;
+ }
+
+ switch (ieee802154_daddr_mode(fc)) {
+ case cpu_to_le16(IEEE802154_FCTL_ADDR_NONE):
+ src_pan = skb_mac_header(skb) +
+ IEEE802154_FC_LEN +
+ IEEE802154_SEQ_LEN;
+ break;
+ case cpu_to_le16(IEEE802154_FCTL_DADDR_SHORT):
+ src_pan = skb_mac_header(skb) +
+ IEEE802154_FC_LEN +
+ IEEE802154_SEQ_LEN +
+ IEEE802154_PAN_ID_LEN +
+ IEEE802154_SHORT_ADDR_LEN;
+ break;
+ case cpu_to_le16(IEEE802154_FCTL_DADDR_EXTENDED):
+ src_pan = skb_mac_header(skb) +
+ IEEE802154_FC_LEN +
+ IEEE802154_SEQ_LEN +
+ IEEE802154_PAN_ID_LEN +
+ IEEE802154_EXTENDED_ADDR_LEN;
+ break;
+ default:
+ WARN_ONCE(1, "invalid addr mode detected");
+ src_pan = NULL;
+ break;
+ }
+ break;
+ default:
+ WARN_ONCE(1, "invalid addr mode detected");
+ src_pan = NULL;
+ break;
}
- return get_unaligned_le16(skb_mac_header(skb));
+ return src_pan;
+}
+
+/**
+ * ieee802154_skb_is_intra_pan_addressing - checks whenever the mac addressing
+ * is an intra pan communication
+ * @fc: mac header frame control field
+ * @skb: skb where the source and destination pan should be get from
+ */
+static inline bool ieee802154_skb_is_intra_pan_addressing(__le16 fc,
+ const struct sk_buff *skb)
+{
+ unsigned char *dst_pan = ieee802154_skb_dst_pan(fc, skb),
+ *src_pan = ieee802154_skb_src_pan(fc, skb);
+
+ /* if one is NULL is no intra pan addressing */
+ if (!dst_pan || !src_pan)
+ return false;
+
+ return !memcmp(dst_pan, src_pan, IEEE802154_PAN_ID_LEN);
}
/**
diff --git a/include/net/ncsi.h b/include/net/ncsi.h
new file mode 100644
index 000000000000..1dbf42f79750
--- /dev/null
+++ b/include/net/ncsi.h
@@ -0,0 +1,52 @@
+#ifndef __NET_NCSI_H
+#define __NET_NCSI_H
+
+/*
+ * The NCSI device states seen from external. More NCSI device states are
+ * only visible internally (in net/ncsi/internal.h). When the NCSI device
+ * is registered, it's in ncsi_dev_state_registered state. The state
+ * ncsi_dev_state_start is used to drive to choose active package and
+ * channel. After that, its state is changed to ncsi_dev_state_functional.
+ *
+ * The state ncsi_dev_state_stop helps to shut down the currently active
+ * package and channel while ncsi_dev_state_config helps to reconfigure
+ * them.
+ */
+enum {
+ ncsi_dev_state_registered = 0x0000,
+ ncsi_dev_state_functional = 0x0100,
+ ncsi_dev_state_probe = 0x0200,
+ ncsi_dev_state_config = 0x0300,
+ ncsi_dev_state_suspend = 0x0400,
+};
+
+struct ncsi_dev {
+ int state;
+ int link_up;
+ struct net_device *dev;
+ void (*handler)(struct ncsi_dev *ndev);
+};
+
+#ifdef CONFIG_NET_NCSI
+struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
+ void (*notifier)(struct ncsi_dev *nd));
+int ncsi_start_dev(struct ncsi_dev *nd);
+void ncsi_unregister_dev(struct ncsi_dev *nd);
+#else /* !CONFIG_NET_NCSI */
+static inline struct ncsi_dev *ncsi_register_dev(struct net_device *dev,
+ void (*notifier)(struct ncsi_dev *nd))
+{
+ return NULL;
+}
+
+static inline int ncsi_start_dev(struct ncsi_dev *nd)
+{
+ return -ENOTTY;
+}
+
+static inline void ncsi_unregister_dev(struct ncsi_dev *nd)
+{
+}
+#endif /* CONFIG_NET_NCSI */
+
+#endif /* __NET_NCSI_H */
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 2d8edaad29cb..be1fe2283254 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -35,6 +35,7 @@ enum {
ND_OPT_ROUTE_INFO = 24, /* RFC4191 */
ND_OPT_RDNSS = 25, /* RFC5006 */
ND_OPT_DNSSL = 31, /* RFC6106 */
+ ND_OPT_6CO = 34, /* RFC6775 */
__ND_OPT_MAX
};
@@ -53,11 +54,21 @@ enum {
#include <net/neighbour.h>
+/* Set to 3 to get tracing... */
+#define ND_DEBUG 1
+
+#define ND_PRINTK(val, level, fmt, ...) \
+do { \
+ if (val <= ND_DEBUG) \
+ net_##level##_ratelimited(fmt, ##__VA_ARGS__); \
+} while (0)
+
struct ctl_table;
struct inet6_dev;
struct net_device;
struct net_proto_family;
struct sk_buff;
+struct prefix_info;
extern struct neigh_table nd_tbl;
@@ -99,20 +110,201 @@ struct ndisc_options {
#endif
struct nd_opt_hdr *nd_useropts;
struct nd_opt_hdr *nd_useropts_end;
+#if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN)
+ struct nd_opt_hdr *nd_802154_opt_array[ND_OPT_TARGET_LL_ADDR + 1];
+#endif
};
-#define nd_opts_src_lladdr nd_opt_array[ND_OPT_SOURCE_LL_ADDR]
-#define nd_opts_tgt_lladdr nd_opt_array[ND_OPT_TARGET_LL_ADDR]
-#define nd_opts_pi nd_opt_array[ND_OPT_PREFIX_INFO]
-#define nd_opts_pi_end nd_opt_array[__ND_OPT_PREFIX_INFO_END]
-#define nd_opts_rh nd_opt_array[ND_OPT_REDIRECT_HDR]
-#define nd_opts_mtu nd_opt_array[ND_OPT_MTU]
+#define nd_opts_src_lladdr nd_opt_array[ND_OPT_SOURCE_LL_ADDR]
+#define nd_opts_tgt_lladdr nd_opt_array[ND_OPT_TARGET_LL_ADDR]
+#define nd_opts_pi nd_opt_array[ND_OPT_PREFIX_INFO]
+#define nd_opts_pi_end nd_opt_array[__ND_OPT_PREFIX_INFO_END]
+#define nd_opts_rh nd_opt_array[ND_OPT_REDIRECT_HDR]
+#define nd_opts_mtu nd_opt_array[ND_OPT_MTU]
+#define nd_802154_opts_src_lladdr nd_802154_opt_array[ND_OPT_SOURCE_LL_ADDR]
+#define nd_802154_opts_tgt_lladdr nd_802154_opt_array[ND_OPT_TARGET_LL_ADDR]
#define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
-struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len,
+struct ndisc_options *ndisc_parse_options(const struct net_device *dev,
+ u8 *opt, int opt_len,
struct ndisc_options *ndopts);
+void __ndisc_fill_addr_option(struct sk_buff *skb, int type, void *data,
+ int data_len, int pad);
+
+#define NDISC_OPS_REDIRECT_DATA_SPACE 2
+
+/*
+ * This structure defines the hooks for IPv6 neighbour discovery.
+ * The following hooks can be defined; unless noted otherwise, they are
+ * optional and can be filled with a null pointer.
+ *
+ * int (*is_useropt)(u8 nd_opt_type):
+ * This function is called when IPv6 decide RA userspace options. if
+ * this function returns 1 then the option given by nd_opt_type will
+ * be handled as userspace option additional to the IPv6 options.
+ *
+ * int (*parse_options)(const struct net_device *dev,
+ * struct nd_opt_hdr *nd_opt,
+ * struct ndisc_options *ndopts):
+ * This function is called while parsing ndisc ops and put each position
+ * as pointer into ndopts. If this function return unequal 0, then this
+ * function took care about the ndisc option, if 0 then the IPv6 ndisc
+ * option parser will take care about that option.
+ *
+ * void (*update)(const struct net_device *dev, struct neighbour *n,
+ * u32 flags, u8 icmp6_type,
+ * const struct ndisc_options *ndopts):
+ * This function is called when IPv6 ndisc updates the neighbour cache
+ * entry. Additional options which can be updated may be previously
+ * parsed by parse_opts callback and accessible over ndopts parameter.
+ *
+ * int (*opt_addr_space)(const struct net_device *dev, u8 icmp6_type,
+ * struct neighbour *neigh, u8 *ha_buf,
+ * u8 **ha):
+ * This function is called when the necessary option space will be
+ * calculated before allocating a skb. The parameters neigh, ha_buf
+ * abd ha are available on NDISC_REDIRECT messages only.
+ *
+ * void (*fill_addr_option)(const struct net_device *dev,
+ * struct sk_buff *skb, u8 icmp6_type,
+ * const u8 *ha):
+ * This function is called when the skb will finally fill the option
+ * fields inside skb. NOTE: this callback should fill the option
+ * fields to the skb which are previously indicated by opt_space
+ * parameter. That means the decision to add such option should
+ * not lost between these two callbacks, e.g. protected by interface
+ * up state.
+ *
+ * void (*prefix_rcv_add_addr)(struct net *net, struct net_device *dev,
+ * const struct prefix_info *pinfo,
+ * struct inet6_dev *in6_dev,
+ * struct in6_addr *addr,
+ * int addr_type, u32 addr_flags,
+ * bool sllao, bool tokenized,
+ * __u32 valid_lft, u32 prefered_lft,
+ * bool dev_addr_generated):
+ * This function is called when a RA messages is received with valid
+ * PIO option fields and an IPv6 address will be added to the interface
+ * for autoconfiguration. The parameter dev_addr_generated reports about
+ * if the address was based on dev->dev_addr or not. This can be used
+ * to add a second address if link-layer operates with two link layer
+ * addresses. E.g. 802.15.4 6LoWPAN.
+ */
+struct ndisc_ops {
+ int (*is_useropt)(u8 nd_opt_type);
+ int (*parse_options)(const struct net_device *dev,
+ struct nd_opt_hdr *nd_opt,
+ struct ndisc_options *ndopts);
+ void (*update)(const struct net_device *dev, struct neighbour *n,
+ u32 flags, u8 icmp6_type,
+ const struct ndisc_options *ndopts);
+ int (*opt_addr_space)(const struct net_device *dev, u8 icmp6_type,
+ struct neighbour *neigh, u8 *ha_buf,
+ u8 **ha);
+ void (*fill_addr_option)(const struct net_device *dev,
+ struct sk_buff *skb, u8 icmp6_type,
+ const u8 *ha);
+ void (*prefix_rcv_add_addr)(struct net *net, struct net_device *dev,
+ const struct prefix_info *pinfo,
+ struct inet6_dev *in6_dev,
+ struct in6_addr *addr,
+ int addr_type, u32 addr_flags,
+ bool sllao, bool tokenized,
+ __u32 valid_lft, u32 prefered_lft,
+ bool dev_addr_generated);
+};
+
+#if IS_ENABLED(CONFIG_IPV6)
+static inline int ndisc_ops_is_useropt(const struct net_device *dev,
+ u8 nd_opt_type)
+{
+ if (dev->ndisc_ops && dev->ndisc_ops->is_useropt)
+ return dev->ndisc_ops->is_useropt(nd_opt_type);
+ else
+ return 0;
+}
+
+static inline int ndisc_ops_parse_options(const struct net_device *dev,
+ struct nd_opt_hdr *nd_opt,
+ struct ndisc_options *ndopts)
+{
+ if (dev->ndisc_ops && dev->ndisc_ops->parse_options)
+ return dev->ndisc_ops->parse_options(dev, nd_opt, ndopts);
+ else
+ return 0;
+}
+
+static inline void ndisc_ops_update(const struct net_device *dev,
+ struct neighbour *n, u32 flags,
+ u8 icmp6_type,
+ const struct ndisc_options *ndopts)
+{
+ if (dev->ndisc_ops && dev->ndisc_ops->update)
+ dev->ndisc_ops->update(dev, n, flags, icmp6_type, ndopts);
+}
+
+static inline int ndisc_ops_opt_addr_space(const struct net_device *dev,
+ u8 icmp6_type)
+{
+ if (dev->ndisc_ops && dev->ndisc_ops->opt_addr_space &&
+ icmp6_type != NDISC_REDIRECT)
+ return dev->ndisc_ops->opt_addr_space(dev, icmp6_type, NULL,
+ NULL, NULL);
+ else
+ return 0;
+}
+
+static inline int ndisc_ops_redirect_opt_addr_space(const struct net_device *dev,
+ struct neighbour *neigh,
+ u8 *ha_buf, u8 **ha)
+{
+ if (dev->ndisc_ops && dev->ndisc_ops->opt_addr_space)
+ return dev->ndisc_ops->opt_addr_space(dev, NDISC_REDIRECT,
+ neigh, ha_buf, ha);
+ else
+ return 0;
+}
+
+static inline void ndisc_ops_fill_addr_option(const struct net_device *dev,
+ struct sk_buff *skb,
+ u8 icmp6_type)
+{
+ if (dev->ndisc_ops && dev->ndisc_ops->fill_addr_option &&
+ icmp6_type != NDISC_REDIRECT)
+ dev->ndisc_ops->fill_addr_option(dev, skb, icmp6_type, NULL);
+}
+
+static inline void ndisc_ops_fill_redirect_addr_option(const struct net_device *dev,
+ struct sk_buff *skb,
+ const u8 *ha)
+{
+ if (dev->ndisc_ops && dev->ndisc_ops->fill_addr_option)
+ dev->ndisc_ops->fill_addr_option(dev, skb, NDISC_REDIRECT, ha);
+}
+
+static inline void ndisc_ops_prefix_rcv_add_addr(struct net *net,
+ struct net_device *dev,
+ const struct prefix_info *pinfo,
+ struct inet6_dev *in6_dev,
+ struct in6_addr *addr,
+ int addr_type, u32 addr_flags,
+ bool sllao, bool tokenized,
+ __u32 valid_lft,
+ u32 prefered_lft,
+ bool dev_addr_generated)
+{
+ if (dev->ndisc_ops && dev->ndisc_ops->prefix_rcv_add_addr)
+ dev->ndisc_ops->prefix_rcv_add_addr(net, dev, pinfo, in6_dev,
+ addr, addr_type,
+ addr_flags, sllao,
+ tokenized, valid_lft,
+ prefered_lft,
+ dev_addr_generated);
+}
+#endif
+
/*
* Return the padding between the option length and the start of the
* link addr. Currently only IP-over-InfiniBand needs this, although
@@ -127,23 +319,48 @@ static inline int ndisc_addr_option_pad(unsigned short type)
}
}
-static inline int ndisc_opt_addr_space(struct net_device *dev)
+static inline int __ndisc_opt_addr_space(unsigned char addr_len, int pad)
{
- return NDISC_OPT_SPACE(dev->addr_len +
- ndisc_addr_option_pad(dev->type));
+ return NDISC_OPT_SPACE(addr_len + pad);
}
-static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
- struct net_device *dev)
+#if IS_ENABLED(CONFIG_IPV6)
+static inline int ndisc_opt_addr_space(struct net_device *dev, u8 icmp6_type)
+{
+ return __ndisc_opt_addr_space(dev->addr_len,
+ ndisc_addr_option_pad(dev->type)) +
+ ndisc_ops_opt_addr_space(dev, icmp6_type);
+}
+
+static inline int ndisc_redirect_opt_addr_space(struct net_device *dev,
+ struct neighbour *neigh,
+ u8 *ops_data_buf,
+ u8 **ops_data)
+{
+ return __ndisc_opt_addr_space(dev->addr_len,
+ ndisc_addr_option_pad(dev->type)) +
+ ndisc_ops_redirect_opt_addr_space(dev, neigh, ops_data_buf,
+ ops_data);
+}
+#endif
+
+static inline u8 *__ndisc_opt_addr_data(struct nd_opt_hdr *p,
+ unsigned char addr_len, int prepad)
{
u8 *lladdr = (u8 *)(p + 1);
int lladdrlen = p->nd_opt_len << 3;
- int prepad = ndisc_addr_option_pad(dev->type);
- if (lladdrlen != ndisc_opt_addr_space(dev))
+ if (lladdrlen != __ndisc_opt_addr_space(addr_len, prepad))
return NULL;
return lladdr + prepad;
}
+static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
+ struct net_device *dev)
+{
+ return __ndisc_opt_addr_data(p, dev->addr_len,
+ ndisc_addr_option_pad(dev->type));
+}
+
static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, __u32 *hash_rnd)
{
const u32 *p32 = pkey;
@@ -194,6 +411,9 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target);
int ndisc_mc_map(const struct in6_addr *addr, char *buf, struct net_device *dev,
int dir);
+void ndisc_update(const struct net_device *dev, struct neighbour *neigh,
+ const u8 *lladdr, u8 new, u32 flags, u8 icmp6_type,
+ struct ndisc_options *ndopts);
/*
* IGMP
diff --git a/include/net/netevent.h b/include/net/netevent.h
index d8bbb38584b6..f440df172b56 100644
--- a/include/net/netevent.h
+++ b/include/net/netevent.h
@@ -24,6 +24,7 @@ struct netevent_redirect {
enum netevent_notif_type {
NETEVENT_NEIGH_UPDATE = 1, /* arg is struct neighbour ptr */
NETEVENT_REDIRECT, /* arg is struct netevent_redirect ptr */
+ NETEVENT_DELAY_PROBE_TIME_UPDATE, /* arg is struct neigh_parms ptr */
};
int register_netevent_notifier(struct notifier_block *nb);
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index b6083c34ef0d..445b019c2078 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -17,6 +17,7 @@
#include <linux/bitops.h>
#include <linux/compiler.h>
#include <linux/atomic.h>
+#include <linux/rhashtable.h>
#include <linux/netfilter/nf_conntrack_tcp.h>
#include <linux/netfilter/nf_conntrack_dccp.h>
@@ -85,6 +86,9 @@ struct nf_conn {
spinlock_t lock;
u16 cpu;
+#ifdef CONFIG_NF_CONNTRACK_ZONES
+ struct nf_conntrack_zone zone;
+#endif
/* XXX should I move this to the tail ? - Y.K */
/* These are my tuples; original and reply */
struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
@@ -114,6 +118,9 @@ struct nf_conn {
/* Extensions */
struct nf_ct_ext *ext;
+#if IS_ENABLED(CONFIG_NF_NAT)
+ struct rhash_head nat_bysource;
+#endif
/* Storage reserved for other modules, must be the last member */
union nf_conntrack_proto proto;
};
@@ -263,12 +270,12 @@ static inline int nf_ct_is_template(const struct nf_conn *ct)
}
/* It's confirmed if it is, or has been in the hash table. */
-static inline int nf_ct_is_confirmed(struct nf_conn *ct)
+static inline int nf_ct_is_confirmed(const struct nf_conn *ct)
{
return test_bit(IPS_CONFIRMED_BIT, &ct->status);
}
-static inline int nf_ct_is_dying(struct nf_conn *ct)
+static inline int nf_ct_is_dying(const struct nf_conn *ct)
{
return test_bit(IPS_DYING_BIT, &ct->status);
}
@@ -295,6 +302,7 @@ static inline unsigned long nf_ct_expires(const struct nf_conn *ct)
struct kernel_param;
int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp);
+int nf_conntrack_hash_resize(unsigned int hashsize);
extern unsigned int nf_conntrack_htable_size;
extern unsigned int nf_conntrack_max;
@@ -305,6 +313,7 @@ void nf_ct_tmpl_free(struct nf_conn *tmpl);
#define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count)
#define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count)
+#define NF_CT_STAT_ADD_ATOMIC(net, count, v) this_cpu_add((net)->ct.stat->count, (v))
#define MODULE_ALIAS_NFCT_HELPER(helper) \
MODULE_ALIAS("nfct-helper-" helper)
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index 3e2f3328945c..79d7ac5c9740 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -51,6 +51,8 @@ bool nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
const struct nf_conntrack_l3proto *l3proto,
const struct nf_conntrack_l4proto *l4proto);
+void nf_conntrack_get_ht(struct hlist_nulls_head **hash, unsigned int *hsize);
+
/* Find a connection corresponding to a tuple. */
struct nf_conntrack_tuple_hash *
nf_conntrack_find_get(struct net *net,
diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h
index 55d15049ab2f..1c3035dda31f 100644
--- a/include/net/netfilter/nf_conntrack_extend.h
+++ b/include/net/netfilter/nf_conntrack_extend.h
@@ -15,9 +15,6 @@ enum nf_ct_ext_id {
#ifdef CONFIG_NF_CONNTRACK_EVENTS
NF_CT_EXT_ECACHE,
#endif
-#ifdef CONFIG_NF_CONNTRACK_ZONES
- NF_CT_EXT_ZONE,
-#endif
#ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
NF_CT_EXT_TSTAMP,
#endif
@@ -38,7 +35,6 @@ enum nf_ct_ext_id {
#define NF_CT_EXT_SEQADJ_TYPE struct nf_conn_seqadj
#define NF_CT_EXT_ACCT_TYPE struct nf_conn_acct
#define NF_CT_EXT_ECACHE_TYPE struct nf_conntrack_ecache
-#define NF_CT_EXT_ZONE_TYPE struct nf_conntrack_zone
#define NF_CT_EXT_TSTAMP_TYPE struct nf_conn_tstamp
#define NF_CT_EXT_TIMEOUT_TYPE struct nf_conn_timeout
#define NF_CT_EXT_LABELS_TYPE struct nf_conn_labels
@@ -103,9 +99,6 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id,
struct nf_ct_ext_type {
/* Destroys relationships (can be NULL). */
void (*destroy)(struct nf_conn *ct);
- /* Called when realloacted (can be NULL).
- Contents has already been moved. */
- void (*move)(void *new, void *old);
enum nf_ct_ext_id id;
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index 6cf614bc0029..1eaac1f4cd6a 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -58,10 +58,25 @@ struct nf_conntrack_helper *__nf_conntrack_helper_find(const char *name,
struct nf_conntrack_helper *nf_conntrack_helper_try_module_get(const char *name,
u16 l3num,
u8 protonum);
+void nf_ct_helper_init(struct nf_conntrack_helper *helper,
+ u16 l3num, u16 protonum, const char *name,
+ u16 default_port, u16 spec_port, u32 id,
+ const struct nf_conntrack_expect_policy *exp_pol,
+ u32 expect_class_max, u32 data_len,
+ int (*help)(struct sk_buff *skb, unsigned int protoff,
+ struct nf_conn *ct,
+ enum ip_conntrack_info ctinfo),
+ int (*from_nlattr)(struct nlattr *attr,
+ struct nf_conn *ct),
+ struct module *module);
int nf_conntrack_helper_register(struct nf_conntrack_helper *);
void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);
+int nf_conntrack_helpers_register(struct nf_conntrack_helper *, unsigned int);
+void nf_conntrack_helpers_unregister(struct nf_conntrack_helper *,
+ unsigned int);
+
struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct,
struct nf_conntrack_helper *helper,
gfp_t gfp);
diff --git a/include/net/netfilter/nf_conntrack_labels.h b/include/net/netfilter/nf_conntrack_labels.h
index c5f8fc736b3d..498814626e28 100644
--- a/include/net/netfilter/nf_conntrack_labels.h
+++ b/include/net/netfilter/nf_conntrack_labels.h
@@ -10,8 +10,7 @@
#define NF_CT_LABELS_MAX_SIZE ((XT_CONNLABEL_MAXBIT + 1) / BITS_PER_BYTE)
struct nf_conn_labels {
- u8 words;
- unsigned long bits[];
+ unsigned long bits[NF_CT_LABELS_MAX_SIZE / sizeof(long)];
};
static inline struct nf_conn_labels *nf_ct_labels_find(const struct nf_conn *ct)
@@ -26,27 +25,18 @@ static inline struct nf_conn_labels *nf_ct_labels_find(const struct nf_conn *ct)
static inline struct nf_conn_labels *nf_ct_labels_ext_add(struct nf_conn *ct)
{
#ifdef CONFIG_NF_CONNTRACK_LABELS
- struct nf_conn_labels *cl_ext;
struct net *net = nf_ct_net(ct);
- u8 words;
- words = ACCESS_ONCE(net->ct.label_words);
- if (words == 0)
+ if (net->ct.labels_used == 0)
return NULL;
- cl_ext = nf_ct_ext_add_length(ct, NF_CT_EXT_LABELS,
- words * sizeof(long), GFP_ATOMIC);
- if (cl_ext != NULL)
- cl_ext->words = words;
-
- return cl_ext;
+ return nf_ct_ext_add_length(ct, NF_CT_EXT_LABELS,
+ sizeof(struct nf_conn_labels), GFP_ATOMIC);
#else
return NULL;
#endif
}
-int nf_connlabel_set(struct nf_conn *ct, u16 bit);
-
int nf_connlabels_replace(struct nf_conn *ct,
const u32 *data, const u32 *mask, unsigned int words);
diff --git a/include/net/netfilter/nf_conntrack_zones.h b/include/net/netfilter/nf_conntrack_zones.h
index 4e32512cef32..64a718b60839 100644
--- a/include/net/netfilter/nf_conntrack_zones.h
+++ b/include/net/netfilter/nf_conntrack_zones.h
@@ -9,12 +9,11 @@
static inline const struct nf_conntrack_zone *
nf_ct_zone(const struct nf_conn *ct)
{
- const struct nf_conntrack_zone *nf_ct_zone = NULL;
-
#ifdef CONFIG_NF_CONNTRACK_ZONES
- nf_ct_zone = nf_ct_ext_find(ct, NF_CT_EXT_ZONE);
+ return &ct->zone;
+#else
+ return &nf_ct_zone_dflt;
#endif
- return nf_ct_zone ? nf_ct_zone : &nf_ct_zone_dflt;
}
static inline const struct nf_conntrack_zone *
@@ -31,32 +30,22 @@ static inline const struct nf_conntrack_zone *
nf_ct_zone_tmpl(const struct nf_conn *tmpl, const struct sk_buff *skb,
struct nf_conntrack_zone *tmp)
{
- const struct nf_conntrack_zone *zone;
-
+#ifdef CONFIG_NF_CONNTRACK_ZONES
if (!tmpl)
return &nf_ct_zone_dflt;
- zone = nf_ct_zone(tmpl);
- if (zone->flags & NF_CT_FLAG_MARK)
- zone = nf_ct_zone_init(tmp, skb->mark, zone->dir, 0);
-
- return zone;
+ if (tmpl->zone.flags & NF_CT_FLAG_MARK)
+ return nf_ct_zone_init(tmp, skb->mark, tmpl->zone.dir, 0);
+#endif
+ return nf_ct_zone(tmpl);
}
-static inline int nf_ct_zone_add(struct nf_conn *ct, gfp_t flags,
- const struct nf_conntrack_zone *info)
+static inline void nf_ct_zone_add(struct nf_conn *ct,
+ const struct nf_conntrack_zone *zone)
{
#ifdef CONFIG_NF_CONNTRACK_ZONES
- struct nf_conntrack_zone *nf_ct_zone;
-
- nf_ct_zone = nf_ct_ext_add(ct, NF_CT_EXT_ZONE, flags);
- if (!nf_ct_zone)
- return -ENOMEM;
-
- nf_ct_zone_init(nf_ct_zone, info->id, info->dir,
- info->flags);
+ ct->zone = *zone;
#endif
- return 0;
}
static inline bool nf_ct_zone_matches_dir(const struct nf_conntrack_zone *zone,
@@ -68,22 +57,34 @@ static inline bool nf_ct_zone_matches_dir(const struct nf_conntrack_zone *zone,
static inline u16 nf_ct_zone_id(const struct nf_conntrack_zone *zone,
enum ip_conntrack_dir dir)
{
+#ifdef CONFIG_NF_CONNTRACK_ZONES
return nf_ct_zone_matches_dir(zone, dir) ?
zone->id : NF_CT_DEFAULT_ZONE_ID;
+#else
+ return NF_CT_DEFAULT_ZONE_ID;
+#endif
}
static inline bool nf_ct_zone_equal(const struct nf_conn *a,
const struct nf_conntrack_zone *b,
enum ip_conntrack_dir dir)
{
+#ifdef CONFIG_NF_CONNTRACK_ZONES
return nf_ct_zone_id(nf_ct_zone(a), dir) ==
nf_ct_zone_id(b, dir);
+#else
+ return true;
+#endif
}
static inline bool nf_ct_zone_equal_any(const struct nf_conn *a,
const struct nf_conntrack_zone *b)
{
+#ifdef CONFIG_NF_CONNTRACK_ZONES
return nf_ct_zone(a)->id == b->id;
+#else
+ return true;
+#endif
}
#endif /* IS_ENABLED(CONFIG_NF_CONNTRACK) */
#endif /* _NF_CONNTRACK_ZONES_H */
diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h
index 57639fca223a..83d855ba6af1 100644
--- a/include/net/netfilter/nf_log.h
+++ b/include/net/netfilter/nf_log.h
@@ -12,6 +12,9 @@
#define NF_LOG_UID 0x08 /* Log UID owning local socket */
#define NF_LOG_MASK 0x0f
+/* This flag indicates that copy_len field in nf_loginfo is set */
+#define NF_LOG_F_COPY_LEN 0x1
+
enum nf_log_type {
NF_LOG_TYPE_LOG = 0,
NF_LOG_TYPE_ULOG,
@@ -22,9 +25,13 @@ struct nf_loginfo {
u_int8_t type;
union {
struct {
+ /* copy_len will be used iff you set
+ * NF_LOG_F_COPY_LEN in flags
+ */
u_int32_t copy_len;
u_int16_t group;
u_int16_t qthreshold;
+ u_int16_t flags;
} ulog;
struct {
u_int8_t level;
diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
index 344b1ab19220..c327a431a6f3 100644
--- a/include/net/netfilter/nf_nat.h
+++ b/include/net/netfilter/nf_nat.h
@@ -1,5 +1,6 @@
#ifndef _NF_NAT_H
#define _NF_NAT_H
+#include <linux/rhashtable.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter/nf_nat.h>
#include <net/netfilter/nf_conntrack_tuple.h>
@@ -29,8 +30,6 @@ struct nf_conn;
/* The structure embedded in the conntrack structure. */
struct nf_conn_nat {
- struct hlist_node bysource;
- struct nf_conn *ct;
union nf_conntrack_nat_help help;
#if IS_ENABLED(CONFIG_NF_NAT_MASQUERADE_IPV4) || \
IS_ENABLED(CONFIG_NF_NAT_MASQUERADE_IPV6)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index f7c291ff4074..f2f13399ce44 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -236,7 +236,8 @@ struct nft_expr;
* @features: features supported by the implementation
*/
struct nft_set_ops {
- bool (*lookup)(const struct nft_set *set,
+ bool (*lookup)(const struct net *net,
+ const struct nft_set *set,
const u32 *key,
const struct nft_set_ext **ext);
bool (*update)(struct nft_set *set,
@@ -248,11 +249,14 @@ struct nft_set_ops {
struct nft_regs *regs,
const struct nft_set_ext **ext);
- int (*insert)(const struct nft_set *set,
+ int (*insert)(const struct net *net,
+ const struct nft_set *set,
const struct nft_set_elem *elem);
- void (*activate)(const struct nft_set *set,
+ void (*activate)(const struct net *net,
+ const struct nft_set *set,
const struct nft_set_elem *elem);
- void * (*deactivate)(const struct nft_set *set,
+ void * (*deactivate)(const struct net *net,
+ const struct nft_set *set,
const struct nft_set_elem *elem);
void (*remove)(const struct nft_set *set,
const struct nft_set_elem *elem);
@@ -295,8 +299,8 @@ void nft_unregister_set(struct nft_set_ops *ops);
* @udlen: user data length
* @udata: user data
* @ops: set ops
- * @pnet: network namespace
* @flags: set flags
+ * @genmask: generation mask
* @klen: key length
* @dlen: data length
* @data: private set data
@@ -317,8 +321,8 @@ struct nft_set {
unsigned char *udata;
/* runtime data below here */
const struct nft_set_ops *ops ____cacheline_aligned;
- possible_net_t pnet;
- u16 flags;
+ u16 flags:14,
+ genmask:2;
u8 klen;
u8 dlen;
unsigned char data[]
@@ -336,9 +340,9 @@ static inline struct nft_set *nft_set_container_of(const void *priv)
}
struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
- const struct nlattr *nla);
+ const struct nlattr *nla, u8 genmask);
struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
- const struct nlattr *nla);
+ const struct nlattr *nla, u8 genmask);
static inline unsigned long nft_set_gc_interval(const struct nft_set *set)
{
@@ -733,7 +737,6 @@ static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule)
enum nft_chain_flags {
NFT_BASE_CHAIN = 0x1,
- NFT_CHAIN_INACTIVE = 0x2,
};
/**
@@ -755,7 +758,8 @@ struct nft_chain {
u64 handle;
u32 use;
u16 level;
- u8 flags;
+ u8 flags:6,
+ genmask:2;
char name[NFT_CHAIN_MAXNAMELEN];
};
@@ -797,13 +801,11 @@ struct nft_stats {
};
#define NFT_HOOK_OPS_MAX 2
-#define NFT_BASECHAIN_DISABLED (1 << 0)
/**
* struct nft_base_chain - nf_tables base chain
*
* @ops: netfilter hook ops
- * @pnet: net namespace that this chain belongs to
* @type: chain type
* @policy: default policy
* @stats: per-cpu chain stats
@@ -812,7 +814,6 @@ struct nft_stats {
*/
struct nft_base_chain {
struct nf_hook_ops ops[NFT_HOOK_OPS_MAX];
- possible_net_t pnet;
const struct nf_chain_type *type;
u8 policy;
u8 flags;
@@ -839,6 +840,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
* @hgenerator: handle generator state
* @use: number of chain references to this table
* @flags: table flag (see enum nft_table_flags)
+ * @genmask: generation mask
* @name: name of the table
*/
struct nft_table {
@@ -847,7 +849,8 @@ struct nft_table {
struct list_head sets;
u64 hgenerator;
u32 use;
- u16 flags;
+ u16 flags:14,
+ genmask:2;
char name[NFT_TABLE_MAXNAMELEN];
};
@@ -971,6 +974,32 @@ static inline u8 nft_genmask_cur(const struct net *net)
#define NFT_GENMASK_ANY ((1 << 0) | (1 << 1))
/*
+ * Generic transaction helpers
+ */
+
+/* Check if this object is currently active. */
+#define nft_is_active(__net, __obj) \
+ (((__obj)->genmask & nft_genmask_cur(__net)) == 0)
+
+/* Check if this object is active in the next generation. */
+#define nft_is_active_next(__net, __obj) \
+ (((__obj)->genmask & nft_genmask_next(__net)) == 0)
+
+/* This object becomes active in the next generation. */
+#define nft_activate_next(__net, __obj) \
+ (__obj)->genmask = nft_genmask_cur(__net)
+
+/* This object becomes inactive in the next generation. */
+#define nft_deactivate_next(__net, __obj) \
+ (__obj)->genmask = nft_genmask_next(__net)
+
+/* After committing the ruleset, clear the stale generation bit. */
+#define nft_clear(__net, __obj) \
+ (__obj)->genmask &= ~nft_genmask_next(__net)
+#define nft_active_genmask(__obj, __genmask) \
+ !((__obj)->genmask & __genmask)
+
+/*
* Set element transaction helpers
*/
@@ -980,10 +1009,11 @@ static inline bool nft_set_elem_active(const struct nft_set_ext *ext,
return !(ext->genmask & genmask);
}
-static inline void nft_set_elem_change_active(const struct nft_set *set,
+static inline void nft_set_elem_change_active(const struct net *net,
+ const struct nft_set *set,
struct nft_set_ext *ext)
{
- ext->genmask ^= nft_genmask_next(read_pnet(&set->pnet));
+ ext->genmask ^= nft_genmask_next(net);
}
/*
diff --git a/include/net/nfc/digital.h b/include/net/nfc/digital.h
index 0ae101eef0f4..74fa7eb94e72 100644
--- a/include/net/nfc/digital.h
+++ b/include/net/nfc/digital.h
@@ -220,12 +220,13 @@ struct nfc_digital_dev {
struct list_head cmd_queue;
struct mutex cmd_lock;
- struct work_struct poll_work;
+ struct delayed_work poll_work;
u8 curr_protocol;
u8 curr_rf_tech;
u8 curr_nfc_dep_pni;
u8 did;
+ u16 dep_rwt;
u8 local_payload_max;
u8 remote_payload_max;
@@ -237,7 +238,6 @@ struct nfc_digital_dev {
int nack_count;
struct sk_buff *saved_skb;
- unsigned int saved_skb_len;
u16 target_fsc;
diff --git a/include/net/nfc/llc.h b/include/net/nfc/llc.h
index c25fbdee0d61..7ecb45757897 100644
--- a/include/net/nfc/llc.h
+++ b/include/net/nfc/llc.h
@@ -37,10 +37,6 @@ struct nfc_llc *nfc_llc_allocate(const char *name, struct nfc_hci_dev *hdev,
int tx_tailroom, llc_failure_t llc_failure);
void nfc_llc_free(struct nfc_llc *llc);
-void nfc_llc_get_rx_head_tail_room(struct nfc_llc *llc, int *rx_headroom,
- int *rx_tailroom);
-
-
int nfc_llc_start(struct nfc_llc *llc);
int nfc_llc_stop(struct nfc_llc *llc);
void nfc_llc_rcv_from_drv(struct nfc_llc *llc, struct sk_buff *skb);
diff --git a/include/net/nl802154.h b/include/net/nl802154.h
index fcab4de49951..ddcee128f5d9 100644
--- a/include/net/nl802154.h
+++ b/include/net/nl802154.h
@@ -54,6 +54,8 @@ enum nl802154_commands {
NL802154_CMD_SET_ACKREQ_DEFAULT,
+ NL802154_CMD_SET_WPAN_PHY_NETNS,
+
/* add new commands above here */
#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
@@ -124,6 +126,11 @@ enum nl802154_attrs {
NL802154_ATTR_ACKREQ_DEFAULT,
+ NL802154_ATTR_PAD,
+
+ NL802154_ATTR_PID,
+ NL802154_ATTR_NETNS_FD,
+
/* add attributes here, update the policy in nl802154.c */
#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
@@ -138,8 +145,6 @@ enum nl802154_attrs {
NL802154_ATTR_SEC_KEY,
#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
- NL802154_ATTR_PAD,
-
__NL802154_ATTR_AFTER_LAST,
NL802154_ATTR_MAX = __NL802154_ATTR_AFTER_LAST - 1
};
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 3722dda0199d..6f8d65342d3a 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -442,4 +442,15 @@ struct tc_cls_flower_offload {
struct tcf_exts *exts;
};
+enum tc_matchall_command {
+ TC_CLSMATCHALL_REPLACE,
+ TC_CLSMATCHALL_DESTROY,
+};
+
+struct tc_cls_matchall_offload {
+ enum tc_matchall_command command;
+ struct tcf_exts *exts;
+ unsigned long cookie;
+};
+
#endif
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index fea53f4d92ca..7caa99b482c6 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -67,12 +67,12 @@ struct qdisc_watchdog {
};
void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc);
-void qdisc_watchdog_schedule_ns(struct qdisc_watchdog *wd, u64 expires, bool throttle);
+void qdisc_watchdog_schedule_ns(struct qdisc_watchdog *wd, u64 expires);
static inline void qdisc_watchdog_schedule(struct qdisc_watchdog *wd,
psched_time_t expires)
{
- qdisc_watchdog_schedule_ns(wd, PSCHED_TICKS2NS(expires), true);
+ qdisc_watchdog_schedule_ns(wd, PSCHED_TICKS2NS(expires));
}
void qdisc_watchdog_cancel(struct qdisc_watchdog *wd);
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 006a7b81d758..4113916cc1bb 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -98,10 +98,11 @@ struct rtnl_link_ops {
const struct net_device *dev,
const struct net_device *slave_dev);
struct net *(*get_link_net)(const struct net_device *dev);
- size_t (*get_linkxstats_size)(const struct net_device *dev);
+ size_t (*get_linkxstats_size)(const struct net_device *dev,
+ int attr);
int (*fill_linkxstats)(struct sk_buff *skb,
const struct net_device *dev,
- int *prividx);
+ int *prividx, int attr);
};
int __rtnl_link_register(struct rtnl_link_ops *ops);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 62d553184e91..909aff2db2b3 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -26,14 +26,6 @@ struct qdisc_rate_table {
enum qdisc_state_t {
__QDISC_STATE_SCHED,
__QDISC_STATE_DEACTIVATED,
- __QDISC_STATE_THROTTLED,
-};
-
-/*
- * following bits are only changed while qdisc lock is held
- */
-enum qdisc___state_t {
- __QDISC___STATE_RUNNING = 1,
};
struct qdisc_size_table {
@@ -45,8 +37,10 @@ struct qdisc_size_table {
};
struct Qdisc {
- int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev);
- struct sk_buff * (*dequeue)(struct Qdisc *dev);
+ int (*enqueue)(struct sk_buff *skb,
+ struct Qdisc *sch,
+ struct sk_buff **to_free);
+ struct sk_buff * (*dequeue)(struct Qdisc *sch);
unsigned int flags;
#define TCQ_F_BUILTIN 1
#define TCQ_F_INGRESS 2
@@ -70,31 +64,25 @@ struct Qdisc {
struct list_head list;
u32 handle;
u32 parent;
- int (*reshape_fail)(struct sk_buff *skb,
- struct Qdisc *q);
-
void *u32_node;
- /* This field is deprecated, but it is still used by CBQ
- * and it will live until better solution will be invented.
- */
- struct Qdisc *__parent;
struct netdev_queue *dev_queue;
struct gnet_stats_rate_est64 rate_est;
struct gnet_stats_basic_cpu __percpu *cpu_bstats;
struct gnet_stats_queue __percpu *cpu_qstats;
- struct Qdisc *next_sched;
- struct sk_buff *gso_skb;
/*
* For performance sake on SMP, we put highly modified fields at the end
*/
- unsigned long state;
+ struct sk_buff *gso_skb ____cacheline_aligned_in_smp;
struct sk_buff_head q;
struct gnet_stats_basic_packed bstats;
- unsigned int __state;
+ seqcount_t running;
struct gnet_stats_queue qstats;
+ unsigned long state;
+ struct Qdisc *next_sched;
+ struct sk_buff *skb_bad_txq;
struct rcu_head rcu_head;
int padded;
atomic_t refcnt;
@@ -104,20 +92,24 @@ struct Qdisc {
static inline bool qdisc_is_running(const struct Qdisc *qdisc)
{
- return (qdisc->__state & __QDISC___STATE_RUNNING) ? true : false;
+ return (raw_read_seqcount(&qdisc->running) & 1) ? true : false;
}
static inline bool qdisc_run_begin(struct Qdisc *qdisc)
{
if (qdisc_is_running(qdisc))
return false;
- qdisc->__state |= __QDISC___STATE_RUNNING;
+ /* Variant of write_seqcount_begin() telling lockdep a trylock
+ * was attempted.
+ */
+ raw_write_seqcount_begin(&qdisc->running);
+ seqcount_acquire(&qdisc->running.dep_map, 0, 1, _RET_IP_);
return true;
}
static inline void qdisc_run_end(struct Qdisc *qdisc)
{
- qdisc->__state &= ~__QDISC___STATE_RUNNING;
+ write_seqcount_end(&qdisc->running);
}
static inline bool qdisc_may_bulk(const struct Qdisc *qdisc)
@@ -135,21 +127,6 @@ static inline int qdisc_avail_bulklimit(const struct netdev_queue *txq)
#endif
}
-static inline bool qdisc_is_throttled(const struct Qdisc *qdisc)
-{
- return test_bit(__QDISC_STATE_THROTTLED, &qdisc->state) ? true : false;
-}
-
-static inline void qdisc_throttled(struct Qdisc *qdisc)
-{
- set_bit(__QDISC_STATE_THROTTLED, &qdisc->state);
-}
-
-static inline void qdisc_unthrottled(struct Qdisc *qdisc)
-{
- clear_bit(__QDISC_STATE_THROTTLED, &qdisc->state);
-}
-
struct Qdisc_class_ops {
/* Child qdisc manipulation */
struct netdev_queue * (*select_queue)(struct Qdisc *, struct tcmsg *);
@@ -186,10 +163,11 @@ struct Qdisc_ops {
char id[IFNAMSIZ];
int priv_size;
- int (*enqueue)(struct sk_buff *, struct Qdisc *);
+ int (*enqueue)(struct sk_buff *skb,
+ struct Qdisc *sch,
+ struct sk_buff **to_free);
struct sk_buff * (*dequeue)(struct Qdisc *);
struct sk_buff * (*peek)(struct Qdisc *);
- unsigned int (*drop)(struct Qdisc *);
int (*init)(struct Qdisc *, struct nlattr *arg);
void (*reset)(struct Qdisc *);
@@ -322,6 +300,14 @@ static inline spinlock_t *qdisc_root_sleeping_lock(const struct Qdisc *qdisc)
return qdisc_lock(root);
}
+static inline seqcount_t *qdisc_root_sleeping_running(const struct Qdisc *qdisc)
+{
+ struct Qdisc *root = qdisc_root_sleeping(qdisc);
+
+ ASSERT_RTNL();
+ return &root->running;
+}
+
static inline struct net_device *qdisc_dev(const struct Qdisc *qdisc)
{
return qdisc->dev_queue->dev;
@@ -517,10 +503,11 @@ static inline void qdisc_calculate_pkt_len(struct sk_buff *skb,
#endif
}
-static inline int qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+static inline int qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ struct sk_buff **to_free)
{
qdisc_calculate_pkt_len(skb, sch);
- return sch->enqueue(skb, sch);
+ return sch->enqueue(skb, sch, to_free);
}
static inline bool qdisc_is_percpu_stats(const struct Qdisc *q)
@@ -645,40 +632,36 @@ static inline struct sk_buff *qdisc_dequeue_head(struct Qdisc *sch)
return __qdisc_dequeue_head(sch, &sch->q);
}
+/* Instead of calling kfree_skb() while root qdisc lock is held,
+ * queue the skb for future freeing at end of __dev_xmit_skb()
+ */
+static inline void __qdisc_drop(struct sk_buff *skb, struct sk_buff **to_free)
+{
+ skb->next = *to_free;
+ *to_free = skb;
+}
+
static inline unsigned int __qdisc_queue_drop_head(struct Qdisc *sch,
- struct sk_buff_head *list)
+ struct sk_buff_head *list,
+ struct sk_buff **to_free)
{
struct sk_buff *skb = __skb_dequeue(list);
if (likely(skb != NULL)) {
unsigned int len = qdisc_pkt_len(skb);
+
qdisc_qstats_backlog_dec(sch, skb);
- kfree_skb(skb);
+ __qdisc_drop(skb, to_free);
return len;
}
return 0;
}
-static inline unsigned int qdisc_queue_drop_head(struct Qdisc *sch)
-{
- return __qdisc_queue_drop_head(sch, &sch->q);
-}
-
-static inline struct sk_buff *__qdisc_dequeue_tail(struct Qdisc *sch,
- struct sk_buff_head *list)
-{
- struct sk_buff *skb = __skb_dequeue_tail(list);
-
- if (likely(skb != NULL))
- qdisc_qstats_backlog_dec(sch, skb);
-
- return skb;
-}
-
-static inline struct sk_buff *qdisc_dequeue_tail(struct Qdisc *sch)
+static inline unsigned int qdisc_queue_drop_head(struct Qdisc *sch,
+ struct sk_buff **to_free)
{
- return __qdisc_dequeue_tail(sch, &sch->q);
+ return __qdisc_queue_drop_head(sch, &sch->q, to_free);
}
static inline struct sk_buff *qdisc_peek_head(struct Qdisc *sch)
@@ -718,19 +701,21 @@ static inline struct sk_buff *qdisc_dequeue_peeked(struct Qdisc *sch)
return skb;
}
-static inline void __qdisc_reset_queue(struct Qdisc *sch,
- struct sk_buff_head *list)
+static inline void __qdisc_reset_queue(struct sk_buff_head *list)
{
/*
* We do not know the backlog in bytes of this list, it
* is up to the caller to correct it
*/
- __skb_queue_purge(list);
+ if (!skb_queue_empty(list)) {
+ rtnl_kfree_skbs(list->next, list->prev);
+ __skb_queue_head_init(list);
+ }
}
static inline void qdisc_reset_queue(struct Qdisc *sch)
{
- __qdisc_reset_queue(sch, &sch->q);
+ __qdisc_reset_queue(&sch->q);
sch->qstats.backlog = 0;
}
@@ -751,46 +736,19 @@ static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new,
return old;
}
-static inline unsigned int __qdisc_queue_drop(struct Qdisc *sch,
- struct sk_buff_head *list)
+static inline void rtnl_qdisc_drop(struct sk_buff *skb, struct Qdisc *sch)
{
- struct sk_buff *skb = __qdisc_dequeue_tail(sch, list);
-
- if (likely(skb != NULL)) {
- unsigned int len = qdisc_pkt_len(skb);
- kfree_skb(skb);
- return len;
- }
-
- return 0;
-}
-
-static inline unsigned int qdisc_queue_drop(struct Qdisc *sch)
-{
- return __qdisc_queue_drop(sch, &sch->q);
-}
-
-static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch)
-{
- kfree_skb(skb);
+ rtnl_kfree_skbs(skb, skb);
qdisc_qstats_drop(sch);
-
- return NET_XMIT_DROP;
}
-static inline int qdisc_reshape_fail(struct sk_buff *skb, struct Qdisc *sch)
+
+static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch,
+ struct sk_buff **to_free)
{
+ __qdisc_drop(skb, to_free);
qdisc_qstats_drop(sch);
-#ifdef CONFIG_NET_CLS_ACT
- if (sch->reshape_fail == NULL || sch->reshape_fail(skb, sch))
- goto drop;
-
- return NET_XMIT_SUCCESS;
-
-drop:
-#endif
- kfree_skb(skb);
return NET_XMIT_DROP;
}
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index b392ac8382f2..632e205ca54b 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -186,6 +186,10 @@ void sctp_assocs_proc_exit(struct net *net);
int sctp_remaddr_proc_init(struct net *net);
void sctp_remaddr_proc_exit(struct net *net);
+/*
+ * sctp/offload.c
+ */
+int sctp_offload_init(void);
/*
* Module global variables
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 16b013a6191c..ce93c4b10d26 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -59,6 +59,7 @@
#include <linux/workqueue.h> /* We need tq_struct. */
#include <linux/sctp.h> /* We need sctp* header structs. */
#include <net/sctp/auth.h> /* We need auth specific structs */
+#include <net/ip.h> /* For inet_skb_parm */
/* A convenience structure for handling sockaddr structures.
* We should wean ourselves off this.
@@ -566,6 +567,9 @@ struct sctp_chunk {
/* This points to the sk_buff containing the actual data. */
struct sk_buff *skb;
+ /* In case of GSO packets, this will store the head one */
+ struct sk_buff *head_skb;
+
/* These are the SCTP headers by reverse order in a packet.
* Note that some of these may happen more than once. In that
* case, we point at the "current" one, whatever that means
@@ -599,6 +603,16 @@ struct sctp_chunk {
/* This needs to be recoverable for SCTP_SEND_FAILED events. */
struct sctp_sndrcvinfo sinfo;
+ /* We use this field to record param for prsctp policies,
+ * for TTL policy, it is the time_to_drop of this chunk,
+ * for RTX policy, it is the max_sent_count of this chunk,
+ * for PRIO policy, it is the priority of this chunk.
+ */
+ unsigned long prsctp_param;
+
+ /* How many times this chunk have been sent, for prsctp RTX policy */
+ int sent_count;
+
/* Which association does this belong to? */
struct sctp_association *asoc;
@@ -696,6 +710,8 @@ struct sctp_packet {
size_t overhead;
/* This is the total size of all chunks INCLUDING padding. */
size_t size;
+ /* This is the maximum size this packet may have */
+ size_t max_size;
/* The packet is destined for this transport address.
* The function we finally use to pass down to the next lower
@@ -1069,12 +1085,36 @@ void sctp_retransmit(struct sctp_outq *, struct sctp_transport *,
sctp_retransmit_reason_t);
void sctp_retransmit_mark(struct sctp_outq *, struct sctp_transport *, __u8);
int sctp_outq_uncork(struct sctp_outq *, gfp_t gfp);
+void sctp_prsctp_prune(struct sctp_association *asoc,
+ struct sctp_sndrcvinfo *sinfo, int msg_len);
/* Uncork and flush an outqueue. */
static inline void sctp_outq_cork(struct sctp_outq *q)
{
q->cork = 1;
}
+/* SCTP skb control block.
+ * sctp_input_cb is currently used on rx and sock rx queue
+ */
+struct sctp_input_cb {
+ union {
+ struct inet_skb_parm h4;
+#if IS_ENABLED(CONFIG_IPV6)
+ struct inet6_skb_parm h6;
+#endif
+ } header;
+ struct sctp_chunk *chunk;
+ struct sctp_af *af;
+};
+#define SCTP_INPUT_CB(__skb) ((struct sctp_input_cb *)&((__skb)->cb[0]))
+
+static inline const struct sk_buff *sctp_gso_headskb(const struct sk_buff *skb)
+{
+ const struct sctp_chunk *chunk = SCTP_INPUT_CB(skb)->chunk;
+
+ return chunk->head_skb ? : skb;
+}
+
/* These bind address data fields common between endpoints and associations */
struct sctp_bind_addr {
@@ -1251,7 +1291,8 @@ struct sctp_endpoint {
/* SCTP-AUTH: endpoint shared keys */
struct list_head endpoint_shared_keys;
__u16 active_key_id;
- __u8 auth_enable;
+ __u8 auth_enable:1,
+ prsctp_enable:1;
};
/* Recover the outter endpoint structure. */
@@ -1843,9 +1884,15 @@ struct sctp_association {
__u16 active_key_id;
__u8 need_ecne:1, /* Need to send an ECNE Chunk? */
- temp:1; /* Is it a temporary association? */
+ temp:1, /* Is it a temporary association? */
+ prsctp_enable:1;
struct sctp_priv_assoc_stats stats;
+
+ int sent_cnt_removable;
+
+ __u64 abandoned_unsent[SCTP_PR_INDEX(MAX) + 1];
+ __u64 abandoned_sent[SCTP_PR_INDEX(MAX) + 1];
};
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
index cccdcfd14973..2c098cd7e7e2 100644
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -48,15 +48,15 @@
*/
struct sctp_ulpevent {
struct sctp_association *asoc;
- __u16 stream;
- __u16 ssn;
- __u16 flags;
+ struct sctp_chunk *chunk;
+ unsigned int rmem_len;
__u32 ppid;
__u32 tsn;
__u32 cumtsn;
- int msg_flags;
- int iif;
- unsigned int rmem_len;
+ __u16 stream;
+ __u16 ssn;
+ __u16 flags;
+ __u16 msg_flags;
};
/* Retrieve the skb this event sits inside of. */
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 1d8e158241da..62f6a967a1b7 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -227,6 +227,8 @@ void switchdev_port_fwd_mark_set(struct net_device *dev,
struct net_device *group_dev,
bool joining);
+bool switchdev_port_same_parent_id(struct net_device *a,
+ struct net_device *b);
#else
static inline void switchdev_deferred_process(void)
@@ -351,6 +353,12 @@ static inline void switchdev_port_fwd_mark_set(struct net_device *dev,
{
}
+static inline bool switchdev_port_same_parent_id(struct net_device *a,
+ struct net_device *b)
+{
+ return false;
+}
+
#endif
#endif /* _LINUX_SWITCHDEV_H_ */
diff --git a/include/net/tc_act/tc_bpf.h b/include/net/tc_act/tc_bpf.h
index 958d69cfb19c..2b94673a3dbc 100644
--- a/include/net/tc_act/tc_bpf.h
+++ b/include/net/tc_act/tc_bpf.h
@@ -14,7 +14,7 @@
#include <net/act_api.h>
struct tcf_bpf {
- struct tcf_common common;
+ struct tc_action common;
struct bpf_prog __rcu *filter;
union {
u32 bpf_fd;
@@ -23,7 +23,6 @@ struct tcf_bpf {
struct sock_filter *bpf_ops;
const char *bpf_name;
};
-#define to_bpf(a) \
- container_of(a->priv, struct tcf_bpf, common)
+#define to_bpf(a) ((struct tcf_bpf *)a)
#endif /* __NET_TC_BPF_H */
diff --git a/include/net/tc_act/tc_connmark.h b/include/net/tc_act/tc_connmark.h
index 02caa406611b..59b515d32bb4 100644
--- a/include/net/tc_act/tc_connmark.h
+++ b/include/net/tc_act/tc_connmark.h
@@ -4,12 +4,11 @@
#include <net/act_api.h>
struct tcf_connmark_info {
- struct tcf_common common;
+ struct tc_action common;
struct net *net;
u16 zone;
};
-#define to_connmark(a) \
- container_of(a->priv, struct tcf_connmark_info, common)
+#define to_connmark(a) ((struct tcf_connmark_info *)a)
#endif /* __NET_TC_CONNMARK_H */
diff --git a/include/net/tc_act/tc_csum.h b/include/net/tc_act/tc_csum.h
index fa8f5fac65e9..f31fb6331a53 100644
--- a/include/net/tc_act/tc_csum.h
+++ b/include/net/tc_act/tc_csum.h
@@ -5,11 +5,10 @@
#include <net/act_api.h>
struct tcf_csum {
- struct tcf_common common;
+ struct tc_action common;
u32 update_flags;
};
-#define to_tcf_csum(a) \
- container_of(a->priv,struct tcf_csum,common)
+#define to_tcf_csum(a) ((struct tcf_csum *)a)
#endif /* __NET_TC_CSUM_H */
diff --git a/include/net/tc_act/tc_defact.h b/include/net/tc_act/tc_defact.h
index 9763dcbb9bc3..d47f040a3bdf 100644
--- a/include/net/tc_act/tc_defact.h
+++ b/include/net/tc_act/tc_defact.h
@@ -4,11 +4,10 @@
#include <net/act_api.h>
struct tcf_defact {
- struct tcf_common common;
- u32 tcfd_datalen;
- void *tcfd_defdata;
+ struct tc_action common;
+ u32 tcfd_datalen;
+ void *tcfd_defdata;
};
-#define to_defact(a) \
- container_of(a->priv, struct tcf_defact, common)
+#define to_defact(a) ((struct tcf_defact *)a)
#endif /* __NET_TC_DEF_H */
diff --git a/include/net/tc_act/tc_gact.h b/include/net/tc_act/tc_gact.h
index 93c520b83d10..b6f173910226 100644
--- a/include/net/tc_act/tc_gact.h
+++ b/include/net/tc_act/tc_gact.h
@@ -5,7 +5,7 @@
#include <linux/tc_act/tc_gact.h>
struct tcf_gact {
- struct tcf_common common;
+ struct tc_action common;
#ifdef CONFIG_GACT_PROB
u16 tcfg_ptype;
u16 tcfg_pval;
@@ -13,8 +13,7 @@ struct tcf_gact {
atomic_t packets;
#endif
};
-#define to_gact(a) \
- container_of(a->priv, struct tcf_gact, common)
+#define to_gact(a) ((struct tcf_gact *)a)
static inline bool is_tcf_gact_shot(const struct tc_action *a)
{
@@ -24,7 +23,7 @@ static inline bool is_tcf_gact_shot(const struct tc_action *a)
if (a->ops && a->ops->type != TCA_ACT_GACT)
return false;
- gact = a->priv;
+ gact = to_gact(a);
if (gact->tcf_action == TC_ACT_SHOT)
return true;
diff --git a/include/net/tc_act/tc_ife.h b/include/net/tc_act/tc_ife.h
index c55facd17b7e..5164bd7a38fb 100644
--- a/include/net/tc_act/tc_ife.h
+++ b/include/net/tc_act/tc_ife.h
@@ -8,7 +8,7 @@
#define IFE_METAHDRLEN 2
struct tcf_ife_info {
- struct tcf_common common;
+ struct tc_action common;
u8 eth_dst[ETH_ALEN];
u8 eth_src[ETH_ALEN];
u16 eth_type;
@@ -16,8 +16,7 @@ struct tcf_ife_info {
/* list of metaids allowed */
struct list_head metalist;
};
-#define to_ife(a) \
- container_of(a->priv, struct tcf_ife_info, common)
+#define to_ife(a) ((struct tcf_ife_info *)a)
struct tcf_meta_info {
const struct tcf_meta_ops *ops;
diff --git a/include/net/tc_act/tc_ipt.h b/include/net/tc_act/tc_ipt.h
index c0f4193f432c..31309766e379 100644
--- a/include/net/tc_act/tc_ipt.h
+++ b/include/net/tc_act/tc_ipt.h
@@ -6,12 +6,11 @@
struct xt_entry_target;
struct tcf_ipt {
- struct tcf_common common;
+ struct tc_action common;
u32 tcfi_hook;
char *tcfi_tname;
struct xt_entry_target *tcfi_t;
};
-#define to_ipt(a) \
- container_of(a->priv, struct tcf_ipt, common)
+#define to_ipt(a) ((struct tcf_ipt *)a)
#endif /* __NET_TC_IPT_H */
diff --git a/include/net/tc_act/tc_mirred.h b/include/net/tc_act/tc_mirred.h
index e891835eb74e..62770add15bd 100644
--- a/include/net/tc_act/tc_mirred.h
+++ b/include/net/tc_act/tc_mirred.h
@@ -5,15 +5,14 @@
#include <linux/tc_act/tc_mirred.h>
struct tcf_mirred {
- struct tcf_common common;
+ struct tc_action common;
int tcfm_eaction;
int tcfm_ifindex;
int tcfm_ok_push;
struct net_device __rcu *tcfm_dev;
struct list_head tcfm_list;
};
-#define to_mirred(a) \
- container_of(a->priv, struct tcf_mirred, common)
+#define to_mirred(a) ((struct tcf_mirred *)a)
static inline bool is_tcf_mirred_redirect(const struct tc_action *a)
{
@@ -24,6 +23,15 @@ static inline bool is_tcf_mirred_redirect(const struct tc_action *a)
return false;
}
+static inline bool is_tcf_mirred_mirror(const struct tc_action *a)
+{
+#ifdef CONFIG_NET_CLS_ACT
+ if (a->ops && a->ops->type == TCA_ACT_MIRRED)
+ return to_mirred(a)->tcfm_eaction == TCA_EGRESS_MIRROR;
+#endif
+ return false;
+}
+
static inline int tcf_mirred_ifindex(const struct tc_action *a)
{
return to_mirred(a)->tcfm_ifindex;
diff --git a/include/net/tc_act/tc_nat.h b/include/net/tc_act/tc_nat.h
index 63d8e9ca9d99..56681a320612 100644
--- a/include/net/tc_act/tc_nat.h
+++ b/include/net/tc_act/tc_nat.h
@@ -5,7 +5,7 @@
#include <net/act_api.h>
struct tcf_nat {
- struct tcf_common common;
+ struct tc_action common;
__be32 old_addr;
__be32 new_addr;
@@ -13,9 +13,6 @@ struct tcf_nat {
u32 flags;
};
-static inline struct tcf_nat *to_tcf_nat(struct tc_action *a)
-{
- return container_of(a->priv, struct tcf_nat, common);
-}
+#define to_tcf_nat(a) ((struct tcf_nat *)a)
#endif /* __NET_TC_NAT_H */
diff --git a/include/net/tc_act/tc_pedit.h b/include/net/tc_act/tc_pedit.h
index 5b80998879c7..29e38d6823df 100644
--- a/include/net/tc_act/tc_pedit.h
+++ b/include/net/tc_act/tc_pedit.h
@@ -4,12 +4,11 @@
#include <net/act_api.h>
struct tcf_pedit {
- struct tcf_common common;
+ struct tc_action common;
unsigned char tcfp_nkeys;
unsigned char tcfp_flags;
struct tc_pedit_key *tcfp_keys;
};
-#define to_pedit(a) \
- container_of(a->priv, struct tcf_pedit, common)
+#define to_pedit(a) ((struct tcf_pedit *)a)
#endif /* __NET_TC_PED_H */
diff --git a/include/net/tc_act/tc_skbedit.h b/include/net/tc_act/tc_skbedit.h
index b496d5ad7d42..5767e9dbcf92 100644
--- a/include/net/tc_act/tc_skbedit.h
+++ b/include/net/tc_act/tc_skbedit.h
@@ -23,15 +23,14 @@
#include <linux/tc_act/tc_skbedit.h>
struct tcf_skbedit {
- struct tcf_common common;
- u32 flags;
- u32 priority;
- u32 mark;
- u16 queue_mapping;
- /* XXX: 16-bit pad here? */
+ struct tc_action common;
+ u32 flags;
+ u32 priority;
+ u32 mark;
+ u16 queue_mapping;
+ u16 ptype;
};
-#define to_skbedit(a) \
- container_of(a->priv, struct tcf_skbedit, common)
+#define to_skbedit(a) ((struct tcf_skbedit *)a)
/* Return true iff action is mark */
static inline bool is_tcf_skbedit_mark(const struct tc_action *a)
diff --git a/include/net/tc_act/tc_vlan.h b/include/net/tc_act/tc_vlan.h
index 93b70ade1ff3..e29f52e8bdf1 100644
--- a/include/net/tc_act/tc_vlan.h
+++ b/include/net/tc_act/tc_vlan.h
@@ -16,12 +16,11 @@
#define VLAN_F_PUSH 0x2
struct tcf_vlan {
- struct tcf_common common;
+ struct tc_action common;
int tcfv_action;
u16 tcfv_push_vid;
__be16 tcfv_push_proto;
};
-#define to_vlan(a) \
- container_of(a->priv, struct tcf_vlan, common)
+#define to_vlan(a) ((struct tcf_vlan *)a)
#endif /* __NET_TC_VLAN_H */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 0bcc70f4e1fb..c00e7d51bb18 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -589,7 +589,7 @@ static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
* On the other hand, for extremely large MSS devices, handling
* smaller than MSS windows in this way does make sense.
*/
- if (tp->max_window >= 512)
+ if (tp->max_window > TCP_MSS_DEFAULT)
cutoff = (tp->max_window >> 1);
else
cutoff = tp->max_window;
@@ -767,6 +767,7 @@ struct tcp_skb_cb {
union {
struct {
/* There is space for up to 20 bytes */
+ __u32 in_flight;/* Bytes in flight when packet sent */
} tx; /* only used for outgoing skbs */
union {
struct inet_skb_parm h4;
@@ -859,6 +860,7 @@ union tcp_cc_info;
struct ack_sample {
u32 pkts_acked;
s32 rtt_us;
+ u32 in_flight;
};
struct tcp_congestion_ops {
@@ -1382,7 +1384,7 @@ union tcp_md5sum_block {
/* - pool: digest algorithm, hash description and scratch buffer */
struct tcp_md5sig_pool {
struct ahash_request *md5_req;
- union tcp_md5sum_block md5_blk;
+ void *scratch;
};
/* - functions */
@@ -1418,7 +1420,6 @@ static inline void tcp_put_md5sig_pool(void)
local_bh_enable();
}
-int tcp_md5_hash_header(struct tcp_md5sig_pool *, const struct tcphdr *);
int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *, const struct sk_buff *,
unsigned int header_len);
int tcp_md5_hash_key(struct tcp_md5sig_pool *hp,
diff --git a/include/net/udp.h b/include/net/udp.h
index ae07f375370d..8894d7144189 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -160,8 +160,8 @@ void udp_set_csum(bool nocheck, struct sk_buff *skb,
static inline void udp_csum_pull_header(struct sk_buff *skb)
{
- if (skb->ip_summed == CHECKSUM_NONE)
- skb->csum = csum_partial(udp_hdr(skb), sizeof(struct udphdr),
+ if (!skb->csum_valid && skb->ip_summed == CHECKSUM_NONE)
+ skb->csum = csum_partial(skb->data, sizeof(struct udphdr),
skb->csum);
skb_pull_rcsum(skb, sizeof(struct udphdr));
UDP_SKB_CB(skb)->cscov -= sizeof(struct udphdr);
diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
index 9d14f707e534..02c5be037451 100644
--- a/include/net/udp_tunnel.h
+++ b/include/net/udp_tunnel.h
@@ -84,6 +84,46 @@ struct udp_tunnel_sock_cfg {
void setup_udp_tunnel_sock(struct net *net, struct socket *sock,
struct udp_tunnel_sock_cfg *sock_cfg);
+/* -- List of parsable UDP tunnel types --
+ *
+ * Adding to this list will result in serious debate. The main issue is
+ * that this list is essentially a list of workarounds for either poorly
+ * designed tunnels, or poorly designed device offloads.
+ *
+ * The parsing supported via these types should really be used for Rx
+ * traffic only as the network stack will have already inserted offsets for
+ * the location of the headers in the skb. In addition any ports that are
+ * pushed should be kept within the namespace without leaking to other
+ * devices such as VFs or other ports on the same device.
+ *
+ * It is strongly encouraged to use CHECKSUM_COMPLETE for Rx to avoid the
+ * need to use this for Rx checksum offload. It should not be necessary to
+ * call this function to perform Tx offloads on outgoing traffic.
+ */
+enum udp_parsable_tunnel_type {
+ UDP_TUNNEL_TYPE_VXLAN, /* RFC 7348 */
+ UDP_TUNNEL_TYPE_GENEVE, /* draft-ietf-nvo3-geneve */
+ UDP_TUNNEL_TYPE_VXLAN_GPE, /* draft-ietf-nvo3-vxlan-gpe */
+};
+
+struct udp_tunnel_info {
+ unsigned short type;
+ sa_family_t sa_family;
+ __be16 port;
+};
+
+/* Notify network devices of offloadable types */
+void udp_tunnel_push_rx_port(struct net_device *dev, struct socket *sock,
+ unsigned short type);
+void udp_tunnel_notify_add_rx_port(struct socket *sock, unsigned short type);
+void udp_tunnel_notify_del_rx_port(struct socket *sock, unsigned short type);
+
+static inline void udp_tunnel_get_rx_info(struct net_device *dev)
+{
+ ASSERT_RTNL();
+ call_netdevice_notifiers(NETDEV_UDP_TUNNEL_PUSH_INFO, dev);
+}
+
/* Transmit the skb using UDP encapsulation. */
void udp_tunnel_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 tos, __u8 ttl,
@@ -105,12 +145,14 @@ struct metadata_dst *udp_tun_rx_dst(struct sk_buff *skb, unsigned short family,
__be16 flags, __be64 tunnel_id,
int md_size);
+#ifdef CONFIG_INET
static inline int udp_tunnel_handle_offloads(struct sk_buff *skb, bool udp_csum)
{
int type = udp_csum ? SKB_GSO_UDP_TUNNEL_CSUM : SKB_GSO_UDP_TUNNEL;
return iptunnel_handle_offloads(skb, type);
}
+#endif
static inline void udp_tunnel_encap_enable(struct socket *sock)
{
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index b8803165df91..b96d0360c095 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -1,13 +1,10 @@
#ifndef __NET_VXLAN_H
#define __NET_VXLAN_H 1
-#include <linux/ip.h>
-#include <linux/ipv6.h>
#include <linux/if_vlan.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/udp.h>
+#include <net/udp_tunnel.h>
#include <net/dst_metadata.h>
+#include <net/udp_tunnel.h>
/* VXLAN protocol (RFC 7348) header:
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -392,12 +389,6 @@ static inline __be32 vxlan_compute_rco(unsigned int start, unsigned int offset)
return vni_field;
}
-static inline void vxlan_get_rx_port(struct net_device *netdev)
-{
- ASSERT_RTNL();
- call_netdevice_notifiers(NETDEV_OFFLOAD_PUSH_VXLAN, netdev);
-}
-
static inline unsigned short vxlan_get_sk_family(struct vxlan_sock *vs)
{
return vs->sock->sk->sk_family;
diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h
index 1443d79e4fe6..1791a12cfa85 100644
--- a/include/ras/ras_event.h
+++ b/include/ras/ras_event.h
@@ -147,7 +147,7 @@ TRACE_EVENT(mc_event,
__entry->error_count,
mc_event_error_type(__entry->error_type),
__entry->error_count > 1 ? "s" : "",
- ((char *)__get_str(msg))[0] ? " " : "",
+ __get_str(msg)[0] ? " " : "",
__get_str(msg),
__get_str(label),
__entry->mc_index,
@@ -157,7 +157,7 @@ TRACE_EVENT(mc_event,
__entry->address,
1 << __entry->grain_bits,
__entry->syndrome,
- ((char *)__get_str(driver_detail))[0] ? " " : "",
+ __get_str(driver_detail)[0] ? " " : "",
__get_str(driver_detail))
);
diff --git a/include/scsi/fc/fc_fip.h b/include/scsi/fc/fc_fip.h
index ae25d4ab2548..9710254fd98c 100644
--- a/include/scsi/fc/fc_fip.h
+++ b/include/scsi/fc/fc_fip.h
@@ -22,7 +22,7 @@
/*
* This version is based on:
* http://www.t11.org/ftp/t11/pub/fc/bb-5/08-543v1.pdf
- * and T11 FC-BB-6 10-019v4.pdf (June 2010 VN2VN proposal)
+ * and T11 FC-BB-6 13-091v5.pdf (December 2013 VN2VN proposal)
*/
#define FIP_DEF_PRI 128 /* default selection priority */
@@ -109,8 +109,9 @@ enum fip_reset_subcode {
* Subcodes for FIP_OP_VLAN.
*/
enum fip_vlan_subcode {
- FIP_SC_VL_REQ = 1, /* request */
- FIP_SC_VL_REP = 2, /* reply */
+ FIP_SC_VL_REQ = 1, /* vlan request */
+ FIP_SC_VL_NOTE = 2, /* vlan notification */
+ FIP_SC_VL_VN2VN_NOTE = 3, /* VN2VN vlan notification */
};
/*
@@ -130,6 +131,8 @@ enum fip_vn2vn_subcode {
enum fip_flag {
FIP_FL_FPMA = 0x8000, /* supports FPMA fabric-provided MACs */
FIP_FL_SPMA = 0x4000, /* supports SPMA server-provided MACs */
+ FIP_FL_FCF = 0x0020, /* originated from a controlling FCF */
+ FIP_FL_FDF = 0x0010, /* originated from an FDF */
FIP_FL_REC_OR_P2P = 0x0008, /* configured addr or point-to-point */
FIP_FL_AVAIL = 0x0004, /* available for FLOGI/ELP */
FIP_FL_SOL = 0x0002, /* this is a solicited message */
@@ -161,7 +164,9 @@ enum fip_desc_type {
FIP_DT_VLAN = 14, /* vlan number */
FIP_DT_FC4F = 15, /* FC-4 features */
FIP_DT_LIMIT, /* max defined desc_type + 1 */
- FIP_DT_VENDOR_BASE = 128, /* first vendor-specific desc_type */
+ FIP_DT_NON_CRITICAL = 128, /* First non-critical descriptor */
+ FIP_DT_CLR_VLINKS = 128, /* Clear virtual links reason code */
+ FIP_DT_VENDOR_BASE = 241, /* first vendor-specific desc_type */
};
/*
@@ -259,6 +264,14 @@ enum fip_fka_flags {
/* FIP_DT_FKA flags */
/*
+ * FIP_DT_VLAN descriptor
+ */
+struct fip_vlan_desc {
+ struct fip_desc fd_desc;
+ __be16 fd_vlan; /* Note: highest 4 bytes are unused */
+} __attribute__((packed));
+
+/*
* FIP_DT_FC4F - FC-4 features.
*/
struct fip_fc4_feat {
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 93d14daf0994..7428a53257ca 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -878,6 +878,7 @@ struct fc_lport {
struct libfc_function_template tt;
u8 link_up;
u8 qfull;
+ u16 vlan;
enum fc_lport_state state;
unsigned long boot_time;
struct fc_host_statistics host_stats;
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index de7e3ee60f0c..722d3264d3bf 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -78,10 +78,12 @@ enum fip_state {
* The mode is the state that is to be entered after link up.
* It must not change after fcoe_ctlr_init() sets it.
*/
-#define FIP_MODE_AUTO FIP_ST_AUTO
-#define FIP_MODE_NON_FIP FIP_ST_NON_FIP
-#define FIP_MODE_FABRIC FIP_ST_ENABLED
-#define FIP_MODE_VN2VN FIP_ST_VNMP_START
+enum fip_mode {
+ FIP_MODE_AUTO = FIP_ST_AUTO,
+ FIP_MODE_NON_FIP,
+ FIP_MODE_FABRIC,
+ FIP_MODE_VN2VN,
+};
/**
* struct fcoe_ctlr - FCoE Controller and FIP state
@@ -108,8 +110,10 @@ enum fip_state {
* @flogi_req_send: send of FLOGI requested
* @flogi_count: number of FLOGI attempts in AUTO mode.
* @map_dest: use the FC_MAP mode for destination MAC addresses.
+ * @fip_resp: start FIP VLAN discovery responder
* @spma: supports SPMA server-provided MACs mode
* @probe_tries: number of FC_IDs probed
+ * @priority: DCBx FCoE APP priority
* @dest_addr: MAC address of the selected FC forwarder.
* @ctl_src_addr: the native MAC address of our local port.
* @send: LLD-supplied function to handle sending FIP Ethernet frames
@@ -124,7 +128,7 @@ enum fip_state {
*/
struct fcoe_ctlr {
enum fip_state state;
- enum fip_state mode;
+ enum fip_mode mode;
struct fc_lport *lp;
struct fcoe_fcf *sel_fcf;
struct list_head fcfs;
@@ -147,7 +151,8 @@ struct fcoe_ctlr {
u16 flogi_oxid;
u8 flogi_req_send;
u8 flogi_count;
- u8 map_dest;
+ bool map_dest;
+ bool fip_resp;
u8 spma;
u8 probe_tries;
u8 priority;
@@ -311,7 +316,7 @@ struct fcoe_transport {
struct list_head list;
bool (*match) (struct net_device *device);
int (*alloc) (struct net_device *device);
- int (*create) (struct net_device *device, enum fip_state fip_mode);
+ int (*create) (struct net_device *device, enum fip_mode fip_mode);
int (*destroy) (struct net_device *device);
int (*enable) (struct net_device *device);
int (*disable) (struct net_device *device);
@@ -319,14 +324,16 @@ struct fcoe_transport {
/**
* struct fcoe_percpu_s - The context for FCoE receive thread(s)
- * @thread: The thread context
+ * @kthread: The thread context (used by bnx2fc)
+ * @work: The work item (used by fcoe)
* @fcoe_rx_list: The queue of pending packets to process
* @page: The memory page for calculating frame trailer CRCs
* @crc_eof_offset: The offset into the CRC page pointing to available
* memory for a new trailer
*/
struct fcoe_percpu_s {
- struct task_struct *thread;
+ struct task_struct *kthread;
+ struct work_struct work;
struct sk_buff_head fcoe_rx_list;
struct page *crc_eof_page;
int crc_eof_offset;
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index a6c346df290d..8a9563144890 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -94,7 +94,6 @@ struct scsi_device {
spinlock_t list_lock;
struct list_head cmd_list; /* queue of in use SCSI Command structures */
struct list_head starved_entry;
- struct scsi_cmnd *current_cmnd; /* currently active command */
unsigned short queue_depth; /* How deep of a queue we want */
unsigned short max_queue_depth; /* max queue depth */
unsigned short last_queue_full_depth; /* These two are used by */
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 76e9d278c334..0dee7afa93d6 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -495,9 +495,6 @@ struct scsi_host_template {
*/
unsigned int cmd_size;
struct scsi_host_cmd_pool *cmd_pool;
-
- /* temporary flag to disable blk-mq I/O path */
- bool disable_blk_mq;
};
/*
@@ -778,7 +775,8 @@ extern bool scsi_use_blk_mq;
static inline bool shost_use_blk_mq(struct Scsi_Host *shost)
{
- return shost->use_blk_mq;
+ return scsi_use_blk_mq;
+
}
extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *);
diff --git a/include/soc/fsl/qe/immap_qe.h b/include/soc/fsl/qe/immap_qe.h
index bedbff891423..c76ef30b05ba 100644
--- a/include/soc/fsl/qe/immap_qe.h
+++ b/include/soc/fsl/qe/immap_qe.h
@@ -159,10 +159,7 @@ struct spi {
/* SI */
struct si1 {
- __be16 siamr1; /* SI1 TDMA mode register */
- __be16 sibmr1; /* SI1 TDMB mode register */
- __be16 sicmr1; /* SI1 TDMC mode register */
- __be16 sidmr1; /* SI1 TDMD mode register */
+ __be16 sixmr1[4]; /* SI1 TDMx (x = A B C D) mode register */
u8 siglmr1_h; /* SI1 global mode register high */
u8 res0[0x1];
u8 sicmdr1_h; /* SI1 command register high */
diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h
index 33b29ead3d55..70339d7958c0 100644
--- a/include/soc/fsl/qe/qe.h
+++ b/include/soc/fsl/qe/qe.h
@@ -80,6 +80,8 @@ enum qe_clock {
QE_CLK22, /* Clock 22 */
QE_CLK23, /* Clock 23 */
QE_CLK24, /* Clock 24 */
+ QE_RSYNC_PIN, /* RSYNC from pin */
+ QE_TSYNC_PIN, /* TSYNC from pin */
QE_CLK_DUMMY
};
@@ -242,6 +244,22 @@ static inline int qe_alive_during_sleep(void)
#define qe_muram_addr cpm_muram_addr
#define qe_muram_offset cpm_muram_offset
+#define qe_setbits32(_addr, _v) iowrite32be(ioread32be(_addr) | (_v), (_addr))
+#define qe_clrbits32(_addr, _v) iowrite32be(ioread32be(_addr) & ~(_v), (_addr))
+
+#define qe_setbits16(_addr, _v) iowrite16be(ioread16be(_addr) | (_v), (_addr))
+#define qe_clrbits16(_addr, _v) iowrite16be(ioread16be(_addr) & ~(_v), (_addr))
+
+#define qe_setbits8(_addr, _v) iowrite8(ioread8(_addr) | (_v), (_addr))
+#define qe_clrbits8(_addr, _v) iowrite8(ioread8(_addr) & ~(_v), (_addr))
+
+#define qe_clrsetbits32(addr, clear, set) \
+ iowrite32be((ioread32be(addr) & ~(clear)) | (set), (addr))
+#define qe_clrsetbits16(addr, clear, set) \
+ iowrite16be((ioread16be(addr) & ~(clear)) | (set), (addr))
+#define qe_clrsetbits8(addr, clear, set) \
+ iowrite8((ioread8(addr) & ~(clear)) | (set), (addr))
+
/* Structure that defines QE firmware binary files.
*
* See Documentation/powerpc/qe_firmware.txt for a description of these
@@ -639,6 +657,7 @@ struct ucc_slow_pram {
#define UCC_SLOW_GUMR_L_MODE_QMC 0x00000002
/* General UCC FAST Mode Register */
+#define UCC_FAST_GUMR_LOOPBACK 0x40000000
#define UCC_FAST_GUMR_TCI 0x20000000
#define UCC_FAST_GUMR_TRX 0x10000000
#define UCC_FAST_GUMR_TTX 0x08000000
diff --git a/include/soc/fsl/qe/qe_tdm.h b/include/soc/fsl/qe/qe_tdm.h
new file mode 100644
index 000000000000..a1664b635f1a
--- /dev/null
+++ b/include/soc/fsl/qe/qe_tdm.h
@@ -0,0 +1,94 @@
+/*
+ * Internal header file for QE TDM mode routines.
+ *
+ * Copyright (C) 2016 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Authors: Zhao Qiang <qiang.zhao@nxp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version
+ */
+
+#ifndef _QE_TDM_H_
+#define _QE_TDM_H_
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+
+#include <soc/fsl/qe/immap_qe.h>
+#include <soc/fsl/qe/qe.h>
+
+#include <soc/fsl/qe/ucc.h>
+#include <soc/fsl/qe/ucc_fast.h>
+
+/* SI RAM entries */
+#define SIR_LAST 0x0001
+#define SIR_BYTE 0x0002
+#define SIR_CNT(x) ((x) << 2)
+#define SIR_CSEL(x) ((x) << 5)
+#define SIR_SGS 0x0200
+#define SIR_SWTR 0x4000
+#define SIR_MCC 0x8000
+#define SIR_IDLE 0
+
+/* SIxMR fields */
+#define SIMR_SAD(x) ((x) << 12)
+#define SIMR_SDM_NORMAL 0x0000
+#define SIMR_SDM_INTERNAL_LOOPBACK 0x0800
+#define SIMR_SDM_MASK 0x0c00
+#define SIMR_CRT 0x0040
+#define SIMR_SL 0x0020
+#define SIMR_CE 0x0010
+#define SIMR_FE 0x0008
+#define SIMR_GM 0x0004
+#define SIMR_TFSD(n) (n)
+#define SIMR_RFSD(n) ((n) << 8)
+
+enum tdm_ts_t {
+ TDM_TX_TS,
+ TDM_RX_TS
+};
+
+enum tdm_framer_t {
+ TDM_FRAMER_T1,
+ TDM_FRAMER_E1
+};
+
+enum tdm_mode_t {
+ TDM_INTERNAL_LOOPBACK,
+ TDM_NORMAL
+};
+
+struct si_mode_info {
+ u8 simr_rfsd;
+ u8 simr_tfsd;
+ u8 simr_crt;
+ u8 simr_sl;
+ u8 simr_ce;
+ u8 simr_fe;
+ u8 simr_gm;
+};
+
+struct ucc_tdm_info {
+ struct ucc_fast_info uf_info;
+ struct si_mode_info si_info;
+};
+
+struct ucc_tdm {
+ u16 tdm_port; /* port for this tdm:TDMA,TDMB */
+ u32 siram_entry_id;
+ u16 __iomem *siram;
+ struct si1 __iomem *si_regs;
+ enum tdm_framer_t tdm_framer_type;
+ enum tdm_mode_t tdm_mode;
+ u8 num_of_ts; /* the number of timeslots in this tdm frame */
+ u32 tx_ts_mask; /* tx time slot mask */
+ u32 rx_ts_mask; /* rx time slot mask */
+};
+
+int ucc_of_parse_tdm(struct device_node *np, struct ucc_tdm *utdm,
+ struct ucc_tdm_info *ut_info);
+void ucc_tdm_init(struct ucc_tdm *utdm, struct ucc_tdm_info *ut_info);
+#endif
diff --git a/include/soc/fsl/qe/ucc.h b/include/soc/fsl/qe/ucc.h
index 894f14cbb044..6bbbb597f2af 100644
--- a/include/soc/fsl/qe/ucc.h
+++ b/include/soc/fsl/qe/ucc.h
@@ -41,6 +41,10 @@ int ucc_set_qe_mux_mii_mng(unsigned int ucc_num);
int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock,
enum comm_dir mode);
+int ucc_set_tdm_rxtx_clk(unsigned int tdm_num, enum qe_clock clock,
+ enum comm_dir mode);
+int ucc_set_tdm_rxtx_sync(unsigned int tdm_num, enum qe_clock clock,
+ enum comm_dir mode);
int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask);
diff --git a/include/soc/fsl/qe/ucc_fast.h b/include/soc/fsl/qe/ucc_fast.h
index df8ea7958c63..3ee9e7c1a7d7 100644
--- a/include/soc/fsl/qe/ucc_fast.h
+++ b/include/soc/fsl/qe/ucc_fast.h
@@ -21,19 +21,37 @@
#include <soc/fsl/qe/ucc.h>
-/* Receive BD's status */
+/* Receive BD's status and length*/
#define R_E 0x80000000 /* buffer empty */
#define R_W 0x20000000 /* wrap bit */
#define R_I 0x10000000 /* interrupt on reception */
#define R_L 0x08000000 /* last */
#define R_F 0x04000000 /* first */
-/* transmit BD's status */
+/* transmit BD's status and length*/
#define T_R 0x80000000 /* ready bit */
#define T_W 0x20000000 /* wrap bit */
#define T_I 0x10000000 /* interrupt on completion */
#define T_L 0x08000000 /* last */
+/* Receive BD's status */
+#define R_E_S 0x8000 /* buffer empty */
+#define R_W_S 0x2000 /* wrap bit */
+#define R_I_S 0x1000 /* interrupt on reception */
+#define R_L_S 0x0800 /* last */
+#define R_F_S 0x0400 /* first */
+#define R_CM_S 0x0200 /* continuous mode */
+#define R_CR_S 0x0004 /* crc */
+#define R_OV_S 0x0002 /* crc */
+
+/* transmit BD's status */
+#define T_R_S 0x8000 /* ready bit */
+#define T_W_S 0x2000 /* wrap bit */
+#define T_I_S 0x1000 /* interrupt on completion */
+#define T_L_S 0x0800 /* last */
+#define T_TC_S 0x0400 /* crc */
+#define T_TM_S 0x0200 /* continuous mode */
+
/* Rx Data buffer must be 4 bytes aligned in most cases */
#define UCC_FAST_RX_ALIGN 4
#define UCC_FAST_MRBLR_ALIGNMENT 4
@@ -118,9 +136,12 @@ enum ucc_fast_transparent_tcrc {
/* Fast UCC initialization structure */
struct ucc_fast_info {
int ucc_num;
+ int tdm_num;
enum qe_clock rx_clock;
enum qe_clock tx_clock;
- u32 regs;
+ enum qe_clock rx_sync;
+ enum qe_clock tx_sync;
+ resource_size_t regs;
int irq;
u32 uccm_mask;
int bd_mem_part;
diff --git a/include/trace/events/bcache.h b/include/trace/events/bcache.h
index 981acf74b14f..65673d8b81ac 100644
--- a/include/trace/events/bcache.h
+++ b/include/trace/events/bcache.h
@@ -27,7 +27,8 @@ DECLARE_EVENT_CLASS(bcache_request,
__entry->sector = bio->bi_iter.bi_sector;
__entry->orig_sector = bio->bi_iter.bi_sector - 16;
__entry->nr_sector = bio->bi_iter.bi_size >> 9;
- blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+ blk_fill_rwbs(__entry->rwbs, bio_op(bio), bio->bi_rw,
+ bio->bi_iter.bi_size);
),
TP_printk("%d,%d %s %llu + %u (from %d,%d @ %llu)",
@@ -101,7 +102,8 @@ DECLARE_EVENT_CLASS(bcache_bio,
__entry->dev = bio->bi_bdev->bd_dev;
__entry->sector = bio->bi_iter.bi_sector;
__entry->nr_sector = bio->bi_iter.bi_size >> 9;
- blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+ blk_fill_rwbs(__entry->rwbs, bio_op(bio), bio->bi_rw,
+ bio->bi_iter.bi_size);
),
TP_printk("%d,%d %s %llu + %u",
@@ -136,7 +138,8 @@ TRACE_EVENT(bcache_read,
__entry->dev = bio->bi_bdev->bd_dev;
__entry->sector = bio->bi_iter.bi_sector;
__entry->nr_sector = bio->bi_iter.bi_size >> 9;
- blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+ blk_fill_rwbs(__entry->rwbs, bio_op(bio), bio->bi_rw,
+ bio->bi_iter.bi_size);
__entry->cache_hit = hit;
__entry->bypass = bypass;
),
@@ -167,7 +170,8 @@ TRACE_EVENT(bcache_write,
__entry->inode = inode;
__entry->sector = bio->bi_iter.bi_sector;
__entry->nr_sector = bio->bi_iter.bi_size >> 9;
- blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+ blk_fill_rwbs(__entry->rwbs, bio_op(bio), bio->bi_rw,
+ bio->bi_iter.bi_size);
__entry->writeback = writeback;
__entry->bypass = bypass;
),
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index e8a5eca1dbe5..5a2a7592068f 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -84,7 +84,8 @@ DECLARE_EVENT_CLASS(block_rq_with_error,
0 : blk_rq_sectors(rq);
__entry->errors = rq->errors;
- blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq));
+ blk_fill_rwbs(__entry->rwbs, req_op(rq), rq->cmd_flags,
+ blk_rq_bytes(rq));
blk_dump_cmd(__get_str(cmd), rq);
),
@@ -162,7 +163,7 @@ TRACE_EVENT(block_rq_complete,
__entry->nr_sector = nr_bytes >> 9;
__entry->errors = rq->errors;
- blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, nr_bytes);
+ blk_fill_rwbs(__entry->rwbs, req_op(rq), rq->cmd_flags, nr_bytes);
blk_dump_cmd(__get_str(cmd), rq);
),
@@ -198,7 +199,8 @@ DECLARE_EVENT_CLASS(block_rq,
__entry->bytes = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ?
blk_rq_bytes(rq) : 0;
- blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq));
+ blk_fill_rwbs(__entry->rwbs, req_op(rq), rq->cmd_flags,
+ blk_rq_bytes(rq));
blk_dump_cmd(__get_str(cmd), rq);
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
),
@@ -272,7 +274,8 @@ TRACE_EVENT(block_bio_bounce,
bio->bi_bdev->bd_dev : 0;
__entry->sector = bio->bi_iter.bi_sector;
__entry->nr_sector = bio_sectors(bio);
- blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+ blk_fill_rwbs(__entry->rwbs, bio_op(bio), bio->bi_rw,
+ bio->bi_iter.bi_size);
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
),
@@ -310,7 +313,8 @@ TRACE_EVENT(block_bio_complete,
__entry->sector = bio->bi_iter.bi_sector;
__entry->nr_sector = bio_sectors(bio);
__entry->error = error;
- blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+ blk_fill_rwbs(__entry->rwbs, bio_op(bio), bio->bi_rw,
+ bio->bi_iter.bi_size);
),
TP_printk("%d,%d %s %llu + %u [%d]",
@@ -337,7 +341,8 @@ DECLARE_EVENT_CLASS(block_bio_merge,
__entry->dev = bio->bi_bdev->bd_dev;
__entry->sector = bio->bi_iter.bi_sector;
__entry->nr_sector = bio_sectors(bio);
- blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+ blk_fill_rwbs(__entry->rwbs, bio_op(bio), bio->bi_rw,
+ bio->bi_iter.bi_size);
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
),
@@ -404,7 +409,8 @@ TRACE_EVENT(block_bio_queue,
__entry->dev = bio->bi_bdev->bd_dev;
__entry->sector = bio->bi_iter.bi_sector;
__entry->nr_sector = bio_sectors(bio);
- blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+ blk_fill_rwbs(__entry->rwbs, bio_op(bio), bio->bi_rw,
+ bio->bi_iter.bi_size);
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
),
@@ -432,7 +438,7 @@ DECLARE_EVENT_CLASS(block_get_rq,
__entry->dev = bio ? bio->bi_bdev->bd_dev : 0;
__entry->sector = bio ? bio->bi_iter.bi_sector : 0;
__entry->nr_sector = bio ? bio_sectors(bio) : 0;
- blk_fill_rwbs(__entry->rwbs,
+ blk_fill_rwbs(__entry->rwbs, bio ? bio_op(bio) : 0,
bio ? bio->bi_rw : 0, __entry->nr_sector);
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
),
@@ -567,7 +573,8 @@ TRACE_EVENT(block_split,
__entry->dev = bio->bi_bdev->bd_dev;
__entry->sector = bio->bi_iter.bi_sector;
__entry->new_sector = new_sector;
- blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+ blk_fill_rwbs(__entry->rwbs, bio_op(bio), bio->bi_rw,
+ bio->bi_iter.bi_size);
memcpy(__entry->comm, current->comm, TASK_COMM_LEN);
),
@@ -610,7 +617,8 @@ TRACE_EVENT(block_bio_remap,
__entry->nr_sector = bio_sectors(bio);
__entry->old_dev = dev;
__entry->old_sector = from;
- blk_fill_rwbs(__entry->rwbs, bio->bi_rw, bio->bi_iter.bi_size);
+ blk_fill_rwbs(__entry->rwbs, bio_op(bio), bio->bi_rw,
+ bio->bi_iter.bi_size);
),
TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu",
@@ -656,7 +664,8 @@ TRACE_EVENT(block_rq_remap,
__entry->old_dev = dev;
__entry->old_sector = from;
__entry->nr_bios = blk_rq_count_bios(rq);
- blk_fill_rwbs(__entry->rwbs, rq->cmd_flags, blk_rq_bytes(rq));
+ blk_fill_rwbs(__entry->rwbs, req_op(rq), rq->cmd_flags,
+ blk_rq_bytes(rq));
),
TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu %u",
diff --git a/include/trace/events/compaction.h b/include/trace/events/compaction.h
index 36e2d6fb1360..c2ba402ab256 100644
--- a/include/trace/events/compaction.h
+++ b/include/trace/events/compaction.h
@@ -226,26 +226,26 @@ TRACE_EVENT(mm_compaction_try_to_compact_pages,
TP_PROTO(
int order,
gfp_t gfp_mask,
- enum migrate_mode mode),
+ int prio),
- TP_ARGS(order, gfp_mask, mode),
+ TP_ARGS(order, gfp_mask, prio),
TP_STRUCT__entry(
__field(int, order)
__field(gfp_t, gfp_mask)
- __field(enum migrate_mode, mode)
+ __field(int, prio)
),
TP_fast_assign(
__entry->order = order;
__entry->gfp_mask = gfp_mask;
- __entry->mode = mode;
+ __entry->prio = prio;
),
- TP_printk("order=%d gfp_mask=0x%x mode=%d",
+ TP_printk("order=%d gfp_mask=0x%x priority=%d",
__entry->order,
__entry->gfp_mask,
- (int)__entry->mode)
+ __entry->prio)
);
DECLARE_EVENT_CLASS(mm_compaction_suitable_template,
diff --git a/include/trace/events/devlink.h b/include/trace/events/devlink.h
new file mode 100644
index 000000000000..09f1df228f2c
--- /dev/null
+++ b/include/trace/events/devlink.h
@@ -0,0 +1,68 @@
+#if IS_ENABLED(CONFIG_NET_DEVLINK)
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM devlink
+
+#if !defined(_TRACE_DEVLINK_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_DEVLINK_H
+
+#include <linux/device.h>
+#include <net/devlink.h>
+#include <linux/tracepoint.h>
+
+/*
+ * Tracepoint for devlink hardware message:
+ */
+TRACE_EVENT(devlink_hwmsg,
+ TP_PROTO(const struct devlink *devlink, bool incoming,
+ unsigned long type, const u8 *buf, size_t len),
+
+ TP_ARGS(devlink, incoming, type, buf, len),
+
+ TP_STRUCT__entry(
+ __string(bus_name, devlink->dev->bus->name)
+ __string(dev_name, dev_name(devlink->dev))
+ __string(driver_name, devlink->dev->driver->name)
+ __field(bool, incoming)
+ __field(unsigned long, type)
+ __dynamic_array(u8, buf, len)
+ __field(size_t, len)
+ ),
+
+ TP_fast_assign(
+ __assign_str(bus_name, devlink->dev->bus->name);
+ __assign_str(dev_name, dev_name(devlink->dev));
+ __assign_str(driver_name, devlink->dev->driver->name);
+ __entry->incoming = incoming;
+ __entry->type = type;
+ memcpy(__get_dynamic_array(buf), buf, len);
+ __entry->len = len;
+ ),
+
+ TP_printk("bus_name=%s dev_name=%s driver_name=%s incoming=%d type=%lu buf=0x[%*phD] len=%zu",
+ __get_str(bus_name), __get_str(dev_name),
+ __get_str(driver_name), __entry->incoming, __entry->type,
+ (int) __entry->len, __get_dynamic_array(buf), __entry->len)
+);
+
+#endif /* _TRACE_DEVLINK_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
+
+#else /* CONFIG_NET_DEVLINK */
+
+#if !defined(_TRACE_DEVLINK_H)
+#define _TRACE_DEVLINK_H
+
+#include <net/devlink.h>
+
+static inline void trace_devlink_hwmsg(const struct devlink *devlink,
+ bool incoming, unsigned long type,
+ const u8 *buf, size_t len)
+{
+}
+
+#endif /* _TRACE_DEVLINK_H */
+
+#endif
diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
index 3a09bb4dc3b2..ff95fd02116f 100644
--- a/include/trace/events/f2fs.h
+++ b/include/trace/events/f2fs.h
@@ -31,10 +31,9 @@ TRACE_DEFINE_ENUM(BG_GC);
TRACE_DEFINE_ENUM(LFS);
TRACE_DEFINE_ENUM(SSR);
TRACE_DEFINE_ENUM(__REQ_RAHEAD);
-TRACE_DEFINE_ENUM(__REQ_WRITE);
TRACE_DEFINE_ENUM(__REQ_SYNC);
TRACE_DEFINE_ENUM(__REQ_NOIDLE);
-TRACE_DEFINE_ENUM(__REQ_FLUSH);
+TRACE_DEFINE_ENUM(__REQ_PREFLUSH);
TRACE_DEFINE_ENUM(__REQ_FUA);
TRACE_DEFINE_ENUM(__REQ_PRIO);
TRACE_DEFINE_ENUM(__REQ_META);
@@ -56,17 +55,21 @@ TRACE_DEFINE_ENUM(CP_DISCARD);
{ IPU, "IN-PLACE" }, \
{ OPU, "OUT-OF-PLACE" })
-#define F2FS_BIO_MASK(t) (t & (READA | WRITE_FLUSH_FUA))
+#define F2FS_BIO_FLAG_MASK(t) (t & (REQ_RAHEAD | WRITE_FLUSH_FUA))
#define F2FS_BIO_EXTRA_MASK(t) (t & (REQ_META | REQ_PRIO))
-#define show_bio_type(type) show_bio_base(type), show_bio_extra(type)
+#define show_bio_type(op, op_flags) show_bio_op(op), \
+ show_bio_op_flags(op_flags), show_bio_extra(op_flags)
-#define show_bio_base(type) \
- __print_symbolic(F2FS_BIO_MASK(type), \
+#define show_bio_op(op) \
+ __print_symbolic(op, \
{ READ, "READ" }, \
- { READA, "READAHEAD" }, \
+ { WRITE, "WRITE" })
+
+#define show_bio_op_flags(flags) \
+ __print_symbolic(F2FS_BIO_FLAG_MASK(flags), \
+ { REQ_RAHEAD, "READAHEAD" }, \
{ READ_SYNC, "READ_SYNC" }, \
- { WRITE, "WRITE" }, \
{ WRITE_SYNC, "WRITE_SYNC" }, \
{ WRITE_FLUSH, "WRITE_FLUSH" }, \
{ WRITE_FUA, "WRITE_FUA" }, \
@@ -734,7 +737,8 @@ DECLARE_EVENT_CLASS(f2fs__submit_page_bio,
__field(pgoff_t, index)
__field(block_t, old_blkaddr)
__field(block_t, new_blkaddr)
- __field(int, rw)
+ __field(int, op)
+ __field(int, op_flags)
__field(int, type)
),
@@ -744,17 +748,18 @@ DECLARE_EVENT_CLASS(f2fs__submit_page_bio,
__entry->index = page->index;
__entry->old_blkaddr = fio->old_blkaddr;
__entry->new_blkaddr = fio->new_blkaddr;
- __entry->rw = fio->rw;
+ __entry->op = fio->op;
+ __entry->op_flags = fio->op_flags;
__entry->type = fio->type;
),
TP_printk("dev = (%d,%d), ino = %lu, page_index = 0x%lx, "
- "oldaddr = 0x%llx, newaddr = 0x%llx rw = %s%s, type = %s",
+ "oldaddr = 0x%llx, newaddr = 0x%llx rw = %s%si%s, type = %s",
show_dev_ino(__entry),
(unsigned long)__entry->index,
(unsigned long long)__entry->old_blkaddr,
(unsigned long long)__entry->new_blkaddr,
- show_bio_type(__entry->rw),
+ show_bio_type(__entry->op, __entry->op_flags),
show_block_type(__entry->type))
);
@@ -785,7 +790,8 @@ DECLARE_EVENT_CLASS(f2fs__submit_bio,
TP_STRUCT__entry(
__field(dev_t, dev)
- __field(int, rw)
+ __field(int, op)
+ __field(int, op_flags)
__field(int, type)
__field(sector_t, sector)
__field(unsigned int, size)
@@ -793,15 +799,16 @@ DECLARE_EVENT_CLASS(f2fs__submit_bio,
TP_fast_assign(
__entry->dev = sb->s_dev;
- __entry->rw = fio->rw;
+ __entry->op = fio->op;
+ __entry->op_flags = fio->op_flags;
__entry->type = fio->type;
__entry->sector = bio->bi_iter.bi_sector;
__entry->size = bio->bi_iter.bi_size;
),
- TP_printk("dev = (%d,%d), %s%s, %s, sector = %lld, size = %u",
+ TP_printk("dev = (%d,%d), %s%s%s, %s, sector = %lld, size = %u",
show_dev(__entry),
- show_bio_type(__entry->rw),
+ show_bio_type(__entry->op, __entry->op_flags),
show_block_type(__entry->type),
(unsigned long long)__entry->sector,
__entry->size)
diff --git a/include/trace/events/huge_memory.h b/include/trace/events/huge_memory.h
index 551ba4acde4d..04f58acda8e8 100644
--- a/include/trace/events/huge_memory.h
+++ b/include/trace/events/huge_memory.h
@@ -13,7 +13,7 @@
EM( SCAN_EXCEED_NONE_PTE, "exceed_none_pte") \
EM( SCAN_PTE_NON_PRESENT, "pte_non_present") \
EM( SCAN_PAGE_RO, "no_writable_page") \
- EM( SCAN_NO_REFERENCED_PAGE, "no_referenced_page") \
+ EM( SCAN_LACK_REFERENCED_PAGE, "lack_referenced_page") \
EM( SCAN_PAGE_NULL, "page_null") \
EM( SCAN_SCAN_ABORT, "scan_aborted") \
EM( SCAN_PAGE_COUNT, "not_suitable_page_count") \
@@ -28,7 +28,9 @@
EM( SCAN_SWAP_CACHE_PAGE, "page_swap_cache") \
EM( SCAN_DEL_PAGE_LRU, "could_not_delete_page_from_lru")\
EM( SCAN_ALLOC_HUGE_PAGE_FAIL, "alloc_huge_page_failed") \
- EMe( SCAN_CGROUP_CHARGE_FAIL, "ccgroup_charge_failed")
+ EM( SCAN_CGROUP_CHARGE_FAIL, "ccgroup_charge_failed") \
+ EM( SCAN_EXCEED_SWAP_PTE, "exceed_swap_pte") \
+ EMe(SCAN_TRUNCATED, "truncated") \
#undef EM
#undef EMe
@@ -45,17 +47,18 @@ SCAN_STATUS
TRACE_EVENT(mm_khugepaged_scan_pmd,
TP_PROTO(struct mm_struct *mm, struct page *page, bool writable,
- bool referenced, int none_or_zero, int status),
+ int referenced, int none_or_zero, int status, int unmapped),
- TP_ARGS(mm, page, writable, referenced, none_or_zero, status),
+ TP_ARGS(mm, page, writable, referenced, none_or_zero, status, unmapped),
TP_STRUCT__entry(
__field(struct mm_struct *, mm)
__field(unsigned long, pfn)
__field(bool, writable)
- __field(bool, referenced)
+ __field(int, referenced)
__field(int, none_or_zero)
__field(int, status)
+ __field(int, unmapped)
),
TP_fast_assign(
@@ -65,15 +68,17 @@ TRACE_EVENT(mm_khugepaged_scan_pmd,
__entry->referenced = referenced;
__entry->none_or_zero = none_or_zero;
__entry->status = status;
+ __entry->unmapped = unmapped;
),
- TP_printk("mm=%p, scan_pfn=0x%lx, writable=%d, referenced=%d, none_or_zero=%d, status=%s",
+ TP_printk("mm=%p, scan_pfn=0x%lx, writable=%d, referenced=%d, none_or_zero=%d, status=%s, unmapped=%d",
__entry->mm,
__entry->pfn,
__entry->writable,
__entry->referenced,
__entry->none_or_zero,
- __print_symbolic(__entry->status, SCAN_STATUS))
+ __print_symbolic(__entry->status, SCAN_STATUS),
+ __entry->unmapped)
);
TRACE_EVENT(mm_collapse_huge_page,
@@ -103,14 +108,14 @@ TRACE_EVENT(mm_collapse_huge_page,
TRACE_EVENT(mm_collapse_huge_page_isolate,
TP_PROTO(struct page *page, int none_or_zero,
- bool referenced, bool writable, int status),
+ int referenced, bool writable, int status),
TP_ARGS(page, none_or_zero, referenced, writable, status),
TP_STRUCT__entry(
__field(unsigned long, pfn)
__field(int, none_or_zero)
- __field(bool, referenced)
+ __field(int, referenced)
__field(bool, writable)
__field(int, status)
),
@@ -131,5 +136,32 @@ TRACE_EVENT(mm_collapse_huge_page_isolate,
__print_symbolic(__entry->status, SCAN_STATUS))
);
+TRACE_EVENT(mm_collapse_huge_page_swapin,
+
+ TP_PROTO(struct mm_struct *mm, int swapped_in, int referenced, int ret),
+
+ TP_ARGS(mm, swapped_in, referenced, ret),
+
+ TP_STRUCT__entry(
+ __field(struct mm_struct *, mm)
+ __field(int, swapped_in)
+ __field(int, referenced)
+ __field(int, ret)
+ ),
+
+ TP_fast_assign(
+ __entry->mm = mm;
+ __entry->swapped_in = swapped_in;
+ __entry->referenced = referenced;
+ __entry->ret = ret;
+ ),
+
+ TP_printk("mm=%p, swapped_in=%d, referenced=%d, ret=%d",
+ __entry->mm,
+ __entry->swapped_in,
+ __entry->referenced,
+ __entry->ret)
+);
+
#endif /* __HUGE_MEMORY_H */
#include <trace/define_trace.h>
diff --git a/include/trace/events/libata.h b/include/trace/events/libata.h
index 75fff8696bae..2fbbf990e4b3 100644
--- a/include/trace/events/libata.h
+++ b/include/trace/events/libata.h
@@ -126,6 +126,7 @@
ata_protocol_name(ATA_PROT_PIO), \
ata_protocol_name(ATA_PROT_DMA), \
ata_protocol_name(ATA_PROT_NCQ), \
+ ata_protocol_name(ATA_PROT_NCQ_NODATA), \
ata_protocol_name(ATAPI_PROT_NODATA), \
ata_protocol_name(ATAPI_PROT_PIO), \
ata_protocol_name(ATAPI_PROT_DMA))
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index 43cedbf0c759..5a81ab48a2fb 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -11,6 +11,7 @@
#define __def_gfpflag_names \
{(unsigned long)GFP_TRANSHUGE, "GFP_TRANSHUGE"}, \
+ {(unsigned long)GFP_TRANSHUGE_LIGHT, "GFP_TRANSHUGE_LIGHT"}, \
{(unsigned long)GFP_HIGHUSER_MOVABLE, "GFP_HIGHUSER_MOVABLE"},\
{(unsigned long)GFP_HIGHUSER, "GFP_HIGHUSER"}, \
{(unsigned long)GFP_USER, "GFP_USER"}, \
diff --git a/include/trace/events/napi.h b/include/trace/events/napi.h
index 8fe1e93f531d..0b9e5136a2a3 100644
--- a/include/trace/events/napi.h
+++ b/include/trace/events/napi.h
@@ -12,22 +12,27 @@
TRACE_EVENT(napi_poll,
- TP_PROTO(struct napi_struct *napi),
+ TP_PROTO(struct napi_struct *napi, int work, int budget),
- TP_ARGS(napi),
+ TP_ARGS(napi, work, budget),
TP_STRUCT__entry(
__field( struct napi_struct *, napi)
__string( dev_name, napi->dev ? napi->dev->name : NO_DEV)
+ __field( int, work)
+ __field( int, budget)
),
TP_fast_assign(
__entry->napi = napi;
__assign_str(dev_name, napi->dev ? napi->dev->name : NO_DEV);
+ __entry->work = work;
+ __entry->budget = budget;
),
- TP_printk("napi poll on napi struct %p for device %s",
- __entry->napi, __get_str(dev_name))
+ TP_printk("napi poll on napi struct %p for device %s work %d budget %d",
+ __entry->napi, __get_str(dev_name),
+ __entry->work, __entry->budget)
);
#undef NO_DEV
diff --git a/include/trace/events/printk.h b/include/trace/events/printk.h
index c008bc99f9fa..f350170059c6 100644
--- a/include/trace/events/printk.h
+++ b/include/trace/events/printk.h
@@ -16,8 +16,16 @@ TRACE_EVENT(console,
),
TP_fast_assign(
- memcpy(__get_dynamic_array(msg), text, len);
- ((char *)__get_dynamic_array(msg))[len] = 0;
+ /*
+ * Each trace entry is printed in a new line.
+ * If the msg finishes with '\n', cut it off
+ * to avoid blank lines in the trace.
+ */
+ if ((len > 0) && (text[len-1] == '\n'))
+ len -= 1;
+
+ memcpy(__get_str(msg), text, len);
+ __get_str(msg)[len] = 0;
),
TP_printk("%s", __get_str(msg))
diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h
index 0101ef37f1ee..c88fd0934e7e 100644
--- a/include/trace/events/vmscan.h
+++ b/include/trace/events/vmscan.h
@@ -55,21 +55,23 @@ TRACE_EVENT(mm_vmscan_kswapd_sleep,
TRACE_EVENT(mm_vmscan_kswapd_wake,
- TP_PROTO(int nid, int order),
+ TP_PROTO(int nid, int zid, int order),
- TP_ARGS(nid, order),
+ TP_ARGS(nid, zid, order),
TP_STRUCT__entry(
__field( int, nid )
+ __field( int, zid )
__field( int, order )
),
TP_fast_assign(
__entry->nid = nid;
+ __entry->zid = zid;
__entry->order = order;
),
- TP_printk("nid=%d order=%d", __entry->nid, __entry->order)
+ TP_printk("nid=%d zid=%d order=%d", __entry->nid, __entry->zid, __entry->order)
);
TRACE_EVENT(mm_vmscan_wakeup_kswapd,
@@ -98,47 +100,50 @@ TRACE_EVENT(mm_vmscan_wakeup_kswapd,
DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_begin_template,
- TP_PROTO(int order, int may_writepage, gfp_t gfp_flags),
+ TP_PROTO(int order, int may_writepage, gfp_t gfp_flags, int classzone_idx),
- TP_ARGS(order, may_writepage, gfp_flags),
+ TP_ARGS(order, may_writepage, gfp_flags, classzone_idx),
TP_STRUCT__entry(
__field( int, order )
__field( int, may_writepage )
__field( gfp_t, gfp_flags )
+ __field( int, classzone_idx )
),
TP_fast_assign(
__entry->order = order;
__entry->may_writepage = may_writepage;
__entry->gfp_flags = gfp_flags;
+ __entry->classzone_idx = classzone_idx;
),
- TP_printk("order=%d may_writepage=%d gfp_flags=%s",
+ TP_printk("order=%d may_writepage=%d gfp_flags=%s classzone_idx=%d",
__entry->order,
__entry->may_writepage,
- show_gfp_flags(__entry->gfp_flags))
+ show_gfp_flags(__entry->gfp_flags),
+ __entry->classzone_idx)
);
DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_direct_reclaim_begin,
- TP_PROTO(int order, int may_writepage, gfp_t gfp_flags),
+ TP_PROTO(int order, int may_writepage, gfp_t gfp_flags, int classzone_idx),
- TP_ARGS(order, may_writepage, gfp_flags)
+ TP_ARGS(order, may_writepage, gfp_flags, classzone_idx)
);
DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_reclaim_begin,
- TP_PROTO(int order, int may_writepage, gfp_t gfp_flags),
+ TP_PROTO(int order, int may_writepage, gfp_t gfp_flags, int classzone_idx),
- TP_ARGS(order, may_writepage, gfp_flags)
+ TP_ARGS(order, may_writepage, gfp_flags, classzone_idx)
);
DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_softlimit_reclaim_begin,
- TP_PROTO(int order, int may_writepage, gfp_t gfp_flags),
+ TP_PROTO(int order, int may_writepage, gfp_t gfp_flags, int classzone_idx),
- TP_ARGS(order, may_writepage, gfp_flags)
+ TP_ARGS(order, may_writepage, gfp_flags, classzone_idx)
);
DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template,
@@ -266,16 +271,18 @@ TRACE_EVENT(mm_shrink_slab_end,
DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template,
- TP_PROTO(int order,
+ TP_PROTO(int classzone_idx,
+ int order,
unsigned long nr_requested,
unsigned long nr_scanned,
unsigned long nr_taken,
isolate_mode_t isolate_mode,
int file),
- TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file),
+ TP_ARGS(classzone_idx, order, nr_requested, nr_scanned, nr_taken, isolate_mode, file),
TP_STRUCT__entry(
+ __field(int, classzone_idx)
__field(int, order)
__field(unsigned long, nr_requested)
__field(unsigned long, nr_scanned)
@@ -285,6 +292,7 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template,
),
TP_fast_assign(
+ __entry->classzone_idx = classzone_idx;
__entry->order = order;
__entry->nr_requested = nr_requested;
__entry->nr_scanned = nr_scanned;
@@ -293,8 +301,9 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template,
__entry->file = file;
),
- TP_printk("isolate_mode=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu file=%d",
+ TP_printk("isolate_mode=%d classzone=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu file=%d",
__entry->isolate_mode,
+ __entry->classzone_idx,
__entry->order,
__entry->nr_requested,
__entry->nr_scanned,
@@ -304,27 +313,29 @@ DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template,
DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate,
- TP_PROTO(int order,
+ TP_PROTO(int classzone_idx,
+ int order,
unsigned long nr_requested,
unsigned long nr_scanned,
unsigned long nr_taken,
isolate_mode_t isolate_mode,
int file),
- TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file)
+ TP_ARGS(classzone_idx, order, nr_requested, nr_scanned, nr_taken, isolate_mode, file)
);
DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate,
- TP_PROTO(int order,
+ TP_PROTO(int classzone_idx,
+ int order,
unsigned long nr_requested,
unsigned long nr_scanned,
unsigned long nr_taken,
isolate_mode_t isolate_mode,
int file),
- TP_ARGS(order, nr_requested, nr_scanned, nr_taken, isolate_mode, file)
+ TP_ARGS(classzone_idx, order, nr_requested, nr_scanned, nr_taken, isolate_mode, file)
);
@@ -352,15 +363,14 @@ TRACE_EVENT(mm_vmscan_writepage,
TRACE_EVENT(mm_vmscan_lru_shrink_inactive,
- TP_PROTO(struct zone *zone,
+ TP_PROTO(int nid,
unsigned long nr_scanned, unsigned long nr_reclaimed,
int priority, int file),
- TP_ARGS(zone, nr_scanned, nr_reclaimed, priority, file),
+ TP_ARGS(nid, nr_scanned, nr_reclaimed, priority, file),
TP_STRUCT__entry(
__field(int, nid)
- __field(int, zid)
__field(unsigned long, nr_scanned)
__field(unsigned long, nr_reclaimed)
__field(int, priority)
@@ -368,16 +378,15 @@ TRACE_EVENT(mm_vmscan_lru_shrink_inactive,
),
TP_fast_assign(
- __entry->nid = zone_to_nid(zone);
- __entry->zid = zone_idx(zone);
+ __entry->nid = nid;
__entry->nr_scanned = nr_scanned;
__entry->nr_reclaimed = nr_reclaimed;
__entry->priority = priority;
__entry->reclaim_flags = trace_shrink_flags(file);
),
- TP_printk("nid=%d zid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s",
- __entry->nid, __entry->zid,
+ TP_printk("nid=%d nr_scanned=%ld nr_reclaimed=%ld priority=%d flags=%s",
+ __entry->nid,
__entry->nr_scanned, __entry->nr_reclaimed,
__entry->priority,
show_reclaim_flags(__entry->reclaim_flags))
diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h
index 73614ce1d204..2ccd9ccbf9ef 100644
--- a/include/trace/events/writeback.h
+++ b/include/trace/events/writeback.h
@@ -412,11 +412,11 @@ TRACE_EVENT(global_dirty_state,
),
TP_fast_assign(
- __entry->nr_dirty = global_page_state(NR_FILE_DIRTY);
- __entry->nr_writeback = global_page_state(NR_WRITEBACK);
- __entry->nr_unstable = global_page_state(NR_UNSTABLE_NFS);
- __entry->nr_dirtied = global_page_state(NR_DIRTIED);
- __entry->nr_written = global_page_state(NR_WRITTEN);
+ __entry->nr_dirty = global_node_page_state(NR_FILE_DIRTY);
+ __entry->nr_writeback = global_node_page_state(NR_WRITEBACK);
+ __entry->nr_unstable = global_node_page_state(NR_UNSTABLE_NFS);
+ __entry->nr_dirtied = global_node_page_state(NR_DIRTIED);
+ __entry->nr_written = global_node_page_state(NR_WRITTEN);
__entry->background_thresh = background_thresh;
__entry->dirty_thresh = dirty_thresh;
__entry->dirty_limit = global_wb_domain.dirty_limit;
@@ -696,7 +696,7 @@ DEFINE_EVENT(writeback_single_inode_template, writeback_single_inode,
TP_ARGS(inode, wbc, nr_to_write)
);
-DECLARE_EVENT_CLASS(writeback_lazytime_template,
+DECLARE_EVENT_CLASS(writeback_inode_template,
TP_PROTO(struct inode *inode),
TP_ARGS(inode),
@@ -723,25 +723,39 @@ DECLARE_EVENT_CLASS(writeback_lazytime_template,
show_inode_state(__entry->state), __entry->mode)
);
-DEFINE_EVENT(writeback_lazytime_template, writeback_lazytime,
+DEFINE_EVENT(writeback_inode_template, writeback_lazytime,
TP_PROTO(struct inode *inode),
TP_ARGS(inode)
);
-DEFINE_EVENT(writeback_lazytime_template, writeback_lazytime_iput,
+DEFINE_EVENT(writeback_inode_template, writeback_lazytime_iput,
TP_PROTO(struct inode *inode),
TP_ARGS(inode)
);
-DEFINE_EVENT(writeback_lazytime_template, writeback_dirty_inode_enqueue,
+DEFINE_EVENT(writeback_inode_template, writeback_dirty_inode_enqueue,
TP_PROTO(struct inode *inode),
TP_ARGS(inode)
);
+/*
+ * Inode writeback list tracking.
+ */
+
+DEFINE_EVENT(writeback_inode_template, sb_mark_inode_writeback,
+ TP_PROTO(struct inode *inode),
+ TP_ARGS(inode)
+);
+
+DEFINE_EVENT(writeback_inode_template, sb_clear_inode_writeback,
+ TP_PROTO(struct inode *inode),
+ TP_ARGS(inode)
+);
+
#endif /* _TRACE_WRITEBACK_H */
/* This part must be outside protection */
diff --git a/include/trace/perf.h b/include/trace/perf.h
index 88de5c205e86..04fe68bbe767 100644
--- a/include/trace/perf.h
+++ b/include/trace/perf.h
@@ -15,7 +15,7 @@
((__entry->__data_loc_##field >> 16) & 0xffff)
#undef __get_str
-#define __get_str(field) (char *)__get_dynamic_array(field)
+#define __get_str(field) ((char *)__get_dynamic_array(field))
#undef __get_bitmask
#define __get_bitmask(field) (char *)__get_dynamic_array(field)
diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h
index 80679a9fae65..467e12f780d8 100644
--- a/include/trace/trace_events.h
+++ b/include/trace/trace_events.h
@@ -256,7 +256,7 @@ TRACE_MAKE_SYSTEM_STR();
((__entry->__data_loc_##field >> 16) & 0xffff)
#undef __get_str
-#define __get_str(field) (char *)__get_dynamic_array(field)
+#define __get_str(field) ((char *)__get_dynamic_array(field))
#undef __get_bitmask
#define __get_bitmask(field) \
diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
new file mode 100644
index 000000000000..0fbf6fd4711b
--- /dev/null
+++ b/include/uapi/linux/batman_adv.h
@@ -0,0 +1,114 @@
+/* Copyright (C) 2016 B.A.T.M.A.N. contributors:
+ *
+ * Matthias Schiffer
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _UAPI_LINUX_BATMAN_ADV_H_
+#define _UAPI_LINUX_BATMAN_ADV_H_
+
+#define BATADV_NL_NAME "batadv"
+
+#define BATADV_NL_MCAST_GROUP_TPMETER "tpmeter"
+
+/**
+ * enum batadv_nl_attrs - batman-adv netlink attributes
+ *
+ * @BATADV_ATTR_UNSPEC: unspecified attribute to catch errors
+ * @BATADV_ATTR_VERSION: batman-adv version string
+ * @BATADV_ATTR_ALGO_NAME: name of routing algorithm
+ * @BATADV_ATTR_MESH_IFINDEX: index of the batman-adv interface
+ * @BATADV_ATTR_MESH_IFNAME: name of the batman-adv interface
+ * @BATADV_ATTR_MESH_ADDRESS: mac address of the batman-adv interface
+ * @BATADV_ATTR_HARD_IFINDEX: index of the non-batman-adv interface
+ * @BATADV_ATTR_HARD_IFNAME: name of the non-batman-adv interface
+ * @BATADV_ATTR_HARD_ADDRESS: mac address of the non-batman-adv interface
+ * @BATADV_ATTR_ORIG_ADDRESS: originator mac address
+ * @BATADV_ATTR_TPMETER_RESULT: result of run (see batadv_tp_meter_status)
+ * @BATADV_ATTR_TPMETER_TEST_TIME: time (msec) the run took
+ * @BATADV_ATTR_TPMETER_BYTES: amount of acked bytes during run
+ * @BATADV_ATTR_TPMETER_COOKIE: session cookie to match tp_meter session
+ * @BATADV_ATTR_PAD: attribute used for padding for 64-bit alignment
+ * @__BATADV_ATTR_AFTER_LAST: internal use
+ * @NUM_BATADV_ATTR: total number of batadv_nl_attrs available
+ * @BATADV_ATTR_MAX: highest attribute number currently defined
+ */
+enum batadv_nl_attrs {
+ BATADV_ATTR_UNSPEC,
+ BATADV_ATTR_VERSION,
+ BATADV_ATTR_ALGO_NAME,
+ BATADV_ATTR_MESH_IFINDEX,
+ BATADV_ATTR_MESH_IFNAME,
+ BATADV_ATTR_MESH_ADDRESS,
+ BATADV_ATTR_HARD_IFINDEX,
+ BATADV_ATTR_HARD_IFNAME,
+ BATADV_ATTR_HARD_ADDRESS,
+ BATADV_ATTR_ORIG_ADDRESS,
+ BATADV_ATTR_TPMETER_RESULT,
+ BATADV_ATTR_TPMETER_TEST_TIME,
+ BATADV_ATTR_TPMETER_BYTES,
+ BATADV_ATTR_TPMETER_COOKIE,
+ BATADV_ATTR_PAD,
+ /* add attributes above here, update the policy in netlink.c */
+ __BATADV_ATTR_AFTER_LAST,
+ NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST,
+ BATADV_ATTR_MAX = __BATADV_ATTR_AFTER_LAST - 1
+};
+
+/**
+ * enum batadv_nl_commands - supported batman-adv netlink commands
+ *
+ * @BATADV_CMD_UNSPEC: unspecified command to catch errors
+ * @BATADV_CMD_GET_MESH_INFO: Query basic information about batman-adv device
+ * @BATADV_CMD_TP_METER: Start a tp meter session
+ * @BATADV_CMD_TP_METER_CANCEL: Cancel a tp meter session
+ * @__BATADV_CMD_AFTER_LAST: internal use
+ * @BATADV_CMD_MAX: highest used command number
+ */
+enum batadv_nl_commands {
+ BATADV_CMD_UNSPEC,
+ BATADV_CMD_GET_MESH_INFO,
+ BATADV_CMD_TP_METER,
+ BATADV_CMD_TP_METER_CANCEL,
+ /* add new commands above here */
+ __BATADV_CMD_AFTER_LAST,
+ BATADV_CMD_MAX = __BATADV_CMD_AFTER_LAST - 1
+};
+
+/**
+ * enum batadv_tp_meter_reason - reason of a tp meter test run stop
+ * @BATADV_TP_REASON_COMPLETE: sender finished tp run
+ * @BATADV_TP_REASON_CANCEL: sender was stopped during run
+ * @BATADV_TP_REASON_DST_UNREACHABLE: receiver could not be reached or didn't
+ * answer
+ * @BATADV_TP_REASON_RESEND_LIMIT: (unused) sender retry reached limit
+ * @BATADV_TP_REASON_ALREADY_ONGOING: test to or from the same node already
+ * ongoing
+ * @BATADV_TP_REASON_MEMORY_ERROR: test was stopped due to low memory
+ * @BATADV_TP_REASON_CANT_SEND: failed to send via outgoing interface
+ * @BATADV_TP_REASON_TOO_MANY: too many ongoing sessions
+ */
+enum batadv_tp_meter_reason {
+ BATADV_TP_REASON_COMPLETE = 3,
+ BATADV_TP_REASON_CANCEL = 4,
+ /* error status >= 128 */
+ BATADV_TP_REASON_DST_UNREACHABLE = 128,
+ BATADV_TP_REASON_RESEND_LIMIT = 129,
+ BATADV_TP_REASON_ALREADY_ONGOING = 130,
+ BATADV_TP_REASON_MEMORY_ERROR = 131,
+ BATADV_TP_REASON_CANT_SEND = 132,
+ BATADV_TP_REASON_TOO_MANY = 133,
+};
+
+#endif /* _UAPI_LINUX_BATMAN_ADV_H_ */
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 406459b935a2..da218fec6056 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -84,6 +84,7 @@ enum bpf_map_type {
BPF_MAP_TYPE_PERCPU_HASH,
BPF_MAP_TYPE_PERCPU_ARRAY,
BPF_MAP_TYPE_STACK_TRACE,
+ BPF_MAP_TYPE_CGROUP_ARRAY,
};
enum bpf_prog_type {
@@ -93,6 +94,7 @@ enum bpf_prog_type {
BPF_PROG_TYPE_SCHED_CLS,
BPF_PROG_TYPE_SCHED_ACT,
BPF_PROG_TYPE_TRACEPOINT,
+ BPF_PROG_TYPE_XDP,
};
#define BPF_PSEUDO_MAP_FD 1
@@ -313,6 +315,66 @@ enum bpf_func_id {
*/
BPF_FUNC_skb_get_tunnel_opt,
BPF_FUNC_skb_set_tunnel_opt,
+
+ /**
+ * bpf_skb_change_proto(skb, proto, flags)
+ * Change protocol of the skb. Currently supported is
+ * v4 -> v6, v6 -> v4 transitions. The helper will also
+ * resize the skb. eBPF program is expected to fill the
+ * new headers via skb_store_bytes and lX_csum_replace.
+ * @skb: pointer to skb
+ * @proto: new skb->protocol type
+ * @flags: reserved
+ * Return: 0 on success or negative error
+ */
+ BPF_FUNC_skb_change_proto,
+
+ /**
+ * bpf_skb_change_type(skb, type)
+ * Change packet type of skb.
+ * @skb: pointer to skb
+ * @type: new skb->pkt_type type
+ * Return: 0 on success or negative error
+ */
+ BPF_FUNC_skb_change_type,
+
+ /**
+ * bpf_skb_in_cgroup(skb, map, index) - Check cgroup2 membership of skb
+ * @skb: pointer to skb
+ * @map: pointer to bpf_map in BPF_MAP_TYPE_CGROUP_ARRAY type
+ * @index: index of the cgroup in the bpf_map
+ * Return:
+ * == 0 skb failed the cgroup2 descendant test
+ * == 1 skb succeeded the cgroup2 descendant test
+ * < 0 error
+ */
+ BPF_FUNC_skb_in_cgroup,
+
+ /**
+ * bpf_get_hash_recalc(skb)
+ * Retrieve and possibly recalculate skb->hash.
+ * @skb: pointer to skb
+ * Return: hash
+ */
+ BPF_FUNC_get_hash_recalc,
+
+ /**
+ * u64 bpf_get_current_task(void)
+ * Returns current task_struct
+ * Return: current
+ */
+ BPF_FUNC_get_current_task,
+
+ /**
+ * bpf_probe_write_user(void *dst, void *src, int len)
+ * safely attempt to write to a location
+ * @dst: destination address in userspace
+ * @src: source address on stack
+ * @len: number of bytes to copy
+ * Return: 0 on success or negative error
+ */
+ BPF_FUNC_probe_write_user,
+
__BPF_FUNC_MAX_ID,
};
@@ -347,9 +409,11 @@ enum bpf_func_id {
#define BPF_F_ZERO_CSUM_TX (1ULL << 1)
#define BPF_F_DONT_FRAGMENT (1ULL << 2)
-/* BPF_FUNC_perf_event_output flags. */
+/* BPF_FUNC_perf_event_output and BPF_FUNC_perf_event_read flags. */
#define BPF_F_INDEX_MASK 0xffffffffULL
#define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK
+/* BPF_FUNC_perf_event_output for sk_buff input context. */
+#define BPF_F_CTXLEN_MASK (0xfffffULL << 32)
/* user accessible mirror of in-kernel sk_buff.
* new fields can only be added to the end of this structure
@@ -386,4 +450,24 @@ struct bpf_tunnel_key {
__u32 tunnel_label;
};
+/* User return codes for XDP prog type.
+ * A valid XDP program must return one of these defined values. All other
+ * return codes are reserved for future use. Unknown return codes will result
+ * in packet drop.
+ */
+enum xdp_action {
+ XDP_ABORTED = 0,
+ XDP_DROP,
+ XDP_PASS,
+ XDP_TX,
+};
+
+/* user accessible metadata for XDP packet hook
+ * new fields must be added to the end of this structure
+ */
+struct xdp_md {
+ __u32 data;
+ __u32 data_end;
+};
+
#endif /* _UAPI__LINUX_BPF_H__ */
diff --git a/include/uapi/linux/can/bcm.h b/include/uapi/linux/can/bcm.h
index 7a291dc1ff15..cefb304414ba 100644
--- a/include/uapi/linux/can/bcm.h
+++ b/include/uapi/linux/can/bcm.h
@@ -99,5 +99,6 @@ enum {
#define RX_ANNOUNCE_RESUME 0x0100
#define TX_RESET_MULTI_IDX 0x0200
#define RX_RTR_FRAME 0x0400
+#define CAN_FD_FRAME 0x0800
#endif /* !_UAPI_CAN_BCM_H */
diff --git a/include/uapi/linux/cryptouser.h b/include/uapi/linux/cryptouser.h
index 2e67bb64c1da..79b5ded2001a 100644
--- a/include/uapi/linux/cryptouser.h
+++ b/include/uapi/linux/cryptouser.h
@@ -45,6 +45,7 @@ enum crypto_attr_type_t {
CRYPTOCFGA_REPORT_RNG, /* struct crypto_report_rng */
CRYPTOCFGA_REPORT_CIPHER, /* struct crypto_report_cipher */
CRYPTOCFGA_REPORT_AKCIPHER, /* struct crypto_report_akcipher */
+ CRYPTOCFGA_REPORT_KPP, /* struct crypto_report_kpp */
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
@@ -107,5 +108,9 @@ struct crypto_report_akcipher {
char type[CRYPTO_MAX_NAME];
};
+struct crypto_report_kpp {
+ char type[CRYPTO_MAX_NAME];
+};
+
#define CRYPTO_REPORT_MAXSIZE (sizeof(struct crypto_user_alg) + \
sizeof(struct crypto_report_blkcipher))
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index ba0073b26fa6..915bfa74458c 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -57,6 +57,8 @@ enum devlink_command {
DEVLINK_CMD_SB_OCC_SNAPSHOT,
DEVLINK_CMD_SB_OCC_MAX_CLEAR,
+ DEVLINK_CMD_ESWITCH_MODE_GET,
+ DEVLINK_CMD_ESWITCH_MODE_SET,
/* add new commands above here */
__DEVLINK_CMD_MAX,
@@ -95,6 +97,11 @@ enum devlink_sb_threshold_type {
#define DEVLINK_SB_THRESHOLD_TO_ALPHA_MAX 20
+enum devlink_eswitch_mode {
+ DEVLINK_ESWITCH_MODE_LEGACY,
+ DEVLINK_ESWITCH_MODE_SWITCHDEV,
+};
+
enum devlink_attr {
/* don't change the order or add anything between, this is ABI! */
DEVLINK_ATTR_UNSPEC,
@@ -125,6 +132,7 @@ enum devlink_attr {
DEVLINK_ATTR_SB_TC_INDEX, /* u16 */
DEVLINK_ATTR_SB_OCC_CUR, /* u32 */
DEVLINK_ATTR_SB_OCC_MAX, /* u32 */
+ DEVLINK_ATTR_ESWITCH_MODE, /* u16 */
/* add new attributes above here, update the policy in devlink.c */
diff --git a/include/uapi/linux/dm-ioctl.h b/include/uapi/linux/dm-ioctl.h
index 30afd0a23c4b..4bf9f1eabffc 100644
--- a/include/uapi/linux/dm-ioctl.h
+++ b/include/uapi/linux/dm-ioctl.h
@@ -267,9 +267,9 @@ enum {
#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
#define DM_VERSION_MAJOR 4
-#define DM_VERSION_MINOR 34
+#define DM_VERSION_MINOR 35
#define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl (2015-10-28)"
+#define DM_VERSION_EXTRA "-ioctl (2016-06-23)"
/* Status bits */
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
diff --git a/include/uapi/linux/elf-em.h b/include/uapi/linux/elf-em.h
index c3fdfe79e5cc..cb5d1a519202 100644
--- a/include/uapi/linux/elf-em.h
+++ b/include/uapi/linux/elf-em.h
@@ -40,6 +40,7 @@
#define EM_TILEPRO 188 /* Tilera TILEPro */
#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */
#define EM_TILEGX 191 /* Tilera TILE-Gx */
+#define EM_BPF 247 /* Linux BPF - in-kernel virtual machine */
#define EM_FRV 0x5441 /* Fujitsu FR-V */
#define EM_AVR32 0x18ad /* Atmel AVR32 */
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 5f030b46cff4..b8f38e84d93a 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -1362,6 +1362,7 @@ enum ethtool_link_mode_bit_indices {
ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT = 37,
ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT = 38,
ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT = 39,
+ ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT = 40,
/* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit
* 31. Please do NOT define any SUPPORTED_* or ADVERTISED_*
@@ -1370,7 +1371,7 @@ enum ethtool_link_mode_bit_indices {
*/
__ETHTOOL_LINK_MODE_LAST
- = ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
+ = ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
};
#define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name) \
diff --git a/include/uapi/linux/fib_rules.h b/include/uapi/linux/fib_rules.h
index 620c8a5ddc00..14404b3ebb89 100644
--- a/include/uapi/linux/fib_rules.h
+++ b/include/uapi/linux/fib_rules.h
@@ -50,6 +50,7 @@ enum {
FRA_FWMASK, /* mask for netfilter mark */
FRA_OIFNAME,
FRA_PAD,
+ FRA_L3MDEV, /* iif or oif is l3mdev goto its table */
__FRA_MAX
};
diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h
index d0a3cac72250..333d3544c964 100644
--- a/include/uapi/linux/gpio.h
+++ b/include/uapi/linux/gpio.h
@@ -1,7 +1,7 @@
/*
* <linux/gpio.h> - userspace ABI for the GPIO character devices
*
- * Copyright (C) 2015 Linus Walleij
+ * Copyright (C) 2016 Linus Walleij
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
@@ -26,8 +26,8 @@ struct gpiochip_info {
__u32 lines;
};
-/* Line is in use by the kernel */
-#define GPIOLINE_FLAG_KERNEL (1UL << 0)
+/* Informational flags */
+#define GPIOLINE_FLAG_KERNEL (1UL << 0) /* Line used by the kernel */
#define GPIOLINE_FLAG_IS_OUT (1UL << 1)
#define GPIOLINE_FLAG_ACTIVE_LOW (1UL << 2)
#define GPIOLINE_FLAG_OPEN_DRAIN (1UL << 3)
@@ -52,7 +52,106 @@ struct gpioline_info {
char consumer[32];
};
+/* Maximum number of requested handles */
+#define GPIOHANDLES_MAX 64
+
+/* Linerequest flags */
+#define GPIOHANDLE_REQUEST_INPUT (1UL << 0)
+#define GPIOHANDLE_REQUEST_OUTPUT (1UL << 1)
+#define GPIOHANDLE_REQUEST_ACTIVE_LOW (1UL << 2)
+#define GPIOHANDLE_REQUEST_OPEN_DRAIN (1UL << 3)
+#define GPIOHANDLE_REQUEST_OPEN_SOURCE (1UL << 4)
+
+/**
+ * struct gpiohandle_request - Information about a GPIO handle request
+ * @lineoffsets: an array desired lines, specified by offset index for the
+ * associated GPIO device
+ * @flags: desired flags for the desired GPIO lines, such as
+ * GPIOHANDLE_REQUEST_OUTPUT, GPIOHANDLE_REQUEST_ACTIVE_LOW etc, OR:ed
+ * together. Note that even if multiple lines are requested, the same flags
+ * must be applicable to all of them, if you want lines with individual
+ * flags set, request them one by one. It is possible to select
+ * a batch of input or output lines, but they must all have the same
+ * characteristics, i.e. all inputs or all outputs, all active low etc
+ * @default_values: if the GPIOHANDLE_REQUEST_OUTPUT is set for a requested
+ * line, this specifies the default output value, should be 0 (low) or
+ * 1 (high), anything else than 0 or 1 will be interpreted as 1 (high)
+ * @consumer_label: a desired consumer label for the selected GPIO line(s)
+ * such as "my-bitbanged-relay"
+ * @lines: number of lines requested in this request, i.e. the number of
+ * valid fields in the above arrays, set to 1 to request a single line
+ * @fd: if successful this field will contain a valid anonymous file handle
+ * after a GPIO_GET_LINEHANDLE_IOCTL operation, zero or negative value
+ * means error
+ */
+struct gpiohandle_request {
+ __u32 lineoffsets[GPIOHANDLES_MAX];
+ __u32 flags;
+ __u8 default_values[GPIOHANDLES_MAX];
+ char consumer_label[32];
+ __u32 lines;
+ int fd;
+};
+
+/**
+ * struct gpiohandle_data - Information of values on a GPIO handle
+ * @values: when getting the state of lines this contains the current
+ * state of a line, when setting the state of lines these should contain
+ * the desired target state
+ */
+struct gpiohandle_data {
+ __u8 values[GPIOHANDLES_MAX];
+};
+
+#define GPIOHANDLE_GET_LINE_VALUES_IOCTL _IOWR(0xB4, 0x08, struct gpiohandle_data)
+#define GPIOHANDLE_SET_LINE_VALUES_IOCTL _IOWR(0xB4, 0x09, struct gpiohandle_data)
+
+/* Eventrequest flags */
+#define GPIOEVENT_REQUEST_RISING_EDGE (1UL << 0)
+#define GPIOEVENT_REQUEST_FALLING_EDGE (1UL << 1)
+#define GPIOEVENT_REQUEST_BOTH_EDGES ((1UL << 0) | (1UL << 1))
+
+/**
+ * struct gpioevent_request - Information about a GPIO event request
+ * @lineoffset: the desired line to subscribe to events from, specified by
+ * offset index for the associated GPIO device
+ * @handleflags: desired handle flags for the desired GPIO line, such as
+ * GPIOHANDLE_REQUEST_ACTIVE_LOW or GPIOHANDLE_REQUEST_OPEN_DRAIN
+ * @eventflags: desired flags for the desired GPIO event line, such as
+ * GPIOEVENT_REQUEST_RISING_EDGE or GPIOEVENT_REQUEST_FALLING_EDGE
+ * @consumer_label: a desired consumer label for the selected GPIO line(s)
+ * such as "my-listener"
+ * @fd: if successful this field will contain a valid anonymous file handle
+ * after a GPIO_GET_LINEEVENT_IOCTL operation, zero or negative value
+ * means error
+ */
+struct gpioevent_request {
+ __u32 lineoffset;
+ __u32 handleflags;
+ __u32 eventflags;
+ char consumer_label[32];
+ int fd;
+};
+
+/**
+ * GPIO event types
+ */
+#define GPIOEVENT_EVENT_RISING_EDGE 0x01
+#define GPIOEVENT_EVENT_FALLING_EDGE 0x02
+
+/**
+ * struct gpioevent_data - The actual event being pushed to userspace
+ * @timestamp: best estimate of time of event occurrence, in nanoseconds
+ * @id: event identifier
+ */
+struct gpioevent_data {
+ __u64 timestamp;
+ __u32 id;
+};
+
#define GPIO_GET_CHIPINFO_IOCTL _IOR(0xB4, 0x01, struct gpiochip_info)
#define GPIO_GET_LINEINFO_IOCTL _IOWR(0xB4, 0x02, struct gpioline_info)
+#define GPIO_GET_LINEHANDLE_IOCTL _IOWR(0xB4, 0x03, struct gpiohandle_request)
+#define GPIO_GET_LINEEVENT_IOCTL _IOWR(0xB4, 0x04, struct gpioevent_request)
#endif /* _UAPI_GPIO_H_ */
diff --git a/include/uapi/linux/i2c.h b/include/uapi/linux/i2c.h
index adcbef4bff61..009e27bb9abe 100644
--- a/include/uapi/linux/i2c.h
+++ b/include/uapi/linux/i2c.h
@@ -102,6 +102,7 @@ struct i2c_msg {
#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */
#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */
+#define I2C_FUNC_SMBUS_HOST_NOTIFY 0x10000000
#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
I2C_FUNC_SMBUS_WRITE_BYTE)
diff --git a/include/uapi/linux/icmp.h b/include/uapi/linux/icmp.h
index 16fff055f734..fddd9d736284 100644
--- a/include/uapi/linux/icmp.h
+++ b/include/uapi/linux/icmp.h
@@ -79,6 +79,7 @@ struct icmphdr {
__be16 __unused;
__be16 mtu;
} frag;
+ __u8 reserved[4];
} un;
};
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
index 397d503fdedb..c186f64fffca 100644
--- a/include/uapi/linux/if_bridge.h
+++ b/include/uapi/linux/if_bridge.h
@@ -247,8 +247,37 @@ enum {
enum {
BRIDGE_XSTATS_UNSPEC,
BRIDGE_XSTATS_VLAN,
+ BRIDGE_XSTATS_MCAST,
+ BRIDGE_XSTATS_PAD,
__BRIDGE_XSTATS_MAX
};
#define BRIDGE_XSTATS_MAX (__BRIDGE_XSTATS_MAX - 1)
+enum {
+ BR_MCAST_DIR_RX,
+ BR_MCAST_DIR_TX,
+ BR_MCAST_DIR_SIZE
+};
+
+/* IGMP/MLD statistics */
+struct br_mcast_stats {
+ __u64 igmp_v1queries[BR_MCAST_DIR_SIZE];
+ __u64 igmp_v2queries[BR_MCAST_DIR_SIZE];
+ __u64 igmp_v3queries[BR_MCAST_DIR_SIZE];
+ __u64 igmp_leaves[BR_MCAST_DIR_SIZE];
+ __u64 igmp_v1reports[BR_MCAST_DIR_SIZE];
+ __u64 igmp_v2reports[BR_MCAST_DIR_SIZE];
+ __u64 igmp_v3reports[BR_MCAST_DIR_SIZE];
+ __u64 igmp_parse_errors;
+
+ __u64 mld_v1queries[BR_MCAST_DIR_SIZE];
+ __u64 mld_v2queries[BR_MCAST_DIR_SIZE];
+ __u64 mld_leaves[BR_MCAST_DIR_SIZE];
+ __u64 mld_v1reports[BR_MCAST_DIR_SIZE];
+ __u64 mld_v2reports[BR_MCAST_DIR_SIZE];
+ __u64 mld_parse_errors;
+
+ __u64 mcast_bytes[BR_MCAST_DIR_SIZE];
+ __u64 mcast_packets[BR_MCAST_DIR_SIZE];
+};
#endif /* _UAPI_LINUX_IF_BRIDGE_H */
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
index cec849a239f6..117d02e0fc31 100644
--- a/include/uapi/linux/if_ether.h
+++ b/include/uapi/linux/if_ether.h
@@ -87,6 +87,7 @@
#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
#define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */
#define ETH_P_1588 0x88F7 /* IEEE 1588 Timesync */
+#define ETH_P_NCSI 0x88F8 /* NCSI protocol */
#define ETH_P_PRP 0x88FB /* IEC 62439-3 PRP/HSRv0 */
#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
#define ETH_P_TDLS 0x890D /* TDLS */
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index bb36bd5675a7..a1b5202c5f6b 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -156,6 +156,7 @@ enum {
IFLA_GSO_MAX_SEGS,
IFLA_GSO_MAX_SIZE,
IFLA_PAD,
+ IFLA_XDP,
__IFLA_MAX
};
@@ -273,6 +274,7 @@ enum {
IFLA_BR_VLAN_DEFAULT_PVID,
IFLA_BR_PAD,
IFLA_BR_VLAN_STATS_ENABLED,
+ IFLA_BR_MCAST_STATS_ENABLED,
__IFLA_BR_MAX,
};
@@ -822,6 +824,7 @@ enum {
IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */
IFLA_STATS_LINK_64,
IFLA_STATS_LINK_XSTATS,
+ IFLA_STATS_LINK_XSTATS_SLAVE,
__IFLA_STATS_MAX,
};
@@ -841,4 +844,15 @@ enum {
};
#define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1)
+/* XDP section */
+
+enum {
+ IFLA_XDP_UNSPEC,
+ IFLA_XDP_FD,
+ IFLA_XDP_ATTACHED,
+ __IFLA_XDP_MAX,
+};
+
+#define IFLA_XDP_MAX (__IFLA_XDP_MAX - 1)
+
#endif /* _UAPI_LINUX_IF_LINK_H */
diff --git a/include/uapi/linux/if_macsec.h b/include/uapi/linux/if_macsec.h
index f7d4831a2cc7..02fc49cb72d8 100644
--- a/include/uapi/linux/if_macsec.h
+++ b/include/uapi/linux/if_macsec.h
@@ -26,6 +26,8 @@
#define MACSEC_MIN_ICV_LEN 8
#define MACSEC_MAX_ICV_LEN 32
+/* upper limit for ICV length as recommended by IEEE802.1AE-2006 */
+#define MACSEC_STD_ICV_LEN 16
enum macsec_attrs {
MACSEC_ATTR_UNSPEC,
diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h
index af4de90ba27d..1046f5515174 100644
--- a/include/uapi/linux/if_tunnel.h
+++ b/include/uapi/linux/if_tunnel.h
@@ -113,6 +113,7 @@ enum {
IFLA_GRE_ENCAP_SPORT,
IFLA_GRE_ENCAP_DPORT,
IFLA_GRE_COLLECT_METADATA,
+ IFLA_GRE_IGNORE_DF,
__IFLA_GRE_MAX,
};
diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h
index b0916fc72cce..22e5e589a274 100644
--- a/include/uapi/linux/iio/types.h
+++ b/include/uapi/linux/iio/types.h
@@ -39,6 +39,7 @@ enum iio_chan_type {
IIO_RESISTANCE,
IIO_PH,
IIO_UVINDEX,
+ IIO_ELECTRICALCONDUCTIVITY,
};
enum iio_modifier {
diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h
index a16643705669..abbd1dc5d683 100644
--- a/include/uapi/linux/inet_diag.h
+++ b/include/uapi/linux/inet_diag.h
@@ -72,6 +72,7 @@ enum {
INET_DIAG_BC_AUTO,
INET_DIAG_BC_S_COND,
INET_DIAG_BC_D_COND,
+ INET_DIAG_BC_DEV_COND, /* u32 ifindex */
};
struct inet_diag_hostcond {
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
index 99048e501b88..aae5ebf2022b 100644
--- a/include/uapi/linux/kexec.h
+++ b/include/uapi/linux/kexec.h
@@ -39,6 +39,7 @@
#define KEXEC_ARCH_SH (42 << 16)
#define KEXEC_ARCH_MIPS_LE (10 << 16)
#define KEXEC_ARCH_MIPS ( 8 << 16)
+#define KEXEC_ARCH_AARCH64 (183 << 16)
/* The artificial cap on the number of segments passed to kexec_load. */
#define KEXEC_SEGMENT_MAX 16
diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h
index 4b3ab2966b5a..991ab4570b8e 100644
--- a/include/uapi/linux/lirc.h
+++ b/include/uapi/linux/lirc.h
@@ -90,20 +90,11 @@
#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, __u32)
#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, __u32)
-#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, __u32)
-#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, __u32)
-#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, __u32)
-#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, __u32)
#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, __u32)
#define LIRC_GET_MIN_TIMEOUT _IOR('i', 0x00000008, __u32)
#define LIRC_GET_MAX_TIMEOUT _IOR('i', 0x00000009, __u32)
-#define LIRC_GET_MIN_FILTER_PULSE _IOR('i', 0x0000000a, __u32)
-#define LIRC_GET_MAX_FILTER_PULSE _IOR('i', 0x0000000b, __u32)
-#define LIRC_GET_MIN_FILTER_SPACE _IOR('i', 0x0000000c, __u32)
-#define LIRC_GET_MAX_FILTER_SPACE _IOR('i', 0x0000000d, __u32)
-
/* code length in bits, currently only for LIRC_MODE_LIRCCODE */
#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, __u32)
@@ -113,7 +104,6 @@
#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, __u32)
#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, __u32)
#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, __u32)
-#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, __u32)
#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, __u32)
/*
@@ -127,42 +117,17 @@
#define LIRC_SET_REC_TIMEOUT_REPORTS _IOW('i', 0x00000019, __u32)
/*
- * pulses shorter than this are filtered out by hardware (software
- * emulation in lirc_dev?)
- */
-#define LIRC_SET_REC_FILTER_PULSE _IOW('i', 0x0000001a, __u32)
-/*
- * spaces shorter than this are filtered out by hardware (software
- * emulation in lirc_dev?)
- */
-#define LIRC_SET_REC_FILTER_SPACE _IOW('i', 0x0000001b, __u32)
-/*
- * if filter cannot be set independently for pulse/space, this should
- * be used
- */
-#define LIRC_SET_REC_FILTER _IOW('i', 0x0000001c, __u32)
-
-/*
* if enabled from the next key press on the driver will send
* LIRC_MODE2_FREQUENCY packets
*/
#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x0000001d, __u32)
/*
- * to set a range use
- * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the
- * lower bound first and later
- * LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound
+ * to set a range use LIRC_SET_REC_CARRIER_RANGE with the
+ * lower bound first and later LIRC_SET_REC_CARRIER with the upper bound
*/
-
-#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, __u32)
#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, __u32)
-#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020)
-
-#define LIRC_SETUP_START _IO('i', 0x00000021)
-#define LIRC_SETUP_END _IO('i', 0x00000022)
-
#define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32)
#endif
diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h
index 546b38886e11..e398beac67b8 100644
--- a/include/uapi/linux/magic.h
+++ b/include/uapi/linux/magic.h
@@ -80,5 +80,7 @@
#define BPF_FS_MAGIC 0xcafe4a11
/* Since UDF 2.01 is ISO 13346 based... */
#define UDF_SUPER_MAGIC 0x15013346
+#define BALLOON_KVM_MAGIC 0x13661366
+#define ZSMALLOC_MAGIC 0x58295829
#endif /* __LINUX_MAGIC_H__ */
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index df59edee25d1..7acf0f634f70 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -95,6 +95,16 @@ struct media_device_info {
#define MEDIA_ENT_F_AUDIO_MIXER (MEDIA_ENT_F_BASE + 0x03003)
/*
+ * Processing entities
+ */
+#define MEDIA_ENT_F_PROC_VIDEO_COMPOSER (MEDIA_ENT_F_BASE + 0x4001)
+#define MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER (MEDIA_ENT_F_BASE + 0x4002)
+#define MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV (MEDIA_ENT_F_BASE + 0x4003)
+#define MEDIA_ENT_F_PROC_VIDEO_LUT (MEDIA_ENT_F_BASE + 0x4004)
+#define MEDIA_ENT_F_PROC_VIDEO_SCALER (MEDIA_ENT_F_BASE + 0x4005)
+#define MEDIA_ENT_F_PROC_VIDEO_STATISTICS (MEDIA_ENT_F_BASE + 0x4006)
+
+/*
* Connectors
*/
/* It is a responsibility of the entity drivers to add connectors and links */
diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
index 309915f74492..ba5a8c79652a 100644
--- a/include/uapi/linux/ndctl.h
+++ b/include/uapi/linux/ndctl.h
@@ -298,6 +298,7 @@ struct nd_cmd_pkg {
#define NVDIMM_FAMILY_INTEL 0
#define NVDIMM_FAMILY_HPE1 1
#define NVDIMM_FAMILY_HPE2 2
+#define NVDIMM_FAMILY_MSFT 3
#define ND_IOCTL_CALL _IOWR(ND_IOCTL, ND_CMD_CALL,\
struct nd_cmd_pkg)
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 6a4dbe04f09e..01751faccaf8 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -546,6 +546,10 @@ enum nft_cmp_attributes {
};
#define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1)
+enum nft_lookup_flags {
+ NFT_LOOKUP_F_INV = (1 << 0),
+};
+
/**
* enum nft_lookup_attributes - nf_tables set lookup expression netlink attributes
*
@@ -553,6 +557,7 @@ enum nft_cmp_attributes {
* @NFTA_LOOKUP_SREG: source register of the data to look for (NLA_U32: nft_registers)
* @NFTA_LOOKUP_DREG: destination register (NLA_U32: nft_registers)
* @NFTA_LOOKUP_SET_ID: uniquely identifies a set in a transaction (NLA_U32)
+ * @NFTA_LOOKUP_FLAGS: flags (NLA_U32: enum nft_lookup_flags)
*/
enum nft_lookup_attributes {
NFTA_LOOKUP_UNSPEC,
@@ -560,6 +565,7 @@ enum nft_lookup_attributes {
NFTA_LOOKUP_SREG,
NFTA_LOOKUP_DREG,
NFTA_LOOKUP_SET_ID,
+ NFTA_LOOKUP_FLAGS,
__NFTA_LOOKUP_MAX
};
#define NFTA_LOOKUP_MAX (__NFTA_LOOKUP_MAX - 1)
diff --git a/include/uapi/linux/netfilter/xt_NFLOG.h b/include/uapi/linux/netfilter/xt_NFLOG.h
index 87b58311ce6b..f33070730fc8 100644
--- a/include/uapi/linux/netfilter/xt_NFLOG.h
+++ b/include/uapi/linux/netfilter/xt_NFLOG.h
@@ -6,9 +6,13 @@
#define XT_NFLOG_DEFAULT_GROUP 0x1
#define XT_NFLOG_DEFAULT_THRESHOLD 0
-#define XT_NFLOG_MASK 0x0
+#define XT_NFLOG_MASK 0x1
+
+/* This flag indicates that 'len' field in xt_nflog_info is set*/
+#define XT_NFLOG_F_COPY_LEN 0x1
struct xt_nflog_info {
+ /* 'len' will be used iff you set XT_NFLOG_F_COPY_LEN in flags */
__u32 len;
__u16 group;
__u16 threshold;
diff --git a/include/uapi/linux/netlink_diag.h b/include/uapi/linux/netlink_diag.h
index d79399394b46..76b4d87c83a8 100644
--- a/include/uapi/linux/netlink_diag.h
+++ b/include/uapi/linux/netlink_diag.h
@@ -49,6 +49,7 @@ enum {
#define NDIAG_SHOW_MEMINFO 0x00000001 /* show memory info of a socket */
#define NDIAG_SHOW_GROUPS 0x00000002 /* show groups of a netlink socket */
#ifndef __KERNEL__
+/* deprecated since 4.6 */
#define NDIAG_SHOW_RING_CFG 0x00000004 /* show ring configuration */
#endif
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index e23d78685a01..220694151434 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -493,7 +493,12 @@
* This attribute is ignored if driver does not support roam scan.
* It is also sent as an event, with the BSSID and response IEs when the
* connection is established or failed to be established. This can be
- * determined by the STATUS_CODE attribute.
+ * determined by the %NL80211_ATTR_STATUS_CODE attribute (0 = success,
+ * non-zero = failure). If %NL80211_ATTR_TIMED_OUT is included in the
+ * event, the connection attempt failed due to not being able to initiate
+ * authentication/association or not receiving a response from the AP.
+ * Non-zero %NL80211_ATTR_STATUS_CODE value is indicated in that case as
+ * well to remain backwards compatible.
* @NL80211_CMD_ROAM: request that the card roam (currently not implemented),
* sent as an event when the card/driver roamed by itself.
* @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify
@@ -1819,6 +1824,49 @@ enum nl80211_commands {
*
* @NL80211_ATTR_PAD: attribute used for padding for 64-bit alignment
*
+ * @NL80211_ATTR_IFTYPE_EXT_CAPA: Nested attribute of the following attributes:
+ * %NL80211_ATTR_IFTYPE, %NL80211_ATTR_EXT_CAPA,
+ * %NL80211_ATTR_EXT_CAPA_MASK, to specify the extended capabilities per
+ * interface type.
+ *
+ * @NL80211_ATTR_MU_MIMO_GROUP_DATA: array of 24 bytes that defines a MU-MIMO
+ * groupID for monitor mode.
+ * The first 8 bytes are a mask that defines the membership in each
+ * group (there are 64 groups, group 0 and 63 are reserved),
+ * each bit represents a group and set to 1 for being a member in
+ * that group and 0 for not being a member.
+ * The remaining 16 bytes define the position in each group: 2 bits for
+ * each group.
+ * (smaller group numbers represented on most significant bits and bigger
+ * group numbers on least significant bits.)
+ * This attribute is used only if all interfaces are in monitor mode.
+ * Set this attribute in order to monitor packets using the given MU-MIMO
+ * groupID data.
+ * to turn off that feature set all the bits of the groupID to zero.
+ * @NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR: mac address for the sniffer to follow
+ * when using MU-MIMO air sniffer.
+ * to turn that feature off set an invalid mac address
+ * (e.g. FF:FF:FF:FF:FF:FF)
+ *
+ * @NL80211_ATTR_SCAN_START_TIME_TSF: The time at which the scan was actually
+ * started (u64). The time is the TSF of the BSS the interface that
+ * requested the scan is connected to (if available, otherwise this
+ * attribute must not be included).
+ * @NL80211_ATTR_SCAN_START_TIME_TSF_BSSID: The BSS according to which
+ * %NL80211_ATTR_SCAN_START_TIME_TSF is set.
+ * @NL80211_ATTR_MEASUREMENT_DURATION: measurement duration in TUs (u16). If
+ * %NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY is not set, this is the
+ * maximum measurement duration allowed. This attribute is used with
+ * measurement requests. It can also be used with %NL80211_CMD_TRIGGER_SCAN
+ * if the scan is used for beacon report radio measurement.
+ * @NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY: flag attribute that indicates
+ * that the duration specified with %NL80211_ATTR_MEASUREMENT_DURATION is
+ * mandatory. If this flag is not set, the duration is the maximum duration
+ * and the actual measurement duration may be shorter.
+ *
+ * @NL80211_ATTR_MESH_PEER_AID: Association ID for the mesh peer (u16). This is
+ * used to pull the stored data for mesh peer in power save state.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2201,6 +2249,18 @@ enum nl80211_attrs {
NL80211_ATTR_PAD,
+ NL80211_ATTR_IFTYPE_EXT_CAPA,
+
+ NL80211_ATTR_MU_MIMO_GROUP_DATA,
+ NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR,
+
+ NL80211_ATTR_SCAN_START_TIME_TSF,
+ NL80211_ATTR_SCAN_START_TIME_TSF_BSSID,
+ NL80211_ATTR_MEASUREMENT_DURATION,
+ NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY,
+
+ NL80211_ATTR_MESH_PEER_AID,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -3462,6 +3522,12 @@ enum nl80211_bss_scan_width {
* was last updated by a received frame. The value is expected to be
* accurate to about 10ms. (u64, nanoseconds)
* @NL80211_BSS_PAD: attribute used for padding for 64-bit alignment
+ * @NL80211_BSS_PARENT_TSF: the time at the start of reception of the first
+ * octet of the timestamp field of the last beacon/probe received for
+ * this BSS. The time is the TSF of the BSS specified by
+ * @NL80211_BSS_PARENT_BSSID. (u64).
+ * @NL80211_BSS_PARENT_BSSID: the BSS according to which @NL80211_BSS_PARENT_TSF
+ * is set.
* @__NL80211_BSS_AFTER_LAST: internal
* @NL80211_BSS_MAX: highest BSS attribute
*/
@@ -3483,6 +3549,8 @@ enum nl80211_bss {
NL80211_BSS_PRESP_DATA,
NL80211_BSS_LAST_SEEN_BOOTTIME,
NL80211_BSS_PAD,
+ NL80211_BSS_PARENT_TSF,
+ NL80211_BSS_PARENT_BSSID,
/* keep last */
__NL80211_BSS_AFTER_LAST,
@@ -4467,6 +4535,22 @@ enum nl80211_feature_flags {
* %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests, which will set
* the ASSOC_REQ_USE_RRM flag in the association request even if
* NL80211_FEATURE_QUIET is not advertized.
+ * @NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER: This device supports MU-MIMO air
+ * sniffer which means that it can be configured to hear packets from
+ * certain groups which can be configured by the
+ * %NL80211_ATTR_MU_MIMO_GROUP_DATA attribute,
+ * or can be configured to follow a station by configuring the
+ * %NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR attribute.
+ * @NL80211_EXT_FEATURE_SCAN_START_TIME: This driver includes the actual
+ * time the scan started in scan results event. The time is the TSF of
+ * the BSS that the interface that requested the scan is connected to
+ * (if available).
+ * @NL80211_EXT_FEATURE_BSS_PARENT_TSF: Per BSS, this driver reports the
+ * time the last beacon/probe was received. The time is the TSF of the
+ * BSS that the interface that requested the scan is connected to
+ * (if available).
+ * @NL80211_EXT_FEATURE_SET_SCAN_DWELL: This driver supports configuration of
+ * channel dwell time.
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4474,6 +4558,10 @@ enum nl80211_feature_flags {
enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_VHT_IBSS,
NL80211_EXT_FEATURE_RRM,
+ NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER,
+ NL80211_EXT_FEATURE_SCAN_START_TIME,
+ NL80211_EXT_FEATURE_BSS_PARENT_TSF,
+ NL80211_EXT_FEATURE_SET_SCAN_DWELL,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h
index bb0d515b7654..d95a3018f6a1 100644
--- a/include/uapi/linux/openvswitch.h
+++ b/include/uapi/linux/openvswitch.h
@@ -166,6 +166,7 @@ enum ovs_packet_cmd {
* output port is actually a tunnel port. Contains the output tunnel key
* extracted from the packet as nested %OVS_TUNNEL_KEY_ATTR_* attributes.
* @OVS_PACKET_ATTR_MRU: Present for an %OVS_PACKET_CMD_ACTION and
+ * @OVS_PACKET_ATTR_LEN: Packet size before truncation.
* %OVS_PACKET_ATTR_USERSPACE action specify the Maximum received fragment
* size.
*
@@ -185,6 +186,7 @@ enum ovs_packet_attr {
OVS_PACKET_ATTR_PROBE, /* Packet operation is a feature probe,
error logging should be suppressed. */
OVS_PACKET_ATTR_MRU, /* Maximum received IP fragment size. */
+ OVS_PACKET_ATTR_LEN, /* Packet size before truncation. */
__OVS_PACKET_ATTR_MAX
};
@@ -580,6 +582,10 @@ enum ovs_userspace_attr {
#define OVS_USERSPACE_ATTR_MAX (__OVS_USERSPACE_ATTR_MAX - 1)
+struct ovs_action_trunc {
+ uint32_t max_len; /* Max packet size in bytes. */
+};
+
/**
* struct ovs_action_push_mpls - %OVS_ACTION_ATTR_PUSH_MPLS action argument.
* @mpls_lse: MPLS label stack entry to push.
@@ -703,6 +709,7 @@ enum ovs_nat_attr {
* enum ovs_action_attr - Action types.
*
* @OVS_ACTION_ATTR_OUTPUT: Output packet to port.
+ * @OVS_ACTION_ATTR_TRUNC: Output packet to port with truncated packet size.
* @OVS_ACTION_ATTR_USERSPACE: Send packet to userspace according to nested
* %OVS_USERSPACE_ATTR_* attributes.
* @OVS_ACTION_ATTR_SET: Replaces the contents of an existing header. The
@@ -756,6 +763,7 @@ enum ovs_action_attr {
* The data must be zero for the unmasked
* bits. */
OVS_ACTION_ATTR_CT, /* Nested OVS_CT_ATTR_* . */
+ OVS_ACTION_ATTR_TRUNC, /* u32 struct ovs_action_trunc. */
__OVS_ACTION_ATTR_MAX, /* Nothing past this will be accepted
* from userspace. */
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 36ce552cf6a9..c66a485a24ac 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -276,6 +276,9 @@ enum perf_event_read_format {
/*
* Hardware event_id to monitor via a performance monitoring event:
+ *
+ * @sample_max_stack: Max number of frame pointers in a callchain,
+ * should be < /proc/sys/kernel/perf_event_max_stack
*/
struct perf_event_attr {
@@ -385,7 +388,8 @@ struct perf_event_attr {
* Wakeup watermark for AUX area
*/
__u32 aux_watermark;
- __u32 __reserved_2; /* align to __u64 */
+ __u16 sample_max_stack;
+ __u16 __reserved_2; /* align to __u64 */
};
#define perf_flags(attr) (*(&(attr)->read_format + 1))
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index f4297c8a42fe..d1c1ccaba787 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -115,8 +115,8 @@ struct tc_police {
__u32 mtu;
struct tc_ratespec rate;
struct tc_ratespec peakrate;
- int refcnt;
- int bindcnt;
+ int refcnt;
+ int bindcnt;
__u32 capab;
};
@@ -124,10 +124,11 @@ struct tcf_t {
__u64 install;
__u64 lastuse;
__u64 expires;
+ __u64 firstuse;
};
struct tc_cnt {
- int refcnt;
+ int refcnt;
int bindcnt;
};
@@ -432,6 +433,18 @@ enum {
#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
+/* Match-all classifier */
+
+enum {
+ TCA_MATCHALL_UNSPEC,
+ TCA_MATCHALL_CLASSID,
+ TCA_MATCHALL_ACT,
+ TCA_MATCHALL_FLAGS,
+ __TCA_MATCHALL_MAX,
+};
+
+#define TCA_MATCHALL_MAX (__TCA_MATCHALL_MAX - 1)
+
/* Extended Matches */
struct tcf_ematch_tree_hdr {
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index ce70fe6b45df..d304f4c9792c 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -112,6 +112,31 @@ typedef __s32 sctp_assoc_t;
#define SCTP_SOCKOPT_CONNECTX 110 /* CONNECTX requests. */
#define SCTP_SOCKOPT_CONNECTX3 111 /* CONNECTX requests (updated) */
#define SCTP_GET_ASSOC_STATS 112 /* Read only */
+#define SCTP_PR_SUPPORTED 113
+#define SCTP_DEFAULT_PRINFO 114
+#define SCTP_PR_ASSOC_STATUS 115
+
+/* PR-SCTP policies */
+#define SCTP_PR_SCTP_NONE 0x0000
+#define SCTP_PR_SCTP_TTL 0x0010
+#define SCTP_PR_SCTP_RTX 0x0020
+#define SCTP_PR_SCTP_PRIO 0x0030
+#define SCTP_PR_SCTP_MAX SCTP_PR_SCTP_PRIO
+#define SCTP_PR_SCTP_MASK 0x0030
+
+#define __SCTP_PR_INDEX(x) ((x >> 4) - 1)
+#define SCTP_PR_INDEX(x) __SCTP_PR_INDEX(SCTP_PR_SCTP_ ## x)
+
+#define SCTP_PR_POLICY(x) ((x) & SCTP_PR_SCTP_MASK)
+#define SCTP_PR_SET_POLICY(flags, x) \
+ do { \
+ flags &= ~SCTP_PR_SCTP_MASK; \
+ flags |= x; \
+ } while (0)
+
+#define SCTP_PR_TTL_ENABLED(x) (SCTP_PR_POLICY(x) == SCTP_PR_SCTP_TTL)
+#define SCTP_PR_RTX_ENABLED(x) (SCTP_PR_POLICY(x) == SCTP_PR_SCTP_RTX)
+#define SCTP_PR_PRIO_ENABLED(x) (SCTP_PR_POLICY(x) == SCTP_PR_SCTP_PRIO)
/* These are bit fields for msghdr->msg_flags. See section 5.1. */
/* On user space Linux, these live in <bits/socket.h> as an enum. */
@@ -902,4 +927,21 @@ struct sctp_paddrthlds {
__u16 spt_pathpfthld;
};
+/*
+ * Socket Option for Getting the Association/Stream-Specific PR-SCTP Status
+ */
+struct sctp_prstatus {
+ sctp_assoc_t sprstat_assoc_id;
+ __u16 sprstat_sid;
+ __u16 sprstat_policy;
+ __u64 sprstat_abandoned_unsent;
+ __u64 sprstat_abandoned_sent;
+};
+
+struct sctp_default_prinfo {
+ sctp_assoc_t pr_assoc_id;
+ __u32 pr_value;
+ __u16 pr_policy;
+};
+
#endif /* _UAPI_SCTP_H */
diff --git a/include/uapi/linux/serio.h b/include/uapi/linux/serio.h
index c2ea1698257f..f2447a83ac8d 100644
--- a/include/uapi/linux/serio.h
+++ b/include/uapi/linux/serio.h
@@ -78,5 +78,6 @@
#define SERIO_TSC40 0x3d
#define SERIO_WACOM_IV 0x3e
#define SERIO_EGALAX 0x3f
+#define SERIO_PULSE8_CEC 0x40
#endif /* _UAPI_SERIO_H */
diff --git a/include/uapi/linux/tc_act/tc_skbedit.h b/include/uapi/linux/tc_act/tc_skbedit.h
index fecb5cc48c40..a4d00c608d8f 100644
--- a/include/uapi/linux/tc_act/tc_skbedit.h
+++ b/include/uapi/linux/tc_act/tc_skbedit.h
@@ -27,6 +27,7 @@
#define SKBEDIT_F_PRIORITY 0x1
#define SKBEDIT_F_QUEUE_MAPPING 0x2
#define SKBEDIT_F_MARK 0x4
+#define SKBEDIT_F_PTYPE 0x8
struct tc_skbedit {
tc_gen;
@@ -40,6 +41,7 @@ enum {
TCA_SKBEDIT_QUEUE_MAPPING,
TCA_SKBEDIT_MARK,
TCA_SKBEDIT_PAD,
+ TCA_SKBEDIT_PTYPE,
__TCA_SKBEDIT_MAX
};
#define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1)
diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h
index 53e8e3fe6b1b..482898fc433a 100644
--- a/include/uapi/linux/tcp.h
+++ b/include/uapi/linux/tcp.h
@@ -115,12 +115,22 @@ enum {
#define TCP_CC_INFO 26 /* Get Congestion Control (optional) info */
#define TCP_SAVE_SYN 27 /* Record SYN headers for new connections */
#define TCP_SAVED_SYN 28 /* Get SYN headers recorded for connection */
+#define TCP_REPAIR_WINDOW 29 /* Get/set window parameters */
struct tcp_repair_opt {
__u32 opt_code;
__u32 opt_val;
};
+struct tcp_repair_window {
+ __u32 snd_wl1;
+ __u32 snd_wnd;
+ __u32 max_window;
+
+ __u32 rcv_wnd;
+ __u32 rcv_wup;
+};
+
enum {
TCP_NO_QUEUE,
TCP_RECV_QUEUE,
diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
index 6f71b9b41595..bf049e8fe31b 100644
--- a/include/uapi/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
@@ -60,26 +60,48 @@ struct tipc_name_seq {
__u32 upper;
};
+/* TIPC Address Size, Offset, Mask specification for Z.C.N
+ */
+#define TIPC_NODE_BITS 12
+#define TIPC_CLUSTER_BITS 12
+#define TIPC_ZONE_BITS 8
+
+#define TIPC_NODE_OFFSET 0
+#define TIPC_CLUSTER_OFFSET TIPC_NODE_BITS
+#define TIPC_ZONE_OFFSET (TIPC_CLUSTER_OFFSET + TIPC_CLUSTER_BITS)
+
+#define TIPC_NODE_SIZE ((1UL << TIPC_NODE_BITS) - 1)
+#define TIPC_CLUSTER_SIZE ((1UL << TIPC_CLUSTER_BITS) - 1)
+#define TIPC_ZONE_SIZE ((1UL << TIPC_ZONE_BITS) - 1)
+
+#define TIPC_NODE_MASK (TIPC_NODE_SIZE << TIPC_NODE_OFFSET)
+#define TIPC_CLUSTER_MASK (TIPC_CLUSTER_SIZE << TIPC_CLUSTER_OFFSET)
+#define TIPC_ZONE_MASK (TIPC_ZONE_SIZE << TIPC_ZONE_OFFSET)
+
+#define TIPC_ZONE_CLUSTER_MASK (TIPC_ZONE_MASK | TIPC_CLUSTER_MASK)
+
static inline __u32 tipc_addr(unsigned int zone,
unsigned int cluster,
unsigned int node)
{
- return (zone << 24) | (cluster << 12) | node;
+ return (zone << TIPC_ZONE_OFFSET) |
+ (cluster << TIPC_CLUSTER_OFFSET) |
+ node;
}
static inline unsigned int tipc_zone(__u32 addr)
{
- return addr >> 24;
+ return addr >> TIPC_ZONE_OFFSET;
}
static inline unsigned int tipc_cluster(__u32 addr)
{
- return (addr >> 12) & 0xfff;
+ return (addr & TIPC_CLUSTER_MASK) >> TIPC_CLUSTER_OFFSET;
}
static inline unsigned int tipc_node(__u32 addr)
{
- return addr & 0xfff;
+ return addr & TIPC_NODE_MASK;
}
/*
diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h
index d4c8f142ba63..5f3f6d09fb79 100644
--- a/include/uapi/linux/tipc_netlink.h
+++ b/include/uapi/linux/tipc_netlink.h
@@ -56,6 +56,9 @@ enum {
TIPC_NL_NET_GET,
TIPC_NL_NET_SET,
TIPC_NL_NAME_TABLE_GET,
+ TIPC_NL_MON_SET,
+ TIPC_NL_MON_GET,
+ TIPC_NL_MON_PEER_GET,
__TIPC_NL_CMD_MAX,
TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
@@ -72,6 +75,8 @@ enum {
TIPC_NLA_NODE, /* nest */
TIPC_NLA_NET, /* nest */
TIPC_NLA_NAME_TABLE, /* nest */
+ TIPC_NLA_MON, /* nest */
+ TIPC_NLA_MON_PEER, /* nest */
__TIPC_NLA_MAX,
TIPC_NLA_MAX = __TIPC_NLA_MAX - 1
@@ -166,6 +171,20 @@ enum {
TIPC_NLA_NAME_TABLE_MAX = __TIPC_NLA_NAME_TABLE_MAX - 1
};
+/* Monitor info */
+enum {
+ TIPC_NLA_MON_UNSPEC,
+ TIPC_NLA_MON_ACTIVATION_THRESHOLD, /* u32 */
+ TIPC_NLA_MON_REF, /* u32 */
+ TIPC_NLA_MON_ACTIVE, /* flag */
+ TIPC_NLA_MON_BEARER_NAME, /* string */
+ TIPC_NLA_MON_PEERCNT, /* u32 */
+ TIPC_NLA_MON_LISTGEN, /* u32 */
+
+ __TIPC_NLA_MON_MAX,
+ TIPC_NLA_MON_MAX = __TIPC_NLA_MON_MAX - 1
+};
+
/* Publication info */
enum {
TIPC_NLA_PUBL_UNSPEC,
@@ -182,6 +201,24 @@ enum {
TIPC_NLA_PUBL_MAX = __TIPC_NLA_PUBL_MAX - 1
};
+/* Monitor peer info */
+enum {
+ TIPC_NLA_MON_PEER_UNSPEC,
+
+ TIPC_NLA_MON_PEER_ADDR, /* u32 */
+ TIPC_NLA_MON_PEER_DOMGEN, /* u32 */
+ TIPC_NLA_MON_PEER_APPLIED, /* u32 */
+ TIPC_NLA_MON_PEER_UPMAP, /* u64 */
+ TIPC_NLA_MON_PEER_MEMBERS, /* tlv */
+ TIPC_NLA_MON_PEER_UP, /* flag */
+ TIPC_NLA_MON_PEER_HEAD, /* flag */
+ TIPC_NLA_MON_PEER_LOCAL, /* flag */
+ TIPC_NLA_MON_PEER_PAD, /* flag */
+
+ __TIPC_NLA_MON_PEER_MAX,
+ TIPC_NLA_MON_PEER_MAX = __TIPC_NLA_MON_PEER_MAX - 1
+};
+
/* Nest, connection info */
enum {
TIPC_NLA_CON_UNSPEC,
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 8f951917be74..724f43e69d03 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -504,22 +504,16 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_UV8 v4l2_fourcc('U', 'V', '8', ' ') /* 8 UV 4:4 */
/* Luminance+Chrominance formats */
-#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */
-#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */
#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */
#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16 YUV 4:2:2 */
#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */
#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */
#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */
-#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */
-#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */
#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */
#define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') /* 16 xxxxyyyy uuuuvvvv */
#define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') /* 16 YUV-5-5-5 */
#define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') /* 16 YUV-5-6-5 */
#define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') /* 32 YUV-8-8-8-8 */
-#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */
-#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */
#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */
#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */
#define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0') /* 12 YUV 4:2:0 2 lines y, 1 line uv interleaved */
@@ -540,6 +534,14 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */
#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 16x16 macroblocks */
+/* three planes - Y Cb, Cr */
+#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */
+#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */
+#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 12 YVU411 planar */
+#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */
+#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */
+#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */
+
/* three non contiguous planes - Y, Cb, Cr */
#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 planar */
#define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'M', '2', '1') /* 12 YVU420 planar */
diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
index ec32293a00db..fc353b518288 100644
--- a/include/uapi/linux/virtio_net.h
+++ b/include/uapi/linux/virtio_net.h
@@ -1,5 +1,5 @@
-#ifndef _LINUX_VIRTIO_NET_H
-#define _LINUX_VIRTIO_NET_H
+#ifndef _UAPI_LINUX_VIRTIO_NET_H
+#define _UAPI_LINUX_VIRTIO_NET_H
/* This header is BSD licensed so anyone can use the definitions to implement
* compatible drivers/servers.
*
@@ -35,6 +35,7 @@
#define VIRTIO_NET_F_CSUM 0 /* Host handles pkts w/ partial csum */
#define VIRTIO_NET_F_GUEST_CSUM 1 /* Guest handles pkts w/ partial csum */
#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload configuration. */
+#define VIRTIO_NET_F_MTU 3 /* Initial MTU advice */
#define VIRTIO_NET_F_MAC 5 /* Host has given MAC address. */
#define VIRTIO_NET_F_GUEST_TSO4 7 /* Guest can handle TSOv4 in. */
#define VIRTIO_NET_F_GUEST_TSO6 8 /* Guest can handle TSOv6 in. */
@@ -73,6 +74,8 @@ struct virtio_net_config {
* Legal values are between 1 and 0x8000
*/
__u16 max_virtqueue_pairs;
+ /* Default maximum transmit unit advice */
+ __u16 mtu;
} __attribute__((packed));
/*
@@ -242,4 +245,4 @@ struct virtio_net_ctrl_mq {
#define VIRTIO_NET_CTRL_GUEST_OFFLOADS 5
#define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET 0
-#endif /* _LINUX_VIRTIO_NET_H */
+#endif /* _UAPI_LINUX_VIRTIO_NET_H */
diff --git a/include/uapi/linux/vsp1.h b/include/uapi/linux/vsp1.h
deleted file mode 100644
index 9a823696d816..000000000000
--- a/include/uapi/linux/vsp1.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * vsp1.h
- *
- * Renesas R-Car VSP1 - User-space API
- *
- * Copyright (C) 2013 Renesas Corporation
- *
- * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __VSP1_USER_H__
-#define __VSP1_USER_H__
-
-#include <linux/types.h>
-#include <linux/videodev2.h>
-
-/*
- * Private IOCTLs
- *
- * VIDIOC_VSP1_LUT_CONFIG - Configure the lookup table
- */
-
-#define VIDIOC_VSP1_LUT_CONFIG \
- _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct vsp1_lut_config)
-
-struct vsp1_lut_config {
- __u32 lut[256];
-};
-
-#endif /* __VSP1_USER_H__ */
diff --git a/include/uapi/linux/wireless.h b/include/uapi/linux/wireless.h
index c1592e3e4036..d9ecd7c6d691 100644
--- a/include/uapi/linux/wireless.h
+++ b/include/uapi/linux/wireless.h
@@ -670,8 +670,7 @@
/*
* Generic format for most parameters that fit in an int
*/
-struct iw_param
-{
+struct iw_param {
__s32 value; /* The value of the parameter itself */
__u8 fixed; /* Hardware should not use auto select */
__u8 disabled; /* Disable the feature */
@@ -682,8 +681,7 @@ struct iw_param
* For all data larger than 16 octets, we need to use a
* pointer to memory allocated in user space.
*/
-struct iw_point
-{
+struct iw_point {
void __user *pointer; /* Pointer to the data (in user space) */
__u16 length; /* number of fields or size in bytes */
__u16 flags; /* Optional params */
@@ -698,8 +696,7 @@ struct iw_point
* of 10 to get 'm' lower than 10^9, with 'm'= f / (10^'e')...
* The power of 10 is in 'e', the result of the division is in 'm'.
*/
-struct iw_freq
-{
+struct iw_freq {
__s32 m; /* Mantissa */
__s16 e; /* Exponent */
__u8 i; /* List index (when in range struct) */
@@ -709,8 +706,7 @@ struct iw_freq
/*
* Quality of the link
*/
-struct iw_quality
-{
+struct iw_quality {
__u8 qual; /* link quality (%retries, SNR,
%missed beacons or better...) */
__u8 level; /* signal level (dBm) */
@@ -725,8 +721,7 @@ struct iw_quality
* is already pretty exhaustive, and you should use that first.
* This is only additional stats...
*/
-struct iw_discarded
-{
+struct iw_discarded {
__u32 nwid; /* Rx : Wrong nwid/essid */
__u32 code; /* Rx : Unable to code/decode (WEP) */
__u32 fragment; /* Rx : Can't perform MAC reassembly */
@@ -738,16 +733,14 @@ struct iw_discarded
* Packet/Time period missed in the wireless adapter due to
* "wireless" specific problems...
*/
-struct iw_missed
-{
+struct iw_missed {
__u32 beacon; /* Missed beacons/superframe */
};
/*
* Quality range (for spy threshold)
*/
-struct iw_thrspy
-{
+struct iw_thrspy {
struct sockaddr addr; /* Source address (hw/mac) */
struct iw_quality qual; /* Quality of the link */
struct iw_quality low; /* Low threshold */
@@ -765,8 +758,7 @@ struct iw_thrspy
* Especially, scan results are required to include an entry for the
* current BSS if the driver is in Managed mode and associated with an AP.
*/
-struct iw_scan_req
-{
+struct iw_scan_req {
__u8 scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} */
__u8 essid_len;
__u8 num_channels; /* num entries in channel_list;
@@ -827,8 +819,7 @@ struct iw_scan_req
* RX_SEQ_VALID for SIOCGIWENCODEEXT are optional, but can be useful for
* debugging/testing.
*/
-struct iw_encode_ext
-{
+struct iw_encode_ext {
__u32 ext_flags; /* IW_ENCODE_EXT_* */
__u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
__u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
@@ -841,8 +832,7 @@ struct iw_encode_ext
};
/* SIOCSIWMLME data */
-struct iw_mlme
-{
+struct iw_mlme {
__u16 cmd; /* IW_MLME_* */
__u16 reason_code;
struct sockaddr addr;
@@ -855,16 +845,14 @@ struct iw_mlme
#define IW_PMKID_LEN 16
-struct iw_pmksa
-{
+struct iw_pmksa {
__u32 cmd; /* IW_PMKSA_* */
struct sockaddr bssid;
__u8 pmkid[IW_PMKID_LEN];
};
/* IWEVMICHAELMICFAILURE data */
-struct iw_michaelmicfailure
-{
+struct iw_michaelmicfailure {
__u32 flags;
struct sockaddr src_addr;
__u8 tsc[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */
@@ -872,8 +860,7 @@ struct iw_michaelmicfailure
/* IWEVPMKIDCAND data */
#define IW_PMKID_CAND_PREAUTH 0x00000001 /* RNS pre-authentication enabled */
-struct iw_pmkid_cand
-{
+struct iw_pmkid_cand {
__u32 flags; /* IW_PMKID_CAND_* */
__u32 index; /* the smaller the index, the higher the
* priority */
@@ -884,8 +871,7 @@ struct iw_pmkid_cand
/*
* Wireless statistics (used for /proc/net/wireless)
*/
-struct iw_statistics
-{
+struct iw_statistics {
__u16 status; /* Status
* - device dependent for now */
@@ -897,7 +883,7 @@ struct iw_statistics
/* ------------------------ IOCTL REQUEST ------------------------ */
/*
- * This structure defines the payload of an ioctl, and is used
+ * This structure defines the payload of an ioctl, and is used
* below.
*
* Note that this structure should fit on the memory footprint
@@ -906,8 +892,7 @@ struct iw_statistics
* You should check this when increasing the structures defined
* above in this file...
*/
-union iwreq_data
-{
+union iwreq_data {
/* Config - generic */
char name[IFNAMSIZ];
/* Name : used to verify the presence of wireless extensions.
@@ -944,15 +929,14 @@ union iwreq_data
* convenience...
* Do I need to remind you about structure size (32 octets) ?
*/
-struct iwreq
-{
+struct iwreq {
union
{
char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */
} ifr_ifrn;
/* Data part (defined just above) */
- union iwreq_data u;
+ union iwreq_data u;
};
/* -------------------------- IOCTL DATA -------------------------- */
@@ -965,8 +949,7 @@ struct iwreq
* Range of parameters
*/
-struct iw_range
-{
+struct iw_range {
/* Informative stuff (to choose between different interface) */
__u32 throughput; /* To give an idea... */
/* In theory this value should be the maximum benchmarked
@@ -1069,9 +1052,8 @@ struct iw_range
/*
* Private ioctl interface information
*/
-
-struct iw_priv_args
-{
+
+struct iw_priv_args {
__u32 cmd; /* Number of the ioctl to issue */
__u16 set_args; /* Type and number of args */
__u16 get_args; /* Type and number of args */
@@ -1088,8 +1070,7 @@ struct iw_priv_args
/*
* A Wireless Event. Contains basically the same data as the ioctl...
*/
-struct iw_event
-{
+struct iw_event {
__u16 len; /* Real length of this stuff */
__u16 cmd; /* Wireless IOCTL */
union iwreq_data u; /* IOCTL fixed payload */
diff --git a/include/uapi/xen/evtchn.h b/include/uapi/xen/evtchn.h
index 14e833ee4e0b..cb4aa4bb905e 100644
--- a/include/uapi/xen/evtchn.h
+++ b/include/uapi/xen/evtchn.h
@@ -85,4 +85,19 @@ struct ioctl_evtchn_notify {
#define IOCTL_EVTCHN_RESET \
_IOC(_IOC_NONE, 'E', 5, 0)
+/*
+ * Restrict this file descriptor so that it can only be used to bind
+ * new interdomain events from one domain.
+ *
+ * Once a file descriptor has been restricted it cannot be
+ * de-restricted, and must be closed and re-opened. Event channels
+ * which were bound before restricting remain bound afterwards, and
+ * can be notified as usual.
+ */
+#define IOCTL_EVTCHN_RESTRICT_DOMID \
+ _IOC(_IOC_NONE, 'E', 6, sizeof(struct ioctl_evtchn_restrict_domid))
+struct ioctl_evtchn_restrict_domid {
+ domid_t domid;
+};
+
#endif /* __LINUX_PUBLIC_EVTCHN_H__ */
diff --git a/include/xen/interface/hvm/params.h b/include/xen/interface/hvm/params.h
index a6c79911e729..4d61fc58d99d 100644
--- a/include/xen/interface/hvm/params.h
+++ b/include/xen/interface/hvm/params.h
@@ -27,16 +27,44 @@
* Parameter space for HVMOP_{set,get}_param.
*/
+#define HVM_PARAM_CALLBACK_IRQ 0
/*
* How should CPU0 event-channel notifications be delivered?
- * val[63:56] == 0: val[55:0] is a delivery GSI (Global System Interrupt).
- * val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows:
- * Domain = val[47:32], Bus = val[31:16],
- * DevFn = val[15: 8], IntX = val[ 1: 0]
- * val[63:56] == 2: val[7:0] is a vector number.
+ *
* If val == 0 then CPU0 event-channel notifications are not delivered.
+ * If val != 0, val[63:56] encodes the type, as follows:
*/
-#define HVM_PARAM_CALLBACK_IRQ 0
+
+#define HVM_PARAM_CALLBACK_TYPE_GSI 0
+/*
+ * val[55:0] is a delivery GSI. GSI 0 cannot be used, as it aliases val == 0,
+ * and disables all notifications.
+ */
+
+#define HVM_PARAM_CALLBACK_TYPE_PCI_INTX 1
+/*
+ * val[55:0] is a delivery PCI INTx line:
+ * Domain = val[47:32], Bus = val[31:16] DevFn = val[15:8], IntX = val[1:0]
+ */
+
+#if defined(__i386__) || defined(__x86_64__)
+#define HVM_PARAM_CALLBACK_TYPE_VECTOR 2
+/*
+ * val[7:0] is a vector number. Check for XENFEAT_hvm_callback_vector to know
+ * if this delivery method is available.
+ */
+#elif defined(__arm__) || defined(__aarch64__)
+#define HVM_PARAM_CALLBACK_TYPE_PPI 2
+/*
+ * val[55:16] needs to be zero.
+ * val[15:8] is interrupt flag of the PPI used by event-channel:
+ * bit 8: the PPI is edge(1) or level(0) triggered
+ * bit 9: the PPI is active low(1) or high(0)
+ * val[7:0] is a PPI number used by event-channel.
+ * This is only used by ARM/ARM64 and masking/eoi the interrupt associated to
+ * the notification is handled by the interrupt controller.
+ */
+#endif
#define HVM_PARAM_STORE_PFN 1
#define HVM_PARAM_STORE_EVTCHN 2
diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h
index 2ecfe4f700d9..9aa8988cb340 100644
--- a/include/xen/interface/memory.h
+++ b/include/xen/interface/memory.h
@@ -160,6 +160,7 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mapping_t);
#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom,
* XENMEM_add_to_physmap_range only.
*/
+#define XENMAPSPACE_dev_mmio 5 /* device mmio region */
/*
* Sets the GPFN at which a particular page appears in the specified guest's
diff --git a/include/xen/interface/vcpu.h b/include/xen/interface/vcpu.h
index b05288ce3991..98188c87f5c1 100644
--- a/include/xen/interface/vcpu.h
+++ b/include/xen/interface/vcpu.h
@@ -75,15 +75,21 @@
*/
#define VCPUOP_get_runstate_info 4
struct vcpu_runstate_info {
- /* VCPU's current state (RUNSTATE_*). */
- int state;
- /* When was current state entered (system time, ns)? */
- uint64_t state_entry_time;
- /*
- * Time spent in each RUNSTATE_* (ns). The sum of these times is
- * guaranteed not to drift from system time.
- */
- uint64_t time[4];
+ /* VCPU's current state (RUNSTATE_*). */
+ int state;
+ /* When was current state entered (system time, ns)? */
+ uint64_t state_entry_time;
+ /*
+ * Update indicator set in state_entry_time:
+ * When activated via VMASST_TYPE_runstate_update_flag, set during
+ * updates in guest memory mapped copy of vcpu_runstate_info.
+ */
+#define XEN_RUNSTATE_UPDATE (1ULL << 63)
+ /*
+ * Time spent in each RUNSTATE_* (ns). The sum of these times is
+ * guaranteed not to drift from system time.
+ */
+ uint64_t time[4];
};
DEFINE_GUEST_HANDLE_STRUCT(vcpu_runstate_info);
diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h
index d1331121c0bd..1b0d189cd3d3 100644
--- a/include/xen/interface/xen.h
+++ b/include/xen/interface/xen.h
@@ -413,7 +413,22 @@ DEFINE_GUEST_HANDLE_STRUCT(mmuext_op);
/* x86/PAE guests: support PDPTs above 4GB. */
#define VMASST_TYPE_pae_extended_cr3 3
-#define MAX_VMASST_TYPE 3
+/*
+ * x86 guests: Sane behaviour for virtual iopl
+ * - virtual iopl updated from do_iret() hypercalls.
+ * - virtual iopl reported in bounce frames.
+ * - guest kernels assumed to be level 0 for the purpose of iopl checks.
+ */
+#define VMASST_TYPE_architectural_iopl 4
+
+/*
+ * All guests: activate update indicator in vcpu_runstate_info
+ * Enable setting the XEN_RUNSTATE_UPDATE flag in guest memory mapped
+ * vcpu_runstate_info during updates of the runstate information.
+ */
+#define VMASST_TYPE_runstate_update_flag 5
+
+#define MAX_VMASST_TYPE 5
#ifndef __ASSEMBLY__
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
index 86abe07b20ec..9a37c541822f 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
@@ -9,6 +9,12 @@
DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
+DECLARE_PER_CPU(int, xen_vcpu_id);
+static inline int xen_vcpu_nr(int cpu)
+{
+ return per_cpu(xen_vcpu_id, cpu);
+}
+
void xen_arch_pre_suspend(void);
void xen_arch_post_suspend(int suspend_cancelled);
@@ -21,7 +27,9 @@ void xen_resume_notifier_unregister(struct notifier_block *nb);
bool xen_vcpu_stolen(int vcpu);
void xen_setup_runstate_info(int cpu);
+void xen_time_setup_guest(void);
void xen_get_runstate_snapshot(struct vcpu_runstate_info *res);
+u64 xen_steal_clock(int cpu);
int xen_setup_shutdown_event(void);
@@ -85,17 +93,33 @@ int xen_xlate_remap_gfn_array(struct vm_area_struct *vma,
struct page **pages);
int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
int nr, struct page **pages);
+int xen_xlate_map_ballooned_pages(xen_pfn_t **pfns, void **vaddr,
+ unsigned long nr_grant_frames);
bool xen_running_on_version_or_later(unsigned int major, unsigned int minor);
-#ifdef CONFIG_XEN_EFI
-extern efi_system_table_t *xen_efi_probe(void);
-#else
-static inline efi_system_table_t __init *xen_efi_probe(void)
-{
- return NULL;
-}
-#endif
+efi_status_t xen_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc);
+efi_status_t xen_efi_set_time(efi_time_t *tm);
+efi_status_t xen_efi_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending,
+ efi_time_t *tm);
+efi_status_t xen_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm);
+efi_status_t xen_efi_get_variable(efi_char16_t *name, efi_guid_t *vendor,
+ u32 *attr, unsigned long *data_size,
+ void *data);
+efi_status_t xen_efi_get_next_variable(unsigned long *name_size,
+ efi_char16_t *name, efi_guid_t *vendor);
+efi_status_t xen_efi_set_variable(efi_char16_t *name, efi_guid_t *vendor,
+ u32 attr, unsigned long data_size,
+ void *data);
+efi_status_t xen_efi_query_variable_info(u32 attr, u64 *storage_space,
+ u64 *remaining_space,
+ u64 *max_variable_size);
+efi_status_t xen_efi_get_next_high_mono_count(u32 *count);
+efi_status_t xen_efi_update_capsule(efi_capsule_header_t **capsules,
+ unsigned long count, unsigned long sg_list);
+efi_status_t xen_efi_query_capsule_caps(efi_capsule_header_t **capsules,
+ unsigned long count, u64 *max_size,
+ int *reset_type);
#ifdef CONFIG_PREEMPT