diff options
Diffstat (limited to 'include')
117 files changed, 2886 insertions, 1042 deletions
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index a75cb371cd19..88ebc6102c7c 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -1095,6 +1095,24 @@ static inline bool arch_has_pfn_modify_check(void) } #endif /* !_HAVE_ARCH_PFN_MODIFY_ALLOWED */ +/* + * Architecture PAGE_KERNEL_* fallbacks + * + * Some architectures don't define certain PAGE_KERNEL_* flags. This is either + * because they really don't support them, or the port needs to be updated to + * reflect the required functionality. Below are a set of relatively safe + * fallbacks, as best effort, which we can count on in lieu of the architectures + * not defining them on their own yet. + */ + +#ifndef PAGE_KERNEL_RO +# define PAGE_KERNEL_RO PAGE_KERNEL +#endif + +#ifndef PAGE_KERNEL_EXEC +# define PAGE_KERNEL_EXEC PAGE_KERNEL +#endif + #endif /* !__ASSEMBLY__ */ #ifndef io_remap_pfn_range diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index e373e2e10f6a..f173b5f30dbe 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -218,7 +218,6 @@ #define TIMER_OF_TABLES() OF_TABLE(CONFIG_TIMER_OF, timer) #define IRQCHIP_OF_MATCH_TABLE() OF_TABLE(CONFIG_IRQCHIP, irqchip) #define CLK_OF_TABLES() OF_TABLE(CONFIG_COMMON_CLK, clk) -#define IOMMU_OF_TABLES() OF_TABLE(CONFIG_OF_IOMMU, iommu) #define RESERVEDMEM_OF_TABLES() OF_TABLE(CONFIG_OF_RESERVED_MEM, reservedmem) #define CPU_METHOD_OF_TABLES() OF_TABLE(CONFIG_SMP, cpu_method) #define CPUIDLE_METHOD_OF_TABLES() OF_TABLE(CONFIG_CPU_IDLE, cpuidle_method) @@ -601,7 +600,6 @@ CLK_OF_TABLES() \ RESERVEDMEM_OF_TABLES() \ TIMER_OF_TABLES() \ - IOMMU_OF_TABLES() \ CPU_METHOD_OF_TABLES() \ CPUIDLE_METHOD_OF_TABLES() \ KERNEL_DTB() \ diff --git a/include/dt-bindings/iio/adc/at91-sama5d2_adc.h b/include/dt-bindings/iio/adc/at91-sama5d2_adc.h new file mode 100644 index 000000000000..70f99dbdbb42 --- /dev/null +++ b/include/dt-bindings/iio/adc/at91-sama5d2_adc.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * This header provides constants for configuring the AT91 SAMA5D2 ADC + */ + +#ifndef _DT_BINDINGS_IIO_ADC_AT91_SAMA5D2_ADC_H +#define _DT_BINDINGS_IIO_ADC_AT91_SAMA5D2_ADC_H + +/* X relative position channel index */ +#define AT91_SAMA5D2_ADC_X_CHANNEL 24 +/* Y relative position channel index */ +#define AT91_SAMA5D2_ADC_Y_CHANNEL 25 +/* pressure channel index */ +#define AT91_SAMA5D2_ADC_P_CHANNEL 26 + +#endif diff --git a/include/dt-bindings/usb/pd.h b/include/dt-bindings/usb/pd.h new file mode 100644 index 000000000000..7b7a92fefa0a --- /dev/null +++ b/include/dt-bindings/usb/pd.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __DT_POWER_DELIVERY_H +#define __DT_POWER_DELIVERY_H + +/* Power delivery Power Data Object definitions */ +#define PDO_TYPE_FIXED 0 +#define PDO_TYPE_BATT 1 +#define PDO_TYPE_VAR 2 +#define PDO_TYPE_APDO 3 + +#define PDO_TYPE_SHIFT 30 +#define PDO_TYPE_MASK 0x3 + +#define PDO_TYPE(t) ((t) << PDO_TYPE_SHIFT) + +#define PDO_VOLT_MASK 0x3ff +#define PDO_CURR_MASK 0x3ff +#define PDO_PWR_MASK 0x3ff + +#define PDO_FIXED_DUAL_ROLE (1 << 29) /* Power role swap supported */ +#define PDO_FIXED_SUSPEND (1 << 28) /* USB Suspend supported (Source) */ +#define PDO_FIXED_HIGHER_CAP (1 << 28) /* Requires more than vSafe5V (Sink) */ +#define PDO_FIXED_EXTPOWER (1 << 27) /* Externally powered */ +#define PDO_FIXED_USB_COMM (1 << 26) /* USB communications capable */ +#define PDO_FIXED_DATA_SWAP (1 << 25) /* Data role swap supported */ +#define PDO_FIXED_VOLT_SHIFT 10 /* 50mV units */ +#define PDO_FIXED_CURR_SHIFT 0 /* 10mA units */ + +#define PDO_FIXED_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_FIXED_VOLT_SHIFT) +#define PDO_FIXED_CURR(ma) ((((ma) / 10) & PDO_CURR_MASK) << PDO_FIXED_CURR_SHIFT) + +#define PDO_FIXED(mv, ma, flags) \ + (PDO_TYPE(PDO_TYPE_FIXED) | (flags) | \ + PDO_FIXED_VOLT(mv) | PDO_FIXED_CURR(ma)) + +#define VSAFE5V 5000 /* mv units */ + +#define PDO_BATT_MAX_VOLT_SHIFT 20 /* 50mV units */ +#define PDO_BATT_MIN_VOLT_SHIFT 10 /* 50mV units */ +#define PDO_BATT_MAX_PWR_SHIFT 0 /* 250mW units */ + +#define PDO_BATT_MIN_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_BATT_MIN_VOLT_SHIFT) +#define PDO_BATT_MAX_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_BATT_MAX_VOLT_SHIFT) +#define PDO_BATT_MAX_POWER(mw) ((((mw) / 250) & PDO_PWR_MASK) << PDO_BATT_MAX_PWR_SHIFT) + +#define PDO_BATT(min_mv, max_mv, max_mw) \ + (PDO_TYPE(PDO_TYPE_BATT) | PDO_BATT_MIN_VOLT(min_mv) | \ + PDO_BATT_MAX_VOLT(max_mv) | PDO_BATT_MAX_POWER(max_mw)) + +#define PDO_VAR_MAX_VOLT_SHIFT 20 /* 50mV units */ +#define PDO_VAR_MIN_VOLT_SHIFT 10 /* 50mV units */ +#define PDO_VAR_MAX_CURR_SHIFT 0 /* 10mA units */ + +#define PDO_VAR_MIN_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_VAR_MIN_VOLT_SHIFT) +#define PDO_VAR_MAX_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_VAR_MAX_VOLT_SHIFT) +#define PDO_VAR_MAX_CURR(ma) ((((ma) / 10) & PDO_CURR_MASK) << PDO_VAR_MAX_CURR_SHIFT) + +#define PDO_VAR(min_mv, max_mv, max_ma) \ + (PDO_TYPE(PDO_TYPE_VAR) | PDO_VAR_MIN_VOLT(min_mv) | \ + PDO_VAR_MAX_VOLT(max_mv) | PDO_VAR_MAX_CURR(max_ma)) + + #endif /* __DT_POWER_DELIVERY_H */ diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h index 65a6981eef7b..3f1ef4450a7c 100644 --- a/include/linux/bitfield.h +++ b/include/linux/bitfield.h @@ -53,7 +53,7 @@ ({ \ BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \ _pfx "mask is not constant"); \ - BUILD_BUG_ON_MSG(!(_mask), _pfx "mask is zero"); \ + BUILD_BUG_ON_MSG((_mask) == 0, _pfx "mask is zero"); \ BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \ ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \ _pfx "value too large for the field"); \ diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index 1ee46f492267..acf5e8df3504 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -105,6 +105,14 @@ */ /* + * Allocation and deallocation of bitmap. + * Provided in lib/bitmap.c to avoid circular dependency. + */ +extern unsigned long *bitmap_alloc(unsigned int nbits, gfp_t flags); +extern unsigned long *bitmap_zalloc(unsigned int nbits, gfp_t flags); +extern void bitmap_free(const unsigned long *bitmap); + +/* * lib/bitmap.c provides these functions: */ diff --git a/include/linux/cma.h b/include/linux/cma.h index bf90f0bb42bd..190184b5ff32 100644 --- a/include/linux/cma.h +++ b/include/linux/cma.h @@ -33,7 +33,7 @@ extern int cma_init_reserved_mem(phys_addr_t base, phys_addr_t size, const char *name, struct cma **res_cma); extern struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, - gfp_t gfp_mask); + bool no_warn); extern bool cma_release(struct cma *cma, const struct page *pages, unsigned int count); extern int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data); diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 573f5a7d42d4..3e70b7d4e9ed 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -103,7 +103,6 @@ #define __always_inline inline __attribute__((always_inline)) #define noinline __attribute__((noinline)) -#define __deprecated __attribute__((deprecated)) #define __packed __attribute__((packed)) #define __weak __attribute__((weak)) #define __alias(symbol) __attribute__((alias(#symbol))) diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index a8ba6b04152c..fbf337933fd8 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -111,21 +111,10 @@ struct ftrace_likely_data { #endif /* __ASSEMBLY__ */ #ifdef __KERNEL__ -/* - * Allow us to mark functions as 'deprecated' and have gcc emit a nice - * warning for each use, in hopes of speeding the functions removal. - * Usage is: - * int __deprecated foo(void) - */ -#ifndef __deprecated -# define __deprecated /* unimplemented */ -#endif -#ifdef MODULE -#define __deprecated_for_modules __deprecated -#else +/* Don't. Just don't. */ +#define __deprecated #define __deprecated_for_modules -#endif #ifndef __must_check #define __must_check @@ -135,12 +124,6 @@ struct ftrace_likely_data { #undef __must_check #define __must_check #endif -#ifndef CONFIG_ENABLE_WARN_DEPRECATED -#undef __deprecated -#undef __deprecated_for_modules -#define __deprecated -#define __deprecated_for_modules -#endif #ifndef __malloc #define __malloc diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h index c0ec478ea5bf..fea64f2692a0 100644 --- a/include/linux/console_struct.h +++ b/include/linux/console_struct.h @@ -17,8 +17,8 @@ #include <linux/vt.h> #include <linux/workqueue.h> -struct vt_struct; struct uni_pagedir; +struct uni_screen; #define NPAR 16 @@ -140,6 +140,7 @@ struct vc_data { struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */ struct uni_pagedir *vc_uni_pagedir; struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */ + struct uni_screen *vc_uni_screen; /* unicode screen content */ bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */ /* additional information is in vt_kern.h */ }; @@ -148,7 +149,7 @@ struct vc { struct vc_data *d; struct work_struct SAK_work; - /* might add scrmem, vt_struct, kbd at some time, + /* might add scrmem, kbd at some time, to have everything in one place - the disadvantage would be that vc_cons etc can no longer be static */ }; diff --git a/include/linux/coresight.h b/include/linux/coresight.h index c265e0468414..d828a6efe0b1 100644 --- a/include/linux/coresight.h +++ b/include/linux/coresight.h @@ -40,6 +40,7 @@ enum coresight_dev_type { CORESIGHT_DEV_TYPE_LINK, CORESIGHT_DEV_TYPE_LINKSINK, CORESIGHT_DEV_TYPE_SOURCE, + CORESIGHT_DEV_TYPE_HELPER, }; enum coresight_dev_subtype_sink { @@ -62,19 +63,30 @@ enum coresight_dev_subtype_source { CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE, }; +enum coresight_dev_subtype_helper { + CORESIGHT_DEV_SUBTYPE_HELPER_NONE, + CORESIGHT_DEV_SUBTYPE_HELPER_CATU, +}; + /** - * struct coresight_dev_subtype - further characterisation of a type + * union coresight_dev_subtype - further characterisation of a type * @sink_subtype: type of sink this component is, as defined - by @coresight_dev_subtype_sink. + * by @coresight_dev_subtype_sink. * @link_subtype: type of link this component is, as defined - by @coresight_dev_subtype_link. + * by @coresight_dev_subtype_link. * @source_subtype: type of source this component is, as defined - by @coresight_dev_subtype_source. + * by @coresight_dev_subtype_source. + * @helper_subtype: type of helper this component is, as defined + * by @coresight_dev_subtype_helper. */ -struct coresight_dev_subtype { - enum coresight_dev_subtype_sink sink_subtype; - enum coresight_dev_subtype_link link_subtype; +union coresight_dev_subtype { + /* We have some devices which acts as LINK and SINK */ + struct { + enum coresight_dev_subtype_sink sink_subtype; + enum coresight_dev_subtype_link link_subtype; + }; enum coresight_dev_subtype_source source_subtype; + enum coresight_dev_subtype_helper helper_subtype; }; /** @@ -87,7 +99,6 @@ struct coresight_dev_subtype { * @child_ports:child component port number the current component is connected to. * @nr_outport: number of output ports for this component. - * @clk: The clock this component is associated to. */ struct coresight_platform_data { int cpu; @@ -97,7 +108,6 @@ struct coresight_platform_data { const char **child_names; int *child_ports; int nr_outport; - struct clk *clk; }; /** @@ -113,7 +123,7 @@ struct coresight_platform_data { */ struct coresight_desc { enum coresight_dev_type type; - struct coresight_dev_subtype subtype; + union coresight_dev_subtype subtype; const struct coresight_ops *ops; struct coresight_platform_data *pdata; struct device *dev; @@ -157,7 +167,7 @@ struct coresight_device { int nr_inport; int nr_outport; enum coresight_dev_type type; - struct coresight_dev_subtype subtype; + union coresight_dev_subtype subtype; const struct coresight_ops *ops; struct device dev; atomic_t *refcnt; @@ -171,6 +181,7 @@ struct coresight_device { #define source_ops(csdev) csdev->ops->source_ops #define sink_ops(csdev) csdev->ops->sink_ops #define link_ops(csdev) csdev->ops->link_ops +#define helper_ops(csdev) csdev->ops->helper_ops /** * struct coresight_ops_sink - basic operations for a sink @@ -230,10 +241,25 @@ struct coresight_ops_source { struct perf_event *event); }; +/** + * struct coresight_ops_helper - Operations for a helper device. + * + * All operations could pass in a device specific data, which could + * help the helper device to determine what to do. + * + * @enable : Enable the device + * @disable : Disable the device + */ +struct coresight_ops_helper { + int (*enable)(struct coresight_device *csdev, void *data); + int (*disable)(struct coresight_device *csdev, void *data); +}; + struct coresight_ops { const struct coresight_ops_sink *sink_ops; const struct coresight_ops_link *link_ops; const struct coresight_ops_source *source_ops; + const struct coresight_ops_helper *helper_ops; }; #ifdef CONFIG_CORESIGHT @@ -267,24 +293,4 @@ static inline struct coresight_platform_data *of_get_coresight_platform_data( struct device *dev, const struct device_node *node) { return NULL; } #endif -#ifdef CONFIG_PID_NS -static inline unsigned long -coresight_vpid_to_pid(unsigned long vpid) -{ - struct task_struct *task = NULL; - unsigned long pid = 0; - - rcu_read_lock(); - task = find_task_by_vpid(vpid); - if (task) - pid = task_pid_nr(task); - rcu_read_unlock(); - - return pid; -} -#else -static inline unsigned long -coresight_vpid_to_pid(unsigned long vpid) { return vpid; } -#endif - #endif diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 4cf06a64bc02..c49843c4d031 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -125,6 +125,7 @@ enum cpuhp_state { CPUHP_AP_MARCO_TIMER_STARTING, CPUHP_AP_MIPS_GIC_TIMER_STARTING, CPUHP_AP_ARC_TIMER_STARTING, + CPUHP_AP_RISCV_TIMER_STARTING, CPUHP_AP_KVM_STARTING, CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING, CPUHP_AP_KVM_ARM_VGIC_STARTING, diff --git a/include/linux/device.h b/include/linux/device.h index 2a562f4ded07..8f882549edee 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -339,6 +339,8 @@ struct device *driver_find_device(struct device_driver *drv, struct device *start, void *data, int (*match)(struct device *dev, void *data)); +int driver_deferred_probe_check_state(struct device *dev); + /** * struct subsys_interface - interfaces to device functions * @name: name of the device function @@ -701,6 +703,10 @@ extern void devm_free_pages(struct device *dev, unsigned long addr); void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); +void __iomem *devm_of_iomap(struct device *dev, + struct device_node *node, int index, + resource_size_t *size); + /* allows to add/remove a custom action to devres stack */ int devm_add_action(struct device *dev, void (*action)(void *), void *data); void devm_remove_action(struct device *dev, void (*action)(void *), void *data); @@ -1325,30 +1331,34 @@ struct device_link *device_link_add(struct device *consumer, void device_link_del(struct device_link *link); void device_link_remove(void *consumer, struct device *supplier); +#ifndef dev_fmt +#define dev_fmt(fmt) fmt +#endif + #ifdef CONFIG_PRINTK -extern __printf(3, 0) +__printf(3, 0) int dev_vprintk_emit(int level, const struct device *dev, const char *fmt, va_list args); -extern __printf(3, 4) +__printf(3, 4) int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...); -extern __printf(3, 4) +__printf(3, 4) void dev_printk(const char *level, const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) -void dev_emerg(const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) -void dev_alert(const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) -void dev_crit(const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) -void dev_err(const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) -void dev_warn(const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) -void dev_notice(const struct device *dev, const char *fmt, ...); -extern __printf(2, 3) +__printf(2, 3) +void _dev_emerg(const struct device *dev, const char *fmt, ...); +__printf(2, 3) +void _dev_alert(const struct device *dev, const char *fmt, ...); +__printf(2, 3) +void _dev_crit(const struct device *dev, const char *fmt, ...); +__printf(2, 3) +void _dev_err(const struct device *dev, const char *fmt, ...); +__printf(2, 3) +void _dev_warn(const struct device *dev, const char *fmt, ...); +__printf(2, 3) +void _dev_notice(const struct device *dev, const char *fmt, ...); +__printf(2, 3) void _dev_info(const struct device *dev, const char *fmt, ...); #else @@ -1366,26 +1376,26 @@ static inline void __dev_printk(const char *level, const struct device *dev, {} static inline __printf(3, 4) void dev_printk(const char *level, const struct device *dev, - const char *fmt, ...) + const char *fmt, ...) {} static inline __printf(2, 3) -void dev_emerg(const struct device *dev, const char *fmt, ...) +void _dev_emerg(const struct device *dev, const char *fmt, ...) {} static inline __printf(2, 3) -void dev_crit(const struct device *dev, const char *fmt, ...) +void _dev_crit(const struct device *dev, const char *fmt, ...) {} static inline __printf(2, 3) -void dev_alert(const struct device *dev, const char *fmt, ...) +void _dev_alert(const struct device *dev, const char *fmt, ...) {} static inline __printf(2, 3) -void dev_err(const struct device *dev, const char *fmt, ...) +void _dev_err(const struct device *dev, const char *fmt, ...) {} static inline __printf(2, 3) -void dev_warn(const struct device *dev, const char *fmt, ...) +void _dev_warn(const struct device *dev, const char *fmt, ...) {} static inline __printf(2, 3) -void dev_notice(const struct device *dev, const char *fmt, ...) +void _dev_notice(const struct device *dev, const char *fmt, ...) {} static inline __printf(2, 3) void _dev_info(const struct device *dev, const char *fmt, ...) @@ -1394,27 +1404,36 @@ void _dev_info(const struct device *dev, const char *fmt, ...) #endif /* - * Stupid hackaround for existing uses of non-printk uses dev_info - * - * Note that the definition of dev_info below is actually _dev_info - * and a macro is used to avoid redefining dev_info + * #defines for all the dev_<level> macros to prefix with whatever + * possible use of #define dev_fmt(fmt) ... */ -#define dev_info(dev, fmt, arg...) _dev_info(dev, fmt, ##arg) +#define dev_emerg(dev, fmt, ...) \ + _dev_emerg(dev, dev_fmt(fmt), ##__VA_ARGS__) +#define dev_crit(dev, fmt, ...) \ + _dev_crit(dev, dev_fmt(fmt), ##__VA_ARGS__) +#define dev_alert(dev, fmt, ...) \ + _dev_alert(dev, dev_fmt(fmt), ##__VA_ARGS__) +#define dev_err(dev, fmt, ...) \ + _dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__) +#define dev_warn(dev, fmt, ...) \ + _dev_warn(dev, dev_fmt(fmt), ##__VA_ARGS__) +#define dev_notice(dev, fmt, ...) \ + _dev_notice(dev, dev_fmt(fmt), ##__VA_ARGS__) +#define dev_info(dev, fmt, ...) \ + _dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__) #if defined(CONFIG_DYNAMIC_DEBUG) -#define dev_dbg(dev, format, ...) \ -do { \ - dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \ -} while (0) +#define dev_dbg(dev, fmt, ...) \ + dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__) #elif defined(DEBUG) -#define dev_dbg(dev, format, arg...) \ - dev_printk(KERN_DEBUG, dev, format, ##arg) +#define dev_dbg(dev, fmt, ...) \ + dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__) #else -#define dev_dbg(dev, format, arg...) \ -({ \ - if (0) \ - dev_printk(KERN_DEBUG, dev, format, ##arg); \ +#define dev_dbg(dev, fmt, ...) \ +({ \ + if (0) \ + dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ }) #endif @@ -1486,7 +1505,7 @@ do { \ DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) && \ __ratelimit(&_rs)) \ - __dynamic_dev_dbg(&descriptor, dev, fmt, \ + __dynamic_dev_dbg(&descriptor, dev, dev_fmt(fmt), \ ##__VA_ARGS__); \ } while (0) #elif defined(DEBUG) @@ -1496,23 +1515,23 @@ do { \ DEFAULT_RATELIMIT_INTERVAL, \ DEFAULT_RATELIMIT_BURST); \ if (__ratelimit(&_rs)) \ - dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \ + dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ } while (0) #else #define dev_dbg_ratelimited(dev, fmt, ...) \ do { \ if (0) \ - dev_printk(KERN_DEBUG, dev, fmt, ##__VA_ARGS__); \ + dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ } while (0) #endif #ifdef VERBOSE_DEBUG #define dev_vdbg dev_dbg #else -#define dev_vdbg(dev, format, arg...) \ -({ \ - if (0) \ - dev_printk(KERN_DEBUG, dev, format, ##arg); \ +#define dev_vdbg(dev, fmt, ...) \ +({ \ + if (0) \ + dev_printk(KERN_DEBUG, dev, dev_fmt(fmt), ##__VA_ARGS__); \ }) #endif diff --git a/include/linux/dm-kcopyd.h b/include/linux/dm-kcopyd.h index cfac8588ed56..e42de7750c88 100644 --- a/include/linux/dm-kcopyd.h +++ b/include/linux/dm-kcopyd.h @@ -62,9 +62,9 @@ void dm_kcopyd_client_destroy(struct dm_kcopyd_client *kc); typedef void (*dm_kcopyd_notify_fn)(int read_err, unsigned long write_err, void *context); -int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, - unsigned num_dests, struct dm_io_region *dests, - unsigned flags, dm_kcopyd_notify_fn fn, void *context); +void dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, + unsigned num_dests, struct dm_io_region *dests, + unsigned flags, dm_kcopyd_notify_fn fn, void *context); /* * Prepare a callback and submit it via the kcopyd thread. @@ -81,9 +81,9 @@ void *dm_kcopyd_prepare_callback(struct dm_kcopyd_client *kc, dm_kcopyd_notify_fn fn, void *context); void dm_kcopyd_do_callback(void *job, int read_err, unsigned long write_err); -int dm_kcopyd_zero(struct dm_kcopyd_client *kc, - unsigned num_dests, struct dm_io_region *dests, - unsigned flags, dm_kcopyd_notify_fn fn, void *context); +void dm_kcopyd_zero(struct dm_kcopyd_client *kc, + unsigned num_dests, struct dm_io_region *dests, + unsigned flags, dm_kcopyd_notify_fn fn, void *context); #endif /* __KERNEL__ */ #endif /* _LINUX_DM_KCOPYD_H */ diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h index 3c5a4cb3eb95..f247e8aa5e3d 100644 --- a/include/linux/dma-contiguous.h +++ b/include/linux/dma-contiguous.h @@ -112,7 +112,7 @@ static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size, } struct page *dma_alloc_from_contiguous(struct device *dev, size_t count, - unsigned int order, gfp_t gfp_mask); + unsigned int order, bool no_warn); bool dma_release_from_contiguous(struct device *dev, struct page *pages, int count); @@ -145,7 +145,7 @@ int dma_declare_contiguous(struct device *dev, phys_addr_t size, static inline struct page *dma_alloc_from_contiguous(struct device *dev, size_t count, - unsigned int order, gfp_t gfp_mask) + unsigned int order, bool no_warn) { return NULL; } diff --git a/include/linux/dma/xilinx_dma.h b/include/linux/dma/xilinx_dma.h index 34b98f276ed0..5b6e61e4b3aa 100644 --- a/include/linux/dma/xilinx_dma.h +++ b/include/linux/dma/xilinx_dma.h @@ -27,6 +27,7 @@ * @delay: Delay counter * @reset: Reset Channel * @ext_fsync: External Frame Sync source + * @vflip_en: Vertical Flip enable */ struct xilinx_vdma_config { int frm_dly; @@ -39,6 +40,7 @@ struct xilinx_vdma_config { int delay; int reset; int ext_fsync; + bool vflip_en; }; int xilinx_vdma_channel_set_config(struct dma_chan *dchan, diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 861be5cab1df..d49ec5c31944 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -415,7 +415,9 @@ enum dma_residue_granularity { * each type, the dma controller should set BIT(<TYPE>) and same * should be checked by controller as well * @max_burst: max burst capability per-transfer - * @cmd_pause: true, if pause and thereby resume is supported + * @cmd_pause: true, if pause is supported (i.e. for reading residue or + * for resume later) + * @cmd_resume: true, if resume is supported * @cmd_terminate: true, if terminate cmd is supported * @residue_granularity: granularity of the reported transfer residue * @descriptor_reuse: if a descriptor can be reused by client and @@ -427,6 +429,7 @@ struct dma_slave_caps { u32 directions; u32 max_burst; bool cmd_pause; + bool cmd_resume; bool cmd_terminate; enum dma_residue_granularity residue_granularity; bool descriptor_reuse; @@ -1403,6 +1406,7 @@ static inline int dmaengine_desc_free(struct dma_async_tx_descriptor *desc) /* --- DMA device --- */ int dma_async_device_register(struct dma_device *device); +int dmaenginem_async_device_register(struct dma_device *device); void dma_async_device_unregister(struct dma_device *device); void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_get_slave_channel(struct dma_chan *chan); diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h index eec7c2478b0d..8942e61f0028 100644 --- a/include/linux/fpga/fpga-mgr.h +++ b/include/linux/fpga/fpga-mgr.h @@ -77,6 +77,7 @@ enum fpga_mgr_states { * @sgt: scatter/gather table containing FPGA image * @buf: contiguous buffer containing FPGA image * @count: size of buf + * @region_id: id of target region * @dev: device that owns this * @overlay: Device Tree overlay */ @@ -89,6 +90,7 @@ struct fpga_image_info { struct sg_table *sgt; const char *buf; size_t count; + int region_id; struct device *dev; #ifdef CONFIG_OF struct device_node *overlay; @@ -99,6 +101,7 @@ struct fpga_image_info { * struct fpga_manager_ops - ops for low level fpga manager drivers * @initial_header_size: Maximum number of bytes that should be passed into write_init * @state: returns an enum value of the FPGA's state + * @status: returns status of the FPGA, including reconfiguration error code * @write_init: prepare the FPGA to receive confuration data * @write: write count bytes of configuration data to the FPGA * @write_sg: write the scatter list of configuration data to the FPGA @@ -113,6 +116,7 @@ struct fpga_image_info { struct fpga_manager_ops { size_t initial_header_size; enum fpga_mgr_states (*state)(struct fpga_manager *mgr); + u64 (*status)(struct fpga_manager *mgr); int (*write_init)(struct fpga_manager *mgr, struct fpga_image_info *info, const char *buf, size_t count); @@ -124,12 +128,31 @@ struct fpga_manager_ops { const struct attribute_group **groups; }; +/* FPGA manager status: Partial/Full Reconfiguration errors */ +#define FPGA_MGR_STATUS_OPERATION_ERR BIT(0) +#define FPGA_MGR_STATUS_CRC_ERR BIT(1) +#define FPGA_MGR_STATUS_INCOMPATIBLE_IMAGE_ERR BIT(2) +#define FPGA_MGR_STATUS_IP_PROTOCOL_ERR BIT(3) +#define FPGA_MGR_STATUS_FIFO_OVERFLOW_ERR BIT(4) + +/** + * struct fpga_compat_id - id for compatibility check + * + * @id_h: high 64bit of the compat_id + * @id_l: low 64bit of the compat_id + */ +struct fpga_compat_id { + u64 id_h; + u64 id_l; +}; + /** * struct fpga_manager - fpga manager structure * @name: name of low level fpga manager * @dev: fpga manager device * @ref_mutex: only allows one reference to fpga manager * @state: state of fpga manager + * @compat_id: FPGA manager id for compatibility check. * @mops: pointer to struct of fpga manager ops * @priv: low level driver private date */ @@ -138,6 +161,7 @@ struct fpga_manager { struct device dev; struct mutex ref_mutex; enum fpga_mgr_states state; + struct fpga_compat_id *compat_id; const struct fpga_manager_ops *mops; void *priv; }; diff --git a/include/linux/fpga/fpga-region.h b/include/linux/fpga/fpga-region.h index d7071cddd727..0521b7f577a4 100644 --- a/include/linux/fpga/fpga-region.h +++ b/include/linux/fpga/fpga-region.h @@ -14,6 +14,7 @@ * @bridge_list: list of FPGA bridges specified in region * @mgr: FPGA manager * @info: FPGA image info + * @compat_id: FPGA region id for compatibility check. * @priv: private data * @get_bridges: optional function to get bridges to a list */ @@ -23,6 +24,7 @@ struct fpga_region { struct list_head bridge_list; struct fpga_manager *mgr; struct fpga_image_info *info; + struct fpga_compat_id *compat_id; void *priv; int (*get_bridges)(struct fpga_region *region); }; diff --git a/include/linux/fs.h b/include/linux/fs.h index 1ec33fd0423f..a9242f336f02 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -179,7 +179,6 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset, #define ATTR_ATIME_SET (1 << 7) #define ATTR_MTIME_SET (1 << 8) #define ATTR_FORCE (1 << 9) /* Not a change, but a change it */ -#define ATTR_ATTR_FLAG (1 << 10) #define ATTR_KILL_SUID (1 << 11) #define ATTR_KILL_SGID (1 << 12) #define ATTR_FILE (1 << 13) @@ -345,6 +344,10 @@ struct address_space_operations { /* Set a page dirty. Return true if this dirtied it */ int (*set_page_dirty)(struct page *page); + /* + * Reads in the requested pages. Unlike ->readpage(), this is + * PURELY used for read-ahead!. + */ int (*readpages)(struct file *filp, struct address_space *mapping, struct list_head *pages, unsigned nr_pages); diff --git a/include/linux/fsi-sbefifo.h b/include/linux/fsi-sbefifo.h new file mode 100644 index 000000000000..13f9ebeaa25e --- /dev/null +++ b/include/linux/fsi-sbefifo.h @@ -0,0 +1,33 @@ +/* + * SBEFIFO FSI Client device driver + * + * Copyright (C) IBM Corporation 2017 + * + * 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 + * MERGCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef LINUX_FSI_SBEFIFO_H +#define LINUX_FSI_SBEFIFO_H + +#define SBEFIFO_CMD_PUT_OCC_SRAM 0xa404 +#define SBEFIFO_CMD_GET_OCC_SRAM 0xa403 +#define SBEFIFO_CMD_GET_SBE_FFDC 0xa801 + +#define SBEFIFO_MAX_FFDC_SIZE 0x2000 + +struct device; + +int sbefifo_submit(struct device *dev, const __be32 *command, size_t cmd_len, + __be32 *response, size_t *resp_len); + +int sbefifo_parse_status(struct device *dev, u16 cmd, __be32 *response, + size_t resp_len, size_t *data_len); + +#endif /* LINUX_FSI_SBEFIFO_H */ diff --git a/include/linux/fsi.h b/include/linux/fsi.h index 141fd38d061f..ec3be0d5b786 100644 --- a/include/linux/fsi.h +++ b/include/linux/fsi.h @@ -76,8 +76,18 @@ extern int fsi_slave_read(struct fsi_slave *slave, uint32_t addr, extern int fsi_slave_write(struct fsi_slave *slave, uint32_t addr, const void *val, size_t size); +extern struct bus_type fsi_bus_type; +extern const struct device_type fsi_cdev_type; +enum fsi_dev_type { + fsi_dev_cfam, + fsi_dev_sbefifo, + fsi_dev_scom, + fsi_dev_occ +}; -extern struct bus_type fsi_bus_type; +extern int fsi_get_new_minor(struct fsi_device *fdev, enum fsi_dev_type type, + dev_t *out_dev, int *out_index); +extern void fsi_free_minor(dev_t dev); #endif /* LINUX_FSI_H */ diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index b38964a7a521..b8f4182f42f1 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -84,6 +84,8 @@ struct fsnotify_event_private_data; struct fsnotify_fname; struct fsnotify_iter_info; +struct mem_cgroup; + /* * Each group much define these ops. The fsnotify infrastructure will call * these operations for each relevant group. @@ -127,6 +129,8 @@ struct fsnotify_event { * everything will be cleaned up. */ struct fsnotify_group { + const struct fsnotify_ops *ops; /* how this group handles things */ + /* * How the refcnt is used is up to each group. When the refcnt hits 0 * fsnotify will clean up all of the resources associated with this group. @@ -137,8 +141,6 @@ struct fsnotify_group { */ refcount_t refcnt; /* things with interest in this group */ - const struct fsnotify_ops *ops; /* how this group handles things */ - /* needed to send notification to userspace */ spinlock_t notification_lock; /* protect the notification_list */ struct list_head notification_list; /* list of event_holder this group needs to send to userspace */ @@ -160,6 +162,8 @@ struct fsnotify_group { atomic_t num_marks; /* 1 for each mark and 1 for not being * past the point of no return when freeing * a group */ + atomic_t user_waits; /* Number of tasks waiting for user + * response */ struct list_head marks_list; /* all inode marks for this group */ struct fasync_struct *fsn_fa; /* async notification */ @@ -167,8 +171,8 @@ struct fsnotify_group { struct fsnotify_event *overflow_event; /* Event we queue when the * notification list is too * full */ - atomic_t user_waits; /* Number of tasks waiting for user - * response */ + + struct mem_cgroup *memcg; /* memcg to charge allocations */ /* groups can define private fields here or use the void *private */ union { @@ -210,6 +214,11 @@ enum fsnotify_obj_type { #define FSNOTIFY_OBJ_TYPE_VFSMOUNT_FL (1U << FSNOTIFY_OBJ_TYPE_VFSMOUNT) #define FSNOTIFY_OBJ_ALL_TYPES_MASK ((1U << FSNOTIFY_OBJ_TYPE_COUNT) - 1) +static inline bool fsnotify_valid_obj_type(unsigned int type) +{ + return (type < FSNOTIFY_OBJ_TYPE_COUNT); +} + struct fsnotify_iter_info { struct fsnotify_mark *marks[FSNOTIFY_OBJ_TYPE_COUNT]; unsigned int report_mask; @@ -251,6 +260,13 @@ FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT) for (type = 0; type < FSNOTIFY_OBJ_TYPE_COUNT; type++) /* + * fsnotify_connp_t is what we embed in objects which connector can be attached + * to. fsnotify_connp_t * is how we refer from connector back to object. + */ +struct fsnotify_mark_connector; +typedef struct fsnotify_mark_connector __rcu *fsnotify_connp_t; + +/* * Inode / vfsmount point to this structure which tracks all marks attached to * the inode / vfsmount. The reference to inode / vfsmount is held by this * structure. We destroy this structure when there are no more marks attached @@ -259,9 +275,9 @@ FSNOTIFY_ITER_FUNCS(vfsmount, VFSMOUNT) struct fsnotify_mark_connector { spinlock_t lock; unsigned int type; /* Type of object [lock] */ - union { /* Object pointer [lock] */ - struct inode *inode; - struct vfsmount *mnt; + union { + /* Object pointer [lock] */ + fsnotify_connp_t *obj; /* Used listing heads to free after srcu period expires */ struct fsnotify_mark_connector *destroy_next; }; @@ -389,32 +405,36 @@ extern struct fsnotify_event *fsnotify_remove_first_event(struct fsnotify_group /* functions used to manipulate the marks attached to inodes */ +/* Get mask of events for a list of marks */ +extern __u32 fsnotify_conn_mask(struct fsnotify_mark_connector *conn); /* Calculate mask of events for a list of marks */ extern void fsnotify_recalc_mask(struct fsnotify_mark_connector *conn); extern void fsnotify_init_mark(struct fsnotify_mark *mark, struct fsnotify_group *group); /* Find mark belonging to given group in the list of marks */ -extern struct fsnotify_mark *fsnotify_find_mark( - struct fsnotify_mark_connector __rcu **connp, - struct fsnotify_group *group); -/* attach the mark to the inode or vfsmount */ -extern int fsnotify_add_mark(struct fsnotify_mark *mark, struct inode *inode, - struct vfsmount *mnt, int allow_dups); +extern struct fsnotify_mark *fsnotify_find_mark(fsnotify_connp_t *connp, + struct fsnotify_group *group); +/* attach the mark to the object */ +extern int fsnotify_add_mark(struct fsnotify_mark *mark, + fsnotify_connp_t *connp, unsigned int type, + int allow_dups); extern int fsnotify_add_mark_locked(struct fsnotify_mark *mark, - struct inode *inode, struct vfsmount *mnt, + fsnotify_connp_t *connp, unsigned int type, int allow_dups); /* attach the mark to the inode */ static inline int fsnotify_add_inode_mark(struct fsnotify_mark *mark, struct inode *inode, int allow_dups) { - return fsnotify_add_mark(mark, inode, NULL, allow_dups); + return fsnotify_add_mark(mark, &inode->i_fsnotify_marks, + FSNOTIFY_OBJ_TYPE_INODE, allow_dups); } static inline int fsnotify_add_inode_mark_locked(struct fsnotify_mark *mark, struct inode *inode, int allow_dups) { - return fsnotify_add_mark_locked(mark, inode, NULL, allow_dups); + return fsnotify_add_mark_locked(mark, &inode->i_fsnotify_marks, + FSNOTIFY_OBJ_TYPE_INODE, allow_dups); } /* given a group and a mark, flag mark to be freed when all references are dropped */ extern void fsnotify_destroy_mark(struct fsnotify_mark *mark, diff --git a/include/linux/gnss.h b/include/linux/gnss.h new file mode 100644 index 000000000000..43546977098c --- /dev/null +++ b/include/linux/gnss.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * GNSS receiver support + * + * Copyright (C) 2018 Johan Hovold <johan@kernel.org> + */ + +#ifndef _LINUX_GNSS_H +#define _LINUX_GNSS_H + +#include <linux/cdev.h> +#include <linux/device.h> +#include <linux/kfifo.h> +#include <linux/mutex.h> +#include <linux/rwsem.h> +#include <linux/types.h> +#include <linux/wait.h> + +struct gnss_device; + +enum gnss_type { + GNSS_TYPE_NMEA = 0, + GNSS_TYPE_SIRF, + GNSS_TYPE_UBX, + + GNSS_TYPE_COUNT +}; + +struct gnss_operations { + int (*open)(struct gnss_device *gdev); + void (*close)(struct gnss_device *gdev); + int (*write_raw)(struct gnss_device *gdev, const unsigned char *buf, + size_t count); +}; + +struct gnss_device { + struct device dev; + struct cdev cdev; + int id; + + enum gnss_type type; + unsigned long flags; + + struct rw_semaphore rwsem; + const struct gnss_operations *ops; + unsigned int count; + unsigned int disconnected:1; + + struct mutex read_mutex; + struct kfifo read_fifo; + wait_queue_head_t read_queue; + + struct mutex write_mutex; + char *write_buf; +}; + +struct gnss_device *gnss_allocate_device(struct device *parent); +void gnss_put_device(struct gnss_device *gdev); +int gnss_register_device(struct gnss_device *gdev); +void gnss_deregister_device(struct gnss_device *gdev); + +int gnss_insert_raw(struct gnss_device *gdev, const unsigned char *buf, + size_t count); + +static inline void gnss_set_drvdata(struct gnss_device *gdev, void *data) +{ + dev_set_drvdata(&gdev->dev, data); +} + +static inline void *gnss_get_drvdata(struct gnss_device *gdev) +{ + return dev_get_drvdata(&gdev->dev); +} + +#endif /* _LINUX_GNSS_H */ diff --git a/include/linux/goldfish.h b/include/linux/goldfish.h index 2835c150c3ff..265a099cd3b8 100644 --- a/include/linux/goldfish.h +++ b/include/linux/goldfish.h @@ -2,14 +2,20 @@ #ifndef __LINUX_GOLDFISH_H #define __LINUX_GOLDFISH_H +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/io.h> + /* Helpers for Goldfish virtual platform */ static inline void gf_write_ptr(const void *ptr, void __iomem *portl, void __iomem *porth) { - writel((u32)(unsigned long)ptr, portl); + const unsigned long addr = (unsigned long)ptr; + + writel(lower_32_bits(addr), portl); #ifdef CONFIG_64BIT - writel((unsigned long)ptr >> 32, porth); + writel(upper_32_bits(addr), porth); #endif } @@ -17,9 +23,9 @@ static inline void gf_write_dma_addr(const dma_addr_t addr, void __iomem *portl, void __iomem *porth) { - writel((u32)addr, portl); + writel(lower_32_bits(addr), portl); #ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT - writel(addr >> 32, porth); + writel(upper_32_bits(addr), porth); #endif } diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index 7160df54a6fe..3f84aeb81e48 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -2,6 +2,8 @@ #ifndef _GPIO_KEYS_H #define _GPIO_KEYS_H +#include <linux/types.h> + struct device; /** diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 36fa6a2a82e3..c39d9170a8a0 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -348,9 +348,6 @@ struct hstate { struct huge_bootmem_page { struct list_head list; struct hstate *hstate; -#ifdef CONFIG_HIGHMEM - phys_addr_t phys; -#endif }; struct page *alloc_huge_page(struct vm_area_struct *vma, diff --git a/include/linux/hwspinlock.h b/include/linux/hwspinlock.h index 57537e67b468..0afe693be5f4 100644 --- a/include/linux/hwspinlock.h +++ b/include/linux/hwspinlock.h @@ -52,7 +52,7 @@ struct hwspinlock_pdata { int base_id; }; -#if defined(CONFIG_HWSPINLOCK) || defined(CONFIG_HWSPINLOCK_MODULE) +#ifdef CONFIG_HWSPINLOCK int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev, const struct hwspinlock_ops *ops, int base_id, int num_locks); @@ -66,6 +66,17 @@ int __hwspin_lock_timeout(struct hwspinlock *, unsigned int, int, unsigned long *); int __hwspin_trylock(struct hwspinlock *, int, unsigned long *); void __hwspin_unlock(struct hwspinlock *, int, unsigned long *); +int of_hwspin_lock_get_id_byname(struct device_node *np, const char *name); +int devm_hwspin_lock_free(struct device *dev, struct hwspinlock *hwlock); +struct hwspinlock *devm_hwspin_lock_request(struct device *dev); +struct hwspinlock *devm_hwspin_lock_request_specific(struct device *dev, + unsigned int id); +int devm_hwspin_lock_unregister(struct device *dev, + struct hwspinlock_device *bank); +int devm_hwspin_lock_register(struct device *dev, + struct hwspinlock_device *bank, + const struct hwspinlock_ops *ops, + int base_id, int num_locks); #else /* !CONFIG_HWSPINLOCK */ @@ -125,6 +136,30 @@ static inline int hwspin_lock_get_id(struct hwspinlock *hwlock) return 0; } +static inline +int of_hwspin_lock_get_id_byname(struct device_node *np, const char *name) +{ + return 0; +} + +static inline +int devm_hwspin_lock_free(struct device *dev, struct hwspinlock *hwlock) +{ + return 0; +} + +static inline struct hwspinlock *devm_hwspin_lock_request(struct device *dev) +{ + return ERR_PTR(-ENODEV); +} + +static inline +struct hwspinlock *devm_hwspin_lock_request_specific(struct device *dev, + unsigned int id) +{ + return ERR_PTR(-ENODEV); +} + #endif /* !CONFIG_HWSPINLOCK */ /** diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 3a3012f57be4..efda23cf32c7 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -89,18 +89,33 @@ struct hv_ring_buffer { u32 interrupt_mask; /* - * Win8 uses some of the reserved bits to implement - * interrupt driven flow management. On the send side - * we can request that the receiver interrupt the sender - * when the ring transitions from being full to being able - * to handle a message of size "pending_send_sz". + * WS2012/Win8 and later versions of Hyper-V implement interrupt + * driven flow management. The feature bit feat_pending_send_sz + * is set by the host on the host->guest ring buffer, and by the + * guest on the guest->host ring buffer. * - * Add necessary state for this enhancement. + * The meaning of the feature bit is a bit complex in that it has + * semantics that apply to both ring buffers. If the guest sets + * the feature bit in the guest->host ring buffer, the guest is + * telling the host that: + * 1) It will set the pending_send_sz field in the guest->host ring + * buffer when it is waiting for space to become available, and + * 2) It will read the pending_send_sz field in the host->guest + * ring buffer and interrupt the host when it frees enough space + * + * Similarly, if the host sets the feature bit in the host->guest + * ring buffer, the host is telling the guest that: + * 1) It will set the pending_send_sz field in the host->guest ring + * buffer when it is waiting for space to become available, and + * 2) It will read the pending_send_sz field in the guest->host + * ring buffer and interrupt the guest when it frees enough space + * + * If either the guest or host does not set the feature bit that it + * owns, that guest or host must do polling if it encounters a full + * ring buffer, and not signal the other end with an interrupt. */ u32 pending_send_sz; - u32 reserved1[12]; - union { struct { u32 feat_pending_send_sz:1; @@ -1046,6 +1061,8 @@ extern int vmbus_establish_gpadl(struct vmbus_channel *channel, extern int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle); +void vmbus_reset_channel_cb(struct vmbus_channel *channel); + extern int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, u32 bufferlen, diff --git a/include/linux/idr.h b/include/linux/idr.h index e856f4e0ab35..3e8215b2c371 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -98,6 +98,17 @@ static inline void idr_set_cursor(struct idr *idr, unsigned int val) * period). */ +#define idr_lock(idr) xa_lock(&(idr)->idr_rt) +#define idr_unlock(idr) xa_unlock(&(idr)->idr_rt) +#define idr_lock_bh(idr) xa_lock_bh(&(idr)->idr_rt) +#define idr_unlock_bh(idr) xa_unlock_bh(&(idr)->idr_rt) +#define idr_lock_irq(idr) xa_lock_irq(&(idr)->idr_rt) +#define idr_unlock_irq(idr) xa_unlock_irq(&(idr)->idr_rt) +#define idr_lock_irqsave(idr, flags) \ + xa_lock_irqsave(&(idr)->idr_rt, flags) +#define idr_unlock_irqrestore(idr, flags) \ + xa_unlock_irqrestore(&(idr)->idr_rt, flags) + void idr_preload(gfp_t gfp_mask); int idr_alloc(struct idr *, void *ptr, int start, int end, gfp_t); diff --git a/include/linux/inotify.h b/include/linux/inotify.h index 44f9ffe72c87..6a24905f6e1e 100644 --- a/include/linux/inotify.h +++ b/include/linux/inotify.h @@ -18,6 +18,6 @@ extern struct ctl_table inotify_table[]; /* for sysctl */ IN_DELETE_SELF | IN_MOVE_SELF | IN_UNMOUNT | \ IN_Q_OVERFLOW | IN_IGNORED | IN_ONLYDIR | \ IN_DONT_FOLLOW | IN_EXCL_UNLINK | IN_MASK_ADD | \ - IN_ISDIR | IN_ONESHOT) + IN_MASK_CREATE | IN_ISDIR | IN_ONESHOT) #endif /* _LINUX_INOTIFY_H */ diff --git a/include/linux/joystick.h b/include/linux/joystick.h index cbf2aa9e93b9..5153f5b9294c 100644 --- a/include/linux/joystick.h +++ b/include/linux/joystick.h @@ -17,10 +17,6 @@ * 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 - * - * Should you need to contact me, the author, you can do so either by - * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic */ #ifndef _LINUX_JOYSTICK_H #define _LINUX_JOYSTICK_H diff --git a/include/linux/kasan.h b/include/linux/kasan.h index de784fd11d12..46aae129917c 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -20,7 +20,7 @@ extern pmd_t kasan_zero_pmd[PTRS_PER_PMD]; extern pud_t kasan_zero_pud[PTRS_PER_PUD]; extern p4d_t kasan_zero_p4d[MAX_PTRS_PER_P4D]; -void kasan_populate_zero_shadow(const void *shadow_start, +int kasan_populate_zero_shadow(const void *shadow_start, const void *shadow_end); static inline void *kasan_mem_to_shadow(const void *addr) @@ -71,6 +71,9 @@ struct kasan_cache { int kasan_module_alloc(void *addr, size_t size); void kasan_free_shadow(const struct vm_struct *vm); +int kasan_add_zero_shadow(void *start, unsigned long size); +void kasan_remove_zero_shadow(void *start, unsigned long size); + 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); @@ -124,6 +127,14 @@ static inline bool kasan_slab_free(struct kmem_cache *s, void *object, 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 int kasan_add_zero_shadow(void *start, unsigned long size) +{ + return 0; +} +static inline void kasan_remove_zero_shadow(void *start, + unsigned long size) +{} + static inline void kasan_unpoison_slab(const void *ptr) { } static inline size_t kasan_metadata_size(struct kmem_cache *cache) { return 0; } diff --git a/include/linux/kobject.h b/include/linux/kobject.h index b49ff230beba..1ab0d624fb36 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -119,6 +119,23 @@ extern void kobject_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid); extern char *kobject_get_path(struct kobject *kobj, gfp_t flag); +/** + * kobject_has_children - Returns whether a kobject has children. + * @kobj: the object to test + * + * This will return whether a kobject has other kobjects as children. + * + * It does NOT account for the presence of attribute files, only sub + * directories. It also assumes there is no concurrent addition or + * removal of such children, and thus relies on external locking. + */ +static inline bool kobject_has_children(struct kobject *kobj) +{ + WARN_ON_ONCE(kref_read(&kobj->kref) == 0); + + return kobj->sd && kobj->sd->dir.subdirs; +} + struct kobj_type { void (*release)(struct kobject *kobj); const struct sysfs_ops *sysfs_ops; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 4ee7bc548a83..7c7362dd2faa 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -130,7 +130,7 @@ static inline bool is_error_page(struct page *page) #define KVM_REQUEST_ARCH_BASE 8 #define KVM_ARCH_REQ_FLAGS(nr, flags) ({ \ - BUILD_BUG_ON((unsigned)(nr) >= 32 - KVM_REQUEST_ARCH_BASE); \ + BUILD_BUG_ON((unsigned)(nr) >= (FIELD_SIZEOF(struct kvm_vcpu, requests) * 8) - KVM_REQUEST_ARCH_BASE); \ (unsigned)(((nr) + KVM_REQUEST_ARCH_BASE) | (flags)); \ }) #define KVM_ARCH_REQ(nr) KVM_ARCH_REQ_FLAGS(nr, 0) @@ -224,7 +224,7 @@ struct kvm_vcpu { int vcpu_id; int srcu_idx; int mode; - unsigned long requests; + u64 requests; unsigned long guest_debug; int pre_pcpu; @@ -309,6 +309,13 @@ static inline unsigned long kvm_dirty_bitmap_bytes(struct kvm_memory_slot *memsl return ALIGN(memslot->npages, BITS_PER_LONG) / 8; } +static inline unsigned long *kvm_second_dirty_bitmap(struct kvm_memory_slot *memslot) +{ + unsigned long len = kvm_dirty_bitmap_bytes(memslot); + + return memslot->dirty_bitmap + len / sizeof(*memslot->dirty_bitmap); +} + struct kvm_s390_adapter_int { u64 ind_addr; u64 summary_addr; @@ -827,6 +834,13 @@ static inline void kvm_arch_free_vm(struct kvm *kvm) } #endif +#ifndef __KVM_HAVE_ARCH_FLUSH_REMOTE_TLB +static inline int kvm_arch_flush_remote_tlb(struct kvm *kvm) +{ + return -ENOTSUPP; +} +#endif + #ifdef __KVM_HAVE_ARCH_NONCOHERENT_DMA void kvm_arch_register_noncoherent_dma(struct kvm *kvm); void kvm_arch_unregister_noncoherent_dma(struct kvm *kvm); @@ -1124,7 +1138,7 @@ static inline void kvm_make_request(int req, struct kvm_vcpu *vcpu) * caller. Paired with the smp_mb__after_atomic in kvm_check_request. */ smp_wmb(); - set_bit(req & KVM_REQUEST_MASK, &vcpu->requests); + set_bit(req & KVM_REQUEST_MASK, (void *)&vcpu->requests); } static inline bool kvm_request_pending(struct kvm_vcpu *vcpu) @@ -1134,12 +1148,12 @@ static inline bool kvm_request_pending(struct kvm_vcpu *vcpu) static inline bool kvm_test_request(int req, struct kvm_vcpu *vcpu) { - return test_bit(req & KVM_REQUEST_MASK, &vcpu->requests); + return test_bit(req & KVM_REQUEST_MASK, (void *)&vcpu->requests); } static inline void kvm_clear_request(int req, struct kvm_vcpu *vcpu) { - clear_bit(req & KVM_REQUEST_MASK, &vcpu->requests); + clear_bit(req & KVM_REQUEST_MASK, (void *)&vcpu->requests); } static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu) diff --git a/include/linux/list_lru.h b/include/linux/list_lru.h index 96def9d15b1b..aa5efd9351eb 100644 --- a/include/linux/list_lru.h +++ b/include/linux/list_lru.h @@ -42,7 +42,7 @@ struct list_lru_node { spinlock_t lock; /* global list, used for the root cgroup in cgroup aware lrus */ struct list_lru_one lru; -#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB) +#ifdef CONFIG_MEMCG_KMEM /* for cgroup aware lrus points to per cgroup lists, otherwise NULL */ struct list_lru_memcg __rcu *memcg_lrus; #endif @@ -51,21 +51,25 @@ struct list_lru_node { struct list_lru { struct list_lru_node *node; -#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB) +#ifdef CONFIG_MEMCG_KMEM struct list_head list; + int shrinker_id; #endif }; void list_lru_destroy(struct list_lru *lru); int __list_lru_init(struct list_lru *lru, bool memcg_aware, - struct lock_class_key *key); + struct lock_class_key *key, struct shrinker *shrinker); -#define list_lru_init(lru) __list_lru_init((lru), false, NULL) -#define list_lru_init_key(lru, key) __list_lru_init((lru), false, (key)) -#define list_lru_init_memcg(lru) __list_lru_init((lru), true, NULL) +#define list_lru_init(lru) \ + __list_lru_init((lru), false, NULL, NULL) +#define list_lru_init_key(lru, key) \ + __list_lru_init((lru), false, (key), NULL) +#define list_lru_init_memcg(lru, shrinker) \ + __list_lru_init((lru), true, NULL, shrinker) int memcg_update_all_list_lrus(int num_memcgs); -void memcg_drain_all_list_lrus(int src_idx, int dst_idx); +void memcg_drain_all_list_lrus(int src_idx, struct mem_cgroup *dst_memcg); /** * list_lru_add: add an element to the lru list's tail @@ -162,6 +166,23 @@ unsigned long list_lru_walk_one(struct list_lru *lru, int nid, struct mem_cgroup *memcg, list_lru_walk_cb isolate, void *cb_arg, unsigned long *nr_to_walk); +/** + * list_lru_walk_one_irq: walk a list_lru, isolating and disposing freeable items. + * @lru: the lru pointer. + * @nid: the node id to scan from. + * @memcg: the cgroup to scan from. + * @isolate: callback function that is resposible for deciding what to do with + * the item currently being scanned + * @cb_arg: opaque type that will be passed to @isolate + * @nr_to_walk: how many items to scan. + * + * Same as @list_lru_walk_one except that the spinlock is acquired with + * spin_lock_irq(). + */ +unsigned long list_lru_walk_one_irq(struct list_lru *lru, + int nid, struct mem_cgroup *memcg, + list_lru_walk_cb isolate, void *cb_arg, + unsigned long *nr_to_walk); unsigned long list_lru_walk_node(struct list_lru *lru, int nid, list_lru_walk_cb isolate, void *cb_arg, unsigned long *nr_to_walk); @@ -175,6 +196,14 @@ list_lru_shrink_walk(struct list_lru *lru, struct shrink_control *sc, } static inline unsigned long +list_lru_shrink_walk_irq(struct list_lru *lru, struct shrink_control *sc, + list_lru_walk_cb isolate, void *cb_arg) +{ + return list_lru_walk_one_irq(lru, sc->nid, sc->memcg, isolate, cb_arg, + &sc->nr_to_scan); +} + +static inline unsigned long list_lru_walk(struct list_lru *lru, list_lru_walk_cb isolate, void *cb_arg, unsigned long nr_to_walk) { diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 680d3395fc83..0e6c515fb698 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -112,6 +112,15 @@ struct lruvec_stat { }; /* + * Bitmap of shrinker::id corresponding to memcg-aware shrinkers, + * which have elements charged to this memcg. + */ +struct memcg_shrinker_map { + struct rcu_head rcu; + unsigned long map[0]; +}; + +/* * per-zone information in memory controller. */ struct mem_cgroup_per_node { @@ -124,6 +133,9 @@ struct mem_cgroup_per_node { struct mem_cgroup_reclaim_iter iter[DEF_PRIORITY + 1]; +#ifdef CONFIG_MEMCG_KMEM + struct memcg_shrinker_map __rcu *shrinker_map; +#endif struct rb_node tree_node; /* RB tree node */ unsigned long usage_in_excess;/* Set to the value by which */ /* the soft limit is exceeded*/ @@ -271,7 +283,7 @@ struct mem_cgroup { bool tcpmem_active; int tcpmem_pressure; -#ifndef CONFIG_SLOB +#ifdef CONFIG_MEMCG_KMEM /* Index in the kmem_cache->memcg_params.memcg_caches array */ int kmemcg_id; enum memcg_kmem_state kmem_state; @@ -306,6 +318,11 @@ struct mem_cgroup { extern struct mem_cgroup *root_mem_cgroup; +static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg) +{ + return (memcg == root_mem_cgroup); +} + static inline bool mem_cgroup_disabled(void) { return !cgroup_subsys_enabled(memory_cgrp_subsys); @@ -373,11 +390,21 @@ 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); +struct mem_cgroup *get_mem_cgroup_from_mm(struct mm_struct *mm); + +struct mem_cgroup *get_mem_cgroup_from_page(struct page *page); + static inline struct mem_cgroup *mem_cgroup_from_css(struct cgroup_subsys_state *css){ return css ? container_of(css, struct mem_cgroup, css) : NULL; } +static inline void mem_cgroup_put(struct mem_cgroup *memcg) +{ + if (memcg) + css_put(&memcg->css); +} + #define mem_cgroup_from_counter(counter, member) \ container_of(counter, struct mem_cgroup, member) @@ -497,16 +524,16 @@ unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg); void mem_cgroup_print_oom_info(struct mem_cgroup *memcg, struct task_struct *p); -static inline void mem_cgroup_oom_enable(void) +static inline void mem_cgroup_enter_user_fault(void) { - WARN_ON(current->memcg_may_oom); - current->memcg_may_oom = 1; + WARN_ON(current->in_user_fault); + current->in_user_fault = 1; } -static inline void mem_cgroup_oom_disable(void) +static inline void mem_cgroup_exit_user_fault(void) { - WARN_ON(!current->memcg_may_oom); - current->memcg_may_oom = 0; + WARN_ON(!current->in_user_fault); + current->in_user_fault = 0; } static inline bool task_in_memcg_oom(struct task_struct *p) @@ -762,6 +789,11 @@ void mem_cgroup_split_huge_fixup(struct page *head); struct mem_cgroup; +static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg) +{ + return true; +} + static inline bool mem_cgroup_disabled(void) { return true; @@ -850,6 +882,20 @@ static inline bool task_in_mem_cgroup(struct task_struct *task, return true; } +static inline struct mem_cgroup *get_mem_cgroup_from_mm(struct mm_struct *mm) +{ + return NULL; +} + +static inline struct mem_cgroup *get_mem_cgroup_from_page(struct page *page) +{ + return NULL; +} + +static inline void mem_cgroup_put(struct mem_cgroup *memcg) +{ +} + static inline struct mem_cgroup * mem_cgroup_iter(struct mem_cgroup *root, struct mem_cgroup *prev, @@ -937,11 +983,11 @@ static inline void mem_cgroup_handle_over_high(void) { } -static inline void mem_cgroup_oom_enable(void) +static inline void mem_cgroup_enter_user_fault(void) { } -static inline void mem_cgroup_oom_disable(void) +static inline void mem_cgroup_exit_user_fault(void) { } @@ -1207,7 +1253,7 @@ int memcg_kmem_charge_memcg(struct page *page, gfp_t gfp, int order, 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) +#ifdef CONFIG_MEMCG_KMEM extern struct static_key_false memcg_kmem_enabled_key; extern struct workqueue_struct *memcg_kmem_cache_wq; @@ -1238,6 +1284,10 @@ static inline int memcg_cache_id(struct mem_cgroup *memcg) return memcg ? memcg->kmemcg_id : -1; } +extern int memcg_expand_shrinker_maps(int new_id); + +extern void memcg_set_shrinker_bit(struct mem_cgroup *memcg, + int nid, int shrinker_id); #else #define for_each_memcg_cache_index(_idx) \ for (; NULL; ) @@ -1260,6 +1310,8 @@ static inline void memcg_put_cache_ids(void) { } -#endif /* CONFIG_MEMCG && !CONFIG_SLOB */ +static inline void memcg_set_shrinker_bit(struct mem_cgroup *memcg, + int nid, int shrinker_id) { } +#endif /* CONFIG_MEMCG_KMEM */ #endif /* _LINUX_MEMCONTROL_H */ diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index 91f92215ca74..77866214ab51 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h @@ -90,6 +90,9 @@ /* Some controllers have a CBSY bit */ #define TMIO_MMC_HAVE_CBSY BIT(11) +/* Some controllers that support HS400 use use 4 taps while others use 8. */ +#define TMIO_MMC_HAVE_4TAP_HS400 BIT(13) + int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base); int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base); void tmio_core_mmc_pwr(void __iomem *cnf, int shift, int state); diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 54f385cc8811..7a452716de4b 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -1235,14 +1235,11 @@ struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev, { return ERR_PTR(-EOPNOTSUPP); } - -static inline void mlx5_rdma_netdev_free(struct net_device *netdev) {} #else struct net_device *mlx5_rdma_netdev_alloc(struct mlx5_core_dev *mdev, struct ib_device *ibdev, const char *name, void (*setup)(struct net_device *)); -void mlx5_rdma_netdev_free(struct net_device *netdev); #endif /* CONFIG_MLX5_CORE_IPOIB */ struct mlx5_profile { diff --git a/include/linux/mlx5/fs.h b/include/linux/mlx5/fs.h index 71fb503b2b52..804516e4f483 100644 --- a/include/linux/mlx5/fs.h +++ b/include/linux/mlx5/fs.h @@ -89,6 +89,7 @@ struct mlx5_flow_destination { enum mlx5_flow_destination_type type; union { u32 tir_num; + u32 ft_num; struct mlx5_flow_table *ft; struct mlx5_fc *counter; struct { diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index 6ead9c1a5396..f043d65b9bac 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -82,6 +82,7 @@ enum { enum { MLX5_OBJ_TYPE_UCTX = 0x0004, + MLX5_OBJ_TYPE_UMEM = 0x0005, }; enum { @@ -246,12 +247,15 @@ enum { MLX5_CMD_OP_DEALLOC_ENCAP_HEADER = 0x93e, MLX5_CMD_OP_ALLOC_MODIFY_HEADER_CONTEXT = 0x940, MLX5_CMD_OP_DEALLOC_MODIFY_HEADER_CONTEXT = 0x941, + MLX5_CMD_OP_QUERY_MODIFY_HEADER_CONTEXT = 0x942, MLX5_CMD_OP_FPGA_CREATE_QP = 0x960, MLX5_CMD_OP_FPGA_MODIFY_QP = 0x961, MLX5_CMD_OP_FPGA_QUERY_QP = 0x962, MLX5_CMD_OP_FPGA_DESTROY_QP = 0x963, MLX5_CMD_OP_FPGA_QUERY_QP_COUNTERS = 0x964, MLX5_CMD_OP_CREATE_GENERAL_OBJECT = 0xa00, + MLX5_CMD_OP_MODIFY_GENERAL_OBJECT = 0xa01, + MLX5_CMD_OP_QUERY_GENERAL_OBJECT = 0xa02, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT = 0xa03, MLX5_CMD_OP_MAX }; @@ -1185,6 +1189,7 @@ enum mlx5_flow_destination_type { MLX5_FLOW_DESTINATION_TYPE_PORT = 0x99, MLX5_FLOW_DESTINATION_TYPE_COUNTER = 0x100, + MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM = 0x101, }; struct mlx5_ifc_dest_format_struct_bits { diff --git a/include/linux/mm.h b/include/linux/mm.h index 68a5121694ef..a3cae495f9ce 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2665,12 +2665,7 @@ extern int randomize_va_space; const char * arch_vma_name(struct vm_area_struct *vma); void print_vma_addr(char *prefix, unsigned long rip); -void sparse_mem_maps_populate_node(struct page **map_map, - unsigned long pnum_begin, - unsigned long pnum_end, - unsigned long map_count, - int nodeid); - +void *sparse_buffer_alloc(unsigned long size); struct page *sparse_mem_map_populate(unsigned long pnum, int nid, struct vmem_altmap *altmap); pgd_t *vmemmap_pgd_populate(unsigned long addr, int node); @@ -2752,7 +2747,8 @@ extern void clear_huge_page(struct page *page, unsigned long addr_hint, unsigned int pages_per_huge_page); extern void copy_user_huge_page(struct page *dst, struct page *src, - unsigned long addr, struct vm_area_struct *vma, + unsigned long addr_hint, + struct vm_area_struct *vma, unsigned int pages_per_huge_page); extern long copy_huge_page_from_user(struct page *dst_page, const void __user *usr_src, diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index efdc24dd9e97..cd2bc939efd0 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -139,7 +139,10 @@ struct page { unsigned long _pt_pad_1; /* compound_head */ pgtable_t pmd_huge_pte; /* protected by page->ptl */ unsigned long _pt_pad_2; /* mapping */ - struct mm_struct *pt_mm; /* x86 pgds only */ + union { + struct mm_struct *pt_mm; /* x86 pgds only */ + atomic_t pt_frag_refcount; /* powerpc */ + }; #if ALLOC_SPLIT_PTLOCKS spinlock_t *ptl; #else diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 64300a48dcce..beed7121c781 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -146,6 +146,13 @@ struct mmc_host_ops { /* Prepare HS400 target operating frequency depending host driver */ int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios); + + /* Prepare for switching from HS400 to HS200 */ + void (*hs400_downgrade)(struct mmc_host *host); + + /* Complete selection of HS400 */ + void (*hs400_complete)(struct mmc_host *host); + /* Prepare enhanced strobe depending host driver */ void (*hs400_enhanced_strobe)(struct mmc_host *host, struct mmc_ios *ios); @@ -474,9 +481,6 @@ static inline void *mmc_priv(struct mmc_host *host) #define mmc_classdev(x) (&(x)->class_dev) #define mmc_hostname(x) (dev_name(&(x)->class_dev)) -int mmc_power_save_host(struct mmc_host *host); -int mmc_power_restore_host(struct mmc_host *host); - void mmc_detect_change(struct mmc_host *, unsigned long delay); void mmc_request_done(struct mmc_host *, struct mmc_request *); void mmc_command_done(struct mmc_host *host, struct mmc_request *mrq); diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 3ffc27aaeeaf..897a87c4c827 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -144,7 +144,7 @@ static inline bool mmc_op_multi(u32 opcode) #define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */ #define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */ #define R1_ERASE_RESET (1 << 13) /* sr, c */ -#define R1_STATUS(x) (x & 0xFFFFE000) +#define R1_STATUS(x) (x & 0xFFF9A000) #define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ #define R1_READY_FOR_DATA (1 << 8) /* sx, a */ #define R1_SWITCH_ERROR (1 << 7) /* sx, c */ diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 96a71a648eed..1298a7daa57d 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -746,4 +746,19 @@ struct tb_service_id { #define TBSVC_MATCH_PROTOCOL_VERSION 0x0004 #define TBSVC_MATCH_PROTOCOL_REVISION 0x0008 +/* USB Type-C Alternate Modes */ + +#define TYPEC_ANY_MODE 0x7 + +/** + * struct typec_device_id - USB Type-C alternate mode identifiers + * @svid: Standard or Vendor ID + * @mode: Mode index + */ +struct typec_device_id { + __u16 svid; + __u8 mode; + kernel_ulong_t driver_data; +}; + #endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/include/linux/module.h b/include/linux/module.h index d44df9b2c131..f807f15bebbe 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -266,7 +266,7 @@ extern int modules_disabled; /* for sysctl */ /* Get/put a kernel symbol (calls must be symmetric) */ void *__symbol_get(const char *symbol); void *__symbol_get_gpl(const char *symbol); -#define symbol_get(x) ((typeof(&x))(__symbol_get(VMLINUX_SYMBOL_STR(x)))) +#define symbol_get(x) ((typeof(&x))(__symbol_get(__stringify(x)))) /* modules using other modules: kdb wants to see this. */ struct module_use { @@ -575,7 +575,7 @@ extern void __noreturn __module_put_and_exit(struct module *mod, #ifdef CONFIG_MODULE_UNLOAD int module_refcount(struct module *mod); void __symbol_put(const char *symbol); -#define symbol_put(x) __symbol_put(VMLINUX_SYMBOL_STR(x)) +#define symbol_put(x) __symbol_put(__stringify(x)) void symbol_put_addr(void *addr); /* Sometimes we know we already have a refcount, and it's easier not diff --git a/include/linux/node.h b/include/linux/node.h index 6d336e38d155..257bb3d6d014 100644 --- a/include/linux/node.h +++ b/include/linux/node.h @@ -33,10 +33,10 @@ typedef void (*node_registration_func_t)(struct node *); #if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_NUMA) extern int link_mem_sections(int nid, unsigned long start_pfn, - unsigned long nr_pages, bool check_nid); + unsigned long end_pfn); #else static inline int link_mem_sections(int nid, unsigned long start_pfn, - unsigned long nr_pages, bool check_nid) + unsigned long end_pfn) { return 0; } @@ -54,12 +54,14 @@ static inline int register_one_node(int nid) if (node_online(nid)) { struct pglist_data *pgdat = NODE_DATA(nid); + unsigned long start_pfn = pgdat->node_start_pfn; + unsigned long end_pfn = start_pfn + pgdat->node_spanned_pages; error = __register_one_node(nid); if (error) return error; /* link memory sections under this node */ - error = link_mem_sections(nid, pgdat->node_start_pfn, pgdat->node_spanned_pages, true); + error = link_mem_sections(nid, start_pfn, end_pfn); } return error; @@ -69,7 +71,7 @@ extern void unregister_one_node(int nid); extern int register_cpu_under_node(unsigned int cpu, unsigned int nid); extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid); extern int register_mem_sect_under_node(struct memory_block *mem_blk, - int nid, bool check_nid); + void *arg); extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, unsigned long phys_index); @@ -99,7 +101,7 @@ static inline int unregister_cpu_under_node(unsigned int cpu, unsigned int nid) return 0; } static inline int register_mem_sect_under_node(struct memory_block *mem_blk, - int nid, bool check_nid) + void *arg) { return 0; } diff --git a/include/linux/of_iommu.h b/include/linux/of_iommu.h index 4fa654e4b5a9..f3d40dd7bb66 100644 --- a/include/linux/of_iommu.h +++ b/include/linux/of_iommu.h @@ -32,8 +32,4 @@ static inline const struct iommu_ops *of_iommu_configure(struct device *dev, #endif /* CONFIG_OF_IOMMU */ -extern struct of_device_id __iommu_of_table; - -#define IOMMU_OF_DECLARE(name, compat) OF_DECLARE_1(iommu, name, compat, NULL) - #endif /* __OF_IOMMU_H */ diff --git a/include/linux/overflow.h b/include/linux/overflow.h index 8712ff70995f..40b48e2133cb 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -202,6 +202,37 @@ #endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */ +/** check_shl_overflow() - Calculate a left-shifted value and check overflow + * + * @a: Value to be shifted + * @s: How many bits left to shift + * @d: Pointer to where to store the result + * + * Computes *@d = (@a << @s) + * + * Returns true if '*d' cannot hold the result or when 'a << s' doesn't + * make sense. Example conditions: + * - 'a << s' causes bits to be lost when stored in *d. + * - 's' is garbage (e.g. negative) or so large that the result of + * 'a << s' is guaranteed to be 0. + * - 'a' is negative. + * - 'a << s' sets the sign bit, if any, in '*d'. + * + * '*d' will hold the results of the attempted shift, but is not + * considered "safe for use" if false is returned. + */ +#define check_shl_overflow(a, s, d) ({ \ + typeof(a) _a = a; \ + typeof(s) _s = s; \ + typeof(d) _d = d; \ + u64 _a_full = _a; \ + unsigned int _to_shift = \ + _s >= 0 && _s < 8 * sizeof(*d) ? _s : 0; \ + *_d = (_a_full << _to_shift); \ + (_to_shift != _s || *_d < 0 || _a < 0 || \ + (*_d >> _to_shift) != _a); \ +}) + /** * array_size() - Calculate size of 2-dimensional array. * diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h index ca5461efae2f..f84f167ec04c 100644 --- a/include/linux/page_ext.h +++ b/include/linux/page_ext.h @@ -16,18 +16,7 @@ struct page_ext_operations { #ifdef CONFIG_PAGE_EXTENSION -/* - * page_ext->flags bits: - * - * PAGE_EXT_DEBUG_POISON is set for poisoned pages. This is used to - * implement generic debug pagealloc feature. The pages are filled with - * poison patterns and set this flag after free_pages(). The poisoned - * pages are verified whether the patterns are not corrupted and clear - * the flag before alloc_pages(). - */ - enum page_ext_flags { - PAGE_EXT_DEBUG_POISON, /* Page is poisoned */ PAGE_EXT_DEBUG_GUARD, PAGE_EXT_OWNER, #if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT) @@ -61,7 +50,7 @@ static inline void page_ext_init(void) } #endif -struct page_ext *lookup_page_ext(struct page *page); +struct page_ext *lookup_page_ext(const struct page *page); #else /* !CONFIG_PAGE_EXTENSION */ struct page_ext; @@ -70,7 +59,7 @@ static inline void pgdat_page_ext_init(struct pglist_data *pgdat) { } -static inline struct page_ext *lookup_page_ext(struct page *page) +static inline struct page_ext *lookup_page_ext(const struct page *page) { return NULL; } diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h index 7daa78a2f342..640dec8b5b0c 100644 --- a/include/linux/platform_data/mmc-esdhc-imx.h +++ b/include/linux/platform_data/mmc-esdhc-imx.h @@ -34,7 +34,6 @@ enum cd_types { * @cd_gpio: gpio for card_detect interrupt * @wp_type: type of write_protect method (see wp_types enum above) * @cd_type: type of card_detect method (see cd_types enum above) - * @support_vsel: indicate it supports 1.8v switching */ struct esdhc_platform_data { @@ -43,7 +42,6 @@ struct esdhc_platform_data { enum wp_types wp_type; enum cd_types cd_type; int max_bus_width; - bool support_vsel; unsigned int delay_line; unsigned int tuning_step; /* The delay cell steps in tuning procedure */ unsigned int tuning_start_tap; /* The start delay cell point in tuning procedure */ diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 3097c943fab9..1a9f38f27f65 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -12,13 +12,13 @@ #define _PLATFORM_DEVICE_H_ #include <linux/device.h> -#include <linux/mod_devicetable.h> #define PLATFORM_DEVID_NONE (-1) #define PLATFORM_DEVID_AUTO (-2) struct mfd_cell; struct property_entry; +struct platform_device_id; struct platform_device { const char *name; diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index dfdaede9139e..e3c5d856b6da 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -477,15 +477,19 @@ struct rproc { /** * struct rproc_subdev - subdevice tied to a remoteproc * @node: list node related to the rproc subdevs list - * @probe: probe function, called as the rproc is started - * @remove: remove function, called as the rproc is being stopped, the @crashed - * parameter indicates if this originates from the a recovery + * @prepare: prepare function, called before the rproc is started + * @start: start function, called after the rproc has been started + * @stop: stop function, called before the rproc is stopped; the @crashed + * parameter indicates if this originates from a recovery + * @unprepare: unprepare function, called after the rproc has been stopped */ struct rproc_subdev { struct list_head node; - int (*probe)(struct rproc_subdev *subdev); - void (*remove)(struct rproc_subdev *subdev, bool crashed); + int (*prepare)(struct rproc_subdev *subdev); + int (*start)(struct rproc_subdev *subdev); + void (*stop)(struct rproc_subdev *subdev, bool crashed); + void (*unprepare)(struct rproc_subdev *subdev); }; /* we currently support only two vrings per rvdev */ @@ -566,10 +570,7 @@ static inline struct rproc *vdev_to_rproc(struct virtio_device *vdev) return rvdev->rproc; } -void rproc_add_subdev(struct rproc *rproc, - struct rproc_subdev *subdev, - int (*probe)(struct rproc_subdev *subdev), - void (*remove)(struct rproc_subdev *subdev, bool crashed)); +void rproc_add_subdev(struct rproc *rproc, struct rproc_subdev *subdev); void rproc_remove_subdev(struct rproc *rproc, struct rproc_subdev *subdev); diff --git a/include/linux/sched.h b/include/linux/sched.h index 95a5018c338e..789923fbee3a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -722,8 +722,8 @@ struct task_struct { unsigned restore_sigmask:1; #endif #ifdef CONFIG_MEMCG - unsigned memcg_may_oom:1; -#ifndef CONFIG_SLOB + unsigned in_user_fault:1; +#ifdef CONFIG_MEMCG_KMEM unsigned memcg_kmem_skip_account:1; #endif #endif @@ -1152,6 +1152,9 @@ struct task_struct { /* Number of pages to reclaim on returning to userland: */ unsigned int memcg_nr_pages_over_high; + + /* Used by memcontrol for targeted memcg charge: */ + struct mem_cgroup *active_memcg; #endif #ifdef CONFIG_BLK_CGROUP diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h index 44d356f5e47c..aebb370a0006 100644 --- a/include/linux/sched/mm.h +++ b/include/linux/sched/mm.h @@ -248,6 +248,43 @@ static inline void memalloc_noreclaim_restore(unsigned int flags) current->flags = (current->flags & ~PF_MEMALLOC) | flags; } +#ifdef CONFIG_MEMCG +/** + * memalloc_use_memcg - Starts the remote memcg charging scope. + * @memcg: memcg to charge. + * + * This function marks the beginning of the remote memcg charging scope. All the + * __GFP_ACCOUNT allocations till the end of the scope will be charged to the + * given memcg. + * + * NOTE: This function is not nesting safe. + */ +static inline void memalloc_use_memcg(struct mem_cgroup *memcg) +{ + WARN_ON_ONCE(current->active_memcg); + current->active_memcg = memcg; +} + +/** + * memalloc_unuse_memcg - Ends the remote memcg charging scope. + * + * This function marks the end of the remote memcg charging scope started by + * memalloc_use_memcg(). + */ +static inline void memalloc_unuse_memcg(void) +{ + current->active_memcg = NULL; +} +#else +static inline void memalloc_use_memcg(struct mem_cgroup *memcg) +{ +} + +static inline void memalloc_unuse_memcg(void) +{ +} +#endif + #ifdef CONFIG_MEMBARRIER enum { MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY = (1U << 0), diff --git a/include/linux/selection.h b/include/linux/selection.h index 5b278ce99d8d..a8f5b97b216f 100644 --- a/include/linux/selection.h +++ b/include/linux/selection.h @@ -32,6 +32,7 @@ extern unsigned char default_blu[]; extern unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed); extern u16 screen_glyph(struct vc_data *vc, int offset); +extern u32 screen_glyph_unicode(struct vc_data *vc, int offset); extern void complement_pos(struct vc_data *vc, int offset); extern void invert_screen(struct vc_data *vc, int offset, int count, int shift); @@ -42,4 +43,9 @@ extern u16 vcs_scr_readw(struct vc_data *vc, const u16 *org); extern void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org); extern void vcs_scr_updated(struct vc_data *vc); +extern int vc_uniscr_check(struct vc_data *vc); +extern void vc_uniscr_copy_line(struct vc_data *vc, void *dest, int viewed, + unsigned int row, unsigned int col, + unsigned int nr); + #endif diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index 76b9db71e489..18e21427bce4 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -160,6 +160,9 @@ extern void serial8250_do_shutdown(struct uart_port *port); extern void serial8250_do_pm(struct uart_port *port, unsigned int state, unsigned int oldstate); extern void serial8250_do_set_mctrl(struct uart_port *port, unsigned int mctrl); +extern void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud, + unsigned int quot, + unsigned int quot_frac); extern int fsl8250_handle_irq(struct uart_port *port); int serial8250_handle_irq(struct uart_port *port, unsigned int iir); unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr); diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 06ea4eeb09ab..406edae44ca3 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -127,6 +127,13 @@ struct uart_port { struct ktermios *); unsigned int (*get_mctrl)(struct uart_port *); void (*set_mctrl)(struct uart_port *, unsigned int); + unsigned int (*get_divisor)(struct uart_port *, + unsigned int baud, + unsigned int *frac); + void (*set_divisor)(struct uart_port *, + unsigned int baud, + unsigned int quot, + unsigned int quot_frac); int (*startup)(struct uart_port *port); void (*shutdown)(struct uart_port *port); void (*throttle)(struct uart_port *port); diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h index 6794490f25b2..b154fd2b084c 100644 --- a/include/linux/shrinker.h +++ b/include/linux/shrinker.h @@ -34,12 +34,15 @@ struct shrink_control { }; #define SHRINK_STOP (~0UL) +#define SHRINK_EMPTY (~0UL - 1) /* * A callback you can register to apply pressure to ageable caches. * * @count_objects should return the number of freeable items in the cache. If - * there are no objects to free or the number of freeable items cannot be - * determined, it should return 0. No deadlock checks should be done during the + * there are no objects to free, it should return SHRINK_EMPTY, while 0 is + * returned in cases of the number of freeable items cannot be determined + * or shrinker should skip this cache for this time (e.g., their number + * is below shrinkable limit). No deadlock checks should be done during the * count callback - the shrinker relies on aggregating scan counts that couldn't * be executed due to potential deadlocks to be run at a later call when the * deadlock condition is no longer pending. @@ -66,6 +69,10 @@ struct shrinker { /* These are for internal use */ struct list_head list; +#ifdef CONFIG_MEMCG_KMEM + /* ID in shrinker_idr */ + int id; +#endif /* objs pending delete, per node */ atomic_long_t *nr_deferred; }; diff --git a/include/linux/slab.h b/include/linux/slab.h index 14e3fe4bd6a1..ed9cbddeb4a6 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -97,7 +97,7 @@ # define SLAB_FAILSLAB 0 #endif /* Account to memcg */ -#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB) +#ifdef CONFIG_MEMCG_KMEM # define SLAB_ACCOUNT ((slab_flags_t __force)0x04000000U) #else # define SLAB_ACCOUNT 0 diff --git a/include/linux/slimbus.h b/include/linux/slimbus.h index c36cf121d2cd..12c9719b2a55 100644 --- a/include/linux/slimbus.h +++ b/include/linux/slimbus.h @@ -14,16 +14,16 @@ extern struct bus_type slimbus_bus; /** * struct slim_eaddr - Enumeration address for a SLIMbus device - * @manf_id: Manufacturer Id for the device - * @prod_code: Product code - * @dev_index: Device index * @instance: Instance value + * @dev_index: Device index + * @prod_code: Product code + * @manf_id: Manufacturer Id for the device */ struct slim_eaddr { - u16 manf_id; - u16 prod_code; - u8 dev_index; u8 instance; + u8 dev_index; + u16 prod_code; + u16 manf_id; } __packed; /** @@ -48,6 +48,8 @@ struct slim_controller; * @ctrl: slim controller instance. * @laddr: 1-byte Logical address of this device. * @is_laddr_valid: indicates if the laddr is valid or not + * @stream_list: List of streams on this device + * @stream_list_lock: lock to protect the stream list * * This is the client/device handle returned when a SLIMbus * device is registered with a controller. @@ -60,6 +62,8 @@ struct slim_device { enum slim_device_status status; u8 laddr; bool is_laddr_valid; + struct list_head stream_list; + spinlock_t stream_list_lock; }; #define to_slim_device(d) container_of(d, struct slim_device, dev) @@ -108,6 +112,36 @@ struct slim_val_inf { struct completion *comp; }; +#define SLIM_DEVICE_MAX_CHANNELS 256 +/* A SLIMBus Device may have frmo 0 to 31 Ports (inclusive) */ +#define SLIM_DEVICE_MAX_PORTS 32 + +/** + * struct slim_stream_config - SLIMbus stream configuration + * Configuring a stream is done at hw_params or prepare call + * from audio drivers where they have all the required information + * regarding rate, number of channels and so on. + * There is a 1:1 mapping of channel and ports. + * + * @rate: data rate + * @bps: bits per data sample + * @ch_count: number of channels + * @chs: pointer to list of channel numbers + * @port_mask: port mask of ports to use for this stream + * @direction: direction of the stream, SNDRV_PCM_STREAM_PLAYBACK + * or SNDRV_PCM_STREAM_CAPTURE. + */ +struct slim_stream_config { + unsigned int rate; + unsigned int bps; + /* MAX 256 channels */ + unsigned int ch_count; + unsigned int *chs; + /* Max 32 ports per device */ + unsigned long port_mask; + int direction; +}; + /* * use a macro to avoid include chaining to get THIS_MODULE */ @@ -138,6 +172,8 @@ static inline void slim_set_devicedata(struct slim_device *dev, void *data) dev_set_drvdata(&dev->dev, data); } +struct slim_device *of_slim_get_device(struct slim_controller *ctrl, + struct device_node *np); struct slim_device *slim_get_device(struct slim_controller *ctrl, struct slim_eaddr *e_addr); int slim_get_logical_addr(struct slim_device *sbdev); @@ -161,4 +197,16 @@ int slim_readb(struct slim_device *sdev, u32 addr); int slim_writeb(struct slim_device *sdev, u32 addr, u8 value); int slim_read(struct slim_device *sdev, u32 addr, size_t count, u8 *val); int slim_write(struct slim_device *sdev, u32 addr, size_t count, u8 *val); + +/* SLIMbus Stream apis */ +struct slim_stream_runtime; +struct slim_stream_runtime *slim_stream_allocate(struct slim_device *dev, + const char *sname); +int slim_stream_prepare(struct slim_stream_runtime *stream, + struct slim_stream_config *c); +int slim_stream_enable(struct slim_stream_runtime *stream); +int slim_stream_disable(struct slim_stream_runtime *stream); +int slim_stream_unprepare(struct slim_stream_runtime *stream); +int slim_stream_free(struct slim_stream_runtime *stream); + #endif /* _LINUX_SLIMBUS_H */ diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h index 5b98bbdabc25..944b06aefb0f 100644 --- a/include/linux/soc/qcom/mdt_loader.h +++ b/include/linux/soc/qcom/mdt_loader.h @@ -17,4 +17,8 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw, phys_addr_t mem_phys, size_t mem_size, phys_addr_t *reloc_base); +int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw, + const char *fw_name, int pas_id, void *mem_region, + phys_addr_t mem_phys, size_t mem_size, + phys_addr_t *reloc_base); #endif diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 3c12198c0103..987cefa337de 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -91,9 +91,9 @@ struct attribute_group { struct bin_attribute **bin_attrs; }; -/** - * Use these macros to make defining attributes easier. See include/linux/device.h - * for examples.. +/* + * Use these macros to make defining attributes easier. + * See include/linux/device.h for examples.. */ #define SYSFS_PREALLOC 010000 diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 1ef64d4ad887..840894ca3fc0 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -119,13 +119,13 @@ #include <linux/fs.h> #include <linux/wait.h> - +#include <linux/atomic.h> /* * the semaphore definition */ struct ld_semaphore { - long count; + atomic_long_t count; raw_spinlock_t wait_lock; unsigned int wait_readers; struct list_head read_wait; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 34a6ded6f319..97e2ddec18b1 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -322,6 +322,7 @@ struct hc_driver { int (*bus_suspend)(struct usb_hcd *); int (*bus_resume)(struct usb_hcd *); int (*start_port_reset)(struct usb_hcd *, unsigned port_num); + unsigned long (*get_resuming_ports)(struct usb_hcd *); /* force handover of high-speed port to full-speed companion */ void (*relinquish_port)(struct usb_hcd *, int); diff --git a/include/linux/usb/pd.h b/include/linux/usb/pd.h index 09b570feb297..f2162e0fe531 100644 --- a/include/linux/usb/pd.h +++ b/include/linux/usb/pd.h @@ -15,6 +15,7 @@ #ifndef __LINUX_USB_PD_H #define __LINUX_USB_PD_H +#include <linux/kernel.h> #include <linux/types.h> #include <linux/usb/typec.h> diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h index b231b9314240..7e7fbfb84e8e 100644 --- a/include/linux/usb/tcpm.h +++ b/include/linux/usb/tcpm.h @@ -98,18 +98,10 @@ struct tcpc_config { #define TCPC_MUX_DP_ENABLED BIT(1) /* DP enabled */ #define TCPC_MUX_POLARITY_INVERTED BIT(2) /* Polarity inverted */ -/* Mux modes, decoded to attributes */ -enum tcpc_mux_mode { - TYPEC_MUX_NONE = 0, /* Open switch */ - TYPEC_MUX_USB = TCPC_MUX_USB_ENABLED, /* USB only */ - TYPEC_MUX_DP = TCPC_MUX_DP_ENABLED, /* DP only */ - TYPEC_MUX_DOCK = TCPC_MUX_USB_ENABLED | /* Both USB and DP */ - TCPC_MUX_DP_ENABLED, -}; - /** * struct tcpc_dev - Port configuration and callback functions * @config: Pointer to port configuration + * @fwnode: Pointer to port fwnode * @get_vbus: Called to read current VBUS state * @get_current_limit: * Optional; called by the tcpm core when configured as a snk @@ -138,6 +130,7 @@ enum tcpc_mux_mode { */ struct tcpc_dev { const struct tcpc_config *config; + struct fwnode_handle *fwnode; int (*init)(struct tcpc_dev *dev); int (*get_vbus)(struct tcpc_dev *dev); diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 672b39bb0adc..7df4ecabc78a 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -5,21 +5,18 @@ #include <linux/types.h> -/* XXX: Once we have a header for USB Power Delivery, this belongs there */ -#define ALTMODE_MAX_MODES 6 - /* USB Type-C Specification releases */ #define USB_TYPEC_REV_1_0 0x100 /* 1.0 */ #define USB_TYPEC_REV_1_1 0x110 /* 1.1 */ #define USB_TYPEC_REV_1_2 0x120 /* 1.2 */ -struct typec_altmode; struct typec_partner; struct typec_cable; struct typec_plug; struct typec_port; struct fwnode_handle; +struct device; enum typec_port_type { TYPEC_PORT_SRC, @@ -93,39 +90,21 @@ int typec_partner_set_identity(struct typec_partner *partner); int typec_cable_set_identity(struct typec_cable *cable); /* - * struct typec_mode_desc - Individual Mode of an Alternate Mode - * @index: Index of the Mode within the SVID - * @vdo: VDO returned by Discover Modes USB PD command - * @desc: Optional human readable description of the mode - * @roles: Only for ports. DRP if the mode is available in both roles - * - * Description of a mode of an Alternate Mode which a connector, cable plug or - * partner supports. Every mode will have it's own sysfs group. The details are - * the VDO returned by discover modes command, description for the mode and - * active flag telling has the mode being entered or not. - */ -struct typec_mode_desc { - int index; - u32 vdo; - char *desc; - /* Only used with ports */ - enum typec_port_type roles; -}; - -/* * struct typec_altmode_desc - USB Type-C Alternate Mode Descriptor * @svid: Standard or Vendor ID - * @n_modes: Number of modes - * @modes: Array of modes supported by the Alternate Mode + * @mode: Index of the Mode + * @vdo: VDO returned by Discover Modes USB PD command + * @roles: Only for ports. DRP if the mode is available in both roles * - * Representation of an Alternate Mode that has SVID assigned by USB-IF. The - * array of modes will list the modes of a particular SVID that are supported by - * a connector, partner of a cable plug. + * Description of an Alternate Mode which a connector, cable plug or partner + * supports. */ struct typec_altmode_desc { u16 svid; - int n_modes; - struct typec_mode_desc modes[ALTMODE_MAX_MODES]; + u8 mode; + u32 vdo; + /* Only used with ports */ + enum typec_port_data roles; }; struct typec_altmode @@ -141,8 +120,7 @@ void typec_unregister_altmode(struct typec_altmode *altmode); struct typec_port *typec_altmode2port(struct typec_altmode *alt); -void typec_altmode_update_active(struct typec_altmode *alt, int mode, - bool active); +void typec_altmode_update_active(struct typec_altmode *alt, bool active); enum typec_plug_index { TYPEC_PLUG_SOP_P, @@ -205,7 +183,6 @@ struct typec_partner_desc { * @dr_set: Set Data Role * @pr_set: Set Power Role * @vconn_set: Set VCONN Role - * @activate_mode: Enter/exit given Alternate Mode * @port_type_set: Set port type * * Static capabilities of a single USB Type-C port. @@ -231,12 +208,8 @@ struct typec_capability { enum typec_role); int (*vconn_set)(const struct typec_capability *, enum typec_role); - - int (*activate_mode)(const struct typec_capability *, - int mode, int activate); int (*port_type_set)(const struct typec_capability *, - enum typec_port_type); - + enum typec_port_type); }; /* Specific to try_role(). Indicates the user want's to clear the preference. */ @@ -265,6 +238,10 @@ void typec_set_pwr_opmode(struct typec_port *port, enum typec_pwr_opmode mode); int typec_set_orientation(struct typec_port *port, enum typec_orientation orientation); +enum typec_orientation typec_get_orientation(struct typec_port *port); int typec_set_mode(struct typec_port *port, int mode); +int typec_find_port_power_role(const char *name); +int typec_find_power_role(const char *name); +int typec_find_port_data_role(const char *name); #endif /* __LINUX_USB_TYPEC_H */ diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h new file mode 100644 index 000000000000..9a88c74a1d0d --- /dev/null +++ b/include/linux/usb/typec_altmode.h @@ -0,0 +1,160 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __USB_TYPEC_ALTMODE_H +#define __USB_TYPEC_ALTMODE_H + +#include <linux/mod_devicetable.h> +#include <linux/usb/typec.h> +#include <linux/device.h> + +#define MODE_DISCOVERY_MAX 6 + +struct typec_altmode_ops; + +/** + * struct typec_altmode - USB Type-C alternate mode device + * @dev: Driver model's view of this device + * @svid: Standard or Vendor ID (SVID) of the alternate mode + * @mode: Index of the Mode + * @vdo: VDO returned by Discover Modes USB PD command + * @active: Tells has the mode been entered or not + * @desc: Optional human readable description of the mode + * @ops: Operations vector from the driver + */ +struct typec_altmode { + struct device dev; + u16 svid; + int mode; + u32 vdo; + unsigned int active:1; + + char *desc; + const struct typec_altmode_ops *ops; +}; + +#define to_typec_altmode(d) container_of(d, struct typec_altmode, dev) + +static inline void typec_altmode_set_drvdata(struct typec_altmode *altmode, + void *data) +{ + dev_set_drvdata(&altmode->dev, data); +} + +static inline void *typec_altmode_get_drvdata(struct typec_altmode *altmode) +{ + return dev_get_drvdata(&altmode->dev); +} + +/** + * struct typec_altmode_ops - Alternate mode specific operations vector + * @enter: Operations to be executed with Enter Mode Command + * @exit: Operations to be executed with Exit Mode Command + * @attention: Callback for Attention Command + * @vdm: Callback for SVID specific commands + * @notify: Communication channel for platform and the alternate mode + * @activate: User callback for Enter/Exit Mode + */ +struct typec_altmode_ops { + int (*enter)(struct typec_altmode *altmode); + int (*exit)(struct typec_altmode *altmode); + void (*attention)(struct typec_altmode *altmode, u32 vdo); + int (*vdm)(struct typec_altmode *altmode, const u32 hdr, + const u32 *vdo, int cnt); + int (*notify)(struct typec_altmode *altmode, unsigned long conf, + void *data); + int (*activate)(struct typec_altmode *altmode, int activate); +}; + +int typec_altmode_enter(struct typec_altmode *altmode); +int typec_altmode_exit(struct typec_altmode *altmode); +void typec_altmode_attention(struct typec_altmode *altmode, u32 vdo); +int typec_altmode_vdm(struct typec_altmode *altmode, + const u32 header, const u32 *vdo, int count); +int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf, + void *data); +const struct typec_altmode * +typec_altmode_get_partner(struct typec_altmode *altmode); + +/* + * These are the connector states (USB, Safe and Alt Mode) defined in USB Type-C + * Specification. SVID specific connector states are expected to follow and + * start from the value TYPEC_STATE_MODAL. + */ +enum { + TYPEC_STATE_SAFE, /* USB Safe State */ + TYPEC_STATE_USB, /* USB Operation */ + TYPEC_STATE_MODAL, /* Alternate Modes */ +}; + +/* + * For the muxes there is no difference between Accessory Modes and Alternate + * Modes, so the Accessory Modes are supplied with specific modal state values + * here. Unlike with Alternate Modes, where the mux will be linked with the + * alternate mode device, the mux for Accessory Modes will be linked with the + * port device instead. + * + * Port drivers can use TYPEC_MODE_AUDIO and TYPEC_MODE_DEBUG as the mode + * value for typec_set_mode() when accessory modes are supported. + */ +enum { + TYPEC_MODE_AUDIO = TYPEC_STATE_MODAL, /* Audio Accessory */ + TYPEC_MODE_DEBUG, /* Debug Accessory */ +}; + +#define TYPEC_MODAL_STATE(_state_) ((_state_) + TYPEC_STATE_MODAL) + +struct typec_altmode *typec_altmode_get_plug(struct typec_altmode *altmode, + enum typec_plug_index index); +void typec_altmode_put_plug(struct typec_altmode *plug); + +struct typec_altmode *typec_match_altmode(struct typec_altmode **altmodes, + size_t n, u16 svid, u8 mode); + +struct typec_altmode * +typec_altmode_register_notifier(struct device *dev, u16 svid, u8 mode, + struct notifier_block *nb); + +void typec_altmode_unregister_notifier(struct typec_altmode *adev, + struct notifier_block *nb); + +/** + * typec_altmode_get_orientation - Get cable plug orientation + * altmode: Handle to the alternate mode + */ +static inline enum typec_orientation +typec_altmode_get_orientation(struct typec_altmode *altmode) +{ + return typec_get_orientation(typec_altmode2port(altmode)); +} + +/** + * struct typec_altmode_driver - USB Type-C alternate mode device driver + * @id_table: Null terminated array of SVIDs + * @probe: Callback for device binding + * @remove: Callback for device unbinding + * @driver: Device driver model driver + * + * These drivers will be bind to the partner alternate mode devices. They will + * handle all SVID specific communication. + */ +struct typec_altmode_driver { + const struct typec_device_id *id_table; + int (*probe)(struct typec_altmode *altmode); + void (*remove)(struct typec_altmode *altmode); + struct device_driver driver; +}; + +#define to_altmode_driver(d) container_of(d, struct typec_altmode_driver, \ + driver) + +#define typec_altmode_register_driver(drv) \ + __typec_altmode_register_driver(drv, THIS_MODULE) +int __typec_altmode_register_driver(struct typec_altmode_driver *drv, + struct module *module); +void typec_altmode_unregister_driver(struct typec_altmode_driver *drv); + +#define module_typec_altmode_driver(__typec_altmode_driver) \ + module_driver(__typec_altmode_driver, typec_altmode_register_driver, \ + typec_altmode_unregister_driver) + +#endif /* __USB_TYPEC_ALTMODE_H */ diff --git a/include/linux/usb/typec_dp.h b/include/linux/usb/typec_dp.h new file mode 100644 index 000000000000..55ae781d60a9 --- /dev/null +++ b/include/linux/usb/typec_dp.h @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __USB_TYPEC_DP_H +#define __USB_TYPEC_DP_H + +#include <linux/usb/typec_altmode.h> + +#define USB_TYPEC_DP_SID 0xff01 +#define USB_TYPEC_DP_MODE 1 + +/* + * Connector states matching the pin assignments in DisplayPort Alt Mode + * Specification. + * + * These values are meant primarily to be used by the mux drivers, but they are + * also used as the "value" part in the alternate mode notification chain, so + * receivers of those notifications will always see them. + * + * Note. DisplayPort USB Type-C Alt Mode Specification version 1.0b deprecated + * pin assignments A, B and F, but they are still defined here for legacy + * purposes. + */ +enum { + TYPEC_DP_STATE_A = TYPEC_STATE_MODAL, /* Not supported after v1.0b */ + TYPEC_DP_STATE_B, /* Not supported after v1.0b */ + TYPEC_DP_STATE_C, + TYPEC_DP_STATE_D, + TYPEC_DP_STATE_E, + TYPEC_DP_STATE_F, /* Not supported after v1.0b */ +}; + +/* + * struct typec_displayport_data - DisplayPort Alt Mode specific data + * @status: Status Update command VDO content + * @conf: Configure command VDO content + * + * This structure is delivered as the data part with the notifications. It + * contains the VDOs from the two DisplayPort Type-C alternate mode specific + * commands: Status Update and Configure. + * + * @status will show for example the status of the HPD signal. + */ +struct typec_displayport_data { + u32 status; + u32 conf; +}; + +enum { + DP_PIN_ASSIGN_A, /* Not supported after v1.0b */ + DP_PIN_ASSIGN_B, /* Not supported after v1.0b */ + DP_PIN_ASSIGN_C, + DP_PIN_ASSIGN_D, + DP_PIN_ASSIGN_E, + DP_PIN_ASSIGN_F, /* Not supported after v1.0b */ +}; + +/* DisplayPort alt mode specific commands */ +#define DP_CMD_STATUS_UPDATE VDO_CMD_VENDOR(0) +#define DP_CMD_CONFIGURE VDO_CMD_VENDOR(1) + +/* DisplayPort Capabilities VDO bits (returned with Discover Modes) */ +#define DP_CAP_CAPABILITY(_cap_) ((_cap_) & 3) +#define DP_CAP_UFP_D 1 +#define DP_CAP_DFP_D 2 +#define DP_CAP_DFP_D_AND_UFP_D 3 +#define DP_CAP_DP_SIGNALING BIT(2) /* Always set */ +#define DP_CAP_GEN2 BIT(3) /* Reserved after v1.0b */ +#define DP_CAP_RECEPTACLE BIT(6) +#define DP_CAP_USB BIT(7) +#define DP_CAP_DFP_D_PIN_ASSIGN(_cap_) (((_cap_) & GENMASK(15, 8)) >> 8) +#define DP_CAP_UFP_D_PIN_ASSIGN(_cap_) (((_cap_) & GENMASK(23, 16)) >> 16) + +/* DisplayPort Status Update VDO bits */ +#define DP_STATUS_CONNECTION(_status_) ((_status_) & 3) +#define DP_STATUS_CON_DISABLED 0 +#define DP_STATUS_CON_DFP_D 1 +#define DP_STATUS_CON_UFP_D 2 +#define DP_STATUS_CON_BOTH 3 +#define DP_STATUS_POWER_LOW BIT(2) +#define DP_STATUS_ENABLED BIT(3) +#define DP_STATUS_PREFER_MULTI_FUNC BIT(4) +#define DP_STATUS_SWITCH_TO_USB BIT(5) +#define DP_STATUS_EXIT_DP_MODE BIT(6) +#define DP_STATUS_HPD_STATE BIT(7) /* 0 = HPD_Low, 1 = HPD_High */ +#define DP_STATUS_IRQ_HPD BIT(8) + +/* DisplayPort Configurations VDO bits */ +#define DP_CONF_CURRENTLY(_conf_) ((_conf_) & 3) +#define DP_CONF_UFP_U_AS_DFP_D BIT(0) +#define DP_CONF_UFP_U_AS_UFP_D BIT(1) +#define DP_CONF_SIGNALING_DP BIT(2) +#define DP_CONF_SIGNALING_GEN_2 BIT(3) /* Reserved after v1.0b */ +#define DP_CONF_PIN_ASSIGNEMENT_SHIFT 8 +#define DP_CONF_PIN_ASSIGNEMENT_MASK GENMASK(15, 8) + +#endif /* __USB_TYPEC_DP_H */ diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h index 12c1b057834b..79293f630ee1 100644 --- a/include/linux/usb/typec_mux.h +++ b/include/linux/usb/typec_mux.h @@ -47,7 +47,7 @@ void typec_switch_put(struct typec_switch *sw); int typec_switch_register(struct typec_switch *sw); void typec_switch_unregister(struct typec_switch *sw); -struct typec_mux *typec_mux_get(struct device *dev); +struct typec_mux *typec_mux_get(struct device *dev, const char *name); void typec_mux_put(struct typec_mux *mux); int typec_mux_register(struct typec_mux *mux); void typec_mux_unregister(struct typec_mux *mux); diff --git a/include/linux/vmacache.h b/include/linux/vmacache.h index a5b3aa8d281f..3e9a963edd6a 100644 --- a/include/linux/vmacache.h +++ b/include/linux/vmacache.h @@ -5,12 +5,6 @@ #include <linux/sched.h> #include <linux/mm.h> -/* - * Hash based on the page number. Provides a good hit rate for - * workloads with good locality and those with random accesses as well. - */ -#define VMACACHE_HASH(addr) ((addr >> PAGE_SHIFT) & VMACACHE_MASK) - static inline void vmacache_flush(struct task_struct *tsk) { memset(tsk->vmacache.vmas, 0, sizeof(tsk->vmacache.vmas)); diff --git a/include/misc/cxl-base.h b/include/misc/cxl-base.h index b2ebc91fe09a..f53808fa638a 100644 --- a/include/misc/cxl-base.h +++ b/include/misc/cxl-base.h @@ -10,8 +10,6 @@ #ifndef _MISC_CXL_BASE_H #define _MISC_CXL_BASE_H -#include <misc/cxl.h> - #ifdef CONFIG_CXL_BASE #define CXL_IRQ_RANGES 4 @@ -41,10 +39,6 @@ static inline void cxl_ctx_put(void) struct cxl_afu *cxl_afu_get(struct cxl_afu *afu); void cxl_afu_put(struct cxl_afu *afu); void cxl_slbia(struct mm_struct *mm); -bool cxl_pci_associate_default_context(struct pci_dev *dev, struct cxl_afu *afu); -void cxl_pci_disable_device(struct pci_dev *dev); -int cxl_cx4_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type); -void cxl_cx4_teardown_msi_irqs(struct pci_dev *pdev); #else /* CONFIG_CXL_BASE */ @@ -52,10 +46,6 @@ static inline bool cxl_ctx_in_use(void) { return false; } static inline struct cxl_afu *cxl_afu_get(struct cxl_afu *afu) { return NULL; } static inline void cxl_afu_put(struct cxl_afu *afu) {} static inline void cxl_slbia(struct mm_struct *mm) {} -static inline bool cxl_pci_associate_default_context(struct pci_dev *dev, struct cxl_afu *afu) { return false; } -static inline void cxl_pci_disable_device(struct pci_dev *dev) {} -static inline int cxl_cx4_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) { return -ENODEV; } -static inline void cxl_cx4_teardown_msi_irqs(struct pci_dev *pdev) {} #endif /* CONFIG_CXL_BASE */ diff --git a/include/misc/cxl.h b/include/misc/cxl.h index b712be544f8c..ea9ff4a1a9ca 100644 --- a/include/misc/cxl.h +++ b/include/misc/cxl.h @@ -24,46 +24,6 @@ * generic PCI API. This API is agnostic to the actual AFU. */ -#define CXL_SLOT_FLAG_DMA 0x1 - -/* - * Checks if the given card is in a cxl capable slot. Pass CXL_SLOT_FLAG_DMA if - * the card requires CAPP DMA mode to also check if the system supports it. - * This is intended to be used by bi-modal devices to determine if they can use - * cxl mode or if they should continue running in PCI mode. - * - * Note that this only checks if the slot is cxl capable - it does not - * currently check if the CAPP is currently available for chips where it can be - * assigned to different PHBs on a first come first serve basis (i.e. P8) - */ -bool cxl_slot_is_supported(struct pci_dev *dev, int flags); - - -#define CXL_BIMODE_CXL 1 -#define CXL_BIMODE_PCI 2 - -/* - * Check the mode that the given bi-modal CXL adapter is currently in and - * change it if necessary. This does not apply to AFU drivers. - * - * If the mode matches the requested mode this function will return 0 - if the - * driver was expecting the generic CXL driver to have bound to the adapter and - * it gets this return value it should fail the probe function to give the CXL - * driver a chance to probe it. - * - * If the mode does not match it will start a background task to unplug the - * device from Linux and switch its mode, and will return -EBUSY. At this - * point the calling driver should make sure it has released the device and - * fail its probe function. - * - * The offset of the CXL VSEC can be provided to this function. If 0 is passed, - * this function will search for a CXL VSEC with ID 0x1280 and return -ENODEV - * if it is not found. - */ -#ifdef CONFIG_CXL_BIMODAL -int cxl_check_and_switch_mode(struct pci_dev *dev, int mode, int vsec); -#endif - /* Get the AFU associated with a pci_dev */ struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev); @@ -174,14 +134,6 @@ int cxl_afu_reset(struct cxl_context *ctx); void cxl_set_master(struct cxl_context *ctx); /* - * Sets the context to use real mode memory accesses to operate with - * translation disabled. Note that this only makes sense for kernel contexts - * under bare metal, and will not work with virtualisation. May only be - * performed on stopped contexts. - */ -int cxl_set_translation_mode(struct cxl_context *ctx, bool real_mode); - -/* * Map and unmap the AFU Problem Space area. The amount and location mapped * depends on if this context is a master or slave. */ @@ -192,26 +144,6 @@ void cxl_psa_unmap(void __iomem *addr); int cxl_process_element(struct cxl_context *ctx); /* - * Limit the number of interrupts that a single context can allocate via - * cxl_start_work. If using the api with a real phb, this may be used to - * request that additional default contexts be created when allocating - * interrupts via pci_enable_msix_range. These will be set to the same running - * state as the default context, and if that is running it will reuse the - * parameters previously passed to cxl_start_context for the default context. - */ -int cxl_set_max_irqs_per_process(struct pci_dev *dev, int irqs); -int cxl_get_max_irqs_per_process(struct pci_dev *dev); - -/* - * Use to simultaneously iterate over hardware interrupt numbers, contexts and - * afu interrupt numbers allocated for the device via pci_enable_msix_range and - * is a useful convenience function when working with hardware that has - * limitations on the number of interrupts per process. *ctx and *afu_irq - * should be NULL and 0 to start the iteration. - */ -int cxl_next_msi_hwirq(struct pci_dev *pdev, struct cxl_context **ctx, int *afu_irq); - -/* * These calls allow drivers to create their own file descriptors and make them * identical to the cxl file descriptor user API. An example use case: * diff --git a/include/net/9p/client.h b/include/net/9p/client.h index 7af9d769b97d..0fa0fbab33b0 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -27,6 +27,7 @@ #define NET_9P_CLIENT_H #include <linux/utsname.h> +#include <linux/idr.h> /* Number of requests per row */ #define P9_ROW_MAXTAG 255 @@ -112,7 +113,7 @@ enum p9_req_status_t { struct p9_req_t { int status; int t_err; - wait_queue_head_t *wq; + wait_queue_head_t wq; struct p9_fcall *tc; struct p9_fcall *rc; void *aux; @@ -128,8 +129,7 @@ struct p9_req_t { * @proto_version: 9P protocol version to use * @trans_mod: module API instantiated with this client * @trans: tranport instance state and API - * @fidpool: fid handle accounting for session - * @fidlist: List of active fid handles + * @fids: All active FID handles * @tagpool - transaction id accounting for session * @reqs - 2D array of requests * @max_tag - current maximum tag id allocated @@ -169,8 +169,7 @@ struct p9_client { } tcp; } trans_opts; - struct p9_idpool *fidpool; - struct list_head fidlist; + struct idr fids; struct p9_idpool *tagpool; struct p9_req_t *reqs[P9_ROW_MAXTAG]; @@ -188,7 +187,6 @@ struct p9_client { * @iounit: the server reported maximum transaction size for this file * @uid: the numeric uid of the local user who owns this handle * @rdir: readdir accounting structure (allocated on demand) - * @flist: per-client-instance fid tracking * @dlist: per-dentry fid tracking * * TODO: This needs lots of explanation. @@ -204,7 +202,6 @@ struct p9_fid { void *rdir; - struct list_head flist; struct hlist_node dlist; /* list of all fids attached to a dentry */ }; diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index 2d56e428506c..3037157855f0 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -206,16 +206,6 @@ int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val); /* device configuration */ int pcmcia_request_io(struct pcmcia_device *p_dev); -int __must_check -__pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, - irq_handler_t handler); -static inline __must_check __deprecated int -pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, - irq_handler_t handler) -{ - return __pcmcia_request_exclusive_irq(p_dev, handler); -} - int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev, irq_handler_t handler); diff --git a/include/rdma/ib.h b/include/rdma/ib.h index 66dbed0c146d..4f385ec54f80 100644 --- a/include/rdma/ib.h +++ b/include/rdma/ib.h @@ -53,12 +53,12 @@ struct ib_addr { #define sib_interface_id ib_u.uib_addr64[1] }; -static inline int ib_addr_any(const struct ib_addr *a) +static inline bool ib_addr_any(const struct ib_addr *a) { return ((a->sib_addr64[0] | a->sib_addr64[1]) == 0); } -static inline int ib_addr_loopback(const struct ib_addr *a) +static inline bool ib_addr_loopback(const struct ib_addr *a) { return ((a->sib_addr32[0] | a->sib_addr32[1] | a->sib_addr32[2] | (a->sib_addr32[3] ^ htonl(1))) == 0); diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h index c2c8b1fdeead..77c7908b7d73 100644 --- a/include/rdma/ib_addr.h +++ b/include/rdma/ib_addr.h @@ -58,6 +58,7 @@ * @bound_dev_if: An optional device interface index. * @transport: The transport type used. * @net: Network namespace containing the bound_dev_if net_dev. + * @sgid_attr: GID attribute to use for identified SGID */ struct rdma_dev_addr { unsigned char src_dev_addr[MAX_ADDR_LEN]; @@ -67,6 +68,7 @@ struct rdma_dev_addr { int bound_dev_if; enum rdma_transport_type transport; struct net *net; + const struct ib_gid_attr *sgid_attr; enum rdma_network_type network; int hoplimit; }; @@ -95,7 +97,7 @@ int rdma_translate_ip(const struct sockaddr *addr, * or been canceled. A status of 0 indicates success. * @context: User-specified context associated with the call. */ -int rdma_resolve_ip(struct sockaddr *src_addr, struct sockaddr *dst_addr, +int rdma_resolve_ip(struct sockaddr *src_addr, const struct sockaddr *dst_addr, struct rdma_dev_addr *addr, int timeout_ms, void (*callback)(int status, struct sockaddr *src_addr, struct rdma_dev_addr *addr, void *context), @@ -107,7 +109,7 @@ void rdma_copy_addr(struct rdma_dev_addr *dev_addr, const struct net_device *dev, const unsigned char *dst_dev_addr); -int rdma_addr_size(struct sockaddr *addr); +int rdma_addr_size(const struct sockaddr *addr); int rdma_addr_size_in6(struct sockaddr_in6 *addr); int rdma_addr_size_kss(struct __kernel_sockaddr_storage *addr); diff --git a/include/rdma/ib_cache.h b/include/rdma/ib_cache.h index a5f249828115..3e11e7cc60b7 100644 --- a/include/rdma/ib_cache.h +++ b/include/rdma/ib_cache.h @@ -37,45 +37,23 @@ #include <rdma/ib_verbs.h> -/** - * ib_get_cached_gid - Returns a cached GID table entry - * @device: The device to query. - * @port_num: The port number of the device to query. - * @index: The index into the cached GID table to query. - * @gid: The GID value found at the specified index. - * @attr: The GID attribute found at the specified index (only in RoCE). - * NULL means ignore (output parameter). - * - * ib_get_cached_gid() fetches the specified GID table entry stored in - * the local software cache. - */ -int ib_get_cached_gid(struct ib_device *device, - u8 port_num, - int index, - union ib_gid *gid, - struct ib_gid_attr *attr); - -int ib_find_cached_gid(struct ib_device *device, - const union ib_gid *gid, - enum ib_gid_type gid_type, - struct net_device *ndev, - u8 *port_num, - u16 *index); - -int ib_find_cached_gid_by_port(struct ib_device *device, - const union ib_gid *gid, - enum ib_gid_type gid_type, - u8 port_num, - struct net_device *ndev, - u16 *index); +int rdma_query_gid(struct ib_device *device, u8 port_num, int index, + union ib_gid *gid); +const struct ib_gid_attr *rdma_find_gid(struct ib_device *device, + const union ib_gid *gid, + enum ib_gid_type gid_type, + struct net_device *ndev); +const struct ib_gid_attr *rdma_find_gid_by_port(struct ib_device *ib_dev, + const union ib_gid *gid, + enum ib_gid_type gid_type, + u8 port, + struct net_device *ndev); +const struct ib_gid_attr *rdma_find_gid_by_filter( + struct ib_device *device, const union ib_gid *gid, u8 port_num, + bool (*filter)(const union ib_gid *gid, const struct ib_gid_attr *, + void *), + void *context); -int ib_find_gid_by_filter(struct ib_device *device, - const union ib_gid *gid, - u8 port_num, - bool (*filter)(const union ib_gid *gid, - const struct ib_gid_attr *, - void *), - void *context, u16 *index); /** * ib_get_cached_pkey - Returns a cached PKey table entry * @device: The device to query. @@ -150,4 +128,33 @@ int ib_get_cached_port_state(struct ib_device *device, enum ib_port_state *port_active); bool rdma_is_zero_gid(const union ib_gid *gid); +const struct ib_gid_attr *rdma_get_gid_attr(struct ib_device *device, + u8 port_num, int index); +void rdma_put_gid_attr(const struct ib_gid_attr *attr); +void rdma_hold_gid_attr(const struct ib_gid_attr *attr); + +/* + * This is to be removed. It only exists to make merging rdma and smc simpler. + */ +static inline __deprecated int ib_query_gid(struct ib_device *device, + u8 port_num, int index, + union ib_gid *gid, + struct ib_gid_attr *attr_out) +{ + const struct ib_gid_attr *attr; + + memset(attr_out, 0, sizeof(*attr_out)); + attr = rdma_get_gid_attr(device, port_num, index); + if (IS_ERR(attr)) + return PTR_ERR(attr); + + if (attr->ndev) + dev_hold(attr->ndev); + *attr_out = *attr; + + rdma_put_gid_attr(attr); + + return 0; +} + #endif /* _IB_CACHE_H */ diff --git a/include/rdma/ib_cm.h b/include/rdma/ib_cm.h index 7979cb04f529..c10f4b5ea8ab 100644 --- a/include/rdma/ib_cm.h +++ b/include/rdma/ib_cm.h @@ -120,6 +120,13 @@ struct ib_cm_req_event_param { struct sa_path_rec *primary_path; struct sa_path_rec *alternate_path; + /* + * SGID attribute of the primary path. Currently only + * useful for RoCE. Alternate path GID attributes + * are not yet supported. + */ + const struct ib_gid_attr *ppath_sgid_attr; + __be64 remote_ca_guid; u32 remote_qkey; u32 remote_qpn; @@ -226,6 +233,12 @@ struct ib_cm_apr_event_param { struct ib_cm_sidr_req_event_param { struct ib_cm_id *listen_id; __be64 service_id; + + /* + * SGID attribute of the request. Currently only + * useful for RoCE. + */ + const struct ib_gid_attr *sgid_attr; /* P_Key that was used by the GMP's BTH header */ u16 bth_pkey; u8 port; @@ -246,6 +259,7 @@ struct ib_cm_sidr_rep_event_param { u32 qkey; u32 qpn; void *info; + const struct ib_gid_attr *sgid_attr; u8 info_len; }; @@ -297,7 +311,7 @@ struct ib_cm_event { * destroy the @cm_id after the callback completes. */ typedef int (*ib_cm_handler)(struct ib_cm_id *cm_id, - struct ib_cm_event *event); + const struct ib_cm_event *event); struct ib_cm_id { ib_cm_handler cm_handler; @@ -365,6 +379,7 @@ struct ib_cm_id *ib_cm_insert_listen(struct ib_device *device, struct ib_cm_req_param { struct sa_path_rec *primary_path; struct sa_path_rec *alternate_path; + const struct ib_gid_attr *ppath_sgid_attr; __be64 service_id; u32 qp_num; enum ib_qp_type qp_type; @@ -566,6 +581,7 @@ int ib_send_cm_apr(struct ib_cm_id *cm_id, struct ib_cm_sidr_req_param { struct sa_path_rec *path; + const struct ib_gid_attr *sgid_attr; __be64 service_id; int timeout_ms; const void *private_data; diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h index 2f4f1768ded4..f6ba366051c7 100644 --- a/include/rdma/ib_mad.h +++ b/include/rdma/ib_mad.h @@ -262,6 +262,39 @@ struct ib_class_port_info { __be32 trap_qkey; }; +/* PortInfo CapabilityMask */ +enum ib_port_capability_mask_bits { + IB_PORT_SM = 1 << 1, + IB_PORT_NOTICE_SUP = 1 << 2, + IB_PORT_TRAP_SUP = 1 << 3, + IB_PORT_OPT_IPD_SUP = 1 << 4, + IB_PORT_AUTO_MIGR_SUP = 1 << 5, + IB_PORT_SL_MAP_SUP = 1 << 6, + IB_PORT_MKEY_NVRAM = 1 << 7, + IB_PORT_PKEY_NVRAM = 1 << 8, + IB_PORT_LED_INFO_SUP = 1 << 9, + IB_PORT_SM_DISABLED = 1 << 10, + IB_PORT_SYS_IMAGE_GUID_SUP = 1 << 11, + IB_PORT_PKEY_SW_EXT_PORT_TRAP_SUP = 1 << 12, + IB_PORT_EXTENDED_SPEEDS_SUP = 1 << 14, + IB_PORT_CM_SUP = 1 << 16, + IB_PORT_SNMP_TUNNEL_SUP = 1 << 17, + IB_PORT_REINIT_SUP = 1 << 18, + IB_PORT_DEVICE_MGMT_SUP = 1 << 19, + IB_PORT_VENDOR_CLASS_SUP = 1 << 20, + IB_PORT_DR_NOTICE_SUP = 1 << 21, + IB_PORT_CAP_MASK_NOTICE_SUP = 1 << 22, + IB_PORT_BOOT_MGMT_SUP = 1 << 23, + IB_PORT_LINK_LATENCY_SUP = 1 << 24, + IB_PORT_CLIENT_REG_SUP = 1 << 25, + IB_PORT_OTHER_LOCAL_CHANGES_SUP = 1 << 26, + IB_PORT_LINK_SPEED_WIDTH_TABLE_SUP = 1 << 27, + IB_PORT_VENDOR_SPECIFIC_MADS_TABLE_SUP = 1 << 28, + IB_PORT_MCAST_PKEY_TRAP_SUPPRESSION_SUP = 1 << 29, + IB_PORT_MCAST_FDB_TOP_SUP = 1 << 30, + IB_PORT_HIERARCHY_INFO_SUP = 1ULL << 31, +}; + #define OPA_CLASS_PORT_INFO_PR_SUPPORT BIT(26) struct opa_class_port_info { diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h index bacb144f7780..b6ddf2a1b9d8 100644 --- a/include/rdma/ib_sa.h +++ b/include/rdma/ib_sa.h @@ -172,12 +172,7 @@ struct sa_path_rec_ib { */ struct sa_path_rec_roce { bool route_resolved; - u8 dmac[ETH_ALEN]; - /* ignored in IB */ - int ifindex; - /* ignored in IB */ - struct net *net; - + u8 dmac[ETH_ALEN]; }; struct sa_path_rec_opa { @@ -556,13 +551,10 @@ int ib_init_ah_from_mcmember(struct ib_device *device, u8 port_num, enum ib_gid_type gid_type, struct rdma_ah_attr *ah_attr); -/** - * ib_init_ah_attr_from_path - Initialize address handle attributes based on - * an SA path record. - */ int ib_init_ah_attr_from_path(struct ib_device *device, u8 port_num, struct sa_path_rec *rec, - struct rdma_ah_attr *ah_attr); + struct rdma_ah_attr *ah_attr, + const struct ib_gid_attr *sgid_attr); /** * ib_sa_pack_path - Conert a path record from struct ib_sa_path_rec @@ -667,45 +659,10 @@ static inline void sa_path_set_dmac_zero(struct sa_path_rec *rec) eth_zero_addr(rec->roce.dmac); } -static inline void sa_path_set_ifindex(struct sa_path_rec *rec, int ifindex) -{ - if (sa_path_is_roce(rec)) - rec->roce.ifindex = ifindex; -} - -static inline void sa_path_set_ndev(struct sa_path_rec *rec, struct net *net) -{ - if (sa_path_is_roce(rec)) - rec->roce.net = net; -} - static inline u8 *sa_path_get_dmac(struct sa_path_rec *rec) { if (sa_path_is_roce(rec)) return rec->roce.dmac; return NULL; } - -static inline int sa_path_get_ifindex(struct sa_path_rec *rec) -{ - if (sa_path_is_roce(rec)) - return rec->roce.ifindex; - return 0; -} - -static inline struct net *sa_path_get_ndev(struct sa_path_rec *rec) -{ - if (sa_path_is_roce(rec)) - return rec->roce.net; - return NULL; -} - -static inline struct net_device *ib_get_ndev_from_path(struct sa_path_rec *rec) -{ - return sa_path_get_ndev(rec) ? - dev_get_by_index(sa_path_get_ndev(rec), - sa_path_get_ifindex(rec)) - : NULL; -} - #endif /* IB_SA_H */ diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 6c003995347a..e950c2a68f06 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -94,6 +94,7 @@ enum ib_gid_type { struct ib_gid_attr { struct net_device *ndev; struct ib_device *device; + union ib_gid gid; enum ib_gid_type gid_type; u16 index; u8 port_num; @@ -148,13 +149,13 @@ static inline enum ib_gid_type ib_network_to_gid_type(enum rdma_network_type net return IB_GID_TYPE_IB; } -static inline enum rdma_network_type ib_gid_to_network_type(enum ib_gid_type gid_type, - union ib_gid *gid) +static inline enum rdma_network_type +rdma_gid_attr_network_type(const struct ib_gid_attr *attr) { - if (gid_type == IB_GID_TYPE_IB) + if (attr->gid_type == IB_GID_TYPE_IB) return RDMA_NETWORK_IB; - if (ipv6_addr_v4mapped((struct in6_addr *)gid)) + if (ipv6_addr_v4mapped((struct in6_addr *)&attr->gid)) return RDMA_NETWORK_IPV4; else return RDMA_NETWORK_IPV6; @@ -344,7 +345,8 @@ struct ib_device_attr { int max_qp; int max_qp_wr; u64 device_cap_flags; - int max_sge; + int max_send_sge; + int max_recv_sge; int max_sge_rd; int max_cq; int max_cqe; @@ -430,33 +432,6 @@ enum ib_port_state { IB_PORT_ACTIVE_DEFER = 5 }; -enum ib_port_cap_flags { - IB_PORT_SM = 1 << 1, - IB_PORT_NOTICE_SUP = 1 << 2, - IB_PORT_TRAP_SUP = 1 << 3, - IB_PORT_OPT_IPD_SUP = 1 << 4, - IB_PORT_AUTO_MIGR_SUP = 1 << 5, - IB_PORT_SL_MAP_SUP = 1 << 6, - IB_PORT_MKEY_NVRAM = 1 << 7, - IB_PORT_PKEY_NVRAM = 1 << 8, - IB_PORT_LED_INFO_SUP = 1 << 9, - IB_PORT_SM_DISABLED = 1 << 10, - IB_PORT_SYS_IMAGE_GUID_SUP = 1 << 11, - IB_PORT_PKEY_SW_EXT_PORT_TRAP_SUP = 1 << 12, - IB_PORT_EXTENDED_SPEEDS_SUP = 1 << 14, - IB_PORT_CM_SUP = 1 << 16, - IB_PORT_SNMP_TUNNEL_SUP = 1 << 17, - IB_PORT_REINIT_SUP = 1 << 18, - IB_PORT_DEVICE_MGMT_SUP = 1 << 19, - IB_PORT_VENDOR_CLASS_SUP = 1 << 20, - IB_PORT_DR_NOTICE_SUP = 1 << 21, - IB_PORT_CAP_MASK_NOTICE_SUP = 1 << 22, - IB_PORT_BOOT_MGMT_SUP = 1 << 23, - IB_PORT_LINK_LATENCY_SUP = 1 << 24, - IB_PORT_CLIENT_REG_SUP = 1 << 25, - IB_PORT_IP_BASED_GIDS = 1 << 26, -}; - enum ib_port_width { IB_WIDTH_1X = 1, IB_WIDTH_4X = 2, @@ -554,6 +529,7 @@ static inline struct rdma_hw_stats *rdma_alloc_hw_stats_struct( #define RDMA_CORE_CAP_AF_IB 0x00001000 #define RDMA_CORE_CAP_ETH_AH 0x00002000 #define RDMA_CORE_CAP_OPA_AH 0x00004000 +#define RDMA_CORE_CAP_IB_GRH_REQUIRED 0x00008000 /* Protocol 0xFFF00000 */ #define RDMA_CORE_CAP_PROT_IB 0x00100000 @@ -563,6 +539,10 @@ static inline struct rdma_hw_stats *rdma_alloc_hw_stats_struct( #define RDMA_CORE_CAP_PROT_RAW_PACKET 0x01000000 #define RDMA_CORE_CAP_PROT_USNIC 0x02000000 +#define RDMA_CORE_PORT_IB_GRH_REQUIRED (RDMA_CORE_CAP_IB_GRH_REQUIRED \ + | RDMA_CORE_CAP_PROT_ROCE \ + | RDMA_CORE_CAP_PROT_ROCE_UDP_ENCAP) + #define RDMA_CORE_PORT_IBA_IB (RDMA_CORE_CAP_PROT_IB \ | RDMA_CORE_CAP_IB_MAD \ | RDMA_CORE_CAP_IB_SMI \ @@ -595,6 +575,8 @@ struct ib_port_attr { enum ib_mtu max_mtu; enum ib_mtu active_mtu; int gid_tbl_len; + unsigned int ip_gids:1; + /* This is the value from PortInfo CapabilityMask, defined by IBA */ u32 port_cap_flags; u32 max_msg_sz; u32 bad_pkey_cntr; @@ -610,7 +592,6 @@ struct ib_port_attr { u8 active_width; u8 active_speed; u8 phys_state; - bool grh_required; }; enum ib_device_modify_flags { @@ -689,6 +670,7 @@ struct ib_event_handler { } while (0) struct ib_global_route { + const struct ib_gid_attr *sgid_attr; union ib_gid dgid; u32 flow_label; u8 sgid_index; @@ -1370,7 +1352,7 @@ struct ib_rdma_wr { u32 rkey; }; -static inline struct ib_rdma_wr *rdma_wr(struct ib_send_wr *wr) +static inline const struct ib_rdma_wr *rdma_wr(const struct ib_send_wr *wr) { return container_of(wr, struct ib_rdma_wr, wr); } @@ -1385,7 +1367,7 @@ struct ib_atomic_wr { u32 rkey; }; -static inline struct ib_atomic_wr *atomic_wr(struct ib_send_wr *wr) +static inline const struct ib_atomic_wr *atomic_wr(const struct ib_send_wr *wr) { return container_of(wr, struct ib_atomic_wr, wr); } @@ -1402,7 +1384,7 @@ struct ib_ud_wr { u8 port_num; /* valid for DR SMPs on switch only */ }; -static inline struct ib_ud_wr *ud_wr(struct ib_send_wr *wr) +static inline const struct ib_ud_wr *ud_wr(const struct ib_send_wr *wr) { return container_of(wr, struct ib_ud_wr, wr); } @@ -1414,7 +1396,7 @@ struct ib_reg_wr { int access; }; -static inline struct ib_reg_wr *reg_wr(struct ib_send_wr *wr) +static inline const struct ib_reg_wr *reg_wr(const struct ib_send_wr *wr) { return container_of(wr, struct ib_reg_wr, wr); } @@ -1427,7 +1409,8 @@ struct ib_sig_handover_wr { struct ib_sge *prot; }; -static inline struct ib_sig_handover_wr *sig_handover_wr(struct ib_send_wr *wr) +static inline const struct ib_sig_handover_wr * +sig_handover_wr(const struct ib_send_wr *wr) { return container_of(wr, struct ib_sig_handover_wr, wr); } @@ -1443,14 +1426,16 @@ struct ib_recv_wr { }; enum ib_access_flags { - IB_ACCESS_LOCAL_WRITE = 1, - IB_ACCESS_REMOTE_WRITE = (1<<1), - IB_ACCESS_REMOTE_READ = (1<<2), - IB_ACCESS_REMOTE_ATOMIC = (1<<3), - IB_ACCESS_MW_BIND = (1<<4), - IB_ZERO_BASED = (1<<5), - IB_ACCESS_ON_DEMAND = (1<<6), - IB_ACCESS_HUGETLB = (1<<7), + IB_ACCESS_LOCAL_WRITE = IB_UVERBS_ACCESS_LOCAL_WRITE, + IB_ACCESS_REMOTE_WRITE = IB_UVERBS_ACCESS_REMOTE_WRITE, + IB_ACCESS_REMOTE_READ = IB_UVERBS_ACCESS_REMOTE_READ, + IB_ACCESS_REMOTE_ATOMIC = IB_UVERBS_ACCESS_REMOTE_ATOMIC, + IB_ACCESS_MW_BIND = IB_UVERBS_ACCESS_MW_BIND, + IB_ZERO_BASED = IB_UVERBS_ACCESS_ZERO_BASED, + IB_ACCESS_ON_DEMAND = IB_UVERBS_ACCESS_ON_DEMAND, + IB_ACCESS_HUGETLB = IB_UVERBS_ACCESS_HUGETLB, + + IB_ACCESS_SUPPORTED = ((IB_ACCESS_HUGETLB << 1) - 1) }; /* @@ -1473,14 +1458,17 @@ struct ib_fmr_attr { struct ib_umem; enum rdma_remove_reason { - /* Userspace requested uobject deletion. Call could fail */ + /* + * Userspace requested uobject deletion or initial try + * to remove uobject via cleanup. Call could fail + */ RDMA_REMOVE_DESTROY, /* Context deletion. This call should delete the actual object itself */ RDMA_REMOVE_CLOSE, /* Driver is being hot-unplugged. This call should delete the actual object itself */ RDMA_REMOVE_DRIVER_REMOVE, - /* Context is being cleaned-up, but commit was just completed */ - RDMA_REMOVE_DURING_CLEANUP, + /* uobj is being cleaned-up before being committed */ + RDMA_REMOVE_ABORT, }; struct ib_rdmacg_object { @@ -1492,14 +1480,14 @@ struct ib_rdmacg_object { struct ib_ucontext { struct ib_device *device; struct ib_uverbs_file *ufile; + /* + * 'closing' can be read by the driver only during a destroy callback, + * it is set when we are closing the file descriptor and indicates + * that mm_sem may be locked. + */ int closing; - /* locking the uobjects_list */ - struct mutex uobjects_lock; - struct list_head uobjects; - /* protects cleanup process from other actions */ - struct rw_semaphore cleanup_rwsem; - enum rdma_remove_reason cleanup_reason; + bool cleanup_retryable; struct pid *tgid; #ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING @@ -1524,6 +1512,9 @@ struct ib_ucontext { struct ib_uobject { u64 user_handle; /* handle given to us by userspace */ + /* ufile & ucontext owning this object */ + struct ib_uverbs_file *ufile; + /* FIXME, save memory: ufile->context == context */ struct ib_ucontext *context; /* associated user context */ void *object; /* containing object */ struct list_head list; /* link to context's list */ @@ -1533,13 +1524,7 @@ struct ib_uobject { atomic_t usecnt; /* protects exclusive access */ struct rcu_head rcu; /* kfree_rcu() overhead */ - const struct uverbs_obj_type *type; -}; - -struct ib_uobject_file { - struct ib_uobject uobj; - /* ufile contains the lock between context release and file close */ - struct ib_uverbs_file *ufile; + const struct uverbs_api_object *uapi_object; }; struct ib_udata { @@ -1578,6 +1563,7 @@ struct ib_ah { struct ib_device *device; struct ib_pd *pd; struct ib_uobject *uobject; + const struct ib_gid_attr *sgid_attr; enum rdma_ah_attr_type type; }; @@ -1776,6 +1762,9 @@ struct ib_qp { struct ib_uobject *uobject; void (*event_handler)(struct ib_event *, void *); void *qp_context; + /* sgid_attrs associated with the AV's */ + const struct ib_gid_attr *av_sgid_attr; + const struct ib_gid_attr *alt_path_sgid_attr; u32 qp_num; u32 max_write_sge; u32 max_read_sge; @@ -2098,6 +2087,7 @@ struct ib_flow_attr { struct ib_flow { struct ib_qp *qp; + struct ib_device *device; struct ib_uobject *uobject; }; @@ -2213,7 +2203,11 @@ struct rdma_netdev { struct ib_device *hca; u8 port_num; - /* cleanup function must be specified */ + /* + * cleanup function must be specified. + * FIXME: This is only used for OPA_VNIC and that usage should be + * removed too. + */ void (*free_rdma_netdev)(struct net_device *netdev); /* control functions */ @@ -2242,11 +2236,6 @@ struct ib_counters { atomic_t usecnt; }; -enum ib_read_counters_flags { - /* prefer read values from driver cache */ - IB_READ_COUNTERS_ATTR_PREFER_CACHED = 1 << 0, -}; - struct ib_counters_read_attr { u64 *counters_buff; u32 ncounters; @@ -2341,8 +2330,7 @@ struct ib_device { * concurrently for different ports. This function is only called when * roce_gid_table is used. */ - int (*add_gid)(const union ib_gid *gid, - const struct ib_gid_attr *attr, + int (*add_gid)(const struct ib_gid_attr *attr, void **context); /* When calling del_gid, the HW vendor's driver should delete the * gid of device @device at gid index gid_index of port port_num @@ -2389,8 +2377,8 @@ struct ib_device { struct ib_srq_attr *srq_attr); int (*destroy_srq)(struct ib_srq *srq); int (*post_srq_recv)(struct ib_srq *srq, - struct ib_recv_wr *recv_wr, - struct ib_recv_wr **bad_recv_wr); + const struct ib_recv_wr *recv_wr, + const struct ib_recv_wr **bad_recv_wr); struct ib_qp * (*create_qp)(struct ib_pd *pd, struct ib_qp_init_attr *qp_init_attr, struct ib_udata *udata); @@ -2404,11 +2392,11 @@ struct ib_device { struct ib_qp_init_attr *qp_init_attr); int (*destroy_qp)(struct ib_qp *qp); int (*post_send)(struct ib_qp *qp, - struct ib_send_wr *send_wr, - struct ib_send_wr **bad_send_wr); + const struct ib_send_wr *send_wr, + const struct ib_send_wr **bad_send_wr); int (*post_recv)(struct ib_qp *qp, - struct ib_recv_wr *recv_wr, - struct ib_recv_wr **bad_recv_wr); + const struct ib_recv_wr *recv_wr, + const struct ib_recv_wr **bad_recv_wr); struct ib_cq * (*create_cq)(struct ib_device *device, const struct ib_cq_init_attr *attr, struct ib_ucontext *context, @@ -2592,7 +2580,7 @@ struct ib_device { const struct cpumask *(*get_vector_affinity)(struct ib_device *ibdev, int comp_vector); - struct uverbs_root_spec *specs_root; + const struct uverbs_object_tree_def *const *driver_specs; enum rdma_driver_id driver_id; }; @@ -2679,6 +2667,46 @@ static inline bool ib_is_udata_cleared(struct ib_udata *udata, } /** + * ib_is_destroy_retryable - Check whether the uobject destruction + * is retryable. + * @ret: The initial destruction return code + * @why: remove reason + * @uobj: The uobject that is destroyed + * + * This function is a helper function that IB layer and low-level drivers + * can use to consider whether the destruction of the given uobject is + * retry-able. + * It checks the original return code, if it wasn't success the destruction + * is retryable according to the ucontext state (i.e. cleanup_retryable) and + * the remove reason. (i.e. why). + * Must be called with the object locked for destroy. + */ +static inline bool ib_is_destroy_retryable(int ret, enum rdma_remove_reason why, + struct ib_uobject *uobj) +{ + return ret && (why == RDMA_REMOVE_DESTROY || + uobj->context->cleanup_retryable); +} + +/** + * ib_destroy_usecnt - Called during destruction to check the usecnt + * @usecnt: The usecnt atomic + * @why: remove reason + * @uobj: The uobject that is destroyed + * + * Non-zero usecnts will block destruction unless destruction was triggered by + * a ucontext cleanup. + */ +static inline int ib_destroy_usecnt(atomic_t *usecnt, + enum rdma_remove_reason why, + struct ib_uobject *uobj) +{ + if (atomic_read(usecnt) && ib_is_destroy_retryable(-EBUSY, why, uobj)) + return -EBUSY; + return 0; +} + +/** * ib_modify_qp_is_ok - Check that the supplied attribute mask * contains all required attributes and no attributes not allowed for * the given QP state transition. @@ -2755,6 +2783,13 @@ static inline int rdma_is_port_valid(const struct ib_device *device, port <= rdma_end_port(device)); } +static inline bool rdma_is_grh_required(const struct ib_device *device, + u8 port_num) +{ + return device->port_immutable[port_num].core_cap_flags & + RDMA_CORE_PORT_IB_GRH_REQUIRED; +} + static inline bool rdma_protocol_ib(const struct ib_device *device, u8 port_num) { return device->port_immutable[port_num].core_cap_flags & RDMA_CORE_CAP_PROT_IB; @@ -3046,10 +3081,6 @@ static inline bool rdma_cap_read_inv(struct ib_device *dev, u32 port_num) return rdma_protocol_iwarp(dev, port_num); } -int ib_query_gid(struct ib_device *device, - u8 port_num, int index, union ib_gid *gid, - struct ib_gid_attr *attr); - int ib_set_vf_link_state(struct ib_device *device, int vf, u8 port, int state); int ib_get_vf_config(struct ib_device *device, int vf, u8 port, @@ -3148,6 +3179,13 @@ int ib_get_rdma_header_version(const union rdma_network_hdr *hdr); * ignored unless the work completion indicates that the GRH is valid. * @ah_attr: Returned attributes that can be used when creating an address * handle for replying to the message. + * When ib_init_ah_attr_from_wc() returns success, + * (a) for IB link layer it optionally contains a reference to SGID attribute + * when GRH is present for IB link layer. + * (b) for RoCE link layer it contains a reference to SGID attribute. + * User must invoke rdma_cleanup_ah_attr_gid_attr() to release reference to SGID + * attributes which are initialized using ib_init_ah_attr_from_wc(). + * */ int ib_init_ah_attr_from_wc(struct ib_device *device, u8 port_num, const struct ib_wc *wc, const struct ib_grh *grh, @@ -3247,10 +3285,12 @@ int ib_destroy_srq(struct ib_srq *srq); * the work request that failed to be posted on the QP. */ static inline int ib_post_srq_recv(struct ib_srq *srq, - struct ib_recv_wr *recv_wr, - struct ib_recv_wr **bad_recv_wr) + const struct ib_recv_wr *recv_wr, + const struct ib_recv_wr **bad_recv_wr) { - return srq->device->post_srq_recv(srq, recv_wr, bad_recv_wr); + const struct ib_recv_wr *dummy; + + return srq->device->post_srq_recv(srq, recv_wr, bad_recv_wr ? : &dummy); } /** @@ -3348,10 +3388,12 @@ int ib_close_qp(struct ib_qp *qp); * earlier work requests in the list. */ static inline int ib_post_send(struct ib_qp *qp, - struct ib_send_wr *send_wr, - struct ib_send_wr **bad_send_wr) + const struct ib_send_wr *send_wr, + const struct ib_send_wr **bad_send_wr) { - return qp->device->post_send(qp, send_wr, bad_send_wr); + const struct ib_send_wr *dummy; + + return qp->device->post_send(qp, send_wr, bad_send_wr ? : &dummy); } /** @@ -3363,10 +3405,12 @@ static inline int ib_post_send(struct ib_qp *qp, * the work request that failed to be posted on the QP. */ static inline int ib_post_recv(struct ib_qp *qp, - struct ib_recv_wr *recv_wr, - struct ib_recv_wr **bad_recv_wr) + const struct ib_recv_wr *recv_wr, + const struct ib_recv_wr **bad_recv_wr) { - return qp->device->post_recv(qp, recv_wr, bad_recv_wr); + const struct ib_recv_wr *dummy; + + return qp->device->post_recv(qp, recv_wr, bad_recv_wr ? : &dummy); } struct ib_cq *__ib_alloc_cq(struct ib_device *dev, void *private, @@ -3801,10 +3845,6 @@ struct ib_xrcd *__ib_alloc_xrcd(struct ib_device *device, const char *caller); */ int ib_dealloc_xrcd(struct ib_xrcd *xrcd); -struct ib_flow *ib_create_flow(struct ib_qp *qp, - struct ib_flow_attr *flow_attr, int domain); -int ib_destroy_flow(struct ib_flow *flow_id); - static inline int ib_check_mr_access(int flags) { /* @@ -4033,8 +4073,19 @@ static inline void rdma_ah_set_grh(struct rdma_ah_attr *attr, grh->sgid_index = sgid_index; grh->hop_limit = hop_limit; grh->traffic_class = traffic_class; + grh->sgid_attr = NULL; } +void rdma_destroy_ah_attr(struct rdma_ah_attr *ah_attr); +void rdma_move_grh_sgid_attr(struct rdma_ah_attr *attr, union ib_gid *dgid, + u32 flow_label, u8 hop_limit, u8 traffic_class, + const struct ib_gid_attr *sgid_attr); +void rdma_copy_ah_attr(struct rdma_ah_attr *dest, + const struct rdma_ah_attr *src); +void rdma_replace_ah_attr(struct rdma_ah_attr *old, + const struct rdma_ah_attr *new); +void rdma_move_ah_attr(struct rdma_ah_attr *dest, struct rdma_ah_attr *src); + /** * rdma_ah_find_type - Return address handle type. * @@ -4102,6 +4153,20 @@ ib_get_vector_affinity(struct ib_device *device, int comp_vector) } +static inline void ib_set_flow(struct ib_uobject *uobj, struct ib_flow *ibflow, + struct ib_qp *qp, struct ib_device *device) +{ + uobj->object = ibflow; + ibflow->uobject = uobj; + + if (qp) { + atomic_inc(&qp->usecnt); + ibflow->qp = qp; + } + + ibflow->device = device; +} + /** * rdma_roce_rescan_device - Rescan all of the network devices in the system * and add their gids, as needed, to the relevant RoCE devices. @@ -4110,4 +4175,8 @@ ib_get_vector_affinity(struct ib_device *device, int comp_vector) */ void rdma_roce_rescan_device(struct ib_device *ibdev); +struct ib_ucontext *ib_uverbs_get_ucontext(struct ib_uverbs_file *ufile); + +int uverbs_destroy_def_handler(struct ib_uverbs_file *file, + struct uverbs_attr_bundle *attrs); #endif /* IB_VERBS_H */ diff --git a/include/rdma/opa_addr.h b/include/rdma/opa_addr.h index 2bbb7a67e643..66d4393d339c 100644 --- a/include/rdma/opa_addr.h +++ b/include/rdma/opa_addr.h @@ -120,7 +120,7 @@ static inline bool rdma_is_valid_unicast_lid(struct rdma_ah_attr *attr) if (attr->type == RDMA_AH_ATTR_TYPE_IB) { if (!rdma_ah_get_dlid(attr) || rdma_ah_get_dlid(attr) >= - be32_to_cpu(IB_MULTICAST_LID_BASE)) + be16_to_cpu(IB_MULTICAST_LID_BASE)) return false; } else if (attr->type == RDMA_AH_ATTR_TYPE_OPA) { if (!rdma_ah_get_dlid(attr) || diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h index c5c1435c129a..5d71a7f51a9f 100644 --- a/include/rdma/rdma_cm.h +++ b/include/rdma/rdma_cm.h @@ -192,7 +192,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr); * @timeout_ms: Time to wait for resolution to complete. */ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, - struct sockaddr *dst_addr, int timeout_ms); + const struct sockaddr *dst_addr, int timeout_ms); /** * rdma_resolve_route - Resolve the RDMA address bound to the RDMA identifier diff --git a/include/rdma/rdmavt_qp.h b/include/rdma/rdmavt_qp.h index 1145a4c154b2..927f6d5b6d0f 100644 --- a/include/rdma/rdmavt_qp.h +++ b/include/rdma/rdmavt_qp.h @@ -2,7 +2,7 @@ #define DEF_RDMAVT_INCQP_H /* - * Copyright(c) 2016, 2017 Intel Corporation. + * Copyright(c) 2016 - 2018 Intel Corporation. * * This file is provided under a dual BSD/GPLv2 license. When using or * redistributing this file, you may do so under either license. @@ -91,6 +91,7 @@ * RVT_S_WAIT_ACK - waiting for an ACK packet before sending more requests * RVT_S_SEND_ONE - send one packet, request ACK, then wait for ACK * RVT_S_ECN - a BECN was queued to the send engine + * RVT_S_MAX_BIT_MASK - The max bit that can be used by rdmavt */ #define RVT_S_SIGNAL_REQ_WR 0x0001 #define RVT_S_BUSY 0x0002 @@ -103,23 +104,26 @@ #define RVT_S_WAIT_SSN_CREDIT 0x0100 #define RVT_S_WAIT_DMA 0x0200 #define RVT_S_WAIT_PIO 0x0400 -#define RVT_S_WAIT_PIO_DRAIN 0x0800 -#define RVT_S_WAIT_TX 0x1000 -#define RVT_S_WAIT_DMA_DESC 0x2000 -#define RVT_S_WAIT_KMEM 0x4000 -#define RVT_S_WAIT_PSN 0x8000 -#define RVT_S_WAIT_ACK 0x10000 -#define RVT_S_SEND_ONE 0x20000 -#define RVT_S_UNLIMITED_CREDIT 0x40000 -#define RVT_S_AHG_VALID 0x80000 -#define RVT_S_AHG_CLEAR 0x100000 -#define RVT_S_ECN 0x200000 +#define RVT_S_WAIT_TX 0x0800 +#define RVT_S_WAIT_DMA_DESC 0x1000 +#define RVT_S_WAIT_KMEM 0x2000 +#define RVT_S_WAIT_PSN 0x4000 +#define RVT_S_WAIT_ACK 0x8000 +#define RVT_S_SEND_ONE 0x10000 +#define RVT_S_UNLIMITED_CREDIT 0x20000 +#define RVT_S_ECN 0x40000 +#define RVT_S_MAX_BIT_MASK 0x800000 + +/* + * Drivers should use s_flags starting with bit 31 down to the bit next to + * RVT_S_MAX_BIT_MASK + */ /* * Wait flags that would prevent any packet type from being sent. */ #define RVT_S_ANY_WAIT_IO \ - (RVT_S_WAIT_PIO | RVT_S_WAIT_PIO_DRAIN | RVT_S_WAIT_TX | \ + (RVT_S_WAIT_PIO | RVT_S_WAIT_TX | \ RVT_S_WAIT_DMA_DESC | RVT_S_WAIT_KMEM) /* diff --git a/include/rdma/uverbs_ioctl.h b/include/rdma/uverbs_ioctl.h index bd6bba3a6e04..9e997c3c2f04 100644 --- a/include/rdma/uverbs_ioctl.h +++ b/include/rdma/uverbs_ioctl.h @@ -61,103 +61,195 @@ enum uverbs_obj_access { UVERBS_ACCESS_DESTROY }; -enum { - UVERBS_ATTR_SPEC_F_MANDATORY = 1U << 0, - /* Support extending attributes by length, validate all unknown size == zero */ - UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO = 1U << 1, -}; - /* Specification of a single attribute inside the ioctl message */ +/* good size 16 */ struct uverbs_attr_spec { + u8 type; + + /* + * Support extending attributes by length. Allow the user to provide + * more bytes than ptr.len, but check that everything after is zero'd + * by the user. + */ + u8 zero_trailing:1; + /* + * Valid only for PTR_IN. Allocate and copy the data inside + * the parser + */ + u8 alloc_and_copy:1; + u8 mandatory:1; + union { - /* Header shared by all following union members - to reduce space. */ - struct { - enum uverbs_attr_type type; - /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */ - u8 flags; - }; struct { - enum uverbs_attr_type type; - /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */ - u8 flags; /* Current known size to kernel */ - u16 len; + u16 len; /* User isn't allowed to provide something < min_len */ - u16 min_len; + u16 min_len; } ptr; + struct { - enum uverbs_attr_type type; - /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */ - u8 flags; /* * higher bits mean the namespace and lower bits mean * the type id within the namespace. */ - u16 obj_type; - u8 access; + u16 obj_type; + u8 access; } obj; + + struct { + u8 num_elems; + } enum_def; + } u; + + /* This weird split of the enum lets us remove some padding */ + union { struct { - enum uverbs_attr_type type; - /* Combination of bits from enum UVERBS_ATTR_SPEC_F_XXXX */ - u8 flags; - u8 num_elems; /* * The enum attribute can select one of the attributes * contained in the ids array. Currently only PTR_IN * attributes are supported in the ids array. */ - const struct uverbs_attr_spec *ids; + const struct uverbs_attr_spec *ids; } enum_def; - }; + } u2; }; -struct uverbs_attr_spec_hash { - size_t num_attrs; - unsigned long *mandatory_attrs_bitmask; - struct uverbs_attr_spec attrs[0]; +/* + * Information about the API is loaded into a radix tree. For IOCTL we start + * with a tuple of: + * object_id, attr_id, method_id + * + * Which is a 48 bit value, with most of the bits guaranteed to be zero. Based + * on the current kernel support this is compressed into 16 bit key for the + * radix tree. Since this compression is entirely internal to the kernel the + * below limits can be revised if the kernel gains additional data. + * + * With 64 leafs per node this is a 3 level radix tree. + * + * The tree encodes multiple types, and uses a scheme where OBJ_ID,0,0 returns + * the object slot, and OBJ_ID,METH_ID,0 and returns the method slot. + */ +enum uapi_radix_data { + UVERBS_API_NS_FLAG = 1U << UVERBS_ID_NS_SHIFT, + + UVERBS_API_ATTR_KEY_BITS = 6, + UVERBS_API_ATTR_KEY_MASK = GENMASK(UVERBS_API_ATTR_KEY_BITS - 1, 0), + UVERBS_API_ATTR_BKEY_LEN = (1 << UVERBS_API_ATTR_KEY_BITS) - 1, + + UVERBS_API_METHOD_KEY_BITS = 5, + UVERBS_API_METHOD_KEY_SHIFT = UVERBS_API_ATTR_KEY_BITS, + UVERBS_API_METHOD_KEY_NUM_CORE = 24, + UVERBS_API_METHOD_KEY_NUM_DRIVER = (1 << UVERBS_API_METHOD_KEY_BITS) - + UVERBS_API_METHOD_KEY_NUM_CORE, + UVERBS_API_METHOD_KEY_MASK = GENMASK( + UVERBS_API_METHOD_KEY_BITS + UVERBS_API_METHOD_KEY_SHIFT - 1, + UVERBS_API_METHOD_KEY_SHIFT), + + UVERBS_API_OBJ_KEY_BITS = 5, + UVERBS_API_OBJ_KEY_SHIFT = + UVERBS_API_METHOD_KEY_BITS + UVERBS_API_METHOD_KEY_SHIFT, + UVERBS_API_OBJ_KEY_NUM_CORE = 24, + UVERBS_API_OBJ_KEY_NUM_DRIVER = + (1 << UVERBS_API_OBJ_KEY_BITS) - UVERBS_API_OBJ_KEY_NUM_CORE, + UVERBS_API_OBJ_KEY_MASK = GENMASK(31, UVERBS_API_OBJ_KEY_SHIFT), + + /* This id guaranteed to not exist in the radix tree */ + UVERBS_API_KEY_ERR = 0xFFFFFFFF, }; -struct uverbs_attr_bundle; -struct ib_uverbs_file; +static inline __attribute_const__ u32 uapi_key_obj(u32 id) +{ + if (id & UVERBS_API_NS_FLAG) { + id &= ~UVERBS_API_NS_FLAG; + if (id >= UVERBS_API_OBJ_KEY_NUM_DRIVER) + return UVERBS_API_KEY_ERR; + id = id + UVERBS_API_OBJ_KEY_NUM_CORE; + } else { + if (id >= UVERBS_API_OBJ_KEY_NUM_CORE) + return UVERBS_API_KEY_ERR; + } -enum { - /* - * Action marked with this flag creates a context (or root for all - * objects). - */ - UVERBS_ACTION_FLAG_CREATE_ROOT = 1U << 0, -}; + return id << UVERBS_API_OBJ_KEY_SHIFT; +} -struct uverbs_method_spec { - /* Combination of bits from enum UVERBS_ACTION_FLAG_XXXX */ - u32 flags; - size_t num_buckets; - size_t num_child_attrs; - int (*handler)(struct ib_device *ib_dev, struct ib_uverbs_file *ufile, - struct uverbs_attr_bundle *ctx); - struct uverbs_attr_spec_hash *attr_buckets[0]; -}; +static inline __attribute_const__ bool uapi_key_is_object(u32 key) +{ + return (key & ~UVERBS_API_OBJ_KEY_MASK) == 0; +} -struct uverbs_method_spec_hash { - size_t num_methods; - struct uverbs_method_spec *methods[0]; -}; +static inline __attribute_const__ u32 uapi_key_ioctl_method(u32 id) +{ + if (id & UVERBS_API_NS_FLAG) { + id &= ~UVERBS_API_NS_FLAG; + if (id >= UVERBS_API_METHOD_KEY_NUM_DRIVER) + return UVERBS_API_KEY_ERR; + id = id + UVERBS_API_METHOD_KEY_NUM_CORE; + } else { + id++; + if (id >= UVERBS_API_METHOD_KEY_NUM_CORE) + return UVERBS_API_KEY_ERR; + } -struct uverbs_object_spec { - const struct uverbs_obj_type *type_attrs; - size_t num_buckets; - struct uverbs_method_spec_hash *method_buckets[0]; -}; + return id << UVERBS_API_METHOD_KEY_SHIFT; +} -struct uverbs_object_spec_hash { - size_t num_objects; - struct uverbs_object_spec *objects[0]; -}; +static inline __attribute_const__ u32 uapi_key_attr_to_method(u32 attr_key) +{ + return attr_key & + (UVERBS_API_OBJ_KEY_MASK | UVERBS_API_METHOD_KEY_MASK); +} -struct uverbs_root_spec { - size_t num_buckets; - struct uverbs_object_spec_hash *object_buckets[0]; -}; +static inline __attribute_const__ bool uapi_key_is_ioctl_method(u32 key) +{ + return (key & UVERBS_API_METHOD_KEY_MASK) != 0 && + (key & UVERBS_API_ATTR_KEY_MASK) == 0; +} + +static inline __attribute_const__ u32 uapi_key_attrs_start(u32 ioctl_method_key) +{ + /* 0 is the method slot itself */ + return ioctl_method_key + 1; +} + +static inline __attribute_const__ u32 uapi_key_attr(u32 id) +{ + /* + * The attr is designed to fit in the typical single radix tree node + * of 64 entries. Since allmost all methods have driver attributes we + * organize things so that the driver and core attributes interleave to + * reduce the length of the attributes array in typical cases. + */ + if (id & UVERBS_API_NS_FLAG) { + id &= ~UVERBS_API_NS_FLAG; + id++; + if (id >= 1 << (UVERBS_API_ATTR_KEY_BITS - 1)) + return UVERBS_API_KEY_ERR; + id = (id << 1) | 0; + } else { + if (id >= 1 << (UVERBS_API_ATTR_KEY_BITS - 1)) + return UVERBS_API_KEY_ERR; + id = (id << 1) | 1; + } + + return id; +} + +static inline __attribute_const__ bool uapi_key_is_attr(u32 key) +{ + return (key & UVERBS_API_METHOD_KEY_MASK) != 0 && + (key & UVERBS_API_ATTR_KEY_MASK) != 0; +} + +/* + * This returns a value in the range [0 to UVERBS_API_ATTR_BKEY_LEN), + * basically it undoes the reservation of 0 in the ID numbering. attr_key + * must already be masked with UVERBS_API_ATTR_KEY_MASK, or be the output of + * uapi_key_attr(). + */ +static inline __attribute_const__ u32 uapi_bkey_attr(u32 attr_key) +{ + return attr_key - 1; +} /* * ======================================= @@ -176,7 +268,7 @@ struct uverbs_method_def { u32 flags; size_t num_attrs; const struct uverbs_attr_def * const (*attrs)[]; - int (*handler)(struct ib_device *ib_dev, struct ib_uverbs_file *ufile, + int (*handler)(struct ib_uverbs_file *ufile, struct uverbs_attr_bundle *ctx); }; @@ -192,196 +284,171 @@ struct uverbs_object_tree_def { const struct uverbs_object_def * const (*objects)[]; }; -#define UA_FLAGS(_flags) .flags = _flags -#define __UVERBS_ATTR0(_id, _type, _fld, _attr, ...) \ - ((const struct uverbs_attr_def) \ - {.id = _id, .attr = {{._fld = {.type = _type, _attr, .flags = 0, } }, } }) -#define __UVERBS_ATTR1(_id, _type, _fld, _attr, _extra1, ...) \ - ((const struct uverbs_attr_def) \ - {.id = _id, .attr = {{._fld = {.type = _type, _attr, _extra1 } },} }) -#define __UVERBS_ATTR2(_id, _type, _fld, _attr, _extra1, _extra2) \ - ((const struct uverbs_attr_def) \ - {.id = _id, .attr = {{._fld = {.type = _type, _attr, _extra1, _extra2 } },} }) -#define __UVERBS_ATTR(_id, _type, _fld, _attr, _extra1, _extra2, _n, ...) \ - __UVERBS_ATTR##_n(_id, _type, _fld, _attr, _extra1, _extra2) +/* + * ======================================= + * Attribute Specifications + * ======================================= + */ -#define UVERBS_ATTR_TYPE(_type) \ - .min_len = sizeof(_type), .len = sizeof(_type) -#define UVERBS_ATTR_STRUCT(_type, _last) \ - .min_len = ((uintptr_t)(&((_type *)0)->_last + 1)), .len = sizeof(_type) #define UVERBS_ATTR_SIZE(_min_len, _len) \ - .min_len = _min_len, .len = _len + .u.ptr.min_len = _min_len, .u.ptr.len = _len + +#define UVERBS_ATTR_NO_DATA() UVERBS_ATTR_SIZE(0, 0) /* - * In new compiler, UVERBS_ATTR could be simplified by declaring it as - * [_id] = {.type = _type, .len = _len, ##__VA_ARGS__} - * But since we support older compilers too, we need the more complex code. + * Specifies a uapi structure that cannot be extended. The user must always + * supply the whole structure and nothing more. The structure must be declared + * in a header under include/uapi/rdma. */ -#define UVERBS_ATTR(_id, _type, _fld, _attr, ...) \ - __UVERBS_ATTR(_id, _type, _fld, _attr, ##__VA_ARGS__, 2, 1, 0) -#define UVERBS_ATTR_PTR_IN_SZ(_id, _len, ...) \ - UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_PTR_IN, ptr, _len, ##__VA_ARGS__) -/* If sizeof(_type) <= sizeof(u64), this will be inlined rather than a pointer */ -#define UVERBS_ATTR_PTR_IN(_id, _type, ...) \ - UVERBS_ATTR_PTR_IN_SZ(_id, _type, ##__VA_ARGS__) -#define UVERBS_ATTR_PTR_OUT_SZ(_id, _len, ...) \ - UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_PTR_OUT, ptr, _len, ##__VA_ARGS__) -#define UVERBS_ATTR_PTR_OUT(_id, _type, ...) \ - UVERBS_ATTR_PTR_OUT_SZ(_id, _type, ##__VA_ARGS__) -#define UVERBS_ATTR_ENUM_IN(_id, _enum_arr, ...) \ - UVERBS_ATTR(_id, UVERBS_ATTR_TYPE_ENUM_IN, enum_def, \ - .ids = (_enum_arr), \ - .num_elems = ARRAY_SIZE(_enum_arr), ##__VA_ARGS__) +#define UVERBS_ATTR_TYPE(_type) \ + .u.ptr.min_len = sizeof(_type), .u.ptr.len = sizeof(_type) +/* + * Specifies a uapi structure where the user must provide at least up to + * member 'last'. Anything after last and up until the end of the structure + * can be non-zero, anything longer than the end of the structure must be + * zero. The structure must be declared in a header under include/uapi/rdma. + */ +#define UVERBS_ATTR_STRUCT(_type, _last) \ + .zero_trailing = 1, \ + UVERBS_ATTR_SIZE(((uintptr_t)(&((_type *)0)->_last + 1)), \ + sizeof(_type)) +/* + * Specifies at least min_len bytes must be passed in, but the amount can be + * larger, up to the protocol maximum size. No check for zeroing is done. + */ +#define UVERBS_ATTR_MIN_SIZE(_min_len) UVERBS_ATTR_SIZE(_min_len, USHRT_MAX) + +/* Must be used in the '...' of any UVERBS_ATTR */ +#define UA_ALLOC_AND_COPY .alloc_and_copy = 1 +#define UA_MANDATORY .mandatory = 1 +#define UA_OPTIONAL .mandatory = 0 + +#define UVERBS_ATTR_IDR(_attr_id, _idr_type, _access, ...) \ + (&(const struct uverbs_attr_def){ \ + .id = _attr_id, \ + .attr = { .type = UVERBS_ATTR_TYPE_IDR, \ + .u.obj.obj_type = _idr_type, \ + .u.obj.access = _access, \ + __VA_ARGS__ } }) + +#define UVERBS_ATTR_FD(_attr_id, _fd_type, _access, ...) \ + (&(const struct uverbs_attr_def){ \ + .id = (_attr_id) + \ + BUILD_BUG_ON_ZERO((_access) != UVERBS_ACCESS_NEW && \ + (_access) != UVERBS_ACCESS_READ), \ + .attr = { .type = UVERBS_ATTR_TYPE_FD, \ + .u.obj.obj_type = _fd_type, \ + .u.obj.access = _access, \ + __VA_ARGS__ } }) + +#define UVERBS_ATTR_PTR_IN(_attr_id, _type, ...) \ + (&(const struct uverbs_attr_def){ \ + .id = _attr_id, \ + .attr = { .type = UVERBS_ATTR_TYPE_PTR_IN, \ + _type, \ + __VA_ARGS__ } }) + +#define UVERBS_ATTR_PTR_OUT(_attr_id, _type, ...) \ + (&(const struct uverbs_attr_def){ \ + .id = _attr_id, \ + .attr = { .type = UVERBS_ATTR_TYPE_PTR_OUT, \ + _type, \ + __VA_ARGS__ } }) + +/* _enum_arry should be a 'static const union uverbs_attr_spec[]' */ +#define UVERBS_ATTR_ENUM_IN(_attr_id, _enum_arr, ...) \ + (&(const struct uverbs_attr_def){ \ + .id = _attr_id, \ + .attr = { .type = UVERBS_ATTR_TYPE_ENUM_IN, \ + .u2.enum_def.ids = _enum_arr, \ + .u.enum_def.num_elems = ARRAY_SIZE(_enum_arr), \ + __VA_ARGS__ }, \ + }) /* - * In new compiler, UVERBS_ATTR_IDR (and FD) could be simplified by declaring - * it as - * {.id = _id, \ - * .attr {.type = __obj_class, \ - * .obj = {.obj_type = _idr_type, \ - * .access = _access \ - * }, ##__VA_ARGS__ } } - * But since we support older compilers too, we need the more complex code. + * An input value that is a bitwise combination of values of _enum_type. + * This permits the flag value to be passed as either a u32 or u64, it must + * be retrieved via uverbs_get_flag(). */ -#define ___UVERBS_ATTR_OBJ0(_id, _obj_class, _obj_type, _access, ...)\ - ((const struct uverbs_attr_def) \ - {.id = _id, \ - .attr = { {.obj = {.type = _obj_class, .obj_type = _obj_type, \ - .access = _access, .flags = 0 } }, } }) -#define ___UVERBS_ATTR_OBJ1(_id, _obj_class, _obj_type, _access, _flags)\ - ((const struct uverbs_attr_def) \ - {.id = _id, \ - .attr = { {.obj = {.type = _obj_class, .obj_type = _obj_type, \ - .access = _access, _flags} }, } }) -#define ___UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, _flags, \ - _n, ...) \ - ___UVERBS_ATTR_OBJ##_n(_id, _obj_class, _obj_type, _access, _flags) -#define __UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, ...) \ - ___UVERBS_ATTR_OBJ(_id, _obj_class, _obj_type, _access, \ - ##__VA_ARGS__, 1, 0) -#define UVERBS_ATTR_IDR(_id, _idr_type, _access, ...) \ - __UVERBS_ATTR_OBJ(_id, UVERBS_ATTR_TYPE_IDR, _idr_type, _access,\ - ##__VA_ARGS__) -#define UVERBS_ATTR_FD(_id, _fd_type, _access, ...) \ - __UVERBS_ATTR_OBJ(_id, UVERBS_ATTR_TYPE_FD, _fd_type, \ - (_access) + BUILD_BUG_ON_ZERO( \ - (_access) != UVERBS_ACCESS_NEW && \ - (_access) != UVERBS_ACCESS_READ), \ - ##__VA_ARGS__) -#define DECLARE_UVERBS_ATTR_SPEC(_name, ...) \ - const struct uverbs_attr_def _name = __VA_ARGS__ - -#define DECLARE_UVERBS_ENUM(_name, ...) \ - const struct uverbs_enum_spec _name = { \ - .len = ARRAY_SIZE(((struct uverbs_attr_spec[]){__VA_ARGS__})),\ - .ids = {__VA_ARGS__}, \ +#define UVERBS_ATTR_FLAGS_IN(_attr_id, _enum_type, ...) \ + UVERBS_ATTR_PTR_IN( \ + _attr_id, \ + UVERBS_ATTR_SIZE(sizeof(u32) + BUILD_BUG_ON_ZERO( \ + !sizeof(_enum_type *)), \ + sizeof(u64)), \ + __VA_ARGS__) + +/* + * This spec is used in order to pass information to the hardware driver in a + * legacy way. Every verb that could get driver specific data should get this + * spec. + */ +#define UVERBS_ATTR_UHW() \ + UVERBS_ATTR_PTR_IN(UVERBS_ATTR_UHW_IN, \ + UVERBS_ATTR_MIN_SIZE(0), \ + UA_OPTIONAL), \ + UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_UHW_OUT, \ + UVERBS_ATTR_MIN_SIZE(0), \ + UA_OPTIONAL) + +/* + * ======================================= + * Declaration helpers + * ======================================= + */ + +#define DECLARE_UVERBS_OBJECT_TREE(_name, ...) \ + static const struct uverbs_object_def *const _name##_ptr[] = { \ + __VA_ARGS__, \ + }; \ + static const struct uverbs_object_tree_def _name = { \ + .num_objects = ARRAY_SIZE(_name##_ptr), \ + .objects = &_name##_ptr, \ } -#define _UVERBS_METHOD_ATTRS_SZ(...) \ - (sizeof((const struct uverbs_attr_def * const []){__VA_ARGS__}) /\ - sizeof(const struct uverbs_attr_def *)) -#define _UVERBS_METHOD(_id, _handler, _flags, ...) \ - ((const struct uverbs_method_def) { \ - .id = _id, \ - .flags = _flags, \ - .handler = _handler, \ - .num_attrs = _UVERBS_METHOD_ATTRS_SZ(__VA_ARGS__), \ - .attrs = &(const struct uverbs_attr_def * const []){__VA_ARGS__} }) -#define DECLARE_UVERBS_METHOD(_name, _id, _handler, ...) \ - const struct uverbs_method_def _name = \ - _UVERBS_METHOD(_id, _handler, 0, ##__VA_ARGS__) -#define DECLARE_UVERBS_CTX_METHOD(_name, _id, _handler, _flags, ...) \ - const struct uverbs_method_def _name = \ - _UVERBS_METHOD(_id, _handler, \ - UVERBS_ACTION_FLAG_CREATE_ROOT, \ - ##__VA_ARGS__) -#define _UVERBS_OBJECT_METHODS_SZ(...) \ - (sizeof((const struct uverbs_method_def * const []){__VA_ARGS__}) / \ - sizeof(const struct uverbs_method_def *)) -#define _UVERBS_OBJECT(_id, _type_attrs, ...) \ - ((const struct uverbs_object_def) { \ - .id = _id, \ - .type_attrs = _type_attrs, \ - .num_methods = _UVERBS_OBJECT_METHODS_SZ(__VA_ARGS__), \ - .methods = &(const struct uverbs_method_def * const []){__VA_ARGS__} }) -#define DECLARE_UVERBS_OBJECT(_name, _id, _type_attrs, ...) \ - const struct uverbs_object_def _name = \ - _UVERBS_OBJECT(_id, _type_attrs, ##__VA_ARGS__) -#define _UVERBS_TREE_OBJECTS_SZ(...) \ - (sizeof((const struct uverbs_object_def * const []){__VA_ARGS__}) / \ - sizeof(const struct uverbs_object_def *)) -#define _UVERBS_OBJECT_TREE(...) \ - ((const struct uverbs_object_tree_def) { \ - .num_objects = _UVERBS_TREE_OBJECTS_SZ(__VA_ARGS__), \ - .objects = &(const struct uverbs_object_def * const []){__VA_ARGS__} }) -#define DECLARE_UVERBS_OBJECT_TREE(_name, ...) \ - const struct uverbs_object_tree_def _name = \ - _UVERBS_OBJECT_TREE(__VA_ARGS__) /* ================================================= * Parsing infrastructure * ================================================= */ + struct uverbs_ptr_attr { - u64 data; + /* + * If UVERBS_ATTR_SPEC_F_ALLOC_AND_COPY is set then the 'ptr' is + * used. + */ + union { + void *ptr; + u64 data; + }; u16 len; - /* Combination of bits from enum UVERBS_ATTR_F_XXXX */ - u16 flags; + u16 uattr_idx; u8 enum_id; }; struct uverbs_obj_attr { - /* pointer to the kernel descriptor -> type, access, etc */ - const struct uverbs_obj_type *type; struct ib_uobject *uobject; - /* fd or id in idr of this object */ - int id; + const struct uverbs_api_attr *attr_elm; }; struct uverbs_attr { - /* - * pointer to the user-space given attribute, in order to write the - * new uobject's id or update flags. - */ - struct ib_uverbs_attr __user *uattr; union { struct uverbs_ptr_attr ptr_attr; struct uverbs_obj_attr obj_attr; }; }; -struct uverbs_attr_bundle_hash { - /* if bit i is set, it means attrs[i] contains valid information */ - unsigned long *valid_bitmap; - size_t num_attrs; - /* - * arrays of attributes, each element corresponds to the specification - * of the attribute in the same index. - */ - struct uverbs_attr *attrs; -}; - struct uverbs_attr_bundle { - size_t num_buckets; - struct uverbs_attr_bundle_hash hash[]; + struct ib_uverbs_file *ufile; + DECLARE_BITMAP(attr_present, UVERBS_API_ATTR_BKEY_LEN); + struct uverbs_attr attrs[]; }; -static inline bool uverbs_attr_is_valid_in_hash(const struct uverbs_attr_bundle_hash *attrs_hash, - unsigned int idx) -{ - return test_bit(idx, attrs_hash->valid_bitmap); -} - static inline bool uverbs_attr_is_valid(const struct uverbs_attr_bundle *attrs_bundle, unsigned int idx) { - u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT; - - if (attrs_bundle->num_buckets <= idx_bucket) - return false; - - return uverbs_attr_is_valid_in_hash(&attrs_bundle->hash[idx_bucket], - idx & ~UVERBS_ID_NS_MASK); + return test_bit(uapi_bkey_attr(uapi_key_attr(idx)), + attrs_bundle->attr_present); } #define IS_UVERBS_COPY_ERR(_ret) ((_ret) && (_ret) != -ENOENT) @@ -389,12 +456,10 @@ static inline bool uverbs_attr_is_valid(const struct uverbs_attr_bundle *attrs_b static inline const struct uverbs_attr *uverbs_attr_get(const struct uverbs_attr_bundle *attrs_bundle, u16 idx) { - u16 idx_bucket = idx >> UVERBS_ID_NS_SHIFT; - if (!uverbs_attr_is_valid(attrs_bundle, idx)) return ERR_PTR(-ENOENT); - return &attrs_bundle->hash[idx_bucket].attrs[idx & ~UVERBS_ID_NS_MASK]; + return &attrs_bundle->attrs[uapi_bkey_attr(uapi_key_attr(idx))]; } static inline int uverbs_attr_get_enum_id(const struct uverbs_attr_bundle *attrs_bundle, @@ -431,25 +496,15 @@ static inline struct ib_uobject *uverbs_attr_get_uobject(const struct uverbs_att return attr->obj_attr.uobject; } -static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle, - size_t idx, const void *from, size_t size) +static inline int +uverbs_attr_get_len(const struct uverbs_attr_bundle *attrs_bundle, u16 idx) { const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); - u16 flags; - size_t min_size; if (IS_ERR(attr)) return PTR_ERR(attr); - min_size = min_t(size_t, attr->ptr_attr.len, size); - if (copy_to_user(u64_to_user_ptr(attr->ptr_attr.data), from, min_size)) - return -EFAULT; - - flags = attr->ptr_attr.flags | UVERBS_ATTR_F_VALID_OUTPUT; - if (put_user(flags, &attr->uattr->flags)) - return -EFAULT; - - return 0; + return attr->ptr_attr.len; } static inline bool uverbs_attr_ptr_is_inline(const struct uverbs_attr *attr) @@ -457,6 +512,18 @@ static inline bool uverbs_attr_ptr_is_inline(const struct uverbs_attr *attr) return attr->ptr_attr.len <= sizeof(attr->ptr_attr.data); } +static inline void *uverbs_attr_get_alloced_ptr( + const struct uverbs_attr_bundle *attrs_bundle, u16 idx) +{ + const struct uverbs_attr *attr = uverbs_attr_get(attrs_bundle, idx); + + if (IS_ERR(attr)) + return (void *)attr; + + return uverbs_attr_ptr_is_inline(attr) ? (void *)&attr->ptr_attr.data : + attr->ptr_attr.ptr; +} + static inline int _uverbs_copy_from(void *to, const struct uverbs_attr_bundle *attrs_bundle, size_t idx, @@ -515,54 +582,54 @@ static inline int _uverbs_copy_from_or_zero(void *to, #define uverbs_copy_from_or_zero(to, attrs_bundle, idx) \ _uverbs_copy_from_or_zero(to, attrs_bundle, idx, sizeof(*to)) -/* ================================================= - * Definitions -> Specs infrastructure - * ================================================= - */ - -/* - * uverbs_alloc_spec_tree - Merges different common and driver specific feature - * into one parsing tree that every uverbs command will be parsed upon. - * - * @num_trees: Number of trees in the array @trees. - * @trees: Array of pointers to tree root definitions to merge. Each such tree - * possibly contains objects, methods and attributes definitions. - * - * Returns: - * uverbs_root_spec *: The root of the merged parsing tree. - * On error, we return an error code. Error is checked via IS_ERR. - * - * The following merges could take place: - * a. Two trees representing the same method with different handler - * -> We take the handler of the tree that its handler != NULL - * and its index in the trees array is greater. The incentive for that - * is that developers are expected to first merge common trees and then - * merge trees that gives specialized the behaviour. - * b. Two trees representing the same object with different - * type_attrs (struct uverbs_obj_type): - * -> We take the type_attrs of the tree that its type_attr != NULL - * and its index in the trees array is greater. This could be used - * in order to override the free function, allocation size, etc. - * c. Two trees representing the same method attribute (same id but possibly - * different attributes): - * -> ERROR (-ENOENT), we believe that's not the programmer's intent. - * - * An object without any methods is considered invalid and will abort the - * function with -ENOENT error. - */ #if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS) -struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees, - const struct uverbs_object_tree_def **trees); -void uverbs_free_spec_tree(struct uverbs_root_spec *root); -#else -static inline struct uverbs_root_spec *uverbs_alloc_spec_tree(unsigned int num_trees, - const struct uverbs_object_tree_def **trees) +int uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle, + size_t idx, u64 allowed_bits); +int uverbs_get_flags32(u32 *to, const struct uverbs_attr_bundle *attrs_bundle, + size_t idx, u64 allowed_bits); +int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle, size_t idx, + const void *from, size_t size); +__malloc void *_uverbs_alloc(struct uverbs_attr_bundle *bundle, size_t size, + gfp_t flags); + +static inline __malloc void *uverbs_alloc(struct uverbs_attr_bundle *bundle, + size_t size) { - return NULL; + return _uverbs_alloc(bundle, size, GFP_KERNEL); } -static inline void uverbs_free_spec_tree(struct uverbs_root_spec *root) +static inline __malloc void *uverbs_zalloc(struct uverbs_attr_bundle *bundle, + size_t size) +{ + return _uverbs_alloc(bundle, size, GFP_KERNEL | __GFP_ZERO); +} +#else +static inline int +uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle, + size_t idx, u64 allowed_bits) +{ + return -EINVAL; +} +static inline int +uverbs_get_flags32(u32 *to, const struct uverbs_attr_bundle *attrs_bundle, + size_t idx, u64 allowed_bits) +{ + return -EINVAL; +} +static inline int uverbs_copy_to(const struct uverbs_attr_bundle *attrs_bundle, + size_t idx, const void *from, size_t size) +{ + return -EINVAL; +} +static inline __malloc void *uverbs_alloc(struct uverbs_attr_bundle *bundle, + size_t size) +{ + return ERR_PTR(-EINVAL); +} +static inline __malloc void *uverbs_zalloc(struct uverbs_attr_bundle *bundle, + size_t size) { + return ERR_PTR(-EINVAL); } #endif diff --git a/include/rdma/uverbs_named_ioctl.h b/include/rdma/uverbs_named_ioctl.h index c5bb4ebdb0b0..b3b21733cc55 100644 --- a/include/rdma/uverbs_named_ioctl.h +++ b/include/rdma/uverbs_named_ioctl.h @@ -43,48 +43,89 @@ #define _UVERBS_NAME(x, y) _UVERBS_PASTE(x, y) #define UVERBS_METHOD(id) _UVERBS_NAME(UVERBS_MODULE_NAME, _method_##id) #define UVERBS_HANDLER(id) _UVERBS_NAME(UVERBS_MODULE_NAME, _handler_##id) +#define UVERBS_OBJECT(id) _UVERBS_NAME(UVERBS_MOUDLE_NAME, _object_##id) -#define DECLARE_UVERBS_NAMED_METHOD(id, ...) \ - DECLARE_UVERBS_METHOD(UVERBS_METHOD(id), id, UVERBS_HANDLER(id), ##__VA_ARGS__) +/* These are static so they do not need to be qualified */ +#define UVERBS_METHOD_ATTRS(method_id) _method_attrs_##method_id +#define UVERBS_OBJECT_METHODS(object_id) _object_methods_##object_id -#define DECLARE_UVERBS_NAMED_METHOD_WITH_HANDLER(id, handler, ...) \ - DECLARE_UVERBS_METHOD(UVERBS_METHOD(id), id, handler, ##__VA_ARGS__) +#define DECLARE_UVERBS_NAMED_METHOD(_method_id, ...) \ + static const struct uverbs_attr_def *const UVERBS_METHOD_ATTRS( \ + _method_id)[] = { __VA_ARGS__ }; \ + static const struct uverbs_method_def UVERBS_METHOD(_method_id) = { \ + .id = _method_id, \ + .handler = UVERBS_HANDLER(_method_id), \ + .num_attrs = ARRAY_SIZE(UVERBS_METHOD_ATTRS(_method_id)), \ + .attrs = &UVERBS_METHOD_ATTRS(_method_id), \ + } -#define DECLARE_UVERBS_NAMED_METHOD_NO_OVERRIDE(id, handler, ...) \ - DECLARE_UVERBS_METHOD(UVERBS_METHOD(id), id, NULL, ##__VA_ARGS__) - -#define DECLARE_UVERBS_NAMED_OBJECT(id, ...) \ - DECLARE_UVERBS_OBJECT(UVERBS_OBJECT(id), id, ##__VA_ARGS__) +/* Create a standard destroy method using the default handler. The handle_attr + * argument must be the attribute specifying the handle to destroy, the + * default handler does not support any other attributes. + */ +#define DECLARE_UVERBS_NAMED_METHOD_DESTROY(_method_id, _handle_attr) \ + static const struct uverbs_attr_def *const UVERBS_METHOD_ATTRS( \ + _method_id)[] = { _handle_attr }; \ + static const struct uverbs_method_def UVERBS_METHOD(_method_id) = { \ + .id = _method_id, \ + .handler = uverbs_destroy_def_handler, \ + .num_attrs = ARRAY_SIZE(UVERBS_METHOD_ATTRS(_method_id)), \ + .attrs = &UVERBS_METHOD_ATTRS(_method_id), \ + } -#define _UVERBS_COMP_NAME(x, y, z) _UVERBS_NAME(_UVERBS_NAME(x, y), z) +#define DECLARE_UVERBS_NAMED_OBJECT(_object_id, _type_attrs, ...) \ + static const struct uverbs_method_def *const UVERBS_OBJECT_METHODS( \ + _object_id)[] = { __VA_ARGS__ }; \ + const struct uverbs_object_def UVERBS_OBJECT(_object_id) = { \ + .id = _object_id, \ + .type_attrs = &_type_attrs, \ + .num_methods = ARRAY_SIZE(UVERBS_OBJECT_METHODS(_object_id)), \ + .methods = &UVERBS_OBJECT_METHODS(_object_id) \ + } -#define UVERBS_NO_OVERRIDE NULL +/* + * Declare global methods. These still have a unique object_id because we + * identify all uapi methods with a (object,method) tuple. However, they have + * no type pointer. + */ +#define DECLARE_UVERBS_GLOBAL_METHODS(_object_id, ...) \ + static const struct uverbs_method_def *const UVERBS_OBJECT_METHODS( \ + _object_id)[] = { __VA_ARGS__ }; \ + const struct uverbs_object_def UVERBS_OBJECT(_object_id) = { \ + .id = _object_id, \ + .num_methods = ARRAY_SIZE(UVERBS_OBJECT_METHODS(_object_id)), \ + .methods = &UVERBS_OBJECT_METHODS(_object_id) \ + } -/* This declares a parsing tree with one object and one method. This is usually - * used for merging driver attributes to the common attributes. The driver has - * a chance to override the handler and type attrs of the original object. - * The __VA_ARGS__ just contains a list of attributes. +/* Used by drivers to declare a complete parsing tree for new methods */ -#define ADD_UVERBS_ATTRIBUTES(_name, _object, _method, _type_attrs, _handler, ...) \ -static DECLARE_UVERBS_METHOD(_UVERBS_COMP_NAME(UVERBS_MODULE_NAME, \ - _method_, _name), \ - _method, _handler, ##__VA_ARGS__); \ - \ -static DECLARE_UVERBS_OBJECT(_UVERBS_COMP_NAME(UVERBS_MODULE_NAME, \ - _object_, _name), \ - _object, _type_attrs, \ - &_UVERBS_COMP_NAME(UVERBS_MODULE_NAME, \ - _method_, _name)); \ - \ -static DECLARE_UVERBS_OBJECT_TREE(_name, \ - &_UVERBS_COMP_NAME(UVERBS_MODULE_NAME, \ - _object_, _name)) +#define ADD_UVERBS_METHODS(_name, _object_id, ...) \ + static const struct uverbs_method_def *const UVERBS_OBJECT_METHODS( \ + _object_id)[] = { __VA_ARGS__ }; \ + static const struct uverbs_object_def _name##_struct = { \ + .id = _object_id, \ + .num_methods = ARRAY_SIZE(UVERBS_OBJECT_METHODS(_object_id)), \ + .methods = &UVERBS_OBJECT_METHODS(_object_id) \ + }; \ + static const struct uverbs_object_def *const _name##_ptrs[] = { \ + &_name##_struct, \ + }; \ + static const struct uverbs_object_tree_def _name = { \ + .num_objects = 1, \ + .objects = &_name##_ptrs, \ + } -/* A very common use case is that the driver doesn't override the handler and - * type_attrs. Therefore, we provide a simplified macro for this common case. +/* Used by drivers to declare a complete parsing tree for a single method that + * differs only in having additional driver specific attributes. */ -#define ADD_UVERBS_ATTRIBUTES_SIMPLE(_name, _object, _method, ...) \ - ADD_UVERBS_ATTRIBUTES(_name, _object, _method, UVERBS_NO_OVERRIDE, \ - UVERBS_NO_OVERRIDE, ##__VA_ARGS__) +#define ADD_UVERBS_ATTRIBUTES_SIMPLE(_name, _object_id, _method_id, ...) \ + static const struct uverbs_attr_def *const UVERBS_METHOD_ATTRS( \ + _method_id)[] = { __VA_ARGS__ }; \ + static const struct uverbs_method_def UVERBS_METHOD(_method_id) = { \ + .id = _method_id, \ + .num_attrs = ARRAY_SIZE(UVERBS_METHOD_ATTRS(_method_id)), \ + .attrs = &UVERBS_METHOD_ATTRS(_method_id), \ + }; \ + ADD_UVERBS_METHODS(_name, _object_id, &UVERBS_METHOD(_method_id)) #endif diff --git a/include/rdma/uverbs_std_types.h b/include/rdma/uverbs_std_types.h index 9d56cdb84655..3b00231cc084 100644 --- a/include/rdma/uverbs_std_types.h +++ b/include/rdma/uverbs_std_types.h @@ -37,8 +37,6 @@ #include <rdma/uverbs_ioctl.h> #include <rdma/ib_user_ioctl_verbs.h> -#define UVERBS_OBJECT(id) uverbs_object_##id - #if IS_ENABLED(CONFIG_INFINIBAND_USER_ACCESS) const struct uverbs_object_tree_def *uverbs_default_get_objects(void); #else @@ -48,34 +46,61 @@ static inline const struct uverbs_object_tree_def *uverbs_default_get_objects(vo } #endif -static inline struct ib_uobject *__uobj_get(const struct uverbs_obj_type *type, - bool write, - struct ib_ucontext *ucontext, - int id) +/* Returns _id, or causes a compile error if _id is not a u32. + * + * The uobj APIs should only be used with the write based uAPI to access + * object IDs. The write API must use a u32 for the object handle, which is + * checked by this macro. + */ +#define _uobj_check_id(_id) ((_id) * typecheck(u32, _id)) + +#define uobj_get_type(_ufile, _object) \ + uapi_get_object((_ufile)->device->uapi, _object) + +#define uobj_get_read(_type, _id, _ufile) \ + rdma_lookup_get_uobject(uobj_get_type(_ufile, _type), _ufile, \ + _uobj_check_id(_id), UVERBS_LOOKUP_READ) + +#define ufd_get_read(_type, _fdnum, _ufile) \ + rdma_lookup_get_uobject(uobj_get_type(_ufile, _type), _ufile, \ + (_fdnum)*typecheck(s32, _fdnum), \ + UVERBS_LOOKUP_READ) + +static inline void *_uobj_get_obj_read(struct ib_uobject *uobj) { - return rdma_lookup_get_uobject(type, ucontext, id, write); + if (IS_ERR(uobj)) + return NULL; + return uobj->object; } +#define uobj_get_obj_read(_object, _type, _id, _ufile) \ + ((struct ib_##_object *)_uobj_get_obj_read( \ + uobj_get_read(_type, _id, _ufile))) -#define uobj_get_type(_object) UVERBS_OBJECT(_object).type_attrs +#define uobj_get_write(_type, _id, _ufile) \ + rdma_lookup_get_uobject(uobj_get_type(_ufile, _type), _ufile, \ + _uobj_check_id(_id), UVERBS_LOOKUP_WRITE) -#define uobj_get_read(_type, _id, _ucontext) \ - __uobj_get(uobj_get_type(_type), false, _ucontext, _id) +int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id, + struct ib_uverbs_file *ufile, int success_res); +#define uobj_perform_destroy(_type, _id, _ufile, _success_res) \ + __uobj_perform_destroy(uobj_get_type(_ufile, _type), \ + _uobj_check_id(_id), _ufile, _success_res) -#define uobj_get_obj_read(_object, _type, _id, _ucontext) \ -({ \ - struct ib_uobject *__uobj = \ - __uobj_get(uobj_get_type(_type), \ - false, _ucontext, _id); \ - \ - (struct ib_##_object *)(IS_ERR(__uobj) ? NULL : __uobj->object);\ -}) +struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj, + u32 id, struct ib_uverbs_file *ufile); -#define uobj_get_write(_type, _id, _ucontext) \ - __uobj_get(uobj_get_type(_type), true, _ucontext, _id) +#define uobj_get_destroy(_type, _id, _ufile) \ + __uobj_get_destroy(uobj_get_type(_ufile, _type), _uobj_check_id(_id), \ + _ufile) + +static inline void uobj_put_destroy(struct ib_uobject *uobj) +{ + rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE); +} static inline void uobj_put_read(struct ib_uobject *uobj) { - rdma_lookup_put_uobject(uobj, false); + rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_READ); } #define uobj_put_obj_read(_obj) \ @@ -83,17 +108,17 @@ static inline void uobj_put_read(struct ib_uobject *uobj) static inline void uobj_put_write(struct ib_uobject *uobj) { - rdma_lookup_put_uobject(uobj, true); + rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE); } -static inline int __must_check uobj_remove_commit(struct ib_uobject *uobj) +static inline int __must_check uobj_alloc_commit(struct ib_uobject *uobj, + int success_res) { - return rdma_remove_commit_uobject(uobj); -} + int ret = rdma_alloc_commit_uobject(uobj); -static inline void uobj_alloc_commit(struct ib_uobject *uobj) -{ - rdma_alloc_commit_uobject(uobj); + if (ret) + return ret; + return success_res; } static inline void uobj_alloc_abort(struct ib_uobject *uobj) @@ -101,14 +126,19 @@ static inline void uobj_alloc_abort(struct ib_uobject *uobj) rdma_alloc_abort_uobject(uobj); } -static inline struct ib_uobject *__uobj_alloc(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext) +static inline struct ib_uobject * +__uobj_alloc(const struct uverbs_api_object *obj, struct ib_uverbs_file *ufile, + struct ib_device **ib_dev) { - return rdma_alloc_begin_uobject(type, ucontext); + struct ib_uobject *uobj = rdma_alloc_begin_uobject(obj, ufile); + + if (!IS_ERR(uobj)) + *ib_dev = uobj->context->device; + return uobj; } -#define uobj_alloc(_type, ucontext) \ - __uobj_alloc(uobj_get_type(_type), ucontext) +#define uobj_alloc(_type, _ufile, _ib_dev) \ + __uobj_alloc(uobj_get_type(_ufile, _type), _ufile, _ib_dev) #endif diff --git a/include/rdma/uverbs_types.h b/include/rdma/uverbs_types.h index cc04ec65588d..acb1bfa3cc99 100644 --- a/include/rdma/uverbs_types.h +++ b/include/rdma/uverbs_types.h @@ -37,63 +37,72 @@ #include <rdma/ib_verbs.h> struct uverbs_obj_type; +struct uverbs_api_object; -struct uverbs_obj_type_class { +enum rdma_lookup_mode { + UVERBS_LOOKUP_READ, + UVERBS_LOOKUP_WRITE, /* - * Get an ib_uobject that corresponds to the given id from ucontext, - * These functions could create or destroy objects if required. - * The action will be finalized only when commit, abort or put fops are - * called. - * The flow of the different actions is: - * [alloc]: Starts with alloc_begin. The handlers logic is than - * executed. If the handler is successful, alloc_commit - * is called and the object is inserted to the repository. - * Once alloc_commit completes the object is visible to - * other threads and userspace. - e Otherwise, alloc_abort is called and the object is - * destroyed. - * [lookup]: Starts with lookup_get which fetches and locks the - * object. After the handler finished using the object, it - * needs to call lookup_put to unlock it. The exclusive - * flag indicates if the object is locked for exclusive - * access. - * [remove]: Starts with lookup_get with exclusive flag set. This - * locks the object for exclusive access. If the handler - * code completed successfully, remove_commit is called - * and the ib_uobject is removed from the context's - * uobjects repository and put. The object itself is - * destroyed as well. Once remove succeeds new krefs to - * the object cannot be acquired by other threads or - * userspace and the hardware driver is removed from the - * object. Other krefs on the object may still exist. - * If the handler code failed, lookup_put should be - * called. This callback is used when the context - * is destroyed as well (process termination, - * reset flow). + * Destroy is like LOOKUP_WRITE, except that the uobject is not + * locked. uobj_destroy is used to convert a LOOKUP_DESTROY lock into + * a LOOKUP_WRITE lock. */ - struct ib_uobject *(*alloc_begin)(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext); - void (*alloc_commit)(struct ib_uobject *uobj); + UVERBS_LOOKUP_DESTROY, +}; + +/* + * The following sequences are valid: + * Success flow: + * alloc_begin + * alloc_commit + * [..] + * Access flow: + * lookup_get(exclusive=false) & uverbs_try_lock_object + * lookup_put(exclusive=false) via rdma_lookup_put_uobject + * Destruction flow: + * lookup_get(exclusive=true) & uverbs_try_lock_object + * remove_commit + * remove_handle (optional) + * lookup_put(exclusive=true) via rdma_lookup_put_uobject + * + * Allocate Error flow #1 + * alloc_begin + * alloc_abort + * Allocate Error flow #2 + * alloc_begin + * remove_commit + * alloc_abort + * Allocate Error flow #3 + * alloc_begin + * alloc_commit (fails) + * remove_commit + * alloc_abort + * + * In all cases the caller must hold the ufile kref until alloc_commit or + * alloc_abort returns. + */ +struct uverbs_obj_type_class { + struct ib_uobject *(*alloc_begin)(const struct uverbs_api_object *obj, + struct ib_uverbs_file *ufile); + /* This consumes the kref on uobj */ + int (*alloc_commit)(struct ib_uobject *uobj); + /* This does not consume the kref on uobj */ void (*alloc_abort)(struct ib_uobject *uobj); - struct ib_uobject *(*lookup_get)(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext, int id, - bool exclusive); - void (*lookup_put)(struct ib_uobject *uobj, bool exclusive); - /* - * Must be called with the exclusive lock held. If successful uobj is - * invalid on return. On failure uobject is left completely - * unchanged - */ - int __must_check (*remove_commit)(struct ib_uobject *uobj, - enum rdma_remove_reason why); + struct ib_uobject *(*lookup_get)(const struct uverbs_api_object *obj, + struct ib_uverbs_file *ufile, s64 id, + enum rdma_lookup_mode mode); + void (*lookup_put)(struct ib_uobject *uobj, enum rdma_lookup_mode mode); + /* This does not consume the kref on uobj */ + int __must_check (*destroy_hw)(struct ib_uobject *uobj, + enum rdma_remove_reason why); + void (*remove_handle)(struct ib_uobject *uobj); u8 needs_kfree_rcu; }; struct uverbs_obj_type { const struct uverbs_obj_type_class * const type_class; size_t obj_size; - unsigned int destroy_order; }; /* @@ -120,16 +129,15 @@ struct uverbs_obj_idr_type { enum rdma_remove_reason why); }; -struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext, - int id, bool exclusive); -void rdma_lookup_put_uobject(struct ib_uobject *uobj, bool exclusive); -struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_obj_type *type, - struct ib_ucontext *ucontext); +struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_api_object *obj, + struct ib_uverbs_file *ufile, s64 id, + enum rdma_lookup_mode mode); +void rdma_lookup_put_uobject(struct ib_uobject *uobj, + enum rdma_lookup_mode mode); +struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_api_object *obj, + struct ib_uverbs_file *ufile); void rdma_alloc_abort_uobject(struct ib_uobject *uobj); -int __must_check rdma_remove_commit_uobject(struct ib_uobject *uobj); -int rdma_alloc_commit_uobject(struct ib_uobject *uobj); -int rdma_explicit_destroy(struct ib_uobject *uobject); +int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj); struct uverbs_obj_fd_type { /* @@ -140,7 +148,7 @@ struct uverbs_obj_fd_type { * the driver is removed or the process terminated. */ struct uverbs_obj_type type; - int (*context_closed)(struct ib_uobject_file *uobj_file, + int (*context_closed)(struct ib_uobject *uobj, enum rdma_remove_reason why); const struct file_operations *fops; const char *name; @@ -152,30 +160,29 @@ extern const struct uverbs_obj_type_class uverbs_fd_class; #define UVERBS_BUILD_BUG_ON(cond) (sizeof(char[1 - 2 * !!(cond)]) - \ sizeof(char)) -#define UVERBS_TYPE_ALLOC_FD(_order, _obj_size, _context_closed, _fops, _name, _flags)\ +#define UVERBS_TYPE_ALLOC_FD(_obj_size, _context_closed, _fops, _name, _flags)\ ((&((const struct uverbs_obj_fd_type) \ {.type = { \ - .destroy_order = _order, \ .type_class = &uverbs_fd_class, \ .obj_size = (_obj_size) + \ - UVERBS_BUILD_BUG_ON((_obj_size) < sizeof(struct ib_uobject_file)), \ + UVERBS_BUILD_BUG_ON((_obj_size) < \ + sizeof(struct ib_uobject)), \ }, \ .context_closed = _context_closed, \ .fops = _fops, \ .name = _name, \ .flags = _flags}))->type) -#define UVERBS_TYPE_ALLOC_IDR_SZ(_size, _order, _destroy_object) \ +#define UVERBS_TYPE_ALLOC_IDR_SZ(_size, _destroy_object) \ ((&((const struct uverbs_obj_idr_type) \ {.type = { \ - .destroy_order = _order, \ .type_class = &uverbs_idr_class, \ .obj_size = (_size) + \ UVERBS_BUILD_BUG_ON((_size) < \ sizeof(struct ib_uobject)) \ }, \ .destroy_object = _destroy_object,}))->type) -#define UVERBS_TYPE_ALLOC_IDR(_order, _destroy_object) \ - UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uobject), _order, \ +#define UVERBS_TYPE_ALLOC_IDR(_destroy_object) \ + UVERBS_TYPE_ALLOC_IDR_SZ(sizeof(struct ib_uobject), \ _destroy_object) #endif diff --git a/include/trace/events/fsi_master_ast_cf.h b/include/trace/events/fsi_master_ast_cf.h new file mode 100644 index 000000000000..a0fdfa58622a --- /dev/null +++ b/include/trace/events/fsi_master_ast_cf.h @@ -0,0 +1,150 @@ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM fsi_master_ast_cf + +#if !defined(_TRACE_FSI_MASTER_ACF_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_FSI_MASTER_ACF_H + +#include <linux/tracepoint.h> + +TRACE_EVENT(fsi_master_acf_copro_command, + TP_PROTO(const struct fsi_master_acf *master, uint32_t op), + TP_ARGS(master, op), + TP_STRUCT__entry( + __field(int, master_idx) + __field(uint32_t, op) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->op = op; + ), + TP_printk("fsi-acf%d command %08x", + __entry->master_idx, __entry->op + ) +); + +TRACE_EVENT(fsi_master_acf_send_request, + TP_PROTO(const struct fsi_master_acf *master, const struct fsi_msg *cmd, u8 rbits), + TP_ARGS(master, cmd, rbits), + TP_STRUCT__entry( + __field(int, master_idx) + __field(uint64_t, msg) + __field(u8, bits) + __field(u8, rbits) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->msg = cmd->msg; + __entry->bits = cmd->bits; + __entry->rbits = rbits; + ), + TP_printk("fsi-acf%d cmd: %016llx/%d/%d", + __entry->master_idx, (unsigned long long)__entry->msg, + __entry->bits, __entry->rbits + ) +); + +TRACE_EVENT(fsi_master_acf_copro_response, + TP_PROTO(const struct fsi_master_acf *master, u8 rtag, u8 rcrc, __be32 rdata, bool crc_ok), + TP_ARGS(master, rtag, rcrc, rdata, crc_ok), + TP_STRUCT__entry( + __field(int, master_idx) + __field(u8, rtag) + __field(u8, rcrc) + __field(u32, rdata) + __field(bool, crc_ok) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->rtag = rtag; + __entry->rcrc = rcrc; + __entry->rdata = be32_to_cpu(rdata); + __entry->crc_ok = crc_ok; + ), + TP_printk("fsi-acf%d rsp: tag=%04x crc=%04x data=%08x %c\n", + __entry->master_idx, __entry->rtag, __entry->rcrc, + __entry->rdata, __entry->crc_ok ? ' ' : '!' + ) +); + +TRACE_EVENT(fsi_master_acf_crc_rsp_error, + TP_PROTO(const struct fsi_master_acf *master, int retries), + TP_ARGS(master, retries), + TP_STRUCT__entry( + __field(int, master_idx) + __field(int, retries) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->retries = retries; + ), + TP_printk("fsi-acf%d CRC error in response retry %d", + __entry->master_idx, __entry->retries + ) +); + +TRACE_EVENT(fsi_master_acf_poll_response_busy, + TP_PROTO(const struct fsi_master_acf *master, int busy_count), + TP_ARGS(master, busy_count), + TP_STRUCT__entry( + __field(int, master_idx) + __field(int, busy_count) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->busy_count = busy_count; + ), + TP_printk("fsi-acf%d: device reported busy %d times", + __entry->master_idx, __entry->busy_count + ) +); + +TRACE_EVENT(fsi_master_acf_cmd_abs_addr, + TP_PROTO(const struct fsi_master_acf *master, u32 addr), + TP_ARGS(master, addr), + TP_STRUCT__entry( + __field(int, master_idx) + __field(u32, addr) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->addr = addr; + ), + TP_printk("fsi-acf%d: Sending ABS_ADR %06x", + __entry->master_idx, __entry->addr + ) +); + +TRACE_EVENT(fsi_master_acf_cmd_rel_addr, + TP_PROTO(const struct fsi_master_acf *master, u32 rel_addr), + TP_ARGS(master, rel_addr), + TP_STRUCT__entry( + __field(int, master_idx) + __field(u32, rel_addr) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->rel_addr = rel_addr; + ), + TP_printk("fsi-acf%d: Sending REL_ADR %03x", + __entry->master_idx, __entry->rel_addr + ) +); + +TRACE_EVENT(fsi_master_acf_cmd_same_addr, + TP_PROTO(const struct fsi_master_acf *master), + TP_ARGS(master), + TP_STRUCT__entry( + __field(int, master_idx) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + ), + TP_printk("fsi-acf%d: Sending SAME_ADR", + __entry->master_idx + ) +); + +#endif /* _TRACE_FSI_MASTER_ACF_H */ + +#include <trace/define_trace.h> diff --git a/include/trace/events/fsi_master_gpio.h b/include/trace/events/fsi_master_gpio.h index f95cf3264bf9..70ef66e63e84 100644 --- a/include/trace/events/fsi_master_gpio.h +++ b/include/trace/events/fsi_master_gpio.h @@ -50,6 +50,22 @@ TRACE_EVENT(fsi_master_gpio_out, ) ); +TRACE_EVENT(fsi_master_gpio_clock_zeros, + TP_PROTO(const struct fsi_master_gpio *master, int clocks), + TP_ARGS(master, clocks), + TP_STRUCT__entry( + __field(int, master_idx) + __field(int, clocks) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->clocks = clocks; + ), + TP_printk("fsi-gpio%d clock %d zeros", + __entry->master_idx, __entry->clocks + ) +); + TRACE_EVENT(fsi_master_gpio_break, TP_PROTO(const struct fsi_master_gpio *master), TP_ARGS(master), @@ -64,6 +80,92 @@ TRACE_EVENT(fsi_master_gpio_break, ) ); +TRACE_EVENT(fsi_master_gpio_crc_cmd_error, + TP_PROTO(const struct fsi_master_gpio *master), + TP_ARGS(master), + TP_STRUCT__entry( + __field(int, master_idx) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + ), + TP_printk("fsi-gpio%d ----CRC command retry---", + __entry->master_idx + ) +); + +TRACE_EVENT(fsi_master_gpio_crc_rsp_error, + TP_PROTO(const struct fsi_master_gpio *master), + TP_ARGS(master), + TP_STRUCT__entry( + __field(int, master_idx) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + ), + TP_printk("fsi-gpio%d ----CRC response---", + __entry->master_idx + ) +); + +TRACE_EVENT(fsi_master_gpio_poll_response_busy, + TP_PROTO(const struct fsi_master_gpio *master, int busy), + TP_ARGS(master, busy), + TP_STRUCT__entry( + __field(int, master_idx) + __field(int, busy) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->busy = busy; + ), + TP_printk("fsi-gpio%d: device reported busy %d times", + __entry->master_idx, __entry->busy) +); + +TRACE_EVENT(fsi_master_gpio_cmd_abs_addr, + TP_PROTO(const struct fsi_master_gpio *master, u32 addr), + TP_ARGS(master, addr), + TP_STRUCT__entry( + __field(int, master_idx) + __field(u32, addr) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->addr = addr; + ), + TP_printk("fsi-gpio%d: Sending ABS_ADR %06x", + __entry->master_idx, __entry->addr) +); + +TRACE_EVENT(fsi_master_gpio_cmd_rel_addr, + TP_PROTO(const struct fsi_master_gpio *master, u32 rel_addr), + TP_ARGS(master, rel_addr), + TP_STRUCT__entry( + __field(int, master_idx) + __field(u32, rel_addr) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + __entry->rel_addr = rel_addr; + ), + TP_printk("fsi-gpio%d: Sending REL_ADR %03x", + __entry->master_idx, __entry->rel_addr) +); + +TRACE_EVENT(fsi_master_gpio_cmd_same_addr, + TP_PROTO(const struct fsi_master_gpio *master), + TP_ARGS(master), + TP_STRUCT__entry( + __field(int, master_idx) + ), + TP_fast_assign( + __entry->master_idx = master->master.idx; + ), + TP_printk("fsi-gpio%d: Sending SAME_ADR", + __entry->master_idx) +); + #endif /* _TRACE_FSI_MASTER_GPIO_H */ #include <trace/define_trace.h> diff --git a/include/uapi/linux/eventpoll.h b/include/uapi/linux/eventpoll.h index bf48e71f2634..8a3432d0f0dc 100644 --- a/include/uapi/linux/eventpoll.h +++ b/include/uapi/linux/eventpoll.h @@ -42,7 +42,7 @@ #define EPOLLRDHUP (__force __poll_t)0x00002000 /* Set exclusive wakeup mode for the target file descriptor */ -#define EPOLLEXCLUSIVE (__force __poll_t)(1U << 28) +#define EPOLLEXCLUSIVE ((__force __poll_t)(1U << 28)) /* * Request the handling of system wakeup events so as to prevent system suspends @@ -54,13 +54,13 @@ * * Requires CAP_BLOCK_SUSPEND */ -#define EPOLLWAKEUP (__force __poll_t)(1U << 29) +#define EPOLLWAKEUP ((__force __poll_t)(1U << 29)) /* Set the One Shot behaviour for the target file descriptor */ -#define EPOLLONESHOT (__force __poll_t)(1U << 30) +#define EPOLLONESHOT ((__force __poll_t)(1U << 30)) /* Set the Edge Triggered behaviour for the target file descriptor */ -#define EPOLLET (__force __poll_t)(1U << 31) +#define EPOLLET ((__force __poll_t)(1U << 31)) /* * On x86-64 make the 64bit structure have the same alignment as the diff --git a/include/uapi/linux/fpga-dfl.h b/include/uapi/linux/fpga-dfl.h new file mode 100644 index 000000000000..2e324e515c41 --- /dev/null +++ b/include/uapi/linux/fpga-dfl.h @@ -0,0 +1,179 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Header File for FPGA DFL User API + * + * Copyright (C) 2017-2018 Intel Corporation, Inc. + * + * Authors: + * Kang Luwei <luwei.kang@intel.com> + * Zhang Yi <yi.z.zhang@intel.com> + * Wu Hao <hao.wu@intel.com> + * Xiao Guangrong <guangrong.xiao@linux.intel.com> + */ + +#ifndef _UAPI_LINUX_FPGA_DFL_H +#define _UAPI_LINUX_FPGA_DFL_H + +#include <linux/types.h> +#include <linux/ioctl.h> + +#define DFL_FPGA_API_VERSION 0 + +/* + * The IOCTL interface for DFL based FPGA is designed for extensibility by + * embedding the structure length (argsz) and flags into structures passed + * between kernel and userspace. This design referenced the VFIO IOCTL + * interface (include/uapi/linux/vfio.h). + */ + +#define DFL_FPGA_MAGIC 0xB6 + +#define DFL_FPGA_BASE 0 +#define DFL_PORT_BASE 0x40 +#define DFL_FME_BASE 0x80 + +/* Common IOCTLs for both FME and AFU file descriptor */ + +/** + * DFL_FPGA_GET_API_VERSION - _IO(DFL_FPGA_MAGIC, DFL_FPGA_BASE + 0) + * + * Report the version of the driver API. + * Return: Driver API Version. + */ + +#define DFL_FPGA_GET_API_VERSION _IO(DFL_FPGA_MAGIC, DFL_FPGA_BASE + 0) + +/** + * DFL_FPGA_CHECK_EXTENSION - _IO(DFL_FPGA_MAGIC, DFL_FPGA_BASE + 1) + * + * Check whether an extension is supported. + * Return: 0 if not supported, otherwise the extension is supported. + */ + +#define DFL_FPGA_CHECK_EXTENSION _IO(DFL_FPGA_MAGIC, DFL_FPGA_BASE + 1) + +/* IOCTLs for AFU file descriptor */ + +/** + * DFL_FPGA_PORT_RESET - _IO(DFL_FPGA_MAGIC, DFL_PORT_BASE + 0) + * + * Reset the FPGA Port and its AFU. No parameters are supported. + * Userspace can do Port reset at any time, e.g. during DMA or PR. But + * it should never cause any system level issue, only functional failure + * (e.g. DMA or PR operation failure) and be recoverable from the failure. + * Return: 0 on success, -errno of failure + */ + +#define DFL_FPGA_PORT_RESET _IO(DFL_FPGA_MAGIC, DFL_PORT_BASE + 0) + +/** + * DFL_FPGA_PORT_GET_INFO - _IOR(DFL_FPGA_MAGIC, DFL_PORT_BASE + 1, + * struct dfl_fpga_port_info) + * + * Retrieve information about the fpga port. + * Driver fills the info in provided struct dfl_fpga_port_info. + * Return: 0 on success, -errno on failure. + */ +struct dfl_fpga_port_info { + /* Input */ + __u32 argsz; /* Structure length */ + /* Output */ + __u32 flags; /* Zero for now */ + __u32 num_regions; /* The number of supported regions */ + __u32 num_umsgs; /* The number of allocated umsgs */ +}; + +#define DFL_FPGA_PORT_GET_INFO _IO(DFL_FPGA_MAGIC, DFL_PORT_BASE + 1) + +/** + * FPGA_PORT_GET_REGION_INFO - _IOWR(FPGA_MAGIC, PORT_BASE + 2, + * struct dfl_fpga_port_region_info) + * + * Retrieve information about a device memory region. + * Caller provides struct dfl_fpga_port_region_info with index value set. + * Driver returns the region info in other fields. + * Return: 0 on success, -errno on failure. + */ +struct dfl_fpga_port_region_info { + /* input */ + __u32 argsz; /* Structure length */ + /* Output */ + __u32 flags; /* Access permission */ +#define DFL_PORT_REGION_READ (1 << 0) /* Region is readable */ +#define DFL_PORT_REGION_WRITE (1 << 1) /* Region is writable */ +#define DFL_PORT_REGION_MMAP (1 << 2) /* Can be mmaped to userspace */ + /* Input */ + __u32 index; /* Region index */ +#define DFL_PORT_REGION_INDEX_AFU 0 /* AFU */ +#define DFL_PORT_REGION_INDEX_STP 1 /* Signal Tap */ + __u32 padding; + /* Output */ + __u64 size; /* Region size (bytes) */ + __u64 offset; /* Region offset from start of device fd */ +}; + +#define DFL_FPGA_PORT_GET_REGION_INFO _IO(DFL_FPGA_MAGIC, DFL_PORT_BASE + 2) + +/** + * DFL_FPGA_PORT_DMA_MAP - _IOWR(DFL_FPGA_MAGIC, DFL_PORT_BASE + 3, + * struct dfl_fpga_port_dma_map) + * + * Map the dma memory per user_addr and length which are provided by caller. + * Driver fills the iova in provided struct afu_port_dma_map. + * This interface only accepts page-size aligned user memory for dma mapping. + * Return: 0 on success, -errno on failure. + */ +struct dfl_fpga_port_dma_map { + /* Input */ + __u32 argsz; /* Structure length */ + __u32 flags; /* Zero for now */ + __u64 user_addr; /* Process virtual address */ + __u64 length; /* Length of mapping (bytes)*/ + /* Output */ + __u64 iova; /* IO virtual address */ +}; + +#define DFL_FPGA_PORT_DMA_MAP _IO(DFL_FPGA_MAGIC, DFL_PORT_BASE + 3) + +/** + * DFL_FPGA_PORT_DMA_UNMAP - _IOW(FPGA_MAGIC, PORT_BASE + 4, + * struct dfl_fpga_port_dma_unmap) + * + * Unmap the dma memory per iova provided by caller. + * Return: 0 on success, -errno on failure. + */ +struct dfl_fpga_port_dma_unmap { + /* Input */ + __u32 argsz; /* Structure length */ + __u32 flags; /* Zero for now */ + __u64 iova; /* IO virtual address */ +}; + +#define DFL_FPGA_PORT_DMA_UNMAP _IO(DFL_FPGA_MAGIC, DFL_PORT_BASE + 4) + +/* IOCTLs for FME file descriptor */ + +/** + * DFL_FPGA_FME_PORT_PR - _IOW(DFL_FPGA_MAGIC, DFL_FME_BASE + 0, + * struct dfl_fpga_fme_port_pr) + * + * Driver does Partial Reconfiguration based on Port ID and Buffer (Image) + * provided by caller. + * Return: 0 on success, -errno on failure. + * If DFL_FPGA_FME_PORT_PR returns -EIO, that indicates the HW has detected + * some errors during PR, under this case, the user can fetch HW error info + * from the status of FME's fpga manager. + */ + +struct dfl_fpga_fme_port_pr { + /* Input */ + __u32 argsz; /* Structure length */ + __u32 flags; /* Zero for now */ + __u32 port_id; + __u32 buffer_size; + __u64 buffer_address; /* Userspace address to the buffer for PR */ +}; + +#define DFL_FPGA_FME_PORT_PR _IO(DFL_FPGA_MAGIC, DFL_FME_BASE + 0) + +#endif /* _UAPI_LINUX_FPGA_DFL_H */ diff --git a/include/uapi/linux/fsi.h b/include/uapi/linux/fsi.h new file mode 100644 index 000000000000..da577ecd90e7 --- /dev/null +++ b/include/uapi/linux/fsi.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_FSI_H +#define _UAPI_LINUX_FSI_H + +#include <linux/types.h> +#include <linux/ioctl.h> + +/* + * /dev/scom "raw" ioctl interface + * + * The driver supports a high level "read/write" interface which + * handles retries and converts the status to Linux error codes, + * however low level tools an debugger need to access the "raw" + * HW status information and interpret it themselves, so this + * ioctl interface is also provided for their use case. + */ + +/* Structure for SCOM read/write */ +struct scom_access { + __u64 addr; /* SCOM address, supports indirect */ + __u64 data; /* SCOM data (in for write, out for read) */ + __u64 mask; /* Data mask for writes */ + __u32 intf_errors; /* Interface error flags */ +#define SCOM_INTF_ERR_PARITY 0x00000001 /* Parity error */ +#define SCOM_INTF_ERR_PROTECTION 0x00000002 /* Blocked by secure boot */ +#define SCOM_INTF_ERR_ABORT 0x00000004 /* PIB reset during access */ +#define SCOM_INTF_ERR_UNKNOWN 0x80000000 /* Unknown error */ + /* + * Note: Any other bit set in intf_errors need to be considered as an + * error. Future implementations may define new error conditions. The + * pib_status below is only valid if intf_errors is 0. + */ + __u8 pib_status; /* 3-bit PIB status */ +#define SCOM_PIB_SUCCESS 0 /* Access successful */ +#define SCOM_PIB_BLOCKED 1 /* PIB blocked, pls retry */ +#define SCOM_PIB_OFFLINE 2 /* Chiplet offline */ +#define SCOM_PIB_PARTIAL 3 /* Partial good */ +#define SCOM_PIB_BAD_ADDR 4 /* Invalid address */ +#define SCOM_PIB_CLK_ERR 5 /* Clock error */ +#define SCOM_PIB_PARITY_ERR 6 /* Parity error on the PIB bus */ +#define SCOM_PIB_TIMEOUT 7 /* Bus timeout */ + __u8 pad; +}; + +/* Flags for SCOM check */ +#define SCOM_CHECK_SUPPORTED 0x00000001 /* Interface supported */ +#define SCOM_CHECK_PROTECTED 0x00000002 /* Interface blocked by secure boot */ + +/* Flags for SCOM reset */ +#define SCOM_RESET_INTF 0x00000001 /* Reset interface */ +#define SCOM_RESET_PIB 0x00000002 /* Reset PIB */ + +#define FSI_SCOM_CHECK _IOR('s', 0x00, __u32) +#define FSI_SCOM_READ _IOWR('s', 0x01, struct scom_access) +#define FSI_SCOM_WRITE _IOWR('s', 0x02, struct scom_access) +#define FSI_SCOM_RESET _IOW('s', 0x03, __u32) + +#endif /* _UAPI_LINUX_FSI_H */ diff --git a/include/uapi/linux/iio/types.h b/include/uapi/linux/iio/types.h index 4213cdf88e3c..92baabc103ac 100644 --- a/include/uapi/linux/iio/types.h +++ b/include/uapi/linux/iio/types.h @@ -44,6 +44,8 @@ enum iio_chan_type { IIO_COUNT, IIO_INDEX, IIO_GRAVITY, + IIO_POSITIONRELATIVE, + IIO_PHASE, }; enum iio_modifier { @@ -84,6 +86,7 @@ enum iio_modifier { IIO_MOD_CO2, IIO_MOD_VOC, IIO_MOD_LIGHT_UV, + IIO_MOD_LIGHT_DUV, }; enum iio_event_type { diff --git a/include/uapi/linux/inotify.h b/include/uapi/linux/inotify.h index 4800bf2a531d..884b4846b630 100644 --- a/include/uapi/linux/inotify.h +++ b/include/uapi/linux/inotify.h @@ -53,6 +53,7 @@ struct inotify_event { #define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */ #define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */ #define IN_EXCL_UNLINK 0x04000000 /* exclude events on unlinked objects */ +#define IN_MASK_CREATE 0x10000000 /* only create watches */ #define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */ #define IN_ISDIR 0x40000000 /* event occurred against dir */ #define IN_ONESHOT 0x80000000 /* only send event once */ diff --git a/include/uapi/linux/joystick.h b/include/uapi/linux/joystick.h index 64aabb84a66d..192bf2cf182d 100644 --- a/include/uapi/linux/joystick.h +++ b/include/uapi/linux/joystick.h @@ -18,10 +18,6 @@ * 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 - * - * Should you need to contact me, the author, you can do so either by - * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: - * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic */ #ifndef _UAPI_LINUX_JOYSTICK_H #define _UAPI_LINUX_JOYSTICK_H diff --git a/include/uapi/linux/keyboard.h b/include/uapi/linux/keyboard.h index ab4108c83186..4846716e7c5c 100644 --- a/include/uapi/linux/keyboard.h +++ b/include/uapi/linux/keyboard.h @@ -357,8 +357,29 @@ #define K_DTILDE K(KT_DEAD,3) #define K_DDIERE K(KT_DEAD,4) #define K_DCEDIL K(KT_DEAD,5) +#define K_DMACRON K(KT_DEAD,6) +#define K_DBREVE K(KT_DEAD,7) +#define K_DABDOT K(KT_DEAD,8) +#define K_DABRING K(KT_DEAD,9) +#define K_DDBACUTE K(KT_DEAD,10) +#define K_DCARON K(KT_DEAD,11) +#define K_DOGONEK K(KT_DEAD,12) +#define K_DIOTA K(KT_DEAD,13) +#define K_DVOICED K(KT_DEAD,14) +#define K_DSEMVOICED K(KT_DEAD,15) +#define K_DBEDOT K(KT_DEAD,16) +#define K_DHOOK K(KT_DEAD,17) +#define K_DHORN K(KT_DEAD,18) +#define K_DSTROKE K(KT_DEAD,19) +#define K_DABCOMMA K(KT_DEAD,20) +#define K_DABREVCOMMA K(KT_DEAD,21) +#define K_DDBGRAVE K(KT_DEAD,22) +#define K_DINVBREVE K(KT_DEAD,23) +#define K_DBECOMMA K(KT_DEAD,24) +#define K_DCURRENCY K(KT_DEAD,25) +#define K_DGREEK K(KT_DEAD,26) -#define NR_DEAD 6 +#define NR_DEAD 27 #define K_DOWN K(KT_CUR,0) #define K_LEFT K(KT_CUR,1) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index b955b986b341..3cf632839337 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -950,6 +950,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_HYPERV_EVENTFD 154 #define KVM_CAP_HYPERV_TLBFLUSH 155 #define KVM_CAP_S390_HPAGE_1M 156 +#define KVM_CAP_NESTED_STATE 157 #ifdef KVM_CAP_IRQ_ROUTING @@ -1392,6 +1393,9 @@ struct kvm_enc_region { /* Available with KVM_CAP_HYPERV_EVENTFD */ #define KVM_HYPERV_EVENTFD _IOW(KVMIO, 0xbd, struct kvm_hyperv_eventfd) +/* Available with KVM_CAP_NESTED_STATE */ +#define KVM_GET_NESTED_STATE _IOWR(KVMIO, 0xbe, struct kvm_nested_state) +#define KVM_SET_NESTED_STATE _IOW(KVMIO, 0xbf, struct kvm_nested_state) /* Secure Encrypted Virtualization command */ enum sev_cmd_id { diff --git a/include/uapi/linux/kvm_para.h b/include/uapi/linux/kvm_para.h index dcf629dd2889..6c0ce49931e5 100644 --- a/include/uapi/linux/kvm_para.h +++ b/include/uapi/linux/kvm_para.h @@ -13,6 +13,7 @@ /* Return values for hypercalls */ #define KVM_ENOSYS 1000 #define KVM_EFAULT EFAULT +#define KVM_EINVAL EINVAL #define KVM_E2BIG E2BIG #define KVM_EPERM EPERM #define KVM_EOPNOTSUPP 95 @@ -26,6 +27,7 @@ #define KVM_HC_MIPS_EXIT_VM 7 #define KVM_HC_MIPS_CONSOLE_OUTPUT 8 #define KVM_HC_CLOCK_PAIRING 9 +#define KVM_HC_SEND_IPI 10 /* * hypercalls use architecture specific diff --git a/include/uapi/linux/pmu.h b/include/uapi/linux/pmu.h index 89cb1acea93a..97256f90e6df 100644 --- a/include/uapi/linux/pmu.h +++ b/include/uapi/linux/pmu.h @@ -93,8 +93,8 @@ enum { PMU_HEATHROW_BASED, /* PowerBook G3 series */ PMU_PADDINGTON_BASED, /* 1999 PowerBook G3 */ PMU_KEYLARGO_BASED, /* Core99 motherboard (PMU99) */ - PMU_68K_V1, /* 68K PMU, version 1 */ - PMU_68K_V2, /* 68K PMU, version 2 */ + PMU_68K_V1, /* Unused/deprecated */ + PMU_68K_V2, /* Unused/deprecated */ }; /* PMU PMU_POWER_EVENTS commands */ diff --git a/include/uapi/linux/usb/g_uvc.h b/include/uapi/linux/usb/g_uvc.h new file mode 100644 index 000000000000..3c9ee3020cbb --- /dev/null +++ b/include/uapi/linux/usb/g_uvc.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * g_uvc.h -- USB Video Class Gadget driver API + * + * Copyright (C) 2009-2010 Laurent Pinchart <laurent.pinchart@ideasonboard.com> + */ + +#ifndef __LINUX_USB_G_UVC_H +#define __LINUX_USB_G_UVC_H + +#include <linux/ioctl.h> +#include <linux/types.h> +#include <linux/usb/ch9.h> + +#define UVC_EVENT_FIRST (V4L2_EVENT_PRIVATE_START + 0) +#define UVC_EVENT_CONNECT (V4L2_EVENT_PRIVATE_START + 0) +#define UVC_EVENT_DISCONNECT (V4L2_EVENT_PRIVATE_START + 1) +#define UVC_EVENT_STREAMON (V4L2_EVENT_PRIVATE_START + 2) +#define UVC_EVENT_STREAMOFF (V4L2_EVENT_PRIVATE_START + 3) +#define UVC_EVENT_SETUP (V4L2_EVENT_PRIVATE_START + 4) +#define UVC_EVENT_DATA (V4L2_EVENT_PRIVATE_START + 5) +#define UVC_EVENT_LAST (V4L2_EVENT_PRIVATE_START + 5) + +struct uvc_request_data { + __s32 length; + __u8 data[60]; +}; + +struct uvc_event { + union { + enum usb_device_speed speed; + struct usb_ctrlrequest req; + struct uvc_request_data data; + }; +}; + +#define UVCIOC_SEND_RESPONSE _IOW('U', 1, struct uvc_request_data) + +#endif /* __LINUX_USB_G_UVC_H */ diff --git a/include/uapi/linux/usb/tmc.h b/include/uapi/linux/usb/tmc.h index 03f6adc8f35b..729af2f861a4 100644 --- a/include/uapi/linux/usb/tmc.h +++ b/include/uapi/linux/usb/tmc.h @@ -16,6 +16,8 @@ #ifndef __LINUX_USB_TMC_H #define __LINUX_USB_TMC_H +#include <linux/types.h> /* __u8 etc */ + /* USB TMC status values */ #define USBTMC_STATUS_SUCCESS 0x01 #define USBTMC_STATUS_PENDING 0x02 @@ -38,6 +40,11 @@ #define USBTMC488_REQUEST_GOTO_LOCAL 161 #define USBTMC488_REQUEST_LOCAL_LOCKOUT 162 +struct usbtmc_termchar { + __u8 term_char; + __u8 term_char_enabled; +} __attribute__ ((packed)); + /* Request values for USBTMC driver's ioctl entry point */ #define USBTMC_IOC_NR 91 #define USBTMC_IOCTL_INDICATOR_PULSE _IO(USBTMC_IOC_NR, 1) @@ -46,11 +53,17 @@ #define USBTMC_IOCTL_ABORT_BULK_IN _IO(USBTMC_IOC_NR, 4) #define USBTMC_IOCTL_CLEAR_OUT_HALT _IO(USBTMC_IOC_NR, 6) #define USBTMC_IOCTL_CLEAR_IN_HALT _IO(USBTMC_IOC_NR, 7) +#define USBTMC_IOCTL_GET_TIMEOUT _IOR(USBTMC_IOC_NR, 9, __u32) +#define USBTMC_IOCTL_SET_TIMEOUT _IOW(USBTMC_IOC_NR, 10, __u32) +#define USBTMC_IOCTL_EOM_ENABLE _IOW(USBTMC_IOC_NR, 11, __u8) +#define USBTMC_IOCTL_CONFIG_TERMCHAR _IOW(USBTMC_IOC_NR, 12, struct usbtmc_termchar) + #define USBTMC488_IOCTL_GET_CAPS _IOR(USBTMC_IOC_NR, 17, unsigned char) #define USBTMC488_IOCTL_READ_STB _IOR(USBTMC_IOC_NR, 18, unsigned char) #define USBTMC488_IOCTL_REN_CONTROL _IOW(USBTMC_IOC_NR, 19, unsigned char) #define USBTMC488_IOCTL_GOTO_LOCAL _IO(USBTMC_IOC_NR, 20) #define USBTMC488_IOCTL_LOCAL_LOCKOUT _IO(USBTMC_IOC_NR, 21) +#define USBTMC488_IOCTL_TRIGGER _IO(USBTMC_IOC_NR, 22) /* Driver encoded usb488 capabilities */ #define USBTMC488_CAPABILITY_TRIGGER 1 diff --git a/include/uapi/rdma/cxgb4-abi.h b/include/uapi/rdma/cxgb4-abi.h index a159ba8dcf8f..f85ec1a3f727 100644 --- a/include/uapi/rdma/cxgb4-abi.h +++ b/include/uapi/rdma/cxgb4-abi.h @@ -44,6 +44,16 @@ * In particular do not use pointer types -- pass pointers in __aligned_u64 * instead. */ + +enum { + C4IW_64B_CQE = (1 << 0) +}; + +struct c4iw_create_cq { + __u32 flags; + __u32 reserved; +}; + struct c4iw_create_cq_resp { __aligned_u64 key; __aligned_u64 gts_key; @@ -51,11 +61,12 @@ struct c4iw_create_cq_resp { __u32 cqid; __u32 size; __u32 qid_mask; - __u32 reserved; /* explicit padding (optional for i386) */ + __u32 flags; }; enum { - C4IW_QPF_ONCHIP = (1 << 0) + C4IW_QPF_ONCHIP = (1 << 0), + C4IW_QPF_WRITE_W_IMM = (1 << 1) }; struct c4iw_create_qp_resp { @@ -74,6 +85,23 @@ struct c4iw_create_qp_resp { __u32 flags; }; +struct c4iw_create_srq_resp { + __aligned_u64 srq_key; + __aligned_u64 srq_db_gts_key; + __aligned_u64 srq_memsize; + __u32 srqid; + __u32 srq_size; + __u32 rqt_abs_idx; + __u32 qid_mask; + __u32 flags; + __u32 reserved; /* explicit padding */ +}; + +enum { + /* HW supports SRQ_LIMIT_REACHED event */ + T4_SRQ_LIMIT_SUPPORT = 1 << 0, +}; + struct c4iw_alloc_ucontext_resp { __aligned_u64 status_page_key; __u32 status_page_size; diff --git a/include/uapi/rdma/hns-abi.h b/include/uapi/rdma/hns-abi.h index 78613b609fa8..c1f87735514f 100644 --- a/include/uapi/rdma/hns-abi.h +++ b/include/uapi/rdma/hns-abi.h @@ -53,6 +53,7 @@ struct hns_roce_ib_create_qp { __u8 log_sq_stride; __u8 sq_no_prefetch; __u8 reserved[5]; + __aligned_u64 sdb_addr; }; struct hns_roce_ib_create_qp_resp { diff --git a/include/uapi/rdma/ib_user_ioctl_cmds.h b/include/uapi/rdma/ib_user_ioctl_cmds.h index 888ac5975a6c..2c881aaf05c2 100644 --- a/include/uapi/rdma/ib_user_ioctl_cmds.h +++ b/include/uapi/rdma/ib_user_ioctl_cmds.h @@ -79,7 +79,7 @@ enum uverbs_attrs_destroy_cq_cmd_attr_ids { }; enum uverbs_attrs_create_flow_action_esp { - UVERBS_ATTR_FLOW_ACTION_ESP_HANDLE, + UVERBS_ATTR_CREATE_FLOW_ACTION_ESP_HANDLE, UVERBS_ATTR_FLOW_ACTION_ESP_ATTRS, UVERBS_ATTR_FLOW_ACTION_ESP_ESN, UVERBS_ATTR_FLOW_ACTION_ESP_KEYMAT, @@ -87,6 +87,11 @@ enum uverbs_attrs_create_flow_action_esp { UVERBS_ATTR_FLOW_ACTION_ESP_ENCAP, }; +enum uverbs_attrs_modify_flow_action_esp { + UVERBS_ATTR_MODIFY_FLOW_ACTION_ESP_HANDLE = + UVERBS_ATTR_CREATE_FLOW_ACTION_ESP_HANDLE, +}; + enum uverbs_attrs_destroy_flow_action_esp { UVERBS_ATTR_DESTROY_FLOW_ACTION_HANDLE, }; diff --git a/include/uapi/rdma/ib_user_ioctl_verbs.h b/include/uapi/rdma/ib_user_ioctl_verbs.h index 625545d862d7..6cdf192070a2 100644 --- a/include/uapi/rdma/ib_user_ioctl_verbs.h +++ b/include/uapi/rdma/ib_user_ioctl_verbs.h @@ -40,6 +40,59 @@ #define RDMA_UAPI_PTR(_type, _name) __aligned_u64 _name #endif +enum ib_uverbs_access_flags { + IB_UVERBS_ACCESS_LOCAL_WRITE = 1 << 0, + IB_UVERBS_ACCESS_REMOTE_WRITE = 1 << 1, + IB_UVERBS_ACCESS_REMOTE_READ = 1 << 2, + IB_UVERBS_ACCESS_REMOTE_ATOMIC = 1 << 3, + IB_UVERBS_ACCESS_MW_BIND = 1 << 4, + IB_UVERBS_ACCESS_ZERO_BASED = 1 << 5, + IB_UVERBS_ACCESS_ON_DEMAND = 1 << 6, + IB_UVERBS_ACCESS_HUGETLB = 1 << 7, +}; + +enum ib_uverbs_query_port_cap_flags { + IB_UVERBS_PCF_SM = 1 << 1, + IB_UVERBS_PCF_NOTICE_SUP = 1 << 2, + IB_UVERBS_PCF_TRAP_SUP = 1 << 3, + IB_UVERBS_PCF_OPT_IPD_SUP = 1 << 4, + IB_UVERBS_PCF_AUTO_MIGR_SUP = 1 << 5, + IB_UVERBS_PCF_SL_MAP_SUP = 1 << 6, + IB_UVERBS_PCF_MKEY_NVRAM = 1 << 7, + IB_UVERBS_PCF_PKEY_NVRAM = 1 << 8, + IB_UVERBS_PCF_LED_INFO_SUP = 1 << 9, + IB_UVERBS_PCF_SM_DISABLED = 1 << 10, + IB_UVERBS_PCF_SYS_IMAGE_GUID_SUP = 1 << 11, + IB_UVERBS_PCF_PKEY_SW_EXT_PORT_TRAP_SUP = 1 << 12, + IB_UVERBS_PCF_EXTENDED_SPEEDS_SUP = 1 << 14, + IB_UVERBS_PCF_CM_SUP = 1 << 16, + IB_UVERBS_PCF_SNMP_TUNNEL_SUP = 1 << 17, + IB_UVERBS_PCF_REINIT_SUP = 1 << 18, + IB_UVERBS_PCF_DEVICE_MGMT_SUP = 1 << 19, + IB_UVERBS_PCF_VENDOR_CLASS_SUP = 1 << 20, + IB_UVERBS_PCF_DR_NOTICE_SUP = 1 << 21, + IB_UVERBS_PCF_CAP_MASK_NOTICE_SUP = 1 << 22, + IB_UVERBS_PCF_BOOT_MGMT_SUP = 1 << 23, + IB_UVERBS_PCF_LINK_LATENCY_SUP = 1 << 24, + IB_UVERBS_PCF_CLIENT_REG_SUP = 1 << 25, + /* + * IsOtherLocalChangesNoticeSupported is aliased by IP_BASED_GIDS and + * is inaccessible + */ + IB_UVERBS_PCF_LINK_SPEED_WIDTH_TABLE_SUP = 1 << 27, + IB_UVERBS_PCF_VENDOR_SPECIFIC_MADS_TABLE_SUP = 1 << 28, + IB_UVERBS_PCF_MCAST_PKEY_TRAP_SUPPRESSION_SUP = 1 << 29, + IB_UVERBS_PCF_MCAST_FDB_TOP_SUP = 1 << 30, + IB_UVERBS_PCF_HIERARCHY_INFO_SUP = 1ULL << 31, + + /* NOTE this is an internal flag, not an IBA flag */ + IB_UVERBS_PCF_IP_BASED_GIDS = 1 << 26, +}; + +enum ib_uverbs_query_port_flags { + IB_UVERBS_QPF_GRH_REQUIRED = 1 << 0, +}; + enum ib_uverbs_flow_action_esp_keymat { IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM, }; @@ -99,4 +152,9 @@ struct ib_uverbs_flow_action_esp { __aligned_u64 hard_limit_pkts; }; +enum ib_uverbs_read_counters_flags { + /* prefer read values from driver cache */ + IB_UVERBS_READ_COUNTERS_PREFER_CACHED = 1 << 0, +}; + #endif diff --git a/include/uapi/rdma/ib_user_verbs.h b/include/uapi/rdma/ib_user_verbs.h index 4f9991de8e3a..25a16760de2a 100644 --- a/include/uapi/rdma/ib_user_verbs.h +++ b/include/uapi/rdma/ib_user_verbs.h @@ -279,7 +279,7 @@ struct ib_uverbs_query_port { }; struct ib_uverbs_query_port_resp { - __u32 port_cap_flags; + __u32 port_cap_flags; /* see ib_uverbs_query_port_cap_flags */ __u32 max_msg_sz; __u32 bad_pkey_cntr; __u32 qkey_viol_cntr; @@ -299,7 +299,8 @@ struct ib_uverbs_query_port_resp { __u8 active_speed; __u8 phys_state; __u8 link_layer; - __u8 reserved[2]; + __u8 flags; /* see ib_uverbs_query_port_flags */ + __u8 reserved; }; struct ib_uverbs_alloc_pd { diff --git a/include/uapi/rdma/mlx5-abi.h b/include/uapi/rdma/mlx5-abi.h index 8daec1fa49cf..addbb9c4529e 100644 --- a/include/uapi/rdma/mlx5-abi.h +++ b/include/uapi/rdma/mlx5-abi.h @@ -76,6 +76,9 @@ enum mlx5_lib_caps { MLX5_LIB_CAP_4K_UAR = (__u64)1 << 0, }; +enum mlx5_ib_alloc_uctx_v2_flags { + MLX5_IB_ALLOC_UCTX_DEVX = 1 << 0, +}; struct mlx5_ib_alloc_ucontext_req_v2 { __u32 total_num_bfregs; __u32 num_low_latency_bfregs; @@ -90,6 +93,7 @@ struct mlx5_ib_alloc_ucontext_req_v2 { enum mlx5_ib_alloc_ucontext_resp_mask { MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_CORE_CLOCK_OFFSET = 1UL << 0, + MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_DUMP_FILL_MKEY = 1UL << 1, }; enum mlx5_user_cmds_supp_uhw { @@ -138,7 +142,7 @@ struct mlx5_ib_alloc_ucontext_resp { __u32 log_uar_size; __u32 num_uars_per_page; __u32 num_dyn_bfregs; - __u32 reserved3; + __u32 dump_fill_mkey; }; struct mlx5_ib_alloc_pd_resp { diff --git a/include/uapi/rdma/mlx5_user_ioctl_cmds.h b/include/uapi/rdma/mlx5_user_ioctl_cmds.h index f7d685ef2d1f..9c51801b9e64 100644 --- a/include/uapi/rdma/mlx5_user_ioctl_cmds.h +++ b/include/uapi/rdma/mlx5_user_ioctl_cmds.h @@ -33,6 +33,7 @@ #ifndef MLX5_USER_IOCTL_CMDS_H #define MLX5_USER_IOCTL_CMDS_H +#include <linux/types.h> #include <rdma/ib_user_ioctl_cmds.h> enum mlx5_ib_create_flow_action_attrs { @@ -45,4 +46,124 @@ enum mlx5_ib_alloc_dm_attrs { MLX5_IB_ATTR_ALLOC_DM_RESP_PAGE_INDEX, }; +enum mlx5_ib_devx_methods { + MLX5_IB_METHOD_DEVX_OTHER = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_METHOD_DEVX_QUERY_UAR, + MLX5_IB_METHOD_DEVX_QUERY_EQN, +}; + +enum mlx5_ib_devx_other_attrs { + MLX5_IB_ATTR_DEVX_OTHER_CMD_IN = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_ATTR_DEVX_OTHER_CMD_OUT, +}; + +enum mlx5_ib_devx_obj_create_attrs { + MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_IN, + MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, +}; + +enum mlx5_ib_devx_query_uar_attrs { + MLX5_IB_ATTR_DEVX_QUERY_UAR_USER_IDX = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_ATTR_DEVX_QUERY_UAR_DEV_IDX, +}; + +enum mlx5_ib_devx_obj_destroy_attrs { + MLX5_IB_ATTR_DEVX_OBJ_DESTROY_HANDLE = (1U << UVERBS_ID_NS_SHIFT), +}; + +enum mlx5_ib_devx_obj_modify_attrs { + MLX5_IB_ATTR_DEVX_OBJ_MODIFY_HANDLE = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_IN, + MLX5_IB_ATTR_DEVX_OBJ_MODIFY_CMD_OUT, +}; + +enum mlx5_ib_devx_obj_query_attrs { + MLX5_IB_ATTR_DEVX_OBJ_QUERY_HANDLE = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_IN, + MLX5_IB_ATTR_DEVX_OBJ_QUERY_CMD_OUT, +}; + +enum mlx5_ib_devx_query_eqn_attrs { + MLX5_IB_ATTR_DEVX_QUERY_EQN_USER_VEC = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_ATTR_DEVX_QUERY_EQN_DEV_EQN, +}; + +enum mlx5_ib_devx_obj_methods { + MLX5_IB_METHOD_DEVX_OBJ_CREATE = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_METHOD_DEVX_OBJ_DESTROY, + MLX5_IB_METHOD_DEVX_OBJ_MODIFY, + MLX5_IB_METHOD_DEVX_OBJ_QUERY, +}; + +enum mlx5_ib_devx_umem_reg_attrs { + MLX5_IB_ATTR_DEVX_UMEM_REG_HANDLE = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_ATTR_DEVX_UMEM_REG_ADDR, + MLX5_IB_ATTR_DEVX_UMEM_REG_LEN, + MLX5_IB_ATTR_DEVX_UMEM_REG_ACCESS, + MLX5_IB_ATTR_DEVX_UMEM_REG_OUT_ID, +}; + +enum mlx5_ib_devx_umem_dereg_attrs { + MLX5_IB_ATTR_DEVX_UMEM_DEREG_HANDLE = (1U << UVERBS_ID_NS_SHIFT), +}; + +enum mlx5_ib_devx_umem_methods { + MLX5_IB_METHOD_DEVX_UMEM_REG = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_METHOD_DEVX_UMEM_DEREG, +}; + +enum mlx5_ib_objects { + MLX5_IB_OBJECT_DEVX = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_OBJECT_DEVX_OBJ, + MLX5_IB_OBJECT_DEVX_UMEM, + MLX5_IB_OBJECT_FLOW_MATCHER, +}; + +enum mlx5_ib_flow_matcher_create_attrs { + MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK, + MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE, + MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA, +}; + +enum mlx5_ib_flow_matcher_destroy_attrs { + MLX5_IB_ATTR_FLOW_MATCHER_DESTROY_HANDLE = (1U << UVERBS_ID_NS_SHIFT), +}; + +enum mlx5_ib_flow_matcher_methods { + MLX5_IB_METHOD_FLOW_MATCHER_CREATE = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_METHOD_FLOW_MATCHER_DESTROY, +}; + +#define MLX5_IB_DW_MATCH_PARAM 0x80 + +struct mlx5_ib_match_params { + __u32 match_params[MLX5_IB_DW_MATCH_PARAM]; +}; + +enum mlx5_ib_flow_type { + MLX5_IB_FLOW_TYPE_NORMAL, + MLX5_IB_FLOW_TYPE_SNIFFER, + MLX5_IB_FLOW_TYPE_ALL_DEFAULT, + MLX5_IB_FLOW_TYPE_MC_DEFAULT, +}; + +enum mlx5_ib_create_flow_attrs { + MLX5_IB_ATTR_CREATE_FLOW_HANDLE = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE, + MLX5_IB_ATTR_CREATE_FLOW_DEST_QP, + MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX, + MLX5_IB_ATTR_CREATE_FLOW_MATCHER, +}; + +enum mlx5_ib_destoy_flow_attrs { + MLX5_IB_ATTR_DESTROY_FLOW_HANDLE = (1U << UVERBS_ID_NS_SHIFT), +}; + +enum mlx5_ib_flow_methods { + MLX5_IB_METHOD_CREATE_FLOW = (1U << UVERBS_ID_NS_SHIFT), + MLX5_IB_METHOD_DESTROY_FLOW, +}; + #endif diff --git a/include/uapi/rdma/qedr-abi.h b/include/uapi/rdma/qedr-abi.h index 24c658b3c790..7a10b3a325fa 100644 --- a/include/uapi/rdma/qedr-abi.h +++ b/include/uapi/rdma/qedr-abi.h @@ -111,4 +111,21 @@ struct qedr_create_qp_uresp { __u32 reserved; }; +struct qedr_create_srq_ureq { + /* user space virtual address of producer pair */ + __aligned_u64 prod_pair_addr; + + /* user space virtual address of SRQ buffer */ + __aligned_u64 srq_addr; + + /* length of SRQ buffer */ + __aligned_u64 srq_len; +}; + +struct qedr_create_srq_uresp { + __u16 srq_id; + __u16 reserved0; + __u32 reserved1; +}; + #endif /* __QEDR_USER_H__ */ diff --git a/include/uapi/rdma/rdma_user_ioctl_cmds.h b/include/uapi/rdma/rdma_user_ioctl_cmds.h index 1da5a1e1f3a8..24800c6c1f32 100644 --- a/include/uapi/rdma/rdma_user_ioctl_cmds.h +++ b/include/uapi/rdma/rdma_user_ioctl_cmds.h @@ -62,7 +62,12 @@ struct ib_uverbs_attr { } enum_data; __u16 reserved; } attr_data; - __aligned_u64 data; /* ptr to command, inline data or idr/fd */ + union { + /* Used by PTR_IN/OUT, ENUM_IN and IDR */ + __aligned_u64 data; + /* Used by FD_IN and FD_OUT */ + __s64 data_s64; + }; }; struct ib_uverbs_ioctl_hdr { diff --git a/include/xen/interface/io/displif.h b/include/xen/interface/io/displif.h index 596578d9be3e..fdc279dc4a88 100644 --- a/include/xen/interface/io/displif.h +++ b/include/xen/interface/io/displif.h @@ -189,6 +189,13 @@ * *----------------------------- Connector settings ---------------------------- * + * unique-id + * Values: <string> + * + * After device instance initialization each connector is assigned a + * unique ID, so it can be identified by the backend by this ID. + * This can be UUID or such. + * * resolution * Values: <width, uint32_t>x<height, uint32_t> * @@ -368,6 +375,7 @@ #define XENDISPL_FIELD_EVT_CHANNEL "evt-event-channel" #define XENDISPL_FIELD_RESOLUTION "resolution" #define XENDISPL_FIELD_BE_ALLOC "be-alloc" +#define XENDISPL_FIELD_UNIQUE_ID "unique-id" /* ****************************************************************************** diff --git a/include/xen/interface/io/kbdif.h b/include/xen/interface/io/kbdif.h index e2340a4130cf..5c7630d7376e 100644 --- a/include/xen/interface/io/kbdif.h +++ b/include/xen/interface/io/kbdif.h @@ -51,6 +51,18 @@ * corresponding entries in XenStore and puts 1 as the value of the entry. * If a feature is not supported then 0 must be set or feature entry omitted. * + * feature-disable-keyboard + * Values: <uint> + * + * If there is no need to expose a virtual keyboard device by the + * frontend then this must be set to 1. + * + * feature-disable-pointer + * Values: <uint> + * + * If there is no need to expose a virtual pointer device by the + * frontend then this must be set to 1. + * * feature-abs-pointer * Values: <uint> * @@ -63,6 +75,22 @@ * Backends, which support reporting of multi-touch events * should set this to 1. * + * feature-raw-pointer + * Values: <uint> + * + * Backends, which support reporting raw (unscaled) absolute coordinates + * for pointer devices should set this to 1. Raw (unscaled) values have + * a range of [0, 0x7fff]. + * + *----------------------- Device Instance Parameters ------------------------ + * + * unique-id + * Values: <string> + * + * After device instance initialization it is assigned a unique ID, + * so every instance of the frontend can be identified by the backend + * by this ID. This can be UUID or such. + * *------------------------- Pointer Device Parameters ------------------------ * * width @@ -77,6 +105,25 @@ * Maximum Y coordinate (height) to be used by the frontend * while reporting input events, pixels, [0; UINT32_MAX]. * + *----------------------- Multi-touch Device Parameters ---------------------- + * + * multi-touch-num-contacts + * Values: <uint> + * + * Number of simultaneous touches reported. + * + * multi-touch-width + * Values: <uint> + * + * Width of the touch area to be used by the frontend + * while reporting input events, pixels, [0; UINT32_MAX]. + * + * multi-touch-height + * Values: <uint> + * + * Height of the touch area to be used by the frontend + * while reporting input events, pixels, [0; UINT32_MAX]. + * ***************************************************************************** * Frontend XenBus Nodes ***************************************************************************** @@ -98,6 +145,13 @@ * * Request backend to report multi-touch events. * + * request-raw-pointer + * Values: <uint> + * + * Request backend to report raw unscaled absolute pointer coordinates. + * This option is only valid if request-abs-pointer is also set. + * Raw unscaled coordinates have the range [0, 0x7fff] + * *----------------------- Request Transport Parameters ----------------------- * * event-channel @@ -117,25 +171,6 @@ * * OBSOLETE, not recommended for use. * PFN of the shared page. - * - *----------------------- Multi-touch Device Parameters ----------------------- - * - * multi-touch-num-contacts - * Values: <uint> - * - * Number of simultaneous touches reported. - * - * multi-touch-width - * Values: <uint> - * - * Width of the touch area to be used by the frontend - * while reporting input events, pixels, [0; UINT32_MAX]. - * - * multi-touch-height - * Values: <uint> - * - * Height of the touch area to be used by the frontend - * while reporting input events, pixels, [0; UINT32_MAX]. */ /* @@ -163,9 +198,13 @@ #define XENKBD_DRIVER_NAME "vkbd" +#define XENKBD_FIELD_FEAT_DSBL_KEYBRD "feature-disable-keyboard" +#define XENKBD_FIELD_FEAT_DSBL_POINTER "feature-disable-pointer" #define XENKBD_FIELD_FEAT_ABS_POINTER "feature-abs-pointer" +#define XENKBD_FIELD_FEAT_RAW_POINTER "feature-raw-pointer" #define XENKBD_FIELD_FEAT_MTOUCH "feature-multi-touch" #define XENKBD_FIELD_REQ_ABS_POINTER "request-abs-pointer" +#define XENKBD_FIELD_REQ_RAW_POINTER "request-raw-pointer" #define XENKBD_FIELD_REQ_MTOUCH "request-multi-touch" #define XENKBD_FIELD_RING_GREF "page-gref" #define XENKBD_FIELD_EVT_CHANNEL "event-channel" @@ -174,6 +213,7 @@ #define XENKBD_FIELD_MT_WIDTH "multi-touch-width" #define XENKBD_FIELD_MT_HEIGHT "multi-touch-height" #define XENKBD_FIELD_MT_NUM_CONTACTS "multi-touch-num-contacts" +#define XENKBD_FIELD_UNIQUE_ID "unique-id" /* OBSOLETE, not recommended for use */ #define XENKBD_FIELD_RING_REF "page-ref" diff --git a/include/xen/interface/io/sndif.h b/include/xen/interface/io/sndif.h index 78bb5d9f8d83..2aac8f73614c 100644 --- a/include/xen/interface/io/sndif.h +++ b/include/xen/interface/io/sndif.h @@ -278,13 +278,11 @@ * defined under the same device. * * unique-id - * Values: <uint32_t> + * Values: <string> * - * After stream initialization it is assigned a unique ID (within the front - * driver), so every stream of the frontend can be identified by the - * backend by this ID. This is not equal to stream-idx as the later is - * zero based within the device, but this index is contigous within the - * driver. + * After stream initialization it is assigned a unique ID, so every + * stream of the frontend can be identified by the backend by this ID. + * This can be UUID or such. * *-------------------- Stream Request Transport Parameters -------------------- * |