From e20eaa2382e7888a4e06ccb015c476a6fb1fda0c Mon Sep 17 00:00:00 2001 From: Tina Zhang Date: Thu, 23 Nov 2017 16:26:35 +0800 Subject: vfio: ABI for mdev display dma-buf operation Add VFIO_DEVICE_QUERY_GFX_PLANE ioctl command to let user query and get a plane and its information. So far, two types of buffers are supported: buffers based on dma-buf and buffers based on region. This ioctl can be invoked with: 1) Either DMABUF or REGION flag. Vendor driver returns a plane_info successfully only when the specific kind of buffer is supported. 2) Flag PROBE. And at the same time either DMABUF or REGION must be set, so that vendor driver returns success only when the specific kind of buffer is supported. Add VFIO_DEVICE_GET_GFX_DMABUF ioctl command to let user get a specific dma-buf fd of an exposed MDEV buffer provided by dmabuf_id which was returned in VFIO_DEVICE_QUERY_GFX_PLANE ioctl command. The life cycle of an exposed MDEV buffer is handled by userspace and tracked by kernel space. The returned dmabuf_id in struct vfio_device_ query_gfx_plane can be a new id of a new exposed buffer or an old id of a re-exported buffer. Host user can check the value of dmabuf_id to see if it needs to create new resources according to the new exposed buffer or just re-use the existing resource related to the old buffer. v18: - update comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex) v17: - modify VFIO_DEVICE_GET_GFX_DMABUF interface. (Alex) v16: - add x_hot and y_hot fields. (Gerd) - add comments for VFIO_DEVICE_GET_GFX_DMABUF. (Alex) - rebase to 4.14.0-rc6. v15: - add a ioctl to get a dmabuf for a given dmabuf id. (Gerd) v14: - add PROBE, DMABUF and REGION flags. (Alex) v12: - add drm_format_mod back. (Gerd and Zhenyu) - add region_index. (Gerd) v11: - rename plane_type to drm_plane_type. (Gerd) - move fields of vfio_device_query_gfx_plane to vfio_device_gfx_plane_info. (Gerd) - remove drm_format_mod, start fields. (Daniel) - remove plane_id. v10: - refine the ABI API VFIO_DEVICE_QUERY_GFX_PLANE. (Alex) (Gerd) v3: - add a field gvt_plane_info in the drm_i915_gem_obj structure to save the decoded plane information to avoid look up while need the plane info. (Gerd) Signed-off-by: Tina Zhang Reviewed-by: Gerd Hoffmann Reviewed-by: Kirti Wankhede Acked-by: Alex Williamson Cc: Daniel Vetter Signed-off-by: Zhenyu Wang --- include/uapi/linux/vfio.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index ae461050661a..5c1cca2ba04d 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -502,6 +502,68 @@ struct vfio_pci_hot_reset { #define VFIO_DEVICE_PCI_HOT_RESET _IO(VFIO_TYPE, VFIO_BASE + 13) +/** + * VFIO_DEVICE_QUERY_GFX_PLANE - _IOW(VFIO_TYPE, VFIO_BASE + 14, + * struct vfio_device_query_gfx_plane) + * + * Set the drm_plane_type and flags, then retrieve the gfx plane info. + * + * flags supported: + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_DMABUF are set + * to ask if the mdev supports dma-buf. 0 on support, -EINVAL on no + * support for dma-buf. + * - VFIO_GFX_PLANE_TYPE_PROBE and VFIO_GFX_PLANE_TYPE_REGION are set + * to ask if the mdev supports region. 0 on support, -EINVAL on no + * support for region. + * - VFIO_GFX_PLANE_TYPE_DMABUF or VFIO_GFX_PLANE_TYPE_REGION is set + * with each call to query the plane info. + * - Others are invalid and return -EINVAL. + * + * Note: + * 1. Plane could be disabled by guest. In that case, success will be + * returned with zero-initialized drm_format, size, width and height + * fields. + * 2. x_hot/y_hot is set to 0xFFFFFFFF if no hotspot information available + * + * Return: 0 on success, -errno on other failure. + */ +struct vfio_device_gfx_plane_info { + __u32 argsz; + __u32 flags; +#define VFIO_GFX_PLANE_TYPE_PROBE (1 << 0) +#define VFIO_GFX_PLANE_TYPE_DMABUF (1 << 1) +#define VFIO_GFX_PLANE_TYPE_REGION (1 << 2) + /* in */ + __u32 drm_plane_type; /* type of plane: DRM_PLANE_TYPE_* */ + /* out */ + __u32 drm_format; /* drm format of plane */ + __u64 drm_format_mod; /* tiled mode */ + __u32 width; /* width of plane */ + __u32 height; /* height of plane */ + __u32 stride; /* stride of plane */ + __u32 size; /* size of plane in bytes, align on page*/ + __u32 x_pos; /* horizontal position of cursor plane */ + __u32 y_pos; /* vertical position of cursor plane*/ + __u32 x_hot; /* horizontal position of cursor hotspot */ + __u32 y_hot; /* vertical position of cursor hotspot */ + union { + __u32 region_index; /* region index */ + __u32 dmabuf_id; /* dma-buf id */ + }; +}; + +#define VFIO_DEVICE_QUERY_GFX_PLANE _IO(VFIO_TYPE, VFIO_BASE + 14) + +/** + * VFIO_DEVICE_GET_GFX_DMABUF - _IOW(VFIO_TYPE, VFIO_BASE + 15, __u32) + * + * Return a new dma-buf file descriptor for an exposed guest framebuffer + * described by the provided dmabuf_id. The dmabuf_id is returned from VFIO_ + * DEVICE_QUERY_GFX_PLANE as a token of the exposed guest framebuffer. + */ + +#define VFIO_DEVICE_GET_GFX_DMABUF _IO(VFIO_TYPE, VFIO_BASE + 15) + /* -------- API for Type1 VFIO IOMMU -------- */ /** -- cgit v1.2.3-59-g8ed1b From 373d7080896a3cb3b28ae3a2abdafb7bb87552b1 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Tue, 14 Nov 2017 16:41:19 -0500 Subject: drm/amdkfd: Add CWSR support This hardware feature allows the GPU to preempt shader execution in the middle of a compute wave, save the state and restore it later to resume execution. Memory for saving the state is allocated per queue in user mode and the address and size passed to the create_queue ioctl. The size depends on the number of waves that can be in flight simultaneously on a given ASIC. Signed-off-by: Shaoyun.liu Signed-off-by: Yong Zhao Signed-off-by: Felix Kuehling Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 7 +- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 20 ++++- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 6 ++ drivers/gpu/drm/amd/amdkfd/kfd_module.c | 4 + drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c | 27 +++++++ drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 31 +++++++- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 87 +++++++++++++++++++++- include/uapi/linux/kfd_ioctl.h | 3 +- 8 files changed, 179 insertions(+), 6 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 505d39156acd..2a4612d8437a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -117,7 +117,7 @@ static int kfd_open(struct inode *inode, struct file *filep) return -EPERM; } - process = kfd_create_process(current); + process = kfd_create_process(filep); if (IS_ERR(process)) return PTR_ERR(process); @@ -206,6 +206,7 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties, q_properties->ctx_save_restore_area_address = args->ctx_save_restore_address; q_properties->ctx_save_restore_area_size = args->ctx_save_restore_size; + q_properties->ctl_stack_size = args->ctl_stack_size; if (args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE || args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE_AQL) q_properties->type = KFD_QUEUE_TYPE_COMPUTE; @@ -1088,6 +1089,10 @@ static int kfd_mmap(struct file *filp, struct vm_area_struct *vma) KFD_MMAP_EVENTS_MASK) { vma->vm_pgoff = vma->vm_pgoff ^ KFD_MMAP_EVENTS_MASK; return kfd_event_mmap(process, vma); + } else if ((vma->vm_pgoff & KFD_MMAP_RESERVED_MEM_MASK) == + KFD_MMAP_RESERVED_MEM_MASK) { + vma->vm_pgoff = vma->vm_pgoff ^ KFD_MMAP_RESERVED_MEM_MASK; + return kfd_reserved_mem_mmap(process, vma); } return -EFAULT; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 621a3b53a038..4f05eacca786 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -27,6 +27,7 @@ #include "kfd_priv.h" #include "kfd_device_queue_manager.h" #include "kfd_pm4_headers_vi.h" +#include "cwsr_trap_handler_gfx8.asm" #define MQD_SIZE_ALIGNED 768 @@ -38,7 +39,8 @@ static const struct kfd_device_info kaveri_device_info = { .ih_ring_entry_size = 4 * sizeof(uint32_t), .event_interrupt_class = &event_interrupt_class_cik, .num_of_watch_points = 4, - .mqd_size_aligned = MQD_SIZE_ALIGNED + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = false, }; static const struct kfd_device_info carrizo_device_info = { @@ -49,7 +51,8 @@ static const struct kfd_device_info carrizo_device_info = { .ih_ring_entry_size = 4 * sizeof(uint32_t), .event_interrupt_class = &event_interrupt_class_cik, .num_of_watch_points = 4, - .mqd_size_aligned = MQD_SIZE_ALIGNED + .mqd_size_aligned = MQD_SIZE_ALIGNED, + .supports_cwsr = true, }; struct kfd_deviceid { @@ -212,6 +215,17 @@ static int iommu_invalid_ppr_cb(struct pci_dev *pdev, int pasid, return AMD_IOMMU_INV_PRI_RSP_INVALID; } +static void kfd_cwsr_init(struct kfd_dev *kfd) +{ + if (cwsr_enable && kfd->device_info->supports_cwsr) { + BUILD_BUG_ON(sizeof(cwsr_trap_gfx8_hex) > PAGE_SIZE); + + kfd->cwsr_isa = cwsr_trap_gfx8_hex; + kfd->cwsr_isa_size = sizeof(cwsr_trap_gfx8_hex); + kfd->cwsr_enabled = true; + } +} + bool kgd2kfd_device_init(struct kfd_dev *kfd, const struct kgd2kfd_shared_resources *gpu_resources) { @@ -286,6 +300,8 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, goto device_iommu_pasid_error; } + kfd_cwsr_init(kfd); + if (kfd_resume(kfd)) goto kfd_resume_error; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index e202921c150e..5c065024e285 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -173,6 +173,9 @@ static int create_queue_nocpsch(struct device_queue_manager *dqm, *allocated_vmid = qpd->vmid; q->properties.vmid = qpd->vmid; + q->properties.tba_addr = qpd->tba_addr; + q->properties.tma_addr = qpd->tma_addr; + if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE) retval = create_compute_queue_nocpsch(dqm, q, qpd); else if (q->properties.type == KFD_QUEUE_TYPE_SDMA) @@ -846,6 +849,9 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, } dqm->asic_ops.init_sdma_vm(dqm, q, qpd); + + q->properties.tba_addr = qpd->tba_addr; + q->properties.tma_addr = qpd->tma_addr; retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj, &q->gart_mqd_addr, &q->properties); if (retval) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_module.c b/drivers/gpu/drm/amd/amdkfd/kfd_module.c index f744caeaee04..ee8adf654cd0 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_module.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_module.c @@ -50,6 +50,10 @@ module_param(sched_policy, int, 0444); MODULE_PARM_DESC(sched_policy, "Scheduling policy (0 = HWS (Default), 1 = HWS without over-subscription, 2 = Non-HWS (Used for debugging only)"); +int cwsr_enable = 1; +module_param(cwsr_enable, int, 0444); +MODULE_PARM_DESC(cwsr_enable, "CWSR enable (0 = Off, 1 = On (Default))"); + int max_num_of_queues_per_device = KFD_MAX_NUM_OF_QUEUES_PER_DEVICE_DEFAULT; module_param(max_num_of_queues_per_device, int, 0444); MODULE_PARM_DESC(max_num_of_queues_per_device, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c index 2ba7cea7b99b..00e1f1a9728b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c @@ -89,6 +89,28 @@ static int init_mqd(struct mqd_manager *mm, void **mqd, if (q->format == KFD_QUEUE_FORMAT_AQL) m->cp_hqd_iq_rptr = 1; + if (q->tba_addr) { + m->compute_tba_lo = lower_32_bits(q->tba_addr >> 8); + m->compute_tba_hi = upper_32_bits(q->tba_addr >> 8); + m->compute_tma_lo = lower_32_bits(q->tma_addr >> 8); + m->compute_tma_hi = upper_32_bits(q->tma_addr >> 8); + m->compute_pgm_rsrc2 |= + (1 << COMPUTE_PGM_RSRC2__TRAP_PRESENT__SHIFT); + } + + if (mm->dev->cwsr_enabled && q->ctx_save_restore_area_address) { + m->cp_hqd_persistent_state |= + (1 << CP_HQD_PERSISTENT_STATE__QSWITCH_MODE__SHIFT); + m->cp_hqd_ctx_save_base_addr_lo = + lower_32_bits(q->ctx_save_restore_area_address); + m->cp_hqd_ctx_save_base_addr_hi = + upper_32_bits(q->ctx_save_restore_area_address); + m->cp_hqd_ctx_save_size = q->ctx_save_restore_area_size; + m->cp_hqd_cntl_stack_size = q->ctl_stack_size; + m->cp_hqd_cntl_stack_offset = q->ctl_stack_size; + m->cp_hqd_wg_state_offset = q->ctl_stack_size; + } + *mqd = m; if (gart_addr) *gart_addr = addr; @@ -167,6 +189,11 @@ static int __update_mqd(struct mqd_manager *mm, void *mqd, 2 << CP_HQD_PQ_CONTROL__SLOT_BASED_WPTR__SHIFT; } + if (mm->dev->cwsr_enabled && q->ctx_save_restore_area_address) + m->cp_hqd_ctx_save_control = + atc_bit << CP_HQD_CTX_SAVE_CONTROL__ATC__SHIFT | + mtype << CP_HQD_CTX_SAVE_CONTROL__MTYPE__SHIFT; + q->is_active = (q->queue_size > 0 && q->queue_address != 0 && q->queue_percent > 0); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 47504737ab4a..a66876467995 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -41,6 +41,7 @@ #define KFD_MMAP_DOORBELL_MASK 0x8000000000000 #define KFD_MMAP_EVENTS_MASK 0x4000000000000 +#define KFD_MMAP_RESERVED_MEM_MASK 0x2000000000000 /* * When working with cp scheduler we should assign the HIQ manually or via @@ -62,6 +63,15 @@ #define KFD_MAX_NUM_OF_PROCESSES 512 #define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS 1024 +/* + * Size of the per-process TBA+TMA buffer: 2 pages + * + * The first page is the TBA used for the CWSR ISA code. The second + * page is used as TMA for daisy changing a user-mode trap handler. + */ +#define KFD_CWSR_TBA_TMA_SIZE (PAGE_SIZE * 2) +#define KFD_CWSR_TMA_OFFSET PAGE_SIZE + /* * Kernel module parameter to specify maximum number of supported queues per * device @@ -78,6 +88,8 @@ extern int max_num_of_queues_per_device; /* Kernel module parameter to specify the scheduling policy */ extern int sched_policy; +extern int cwsr_enable; + /* * Kernel module parameter to specify whether to send sigterm to HSA process on * unhandled exception @@ -131,6 +143,7 @@ struct kfd_device_info { size_t ih_ring_entry_size; uint8_t num_of_watch_points; uint16_t mqd_size_aligned; + bool supports_cwsr; }; struct kfd_mem_obj { @@ -200,6 +213,11 @@ struct kfd_dev { /* Debug manager */ struct kfd_dbgmgr *dbgmgr; + + /* CWSR */ + bool cwsr_enabled; + const void *cwsr_isa; + unsigned int cwsr_isa_size; }; /* KGD2KFD callbacks */ @@ -332,6 +350,9 @@ struct queue_properties { uint32_t eop_ring_buffer_size; uint64_t ctx_save_restore_area_address; uint32_t ctx_save_restore_area_size; + uint32_t ctl_stack_size; + uint64_t tba_addr; + uint64_t tma_addr; }; /** @@ -439,6 +460,11 @@ struct qcm_process_device { uint32_t num_gws; uint32_t num_oac; uint32_t sh_hidden_private_base; + + /* CWSR memory */ + void *cwsr_kaddr; + uint64_t tba_addr; + uint64_t tma_addr; }; @@ -563,7 +589,7 @@ struct amdkfd_ioctl_desc { void kfd_process_create_wq(void); void kfd_process_destroy_wq(void); -struct kfd_process *kfd_create_process(const struct task_struct *); +struct kfd_process *kfd_create_process(struct file *filep); struct kfd_process *kfd_get_process(const struct task_struct *); struct kfd_process *kfd_lookup_process_by_pasid(unsigned int pasid); @@ -577,6 +603,9 @@ struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev, struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev, struct kfd_process *p); +int kfd_reserved_mem_mmap(struct kfd_process *process, + struct vm_area_struct *vma); + /* Process device data iterator */ struct kfd_process_device *kfd_get_first_process_device_data( struct kfd_process *p); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 1bb9b2643d5a..39f4c19aaf61 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -28,6 +28,7 @@ #include #include #include +#include struct mm_struct; @@ -53,6 +54,8 @@ struct kfd_process_release_work { static struct kfd_process *find_process(const struct task_struct *thread); static struct kfd_process *create_process(const struct task_struct *thread); +static int kfd_process_init_cwsr(struct kfd_process *p, struct file *filep); + void kfd_process_create_wq(void) { @@ -68,9 +71,10 @@ void kfd_process_destroy_wq(void) } } -struct kfd_process *kfd_create_process(const struct task_struct *thread) +struct kfd_process *kfd_create_process(struct file *filep) { struct kfd_process *process; + struct task_struct *thread = current; if (!thread->mm) return ERR_PTR(-EINVAL); @@ -101,6 +105,8 @@ struct kfd_process *kfd_create_process(const struct task_struct *thread) up_write(&thread->mm->mmap_sem); + kfd_process_init_cwsr(process, filep); + return process; } @@ -168,6 +174,11 @@ static void kfd_process_wq_release(struct work_struct *work) amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid); list_del(&pdd->per_device_list); + + if (pdd->qpd.cwsr_kaddr) + free_pages((unsigned long)pdd->qpd.cwsr_kaddr, + get_order(KFD_CWSR_TBA_TMA_SIZE)); + kfree(pdd); } @@ -260,6 +271,46 @@ static const struct mmu_notifier_ops kfd_process_mmu_notifier_ops = { .release = kfd_process_notifier_release, }; +static int kfd_process_init_cwsr(struct kfd_process *p, struct file *filep) +{ + int err = 0; + unsigned long offset; + struct kfd_process_device *temp, *pdd = NULL; + struct kfd_dev *dev = NULL; + struct qcm_process_device *qpd = NULL; + + mutex_lock(&p->mutex); + list_for_each_entry_safe(pdd, temp, &p->per_device_data, + per_device_list) { + dev = pdd->dev; + qpd = &pdd->qpd; + if (!dev->cwsr_enabled || qpd->cwsr_kaddr) + continue; + offset = (dev->id | KFD_MMAP_RESERVED_MEM_MASK) << PAGE_SHIFT; + qpd->tba_addr = (int64_t)vm_mmap(filep, 0, + KFD_CWSR_TBA_TMA_SIZE, PROT_READ | PROT_EXEC, + MAP_SHARED, offset); + + if (IS_ERR_VALUE(qpd->tba_addr)) { + pr_err("Failure to set tba address. error -%d.\n", + (int)qpd->tba_addr); + err = qpd->tba_addr; + qpd->tba_addr = 0; + qpd->cwsr_kaddr = NULL; + goto out; + } + + memcpy(qpd->cwsr_kaddr, dev->cwsr_isa, dev->cwsr_isa_size); + + qpd->tma_addr = qpd->tba_addr + KFD_CWSR_TMA_OFFSET; + pr_debug("set tba :0x%llx, tma:0x%llx, cwsr_kaddr:%p for pqm.\n", + qpd->tba_addr, qpd->tma_addr, qpd->cwsr_kaddr); + } +out: + mutex_unlock(&p->mutex); + return err; +} + static struct kfd_process *create_process(const struct task_struct *thread) { struct kfd_process *process; @@ -535,3 +586,37 @@ struct kfd_process *kfd_lookup_process_by_pasid(unsigned int pasid) return p; } + +int kfd_reserved_mem_mmap(struct kfd_process *process, + struct vm_area_struct *vma) +{ + struct kfd_dev *dev = kfd_device_by_id(vma->vm_pgoff); + struct kfd_process_device *pdd; + struct qcm_process_device *qpd; + + if (!dev) + return -EINVAL; + if ((vma->vm_end - vma->vm_start) != KFD_CWSR_TBA_TMA_SIZE) { + pr_err("Incorrect CWSR mapping size.\n"); + return -EINVAL; + } + + pdd = kfd_get_process_device_data(dev, process); + if (!pdd) + return -EINVAL; + qpd = &pdd->qpd; + + qpd->cwsr_kaddr = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, + get_order(KFD_CWSR_TBA_TMA_SIZE)); + if (!qpd->cwsr_kaddr) { + pr_err("Error allocating per process CWSR buffer.\n"); + return -ENOMEM; + } + + vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND + | VM_NORESERVE | VM_DONTDUMP | VM_PFNMAP; + /* Mapping pages to user process */ + return remap_pfn_range(vma, vma->vm_start, + PFN_DOWN(__pa(qpd->cwsr_kaddr)), + KFD_CWSR_TBA_TMA_SIZE, vma->vm_page_prot); +} diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h index 6e80501368ae..f7563ef2e883 100644 --- a/include/uapi/linux/kfd_ioctl.h +++ b/include/uapi/linux/kfd_ioctl.h @@ -58,7 +58,8 @@ struct kfd_ioctl_create_queue_args { __u64 eop_buffer_address; /* to KFD */ __u64 eop_buffer_size; /* to KFD */ __u64 ctx_save_restore_address; /* to KFD */ - __u64 ctx_save_restore_size; /* to KFD */ + __u32 ctx_save_restore_size; /* to KFD */ + __u32 ctl_stack_size; /* to KFD */ }; struct kfd_ioctl_destroy_queue_args { -- cgit v1.2.3-59-g8ed1b From d7b9bd2248d794275b53d34e665f7c5a08c4b396 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Tue, 14 Nov 2017 16:41:20 -0500 Subject: drm/amdkfd: Add support for user-mode trap handlers A second-level user mode trap handler can be installed. The CWSR trap handler jumps to the secondary trap handler conditionally for any conditions not handled by it. This can be used e.g. for debugging or catching math exceptions. When CWSR is disabled, the user mode trap handler is installed as first level trap handler. Signed-off-by: Shaoyun.liu Signed-off-by: Jay Cornwall Signed-off-by: Felix Kuehling Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 37 +++++++++++++++++++++- .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 22 +++++++++++++ .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 5 +++ include/uapi/linux/kfd_ioctl.h | 12 ++++++- 4 files changed, 74 insertions(+), 2 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 2a4612d8437a..cc61ec289880 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -432,6 +432,38 @@ out: return err; } +static int kfd_ioctl_set_trap_handler(struct file *filep, + struct kfd_process *p, void *data) +{ + struct kfd_ioctl_set_trap_handler_args *args = data; + struct kfd_dev *dev; + int err = 0; + struct kfd_process_device *pdd; + + dev = kfd_device_by_id(args->gpu_id); + if (dev == NULL) + return -EINVAL; + + mutex_lock(&p->mutex); + + pdd = kfd_bind_process_to_device(dev, p); + if (IS_ERR(pdd)) { + err = -ESRCH; + goto out; + } + + if (dev->dqm->ops.set_trap_handler(dev->dqm, + &pdd->qpd, + args->tba_addr, + args->tma_addr)) + err = -EINVAL; + +out: + mutex_unlock(&p->mutex); + + return err; +} + static int kfd_ioctl_dbg_register(struct file *filep, struct kfd_process *p, void *data) { @@ -980,7 +1012,10 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = { kfd_ioctl_set_scratch_backing_va, 0), AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_TILE_CONFIG, - kfd_ioctl_get_tile_config, 0) + kfd_ioctl_get_tile_config, 0), + + AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_TRAP_HANDLER, + kfd_ioctl_set_trap_handler, 0), }; #define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 5c065024e285..8447810c9a1e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -1116,6 +1116,26 @@ out: return retval; } +static int set_trap_handler(struct device_queue_manager *dqm, + struct qcm_process_device *qpd, + uint64_t tba_addr, + uint64_t tma_addr) +{ + uint64_t *tma; + + if (dqm->dev->cwsr_enabled) { + /* Jump from CWSR trap handler to user trap */ + tma = (uint64_t *)(qpd->cwsr_kaddr + KFD_CWSR_TMA_OFFSET); + tma[0] = tba_addr; + tma[1] = tma_addr; + } else { + qpd->tba_addr = tba_addr; + qpd->tma_addr = tma_addr; + } + + return 0; +} + static int process_termination_nocpsch(struct device_queue_manager *dqm, struct qcm_process_device *qpd) { @@ -1247,6 +1267,7 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) dqm->ops.create_kernel_queue = create_kernel_queue_cpsch; dqm->ops.destroy_kernel_queue = destroy_kernel_queue_cpsch; dqm->ops.set_cache_memory_policy = set_cache_memory_policy; + dqm->ops.set_trap_handler = set_trap_handler; dqm->ops.process_termination = process_termination_cpsch; break; case KFD_SCHED_POLICY_NO_HWS: @@ -1262,6 +1283,7 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) dqm->ops.initialize = initialize_nocpsch; dqm->ops.uninitialize = uninitialize; dqm->ops.set_cache_memory_policy = set_cache_memory_policy; + dqm->ops.set_trap_handler = set_trap_handler; dqm->ops.process_termination = process_termination_nocpsch; break; default: diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index 5b77cb69f732..8752edf9cd9b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h @@ -123,6 +123,11 @@ struct device_queue_manager_ops { void __user *alternate_aperture_base, uint64_t alternate_aperture_size); + int (*set_trap_handler)(struct device_queue_manager *dqm, + struct qcm_process_device *qpd, + uint64_t tba_addr, + uint64_t tma_addr); + int (*process_termination)(struct device_queue_manager *dqm, struct qcm_process_device *qpd); }; diff --git a/include/uapi/linux/kfd_ioctl.h b/include/uapi/linux/kfd_ioctl.h index f7563ef2e883..f4cab5b3ba9a 100644 --- a/include/uapi/linux/kfd_ioctl.h +++ b/include/uapi/linux/kfd_ioctl.h @@ -262,6 +262,13 @@ struct kfd_ioctl_get_tile_config_args { */ }; +struct kfd_ioctl_set_trap_handler_args { + uint64_t tba_addr; /* to KFD */ + uint64_t tma_addr; /* to KFD */ + uint32_t gpu_id; /* to KFD */ + uint32_t pad; +}; + #define AMDKFD_IOCTL_BASE 'K' #define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr) #define AMDKFD_IOR(nr, type) _IOR(AMDKFD_IOCTL_BASE, nr, type) @@ -322,7 +329,10 @@ struct kfd_ioctl_get_tile_config_args { #define AMDKFD_IOC_GET_TILE_CONFIG \ AMDKFD_IOWR(0x12, struct kfd_ioctl_get_tile_config_args) +#define AMDKFD_IOC_SET_TRAP_HANDLER \ + AMDKFD_IOW(0x13, struct kfd_ioctl_set_trap_handler_args) + #define AMDKFD_COMMAND_START 0x01 -#define AMDKFD_COMMAND_END 0x13 +#define AMDKFD_COMMAND_END 0x14 #endif -- cgit v1.2.3-59-g8ed1b From 8ced390c2b18364af35e3d3f080e06f8ea96be9a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 2 Jul 2017 22:05:03 -0400 Subject: define __poll_t, annotate constants Signed-off-by: Al Viro --- arch/blackfin/include/uapi/asm/poll.h | 4 ++-- arch/frv/include/uapi/asm/poll.h | 2 +- arch/m68k/include/uapi/asm/poll.h | 2 +- arch/mips/include/uapi/asm/poll.h | 2 +- arch/sparc/include/uapi/asm/poll.h | 8 ++++---- arch/xtensa/include/uapi/asm/poll.h | 4 ++-- include/uapi/asm-generic/poll.h | 30 +++++++++++++++--------------- include/uapi/linux/types.h | 6 ++++++ 8 files changed, 32 insertions(+), 26 deletions(-) (limited to 'include/uapi/linux') diff --git a/arch/blackfin/include/uapi/asm/poll.h b/arch/blackfin/include/uapi/asm/poll.h index 8b094d43e9b7..961e49056b0a 100644 --- a/arch/blackfin/include/uapi/asm/poll.h +++ b/arch/blackfin/include/uapi/asm/poll.h @@ -9,8 +9,8 @@ #ifndef _UAPI__BFIN_POLL_H #define _UAPI__BFIN_POLL_H -#define POLLWRNORM 4 /* POLLOUT */ -#define POLLWRBAND 256 +#define POLLWRNORM (__force __poll_t)4 /* POLLOUT */ +#define POLLWRBAND (__force __poll_t)256 #include diff --git a/arch/frv/include/uapi/asm/poll.h b/arch/frv/include/uapi/asm/poll.h index 887b67288340..d7053ada7c69 100644 --- a/arch/frv/include/uapi/asm/poll.h +++ b/arch/frv/include/uapi/asm/poll.h @@ -3,7 +3,7 @@ #define _ASM_POLL_H #define POLLWRNORM POLLOUT -#define POLLWRBAND 256 +#define POLLWRBAND (__force __poll_t)256 #include diff --git a/arch/m68k/include/uapi/asm/poll.h b/arch/m68k/include/uapi/asm/poll.h index c3e3fcc15e1d..99314937fe5c 100644 --- a/arch/m68k/include/uapi/asm/poll.h +++ b/arch/m68k/include/uapi/asm/poll.h @@ -3,7 +3,7 @@ #define __m68k_POLL_H #define POLLWRNORM POLLOUT -#define POLLWRBAND 256 +#define POLLWRBAND (__force __poll_t)256 #include diff --git a/arch/mips/include/uapi/asm/poll.h b/arch/mips/include/uapi/asm/poll.h index ad289d7b7434..e937f8b1b007 100644 --- a/arch/mips/include/uapi/asm/poll.h +++ b/arch/mips/include/uapi/asm/poll.h @@ -3,7 +3,7 @@ #define __ASM_POLL_H #define POLLWRNORM POLLOUT -#define POLLWRBAND 0x0100 +#define POLLWRBAND (__force __poll_t)0x0100 #include diff --git a/arch/sparc/include/uapi/asm/poll.h b/arch/sparc/include/uapi/asm/poll.h index 72356c999125..595cb12df1f1 100644 --- a/arch/sparc/include/uapi/asm/poll.h +++ b/arch/sparc/include/uapi/asm/poll.h @@ -3,10 +3,10 @@ #define __SPARC_POLL_H #define POLLWRNORM POLLOUT -#define POLLWRBAND 256 -#define POLLMSG 512 -#define POLLREMOVE 1024 -#define POLLRDHUP 2048 +#define POLLWRBAND (__force __poll_t)256 +#define POLLMSG (__force __poll_t)512 +#define POLLREMOVE (__force __poll_t)1024 +#define POLLRDHUP (__force __poll_t)2048 #include diff --git a/arch/xtensa/include/uapi/asm/poll.h b/arch/xtensa/include/uapi/asm/poll.h index 4d249040b33d..22bbc48b9f85 100644 --- a/arch/xtensa/include/uapi/asm/poll.h +++ b/arch/xtensa/include/uapi/asm/poll.h @@ -13,8 +13,8 @@ #define _XTENSA_POLL_H #define POLLWRNORM POLLOUT -#define POLLWRBAND 0x0100 -#define POLLREMOVE 0x0800 +#define POLLWRBAND (__force __poll_t)0x0100 +#define POLLREMOVE (__force __poll_t)0x0800 #include diff --git a/include/uapi/asm-generic/poll.h b/include/uapi/asm-generic/poll.h index fefb3d2c3fac..8c0e9dd384b6 100644 --- a/include/uapi/asm-generic/poll.h +++ b/include/uapi/asm-generic/poll.h @@ -3,35 +3,35 @@ #define __ASM_GENERIC_POLL_H /* These are specified by iBCS2 */ -#define POLLIN 0x0001 -#define POLLPRI 0x0002 -#define POLLOUT 0x0004 -#define POLLERR 0x0008 -#define POLLHUP 0x0010 -#define POLLNVAL 0x0020 +#define POLLIN (__force __poll_t)0x0001 +#define POLLPRI (__force __poll_t)0x0002 +#define POLLOUT (__force __poll_t)0x0004 +#define POLLERR (__force __poll_t)0x0008 +#define POLLHUP (__force __poll_t)0x0010 +#define POLLNVAL (__force __poll_t)0x0020 /* The rest seem to be more-or-less nonstandard. Check them! */ -#define POLLRDNORM 0x0040 -#define POLLRDBAND 0x0080 +#define POLLRDNORM (__force __poll_t)0x0040 +#define POLLRDBAND (__force __poll_t)0x0080 #ifndef POLLWRNORM -#define POLLWRNORM 0x0100 +#define POLLWRNORM (__force __poll_t)0x0100 #endif #ifndef POLLWRBAND -#define POLLWRBAND 0x0200 +#define POLLWRBAND (__force __poll_t)0x0200 #endif #ifndef POLLMSG -#define POLLMSG 0x0400 +#define POLLMSG (__force __poll_t)0x0400 #endif #ifndef POLLREMOVE -#define POLLREMOVE 0x1000 +#define POLLREMOVE (__force __poll_t)0x1000 #endif #ifndef POLLRDHUP -#define POLLRDHUP 0x2000 +#define POLLRDHUP (__force __poll_t)0x2000 #endif -#define POLLFREE 0x4000 /* currently only for epoll */ +#define POLLFREE (__force __poll_t)0x4000 /* currently only for epoll */ -#define POLL_BUSY_LOOP 0x8000 +#define POLL_BUSY_LOOP (__force __poll_t)0x8000 struct pollfd { int fd; diff --git a/include/uapi/linux/types.h b/include/uapi/linux/types.h index e3d1d0c78f3c..cd4f0b897a48 100644 --- a/include/uapi/linux/types.h +++ b/include/uapi/linux/types.h @@ -49,5 +49,11 @@ typedef __u32 __bitwise __wsum; #define __aligned_be64 __be64 __attribute__((aligned(8))) #define __aligned_le64 __le64 __attribute__((aligned(8))) +#ifdef __CHECK_POLL +typedef unsigned __bitwise __poll_t; +#else +typedef unsigned __poll_t; +#endif + #endif /* __ASSEMBLY__ */ #endif /* _UAPI_LINUX_TYPES_H */ -- cgit v1.2.3-59-g8ed1b From 9a450484089dfa8b6348eff2a918f3c8f38585b9 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 27 Nov 2017 12:29:50 +0100 Subject: lp: support 64-bit time_t user space Once we get a glibc with 64-bit time_t, the LPSETTIMEOUT ioctl stops working, since the command number and data structure no longer match. To work around that, this introduces a new command number LPSETTIMEOUT_NEW that is used whenever the modified user space evaluates the LPSETTIMEOUT macro. The trick we use is a bit convoluted but necessary: we cannot check for any macros set by the C library in linux/lp.h, because this particular header can be included before including sys/time.h. However, we can assume that by the time that LPSETTIMEOUT is seen in the code, the definition for 'timeval' and 'time_t' has been seen as well, so we can use the sizeof() operator to determine whether we should use the old or the new definition. We use the old one not only for traditional 32-bit user space with 32-bit time_t, but also for all 64-bit architectures and x32, which always use a 64-bit time_t, the new definition will be used only for 32-bit user space with 64-bit time_t, which also requires a newer kernel. The compat_ioctl() handler now implements both commands, but has to use a special case for existing x32 binaries. The native ioctl handler now implements both command numbers on both 32-bit and 64-bit, though the latter version use the same interpretation for both. This is based on an earlier patch from Bamvor. Cc: Bamvor Jian Zhang Link: http://www.spinics.net/lists/y2038/msg01162.html Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/char/lp.c | 67 +++++++++++++++++++++++++++++++++++++------------ include/uapi/linux/lp.h | 12 ++++++++- 2 files changed, 62 insertions(+), 17 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 8249762192d5..be14abf70da1 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -659,17 +659,31 @@ static int lp_do_ioctl(unsigned int minor, unsigned int cmd, return retval; } -static int lp_set_timeout(unsigned int minor, struct timeval *par_timeout) +static int lp_set_timeout(unsigned int minor, s64 tv_sec, long tv_usec) { long to_jiffies; /* Convert to jiffies, place in lp_table */ - if ((par_timeout->tv_sec < 0) || - (par_timeout->tv_usec < 0)) { + if (tv_sec < 0 || tv_usec < 0) return -EINVAL; + + /* + * we used to not check, so let's not make this fatal, + * but deal with user space passing a 32-bit tv_nsec in + * a 64-bit field, capping the timeout to 1 second + * worth of microseconds, and capping the total at + * MAX_JIFFY_OFFSET. + */ + if (tv_usec > 999999) + tv_usec = 999999; + + if (tv_sec >= MAX_SEC_IN_JIFFIES - 1) { + to_jiffies = MAX_JIFFY_OFFSET; + } else { + to_jiffies = DIV_ROUND_UP(tv_usec, 1000000/HZ); + to_jiffies += tv_sec * (long) HZ; } - to_jiffies = DIV_ROUND_UP(par_timeout->tv_usec, 1000000/HZ); - to_jiffies += par_timeout->tv_sec * (long) HZ; + if (to_jiffies <= 0) { return -EINVAL; } @@ -677,23 +691,43 @@ static int lp_set_timeout(unsigned int minor, struct timeval *par_timeout) return 0; } +static int lp_set_timeout32(unsigned int minor, void __user *arg) +{ + s32 karg[2]; + + if (copy_from_user(karg, arg, sizeof(karg))) + return -EFAULT; + + return lp_set_timeout(minor, karg[0], karg[1]); +} + +static int lp_set_timeout64(unsigned int minor, void __user *arg) +{ + s64 karg[2]; + + if (copy_from_user(karg, arg, sizeof(karg))) + return -EFAULT; + + return lp_set_timeout(minor, karg[0], karg[1]); +} + static long lp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { unsigned int minor; - struct timeval par_timeout; int ret; minor = iminor(file_inode(file)); mutex_lock(&lp_mutex); switch (cmd) { - case LPSETTIMEOUT: - if (copy_from_user(&par_timeout, (void __user *)arg, - sizeof (struct timeval))) { - ret = -EFAULT; + case LPSETTIMEOUT_OLD: + if (BITS_PER_LONG == 32) { + ret = lp_set_timeout32(minor, (void __user *)arg); break; } - ret = lp_set_timeout(minor, &par_timeout); + /* fallthrough for 64-bit */ + case LPSETTIMEOUT_NEW: + ret = lp_set_timeout64(minor, (void __user *)arg); break; default: ret = lp_do_ioctl(minor, cmd, arg, (void __user *)arg); @@ -709,18 +743,19 @@ static long lp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { unsigned int minor; - struct timeval par_timeout; int ret; minor = iminor(file_inode(file)); mutex_lock(&lp_mutex); switch (cmd) { - case LPSETTIMEOUT: - if (compat_get_timeval(&par_timeout, compat_ptr(arg))) { - ret = -EFAULT; + case LPSETTIMEOUT_OLD: + if (!COMPAT_USE_64BIT_TIME) { + ret = lp_set_timeout32(minor, (void __user *)arg); break; } - ret = lp_set_timeout(minor, &par_timeout); + /* fallthrough for x32 mode */ + case LPSETTIMEOUT_NEW: + ret = lp_set_timeout64(minor, (void __user *)arg); break; #ifdef LP_STATS case LPGETSTATS: diff --git a/include/uapi/linux/lp.h b/include/uapi/linux/lp.h index dafcfe4e4834..8589a27037d7 100644 --- a/include/uapi/linux/lp.h +++ b/include/uapi/linux/lp.h @@ -8,6 +8,8 @@ #ifndef _UAPI_LINUX_LP_H #define _UAPI_LINUX_LP_H +#include +#include /* * Per POSIX guidelines, this module reserves the LP and lp prefixes @@ -88,7 +90,15 @@ #define LPGETSTATS 0x060d /* get statistics (struct lp_stats) */ #endif #define LPGETFLAGS 0x060e /* get status flags */ -#define LPSETTIMEOUT 0x060f /* set parport timeout */ +#define LPSETTIMEOUT_OLD 0x060f /* set parport timeout */ +#define LPSETTIMEOUT_NEW \ + _IOW(0x6, 0xf, __s64[2]) /* set parport timeout */ +#if __BITS_PER_LONG == 64 +#define LPSETTIMEOUT LPSETTIMEOUT_OLD +#else +#define LPSETTIMEOUT (sizeof(time_t) > sizeof(__kernel_long_t) ? \ + LPSETTIMEOUT_NEW : LPSETTIMEOUT_OLD) +#endif /* timeout for printk'ing a timeout, in jiffies (100ths of a second). This is also used for re-checking error conditions if LP_ABORT is -- cgit v1.2.3-59-g8ed1b From 26500475ac1b499d8636ff281311d633909f5d20 Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Wed, 11 Oct 2017 09:39:21 -0600 Subject: ptrace, seccomp: add support for retrieving seccomp metadata With the new SECCOMP_FILTER_FLAG_LOG, we need to be able to extract these flags for checkpoint restore, since they describe the state of a filter. So, let's add PTRACE_SECCOMP_GET_METADATA, similar to ..._GET_FILTER, which returns the metadata of the nth filter (right now, just the flags). Hopefully this will be future proof, and new per-filter metadata can be added to this struct. Signed-off-by: Tycho Andersen CC: Kees Cook CC: Andy Lutomirski CC: Oleg Nesterov Signed-off-by: Kees Cook --- include/linux/seccomp.h | 8 ++++++++ include/uapi/linux/ptrace.h | 6 ++++++ kernel/ptrace.c | 4 ++++ kernel/seccomp.c | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h index 10f25f7e4304..c723a5c4e3ff 100644 --- a/include/linux/seccomp.h +++ b/include/linux/seccomp.h @@ -95,11 +95,19 @@ static inline void get_seccomp_filter(struct task_struct *tsk) #if defined(CONFIG_SECCOMP_FILTER) && defined(CONFIG_CHECKPOINT_RESTORE) extern long seccomp_get_filter(struct task_struct *task, unsigned long filter_off, void __user *data); +extern long seccomp_get_metadata(struct task_struct *task, + unsigned long filter_off, void __user *data); #else static inline long seccomp_get_filter(struct task_struct *task, unsigned long n, void __user *data) { return -EINVAL; } +static inline long seccomp_get_metadata(struct task_struct *task, + unsigned long filter_off, + void __user *data) +{ + return -EINVAL; +} #endif /* CONFIG_SECCOMP_FILTER && CONFIG_CHECKPOINT_RESTORE */ #endif /* _LINUX_SECCOMP_H */ diff --git a/include/uapi/linux/ptrace.h b/include/uapi/linux/ptrace.h index e3939e00980b..e46d82b91166 100644 --- a/include/uapi/linux/ptrace.h +++ b/include/uapi/linux/ptrace.h @@ -66,6 +66,12 @@ struct ptrace_peeksiginfo_args { #define PTRACE_SETSIGMASK 0x420b #define PTRACE_SECCOMP_GET_FILTER 0x420c +#define PTRACE_SECCOMP_GET_METADATA 0x420d + +struct seccomp_metadata { + unsigned long filter_off; /* Input: which filter */ + unsigned int flags; /* Output: filter's flags */ +}; /* Read signals from a shared (process wide) queue */ #define PTRACE_PEEKSIGINFO_SHARED (1 << 0) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 84b1367935e4..58291e9f3276 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -1092,6 +1092,10 @@ int ptrace_request(struct task_struct *child, long request, ret = seccomp_get_filter(child, addr, datavp); break; + case PTRACE_SECCOMP_GET_METADATA: + ret = seccomp_get_metadata(child, addr, datavp); + break; + default: break; } diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 99bddaf79076..61bd9dc260c8 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -1061,6 +1061,39 @@ out: __put_seccomp_filter(filter); return ret; } + +long seccomp_get_metadata(struct task_struct *task, + unsigned long size, void __user *data) +{ + long ret; + struct seccomp_filter *filter; + struct seccomp_metadata kmd = {}; + + if (!capable(CAP_SYS_ADMIN) || + current->seccomp.mode != SECCOMP_MODE_DISABLED) { + return -EACCES; + } + + size = min_t(unsigned long, size, sizeof(kmd)); + + if (copy_from_user(&kmd, data, size)) + return -EFAULT; + + filter = get_nth_filter(task, kmd.filter_off); + if (IS_ERR(filter)) + return PTR_ERR(filter); + + memset(&kmd, 0, sizeof(kmd)); + if (filter->log) + kmd.flags |= SECCOMP_FILTER_FLAG_LOG; + + ret = size; + if (copy_to_user(data, &kmd, size)) + ret = -EFAULT; + + __put_seccomp_filter(filter); + return ret; +} #endif #ifdef CONFIG_SYSCTL -- cgit v1.2.3-59-g8ed1b From f2aa97240c84b8f258710e297ba60048bd9c153e Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Fri, 23 Dec 2016 13:13:34 +0100 Subject: tee: add TEE_IOCTL_PARAM_ATTR_META Adds TEE_IOCTL_PARAM_ATTR_META which can be used to indicate meta parameters when communicating with user space. These meta parameters can be used by supplicant support multiple parallel requests at a time. Reviewed-by: Etienne Carriere Signed-off-by: Jens Wiklander --- drivers/tee/optee/supp.c | 25 +++++++++++++++++++++++++ drivers/tee/tee_core.c | 16 ++++++++++------ include/uapi/linux/tee.h | 7 +++++++ 3 files changed, 42 insertions(+), 6 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/tee/optee/supp.c b/drivers/tee/optee/supp.c index b4ea0678a436..56aa8b929b8c 100644 --- a/drivers/tee/optee/supp.c +++ b/drivers/tee/optee/supp.c @@ -119,6 +119,27 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, return ret; } +static int supp_check_recv_params(size_t num_params, struct tee_param *params) +{ + size_t n; + + /* + * If there's memrefs we need to decrease those as they where + * increased earlier and we'll even refuse to accept any below. + */ + for (n = 0; n < num_params; n++) + if (tee_param_is_memref(params + n) && params[n].u.memref.shm) + tee_shm_put(params[n].u.memref.shm); + + /* + * We only expect parameters as TEE_IOCTL_PARAM_ATTR_TYPE_NONE (0). + */ + for (n = 0; n < num_params; n++) + if (params[n].attr) + return -EINVAL; + return 0; +} + /** * optee_supp_recv() - receive request for supplicant * @ctx: context receiving the request @@ -137,6 +158,10 @@ int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params, struct optee_supp *supp = &optee->supp; int rc; + rc = supp_check_recv_params(*num_params, param); + if (rc) + return rc; + /* * In case two threads in one supplicant is calling this function * simultaneously we need to protect the data with a mutex which diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index c78104589e42..4d0ce606f0fc 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -152,11 +152,11 @@ static int params_from_user(struct tee_context *ctx, struct tee_param *params, return -EFAULT; /* All unused attribute bits has to be zero */ - if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_TYPE_MASK) + if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_MASK) return -EINVAL; params[n].attr = ip.attr; - switch (ip.attr) { + switch (ip.attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { case TEE_IOCTL_PARAM_ATTR_TYPE_NONE: case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT: break; @@ -394,8 +394,8 @@ static int params_to_supp(struct tee_context *ctx, struct tee_ioctl_param ip; struct tee_param *p = params + n; - ip.attr = p->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK; - switch (p->attr) { + ip.attr = p->attr; + switch (p->attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: ip.a = p->u.value.a; @@ -459,6 +459,10 @@ static int tee_ioctl_supp_recv(struct tee_context *ctx, if (!params) return -ENOMEM; + rc = params_from_user(ctx, params, num_params, uarg->params); + if (rc) + goto out; + rc = ctx->teedev->desc->ops->supp_recv(ctx, &func, &num_params, params); if (rc) goto out; @@ -488,11 +492,11 @@ static int params_from_supp(struct tee_param *params, size_t num_params, return -EFAULT; /* All unused attribute bits has to be zero */ - if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_TYPE_MASK) + if (ip.attr & ~TEE_IOCTL_PARAM_ATTR_MASK) return -EINVAL; p->attr = ip.attr; - switch (ip.attr) { + switch (ip.attr & TEE_IOCTL_PARAM_ATTR_TYPE_MASK) { case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT: /* Only out and in/out values can be updated */ diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h index 688782e90140..267c12e7fd79 100644 --- a/include/uapi/linux/tee.h +++ b/include/uapi/linux/tee.h @@ -154,6 +154,13 @@ struct tee_ioctl_buf_data { */ #define TEE_IOCTL_PARAM_ATTR_TYPE_MASK 0xff +/* Meta parameter carrying extra information about the message. */ +#define TEE_IOCTL_PARAM_ATTR_META 0x100 + +/* Mask of all known attr bits */ +#define TEE_IOCTL_PARAM_ATTR_MASK \ + (TEE_IOCTL_PARAM_ATTR_TYPE_MASK | TEE_IOCTL_PARAM_ATTR_META) + /* * Matches TEEC_LOGIN_* in GP TEE Client API * Are only defined for GP compliant TEEs -- cgit v1.2.3-59-g8ed1b From 40e44a1e669d078946f46853808a60d29e6f0885 Mon Sep 17 00:00:00 2001 From: Scott Branden Date: Thu, 30 Nov 2017 11:35:59 -0800 Subject: net: ethtool: add support for reset of AP inside NIC interface. Add ETH_RESET_AP to reset the application processor(s) inside the NIC interface. Current ETH_RESET_MGMT supports a management processor inside this NIC. This is typically used for remote NIC management purposes. Application processors exist inside some SmartNICs to run various applications inside the NIC processor - be it a simple algorithm without an OS to as complex as hosting multiple VMs. Signed-off-by: Scott Branden Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- include/uapi/linux/ethtool.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index ac71559314e7..44a0b675a6bc 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -1686,6 +1686,7 @@ enum ethtool_reset_flags { ETH_RESET_PHY = 1 << 6, /* Transceiver/PHY */ ETH_RESET_RAM = 1 << 7, /* RAM shared between * multiple components */ + ETH_RESET_AP = 1 << 8, /* Application processor */ ETH_RESET_DEDICATED = 0x0000ffff, /* All components dedicated to * this interface */ -- cgit v1.2.3-59-g8ed1b From 521a72e1f2e8141d78e7699eaacda24e308ed428 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 4 Nov 2017 21:20:01 +0100 Subject: i2c: add a message flag for DMA safe buffers I2C has no requirement that the buffer of a message needs to be DMA safe. In case it is, it can now be flagged, so drivers wishing to do DMA can use the buffer directly. Reviewed-by: Jonathan Cameron Signed-off-by: Wolfram Sang Signed-off-by: Wolfram Sang --- include/uapi/linux/i2c.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/i2c.h b/include/uapi/linux/i2c.h index fe648032d6b9..f71a1751cacf 100644 --- a/include/uapi/linux/i2c.h +++ b/include/uapi/linux/i2c.h @@ -72,6 +72,9 @@ struct i2c_msg { #define I2C_M_RD 0x0001 /* read data, from slave to master */ /* I2C_M_RD is guaranteed to be 0x0001! */ #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ +#define I2C_M_DMA_SAFE 0x0200 /* the buffer of this message is DMA safe */ + /* makes only sense in kernelspace */ + /* userspace buffers are copied anyway */ #define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ -- cgit v1.2.3-59-g8ed1b From cdd77d3e193031cc67426cd671d8aa370f7dfee4 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 17 Nov 2017 16:23:08 -0800 Subject: nfit, libnvdimm: deprecate the generic SMART ioctl The kernel's ND_IOCTL_SMART_THRESHOLD command is based on a payload definition that has become broken / out-of-sync with recent versions of the NVDIMM_FAMILY_INTEL definition. Deprecate the use of the ND_IOCTL_SMART_THRESHOLD command in favor of the ND_CMD_CALL approach taken by NVDIMM_FAMILY_{HPE,MSFT}, where we can manage the per-vendor variance in userspace. In a couple years, when the new scheme is widely deployed in userspace packages, the ND_IOCTL_SMART_THRESHOLD support can be removed. For now we prevent new binaries from compiling against the kernel header definitions, but kernel still compatible with old binaries. The libndctl.h [1] header is now the authoritative interface definition for NVDIMM SMART. [1]: https://github.com/pmem/ndctl Signed-off-by: Dan Williams --- drivers/nvdimm/bus.c | 3 -- include/uapi/linux/ndctl.h | 54 -------------------------------- tools/testing/nvdimm/test/nfit.c | 39 ++++++++++++++--------- tools/testing/nvdimm/test/nfit_test.h | 59 +++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 71 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 0a5e6cd758fe..78eabc3a1ab1 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -1142,9 +1142,6 @@ int __init nvdimm_bus_init(void) { int rc; - BUILD_BUG_ON(sizeof(struct nd_smart_payload) != 128); - BUILD_BUG_ON(sizeof(struct nd_smart_threshold_payload) != 8); - rc = bus_register(&nvdimm_bus_type); if (rc) return rc; diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h index 3f03567631cb..30ef1236aafa 100644 --- a/include/uapi/linux/ndctl.h +++ b/include/uapi/linux/ndctl.h @@ -15,54 +15,6 @@ #include -struct nd_cmd_smart { - __u32 status; - __u8 data[128]; -} __packed; - -#define ND_SMART_HEALTH_VALID (1 << 0) -#define ND_SMART_SPARES_VALID (1 << 1) -#define ND_SMART_USED_VALID (1 << 2) -#define ND_SMART_TEMP_VALID (1 << 3) -#define ND_SMART_CTEMP_VALID (1 << 4) -#define ND_SMART_ALARM_VALID (1 << 9) -#define ND_SMART_SHUTDOWN_VALID (1 << 10) -#define ND_SMART_VENDOR_VALID (1 << 11) -#define ND_SMART_SPARE_TRIP (1 << 0) -#define ND_SMART_TEMP_TRIP (1 << 1) -#define ND_SMART_CTEMP_TRIP (1 << 2) -#define ND_SMART_NON_CRITICAL_HEALTH (1 << 0) -#define ND_SMART_CRITICAL_HEALTH (1 << 1) -#define ND_SMART_FATAL_HEALTH (1 << 2) - -struct nd_smart_payload { - __u32 flags; - __u8 reserved0[4]; - __u8 health; - __u8 spares; - __u8 life_used; - __u8 alarm_flags; - __u16 temperature; - __u16 ctrl_temperature; - __u8 reserved1[15]; - __u8 shutdown_state; - __u32 vendor_size; - __u8 vendor_data[92]; -} __packed; - -struct nd_cmd_smart_threshold { - __u32 status; - __u8 data[8]; -} __packed; - -struct nd_smart_threshold_payload { - __u8 alarm_control; - __u8 reserved0; - __u16 temperature; - __u8 spares; - __u8 reserved[3]; -} __packed; - struct nd_cmd_dimm_flags { __u32 status; __u32 flags; @@ -211,12 +163,6 @@ static inline const char *nvdimm_cmd_name(unsigned cmd) #define ND_IOCTL 'N' -#define ND_IOCTL_SMART _IOWR(ND_IOCTL, ND_CMD_SMART,\ - struct nd_cmd_smart) - -#define ND_IOCTL_SMART_THRESHOLD _IOWR(ND_IOCTL, ND_CMD_SMART_THRESHOLD,\ - struct nd_cmd_smart_threshold) - #define ND_IOCTL_DIMM_FLAGS _IOWR(ND_IOCTL, ND_CMD_DIMM_FLAGS,\ struct nd_cmd_dimm_flags) diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c index 7217b2b953b5..640c02b08a50 100644 --- a/tools/testing/nvdimm/test/nfit.c +++ b/tools/testing/nvdimm/test/nfit.c @@ -440,39 +440,50 @@ static int nfit_test_cmd_translate_spa(struct nvdimm_bus *bus, return 0; } -static int nfit_test_cmd_smart(struct nd_cmd_smart *smart, unsigned int buf_len) +static int nfit_test_cmd_smart(struct nd_intel_smart *smart, unsigned int buf_len) { - static const struct nd_smart_payload smart_data = { - .flags = ND_SMART_HEALTH_VALID | ND_SMART_TEMP_VALID - | ND_SMART_SPARES_VALID | ND_SMART_ALARM_VALID - | ND_SMART_USED_VALID | ND_SMART_SHUTDOWN_VALID, - .health = ND_SMART_NON_CRITICAL_HEALTH, - .temperature = 23 * 16, + static const struct nd_intel_smart smart_data = { + .flags = ND_INTEL_SMART_HEALTH_VALID + | ND_INTEL_SMART_SPARES_VALID + | ND_INTEL_SMART_ALARM_VALID + | ND_INTEL_SMART_USED_VALID + | ND_INTEL_SMART_SHUTDOWN_VALID + | ND_INTEL_SMART_MTEMP_VALID, + .health = ND_INTEL_SMART_NON_CRITICAL_HEALTH, + .media_temperature = 23 * 16, + .ctrl_temperature = 30 * 16, + .pmic_temperature = 40 * 16, .spares = 75, - .alarm_flags = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP, + .alarm_flags = ND_INTEL_SMART_SPARE_TRIP + | ND_INTEL_SMART_TEMP_TRIP, + .ait_status = 1, .life_used = 5, .shutdown_state = 0, .vendor_size = 0, + .shutdown_count = 100, }; if (buf_len < sizeof(*smart)) return -EINVAL; - memcpy(smart->data, &smart_data, sizeof(smart_data)); + memcpy(smart, &smart_data, sizeof(smart_data)); return 0; } -static int nfit_test_cmd_smart_threshold(struct nd_cmd_smart_threshold *smart_t, +static int nfit_test_cmd_smart_threshold( + struct nd_intel_smart_threshold *smart_t, unsigned int buf_len) { - static const struct nd_smart_threshold_payload smart_t_data = { - .alarm_control = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP, - .temperature = 40 * 16, + static const struct nd_intel_smart_threshold smart_t_data = { + .alarm_control = ND_INTEL_SMART_SPARE_TRIP + | ND_INTEL_SMART_TEMP_TRIP, + .media_temperature = 40 * 16, + .ctrl_temperature = 30 * 16, .spares = 5, }; if (buf_len < sizeof(*smart_t)) return -EINVAL; - memcpy(smart_t->data, &smart_t_data, sizeof(smart_t_data)); + memcpy(smart_t, &smart_t_data, sizeof(smart_t_data)); return 0; } diff --git a/tools/testing/nvdimm/test/nfit_test.h b/tools/testing/nvdimm/test/nfit_test.h index 113b44675a71..b85fba2856c7 100644 --- a/tools/testing/nvdimm/test/nfit_test.h +++ b/tools/testing/nvdimm/test/nfit_test.h @@ -84,6 +84,65 @@ struct nd_cmd_ars_err_inj_stat { } __packed record[0]; } __packed; +#define ND_INTEL_SMART 1 +#define ND_INTEL_SMART_THRESHOLD 2 + +#define ND_INTEL_SMART_HEALTH_VALID (1 << 0) +#define ND_INTEL_SMART_SPARES_VALID (1 << 1) +#define ND_INTEL_SMART_USED_VALID (1 << 2) +#define ND_INTEL_SMART_MTEMP_VALID (1 << 3) +#define ND_INTEL_SMART_CTEMP_VALID (1 << 4) +#define ND_INTEL_SMART_SHUTDOWN_COUNT_VALID (1 << 5) +#define ND_INTEL_SMART_AIT_STATUS_VALID (1 << 6) +#define ND_INTEL_SMART_PTEMP_VALID (1 << 7) +#define ND_INTEL_SMART_ALARM_VALID (1 << 9) +#define ND_INTEL_SMART_SHUTDOWN_VALID (1 << 10) +#define ND_INTEL_SMART_VENDOR_VALID (1 << 11) +#define ND_INTEL_SMART_SPARE_TRIP (1 << 0) +#define ND_INTEL_SMART_TEMP_TRIP (1 << 1) +#define ND_INTEL_SMART_CTEMP_TRIP (1 << 2) +#define ND_INTEL_SMART_NON_CRITICAL_HEALTH (1 << 0) +#define ND_INTEL_SMART_CRITICAL_HEALTH (1 << 1) +#define ND_INTEL_SMART_FATAL_HEALTH (1 << 2) + +struct nd_intel_smart { + __u32 status; + union { + struct { + __u32 flags; + __u8 reserved0[4]; + __u8 health; + __u8 spares; + __u8 life_used; + __u8 alarm_flags; + __u16 media_temperature; + __u16 ctrl_temperature; + __u32 shutdown_count; + __u8 ait_status; + __u16 pmic_temperature; + __u8 reserved1[8]; + __u8 shutdown_state; + __u32 vendor_size; + __u8 vendor_data[92]; + } __packed; + __u8 data[128]; + }; +} __packed; + +struct nd_intel_smart_threshold { + __u32 status; + union { + struct { + __u16 alarm_control; + __u8 spares; + __u16 media_temperature; + __u16 ctrl_temperature; + __u8 reserved[1]; + } __packed; + __u8 data[8]; + }; +} __packed; + union acpi_object; typedef void *acpi_handle; -- cgit v1.2.3-59-g8ed1b From f19397a5c65665d66e3866b42056f1f58b7a366b Mon Sep 17 00:00:00 2001 From: Lawrence Brakmo Date: Fri, 1 Dec 2017 10:15:04 -0800 Subject: bpf: Add access to snd_cwnd and others in sock_ops Adds read access to snd_cwnd and srtt_us fields of tcp_sock. Since these fields are only valid if the socket associated with the sock_ops program call is a full socket, the field is_fullsock is also added to the bpf_sock_ops struct. If the socket is not a full socket, reading these fields returns 0. Note that in most cases it will not be necessary to check is_fullsock to know if there is a full socket. The context of the call, as specified by the 'op' field, can sometimes determine whether there is a full socket. The struct bpf_sock_ops has the following fields added: __u32 is_fullsock; /* Some TCP fields are only valid if * there is a full socket. If not, the * fields read as zero. */ __u32 snd_cwnd; __u32 srtt_us; /* Averaged RTT << 3 in usecs */ There is a new macro, SOCK_OPS_GET_TCP32(NAME), to make it easier to add read access to more 32 bit tcp_sock fields. Signed-off-by: Lawrence Brakmo Acked-by: Alexei Starovoitov Signed-off-by: Daniel Borkmann --- include/linux/filter.h | 1 + include/net/tcp.h | 6 ++++-- include/uapi/linux/bpf.h | 6 ++++++ net/core/filter.c | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 2 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/linux/filter.h b/include/linux/filter.h index 80b5b482cb46..0062302e1285 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -985,6 +985,7 @@ struct bpf_sock_ops_kern { u32 reply; u32 replylong[4]; }; + u32 is_fullsock; }; #endif /* __LINUX_FILTER_H__ */ diff --git a/include/net/tcp.h b/include/net/tcp.h index 4e09398009c1..89a656077884 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -2012,10 +2012,12 @@ static inline int tcp_call_bpf(struct sock *sk, int op) struct bpf_sock_ops_kern sock_ops; int ret; - if (sk_fullsock(sk)) + memset(&sock_ops, 0, sizeof(sock_ops)); + if (sk_fullsock(sk)) { + sock_ops.is_fullsock = 1; sock_owned_by_me(sk); + } - memset(&sock_ops, 0, sizeof(sock_ops)); sock_ops.sk = sk; sock_ops.op = op; diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 4c223ab30293..80d62e88590c 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -941,6 +941,12 @@ struct bpf_sock_ops { __u32 local_ip6[4]; /* Stored in network byte order */ __u32 remote_port; /* Stored in network byte order */ __u32 local_port; /* stored in host byte order */ + __u32 is_fullsock; /* Some TCP fields are only valid if + * there is a full socket. If not, the + * fields read as zero. + */ + __u32 snd_cwnd; + __u32 srtt_us; /* Averaged RTT << 3 in usecs */ }; /* List of known BPF sock_ops operators. diff --git a/net/core/filter.c b/net/core/filter.c index 4d644ad17457..754abe1041b7 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -4437,6 +4437,42 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type, *insn++ = BPF_LDX_MEM(BPF_H, si->dst_reg, si->dst_reg, offsetof(struct sock_common, skc_num)); break; + + case offsetof(struct bpf_sock_ops, is_fullsock): + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( + struct bpf_sock_ops_kern, + is_fullsock), + si->dst_reg, si->src_reg, + offsetof(struct bpf_sock_ops_kern, + is_fullsock)); + break; + +/* Helper macro for adding read access to tcp_sock fields. */ +#define SOCK_OPS_GET_TCP32(FIELD_NAME) \ + do { \ + BUILD_BUG_ON(FIELD_SIZEOF(struct tcp_sock, FIELD_NAME) != 4); \ + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( \ + struct bpf_sock_ops_kern, \ + is_fullsock), \ + si->dst_reg, si->src_reg, \ + offsetof(struct bpf_sock_ops_kern, \ + is_fullsock)); \ + *insn++ = BPF_JMP_IMM(BPF_JEQ, si->dst_reg, 0, 2); \ + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( \ + struct bpf_sock_ops_kern, sk),\ + si->dst_reg, si->src_reg, \ + offsetof(struct bpf_sock_ops_kern, sk));\ + *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg, \ + offsetof(struct tcp_sock, FIELD_NAME)); \ + } while (0) + + case offsetof(struct bpf_sock_ops, snd_cwnd): + SOCK_OPS_GET_TCP32(snd_cwnd); + break; + + case offsetof(struct bpf_sock_ops, srtt_us): + SOCK_OPS_GET_TCP32(srtt_us); + break; } return insn - insn_buf; } -- cgit v1.2.3-59-g8ed1b From 96f84061620c6325a2ca9a9a05b410e6461d03c3 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Mon, 4 Dec 2017 17:31:23 +0800 Subject: tun: add eBPF based queue selection method This patch introduces an eBPF based queue selection method. With this, the policy could be offloaded to userspace completely through a new ioctl TUNSETSTEERINGEBPF. Signed-off-by: Jason Wang Acked-by: Willem de Bruijn Signed-off-by: David S. Miller --- drivers/net/tun.c | 145 +++++++++++++++++++++++++++++++++++++------- include/uapi/linux/if_tun.h | 1 + 2 files changed, 123 insertions(+), 23 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 80568f81a7c8..787cc35ef89b 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -195,6 +195,11 @@ struct tun_flow_entry { #define TUN_NUM_FLOW_ENTRIES 1024 +struct tun_steering_prog { + struct rcu_head rcu; + struct bpf_prog *prog; +}; + /* Since the socket were moved to tun_file, to preserve the behavior of persist * device, socket filter, sndbuf and vnet header size were restore when the * file were attached to a persist device. @@ -232,6 +237,7 @@ struct tun_struct { u32 rx_batched; struct tun_pcpu_stats __percpu *pcpu_stats; struct bpf_prog __rcu *xdp_prog; + struct tun_steering_prog __rcu *steering_prog; }; static int tun_napi_receive(struct napi_struct *napi, int budget) @@ -537,15 +543,12 @@ static inline void tun_flow_save_rps_rxhash(struct tun_flow_entry *e, u32 hash) * different rxq no. here. If we could not get rxhash, then we would * hope the rxq no. may help here. */ -static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, - void *accel_priv, select_queue_fallback_t fallback) +static u16 tun_automq_select_queue(struct tun_struct *tun, struct sk_buff *skb) { - struct tun_struct *tun = netdev_priv(dev); struct tun_flow_entry *e; u32 txq = 0; u32 numqueues = 0; - rcu_read_lock(); numqueues = READ_ONCE(tun->numqueues); txq = __skb_get_hash_symmetric(skb); @@ -563,10 +566,37 @@ static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, txq -= numqueues; } - rcu_read_unlock(); return txq; } +static u16 tun_ebpf_select_queue(struct tun_struct *tun, struct sk_buff *skb) +{ + struct tun_steering_prog *prog; + u16 ret = 0; + + prog = rcu_dereference(tun->steering_prog); + if (prog) + ret = bpf_prog_run_clear_cb(prog->prog, skb); + + return ret % tun->numqueues; +} + +static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb, + void *accel_priv, select_queue_fallback_t fallback) +{ + struct tun_struct *tun = netdev_priv(dev); + u16 ret; + + rcu_read_lock(); + if (rcu_dereference(tun->steering_prog)) + ret = tun_ebpf_select_queue(tun, skb); + else + ret = tun_automq_select_queue(tun, skb); + rcu_read_unlock(); + + return ret; +} + static inline bool tun_not_capable(struct tun_struct *tun) { const struct cred *cred = current_cred(); @@ -933,23 +963,10 @@ static int tun_net_close(struct net_device *dev) } /* Net device start xmit */ -static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) +static void tun_automq_xmit(struct tun_struct *tun, struct sk_buff *skb) { - struct tun_struct *tun = netdev_priv(dev); - int txq = skb->queue_mapping; - struct tun_file *tfile; - u32 numqueues = 0; - - rcu_read_lock(); - tfile = rcu_dereference(tun->tfiles[txq]); - numqueues = READ_ONCE(tun->numqueues); - - /* Drop packet if interface is not attached */ - if (txq >= numqueues) - goto drop; - #ifdef CONFIG_RPS - if (numqueues == 1 && static_key_false(&rps_needed)) { + if (tun->numqueues == 1 && static_key_false(&rps_needed)) { /* Select queue was not called for the skbuff, so we extract the * RPS hash and save it into the flow_table here. */ @@ -965,6 +982,26 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) } } #endif +} + +/* Net device start xmit */ +static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct tun_struct *tun = netdev_priv(dev); + int txq = skb->queue_mapping; + struct tun_file *tfile; + u32 numqueues = 0; + + rcu_read_lock(); + tfile = rcu_dereference(tun->tfiles[txq]); + numqueues = READ_ONCE(tun->numqueues); + + /* Drop packet if interface is not attached */ + if (txq >= numqueues) + goto drop; + + if (!rcu_dereference(tun->steering_prog)) + tun_automq_xmit(tun, skb); tun_debug(KERN_INFO, tun, "tun_net_xmit %d\n", skb->len); @@ -1547,7 +1584,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, int copylen; bool zerocopy = false; int err; - u32 rxhash; + u32 rxhash = 0; int skb_xdp = 1; bool frags = tun_napi_frags_enabled(tun); @@ -1735,7 +1772,10 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, rcu_read_unlock(); } - rxhash = __skb_get_hash_symmetric(skb); + rcu_read_lock(); + if (!rcu_dereference(tun->steering_prog)) + rxhash = __skb_get_hash_symmetric(skb); + rcu_read_unlock(); if (frags) { /* Exercise flow dissector code path. */ @@ -1779,7 +1819,9 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, u64_stats_update_end(&stats->syncp); put_cpu_ptr(stats); - tun_flow_update(tun, rxhash, tfile); + if (rxhash) + tun_flow_update(tun, rxhash, tfile); + return total_len; } @@ -1987,6 +2029,36 @@ static ssize_t tun_chr_read_iter(struct kiocb *iocb, struct iov_iter *to) return ret; } +static void tun_steering_prog_free(struct rcu_head *rcu) +{ + struct tun_steering_prog *prog = container_of(rcu, + struct tun_steering_prog, rcu); + + bpf_prog_destroy(prog->prog); + kfree(prog); +} + +static int __tun_set_steering_ebpf(struct tun_struct *tun, + struct bpf_prog *prog) +{ + struct tun_steering_prog *old, *new = NULL; + + if (prog) { + new = kmalloc(sizeof(*new), GFP_KERNEL); + if (!new) + return -ENOMEM; + new->prog = prog; + } + + old = rtnl_dereference(tun->steering_prog); + rcu_assign_pointer(tun->steering_prog, new); + + if (old) + call_rcu(&old->rcu, tun_steering_prog_free); + + return 0; +} + static void tun_free_netdev(struct net_device *dev) { struct tun_struct *tun = netdev_priv(dev); @@ -1995,6 +2067,9 @@ static void tun_free_netdev(struct net_device *dev) free_percpu(tun->pcpu_stats); tun_flow_uninit(tun); security_tun_dev_free_security(tun->security); + rtnl_lock(); + __tun_set_steering_ebpf(tun, NULL); + rtnl_unlock(); } static void tun_setup(struct net_device *dev) @@ -2283,6 +2358,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun->filter_attached = false; tun->sndbuf = tfile->socket.sk->sk_sndbuf; tun->rx_batched = 0; + RCU_INIT_POINTER(tun->steering_prog, NULL); tun->pcpu_stats = netdev_alloc_pcpu_stats(struct tun_pcpu_stats); if (!tun->pcpu_stats) { @@ -2475,6 +2551,25 @@ unlock: return ret; } +static int tun_set_steering_ebpf(struct tun_struct *tun, void __user *data) +{ + struct bpf_prog *prog; + int fd; + + if (copy_from_user(&fd, data, sizeof(fd))) + return -EFAULT; + + if (fd == -1) { + prog = NULL; + } else { + prog = bpf_prog_get_type(fd, BPF_PROG_TYPE_SOCKET_FILTER); + if (IS_ERR(prog)) + return PTR_ERR(prog); + } + + return __tun_set_steering_ebpf(tun, prog); +} + static long __tun_chr_ioctl(struct file *file, unsigned int cmd, unsigned long arg, int ifreq_len) { @@ -2751,6 +2846,10 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, ret = 0; break; + case TUNSETSTEERINGEBPF: + ret = tun_set_steering_ebpf(tun, argp); + break; + default: ret = -EINVAL; break; diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h index 030d3e6d6029..fb38c1797131 100644 --- a/include/uapi/linux/if_tun.h +++ b/include/uapi/linux/if_tun.h @@ -57,6 +57,7 @@ */ #define TUNSETVNETBE _IOW('T', 222, int) #define TUNGETVNETBE _IOR('T', 223, int) +#define TUNSETSTEERINGEBPF _IOR('T', 224, int) /* TUNSETIFF ifr flags */ #define IFF_TUN 0x0001 -- cgit v1.2.3-59-g8ed1b From 772a58693fc3116d05b7969223a80a6376e639eb Mon Sep 17 00:00:00 2001 From: Xin Long Date: Fri, 8 Dec 2017 21:03:58 +0800 Subject: sctp: add stream interleave enable members and sockopt This patch adds intl_enable in asoc and netns, and strm_interleave in sctp_sock to indicate if stream interleave is enabled and supported. netns intl_enable would be set via procfs, but that is not added yet until all stream interleave codes are completely implemented; asoc intl_enable will be set when doing 4-shakehands. sp strm_interleave can be set by sockopt SCTP_INTERLEAVING_SUPPORTED which is also added in this patch. This socket option is defined in section 4.3.1 of RFC8260. Note that strm_interleave can only be set by sockopt when both netns intl_enable and sp frag_interleave are set. Signed-off-by: Xin Long Acked-by: Marcelo Ricardo Leitner Acked-by: Neil Horman Signed-off-by: David S. Miller --- include/net/netns/sctp.h | 5 ++- include/net/sctp/structs.h | 2 ++ include/uapi/linux/sctp.h | 1 + net/sctp/socket.c | 88 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 94 insertions(+), 2 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/net/netns/sctp.h b/include/net/netns/sctp.h index ebc813277662..0db7fb3e4e15 100644 --- a/include/net/netns/sctp.h +++ b/include/net/netns/sctp.h @@ -122,9 +122,12 @@ struct netns_sctp { /* Flag to indicate if PR-CONFIG is enabled. */ int reconf_enable; - /* Flag to idicate if SCTP-AUTH is enabled */ + /* Flag to indicate if SCTP-AUTH is enabled */ int auth_enable; + /* Flag to indicate if stream interleave is enabled */ + int intl_enable; + /* * Policy to control SCTP IPv4 address scoping * 0 - Disable IPv4 address scoping diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 2f8f93da5dc2..7030cbe11f45 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -217,6 +217,7 @@ struct sctp_sock { disable_fragments:1, v4mapped:1, frag_interleave:1, + strm_interleave:1, recvrcvinfo:1, recvnxtinfo:1, data_ready_signalled:1; @@ -1940,6 +1941,7 @@ struct sctp_association { __u8 need_ecne:1, /* Need to send an ECNE Chunk? */ temp:1, /* Is it a temporary association? */ force_delay:1, + intl_enable:1, prsctp_enable:1, reconf_enable:1; diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h index d9adab32dbee..6ed934c65a5f 100644 --- a/include/uapi/linux/sctp.h +++ b/include/uapi/linux/sctp.h @@ -125,6 +125,7 @@ typedef __s32 sctp_assoc_t; #define SCTP_SOCKOPT_PEELOFF_FLAGS 122 #define SCTP_STREAM_SCHEDULER 123 #define SCTP_STREAM_SCHEDULER_VALUE 124 +#define SCTP_INTERLEAVING_SUPPORTED 125 /* PR-SCTP policies */ #define SCTP_PR_SCTP_NONE 0x0000 diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 3e55daa37e66..306c737bde87 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -3350,7 +3350,10 @@ static int sctp_setsockopt_fragment_interleave(struct sock *sk, if (get_user(val, (int __user *)optval)) return -EFAULT; - sctp_sk(sk)->frag_interleave = (val == 0) ? 0 : 1; + sctp_sk(sk)->frag_interleave = !!val; + + if (!sctp_sk(sk)->frag_interleave) + sctp_sk(sk)->strm_interleave = 0; return 0; } @@ -4019,6 +4022,40 @@ out: return retval; } +static int sctp_setsockopt_interleaving_supported(struct sock *sk, + char __user *optval, + unsigned int optlen) +{ + struct sctp_sock *sp = sctp_sk(sk); + struct net *net = sock_net(sk); + struct sctp_assoc_value params; + int retval = -EINVAL; + + if (optlen < sizeof(params)) + goto out; + + optlen = sizeof(params); + if (copy_from_user(¶ms, optval, optlen)) { + retval = -EFAULT; + goto out; + } + + if (params.assoc_id) + goto out; + + if (!net->sctp.intl_enable || !sp->frag_interleave) { + retval = -EPERM; + goto out; + } + + sp->strm_interleave = !!params.assoc_value; + + retval = 0; + +out: + return retval; +} + /* API 6.2 setsockopt(), getsockopt() * * Applications use setsockopt() and getsockopt() to set or retrieve @@ -4206,6 +4243,10 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname, case SCTP_STREAM_SCHEDULER_VALUE: retval = sctp_setsockopt_scheduler_value(sk, optval, optlen); break; + case SCTP_INTERLEAVING_SUPPORTED: + retval = sctp_setsockopt_interleaving_supported(sk, optval, + optlen); + break; default: retval = -ENOPROTOOPT; break; @@ -6969,6 +7010,47 @@ out: return retval; } +static int sctp_getsockopt_interleaving_supported(struct sock *sk, int len, + char __user *optval, + int __user *optlen) +{ + struct sctp_assoc_value params; + struct sctp_association *asoc; + int retval = -EFAULT; + + if (len < sizeof(params)) { + retval = -EINVAL; + goto out; + } + + len = sizeof(params); + if (copy_from_user(¶ms, optval, len)) + goto out; + + asoc = sctp_id2assoc(sk, params.assoc_id); + if (asoc) { + params.assoc_value = asoc->intl_enable; + } else if (!params.assoc_id) { + struct sctp_sock *sp = sctp_sk(sk); + + params.assoc_value = sp->strm_interleave; + } else { + retval = -EINVAL; + goto out; + } + + if (put_user(len, optlen)) + goto out; + + if (copy_to_user(optval, ¶ms, len)) + goto out; + + retval = 0; + +out: + return retval; +} + static int sctp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen) { @@ -7159,6 +7241,10 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname, retval = sctp_getsockopt_scheduler_value(sk, len, optval, optlen); break; + case SCTP_INTERLEAVING_SUPPORTED: + retval = sctp_getsockopt_interleaving_supported(sk, len, optval, + optlen); + break; default: retval = -ENOPROTOOPT; break; -- cgit v1.2.3-59-g8ed1b From 65f5e357839e40817aead853d7a7f61ff828b52b Mon Sep 17 00:00:00 2001 From: Xin Long Date: Fri, 8 Dec 2017 21:04:08 +0800 Subject: sctp: implement abort_pd for sctp_stream_interleave abort_pd is added as a member of sctp_stream_interleave, used to abort partial delivery for data or idata, called in sctp_cmd_assoc_failed. Since stream interleave allows to do partial delivery for each stream at the same time, sctp_intl_abort_pd for idata would be very different from the old function sctp_ulpq_abort_pd for data. Note that sctp_ulpevent_make_pdapi will support per stream in this patch by adding pdapi_stream and pdapi_seq in sctp_pdapi_event, as described in section 6.1.7 of RFC6458. Signed-off-by: Xin Long Acked-by: Marcelo Ricardo Leitner Acked-by: Neil Horman Signed-off-by: David S. Miller --- include/net/sctp/stream_interleave.h | 1 + include/net/sctp/ulpevent.h | 3 +- include/uapi/linux/sctp.h | 2 + net/sctp/sm_sideeffect.c | 2 +- net/sctp/stream_interleave.c | 99 ++++++++++++++++++++++++++++++++++++ net/sctp/ulpevent.c | 9 ++-- net/sctp/ulpqueue.c | 2 +- 7 files changed, 112 insertions(+), 6 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/net/sctp/stream_interleave.h b/include/net/sctp/stream_interleave.h index 317d9b3a5299..501b2be049a3 100644 --- a/include/net/sctp/stream_interleave.h +++ b/include/net/sctp/stream_interleave.h @@ -46,6 +46,7 @@ struct sctp_stream_interleave { void (*renege_events)(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, gfp_t gfp); void (*start_pd)(struct sctp_ulpq *ulpq, gfp_t gfp); + void (*abort_pd)(struct sctp_ulpq *ulpq, gfp_t gfp); }; void sctp_stream_interleave_init(struct sctp_stream *stream); diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h index ce4f2aa35d56..51b4e0626c34 100644 --- a/include/net/sctp/ulpevent.h +++ b/include/net/sctp/ulpevent.h @@ -122,7 +122,8 @@ struct sctp_ulpevent *sctp_ulpevent_make_shutdown_event( struct sctp_ulpevent *sctp_ulpevent_make_pdapi( const struct sctp_association *asoc, - __u32 indication, gfp_t gfp); + __u32 indication, __u32 sid, __u32 seq, + __u32 flags, gfp_t gfp); struct sctp_ulpevent *sctp_ulpevent_make_adaptation_indication( const struct sctp_association *asoc, gfp_t gfp); diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h index 6ed934c65a5f..4c4db14786bd 100644 --- a/include/uapi/linux/sctp.h +++ b/include/uapi/linux/sctp.h @@ -460,6 +460,8 @@ struct sctp_pdapi_event { __u32 pdapi_length; __u32 pdapi_indication; sctp_assoc_t pdapi_assoc_id; + __u32 pdapi_stream; + __u32 pdapi_seq; }; enum { SCTP_PARTIAL_DELIVERY_ABORTED=0, }; diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 36710549a4ca..8adde71fdb31 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -632,7 +632,7 @@ static void sctp_cmd_assoc_failed(struct sctp_cmd_seq *commands, struct sctp_chunk *abort; /* Cancel any partial delivery in progress. */ - sctp_ulpq_abort_pd(&asoc->ulpq, GFP_ATOMIC); + asoc->stream.si->abort_pd(&asoc->ulpq, GFP_ATOMIC); if (event_type == SCTP_EVENT_T_CHUNK && subtype.chunk == SCTP_CID_ABORT) event = sctp_ulpevent_make_assoc_change(asoc, 0, SCTP_COMM_LOST, diff --git a/net/sctp/stream_interleave.c b/net/sctp/stream_interleave.c index 4dce8d33c5ab..d15645ea338b 100644 --- a/net/sctp/stream_interleave.c +++ b/net/sctp/stream_interleave.c @@ -652,6 +652,103 @@ static void sctp_renege_events(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, sk_mem_reclaim(asoc->base.sk); } +static void sctp_intl_stream_abort_pd(struct sctp_ulpq *ulpq, __u16 sid, + __u32 mid, __u16 flags, gfp_t gfp) +{ + struct sock *sk = ulpq->asoc->base.sk; + struct sctp_ulpevent *ev = NULL; + + if (!sctp_ulpevent_type_enabled(SCTP_PARTIAL_DELIVERY_EVENT, + &sctp_sk(sk)->subscribe)) + return; + + ev = sctp_ulpevent_make_pdapi(ulpq->asoc, SCTP_PARTIAL_DELIVERY_ABORTED, + sid, mid, flags, gfp); + if (ev) { + __skb_queue_tail(&sk->sk_receive_queue, sctp_event2skb(ev)); + + if (!sctp_sk(sk)->data_ready_signalled) { + sctp_sk(sk)->data_ready_signalled = 1; + sk->sk_data_ready(sk); + } + } +} + +static void sctp_intl_reap_ordered(struct sctp_ulpq *ulpq, __u16 sid) +{ + struct sctp_stream *stream = &ulpq->asoc->stream; + struct sctp_ulpevent *cevent, *event = NULL; + struct sk_buff_head *lobby = &ulpq->lobby; + struct sk_buff *pos, *tmp; + struct sk_buff_head temp; + __u16 csid; + __u32 cmid; + + skb_queue_head_init(&temp); + sctp_skb_for_each(pos, lobby, tmp) { + cevent = (struct sctp_ulpevent *)pos->cb; + csid = cevent->stream; + cmid = cevent->mid; + + if (csid > sid) + break; + + if (csid < sid) + continue; + + if (!MID_lt(cmid, sctp_mid_peek(stream, in, csid))) + break; + + __skb_unlink(pos, lobby); + if (!event) + event = sctp_skb2event(pos); + + __skb_queue_tail(&temp, pos); + } + + if (!event && pos != (struct sk_buff *)lobby) { + cevent = (struct sctp_ulpevent *)pos->cb; + csid = cevent->stream; + cmid = cevent->mid; + + if (csid == sid && cmid == sctp_mid_peek(stream, in, csid)) { + sctp_mid_next(stream, in, csid); + __skb_unlink(pos, lobby); + __skb_queue_tail(&temp, pos); + event = sctp_skb2event(pos); + } + } + + if (event) { + sctp_intl_retrieve_ordered(ulpq, event); + sctp_enqueue_event(ulpq, event); + } +} + +static void sctp_intl_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp) +{ + struct sctp_stream *stream = &ulpq->asoc->stream; + __u16 sid; + + for (sid = 0; sid < stream->incnt; sid++) { + struct sctp_stream_in *sin = &stream->in[sid]; + __u32 mid; + + if (sin->pd_mode) { + sin->pd_mode = 0; + + mid = sin->mid; + sctp_intl_stream_abort_pd(ulpq, sid, mid, 0, gfp); + sctp_mid_skip(stream, in, sid, mid); + + sctp_intl_reap_ordered(ulpq, sid); + } + } + + /* intl abort pd happens only when all data needs to be cleaned */ + sctp_ulpq_flush(ulpq); +} + static struct sctp_stream_interleave sctp_stream_interleave_0 = { .data_chunk_len = sizeof(struct sctp_data_chunk), /* DATA process functions */ @@ -662,6 +759,7 @@ static struct sctp_stream_interleave sctp_stream_interleave_0 = { .enqueue_event = sctp_ulpq_tail_event, .renege_events = sctp_ulpq_renege, .start_pd = sctp_ulpq_partial_delivery, + .abort_pd = sctp_ulpq_abort_pd, }; static struct sctp_stream_interleave sctp_stream_interleave_1 = { @@ -674,6 +772,7 @@ static struct sctp_stream_interleave sctp_stream_interleave_1 = { .enqueue_event = sctp_enqueue_event, .renege_events = sctp_renege_events, .start_pd = sctp_intl_start_pd, + .abort_pd = sctp_intl_abort_pd, }; void sctp_stream_interleave_init(struct sctp_stream *stream) diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index d3218f3e9cf7..84207ad33e8e 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -730,8 +730,9 @@ fail: * various events. */ struct sctp_ulpevent *sctp_ulpevent_make_pdapi( - const struct sctp_association *asoc, __u32 indication, - gfp_t gfp) + const struct sctp_association *asoc, + __u32 indication, __u32 sid, __u32 seq, + __u32 flags, gfp_t gfp) { struct sctp_ulpevent *event; struct sctp_pdapi_event *pd; @@ -752,7 +753,9 @@ struct sctp_ulpevent *sctp_ulpevent_make_pdapi( * Currently unused. */ pd->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT; - pd->pdapi_flags = 0; + pd->pdapi_flags = flags; + pd->pdapi_stream = sid; + pd->pdapi_seq = seq; /* pdapi_length: 32 bits (unsigned integer) * diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index 76ec5149a093..dd53daab4a25 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c @@ -1144,7 +1144,7 @@ void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, gfp_t gfp) &sctp_sk(sk)->subscribe)) ev = sctp_ulpevent_make_pdapi(ulpq->asoc, SCTP_PARTIAL_DELIVERY_ABORTED, - gfp); + 0, 0, 0, gfp); if (ev) __skb_queue_tail(&sk->sk_receive_queue, sctp_event2skb(ev)); -- cgit v1.2.3-59-g8ed1b From aa15d3d257f9edcb8d15ed27e228d1c0080cb919 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 11 Dec 2017 11:58:21 -0500 Subject: USB: remove the URB_NO_FSBR flag The URB_NO_FSBR flag has never really been used. It was introduced as a potential way for UHCI to minimize PCI bus usage (by not attempting full-speed bulk and control transfers more than once per frame), but the flag was not set by any drivers. There's no point in keeping it around. This patch simplifies the API by removing it. Unfortunately, it does have to be kept as part of the usbfs ABI, but at least we can document in include/uapi/linux/usbdevice_fs.h that it doesn't do anything. Signed-off-by: Alan Stern Acked-by: Shuah Khan Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/usbip_protocol.txt | 1 - drivers/usb/core/devio.c | 2 -- drivers/usb/core/urb.c | 3 --- drivers/usb/host/uhci-q.c | 3 +-- drivers/usb/usbip/stub_rx.c | 3 --- include/linux/usb.h | 1 - include/uapi/linux/usbdevice_fs.h | 2 +- 7 files changed, 2 insertions(+), 13 deletions(-) (limited to 'include/uapi/linux') diff --git a/Documentation/usb/usbip_protocol.txt b/Documentation/usb/usbip_protocol.txt index 16b6fe27284c..c7a0f4c7e7f1 100644 --- a/Documentation/usb/usbip_protocol.txt +++ b/Documentation/usb/usbip_protocol.txt @@ -274,7 +274,6 @@ USBIP_CMD_SUBMIT: Submit an URB URB_SHORT_NOT_OK | 0x00000001 | only in | only in | only in | no URB_ISO_ASAP | 0x00000002 | no | no | no | yes URB_NO_TRANSFER_DMA_MAP | 0x00000004 | yes | yes | yes | yes - URB_NO_FSBR | 0x00000020 | yes | no | no | no URB_ZERO_PACKET | 0x00000040 | no | no | only out | no URB_NO_INTERRUPT | 0x00000080 | yes | yes | yes | yes URB_FREE_BUFFER | 0x00000100 | yes | yes | yes | yes diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 705c573d0257..808b370f1737 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1677,8 +1677,6 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb u |= URB_ISO_ASAP; if (uurb->flags & USBDEVFS_URB_SHORT_NOT_OK && is_in) u |= URB_SHORT_NOT_OK; - if (uurb->flags & USBDEVFS_URB_NO_FSBR) - u |= URB_NO_FSBR; if (uurb->flags & USBDEVFS_URB_ZERO_PACKET) u |= URB_ZERO_PACKET; if (uurb->flags & USBDEVFS_URB_NO_INTERRUPT) diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 9fdf137c4865..796c9b149728 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -479,9 +479,6 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) if (is_out) allowed |= URB_ZERO_PACKET; /* FALLTHROUGH */ - case USB_ENDPOINT_XFER_CONTROL: - allowed |= URB_NO_FSBR; /* only affects UHCI */ - /* FALLTHROUGH */ default: /* all non-iso endpoints */ if (!is_out) allowed |= URB_SHORT_NOT_OK; diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index d40438238938..35fcb826152c 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -73,8 +73,7 @@ static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb) { struct urb_priv *urbp = urb->hcpriv; - if (!(urb->transfer_flags & URB_NO_FSBR)) - urbp->fsbr = 1; + urbp->fsbr = 1; } static void uhci_urbp_wants_fsbr(struct uhci_hcd *uhci, struct urb_priv *urbp) diff --git a/drivers/usb/usbip/stub_rx.c b/drivers/usb/usbip/stub_rx.c index 536e037f541f..7a9aa9ff485d 100644 --- a/drivers/usb/usbip/stub_rx.c +++ b/drivers/usb/usbip/stub_rx.c @@ -412,9 +412,6 @@ static void masking_bogus_flags(struct urb *urb) if (is_out) allowed |= URB_ZERO_PACKET; /* FALLTHROUGH */ - case USB_ENDPOINT_XFER_CONTROL: - allowed |= URB_NO_FSBR; /* only affects UHCI */ - /* FALLTHROUGH */ default: /* all non-iso endpoints */ if (!is_out) allowed |= URB_SHORT_NOT_OK; diff --git a/include/linux/usb.h b/include/linux/usb.h index fbbe974661f2..fe665a0d5bce 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1293,7 +1293,6 @@ extern int usb_disabled(void); #define URB_ISO_ASAP 0x0002 /* iso-only; use the first unexpired * slot in the schedule */ #define URB_NO_TRANSFER_DMA_MAP 0x0004 /* urb->transfer_dma valid on submit */ -#define URB_NO_FSBR 0x0020 /* UHCI-specific */ #define URB_ZERO_PACKET 0x0040 /* Finish bulk OUT with short packet */ #define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt * needed */ diff --git a/include/uapi/linux/usbdevice_fs.h b/include/uapi/linux/usbdevice_fs.h index 70ed5338d447..964e87217be4 100644 --- a/include/uapi/linux/usbdevice_fs.h +++ b/include/uapi/linux/usbdevice_fs.h @@ -79,7 +79,7 @@ struct usbdevfs_connectinfo { #define USBDEVFS_URB_SHORT_NOT_OK 0x01 #define USBDEVFS_URB_ISO_ASAP 0x02 #define USBDEVFS_URB_BULK_CONTINUATION 0x04 -#define USBDEVFS_URB_NO_FSBR 0x20 +#define USBDEVFS_URB_NO_FSBR 0x20 /* Not used */ #define USBDEVFS_URB_ZERO_PACKET 0x40 #define USBDEVFS_URB_NO_INTERRUPT 0x80 -- cgit v1.2.3-59-g8ed1b From f371b304f12e31fe30207c41ca7754564e0ea4dc Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Mon, 11 Dec 2017 11:39:02 -0800 Subject: bpf/tracing: allow user space to query prog array on the same tp Commit e87c6bc3852b ("bpf: permit multiple bpf attachments for a single perf event") added support to attach multiple bpf programs to a single perf event. Although this provides flexibility, users may want to know what other bpf programs attached to the same tp interface. Besides getting visibility for the underlying bpf system, such information may also help consolidate multiple bpf programs, understand potential performance issues due to a large array, and debug (e.g., one bpf program which overwrites return code may impact subsequent program results). Commit 2541517c32be ("tracing, perf: Implement BPF programs attached to kprobes") utilized the existing perf ioctl interface and added the command PERF_EVENT_IOC_SET_BPF to attach a bpf program to a tracepoint. This patch adds a new ioctl command, given a perf event fd, to query the bpf program array attached to the same perf tracepoint event. The new uapi ioctl command: PERF_EVENT_IOC_QUERY_BPF The new uapi/linux/perf_event.h structure: struct perf_event_query_bpf { __u32 ids_len; __u32 prog_cnt; __u32 ids[0]; }; User space provides buffer "ids" for kernel to copy to. When returning from the kernel, the number of available programs in the array is set in "prog_cnt". The usage: struct perf_event_query_bpf *query = malloc(sizeof(*query) + sizeof(u32) * ids_len); query.ids_len = ids_len; err = ioctl(pmu_efd, PERF_EVENT_IOC_QUERY_BPF, query); if (err == 0) { /* query.prog_cnt is the number of available progs, * number of progs in ids: (ids_len == 0) ? 0 : query.prog_cnt */ } else if (errno == ENOSPC) { /* query.ids_len number of progs copied, * query.prog_cnt is the number of available progs */ } else { /* other errors */ } Signed-off-by: Yonghong Song Acked-by: Peter Zijlstra (Intel) Acked-by: Alexei Starovoitov Signed-off-by: Alexei Starovoitov --- include/linux/bpf.h | 4 ++++ include/uapi/linux/perf_event.h | 22 ++++++++++++++++++++++ kernel/bpf/core.c | 21 +++++++++++++++++++++ kernel/events/core.c | 3 +++ kernel/trace/bpf_trace.c | 23 +++++++++++++++++++++++ 5 files changed, 73 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/linux/bpf.h b/include/linux/bpf.h index e55e4255a210..f812ac508e9f 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -254,6 +254,7 @@ typedef unsigned long (*bpf_ctx_copy_t)(void *dst, const void *src, u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size, void *ctx, u64 ctx_size, bpf_ctx_copy_t ctx_copy); +int bpf_event_query_prog_array(struct perf_event *event, void __user *info); int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, union bpf_attr __user *uattr); @@ -285,6 +286,9 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs, void bpf_prog_array_delete_safe(struct bpf_prog_array __rcu *progs, struct bpf_prog *old_prog); +int bpf_prog_array_copy_info(struct bpf_prog_array __rcu *array, + __u32 __user *prog_ids, u32 request_cnt, + __u32 __user *prog_cnt); int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array, struct bpf_prog *exclude_prog, struct bpf_prog *include_prog, diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index b9a4953018ed..769533696483 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -418,6 +418,27 @@ struct perf_event_attr { __u16 __reserved_2; /* align to __u64 */ }; +/* + * Structure used by below PERF_EVENT_IOC_QUERY_BPF command + * to query bpf programs attached to the same perf tracepoint + * as the given perf event. + */ +struct perf_event_query_bpf { + /* + * The below ids array length + */ + __u32 ids_len; + /* + * Set by the kernel to indicate the number of + * available programs + */ + __u32 prog_cnt; + /* + * User provided buffer to store program ids + */ + __u32 ids[0]; +}; + #define perf_flags(attr) (*(&(attr)->read_format + 1)) /* @@ -433,6 +454,7 @@ struct perf_event_attr { #define PERF_EVENT_IOC_ID _IOR('$', 7, __u64 *) #define PERF_EVENT_IOC_SET_BPF _IOW('$', 8, __u32) #define PERF_EVENT_IOC_PAUSE_OUTPUT _IOW('$', 9, __u32) +#define PERF_EVENT_IOC_QUERY_BPF _IOWR('$', 10, struct perf_event_query_bpf *) enum perf_event_ioc_flags { PERF_IOC_FLAG_GROUP = 1U << 0, diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 86b50aa26ee8..b16c6f8f42b6 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -1462,6 +1462,8 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs, rcu_read_lock(); prog = rcu_dereference(progs)->progs; for (; *prog; prog++) { + if (*prog == &dummy_bpf_prog.prog) + continue; id = (*prog)->aux->id; if (copy_to_user(prog_ids + i, &id, sizeof(id))) { rcu_read_unlock(); @@ -1545,6 +1547,25 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array, return 0; } +int bpf_prog_array_copy_info(struct bpf_prog_array __rcu *array, + __u32 __user *prog_ids, u32 request_cnt, + __u32 __user *prog_cnt) +{ + u32 cnt = 0; + + if (array) + cnt = bpf_prog_array_length(array); + + if (copy_to_user(prog_cnt, &cnt, sizeof(cnt))) + return -EFAULT; + + /* return early if user requested only program count or nothing to copy */ + if (!request_cnt || !cnt) + return 0; + + return bpf_prog_array_copy_to_user(array, prog_ids, request_cnt); +} + static void bpf_prog_free_deferred(struct work_struct *work) { struct bpf_prog_aux *aux; diff --git a/kernel/events/core.c b/kernel/events/core.c index 16beab4767e1..f10609e539d4 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -4723,6 +4723,9 @@ static long _perf_ioctl(struct perf_event *event, unsigned int cmd, unsigned lon rcu_read_unlock(); return 0; } + + case PERF_EVENT_IOC_QUERY_BPF: + return bpf_event_query_prog_array(event, (void __user *)arg); default: return -ENOTTY; } diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 0ce99c379c30..b143f2a05aff 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -820,3 +820,26 @@ void perf_event_detach_bpf_prog(struct perf_event *event) unlock: mutex_unlock(&bpf_event_mutex); } + +int bpf_event_query_prog_array(struct perf_event *event, void __user *info) +{ + struct perf_event_query_bpf __user *uquery = info; + struct perf_event_query_bpf query = {}; + int ret; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (event->attr.type != PERF_TYPE_TRACEPOINT) + return -EINVAL; + if (copy_from_user(&query, uquery, sizeof(query))) + return -EFAULT; + + mutex_lock(&bpf_event_mutex); + ret = bpf_prog_array_copy_info(event->tp_event->prog_array, + uquery->ids, + query.ids_len, + &uquery->prog_cnt); + mutex_unlock(&bpf_event_mutex); + + return ret; +} -- cgit v1.2.3-59-g8ed1b From 9802d86585db91655c7d1929a4f6bbe0952ea88e Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Mon, 11 Dec 2017 11:36:48 -0500 Subject: bpf: add a bpf_override_function helper Error injection is sloppy and very ad-hoc. BPF could fill this niche perfectly with it's kprobe functionality. We could make sure errors are only triggered in specific call chains that we care about with very specific situations. Accomplish this with the bpf_override_funciton helper. This will modify the probe'd callers return value to the specified value and set the PC to an override function that simply returns, bypassing the originally probed function. This gives us a nice clean way to implement systematic error injection for all of our code paths. Acked-by: Alexei Starovoitov Acked-by: Ingo Molnar Signed-off-by: Josef Bacik Signed-off-by: Alexei Starovoitov --- arch/Kconfig | 3 +++ arch/x86/Kconfig | 1 + arch/x86/include/asm/kprobes.h | 4 +++ arch/x86/include/asm/ptrace.h | 5 ++++ arch/x86/kernel/kprobes/ftrace.c | 14 ++++++++++ include/linux/filter.h | 3 ++- include/linux/trace_events.h | 1 + include/uapi/linux/bpf.h | 7 ++++- kernel/bpf/core.c | 3 +++ kernel/bpf/verifier.c | 2 ++ kernel/events/core.c | 7 +++++ kernel/trace/Kconfig | 11 ++++++++ kernel/trace/bpf_trace.c | 35 +++++++++++++++++++++++++ kernel/trace/trace_kprobe.c | 55 +++++++++++++++++++++++++++++++++++----- kernel/trace/trace_probe.h | 12 +++++++++ 15 files changed, 154 insertions(+), 9 deletions(-) (limited to 'include/uapi/linux') diff --git a/arch/Kconfig b/arch/Kconfig index 400b9e1b2f27..d3f4aaf9cb7a 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -196,6 +196,9 @@ config HAVE_OPTPROBES config HAVE_KPROBES_ON_FTRACE bool +config HAVE_KPROBE_OVERRIDE + bool + config HAVE_NMI bool diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 8eed3f94bfc7..04d66e6fa447 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -154,6 +154,7 @@ config X86 select HAVE_KERNEL_XZ select HAVE_KPROBES select HAVE_KPROBES_ON_FTRACE + select HAVE_KPROBE_OVERRIDE select HAVE_KRETPROBES select HAVE_KVM select HAVE_LIVEPATCH if X86_64 diff --git a/arch/x86/include/asm/kprobes.h b/arch/x86/include/asm/kprobes.h index 9f2e3102e0bb..36abb23a7a35 100644 --- a/arch/x86/include/asm/kprobes.h +++ b/arch/x86/include/asm/kprobes.h @@ -67,6 +67,10 @@ extern const int kretprobe_blacklist_size; void arch_remove_kprobe(struct kprobe *p); asmlinkage void kretprobe_trampoline(void); +#ifdef CONFIG_KPROBES_ON_FTRACE +extern void arch_ftrace_kprobe_override_function(struct pt_regs *regs); +#endif + /* Architecture specific copy of original instruction*/ struct arch_specific_insn { /* copy of the original instruction */ diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 14131dd06b29..6de1fd3d0097 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -109,6 +109,11 @@ static inline unsigned long regs_return_value(struct pt_regs *regs) return regs->ax; } +static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) +{ + regs->ax = rc; +} + /* * user_mode(regs) determines whether a register set came from user * mode. On x86_32, this is true if V8086 mode was enabled OR if the diff --git a/arch/x86/kernel/kprobes/ftrace.c b/arch/x86/kernel/kprobes/ftrace.c index 8dc0161cec8f..1ea748d682fd 100644 --- a/arch/x86/kernel/kprobes/ftrace.c +++ b/arch/x86/kernel/kprobes/ftrace.c @@ -97,3 +97,17 @@ int arch_prepare_kprobe_ftrace(struct kprobe *p) p->ainsn.boostable = false; return 0; } + +asmlinkage void override_func(void); +asm( + ".type override_func, @function\n" + "override_func:\n" + " ret\n" + ".size override_func, .-override_func\n" +); + +void arch_ftrace_kprobe_override_function(struct pt_regs *regs) +{ + regs->ip = (unsigned long)&override_func; +} +NOKPROBE_SYMBOL(arch_ftrace_kprobe_override_function); diff --git a/include/linux/filter.h b/include/linux/filter.h index 0062302e1285..5feb441d3dd9 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -458,7 +458,8 @@ struct bpf_prog { locked:1, /* Program image locked? */ gpl_compatible:1, /* Is filter GPL compatible? */ cb_access:1, /* Is control block accessed? */ - dst_needed:1; /* Do we need dst entry? */ + dst_needed:1, /* Do we need dst entry? */ + kprobe_override:1; /* Do we override a kprobe? */ enum bpf_prog_type type; /* Type of BPF program */ u32 len; /* Number of filter blocks */ u32 jited_len; /* Size of jited insns in bytes */ diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index af44e7c2d577..5fea451f6e28 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -528,6 +528,7 @@ do { \ struct perf_event; DECLARE_PER_CPU(struct pt_regs, perf_trace_regs); +DECLARE_PER_CPU(int, bpf_kprobe_override); extern int perf_trace_init(struct perf_event *event); extern void perf_trace_destroy(struct perf_event *event); diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 80d62e88590c..595bda120cfb 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -677,6 +677,10 @@ union bpf_attr { * @buf: buf to fill * @buf_size: size of the buf * Return : 0 on success or negative error code + * + * int bpf_override_return(pt_regs, rc) + * @pt_regs: pointer to struct pt_regs + * @rc: the return value to set */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -736,7 +740,8 @@ union bpf_attr { FN(xdp_adjust_meta), \ FN(perf_event_read_value), \ FN(perf_prog_read_value), \ - FN(getsockopt), + FN(getsockopt), \ + FN(override_return), /* integer value in 'imm' field of BPF_CALL instruction selects which helper * function eBPF program intends to call diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index b16c6f8f42b6..d32bebf4f2de 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -1320,6 +1320,9 @@ EVAL4(PROG_NAME_LIST, 416, 448, 480, 512) bool bpf_prog_array_compatible(struct bpf_array *array, const struct bpf_prog *fp) { + if (fp->kprobe_override) + return false; + if (!array->owner_prog_type) { /* There's no owner yet where we could check for * compatibility. diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 7afa92e9b409..e807bda7fe29 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -4413,6 +4413,8 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) prog->dst_needed = 1; if (insn->imm == BPF_FUNC_get_prandom_u32) bpf_user_rnd_init_once(); + if (insn->imm == BPF_FUNC_override_return) + prog->kprobe_override = 1; if (insn->imm == BPF_FUNC_tail_call) { /* If we tail call into other programs, we * cannot make any assumptions since they can diff --git a/kernel/events/core.c b/kernel/events/core.c index f10609e539d4..5857c500721b 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -8080,6 +8080,13 @@ static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd) return -EINVAL; } + /* Kprobe override only works for kprobes, not uprobes. */ + if (prog->kprobe_override && + !(event->tp_event->flags & TRACE_EVENT_FL_KPROBE)) { + bpf_prog_put(prog); + return -EINVAL; + } + if (is_tracepoint || is_syscall_tp) { int off = trace_event_get_offsets(event->tp_event); diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index af7dad126c13..3e6fd580fe7f 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -529,6 +529,17 @@ config FUNCTION_PROFILER If in doubt, say N. +config BPF_KPROBE_OVERRIDE + bool "Enable BPF programs to override a kprobed function" + depends on BPF_EVENTS + depends on KPROBES_ON_FTRACE + depends on HAVE_KPROBE_OVERRIDE + depends on DYNAMIC_FTRACE_WITH_REGS + default n + help + Allows BPF to override the execution of a probed function and + set a different return value. This is used for error injection. + config FTRACE_MCOUNT_RECORD def_bool y depends on DYNAMIC_FTRACE diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index b143f2a05aff..e009b7ecf473 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -13,6 +13,10 @@ #include #include #include +#include +#include + +#include "trace_probe.h" #include "trace.h" u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5); @@ -76,6 +80,24 @@ unsigned int trace_call_bpf(struct trace_event_call *call, void *ctx) } EXPORT_SYMBOL_GPL(trace_call_bpf); +#ifdef CONFIG_BPF_KPROBE_OVERRIDE +BPF_CALL_2(bpf_override_return, struct pt_regs *, regs, unsigned long, rc) +{ + __this_cpu_write(bpf_kprobe_override, 1); + regs_set_return_value(regs, rc); + arch_ftrace_kprobe_override_function(regs); + return 0; +} + +static const struct bpf_func_proto bpf_override_return_proto = { + .func = bpf_override_return, + .gpl_only = true, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; +#endif + BPF_CALL_3(bpf_probe_read, void *, dst, u32, size, const void *, unsafe_ptr) { int ret; @@ -551,6 +573,10 @@ static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id func return &bpf_get_stackid_proto; case BPF_FUNC_perf_event_read_value: return &bpf_perf_event_read_value_proto; +#ifdef CONFIG_BPF_KPROBE_OVERRIDE + case BPF_FUNC_override_return: + return &bpf_override_return_proto; +#endif default: return tracing_func_proto(func_id); } @@ -768,6 +794,15 @@ int perf_event_attach_bpf_prog(struct perf_event *event, struct bpf_prog_array *new_array; int ret = -EEXIST; + /* + * Kprobe override only works for ftrace based kprobes, and only if they + * are on the opt-in list. + */ + if (prog->kprobe_override && + (!trace_kprobe_ftrace(event->tp_event) || + !trace_kprobe_error_injectable(event->tp_event))) + return -EINVAL; + mutex_lock(&bpf_event_mutex); if (event->prog) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 492700c5fb4d..5db849809a56 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -42,6 +42,7 @@ struct trace_kprobe { (offsetof(struct trace_kprobe, tp.args) + \ (sizeof(struct probe_arg) * (n))) +DEFINE_PER_CPU(int, bpf_kprobe_override); static nokprobe_inline bool trace_kprobe_is_return(struct trace_kprobe *tk) { @@ -87,6 +88,27 @@ static nokprobe_inline unsigned long trace_kprobe_nhit(struct trace_kprobe *tk) return nhit; } +int trace_kprobe_ftrace(struct trace_event_call *call) +{ + struct trace_kprobe *tk = (struct trace_kprobe *)call->data; + return kprobe_ftrace(&tk->rp.kp); +} + +int trace_kprobe_error_injectable(struct trace_event_call *call) +{ + struct trace_kprobe *tk = (struct trace_kprobe *)call->data; + unsigned long addr; + + if (tk->symbol) { + addr = (unsigned long) + kallsyms_lookup_name(trace_kprobe_symbol(tk)); + addr += tk->rp.kp.offset; + } else { + addr = (unsigned long)tk->rp.kp.addr; + } + return within_kprobe_error_injection_list(addr); +} + static int register_kprobe_event(struct trace_kprobe *tk); static int unregister_kprobe_event(struct trace_kprobe *tk); @@ -1170,7 +1192,7 @@ static int kretprobe_event_define_fields(struct trace_event_call *event_call) #ifdef CONFIG_PERF_EVENTS /* Kprobe profile handler */ -static void +static int kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs) { struct trace_event_call *call = &tk->tp.call; @@ -1179,12 +1201,29 @@ kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs) int size, __size, dsize; int rctx; - if (bpf_prog_array_valid(call) && !trace_call_bpf(call, regs)) - return; + if (bpf_prog_array_valid(call)) { + int ret; + + ret = trace_call_bpf(call, regs); + + /* + * We need to check and see if we modified the pc of the + * pt_regs, and if so clear the kprobe and return 1 so that we + * don't do the instruction skipping. Also reset our state so + * we are clean the next pass through. + */ + if (__this_cpu_read(bpf_kprobe_override)) { + __this_cpu_write(bpf_kprobe_override, 0); + reset_current_kprobe(); + return 1; + } + if (!ret) + return 0; + } head = this_cpu_ptr(call->perf_events); if (hlist_empty(head)) - return; + return 0; dsize = __get_data_size(&tk->tp, regs); __size = sizeof(*entry) + tk->tp.size + dsize; @@ -1193,13 +1232,14 @@ kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs) entry = perf_trace_buf_alloc(size, NULL, &rctx); if (!entry) - return; + return 0; entry->ip = (unsigned long)tk->rp.kp.addr; memset(&entry[1], 0, dsize); store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize); perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs, head, NULL); + return 0; } NOKPROBE_SYMBOL(kprobe_perf_func); @@ -1275,6 +1315,7 @@ static int kprobe_register(struct trace_event_call *event, static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) { struct trace_kprobe *tk = container_of(kp, struct trace_kprobe, rp.kp); + int ret = 0; raw_cpu_inc(*tk->nhit); @@ -1282,9 +1323,9 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) kprobe_trace_func(tk, regs); #ifdef CONFIG_PERF_EVENTS if (tk->tp.flags & TP_FLAG_PROFILE) - kprobe_perf_func(tk, regs); + ret = kprobe_perf_func(tk, regs); #endif - return 0; /* We don't tweek kernel, so just return 0 */ + return ret; } NOKPROBE_SYMBOL(kprobe_dispatcher); diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index fb66e3eaa192..5e54d748c84c 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -252,6 +252,8 @@ struct symbol_cache; unsigned long update_symbol_cache(struct symbol_cache *sc); void free_symbol_cache(struct symbol_cache *sc); struct symbol_cache *alloc_symbol_cache(const char *sym, long offset); +int trace_kprobe_ftrace(struct trace_event_call *call); +int trace_kprobe_error_injectable(struct trace_event_call *call); #else /* uprobes do not support symbol fetch methods */ #define fetch_symbol_u8 NULL @@ -277,6 +279,16 @@ alloc_symbol_cache(const char *sym, long offset) { return NULL; } + +static inline int trace_kprobe_ftrace(struct trace_event_call *call) +{ + return 0; +} + +static inline int trace_kprobe_error_injectable(struct trace_event_call *call) +{ + return 0; +} #endif /* CONFIG_KPROBE_EVENTS */ struct probe_arg { -- cgit v1.2.3-59-g8ed1b From 65adc27375a85beb57c3869cedb2a410fad9c288 Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Tue, 12 Dec 2017 11:37:15 -0600 Subject: gfs2: Add a next-resource-group pointer to resource groups Add a new rg_skip field to struct gfs2_rgrp, replacing __pad. The rg_skip field has the following meaning: - If rg_skip is zero, it is considered unset and not useful. - If rg_skip is non-zero, its value will be the number of blocks between this rgrp's address and the next rgrp's address. This can be used as a hint by fsck.gfs2 when rebuilding a bad rindex, for example. This will provide less dependency on the rindex in future, and allow tools such as fsck.gfs2 to iterate the resource groups without keeping the rindex around. The field is updated in gfs2_rgrp_out() so that existing file systems will have it set. This means that any resource groups that aren't ever written will not be updated. The final rgrp is a special case as there is no next rgrp, so it will always have a rg_skip of 0 (unless the fs is extended). Before this patch, gfs2_rgrp_out() zeroes the __pad field explicitly, so the rg_skip field can get set back to 0 in cases where nodes with and without this patch are mixed in a cluster. In some cases, the field may bounce between being set by one node and then zeroed by another which may harm performance slightly, e.g. when two nodes create many small files. In testing this situation is rare but it becomes more likely as the filesystem fills up and there are fewer resource groups to choose from. The problem goes away when all nodes are running with this patch. Dipping into the space currently occupied by the rg_reserved field would have resulted in the same problem as it is also explicitly zeroed, so unfortunately there is no other way around it. Signed-off-by: Andrew Price Signed-off-by: Bob Peterson --- fs/gfs2/rgrp.c | 6 +++++- include/uapi/linux/gfs2_ondisk.h | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'include/uapi/linux') diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index b52c5c3ac445..be2fc26029e4 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1044,12 +1044,16 @@ static void gfs2_rgrp_in(struct gfs2_rgrpd *rgd, const void *buf) static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) { + struct gfs2_rgrpd *next = gfs2_rgrpd_get_next(rgd); struct gfs2_rgrp *str = buf; str->rg_flags = cpu_to_be32(rgd->rd_flags & ~GFS2_RDF_MASK); str->rg_free = cpu_to_be32(rgd->rd_free); str->rg_dinodes = cpu_to_be32(rgd->rd_dinodes); - str->__pad = cpu_to_be32(0); + if (next == NULL) + str->rg_skip = 0; + else if (next->rd_addr > rgd->rd_addr) + str->rg_skip = cpu_to_be32(next->rd_addr - rgd->rd_addr); str->rg_igeneration = cpu_to_be64(rgd->rd_igeneration); memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); } diff --git a/include/uapi/linux/gfs2_ondisk.h b/include/uapi/linux/gfs2_ondisk.h index 5156bad77b47..da7a30ddef72 100644 --- a/include/uapi/linux/gfs2_ondisk.h +++ b/include/uapi/linux/gfs2_ondisk.h @@ -187,7 +187,10 @@ struct gfs2_rgrp { __be32 rg_flags; __be32 rg_free; __be32 rg_dinodes; - __be32 __pad; + union { + __be32 __pad; + __be32 rg_skip; /* Distance to the next rgrp in fs blocks */ + }; __be64 rg_igeneration; __u8 rg_reserved[80]; /* Several fields from gfs1 now reserved */ -- cgit v1.2.3-59-g8ed1b From 166725d96322473305e35f9d580591a01697ab29 Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Tue, 12 Dec 2017 11:40:05 -0600 Subject: gfs2: Add rindex fields to rgrp headers Add rg_data0, rg_data and rg_bitbytes to struct gfs2_rgrp. The fields are identical to their counterparts in struct gfs2_rindex and are intended to reduce the use of the rindex. For now the fields are only written back as the in-memory equivalents in struct gfs2_rgrpd are set using values from the rindex. However, they are needed at this point so that userspace can make use of them, allowing a migration away from the rindex over time. The new fields take up previously reserved space which was explicitly zeroed on write so, in clusters with mixed kernels, these fields could get zeroed after being set and this should not be treated as an error. Signed-off-by: Andrew Price Signed-off-by: Bob Peterson --- fs/gfs2/rgrp.c | 5 +++++ include/uapi/linux/gfs2_ondisk.h | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index be2fc26029e4..a9184903a9f5 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1040,6 +1040,7 @@ static void gfs2_rgrp_in(struct gfs2_rgrpd *rgd, const void *buf) rgd->rd_free = be32_to_cpu(str->rg_free); rgd->rd_dinodes = be32_to_cpu(str->rg_dinodes); rgd->rd_igeneration = be64_to_cpu(str->rg_igeneration); + /* rd_data0, rd_data and rd_bitbytes already set from rindex */ } static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) @@ -1055,6 +1056,10 @@ static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) else if (next->rd_addr > rgd->rd_addr) str->rg_skip = cpu_to_be32(next->rd_addr - rgd->rd_addr); str->rg_igeneration = cpu_to_be64(rgd->rd_igeneration); + str->rg_data0 = cpu_to_be64(rgd->rd_data0); + str->rg_data = cpu_to_be32(rgd->rd_data); + str->rg_bitbytes = cpu_to_be32(rgd->rd_bitbytes); + memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); } diff --git a/include/uapi/linux/gfs2_ondisk.h b/include/uapi/linux/gfs2_ondisk.h index da7a30ddef72..648e0cbca574 100644 --- a/include/uapi/linux/gfs2_ondisk.h +++ b/include/uapi/linux/gfs2_ondisk.h @@ -192,8 +192,13 @@ struct gfs2_rgrp { __be32 rg_skip; /* Distance to the next rgrp in fs blocks */ }; __be64 rg_igeneration; + /* The following 3 fields are duplicated from gfs2_rindex to reduce + reliance on the rindex */ + __be64 rg_data0; /* First data location */ + __be32 rg_data; /* Number of data blocks in rgrp */ + __be32 rg_bitbytes; /* Number of bytes in data bitmaps */ - __u8 rg_reserved[80]; /* Several fields from gfs1 now reserved */ + __u8 rg_reserved[64]; /* Several fields from gfs1 now reserved */ }; /* -- cgit v1.2.3-59-g8ed1b From 850d2d915fa69011bef9bd668499cce889fdd8b3 Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Tue, 12 Dec 2017 11:42:30 -0600 Subject: gfs2: Add a crc field to resource group headers Add the rg_crc field to store a crc32 of the gfs2_rgrp structure. This allows us to check resource group headers' integrity and removes the requirement to check them against the rindex entries in fsck. If this field is found to be zero, it should be ignored (or updated with an accurate value). Signed-off-by: Andrew Price Signed-off-by: Bob Peterson --- fs/gfs2/rgrp.c | 5 +++++ include/uapi/linux/gfs2_ondisk.h | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index a9184903a9f5..e8aba6fa1472 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -34,6 +34,7 @@ #include "log.h" #include "inode.h" #include "trace_gfs2.h" +#include "dir.h" #define BFITNOENT ((u32)~0) #define NO_BLOCK ((u64)~0) @@ -1047,6 +1048,7 @@ static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) { struct gfs2_rgrpd *next = gfs2_rgrpd_get_next(rgd); struct gfs2_rgrp *str = buf; + u32 crc; str->rg_flags = cpu_to_be32(rgd->rd_flags & ~GFS2_RDF_MASK); str->rg_free = cpu_to_be32(rgd->rd_free); @@ -1059,6 +1061,9 @@ static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) str->rg_data0 = cpu_to_be64(rgd->rd_data0); str->rg_data = cpu_to_be32(rgd->rd_data); str->rg_bitbytes = cpu_to_be32(rgd->rd_bitbytes); + str->rg_crc = 0; + crc = gfs2_disk_hash(buf, sizeof(struct gfs2_rgrp)); + str->rg_crc = cpu_to_be32(crc); memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); } diff --git a/include/uapi/linux/gfs2_ondisk.h b/include/uapi/linux/gfs2_ondisk.h index 648e0cbca574..09f0920f07e9 100644 --- a/include/uapi/linux/gfs2_ondisk.h +++ b/include/uapi/linux/gfs2_ondisk.h @@ -197,8 +197,9 @@ struct gfs2_rgrp { __be64 rg_data0; /* First data location */ __be32 rg_data; /* Number of data blocks in rgrp */ __be32 rg_bitbytes; /* Number of bytes in data bitmaps */ + __be32 rg_crc; /* crc32 of the structure with this field 0 */ - __u8 rg_reserved[64]; /* Several fields from gfs1 now reserved */ + __u8 rg_reserved[60]; /* Several fields from gfs1 now reserved */ }; /* -- cgit v1.2.3-59-g8ed1b From 9b6192589be788dec73a0e99fe49b8f8ddaf825e Mon Sep 17 00:00:00 2001 From: Sean Young Date: Sat, 25 Feb 2017 06:51:29 -0500 Subject: media: lirc: implement scancode sending This introduces a new lirc mode: scancode. Any device which can send raw IR can now also send scancodes. int main() { int mode, fd = open("/dev/lirc0", O_RDWR); mode = LIRC_MODE_SCANCODE; if (ioctl(fd, LIRC_SET_SEND_MODE, &mode)) { // kernel too old or lirc does not support transmit } struct lirc_scancode scancode = { .scancode = 0x1e3d, .rc_proto = RC_PROTO_RC5, }; write(fd, &scancode, sizeof(scancode)); close(fd); } The other fields of lirc_scancode must be set to 0. Note that toggle (rc5, rc6) and repeats (nec) are not implemented. Nor is there a method for holding down a key for a period. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/ir-lirc-codec.c | 99 +++++++++++++++++++++++++++++----------- drivers/media/rc/rc-core-priv.h | 2 +- include/media/rc-map.h | 54 +--------------------- include/uapi/linux/lirc.h | 82 +++++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 81 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c index 9954ad4b8e59..0a3ec693d290 100644 --- a/drivers/media/rc/ir-lirc-codec.c +++ b/drivers/media/rc/ir-lirc-codec.c @@ -107,7 +107,8 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, { struct lirc_codec *lirc; struct rc_dev *dev; - unsigned int *txbuf; /* buffer with values to transmit */ + unsigned int *txbuf = NULL; + struct ir_raw_event *raw = NULL; ssize_t ret = -EINVAL; size_t count; ktime_t start; @@ -121,16 +122,50 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, if (!lirc) return -EFAULT; - if (n < sizeof(unsigned) || n % sizeof(unsigned)) - return -EINVAL; + if (lirc->send_mode == LIRC_MODE_SCANCODE) { + struct lirc_scancode scan; - count = n / sizeof(unsigned); - if (count > LIRCBUF_SIZE || count % 2 == 0) - return -EINVAL; + if (n != sizeof(scan)) + return -EINVAL; - txbuf = memdup_user(buf, n); - if (IS_ERR(txbuf)) - return PTR_ERR(txbuf); + if (copy_from_user(&scan, buf, sizeof(scan))) + return -EFAULT; + + if (scan.flags || scan.keycode || scan.timestamp) + return -EINVAL; + + raw = kmalloc_array(LIRCBUF_SIZE, sizeof(*raw), GFP_KERNEL); + if (!raw) + return -ENOMEM; + + ret = ir_raw_encode_scancode(scan.rc_proto, scan.scancode, + raw, LIRCBUF_SIZE); + if (ret < 0) + goto out; + + count = ret; + + txbuf = kmalloc_array(count, sizeof(unsigned int), GFP_KERNEL); + if (!txbuf) { + ret = -ENOMEM; + goto out; + } + + for (i = 0; i < count; i++) + /* Convert from NS to US */ + txbuf[i] = DIV_ROUND_UP(raw[i].duration, 1000); + } else { + if (n < sizeof(unsigned int) || n % sizeof(unsigned int)) + return -EINVAL; + + count = n / sizeof(unsigned int); + if (count > LIRCBUF_SIZE || count % 2 == 0) + return -EINVAL; + + txbuf = memdup_user(buf, n); + if (IS_ERR(txbuf)) + return PTR_ERR(txbuf); + } dev = lirc->dev; if (!dev) { @@ -156,24 +191,30 @@ static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf, if (ret < 0) goto out; - for (duration = i = 0; i < ret; i++) - duration += txbuf[i]; - - ret *= sizeof(unsigned int); - - /* - * The lircd gap calculation expects the write function to - * wait for the actual IR signal to be transmitted before - * returning. - */ - towait = ktime_us_delta(ktime_add_us(start, duration), ktime_get()); - if (towait > 0) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(usecs_to_jiffies(towait)); + if (lirc->send_mode == LIRC_MODE_SCANCODE) { + ret = n; + } else { + for (duration = i = 0; i < ret; i++) + duration += txbuf[i]; + + ret *= sizeof(unsigned int); + + /* + * The lircd gap calculation expects the write function to + * wait for the actual IR signal to be transmitted before + * returning. + */ + towait = ktime_us_delta(ktime_add_us(start, duration), + ktime_get()); + if (towait > 0) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(usecs_to_jiffies(towait)); + } } out: kfree(txbuf); + kfree(raw); return ret; } @@ -202,20 +243,22 @@ static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, switch (cmd) { - /* legacy support */ + /* mode support */ case LIRC_GET_SEND_MODE: if (!dev->tx_ir) return -ENOTTY; - val = LIRC_MODE_PULSE; + val = lirc->send_mode; break; case LIRC_SET_SEND_MODE: if (!dev->tx_ir) return -ENOTTY; - if (val != LIRC_MODE_PULSE) + if (!(val == LIRC_MODE_PULSE || val == LIRC_MODE_SCANCODE)) return -EINVAL; + + lirc->send_mode = val; return 0; /* TX settings */ @@ -361,7 +404,7 @@ static int ir_lirc_register(struct rc_dev *dev) } if (dev->tx_ir) { - features |= LIRC_CAN_SEND_PULSE; + features |= LIRC_CAN_SEND_PULSE | LIRC_CAN_SEND_SCANCODE; if (dev->s_tx_mask) features |= LIRC_CAN_SET_TRANSMITTER_MASK; if (dev->s_tx_carrier) @@ -399,6 +442,8 @@ static int ir_lirc_register(struct rc_dev *dev) if (rc < 0) goto out; + dev->raw->lirc.send_mode = LIRC_MODE_PULSE; + dev->raw->lirc.ldev = ldev; dev->raw->lirc.dev = dev; return 0; diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 564d6e13585e..d10fc998e1db 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -103,7 +103,7 @@ struct ir_raw_event_ctrl { u64 gap_duration; bool gap; bool send_timeout_reports; - + u8 send_mode; } lirc; struct xmp_dec { int state; diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 72197cb43781..7046734b3895 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -10,59 +10,7 @@ */ #include - -/** - * enum rc_proto - the Remote Controller protocol - * - * @RC_PROTO_UNKNOWN: Protocol not known - * @RC_PROTO_OTHER: Protocol known but proprietary - * @RC_PROTO_RC5: Philips RC5 protocol - * @RC_PROTO_RC5X_20: Philips RC5x 20 bit protocol - * @RC_PROTO_RC5_SZ: StreamZap variant of RC5 - * @RC_PROTO_JVC: JVC protocol - * @RC_PROTO_SONY12: Sony 12 bit protocol - * @RC_PROTO_SONY15: Sony 15 bit protocol - * @RC_PROTO_SONY20: Sony 20 bit protocol - * @RC_PROTO_NEC: NEC protocol - * @RC_PROTO_NECX: Extended NEC protocol - * @RC_PROTO_NEC32: NEC 32 bit protocol - * @RC_PROTO_SANYO: Sanyo protocol - * @RC_PROTO_MCIR2_KBD: RC6-ish MCE keyboard - * @RC_PROTO_MCIR2_MSE: RC6-ish MCE mouse - * @RC_PROTO_RC6_0: Philips RC6-0-16 protocol - * @RC_PROTO_RC6_6A_20: Philips RC6-6A-20 protocol - * @RC_PROTO_RC6_6A_24: Philips RC6-6A-24 protocol - * @RC_PROTO_RC6_6A_32: Philips RC6-6A-32 protocol - * @RC_PROTO_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol - * @RC_PROTO_SHARP: Sharp protocol - * @RC_PROTO_XMP: XMP protocol - * @RC_PROTO_CEC: CEC protocol - */ -enum rc_proto { - RC_PROTO_UNKNOWN = 0, - RC_PROTO_OTHER = 1, - RC_PROTO_RC5 = 2, - RC_PROTO_RC5X_20 = 3, - RC_PROTO_RC5_SZ = 4, - RC_PROTO_JVC = 5, - RC_PROTO_SONY12 = 6, - RC_PROTO_SONY15 = 7, - RC_PROTO_SONY20 = 8, - RC_PROTO_NEC = 9, - RC_PROTO_NECX = 10, - RC_PROTO_NEC32 = 11, - RC_PROTO_SANYO = 12, - RC_PROTO_MCIR2_KBD = 13, - RC_PROTO_MCIR2_MSE = 14, - RC_PROTO_RC6_0 = 15, - RC_PROTO_RC6_6A_20 = 16, - RC_PROTO_RC6_6A_24 = 17, - RC_PROTO_RC6_6A_32 = 18, - RC_PROTO_RC6_MCE = 19, - RC_PROTO_SHARP = 20, - RC_PROTO_XMP = 21, - RC_PROTO_CEC = 22, -}; +#include #define RC_PROTO_BIT_NONE 0ULL #define RC_PROTO_BIT_UNKNOWN BIT_ULL(RC_PROTO_UNKNOWN) diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h index c3aef4316fbf..4fe580d36e41 100644 --- a/include/uapi/linux/lirc.h +++ b/include/uapi/linux/lirc.h @@ -47,12 +47,14 @@ #define LIRC_MODE_RAW 0x00000001 #define LIRC_MODE_PULSE 0x00000002 #define LIRC_MODE_MODE2 0x00000004 +#define LIRC_MODE_SCANCODE 0x00000008 #define LIRC_MODE_LIRCCODE 0x00000010 #define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) #define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) #define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) +#define LIRC_CAN_SEND_SCANCODE LIRC_MODE2SEND(LIRC_MODE_SCANCODE) #define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) #define LIRC_CAN_SEND_MASK 0x0000003f @@ -64,6 +66,7 @@ #define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW) #define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE) #define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2) +#define LIRC_CAN_REC_SCANCODE LIRC_MODE2REC(LIRC_MODE_SCANCODE) #define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE) #define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK) @@ -131,4 +134,83 @@ #define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32) +/* + * struct lirc_scancode - decoded scancode with protocol for use with + * LIRC_MODE_SCANCODE + * + * @timestamp: Timestamp in nanoseconds using CLOCK_MONOTONIC when IR + * was decoded. + * @flags: should be 0 for transmit. When receiving scancodes, + * LIRC_SCANCODE_FLAG_TOGGLE or LIRC_SCANCODE_FLAG_REPEAT can be set + * depending on the protocol + * @rc_proto: see enum rc_proto + * @keycode: the translated keycode. Set to 0 for transmit. + * @scancode: the scancode received or to be sent + */ +struct lirc_scancode { + __u64 timestamp; + __u16 flags; + __u16 rc_proto; + __u32 keycode; + __u64 scancode; +}; + +/* Set if the toggle bit of rc-5 or rc-6 is enabled */ +#define LIRC_SCANCODE_FLAG_TOGGLE 1 +/* Set if this is a nec or sanyo repeat */ +#define LIRC_SCANCODE_FLAG_REPEAT 2 + +/** + * enum rc_proto - the Remote Controller protocol + * + * @RC_PROTO_UNKNOWN: Protocol not known + * @RC_PROTO_OTHER: Protocol known but proprietary + * @RC_PROTO_RC5: Philips RC5 protocol + * @RC_PROTO_RC5X_20: Philips RC5x 20 bit protocol + * @RC_PROTO_RC5_SZ: StreamZap variant of RC5 + * @RC_PROTO_JVC: JVC protocol + * @RC_PROTO_SONY12: Sony 12 bit protocol + * @RC_PROTO_SONY15: Sony 15 bit protocol + * @RC_PROTO_SONY20: Sony 20 bit protocol + * @RC_PROTO_NEC: NEC protocol + * @RC_PROTO_NECX: Extended NEC protocol + * @RC_PROTO_NEC32: NEC 32 bit protocol + * @RC_PROTO_SANYO: Sanyo protocol + * @RC_PROTO_MCIR2_KBD: RC6-ish MCE keyboard + * @RC_PROTO_MCIR2_MSE: RC6-ish MCE mouse + * @RC_PROTO_RC6_0: Philips RC6-0-16 protocol + * @RC_PROTO_RC6_6A_20: Philips RC6-6A-20 protocol + * @RC_PROTO_RC6_6A_24: Philips RC6-6A-24 protocol + * @RC_PROTO_RC6_6A_32: Philips RC6-6A-32 protocol + * @RC_PROTO_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol + * @RC_PROTO_SHARP: Sharp protocol + * @RC_PROTO_XMP: XMP protocol + * @RC_PROTO_CEC: CEC protocol + */ +enum rc_proto { + RC_PROTO_UNKNOWN = 0, + RC_PROTO_OTHER = 1, + RC_PROTO_RC5 = 2, + RC_PROTO_RC5X_20 = 3, + RC_PROTO_RC5_SZ = 4, + RC_PROTO_JVC = 5, + RC_PROTO_SONY12 = 6, + RC_PROTO_SONY15 = 7, + RC_PROTO_SONY20 = 8, + RC_PROTO_NEC = 9, + RC_PROTO_NECX = 10, + RC_PROTO_NEC32 = 11, + RC_PROTO_SANYO = 12, + RC_PROTO_MCIR2_KBD = 13, + RC_PROTO_MCIR2_MSE = 14, + RC_PROTO_RC6_0 = 15, + RC_PROTO_RC6_6A_20 = 16, + RC_PROTO_RC6_6A_24 = 17, + RC_PROTO_RC6_6A_32 = 18, + RC_PROTO_RC6_MCE = 19, + RC_PROTO_SHARP = 20, + RC_PROTO_XMP = 21, + RC_PROTO_CEC = 22, +}; + #endif -- cgit v1.2.3-59-g8ed1b From 033ddf12bcf5326b93bd604f50a7474a434a35f9 Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Wed, 29 Nov 2017 14:48:26 +0200 Subject: tee: add register user memory Added new ioctl to allow users register own buffers as a shared memory. Signed-off-by: Volodymyr Babchuk [jw: moved tee_shm_is_registered() declaration] [jw: added space after __tee_shm_alloc() implementation] Signed-off-by: Jens Wiklander --- drivers/tee/tee_core.c | 41 +++++++++- drivers/tee/tee_shm.c | 206 +++++++++++++++++++++++++++++++++++++++++------ include/linux/tee_drv.h | 47 ++++++++++- include/uapi/linux/tee.h | 30 +++++++ 4 files changed, 294 insertions(+), 30 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 58a5009eacc3..295910f5cdd0 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -114,8 +114,6 @@ static int tee_ioctl_shm_alloc(struct tee_context *ctx, if (data.flags) return -EINVAL; - data.id = -1; - shm = tee_shm_alloc(ctx, data.size, TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); if (IS_ERR(shm)) return PTR_ERR(shm); @@ -138,6 +136,43 @@ static int tee_ioctl_shm_alloc(struct tee_context *ctx, return ret; } +static int +tee_ioctl_shm_register(struct tee_context *ctx, + struct tee_ioctl_shm_register_data __user *udata) +{ + long ret; + struct tee_ioctl_shm_register_data data; + struct tee_shm *shm; + + if (copy_from_user(&data, udata, sizeof(data))) + return -EFAULT; + + /* Currently no input flags are supported */ + if (data.flags) + return -EINVAL; + + shm = tee_shm_register(ctx, data.addr, data.length, + TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED); + if (IS_ERR(shm)) + return PTR_ERR(shm); + + data.id = shm->id; + data.flags = shm->flags; + data.length = shm->size; + + if (copy_to_user(udata, &data, sizeof(data))) + ret = -EFAULT; + else + ret = tee_shm_get_fd(shm); + /* + * When user space closes the file descriptor the shared memory + * should be freed or if tee_shm_get_fd() failed then it will + * be freed immediately. + */ + tee_shm_put(shm); + return ret; +} + static int params_from_user(struct tee_context *ctx, struct tee_param *params, size_t num_params, struct tee_ioctl_param __user *uparams) @@ -586,6 +621,8 @@ static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return tee_ioctl_version(ctx, uarg); case TEE_IOC_SHM_ALLOC: return tee_ioctl_shm_alloc(ctx, uarg); + case TEE_IOC_SHM_REGISTER: + return tee_ioctl_shm_register(ctx, uarg); case TEE_IOC_OPEN_SESSION: return tee_ioctl_open_session(ctx, uarg); case TEE_IOC_INVOKE: diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index fdda89e917f7..11d11a46d86e 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -23,7 +23,6 @@ static void tee_shm_release(struct tee_shm *shm) { struct tee_device *teedev = shm->teedev; - struct tee_shm_pool_mgr *poolm; mutex_lock(&teedev->mutex); idr_remove(&teedev->idr, shm->id); @@ -31,12 +30,29 @@ static void tee_shm_release(struct tee_shm *shm) list_del(&shm->link); mutex_unlock(&teedev->mutex); - if (shm->flags & TEE_SHM_DMA_BUF) - poolm = teedev->pool->dma_buf_mgr; - else - poolm = teedev->pool->private_mgr; + if (shm->flags & TEE_SHM_POOL) { + struct tee_shm_pool_mgr *poolm; + + if (shm->flags & TEE_SHM_DMA_BUF) + poolm = teedev->pool->dma_buf_mgr; + else + poolm = teedev->pool->private_mgr; + + poolm->ops->free(poolm, shm); + } else if (shm->flags & TEE_SHM_REGISTER) { + size_t n; + int rc = teedev->desc->ops->shm_unregister(shm->ctx, shm); + + if (rc) + dev_err(teedev->dev.parent, + "unregister shm %p failed: %d", shm, rc); + + for (n = 0; n < shm->num_pages; n++) + put_page(shm->pages[n]); + + kfree(shm->pages); + } - poolm->ops->free(poolm, shm); kfree(shm); tee_device_put(teedev); @@ -76,6 +92,10 @@ static int tee_shm_op_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) struct tee_shm *shm = dmabuf->priv; size_t size = vma->vm_end - vma->vm_start; + /* Refuse sharing shared memory provided by application */ + if (shm->flags & TEE_SHM_REGISTER) + return -EINVAL; + return remap_pfn_range(vma, vma->vm_start, shm->paddr >> PAGE_SHIFT, size, vma->vm_page_prot); } @@ -89,26 +109,20 @@ static const struct dma_buf_ops tee_shm_dma_buf_ops = { .mmap = tee_shm_op_mmap, }; -/** - * tee_shm_alloc() - Allocate shared memory - * @ctx: Context that allocates the shared memory - * @size: Requested size of shared memory - * @flags: Flags setting properties for the requested shared memory. - * - * Memory allocated as global shared memory is automatically freed when the - * TEE file pointer is closed. The @flags field uses the bits defined by - * TEE_SHM_* in . TEE_SHM_MAPPED must currently always be - * set. If TEE_SHM_DMA_BUF global shared memory will be allocated and - * associated with a dma-buf handle, else driver private memory. - */ -struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) +struct tee_shm *__tee_shm_alloc(struct tee_context *ctx, + struct tee_device *teedev, + size_t size, u32 flags) { - struct tee_device *teedev = ctx->teedev; struct tee_shm_pool_mgr *poolm = NULL; struct tee_shm *shm; void *ret; int rc; + if (ctx && ctx->teedev != teedev) { + dev_err(teedev->dev.parent, "ctx and teedev mismatch\n"); + return ERR_PTR(-EINVAL); + } + if (!(flags & TEE_SHM_MAPPED)) { dev_err(teedev->dev.parent, "only mapped allocations supported\n"); @@ -135,7 +149,7 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) goto err_dev_put; } - shm->flags = flags; + shm->flags = flags | TEE_SHM_POOL; shm->teedev = teedev; shm->ctx = ctx; if (flags & TEE_SHM_DMA_BUF) @@ -171,9 +185,12 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) goto err_rem; } } - mutex_lock(&teedev->mutex); - list_add_tail(&shm->link, &ctx->list_shm); - mutex_unlock(&teedev->mutex); + + if (ctx) { + mutex_lock(&teedev->mutex); + list_add_tail(&shm->link, &ctx->list_shm); + mutex_unlock(&teedev->mutex); + } return shm; err_rem: @@ -188,8 +205,140 @@ err_dev_put: tee_device_put(teedev); return ret; } + +/** + * tee_shm_alloc() - Allocate shared memory + * @ctx: Context that allocates the shared memory + * @size: Requested size of shared memory + * @flags: Flags setting properties for the requested shared memory. + * + * Memory allocated as global shared memory is automatically freed when the + * TEE file pointer is closed. The @flags field uses the bits defined by + * TEE_SHM_* in . TEE_SHM_MAPPED must currently always be + * set. If TEE_SHM_DMA_BUF global shared memory will be allocated and + * associated with a dma-buf handle, else driver private memory. + */ +struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) +{ + return __tee_shm_alloc(ctx, ctx->teedev, size, flags); +} EXPORT_SYMBOL_GPL(tee_shm_alloc); +struct tee_shm *tee_shm_priv_alloc(struct tee_device *teedev, size_t size) +{ + return __tee_shm_alloc(NULL, teedev, size, TEE_SHM_MAPPED); +} +EXPORT_SYMBOL_GPL(tee_shm_priv_alloc); + +struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, + size_t length, u32 flags) +{ + struct tee_device *teedev = ctx->teedev; + const u32 req_flags = TEE_SHM_DMA_BUF | TEE_SHM_USER_MAPPED; + struct tee_shm *shm; + void *ret; + int rc; + int num_pages; + unsigned long start; + + if (flags != req_flags) + return ERR_PTR(-ENOTSUPP); + + if (!tee_device_get(teedev)) + return ERR_PTR(-EINVAL); + + if (!teedev->desc->ops->shm_register || + !teedev->desc->ops->shm_unregister) { + tee_device_put(teedev); + return ERR_PTR(-ENOTSUPP); + } + + shm = kzalloc(sizeof(*shm), GFP_KERNEL); + if (!shm) { + ret = ERR_PTR(-ENOMEM); + goto err; + } + + shm->flags = flags | TEE_SHM_REGISTER; + shm->teedev = teedev; + shm->ctx = ctx; + shm->id = -1; + start = rounddown(addr, PAGE_SIZE); + shm->offset = addr - start; + shm->size = length; + num_pages = (roundup(addr + length, PAGE_SIZE) - start) / PAGE_SIZE; + shm->pages = kcalloc(num_pages, sizeof(*shm->pages), GFP_KERNEL); + if (!shm->pages) { + ret = ERR_PTR(-ENOMEM); + goto err; + } + + rc = get_user_pages_fast(start, num_pages, 1, shm->pages); + if (rc > 0) + shm->num_pages = rc; + if (rc != num_pages) { + if (rc > 0) + rc = -ENOMEM; + ret = ERR_PTR(rc); + goto err; + } + + mutex_lock(&teedev->mutex); + shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL); + mutex_unlock(&teedev->mutex); + + if (shm->id < 0) { + ret = ERR_PTR(shm->id); + goto err; + } + + rc = teedev->desc->ops->shm_register(ctx, shm, shm->pages, + shm->num_pages); + if (rc) { + ret = ERR_PTR(rc); + goto err; + } + + if (flags & TEE_SHM_DMA_BUF) { + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + + exp_info.ops = &tee_shm_dma_buf_ops; + exp_info.size = shm->size; + exp_info.flags = O_RDWR; + exp_info.priv = shm; + + shm->dmabuf = dma_buf_export(&exp_info); + if (IS_ERR(shm->dmabuf)) { + ret = ERR_CAST(shm->dmabuf); + teedev->desc->ops->shm_unregister(ctx, shm); + goto err; + } + } + + mutex_lock(&teedev->mutex); + list_add_tail(&shm->link, &ctx->list_shm); + mutex_unlock(&teedev->mutex); + + return shm; +err: + if (shm) { + size_t n; + + if (shm->id >= 0) { + mutex_lock(&teedev->mutex); + idr_remove(&teedev->idr, shm->id); + mutex_unlock(&teedev->mutex); + } + for (n = 0; n < shm->num_pages; n++) + put_page(shm->pages[n]); + kfree(shm->pages); + } + kfree(shm); + tee_device_put(teedev); + return ret; +} +EXPORT_SYMBOL_GPL(tee_shm_register); + /** * tee_shm_get_fd() - Increase reference count and return file descriptor * @shm: Shared memory handle @@ -197,10 +346,9 @@ EXPORT_SYMBOL_GPL(tee_shm_alloc); */ int tee_shm_get_fd(struct tee_shm *shm) { - u32 req_flags = TEE_SHM_MAPPED | TEE_SHM_DMA_BUF; int fd; - if ((shm->flags & req_flags) != req_flags) + if (!(shm->flags & TEE_SHM_DMA_BUF)) return -EINVAL; fd = dma_buf_fd(shm->dmabuf, O_CLOEXEC); @@ -238,6 +386,8 @@ EXPORT_SYMBOL_GPL(tee_shm_free); */ int tee_shm_va2pa(struct tee_shm *shm, void *va, phys_addr_t *pa) { + if (!(shm->flags & TEE_SHM_MAPPED)) + return -EINVAL; /* Check that we're in the range of the shm */ if ((char *)va < (char *)shm->kaddr) return -EINVAL; @@ -258,6 +408,8 @@ EXPORT_SYMBOL_GPL(tee_shm_va2pa); */ int tee_shm_pa2va(struct tee_shm *shm, phys_addr_t pa, void **va) { + if (!(shm->flags & TEE_SHM_MAPPED)) + return -EINVAL; /* Check that we're in the range of the shm */ if (pa < shm->paddr) return -EINVAL; @@ -284,6 +436,8 @@ EXPORT_SYMBOL_GPL(tee_shm_pa2va); */ void *tee_shm_get_va(struct tee_shm *shm, size_t offs) { + if (!(shm->flags & TEE_SHM_MAPPED)) + return ERR_PTR(-EINVAL); if (offs >= shm->size) return ERR_PTR(-EINVAL); return (char *)shm->kaddr + offs; diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index e9be4a45ff3e..7c8495607b99 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -25,8 +25,12 @@ * specific TEE driver. */ -#define TEE_SHM_MAPPED 0x1 /* Memory mapped by the kernel */ -#define TEE_SHM_DMA_BUF 0x2 /* Memory with dma-buf handle */ +#define TEE_SHM_MAPPED BIT(0) /* Memory mapped by the kernel */ +#define TEE_SHM_DMA_BUF BIT(1) /* Memory with dma-buf handle */ +#define TEE_SHM_EXT_DMA_BUF BIT(2) /* Memory with dma-buf handle */ +#define TEE_SHM_REGISTER BIT(3) /* Memory registered in secure world */ +#define TEE_SHM_USER_MAPPED BIT(4) /* Memory mapped in user space */ +#define TEE_SHM_POOL BIT(5) /* Memory allocated from pool */ struct device; struct tee_device; @@ -76,6 +80,8 @@ struct tee_param { * @cancel_req: request cancel of an ongoing invoke or open * @supp_revc: called for supplicant to get a command * @supp_send: called for supplicant to send a response + * @shm_register: register shared memory buffer in TEE + * @shm_unregister: unregister shared memory buffer in TEE */ struct tee_driver_ops { void (*get_version)(struct tee_device *teedev, @@ -94,6 +100,9 @@ struct tee_driver_ops { struct tee_param *param); int (*supp_send)(struct tee_context *ctx, u32 ret, u32 num_params, struct tee_param *param); + int (*shm_register)(struct tee_context *ctx, struct tee_shm *shm, + struct page **pages, size_t num_pages); + int (*shm_unregister)(struct tee_context *ctx, struct tee_shm *shm); }; /** @@ -301,6 +310,40 @@ void *tee_get_drvdata(struct tee_device *teedev); */ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags); +/** + * tee_shm_priv_alloc() - Allocate shared memory privately + * @dev: Device that allocates the shared memory + * @size: Requested size of shared memory + * + * Allocates shared memory buffer that is not associated with any client + * context. Such buffers are owned by TEE driver and used for internal calls. + * + * @returns a pointer to 'struct tee_shm' + */ +struct tee_shm *tee_shm_priv_alloc(struct tee_device *teedev, size_t size); + +/** + * tee_shm_register() - Register shared memory buffer + * @ctx: Context that registers the shared memory + * @addr: Address is userspace of the shared buffer + * @length: Length of the shared buffer + * @flags: Flags setting properties for the requested shared memory. + * + * @returns a pointer to 'struct tee_shm' + */ +struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, + size_t length, u32 flags); + +/** + * tee_shm_is_registered() - Check if shared memory object in registered in TEE + * @shm: Shared memory handle + * @returns true if object is registered in TEE + */ +static inline bool tee_shm_is_registered(struct tee_shm *shm) +{ + return shm && (shm->flags & TEE_SHM_REGISTER); +} + /** * tee_shm_free() - Free shared memory * @shm: Handle to shared memory to free diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h index 688782e90140..d41a07afe3fc 100644 --- a/include/uapi/linux/tee.h +++ b/include/uapi/linux/tee.h @@ -50,6 +50,7 @@ #define TEE_GEN_CAP_GP (1 << 0)/* GlobalPlatform compliant TEE */ #define TEE_GEN_CAP_PRIVILEGED (1 << 1)/* Privileged device (for supplicant) */ +#define TEE_GEN_CAP_REG_MEM (1 << 2)/* Supports registering shared memory */ /* * TEE Implementation ID @@ -332,6 +333,35 @@ struct tee_iocl_supp_send_arg { #define TEE_IOC_SUPPL_SEND _IOR(TEE_IOC_MAGIC, TEE_IOC_BASE + 7, \ struct tee_ioctl_buf_data) +/** + * struct tee_ioctl_shm_register_data - Shared memory register argument + * @addr: [in] Start address of shared memory to register + * @length: [in/out] Length of shared memory to register + * @flags: [in/out] Flags to/from registration. + * @id: [out] Identifier of the shared memory + * + * The flags field should currently be zero as input. Updated by the call + * with actual flags as defined by TEE_IOCTL_SHM_* above. + * This structure is used as argument for TEE_IOC_SHM_REGISTER below. + */ +struct tee_ioctl_shm_register_data { + __u64 addr; + __u64 length; + __u32 flags; + __s32 id; +}; + +/** + * TEE_IOC_SHM_REGISTER - Register shared memory argument + * + * Registers shared memory between the user space process and secure OS. + * + * Returns a file descriptor on success or < 0 on failure + * + * The shared memory is unregisterred when the descriptor is closed. + */ +#define TEE_IOC_SHM_REGISTER _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 9, \ + struct tee_ioctl_shm_register_data) /* * Five syscalls are used when communicating with the TEE driver. * open(): opens the device associated with the driver -- cgit v1.2.3-59-g8ed1b From 7db7d9f369a47e1a46f93c320b45cb89e81723e7 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 19 Nov 2017 15:05:11 +0100 Subject: batman-adv: Add SPDX license identifier above copyright header The "Linux kernel licensing rules" require that each file has a SPDX license identifier as first line (and sometimes as second line). The FSFE REUSE practices [1] would also require the same tags but have no restrictions on the placement in the source file. Using the "Linux kernel licensing rules" is therefore also fulfilling the FSFE REUSE practices requirements at the same time. [1] https://reuse.software/practices/ Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich --- include/uapi/linux/batman_adv.h | 1 + net/batman-adv/Makefile | 2 +- net/batman-adv/bat_algo.c | 1 + net/batman-adv/bat_algo.h | 1 + net/batman-adv/bat_iv_ogm.c | 1 + net/batman-adv/bat_iv_ogm.h | 1 + net/batman-adv/bat_v.c | 1 + net/batman-adv/bat_v.h | 1 + net/batman-adv/bat_v_elp.c | 1 + net/batman-adv/bat_v_elp.h | 1 + net/batman-adv/bat_v_ogm.c | 1 + net/batman-adv/bat_v_ogm.h | 1 + net/batman-adv/bitarray.c | 1 + net/batman-adv/bitarray.h | 1 + net/batman-adv/bridge_loop_avoidance.c | 1 + net/batman-adv/bridge_loop_avoidance.h | 1 + net/batman-adv/debugfs.c | 1 + net/batman-adv/debugfs.h | 1 + net/batman-adv/distributed-arp-table.c | 1 + net/batman-adv/distributed-arp-table.h | 1 + net/batman-adv/fragmentation.c | 1 + net/batman-adv/fragmentation.h | 1 + net/batman-adv/gateway_client.c | 1 + net/batman-adv/gateway_client.h | 1 + net/batman-adv/gateway_common.c | 1 + net/batman-adv/gateway_common.h | 1 + net/batman-adv/hard-interface.c | 1 + net/batman-adv/hard-interface.h | 1 + net/batman-adv/hash.c | 1 + net/batman-adv/hash.h | 1 + net/batman-adv/icmp_socket.c | 1 + net/batman-adv/icmp_socket.h | 1 + net/batman-adv/log.c | 1 + net/batman-adv/log.h | 1 + net/batman-adv/main.c | 1 + net/batman-adv/main.h | 1 + net/batman-adv/multicast.c | 1 + net/batman-adv/multicast.h | 1 + net/batman-adv/netlink.c | 1 + net/batman-adv/netlink.h | 1 + net/batman-adv/network-coding.c | 1 + net/batman-adv/network-coding.h | 1 + net/batman-adv/originator.c | 1 + net/batman-adv/originator.h | 1 + net/batman-adv/packet.h | 1 + net/batman-adv/routing.c | 1 + net/batman-adv/routing.h | 1 + net/batman-adv/send.c | 1 + net/batman-adv/send.h | 1 + net/batman-adv/soft-interface.c | 1 + net/batman-adv/soft-interface.h | 1 + net/batman-adv/sysfs.c | 1 + net/batman-adv/sysfs.h | 1 + net/batman-adv/tp_meter.c | 1 + net/batman-adv/tp_meter.h | 1 + net/batman-adv/translation-table.c | 1 + net/batman-adv/translation-table.h | 1 + net/batman-adv/tvlv.c | 1 + net/batman-adv/tvlv.h | 1 + net/batman-adv/types.h | 1 + 60 files changed, 60 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h index efd641c8a5d6..fb4533826163 100644 --- a/include/uapi/linux/batman_adv.h +++ b/include/uapi/linux/batman_adv.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: ISC */ /* Copyright (C) 2016-2017 B.A.T.M.A.N. contributors: * * Matthias Schiffer diff --git a/net/batman-adv/Makefile b/net/batman-adv/Makefile index 915987bc6d29..022f6e77307b 100644 --- a/net/batman-adv/Makefile +++ b/net/batman-adv/Makefile @@ -1,4 +1,4 @@ -# +# SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: # # Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/bat_algo.c b/net/batman-adv/bat_algo.c index 44fd073b7546..fa306b25a78b 100644 --- a/net/batman-adv/bat_algo.c +++ b/net/batman-adv/bat_algo.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/bat_algo.h b/net/batman-adv/bat_algo.h index 29f6312f9bf1..029221615ba3 100644 --- a/net/batman-adv/bat_algo.h +++ b/net/batman-adv/bat_algo.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Linus Lüssing diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 1b659ab652fb..bff5ec66a2e1 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/bat_iv_ogm.h b/net/batman-adv/bat_iv_ogm.h index ae2ab526bdb1..9dc0dd5c83df 100644 --- a/net/batman-adv/bat_iv_ogm.h +++ b/net/batman-adv/bat_iv_ogm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 341ceab8338d..16709552c21e 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2013-2017 B.A.T.M.A.N. contributors: * * Linus Lüssing, Marek Lindner diff --git a/net/batman-adv/bat_v.h b/net/batman-adv/bat_v.h index dd7c4b647e6b..a17ab68bbce8 100644 --- a/net/batman-adv/bat_v.h +++ b/net/batman-adv/bat_v.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Linus Lüssing diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index 1de992c58b35..8375fd679db3 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: * * Linus Lüssing, Marek Lindner diff --git a/net/batman-adv/bat_v_elp.h b/net/batman-adv/bat_v_elp.h index 376ead280ab9..5e39d0588a48 100644 --- a/net/batman-adv/bat_v_elp.h +++ b/net/batman-adv/bat_v_elp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2013-2017 B.A.T.M.A.N. contributors: * * Linus Lüssing, Marek Lindner diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index c251445a42a0..22d2bafa814a 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2013-2017 B.A.T.M.A.N. contributors: * * Antonio Quartulli diff --git a/net/batman-adv/bat_v_ogm.h b/net/batman-adv/bat_v_ogm.h index 2068770b542d..6a4c14ccc3c6 100644 --- a/net/batman-adv/bat_v_ogm.h +++ b/net/batman-adv/bat_v_ogm.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2013-2017 B.A.T.M.A.N. contributors: * * Antonio Quartulli diff --git a/net/batman-adv/bitarray.c b/net/batman-adv/bitarray.c index 2b070c7e31da..125817c389e5 100644 --- a/net/batman-adv/bitarray.c +++ b/net/batman-adv/bitarray.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2006-2017 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner diff --git a/net/batman-adv/bitarray.h b/net/batman-adv/bitarray.h index cc262c9d97e0..8cb2c874f5d3 100644 --- a/net/batman-adv/bitarray.h +++ b/net/batman-adv/bitarray.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2006-2017 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index cdd8e8e4df0b..007147f3ed9e 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: * * Simon Wunderlich diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h index 234775748b8e..b568cec819c5 100644 --- a/net/batman-adv/bridge_loop_avoidance.h +++ b/net/batman-adv/bridge_loop_avoidance.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: * * Simon Wunderlich diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c index e32ad47c6efd..d94585dc2dbe 100644 --- a/net/batman-adv/debugfs.c +++ b/net/batman-adv/debugfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2010-2017 B.A.T.M.A.N. contributors: * * Marek Lindner diff --git a/net/batman-adv/debugfs.h b/net/batman-adv/debugfs.h index 9c5d4a65b98c..90a08d35c501 100644 --- a/net/batman-adv/debugfs.h +++ b/net/batman-adv/debugfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2010-2017 B.A.T.M.A.N. contributors: * * Marek Lindner diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index 760c0de72582..3c2faf773335 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: * * Antonio Quartulli diff --git a/net/batman-adv/distributed-arp-table.h b/net/batman-adv/distributed-arp-table.h index ec364a3c1c66..d81a05a6e6f9 100644 --- a/net/batman-adv/distributed-arp-table.h +++ b/net/batman-adv/distributed-arp-table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2011-2017 B.A.T.M.A.N. contributors: * * Antonio Quartulli diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index a98cf1104a30..22ce4c0c86c3 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2013-2017 B.A.T.M.A.N. contributors: * * Martin Hundebøll diff --git a/net/batman-adv/fragmentation.h b/net/batman-adv/fragmentation.h index 1a2d6c308745..30ffa992fcfc 100644 --- a/net/batman-adv/fragmentation.h +++ b/net/batman-adv/fragmentation.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2013-2017 B.A.T.M.A.N. contributors: * * Martin Hundebøll diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 10d521f0b17f..e8db19940ab8 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2009-2017 B.A.T.M.A.N. contributors: * * Marek Lindner diff --git a/net/batman-adv/gateway_client.h b/net/batman-adv/gateway_client.h index 3baa3d466e5e..981f58421a32 100644 --- a/net/batman-adv/gateway_client.h +++ b/net/batman-adv/gateway_client.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2009-2017 B.A.T.M.A.N. contributors: * * Marek Lindner diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c index 2c26039c23fc..a7039503d88e 100644 --- a/net/batman-adv/gateway_common.c +++ b/net/batman-adv/gateway_common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2009-2017 B.A.T.M.A.N. contributors: * * Marek Lindner diff --git a/net/batman-adv/gateway_common.h b/net/batman-adv/gateway_common.h index 0a6a97d201f2..7c298b05c1dc 100644 --- a/net/batman-adv/gateway_common.h +++ b/net/batman-adv/gateway_common.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2009-2017 B.A.T.M.A.N. contributors: * * Marek Lindner diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 4e3d5340ad96..2f067a507fd5 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h index 9f9890ff7a22..ac7311a91f9d 100644 --- a/net/batman-adv/hard-interface.h +++ b/net/batman-adv/hard-interface.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/hash.c b/net/batman-adv/hash.c index b5f7e13918ac..a6dbaf2e9fc9 100644 --- a/net/batman-adv/hash.c +++ b/net/batman-adv/hash.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2006-2017 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner diff --git a/net/batman-adv/hash.h b/net/batman-adv/hash.h index 0c905e91c5e2..81cf54eb2fad 100644 --- a/net/batman-adv/hash.h +++ b/net/batman-adv/hash.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2006-2017 B.A.T.M.A.N. contributors: * * Simon Wunderlich, Marek Lindner diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index bded31121d12..cc76f1365300 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner diff --git a/net/batman-adv/icmp_socket.h b/net/batman-adv/icmp_socket.h index f3fec40aae86..84cddd01eeab 100644 --- a/net/batman-adv/icmp_socket.h +++ b/net/batman-adv/icmp_socket.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner diff --git a/net/batman-adv/log.c b/net/batman-adv/log.c index 4ef4bde2cc2d..148e64e846d2 100644 --- a/net/batman-adv/log.c +++ b/net/batman-adv/log.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2010-2017 B.A.T.M.A.N. contributors: * * Marek Lindner diff --git a/net/batman-adv/log.h b/net/batman-adv/log.h index 65ce97efa6b5..6744a64143c0 100644 --- a/net/batman-adv/log.h +++ b/net/batman-adv/log.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 4daed7ad46f2..5ce2007ea11b 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index bb8003cf2296..4bdb39ab3b20 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c index e553a8770a89..01546a42b7ad 100644 --- a/net/batman-adv/multicast.c +++ b/net/batman-adv/multicast.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2014-2017 B.A.T.M.A.N. contributors: * * Linus Lüssing diff --git a/net/batman-adv/multicast.h b/net/batman-adv/multicast.h index 2a78cddab0e9..51f273b5b77d 100644 --- a/net/batman-adv/multicast.h +++ b/net/batman-adv/multicast.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2014-2017 B.A.T.M.A.N. contributors: * * Linus Lüssing diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c index ab13b4d58733..ce424fe2f24e 100644 --- a/net/batman-adv/netlink.c +++ b/net/batman-adv/netlink.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2016-2017 B.A.T.M.A.N. contributors: * * Matthias Schiffer diff --git a/net/batman-adv/netlink.h b/net/batman-adv/netlink.h index f1cd8c5da966..0e7e57b69b54 100644 --- a/net/batman-adv/netlink.h +++ b/net/batman-adv/netlink.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2016-2017 B.A.T.M.A.N. contributors: * * Matthias Schiffer diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index 3604d7899e2c..5cfac6e56610 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2012-2017 B.A.T.M.A.N. contributors: * * Martin Hundebøll, Jeppe Ledet-Pedersen diff --git a/net/batman-adv/network-coding.h b/net/batman-adv/network-coding.h index c66efb81d2f4..adaeafa4f71e 100644 --- a/net/batman-adv/network-coding.h +++ b/net/batman-adv/network-coding.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2012-2017 B.A.T.M.A.N. contributors: * * Martin Hundebøll, Jeppe Ledet-Pedersen diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 0a565d0422bb..0716daf5b9a7 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2009-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/originator.h b/net/batman-adv/originator.h index 40c7f039d5d7..b5d2164532c9 100644 --- a/net/batman-adv/originator.h +++ b/net/batman-adv/originator.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h index 8e8a5db197cb..4eaf4b426726 100644 --- a/net/batman-adv/packet.h +++ b/net/batman-adv/packet.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 40d9bf3e5bfe..86b0ea1e5c1c 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/routing.h b/net/batman-adv/routing.h index 5ede16c32f15..a1289bc5f115 100644 --- a/net/batman-adv/routing.h +++ b/net/batman-adv/routing.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 7895323fd2a7..a6c53684ba70 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h index a16b34f473ef..eb36820e41bc 100644 --- a/net/batman-adv/send.h +++ b/net/batman-adv/send.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 9f673cdfecf8..e543024f98ef 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h index 639c3abb214a..075c5b5b2ce1 100644 --- a/net/batman-adv/soft-interface.h +++ b/net/batman-adv/soft-interface.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index aa187fd42475..ab0b95f15b36 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2010-2017 B.A.T.M.A.N. contributors: * * Marek Lindner diff --git a/net/batman-adv/sysfs.h b/net/batman-adv/sysfs.h index e487412e256b..0384cb6c406b 100644 --- a/net/batman-adv/sysfs.h +++ b/net/batman-adv/sysfs.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2010-2017 B.A.T.M.A.N. contributors: * * Marek Lindner diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c index 15cd2139381e..601feb2c4ecf 100644 --- a/net/batman-adv/tp_meter.c +++ b/net/batman-adv/tp_meter.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2012-2017 B.A.T.M.A.N. contributors: * * Edo Monticelli, Antonio Quartulli diff --git a/net/batman-adv/tp_meter.h b/net/batman-adv/tp_meter.h index a8ada5c123bd..c8b8f2cb2c2b 100644 --- a/net/batman-adv/tp_meter.h +++ b/net/batman-adv/tp_meter.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2012-2017 B.A.T.M.A.N. contributors: * * Edo Monticelli, Antonio Quartulli diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 8a3ce79b1307..281bd4cf7f90 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich, Antonio Quartulli diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h index 411d586191da..8d9e3abec2c8 100644 --- a/net/batman-adv/translation-table.h +++ b/net/batman-adv/translation-table.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich, Antonio Quartulli diff --git a/net/batman-adv/tvlv.c b/net/batman-adv/tvlv.c index 1d9e267caec9..67b2ba4b824b 100644 --- a/net/batman-adv/tvlv.c +++ b/net/batman-adv/tvlv.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/tvlv.h b/net/batman-adv/tvlv.h index 4d01400ada30..a74df33f446d 100644 --- a/net/batman-adv/tvlv.h +++ b/net/batman-adv/tvlv.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index a62795868794..1df798b32077 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich -- cgit v1.2.3-59-g8ed1b From a010579273bdfbee6ee79422dbebba3dcf18ebf7 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sun, 19 Nov 2017 15:05:16 +0100 Subject: batman-adv: Change batman_adv.h license to MIT The ISC license is considered as not recommended in "Linux kernel licensing rules". It should only be used for existing code or for importing code from a different project with that license. But the kernel still has the similar sounding MIT/Expat license under the preferred licenses. Switching to this license for this relatively new file should therefore allow batman-adv to better follow the new licensing rules. Signed-off-by: Sven Eckelmann Acked-by: Antonio Quartulli Acked-by: Matthias Schiffer Acked-by: Andrew Lunn Signed-off-by: Simon Wunderlich --- include/uapi/linux/batman_adv.h | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h index fb4533826163..ae00c99cbed0 100644 --- a/include/uapi/linux/batman_adv.h +++ b/include/uapi/linux/batman_adv.h @@ -1,19 +1,25 @@ -/* SPDX-License-Identifier: ISC */ +/* SPDX-License-Identifier: MIT */ /* Copyright (C) 2016-2017 B.A.T.M.A.N. contributors: * * Matthias Schiffer * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ #ifndef _UAPI_LINUX_BATMAN_ADV_H_ -- cgit v1.2.3-59-g8ed1b From f551c91de262ba36b20c3ac19538afb4f4507441 Mon Sep 17 00:00:00 2001 From: William Tu Date: Wed, 13 Dec 2017 16:38:56 -0800 Subject: net: erspan: introduce erspan v2 for ip_gre The patch adds support for erspan version 2. Not all features are supported in this patch. The SGT (security group tag), GRA (timestamp granularity), FT (frame type) are set to fixed value. Only hardware ID and direction are configurable. Optional subheader is also not supported. Signed-off-by: William Tu Signed-off-by: David S. Miller --- include/net/erspan.h | 120 ++++++++++++++++++++++++++++++++++++++++- include/net/ip_tunnels.h | 5 +- include/uapi/linux/if_ether.h | 1 + include/uapi/linux/if_tunnel.h | 3 ++ net/ipv4/ip_gre.c | 105 ++++++++++++++++++++++++++++++------ 5 files changed, 216 insertions(+), 18 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/net/erspan.h b/include/net/erspan.h index 70c40c7c75b2..acdf6843095d 100644 --- a/include/net/erspan.h +++ b/include/net/erspan.h @@ -24,11 +24,29 @@ * | Reserved | Index | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * + * + * ERSPAN Version 2 (Type III) header (12 octets [42:49]) + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Ver | VLAN | COS |BSO|T| Session ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Timestamp | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | SGT |P| FT | Hw ID |D|Gra|O| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Platform Specific SubHeader (8 octets, optional) + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Platf ID | Platform Specific Info | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Platform Specific Info | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * * GRE proto ERSPAN type II = 0x88BE, type III = 0x22EB */ #define ERSPAN_VERSION 0x1 /* ERSPAN type II */ - #define VER_MASK 0xf000 #define VLAN_MASK 0x0fff #define COS_MASK 0xe000 @@ -37,6 +55,28 @@ #define ID_MASK 0x03ff #define INDEX_MASK 0xfffff +#define ERSPAN_VERSION2 0x2 /* ERSPAN type III*/ +#define BSO_MASK EN_MASK +#define SGT_MASK 0xffff0000 +#define P_MASK 0x8000 +#define FT_MASK 0x7c00 +#define HWID_MASK 0x03f0 +#define DIR_MASK 0x0008 +#define GRA_MASK 0x0006 +#define O_MASK 0x0001 + +/* ERSPAN version 2 metadata header */ +struct erspan_md2 { + __be32 timestamp; + __be16 sgt; /* security group tag */ + __be16 flags; +#define P_OFFSET 15 +#define FT_OFFSET 10 +#define HWID_OFFSET 4 +#define DIR_OFFSET 3 +#define GRA_OFFSET 1 +}; + enum erspan_encap_type { ERSPAN_ENCAP_NOVLAN = 0x0, /* originally without VLAN tag */ ERSPAN_ENCAP_ISL = 0x1, /* originally ISL encapsulated */ @@ -48,8 +88,10 @@ enum erspan_encap_type { #define ERSPAN_V2_MDSIZE 8 struct erspan_metadata { union { - __be32 index; /* Version 1 (type II)*/ + __be32 index; /* Version 1 (type II)*/ + struct erspan_md2 md2; /* Version 2 (type III) */ } u; + int version; }; struct erspan_base_hdr { @@ -58,6 +100,7 @@ struct erspan_base_hdr { __be16 session_id; #define COS_OFFSET 13 #define EN_OFFSET 11 +#define BSO_OFFSET EN_OFFSET #define T_OFFSET 10 }; @@ -123,4 +166,77 @@ static inline void erspan_build_header(struct sk_buff *skb, ersmd->u.index = htonl(index & INDEX_MASK); } +/* ERSPAN GRA: timestamp granularity + * 00b --> granularity = 100 microseconds + * 01b --> granularity = 100 nanoseconds + * 10b --> granularity = IEEE 1588 + * Here we only support 100 microseconds. + */ +static inline __be32 erspan_get_timestamp(void) +{ + u64 h_usecs; + ktime_t kt; + + kt = ktime_get_real(); + h_usecs = ktime_divns(kt, 100 * NSEC_PER_USEC); + + /* ERSPAN base header only has 32-bit, + * so it wraps around 4 days. + */ + return htonl((u32)h_usecs); +} + +static inline void erspan_build_header_v2(struct sk_buff *skb, + __be32 id, u8 direction, u16 hwid, + bool truncate, bool is_ipv4) +{ + struct ethhdr *eth = eth_hdr(skb); + struct erspan_base_hdr *ershdr; + struct erspan_metadata *md; + struct qtag_prefix { + __be16 eth_type; + __be16 tci; + } *qp; + u16 vlan_tci = 0; + u16 session_id; + u8 gra = 0; /* 100 usec */ + u8 bso = 0; /* Bad/Short/Oversized */ + u8 sgt = 0; + u8 tos; + + tos = is_ipv4 ? ip_hdr(skb)->tos : + (ipv6_hdr(skb)->priority << 4) + + (ipv6_hdr(skb)->flow_lbl[0] >> 4); + + /* Unlike v1, v2 does not have En field, + * so only extract vlan tci field. + */ + if (eth->h_proto == htons(ETH_P_8021Q)) { + qp = (struct qtag_prefix *)(skb->data + 2 * ETH_ALEN); + vlan_tci = ntohs(qp->tci); + } + + skb_push(skb, sizeof(*ershdr) + ERSPAN_V2_MDSIZE); + ershdr = (struct erspan_base_hdr *)skb->data; + memset(ershdr, 0, sizeof(*ershdr) + ERSPAN_V2_MDSIZE); + + /* Build base header */ + ershdr->ver_vlan = htons((vlan_tci & VLAN_MASK) | + (ERSPAN_VERSION2 << VER_OFFSET)); + session_id = (u16)(ntohl(id) & ID_MASK) | + ((tos_to_cos(tos) << COS_OFFSET) & COS_MASK) | + (bso << BSO_OFFSET & BSO_MASK) | + ((truncate << T_OFFSET) & T_MASK); + ershdr->session_id = htons(session_id); + + /* Build metadata */ + md = (struct erspan_metadata *)(ershdr + 1); + md->u.md2.timestamp = erspan_get_timestamp(); + md->u.md2.sgt = htons(sgt); + md->u.md2.flags = htons(((1 << P_OFFSET) & P_MASK) | + ((hwid << HWID_OFFSET) & HWID_MASK) | + ((direction << DIR_OFFSET) & DIR_MASK) | + ((gra << GRA_OFFSET) & GRA_MASK)); +} + #endif diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 24628f6b09bf..1f16773cfd76 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -116,8 +116,11 @@ struct ip_tunnel { u32 o_seqno; /* The last output seqno */ int tun_hlen; /* Precalculated header length */ - /* This field used only by ERSPAN */ + /* These four fields used only by ERSPAN */ u32 index; /* ERSPAN type II index */ + u8 erspan_ver; /* ERSPAN version */ + u8 dir; /* ERSPAN direction */ + u16 hwid; /* ERSPAN hardware ID */ struct dst_cache dst_cache; diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h index 3ee3bf7c8526..87b7529fcdfe 100644 --- a/include/uapi/linux/if_ether.h +++ b/include/uapi/linux/if_ether.h @@ -47,6 +47,7 @@ #define ETH_P_PUP 0x0200 /* Xerox PUP packet */ #define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */ #define ETH_P_TSN 0x22F0 /* TSN (IEEE 1722) packet */ +#define ETH_P_ERSPAN2 0x22EB /* ERSPAN version 2 (type III) */ #define ETH_P_IP 0x0800 /* Internet Protocol packet */ #define ETH_P_X25 0x0805 /* CCITT X.25 */ #define ETH_P_ARP 0x0806 /* Address Resolution packet */ diff --git a/include/uapi/linux/if_tunnel.h b/include/uapi/linux/if_tunnel.h index e68dadbd6d45..1b3d148c4560 100644 --- a/include/uapi/linux/if_tunnel.h +++ b/include/uapi/linux/if_tunnel.h @@ -137,6 +137,9 @@ enum { IFLA_GRE_IGNORE_DF, IFLA_GRE_FWMARK, IFLA_GRE_ERSPAN_INDEX, + IFLA_GRE_ERSPAN_VER, + IFLA_GRE_ERSPAN_DIR, + IFLA_GRE_ERSPAN_HWID, __IFLA_GRE_MAX, }; diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 3e37402147f3..004800b923c6 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -315,11 +315,26 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, return PACKET_REJECT; memcpy(md, pkt_md, sizeof(*md)); + md->version = ver; + info = &tun_dst->u.tun_info; info->key.tun_flags |= TUNNEL_ERSPAN_OPT; info->options_len = sizeof(*md); } else { - tunnel->index = ntohl(pkt_md->u.index); + tunnel->erspan_ver = ver; + if (ver == 1) { + tunnel->index = ntohl(pkt_md->u.index); + } else { + u16 md2_flags; + u16 dir, hwid; + + md2_flags = ntohs(pkt_md->u.md2.flags); + dir = (md2_flags & DIR_MASK) >> DIR_OFFSET; + hwid = (md2_flags & HWID_MASK) >> HWID_OFFSET; + tunnel->dir = dir; + tunnel->hwid = hwid; + } + } skb_reset_mac_header(skb); @@ -413,7 +428,8 @@ static int gre_rcv(struct sk_buff *skb) if (hdr_len < 0) goto drop; - if (unlikely(tpi.proto == htons(ETH_P_ERSPAN))) { + if (unlikely(tpi.proto == htons(ETH_P_ERSPAN) || + tpi.proto == htons(ETH_P_ERSPAN2))) { if (erspan_rcv(skb, &tpi, hdr_len) == PACKET_RCVD) return 0; } @@ -568,6 +584,7 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev, bool truncate = false; struct flowi4 fl; int tunnel_hlen; + int version; __be16 df; tun_info = skb_tunnel_info(skb); @@ -576,9 +593,13 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev, goto err_free_skb; key = &tun_info->key; + md = ip_tunnel_info_opts(tun_info); + if (!md) + goto err_free_rt; /* ERSPAN has fixed 8 byte GRE header */ - tunnel_hlen = 8 + sizeof(struct erspan_base_hdr) + ERSPAN_V1_MDSIZE; + version = md->version; + tunnel_hlen = 8 + erspan_hdr_len(version); rt = prepare_fb_xmit(skb, dev, &fl, tunnel_hlen); if (!rt) @@ -592,12 +613,23 @@ static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev, truncate = true; } - md = ip_tunnel_info_opts(tun_info); - if (!md) - goto err_free_rt; + if (version == 1) { + erspan_build_header(skb, tunnel_id_to_key32(key->tun_id), + ntohl(md->u.index), truncate, true); + } else if (version == 2) { + u16 md2_flags; + u8 direction; + u16 hwid; - erspan_build_header(skb, tunnel_id_to_key32(key->tun_id), - ntohl(md->u.index), truncate, true); + md2_flags = ntohs(md->u.md2.flags); + direction = (md2_flags & DIR_MASK) >> DIR_OFFSET; + hwid = (md2_flags & HWID_MASK) >> HWID_OFFSET; + + erspan_build_header_v2(skb, tunnel_id_to_key32(key->tun_id), + direction, hwid, truncate, true); + } else { + goto err_free_rt; + } gre_build_header(skb, 8, TUNNEL_SEQ, htons(ETH_P_ERSPAN), 0, htonl(tunnel->o_seqno++)); @@ -699,8 +731,14 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, } /* Push ERSPAN header */ - erspan_build_header(skb, tunnel->parms.o_key, tunnel->index, - truncate, true); + if (tunnel->erspan_ver == 1) + erspan_build_header(skb, tunnel->parms.o_key, tunnel->index, + truncate, true); + else + erspan_build_header_v2(skb, tunnel->parms.o_key, + tunnel->dir, tunnel->hwid, + truncate, true); + tunnel->parms.o_flags &= ~TUNNEL_KEY; __gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_ERSPAN)); return NETDEV_TX_OK; @@ -1172,13 +1210,32 @@ static int ipgre_netlink_parms(struct net_device *dev, if (data[IFLA_GRE_FWMARK]) *fwmark = nla_get_u32(data[IFLA_GRE_FWMARK]); - if (data[IFLA_GRE_ERSPAN_INDEX]) { - t->index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]); + if (data[IFLA_GRE_ERSPAN_VER]) { + t->erspan_ver = nla_get_u8(data[IFLA_GRE_ERSPAN_VER]); - if (t->index & ~INDEX_MASK) + if (t->erspan_ver != 1 && t->erspan_ver != 2) return -EINVAL; } + if (t->erspan_ver == 1) { + if (data[IFLA_GRE_ERSPAN_INDEX]) { + t->index = nla_get_u32(data[IFLA_GRE_ERSPAN_INDEX]); + if (t->index & ~INDEX_MASK) + return -EINVAL; + } + } else if (t->erspan_ver == 2) { + if (data[IFLA_GRE_ERSPAN_DIR]) { + t->dir = nla_get_u8(data[IFLA_GRE_ERSPAN_DIR]); + if (t->dir & ~(DIR_MASK >> DIR_OFFSET)) + return -EINVAL; + } + if (data[IFLA_GRE_ERSPAN_HWID]) { + t->hwid = nla_get_u16(data[IFLA_GRE_ERSPAN_HWID]); + if (t->hwid & ~(HWID_MASK >> HWID_OFFSET)) + return -EINVAL; + } + } + return 0; } @@ -1245,7 +1302,7 @@ static int erspan_tunnel_init(struct net_device *dev) tunnel->tun_hlen = 8; tunnel->parms.iph.protocol = IPPROTO_GRE; tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen + - sizeof(struct erspan_base_hdr) + ERSPAN_V1_MDSIZE; + erspan_hdr_len(tunnel->erspan_ver); t_hlen = tunnel->hlen + sizeof(struct iphdr); dev->needed_headroom = LL_MAX_HEADER + t_hlen + 4; @@ -1375,6 +1432,12 @@ static size_t ipgre_get_size(const struct net_device *dev) nla_total_size(4) + /* IFLA_GRE_ERSPAN_INDEX */ nla_total_size(4) + + /* IFLA_GRE_ERSPAN_VER */ + nla_total_size(1) + + /* IFLA_GRE_ERSPAN_DIR */ + nla_total_size(1) + + /* IFLA_GRE_ERSPAN_HWID */ + nla_total_size(2) + 0; } @@ -1417,9 +1480,18 @@ static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev) goto nla_put_failure; } - if (t->index) + if (nla_put_u8(skb, IFLA_GRE_ERSPAN_VER, t->erspan_ver)) + goto nla_put_failure; + + if (t->erspan_ver == 1) { if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, t->index)) goto nla_put_failure; + } else if (t->erspan_ver == 2) { + if (nla_put_u8(skb, IFLA_GRE_ERSPAN_DIR, t->dir)) + goto nla_put_failure; + if (nla_put_u16(skb, IFLA_GRE_ERSPAN_HWID, t->hwid)) + goto nla_put_failure; + } return 0; @@ -1455,6 +1527,9 @@ static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = { [IFLA_GRE_IGNORE_DF] = { .type = NLA_U8 }, [IFLA_GRE_FWMARK] = { .type = NLA_U32 }, [IFLA_GRE_ERSPAN_INDEX] = { .type = NLA_U32 }, + [IFLA_GRE_ERSPAN_VER] = { .type = NLA_U8 }, + [IFLA_GRE_ERSPAN_DIR] = { .type = NLA_U8 }, + [IFLA_GRE_ERSPAN_HWID] = { .type = NLA_U16 }, }; static struct rtnl_link_ops ipgre_link_ops __read_mostly = { -- cgit v1.2.3-59-g8ed1b From cc8b0b92a1699bc32f7fec71daa2bfc90de43a4d Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Thu, 14 Dec 2017 17:55:05 -0800 Subject: bpf: introduce function calls (function boundaries) Allow arbitrary function calls from bpf function to another bpf function. Since the beginning of bpf all bpf programs were represented as a single function and program authors were forced to use always_inline for all functions in their C code. That was causing llvm to unnecessary inflate the code size and forcing developers to move code to header files with little code reuse. With a bit of additional complexity teach verifier to recognize arbitrary function calls from one bpf function to another as long as all of functions are presented to the verifier as a single bpf program. New program layout: r6 = r1 // some code .. r1 = .. // arg1 r2 = .. // arg2 call pc+1 // function call pc-relative exit .. = r1 // access arg1 .. = r2 // access arg2 .. call pc+20 // second level of function call ... It allows for better optimized code and finally allows to introduce the core bpf libraries that can be reused in different projects, since programs are no longer limited by single elf file. With function calls bpf can be compiled into multiple .o files. This patch is the first step. It detects programs that contain multiple functions and checks that calls between them are valid. It splits the sequence of bpf instructions (one program) into a set of bpf functions that call each other. Calls to only known functions are allowed. In the future the verifier may allow calls to unresolved functions and will do dynamic linking. This logic supports statically linked bpf functions only. Such function boundary detection could have been done as part of control flow graph building in check_cfg(), but it's cleaner to separate function boundary detection vs control flow checks within a subprogram (function) into logically indepedent steps. Follow up patches may split check_cfg() further, but not check_subprogs(). Only allow bpf-to-bpf calls for root only and for non-hw-offloaded programs. These restrictions can be relaxed in the future. Signed-off-by: Alexei Starovoitov Acked-by: Daniel Borkmann Signed-off-by: Daniel Borkmann --- include/linux/bpf_verifier.h | 5 +- include/uapi/linux/bpf.h | 6 ++ kernel/bpf/disasm.c | 8 ++- kernel/bpf/verifier.c | 141 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 155 insertions(+), 5 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index c561b986bab0..91a583bb3fa7 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -141,6 +141,8 @@ struct bpf_ext_analyzer_ops { int insn_idx, int prev_insn_idx); }; +#define BPF_MAX_SUBPROGS 256 + /* single container for all structs * one verifier_env per bpf_check() call */ @@ -159,8 +161,9 @@ struct bpf_verifier_env { bool allow_ptr_leaks; bool seen_direct_write; struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */ - struct bpf_verifer_log log; + u32 subprog_starts[BPF_MAX_SUBPROGS]; + u32 subprog_cnt; }; static inline struct bpf_reg_state *cur_regs(struct bpf_verifier_env *env) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 595bda120cfb..d01f1cb3cfc0 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -197,8 +197,14 @@ enum bpf_attach_type { */ #define BPF_F_STRICT_ALIGNMENT (1U << 0) +/* when bpf_ldimm64->src_reg == BPF_PSEUDO_MAP_FD, bpf_ldimm64->imm == fd */ #define BPF_PSEUDO_MAP_FD 1 +/* when bpf_call->src_reg == BPF_PSEUDO_CALL, bpf_call->imm == pc-relative + * offset to another bpf function + */ +#define BPF_PSEUDO_CALL 1 + /* flags for BPF_MAP_UPDATE_ELEM command */ #define BPF_ANY 0 /* create new element or update existing */ #define BPF_NOEXIST 1 /* create new element if it didn't exist */ diff --git a/kernel/bpf/disasm.c b/kernel/bpf/disasm.c index e682850c9715..883f88fa5bfc 100644 --- a/kernel/bpf/disasm.c +++ b/kernel/bpf/disasm.c @@ -189,8 +189,12 @@ void print_bpf_insn(bpf_insn_print_cb verbose, struct bpf_verifier_env *env, u8 opcode = BPF_OP(insn->code); if (opcode == BPF_CALL) { - verbose(env, "(%02x) call %s#%d\n", insn->code, - func_id_name(insn->imm), insn->imm); + if (insn->src_reg == BPF_PSEUDO_CALL) + verbose(env, "(%02x) call pc%+d\n", insn->code, + insn->imm); + else + verbose(env, "(%02x) call %s#%d\n", insn->code, + func_id_name(insn->imm), insn->imm); } else if (insn->code == (BPF_JMP | BPF_JA)) { verbose(env, "(%02x) goto pc%+d\n", insn->code, insn->off); diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index e807bda7fe29..1d0f7ff0b9a9 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include "disasm.h" @@ -636,6 +638,113 @@ enum reg_arg_type { DST_OP_NO_MARK /* same as above, check only, don't mark */ }; +static int cmp_subprogs(const void *a, const void *b) +{ + return *(int *)a - *(int *)b; +} + +static int find_subprog(struct bpf_verifier_env *env, int off) +{ + u32 *p; + + p = bsearch(&off, env->subprog_starts, env->subprog_cnt, + sizeof(env->subprog_starts[0]), cmp_subprogs); + if (!p) + return -ENOENT; + return p - env->subprog_starts; + +} + +static int add_subprog(struct bpf_verifier_env *env, int off) +{ + int insn_cnt = env->prog->len; + int ret; + + if (off >= insn_cnt || off < 0) { + verbose(env, "call to invalid destination\n"); + return -EINVAL; + } + ret = find_subprog(env, off); + if (ret >= 0) + return 0; + if (env->subprog_cnt >= BPF_MAX_SUBPROGS) { + verbose(env, "too many subprograms\n"); + return -E2BIG; + } + env->subprog_starts[env->subprog_cnt++] = off; + sort(env->subprog_starts, env->subprog_cnt, + sizeof(env->subprog_starts[0]), cmp_subprogs, NULL); + return 0; +} + +static int check_subprogs(struct bpf_verifier_env *env) +{ + int i, ret, subprog_start, subprog_end, off, cur_subprog = 0; + struct bpf_insn *insn = env->prog->insnsi; + int insn_cnt = env->prog->len; + + /* determine subprog starts. The end is one before the next starts */ + for (i = 0; i < insn_cnt; i++) { + if (insn[i].code != (BPF_JMP | BPF_CALL)) + continue; + if (insn[i].src_reg != BPF_PSEUDO_CALL) + continue; + if (!env->allow_ptr_leaks) { + verbose(env, "function calls to other bpf functions are allowed for root only\n"); + return -EPERM; + } + if (bpf_prog_is_dev_bound(env->prog->aux)) { + verbose(env, "funcation calls in offloaded programs are not supported yet\n"); + return -EINVAL; + } + ret = add_subprog(env, i + insn[i].imm + 1); + if (ret < 0) + return ret; + } + + if (env->log.level > 1) + for (i = 0; i < env->subprog_cnt; i++) + verbose(env, "func#%d @%d\n", i, env->subprog_starts[i]); + + /* now check that all jumps are within the same subprog */ + subprog_start = 0; + if (env->subprog_cnt == cur_subprog) + subprog_end = insn_cnt; + else + subprog_end = env->subprog_starts[cur_subprog++]; + for (i = 0; i < insn_cnt; i++) { + u8 code = insn[i].code; + + if (BPF_CLASS(code) != BPF_JMP) + goto next; + if (BPF_OP(code) == BPF_EXIT || BPF_OP(code) == BPF_CALL) + goto next; + off = i + insn[i].off + 1; + if (off < subprog_start || off >= subprog_end) { + verbose(env, "jump out of range from insn %d to %d\n", i, off); + return -EINVAL; + } +next: + if (i == subprog_end - 1) { + /* to avoid fall-through from one subprog into another + * the last insn of the subprog should be either exit + * or unconditional jump back + */ + if (code != (BPF_JMP | BPF_EXIT) && + code != (BPF_JMP | BPF_JA)) { + verbose(env, "last insn is not an exit or jmp\n"); + return -EINVAL; + } + subprog_start = subprog_end; + if (env->subprog_cnt == cur_subprog) + subprog_end = insn_cnt; + else + subprog_end = env->subprog_starts[cur_subprog++]; + } + } + return 0; +} + static void mark_reg_read(const struct bpf_verifier_state *state, u32 regno) { struct bpf_verifier_state *parent = state->parent; @@ -3284,6 +3393,10 @@ static int check_cfg(struct bpf_verifier_env *env) int ret = 0; int i, t; + ret = check_subprogs(env); + if (ret < 0) + return ret; + insn_state = kcalloc(insn_cnt, sizeof(int), GFP_KERNEL); if (!insn_state) return -ENOMEM; @@ -3316,6 +3429,14 @@ peek_stack: goto err_free; if (t + 1 < insn_cnt) env->explored_states[t + 1] = STATE_LIST_MARK; + if (insns[t].src_reg == BPF_PSEUDO_CALL) { + env->explored_states[t] = STATE_LIST_MARK; + ret = push_insn(t, t + insns[t].imm + 1, BRANCH, env); + if (ret == 1) + goto peek_stack; + else if (ret < 0) + goto err_free; + } } else if (opcode == BPF_JA) { if (BPF_SRC(insns[t].code) != BPF_K) { ret = -EINVAL; @@ -4245,6 +4366,19 @@ static int adjust_insn_aux_data(struct bpf_verifier_env *env, u32 prog_len, return 0; } +static void adjust_subprog_starts(struct bpf_verifier_env *env, u32 off, u32 len) +{ + int i; + + if (len == 1) + return; + for (i = 0; i < env->subprog_cnt; i++) { + if (env->subprog_starts[i] < off) + continue; + env->subprog_starts[i] += len - 1; + } +} + static struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 off, const struct bpf_insn *patch, u32 len) { @@ -4255,6 +4389,7 @@ static struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 of return NULL; if (adjust_insn_aux_data(env, new_prog->len, off, len)) return NULL; + adjust_subprog_starts(env, off, len); return new_prog; } @@ -4408,6 +4543,8 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) for (i = 0; i < insn_cnt; i++, insn++) { if (insn->code != (BPF_JMP | BPF_CALL)) continue; + if (insn->src_reg == BPF_PSEUDO_CALL) + continue; if (insn->imm == BPF_FUNC_get_route_realm) prog->dst_needed = 1; @@ -4589,12 +4726,12 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr) if (!env->explored_states) goto skip_full_check; + env->allow_ptr_leaks = capable(CAP_SYS_ADMIN); + ret = check_cfg(env); if (ret < 0) goto skip_full_check; - env->allow_ptr_leaks = capable(CAP_SYS_ADMIN); - ret = do_check(env); if (env->cur_state) { free_verifier_state(env->cur_state, true); -- cgit v1.2.3-59-g8ed1b From 0bd9298557eefbf63d169cc8f853fa3f21078cab Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 27 Sep 2017 09:22:01 -0400 Subject: media: frontend: describe nested structs There are some nested structs on this header, with aren't properly document them. This should solve some warnings after the addition of a patche at kernel-doc adding support for nested structs/unions. Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/dvb/frontend.h | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h index b297b65845d6..9dad6c66cc34 100644 --- a/include/uapi/linux/dvb/frontend.h +++ b/include/uapi/linux/dvb/frontend.h @@ -756,16 +756,15 @@ enum fecap_scale_params { /** * struct dtv_stats - Used for reading a DTV status property * - * @scale: Filled with enum fecap_scale_params - the scale - * in usage for that parameter + * @scale: + * Filled with enum fecap_scale_params - the scale in usage + * for that parameter * - * The ``{unnamed_union}`` may have either one of the values below: - * - * %svalue + * @svalue: * integer value of the measure, for %FE_SCALE_DECIBEL, * used for dB measures. The unit is 0.001 dB. * - * %uvalue + * @uvalue: * unsigned integer value of the measure, used when @scale is * either %FE_SCALE_RELATIVE or %FE_SCALE_COUNTER. * @@ -828,19 +827,19 @@ struct dtv_fe_stats { /** * struct dtv_property - store one of frontend command and its value * - * @cmd: Digital TV command. - * @reserved: Not used. - * @u: Union with the values for the command. - * @result: Unused - * - * The @u union may have either one of the values below: + * @cmd: Digital TV command. + * @reserved: Not used. + * @u: Union with the values for the command. + * @u.data: A unsigned 32 bits integer with command value. + * @u.buffer: Struct to store bigger properties. + * Currently unused. + * @u.buffer.data: an unsigned 32-bits array. + * @u.buffer.len: number of elements of the buffer. + * @u.buffer.reserved1: Reserved. + * @u.buffer.reserved2: Reserved. + * @u.st: a &struct dtv_fe_stats array of statistics. + * @result: Currently unused. * - * %data - * an unsigned 32-bits number. - * %st - * a &struct dtv_fe_stats array of statistics. - * %buffer - * a buffer of up to 32 characters (currently unused). */ struct dtv_property { __u32 cmd; -- cgit v1.2.3-59-g8ed1b From f6ddd094f5793447d594aa9f42032a7aba12b4d2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 30 Nov 2017 17:01:25 +0100 Subject: virt: Add vboxguest driver for Virtual Box Guest integration UAPI This commit adds the headers describing the ioctl API for the /dev/vboxguest device used by the Virtual Box Guest Additions in Virtual Box virtual machines. The driver providing the /dev/vboxguest device will allow Virtual Box Guest Additions features such as copy-and-paste, seamless mode and OpenGL pass-through. Signed-off-by: Hans de Goede Reviewed-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 7 + include/uapi/linux/vbox_err.h | 151 +++++++++++++++ include/uapi/linux/vbox_vmmdev_types.h | 226 ++++++++++++++++++++++ include/uapi/linux/vboxguest.h | 330 +++++++++++++++++++++++++++++++++ 4 files changed, 714 insertions(+) create mode 100644 include/uapi/linux/vbox_err.h create mode 100644 include/uapi/linux/vbox_vmmdev_types.h create mode 100644 include/uapi/linux/vboxguest.h (limited to 'include/uapi/linux') diff --git a/MAINTAINERS b/MAINTAINERS index 8d83ed21a62b..405d4d28b612 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14557,6 +14557,13 @@ S: Maintained F: drivers/virtio/virtio_input.c F: include/uapi/linux/virtio_input.h +VIRTUAL BOX GUEST DEVICE DRIVER +M: Hans de Goede +M: Arnd Bergmann +M: Greg Kroah-Hartman +S: Maintained +F: include/uapi/linux/vbox*.h + VIRTUAL SERIO DEVICE DRIVER M: Stephen Chandler Paul S: Maintained diff --git a/include/uapi/linux/vbox_err.h b/include/uapi/linux/vbox_err.h new file mode 100644 index 000000000000..7eae536ff1e6 --- /dev/null +++ b/include/uapi/linux/vbox_err.h @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright (C) 2017 Oracle Corporation */ + +#ifndef __UAPI_VBOX_ERR_H__ +#define __UAPI_VBOX_ERR_H__ + +#define VINF_SUCCESS 0 +#define VERR_GENERAL_FAILURE (-1) +#define VERR_INVALID_PARAMETER (-2) +#define VERR_INVALID_MAGIC (-3) +#define VERR_INVALID_HANDLE (-4) +#define VERR_LOCK_FAILED (-5) +#define VERR_INVALID_POINTER (-6) +#define VERR_IDT_FAILED (-7) +#define VERR_NO_MEMORY (-8) +#define VERR_ALREADY_LOADED (-9) +#define VERR_PERMISSION_DENIED (-10) +#define VERR_VERSION_MISMATCH (-11) +#define VERR_NOT_IMPLEMENTED (-12) +#define VERR_INVALID_FLAGS (-13) + +#define VERR_NOT_EQUAL (-18) +#define VERR_NOT_SYMLINK (-19) +#define VERR_NO_TMP_MEMORY (-20) +#define VERR_INVALID_FMODE (-21) +#define VERR_WRONG_ORDER (-22) +#define VERR_NO_TLS_FOR_SELF (-23) +#define VERR_FAILED_TO_SET_SELF_TLS (-24) +#define VERR_NO_CONT_MEMORY (-26) +#define VERR_NO_PAGE_MEMORY (-27) +#define VERR_THREAD_IS_DEAD (-29) +#define VERR_THREAD_NOT_WAITABLE (-30) +#define VERR_PAGE_TABLE_NOT_PRESENT (-31) +#define VERR_INVALID_CONTEXT (-32) +#define VERR_TIMER_BUSY (-33) +#define VERR_ADDRESS_CONFLICT (-34) +#define VERR_UNRESOLVED_ERROR (-35) +#define VERR_INVALID_FUNCTION (-36) +#define VERR_NOT_SUPPORTED (-37) +#define VERR_ACCESS_DENIED (-38) +#define VERR_INTERRUPTED (-39) +#define VERR_TIMEOUT (-40) +#define VERR_BUFFER_OVERFLOW (-41) +#define VERR_TOO_MUCH_DATA (-42) +#define VERR_MAX_THRDS_REACHED (-43) +#define VERR_MAX_PROCS_REACHED (-44) +#define VERR_SIGNAL_REFUSED (-45) +#define VERR_SIGNAL_PENDING (-46) +#define VERR_SIGNAL_INVALID (-47) +#define VERR_STATE_CHANGED (-48) +#define VERR_INVALID_UUID_FORMAT (-49) +#define VERR_PROCESS_NOT_FOUND (-50) +#define VERR_PROCESS_RUNNING (-51) +#define VERR_TRY_AGAIN (-52) +#define VERR_PARSE_ERROR (-53) +#define VERR_OUT_OF_RANGE (-54) +#define VERR_NUMBER_TOO_BIG (-55) +#define VERR_NO_DIGITS (-56) +#define VERR_NEGATIVE_UNSIGNED (-57) +#define VERR_NO_TRANSLATION (-58) + +#define VERR_NOT_FOUND (-78) +#define VERR_INVALID_STATE (-79) +#define VERR_OUT_OF_RESOURCES (-80) + +#define VERR_FILE_NOT_FOUND (-102) +#define VERR_PATH_NOT_FOUND (-103) +#define VERR_INVALID_NAME (-104) +#define VERR_ALREADY_EXISTS (-105) +#define VERR_TOO_MANY_OPEN_FILES (-106) +#define VERR_SEEK (-107) +#define VERR_NEGATIVE_SEEK (-108) +#define VERR_SEEK_ON_DEVICE (-109) +#define VERR_EOF (-110) +#define VERR_READ_ERROR (-111) +#define VERR_WRITE_ERROR (-112) +#define VERR_WRITE_PROTECT (-113) +#define VERR_SHARING_VIOLATION (-114) +#define VERR_FILE_LOCK_FAILED (-115) +#define VERR_FILE_LOCK_VIOLATION (-116) +#define VERR_CANT_CREATE (-117) +#define VERR_CANT_DELETE_DIRECTORY (-118) +#define VERR_NOT_SAME_DEVICE (-119) +#define VERR_FILENAME_TOO_LONG (-120) +#define VERR_MEDIA_NOT_PRESENT (-121) +#define VERR_MEDIA_NOT_RECOGNIZED (-122) +#define VERR_FILE_NOT_LOCKED (-123) +#define VERR_FILE_LOCK_LOST (-124) +#define VERR_DIR_NOT_EMPTY (-125) +#define VERR_NOT_A_DIRECTORY (-126) +#define VERR_IS_A_DIRECTORY (-127) +#define VERR_FILE_TOO_BIG (-128) + +#define VERR_NET_IO_ERROR (-400) +#define VERR_NET_OUT_OF_RESOURCES (-401) +#define VERR_NET_HOST_NOT_FOUND (-402) +#define VERR_NET_PATH_NOT_FOUND (-403) +#define VERR_NET_PRINT_ERROR (-404) +#define VERR_NET_NO_NETWORK (-405) +#define VERR_NET_NOT_UNIQUE_NAME (-406) + +#define VERR_NET_IN_PROGRESS (-436) +#define VERR_NET_ALREADY_IN_PROGRESS (-437) +#define VERR_NET_NOT_SOCKET (-438) +#define VERR_NET_DEST_ADDRESS_REQUIRED (-439) +#define VERR_NET_MSG_SIZE (-440) +#define VERR_NET_PROTOCOL_TYPE (-441) +#define VERR_NET_PROTOCOL_NOT_AVAILABLE (-442) +#define VERR_NET_PROTOCOL_NOT_SUPPORTED (-443) +#define VERR_NET_SOCKET_TYPE_NOT_SUPPORTED (-444) +#define VERR_NET_OPERATION_NOT_SUPPORTED (-445) +#define VERR_NET_PROTOCOL_FAMILY_NOT_SUPPORTED (-446) +#define VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED (-447) +#define VERR_NET_ADDRESS_IN_USE (-448) +#define VERR_NET_ADDRESS_NOT_AVAILABLE (-449) +#define VERR_NET_DOWN (-450) +#define VERR_NET_UNREACHABLE (-451) +#define VERR_NET_CONNECTION_RESET (-452) +#define VERR_NET_CONNECTION_ABORTED (-453) +#define VERR_NET_CONNECTION_RESET_BY_PEER (-454) +#define VERR_NET_NO_BUFFER_SPACE (-455) +#define VERR_NET_ALREADY_CONNECTED (-456) +#define VERR_NET_NOT_CONNECTED (-457) +#define VERR_NET_SHUTDOWN (-458) +#define VERR_NET_TOO_MANY_REFERENCES (-459) +#define VERR_NET_CONNECTION_TIMED_OUT (-460) +#define VERR_NET_CONNECTION_REFUSED (-461) +#define VERR_NET_HOST_DOWN (-464) +#define VERR_NET_HOST_UNREACHABLE (-465) +#define VERR_NET_PROTOCOL_ERROR (-466) +#define VERR_NET_INCOMPLETE_TX_PACKET (-467) + +/* misc. unsorted codes */ +#define VERR_RESOURCE_BUSY (-138) +#define VERR_DISK_FULL (-152) +#define VERR_TOO_MANY_SYMLINKS (-156) +#define VERR_NO_MORE_FILES (-201) +#define VERR_INTERNAL_ERROR (-225) +#define VERR_INTERNAL_ERROR_2 (-226) +#define VERR_INTERNAL_ERROR_3 (-227) +#define VERR_INTERNAL_ERROR_4 (-228) +#define VERR_DEV_IO_ERROR (-250) +#define VERR_IO_BAD_LENGTH (-255) +#define VERR_BROKEN_PIPE (-301) +#define VERR_NO_DATA (-304) +#define VERR_SEM_DESTROYED (-363) +#define VERR_DEADLOCK (-365) +#define VERR_BAD_EXE_FORMAT (-608) +#define VINF_HGCM_ASYNC_EXECUTE (2903) + +#endif diff --git a/include/uapi/linux/vbox_vmmdev_types.h b/include/uapi/linux/vbox_vmmdev_types.h new file mode 100644 index 000000000000..0e68024f36c7 --- /dev/null +++ b/include/uapi/linux/vbox_vmmdev_types.h @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR CDDL-1.0) */ +/* + * Virtual Device for Guest <-> VMM/Host communication, type definitions + * which are also used for the vboxguest ioctl interface / by vboxsf + * + * Copyright (C) 2006-2016 Oracle Corporation + */ + +#ifndef __UAPI_VBOX_VMMDEV_TYPES_H__ +#define __UAPI_VBOX_VMMDEV_TYPES_H__ + +#include +#include + +/* + * We cannot use linux' compiletime_assert here because it expects to be used + * inside a function only. Use a typedef to a char array with a negative size. + */ +#define VMMDEV_ASSERT_SIZE(type, size) \ + typedef char type ## _asrt_size[1 - 2*!!(sizeof(struct type) != (size))] + +/** enum vmmdev_request_type - VMMDev request types. */ +enum vmmdev_request_type { + VMMDEVREQ_INVALID_REQUEST = 0, + VMMDEVREQ_GET_MOUSE_STATUS = 1, + VMMDEVREQ_SET_MOUSE_STATUS = 2, + VMMDEVREQ_SET_POINTER_SHAPE = 3, + VMMDEVREQ_GET_HOST_VERSION = 4, + VMMDEVREQ_IDLE = 5, + VMMDEVREQ_GET_HOST_TIME = 10, + VMMDEVREQ_GET_HYPERVISOR_INFO = 20, + VMMDEVREQ_SET_HYPERVISOR_INFO = 21, + VMMDEVREQ_REGISTER_PATCH_MEMORY = 22, /* since version 3.0.6 */ + VMMDEVREQ_DEREGISTER_PATCH_MEMORY = 23, /* since version 3.0.6 */ + VMMDEVREQ_SET_POWER_STATUS = 30, + VMMDEVREQ_ACKNOWLEDGE_EVENTS = 41, + VMMDEVREQ_CTL_GUEST_FILTER_MASK = 42, + VMMDEVREQ_REPORT_GUEST_INFO = 50, + VMMDEVREQ_REPORT_GUEST_INFO2 = 58, /* since version 3.2.0 */ + VMMDEVREQ_REPORT_GUEST_STATUS = 59, /* since version 3.2.8 */ + VMMDEVREQ_REPORT_GUEST_USER_STATE = 74, /* since version 4.3 */ + /* Retrieve a display resize request sent by the host, deprecated. */ + VMMDEVREQ_GET_DISPLAY_CHANGE_REQ = 51, + VMMDEVREQ_VIDEMODE_SUPPORTED = 52, + VMMDEVREQ_GET_HEIGHT_REDUCTION = 53, + /** + * @VMMDEVREQ_GET_DISPLAY_CHANGE_REQ2: + * Retrieve a display resize request sent by the host. + * + * Queries a display resize request sent from the host. If the + * event_ack member is sent to true and there is an unqueried request + * available for one of the virtual display then that request will + * be returned. If several displays have unqueried requests the lowest + * numbered display will be chosen first. Only the most recent unseen + * request for each display is remembered. + * If event_ack is set to false, the last host request queried with + * event_ack set is resent, or failing that the most recent received + * from the host. If no host request was ever received then all zeros + * are returned. + */ + VMMDEVREQ_GET_DISPLAY_CHANGE_REQ2 = 54, + VMMDEVREQ_REPORT_GUEST_CAPABILITIES = 55, + VMMDEVREQ_SET_GUEST_CAPABILITIES = 56, + VMMDEVREQ_VIDEMODE_SUPPORTED2 = 57, /* since version 3.2.0 */ + VMMDEVREQ_GET_DISPLAY_CHANGE_REQEX = 80, /* since version 4.2.4 */ + VMMDEVREQ_HGCM_CONNECT = 60, + VMMDEVREQ_HGCM_DISCONNECT = 61, + VMMDEVREQ_HGCM_CALL32 = 62, + VMMDEVREQ_HGCM_CALL64 = 63, + VMMDEVREQ_HGCM_CANCEL = 64, + VMMDEVREQ_HGCM_CANCEL2 = 65, + VMMDEVREQ_VIDEO_ACCEL_ENABLE = 70, + VMMDEVREQ_VIDEO_ACCEL_FLUSH = 71, + VMMDEVREQ_VIDEO_SET_VISIBLE_REGION = 72, + VMMDEVREQ_GET_SEAMLESS_CHANGE_REQ = 73, + VMMDEVREQ_QUERY_CREDENTIALS = 100, + VMMDEVREQ_REPORT_CREDENTIALS_JUDGEMENT = 101, + VMMDEVREQ_REPORT_GUEST_STATS = 110, + VMMDEVREQ_GET_MEMBALLOON_CHANGE_REQ = 111, + VMMDEVREQ_GET_STATISTICS_CHANGE_REQ = 112, + VMMDEVREQ_CHANGE_MEMBALLOON = 113, + VMMDEVREQ_GET_VRDPCHANGE_REQ = 150, + VMMDEVREQ_LOG_STRING = 200, + VMMDEVREQ_GET_CPU_HOTPLUG_REQ = 210, + VMMDEVREQ_SET_CPU_HOTPLUG_STATUS = 211, + VMMDEVREQ_REGISTER_SHARED_MODULE = 212, + VMMDEVREQ_UNREGISTER_SHARED_MODULE = 213, + VMMDEVREQ_CHECK_SHARED_MODULES = 214, + VMMDEVREQ_GET_PAGE_SHARING_STATUS = 215, + VMMDEVREQ_DEBUG_IS_PAGE_SHARED = 216, + VMMDEVREQ_GET_SESSION_ID = 217, /* since version 3.2.8 */ + VMMDEVREQ_WRITE_COREDUMP = 218, + VMMDEVREQ_GUEST_HEARTBEAT = 219, + VMMDEVREQ_HEARTBEAT_CONFIGURE = 220, + /* Ensure the enum is a 32 bit data-type */ + VMMDEVREQ_SIZEHACK = 0x7fffffff +}; + +#if __BITS_PER_LONG == 64 +#define VMMDEVREQ_HGCM_CALL VMMDEVREQ_HGCM_CALL64 +#else +#define VMMDEVREQ_HGCM_CALL VMMDEVREQ_HGCM_CALL32 +#endif + +/** HGCM service location types. */ +enum vmmdev_hgcm_service_location_type { + VMMDEV_HGCM_LOC_INVALID = 0, + VMMDEV_HGCM_LOC_LOCALHOST = 1, + VMMDEV_HGCM_LOC_LOCALHOST_EXISTING = 2, + /* Ensure the enum is a 32 bit data-type */ + VMMDEV_HGCM_LOC_SIZEHACK = 0x7fffffff +}; + +/** HGCM host service location. */ +struct vmmdev_hgcm_service_location_localhost { + /** Service name */ + char service_name[128]; +}; +VMMDEV_ASSERT_SIZE(vmmdev_hgcm_service_location_localhost, 128); + +/** HGCM service location. */ +struct vmmdev_hgcm_service_location { + /** Type of the location. */ + enum vmmdev_hgcm_service_location_type type; + + union { + struct vmmdev_hgcm_service_location_localhost localhost; + } u; +}; +VMMDEV_ASSERT_SIZE(vmmdev_hgcm_service_location, 128 + 4); + +/** HGCM function parameter type. */ +enum vmmdev_hgcm_function_parameter_type { + VMMDEV_HGCM_PARM_TYPE_INVALID = 0, + VMMDEV_HGCM_PARM_TYPE_32BIT = 1, + VMMDEV_HGCM_PARM_TYPE_64BIT = 2, + /** Deprecated Doesn't work, use PAGELIST. */ + VMMDEV_HGCM_PARM_TYPE_PHYSADDR = 3, + /** In and Out, user-memory */ + VMMDEV_HGCM_PARM_TYPE_LINADDR = 4, + /** In, user-memory (read; host<-guest) */ + VMMDEV_HGCM_PARM_TYPE_LINADDR_IN = 5, + /** Out, user-memory (write; host->guest) */ + VMMDEV_HGCM_PARM_TYPE_LINADDR_OUT = 6, + /** In and Out, kernel-memory */ + VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL = 7, + /** In, kernel-memory (read; host<-guest) */ + VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN = 8, + /** Out, kernel-memory (write; host->guest) */ + VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_OUT = 9, + /** Physical addresses of locked pages for a buffer. */ + VMMDEV_HGCM_PARM_TYPE_PAGELIST = 10, + /* Ensure the enum is a 32 bit data-type */ + VMMDEV_HGCM_PARM_TYPE_SIZEHACK = 0x7fffffff +}; + +/** HGCM function parameter, 32-bit client. */ +struct vmmdev_hgcm_function_parameter32 { + enum vmmdev_hgcm_function_parameter_type type; + union { + __u32 value32; + __u64 value64; + struct { + __u32 size; + union { + __u32 phys_addr; + __u32 linear_addr; + } u; + } pointer; + struct { + /** Size of the buffer described by the page list. */ + __u32 size; + /** Relative to the request header. */ + __u32 offset; + } page_list; + } u; +} __packed; +VMMDEV_ASSERT_SIZE(vmmdev_hgcm_function_parameter32, 4 + 8); + +/** HGCM function parameter, 64-bit client. */ +struct vmmdev_hgcm_function_parameter64 { + enum vmmdev_hgcm_function_parameter_type type; + union { + __u32 value32; + __u64 value64; + struct { + __u32 size; + union { + __u64 phys_addr; + __u64 linear_addr; + } u; + } __packed pointer; + struct { + /** Size of the buffer described by the page list. */ + __u32 size; + /** Relative to the request header. */ + __u32 offset; + } page_list; + } __packed u; +} __packed; +VMMDEV_ASSERT_SIZE(vmmdev_hgcm_function_parameter64, 4 + 12); + +#if __BITS_PER_LONG == 64 +#define vmmdev_hgcm_function_parameter vmmdev_hgcm_function_parameter64 +#else +#define vmmdev_hgcm_function_parameter vmmdev_hgcm_function_parameter32 +#endif + +#define VMMDEV_HGCM_F_PARM_DIRECTION_NONE 0x00000000U +#define VMMDEV_HGCM_F_PARM_DIRECTION_TO_HOST 0x00000001U +#define VMMDEV_HGCM_F_PARM_DIRECTION_FROM_HOST 0x00000002U +#define VMMDEV_HGCM_F_PARM_DIRECTION_BOTH 0x00000003U + +/** + * struct vmmdev_hgcm_pagelist - VMMDEV_HGCM_PARM_TYPE_PAGELIST parameters + * point to this structure to actually describe the buffer. + */ +struct vmmdev_hgcm_pagelist { + __u32 flags; /** VMMDEV_HGCM_F_PARM_*. */ + __u16 offset_first_page; /** Data offset in the first page. */ + __u16 page_count; /** Number of pages. */ + __u64 pages[1]; /** Page addresses. */ +}; +VMMDEV_ASSERT_SIZE(vmmdev_hgcm_pagelist, 4 + 2 + 2 + 8); + +#endif diff --git a/include/uapi/linux/vboxguest.h b/include/uapi/linux/vboxguest.h new file mode 100644 index 000000000000..612f0c7d3558 --- /dev/null +++ b/include/uapi/linux/vboxguest.h @@ -0,0 +1,330 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR CDDL-1.0) */ +/* + * VBoxGuest - VirtualBox Guest Additions Driver Interface. + * + * Copyright (C) 2006-2016 Oracle Corporation + */ + +#ifndef __UAPI_VBOXGUEST_H__ +#define __UAPI_VBOXGUEST_H__ + +#include +#include +#include +#include + +/* Version of vbg_ioctl_hdr structure. */ +#define VBG_IOCTL_HDR_VERSION 0x10001 +/* Default request type. Use this for non-VMMDev requests. */ +#define VBG_IOCTL_HDR_TYPE_DEFAULT 0 + +/** + * Common ioctl header. + * + * This is a mirror of vmmdev_request_header to prevent duplicating data and + * needing to verify things multiple times. + */ +struct vbg_ioctl_hdr { + /** IN: The request input size, and output size if size_out is zero. */ + __u32 size_in; + /** IN: Structure version (VBG_IOCTL_HDR_VERSION) */ + __u32 version; + /** IN: The VMMDev request type or VBG_IOCTL_HDR_TYPE_DEFAULT. */ + __u32 type; + /** + * OUT: The VBox status code of the operation, out direction only. + * This is a VINF_ or VERR_ value as defined in vbox_err.h. + */ + __s32 rc; + /** IN: Output size. Set to zero to use size_in as output size. */ + __u32 size_out; + /** Reserved, MBZ. */ + __u32 reserved; +}; +VMMDEV_ASSERT_SIZE(vbg_ioctl_hdr, 24); + + +/* + * The VBoxGuest I/O control version. + * + * As usual, the high word contains the major version and changes to it + * signifies incompatible changes. + * + * The lower word is the minor version number, it is increased when new + * functions are added or existing changed in a backwards compatible manner. + */ +#define VBG_IOC_VERSION 0x00010000u + +/** + * VBG_IOCTL_DRIVER_VERSION_INFO data structure + * + * Note VBG_IOCTL_DRIVER_VERSION_INFO may switch the session to a backwards + * compatible interface version if uClientVersion indicates older client code. + */ +struct vbg_ioctl_driver_version_info { + /** The header. */ + struct vbg_ioctl_hdr hdr; + union { + struct { + /** Requested interface version (VBG_IOC_VERSION). */ + __u32 req_version; + /** + * Minimum interface version number (typically the + * major version part of VBG_IOC_VERSION). + */ + __u32 min_version; + /** Reserved, MBZ. */ + __u32 reserved1; + /** Reserved, MBZ. */ + __u32 reserved2; + } in; + struct { + /** Version for this session (typ. VBG_IOC_VERSION). */ + __u32 session_version; + /** Version of the IDC interface (VBG_IOC_VERSION). */ + __u32 driver_version; + /** The SVN revision of the driver, or 0. */ + __u32 driver_revision; + /** Reserved \#1 (zero until defined). */ + __u32 reserved1; + /** Reserved \#2 (zero until defined). */ + __u32 reserved2; + } out; + } u; +}; +VMMDEV_ASSERT_SIZE(vbg_ioctl_driver_version_info, 24 + 20); + +#define VBG_IOCTL_DRIVER_VERSION_INFO \ + _IOWR('V', 0, struct vbg_ioctl_driver_version_info) + + +/* IOCTL to perform a VMM Device request less than 1KB in size. */ +#define VBG_IOCTL_VMMDEV_REQUEST(s) _IOC(_IOC_READ | _IOC_WRITE, 'V', 2, s) + + +/* IOCTL to perform a VMM Device request larger then 1KB. */ +#define VBG_IOCTL_VMMDEV_REQUEST_BIG _IOC(_IOC_READ | _IOC_WRITE, 'V', 3, 0) + + +/** VBG_IOCTL_HGCM_CONNECT data structure. */ +struct vbg_ioctl_hgcm_connect { + struct vbg_ioctl_hdr hdr; + union { + struct { + struct vmmdev_hgcm_service_location loc; + } in; + struct { + __u32 client_id; + } out; + } u; +}; +VMMDEV_ASSERT_SIZE(vbg_ioctl_hgcm_connect, 24 + 132); + +#define VBG_IOCTL_HGCM_CONNECT \ + _IOWR('V', 4, struct vbg_ioctl_hgcm_connect) + + +/** VBG_IOCTL_HGCM_DISCONNECT data structure. */ +struct vbg_ioctl_hgcm_disconnect { + struct vbg_ioctl_hdr hdr; + union { + struct { + __u32 client_id; + } in; + } u; +}; +VMMDEV_ASSERT_SIZE(vbg_ioctl_hgcm_disconnect, 24 + 4); + +#define VBG_IOCTL_HGCM_DISCONNECT \ + _IOWR('V', 5, struct vbg_ioctl_hgcm_disconnect) + + +/** VBG_IOCTL_HGCM_CALL data structure. */ +struct vbg_ioctl_hgcm_call { + /** The header. */ + struct vbg_ioctl_hdr hdr; + /** Input: The id of the caller. */ + __u32 client_id; + /** Input: Function number. */ + __u32 function; + /** + * Input: How long to wait (milliseconds) for completion before + * cancelling the call. Set to -1 to wait indefinitely. + */ + __u32 timeout_ms; + /** Interruptable flag, ignored for userspace calls. */ + __u8 interruptible; + /** Explicit padding, MBZ. */ + __u8 reserved; + /** + * Input: How many parameters following this structure. + * + * The parameters are either HGCMFunctionParameter64 or 32, + * depending on whether we're receiving a 64-bit or 32-bit request. + * + * The current maximum is 61 parameters (given a 1KB max request size, + * and a 64-bit parameter size of 16 bytes). + */ + __u16 parm_count; + /* + * Parameters follow in form: + * struct hgcm_function_parameter<32|64> parms[parm_count] + */ +}; +VMMDEV_ASSERT_SIZE(vbg_ioctl_hgcm_call, 24 + 16); + +#define VBG_IOCTL_HGCM_CALL_32(s) _IOC(_IOC_READ | _IOC_WRITE, 'V', 6, s) +#define VBG_IOCTL_HGCM_CALL_64(s) _IOC(_IOC_READ | _IOC_WRITE, 'V', 7, s) +#if __BITS_PER_LONG == 64 +#define VBG_IOCTL_HGCM_CALL(s) VBG_IOCTL_HGCM_CALL_64(s) +#else +#define VBG_IOCTL_HGCM_CALL(s) VBG_IOCTL_HGCM_CALL_32(s) +#endif + + +/** VBG_IOCTL_LOG data structure. */ +struct vbg_ioctl_log { + /** The header. */ + struct vbg_ioctl_hdr hdr; + union { + struct { + /** + * The log message, this may be zero terminated. If it + * is not zero terminated then the length is determined + * from the input size. + */ + char msg[1]; + } in; + } u; +}; + +#define VBG_IOCTL_LOG(s) _IOC(_IOC_READ | _IOC_WRITE, 'V', 9, s) + + +/** VBG_IOCTL_WAIT_FOR_EVENTS data structure. */ +struct vbg_ioctl_wait_for_events { + /** The header. */ + struct vbg_ioctl_hdr hdr; + union { + struct { + /** Timeout in milliseconds. */ + __u32 timeout_ms; + /** Events to wait for. */ + __u32 events; + } in; + struct { + /** Events that occurred. */ + __u32 events; + } out; + } u; +}; +VMMDEV_ASSERT_SIZE(vbg_ioctl_wait_for_events, 24 + 8); + +#define VBG_IOCTL_WAIT_FOR_EVENTS \ + _IOWR('V', 10, struct vbg_ioctl_wait_for_events) + + +/* + * IOCTL to VBoxGuest to interrupt (cancel) any pending + * VBG_IOCTL_WAIT_FOR_EVENTS and return. + * + * Handled inside the vboxguest driver and not seen by the host at all. + * After calling this, VBG_IOCTL_WAIT_FOR_EVENTS should no longer be called in + * the same session. Any VBOXGUEST_IOCTL_WAITEVENT calls in the same session + * done after calling this will directly exit with -EINTR. + */ +#define VBG_IOCTL_INTERRUPT_ALL_WAIT_FOR_EVENTS \ + _IOWR('V', 11, struct vbg_ioctl_hdr) + + +/** VBG_IOCTL_CHANGE_FILTER_MASK data structure. */ +struct vbg_ioctl_change_filter { + /** The header. */ + struct vbg_ioctl_hdr hdr; + union { + struct { + /** Flags to set. */ + __u32 or_mask; + /** Flags to remove. */ + __u32 not_mask; + } in; + } u; +}; +VMMDEV_ASSERT_SIZE(vbg_ioctl_change_filter, 24 + 8); + +/* IOCTL to VBoxGuest to control the event filter mask. */ +#define VBG_IOCTL_CHANGE_FILTER_MASK \ + _IOWR('V', 12, struct vbg_ioctl_change_filter) + + +/** VBG_IOCTL_CHANGE_GUEST_CAPABILITIES data structure. */ +struct vbg_ioctl_set_guest_caps { + /** The header. */ + struct vbg_ioctl_hdr hdr; + union { + struct { + /** Capabilities to set (VMMDEV_GUEST_SUPPORTS_XXX). */ + __u32 or_mask; + /** Capabilities to drop (VMMDEV_GUEST_SUPPORTS_XXX). */ + __u32 not_mask; + } in; + struct { + /** Capabilities held by the session after the call. */ + __u32 session_caps; + /** Capabilities for all the sessions after the call. */ + __u32 global_caps; + } out; + } u; +}; +VMMDEV_ASSERT_SIZE(vbg_ioctl_set_guest_caps, 24 + 8); + +#define VBG_IOCTL_CHANGE_GUEST_CAPABILITIES \ + _IOWR('V', 14, struct vbg_ioctl_set_guest_caps) + + +/** VBG_IOCTL_CHECK_BALLOON data structure. */ +struct vbg_ioctl_check_balloon { + /** The header. */ + struct vbg_ioctl_hdr hdr; + union { + struct { + /** The size of the balloon in chunks of 1MB. */ + __u32 balloon_chunks; + /** + * false = handled in R0, no further action required. + * true = allocate balloon memory in R3. + */ + __u8 handle_in_r3; + /** Explicit padding, MBZ. */ + __u8 padding[3]; + } out; + } u; +}; +VMMDEV_ASSERT_SIZE(vbg_ioctl_check_balloon, 24 + 8); + +/* + * IOCTL to check memory ballooning. + * + * The guest kernel module will ask the host for the current size of the + * balloon and adjust the size. Or it will set handle_in_r3 = true and R3 is + * responsible for allocating memory and calling VBG_IOCTL_CHANGE_BALLOON. + */ +#define VBG_IOCTL_CHECK_BALLOON \ + _IOWR('V', 17, struct vbg_ioctl_check_balloon) + + +/** VBG_IOCTL_WRITE_CORE_DUMP data structure. */ +struct vbg_ioctl_write_coredump { + struct vbg_ioctl_hdr hdr; + union { + struct { + __u32 flags; /** Flags (reserved, MBZ). */ + } in; + } u; +}; +VMMDEV_ASSERT_SIZE(vbg_ioctl_write_coredump, 24 + 4); + +#define VBG_IOCTL_WRITE_CORE_DUMP \ + _IOWR('V', 19, struct vbg_ioctl_write_coredump) + +#endif -- cgit v1.2.3-59-g8ed1b From 06ef0ccb5a36e1feba9b413ff59a04ecc4407c1c Mon Sep 17 00:00:00 2001 From: Yonghong Song Date: Mon, 18 Dec 2017 10:13:44 -0800 Subject: bpf/cgroup: fix a verification error for a CGROUP_DEVICE type prog The tools/testing/selftests/bpf test program test_dev_cgroup fails with the following error when compiled with llvm 6.0. (I did not try with earlier versions.) libbpf: load bpf program failed: Permission denied libbpf: -- BEGIN DUMP LOG --- libbpf: 0: (61) r2 = *(u32 *)(r1 +4) 1: (b7) r0 = 0 2: (55) if r2 != 0x1 goto pc+8 R0=inv0 R1=ctx(id=0,off=0,imm=0) R2=inv1 R10=fp0 3: (69) r2 = *(u16 *)(r1 +0) invalid bpf_context access off=0 size=2 ... The culprit is the following statement in dev_cgroup.c: short type = ctx->access_type & 0xFFFF; This code is typical as the ctx->access_type is assigned as below in kernel/bpf/cgroup.c: struct bpf_cgroup_dev_ctx ctx = { .access_type = (access << 16) | dev_type, .major = major, .minor = minor, }; The compiler converts it to u16 access while the verifier cgroup_dev_is_valid_access rejects any non u32 access. This patch permits the field access_type to be accessible with type u16 and u8 as well. Signed-off-by: Yonghong Song Tested-by: Roman Gushchin Signed-off-by: Daniel Borkmann --- include/uapi/linux/bpf.h | 3 ++- kernel/bpf/cgroup.c | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index d01f1cb3cfc0..69eabfcb9bdb 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -1012,7 +1012,8 @@ struct bpf_perf_event_value { #define BPF_DEVCG_DEV_CHAR (1ULL << 1) struct bpf_cgroup_dev_ctx { - __u32 access_type; /* (access << 16) | type */ + /* access_type encoded as (BPF_DEVCG_ACC_* << 16) | BPF_DEVCG_DEV_* */ + __u32 access_type; __u32 major; __u32 minor; }; diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index b789ab78d28f..c1c0b60d3f2f 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -568,6 +568,8 @@ static bool cgroup_dev_is_valid_access(int off, int size, enum bpf_access_type type, struct bpf_insn_access_aux *info) { + const int size_default = sizeof(__u32); + if (type == BPF_WRITE) return false; @@ -576,8 +578,17 @@ static bool cgroup_dev_is_valid_access(int off, int size, /* The verifier guarantees that size > 0. */ if (off % size != 0) return false; - if (size != sizeof(__u32)) - return false; + + switch (off) { + case bpf_ctx_range(struct bpf_cgroup_dev_ctx, access_type): + bpf_ctx_record_field_size(info, size_default); + if (!bpf_ctx_narrow_access_ok(off, size, size_default)) + return false; + break; + default: + if (size != size_default) + return false; + } return true; } -- cgit v1.2.3-59-g8ed1b From f0edce7a7f4c236f2d05040746b388cfac8796a1 Mon Sep 17 00:00:00 2001 From: Logan Gunthorpe Date: Wed, 29 Nov 2017 10:28:43 -0700 Subject: switchtec: Add Global Fabric Manager Server (GFMS) event Add a new event type that is newly exposed by recent firmware. The event will never occur if the firmware is too old. If user space tries to use this event in an older kernel, it will just get an EINVAL which is perfectly acceptable in the existing user space code. Signed-off-by: Logan Gunthorpe Signed-off-by: Bjorn Helgaas --- drivers/pci/switch/switchtec.c | 1 + include/linux/switchtec.h | 3 +++ include/uapi/linux/switchtec_ioctl.h | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c index 730cc897b94d..7668d270725d 100644 --- a/drivers/pci/switch/switchtec.c +++ b/drivers/pci/switch/switchtec.c @@ -707,6 +707,7 @@ static const struct event_reg { EV_GLB(SWITCHTEC_IOCTL_EVENT_CLI_MRPC_COMP_ASYNC, cli_mrpc_comp_async_hdr), EV_GLB(SWITCHTEC_IOCTL_EVENT_GPIO_INT, gpio_interrupt_hdr), + EV_GLB(SWITCHTEC_IOCTL_EVENT_GFMS, gfms_event_hdr), EV_PAR(SWITCHTEC_IOCTL_EVENT_PART_RESET, part_reset_hdr), EV_PAR(SWITCHTEC_IOCTL_EVENT_MRPC_COMP, mrpc_comp_hdr), EV_PAR(SWITCHTEC_IOCTL_EVENT_MRPC_COMP_ASYNC, mrpc_comp_async_hdr), diff --git a/include/linux/switchtec.h b/include/linux/switchtec.h index 09d73d0d1aa8..42d121174fe2 100644 --- a/include/linux/switchtec.h +++ b/include/linux/switchtec.h @@ -100,6 +100,9 @@ struct sw_event_regs { u32 gpio_interrupt_hdr; u32 gpio_interrupt_data; u32 reserved16[4]; + u32 gfms_event_hdr; + u32 gfms_event_data; + u32 reserved17[4]; } __packed; enum { diff --git a/include/uapi/linux/switchtec_ioctl.h b/include/uapi/linux/switchtec_ioctl.h index 75df44373034..4f4daf8db954 100644 --- a/include/uapi/linux/switchtec_ioctl.h +++ b/include/uapi/linux/switchtec_ioctl.h @@ -88,7 +88,8 @@ struct switchtec_ioctl_event_summary { #define SWITCHTEC_IOCTL_EVENT_FORCE_SPEED 26 #define SWITCHTEC_IOCTL_EVENT_CREDIT_TIMEOUT 27 #define SWITCHTEC_IOCTL_EVENT_LINK_STATE 28 -#define SWITCHTEC_IOCTL_MAX_EVENTS 29 +#define SWITCHTEC_IOCTL_EVENT_GFMS 29 +#define SWITCHTEC_IOCTL_MAX_EVENTS 30 #define SWITCHTEC_IOCTL_EVENT_LOCAL_PART_IDX -1 #define SWITCHTEC_IOCTL_EVENT_IDX_ALL -2 -- cgit v1.2.3-59-g8ed1b From 983dafaab799511e092ffd006f3a064b37ccbccf Mon Sep 17 00:00:00 2001 From: Sunil Dutt Date: Wed, 13 Dec 2017 19:51:36 +0200 Subject: cfg80211: Scan results to also report the per chain signal strength This commit enhances the scan results to report the per chain signal strength based on the latest BSS update. This provides similar information to what is already available through STA information. Signed-off-by: Sunil Dutt Signed-off-by: Jouni Malinen Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 8 ++++++++ include/uapi/linux/nl80211.h | 4 ++++ net/wireless/nl80211.c | 5 +++++ net/wireless/scan.c | 5 +++++ 4 files changed, 22 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index d7f8e7b96bcb..3a4a1a903a4d 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1773,6 +1773,8 @@ enum cfg80211_signal_type { * by %parent_bssid. * @parent_bssid: the BSS according to which %parent_tsf is set. This is set to * the BSS that requested the scan in which the beacon/probe was received. + * @chains: bitmask for filled values in @chain_signal. + * @chain_signal: per-chain signal strength of last received BSS in dBm. */ struct cfg80211_inform_bss { struct ieee80211_channel *chan; @@ -1781,6 +1783,8 @@ struct cfg80211_inform_bss { u64 boottime_ns; u64 parent_tsf; u8 parent_bssid[ETH_ALEN] __aligned(2); + u8 chains; + s8 chain_signal[IEEE80211_MAX_CHAINS]; }; /** @@ -1824,6 +1828,8 @@ struct cfg80211_bss_ies { * that holds the beacon data. @beacon_ies is still valid, of course, and * points to the same data as hidden_beacon_bss->beacon_ies in that case. * @signal: signal strength value (type depends on the wiphy's signal_type) + * @chains: bitmask for filled values in @chain_signal. + * @chain_signal: per-chain signal strength of last received BSS in dBm. * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes */ struct cfg80211_bss { @@ -1842,6 +1848,8 @@ struct cfg80211_bss { u16 capability; u8 bssid[ETH_ALEN]; + u8 chains; + s8 chain_signal[IEEE80211_MAX_CHAINS]; u8 priv[0] __aligned(sizeof(void *)); }; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index f882fe1f9709..c587a61c32bf 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -3862,6 +3862,9 @@ enum nl80211_bss_scan_width { * @NL80211_BSS_PARENT_BSSID. (u64). * @NL80211_BSS_PARENT_BSSID: the BSS according to which @NL80211_BSS_PARENT_TSF * is set. + * @NL80211_BSS_CHAIN_SIGNAL: per-chain signal strength of last BSS update. + * Contains a nested array of signal strength attributes (u8, dBm), + * using the nesting index as the antenna number. * @__NL80211_BSS_AFTER_LAST: internal * @NL80211_BSS_MAX: highest BSS attribute */ @@ -3885,6 +3888,7 @@ enum nl80211_bss { NL80211_BSS_PAD, NL80211_BSS_PARENT_TSF, NL80211_BSS_PARENT_BSSID, + NL80211_BSS_CHAIN_SIGNAL, /* keep last */ __NL80211_BSS_AFTER_LAST, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index e4dddfb64ced..b3f8970c3a47 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -7839,6 +7839,11 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, intbss->ts_boottime, NL80211_BSS_PAD)) goto nla_put_failure; + if (!nl80211_put_signal(msg, intbss->pub.chains, + intbss->pub.chain_signal, + NL80211_BSS_CHAIN_SIGNAL)) + goto nla_put_failure; + switch (rdev->wiphy.signal_type) { case CFG80211_SIGNAL_TYPE_MBM: if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal)) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index f6c5fe482506..d36c3eb7b931 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -981,6 +981,9 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev, found->ts = tmp->ts; found->ts_boottime = tmp->ts_boottime; found->parent_tsf = tmp->parent_tsf; + found->pub.chains = tmp->pub.chains; + memcpy(found->pub.chain_signal, tmp->pub.chain_signal, + IEEE80211_MAX_CHAINS); ether_addr_copy(found->parent_bssid, tmp->parent_bssid); } else { struct cfg80211_internal_bss *new; @@ -1233,6 +1236,8 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); tmp.ts_boottime = data->boottime_ns; tmp.parent_tsf = data->parent_tsf; + tmp.pub.chains = data->chains; + memcpy(tmp.pub.chain_signal, data->chain_signal, IEEE80211_MAX_CHAINS); ether_addr_copy(tmp.parent_bssid, data->parent_bssid); signal_valid = abs(data->chan->center_freq - channel->center_freq) <= -- cgit v1.2.3-59-g8ed1b From f9d79126195374c285035777b9d6abd24ceba363 Mon Sep 17 00:00:00 2001 From: Athanasios Oikonomou Date: Sat, 16 Dec 2017 07:23:38 -0500 Subject: media: dvb_frontend: add physical layer scrambling support This commit adds a new property DTV_SCRAMBLING_SEQUENCE_INDEX. This 18 bit field, when present, carries the index of the DVB-S2 physical layer scrambling sequence as defined in clause 5.5.4 of EN 302 307. There is no explicit signalling method to convey scrambling sequence index to the receiver. If S2 satellite delivery system descriptor is available it can be used to read the scrambling sequence index (EN 300 468 table 41). By default, gold scrambling sequence index 0 is used. The valid scrambling sequence index range is from 0 to 262142. Increase the DVB API version in order userspace to be aware of the changes. Signed-off-by: Athanasios Oikonomou Acked-by: Ralph Metzler Signed-off-by: Mauro Carvalho Chehab --- .../media/uapi/dvb/fe_property_parameters.rst | 18 ++++++++++++++++++ .../uapi/dvb/frontend-property-satellite-systems.rst | 2 ++ drivers/media/dvb-core/dvb_frontend.c | 12 ++++++++++++ drivers/media/dvb-core/dvb_frontend.h | 5 +++++ include/uapi/linux/dvb/frontend.h | 5 ++++- include/uapi/linux/dvb/version.h | 2 +- 6 files changed, 42 insertions(+), 2 deletions(-) (limited to 'include/uapi/linux') diff --git a/Documentation/media/uapi/dvb/fe_property_parameters.rst b/Documentation/media/uapi/dvb/fe_property_parameters.rst index 6eef507fea50..3524dcae4604 100644 --- a/Documentation/media/uapi/dvb/fe_property_parameters.rst +++ b/Documentation/media/uapi/dvb/fe_property_parameters.rst @@ -987,3 +987,21 @@ Possible values: 0, 1, LNA_AUTO 1, LNA on use the special macro LNA_AUTO to set LNA auto + + +.. _DTV-SCRAMBLING-SEQUENCE-INDEX: + +DTV_SCRAMBLING_SEQUENCE_INDEX +============================= + +Used on DVB-S2. + +This 18 bit field, when present, carries the index of the DVB-S2 physical +layer scrambling sequence as defined in clause 5.5.4 of EN 302 307. +There is no explicit signalling method to convey scrambling sequence index +to the receiver. If S2 satellite delivery system descriptor is available +it can be used to read the scrambling sequence index (EN 300 468 table 41). + +By default, gold scrambling sequence index 0 is used. + +The valid scrambling sequence index range is from 0 to 262142. diff --git a/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst b/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst index 1f40399c68ff..2929e6999a7a 100644 --- a/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst +++ b/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst @@ -60,6 +60,8 @@ following parameters: - :ref:`DTV_STREAM_ID ` +- :ref:`DTV_SCRAMBLING_SEQUENCE_INDEX ` + In addition, the :ref:`DTV QoS statistics ` are also valid. diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index ee3ea4dcd9c1..5547b9830bbc 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -982,6 +982,7 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe) } c->stream_id = NO_STREAM_ID_FILTER; + c->scrambling_sequence_index = 0;/* default sequence */ switch (c->delivery_system) { case SYS_DVBS: @@ -1072,6 +1073,7 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { _DTV_CMD(DTV_STREAM_ID, 1, 0), _DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY, 1, 0), + _DTV_CMD(DTV_SCRAMBLING_SEQUENCE_INDEX, 1, 0), _DTV_CMD(DTV_LNA, 1, 0), /* Get */ @@ -1417,6 +1419,11 @@ static int dtv_property_process_get(struct dvb_frontend *fe, tvp->u.data = c->stream_id; break; + /* Physical layer scrambling support */ + case DTV_SCRAMBLING_SEQUENCE_INDEX: + tvp->u.data = c->scrambling_sequence_index; + break; + /* ATSC-MH */ case DTV_ATSCMH_FIC_VER: tvp->u.data = fe->dtv_property_cache.atscmh_fic_ver; @@ -1900,6 +1907,11 @@ static int dtv_property_process_set(struct dvb_frontend *fe, c->stream_id = data; break; + /* Physical layer scrambling support */ + case DTV_SCRAMBLING_SEQUENCE_INDEX: + c->scrambling_sequence_index = data; + break; + /* ATSC-MH */ case DTV_ATSCMH_PARADE_ID: fe->dtv_property_cache.atscmh_parade_id = data; diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index ace0c2fb26c2..2bc25f1e425b 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h @@ -513,6 +513,8 @@ struct dvb_fe_events { * @layer.interleaving: per layer interleaving. * @stream_id: If different than zero, enable substream filtering, if * hardware supports (DVB-S2 and DVB-T2). + * @scrambling_sequence_index: Carries the index of the DVB-S2 physical layer + * scrambling sequence. * @atscmh_fic_ver: Version number of the FIC (Fast Information Channel) * signaling data (only ATSC-M/H) * @atscmh_parade_id: Parade identification number (only ATSC-M/H) @@ -591,6 +593,9 @@ struct dtv_frontend_properties { /* Multistream specifics */ u32 stream_id; + /* Physical Layer Scrambling specifics */ + u32 scrambling_sequence_index; + /* ATSC-MH specifics */ u8 atscmh_fic_ver; u8 atscmh_parade_id; diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h index 9dad6c66cc34..4f9b4551c534 100644 --- a/include/uapi/linux/dvb/frontend.h +++ b/include/uapi/linux/dvb/frontend.h @@ -547,7 +547,10 @@ enum fe_interleaving { #define DTV_STAT_ERROR_BLOCK_COUNT 68 #define DTV_STAT_TOTAL_BLOCK_COUNT 69 -#define DTV_MAX_COMMAND DTV_STAT_TOTAL_BLOCK_COUNT +/* Physical layer scrambling */ +#define DTV_SCRAMBLING_SEQUENCE_INDEX 70 + +#define DTV_MAX_COMMAND DTV_SCRAMBLING_SEQUENCE_INDEX /** * enum fe_pilot - Type of pilot tone diff --git a/include/uapi/linux/dvb/version.h b/include/uapi/linux/dvb/version.h index 02e32ea83984..2c5cffe6d2a0 100644 --- a/include/uapi/linux/dvb/version.h +++ b/include/uapi/linux/dvb/version.h @@ -25,6 +25,6 @@ #define _DVBVERSION_H_ #define DVB_API_VERSION 5 -#define DVB_API_VERSION_MINOR 10 +#define DVB_API_VERSION_MINOR 11 #endif /*_DVBVERSION_H_*/ -- cgit v1.2.3-59-g8ed1b From a32295c612c57990d17fb0f41e7134394b2f35f6 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Wed, 13 Dec 2017 13:31:31 +1100 Subject: vfio-pci: Allow mapping MSIX BAR By default VFIO disables mapping of MSIX BAR to the userspace as the userspace may program it in a way allowing spurious interrupts; instead the userspace uses the VFIO_DEVICE_SET_IRQS ioctl. In order to eliminate guessing from the userspace about what is mmapable, VFIO also advertises a sparse list of regions allowed to mmap. This works fine as long as the system page size equals to the MSIX alignment requirement which is 4KB. However with a bigger page size the existing code prohibits mapping non-MSIX parts of a page with MSIX structures so these parts have to be emulated via slow reads/writes on a VFIO device fd. If these emulated bits are accessed often, this has serious impact on performance. This allows mmap of the entire BAR containing MSIX vector table. This removes the sparse capability for PCI devices as it becomes useless. As the userspace needs to know for sure whether mmapping of the MSIX vector containing data can succeed, this adds a new capability - VFIO_REGION_INFO_CAP_MSIX_MAPPABLE - which explicitly tells the userspace that the entire BAR can be mmapped. This does not touch the MSIX mangling in the BAR read/write handlers as we are doing this just to enable direct access to non MSIX registers. Signed-off-by: Alexey Kardashevskiy [aw - fixup whitespace, trim function name] Signed-off-by: Alex Williamson --- drivers/vfio/pci/vfio_pci.c | 64 ++++++--------------------------------------- include/uapi/linux/vfio.h | 10 +++++++ 2 files changed, 18 insertions(+), 56 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c index de48acd29a84..b0f759476900 100644 --- a/drivers/vfio/pci/vfio_pci.c +++ b/drivers/vfio/pci/vfio_pci.c @@ -565,47 +565,15 @@ static int vfio_pci_for_each_slot_or_bus(struct pci_dev *pdev, return walk.ret; } -static int msix_sparse_mmap_cap(struct vfio_pci_device *vdev, - struct vfio_info_cap *caps) +static int msix_mmappable_cap(struct vfio_pci_device *vdev, + struct vfio_info_cap *caps) { - struct vfio_region_info_cap_sparse_mmap *sparse; - size_t end, size; - int nr_areas = 2, i = 0, ret; - - end = pci_resource_len(vdev->pdev, vdev->msix_bar); - - /* If MSI-X table is aligned to the start or end, only one area */ - if (((vdev->msix_offset & PAGE_MASK) == 0) || - (PAGE_ALIGN(vdev->msix_offset + vdev->msix_size) >= end)) - nr_areas = 1; - - size = sizeof(*sparse) + (nr_areas * sizeof(*sparse->areas)); - - sparse = kzalloc(size, GFP_KERNEL); - if (!sparse) - return -ENOMEM; - - sparse->header.id = VFIO_REGION_INFO_CAP_SPARSE_MMAP; - sparse->header.version = 1; - sparse->nr_areas = nr_areas; - - if (vdev->msix_offset & PAGE_MASK) { - sparse->areas[i].offset = 0; - sparse->areas[i].size = vdev->msix_offset & PAGE_MASK; - i++; - } - - if (PAGE_ALIGN(vdev->msix_offset + vdev->msix_size) < end) { - sparse->areas[i].offset = PAGE_ALIGN(vdev->msix_offset + - vdev->msix_size); - sparse->areas[i].size = end - sparse->areas[i].offset; - i++; - } - - ret = vfio_info_add_capability(caps, &sparse->header, size); - kfree(sparse); + struct vfio_info_cap_header header = { + .id = VFIO_REGION_INFO_CAP_MSIX_MAPPABLE, + .version = 1 + }; - return ret; + return vfio_info_add_capability(caps, &header, sizeof(header)); } int vfio_pci_register_dev_region(struct vfio_pci_device *vdev, @@ -696,7 +664,7 @@ static long vfio_pci_ioctl(void *device_data, if (vdev->bar_mmap_supported[info.index]) { info.flags |= VFIO_REGION_INFO_FLAG_MMAP; if (info.index == vdev->msix_bar) { - ret = msix_sparse_mmap_cap(vdev, &caps); + ret = msix_mmappable_cap(vdev, &caps); if (ret) return ret; } @@ -1127,22 +1095,6 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma) if (req_start + req_len > phys_len) return -EINVAL; - if (index == vdev->msix_bar) { - /* - * Disallow mmaps overlapping the MSI-X table; users don't - * get to touch this directly. We could find somewhere - * else to map the overlap, but page granularity is only - * a recommendation, not a requirement, so the user needs - * to know which bits are real. Requiring them to mmap - * around the table makes that clear. - */ - - /* If neither entirely above nor below, then it overlaps */ - if (!(req_start >= vdev->msix_offset + vdev->msix_size || - req_start + req_len <= vdev->msix_offset)) - return -EINVAL; - } - /* * Even though we don't make use of the barmap for the mmap, * we need to request the region and the barmap tracks that. diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index e3301dbd27d4..0d914350f7bf 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -301,6 +301,16 @@ struct vfio_region_info_cap_type { #define VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG (2) #define VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG (3) +/* + * The MSIX mappable capability informs that MSIX data of a BAR can be mmapped + * which allows direct access to non-MSIX registers which happened to be within + * the same system page. + * + * Even though the userspace gets direct access to the MSIX data, the existing + * VFIO_DEVICE_SET_IRQS interface must still be used for MSIX configuration. + */ +#define VFIO_REGION_INFO_CAP_MSIX_MAPPABLE 3 + /** * VFIO_DEVICE_GET_IRQ_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 9, * struct vfio_irq_info) -- cgit v1.2.3-59-g8ed1b From fec149f5d3234c037ec761d1db4cc8c0550e9964 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Thu, 21 Dec 2017 10:17:41 +0100 Subject: batman-adv: Convert packet.h to uapi header The header file is used by different userspace programs to inject packets or to decode sniffed packets. It should therefore be available to them as userspace header. Also other components in the kernel (like the flow dissector) require access to the packet definitions to be able to decode ETH_P_BATMAN ethernet packets. Signed-off-by: Sven Eckelmann Signed-off-by: David S. Miller --- MAINTAINERS | 1 + include/uapi/linux/batadv_packet.h | 644 +++++++++++++++++++++++++++++++++ net/batman-adv/bat_iv_ogm.c | 2 +- net/batman-adv/bat_v.c | 2 +- net/batman-adv/bat_v_elp.c | 2 +- net/batman-adv/bat_v_ogm.c | 2 +- net/batman-adv/bridge_loop_avoidance.c | 2 +- net/batman-adv/distributed-arp-table.h | 2 +- net/batman-adv/fragmentation.c | 2 +- net/batman-adv/gateway_client.c | 2 +- net/batman-adv/gateway_common.c | 2 +- net/batman-adv/hard-interface.c | 2 +- net/batman-adv/icmp_socket.c | 2 +- net/batman-adv/main.c | 2 +- net/batman-adv/main.h | 2 +- net/batman-adv/multicast.c | 2 +- net/batman-adv/netlink.c | 2 +- net/batman-adv/network-coding.c | 2 +- net/batman-adv/packet.h | 644 --------------------------------- net/batman-adv/routing.c | 2 +- net/batman-adv/send.h | 3 +- net/batman-adv/soft-interface.c | 2 +- net/batman-adv/sysfs.c | 2 +- net/batman-adv/tp_meter.c | 2 +- net/batman-adv/translation-table.c | 2 +- net/batman-adv/tvlv.c | 2 +- net/batman-adv/types.h | 3 +- 27 files changed, 669 insertions(+), 670 deletions(-) create mode 100644 include/uapi/linux/batadv_packet.h delete mode 100644 net/batman-adv/packet.h (limited to 'include/uapi/linux') diff --git a/MAINTAINERS b/MAINTAINERS index 129c591e0f34..753799d24cd9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2564,6 +2564,7 @@ S: Maintained F: Documentation/ABI/testing/sysfs-class-net-batman-adv F: Documentation/ABI/testing/sysfs-class-net-mesh F: Documentation/networking/batman-adv.rst +F: include/uapi/linux/batadv_packet.h F: include/uapi/linux/batman_adv.h F: net/batman-adv/ diff --git a/include/uapi/linux/batadv_packet.h b/include/uapi/linux/batadv_packet.h new file mode 100644 index 000000000000..5cb360be2a11 --- /dev/null +++ b/include/uapi/linux/batadv_packet.h @@ -0,0 +1,644 @@ +/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) */ +/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef _UAPI_LINUX_BATADV_PACKET_H_ +#define _UAPI_LINUX_BATADV_PACKET_H_ + +#include +#include +#include + +/** + * batadv_tp_is_error() - Check throughput meter return code for error + * @n: throughput meter return code + * + * Return: 0 when not error was detected, != 0 otherwise + */ +#define batadv_tp_is_error(n) ((__u8)(n) > 127 ? 1 : 0) + +/** + * enum batadv_packettype - types for batman-adv encapsulated packets + * @BATADV_IV_OGM: originator messages for B.A.T.M.A.N. IV + * @BATADV_BCAST: broadcast packets carrying broadcast payload + * @BATADV_CODED: network coded packets + * @BATADV_ELP: echo location packets for B.A.T.M.A.N. V + * @BATADV_OGM2: originator messages for B.A.T.M.A.N. V + * + * @BATADV_UNICAST: unicast packets carrying unicast payload traffic + * @BATADV_UNICAST_FRAG: unicast packets carrying a fragment of the original + * payload packet + * @BATADV_UNICAST_4ADDR: unicast packet including the originator address of + * the sender + * @BATADV_ICMP: unicast packet like IP ICMP used for ping or traceroute + * @BATADV_UNICAST_TVLV: unicast packet carrying TVLV containers + */ +enum batadv_packettype { + /* 0x00 - 0x3f: local packets or special rules for handling */ + BATADV_IV_OGM = 0x00, + BATADV_BCAST = 0x01, + BATADV_CODED = 0x02, + BATADV_ELP = 0x03, + BATADV_OGM2 = 0x04, + /* 0x40 - 0x7f: unicast */ +#define BATADV_UNICAST_MIN 0x40 + BATADV_UNICAST = 0x40, + BATADV_UNICAST_FRAG = 0x41, + BATADV_UNICAST_4ADDR = 0x42, + BATADV_ICMP = 0x43, + BATADV_UNICAST_TVLV = 0x44, +#define BATADV_UNICAST_MAX 0x7f + /* 0x80 - 0xff: reserved */ +}; + +/** + * enum batadv_subtype - packet subtype for unicast4addr + * @BATADV_P_DATA: user payload + * @BATADV_P_DAT_DHT_GET: DHT request message + * @BATADV_P_DAT_DHT_PUT: DHT store message + * @BATADV_P_DAT_CACHE_REPLY: ARP reply generated by DAT + */ +enum batadv_subtype { + BATADV_P_DATA = 0x01, + BATADV_P_DAT_DHT_GET = 0x02, + BATADV_P_DAT_DHT_PUT = 0x03, + BATADV_P_DAT_CACHE_REPLY = 0x04, +}; + +/* this file is included by batctl which needs these defines */ +#define BATADV_COMPAT_VERSION 15 + +/** + * enum batadv_iv_flags - flags used in B.A.T.M.A.N. IV OGM packets + * @BATADV_NOT_BEST_NEXT_HOP: flag is set when ogm packet is forwarded and was + * previously received from someone else than the best neighbor. + * @BATADV_PRIMARIES_FIRST_HOP: flag unused. + * @BATADV_DIRECTLINK: flag is for the first hop or if rebroadcasted from a + * one hop neighbor on the interface where it was originally received. + */ +enum batadv_iv_flags { + BATADV_NOT_BEST_NEXT_HOP = 1UL << 0, + BATADV_PRIMARIES_FIRST_HOP = 1UL << 1, + BATADV_DIRECTLINK = 1UL << 2, +}; + +/** + * enum batadv_icmp_packettype - ICMP message types + * @BATADV_ECHO_REPLY: success reply to BATADV_ECHO_REQUEST + * @BATADV_DESTINATION_UNREACHABLE: failure when route to destination not found + * @BATADV_ECHO_REQUEST: request BATADV_ECHO_REPLY from destination + * @BATADV_TTL_EXCEEDED: error after BATADV_ECHO_REQUEST traversed too many hops + * @BATADV_PARAMETER_PROBLEM: return code for malformed messages + * @BATADV_TP: throughput meter packet + */ +enum batadv_icmp_packettype { + BATADV_ECHO_REPLY = 0, + BATADV_DESTINATION_UNREACHABLE = 3, + BATADV_ECHO_REQUEST = 8, + BATADV_TTL_EXCEEDED = 11, + BATADV_PARAMETER_PROBLEM = 12, + BATADV_TP = 15, +}; + +/** + * enum batadv_mcast_flags - flags for multicast capabilities and settings + * @BATADV_MCAST_WANT_ALL_UNSNOOPABLES: we want all packets destined for + * 224.0.0.0/24 or ff02::1 + * @BATADV_MCAST_WANT_ALL_IPV4: we want all IPv4 multicast packets + * @BATADV_MCAST_WANT_ALL_IPV6: we want all IPv6 multicast packets + */ +enum batadv_mcast_flags { + BATADV_MCAST_WANT_ALL_UNSNOOPABLES = 1UL << 0, + BATADV_MCAST_WANT_ALL_IPV4 = 1UL << 1, + BATADV_MCAST_WANT_ALL_IPV6 = 1UL << 2, +}; + +/* tt data subtypes */ +#define BATADV_TT_DATA_TYPE_MASK 0x0F + +/** + * enum batadv_tt_data_flags - flags for tt data tvlv + * @BATADV_TT_OGM_DIFF: TT diff propagated through OGM + * @BATADV_TT_REQUEST: TT request message + * @BATADV_TT_RESPONSE: TT response message + * @BATADV_TT_FULL_TABLE: contains full table to replace existing table + */ +enum batadv_tt_data_flags { + BATADV_TT_OGM_DIFF = 1UL << 0, + BATADV_TT_REQUEST = 1UL << 1, + BATADV_TT_RESPONSE = 1UL << 2, + BATADV_TT_FULL_TABLE = 1UL << 4, +}; + +/** + * enum batadv_vlan_flags - flags for the four MSB of any vlan ID field + * @BATADV_VLAN_HAS_TAG: whether the field contains a valid vlan tag or not + */ +enum batadv_vlan_flags { + BATADV_VLAN_HAS_TAG = 1UL << 15, +}; + +/** + * enum batadv_bla_claimframe - claim frame types for the bridge loop avoidance + * @BATADV_CLAIM_TYPE_CLAIM: claim of a client mac address + * @BATADV_CLAIM_TYPE_UNCLAIM: unclaim of a client mac address + * @BATADV_CLAIM_TYPE_ANNOUNCE: announcement of backbone with current crc + * @BATADV_CLAIM_TYPE_REQUEST: request of full claim table + * @BATADV_CLAIM_TYPE_LOOPDETECT: mesh-traversing loop detect packet + */ +enum batadv_bla_claimframe { + BATADV_CLAIM_TYPE_CLAIM = 0x00, + BATADV_CLAIM_TYPE_UNCLAIM = 0x01, + BATADV_CLAIM_TYPE_ANNOUNCE = 0x02, + BATADV_CLAIM_TYPE_REQUEST = 0x03, + BATADV_CLAIM_TYPE_LOOPDETECT = 0x04, +}; + +/** + * enum batadv_tvlv_type - tvlv type definitions + * @BATADV_TVLV_GW: gateway tvlv + * @BATADV_TVLV_DAT: distributed arp table tvlv + * @BATADV_TVLV_NC: network coding tvlv + * @BATADV_TVLV_TT: translation table tvlv + * @BATADV_TVLV_ROAM: roaming advertisement tvlv + * @BATADV_TVLV_MCAST: multicast capability tvlv + */ +enum batadv_tvlv_type { + BATADV_TVLV_GW = 0x01, + BATADV_TVLV_DAT = 0x02, + BATADV_TVLV_NC = 0x03, + BATADV_TVLV_TT = 0x04, + BATADV_TVLV_ROAM = 0x05, + BATADV_TVLV_MCAST = 0x06, +}; + +#pragma pack(2) +/* the destination hardware field in the ARP frame is used to + * transport the claim type and the group id + */ +struct batadv_bla_claim_dst { + __u8 magic[3]; /* FF:43:05 */ + __u8 type; /* bla_claimframe */ + __be16 group; /* group id */ +}; + +#pragma pack() + +/** + * struct batadv_ogm_packet - ogm (routing protocol) packet + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @flags: contains routing relevant flags - see enum batadv_iv_flags + * @seqno: sequence identification + * @orig: address of the source node + * @prev_sender: address of the previous sender + * @reserved: reserved byte for alignment + * @tq: transmission quality + * @tvlv_len: length of tvlv data following the ogm header + */ +struct batadv_ogm_packet { + __u8 packet_type; + __u8 version; + __u8 ttl; + __u8 flags; + __be32 seqno; + __u8 orig[ETH_ALEN]; + __u8 prev_sender[ETH_ALEN]; + __u8 reserved; + __u8 tq; + __be16 tvlv_len; + /* __packed is not needed as the struct size is divisible by 4, + * and the largest data type in this struct has a size of 4. + */ +}; + +#define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet) + +/** + * struct batadv_ogm2_packet - ogm2 (routing protocol) packet + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the general header + * @ttl: time to live for this packet, part of the general header + * @flags: reseved for routing relevant flags - currently always 0 + * @seqno: sequence number + * @orig: originator mac address + * @tvlv_len: length of the appended tvlv buffer (in bytes) + * @throughput: the currently flooded path throughput + */ +struct batadv_ogm2_packet { + __u8 packet_type; + __u8 version; + __u8 ttl; + __u8 flags; + __be32 seqno; + __u8 orig[ETH_ALEN]; + __be16 tvlv_len; + __be32 throughput; + /* __packed is not needed as the struct size is divisible by 4, + * and the largest data type in this struct has a size of 4. + */ +}; + +#define BATADV_OGM2_HLEN sizeof(struct batadv_ogm2_packet) + +/** + * struct batadv_elp_packet - elp (neighbor discovery) packet + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @orig: originator mac address + * @seqno: sequence number + * @elp_interval: currently used ELP sending interval in ms + */ +struct batadv_elp_packet { + __u8 packet_type; + __u8 version; + __u8 orig[ETH_ALEN]; + __be32 seqno; + __be32 elp_interval; +}; + +#define BATADV_ELP_HLEN sizeof(struct batadv_elp_packet) + +/** + * struct batadv_icmp_header - common members among all the ICMP packets + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @msg_type: ICMP packet type + * @dst: address of the destination node + * @orig: address of the source node + * @uid: local ICMP socket identifier + * @align: not used - useful for alignment purposes only + * + * This structure is used for ICMP packets parsing only and it is never sent + * over the wire. The alignment field at the end is there to ensure that + * members are padded the same way as they are in real packets. + */ +struct batadv_icmp_header { + __u8 packet_type; + __u8 version; + __u8 ttl; + __u8 msg_type; /* see ICMP message types above */ + __u8 dst[ETH_ALEN]; + __u8 orig[ETH_ALEN]; + __u8 uid; + __u8 align[3]; +}; + +/** + * struct batadv_icmp_packet - ICMP packet + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @msg_type: ICMP packet type + * @dst: address of the destination node + * @orig: address of the source node + * @uid: local ICMP socket identifier + * @reserved: not used - useful for alignment + * @seqno: ICMP sequence number + */ +struct batadv_icmp_packet { + __u8 packet_type; + __u8 version; + __u8 ttl; + __u8 msg_type; /* see ICMP message types above */ + __u8 dst[ETH_ALEN]; + __u8 orig[ETH_ALEN]; + __u8 uid; + __u8 reserved; + __be16 seqno; +}; + +/** + * struct batadv_icmp_tp_packet - ICMP TP Meter packet + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @msg_type: ICMP packet type + * @dst: address of the destination node + * @orig: address of the source node + * @uid: local ICMP socket identifier + * @subtype: TP packet subtype (see batadv_icmp_tp_subtype) + * @session: TP session identifier + * @seqno: the TP sequence number + * @timestamp: time when the packet has been sent. This value is filled in a + * TP_MSG and echoed back in the next TP_ACK so that the sender can compute the + * RTT. Since it is read only by the host which wrote it, there is no need to + * store it using network order + */ +struct batadv_icmp_tp_packet { + __u8 packet_type; + __u8 version; + __u8 ttl; + __u8 msg_type; /* see ICMP message types above */ + __u8 dst[ETH_ALEN]; + __u8 orig[ETH_ALEN]; + __u8 uid; + __u8 subtype; + __u8 session[2]; + __be32 seqno; + __be32 timestamp; +}; + +/** + * enum batadv_icmp_tp_subtype - ICMP TP Meter packet subtypes + * @BATADV_TP_MSG: Msg from sender to receiver + * @BATADV_TP_ACK: acknowledgment from receiver to sender + */ +enum batadv_icmp_tp_subtype { + BATADV_TP_MSG = 0, + BATADV_TP_ACK, +}; + +#define BATADV_RR_LEN 16 + +/** + * struct batadv_icmp_packet_rr - ICMP RouteRecord packet + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @msg_type: ICMP packet type + * @dst: address of the destination node + * @orig: address of the source node + * @uid: local ICMP socket identifier + * @rr_cur: number of entries the rr array + * @seqno: ICMP sequence number + * @rr: route record array + */ +struct batadv_icmp_packet_rr { + __u8 packet_type; + __u8 version; + __u8 ttl; + __u8 msg_type; /* see ICMP message types above */ + __u8 dst[ETH_ALEN]; + __u8 orig[ETH_ALEN]; + __u8 uid; + __u8 rr_cur; + __be16 seqno; + __u8 rr[BATADV_RR_LEN][ETH_ALEN]; +}; + +#define BATADV_ICMP_MAX_PACKET_SIZE sizeof(struct batadv_icmp_packet_rr) + +/* All packet headers in front of an ethernet header have to be completely + * divisible by 2 but not by 4 to make the payload after the ethernet + * header again 4 bytes boundary aligned. + * + * A packing of 2 is necessary to avoid extra padding at the end of the struct + * caused by a structure member which is larger than two bytes. Otherwise + * the structure would not fulfill the previously mentioned rule to avoid the + * misalignment of the payload after the ethernet header. It may also lead to + * leakage of information when the padding it not initialized before sending. + */ +#pragma pack(2) + +/** + * struct batadv_unicast_packet - unicast packet for network payload + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @ttvn: translation table version number + * @dest: originator destination of the unicast packet + */ +struct batadv_unicast_packet { + __u8 packet_type; + __u8 version; + __u8 ttl; + __u8 ttvn; /* destination translation table version number */ + __u8 dest[ETH_ALEN]; + /* "4 bytes boundary + 2 bytes" long to make the payload after the + * following ethernet header again 4 bytes boundary aligned + */ +}; + +/** + * struct batadv_unicast_4addr_packet - extended unicast packet + * @u: common unicast packet header + * @src: address of the source + * @subtype: packet subtype + * @reserved: reserved byte for alignment + */ +struct batadv_unicast_4addr_packet { + struct batadv_unicast_packet u; + __u8 src[ETH_ALEN]; + __u8 subtype; + __u8 reserved; + /* "4 bytes boundary + 2 bytes" long to make the payload after the + * following ethernet header again 4 bytes boundary aligned + */ +}; + +/** + * struct batadv_frag_packet - fragmented packet + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @dest: final destination used when routing fragments + * @orig: originator of the fragment used when merging the packet + * @no: fragment number within this sequence + * @priority: priority of frame, from ToS IP precedence or 802.1p + * @reserved: reserved byte for alignment + * @seqno: sequence identification + * @total_size: size of the merged packet + */ +struct batadv_frag_packet { + __u8 packet_type; + __u8 version; /* batman version field */ + __u8 ttl; +#if defined(__BIG_ENDIAN_BITFIELD) + __u8 no:4; + __u8 priority:3; + __u8 reserved:1; +#elif defined(__LITTLE_ENDIAN_BITFIELD) + __u8 reserved:1; + __u8 priority:3; + __u8 no:4; +#else +#error "unknown bitfield endianness" +#endif + __u8 dest[ETH_ALEN]; + __u8 orig[ETH_ALEN]; + __be16 seqno; + __be16 total_size; +}; + +/** + * struct batadv_bcast_packet - broadcast packet for network payload + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @reserved: reserved byte for alignment + * @seqno: sequence identification + * @orig: originator of the broadcast packet + */ +struct batadv_bcast_packet { + __u8 packet_type; + __u8 version; /* batman version field */ + __u8 ttl; + __u8 reserved; + __be32 seqno; + __u8 orig[ETH_ALEN]; + /* "4 bytes boundary + 2 bytes" long to make the payload after the + * following ethernet header again 4 bytes boundary aligned + */ +}; + +/** + * struct batadv_coded_packet - network coded packet + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @first_source: original source of first included packet + * @first_orig_dest: original destinal of first included packet + * @first_crc: checksum of first included packet + * @first_ttvn: tt-version number of first included packet + * @second_ttl: ttl of second packet + * @second_dest: second receiver of this coded packet + * @second_source: original source of second included packet + * @second_orig_dest: original destination of second included packet + * @second_crc: checksum of second included packet + * @second_ttvn: tt version number of second included packet + * @coded_len: length of network coded part of the payload + */ +struct batadv_coded_packet { + __u8 packet_type; + __u8 version; /* batman version field */ + __u8 ttl; + __u8 first_ttvn; + /* __u8 first_dest[ETH_ALEN]; - saved in mac header destination */ + __u8 first_source[ETH_ALEN]; + __u8 first_orig_dest[ETH_ALEN]; + __be32 first_crc; + __u8 second_ttl; + __u8 second_ttvn; + __u8 second_dest[ETH_ALEN]; + __u8 second_source[ETH_ALEN]; + __u8 second_orig_dest[ETH_ALEN]; + __be32 second_crc; + __be16 coded_len; +}; + +#pragma pack() + +/** + * struct batadv_unicast_tvlv_packet - generic unicast packet with tvlv payload + * @packet_type: batman-adv packet type, part of the general header + * @version: batman-adv protocol version, part of the genereal header + * @ttl: time to live for this packet, part of the genereal header + * @reserved: reserved field (for packet alignment) + * @src: address of the source + * @dst: address of the destination + * @tvlv_len: length of tvlv data following the unicast tvlv header + * @align: 2 bytes to align the header to a 4 byte boundary + */ +struct batadv_unicast_tvlv_packet { + __u8 packet_type; + __u8 version; /* batman version field */ + __u8 ttl; + __u8 reserved; + __u8 dst[ETH_ALEN]; + __u8 src[ETH_ALEN]; + __be16 tvlv_len; + __u16 align; +}; + +/** + * struct batadv_tvlv_hdr - base tvlv header struct + * @type: tvlv container type (see batadv_tvlv_type) + * @version: tvlv container version + * @len: tvlv container length + */ +struct batadv_tvlv_hdr { + __u8 type; + __u8 version; + __be16 len; +}; + +/** + * struct batadv_tvlv_gateway_data - gateway data propagated through gw tvlv + * container + * @bandwidth_down: advertised uplink download bandwidth + * @bandwidth_up: advertised uplink upload bandwidth + */ +struct batadv_tvlv_gateway_data { + __be32 bandwidth_down; + __be32 bandwidth_up; +}; + +/** + * struct batadv_tvlv_tt_data - tt data propagated through the tt tvlv container + * @flags: translation table flags (see batadv_tt_data_flags) + * @ttvn: translation table version number + * @num_vlan: number of announced VLANs. In the TVLV this struct is followed by + * one batadv_tvlv_tt_vlan_data object per announced vlan + */ +struct batadv_tvlv_tt_data { + __u8 flags; + __u8 ttvn; + __be16 num_vlan; +}; + +/** + * struct batadv_tvlv_tt_vlan_data - vlan specific tt data propagated through + * the tt tvlv container + * @crc: crc32 checksum of the entries belonging to this vlan + * @vid: vlan identifier + * @reserved: unused, useful for alignment purposes + */ +struct batadv_tvlv_tt_vlan_data { + __be32 crc; + __be16 vid; + __u16 reserved; +}; + +/** + * struct batadv_tvlv_tt_change - translation table diff data + * @flags: status indicators concerning the non-mesh client (see + * batadv_tt_client_flags) + * @reserved: reserved field - useful for alignment purposes only + * @addr: mac address of non-mesh client that triggered this tt change + * @vid: VLAN identifier + */ +struct batadv_tvlv_tt_change { + __u8 flags; + __u8 reserved[3]; + __u8 addr[ETH_ALEN]; + __be16 vid; +}; + +/** + * struct batadv_tvlv_roam_adv - roaming advertisement + * @client: mac address of roaming client + * @vid: VLAN identifier + */ +struct batadv_tvlv_roam_adv { + __u8 client[ETH_ALEN]; + __be16 vid; +}; + +/** + * struct batadv_tvlv_mcast_data - payload of a multicast tvlv + * @flags: multicast flags announced by the orig node + * @reserved: reserved field + */ +struct batadv_tvlv_mcast_data { + __u8 flags; + __u8 reserved[3]; +}; + +#endif /* _UAPI_LINUX_BATADV_PACKET_H_ */ diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 84c36430c25a..79e326383726 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include "bat_algo.h" @@ -63,7 +64,6 @@ #include "netlink.h" #include "network-coding.h" #include "originator.h" -#include "packet.h" #include "routing.h" #include "send.h" #include "translation-table.h" diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 78ddf3afa83a..27e165ac9302 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "bat_algo.h" @@ -49,7 +50,6 @@ #include "log.h" #include "netlink.h" #include "originator.h" -#include "packet.h" struct sk_buff; diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index 59ae96cef596..a83478c46597 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c @@ -42,13 +42,13 @@ #include #include #include +#include #include "bat_algo.h" #include "bat_v_ogm.h" #include "hard-interface.h" #include "log.h" #include "originator.h" -#include "packet.h" #include "routing.h" #include "send.h" diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index e415974c540d..ba59b77c605d 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -39,13 +39,13 @@ #include #include #include +#include #include "bat_algo.h" #include "hard-interface.h" #include "hash.h" #include "log.h" #include "originator.h" -#include "packet.h" #include "routing.h" #include "send.h" #include "translation-table.h" diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index e647450e5d0f..fad47853ad3c 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include "hard-interface.h" @@ -57,7 +58,6 @@ #include "log.h" #include "netlink.h" #include "originator.h" -#include "packet.h" #include "soft-interface.h" #include "sysfs.h" #include "translation-table.h" diff --git a/net/batman-adv/distributed-arp-table.h b/net/batman-adv/distributed-arp-table.h index 3d47bedaf661..12897eb46268 100644 --- a/net/batman-adv/distributed-arp-table.h +++ b/net/batman-adv/distributed-arp-table.h @@ -24,9 +24,9 @@ #include #include #include +#include #include "originator.h" -#include "packet.h" struct seq_file; struct sk_buff; diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index 4979350af9a7..22dde42fd80e 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c @@ -33,10 +33,10 @@ #include #include #include +#include #include "hard-interface.h" #include "originator.h" -#include "packet.h" #include "routing.h" #include "send.h" #include "soft-interface.h" diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 2488e25d0eef..37fe9a644f22 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include "gateway_common.h" @@ -50,7 +51,6 @@ #include "log.h" #include "netlink.h" #include "originator.h" -#include "packet.h" #include "routing.h" #include "soft-interface.h" #include "sysfs.h" diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c index 83bfeecf661c..b3e156af2256 100644 --- a/net/batman-adv/gateway_common.c +++ b/net/batman-adv/gateway_common.c @@ -27,10 +27,10 @@ #include #include #include +#include #include "gateway_client.h" #include "log.h" -#include "packet.h" #include "tvlv.h" /** diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 13d04dba0b3a..5f186bff284a 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "bat_v.h" #include "bridge_loop_avoidance.h" @@ -46,7 +47,6 @@ #include "gateway_client.h" #include "log.h" #include "originator.h" -#include "packet.h" #include "send.h" #include "soft-interface.h" #include "sysfs.h" diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c index f2ef75b7fa73..8041cf106c37 100644 --- a/net/batman-adv/icmp_socket.c +++ b/net/batman-adv/icmp_socket.c @@ -44,11 +44,11 @@ #include #include #include +#include #include "hard-interface.h" #include "log.h" #include "originator.h" -#include "packet.h" #include "send.h" static struct batadv_socket_client *batadv_socket_client_hash[256]; diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 8bee4279d579..d31c8266e244 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include "bat_algo.h" @@ -63,7 +64,6 @@ #include "netlink.h" #include "network-coding.h" #include "originator.h" -#include "packet.h" #include "routing.h" #include "send.h" #include "soft-interface.h" diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index d5484ac381d3..f7ba3f96d8f3 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -223,8 +223,8 @@ enum batadv_uev_type { #include #include #include +#include -#include "packet.h" #include "types.h" struct net_device; diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c index 8a503c526b90..cbdeb47ec3f6 100644 --- a/net/batman-adv/multicast.c +++ b/net/batman-adv/multicast.c @@ -55,11 +55,11 @@ #include #include #include +#include #include "hard-interface.h" #include "hash.h" #include "log.h" -#include "packet.h" #include "translation-table.h" #include "tvlv.h" diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c index 103d4bdcdbdb..a823d3899bad 100644 --- a/net/batman-adv/netlink.c +++ b/net/batman-adv/netlink.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include "bat_algo.h" @@ -47,7 +48,6 @@ #include "gateway_client.h" #include "hard-interface.h" #include "originator.h" -#include "packet.h" #include "soft-interface.h" #include "tp_meter.h" #include "translation-table.h" diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index 3758be7fd881..b48116bb24ef 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c @@ -49,12 +49,12 @@ #include #include #include +#include #include "hard-interface.h" #include "hash.h" #include "log.h" #include "originator.h" -#include "packet.h" #include "routing.h" #include "send.h" #include "tvlv.h" diff --git a/net/batman-adv/packet.h b/net/batman-adv/packet.h deleted file mode 100644 index 3b2d2db993aa..000000000000 --- a/net/batman-adv/packet.h +++ /dev/null @@ -1,644 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2007-2017 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef _NET_BATMAN_ADV_PACKET_H_ -#define _NET_BATMAN_ADV_PACKET_H_ - -#include -#include -#include - -/** - * batadv_tp_is_error() - Check throughput meter return code for error - * @n: throughput meter return code - * - * Return: 0 when not error was detected, != 0 otherwise - */ -#define batadv_tp_is_error(n) ((__u8)(n) > 127 ? 1 : 0) - -/** - * enum batadv_packettype - types for batman-adv encapsulated packets - * @BATADV_IV_OGM: originator messages for B.A.T.M.A.N. IV - * @BATADV_BCAST: broadcast packets carrying broadcast payload - * @BATADV_CODED: network coded packets - * @BATADV_ELP: echo location packets for B.A.T.M.A.N. V - * @BATADV_OGM2: originator messages for B.A.T.M.A.N. V - * - * @BATADV_UNICAST: unicast packets carrying unicast payload traffic - * @BATADV_UNICAST_FRAG: unicast packets carrying a fragment of the original - * payload packet - * @BATADV_UNICAST_4ADDR: unicast packet including the originator address of - * the sender - * @BATADV_ICMP: unicast packet like IP ICMP used for ping or traceroute - * @BATADV_UNICAST_TVLV: unicast packet carrying TVLV containers - */ -enum batadv_packettype { - /* 0x00 - 0x3f: local packets or special rules for handling */ - BATADV_IV_OGM = 0x00, - BATADV_BCAST = 0x01, - BATADV_CODED = 0x02, - BATADV_ELP = 0x03, - BATADV_OGM2 = 0x04, - /* 0x40 - 0x7f: unicast */ -#define BATADV_UNICAST_MIN 0x40 - BATADV_UNICAST = 0x40, - BATADV_UNICAST_FRAG = 0x41, - BATADV_UNICAST_4ADDR = 0x42, - BATADV_ICMP = 0x43, - BATADV_UNICAST_TVLV = 0x44, -#define BATADV_UNICAST_MAX 0x7f - /* 0x80 - 0xff: reserved */ -}; - -/** - * enum batadv_subtype - packet subtype for unicast4addr - * @BATADV_P_DATA: user payload - * @BATADV_P_DAT_DHT_GET: DHT request message - * @BATADV_P_DAT_DHT_PUT: DHT store message - * @BATADV_P_DAT_CACHE_REPLY: ARP reply generated by DAT - */ -enum batadv_subtype { - BATADV_P_DATA = 0x01, - BATADV_P_DAT_DHT_GET = 0x02, - BATADV_P_DAT_DHT_PUT = 0x03, - BATADV_P_DAT_CACHE_REPLY = 0x04, -}; - -/* this file is included by batctl which needs these defines */ -#define BATADV_COMPAT_VERSION 15 - -/** - * enum batadv_iv_flags - flags used in B.A.T.M.A.N. IV OGM packets - * @BATADV_NOT_BEST_NEXT_HOP: flag is set when ogm packet is forwarded and was - * previously received from someone else than the best neighbor. - * @BATADV_PRIMARIES_FIRST_HOP: flag unused. - * @BATADV_DIRECTLINK: flag is for the first hop or if rebroadcasted from a - * one hop neighbor on the interface where it was originally received. - */ -enum batadv_iv_flags { - BATADV_NOT_BEST_NEXT_HOP = 1UL << 0, - BATADV_PRIMARIES_FIRST_HOP = 1UL << 1, - BATADV_DIRECTLINK = 1UL << 2, -}; - -/** - * enum batadv_icmp_packettype - ICMP message types - * @BATADV_ECHO_REPLY: success reply to BATADV_ECHO_REQUEST - * @BATADV_DESTINATION_UNREACHABLE: failure when route to destination not found - * @BATADV_ECHO_REQUEST: request BATADV_ECHO_REPLY from destination - * @BATADV_TTL_EXCEEDED: error after BATADV_ECHO_REQUEST traversed too many hops - * @BATADV_PARAMETER_PROBLEM: return code for malformed messages - * @BATADV_TP: throughput meter packet - */ -enum batadv_icmp_packettype { - BATADV_ECHO_REPLY = 0, - BATADV_DESTINATION_UNREACHABLE = 3, - BATADV_ECHO_REQUEST = 8, - BATADV_TTL_EXCEEDED = 11, - BATADV_PARAMETER_PROBLEM = 12, - BATADV_TP = 15, -}; - -/** - * enum batadv_mcast_flags - flags for multicast capabilities and settings - * @BATADV_MCAST_WANT_ALL_UNSNOOPABLES: we want all packets destined for - * 224.0.0.0/24 or ff02::1 - * @BATADV_MCAST_WANT_ALL_IPV4: we want all IPv4 multicast packets - * @BATADV_MCAST_WANT_ALL_IPV6: we want all IPv6 multicast packets - */ -enum batadv_mcast_flags { - BATADV_MCAST_WANT_ALL_UNSNOOPABLES = 1UL << 0, - BATADV_MCAST_WANT_ALL_IPV4 = 1UL << 1, - BATADV_MCAST_WANT_ALL_IPV6 = 1UL << 2, -}; - -/* tt data subtypes */ -#define BATADV_TT_DATA_TYPE_MASK 0x0F - -/** - * enum batadv_tt_data_flags - flags for tt data tvlv - * @BATADV_TT_OGM_DIFF: TT diff propagated through OGM - * @BATADV_TT_REQUEST: TT request message - * @BATADV_TT_RESPONSE: TT response message - * @BATADV_TT_FULL_TABLE: contains full table to replace existing table - */ -enum batadv_tt_data_flags { - BATADV_TT_OGM_DIFF = 1UL << 0, - BATADV_TT_REQUEST = 1UL << 1, - BATADV_TT_RESPONSE = 1UL << 2, - BATADV_TT_FULL_TABLE = 1UL << 4, -}; - -/** - * enum batadv_vlan_flags - flags for the four MSB of any vlan ID field - * @BATADV_VLAN_HAS_TAG: whether the field contains a valid vlan tag or not - */ -enum batadv_vlan_flags { - BATADV_VLAN_HAS_TAG = 1UL << 15, -}; - -/** - * enum batadv_bla_claimframe - claim frame types for the bridge loop avoidance - * @BATADV_CLAIM_TYPE_CLAIM: claim of a client mac address - * @BATADV_CLAIM_TYPE_UNCLAIM: unclaim of a client mac address - * @BATADV_CLAIM_TYPE_ANNOUNCE: announcement of backbone with current crc - * @BATADV_CLAIM_TYPE_REQUEST: request of full claim table - * @BATADV_CLAIM_TYPE_LOOPDETECT: mesh-traversing loop detect packet - */ -enum batadv_bla_claimframe { - BATADV_CLAIM_TYPE_CLAIM = 0x00, - BATADV_CLAIM_TYPE_UNCLAIM = 0x01, - BATADV_CLAIM_TYPE_ANNOUNCE = 0x02, - BATADV_CLAIM_TYPE_REQUEST = 0x03, - BATADV_CLAIM_TYPE_LOOPDETECT = 0x04, -}; - -/** - * enum batadv_tvlv_type - tvlv type definitions - * @BATADV_TVLV_GW: gateway tvlv - * @BATADV_TVLV_DAT: distributed arp table tvlv - * @BATADV_TVLV_NC: network coding tvlv - * @BATADV_TVLV_TT: translation table tvlv - * @BATADV_TVLV_ROAM: roaming advertisement tvlv - * @BATADV_TVLV_MCAST: multicast capability tvlv - */ -enum batadv_tvlv_type { - BATADV_TVLV_GW = 0x01, - BATADV_TVLV_DAT = 0x02, - BATADV_TVLV_NC = 0x03, - BATADV_TVLV_TT = 0x04, - BATADV_TVLV_ROAM = 0x05, - BATADV_TVLV_MCAST = 0x06, -}; - -#pragma pack(2) -/* the destination hardware field in the ARP frame is used to - * transport the claim type and the group id - */ -struct batadv_bla_claim_dst { - __u8 magic[3]; /* FF:43:05 */ - __u8 type; /* bla_claimframe */ - __be16 group; /* group id */ -}; - -#pragma pack() - -/** - * struct batadv_ogm_packet - ogm (routing protocol) packet - * @packet_type: batman-adv packet type, part of the general header - * @version: batman-adv protocol version, part of the genereal header - * @ttl: time to live for this packet, part of the genereal header - * @flags: contains routing relevant flags - see enum batadv_iv_flags - * @seqno: sequence identification - * @orig: address of the source node - * @prev_sender: address of the previous sender - * @reserved: reserved byte for alignment - * @tq: transmission quality - * @tvlv_len: length of tvlv data following the ogm header - */ -struct batadv_ogm_packet { - __u8 packet_type; - __u8 version; - __u8 ttl; - __u8 flags; - __be32 seqno; - __u8 orig[ETH_ALEN]; - __u8 prev_sender[ETH_ALEN]; - __u8 reserved; - __u8 tq; - __be16 tvlv_len; - /* __packed is not needed as the struct size is divisible by 4, - * and the largest data type in this struct has a size of 4. - */ -}; - -#define BATADV_OGM_HLEN sizeof(struct batadv_ogm_packet) - -/** - * struct batadv_ogm2_packet - ogm2 (routing protocol) packet - * @packet_type: batman-adv packet type, part of the general header - * @version: batman-adv protocol version, part of the general header - * @ttl: time to live for this packet, part of the general header - * @flags: reseved for routing relevant flags - currently always 0 - * @seqno: sequence number - * @orig: originator mac address - * @tvlv_len: length of the appended tvlv buffer (in bytes) - * @throughput: the currently flooded path throughput - */ -struct batadv_ogm2_packet { - __u8 packet_type; - __u8 version; - __u8 ttl; - __u8 flags; - __be32 seqno; - __u8 orig[ETH_ALEN]; - __be16 tvlv_len; - __be32 throughput; - /* __packed is not needed as the struct size is divisible by 4, - * and the largest data type in this struct has a size of 4. - */ -}; - -#define BATADV_OGM2_HLEN sizeof(struct batadv_ogm2_packet) - -/** - * struct batadv_elp_packet - elp (neighbor discovery) packet - * @packet_type: batman-adv packet type, part of the general header - * @version: batman-adv protocol version, part of the genereal header - * @orig: originator mac address - * @seqno: sequence number - * @elp_interval: currently used ELP sending interval in ms - */ -struct batadv_elp_packet { - __u8 packet_type; - __u8 version; - __u8 orig[ETH_ALEN]; - __be32 seqno; - __be32 elp_interval; -}; - -#define BATADV_ELP_HLEN sizeof(struct batadv_elp_packet) - -/** - * struct batadv_icmp_header - common members among all the ICMP packets - * @packet_type: batman-adv packet type, part of the general header - * @version: batman-adv protocol version, part of the genereal header - * @ttl: time to live for this packet, part of the genereal header - * @msg_type: ICMP packet type - * @dst: address of the destination node - * @orig: address of the source node - * @uid: local ICMP socket identifier - * @align: not used - useful for alignment purposes only - * - * This structure is used for ICMP packets parsing only and it is never sent - * over the wire. The alignment field at the end is there to ensure that - * members are padded the same way as they are in real packets. - */ -struct batadv_icmp_header { - __u8 packet_type; - __u8 version; - __u8 ttl; - __u8 msg_type; /* see ICMP message types above */ - __u8 dst[ETH_ALEN]; - __u8 orig[ETH_ALEN]; - __u8 uid; - __u8 align[3]; -}; - -/** - * struct batadv_icmp_packet - ICMP packet - * @packet_type: batman-adv packet type, part of the general header - * @version: batman-adv protocol version, part of the genereal header - * @ttl: time to live for this packet, part of the genereal header - * @msg_type: ICMP packet type - * @dst: address of the destination node - * @orig: address of the source node - * @uid: local ICMP socket identifier - * @reserved: not used - useful for alignment - * @seqno: ICMP sequence number - */ -struct batadv_icmp_packet { - __u8 packet_type; - __u8 version; - __u8 ttl; - __u8 msg_type; /* see ICMP message types above */ - __u8 dst[ETH_ALEN]; - __u8 orig[ETH_ALEN]; - __u8 uid; - __u8 reserved; - __be16 seqno; -}; - -/** - * struct batadv_icmp_tp_packet - ICMP TP Meter packet - * @packet_type: batman-adv packet type, part of the general header - * @version: batman-adv protocol version, part of the genereal header - * @ttl: time to live for this packet, part of the genereal header - * @msg_type: ICMP packet type - * @dst: address of the destination node - * @orig: address of the source node - * @uid: local ICMP socket identifier - * @subtype: TP packet subtype (see batadv_icmp_tp_subtype) - * @session: TP session identifier - * @seqno: the TP sequence number - * @timestamp: time when the packet has been sent. This value is filled in a - * TP_MSG and echoed back in the next TP_ACK so that the sender can compute the - * RTT. Since it is read only by the host which wrote it, there is no need to - * store it using network order - */ -struct batadv_icmp_tp_packet { - __u8 packet_type; - __u8 version; - __u8 ttl; - __u8 msg_type; /* see ICMP message types above */ - __u8 dst[ETH_ALEN]; - __u8 orig[ETH_ALEN]; - __u8 uid; - __u8 subtype; - __u8 session[2]; - __be32 seqno; - __be32 timestamp; -}; - -/** - * enum batadv_icmp_tp_subtype - ICMP TP Meter packet subtypes - * @BATADV_TP_MSG: Msg from sender to receiver - * @BATADV_TP_ACK: acknowledgment from receiver to sender - */ -enum batadv_icmp_tp_subtype { - BATADV_TP_MSG = 0, - BATADV_TP_ACK, -}; - -#define BATADV_RR_LEN 16 - -/** - * struct batadv_icmp_packet_rr - ICMP RouteRecord packet - * @packet_type: batman-adv packet type, part of the general header - * @version: batman-adv protocol version, part of the genereal header - * @ttl: time to live for this packet, part of the genereal header - * @msg_type: ICMP packet type - * @dst: address of the destination node - * @orig: address of the source node - * @uid: local ICMP socket identifier - * @rr_cur: number of entries the rr array - * @seqno: ICMP sequence number - * @rr: route record array - */ -struct batadv_icmp_packet_rr { - __u8 packet_type; - __u8 version; - __u8 ttl; - __u8 msg_type; /* see ICMP message types above */ - __u8 dst[ETH_ALEN]; - __u8 orig[ETH_ALEN]; - __u8 uid; - __u8 rr_cur; - __be16 seqno; - __u8 rr[BATADV_RR_LEN][ETH_ALEN]; -}; - -#define BATADV_ICMP_MAX_PACKET_SIZE sizeof(struct batadv_icmp_packet_rr) - -/* All packet headers in front of an ethernet header have to be completely - * divisible by 2 but not by 4 to make the payload after the ethernet - * header again 4 bytes boundary aligned. - * - * A packing of 2 is necessary to avoid extra padding at the end of the struct - * caused by a structure member which is larger than two bytes. Otherwise - * the structure would not fulfill the previously mentioned rule to avoid the - * misalignment of the payload after the ethernet header. It may also lead to - * leakage of information when the padding it not initialized before sending. - */ -#pragma pack(2) - -/** - * struct batadv_unicast_packet - unicast packet for network payload - * @packet_type: batman-adv packet type, part of the general header - * @version: batman-adv protocol version, part of the genereal header - * @ttl: time to live for this packet, part of the genereal header - * @ttvn: translation table version number - * @dest: originator destination of the unicast packet - */ -struct batadv_unicast_packet { - __u8 packet_type; - __u8 version; - __u8 ttl; - __u8 ttvn; /* destination translation table version number */ - __u8 dest[ETH_ALEN]; - /* "4 bytes boundary + 2 bytes" long to make the payload after the - * following ethernet header again 4 bytes boundary aligned - */ -}; - -/** - * struct batadv_unicast_4addr_packet - extended unicast packet - * @u: common unicast packet header - * @src: address of the source - * @subtype: packet subtype - * @reserved: reserved byte for alignment - */ -struct batadv_unicast_4addr_packet { - struct batadv_unicast_packet u; - __u8 src[ETH_ALEN]; - __u8 subtype; - __u8 reserved; - /* "4 bytes boundary + 2 bytes" long to make the payload after the - * following ethernet header again 4 bytes boundary aligned - */ -}; - -/** - * struct batadv_frag_packet - fragmented packet - * @packet_type: batman-adv packet type, part of the general header - * @version: batman-adv protocol version, part of the genereal header - * @ttl: time to live for this packet, part of the genereal header - * @dest: final destination used when routing fragments - * @orig: originator of the fragment used when merging the packet - * @no: fragment number within this sequence - * @priority: priority of frame, from ToS IP precedence or 802.1p - * @reserved: reserved byte for alignment - * @seqno: sequence identification - * @total_size: size of the merged packet - */ -struct batadv_frag_packet { - __u8 packet_type; - __u8 version; /* batman version field */ - __u8 ttl; -#if defined(__BIG_ENDIAN_BITFIELD) - __u8 no:4; - __u8 priority:3; - __u8 reserved:1; -#elif defined(__LITTLE_ENDIAN_BITFIELD) - __u8 reserved:1; - __u8 priority:3; - __u8 no:4; -#else -#error "unknown bitfield endianness" -#endif - __u8 dest[ETH_ALEN]; - __u8 orig[ETH_ALEN]; - __be16 seqno; - __be16 total_size; -}; - -/** - * struct batadv_bcast_packet - broadcast packet for network payload - * @packet_type: batman-adv packet type, part of the general header - * @version: batman-adv protocol version, part of the genereal header - * @ttl: time to live for this packet, part of the genereal header - * @reserved: reserved byte for alignment - * @seqno: sequence identification - * @orig: originator of the broadcast packet - */ -struct batadv_bcast_packet { - __u8 packet_type; - __u8 version; /* batman version field */ - __u8 ttl; - __u8 reserved; - __be32 seqno; - __u8 orig[ETH_ALEN]; - /* "4 bytes boundary + 2 bytes" long to make the payload after the - * following ethernet header again 4 bytes boundary aligned - */ -}; - -/** - * struct batadv_coded_packet - network coded packet - * @packet_type: batman-adv packet type, part of the general header - * @version: batman-adv protocol version, part of the genereal header - * @ttl: time to live for this packet, part of the genereal header - * @first_source: original source of first included packet - * @first_orig_dest: original destinal of first included packet - * @first_crc: checksum of first included packet - * @first_ttvn: tt-version number of first included packet - * @second_ttl: ttl of second packet - * @second_dest: second receiver of this coded packet - * @second_source: original source of second included packet - * @second_orig_dest: original destination of second included packet - * @second_crc: checksum of second included packet - * @second_ttvn: tt version number of second included packet - * @coded_len: length of network coded part of the payload - */ -struct batadv_coded_packet { - __u8 packet_type; - __u8 version; /* batman version field */ - __u8 ttl; - __u8 first_ttvn; - /* __u8 first_dest[ETH_ALEN]; - saved in mac header destination */ - __u8 first_source[ETH_ALEN]; - __u8 first_orig_dest[ETH_ALEN]; - __be32 first_crc; - __u8 second_ttl; - __u8 second_ttvn; - __u8 second_dest[ETH_ALEN]; - __u8 second_source[ETH_ALEN]; - __u8 second_orig_dest[ETH_ALEN]; - __be32 second_crc; - __be16 coded_len; -}; - -#pragma pack() - -/** - * struct batadv_unicast_tvlv_packet - generic unicast packet with tvlv payload - * @packet_type: batman-adv packet type, part of the general header - * @version: batman-adv protocol version, part of the genereal header - * @ttl: time to live for this packet, part of the genereal header - * @reserved: reserved field (for packet alignment) - * @src: address of the source - * @dst: address of the destination - * @tvlv_len: length of tvlv data following the unicast tvlv header - * @align: 2 bytes to align the header to a 4 byte boundary - */ -struct batadv_unicast_tvlv_packet { - __u8 packet_type; - __u8 version; /* batman version field */ - __u8 ttl; - __u8 reserved; - __u8 dst[ETH_ALEN]; - __u8 src[ETH_ALEN]; - __be16 tvlv_len; - __u16 align; -}; - -/** - * struct batadv_tvlv_hdr - base tvlv header struct - * @type: tvlv container type (see batadv_tvlv_type) - * @version: tvlv container version - * @len: tvlv container length - */ -struct batadv_tvlv_hdr { - __u8 type; - __u8 version; - __be16 len; -}; - -/** - * struct batadv_tvlv_gateway_data - gateway data propagated through gw tvlv - * container - * @bandwidth_down: advertised uplink download bandwidth - * @bandwidth_up: advertised uplink upload bandwidth - */ -struct batadv_tvlv_gateway_data { - __be32 bandwidth_down; - __be32 bandwidth_up; -}; - -/** - * struct batadv_tvlv_tt_data - tt data propagated through the tt tvlv container - * @flags: translation table flags (see batadv_tt_data_flags) - * @ttvn: translation table version number - * @num_vlan: number of announced VLANs. In the TVLV this struct is followed by - * one batadv_tvlv_tt_vlan_data object per announced vlan - */ -struct batadv_tvlv_tt_data { - __u8 flags; - __u8 ttvn; - __be16 num_vlan; -}; - -/** - * struct batadv_tvlv_tt_vlan_data - vlan specific tt data propagated through - * the tt tvlv container - * @crc: crc32 checksum of the entries belonging to this vlan - * @vid: vlan identifier - * @reserved: unused, useful for alignment purposes - */ -struct batadv_tvlv_tt_vlan_data { - __be32 crc; - __be16 vid; - __u16 reserved; -}; - -/** - * struct batadv_tvlv_tt_change - translation table diff data - * @flags: status indicators concerning the non-mesh client (see - * batadv_tt_client_flags) - * @reserved: reserved field - useful for alignment purposes only - * @addr: mac address of non-mesh client that triggered this tt change - * @vid: VLAN identifier - */ -struct batadv_tvlv_tt_change { - __u8 flags; - __u8 reserved[3]; - __u8 addr[ETH_ALEN]; - __be16 vid; -}; - -/** - * struct batadv_tvlv_roam_adv - roaming advertisement - * @client: mac address of roaming client - * @vid: VLAN identifier - */ -struct batadv_tvlv_roam_adv { - __u8 client[ETH_ALEN]; - __be16 vid; -}; - -/** - * struct batadv_tvlv_mcast_data - payload of a multicast tvlv - * @flags: multicast flags announced by the orig node - * @reserved: reserved field - */ -struct batadv_tvlv_mcast_data { - __u8 flags; - __u8 reserved[3]; -}; - -#endif /* _NET_BATMAN_ADV_PACKET_H_ */ diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index eb835bde502a..b6891e8b741c 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "bitarray.h" #include "bridge_loop_avoidance.h" @@ -44,7 +45,6 @@ #include "log.h" #include "network-coding.h" #include "originator.h" -#include "packet.h" #include "send.h" #include "soft-interface.h" #include "tp_meter.h" diff --git a/net/batman-adv/send.h b/net/batman-adv/send.h index 8c7399dd06ca..1e8c79093623 100644 --- a/net/batman-adv/send.h +++ b/net/batman-adv/send.h @@ -24,8 +24,7 @@ #include #include #include - -#include "packet.h" +#include struct sk_buff; diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 1eb5555c5fe4..900c5ce21cd4 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "bat_algo.h" #include "bridge_loop_avoidance.h" @@ -60,7 +61,6 @@ #include "multicast.h" #include "network-coding.h" #include "originator.h" -#include "packet.h" #include "send.h" #include "sysfs.h" #include "translation-table.h" diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index 56fb42551453..c1578fa0b952 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "bridge_loop_avoidance.h" #include "distributed-arp-table.h" @@ -47,7 +48,6 @@ #include "hard-interface.h" #include "log.h" #include "network-coding.h" -#include "packet.h" #include "soft-interface.h" static struct net_device *batadv_kobj_to_netdev(struct kobject *obj) diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c index 7dcf2aa4deb5..8b576712d0c1 100644 --- a/net/batman-adv/tp_meter.c +++ b/net/batman-adv/tp_meter.c @@ -49,13 +49,13 @@ #include #include #include +#include #include #include "hard-interface.h" #include "log.h" #include "netlink.h" #include "originator.h" -#include "packet.h" #include "send.h" /** diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 0e53be3f8df0..7550a9ccd695 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include "bridge_loop_avoidance.h" @@ -60,7 +61,6 @@ #include "log.h" #include "netlink.h" #include "originator.h" -#include "packet.h" #include "soft-interface.h" #include "tvlv.h" diff --git a/net/batman-adv/tvlv.c b/net/batman-adv/tvlv.c index e189f026974c..5ffcb45ac6ff 100644 --- a/net/batman-adv/tvlv.c +++ b/net/batman-adv/tvlv.c @@ -36,9 +36,9 @@ #include #include #include +#include #include "originator.h" -#include "packet.h" #include "send.h" #include "tvlv.h" diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index 77b145eba193..bb1578410e0c 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -35,10 +35,9 @@ #include #include #include +#include #include -#include "packet.h" - struct seq_file; #ifdef CONFIG_BATMAN_ADV_DAT -- cgit v1.2.3-59-g8ed1b From f15bc54eeecd86dfba3885aab839cd1f45172a38 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 22 Dec 2017 15:10:18 +0100 Subject: l2tp: add peer_offset parameter Introduce peer_offset parameter in order to add the capability to specify two different values for payload offset on tx/rx side. If just offset is provided by userspace use it for rx side as well in order to maintain compatibility with older l2tp versions Signed-off-by: Lorenzo Bianconi Signed-off-by: David S. Miller --- include/uapi/linux/l2tp.h | 1 + net/l2tp/l2tp_core.c | 3 ++- net/l2tp/l2tp_core.h | 13 ++++++++++--- net/l2tp/l2tp_debugfs.c | 8 +++++--- net/l2tp/l2tp_netlink.c | 21 ++++++++++++++++++++- 5 files changed, 38 insertions(+), 8 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h index d84ce5c1c9aa..d6fee55dbded 100644 --- a/include/uapi/linux/l2tp.h +++ b/include/uapi/linux/l2tp.h @@ -127,6 +127,7 @@ enum { L2TP_ATTR_UDP_ZERO_CSUM6_TX, /* flag */ L2TP_ATTR_UDP_ZERO_CSUM6_RX, /* flag */ L2TP_ATTR_PAD, + L2TP_ATTR_PEER_OFFSET, /* u16 */ __L2TP_ATTR_MAX, }; diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 115918ad8eca..6ff64717da1e 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -792,7 +792,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, ptr += 2 + offset; } } else - ptr += session->offset; + ptr += session->peer_offset; offset = ptr - optr; if (!pskb_may_pull(skb, offset)) @@ -1785,6 +1785,7 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn session->lns_mode = cfg->lns_mode; session->reorder_timeout = cfg->reorder_timeout; session->offset = cfg->offset; + session->peer_offset = cfg->peer_offset; session->l2specific_type = cfg->l2specific_type; session->l2specific_len = cfg->l2specific_len; session->cookie_len = cfg->cookie_len; diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index 9534e16965cc..c6fe7cc42a05 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -59,7 +59,8 @@ struct l2tp_session_cfg { int debug; /* bitmask of debug message * categories */ u16 vlan_id; /* VLAN pseudowire only */ - u16 offset; /* offset to payload */ + u16 offset; /* offset to tx payload */ + u16 peer_offset; /* offset to rx payload */ u16 l2specific_len; /* Layer 2 specific length */ u16 l2specific_type; /* Layer 2 specific type */ u8 cookie[8]; /* optional cookie */ @@ -86,8 +87,14 @@ struct l2tp_session { int cookie_len; u8 peer_cookie[8]; int peer_cookie_len; - u16 offset; /* offset from end of L2TP header - to beginning of data */ + u16 offset; /* offset from end of L2TP + * header to beginning of + * tx data + */ + u16 peer_offset; /* offset from end of L2TP + * header to beginning of + * rx data + */ u16 l2specific_len; u16 l2specific_type; u16 hdr_len; diff --git a/net/l2tp/l2tp_debugfs.c b/net/l2tp/l2tp_debugfs.c index eb69411bcb47..4cc30b38aba4 100644 --- a/net/l2tp/l2tp_debugfs.c +++ b/net/l2tp/l2tp_debugfs.c @@ -180,8 +180,9 @@ static void l2tp_dfs_seq_session_show(struct seq_file *m, void *v) session->lns_mode ? "LNS" : "LAC", session->debug, jiffies_to_msecs(session->reorder_timeout)); - seq_printf(m, " offset %hu l2specific %hu/%hu\n", - session->offset, session->l2specific_type, session->l2specific_len); + seq_printf(m, " offset %hu peer_offset %hu l2specific %hu/%hu\n", + session->offset, session->peer_offset, + session->l2specific_type, session->l2specific_len); if (session->cookie_len) { seq_printf(m, " cookie %02x%02x%02x%02x", session->cookie[0], session->cookie[1], @@ -228,7 +229,8 @@ static int l2tp_dfs_seq_show(struct seq_file *m, void *v) seq_puts(m, " debug tx-pkts/bytes/errs rx-pkts/bytes/errs\n"); seq_puts(m, " SESSION ID, peer ID, PWTYPE\n"); seq_puts(m, " refcnt cnt\n"); - seq_puts(m, " offset OFFSET l2specific TYPE/LEN\n"); + seq_puts(m, " offset OFFSET peer_offset OFFSET"); + seq_puts(m, " l2specific TYPE/LEN\n"); seq_puts(m, " [ cookie ]\n"); seq_puts(m, " [ peer cookie ]\n"); seq_puts(m, " config mtu/mru/rcvseq/sendseq/dataseq/lns debug reorderto\n"); diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index 7e9c50125556..d7d4d7a7a54d 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -547,9 +547,25 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf } if (tunnel->version > 2) { - if (info->attrs[L2TP_ATTR_OFFSET]) + if (info->attrs[L2TP_ATTR_PEER_OFFSET]) { + struct nlattr *peer_offset; + + peer_offset = info->attrs[L2TP_ATTR_PEER_OFFSET]; + cfg.peer_offset = nla_get_u16(peer_offset); + } + + if (info->attrs[L2TP_ATTR_OFFSET]) { cfg.offset = nla_get_u16(info->attrs[L2TP_ATTR_OFFSET]); + /* in order to maintain compatibility with older + * versions where offset was used for both tx and + * rx side, update rx side with offset if peer_offset + * is not provided by userspace + */ + if (!info->attrs[L2TP_ATTR_PEER_OFFSET]) + cfg.peer_offset = cfg.offset; + } + if (info->attrs[L2TP_ATTR_DATA_SEQ]) cfg.data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]); @@ -763,6 +779,8 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) || (session->offset && nla_put_u16(skb, L2TP_ATTR_OFFSET, session->offset)) || + (session->peer_offset && + nla_put_u16(skb, L2TP_ATTR_PEER_OFFSET, session->peer_offset)) || (session->cookie_len && nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len, &session->cookie[0])) || @@ -903,6 +921,7 @@ static const struct nla_policy l2tp_nl_policy[L2TP_ATTR_MAX + 1] = { [L2TP_ATTR_PW_TYPE] = { .type = NLA_U16, }, [L2TP_ATTR_ENCAP_TYPE] = { .type = NLA_U16, }, [L2TP_ATTR_OFFSET] = { .type = NLA_U16, }, + [L2TP_ATTR_PEER_OFFSET] = { .type = NLA_U16, }, [L2TP_ATTR_DATA_SEQ] = { .type = NLA_U8, }, [L2TP_ATTR_L2SPEC_TYPE] = { .type = NLA_U8, }, [L2TP_ATTR_L2SPEC_LEN] = { .type = NLA_U8, }, -- cgit v1.2.3-59-g8ed1b From 57868acc369ab73ec8f6b43a0c6749077376b189 Mon Sep 17 00:00:00 2001 From: Satendra Singh Thakur Date: Mon, 18 Dec 2017 22:35:53 -0500 Subject: media: videobuf2: Add new uAPI for DVB streaming I/O Adds a new uAPI for DVB to use streaming I/O which is implemented based on videobuf2, using those new ioctls: - DMX_REQBUFS: Request kernel to allocate buffers which count and size are dedicated by user. - DMX_QUERYBUF: Get the buffer information like a memory offset which will mmap() and be shared with user-space. - DMX_EXPBUF: Just for testing whether buffer-exporting success or not. - DMX_QBUF: Pass the buffer to kernel-space. - DMX_DQBUF: Get back the buffer which may contain TS data. Originally developed by: Junghak Sung , as seen at: https://patchwork.linuxtv.org/patch/31613/ https://patchwork.kernel.org/patch/7334301/ The original patch was written before merging VB2-core functionalities upstream. When such series was added, several adjustments were made, fixing some issues with V4L2, causing the original patch to be non-trivially rebased. After rebased, a few bugs in the patch were fixed. The patch was also enhanced it and polling functionality got added. The main changes over the original patch are: dvb_vb2_fill_buffer(): - Set the size of the outgoing buffer after while loop using vb2_set_plane_payload; - Added NULL check for source buffer as per normal convention of demux driver, this is called twice, first time with valid buffer second time with NULL pointer, if its not handled, it will result in crash - Restricted spinlock for only list_* operations dvb_vb2_init(): - Restricted q->io_modes to only VB2_MMAP as its the only supported mode dvb_vb2_release(): - Replaced the && in if condiion with &, because otherwise it was always getting satisfied. dvb_vb2_stream_off(): - Added list_del code for enqueud buffers upon stream off dvb_vb2_poll(): - Added this new function in order to support polling dvb_demux_poll() and dvb_dvr_poll() - dvb_vb2_poll() is now called from these functions - Ported this patch and latest videobuf2 to lower kernel versions and tested auto scan. Co-developed-by: Junghak Sung [mchehab@s-opensource.com: checkpatch fixes] Signed-off-by: Junghak Sung Signed-off-by: Geunyoung Kim Acked-by: Seung-Woo Kim Acked-by: Inki Dae Signed-off-by: Satendra Singh Thakur Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb-core/Makefile | 2 +- drivers/media/dvb-core/dmxdev.c | 196 +++++++++++++++--- drivers/media/dvb-core/dmxdev.h | 4 + drivers/media/dvb-core/dvb_vb2.c | 423 +++++++++++++++++++++++++++++++++++++++ drivers/media/dvb-core/dvb_vb2.h | 72 +++++++ include/uapi/linux/dvb/dmx.h | 66 +++++- 6 files changed, 733 insertions(+), 30 deletions(-) create mode 100644 drivers/media/dvb-core/dvb_vb2.c create mode 100644 drivers/media/dvb-core/dvb_vb2.h (limited to 'include/uapi/linux') diff --git a/drivers/media/dvb-core/Makefile b/drivers/media/dvb-core/Makefile index 47e2e391bfb8..bbc65dfa0a8e 100644 --- a/drivers/media/dvb-core/Makefile +++ b/drivers/media/dvb-core/Makefile @@ -7,6 +7,6 @@ dvb-net-$(CONFIG_DVB_NET) := dvb_net.o dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \ dvb_ca_en50221.o dvb_frontend.o \ - $(dvb-net-y) dvb_ringbuffer.o dvb_math.o + $(dvb-net-y) dvb_ringbuffer.o dvb_vb2.o dvb_math.o obj-$(CONFIG_DVB_CORE) += dvb-core.o diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index 3ddd44e1ee77..0ddf58adb172 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -28,6 +28,7 @@ #include #include #include "dmxdev.h" +#include "dvb_vb2.h" static int debug; @@ -138,14 +139,8 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) return -ENODEV; } - if ((file->f_flags & O_ACCMODE) == O_RDWR) { - if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { - mutex_unlock(&dmxdev->mutex); - return -EOPNOTSUPP; - } - } - - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { + if (((file->f_flags & O_ACCMODE) == O_RDONLY) || + ((file->f_flags & O_ACCMODE) == O_RDWR)) { void *mem; if (!dvbdev->readers) { @@ -158,6 +153,8 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) return -ENOMEM; } dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE); + dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr", + file->f_flags & O_NONBLOCK); dvbdev->readers--; } @@ -195,7 +192,11 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) dmxdev->demux->connect_frontend(dmxdev->demux, dmxdev->dvr_orig_fe); } - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { + if (((file->f_flags & O_ACCMODE) == O_RDONLY) || + ((file->f_flags & O_ACCMODE) == O_RDWR)) { + if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx)) + dvb_vb2_stream_off(&dmxdev->dvr_vb2_ctx); + dvb_vb2_release(&dmxdev->dvr_vb2_ctx); dvbdev->readers++; if (dmxdev->dvr_buffer.data) { void *mem = dmxdev->dvr_buffer.data; @@ -358,8 +359,8 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, { struct dmxdev_filter *dmxdevfilter = filter->priv; int ret; - - if (dmxdevfilter->buffer.error) { + if (!dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx) && + dmxdevfilter->buffer.error) { wake_up(&dmxdevfilter->buffer.queue); return 0; } @@ -370,11 +371,19 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, } del_timer(&dmxdevfilter->timer); dprintk("section callback %*ph\n", 6, buffer1); - ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, - buffer1_len); - if (ret == buffer1_len) { - ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2, - buffer2_len); + if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) { + ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx, + buffer1, buffer1_len); + if (ret == buffer1_len) + ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx, + buffer2, buffer2_len); + } else { + ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, + buffer1, buffer1_len); + if (ret == buffer1_len) { + ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, + buffer2, buffer2_len); + } } if (ret < 0) dmxdevfilter->buffer.error = ret; @@ -391,6 +400,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, { struct dmxdev_filter *dmxdevfilter = feed->priv; struct dvb_ringbuffer *buffer; + struct dvb_vb2_ctx *ctx; int ret; spin_lock(&dmxdevfilter->dev->lock); @@ -399,19 +409,30 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, return 0; } - if (dmxdevfilter->params.pes.output == DMX_OUT_TAP - || dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) + if (dmxdevfilter->params.pes.output == DMX_OUT_TAP || + dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) { buffer = &dmxdevfilter->buffer; - else + ctx = &dmxdevfilter->vb2_ctx; + } else { buffer = &dmxdevfilter->dev->dvr_buffer; - if (buffer->error) { - spin_unlock(&dmxdevfilter->dev->lock); - wake_up(&buffer->queue); - return 0; + ctx = &dmxdevfilter->dev->dvr_vb2_ctx; + } + + if (dvb_vb2_is_streaming(ctx)) { + ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len); + if (ret == buffer1_len) + ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len); + } else { + if (buffer->error) { + spin_unlock(&dmxdevfilter->dev->lock); + wake_up(&buffer->queue); + return 0; + } + ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len); + if (ret == buffer1_len) + ret = dvb_dmxdev_buffer_write(buffer, + buffer2, buffer2_len); } - ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len); - if (ret == buffer1_len) - ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len); if (ret < 0) buffer->error = ret; spin_unlock(&dmxdevfilter->dev->lock); @@ -750,6 +771,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file) file->private_data = dmxdevfilter; dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192); + dvb_vb2_init(&dmxdevfilter->vb2_ctx, "demux_filter", + file->f_flags & O_NONBLOCK); dmxdevfilter->type = DMXDEV_TYPE_NONE; dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); timer_setup(&dmxdevfilter->timer, dvb_dmxdev_filter_timeout, 0); @@ -765,6 +788,10 @@ static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, { mutex_lock(&dmxdev->mutex); mutex_lock(&dmxdevfilter->mutex); + if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) + dvb_vb2_stream_off(&dmxdevfilter->vb2_ctx); + dvb_vb2_release(&dmxdevfilter->vb2_ctx); + dvb_dmxdev_filter_stop(dmxdevfilter); dvb_dmxdev_filter_reset(dmxdevfilter); @@ -1052,6 +1079,53 @@ static int dvb_demux_do_ioctl(struct file *file, mutex_unlock(&dmxdevfilter->mutex); break; + case DMX_REQBUFS: + if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { + mutex_unlock(&dmxdev->mutex); + return -ERESTARTSYS; + } + ret = dvb_vb2_reqbufs(&dmxdevfilter->vb2_ctx, parg); + mutex_unlock(&dmxdevfilter->mutex); + break; + + case DMX_QUERYBUF: + if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { + mutex_unlock(&dmxdev->mutex); + return -ERESTARTSYS; + } + ret = dvb_vb2_querybuf(&dmxdevfilter->vb2_ctx, parg); + mutex_unlock(&dmxdevfilter->mutex); + break; + + case DMX_EXPBUF: + if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { + mutex_unlock(&dmxdev->mutex); + return -ERESTARTSYS; + } + ret = dvb_vb2_expbuf(&dmxdevfilter->vb2_ctx, parg); + mutex_unlock(&dmxdevfilter->mutex); + break; + + case DMX_QBUF: + if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { + mutex_unlock(&dmxdev->mutex); + return -ERESTARTSYS; + } + ret = dvb_vb2_qbuf(&dmxdevfilter->vb2_ctx, parg); + if (ret == 0 && !dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) + ret = dvb_vb2_stream_on(&dmxdevfilter->vb2_ctx); + mutex_unlock(&dmxdevfilter->mutex); + break; + + case DMX_DQBUF: + if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { + mutex_unlock(&dmxdev->mutex); + return -ERESTARTSYS; + } + ret = dvb_vb2_dqbuf(&dmxdevfilter->vb2_ctx, parg); + mutex_unlock(&dmxdevfilter->mutex); + break; + default: ret = -EINVAL; break; @@ -1073,6 +1147,8 @@ static unsigned int dvb_demux_poll(struct file *file, poll_table *wait) if ((!dmxdevfilter) || dmxdevfilter->dev->exit) return POLLERR; + if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) + return dvb_vb2_poll(&dmxdevfilter->vb2_ctx, file, wait); poll_wait(file, &dmxdevfilter->buffer.queue, wait); @@ -1090,11 +1166,31 @@ static unsigned int dvb_demux_poll(struct file *file, poll_table *wait) return mask; } -static int dvb_demux_release(struct inode *inode, struct file *file) +static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma) { struct dmxdev_filter *dmxdevfilter = file->private_data; struct dmxdev *dmxdev = dmxdevfilter->dev; + int ret; + + if (mutex_lock_interruptible(&dmxdev->mutex)) + return -ERESTARTSYS; + + if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { + mutex_unlock(&dmxdev->mutex); + return -ERESTARTSYS; + } + ret = dvb_vb2_mmap(&dmxdevfilter->vb2_ctx, vma); + mutex_unlock(&dmxdevfilter->mutex); + mutex_unlock(&dmxdev->mutex); + + return ret; +} + +static int dvb_demux_release(struct inode *inode, struct file *file) +{ + struct dmxdev_filter *dmxdevfilter = file->private_data; + struct dmxdev *dmxdev = dmxdevfilter->dev; int ret; ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); @@ -1118,6 +1214,7 @@ static const struct file_operations dvb_demux_fops = { .release = dvb_demux_release, .poll = dvb_demux_poll, .llseek = default_llseek, + .mmap = dvb_demux_mmap, }; static const struct dvb_device dvbdev_demux = { @@ -1146,6 +1243,28 @@ static int dvb_dvr_do_ioctl(struct file *file, ret = dvb_dvr_set_buffer_size(dmxdev, arg); break; + case DMX_REQBUFS: + ret = dvb_vb2_reqbufs(&dmxdev->dvr_vb2_ctx, parg); + break; + + case DMX_QUERYBUF: + ret = dvb_vb2_querybuf(&dmxdev->dvr_vb2_ctx, parg); + break; + + case DMX_EXPBUF: + ret = dvb_vb2_expbuf(&dmxdev->dvr_vb2_ctx, parg); + break; + + case DMX_QBUF: + ret = dvb_vb2_qbuf(&dmxdev->dvr_vb2_ctx, parg); + if (ret == 0 && !dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx)) + ret = dvb_vb2_stream_on(&dmxdev->dvr_vb2_ctx); + break; + + case DMX_DQBUF: + ret = dvb_vb2_dqbuf(&dmxdev->dvr_vb2_ctx, parg); + break; + default: ret = -EINVAL; break; @@ -1170,10 +1289,13 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait) if (dmxdev->exit) return POLLERR; + if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx)) + return dvb_vb2_poll(&dmxdev->dvr_vb2_ctx, file, wait); poll_wait(file, &dmxdev->dvr_buffer.queue, wait); - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { + if (((file->f_flags & O_ACCMODE) == O_RDONLY) || + ((file->f_flags & O_ACCMODE) == O_RDWR)) { if (dmxdev->dvr_buffer.error) mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR); @@ -1185,6 +1307,23 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait) return mask; } +static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct dvb_device *dvbdev = file->private_data; + struct dmxdev *dmxdev = dvbdev->priv; + int ret; + + if (dmxdev->exit) + return -ENODEV; + + if (mutex_lock_interruptible(&dmxdev->mutex)) + return -ERESTARTSYS; + + ret = dvb_vb2_mmap(&dmxdev->dvr_vb2_ctx, vma); + mutex_unlock(&dmxdev->mutex); + return ret; +} + static const struct file_operations dvb_dvr_fops = { .owner = THIS_MODULE, .read = dvb_dvr_read, @@ -1194,6 +1333,7 @@ static const struct file_operations dvb_dvr_fops = { .release = dvb_dvr_release, .poll = dvb_dvr_poll, .llseek = default_llseek, + .mmap = dvb_dvr_mmap, }; static const struct dvb_device dvbdev_dvr = { diff --git a/drivers/media/dvb-core/dmxdev.h b/drivers/media/dvb-core/dmxdev.h index a89d552620a7..a77064d6e2c4 100644 --- a/drivers/media/dvb-core/dmxdev.h +++ b/drivers/media/dvb-core/dmxdev.h @@ -35,6 +35,7 @@ #include "dvbdev.h" #include "demux.h" #include "dvb_ringbuffer.h" +#include "dvb_vb2.h" /** * enum dmxdev_type - type of demux filter type. @@ -140,6 +141,7 @@ struct dmxdev_filter { enum dmxdev_state state; struct dmxdev *dev; struct dvb_ringbuffer buffer; + struct dvb_vb2_ctx vb2_ctx; struct mutex mutex; @@ -183,6 +185,8 @@ struct dmxdev { struct dvb_ringbuffer dvr_buffer; #define DVR_BUFFER_SIZE (10*188*1024) + struct dvb_vb2_ctx dvr_vb2_ctx; + struct mutex mutex; spinlock_t lock; }; diff --git a/drivers/media/dvb-core/dvb_vb2.c b/drivers/media/dvb-core/dvb_vb2.c new file mode 100644 index 000000000000..34193a4acc47 --- /dev/null +++ b/drivers/media/dvb-core/dvb_vb2.c @@ -0,0 +1,423 @@ +/* + * dvb-vb2.c - dvb-vb2 + * + * Copyright (C) 2015 Samsung Electronics + * + * Author: jh1009.sung@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include "dvbdev.h" +#include "dvb_vb2.h" + +static int vb2_debug; +module_param(vb2_debug, int, 0644); + +#define dprintk(level, fmt, arg...) \ + do { \ + if (vb2_debug >= level) \ + pr_info("vb2: %s: " fmt, __func__, ## arg); \ + } while (0) + +static int _queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, unsigned int *nplanes, + unsigned int sizes[], struct device *alloc_devs[]) +{ + struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq); + + *nbuffers = ctx->buf_cnt; + *nplanes = 1; + sizes[0] = ctx->buf_siz; + + /* + * videobuf2-vmalloc allocator is context-less so no need to set + * alloc_ctxs array. + */ + + dprintk(3, "[%s] count=%d, size=%d\n", ctx->name, + *nbuffers, sizes[0]); + + return 0; +} + +static int _buffer_prepare(struct vb2_buffer *vb) +{ + struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + unsigned long size = ctx->buf_siz; + + if (vb2_plane_size(vb, 0) < size) { + dprintk(1, "[%s] data will not fit into plane (%lu < %lu)\n", + ctx->name, vb2_plane_size(vb, 0), size); + return -EINVAL; + } + + vb2_set_plane_payload(vb, 0, size); + dprintk(3, "[%s]\n", ctx->name); + + return 0; +} + +static void _buffer_queue(struct vb2_buffer *vb) +{ + struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct dvb_buffer *buf = container_of(vb, struct dvb_buffer, vb); + unsigned long flags = 0; + + spin_lock_irqsave(&ctx->slock, flags); + list_add_tail(&buf->list, &ctx->dvb_q); + spin_unlock_irqrestore(&ctx->slock, flags); + + dprintk(3, "[%s]\n", ctx->name); +} + +static int _start_streaming(struct vb2_queue *vq, unsigned int count) +{ + struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq); + + dprintk(3, "[%s] count=%d\n", ctx->name, count); + return 0; +} + +static void _stop_streaming(struct vb2_queue *vq) +{ + struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq); + + dprintk(3, "[%s]\n", ctx->name); +} + +static void _dmxdev_lock(struct vb2_queue *vq) +{ + struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq); + + mutex_lock(&ctx->mutex); + dprintk(3, "[%s]\n", ctx->name); +} + +static void _dmxdev_unlock(struct vb2_queue *vq) +{ + struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq); + + if (mutex_is_locked(&ctx->mutex)) + mutex_unlock(&ctx->mutex); + dprintk(3, "[%s]\n", ctx->name); +} + +static const struct vb2_ops dvb_vb2_qops = { + .queue_setup = _queue_setup, + .buf_prepare = _buffer_prepare, + .buf_queue = _buffer_queue, + .start_streaming = _start_streaming, + .stop_streaming = _stop_streaming, + .wait_prepare = _dmxdev_unlock, + .wait_finish = _dmxdev_lock, +}; + +static void _fill_dmx_buffer(struct vb2_buffer *vb, void *pb) +{ + struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + struct dmx_buffer *b = pb; + + b->index = vb->index; + b->length = vb->planes[0].length; + b->bytesused = vb->planes[0].bytesused; + b->offset = vb->planes[0].m.offset; + memset(b->reserved, 0, sizeof(b->reserved)); + dprintk(3, "[%s]\n", ctx->name); +} + +static int _fill_vb2_buffer(struct vb2_buffer *vb, + const void *pb, struct vb2_plane *planes) +{ + struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); + + planes[0].bytesused = 0; + dprintk(3, "[%s]\n", ctx->name); + + return 0; +} + +static const struct vb2_buf_ops dvb_vb2_buf_ops = { + .fill_user_buffer = _fill_dmx_buffer, + .fill_vb2_buffer = _fill_vb2_buffer, +}; + +/* + * Videobuf operations + */ +int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int nonblocking) +{ + struct vb2_queue *q = &ctx->vb_q; + int ret; + + memset(ctx, 0, sizeof(struct dvb_vb2_ctx)); + q->type = DVB_BUF_TYPE_CAPTURE; + /**capture type*/ + q->is_output = 0; + /**only mmap is supported currently*/ + q->io_modes = VB2_MMAP; + q->drv_priv = ctx; + q->buf_struct_size = sizeof(struct dvb_buffer); + q->min_buffers_needed = 1; + q->ops = &dvb_vb2_qops; + q->mem_ops = &vb2_vmalloc_memops; + q->buf_ops = &dvb_vb2_buf_ops; + q->num_buffers = 0; + ret = vb2_core_queue_init(q); + if (ret) { + ctx->state = DVB_VB2_STATE_NONE; + dprintk(1, "[%s] errno=%d\n", ctx->name, ret); + return ret; + } + + mutex_init(&ctx->mutex); + spin_lock_init(&ctx->slock); + INIT_LIST_HEAD(&ctx->dvb_q); + + strncpy(ctx->name, name, DVB_VB2_NAME_MAX); + ctx->nonblocking = nonblocking; + ctx->state = DVB_VB2_STATE_INIT; + + dprintk(3, "[%s]\n", ctx->name); + + return 0; +} + +int dvb_vb2_release(struct dvb_vb2_ctx *ctx) +{ + struct vb2_queue *q = (struct vb2_queue *)&ctx->vb_q; + + if (ctx->state & DVB_VB2_STATE_INIT) + vb2_core_queue_release(q); + + ctx->state = DVB_VB2_STATE_NONE; + dprintk(3, "[%s]\n", ctx->name); + + return 0; +} + +int dvb_vb2_stream_on(struct dvb_vb2_ctx *ctx) +{ + struct vb2_queue *q = &ctx->vb_q; + int ret; + + ret = vb2_core_streamon(q, q->type); + if (ret) { + ctx->state = DVB_VB2_STATE_NONE; + dprintk(1, "[%s] errno=%d\n", ctx->name, ret); + return ret; + } + ctx->state |= DVB_VB2_STATE_STREAMON; + dprintk(3, "[%s]\n", ctx->name); + + return 0; +} + +int dvb_vb2_stream_off(struct dvb_vb2_ctx *ctx) +{ + struct vb2_queue *q = (struct vb2_queue *)&ctx->vb_q; + int ret; + unsigned long flags = 0; + + ctx->state &= ~DVB_VB2_STATE_STREAMON; + spin_lock_irqsave(&ctx->slock, flags); + while (!list_empty(&ctx->dvb_q)) { + struct dvb_buffer *buf; + + buf = list_entry(ctx->dvb_q.next, + struct dvb_buffer, list); + list_del(&buf->list); + spin_unlock_irqrestore(&ctx->slock, flags); + vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); + spin_lock_irqsave(&ctx->slock, flags); + } + spin_unlock_irqrestore(&ctx->slock, flags); + ret = vb2_core_streamoff(q, q->type); + if (ret) { + ctx->state = DVB_VB2_STATE_NONE; + dprintk(1, "[%s] errno=%d\n", ctx->name, ret); + return ret; + } + dprintk(3, "[%s]\n", ctx->name); + + return 0; +} + +int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx) +{ + return (ctx->state & DVB_VB2_STATE_STREAMON); +} + +int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, + const unsigned char *src, int len) +{ + unsigned long flags = 0; + void *vbuf = NULL; + int todo = len; + unsigned char *psrc = (unsigned char *)src; + int ll = 0; + + dprintk(3, "[%s] %d bytes are rcvd\n", ctx->name, len); + if (!src) { + dprintk(3, "[%s]:NULL pointer src\n", ctx->name); + /**normal case: This func is called twice from demux driver + * once with valid src pointer, second time with NULL pointer + */ + return 0; + } + while (todo) { + if (!ctx->buf) { + spin_lock_irqsave(&ctx->slock, flags); + if (list_empty(&ctx->dvb_q)) { + spin_unlock_irqrestore(&ctx->slock, flags); + dprintk(3, "[%s] Buffer overflow!!!\n", + ctx->name); + break; + } + + ctx->buf = list_entry(ctx->dvb_q.next, + struct dvb_buffer, list); + list_del(&ctx->buf->list); + spin_unlock_irqrestore(&ctx->slock, flags); + ctx->remain = vb2_plane_size(&ctx->buf->vb, 0); + ctx->offset = 0; + } + + if (!dvb_vb2_is_streaming(ctx)) { + vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_ERROR); + ctx->buf = NULL; + break; + } + + /* Fill buffer */ + ll = min(todo, ctx->remain); + vbuf = vb2_plane_vaddr(&ctx->buf->vb, 0); + memcpy(vbuf + ctx->offset, psrc, ll); + todo -= ll; + psrc += ll; + + ctx->remain -= ll; + ctx->offset += ll; + + if (ctx->remain == 0) { + vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_DONE); + ctx->buf = NULL; + } + } + + if (ctx->nonblocking && ctx->buf) { + vb2_set_plane_payload(&ctx->buf->vb, 0, ll); + vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_DONE); + ctx->buf = NULL; + } + + if (todo) + dprintk(1, "[%s] %d bytes are dropped.\n", ctx->name, todo); + else + dprintk(3, "[%s]\n", ctx->name); + + dprintk(3, "[%s] %d bytes are copied\n", ctx->name, len - todo); + return (len - todo); +} + +int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req) +{ + int ret; + + ctx->buf_siz = req->size; + ctx->buf_cnt = req->count; + ret = vb2_core_reqbufs(&ctx->vb_q, VB2_MEMORY_MMAP, &req->count); + if (ret) { + ctx->state = DVB_VB2_STATE_NONE; + dprintk(1, "[%s] count=%d size=%d errno=%d\n", ctx->name, + ctx->buf_cnt, ctx->buf_siz, ret); + return ret; + } + ctx->state |= DVB_VB2_STATE_REQBUFS; + dprintk(3, "[%s] count=%d size=%d\n", ctx->name, + ctx->buf_cnt, ctx->buf_siz); + + return 0; +} + +int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) +{ + vb2_core_querybuf(&ctx->vb_q, b->index, b); + dprintk(3, "[%s] index=%d\n", ctx->name, b->index); + return 0; +} + +int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp) +{ + struct vb2_queue *q = &ctx->vb_q; + int ret; + + ret = vb2_core_expbuf(&ctx->vb_q, &exp->fd, q->type, exp->index, + 0, exp->flags); + if (ret) { + dprintk(1, "[%s] index=%d errno=%d\n", ctx->name, + exp->index, ret); + return ret; + } + dprintk(3, "[%s] index=%d fd=%d\n", ctx->name, exp->index, exp->fd); + + return 0; +} + +int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) +{ + int ret; + + ret = vb2_core_qbuf(&ctx->vb_q, b->index, b); + if (ret) { + dprintk(1, "[%s] index=%d errno=%d\n", ctx->name, + b->index, ret); + return ret; + } + dprintk(5, "[%s] index=%d\n", ctx->name, b->index); + + return 0; +} + +int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) +{ + int ret; + + ret = vb2_core_dqbuf(&ctx->vb_q, &b->index, b, ctx->nonblocking); + if (ret) { + dprintk(1, "[%s] errno=%d\n", ctx->name, ret); + return ret; + } + dprintk(5, "[%s] index=%d\n", ctx->name, b->index); + + return 0; +} + +int dvb_vb2_mmap(struct dvb_vb2_ctx *ctx, struct vm_area_struct *vma) +{ + int ret; + + ret = vb2_mmap(&ctx->vb_q, vma); + if (ret) { + dprintk(1, "[%s] errno=%d\n", ctx->name, ret); + return ret; + } + dprintk(3, "[%s] ret=%d\n", ctx->name, ret); + + return 0; +} + +unsigned int dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file, + poll_table *wait) +{ + dprintk(3, "[%s]\n", ctx->name); + return vb2_core_poll(&ctx->vb_q, file, wait); +} + diff --git a/drivers/media/dvb-core/dvb_vb2.h b/drivers/media/dvb-core/dvb_vb2.h new file mode 100644 index 000000000000..d68653926d91 --- /dev/null +++ b/drivers/media/dvb-core/dvb_vb2.h @@ -0,0 +1,72 @@ +/* + * dvb-vb2.h - DVB driver helper framework for streaming I/O + * + * Copyright (C) 2015 Samsung Electronics + * + * Author: jh1009.sung@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation. + */ + +#ifndef _DVB_VB2_H +#define _DVB_VB2_H + +#include +#include +#include +#include +#include +#include + +enum dvb_buf_type { + DVB_BUF_TYPE_CAPTURE = 1, + DVB_BUF_TYPE_OUTPUT = 2, +}; + +#define DVB_VB2_STATE_NONE (0x0) +#define DVB_VB2_STATE_INIT (0x1) +#define DVB_VB2_STATE_REQBUFS (0x2) +#define DVB_VB2_STATE_STREAMON (0x4) + +#define DVB_VB2_NAME_MAX (20) + +struct dvb_buffer { + struct vb2_buffer vb; + struct list_head list; +}; + +struct dvb_vb2_ctx { + struct vb2_queue vb_q; + struct mutex mutex; + spinlock_t slock; + struct list_head dvb_q; + struct dvb_buffer *buf; + int offset; + int remain; + int state; + int buf_siz; + int buf_cnt; + int nonblocking; + char name[DVB_VB2_NAME_MAX + 1]; +}; + +int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int non_blocking); +int dvb_vb2_release(struct dvb_vb2_ctx *ctx); +int dvb_vb2_stream_on(struct dvb_vb2_ctx *ctx); +int dvb_vb2_stream_off(struct dvb_vb2_ctx *ctx); +int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx); +int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, + const unsigned char *src, int len); + +int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req); +int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b); +int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp); +int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b); +int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b); +int dvb_vb2_mmap(struct dvb_vb2_ctx *ctx, struct vm_area_struct *vma); +unsigned int dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file, + poll_table *wait); + +#endif /* _DVB_VB2_H */ diff --git a/include/uapi/linux/dvb/dmx.h b/include/uapi/linux/dvb/dmx.h index c10f1324b4ca..e212aa18ad78 100644 --- a/include/uapi/linux/dvb/dmx.h +++ b/include/uapi/linux/dvb/dmx.h @@ -211,6 +211,64 @@ struct dmx_stc { __u64 stc; }; +/** + * struct dmx_buffer - dmx buffer info + * + * @index: id number of the buffer + * @bytesused: number of bytes occupied by data in the buffer (payload); + * @offset: for buffers with memory == DMX_MEMORY_MMAP; + * offset from the start of the device memory for this plane, + * (or a "cookie" that should be passed to mmap() as offset) + * @length: size in bytes of the buffer + * + * Contains data exchanged by application and driver using one of the streaming + * I/O methods. + */ +struct dmx_buffer { + __u32 index; + __u32 bytesused; + __u32 offset; + __u32 length; + __u32 reserved[4]; +}; + +/** + * struct dmx_requestbuffers - request dmx buffer information + * + * @count: number of requested buffers, + * @size: size in bytes of the requested buffer + * + * Contains data used for requesting a dmx buffer. + * All reserved fields must be set to zero. + */ +struct dmx_requestbuffers { + __u32 count; + __u32 size; + __u32 reserved[2]; +}; + +/** + * struct dmx_exportbuffer - export of dmx buffer as DMABUF file descriptor + * + * @index: id number of the buffer + * @flags: flags for newly created file, currently only O_CLOEXEC is + * supported, refer to manual of open syscall for more details + * @fd: file descriptor associated with DMABUF (set by driver) + * + * Contains data used for exporting a dmx buffer as DMABUF file descriptor. + * The buffer is identified by a 'cookie' returned by DMX_QUERYBUF + * (identical to the cookie used to mmap() the buffer to userspace). All + * reserved fields must be set to zero. The field reserved0 is expected to + * become a structure 'type' allowing an alternative layout of the structure + * content. Therefore this field should not be used for any other extensions. + */ +struct dmx_exportbuffer { + __u32 index; + __u32 flags; + __s32 fd; + __u32 reserved[5]; +}; + #define DMX_START _IO('o', 41) #define DMX_STOP _IO('o', 42) #define DMX_SET_FILTER _IOW('o', 43, struct dmx_sct_filter_params) @@ -231,4 +289,10 @@ typedef struct dmx_filter dmx_filter_t; #endif -#endif /* _UAPI_DVBDMX_H_ */ +#define DMX_REQBUFS _IOWR('o', 60, struct dmx_requestbuffers) +#define DMX_QUERYBUF _IOWR('o', 61, struct dmx_buffer) +#define DMX_EXPBUF _IOWR('o', 62, struct dmx_exportbuffer) +#define DMX_QBUF _IOWR('o', 63, struct dmx_buffer) +#define DMX_DQBUF _IOWR('o', 64, struct dmx_buffer) + +#endif /* _DVBDMX_H_ */ -- cgit v1.2.3-59-g8ed1b From a114a585be4f3173fe454921a0918fb7e71633b0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 21 Dec 2017 10:57:13 -0500 Subject: media: dvb-core: get rid of mmap reserved field The "reserved" field was a way, used at V4L2 API, to add new data to existing structs without breaking userspace. However, there are now clever ways of doing that, without needing to add an uneeded overhead. So, get rid of them. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/dvb/dmx-expbuf.rst | 2 -- Documentation/media/uapi/dvb/dmx-qbuf.rst | 2 -- Documentation/media/uapi/dvb/dmx-querybuf.rst | 2 -- Documentation/media/uapi/dvb/dmx-reqbufs.rst | 2 -- drivers/media/dvb-core/dvb_vb2.c | 1 - include/uapi/linux/dvb/dmx.h | 3 --- 6 files changed, 12 deletions(-) (limited to 'include/uapi/linux') diff --git a/Documentation/media/uapi/dvb/dmx-expbuf.rst b/Documentation/media/uapi/dvb/dmx-expbuf.rst index 51df34c6fb59..2d96cfe891df 100644 --- a/Documentation/media/uapi/dvb/dmx-expbuf.rst +++ b/Documentation/media/uapi/dvb/dmx-expbuf.rst @@ -36,8 +36,6 @@ This ioctl is an extension to the memory mapping I/O method. It can be used to export a buffer as a DMABUF file at any time after buffers have been allocated with the :ref:`DMX_REQBUFS` ioctl. -The ``reserved`` array must be zeroed before calling it. - To export a buffer, applications fill struct :c:type:`dmx_exportbuffer`. Applications must set the ``index`` field. Valid index numbers range from zero to the number of buffers allocated with :ref:`DMX_REQBUFS` diff --git a/Documentation/media/uapi/dvb/dmx-qbuf.rst b/Documentation/media/uapi/dvb/dmx-qbuf.rst index b20b8153d48d..b48c4931658e 100644 --- a/Documentation/media/uapi/dvb/dmx-qbuf.rst +++ b/Documentation/media/uapi/dvb/dmx-qbuf.rst @@ -45,8 +45,6 @@ numbers range from zero to the number of buffers allocated with one. The contents of the struct :c:type:`dmx_buffer` returned by a :ref:`DMX_QUERYBUF` ioctl will do as well. -The and ``reserved`` field must be set to 0. - When ``DMX_QBUF`` is called with a pointer to this structure, it locks the memory pages of the buffer in physical memory, so they cannot be swapped out to disk. Buffers remain locked until dequeued, until the diff --git a/Documentation/media/uapi/dvb/dmx-querybuf.rst b/Documentation/media/uapi/dvb/dmx-querybuf.rst index 46a50f191b10..89481e24bb86 100644 --- a/Documentation/media/uapi/dvb/dmx-querybuf.rst +++ b/Documentation/media/uapi/dvb/dmx-querybuf.rst @@ -36,8 +36,6 @@ This ioctl is part of the mmap streaming I/O method. It can be used to query the status of a buffer at any time after buffers have been allocated with the :ref:`DMX_REQBUFS` ioctl. -The ``reserved`` array must be zeroed before calling it. - Applications set the ``index`` field. Valid index numbers range from zero to the number of buffers allocated with :ref:`DMX_REQBUFS` (struct :c:type:`dvb_requestbuffers` ``count``) minus one. diff --git a/Documentation/media/uapi/dvb/dmx-reqbufs.rst b/Documentation/media/uapi/dvb/dmx-reqbufs.rst index 0749623d9d83..14b80d60bf35 100644 --- a/Documentation/media/uapi/dvb/dmx-reqbufs.rst +++ b/Documentation/media/uapi/dvb/dmx-reqbufs.rst @@ -42,8 +42,6 @@ allocated by applications through a device driver, and this ioctl only configures the driver into DMABUF I/O mode without performing any direct allocation. -The ``reserved`` array must be zeroed before calling it. - To allocate device buffers applications initialize all fields of the struct :c:type:`dmx_requestbuffers` structure. They set the ``count`` field to the desired number of buffers, and ``size`` to the size of each diff --git a/drivers/media/dvb-core/dvb_vb2.c b/drivers/media/dvb-core/dvb_vb2.c index fa1dcde74e81..68c59a497925 100644 --- a/drivers/media/dvb-core/dvb_vb2.c +++ b/drivers/media/dvb-core/dvb_vb2.c @@ -143,7 +143,6 @@ static void _fill_dmx_buffer(struct vb2_buffer *vb, void *pb) b->length = vb->planes[0].length; b->bytesused = vb->planes[0].bytesused; b->offset = vb->planes[0].m.offset; - memset(b->reserved, 0, sizeof(b->reserved)); dprintk(3, "[%s]\n", ctx->name); } diff --git a/include/uapi/linux/dvb/dmx.h b/include/uapi/linux/dvb/dmx.h index e212aa18ad78..5f3c5a918f00 100644 --- a/include/uapi/linux/dvb/dmx.h +++ b/include/uapi/linux/dvb/dmx.h @@ -229,7 +229,6 @@ struct dmx_buffer { __u32 bytesused; __u32 offset; __u32 length; - __u32 reserved[4]; }; /** @@ -244,7 +243,6 @@ struct dmx_buffer { struct dmx_requestbuffers { __u32 count; __u32 size; - __u32 reserved[2]; }; /** @@ -266,7 +264,6 @@ struct dmx_exportbuffer { __u32 index; __u32 flags; __s32 fd; - __u32 reserved[5]; }; #define DMX_START _IO('o', 41) -- cgit v1.2.3-59-g8ed1b From e8391b7654a9d21323fe0226770741c0e42c53f4 Mon Sep 17 00:00:00 2001 From: Yong Zhi Date: Wed, 8 Nov 2017 19:30:36 -0500 Subject: media: videodev2.h, v4l2-ioctl: add IPU3 raw10 color format Add IPU3 specific formats: V4L2_PIX_FMT_IPU3_SBGGR10 V4L2_PIX_FMT_IPU3_SGBRG10 V4L2_PIX_FMT_IPU3_SGRBG10 V4L2_PIX_FMT_IPU3_SRGGB10 Signed-off-by: Yong Zhi Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-ioctl.c | 4 ++++ include/uapi/linux/videodev2.h | 6 ++++++ 2 files changed, 10 insertions(+) (limited to 'include/uapi/linux') diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 79614992ee21..3937945b12dc 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1202,6 +1202,10 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_PIX_FMT_SGBRG10P: descr = "10-bit Bayer GBGB/RGRG Packed"; break; case V4L2_PIX_FMT_SGRBG10P: descr = "10-bit Bayer GRGR/BGBG Packed"; break; case V4L2_PIX_FMT_SRGGB10P: descr = "10-bit Bayer RGRG/GBGB Packed"; break; + case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break; + case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break; + case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break; + case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break; case V4L2_PIX_FMT_SBGGR10ALAW8: descr = "8-bit Bayer BGBG/GRGR (A-law)"; break; case V4L2_PIX_FMT_SGBRG10ALAW8: descr = "8-bit Bayer GBGB/RGRG (A-law)"; break; case V4L2_PIX_FMT_SGRBG10ALAW8: descr = "8-bit Bayer GRGR/BGBG (A-law)"; break; diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 1c095b5a99c5..b26160e0b483 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -669,6 +669,12 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1') /* Mediatek compressed block mode */ #define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */ +/* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */ +#define V4L2_PIX_FMT_IPU3_SBGGR10 v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */ +#define V4L2_PIX_FMT_IPU3_SGBRG10 v4l2_fourcc('i', 'p', '3', 'g') /* IPU3 packed 10-bit GBRG bayer */ +#define V4L2_PIX_FMT_IPU3_SGRBG10 v4l2_fourcc('i', 'p', '3', 'G') /* IPU3 packed 10-bit GRBG bayer */ +#define V4L2_PIX_FMT_IPU3_SRGGB10 v4l2_fourcc('i', 'p', '3', 'r') /* IPU3 packed 10-bit RGGB bayer */ + /* SDR formats - used only for Software Defined Radio devices */ #define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */ #define V4L2_SDR_FMT_CU16LE v4l2_fourcc('C', 'U', '1', '6') /* IQ u16le */ -- cgit v1.2.3-59-g8ed1b From 675fc275a3a2d905535207237402c6d8dcb5fa4b Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Wed, 27 Dec 2017 18:39:09 -0800 Subject: bpf: offload: report device information for offloaded programs Report to the user ifindex and namespace information of offloaded programs. If device has disappeared return -ENODEV. Specify the namespace using dev/inode combination. CC: Eric W. Biederman Signed-off-by: Jakub Kicinski Signed-off-by: Daniel Borkmann --- include/linux/bpf.h | 2 ++ include/uapi/linux/bpf.h | 3 +++ kernel/bpf/offload.c | 59 ++++++++++++++++++++++++++++++++++++++++++ kernel/bpf/syscall.c | 6 +++++ tools/include/uapi/linux/bpf.h | 3 +++ 5 files changed, 73 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 9a916ab34299..7810ae57b357 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -531,6 +531,8 @@ static inline struct bpf_prog *bpf_prog_get_type(u32 ufd, int bpf_prog_offload_compile(struct bpf_prog *prog); void bpf_prog_offload_destroy(struct bpf_prog *prog); +int bpf_prog_offload_info_fill(struct bpf_prog_info *info, + struct bpf_prog *prog); #if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL) int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr); diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 69eabfcb9bdb..f2f8b36e2ad4 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -921,6 +921,9 @@ struct bpf_prog_info { __u32 nr_map_ids; __aligned_u64 map_ids; char name[BPF_OBJ_NAME_LEN]; + __u32 ifindex; + __u64 netns_dev; + __u64 netns_ino; } __attribute__((aligned(8))); struct bpf_map_info { diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c index e4f1668a021c..040d4e0edf3f 100644 --- a/kernel/bpf/offload.c +++ b/kernel/bpf/offload.c @@ -16,9 +16,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -176,6 +178,63 @@ int bpf_prog_offload_compile(struct bpf_prog *prog) return bpf_prog_offload_translate(prog); } +struct ns_get_path_bpf_prog_args { + struct bpf_prog *prog; + struct bpf_prog_info *info; +}; + +static struct ns_common *bpf_prog_offload_info_fill_ns(void *private_data) +{ + struct ns_get_path_bpf_prog_args *args = private_data; + struct bpf_prog_aux *aux = args->prog->aux; + struct ns_common *ns; + struct net *net; + + rtnl_lock(); + down_read(&bpf_devs_lock); + + if (aux->offload) { + args->info->ifindex = aux->offload->netdev->ifindex; + net = dev_net(aux->offload->netdev); + get_net(net); + ns = &net->ns; + } else { + args->info->ifindex = 0; + ns = NULL; + } + + up_read(&bpf_devs_lock); + rtnl_unlock(); + + return ns; +} + +int bpf_prog_offload_info_fill(struct bpf_prog_info *info, + struct bpf_prog *prog) +{ + struct ns_get_path_bpf_prog_args args = { + .prog = prog, + .info = info, + }; + struct inode *ns_inode; + struct path ns_path; + void *res; + + res = ns_get_path_cb(&ns_path, bpf_prog_offload_info_fill_ns, &args); + if (IS_ERR(res)) { + if (!info->ifindex) + return -ENODEV; + return PTR_ERR(res); + } + + ns_inode = ns_path.dentry->d_inode; + info->netns_dev = new_encode_dev(ns_inode->i_sb->s_dev); + info->netns_ino = ns_inode->i_ino; + path_put(&ns_path); + + return 0; +} + const struct bpf_prog_ops bpf_offload_prog_ops = { }; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index e02dafa6f402..ebf0fb23e237 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1707,6 +1707,12 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, return -EFAULT; } + if (bpf_prog_is_dev_bound(prog->aux)) { + err = bpf_prog_offload_info_fill(&info, prog); + if (err) + return err; + } + done: if (copy_to_user(uinfo, &info, info_len) || put_user(info_len, &uattr->info.info_len)) diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index db1b0923a308..4e8c60acfa32 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -921,6 +921,9 @@ struct bpf_prog_info { __u32 nr_map_ids; __aligned_u64 map_ids; char name[BPF_OBJ_NAME_LEN]; + __u32 ifindex; + __u64 netns_dev; + __u64 netns_ino; } __attribute__((aligned(8))); struct bpf_map_info { -- cgit v1.2.3-59-g8ed1b From bbb6189df4077cde8592cd2f804bb1122067dd32 Mon Sep 17 00:00:00 2001 From: Kristian Evensen Date: Wed, 27 Dec 2017 18:27:58 +0100 Subject: inet_diag: Add equal-operator for ports inet_diag currently provides less/greater than or equal operators for comparing ports when filtering sockets. An equal comparison can be performed by combining the two existing operators, or a user can for example request a port range and then do the final filtering in userspace. However, these approaches both have drawbacks. Implementing equal using LE/GE causes the size and complexity of a filter to grow quickly as the number of ports increase, while it on busy machines would be great if the kernel only returns information about relevant sockets. This patch introduces source and destination port equal operators. INET_DIAG_BC_S_EQ is used to match a source port, INET_DIAG_BC_D_EQ a destination port, and usage is the same as for the existing port operators. I.e., the port to match is stored in the no-member of the next inet_diag_bc_op-struct in the filter. Signed-off-by: Kristian Evensen Signed-off-by: David S. Miller --- include/uapi/linux/inet_diag.h | 2 ++ net/ipv4/inet_diag.c | 8 ++++++++ 2 files changed, 10 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h index 817d807e9481..14565d703291 100644 --- a/include/uapi/linux/inet_diag.h +++ b/include/uapi/linux/inet_diag.h @@ -92,6 +92,8 @@ enum { INET_DIAG_BC_D_COND, INET_DIAG_BC_DEV_COND, /* u32 ifindex */ INET_DIAG_BC_MARK_COND, + INET_DIAG_BC_S_EQ, + INET_DIAG_BC_D_EQ, }; struct inet_diag_hostcond { diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index c9c35b61a027..a383f299ce24 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -564,12 +564,18 @@ static int inet_diag_bc_run(const struct nlattr *_bc, case INET_DIAG_BC_JMP: yes = 0; break; + case INET_DIAG_BC_S_EQ: + yes = entry->sport == op[1].no; + break; case INET_DIAG_BC_S_GE: yes = entry->sport >= op[1].no; break; case INET_DIAG_BC_S_LE: yes = entry->sport <= op[1].no; break; + case INET_DIAG_BC_D_EQ: + yes = entry->dport == op[1].no; + break; case INET_DIAG_BC_D_GE: yes = entry->dport >= op[1].no; break; @@ -802,8 +808,10 @@ static int inet_diag_bc_audit(const struct nlattr *attr, if (!valid_devcond(bc, len, &min_len)) return -EINVAL; break; + case INET_DIAG_BC_S_EQ: case INET_DIAG_BC_S_GE: case INET_DIAG_BC_S_LE: + case INET_DIAG_BC_D_EQ: case INET_DIAG_BC_D_GE: case INET_DIAG_BC_D_LE: if (!valid_port_comparison(bc, len, &min_len)) -- cgit v1.2.3-59-g8ed1b From 563a01e1012dddbe120d1e1e1c466ea0639a098b Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 8 Nov 2017 11:00:12 -0500 Subject: media: v4l: Add a UVC Metadata format Add a pixel format, used by the UVC driver to stream metadata. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/meta-formats.rst | 1 + Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst | 51 ++++++++++++++++++++++++ drivers/media/v4l2-core/v4l2-ioctl.c | 1 + include/uapi/linux/videodev2.h | 1 + 4 files changed, 54 insertions(+) create mode 100644 Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst (limited to 'include/uapi/linux') diff --git a/Documentation/media/uapi/v4l/meta-formats.rst b/Documentation/media/uapi/v4l/meta-formats.rst index 01e24e3df571..0c4e1ecf5879 100644 --- a/Documentation/media/uapi/v4l/meta-formats.rst +++ b/Documentation/media/uapi/v4l/meta-formats.rst @@ -12,5 +12,6 @@ These formats are used for the :ref:`metadata` interface only. .. toctree:: :maxdepth: 1 + pixfmt-meta-uvc pixfmt-meta-vsp1-hgo pixfmt-meta-vsp1-hgt diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst b/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst new file mode 100644 index 000000000000..b5165dc090c2 --- /dev/null +++ b/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst @@ -0,0 +1,51 @@ +.. -*- coding: utf-8; mode: rst -*- + +.. _v4l2-meta-fmt-uvc: + +******************************* +V4L2_META_FMT_UVC ('UVCH') +******************************* + +UVC Payload Header Data + + +Description +=========== + +This format describes standard UVC metadata, extracted from UVC packet headers +and provided by the UVC driver through metadata video nodes. That data includes +exact copies of the standard part of UVC Payload Header contents and auxiliary +timing information, required for precise interpretation of timestamps, contained +in those headers. See section "2.4.3.3 Video and Still Image Payload Headers" of +the "UVC 1.5 Class specification" for details. + +Each UVC payload header can be between 2 and 12 bytes large. Buffers can +contain multiple headers, if multiple such headers have been transmitted by the +camera for the respective frame. However, the driver may drop headers when the +buffer is full, when they contain no useful information (e.g. those without the +SCR field or with that field identical to the previous header), or generally to +perform rate limiting when the device sends a large number of headers. + +Each individual block contains the following fields: + +.. flat-table:: UVC Metadata Block + :widths: 1 4 + :header-rows: 1 + :stub-columns: 0 + + * - Field + - Description + * - __u64 ts; + - system timestamp in host byte order, measured by the driver upon + reception of the payload + * - __u16 sof; + - USB Frame Number in host byte order, also obtained by the driver as + close as possible to the above timestamp to enable correlation between + them + * - :cspan:`1` *The rest is an exact copy of the UVC payload header:* + * - __u8 length; + - length of the rest of the block, including this field + * - __u8 flags; + - Flags, indicating presence of other standard UVC fields + * - __u8 buf[]; + - The rest of the header, possibly including UVC PTS and SCR fields diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 3937945b12dc..1d7c2ea78c3e 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -1250,6 +1250,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) case V4L2_TCH_FMT_TU08: descr = "8-bit unsigned touch data"; break; case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break; case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break; + case V4L2_META_FMT_UVC: descr = "UVC payload header metadata"; break; default: /* Compressed formats */ diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index b26160e0b483..faa97fda588a 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -694,6 +694,7 @@ struct v4l2_pix_format { /* Meta-data formats */ #define V4L2_META_FMT_VSP1_HGO v4l2_fourcc('V', 'S', 'P', 'H') /* R-Car VSP1 1-D Histogram */ #define V4L2_META_FMT_VSP1_HGT v4l2_fourcc('V', 'S', 'P', 'T') /* R-Car VSP1 2-D Histogram */ +#define V4L2_META_FMT_UVC v4l2_fourcc('U', 'V', 'C', 'H') /* UVC Payload Header metadata */ /* priv field value to indicates that subsequent fields are valid. */ #define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe -- cgit v1.2.3-59-g8ed1b From 088ead25524583e2200aa99111bea2f66a86545a Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Wed, 6 Dec 2017 10:15:40 -0500 Subject: media: uvcvideo: Add a metadata device node Some UVC video cameras contain metadata in their payload headers. This patch extracts that data, adding more clock synchronisation information, on both bulk and isochronous endpoints and makes it available to the user space on a separate video node, using the V4L2_CAP_META_CAPTURE capability and the V4L2_BUF_TYPE_META_CAPTURE buffer queue type. By default, only the V4L2_META_FMT_UVC pixel format is available from those nodes. However, cameras can be added to the device ID table to additionally specify their own metadata format, in which case that format will also become available from the metadata node. [Use put_unaligned instead of __put_unaligned_cpu64] [Use put_unaligned for the sof field as well] Signed-off-by: Guennadi Liakhovetski Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/uvc/Makefile | 2 +- drivers/media/usb/uvc/uvc_driver.c | 15 ++- drivers/media/usb/uvc/uvc_isight.c | 2 +- drivers/media/usb/uvc/uvc_metadata.c | 179 +++++++++++++++++++++++++++++++++++ drivers/media/usb/uvc/uvc_queue.c | 44 +++++++-- drivers/media/usb/uvc/uvc_video.c | 134 ++++++++++++++++++++++++-- drivers/media/usb/uvc/uvcvideo.h | 16 +++- include/uapi/linux/uvcvideo.h | 26 +++++ 8 files changed, 396 insertions(+), 22 deletions(-) create mode 100644 drivers/media/usb/uvc/uvc_metadata.c (limited to 'include/uapi/linux') diff --git a/drivers/media/usb/uvc/Makefile b/drivers/media/usb/uvc/Makefile index a4fe5b5d533f..4f9eee4f81ab 100644 --- a/drivers/media/usb/uvc/Makefile +++ b/drivers/media/usb/uvc/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 uvcvideo-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \ - uvc_status.o uvc_isight.o uvc_debugfs.o + uvc_status.o uvc_isight.o uvc_debugfs.o uvc_metadata.o ifeq ($(CONFIG_MEDIA_CONTROLLER),y) uvcvideo-objs += uvc_entity.o endif diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 1509bbc77a2f..2886c100abf2 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1883,6 +1883,7 @@ static void uvc_unregister_video(struct uvc_device *dev) continue; video_unregister_device(&stream->vdev); + video_unregister_device(&stream->meta.vdev); uvc_debugfs_cleanup_stream(stream); } @@ -1930,6 +1931,9 @@ int uvc_register_video_device(struct uvc_device *dev, case V4L2_BUF_TYPE_VIDEO_OUTPUT: vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; break; + case V4L2_BUF_TYPE_META_CAPTURE: + vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING; + break; } strlcpy(vdev->name, dev->name, sizeof vdev->name); @@ -1965,7 +1969,8 @@ static int uvc_register_video(struct uvc_device *dev, } if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE; + stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE + | V4L2_CAP_META_CAPTURE; else stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT; @@ -2003,6 +2008,11 @@ static int uvc_register_terms(struct uvc_device *dev, if (ret < 0) return ret; + /* Register a metadata node, but ignore a possible failure, + * complete registration of video nodes anyway. + */ + uvc_meta_register(stream); + term->vdev = &stream->vdev; } @@ -2037,6 +2047,7 @@ static int uvc_register_chains(struct uvc_device *dev) struct uvc_device_info { u32 quirks; + u32 meta_format; }; static int uvc_probe(struct usb_interface *intf, @@ -2074,6 +2085,8 @@ static int uvc_probe(struct usb_interface *intf, dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; dev->quirks = (uvc_quirks_param == -1) ? quirks : uvc_quirks_param; + if (info) + dev->meta_format = info->meta_format; if (udev->product != NULL) strlcpy(dev->name, udev->product, sizeof dev->name); diff --git a/drivers/media/usb/uvc/uvc_isight.c b/drivers/media/usb/uvc/uvc_isight.c index 8510e7259e76..fb940cfae575 100644 --- a/drivers/media/usb/uvc/uvc_isight.c +++ b/drivers/media/usb/uvc/uvc_isight.c @@ -100,7 +100,7 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf, } void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, - struct uvc_buffer *buf) + struct uvc_buffer *buf, struct uvc_buffer *meta_buf) { int ret, i; diff --git a/drivers/media/usb/uvc/uvc_metadata.c b/drivers/media/usb/uvc/uvc_metadata.c new file mode 100644 index 000000000000..cd1aec19cc5b --- /dev/null +++ b/drivers/media/usb/uvc/uvc_metadata.c @@ -0,0 +1,179 @@ +/* + * uvc_metadata.c -- USB Video Class driver - Metadata handling + * + * Copyright (C) 2016 + * Guennadi Liakhovetski (guennadi.liakhovetski@intel.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "uvcvideo.h" + +/* ----------------------------------------------------------------------------- + * V4L2 ioctls + */ + +static int uvc_meta_v4l2_querycap(struct file *file, void *fh, + struct v4l2_capability *cap) +{ + struct v4l2_fh *vfh = file->private_data; + struct uvc_streaming *stream = video_get_drvdata(vfh->vdev); + struct uvc_video_chain *chain = stream->chain; + + strlcpy(cap->driver, "uvcvideo", sizeof(cap->driver)); + strlcpy(cap->card, vfh->vdev->name, sizeof(cap->card)); + usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info)); + cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING + | chain->caps; + + return 0; +} + +static int uvc_meta_v4l2_get_format(struct file *file, void *fh, + struct v4l2_format *format) +{ + struct v4l2_fh *vfh = file->private_data; + struct uvc_streaming *stream = video_get_drvdata(vfh->vdev); + struct v4l2_meta_format *fmt = &format->fmt.meta; + + if (format->type != vfh->vdev->queue->type) + return -EINVAL; + + memset(fmt, 0, sizeof(*fmt)); + + fmt->dataformat = stream->meta.format; + fmt->buffersize = UVC_METATADA_BUF_SIZE; + + return 0; +} + +static int uvc_meta_v4l2_try_format(struct file *file, void *fh, + struct v4l2_format *format) +{ + struct v4l2_fh *vfh = file->private_data; + struct uvc_streaming *stream = video_get_drvdata(vfh->vdev); + struct uvc_device *dev = stream->dev; + struct v4l2_meta_format *fmt = &format->fmt.meta; + u32 fmeta = fmt->dataformat; + + if (format->type != vfh->vdev->queue->type) + return -EINVAL; + + memset(fmt, 0, sizeof(*fmt)); + + fmt->dataformat = fmeta == dev->meta_format ? fmeta : V4L2_META_FMT_UVC; + fmt->buffersize = UVC_METATADA_BUF_SIZE; + + return 0; +} + +static int uvc_meta_v4l2_set_format(struct file *file, void *fh, + struct v4l2_format *format) +{ + struct v4l2_fh *vfh = file->private_data; + struct uvc_streaming *stream = video_get_drvdata(vfh->vdev); + struct v4l2_meta_format *fmt = &format->fmt.meta; + int ret; + + ret = uvc_meta_v4l2_try_format(file, fh, format); + if (ret < 0) + return ret; + + /* + * We could in principle switch at any time, also during streaming. + * Metadata buffers would still be perfectly parseable, but it's more + * consistent and cleaner to disallow that. + */ + mutex_lock(&stream->mutex); + + if (uvc_queue_allocated(&stream->queue)) + ret = -EBUSY; + else + stream->meta.format = fmt->dataformat; + + mutex_unlock(&stream->mutex); + + return ret; +} + +static int uvc_meta_v4l2_enum_formats(struct file *file, void *fh, + struct v4l2_fmtdesc *fdesc) +{ + struct v4l2_fh *vfh = file->private_data; + struct uvc_streaming *stream = video_get_drvdata(vfh->vdev); + struct uvc_device *dev = stream->dev; + u32 index = fdesc->index; + + if (fdesc->type != vfh->vdev->queue->type || + index > 1U || (index && !dev->meta_format)) + return -EINVAL; + + memset(fdesc, 0, sizeof(*fdesc)); + + fdesc->type = vfh->vdev->queue->type; + fdesc->index = index; + fdesc->pixelformat = index ? dev->meta_format : V4L2_META_FMT_UVC; + + return 0; +} + +static const struct v4l2_ioctl_ops uvc_meta_ioctl_ops = { + .vidioc_querycap = uvc_meta_v4l2_querycap, + .vidioc_g_fmt_meta_cap = uvc_meta_v4l2_get_format, + .vidioc_s_fmt_meta_cap = uvc_meta_v4l2_set_format, + .vidioc_try_fmt_meta_cap = uvc_meta_v4l2_try_format, + .vidioc_enum_fmt_meta_cap = uvc_meta_v4l2_enum_formats, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, +}; + +/* ----------------------------------------------------------------------------- + * V4L2 File Operations + */ + +static const struct v4l2_file_operations uvc_meta_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = video_ioctl2, + .open = v4l2_fh_open, + .release = vb2_fop_release, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, +}; + +int uvc_meta_register(struct uvc_streaming *stream) +{ + struct uvc_device *dev = stream->dev; + struct video_device *vdev = &stream->meta.vdev; + struct uvc_video_queue *queue = &stream->meta.queue; + + stream->meta.format = V4L2_META_FMT_UVC; + + /* + * The video interface queue uses manual locking and thus does not set + * the queue pointer. Set it manually here. + */ + vdev->queue = &queue->queue; + + return uvc_register_video_device(dev, stream, vdev, queue, + V4L2_BUF_TYPE_META_CAPTURE, + &uvc_meta_fops, &uvc_meta_ioctl_ops); +} diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c index c8d78b2f3de4..cd2ea5a23086 100644 --- a/drivers/media/usb/uvc/uvc_queue.c +++ b/drivers/media/usb/uvc/uvc_queue.c @@ -79,8 +79,19 @@ static int uvc_queue_setup(struct vb2_queue *vq, unsigned int sizes[], struct device *alloc_devs[]) { struct uvc_video_queue *queue = vb2_get_drv_priv(vq); - struct uvc_streaming *stream = uvc_queue_to_stream(queue); - unsigned size = stream->ctrl.dwMaxVideoFrameSize; + struct uvc_streaming *stream; + unsigned int size; + + switch (vq->type) { + case V4L2_BUF_TYPE_META_CAPTURE: + size = UVC_METATADA_BUF_SIZE; + break; + + default: + stream = uvc_queue_to_stream(queue); + size = stream->ctrl.dwMaxVideoFrameSize; + break; + } /* * When called with plane sizes, validate them. The driver supports @@ -114,7 +125,7 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb) buf->error = 0; buf->mem = vb2_plane_vaddr(vb, 0); buf->length = vb2_plane_size(vb, 0); - if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (vb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) buf->bytesused = 0; else buf->bytesused = vb2_get_plane_payload(vb, 0); @@ -177,10 +188,10 @@ static int uvc_start_streaming(struct vb2_queue *vq, unsigned int count) static void uvc_stop_streaming(struct vb2_queue *vq) { struct uvc_video_queue *queue = vb2_get_drv_priv(vq); - struct uvc_streaming *stream = uvc_queue_to_stream(queue); unsigned long flags; - uvc_video_enable(stream, 0); + if (vq->type != V4L2_BUF_TYPE_META_CAPTURE) + uvc_video_enable(uvc_queue_to_stream(queue), 0); spin_lock_irqsave(&queue->irqlock, flags); uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR); @@ -198,20 +209,39 @@ static const struct vb2_ops uvc_queue_qops = { .stop_streaming = uvc_stop_streaming, }; +static const struct vb2_ops uvc_meta_queue_qops = { + .queue_setup = uvc_queue_setup, + .buf_prepare = uvc_buffer_prepare, + .buf_queue = uvc_buffer_queue, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, + .stop_streaming = uvc_stop_streaming, +}; + int uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, int drop_corrupted) { int ret; queue->queue.type = type; - queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; + queue->queue.io_modes = VB2_MMAP | VB2_USERPTR; queue->queue.drv_priv = queue; queue->queue.buf_struct_size = sizeof(struct uvc_buffer); - queue->queue.ops = &uvc_queue_qops; queue->queue.mem_ops = &vb2_vmalloc_memops; queue->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC | V4L2_BUF_FLAG_TSTAMP_SRC_SOE; queue->queue.lock = &queue->mutex; + + switch (type) { + case V4L2_BUF_TYPE_META_CAPTURE: + queue->queue.ops = &uvc_meta_queue_qops; + break; + default: + queue->queue.io_modes |= VB2_DMABUF; + queue->queue.ops = &uvc_queue_qops; + break; + } + ret = vb2_queue_init(&queue->queue); if (ret) return ret; diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index 13f459ea239c..5441553f74e1 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -1119,6 +1119,84 @@ static int uvc_video_encode_data(struct uvc_streaming *stream, return nbytes; } +/* ------------------------------------------------------------------------ + * Metadata + */ + +/* + * Additionally to the payload headers we also want to provide the user with USB + * Frame Numbers and system time values. The resulting buffer is thus composed + * of blocks, containing a 64-bit timestamp in nanoseconds, a 16-bit USB Frame + * Number, and a copy of the payload header. + * + * Ideally we want to capture all payload headers for each frame. However, their + * number is unknown and unbound. We thus drop headers that contain no vendor + * data and that either contain no SCR value or an SCR value identical to the + * previous header. + */ +static void uvc_video_decode_meta(struct uvc_streaming *stream, + struct uvc_buffer *meta_buf, + const u8 *mem, unsigned int length) +{ + struct uvc_meta_buf *meta; + size_t len_std = 2; + bool has_pts, has_scr; + unsigned long flags; + unsigned int sof; + ktime_t time; + const u8 *scr; + + if (!meta_buf || length == 2) + return; + + if (meta_buf->length - meta_buf->bytesused < + length + sizeof(meta->ns) + sizeof(meta->sof)) { + meta_buf->error = 1; + return; + } + + has_pts = mem[1] & UVC_STREAM_PTS; + has_scr = mem[1] & UVC_STREAM_SCR; + + if (has_pts) { + len_std += 4; + scr = mem + 6; + } else { + scr = mem + 2; + } + + if (has_scr) + len_std += 6; + + if (stream->meta.format == V4L2_META_FMT_UVC) + length = len_std; + + if (length == len_std && (!has_scr || + !memcmp(scr, stream->clock.last_scr, 6))) + return; + + meta = (struct uvc_meta_buf *)((u8 *)meta_buf->mem + meta_buf->bytesused); + local_irq_save(flags); + time = uvc_video_get_time(); + sof = usb_get_current_frame_number(stream->dev->udev); + local_irq_restore(flags); + put_unaligned(ktime_to_ns(time), &meta->ns); + put_unaligned(sof, &meta->sof); + + if (has_scr) + memcpy(stream->clock.last_scr, scr, 6); + + memcpy(&meta->length, mem, length); + meta_buf->bytesused += length + sizeof(meta->ns) + sizeof(meta->sof); + + uvc_trace(UVC_TRACE_FRAME, + "%s(): t-sys %lluns, SOF %u, len %u, flags 0x%x, PTS %u, STC %u frame SOF %u\n", + __func__, time, meta->sof, meta->length, meta->flags, + has_pts ? *(u32 *)meta->buf : 0, + has_scr ? *(u32 *)scr : 0, + has_scr ? *(u32 *)(scr + 4) & 0x7ff : 0); +} + /* ------------------------------------------------------------------------ * URB handling */ @@ -1137,8 +1215,29 @@ static void uvc_video_validate_buffer(const struct uvc_streaming *stream, /* * Completion handler for video URBs. */ + +static void uvc_video_next_buffers(struct uvc_streaming *stream, + struct uvc_buffer **video_buf, struct uvc_buffer **meta_buf) +{ + if (*meta_buf) { + struct vb2_v4l2_buffer *vb2_meta = &(*meta_buf)->buf; + const struct vb2_v4l2_buffer *vb2_video = &(*video_buf)->buf; + + vb2_meta->sequence = vb2_video->sequence; + vb2_meta->field = vb2_video->field; + vb2_meta->vb2_buf.timestamp = vb2_video->vb2_buf.timestamp; + + (*meta_buf)->state = UVC_BUF_STATE_READY; + if (!(*meta_buf)->error) + (*meta_buf)->error = (*video_buf)->error; + *meta_buf = uvc_queue_next_buffer(&stream->meta.queue, + *meta_buf); + } + *video_buf = uvc_queue_next_buffer(&stream->queue, *video_buf); +} + static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream, - struct uvc_buffer *buf) + struct uvc_buffer *buf, struct uvc_buffer *meta_buf) { u8 *mem; int ret, i; @@ -1160,14 +1259,15 @@ static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream, urb->iso_frame_desc[i].actual_length); if (ret == -EAGAIN) { uvc_video_validate_buffer(stream, buf); - buf = uvc_queue_next_buffer(&stream->queue, - buf); + uvc_video_next_buffers(stream, &buf, &meta_buf); } } while (ret == -EAGAIN); if (ret < 0) continue; + uvc_video_decode_meta(stream, meta_buf, mem, ret); + /* Decode the payload data. */ uvc_video_decode_data(stream, buf, mem + ret, urb->iso_frame_desc[i].actual_length - ret); @@ -1178,13 +1278,13 @@ static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream, if (buf->state == UVC_BUF_STATE_READY) { uvc_video_validate_buffer(stream, buf); - buf = uvc_queue_next_buffer(&stream->queue, buf); + uvc_video_next_buffers(stream, &buf, &meta_buf); } } } static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream, - struct uvc_buffer *buf) + struct uvc_buffer *buf, struct uvc_buffer *meta_buf) { u8 *mem; int len, ret; @@ -1207,8 +1307,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream, do { ret = uvc_video_decode_start(stream, buf, mem, len); if (ret == -EAGAIN) - buf = uvc_queue_next_buffer(&stream->queue, - buf); + uvc_video_next_buffers(stream, &buf, &meta_buf); } while (ret == -EAGAIN); /* If an error occurred skip the rest of the payload. */ @@ -1218,6 +1317,8 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream, memcpy(stream->bulk.header, mem, ret); stream->bulk.header_size = ret; + uvc_video_decode_meta(stream, meta_buf, mem, ret); + mem += ret; len -= ret; } @@ -1241,7 +1342,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream, uvc_video_decode_end(stream, buf, stream->bulk.header, stream->bulk.payload_size); if (buf->state == UVC_BUF_STATE_READY) - uvc_queue_next_buffer(&stream->queue, buf); + uvc_video_next_buffers(stream, &buf, &meta_buf); } stream->bulk.header_size = 0; @@ -1251,7 +1352,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream, } static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream, - struct uvc_buffer *buf) + struct uvc_buffer *buf, struct uvc_buffer *meta_buf) { u8 *mem = urb->transfer_buffer; int len = stream->urb_size, ret; @@ -1297,7 +1398,10 @@ static void uvc_video_complete(struct urb *urb) { struct uvc_streaming *stream = urb->context; struct uvc_video_queue *queue = &stream->queue; + struct uvc_video_queue *qmeta = &stream->meta.queue; + struct vb2_queue *vb2_qmeta = stream->meta.vdev.queue; struct uvc_buffer *buf = NULL; + struct uvc_buffer *buf_meta = NULL; unsigned long flags; int ret; @@ -1316,6 +1420,8 @@ static void uvc_video_complete(struct urb *urb) case -ECONNRESET: /* usb_unlink_urb() called. */ case -ESHUTDOWN: /* The endpoint is being disabled. */ uvc_queue_cancel(queue, urb->status == -ESHUTDOWN); + if (vb2_qmeta) + uvc_queue_cancel(qmeta, urb->status == -ESHUTDOWN); return; } @@ -1325,7 +1431,15 @@ static void uvc_video_complete(struct urb *urb) queue); spin_unlock_irqrestore(&queue->irqlock, flags); - stream->decode(urb, stream, buf); + if (vb2_qmeta) { + spin_lock_irqsave(&qmeta->irqlock, flags); + if (!list_empty(&qmeta->irqqueue)) + buf_meta = list_first_entry(&qmeta->irqqueue, + struct uvc_buffer, queue); + spin_unlock_irqrestore(&qmeta->irqlock, flags); + } + + stream->decode(urb, stream, buf, buf_meta); if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n", diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index c36fa0991141..961d7c13b27b 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -479,6 +479,8 @@ struct uvc_stats_stream { unsigned int max_sof; /* Maximum STC.SOF value */ }; +#define UVC_METATADA_BUF_SIZE 1024 + struct uvc_streaming { struct list_head list; struct uvc_device *dev; @@ -510,7 +512,13 @@ struct uvc_streaming { unsigned int frozen : 1; struct uvc_video_queue queue; void (*decode) (struct urb *urb, struct uvc_streaming *video, - struct uvc_buffer *buf); + struct uvc_buffer *buf, struct uvc_buffer *meta_buf); + + struct { + struct video_device vdev; + struct uvc_video_queue queue; + __u32 format; + } meta; /* Context data used by the bulk completion handler. */ struct { @@ -552,6 +560,8 @@ struct uvc_streaming { u16 last_sof; u16 sof_offset; + u8 last_scr[6]; + spinlock_t lock; } clock; }; @@ -561,6 +571,7 @@ struct uvc_device { struct usb_interface *intf; unsigned long warnings; __u32 quirks; + __u32 meta_format; int intfnum; char name[32]; @@ -715,6 +726,7 @@ extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, void uvc_video_clock_update(struct uvc_streaming *stream, struct vb2_v4l2_buffer *vbuf, struct uvc_buffer *buf); +int uvc_meta_register(struct uvc_streaming *stream); int uvc_register_video_device(struct uvc_device *dev, struct uvc_streaming *stream, @@ -777,7 +789,7 @@ extern struct usb_host_endpoint *uvc_find_endpoint( /* Quirks support */ void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream, - struct uvc_buffer *buf); + struct uvc_buffer *buf, struct uvc_buffer *meta_buf); /* debugfs and statistics */ void uvc_debugfs_init(void); diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h index e80b4655d8cd..020714d2c5bd 100644 --- a/include/uapi/linux/uvcvideo.h +++ b/include/uapi/linux/uvcvideo.h @@ -68,4 +68,30 @@ struct uvc_xu_control_query { #define UVCIOC_CTRL_MAP _IOWR('u', 0x20, struct uvc_xu_control_mapping) #define UVCIOC_CTRL_QUERY _IOWR('u', 0x21, struct uvc_xu_control_query) +/* + * Metadata node + */ + +/** + * struct uvc_meta_buf - metadata buffer building block + * @ns - system timestamp of the payload in nanoseconds + * @sof - USB Frame Number + * @length - length of the payload header + * @flags - payload header flags + * @buf - optional device-specific header data + * + * UVC metadata nodes fill buffers with possibly multiple instances of this + * struct. The first two fields are added by the driver, they can be used for + * clock synchronisation. The rest is an exact copy of a UVC payload header. + * Only complete objects with complete buffers are included. Therefore it's + * always sizeof(meta->ts) + sizeof(meta->sof) + meta->length bytes large. + */ +struct uvc_meta_buf { + __u64 ns; + __u16 sof; + __u8 length; + __u8 flags; + __u8 buf[]; +} __packed; + #endif -- cgit v1.2.3-59-g8ed1b From 6e6a8b5a38cb04d5ef35d4eb57836126b954e7c8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 4 Jan 2018 13:08:56 -0500 Subject: media: replace all occurrences There are a lot of places where sequences of space/tabs are found. Get rid of all spaces before tabs. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146/saa7146_video.c | 8 +- drivers/media/dvb-core/Makefile | 2 +- drivers/media/dvb-frontends/au8522_priv.h | 218 ++++++++--------- drivers/media/dvb-frontends/drx39xyj/drx_driver.h | 2 +- drivers/media/dvb-frontends/stb0899_drv.c | 10 +- drivers/media/dvb-frontends/stb0899_drv.h | 2 +- drivers/media/dvb-frontends/stb0899_priv.h | 2 +- drivers/media/dvb-frontends/stv0900_core.c | 2 +- drivers/media/dvb-frontends/stv0900_init.h | 34 +-- drivers/media/dvb-frontends/stv0900_priv.h | 2 +- drivers/media/dvb-frontends/stv090x.c | 12 +- drivers/media/dvb-frontends/stv090x_priv.h | 2 +- drivers/media/dvb-frontends/stv6110x.c | 2 +- drivers/media/dvb-frontends/stv6110x_priv.h | 6 +- drivers/media/dvb-frontends/tda10023.c | 2 +- drivers/media/firewire/firedtv-avc.c | 4 +- drivers/media/firewire/firedtv-fe.c | 6 +- drivers/media/i2c/cx25840/cx25840-core.c | 2 +- drivers/media/i2c/cx25840/cx25840-core.h | 2 +- drivers/media/i2c/cx25840/cx25840-ir.c | 2 +- drivers/media/i2c/ks0127.c | 2 +- drivers/media/i2c/ov7670.c | 38 +-- drivers/media/i2c/saa6752hs.c | 8 +- drivers/media/i2c/saa7115.c | 2 +- drivers/media/i2c/saa7127.c | 162 ++++++------- drivers/media/i2c/saa717x.c | 12 +- drivers/media/i2c/ths7303.c | 2 +- drivers/media/i2c/tvaudio.c | 2 +- drivers/media/i2c/tvp7002_reg.h | 6 +- drivers/media/i2c/vpx3220.c | 2 +- drivers/media/pci/bt8xx/bttv-cards.c | 266 ++++++++++----------- drivers/media/pci/bt8xx/bttv-input.c | 8 +- drivers/media/pci/bt8xx/bttv.h | 4 +- drivers/media/pci/bt8xx/bttvp.h | 6 +- drivers/media/pci/cx18/cx18-alsa-pcm.c | 2 +- drivers/media/pci/cx18/cx18-av-audio.c | 2 +- drivers/media/pci/cx18/cx18-av-core.c | 18 +- drivers/media/pci/cx18/cx18-av-core.h | 2 +- drivers/media/pci/cx18/cx18-cards.c | 8 +- drivers/media/pci/cx18/cx18-cards.h | 32 +-- drivers/media/pci/cx18/cx18-driver.h | 46 ++-- drivers/media/pci/cx18/cx18-firmware.c | 96 ++++---- drivers/media/pci/cx18/cx18-mailbox.c | 8 +- drivers/media/pci/cx18/cx18-streams.c | 2 +- drivers/media/pci/cx18/cx18-vbi.c | 2 +- drivers/media/pci/cx18/cx23418.h | 88 +++---- drivers/media/pci/cx23885/cimax2.c | 2 +- drivers/media/pci/cx23885/cx23885-video.c | 2 +- drivers/media/pci/cx23885/cx23885.h | 4 +- drivers/media/pci/cx23885/cx23888-ir.c | 2 +- drivers/media/pci/ivtv/ivtv-cards.h | 126 +++++----- drivers/media/pci/ivtv/ivtv-driver.h | 102 ++++---- drivers/media/pci/ivtv/ivtv-firmware.c | 36 +-- drivers/media/pci/ivtv/ivtv-i2c.c | 26 +- drivers/media/pci/ivtv/ivtv-ioctl.c | 74 +++--- drivers/media/pci/ivtv/ivtv-mailbox.c | 182 +++++++------- drivers/media/pci/mantis/mantis_reg.h | 6 +- drivers/media/pci/mantis/mantis_vp1041.c | 210 ++++++++-------- drivers/media/pci/meye/meye.c | 2 +- drivers/media/pci/saa7134/saa7134-cards.c | 64 ++--- drivers/media/pci/saa7134/saa7134-dvb.c | 4 +- drivers/media/pci/saa7134/saa7134-video.c | 4 +- drivers/media/pci/saa7134/saa7134.h | 8 +- drivers/media/pci/saa7146/hexium_gemini.c | 22 +- drivers/media/pci/saa7146/hexium_orion.c | 18 +- drivers/media/pci/saa7146/mxb.c | 24 +- drivers/media/pci/ttpci/av7110.h | 2 +- drivers/media/pci/ttpci/budget-av.c | 6 +- drivers/media/pci/ttpci/budget-ci.c | 210 ++++++++-------- drivers/media/pci/zoran/zoran_driver.c | 38 +-- drivers/media/pci/zoran/zr36057.h | 4 +- drivers/media/platform/Makefile | 14 +- drivers/media/platform/arv.c | 50 ++-- drivers/media/platform/coda/coda_regs.h | 2 +- drivers/media/platform/davinci/dm355_ccdc_regs.h | 6 +- drivers/media/platform/davinci/dm644x_ccdc_regs.h | 4 +- drivers/media/platform/davinci/isif_regs.h | 6 +- drivers/media/platform/davinci/vpfe_capture.c | 2 +- drivers/media/platform/davinci/vpif.h | 4 +- drivers/media/platform/davinci/vpss.c | 10 +- drivers/media/platform/exynos4-is/fimc-core.c | 2 +- drivers/media/platform/m2m-deinterlace.c | 12 +- drivers/media/platform/omap/omap_vout.c | 12 +- drivers/media/platform/sh_vou.c | 2 +- drivers/media/radio/radio-aimslab.c | 2 +- drivers/media/radio/radio-aztech.c | 2 +- drivers/media/radio/radio-cadet.c | 4 +- drivers/media/radio/radio-gemtek.c | 8 +- drivers/media/radio/radio-rtrack2.c | 2 +- drivers/media/radio/radio-sf16fmi.c | 4 +- drivers/media/radio/radio-sf16fmr2.c | 2 +- drivers/media/radio/radio-tea5764.c | 2 +- drivers/media/radio/radio-terratec.c | 6 +- drivers/media/radio/tea575x.c | 2 +- drivers/media/rc/keymaps/rc-behold-columbus.c | 6 +- drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c | 2 +- drivers/media/tuners/mxl5005s.c | 6 +- drivers/media/tuners/tda827x.h | 2 +- drivers/media/tuners/tda9887.c | 4 +- drivers/media/tuners/tuner-simple.c | 2 +- drivers/media/tuners/tuner-xc2028.c | 6 +- drivers/media/tuners/tuner-xc2028.h | 2 +- drivers/media/usb/au0828/au0828-cards.h | 2 +- drivers/media/usb/au0828/au0828-video.c | 2 +- drivers/media/usb/au0828/au0828.h | 6 +- drivers/media/usb/cpia2/cpia2_usb.c | 14 +- drivers/media/usb/cx231xx/cx231xx-audio.c | 6 +- drivers/media/usb/cx231xx/cx231xx-avcore.c | 2 +- drivers/media/usb/cx231xx/cx231xx-core.c | 2 +- drivers/media/usb/cx231xx/cx231xx-i2c.c | 2 +- drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h | 2 +- drivers/media/usb/cx231xx/cx231xx-reg.h | 20 +- drivers/media/usb/dvb-usb/az6027.c | 216 ++++++++--------- drivers/media/usb/gspca/stv06xx/stv06xx.c | 2 +- drivers/media/usb/hdpvr/hdpvr-video.c | 26 +- drivers/media/usb/hdpvr/hdpvr.h | 18 +- drivers/media/usb/pwc/pwc.h | 6 +- drivers/media/usb/siano/smsusb.c | 2 +- drivers/media/usb/stk1160/Makefile | 2 +- drivers/media/usb/stkwebcam/stk-sensor.c | 44 ++-- drivers/media/usb/uvc/uvc_driver.c | 14 +- drivers/media/usb/uvc/uvc_isight.c | 10 +- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 6 +- drivers/media/v4l2-core/v4l2-ioctl.c | 62 ++--- include/media/drv-intf/cx2341x.h | 144 +++++------ include/media/drv-intf/msp3400.h | 62 ++--- include/media/drv-intf/saa7146.h | 2 +- include/media/i2c/bt819.h | 4 +- include/media/i2c/m52790.h | 52 ++-- include/media/i2c/saa7115.h | 12 +- include/media/i2c/upd64031a.h | 6 +- include/media/v4l2-common.h | 8 +- include/uapi/linux/dvb/video.h | 20 +- include/uapi/linux/v4l2-controls.h | 96 ++++---- include/uapi/linux/videodev2.h | 56 ++--- 135 files changed, 1722 insertions(+), 1722 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c index 5dfc1f27d1cf..0dfa0c09d646 100644 --- a/drivers/media/common/saa7146/saa7146_video.c +++ b/drivers/media/common/saa7146/saa7146_video.c @@ -1001,9 +1001,9 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = { .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, - .vidioc_overlay = vidioc_overlay, - .vidioc_g_fbuf = vidioc_g_fbuf, - .vidioc_s_fbuf = vidioc_s_fbuf, + .vidioc_overlay = vidioc_overlay, + .vidioc_g_fbuf = vidioc_g_fbuf, + .vidioc_s_fbuf = vidioc_s_fbuf, .vidioc_reqbufs = vidioc_reqbufs, .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, @@ -1012,7 +1012,7 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = { .vidioc_s_std = vidioc_s_std, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, - .vidioc_g_parm = vidioc_g_parm, + .vidioc_g_parm = vidioc_g_parm, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; diff --git a/drivers/media/dvb-core/Makefile b/drivers/media/dvb-core/Makefile index 05827ee2a406..3a105d82019a 100644 --- a/drivers/media/dvb-core/Makefile +++ b/drivers/media/dvb-core/Makefile @@ -7,7 +7,7 @@ dvb-net-$(CONFIG_DVB_NET) := dvb_net.o dvb-vb2-$(CONFIG_DVB_MMSP) := dvb_vb2.o dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \ - dvb_ca_en50221.o dvb_frontend.o \ + dvb_ca_en50221.o dvb_frontend.o \ $(dvb-net-y) dvb_ringbuffer.o $(dvb-vb2-y) dvb_math.o obj-$(CONFIG_DVB_CORE) += dvb-core.o diff --git a/drivers/media/dvb-frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h index f02dac958db6..2043c1744753 100644 --- a/drivers/media/dvb-frontends/au8522_priv.h +++ b/drivers/media/dvb-frontends/au8522_priv.h @@ -99,7 +99,7 @@ int au8522_led_ctrl(struct au8522_state *state, int led); #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H 0x0A5 #define AU8522_AGC_CONTROL_RANGE_REG0A6H 0x0A6 #define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H 0x0A7 -#define AU8522_TUNER_AGC_RF_STOP_REG0A8H 0x0A8 +#define AU8522_TUNER_AGC_RF_STOP_REG0A8H 0x0A8 #define AU8522_TUNER_AGC_RF_START_REG0A9H 0x0A9 #define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH 0x0AA #define AU8522_TUNER_AGC_IF_STOP_REG0ABH 0x0AB @@ -110,18 +110,18 @@ int au8522_led_ctrl(struct au8522_state *state, int led); /* Receiver registers */ #define AU8522_FRMREGTHRD1_REG0B0H 0x0B0 -#define AU8522_FRMREGAGC1H_REG0B1H 0x0B1 -#define AU8522_FRMREGSHIFT1_REG0B2H 0x0B2 -#define AU8522_TOREGAGC1_REG0B3H 0x0B3 -#define AU8522_TOREGASHIFT1_REG0B4H 0x0B4 +#define AU8522_FRMREGAGC1H_REG0B1H 0x0B1 +#define AU8522_FRMREGSHIFT1_REG0B2H 0x0B2 +#define AU8522_TOREGAGC1_REG0B3H 0x0B3 +#define AU8522_TOREGASHIFT1_REG0B4H 0x0B4 #define AU8522_FRMREGBBH_REG0B5H 0x0B5 -#define AU8522_FRMREGBBM_REG0B6H 0x0B6 -#define AU8522_FRMREGBBL_REG0B7H 0x0B7 +#define AU8522_FRMREGBBM_REG0B6H 0x0B6 +#define AU8522_FRMREGBBL_REG0B7H 0x0B7 /* 0xB8 TO 0xD7 are the filter coefficients */ -#define AU8522_FRMREGTHRD2_REG0D8H 0x0D8 -#define AU8522_FRMREGAGC2H_REG0D9H 0x0D9 -#define AU8522_TOREGAGC2_REG0DAH 0x0DA -#define AU8522_TOREGSHIFT2_REG0DBH 0x0DB +#define AU8522_FRMREGTHRD2_REG0D8H 0x0D8 +#define AU8522_FRMREGAGC2H_REG0D9H 0x0D9 +#define AU8522_TOREGAGC2_REG0DAH 0x0DA +#define AU8522_TOREGSHIFT2_REG0DBH 0x0DB #define AU8522_FRMREGPILOTH_REG0DCH 0x0DC #define AU8522_FRMREGPILOTM_REG0DDH 0x0DD #define AU8522_FRMREGPILOTL_REG0DEH 0x0DE @@ -134,9 +134,9 @@ int au8522_led_ctrl(struct au8522_state *state, int led); #define AU8522_CHIP_MODE_REG0FEH 0x0FE /* I2C bus control registers */ -#define AU8522_I2C_CONTROL_REG0_REG090H 0x090 -#define AU8522_I2C_CONTROL_REG1_REG091H 0x091 -#define AU8522_I2C_STATUS_REG092H 0x092 +#define AU8522_I2C_CONTROL_REG0_REG090H 0x090 +#define AU8522_I2C_CONTROL_REG1_REG091H 0x091 +#define AU8522_I2C_STATUS_REG092H 0x092 #define AU8522_I2C_WR_DATA0_REG093H 0x093 #define AU8522_I2C_WR_DATA1_REG094H 0x094 #define AU8522_I2C_WR_DATA2_REG095H 0x095 @@ -156,48 +156,48 @@ int au8522_led_ctrl(struct au8522_state *state, int led); #define AU8522_ENA_USB_REG101H 0x101 -#define AU8522_I2S_CTRL_0_REG110H 0x110 -#define AU8522_I2S_CTRL_1_REG111H 0x111 -#define AU8522_I2S_CTRL_2_REG112H 0x112 +#define AU8522_I2S_CTRL_0_REG110H 0x110 +#define AU8522_I2S_CTRL_1_REG111H 0x111 +#define AU8522_I2S_CTRL_2_REG112H 0x112 -#define AU8522_FRMREGFFECONTROL_REG121H 0x121 -#define AU8522_FRMREGDFECONTROL_REG122H 0x122 +#define AU8522_FRMREGFFECONTROL_REG121H 0x121 +#define AU8522_FRMREGDFECONTROL_REG122H 0x122 -#define AU8522_CARRFREQOFFSET0_REG201H 0x201 +#define AU8522_CARRFREQOFFSET0_REG201H 0x201 #define AU8522_CARRFREQOFFSET1_REG202H 0x202 #define AU8522_DECIMATION_GAIN_REG21AH 0x21A -#define AU8522_FRMREGIFSLP_REG21BH 0x21B -#define AU8522_FRMREGTHRDL2_REG21CH 0x21C -#define AU8522_FRMREGSTEP3DB_REG21DH 0x21D +#define AU8522_FRMREGIFSLP_REG21BH 0x21B +#define AU8522_FRMREGTHRDL2_REG21CH 0x21C +#define AU8522_FRMREGSTEP3DB_REG21DH 0x21D #define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH 0x21E -#define AU8522_FRMREGPLLMODE_REG21FH 0x21F -#define AU8522_FRMREGCSTHRD_REG220H 0x220 -#define AU8522_FRMREGCRLOCKDMAX_REG221H 0x221 -#define AU8522_FRMREGCRPERIODMASK_REG222H 0x222 -#define AU8522_FRMREGCRLOCK0THH_REG223H 0x223 -#define AU8522_FRMREGCRLOCK1THH_REG224H 0x224 -#define AU8522_FRMREGCRLOCK0THL_REG225H 0x225 -#define AU8522_FRMREGCRLOCK1THL_REG226H 0x226 +#define AU8522_FRMREGPLLMODE_REG21FH 0x21F +#define AU8522_FRMREGCSTHRD_REG220H 0x220 +#define AU8522_FRMREGCRLOCKDMAX_REG221H 0x221 +#define AU8522_FRMREGCRPERIODMASK_REG222H 0x222 +#define AU8522_FRMREGCRLOCK0THH_REG223H 0x223 +#define AU8522_FRMREGCRLOCK1THH_REG224H 0x224 +#define AU8522_FRMREGCRLOCK0THL_REG225H 0x225 +#define AU8522_FRMREGCRLOCK1THL_REG226H 0x226 #define AU_FRMREGPLLACQPHASESCL_REG227H 0x227 -#define AU8522_FRMREGFREQFBCTRL_REG228H 0x228 +#define AU8522_FRMREGFREQFBCTRL_REG228H 0x228 /* Analog TV Decoder */ #define AU8522_TVDEC_STATUS_REG000H 0x000 #define AU8522_TVDEC_INT_STATUS_REG001H 0x001 -#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 0x002 +#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 0x002 #define AU8522_TVDEC_SHARPNESSREG009H 0x009 #define AU8522_TVDEC_BRIGHTNESS_REG00AH 0x00A #define AU8522_TVDEC_CONTRAST_REG00BH 0x00B #define AU8522_TVDEC_SATURATION_CB_REG00CH 0x00C #define AU8522_TVDEC_SATURATION_CR_REG00DH 0x00D #define AU8522_TVDEC_HUE_H_REG00EH 0x00E -#define AU8522_TVDEC_HUE_L_REG00FH 0x00F +#define AU8522_TVDEC_HUE_L_REG00FH 0x00F #define AU8522_TVDEC_INT_MASK_REG010H 0x010 #define AU8522_VIDEO_MODE_REG011H 0x011 #define AU8522_TVDEC_PGA_REG012H 0x012 #define AU8522_TVDEC_COMB_MODE_REG015H 0x015 -#define AU8522_REG016H 0x016 +#define AU8522_REG016H 0x016 #define AU8522_TVDED_DBG_MODE_REG060H 0x060 #define AU8522_TVDEC_FORMAT_CTRL1_REG061H 0x061 #define AU8522_TVDEC_FORMAT_CTRL2_REG062H 0x062 @@ -207,13 +207,13 @@ int au8522_led_ctrl(struct au8522_state *state, int led); #define AU8522_TVDEC_COMB_VDIF_THR2_REG066H 0x066 #define AU8522_TVDEC_COMB_VDIF_THR3_REG067H 0x067 #define AU8522_TVDEC_COMB_NOTCH_THR_REG068H 0x068 -#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H 0x069 +#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H 0x069 #define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH 0x06A -#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH 0x06B -#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH 0x06C -#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 0x06D -#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH 0x06E -#define AU8522_TVDEC_UV_SEP_THR_REG06FH 0x06F +#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH 0x06B +#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH 0x06C +#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 0x06D +#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH 0x06E +#define AU8522_TVDEC_UV_SEP_THR_REG06FH 0x06F #define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H 0x070 #define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H 0x073 #define AU8522_TVDEC_DCAGC_CTRL_REG077H 0x077 @@ -229,42 +229,42 @@ int au8522_led_ctrl(struct au8522_state *state, int led); #define AU8522_TVDEC_CHROMA_AGC_REG401H 0x401 #define AU8522_TVDEC_CHROMA_SFT_REG402H 0x402 -#define AU8522_FILTER_COEF_R410 0x410 -#define AU8522_FILTER_COEF_R411 0x411 -#define AU8522_FILTER_COEF_R412 0x412 -#define AU8522_FILTER_COEF_R413 0x413 -#define AU8522_FILTER_COEF_R414 0x414 -#define AU8522_FILTER_COEF_R415 0x415 -#define AU8522_FILTER_COEF_R416 0x416 -#define AU8522_FILTER_COEF_R417 0x417 -#define AU8522_FILTER_COEF_R418 0x418 -#define AU8522_FILTER_COEF_R419 0x419 -#define AU8522_FILTER_COEF_R41A 0x41A -#define AU8522_FILTER_COEF_R41B 0x41B -#define AU8522_FILTER_COEF_R41C 0x41C -#define AU8522_FILTER_COEF_R41D 0x41D -#define AU8522_FILTER_COEF_R41E 0x41E -#define AU8522_FILTER_COEF_R41F 0x41F -#define AU8522_FILTER_COEF_R420 0x420 -#define AU8522_FILTER_COEF_R421 0x421 -#define AU8522_FILTER_COEF_R422 0x422 -#define AU8522_FILTER_COEF_R423 0x423 -#define AU8522_FILTER_COEF_R424 0x424 -#define AU8522_FILTER_COEF_R425 0x425 -#define AU8522_FILTER_COEF_R426 0x426 -#define AU8522_FILTER_COEF_R427 0x427 -#define AU8522_FILTER_COEF_R428 0x428 -#define AU8522_FILTER_COEF_R429 0x429 -#define AU8522_FILTER_COEF_R42A 0x42A -#define AU8522_FILTER_COEF_R42B 0x42B -#define AU8522_FILTER_COEF_R42C 0x42C -#define AU8522_FILTER_COEF_R42D 0x42D +#define AU8522_FILTER_COEF_R410 0x410 +#define AU8522_FILTER_COEF_R411 0x411 +#define AU8522_FILTER_COEF_R412 0x412 +#define AU8522_FILTER_COEF_R413 0x413 +#define AU8522_FILTER_COEF_R414 0x414 +#define AU8522_FILTER_COEF_R415 0x415 +#define AU8522_FILTER_COEF_R416 0x416 +#define AU8522_FILTER_COEF_R417 0x417 +#define AU8522_FILTER_COEF_R418 0x418 +#define AU8522_FILTER_COEF_R419 0x419 +#define AU8522_FILTER_COEF_R41A 0x41A +#define AU8522_FILTER_COEF_R41B 0x41B +#define AU8522_FILTER_COEF_R41C 0x41C +#define AU8522_FILTER_COEF_R41D 0x41D +#define AU8522_FILTER_COEF_R41E 0x41E +#define AU8522_FILTER_COEF_R41F 0x41F +#define AU8522_FILTER_COEF_R420 0x420 +#define AU8522_FILTER_COEF_R421 0x421 +#define AU8522_FILTER_COEF_R422 0x422 +#define AU8522_FILTER_COEF_R423 0x423 +#define AU8522_FILTER_COEF_R424 0x424 +#define AU8522_FILTER_COEF_R425 0x425 +#define AU8522_FILTER_COEF_R426 0x426 +#define AU8522_FILTER_COEF_R427 0x427 +#define AU8522_FILTER_COEF_R428 0x428 +#define AU8522_FILTER_COEF_R429 0x429 +#define AU8522_FILTER_COEF_R42A 0x42A +#define AU8522_FILTER_COEF_R42B 0x42B +#define AU8522_FILTER_COEF_R42C 0x42C +#define AU8522_FILTER_COEF_R42D 0x42D /* VBI Control Registers */ -#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H 0x004 -#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H 0x005 -#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H 0x006 -#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H 0x007 +#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H 0x004 +#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H 0x005 +#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H 0x006 +#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H 0x007 #define AU8522_TVDEC_VBI_CTRL_H_REG017H 0x017 #define AU8522_TVDEC_VBI_CTRL_L_REG018H 0x018 #define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H 0x019 @@ -272,10 +272,10 @@ int au8522_led_ctrl(struct au8522_state *state, int led); #define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH 0x01B #define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH 0x01C #define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH 0x01E -#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH 0x01F -#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H 0x020 -#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 0x021 -#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H 0x022 +#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH 0x01F +#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H 0x020 +#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 0x021 +#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H 0x022 #define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H 0x023 #define AU8522_REG071H 0x071 @@ -315,17 +315,17 @@ int au8522_led_ctrl(struct au8522_state *state, int led); #define AU8522_GPIO_DATA_REG0E2H 0x0E2 /* Audio Control Registers */ -#define AU8522_AUDIOAGC_REG0EEH 0x0EE -#define AU8522_AUDIO_STATUS_REG0F0H 0x0F0 -#define AU8522_AUDIO_MODE_REG0F1H 0x0F1 -#define AU8522_AUDIO_VOLUME_L_REG0F2H 0x0F2 -#define AU8522_AUDIO_VOLUME_R_REG0F3H 0x0F3 -#define AU8522_AUDIO_VOLUME_REG0F4H 0x0F4 -#define AU8522_FRMREGAUPHASE_REG0F7H 0x0F7 +#define AU8522_AUDIOAGC_REG0EEH 0x0EE +#define AU8522_AUDIO_STATUS_REG0F0H 0x0F0 +#define AU8522_AUDIO_MODE_REG0F1H 0x0F1 +#define AU8522_AUDIO_VOLUME_L_REG0F2H 0x0F2 +#define AU8522_AUDIO_VOLUME_R_REG0F3H 0x0F3 +#define AU8522_AUDIO_VOLUME_REG0F4H 0x0F4 +#define AU8522_FRMREGAUPHASE_REG0F7H 0x0F7 #define AU8522_REG0F9H 0x0F9 -#define AU8522_AUDIOAGC2_REG605H 0x605 -#define AU8522_AUDIOFREQ_REG606H 0x606 +#define AU8522_AUDIOAGC2_REG605H 0x605 +#define AU8522_AUDIOFREQ_REG606H 0x606 /**************************************************************/ @@ -356,53 +356,53 @@ int au8522_led_ctrl(struct au8522_state *state, int led); #define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_PAL_M 0x02 -#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4 +#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4 #define AU8522_INPUT_CONTROL_REG081H_ATVRF 0xC4 #define AU8522_INPUT_CONTROL_REG081H_ATVRF13 0xC4 -#define AU8522_INPUT_CONTROL_REG081H_J83B64 0xC4 -#define AU8522_INPUT_CONTROL_REG081H_J83B256 0xC4 -#define AU8522_INPUT_CONTROL_REG081H_CVBS 0x20 +#define AU8522_INPUT_CONTROL_REG081H_J83B64 0xC4 +#define AU8522_INPUT_CONTROL_REG081H_J83B256 0xC4 +#define AU8522_INPUT_CONTROL_REG081H_CVBS 0x20 #define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1 0xA2 #define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2 0xA0 #define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3 0x69 #define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4 0x68 -#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF 0x28 +#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF 0x28 /* CH1 AS Y,CH3 AS C */ -#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 0x23 +#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 0x23 /* CH2 AS Y,CH4 AS C */ -#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24 0x20 -#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC 0x0C -#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64 0x09 -#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256 0x09 -#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS 0x12 -#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF 0x1A +#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24 0x20 +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC 0x0C +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64 0x09 +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256 0x09 +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS 0x12 +#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF 0x1A #define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13 0x1A #define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO 0x02 #define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR 0x00 #define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO 0x9C -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS 0x9D +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS 0x9D #define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC 0xE8 -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 0xCA -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64 0xCA -#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF 0xDD +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 0xCA +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64 0xCA +#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF 0xDD #define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13 0xDD #define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL 0xDD #define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM 0xDD #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC 0x80 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 0x80 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64 0x80 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 0x80 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64 0x80 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC 0x40 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256 0x40 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64 0x40 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR 0x00 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF 0x01 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13 0x01 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO 0x04 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO 0x04 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS 0x01 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM 0x03 -#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS 0x09 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM 0x03 +#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS 0x09 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL 0x01 #define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM 0x01 diff --git a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h index 855685b6b386..1ec20eecc433 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h +++ b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h @@ -932,7 +932,7 @@ STRUCTS * Used by DRX_CTRL_LOAD_UCODE and DRX_CTRL_VERIFY_UCODE */ struct drxu_code_info { - char *mc_file; + char *mc_file; }; /* diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c index 2c5427c77db7..3c654ae16e78 100644 --- a/drivers/media/dvb-frontends/stb0899_drv.c +++ b/drivers/media/dvb-frontends/stb0899_drv.c @@ -1583,15 +1583,15 @@ static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe) static const struct dvb_frontend_ops stb0899_ops = { .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, .info = { - .name = "STB0899 Multistandard", + .name = "STB0899 Multistandard", .frequency_min = 950000, - .frequency_max = 2150000, + .frequency_max = 2150000, .frequency_stepsize = 0, .frequency_tolerance = 0, - .symbol_rate_min = 5000000, - .symbol_rate_max = 45000000, + .symbol_rate_min = 5000000, + .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | + .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO | FE_CAN_2G_MODULATION | FE_CAN_QPSK diff --git a/drivers/media/dvb-frontends/stb0899_drv.h b/drivers/media/dvb-frontends/stb0899_drv.h index 6c285aee7edf..f65f9a8266f8 100644 --- a/drivers/media/dvb-frontends/stb0899_drv.h +++ b/drivers/media/dvb-frontends/stb0899_drv.h @@ -82,7 +82,7 @@ enum stb0899_inversion { * 1. POWER ON/OFF (index 0) * 2. FE_HAS_LOCK/LOCK_LOSS (index 1) * - * @gpio = one of the above listed GPIO's + * @gpio = one of the above listed GPIO's * @level = output state: pulled up or low */ struct stb0899_postproc { diff --git a/drivers/media/dvb-frontends/stb0899_priv.h b/drivers/media/dvb-frontends/stb0899_priv.h index 86d140e4c5ed..3285cd1ba60a 100644 --- a/drivers/media/dvb-frontends/stb0899_priv.h +++ b/drivers/media/dvb-frontends/stb0899_priv.h @@ -252,7 +252,7 @@ extern int stb0899_write_s2reg(struct stb0899_state *state, extern int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable); -#define STB0899_READ_S2REG(DEVICE, REG) (_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG)) +#define STB0899_READ_S2REG(DEVICE, REG) (_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG)) //#define STB0899_WRITE_S2REG(DEVICE, REG, DATA) (_stb0899_write_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG, DATA)) /* stb0899_algo.c */ diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c index 0b739725e3c0..72f17b97ca04 100644 --- a/drivers/media/dvb-frontends/stv0900_core.c +++ b/drivers/media/dvb-frontends/stv0900_core.c @@ -1929,7 +1929,7 @@ struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, switch (demod) { case 0: case 1: - init_params.dmd_ref_clk = config->xtal; + init_params.dmd_ref_clk = config->xtal; init_params.demod_mode = config->demod_mode; init_params.rolloff = STV0900_35; init_params.path1_ts_clock = config->path1_mode; diff --git a/drivers/media/dvb-frontends/stv0900_init.h b/drivers/media/dvb-frontends/stv0900_init.h index 411941442086..550ef4a0f654 100644 --- a/drivers/media/dvb-frontends/stv0900_init.h +++ b/drivers/media/dvb-frontends/stv0900_init.h @@ -148,8 +148,8 @@ struct stv0900_short_frames_car_loop_optim_vs_mod { /* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */ static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = { - /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon - 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ + /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon + 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ { STV0900_QPSK_12, 0x1C, 0x0D, 0x1B, 0x2C, 0x3A, 0x1C, 0x2A, 0x3B, 0x2A, 0x1B }, { STV0900_QPSK_35, 0x2C, 0x0D, 0x2B, 0x2C, 0x3A, @@ -176,15 +176,15 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = { 0x0B, 0x39, 0x1A, 0x19, 0x0A }, { STV0900_8PSK_89, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A, 0x0B, 0x39, 0x1A, 0x29, 0x39 }, - { STV0900_8PSK_910, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A, + { STV0900_8PSK_910, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A, 0x0B, 0x39, 0x1A, 0x29, 0x39 } }; /* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */ static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = { - /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon - 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ + /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon + 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ { STV0900_QPSK_12, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D, 0x1F, 0x3D, 0x3E, 0x3D, 0x1E }, { STV0900_QPSK_35, 0x2F, 0x3F, 0x2E, 0x2F, 0x3D, @@ -211,7 +211,7 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = { 0x1e, 0x3c, 0x2d, 0x2c, 0x1d }, { STV0900_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d }, - { STV0900_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, + { STV0900_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d }, }; @@ -219,8 +219,8 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = { /* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */ static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = { - /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon - 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ + /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon + 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ { STV0900_16APSK_23, 0x0C, 0x0C, 0x0C, 0x0C, 0x1D, 0x0C, 0x3C, 0x0C, 0x2C, 0x0C }, { STV0900_16APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E, @@ -248,8 +248,8 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = { /* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */ static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = { - /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon - 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ + /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon + 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ { STV0900_QPSK_14, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D, 0x2F, 0x2D, 0x1F, 0x3D, 0x3E }, { STV0900_QPSK_13, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D, @@ -275,10 +275,10 @@ struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = { }; static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut30[14] = { - /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon - 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ + /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon + 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ { STV0900_QPSK_12, 0x3C, 0x2C, 0x0C, 0x2C, 0x1B, - 0x2C, 0x1B, 0x1C, 0x0B, 0x3B }, + 0x2C, 0x1B, 0x1C, 0x0B, 0x3B }, { STV0900_QPSK_35, 0x0D, 0x0D, 0x0C, 0x0D, 0x1B, 0x3C, 0x1B, 0x1C, 0x0B, 0x3B }, { STV0900_QPSK_23, 0x1D, 0x0D, 0x0C, 0x1D, 0x2B, @@ -309,8 +309,8 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut30[14] = { static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut30[11] = { - /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon - 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ + /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon + 10MPoff 20MPon 20MPoff 30MPon 30MPoff */ { STV0900_16APSK_23, 0x0A, 0x0A, 0x0A, 0x0A, 0x1A, 0x0A, 0x3A, 0x0A, 0x2A, 0x0A }, { STV0900_16APSK_34, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B, @@ -337,8 +337,8 @@ struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut30[11] = { static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut30[3] = { - /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon - 10MPoff 20MPon 20MPoff 30MPon 30MPoff*/ + /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon + 10MPoff 20MPon 20MPoff 30MPon 30MPoff*/ { STV0900_QPSK_14, 0x0C, 0x3C, 0x0B, 0x3C, 0x2A, 0x2C, 0x2A, 0x1C, 0x3A, 0x3B }, { STV0900_QPSK_13, 0x0C, 0x3C, 0x0B, 0x3C, 0x2A, diff --git a/drivers/media/dvb-frontends/stv0900_priv.h b/drivers/media/dvb-frontends/stv0900_priv.h index 7a95f955627b..d1fc06ff27d3 100644 --- a/drivers/media/dvb-frontends/stv0900_priv.h +++ b/drivers/media/dvb-frontends/stv0900_priv.h @@ -243,7 +243,7 @@ struct stv0900_init_params{ u8 tun1_maddress; int tuner1_adc; - int tuner1_type; + int tuner1_type; /* IQ from the tuner1 to the demod */ enum stv0900_iq_inversion tun1_iq_inv; diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c index 20641bd2f977..9133f65d4623 100644 --- a/drivers/media/dvb-frontends/stv090x.c +++ b/drivers/media/dvb-frontends/stv090x.c @@ -677,7 +677,7 @@ static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut20[] = { /* Cut 3.0 Short Frame Tracking CR Loop */ static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut30[] = { - /* MODCOD 2M 5M 10M 20M 30M */ + /* MODCOD 2M 5M 10M 20M 30M */ { STV090x_QPSK, 0x2C, 0x2B, 0x0B, 0x0B, 0x3A }, { STV090x_8PSK, 0x3B, 0x0B, 0x2A, 0x0A, 0x39 }, { STV090x_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A }, @@ -701,7 +701,7 @@ static int stv090x_read_reg(struct stv090x_state *state, unsigned int reg) u8 buf; struct i2c_msg msg[] = { - { .addr = config->address, .flags = 0, .buf = b0, .len = 2 }, + { .addr = config->address, .flags = 0, .buf = b0, .len = 2 }, { .addr = config->address, .flags = I2C_M_RD, .buf = &buf, .len = 1 } }; @@ -4906,11 +4906,11 @@ static const struct dvb_frontend_ops stv090x_ops = { .info = { .name = "STV090x Multistandard", .frequency_min = 950000, - .frequency_max = 2150000, + .frequency_max = 2150000, .frequency_stepsize = 0, .frequency_tolerance = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO | FE_CAN_QPSK | @@ -4953,7 +4953,7 @@ struct dvb_frontend *stv090x_attach(struct stv090x_config *config, state->frontend.ops = stv090x_ops; state->frontend.demodulator_priv = state; state->demod = demod; - state->demod_mode = config->demod_mode; /* Single or Dual mode */ + state->demod_mode = config->demod_mode; /* Single or Dual mode */ state->device = config->device; state->rolloff = STV090x_RO_35; /* default */ diff --git a/drivers/media/dvb-frontends/stv090x_priv.h b/drivers/media/dvb-frontends/stv090x_priv.h index 37c9f93a8a6a..fdda2185db9d 100644 --- a/drivers/media/dvb-frontends/stv090x_priv.h +++ b/drivers/media/dvb-frontends/stv090x_priv.h @@ -231,7 +231,7 @@ struct stv090x_tab { }; struct stv090x_internal { - struct i2c_adapter *i2c_adap; + struct i2c_adapter *i2c_adap; u8 i2c_addr; struct mutex demod_lock; /* Lock access to shared register */ diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c index d4ac29ac9b4f..d8950028d021 100644 --- a/drivers/media/dvb-frontends/stv6110x.c +++ b/drivers/media/dvb-frontends/stv6110x.c @@ -46,7 +46,7 @@ static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data) u8 b0[] = { reg }; u8 b1[] = { 0 }; struct i2c_msg msg[] = { - { .addr = config->addr, .flags = 0, .buf = b0, .len = 1 }, + { .addr = config->addr, .flags = 0, .buf = b0, .len = 1 }, { .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; diff --git a/drivers/media/dvb-frontends/stv6110x_priv.h b/drivers/media/dvb-frontends/stv6110x_priv.h index a993aba27b7e..109dfaf4ba42 100644 --- a/drivers/media/dvb-frontends/stv6110x_priv.h +++ b/drivers/media/dvb-frontends/stv6110x_priv.h @@ -48,11 +48,11 @@ #define STV6110x_SETFIELD(mask, bitf, val) \ (mask = (mask & (~(((1 << STV6110x_WIDTH_##bitf) - 1) << \ - STV6110x_OFFST_##bitf))) | \ + STV6110x_OFFST_##bitf))) | \ (val << STV6110x_OFFST_##bitf)) #define STV6110x_GETFIELD(bitf, val) \ - ((val >> STV6110x_OFFST_##bitf) & \ + ((val >> STV6110x_OFFST_##bitf) & \ ((1 << STV6110x_WIDTH_##bitf) - 1)) #define MAKEWORD16(a, b) (((a) << 8) | (b)) @@ -68,7 +68,7 @@ struct stv6110x_state { struct i2c_adapter *i2c; const struct stv6110x_config *config; - u8 regs[8]; + u8 regs[8]; const struct stv6110x_devctl *devctl; }; diff --git a/drivers/media/dvb-frontends/tda10023.c b/drivers/media/dvb-frontends/tda10023.c index abe27029fe93..6c84916234e3 100644 --- a/drivers/media/dvb-frontends/tda10023.c +++ b/drivers/media/dvb-frontends/tda10023.c @@ -211,7 +211,7 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr) BDRX=1<<(24+NDEC); BDRX*=sr; - do_div(BDRX, state->sysclk); /* BDRX/=SYSCLK; */ + do_div(BDRX, state->sysclk); /* BDRX/=SYSCLK; */ BDR=(s32)BDRX; } diff --git a/drivers/media/firewire/firedtv-avc.c b/drivers/media/firewire/firedtv-avc.c index 37db04f8104d..1c933b2cf760 100644 --- a/drivers/media/firewire/firedtv-avc.c +++ b/drivers/media/firewire/firedtv-avc.c @@ -47,7 +47,7 @@ #define AVC_OPCODE_DSIT 0xc8 #define AVC_OPCODE_DSD 0xcb -#define DESCRIPTOR_TUNER_STATUS 0x80 +#define DESCRIPTOR_TUNER_STATUS 0x80 #define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00 #define SFE_VENDOR_DE_COMPANYID_0 0x00 /* OUI of Digital Everywhere */ @@ -688,7 +688,7 @@ int avc_tuner_get_ts(struct firedtv *fdtv) c->operand[2] = 0xff; /* status */ c->operand[3] = 0x20; /* system id = DVB */ c->operand[4] = 0x00; /* antenna number */ - c->operand[5] = 0x0; /* system_specific_search_flags */ + c->operand[5] = 0x0; /* system_specific_search_flags */ c->operand[6] = sl; /* system_specific_multiplex selection_length */ /* * operand[7]: valid_flags[0] diff --git a/drivers/media/firewire/firedtv-fe.c b/drivers/media/firewire/firedtv-fe.c index 86efeb10d2f2..a2ef4ede8ebe 100644 --- a/drivers/media/firewire/firedtv-fe.c +++ b/drivers/media/firewire/firedtv-fe.c @@ -165,7 +165,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name) ops->read_snr = fdtv_read_snr; ops->read_ucblocks = fdtv_read_uncorrected_blocks; - ops->diseqc_send_master_cmd = fdtv_diseqc_send_master_cmd; + ops->diseqc_send_master_cmd = fdtv_diseqc_send_master_cmd; ops->diseqc_send_burst = fdtv_diseqc_send_burst; ops->set_tone = fdtv_set_tone; ops->set_voltage = fdtv_set_voltage; @@ -220,7 +220,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name) fi->symbol_rate_min = 870000; fi->symbol_rate_max = 6900000; - fi->caps = FE_CAN_INVERSION_AUTO | + fi->caps = FE_CAN_INVERSION_AUTO | FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | @@ -236,7 +236,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name) fi->frequency_max = 861000000; fi->frequency_stepsize = 62500; - fi->caps = FE_CAN_INVERSION_AUTO | + fi->caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_2_3 | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 4a9c137095fe..98be63ae8590 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -1263,7 +1263,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp static int set_v4lstd(struct i2c_client *client) { struct cx25840_state *state = to_state(i2c_get_clientdata(client)); - u8 fmt = 0; /* zero is autodetect */ + u8 fmt = 0; /* zero is autodetect */ u8 pal_m = 0; /* First tests should be against specific std */ diff --git a/drivers/media/i2c/cx25840/cx25840-core.h b/drivers/media/i2c/cx25840/cx25840-core.h index 55432ed42714..fb13a624d2e3 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.h +++ b/drivers/media/i2c/cx25840/cx25840-core.h @@ -118,7 +118,7 @@ static inline bool is_cx23888(struct cx25840_state *state) } /* ----------------------------------------------------------------------- */ -/* cx25850-core.c */ +/* cx25850-core.c */ int cx25840_write(struct i2c_client *client, u16 addr, u8 value); int cx25840_write4(struct i2c_client *client, u16 addr, u32 value); u8 cx25840_read(struct i2c_client *client, u16 addr); diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c index 548382b2b2e6..ad7f66c7aac8 100644 --- a/drivers/media/i2c/cx25840/cx25840-ir.c +++ b/drivers/media/i2c/cx25840/cx25840-ir.c @@ -28,7 +28,7 @@ static unsigned int ir_debug; module_param(ir_debug, int, 0644); MODULE_PARM_DESC(ir_debug, "enable integrated IR debug messages"); -#define CX25840_IR_REG_BASE 0x200 +#define CX25840_IR_REG_BASE 0x200 #define CX25840_IR_CNTRL_REG 0x200 #define CNTRL_WIN_3_3 0x00000000 diff --git a/drivers/media/i2c/ks0127.c b/drivers/media/i2c/ks0127.c index ab536c4a7115..5905ed6f8397 100644 --- a/drivers/media/i2c/ks0127.c +++ b/drivers/media/i2c/ks0127.c @@ -195,7 +195,7 @@ struct adjust { struct ks0127 { struct v4l2_subdev sd; v4l2_std_id norm; - u8 regs[256]; + u8 regs[256]; }; static inline struct ks0127 *to_ks0127(struct v4l2_subdev *sd) diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index c6c32f649777..fd229bc8a0e5 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -412,12 +412,12 @@ static struct regval_list ov7670_fmt_yuv422[] = { { REG_COM1, 0 }, /* CCIR601 */ { REG_COM15, COM15_R00FF }, { REG_COM9, 0x48 }, /* 32x gain ceiling; 0x8 is reserved bit */ - { 0x4f, 0x80 }, /* "matrix coefficient 1" */ - { 0x50, 0x80 }, /* "matrix coefficient 2" */ + { 0x4f, 0x80 }, /* "matrix coefficient 1" */ + { 0x50, 0x80 }, /* "matrix coefficient 2" */ { 0x51, 0 }, /* vb */ - { 0x52, 0x22 }, /* "matrix coefficient 4" */ - { 0x53, 0x5e }, /* "matrix coefficient 5" */ - { 0x54, 0x80 }, /* "matrix coefficient 6" */ + { 0x52, 0x22 }, /* "matrix coefficient 4" */ + { 0x53, 0x5e }, /* "matrix coefficient 5" */ + { 0x54, 0x80 }, /* "matrix coefficient 6" */ { REG_COM13, COM13_GAMMA|COM13_UVSAT }, { 0xff, 0xff }, }; @@ -427,13 +427,13 @@ static struct regval_list ov7670_fmt_rgb565[] = { { REG_RGB444, 0 }, /* No RGB444 please */ { REG_COM1, 0x0 }, /* CCIR601 */ { REG_COM15, COM15_RGB565 }, - { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */ - { 0x4f, 0xb3 }, /* "matrix coefficient 1" */ - { 0x50, 0xb3 }, /* "matrix coefficient 2" */ + { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */ + { 0x4f, 0xb3 }, /* "matrix coefficient 1" */ + { 0x50, 0xb3 }, /* "matrix coefficient 2" */ { 0x51, 0 }, /* vb */ - { 0x52, 0x3d }, /* "matrix coefficient 4" */ - { 0x53, 0xa7 }, /* "matrix coefficient 5" */ - { 0x54, 0xe4 }, /* "matrix coefficient 6" */ + { 0x52, 0x3d }, /* "matrix coefficient 4" */ + { 0x53, 0xa7 }, /* "matrix coefficient 5" */ + { 0x54, 0xe4 }, /* "matrix coefficient 6" */ { REG_COM13, COM13_GAMMA|COM13_UVSAT }, { 0xff, 0xff }, }; @@ -443,13 +443,13 @@ static struct regval_list ov7670_fmt_rgb444[] = { { REG_RGB444, R444_ENABLE }, /* Enable xxxxrrrr ggggbbbb */ { REG_COM1, 0x0 }, /* CCIR601 */ { REG_COM15, COM15_R01FE|COM15_RGB565 }, /* Data range needed? */ - { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */ - { 0x4f, 0xb3 }, /* "matrix coefficient 1" */ - { 0x50, 0xb3 }, /* "matrix coefficient 2" */ + { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */ + { 0x4f, 0xb3 }, /* "matrix coefficient 1" */ + { 0x50, 0xb3 }, /* "matrix coefficient 2" */ { 0x51, 0 }, /* vb */ - { 0x52, 0x3d }, /* "matrix coefficient 4" */ - { 0x53, 0xa7 }, /* "matrix coefficient 5" */ - { 0x54, 0xe4 }, /* "matrix coefficient 6" */ + { 0x52, 0x3d }, /* "matrix coefficient 4" */ + { 0x53, 0xa7 }, /* "matrix coefficient 5" */ + { 0x54, 0xe4 }, /* "matrix coefficient 6" */ { REG_COM13, COM13_GAMMA|COM13_UVSAT|0x2 }, /* Magic rsvd bit */ { 0xff, 0xff }, }; @@ -667,7 +667,7 @@ static struct ov7670_format_struct { { .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .colorspace = V4L2_COLORSPACE_SRGB, - .regs = ov7670_fmt_yuv422, + .regs = ov7670_fmt_yuv422, .cmatrix = { 128, -128, 0, -34, -94, 128 }, }, { @@ -685,7 +685,7 @@ static struct ov7670_format_struct { { .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, .colorspace = V4L2_COLORSPACE_SRGB, - .regs = ov7670_fmt_raw, + .regs = ov7670_fmt_raw, .cmatrix = { 0, 0, 0, 0, 0, 0 }, }, }; diff --git a/drivers/media/i2c/saa6752hs.c b/drivers/media/i2c/saa6752hs.c index 7202d3a3219a..170cc65c4f23 100644 --- a/drivers/media/i2c/saa6752hs.c +++ b/drivers/media/i2c/saa6752hs.c @@ -72,8 +72,8 @@ struct saa6752hs_mpeg_params { /* video */ enum v4l2_mpeg_video_aspect vi_aspect; enum v4l2_mpeg_video_bitrate_mode vi_bitrate_mode; - __u32 vi_bitrate; - __u32 vi_bitrate_peak; + __u32 vi_bitrate; + __u32 vi_bitrate_peak; }; static const struct v4l2_format v4l2_format_table[] = @@ -98,8 +98,8 @@ struct saa6752hs_state { struct v4l2_ctrl *video_bitrate; struct v4l2_ctrl *video_bitrate_peak; }; - u32 revision; - int has_ac3; + u32 revision; + int has_ac3; struct saa6752hs_mpeg_params params; enum saa6752hs_videoformat video_format; v4l2_std_id standard; diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c index 7dd6cff6d811..e216cd768409 100644 --- a/drivers/media/i2c/saa7115.c +++ b/drivers/media/i2c/saa7115.c @@ -748,7 +748,7 @@ static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq) u32 acni; u32 hz; u64 f; - u8 acc = 0; /* reg 0x3a, audio clock control */ + u8 acc = 0; /* reg 0x3a, audio clock control */ /* Checks for chips that don't have audio clock (saa7111, saa7113) */ if (!saa711x_has_reg(state->ident, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD)) diff --git a/drivers/media/i2c/saa7127.c b/drivers/media/i2c/saa7127.c index 01784d441ae6..e58a150cec5c 100644 --- a/drivers/media/i2c/saa7127.c +++ b/drivers/media/i2c/saa7127.c @@ -132,109 +132,109 @@ struct i2c_reg_value { }; static const struct i2c_reg_value saa7129_init_config_extra[] = { - { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 }, - { SAA7127_REG_VTRIG, 0xfa }, + { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 }, + { SAA7127_REG_VTRIG, 0xfa }, { 0, 0 } }; static const struct i2c_reg_value saa7127_init_config_common[] = { - { SAA7127_REG_WIDESCREEN_CONFIG, 0x0d }, - { SAA7127_REG_WIDESCREEN_ENABLE, 0x00 }, - { SAA7127_REG_COPYGEN_0, 0x77 }, - { SAA7127_REG_COPYGEN_1, 0x41 }, - { SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */ - { SAA7127_REG_OUTPUT_PORT_CONTROL, 0xbf }, - { SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 }, - { SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 }, - { SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */ - { SAA7127_REG_LINE_21_ODD_0, 0x77 }, - { SAA7127_REG_LINE_21_ODD_1, 0x41 }, - { SAA7127_REG_LINE_21_EVEN_0, 0x88 }, - { SAA7127_REG_LINE_21_EVEN_1, 0x41 }, - { SAA7127_REG_RCV_PORT_CONTROL, 0x12 }, - { SAA7127_REG_VTRIG, 0xf9 }, - { SAA7127_REG_HTRIG_HI, 0x00 }, - { SAA7127_REG_RCV2_OUTPUT_START, 0x41 }, - { SAA7127_REG_RCV2_OUTPUT_END, 0xc3 }, - { SAA7127_REG_RCV2_OUTPUT_MSBS, 0x00 }, - { SAA7127_REG_TTX_REQUEST_H_START, 0x3e }, - { SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH, 0xb8 }, - { SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT, 0x03 }, - { SAA7127_REG_TTX_ODD_REQ_VERT_START, 0x15 }, - { SAA7127_REG_TTX_ODD_REQ_VERT_END, 0x16 }, - { SAA7127_REG_TTX_EVEN_REQ_VERT_START, 0x15 }, - { SAA7127_REG_TTX_EVEN_REQ_VERT_END, 0x16 }, - { SAA7127_REG_FIRST_ACTIVE, 0x1a }, - { SAA7127_REG_LAST_ACTIVE, 0x01 }, - { SAA7127_REG_MSB_VERTICAL, 0xc0 }, - { SAA7127_REG_DISABLE_TTX_LINE_LO_0, 0x00 }, - { SAA7127_REG_DISABLE_TTX_LINE_LO_1, 0x00 }, + { SAA7127_REG_WIDESCREEN_CONFIG, 0x0d }, + { SAA7127_REG_WIDESCREEN_ENABLE, 0x00 }, + { SAA7127_REG_COPYGEN_0, 0x77 }, + { SAA7127_REG_COPYGEN_1, 0x41 }, + { SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */ + { SAA7127_REG_OUTPUT_PORT_CONTROL, 0xbf }, + { SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 }, + { SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 }, + { SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */ + { SAA7127_REG_LINE_21_ODD_0, 0x77 }, + { SAA7127_REG_LINE_21_ODD_1, 0x41 }, + { SAA7127_REG_LINE_21_EVEN_0, 0x88 }, + { SAA7127_REG_LINE_21_EVEN_1, 0x41 }, + { SAA7127_REG_RCV_PORT_CONTROL, 0x12 }, + { SAA7127_REG_VTRIG, 0xf9 }, + { SAA7127_REG_HTRIG_HI, 0x00 }, + { SAA7127_REG_RCV2_OUTPUT_START, 0x41 }, + { SAA7127_REG_RCV2_OUTPUT_END, 0xc3 }, + { SAA7127_REG_RCV2_OUTPUT_MSBS, 0x00 }, + { SAA7127_REG_TTX_REQUEST_H_START, 0x3e }, + { SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH, 0xb8 }, + { SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT, 0x03 }, + { SAA7127_REG_TTX_ODD_REQ_VERT_START, 0x15 }, + { SAA7127_REG_TTX_ODD_REQ_VERT_END, 0x16 }, + { SAA7127_REG_TTX_EVEN_REQ_VERT_START, 0x15 }, + { SAA7127_REG_TTX_EVEN_REQ_VERT_END, 0x16 }, + { SAA7127_REG_FIRST_ACTIVE, 0x1a }, + { SAA7127_REG_LAST_ACTIVE, 0x01 }, + { SAA7127_REG_MSB_VERTICAL, 0xc0 }, + { SAA7127_REG_DISABLE_TTX_LINE_LO_0, 0x00 }, + { SAA7127_REG_DISABLE_TTX_LINE_LO_1, 0x00 }, { 0, 0 } }; #define SAA7127_60HZ_DAC_CONTROL 0x15 static const struct i2c_reg_value saa7127_init_config_60hz[] = { - { SAA7127_REG_BURST_START, 0x19 }, + { SAA7127_REG_BURST_START, 0x19 }, /* BURST_END is also used as a chip ID in saa7127_probe */ - { SAA7127_REG_BURST_END, 0x1d }, - { SAA7127_REG_CHROMA_PHASE, 0xa3 }, - { SAA7127_REG_GAINU, 0x98 }, - { SAA7127_REG_GAINV, 0xd3 }, - { SAA7127_REG_BLACK_LEVEL, 0x39 }, - { SAA7127_REG_BLANKING_LEVEL, 0x2e }, - { SAA7127_REG_VBI_BLANKING, 0x2e }, - { SAA7127_REG_DAC_CONTROL, 0x15 }, - { SAA7127_REG_BURST_AMP, 0x4d }, - { SAA7127_REG_SUBC3, 0x1f }, - { SAA7127_REG_SUBC2, 0x7c }, - { SAA7127_REG_SUBC1, 0xf0 }, - { SAA7127_REG_SUBC0, 0x21 }, - { SAA7127_REG_MULTI, 0x90 }, - { SAA7127_REG_CLOSED_CAPTION, 0x11 }, + { SAA7127_REG_BURST_END, 0x1d }, + { SAA7127_REG_CHROMA_PHASE, 0xa3 }, + { SAA7127_REG_GAINU, 0x98 }, + { SAA7127_REG_GAINV, 0xd3 }, + { SAA7127_REG_BLACK_LEVEL, 0x39 }, + { SAA7127_REG_BLANKING_LEVEL, 0x2e }, + { SAA7127_REG_VBI_BLANKING, 0x2e }, + { SAA7127_REG_DAC_CONTROL, 0x15 }, + { SAA7127_REG_BURST_AMP, 0x4d }, + { SAA7127_REG_SUBC3, 0x1f }, + { SAA7127_REG_SUBC2, 0x7c }, + { SAA7127_REG_SUBC1, 0xf0 }, + { SAA7127_REG_SUBC0, 0x21 }, + { SAA7127_REG_MULTI, 0x90 }, + { SAA7127_REG_CLOSED_CAPTION, 0x11 }, { 0, 0 } }; #define SAA7127_50HZ_PAL_DAC_CONTROL 0x02 static struct i2c_reg_value saa7127_init_config_50hz_pal[] = { - { SAA7127_REG_BURST_START, 0x21 }, + { SAA7127_REG_BURST_START, 0x21 }, /* BURST_END is also used as a chip ID in saa7127_probe */ - { SAA7127_REG_BURST_END, 0x1d }, - { SAA7127_REG_CHROMA_PHASE, 0x3f }, - { SAA7127_REG_GAINU, 0x7d }, - { SAA7127_REG_GAINV, 0xaf }, - { SAA7127_REG_BLACK_LEVEL, 0x33 }, - { SAA7127_REG_BLANKING_LEVEL, 0x35 }, - { SAA7127_REG_VBI_BLANKING, 0x35 }, - { SAA7127_REG_DAC_CONTROL, 0x02 }, - { SAA7127_REG_BURST_AMP, 0x2f }, - { SAA7127_REG_SUBC3, 0xcb }, - { SAA7127_REG_SUBC2, 0x8a }, - { SAA7127_REG_SUBC1, 0x09 }, - { SAA7127_REG_SUBC0, 0x2a }, - { SAA7127_REG_MULTI, 0xa0 }, - { SAA7127_REG_CLOSED_CAPTION, 0x00 }, + { SAA7127_REG_BURST_END, 0x1d }, + { SAA7127_REG_CHROMA_PHASE, 0x3f }, + { SAA7127_REG_GAINU, 0x7d }, + { SAA7127_REG_GAINV, 0xaf }, + { SAA7127_REG_BLACK_LEVEL, 0x33 }, + { SAA7127_REG_BLANKING_LEVEL, 0x35 }, + { SAA7127_REG_VBI_BLANKING, 0x35 }, + { SAA7127_REG_DAC_CONTROL, 0x02 }, + { SAA7127_REG_BURST_AMP, 0x2f }, + { SAA7127_REG_SUBC3, 0xcb }, + { SAA7127_REG_SUBC2, 0x8a }, + { SAA7127_REG_SUBC1, 0x09 }, + { SAA7127_REG_SUBC0, 0x2a }, + { SAA7127_REG_MULTI, 0xa0 }, + { SAA7127_REG_CLOSED_CAPTION, 0x00 }, { 0, 0 } }; #define SAA7127_50HZ_SECAM_DAC_CONTROL 0x08 static struct i2c_reg_value saa7127_init_config_50hz_secam[] = { - { SAA7127_REG_BURST_START, 0x21 }, + { SAA7127_REG_BURST_START, 0x21 }, /* BURST_END is also used as a chip ID in saa7127_probe */ - { SAA7127_REG_BURST_END, 0x1d }, - { SAA7127_REG_CHROMA_PHASE, 0x3f }, - { SAA7127_REG_GAINU, 0x6a }, - { SAA7127_REG_GAINV, 0x81 }, - { SAA7127_REG_BLACK_LEVEL, 0x33 }, - { SAA7127_REG_BLANKING_LEVEL, 0x35 }, - { SAA7127_REG_VBI_BLANKING, 0x35 }, - { SAA7127_REG_DAC_CONTROL, 0x08 }, - { SAA7127_REG_BURST_AMP, 0x2f }, - { SAA7127_REG_SUBC3, 0xb2 }, - { SAA7127_REG_SUBC2, 0x3b }, - { SAA7127_REG_SUBC1, 0xa3 }, - { SAA7127_REG_SUBC0, 0x28 }, - { SAA7127_REG_MULTI, 0x90 }, - { SAA7127_REG_CLOSED_CAPTION, 0x00 }, + { SAA7127_REG_BURST_END, 0x1d }, + { SAA7127_REG_CHROMA_PHASE, 0x3f }, + { SAA7127_REG_GAINU, 0x6a }, + { SAA7127_REG_GAINV, 0x81 }, + { SAA7127_REG_BLACK_LEVEL, 0x33 }, + { SAA7127_REG_BLANKING_LEVEL, 0x35 }, + { SAA7127_REG_VBI_BLANKING, 0x35 }, + { SAA7127_REG_DAC_CONTROL, 0x08 }, + { SAA7127_REG_BURST_AMP, 0x2f }, + { SAA7127_REG_SUBC3, 0xb2 }, + { SAA7127_REG_SUBC2, 0x3b }, + { SAA7127_REG_SUBC1, 0xa3 }, + { SAA7127_REG_SUBC0, 0x28 }, + { SAA7127_REG_MULTI, 0x90 }, + { SAA7127_REG_CLOSED_CAPTION, 0x00 }, { 0, 0 } }; diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c index 102467e00fb3..668c39cc29e8 100644 --- a/drivers/media/i2c/saa717x.c +++ b/drivers/media/i2c/saa717x.c @@ -82,13 +82,13 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) /* ----------------------------------------------------------------------- */ /* for audio mode */ -#define TUNER_AUDIO_MONO 0 /* LL */ -#define TUNER_AUDIO_STEREO 1 /* LR */ -#define TUNER_AUDIO_LANG1 2 /* LL */ -#define TUNER_AUDIO_LANG2 3 /* RR */ +#define TUNER_AUDIO_MONO 0 /* LL */ +#define TUNER_AUDIO_STEREO 1 /* LR */ +#define TUNER_AUDIO_LANG1 2 /* LL */ +#define TUNER_AUDIO_LANG2 3 /* RR */ -#define SAA717X_NTSC_WIDTH (704) -#define SAA717X_NTSC_HEIGHT (480) +#define SAA717X_NTSC_WIDTH (704) +#define SAA717X_NTSC_HEIGHT (480) /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/i2c/ths7303.c b/drivers/media/i2c/ths7303.c index 71a31352135c..8206bf7a5a8f 100644 --- a/drivers/media/i2c/ths7303.c +++ b/drivers/media/i2c/ths7303.c @@ -319,7 +319,7 @@ static const struct v4l2_subdev_core_ops ths7303_core_ops = { static const struct v4l2_subdev_ops ths7303_ops = { .core = &ths7303_core_ops, - .video = &ths7303_video_ops, + .video = &ths7303_video_ops, }; static int ths7303_probe(struct i2c_client *client, diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c index e6edda524856..772164b848ef 100644 --- a/drivers/media/i2c/tvaudio.c +++ b/drivers/media/i2c/tvaudio.c @@ -134,7 +134,7 @@ struct CHIPSTATE { /* thread */ struct task_struct *thread; struct timer_list wt; - int audmode; + int audmode; }; static inline struct CHIPSTATE *to_state(struct v4l2_subdev *sd) diff --git a/drivers/media/i2c/tvp7002_reg.h b/drivers/media/i2c/tvp7002_reg.h index 933673561fa2..3c8c8b0a6a4c 100644 --- a/drivers/media/i2c/tvp7002_reg.h +++ b/drivers/media/i2c/tvp7002_reg.h @@ -109,15 +109,15 @@ #define TVP7002_L_FRAME_STAT_LSBS 0x37 #define TVP7002_L_FRAME_STAT_MSBS 0x38 #define TVP7002_CLK_L_STAT_LSBS 0x39 -#define TVP7002_CLK_L_STAT_MSBS 0x3a +#define TVP7002_CLK_L_STAT_MSBS 0x3a #define TVP7002_HSYNC_W 0x3b #define TVP7002_VSYNC_W 0x3c -#define TVP7002_L_LENGTH_TOL 0x3d +#define TVP7002_L_LENGTH_TOL 0x3d /* Reserved 0x3e */ #define TVP7002_VIDEO_BWTH_CTL 0x3f #define TVP7002_AVID_START_PIXEL_LSBS 0x40 #define TVP7002_AVID_START_PIXEL_MSBS 0x41 -#define TVP7002_AVID_STOP_PIXEL_LSBS 0x42 +#define TVP7002_AVID_STOP_PIXEL_LSBS 0x42 #define TVP7002_AVID_STOP_PIXEL_MSBS 0x43 #define TVP7002_VBLK_F_0_START_L_OFF 0x44 #define TVP7002_VBLK_F_1_START_L_OFF 0x45 diff --git a/drivers/media/i2c/vpx3220.c b/drivers/media/i2c/vpx3220.c index 67de79b2d550..c3549fa55b62 100644 --- a/drivers/media/i2c/vpx3220.c +++ b/drivers/media/i2c/vpx3220.c @@ -201,7 +201,7 @@ static const unsigned short init_pal[] = { * skipped by the VFE) */ 0x8b, 16, /* Horizontal begin */ 0x8c, 768, /* Horizontal length */ - 0x8d, 784, /* Number of pixels + 0x8d, 784, /* Number of pixels * Must be >= Horizontal begin + Horizontal length */ 0x8f, 0xc00, /* Disable window 2 */ 0xf0, 0x77, /* 13.5 MHz transport, Forced diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c index 7dcf509e66d9..1902732f90e1 100644 --- a/drivers/media/pci/bt8xx/bttv-cards.c +++ b/drivers/media/pci/bt8xx/bttv-cards.c @@ -373,8 +373,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 10, + .gpiomux = { 2, 0, 0, 0 }, + .gpiomute = 10, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -385,8 +385,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 7, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, + .gpiomux = { 0, 1, 2, 3 }, + .gpiomute = 4, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -397,8 +397,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 7, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 4, 0, 2, 3 }, - .gpiomute = 1, + .gpiomux = { 4, 0, 2, 3 }, + .gpiomute = 1, .no_msp34xx = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, @@ -414,7 +414,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0 }, + .gpiomux = { 0 }, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -425,8 +425,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 3, .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = { 0, 1, 0, 1 }, - .gpiomute = 3, + .gpiomux = { 0, 1, 0, 1 }, + .gpiomute = 3, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -437,7 +437,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomask = 0x0f, - .gpiomux = { 0x0c, 0x04, 0x08, 0x04 }, + .gpiomux = { 0x0c, 0x04, 0x08, 0x04 }, /* 0x04 for some cards ?? */ .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -451,7 +451,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), - .gpiomux = { 0 }, + .gpiomux = { 0 }, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -464,8 +464,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xc00, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0xc00, 0x800, 0x400 }, - .gpiomute = 0xc00, + .gpiomux = { 0, 0xc00, 0x800, 0x400 }, + .gpiomute = 0xc00, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -477,7 +477,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 3, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 1, 1, 2, 3 }, + .gpiomux = { 1, 1, 2, 3 }, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -489,8 +489,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x0f, /* old: 7 */ .muxsel = MUXSEL(2, 0, 1, 1), - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, + .gpiomux = { 0, 1, 2, 3 }, + .gpiomute = 4, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -502,8 +502,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x3014f, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x20001,0x10001, 0, 0 }, - .gpiomute = 10, + .gpiomux = { 0x20001,0x10001, 0, 0 }, + .gpiomute = 10, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -516,7 +516,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 13, 14, 11, 7 }, + .gpiomux = { 13, 14, 11, 7 }, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -527,7 +527,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 13, 14, 11, 7 }, + .gpiomux = { 13, 14, 11, 7 }, .msp34xx_alt = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -542,8 +542,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 7, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */ - .gpiomute = 4, + .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */ + .gpiomute = 4, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -555,8 +555,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0, 1, 0 }, - .gpiomute = 10, + .gpiomux = { 0, 0, 1, 0 }, + .gpiomute = 10, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -571,7 +571,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), /* 2003-10-20 by "Anton A. Arapov" */ .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, - .gpiomute = 0x002000, + .gpiomute = 0x002000, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -583,8 +583,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x8300f8, .muxsel = MUXSEL(2, 3, 1, 1, 0), - .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 }, - .gpiomute = 0xcfa007, + .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 }, + .gpiomute = 0xcfa007, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, .volume_gpio = winview_volume, @@ -597,7 +597,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 1, 0, 0, 0 }, + .gpiomux = { 1, 0, 0, 0 }, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -608,7 +608,7 @@ struct tvcard bttv_tvcards[] = { .svhs = NO_SVHS, .gpiomask = 0x8dff00, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0 }, + .gpiomux = { 0 }, .no_msp34xx = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -631,8 +631,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1800, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, + .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, + .gpiomute = 0x1800, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, @@ -644,8 +644,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xc00, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 1, 0x800, 0x400 }, - .gpiomute = 0xc00, + .gpiomux = { 0, 1, 0x800, 0x400 }, + .gpiomute = 0xc00, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -659,7 +659,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 7, .muxsel = MUXSEL(2, 3, 0), /* input 2 is digital */ /* .digital_mode= DIGITAL_MODE_CAMERA, */ - .gpiomux = { 0, 0, 0, 0 }, + .gpiomux = { 0, 0, 0, 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ALPS_TSBB5_PAL_I, @@ -674,8 +674,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xe00, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = {0x400, 0x400, 0x400, 0x400 }, - .gpiomute = 0xc00, + .gpiomux = {0x400, 0x400, 0x400, 0x400 }, + .gpiomute = 0xc00, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -690,7 +690,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x1f0fff, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, - .gpiomute = 0x40000, + .gpiomute = 0x40000, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, @@ -702,8 +702,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .gpiomask = 7, .muxsel = MUXSEL(2, 0, 1, 1), - .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, + .gpiomux = { 0, 1, 2, 3 }, + .gpiomute = 4, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -714,8 +714,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1800, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, + .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, + .gpiomute = 0x1800, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_SECAM, .tuner_addr = ADDR_UNSET, @@ -729,8 +729,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1f0fff, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 }, - .gpiomute = 0x40000, + .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 }, + .gpiomute = 0x40000, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, @@ -774,7 +774,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 1, /* was: 4 */ .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), - .gpiomux = { 0 }, + .gpiomux = { 0 }, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .muxsel_hook = PXC200_muxsel, @@ -787,8 +787,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1800, /* 0x8dfe00 */ .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0x0800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, + .gpiomux = { 0, 0x0800, 0x1000, 0x1000 }, + .gpiomute = 0x1800, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -800,7 +800,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .gpiomask = 1, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 1, 0, 0, 0 }, + .gpiomux = { 1, 0, 0, 0 }, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -814,7 +814,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0 }, + .gpiomux = { 0 }, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -825,8 +825,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xffff00, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x500, 0, 0x300, 0x900 }, - .gpiomute = 0x900, + .gpiomux = { 0x500, 0, 0x300, 0x900 }, + .gpiomute = 0x900, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -840,8 +840,8 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1, 0), /* Alexander Varakin [stereo version] */ .gpiomask = 0xb33000, - .gpiomux = { 0x122000,0x1000,0x0000,0x620000 }, - .gpiomute = 0x800000, + .gpiomux = { 0x122000,0x1000,0x0000,0x620000 }, + .gpiomute = 0x800000, /* Audio Routing for "WinFast 2000 XP" (no tv stereo !) gpio23 -- hef4052:nEnable (0x800000) gpio12 -- hef4052:A1 @@ -867,8 +867,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1800, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, + .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, + .gpiomute = 0x1800, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -882,8 +882,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1800, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, + .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, + .gpiomute = 0x1800, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -896,8 +896,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xff, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x21, 0x20, 0x24, 0x2c }, - .gpiomute = 0x29, + .gpiomux = { 0x21, 0x20, 0x24, 0x2c }, + .gpiomute = 0x29, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = UNSET, @@ -910,8 +910,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x551e00, .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = { 0x551400, 0x551200, 0, 0 }, - .gpiomute = 0x551c00, + .gpiomux = { 0x551400, 0x551200, 0, 0 }, + .gpiomute = 0x551c00, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, @@ -924,8 +924,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x03000F, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 2, 0xd0001, 0, 0 }, - .gpiomute = 1, + .gpiomux = { 2, 0xd0001, 0, 0 }, + .gpiomute = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -939,8 +939,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 7, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 4, 0, 2, 3 }, - .gpiomute = 1, + .gpiomux = { 4, 0, 2, 3 }, + .gpiomute = 1, .no_msp34xx = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, @@ -954,7 +954,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 13, 4, 11, 7 }, + .gpiomux = { 13, 4, 11, 7 }, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -968,7 +968,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0, 0, 0}, + .gpiomux = { 0, 0, 0, 0}, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, @@ -981,8 +981,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xe00b, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 }, - .gpiomute = 0xff3ffc, + .gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 }, + .gpiomute = 0xff3ffc, .no_msp34xx = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -996,8 +996,8 @@ struct tvcard bttv_tvcards[] = { .svhs = NO_SVHS, .gpiomask = 3, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 1, 1, 0, 2 }, - .gpiomute = 3, + .gpiomux = { 1, 1, 0, 2 }, + .gpiomute = 3, .no_msp34xx = 1, .pll = PLL_NONE, .tuner_type = UNSET, @@ -1010,7 +1010,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), - .gpiomux = { 0 }, + .gpiomux = { 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -1023,8 +1023,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xbcf03f, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0 }, - .gpiomute = 0xbcb03f, + .gpiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0 }, + .gpiomute = 0xbcb03f, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4039FR5_NTSC, @@ -1037,8 +1037,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x70000, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, - .gpiomute = 0x40000, + .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, + .gpiomute = 0x40000, .no_msp34xx = 1, .pll = PLL_35, .tuner_type = TUNER_PHILIPS_PAL_I, @@ -1054,8 +1054,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = {2,0,0,0 }, - .gpiomute = 1, + .gpiomux = {2,0,0,0 }, + .gpiomute = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1067,7 +1067,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x010f00, .muxsel = MUXSEL(2, 3, 0, 0), - .gpiomux = {0x10000, 0, 0x10000, 0 }, + .gpiomux = {0x10000, 0, 0x10000, 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ALPS_TSHC6_NTSC, @@ -1083,8 +1083,8 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0xAA0000, .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */ /* .digital_mode= DIGITAL_MODE_CAMERA, */ - .gpiomux = { 0x20000, 0, 0x80000, 0x80000 }, - .gpiomute = 0xa8000, + .gpiomux = { 0x20000, 0, 0x80000, 0x80000 }, + .gpiomute = 0xa8000, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, @@ -1108,7 +1108,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 7, .muxsel = MUXSEL(2, 0, 1, 1), .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, + .gpiomute = 4, .pll = PLL_28, .tuner_type = UNSET /* TUNER_ALPS_TMDH2_NTSC */, .tuner_addr = ADDR_UNSET, @@ -1123,8 +1123,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 3, .gpiomask = 0x03000F, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 1, 0xd0001, 0, 0 }, - .gpiomute = 10, + .gpiomux = { 1, 0xd0001, 0, 0 }, + .gpiomute = 10, /* sound path (5 sources): MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable) 0= ext. Audio IN @@ -1147,8 +1147,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x1c, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0, 0, 0x10, 8 }, - .gpiomute = 4, + .gpiomux = { 0, 0, 0x10, 8 }, + .gpiomute = 4, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1166,8 +1166,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x18e0, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x0000,0x0800,0x1000,0x1000 }, - .gpiomute = 0x18e0, + .gpiomux = { 0x0000,0x0800,0x1000,0x1000 }, + .gpiomute = 0x18e0, /* For cards with tda9820/tda9821: 0x0000: Tuner normal stereo 0x0080: Tuner A2 SAP (second audio program = Zweikanalton) @@ -1186,7 +1186,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0xF, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 10, + .gpiomute = 10, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -1202,7 +1202,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x1800, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0x800, 0x1000, 0x1000 }, - .gpiomute = 0x1800, + .gpiomute = 0x1800, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1232,7 +1232,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0xe00, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x400, 0x400, 0x400, 0x400 }, - .gpiomute = 0x800, + .gpiomute = 0x800, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4036FY5_NTSC, .tuner_addr = ADDR_UNSET, @@ -1246,7 +1246,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x03000F, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 1, + .gpiomute = 1, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -1263,7 +1263,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 11, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 1 }, - .gpiomute = 8, + .gpiomute = 8, .pll = PLL_35, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -1293,7 +1293,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0xFF, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 1, 0, 4, 4 }, - .gpiomute = 9, + .gpiomute = 9, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1306,8 +1306,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xf03f, .muxsel = MUXSEL(2, 3, 1, 0), - .gpiomux = { 0xbffe, 0, 0xbfff, 0 }, - .gpiomute = 0xbffe, + .gpiomux = { 0xbffe, 0, 0xbfff, 0 }, + .gpiomute = 0xbffe, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, .tuner_addr = ADDR_UNSET, @@ -1322,7 +1322,7 @@ struct tvcard bttv_tvcards[] = { .svhs = NO_SVHS, .gpiomask = 1, .muxsel = MUXSEL(2, 3, 0, 1), - .gpiomux = { 0, 0, 1, 0 }, + .gpiomux = { 0, 0, 1, 0 }, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL, @@ -1339,8 +1339,8 @@ struct tvcard bttv_tvcards[] = { /* Radio changed from 1e80 to 0x800 to make FlyVideo2000S in .hu happy (gm)*/ /* -dk-???: set mute=0x1800 for tda9874h daughterboard */ - .gpiomux = { 0x0000,0x0800,0x1000,0x1000 }, - .gpiomute = 0x1800, + .gpiomux = { 0x0000,0x0800,0x1000,0x1000 }, + .gpiomute = 0x1800, .audio_mode_gpio= fv2000s_audio, .no_msp34xx = 1, .pll = PLL_28, @@ -1354,8 +1354,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0xffff00, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x500, 0x500, 0x300, 0x900 }, - .gpiomute = 0x900, + .gpiomux = { 0x500, 0x500, 0x300, 0x900 }, + .gpiomute = 0x900, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1389,7 +1389,7 @@ struct tvcard bttv_tvcards[] = { /* 0x100000: 1=MSP enabled (0=disable again) * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ .gpiomux = {0x947fff, 0x987fff,0x947fff,0x947fff }, - .gpiomute = 0x947fff, + .gpiomute = 0x947fff, /* tvtuner, radio, external,internal, mute, stereo * tuner, Composit, SVid, Composit-on-Svid-adapter */ .muxsel = MUXSEL(2, 3, 0, 1), @@ -1409,7 +1409,7 @@ struct tvcard bttv_tvcards[] = { /* 0x100000: 1=MSP enabled (0=disable again) * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */ .gpiomux = {0x947fff, 0x987fff,0x947fff,0x947fff }, - .gpiomute = 0x947fff, + .gpiomute = 0x947fff, /* tvtuner, radio, external,internal, mute, stereo * tuner, Composit, SVid, Composit-on-Svid-adapter */ .muxsel = MUXSEL(2, 3, 0, 1), @@ -1438,7 +1438,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */ - .gpiomute = 13, + .gpiomute = 13, .pll = PLL_28, .tuner_type = TUNER_LG_PAL_I_FM, .tuner_addr = ADDR_UNSET, @@ -1473,8 +1473,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x3f, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 0x01, 0x00, 0x03, 0x03 }, - .gpiomute = 0x09, + .gpiomux = { 0x01, 0x00, 0x03, 0x03 }, + .gpiomute = 0x09, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1525,7 +1525,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */ .muxsel = MUXSEL(2, 1, 1), .gpiomux = { 0, 1, 2, 2 }, - .gpiomute = 4, + .gpiomute = 4, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -1542,7 +1542,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x140007, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, + .gpiomute = 4, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= windvr_audio, @@ -1575,7 +1575,7 @@ struct tvcard bttv_tvcards[] = { * gpiomux =1: lower volume, 2+3: mute * btwincap uses 0x80000/0x80003 */ - .gpiomute = 4, + .gpiomute = 4, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1626,7 +1626,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x0f0f80, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = {0x030000, 0x010000, 0, 0 }, - .gpiomute = 0x020000, + .gpiomute = 0x020000, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC_M, @@ -1829,7 +1829,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 7, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3}, - .gpiomute = 4, + .gpiomute = 4, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -1872,7 +1872,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), /* Tuner, Radio, external, internal, off, on */ .gpiomux = { 0x08, 0x0f, 0x0a, 0x08 }, - .gpiomute = 0x0f, + .gpiomute = 0x0f, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, @@ -2139,7 +2139,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x008007, .muxsel = MUXSEL(2, 3, 0, 0), .gpiomux = { 0, 0, 0, 0 }, - .gpiomute = 0x000003, + .gpiomute = 0x000003, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -2182,7 +2182,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x008007, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, - .gpiomute = 3, + .gpiomute = 3, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -2297,7 +2297,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0xFF, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 10, + .gpiomute = 10, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -2326,7 +2326,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x3f, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = {0x31, 0x31, 0x31, 0x31 }, - .gpiomute = 0x31, + .gpiomute = 0x31, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC_M, @@ -2440,7 +2440,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1), .gpiomask = 0x00e00007, .gpiomux = { 0x00400005, 0, 0x00000001, 0 }, - .gpiomute = 0x00c00007, + .gpiomute = 0x00c00007, .no_msp34xx = 1, .no_tda7432 = 1, .has_dvb = 1, @@ -2455,7 +2455,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x01fe00, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, - .gpiomute = 0x002000, + .gpiomute = 0x002000, .pll = PLL_28, .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, .tuner_addr = 0xc1 >>1, @@ -2470,7 +2470,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x001c0007, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, - .gpiomute = 3, + .gpiomute = 3, .pll = PLL_28, .tuner_type = TUNER_TENA_9533_DI, .tuner_addr = ADDR_UNSET, @@ -2505,7 +2505,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x3f, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x21, 0x20, 0x24, 0x2c }, - .gpiomute = 0x29, + .gpiomute = 0x29, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_YMEC_TVF_5533MF, @@ -2549,8 +2549,8 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 2, 0, 0, 0 }, - .gpiomute = 1, + .gpiomux = { 2, 0, 0, 0 }, + .gpiomute = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, @@ -2563,7 +2563,7 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x108007, .muxsel = MUXSEL(2, 3, 1, 1), - .gpiomux = { 100000, 100002, 100002, 100000 }, + .gpiomux = { 100000, 100002, 100002, 100000 }, .no_msp34xx = 1, .no_tda7432 = 1, .pll = PLL_28, @@ -2599,7 +2599,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 7, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3 }, - .gpiomute = 4, + .gpiomute = 4, .tuner_type = TUNER_TEMIC_4009FR5_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -2635,7 +2635,7 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1), .gpiomask = 0x00e00007, .gpiomux = { 0x00400005, 0, 0x00000001, 0 }, - .gpiomute = 0x00c00007, + .gpiomute = 0x00c00007, .no_msp34xx = 1, .no_tda7432 = 1, }, @@ -2679,7 +2679,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x008007, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */ - .gpiomute = 3, /* CONTVFMi */ + .gpiomute = 3, /* CONTVFMi */ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */ .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -2702,7 +2702,7 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x060040, .muxsel = MUXSEL(2, 3, 3), .gpiomux = { 0x60000, 0x60000, 0x20000, 0x20000 }, - .gpiomute = 0, + .gpiomute = 0, .tuner_type = TUNER_TCL_MF02GIP_5N, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -2752,8 +2752,8 @@ struct tvcard bttv_tvcards[] = { /* Bruno Christo * * GeoVision GV-800(S) has 4 Conexant Fusion 878A: - * 1 audio input per BT878A = 4 audio inputs - * 4 video inputs per BT878A = 16 video inputs + * 1 audio input per BT878A = 4 audio inputs + * 4 video inputs per BT878A = 16 video inputs * This is the first BT878A chip of the GV-800(S). It's the * "master" chip and it controls the video inputs through an * analog multiplexer (a CD22M3494) via some GPIO pins. The @@ -2779,8 +2779,8 @@ struct tvcard bttv_tvcards[] = { /* Bruno Christo * * GeoVision GV-800(S) has 4 Conexant Fusion 878A: - * 1 audio input per BT878A = 4 audio inputs - * 4 video inputs per BT878A = 16 video inputs + * 1 audio input per BT878A = 4 audio inputs + * 4 video inputs per BT878A = 16 video inputs * The 3 other BT878A chips are "slave" chips of the GV-800(S) * and should use this card type. * The audio input is not working yet. @@ -4784,9 +4784,9 @@ static void gv800s_write(struct bttv *btv, * GPIO bits 0-9 are used for the analog switch: * 00 - 03: camera selector * 04 - 06: 878A (controller) selector - * 16: cselect + * 16: cselect * 17: strobe - * 18: data (1->on, 0->off) + * 18: data (1->on, 0->off) * 19: reset */ const u32 ADDRESS = ((xaddr&0xf) | (yaddr&3)<<4); @@ -4882,7 +4882,7 @@ void __init bttv_check_chipset(void) int pcipci_fail = 0; struct pci_dev *dev = NULL; - if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) /* should check if target is AGP */ + if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) /* should check if target is AGP */ pcipci_fail = 1; if (pci_pci_problems & (PCIPCI_TRITON|PCIPCI_NATOMA|PCIPCI_VIAETBF)) triton1 = 1; diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c index ac7674700685..da49c5567db5 100644 --- a/drivers/media/pci/bt8xx/bttv-input.c +++ b/drivers/media/pci/bt8xx/bttv-input.c @@ -349,12 +349,12 @@ static int get_key_pv951(struct IR_i2c *ir, enum rc_proto *protocol, * NOTE: * lirc_i2c maps the pv951 code as: * addr = 0x61D6 - * cmd = bit_reverse (b) + * cmd = bit_reverse (b) * So, it seems that this device uses NEC extended * I decided to not fix the table, due to two reasons: - * 1) Without the actual device, this is only a guess; - * 2) As the addr is not reported via I2C, nor can be changed, - * the device is bound to the vendor-provided RC. + * 1) Without the actual device, this is only a guess; + * 2) As the addr is not reported via I2C, nor can be changed, + * the device is bound to the vendor-provided RC. */ *protocol = RC_PROTO_UNKNOWN; diff --git a/drivers/media/pci/bt8xx/bttv.h b/drivers/media/pci/bt8xx/bttv.h index cc555a4d4462..a27384adadd2 100644 --- a/drivers/media/pci/bt8xx/bttv.h +++ b/drivers/media/pci/bt8xx/bttv.h @@ -165,7 +165,7 @@ #define BTTV_BOARD_PV_M4900 0x8b #define BTTV_BOARD_OSPREY440 0x8c #define BTTV_BOARD_ASOUND_SKYEYE 0x8d -#define BTTV_BOARD_SABRENT_TVFM 0x8e +#define BTTV_BOARD_SABRENT_TVFM 0x8e #define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f #define BTTV_BOARD_MACHTV_MAGICTV 0x90 #define BTTV_BOARD_SSAI_SECURITY 0x91 @@ -265,7 +265,7 @@ extern struct tvcard bttv_tvcards[]; * that they are changed to octal. One should not use hex number, macros, or * anything else with this macro. Just use plain integers from 0 to 3. */ -#define _MUXSELf(a) 0##a << 30 +#define _MUXSELf(a) 0##a << 30 #define _MUXSELe(a, b...) 0##a << 28 | _MUXSELf(b) #define _MUXSELd(a, b...) 0##a << 26 | _MUXSELe(b) #define _MUXSELc(a, b...) 0##a << 24 | _MUXSELd(b) diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index cb1b5e611130..7a86e7295166 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h @@ -141,7 +141,7 @@ struct bttv_ir { bool rc5_gpio; /* Is RC5 legacy GPIO enabled? */ u32 last_bit; /* last raw bit seen */ u32 code; /* raw code under construction */ - ktime_t base_time; /* time of last seen code */ + ktime_t base_time; /* time of last seen code */ bool active; /* building raw code */ }; @@ -400,8 +400,8 @@ struct bttv { int i2c_state, i2c_rc; int i2c_done; wait_queue_head_t i2c_queue; - struct v4l2_subdev *sd_msp34xx; - struct v4l2_subdev *sd_tvaudio; + struct v4l2_subdev *sd_msp34xx; + struct v4l2_subdev *sd_tvaudio; struct v4l2_subdev *sd_tda7432; /* video4linux (1) */ diff --git a/drivers/media/pci/cx18/cx18-alsa-pcm.c b/drivers/media/pci/cx18/cx18-alsa-pcm.c index aadd76466aec..4f31042a442a 100644 --- a/drivers/media/pci/cx18/cx18-alsa-pcm.c +++ b/drivers/media/pci/cx18/cx18-alsa-pcm.c @@ -41,7 +41,7 @@ MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm"); #define dprintk(fmt, arg...) do { \ if (pcm_debug) \ printk(KERN_INFO "cx18-alsa-pcm %s: " fmt, \ - __func__, ##arg); \ + __func__, ##arg); \ } while (0) static const struct snd_pcm_hardware snd_cx18_hw_capture = { diff --git a/drivers/media/pci/cx18/cx18-av-audio.c b/drivers/media/pci/cx18/cx18-av-audio.c index 8b95e9aae576..3abc54cbe4a1 100644 --- a/drivers/media/pci/cx18/cx18-av-audio.c +++ b/drivers/media/pci/cx18/cx18-av-audio.c @@ -31,7 +31,7 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) * would ideally be: * * NTSC Color subcarrier freq * 8 = - * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz + * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz * * The accidents of history and rationale that explain from where this * combination of magic numbers originate can be found in: diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c index cf8817e9c8b9..eda343322ee0 100644 --- a/drivers/media/pci/cx18/cx18-av-core.c +++ b/drivers/media/pci/cx18/cx18-av-core.c @@ -236,10 +236,10 @@ static void cx18_av_initialize(struct v4l2_subdev *sd) */ cx18_av_and_or4(cx, CXADEC_AFE_CTRL, 0xFF000000, 0x00005D00); -/* if(dwEnable && dw3DCombAvailable) { */ -/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */ +/* if(dwEnable && dw3DCombAvailable) { */ +/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */ /* } else { */ -/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */ +/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */ /* } */ cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F); default_volume = cx18_av_read(cx, 0x8d4); @@ -319,13 +319,13 @@ void cx18_av_std_setup(struct cx18 *cx) * vblank656: half lines after line 625/mid-313 of blanked video * vblank: half lines, after line 5/317, of blanked video * vactive: half lines of active video + - * 5 half lines after the end of active video + * 5 half lines after the end of active video * * As far as I can tell: * vblank656 starts counting from the falling edge of the first - * vsync pulse (start of line 1 or mid-313) + * vsync pulse (start of line 1 or mid-313) * vblank starts counting from the after the 5 vsync pulses and - * 5 or 4 equalization pulses (start of line 6 or 318) + * 5 or 4 equalization pulses (start of line 6 or 318) * * For 625 line systems the driver will extract VBI information * from lines 6-23 and lines 318-335 (but the slicer can only @@ -395,9 +395,9 @@ void cx18_av_std_setup(struct cx18 *cx) * * As far as I can tell: * vblank656 starts counting from the falling edge of the first - * vsync pulse (start of line 4 or mid-266) + * vsync pulse (start of line 4 or mid-266) * vblank starts counting from the after the 6 vsync pulses and - * 6 or 5 equalization pulses (start of line 10 or 272) + * 6 or 5 equalization pulses (start of line 10 or 272) * * For 525 line systems the driver will extract VBI information * from lines 10-21 and lines 273-284. @@ -851,7 +851,7 @@ static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm) struct cx18_av_state *state = to_cx18_av_state(sd); struct cx18 *cx = v4l2_get_subdevdata(sd); - u8 fmt = 0; /* zero is autodetect */ + u8 fmt = 0; /* zero is autodetect */ u8 pal_m = 0; if (state->radio == 0 && state->std == norm) diff --git a/drivers/media/pci/cx18/cx18-av-core.h b/drivers/media/pci/cx18/cx18-av-core.h index c976ce6e7a78..1a37f269d2e4 100644 --- a/drivers/media/pci/cx18/cx18-av-core.h +++ b/drivers/media/pci/cx18/cx18-av-core.h @@ -349,7 +349,7 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl) } /* ----------------------------------------------------------------------- */ -/* cx18_av-core.c */ +/* cx18_av-core.c */ int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value); int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value); diff --git a/drivers/media/pci/cx18/cx18-cards.c b/drivers/media/pci/cx18/cx18-cards.c index 11e898e66ce9..c2cf965d639e 100644 --- a/drivers/media/pci/cx18/cx18-cards.c +++ b/drivers/media/pci/cx18/cx18-cards.c @@ -388,7 +388,7 @@ static const struct cx18_card cx18_card_cnxt_raptor_pal = { { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 }, }, .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, + { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 }, }, @@ -439,7 +439,7 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = { { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, }, .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, + { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, }, .tuners = { @@ -485,7 +485,7 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = { { CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 }, }, .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, + { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, }, .tuners = { @@ -538,7 +538,7 @@ static const struct cx18_card cx18_card_leadtek_dvr3100h = { { CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 }, }, .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, + { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, }, .tuners = { diff --git a/drivers/media/pci/cx18/cx18-cards.h b/drivers/media/pci/cx18/cx18-cards.h index 5478f62b5cf3..02d0fb703a41 100644 --- a/drivers/media/pci/cx18/cx18-cards.h +++ b/drivers/media/pci/cx18/cx18-cards.h @@ -29,20 +29,20 @@ /* video inputs */ #define CX18_CARD_INPUT_VID_TUNER 1 -#define CX18_CARD_INPUT_SVIDEO1 2 -#define CX18_CARD_INPUT_SVIDEO2 3 -#define CX18_CARD_INPUT_COMPOSITE1 4 -#define CX18_CARD_INPUT_COMPOSITE2 5 -#define CX18_CARD_INPUT_COMPONENT1 6 +#define CX18_CARD_INPUT_SVIDEO1 2 +#define CX18_CARD_INPUT_SVIDEO2 3 +#define CX18_CARD_INPUT_COMPOSITE1 4 +#define CX18_CARD_INPUT_COMPOSITE2 5 +#define CX18_CARD_INPUT_COMPONENT1 6 /* audio inputs */ #define CX18_CARD_INPUT_AUD_TUNER 1 -#define CX18_CARD_INPUT_LINE_IN1 2 -#define CX18_CARD_INPUT_LINE_IN2 3 +#define CX18_CARD_INPUT_LINE_IN1 2 +#define CX18_CARD_INPUT_LINE_IN2 3 #define CX18_CARD_MAX_VIDEO_INPUTS 6 #define CX18_CARD_MAX_AUDIO_INPUTS 3 -#define CX18_CARD_MAX_TUNERS 2 +#define CX18_CARD_MAX_TUNERS 2 /* V4L2 capability aliases */ #define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ @@ -51,7 +51,7 @@ V4L2_CAP_SLICED_VBI_CAPTURE) struct cx18_card_video_input { - u8 video_type; /* video input type */ + u8 video_type; /* video input type */ u8 audio_index; /* index in cx18_card_audio_input array */ u32 video_input; /* hardware video input */ }; @@ -74,7 +74,7 @@ struct cx18_card_pci_info { /* The mask is the set of bits used by the operation */ struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */ - u32 direction; /* DIR setting. Leave to 0 if no init is needed */ + u32 direction; /* DIR setting. Leave to 0 if no init is needed */ u32 initial_value; }; @@ -86,16 +86,16 @@ struct cx18_gpio_i2c_slave_reset { u32 ir_reset_mask; /* GPIO to reset the Zilog Z8F0811 IR contoller */ }; -struct cx18_gpio_audio_input { /* select tuner/line in input */ - u32 mask; /* leave to 0 if not supported */ +struct cx18_gpio_audio_input { /* select tuner/line in input */ + u32 mask; /* leave to 0 if not supported */ u32 tuner; u32 linein; u32 radio; }; struct cx18_card_tuner { - v4l2_std_id std; /* standard for which the tuner is suitable */ - int tuner; /* tuner ID (from tuner.h) */ + v4l2_std_id std; /* standard for which the tuner is suitable */ + int tuner; /* tuner ID (from tuner.h) */ }; struct cx18_card_tuner_i2c { @@ -128,8 +128,8 @@ struct cx18_card { struct cx18_card_audio_input radio_input; /* GPIO card-specific settings */ - u8 xceive_pin; /* XCeive tuner GPIO reset pin */ - struct cx18_gpio_init gpio_init; + u8 xceive_pin; /* XCeive tuner GPIO reset pin */ + struct cx18_gpio_init gpio_init; struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset; struct cx18_gpio_audio_input gpio_audio_input; diff --git a/drivers/media/pci/cx18/cx18-driver.h b/drivers/media/pci/cx18/cx18-driver.h index 3492023a8675..0b707faca543 100644 --- a/drivers/media/pci/cx18/cx18-driver.h +++ b/drivers/media/pci/cx18/cx18-driver.h @@ -75,8 +75,8 @@ /* Supported cards */ #define CX18_CARD_HVR_1600_ESMT 0 /* Hauppauge HVR 1600 (ESMT memory) */ #define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */ -#define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */ -#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ +#define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */ +#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ #define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */ #define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/ #define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */ @@ -99,9 +99,9 @@ #define PCI_DEVICE_ID_CX23418 0x5b7a /* subsystem vendor ID */ -#define CX18_PCI_ID_HAUPPAUGE 0x0070 -#define CX18_PCI_ID_COMPRO 0x185b -#define CX18_PCI_ID_YUAN 0x12ab +#define CX18_PCI_ID_HAUPPAUGE 0x0070 +#define CX18_PCI_ID_COMPRO 0x185b +#define CX18_PCI_ID_YUAN 0x12ab #define CX18_PCI_ID_CONEXANT 0x14f1 #define CX18_PCI_ID_TOSHIBA 0x1179 #define CX18_PCI_ID_LEADTEK 0x107D @@ -260,7 +260,7 @@ struct cx18_options { #define CX18_F_M_NEED_SWAP 0 /* mdl buffer data must be endianness swapped */ /* per-stream, s_flags */ -#define CX18_F_S_CLAIMED 3 /* this stream is claimed */ +#define CX18_F_S_CLAIMED 3 /* this stream is claimed */ #define CX18_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */ #define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ #define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */ @@ -268,12 +268,12 @@ struct cx18_options { #define CX18_F_S_STOPPING 9 /* telling the fw to stop capturing */ /* per-cx18, i_flags */ -#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ -#define CX18_F_I_EOS 4 /* End of encoder stream */ -#define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */ -#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */ -#define CX18_F_I_INITED 21 /* set after first open */ -#define CX18_F_I_FAILED 22 /* set if first open failed */ +#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ +#define CX18_F_I_EOS 4 /* End of encoder stream */ +#define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */ +#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */ +#define CX18_F_I_INITED 21 /* set after first open */ +#define CX18_F_I_FAILED 22 /* set if first open failed */ /* These are the VBI types as they appear in the embedded VBI private packets. */ #define CX18_SLICED_TYPE_TELETEXT_B (1) @@ -370,7 +370,7 @@ struct cx18_stream { is not actually created. */ struct video_device video_dev; /* v4l2_dev is NULL when stream not created */ struct cx18_dvb *dvb; /* DVB / Digital Transport */ - struct cx18 *cx; /* for ease of use */ + struct cx18 *cx; /* for ease of use */ const char *name; /* name of the stream */ int type; /* stream type */ u32 handle; /* task handle */ @@ -525,14 +525,14 @@ struct vbi_info { * into the MPEG PS stream. * * In each sliced_mpeg_data[] buffer is: - * 16 byte MPEG-2 PS Program Pack Header - * 16 byte MPEG-2 Private Stream 1 PES Header - * 4 byte magic number: "itv0" or "ITV0" - * 4 byte first field line mask, if "itv0" - * 4 byte second field line mask, if "itv0" - * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data + * 16 byte MPEG-2 PS Program Pack Header + * 16 byte MPEG-2 Private Stream 1 PES Header + * 4 byte magic number: "itv0" or "ITV0" + * 4 byte first field line mask, if "itv0" + * 4 byte second field line mask, if "itv0" + * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data * - * Each line in the payload is + * Each line in the payload is * 1 byte line header derived from the SDID (WSS, CC, VPS, etc.) * 42 bytes of line data * @@ -583,7 +583,7 @@ struct cx18 { u8 nof_inputs; /* number of video inputs */ u8 nof_audio_inputs; /* number of audio inputs */ u32 v4l2_cap; /* V4L2 capabilities of card */ - u32 hw_flags; /* Hardware description of the board */ + u32 hw_flags; /* Hardware description of the board */ unsigned int free_mdl_idx; struct cx18_scb __iomem *scb; /* pointer to SCB */ struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/ @@ -602,10 +602,10 @@ struct cx18 { u32 dualwatch_stereo_mode; struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */ - struct cx18_options options; /* User options */ + struct cx18_options options; /* User options */ int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */ int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ - struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ + struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ struct snd_cx18_card *alsa; /* ALSA interface for PCM capture stream */ void (*pcm_announce_callback)(struct snd_cx18_card *card, u8 *pcm_data, size_t num_bytes); diff --git a/drivers/media/pci/cx18/cx18-firmware.c b/drivers/media/pci/cx18/cx18-firmware.c index 1b34ea1c3730..498a1854b3b0 100644 --- a/drivers/media/pci/cx18/cx18-firmware.c +++ b/drivers/media/pci/cx18/cx18-firmware.c @@ -23,65 +23,65 @@ #include "cx18-cards.h" #include -#define CX18_PROC_SOFT_RESET 0xc70010 -#define CX18_DDR_SOFT_RESET 0xc70014 -#define CX18_CLOCK_SELECT1 0xc71000 -#define CX18_CLOCK_SELECT2 0xc71004 -#define CX18_HALF_CLOCK_SELECT1 0xc71008 -#define CX18_HALF_CLOCK_SELECT2 0xc7100C -#define CX18_CLOCK_POLARITY1 0xc71010 -#define CX18_CLOCK_POLARITY2 0xc71014 -#define CX18_ADD_DELAY_ENABLE1 0xc71018 -#define CX18_ADD_DELAY_ENABLE2 0xc7101C -#define CX18_CLOCK_ENABLE1 0xc71020 -#define CX18_CLOCK_ENABLE2 0xc71024 - -#define CX18_REG_BUS_TIMEOUT_EN 0xc72024 - -#define CX18_FAST_CLOCK_PLL_INT 0xc78000 -#define CX18_FAST_CLOCK_PLL_FRAC 0xc78004 -#define CX18_FAST_CLOCK_PLL_POST 0xc78008 -#define CX18_FAST_CLOCK_PLL_PRESCALE 0xc7800C +#define CX18_PROC_SOFT_RESET 0xc70010 +#define CX18_DDR_SOFT_RESET 0xc70014 +#define CX18_CLOCK_SELECT1 0xc71000 +#define CX18_CLOCK_SELECT2 0xc71004 +#define CX18_HALF_CLOCK_SELECT1 0xc71008 +#define CX18_HALF_CLOCK_SELECT2 0xc7100C +#define CX18_CLOCK_POLARITY1 0xc71010 +#define CX18_CLOCK_POLARITY2 0xc71014 +#define CX18_ADD_DELAY_ENABLE1 0xc71018 +#define CX18_ADD_DELAY_ENABLE2 0xc7101C +#define CX18_CLOCK_ENABLE1 0xc71020 +#define CX18_CLOCK_ENABLE2 0xc71024 + +#define CX18_REG_BUS_TIMEOUT_EN 0xc72024 + +#define CX18_FAST_CLOCK_PLL_INT 0xc78000 +#define CX18_FAST_CLOCK_PLL_FRAC 0xc78004 +#define CX18_FAST_CLOCK_PLL_POST 0xc78008 +#define CX18_FAST_CLOCK_PLL_PRESCALE 0xc7800C #define CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH 0xc78010 -#define CX18_SLOW_CLOCK_PLL_INT 0xc78014 -#define CX18_SLOW_CLOCK_PLL_FRAC 0xc78018 -#define CX18_SLOW_CLOCK_PLL_POST 0xc7801C +#define CX18_SLOW_CLOCK_PLL_INT 0xc78014 +#define CX18_SLOW_CLOCK_PLL_FRAC 0xc78018 +#define CX18_SLOW_CLOCK_PLL_POST 0xc7801C #define CX18_MPEG_CLOCK_PLL_INT 0xc78040 #define CX18_MPEG_CLOCK_PLL_FRAC 0xc78044 #define CX18_MPEG_CLOCK_PLL_POST 0xc78048 -#define CX18_PLL_POWER_DOWN 0xc78088 +#define CX18_PLL_POWER_DOWN 0xc78088 #define CX18_SW1_INT_STATUS 0xc73104 #define CX18_SW1_INT_ENABLE_PCI 0xc7311C #define CX18_SW2_INT_SET 0xc73140 #define CX18_SW2_INT_STATUS 0xc73144 -#define CX18_ADEC_CONTROL 0xc78120 +#define CX18_ADEC_CONTROL 0xc78120 -#define CX18_DDR_REQUEST_ENABLE 0xc80000 -#define CX18_DDR_CHIP_CONFIG 0xc80004 -#define CX18_DDR_REFRESH 0xc80008 -#define CX18_DDR_TIMING1 0xc8000C -#define CX18_DDR_TIMING2 0xc80010 +#define CX18_DDR_REQUEST_ENABLE 0xc80000 +#define CX18_DDR_CHIP_CONFIG 0xc80004 +#define CX18_DDR_REFRESH 0xc80008 +#define CX18_DDR_TIMING1 0xc8000C +#define CX18_DDR_TIMING2 0xc80010 #define CX18_DDR_POWER_REG 0xc8001C -#define CX18_DDR_TUNE_LANE 0xc80048 -#define CX18_DDR_INITIAL_EMRS 0xc80054 -#define CX18_DDR_MB_PER_ROW_7 0xc8009C -#define CX18_DDR_BASE_63_ADDR 0xc804FC - -#define CX18_WMB_CLIENT02 0xc90108 -#define CX18_WMB_CLIENT05 0xc90114 -#define CX18_WMB_CLIENT06 0xc90118 -#define CX18_WMB_CLIENT07 0xc9011C -#define CX18_WMB_CLIENT08 0xc90120 -#define CX18_WMB_CLIENT09 0xc90124 -#define CX18_WMB_CLIENT10 0xc90128 -#define CX18_WMB_CLIENT11 0xc9012C -#define CX18_WMB_CLIENT12 0xc90130 -#define CX18_WMB_CLIENT13 0xc90134 -#define CX18_WMB_CLIENT14 0xc90138 - -#define CX18_DSP0_INTERRUPT_MASK 0xd0004C +#define CX18_DDR_TUNE_LANE 0xc80048 +#define CX18_DDR_INITIAL_EMRS 0xc80054 +#define CX18_DDR_MB_PER_ROW_7 0xc8009C +#define CX18_DDR_BASE_63_ADDR 0xc804FC + +#define CX18_WMB_CLIENT02 0xc90108 +#define CX18_WMB_CLIENT05 0xc90114 +#define CX18_WMB_CLIENT06 0xc90118 +#define CX18_WMB_CLIENT07 0xc9011C +#define CX18_WMB_CLIENT08 0xc90120 +#define CX18_WMB_CLIENT09 0xc90124 +#define CX18_WMB_CLIENT10 0xc90128 +#define CX18_WMB_CLIENT11 0xc9012C +#define CX18_WMB_CLIENT12 0xc90130 +#define CX18_WMB_CLIENT13 0xc90134 +#define CX18_WMB_CLIENT14 0xc90138 + +#define CX18_DSP0_INTERRUPT_MASK 0xd0004C #define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */ #define APU_ROM_SYNC2 0x72646548 /* "rdeH" */ @@ -229,7 +229,7 @@ void cx18_init_power(struct cx18 *cx, int lowpwr) * would ideally be: * * NTSC Color subcarrier freq * 8 = - * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz + * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz * * The accidents of history and rationale that explain from where this * combination of magic numbers originate can be found in: diff --git a/drivers/media/pci/cx18/cx18-mailbox.c b/drivers/media/pci/cx18/cx18-mailbox.c index 763f960fc918..f66dd63e1994 100644 --- a/drivers/media/pci/cx18/cx18-mailbox.c +++ b/drivers/media/pci/cx18/cx18-mailbox.c @@ -35,7 +35,7 @@ struct cx18_api_info { u32 cmd; u8 flags; /* Flags, see above */ u8 rpu; /* Processing unit */ - const char *name; /* The name of the command */ + const char *name; /* The name of the command */ }; #define API_ENTRY(rpu, x, f) { (x), (f), (rpu), #x } @@ -43,9 +43,9 @@ struct cx18_api_info { static const struct cx18_api_info api_info[] = { /* MPEG encoder API */ API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0), - API_ENTRY(CPU, CX18_EPU_DEBUG, 0), - API_ENTRY(CPU, CX18_CREATE_TASK, 0), - API_ENTRY(CPU, CX18_DESTROY_TASK, 0), + API_ENTRY(CPU, CX18_EPU_DEBUG, 0), + API_ENTRY(CPU, CX18_CREATE_TASK, 0), + API_ENTRY(CPU, CX18_DESTROY_TASK, 0), API_ENTRY(CPU, CX18_CPU_CAPTURE_START, API_SLOW), API_ENTRY(CPU, CX18_CPU_CAPTURE_STOP, API_SLOW), API_ENTRY(CPU, CX18_CPU_CAPTURE_PAUSE, 0), diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c index b9c6831c21c3..a594cfdeca20 100644 --- a/drivers/media/pci/cx18/cx18-streams.c +++ b/drivers/media/pci/cx18/cx18-streams.c @@ -29,7 +29,7 @@ #include "cx18-scb.h" #include "cx18-dvb.h" -#define CX18_DSP0_INTERRUPT_MASK 0xd0004C +#define CX18_DSP0_INTERRUPT_MASK 0xd0004C static const struct v4l2_file_operations cx18_v4l2_enc_fops = { .owner = THIS_MODULE, diff --git a/drivers/media/pci/cx18/cx18-vbi.c b/drivers/media/pci/cx18/cx18-vbi.c index 72c74d60c6fb..81f1e27436fd 100644 --- a/drivers/media/pci/cx18/cx18-vbi.c +++ b/drivers/media/pci/cx18/cx18-vbi.c @@ -47,7 +47,7 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp) 0x00, 0x00, 0x01, 0xbd, /* Priv Stream 1 start */ 0x00, 0x1a, /* length */ 0x84, 0x80, 0x07, /* flags, hdr data len */ - 0x21, 0x00, 0x5d, 0x63, 0xa7, /* PTS, markers */ + 0x21, 0x00, 0x5d, 0x63, 0xa7, /* PTS, markers */ 0xff, 0xff /* stuffing */ }; const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */ diff --git a/drivers/media/pci/cx18/cx23418.h b/drivers/media/pci/cx18/cx23418.h index 901ed7fac10f..15205b662952 100644 --- a/drivers/media/pci/cx18/cx23418.h +++ b/drivers/media/pci/cx18/cx23418.h @@ -19,10 +19,10 @@ #include -#define MGR_CMD_MASK 0x40000000 +#define MGR_CMD_MASK 0x40000000 /* The MSB of the command code indicates that this is the completion of a command */ -#define MGR_CMD_MASK_ACK (MGR_CMD_MASK | 0x80000000) +#define MGR_CMD_MASK_ACK (MGR_CMD_MASK | 0x80000000) /* Description: This command creates a new instance of a certain task IN[0] - Task ID. This is one of the XPU_CMD_MASK_YYY where XPU is @@ -30,26 +30,26 @@ OUT[0] - Task handle. This handle is passed along with commands to dispatch to the right instance of the task ReturnCode - One of the ERR_SYS_... */ -#define CX18_CREATE_TASK (MGR_CMD_MASK | 0x0001) +#define CX18_CREATE_TASK (MGR_CMD_MASK | 0x0001) /* Description: This command destroys an instance of a task IN[0] - Task handle. Hanlde of the task to destroy ReturnCode - One of the ERR_SYS_... */ -#define CX18_DESTROY_TASK (MGR_CMD_MASK | 0x0002) +#define CX18_DESTROY_TASK (MGR_CMD_MASK | 0x0002) /* All commands for CPU have the following mask set */ -#define CPU_CMD_MASK 0x20000000 -#define CPU_CMD_MASK_DEBUG (CPU_CMD_MASK | 0x00000000) -#define CPU_CMD_MASK_ACK (CPU_CMD_MASK | 0x80000000) -#define CPU_CMD_MASK_CAPTURE (CPU_CMD_MASK | 0x00020000) -#define CPU_CMD_MASK_TS (CPU_CMD_MASK | 0x00040000) +#define CPU_CMD_MASK 0x20000000 +#define CPU_CMD_MASK_DEBUG (CPU_CMD_MASK | 0x00000000) +#define CPU_CMD_MASK_ACK (CPU_CMD_MASK | 0x80000000) +#define CPU_CMD_MASK_CAPTURE (CPU_CMD_MASK | 0x00020000) +#define CPU_CMD_MASK_TS (CPU_CMD_MASK | 0x00040000) -#define EPU_CMD_MASK 0x02000000 -#define EPU_CMD_MASK_DEBUG (EPU_CMD_MASK | 0x000000) -#define EPU_CMD_MASK_DE (EPU_CMD_MASK | 0x040000) +#define EPU_CMD_MASK 0x02000000 +#define EPU_CMD_MASK_DEBUG (EPU_CMD_MASK | 0x000000) +#define EPU_CMD_MASK_DE (EPU_CMD_MASK | 0x040000) -#define APU_CMD_MASK 0x10000000 -#define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000) +#define APU_CMD_MASK 0x10000000 +#define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000) #define CX18_APU_ENCODING_METHOD_MPEG (0 << 28) #define CX18_APU_ENCODING_METHOD_AC3 (1 << 28) @@ -67,7 +67,7 @@ /* Description: Command APU to reset the AI ReturnCode - ??? */ -#define CX18_APU_RESETAI (APU_CMD_MASK | 0x05) +#define CX18_APU_RESETAI (APU_CMD_MASK | 0x05) /* Description: This command indicates that a Memory Descriptor List has been filled with the requested channel type @@ -75,13 +75,13 @@ IN[1] - Offset of the MDL_ACK from the beginning of the local DDR. IN[2] - Number of CNXT_MDL_ACK structures in the array pointed to by IN[1] ReturnCode - One of the ERR_DE_... */ -#define CX18_EPU_DMA_DONE (EPU_CMD_MASK_DE | 0x0001) +#define CX18_EPU_DMA_DONE (EPU_CMD_MASK_DE | 0x0001) /* Something interesting happened IN[0] - A value to log IN[1] - An offset of a string in the MiniMe memory; 0/zero/NULL means "I have nothing to say" */ -#define CX18_EPU_DEBUG (EPU_CMD_MASK_DEBUG | 0x0003) +#define CX18_EPU_DEBUG (EPU_CMD_MASK_DEBUG | 0x0003) /* Reads memory/registers (32-bit) IN[0] - Address @@ -91,40 +91,40 @@ /* Description: This command starts streaming with the set channel type IN[0] - Task handle. Handle of the task to start ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_CAPTURE_START (CPU_CMD_MASK_CAPTURE | 0x0002) +#define CX18_CPU_CAPTURE_START (CPU_CMD_MASK_CAPTURE | 0x0002) /* Description: This command stops streaming with the set channel type IN[0] - Task handle. Handle of the task to stop IN[1] - 0 = stop at end of GOP, 1 = stop at end of frame (MPEG only) ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_CAPTURE_STOP (CPU_CMD_MASK_CAPTURE | 0x0003) +#define CX18_CPU_CAPTURE_STOP (CPU_CMD_MASK_CAPTURE | 0x0003) /* Description: This command pauses streaming with the set channel type IN[0] - Task handle. Handle of the task to pause ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_CAPTURE_PAUSE (CPU_CMD_MASK_CAPTURE | 0x0007) +#define CX18_CPU_CAPTURE_PAUSE (CPU_CMD_MASK_CAPTURE | 0x0007) /* Description: This command resumes streaming with the set channel type IN[0] - Task handle. Handle of the task to resume ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_CAPTURE_RESUME (CPU_CMD_MASK_CAPTURE | 0x0008) - -#define CAPTURE_CHANNEL_TYPE_NONE 0 -#define CAPTURE_CHANNEL_TYPE_MPEG 1 -#define CAPTURE_CHANNEL_TYPE_INDEX 2 -#define CAPTURE_CHANNEL_TYPE_YUV 3 -#define CAPTURE_CHANNEL_TYPE_PCM 4 -#define CAPTURE_CHANNEL_TYPE_VBI 5 +#define CX18_CPU_CAPTURE_RESUME (CPU_CMD_MASK_CAPTURE | 0x0008) + +#define CAPTURE_CHANNEL_TYPE_NONE 0 +#define CAPTURE_CHANNEL_TYPE_MPEG 1 +#define CAPTURE_CHANNEL_TYPE_INDEX 2 +#define CAPTURE_CHANNEL_TYPE_YUV 3 +#define CAPTURE_CHANNEL_TYPE_PCM 4 +#define CAPTURE_CHANNEL_TYPE_VBI 5 #define CAPTURE_CHANNEL_TYPE_SLICED_VBI 6 #define CAPTURE_CHANNEL_TYPE_TS 7 -#define CAPTURE_CHANNEL_TYPE_MAX 15 +#define CAPTURE_CHANNEL_TYPE_MAX 15 /* Description: This command sets the channel type. This can only be done when stopped. IN[0] - Task handle. Handle of the task to start IN[1] - Channel Type. See Below. ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_CHANNEL_TYPE (CPU_CMD_MASK_CAPTURE + 1) +#define CX18_CPU_SET_CHANNEL_TYPE (CPU_CMD_MASK_CAPTURE + 1) /* Description: Set stream output type IN[0] - task handle. Handle of the task to start @@ -140,7 +140,7 @@ IN[4] - reserved IN[5] - frame rate, 0 - 29.97f/s, 1 - 25f/s ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_VIDEO_IN (CPU_CMD_MASK_CAPTURE | 0x0004) +#define CX18_CPU_SET_VIDEO_IN (CPU_CMD_MASK_CAPTURE | 0x0004) /* Description: Set video frame rate IN[0] - task handle. Handle of the task to start @@ -149,7 +149,7 @@ IN[3] - video peak rate IN[4] - system mux rate ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_VIDEO_RATE (CPU_CMD_MASK_CAPTURE | 0x0005) +#define CX18_CPU_SET_VIDEO_RATE (CPU_CMD_MASK_CAPTURE | 0x0005) /* Description: Set video output resolution IN[0] - task handle @@ -166,7 +166,7 @@ 3 = horizontal/vertical, 4 = diagonal IN[3] - strength, temporal 0 - 31, spatial 0 - 15 ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_FILTER_PARAM (CPU_CMD_MASK_CAPTURE | 0x0009) +#define CX18_CPU_SET_FILTER_PARAM (CPU_CMD_MASK_CAPTURE | 0x0009) /* Description: This command set spatial filter type IN[0] - Task handle. @@ -174,7 +174,7 @@ 3 = 2D H/V separable, 4 = 2D symmetric non-separable IN[2] - chroma type: 0 - disable, 1 = 1D horizontal ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_SPATIAL_FILTER_TYPE (CPU_CMD_MASK_CAPTURE | 0x000C) +#define CX18_CPU_SET_SPATIAL_FILTER_TYPE (CPU_CMD_MASK_CAPTURE | 0x000C) /* Description: This command set coring levels for median filter IN[0] - Task handle. @@ -183,16 +183,16 @@ IN[3] - chroma_high IN[4] - chroma_low ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E) +#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E) /* Description: This command set the picture type mask for index file IN[0] - Task handle (ignored by firmware) - IN[1] - 0 = disable index file output + IN[1] - 0 = disable index file output 1 = output I picture 2 = P picture 4 = B picture other = illegal */ -#define CX18_CPU_SET_INDEXTABLE (CPU_CMD_MASK_CAPTURE | 0x0010) +#define CX18_CPU_SET_INDEXTABLE (CPU_CMD_MASK_CAPTURE | 0x0010) /* Description: Set audio parameters IN[0] - task handle. Handle of the task to start @@ -218,7 +218,7 @@ /* Description: Set stream output type IN[0] - task handle. Handle of the task to start IN[1] - subType - SET_INITIAL_SCR 1 + SET_INITIAL_SCR 1 SET_QUALITY_MODE 2 SET_VIM_PROTECT_MODE 3 SET_PTS_CORRECTION 4 @@ -311,7 +311,7 @@ bit 0: output user data, 1 - enable bit 1: output private stream, 1 - enable bit 2: mux option, 0 - in GOP, 1 - in picture - bit[7:0] private stream ID + bit[7:0] private stream ID IN[5] - insertion period while mux option is in picture ReturnCode - VBI data offset */ #define CX18_CPU_SET_SLICED_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0020) @@ -344,13 +344,13 @@ #define CX18_CPU_SET_VFC_PARAM (CPU_CMD_MASK_CAPTURE | 0x0023) /* Below is the list of commands related to the data exchange */ -#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000) +#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000) /* Description: This command provides the physical base address of the local DDR as viewed by EPU IN[0] - Physical offset where EPU has the local DDR mapped ReturnCode - One of the ERR_DE_... */ -#define CPU_CMD_DE_SetBase (CPU_CMD_MASK_DE | 0x0001) +#define CPU_CMD_DE_SetBase (CPU_CMD_MASK_DE | 0x0001) /* Description: This command provides the offsets in the device memory where the 2 cx18_mdl_ack blocks reside @@ -360,7 +360,7 @@ IN[2] - Offset of the second cx18_mdl_ack from the beginning of the local DDR. ReturnCode - One of the ERR_DE_... */ -#define CX18_CPU_DE_SET_MDL_ACK (CPU_CMD_MASK_DE | 0x0002) +#define CX18_CPU_DE_SET_MDL_ACK (CPU_CMD_MASK_DE | 0x0002) /* Description: This command provides the offset to a Memory Descriptor List IN[0] - Task handle. Handle of the task to start @@ -369,13 +369,13 @@ IN[3] - Buffer ID IN[4] - Total buffer length ReturnCode - One of the ERR_DE_... */ -#define CX18_CPU_DE_SET_MDL (CPU_CMD_MASK_DE | 0x0005) +#define CX18_CPU_DE_SET_MDL (CPU_CMD_MASK_DE | 0x0005) /* Description: This command requests return of all current Memory Descriptor Lists to the driver IN[0] - Task handle. Handle of the task to start ReturnCode - One of the ERR_DE_... */ -#define CX18_CPU_DE_RELEASE_MDL (CPU_CMD_MASK_DE | 0x0006) +#define CX18_CPU_DE_RELEASE_MDL (CPU_CMD_MASK_DE | 0x0006) /* Description: This command signals the cpu that the dat buffer has been consumed and ready for re-use. diff --git a/drivers/media/pci/cx23885/cimax2.c b/drivers/media/pci/cx23885/cimax2.c index 96f75f658b1b..19c005f4a57d 100644 --- a/drivers/media/pci/cx23885/cimax2.c +++ b/drivers/media/pci/cx23885/cimax2.c @@ -54,7 +54,7 @@ #define NETUP_CI_CTL 0x04 #define NETUP_CI_RD 1 -#define NETUP_IRQ_DETAM 0x1 +#define NETUP_IRQ_DETAM 0x1 #define NETUP_IRQ_IRQAM 0x4 static unsigned int ci_dbg; diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c index ecc580af0148..a03dcb662953 100644 --- a/drivers/media/pci/cx23885/cx23885-video.c +++ b/drivers/media/pci/cx23885/cx23885-video.c @@ -1146,7 +1146,7 @@ static struct video_device cx23885_vbi_template; static struct video_device cx23885_video_template = { .name = "cx23885-video", .fops = &video_fops, - .ioctl_ops = &video_ioctl_ops, + .ioctl_ops = &video_ioctl_ops, .tvnorms = CX23885_NORMS, }; diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 6aab713e0476..2a17209eb4f6 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -357,7 +357,7 @@ struct cx23885_audio_dev { struct cx23885_dev { atomic_t refcount; - struct v4l2_device v4l2_dev; + struct v4l2_device v4l2_dev; struct v4l2_ctrl_handler ctrl_handler; /* pci stuff */ @@ -407,7 +407,7 @@ struct cx23885_dev { unsigned int tuner_bus; unsigned int radio_type; unsigned char radio_addr; - struct v4l2_subdev *sd_cx25840; + struct v4l2_subdev *sd_cx25840; struct work_struct cx25840_work; /* Infrared */ diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c index b0d4e4437b87..00329f668b59 100644 --- a/drivers/media/pci/cx23885/cx23888-ir.c +++ b/drivers/media/pci/cx23885/cx23888-ir.c @@ -29,7 +29,7 @@ static unsigned int ir_888_debug; module_param(ir_888_debug, int, 0644); MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]"); -#define CX23888_IR_REG_BASE 0x170000 +#define CX23888_IR_REG_BASE 0x170000 /* * These CX23888 register offsets have a straightforward one to one mapping * to the CX23885 register offsets of 0x200 through 0x218 diff --git a/drivers/media/pci/ivtv/ivtv-cards.h b/drivers/media/pci/ivtv/ivtv-cards.h index 06e7b4ed6444..1557a6ea4dd9 100644 --- a/drivers/media/pci/ivtv/ivtv-cards.h +++ b/drivers/media/pci/ivtv/ivtv-cards.h @@ -22,26 +22,26 @@ #define IVTV_CARDS_H /* Supported cards */ -#define IVTV_CARD_PVR_250 0 /* WinTV PVR 250 */ -#define IVTV_CARD_PVR_350 1 /* encoder, decoder, tv-out */ -#define IVTV_CARD_PVR_150 2 /* WinTV PVR 150 and PVR 500 (really just two +#define IVTV_CARD_PVR_250 0 /* WinTV PVR 250 */ +#define IVTV_CARD_PVR_350 1 /* encoder, decoder, tv-out */ +#define IVTV_CARD_PVR_150 2 /* WinTV PVR 150 and PVR 500 (really just two PVR150s on one PCI board) */ -#define IVTV_CARD_M179 3 /* AVerMedia M179 (encoder only) */ -#define IVTV_CARD_MPG600 4 /* Kuroutoshikou ITVC16-STVLP/YUAN MPG600, encoder only */ -#define IVTV_CARD_MPG160 5 /* Kuroutoshikou ITVC15-STVLP/YUAN MPG160 +#define IVTV_CARD_M179 3 /* AVerMedia M179 (encoder only) */ +#define IVTV_CARD_MPG600 4 /* Kuroutoshikou ITVC16-STVLP/YUAN MPG600, encoder only */ +#define IVTV_CARD_MPG160 5 /* Kuroutoshikou ITVC15-STVLP/YUAN MPG160 cx23415 based, but does not have tv-out */ -#define IVTV_CARD_PG600 6 /* YUAN PG600/DIAMONDMM PVR-550 based on the CX Falcon 2 */ -#define IVTV_CARD_AVC2410 7 /* Adaptec AVC-2410 */ -#define IVTV_CARD_AVC2010 8 /* Adaptec AVD-2010 (No Tuner) */ -#define IVTV_CARD_TG5000TV 9 /* NAGASE TRANSGEAR 5000TV, encoder only */ +#define IVTV_CARD_PG600 6 /* YUAN PG600/DIAMONDMM PVR-550 based on the CX Falcon 2 */ +#define IVTV_CARD_AVC2410 7 /* Adaptec AVC-2410 */ +#define IVTV_CARD_AVC2010 8 /* Adaptec AVD-2010 (No Tuner) */ +#define IVTV_CARD_TG5000TV 9 /* NAGASE TRANSGEAR 5000TV, encoder only */ #define IVTV_CARD_VA2000MAX_SNT6 10 /* VA2000MAX-STN6 */ -#define IVTV_CARD_CX23416GYC 11 /* Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */ -#define IVTV_CARD_GV_MVPRX 12 /* I/O Data GV-MVP/RX, RX2, RX2W */ -#define IVTV_CARD_GV_MVPRX2E 13 /* I/O Data GV-MVP/RX2E */ +#define IVTV_CARD_CX23416GYC 11 /* Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */ +#define IVTV_CARD_GV_MVPRX 12 /* I/O Data GV-MVP/RX, RX2, RX2W */ +#define IVTV_CARD_GV_MVPRX2E 13 /* I/O Data GV-MVP/RX2E */ #define IVTV_CARD_GOTVIEW_PCI_DVD 14 /* GotView PCI DVD */ #define IVTV_CARD_GOTVIEW_PCI_DVD2 15 /* GotView PCI DVD2 */ #define IVTV_CARD_YUAN_MPC622 16 /* Yuan MPC622 miniPCI */ -#define IVTV_CARD_DCTMTVP1 17 /* DIGITAL COWBOY DCT-MTVP1 */ +#define IVTV_CARD_DCTMTVP1 17 /* DIGITAL COWBOY DCT-MTVP1 */ #define IVTV_CARD_PG600V2 18 /* Yuan PG600V2/GotView PCI DVD Lite */ #define IVTV_CARD_CLUB3D 19 /* Club3D ZAP-TV1x01 */ #define IVTV_CARD_AVERTV_MCE116 20 /* AVerTV MCE 116 Plus */ @@ -52,7 +52,7 @@ #define IVTV_CARD_BUFFALO_MV5L 25 /* Buffalo PC-MV5L/PCI card */ #define IVTV_CARD_AVER_ULTRA1500MCE 26 /* AVerMedia UltraTV 1500 MCE */ #define IVTV_CARD_KIKYOU 27 /* Sony VAIO Giga Pocket (ENX Kikyou) */ -#define IVTV_CARD_LAST 27 +#define IVTV_CARD_LAST 27 /* Variants of existing cards but with the same PCI IDs. The driver detects these based on other device information. @@ -61,7 +61,7 @@ must be adjusted accordingly. */ /* PVR-350 V1 (uses saa7114) */ -#define IVTV_CARD_PVR_350_V1 (IVTV_CARD_LAST+1) +#define IVTV_CARD_PVR_350_V1 (IVTV_CARD_LAST+1) /* 2 variants of Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */ #define IVTV_CARD_CX23416GYC_NOGR (IVTV_CARD_LAST+2) #define IVTV_CARD_CX23416GYC_NOGRYCS (IVTV_CARD_LAST+3) @@ -72,22 +72,22 @@ #define PCI_DEVICE_ID_IVTV16 0x0016 /* subsystem vendor ID */ -#define IVTV_PCI_ID_HAUPPAUGE 0x0070 -#define IVTV_PCI_ID_HAUPPAUGE_ALT1 0x0270 -#define IVTV_PCI_ID_HAUPPAUGE_ALT2 0x4070 -#define IVTV_PCI_ID_ADAPTEC 0x9005 -#define IVTV_PCI_ID_ASUSTEK 0x1043 -#define IVTV_PCI_ID_AVERMEDIA 0x1461 +#define IVTV_PCI_ID_HAUPPAUGE 0x0070 +#define IVTV_PCI_ID_HAUPPAUGE_ALT1 0x0270 +#define IVTV_PCI_ID_HAUPPAUGE_ALT2 0x4070 +#define IVTV_PCI_ID_ADAPTEC 0x9005 +#define IVTV_PCI_ID_ASUSTEK 0x1043 +#define IVTV_PCI_ID_AVERMEDIA 0x1461 #define IVTV_PCI_ID_YUAN1 0x12ab -#define IVTV_PCI_ID_YUAN2 0xff01 -#define IVTV_PCI_ID_YUAN3 0xffab -#define IVTV_PCI_ID_YUAN4 0xfbab -#define IVTV_PCI_ID_DIAMONDMM 0xff92 -#define IVTV_PCI_ID_IODATA 0x10fc -#define IVTV_PCI_ID_MELCO 0x1154 +#define IVTV_PCI_ID_YUAN2 0xff01 +#define IVTV_PCI_ID_YUAN3 0xffab +#define IVTV_PCI_ID_YUAN4 0xfbab +#define IVTV_PCI_ID_DIAMONDMM 0xff92 +#define IVTV_PCI_ID_IODATA 0x10fc +#define IVTV_PCI_ID_MELCO 0x1154 #define IVTV_PCI_ID_GOTVIEW1 0xffac -#define IVTV_PCI_ID_GOTVIEW2 0xffad -#define IVTV_PCI_ID_SONY 0x104d +#define IVTV_PCI_ID_GOTVIEW2 0xffad +#define IVTV_PCI_ID_SONY 0x104d /* hardware flags, no gaps allowed */ #define IVTV_HW_CX25840 (1 << 0) @@ -122,20 +122,20 @@ /* video inputs */ #define IVTV_CARD_INPUT_VID_TUNER 1 -#define IVTV_CARD_INPUT_SVIDEO1 2 -#define IVTV_CARD_INPUT_SVIDEO2 3 -#define IVTV_CARD_INPUT_COMPOSITE1 4 -#define IVTV_CARD_INPUT_COMPOSITE2 5 -#define IVTV_CARD_INPUT_COMPOSITE3 6 +#define IVTV_CARD_INPUT_SVIDEO1 2 +#define IVTV_CARD_INPUT_SVIDEO2 3 +#define IVTV_CARD_INPUT_COMPOSITE1 4 +#define IVTV_CARD_INPUT_COMPOSITE2 5 +#define IVTV_CARD_INPUT_COMPOSITE3 6 /* audio inputs */ #define IVTV_CARD_INPUT_AUD_TUNER 1 -#define IVTV_CARD_INPUT_LINE_IN1 2 -#define IVTV_CARD_INPUT_LINE_IN2 3 +#define IVTV_CARD_INPUT_LINE_IN1 2 +#define IVTV_CARD_INPUT_LINE_IN2 3 #define IVTV_CARD_MAX_VIDEO_INPUTS 6 #define IVTV_CARD_MAX_AUDIO_INPUTS 3 -#define IVTV_CARD_MAX_TUNERS 3 +#define IVTV_CARD_MAX_TUNERS 3 /* SAA71XX HW inputs */ #define IVTV_SAA71XX_COMPOSITE0 0 @@ -172,7 +172,7 @@ V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY) struct ivtv_card_video_input { - u8 video_type; /* video input type */ + u8 video_type; /* video input type */ u8 audio_index; /* index in ivtv_card_audio_input array */ u16 video_input; /* hardware video input */ }; @@ -199,55 +199,55 @@ struct ivtv_card_pci_info { /* The mask is the set of bits used by the operation */ -struct ivtv_gpio_init { /* set initial GPIO DIR and OUT values */ - u16 direction; /* DIR setting. Leave to 0 if no init is needed */ +struct ivtv_gpio_init { /* set initial GPIO DIR and OUT values */ + u16 direction; /* DIR setting. Leave to 0 if no init is needed */ u16 initial_value; }; -struct ivtv_gpio_video_input { /* select tuner/line in input */ - u16 mask; /* leave to 0 if not supported */ +struct ivtv_gpio_video_input { /* select tuner/line in input */ + u16 mask; /* leave to 0 if not supported */ u16 tuner; u16 composite; u16 svideo; }; -struct ivtv_gpio_audio_input { /* select tuner/line in input */ - u16 mask; /* leave to 0 if not supported */ +struct ivtv_gpio_audio_input { /* select tuner/line in input */ + u16 mask; /* leave to 0 if not supported */ u16 tuner; u16 linein; u16 radio; }; struct ivtv_gpio_audio_mute { - u16 mask; /* leave to 0 if not supported */ + u16 mask; /* leave to 0 if not supported */ u16 mute; /* set this value to mute, 0 to unmute */ }; struct ivtv_gpio_audio_mode { - u16 mask; /* leave to 0 if not supported */ - u16 mono; /* set audio to mono */ - u16 stereo; /* set audio to stereo */ + u16 mask; /* leave to 0 if not supported */ + u16 mono; /* set audio to mono */ + u16 stereo; /* set audio to stereo */ u16 lang1; /* set audio to the first language */ u16 lang2; /* set audio to the second language */ - u16 both; /* both languages are output */ + u16 both; /* both languages are output */ }; struct ivtv_gpio_audio_freq { - u16 mask; /* leave to 0 if not supported */ + u16 mask; /* leave to 0 if not supported */ u16 f32000; u16 f44100; u16 f48000; }; struct ivtv_gpio_audio_detect { - u16 mask; /* leave to 0 if not supported */ - u16 stereo; /* if the input matches this value then + u16 mask; /* leave to 0 if not supported */ + u16 stereo; /* if the input matches this value then stereo is detected */ }; struct ivtv_card_tuner { - v4l2_std_id std; /* standard for which the tuner is suitable */ - int tuner; /* tuner ID (from tuner.h) */ + v4l2_std_id std; /* standard for which the tuner is suitable */ + int tuner; /* tuner ID (from tuner.h) */ }; struct ivtv_card_tuner_i2c { @@ -272,17 +272,17 @@ struct ivtv_card { struct ivtv_card_audio_input radio_input; int nof_outputs; const struct ivtv_card_output *video_outputs; - u8 gr_config; /* config byte for the ghost reduction device */ - u8 xceive_pin; /* XCeive tuner GPIO reset pin */ + u8 gr_config; /* config byte for the ghost reduction device */ + u8 xceive_pin; /* XCeive tuner GPIO reset pin */ /* GPIO card-specific settings */ - struct ivtv_gpio_init gpio_init; + struct ivtv_gpio_init gpio_init; struct ivtv_gpio_video_input gpio_video_input; - struct ivtv_gpio_audio_input gpio_audio_input; - struct ivtv_gpio_audio_mute gpio_audio_mute; - struct ivtv_gpio_audio_mode gpio_audio_mode; - struct ivtv_gpio_audio_freq gpio_audio_freq; - struct ivtv_gpio_audio_detect gpio_audio_detect; + struct ivtv_gpio_audio_input gpio_audio_input; + struct ivtv_gpio_audio_mute gpio_audio_mute; + struct ivtv_gpio_audio_mode gpio_audio_mode; + struct ivtv_gpio_audio_freq gpio_audio_freq; + struct ivtv_gpio_audio_detect gpio_audio_detect; struct ivtv_card_tuner tuners[IVTV_CARD_MAX_TUNERS]; struct ivtv_card_tuner_i2c *i2c; diff --git a/drivers/media/pci/ivtv/ivtv-driver.h b/drivers/media/pci/ivtv/ivtv-driver.h index d27c5c2c07ea..cafba6b1055d 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.h +++ b/drivers/media/pci/ivtv/ivtv-driver.h @@ -76,7 +76,7 @@ #define IVTV_ENCODER_SIZE 0x00800000 /* Total size is 0x01000000, but only first half is used */ #define IVTV_DECODER_OFFSET 0x01000000 #define IVTV_DECODER_SIZE 0x00800000 /* Total size is 0x01000000, but only first half is used */ -#define IVTV_REG_OFFSET 0x02000000 +#define IVTV_REG_OFFSET 0x02000000 #define IVTV_REG_SIZE 0x00010000 /* Maximum ivtv driver instances. Some people have a huge number of @@ -97,26 +97,26 @@ #define IVTV_DMA_SG_OSD_ENT (2883584/PAGE_SIZE) /* sg entities */ /* DMA Registers */ -#define IVTV_REG_DMAXFER (0x0000) -#define IVTV_REG_DMASTATUS (0x0004) -#define IVTV_REG_DECDMAADDR (0x0008) -#define IVTV_REG_ENCDMAADDR (0x000c) -#define IVTV_REG_DMACONTROL (0x0010) -#define IVTV_REG_IRQSTATUS (0x0040) -#define IVTV_REG_IRQMASK (0x0048) +#define IVTV_REG_DMAXFER (0x0000) +#define IVTV_REG_DMASTATUS (0x0004) +#define IVTV_REG_DECDMAADDR (0x0008) +#define IVTV_REG_ENCDMAADDR (0x000c) +#define IVTV_REG_DMACONTROL (0x0010) +#define IVTV_REG_IRQSTATUS (0x0040) +#define IVTV_REG_IRQMASK (0x0048) /* Setup Registers */ -#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8) -#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC) -#define IVTV_REG_DEC_SDRAM_REFRESH (0x08F8) -#define IVTV_REG_DEC_SDRAM_PRECHARGE (0x08FC) -#define IVTV_REG_VDM (0x2800) -#define IVTV_REG_AO (0x2D00) -#define IVTV_REG_BYTEFLUSH (0x2D24) -#define IVTV_REG_SPU (0x9050) -#define IVTV_REG_HW_BLOCKS (0x9054) -#define IVTV_REG_VPU (0x9058) -#define IVTV_REG_APU (0xA064) +#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8) +#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC) +#define IVTV_REG_DEC_SDRAM_REFRESH (0x08F8) +#define IVTV_REG_DEC_SDRAM_PRECHARGE (0x08FC) +#define IVTV_REG_VDM (0x2800) +#define IVTV_REG_AO (0x2D00) +#define IVTV_REG_BYTEFLUSH (0x2D24) +#define IVTV_REG_SPU (0x9050) +#define IVTV_REG_HW_BLOCKS (0x9054) +#define IVTV_REG_VPU (0x9058) +#define IVTV_REG_APU (0xA064) /* Other registers */ #define IVTV_REG_DEC_LINE_FIELD (0x28C0) @@ -158,7 +158,7 @@ extern int ivtv_fw_debug; #define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \ do { \ - if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \ + if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \ v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \ } while (0) #define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warn", fmt , ## args) @@ -226,9 +226,9 @@ struct ivtv_mailbox_data { /* per-stream, s_flags */ #define IVTV_F_S_DMA_PENDING 0 /* this stream has pending DMA */ #define IVTV_F_S_DMA_HAS_VBI 1 /* the current DMA request also requests VBI data */ -#define IVTV_F_S_NEEDS_DATA 2 /* this decoding stream needs more data */ +#define IVTV_F_S_NEEDS_DATA 2 /* this decoding stream needs more data */ -#define IVTV_F_S_CLAIMED 3 /* this stream is claimed */ +#define IVTV_F_S_CLAIMED 3 /* this stream is claimed */ #define IVTV_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */ #define IVTV_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ #define IVTV_F_S_PASSTHROUGH 6 /* this stream is in passthrough mode */ @@ -239,35 +239,35 @@ struct ivtv_mailbox_data { #define IVTV_F_S_PIO_HAS_VBI 1 /* the current PIO request also requests VBI data */ /* per-ivtv, i_flags */ -#define IVTV_F_I_DMA 0 /* DMA in progress */ -#define IVTV_F_I_UDMA 1 /* UDMA in progress */ -#define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */ -#define IVTV_F_I_SPEED_CHANGE 3 /* a speed change is in progress */ -#define IVTV_F_I_EOS 4 /* end of encoder stream reached */ -#define IVTV_F_I_RADIO_USER 5 /* the radio tuner is selected */ -#define IVTV_F_I_DIG_RST 6 /* reset digitizer */ -#define IVTV_F_I_DEC_YUV 7 /* YUV instead of MPG is being decoded */ -#define IVTV_F_I_UPDATE_CC 9 /* CC should be updated */ -#define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */ -#define IVTV_F_I_UPDATE_VPS 11 /* VPS should be updated */ -#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */ -#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */ -#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */ -#define IVTV_F_I_HAVE_WORK 15 /* used in the interrupt handler: there is work to be done */ +#define IVTV_F_I_DMA 0 /* DMA in progress */ +#define IVTV_F_I_UDMA 1 /* UDMA in progress */ +#define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */ +#define IVTV_F_I_SPEED_CHANGE 3 /* a speed change is in progress */ +#define IVTV_F_I_EOS 4 /* end of encoder stream reached */ +#define IVTV_F_I_RADIO_USER 5 /* the radio tuner is selected */ +#define IVTV_F_I_DIG_RST 6 /* reset digitizer */ +#define IVTV_F_I_DEC_YUV 7 /* YUV instead of MPG is being decoded */ +#define IVTV_F_I_UPDATE_CC 9 /* CC should be updated */ +#define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */ +#define IVTV_F_I_UPDATE_VPS 11 /* VPS should be updated */ +#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */ +#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */ +#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */ +#define IVTV_F_I_HAVE_WORK 15 /* used in the interrupt handler: there is work to be done */ #define IVTV_F_I_WORK_HANDLER_VBI 16 /* there is work to be done for VBI */ #define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */ #define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */ #define IVTV_F_I_PIO 19 /* PIO in progress */ -#define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */ -#define IVTV_F_I_INITED 21 /* set after first open */ -#define IVTV_F_I_FAILED 22 /* set if first open failed */ +#define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */ +#define IVTV_F_I_INITED 21 /* set after first open */ +#define IVTV_F_I_FAILED 22 /* set if first open failed */ #define IVTV_F_I_WORK_HANDLER_PCM 23 /* there is work to be done for PCM */ /* Event notifications */ #define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ -#define IVTV_F_I_EV_VSYNC 29 /* VSYNC event */ -#define IVTV_F_I_EV_VSYNC_FIELD 30 /* VSYNC event field (0 = first, 1 = second field) */ -#define IVTV_F_I_EV_VSYNC_ENABLED 31 /* VSYNC event enabled */ +#define IVTV_F_I_EV_VSYNC 29 /* VSYNC event */ +#define IVTV_F_I_EV_VSYNC_FIELD 30 /* VSYNC event field (0 = first, 1 = second field) */ +#define IVTV_F_I_EV_VSYNC_ENABLED 31 /* VSYNC event enabled */ /* Scatter-Gather array element, used in DMA transfers */ struct ivtv_sg_element { @@ -330,13 +330,13 @@ struct ivtv_stream { /* These first four fields are always set, even if the stream is not actually created. */ struct video_device vdev; /* vdev.v4l2_dev is NULL if there is no device */ - struct ivtv *itv; /* for ease of use */ + struct ivtv *itv; /* for ease of use */ const char *name; /* name of the stream */ int type; /* stream type */ u32 caps; /* V4L2 capabilities */ struct v4l2_fh *fh; /* pointer to the streaming filehandle */ - spinlock_t qlock; /* locks access to the queues */ + spinlock_t qlock; /* locks access to the queues */ unsigned long s_flags; /* status flags, see above */ int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */ u32 pending_offset; @@ -564,7 +564,7 @@ struct vbi_info { /* Raw VBI compatibility hack */ - u32 frame; /* frame counter hack needed for backwards compatibility + u32 frame; /* frame counter hack needed for backwards compatibility of old VBI software */ /* Sliced VBI output data */ @@ -620,7 +620,7 @@ struct ivtv { u8 nof_inputs; /* number of video inputs */ u8 nof_audio_inputs; /* number of audio inputs */ u32 v4l2_cap; /* V4L2 capabilities of card */ - u32 hw_flags; /* hardware description of the board */ + u32 hw_flags; /* hardware description of the board */ v4l2_std_id tuner_std; /* the norm of the card's tuner (fixed) */ struct v4l2_subdev *sd_video; /* controlling video decoder subdev */ struct v4l2_subdev *sd_audio; /* controlling audio subdev */ @@ -629,7 +629,7 @@ struct ivtv { volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */ volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */ volatile void __iomem *reg_mem; /* pointer to mapped registers */ - struct ivtv_options options; /* user options */ + struct ivtv_options options; /* user options */ struct v4l2_device v4l2_dev; struct cx2341x_handler cxhdl; @@ -668,7 +668,7 @@ struct ivtv { /* Streams */ int stream_buf_size[IVTV_MAX_STREAMS]; /* stream buffer size */ - struct ivtv_stream streams[IVTV_MAX_STREAMS]; /* stream data */ + struct ivtv_stream streams[IVTV_MAX_STREAMS]; /* stream data */ atomic_t capturing; /* count number of active capture streams */ atomic_t decoding; /* count number of active decoding streams */ @@ -704,7 +704,7 @@ struct ivtv { /* Mailbox */ struct ivtv_mailbox_data enc_mbox; /* encoder mailboxes */ struct ivtv_mailbox_data dec_mbox; /* decoder mailboxes */ - struct ivtv_api_cache api_cache[256]; /* cached API commands */ + struct ivtv_api_cache api_cache[256]; /* cached API commands */ /* I2C */ @@ -828,7 +828,7 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv) /* Call the specified callback for all subdevs matching hw (if 0, then match them all). Ignore any errors. */ -#define ivtv_call_hw(itv, hw, o, f, args...) \ +#define ivtv_call_hw(itv, hw, o, f, args...) \ v4l2_device_mask_call_all(&(itv)->v4l2_dev, hw, o, f, ##args) #define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args) diff --git a/drivers/media/pci/ivtv/ivtv-firmware.c b/drivers/media/pci/ivtv/ivtv-firmware.c index ba279fdb3df8..9f05472fca20 100644 --- a/drivers/media/pci/ivtv/ivtv-firmware.c +++ b/drivers/media/pci/ivtv/ivtv-firmware.c @@ -28,26 +28,26 @@ #include #include -#define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE -#define IVTV_MASK_VPU_ENABLE15 0xFFFFFFF6 -#define IVTV_MASK_VPU_ENABLE16 0xFFFFFFFB -#define IVTV_CMD_VDM_STOP 0x00000000 -#define IVTV_CMD_AO_STOP 0x00000005 -#define IVTV_CMD_APU_PING 0x00000000 -#define IVTV_CMD_VPU_STOP15 0xFFFFFFFE -#define IVTV_CMD_VPU_STOP16 0xFFFFFFEE -#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF -#define IVTV_CMD_SPU_STOP 0x00000001 -#define IVTV_CMD_SDRAM_PRECHARGE_INIT 0x0000001A -#define IVTV_CMD_SDRAM_REFRESH_INIT 0x80000640 -#define IVTV_SDRAM_SLEEPTIME 600 - -#define IVTV_DECODE_INIT_MPEG_FILENAME "v4l-cx2341x-init.mpg" -#define IVTV_DECODE_INIT_MPEG_SIZE (152*1024) +#define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE +#define IVTV_MASK_VPU_ENABLE15 0xFFFFFFF6 +#define IVTV_MASK_VPU_ENABLE16 0xFFFFFFFB +#define IVTV_CMD_VDM_STOP 0x00000000 +#define IVTV_CMD_AO_STOP 0x00000005 +#define IVTV_CMD_APU_PING 0x00000000 +#define IVTV_CMD_VPU_STOP15 0xFFFFFFFE +#define IVTV_CMD_VPU_STOP16 0xFFFFFFEE +#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF +#define IVTV_CMD_SPU_STOP 0x00000001 +#define IVTV_CMD_SDRAM_PRECHARGE_INIT 0x0000001A +#define IVTV_CMD_SDRAM_REFRESH_INIT 0x80000640 +#define IVTV_SDRAM_SLEEPTIME 600 + +#define IVTV_DECODE_INIT_MPEG_FILENAME "v4l-cx2341x-init.mpg" +#define IVTV_DECODE_INIT_MPEG_SIZE (152*1024) /* Encoder/decoder firmware sizes */ -#define IVTV_FW_ENC_SIZE (376836) -#define IVTV_FW_DEC_SIZE (256*1024) +#define IVTV_FW_ENC_SIZE (376836) +#define IVTV_FW_DEC_SIZE (256*1024) static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv *itv, long size) { diff --git a/drivers/media/pci/ivtv/ivtv-i2c.c b/drivers/media/pci/ivtv/ivtv-i2c.c index 66696e6ee587..522cd111e399 100644 --- a/drivers/media/pci/ivtv/ivtv-i2c.c +++ b/drivers/media/pci/ivtv/ivtv-i2c.c @@ -76,22 +76,22 @@ #define IVTV_CS53L32A_I2C_ADDR 0x11 #define IVTV_M52790_I2C_ADDR 0x48 -#define IVTV_CX25840_I2C_ADDR 0x44 -#define IVTV_SAA7115_I2C_ADDR 0x21 -#define IVTV_SAA7127_I2C_ADDR 0x44 -#define IVTV_SAA717x_I2C_ADDR 0x21 -#define IVTV_MSP3400_I2C_ADDR 0x40 -#define IVTV_HAUPPAUGE_I2C_ADDR 0x50 -#define IVTV_WM8739_I2C_ADDR 0x1a +#define IVTV_CX25840_I2C_ADDR 0x44 +#define IVTV_SAA7115_I2C_ADDR 0x21 +#define IVTV_SAA7127_I2C_ADDR 0x44 +#define IVTV_SAA717x_I2C_ADDR 0x21 +#define IVTV_MSP3400_I2C_ADDR 0x40 +#define IVTV_HAUPPAUGE_I2C_ADDR 0x50 +#define IVTV_WM8739_I2C_ADDR 0x1a #define IVTV_WM8775_I2C_ADDR 0x1b #define IVTV_TEA5767_I2C_ADDR 0x60 -#define IVTV_UPD64031A_I2C_ADDR 0x12 -#define IVTV_UPD64083_I2C_ADDR 0x5c -#define IVTV_VP27SMPX_I2C_ADDR 0x5b -#define IVTV_M52790_I2C_ADDR 0x48 +#define IVTV_UPD64031A_I2C_ADDR 0x12 +#define IVTV_UPD64083_I2C_ADDR 0x5c +#define IVTV_VP27SMPX_I2C_ADDR 0x5b +#define IVTV_M52790_I2C_ADDR 0x48 #define IVTV_AVERMEDIA_IR_RX_I2C_ADDR 0x40 -#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 0x1a -#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18 +#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 0x1a +#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18 #define IVTV_Z8F0811_IR_TX_I2C_ADDR 0x70 #define IVTV_Z8F0811_IR_RX_I2C_ADDR 0x71 #define IVTV_ADAPTEC_IR_ADDR 0x6b diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c index 670462d195b5..4cdc6d2be85d 100644 --- a/drivers/media/pci/ivtv/ivtv-ioctl.c +++ b/drivers/media/pci/ivtv/ivtv-ioctl.c @@ -1884,65 +1884,65 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio, } static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { - .vidioc_querycap = ivtv_querycap, - .vidioc_s_audio = ivtv_s_audio, - .vidioc_g_audio = ivtv_g_audio, - .vidioc_enumaudio = ivtv_enumaudio, - .vidioc_s_audout = ivtv_s_audout, - .vidioc_g_audout = ivtv_g_audout, - .vidioc_enum_input = ivtv_enum_input, - .vidioc_enum_output = ivtv_enum_output, - .vidioc_enumaudout = ivtv_enumaudout, - .vidioc_cropcap = ivtv_cropcap, + .vidioc_querycap = ivtv_querycap, + .vidioc_s_audio = ivtv_s_audio, + .vidioc_g_audio = ivtv_g_audio, + .vidioc_enumaudio = ivtv_enumaudio, + .vidioc_s_audout = ivtv_s_audout, + .vidioc_g_audout = ivtv_g_audout, + .vidioc_enum_input = ivtv_enum_input, + .vidioc_enum_output = ivtv_enum_output, + .vidioc_enumaudout = ivtv_enumaudout, + .vidioc_cropcap = ivtv_cropcap, .vidioc_s_selection = ivtv_s_selection, .vidioc_g_selection = ivtv_g_selection, - .vidioc_g_input = ivtv_g_input, - .vidioc_s_input = ivtv_s_input, - .vidioc_g_output = ivtv_g_output, - .vidioc_s_output = ivtv_s_output, - .vidioc_g_frequency = ivtv_g_frequency, - .vidioc_s_frequency = ivtv_s_frequency, - .vidioc_s_tuner = ivtv_s_tuner, - .vidioc_g_tuner = ivtv_g_tuner, - .vidioc_g_enc_index = ivtv_g_enc_index, + .vidioc_g_input = ivtv_g_input, + .vidioc_s_input = ivtv_s_input, + .vidioc_g_output = ivtv_g_output, + .vidioc_s_output = ivtv_s_output, + .vidioc_g_frequency = ivtv_g_frequency, + .vidioc_s_frequency = ivtv_s_frequency, + .vidioc_s_tuner = ivtv_s_tuner, + .vidioc_g_tuner = ivtv_g_tuner, + .vidioc_g_enc_index = ivtv_g_enc_index, .vidioc_g_fbuf = ivtv_g_fbuf, .vidioc_s_fbuf = ivtv_s_fbuf, - .vidioc_g_std = ivtv_g_std, - .vidioc_s_std = ivtv_s_std, + .vidioc_g_std = ivtv_g_std, + .vidioc_s_std = ivtv_s_std, .vidioc_overlay = ivtv_overlay, .vidioc_log_status = ivtv_log_status, - .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap, - .vidioc_encoder_cmd = ivtv_encoder_cmd, - .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd, + .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap, + .vidioc_encoder_cmd = ivtv_encoder_cmd, + .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd, .vidioc_decoder_cmd = ivtv_decoder_cmd, .vidioc_try_decoder_cmd = ivtv_try_decoder_cmd, - .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out, - .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap, + .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out, + .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap, .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap, .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap, .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out, .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay, .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out, - .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap, - .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap, + .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap, + .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap, .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap, .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out, .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay, .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out, - .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap, .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap, .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap, - .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out, + .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out, .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay, - .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out, - .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap, + .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out, + .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap, #ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = ivtv_g_register, - .vidioc_s_register = ivtv_s_register, + .vidioc_g_register = ivtv_g_register, + .vidioc_s_register = ivtv_s_register, #endif - .vidioc_default = ivtv_default, - .vidioc_subscribe_event = ivtv_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + .vidioc_default = ivtv_default, + .vidioc_subscribe_event = ivtv_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; void ivtv_set_funcs(struct video_device *vdev) diff --git a/drivers/media/pci/ivtv/ivtv-mailbox.c b/drivers/media/pci/ivtv/ivtv-mailbox.c index 9a2506a5edbe..f317c8f0938d 100644 --- a/drivers/media/pci/ivtv/ivtv-mailbox.c +++ b/drivers/media/pci/ivtv/ivtv-mailbox.c @@ -28,118 +28,118 @@ #define IVTV_MBOX_FIRMWARE_DONE 0x00000004 #define IVTV_MBOX_DRIVER_DONE 0x00000002 #define IVTV_MBOX_DRIVER_BUSY 0x00000001 -#define IVTV_MBOX_FREE 0x00000000 +#define IVTV_MBOX_FREE 0x00000000 /* Firmware mailbox standard timeout */ -#define IVTV_API_STD_TIMEOUT 0x02000000 +#define IVTV_API_STD_TIMEOUT 0x02000000 -#define API_CACHE (1 << 0) /* Allow the command to be stored in the cache */ -#define API_RESULT (1 << 1) /* Allow 1 second for this cmd to end */ +#define API_CACHE (1 << 0) /* Allow the command to be stored in the cache */ +#define API_RESULT (1 << 1) /* Allow 1 second for this cmd to end */ #define API_FAST_RESULT (3 << 1) /* Allow 0.1 second for this cmd to end */ -#define API_DMA (1 << 3) /* DMA mailbox, has special handling */ -#define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */ -#define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */ +#define API_DMA (1 << 3) /* DMA mailbox, has special handling */ +#define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */ +#define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */ #define API_NO_WAIT_RES (1 << 5) /* Command may not wait for the result */ #define API_NO_POLL (1 << 6) /* Avoid pointless polling */ struct ivtv_api_info { int flags; /* Flags, see above */ - const char *name; /* The name of the command */ + const char *name; /* The name of the command */ }; #define API_ENTRY(x, f) [x] = { (f), #x } static const struct ivtv_api_info api_info[256] = { /* MPEG encoder API */ - API_ENTRY(CX2341X_ENC_PING_FW, API_FAST_RESULT), - API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT | API_NO_POLL), - API_ENTRY(CX2341X_ENC_STOP_CAPTURE, API_RESULT), - API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_PCR_ID, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_FRAME_RATE, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_FRAME_SIZE, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_BIT_RATE, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_GOP_PROPERTIES, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_ASPECT_RATIO, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_MODE, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_PROPS, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_CORING_LEVELS, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_VBI_LINE, API_RESULT), - API_ENTRY(CX2341X_ENC_SET_STREAM_TYPE, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_OUTPUT_PORT, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_AUDIO_PROPERTIES, API_CACHE), - API_ENTRY(CX2341X_ENC_HALT_FW, API_FAST_RESULT), - API_ENTRY(CX2341X_ENC_GET_VERSION, API_FAST_RESULT), - API_ENTRY(CX2341X_ENC_SET_GOP_CLOSURE, API_CACHE), - API_ENTRY(CX2341X_ENC_GET_SEQ_END, API_RESULT), - API_ENTRY(CX2341X_ENC_SET_PGM_INDEX_INFO, API_FAST_RESULT), - API_ENTRY(CX2341X_ENC_SET_VBI_CONFIG, API_RESULT), - API_ENTRY(CX2341X_ENC_SET_DMA_BLOCK_SIZE, API_CACHE), - API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_10, API_FAST_RESULT), - API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_9, API_FAST_RESULT), - API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, API_DMA | API_HIGH_VOL), - API_ENTRY(CX2341X_ENC_INITIALIZE_INPUT, API_RESULT), - API_ENTRY(CX2341X_ENC_SET_FRAME_DROP_RATE, API_CACHE), - API_ENTRY(CX2341X_ENC_PAUSE_ENCODER, API_RESULT), - API_ENTRY(CX2341X_ENC_REFRESH_INPUT, API_NO_WAIT_MB | API_HIGH_VOL), - API_ENTRY(CX2341X_ENC_SET_COPYRIGHT, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_EVENT_NOTIFICATION, API_RESULT), - API_ENTRY(CX2341X_ENC_SET_NUM_VSYNC_LINES, API_CACHE), - API_ENTRY(CX2341X_ENC_SET_PLACEHOLDER, API_CACHE), - API_ENTRY(CX2341X_ENC_MUTE_VIDEO, API_RESULT), - API_ENTRY(CX2341X_ENC_MUTE_AUDIO, API_RESULT), + API_ENTRY(CX2341X_ENC_PING_FW, API_FAST_RESULT), + API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT | API_NO_POLL), + API_ENTRY(CX2341X_ENC_STOP_CAPTURE, API_RESULT), + API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_PCR_ID, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_FRAME_RATE, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_FRAME_SIZE, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_BIT_RATE, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_GOP_PROPERTIES, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_ASPECT_RATIO, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_MODE, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_PROPS, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_CORING_LEVELS, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_VBI_LINE, API_RESULT), + API_ENTRY(CX2341X_ENC_SET_STREAM_TYPE, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_OUTPUT_PORT, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_AUDIO_PROPERTIES, API_CACHE), + API_ENTRY(CX2341X_ENC_HALT_FW, API_FAST_RESULT), + API_ENTRY(CX2341X_ENC_GET_VERSION, API_FAST_RESULT), + API_ENTRY(CX2341X_ENC_SET_GOP_CLOSURE, API_CACHE), + API_ENTRY(CX2341X_ENC_GET_SEQ_END, API_RESULT), + API_ENTRY(CX2341X_ENC_SET_PGM_INDEX_INFO, API_FAST_RESULT), + API_ENTRY(CX2341X_ENC_SET_VBI_CONFIG, API_RESULT), + API_ENTRY(CX2341X_ENC_SET_DMA_BLOCK_SIZE, API_CACHE), + API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_10, API_FAST_RESULT), + API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_9, API_FAST_RESULT), + API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, API_DMA | API_HIGH_VOL), + API_ENTRY(CX2341X_ENC_INITIALIZE_INPUT, API_RESULT), + API_ENTRY(CX2341X_ENC_SET_FRAME_DROP_RATE, API_CACHE), + API_ENTRY(CX2341X_ENC_PAUSE_ENCODER, API_RESULT), + API_ENTRY(CX2341X_ENC_REFRESH_INPUT, API_NO_WAIT_MB | API_HIGH_VOL), + API_ENTRY(CX2341X_ENC_SET_COPYRIGHT, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_EVENT_NOTIFICATION, API_RESULT), + API_ENTRY(CX2341X_ENC_SET_NUM_VSYNC_LINES, API_CACHE), + API_ENTRY(CX2341X_ENC_SET_PLACEHOLDER, API_CACHE), + API_ENTRY(CX2341X_ENC_MUTE_VIDEO, API_RESULT), + API_ENTRY(CX2341X_ENC_MUTE_AUDIO, API_RESULT), API_ENTRY(CX2341X_ENC_SET_VERT_CROP_LINE, API_FAST_RESULT), - API_ENTRY(CX2341X_ENC_MISC, API_FAST_RESULT), + API_ENTRY(CX2341X_ENC_MISC, API_FAST_RESULT), /* Obsolete PULLDOWN API command */ - API_ENTRY(0xb1, API_CACHE), + API_ENTRY(0xb1, API_CACHE), /* MPEG decoder API */ - API_ENTRY(CX2341X_DEC_PING_FW, API_FAST_RESULT), - API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT | API_NO_POLL), - API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, API_RESULT), - API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, API_RESULT), - API_ENTRY(CX2341X_DEC_STEP_VIDEO, API_RESULT), - API_ENTRY(CX2341X_DEC_SET_DMA_BLOCK_SIZE, API_CACHE), - API_ENTRY(CX2341X_DEC_GET_XFER_INFO, API_FAST_RESULT), - API_ENTRY(CX2341X_DEC_GET_DMA_STATUS, API_FAST_RESULT), - API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, API_DMA | API_HIGH_VOL), - API_ENTRY(CX2341X_DEC_PAUSE_PLAYBACK, API_RESULT), - API_ENTRY(CX2341X_DEC_HALT_FW, API_FAST_RESULT), - API_ENTRY(CX2341X_DEC_SET_STANDARD, API_CACHE), - API_ENTRY(CX2341X_DEC_GET_VERSION, API_FAST_RESULT), - API_ENTRY(CX2341X_DEC_SET_STREAM_INPUT, API_CACHE), - API_ENTRY(CX2341X_DEC_GET_TIMING_INFO, API_RESULT /*| API_NO_WAIT_RES*/), - API_ENTRY(CX2341X_DEC_SET_AUDIO_MODE, API_CACHE), - API_ENTRY(CX2341X_DEC_SET_EVENT_NOTIFICATION, API_RESULT), - API_ENTRY(CX2341X_DEC_SET_DISPLAY_BUFFERS, API_CACHE), - API_ENTRY(CX2341X_DEC_EXTRACT_VBI, API_RESULT), - API_ENTRY(CX2341X_DEC_SET_DECODER_SOURCE, API_FAST_RESULT), - API_ENTRY(CX2341X_DEC_SET_PREBUFFERING, API_CACHE), + API_ENTRY(CX2341X_DEC_PING_FW, API_FAST_RESULT), + API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT | API_NO_POLL), + API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, API_RESULT), + API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, API_RESULT), + API_ENTRY(CX2341X_DEC_STEP_VIDEO, API_RESULT), + API_ENTRY(CX2341X_DEC_SET_DMA_BLOCK_SIZE, API_CACHE), + API_ENTRY(CX2341X_DEC_GET_XFER_INFO, API_FAST_RESULT), + API_ENTRY(CX2341X_DEC_GET_DMA_STATUS, API_FAST_RESULT), + API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, API_DMA | API_HIGH_VOL), + API_ENTRY(CX2341X_DEC_PAUSE_PLAYBACK, API_RESULT), + API_ENTRY(CX2341X_DEC_HALT_FW, API_FAST_RESULT), + API_ENTRY(CX2341X_DEC_SET_STANDARD, API_CACHE), + API_ENTRY(CX2341X_DEC_GET_VERSION, API_FAST_RESULT), + API_ENTRY(CX2341X_DEC_SET_STREAM_INPUT, API_CACHE), + API_ENTRY(CX2341X_DEC_GET_TIMING_INFO, API_RESULT /*| API_NO_WAIT_RES*/), + API_ENTRY(CX2341X_DEC_SET_AUDIO_MODE, API_CACHE), + API_ENTRY(CX2341X_DEC_SET_EVENT_NOTIFICATION, API_RESULT), + API_ENTRY(CX2341X_DEC_SET_DISPLAY_BUFFERS, API_CACHE), + API_ENTRY(CX2341X_DEC_EXTRACT_VBI, API_RESULT), + API_ENTRY(CX2341X_DEC_SET_DECODER_SOURCE, API_FAST_RESULT), + API_ENTRY(CX2341X_DEC_SET_PREBUFFERING, API_CACHE), /* OSD API */ - API_ENTRY(CX2341X_OSD_GET_FRAMEBUFFER, API_FAST_RESULT), - API_ENTRY(CX2341X_OSD_GET_PIXEL_FORMAT, API_FAST_RESULT), - API_ENTRY(CX2341X_OSD_SET_PIXEL_FORMAT, API_CACHE), - API_ENTRY(CX2341X_OSD_GET_STATE, API_FAST_RESULT), - API_ENTRY(CX2341X_OSD_SET_STATE, API_CACHE), - API_ENTRY(CX2341X_OSD_GET_OSD_COORDS, API_FAST_RESULT), - API_ENTRY(CX2341X_OSD_SET_OSD_COORDS, API_CACHE), - API_ENTRY(CX2341X_OSD_GET_SCREEN_COORDS, API_FAST_RESULT), - API_ENTRY(CX2341X_OSD_SET_SCREEN_COORDS, API_CACHE), - API_ENTRY(CX2341X_OSD_GET_GLOBAL_ALPHA, API_FAST_RESULT), - API_ENTRY(CX2341X_OSD_SET_GLOBAL_ALPHA, API_CACHE), - API_ENTRY(CX2341X_OSD_SET_BLEND_COORDS, API_CACHE), - API_ENTRY(CX2341X_OSD_GET_FLICKER_STATE, API_FAST_RESULT), - API_ENTRY(CX2341X_OSD_SET_FLICKER_STATE, API_CACHE), - API_ENTRY(CX2341X_OSD_BLT_COPY, API_RESULT), - API_ENTRY(CX2341X_OSD_BLT_FILL, API_RESULT), - API_ENTRY(CX2341X_OSD_BLT_TEXT, API_RESULT), - API_ENTRY(CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, API_CACHE), - API_ENTRY(CX2341X_OSD_SET_CHROMA_KEY, API_CACHE), - API_ENTRY(CX2341X_OSD_GET_ALPHA_CONTENT_INDEX, API_FAST_RESULT), - API_ENTRY(CX2341X_OSD_SET_ALPHA_CONTENT_INDEX, API_CACHE) + API_ENTRY(CX2341X_OSD_GET_FRAMEBUFFER, API_FAST_RESULT), + API_ENTRY(CX2341X_OSD_GET_PIXEL_FORMAT, API_FAST_RESULT), + API_ENTRY(CX2341X_OSD_SET_PIXEL_FORMAT, API_CACHE), + API_ENTRY(CX2341X_OSD_GET_STATE, API_FAST_RESULT), + API_ENTRY(CX2341X_OSD_SET_STATE, API_CACHE), + API_ENTRY(CX2341X_OSD_GET_OSD_COORDS, API_FAST_RESULT), + API_ENTRY(CX2341X_OSD_SET_OSD_COORDS, API_CACHE), + API_ENTRY(CX2341X_OSD_GET_SCREEN_COORDS, API_FAST_RESULT), + API_ENTRY(CX2341X_OSD_SET_SCREEN_COORDS, API_CACHE), + API_ENTRY(CX2341X_OSD_GET_GLOBAL_ALPHA, API_FAST_RESULT), + API_ENTRY(CX2341X_OSD_SET_GLOBAL_ALPHA, API_CACHE), + API_ENTRY(CX2341X_OSD_SET_BLEND_COORDS, API_CACHE), + API_ENTRY(CX2341X_OSD_GET_FLICKER_STATE, API_FAST_RESULT), + API_ENTRY(CX2341X_OSD_SET_FLICKER_STATE, API_CACHE), + API_ENTRY(CX2341X_OSD_BLT_COPY, API_RESULT), + API_ENTRY(CX2341X_OSD_BLT_FILL, API_RESULT), + API_ENTRY(CX2341X_OSD_BLT_TEXT, API_RESULT), + API_ENTRY(CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, API_CACHE), + API_ENTRY(CX2341X_OSD_SET_CHROMA_KEY, API_CACHE), + API_ENTRY(CX2341X_OSD_GET_ALPHA_CONTENT_INDEX, API_FAST_RESULT), + API_ENTRY(CX2341X_OSD_SET_ALPHA_CONTENT_INDEX, API_CACHE) }; static int try_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int mb) diff --git a/drivers/media/pci/mantis/mantis_reg.h b/drivers/media/pci/mantis/mantis_reg.h index 7761f9dc7fe0..762ed9f7a08e 100644 --- a/drivers/media/pci/mantis/mantis_reg.h +++ b/drivers/media/pci/mantis/mantis_reg.h @@ -166,12 +166,12 @@ #define MANTIS_CARD_PLUGOUT (0x01 << 0) #define MANTIS_GPIF_BRADDR 0xa0 -#define MANTIS_GPIF_PCMCIAREG (0x01 << 27) -#define MANTIS_GPIF_PCMCIAIOM (0x01 << 26) +#define MANTIS_GPIF_PCMCIAREG (0x01 << 27) +#define MANTIS_GPIF_PCMCIAIOM (0x01 << 26) #define MANTIS_GPIF_BR_ADDR (0xfffffff << 0) #define MANTIS_GPIF_BRBYTES 0xa4 -#define MANTIS_GPIF_BRCNT (0xfff << 0) +#define MANTIS_GPIF_BRCNT (0xfff << 0) #define MANTIS_PCMCIA_RESET 0xa8 #define MANTIS_PCMCIA_RSTVAL (0xff << 0) diff --git a/drivers/media/pci/mantis/mantis_vp1041.c b/drivers/media/pci/mantis/mantis_vp1041.c index 47e0c48c3abc..0eeccc2d19a5 100644 --- a/drivers/media/pci/mantis/mantis_vp1041.c +++ b/drivers/media/pci/mantis/mantis_vp1041.c @@ -47,70 +47,70 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = { /* 0x0000000b, *//* SYSREG */ { STB0899_DEV_ID , 0x30 }, { STB0899_DISCNTRL1 , 0x32 }, - { STB0899_DISCNTRL2 , 0x80 }, - { STB0899_DISRX_ST0 , 0x04 }, - { STB0899_DISRX_ST1 , 0x00 }, - { STB0899_DISPARITY , 0x00 }, + { STB0899_DISCNTRL2 , 0x80 }, + { STB0899_DISRX_ST0 , 0x04 }, + { STB0899_DISRX_ST1 , 0x00 }, + { STB0899_DISPARITY , 0x00 }, { STB0899_DISSTATUS , 0x20 }, - { STB0899_DISF22 , 0x99 }, - { STB0899_DISF22RX , 0xa8 }, + { STB0899_DISF22 , 0x99 }, + { STB0899_DISF22RX , 0xa8 }, /* SYSREG ? */ - { STB0899_ACRPRESC , 0x11 }, - { STB0899_ACRDIV1 , 0x0a }, - { STB0899_ACRDIV2 , 0x05 }, - { STB0899_DACR1 , 0x00 }, - { STB0899_DACR2 , 0x00 }, - { STB0899_OUTCFG , 0x00 }, - { STB0899_MODECFG , 0x00 }, + { STB0899_ACRPRESC , 0x11 }, + { STB0899_ACRDIV1 , 0x0a }, + { STB0899_ACRDIV2 , 0x05 }, + { STB0899_DACR1 , 0x00 }, + { STB0899_DACR2 , 0x00 }, + { STB0899_OUTCFG , 0x00 }, + { STB0899_MODECFG , 0x00 }, { STB0899_IRQSTATUS_3 , 0xfe }, { STB0899_IRQSTATUS_2 , 0x03 }, { STB0899_IRQSTATUS_1 , 0x7c }, { STB0899_IRQSTATUS_0 , 0xf4 }, - { STB0899_IRQMSK_3 , 0xf3 }, - { STB0899_IRQMSK_2 , 0xfc }, - { STB0899_IRQMSK_1 , 0xff }, + { STB0899_IRQMSK_3 , 0xf3 }, + { STB0899_IRQMSK_2 , 0xfc }, + { STB0899_IRQMSK_1 , 0xff }, { STB0899_IRQMSK_0 , 0xff }, { STB0899_IRQCFG , 0x00 }, - { STB0899_I2CCFG , 0x88 }, - { STB0899_I2CRPT , 0x58 }, + { STB0899_I2CCFG , 0x88 }, + { STB0899_I2CRPT , 0x58 }, { STB0899_IOPVALUE5 , 0x00 }, { STB0899_IOPVALUE4 , 0x33 }, { STB0899_IOPVALUE3 , 0x6d }, { STB0899_IOPVALUE2 , 0x90 }, { STB0899_IOPVALUE1 , 0x60 }, { STB0899_IOPVALUE0 , 0x00 }, - { STB0899_GPIO00CFG , 0x82 }, - { STB0899_GPIO01CFG , 0x82 }, - { STB0899_GPIO02CFG , 0x82 }, - { STB0899_GPIO03CFG , 0x82 }, - { STB0899_GPIO04CFG , 0x82 }, - { STB0899_GPIO05CFG , 0x82 }, - { STB0899_GPIO06CFG , 0x82 }, - { STB0899_GPIO07CFG , 0x82 }, - { STB0899_GPIO08CFG , 0x82 }, - { STB0899_GPIO09CFG , 0x82 }, - { STB0899_GPIO10CFG , 0x82 }, - { STB0899_GPIO11CFG , 0x82 }, - { STB0899_GPIO12CFG , 0x82 }, - { STB0899_GPIO13CFG , 0x82 }, - { STB0899_GPIO14CFG , 0x82 }, - { STB0899_GPIO15CFG , 0x82 }, - { STB0899_GPIO16CFG , 0x82 }, - { STB0899_GPIO17CFG , 0x82 }, - { STB0899_GPIO18CFG , 0x82 }, - { STB0899_GPIO19CFG , 0x82 }, - { STB0899_GPIO20CFG , 0x82 }, - { STB0899_SDATCFG , 0xb8 }, - { STB0899_SCLTCFG , 0xba }, - { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ - { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ - { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ - { STB0899_DIRCLKCFG , 0x82 }, - { STB0899_CLKOUT27CFG , 0x7e }, - { STB0899_STDBYCFG , 0x82 }, - { STB0899_CS0CFG , 0x82 }, - { STB0899_CS1CFG , 0x82 }, - { STB0899_DISEQCOCFG , 0x20 }, + { STB0899_GPIO00CFG , 0x82 }, + { STB0899_GPIO01CFG , 0x82 }, + { STB0899_GPIO02CFG , 0x82 }, + { STB0899_GPIO03CFG , 0x82 }, + { STB0899_GPIO04CFG , 0x82 }, + { STB0899_GPIO05CFG , 0x82 }, + { STB0899_GPIO06CFG , 0x82 }, + { STB0899_GPIO07CFG , 0x82 }, + { STB0899_GPIO08CFG , 0x82 }, + { STB0899_GPIO09CFG , 0x82 }, + { STB0899_GPIO10CFG , 0x82 }, + { STB0899_GPIO11CFG , 0x82 }, + { STB0899_GPIO12CFG , 0x82 }, + { STB0899_GPIO13CFG , 0x82 }, + { STB0899_GPIO14CFG , 0x82 }, + { STB0899_GPIO15CFG , 0x82 }, + { STB0899_GPIO16CFG , 0x82 }, + { STB0899_GPIO17CFG , 0x82 }, + { STB0899_GPIO18CFG , 0x82 }, + { STB0899_GPIO19CFG , 0x82 }, + { STB0899_GPIO20CFG , 0x82 }, + { STB0899_SDATCFG , 0xb8 }, + { STB0899_SCLTCFG , 0xba }, + { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ + { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ + { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ + { STB0899_DIRCLKCFG , 0x82 }, + { STB0899_CLKOUT27CFG , 0x7e }, + { STB0899_STDBYCFG , 0x82 }, + { STB0899_CS0CFG , 0x82 }, + { STB0899_CS1CFG , 0x82 }, + { STB0899_DISEQCOCFG , 0x20 }, { STB0899_GPIO32CFG , 0x82 }, { STB0899_GPIO33CFG , 0x82 }, { STB0899_GPIO34CFG , 0x82 }, @@ -119,35 +119,35 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = { { STB0899_GPIO37CFG , 0x82 }, { STB0899_GPIO38CFG , 0x82 }, { STB0899_GPIO39CFG , 0x82 }, - { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ - { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ - { STB0899_FILTCTRL , 0x00 }, - { STB0899_SYSCTRL , 0x01 }, - { STB0899_STOPCLK1 , 0x20 }, - { STB0899_STOPCLK2 , 0x00 }, + { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ + { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ + { STB0899_FILTCTRL , 0x00 }, + { STB0899_SYSCTRL , 0x01 }, + { STB0899_STOPCLK1 , 0x20 }, + { STB0899_STOPCLK2 , 0x00 }, { STB0899_INTBUFSTATUS , 0x00 }, - { STB0899_INTBUFCTRL , 0x0a }, + { STB0899_INTBUFCTRL , 0x0a }, { 0xffff , 0xff }, }; static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = { - { STB0899_DEMOD , 0x00 }, - { STB0899_RCOMPC , 0xc9 }, - { STB0899_AGC1CN , 0x01 }, - { STB0899_AGC1REF , 0x10 }, + { STB0899_DEMOD , 0x00 }, + { STB0899_RCOMPC , 0xc9 }, + { STB0899_AGC1CN , 0x01 }, + { STB0899_AGC1REF , 0x10 }, { STB0899_RTC , 0x23 }, - { STB0899_TMGCFG , 0x4e }, - { STB0899_AGC2REF , 0x34 }, - { STB0899_TLSR , 0x84 }, - { STB0899_CFD , 0xf7 }, + { STB0899_TMGCFG , 0x4e }, + { STB0899_AGC2REF , 0x34 }, + { STB0899_TLSR , 0x84 }, + { STB0899_CFD , 0xf7 }, { STB0899_ACLC , 0x87 }, - { STB0899_BCLC , 0x94 }, - { STB0899_EQON , 0x41 }, - { STB0899_LDT , 0xf1 }, - { STB0899_LDT2 , 0xe3 }, - { STB0899_EQUALREF , 0xb4 }, - { STB0899_TMGRAMP , 0x10 }, - { STB0899_TMGTHD , 0x30 }, + { STB0899_BCLC , 0x94 }, + { STB0899_EQON , 0x41 }, + { STB0899_LDT , 0xf1 }, + { STB0899_LDT2 , 0xe3 }, + { STB0899_EQUALREF , 0xb4 }, + { STB0899_TMGRAMP , 0x10 }, + { STB0899_TMGTHD , 0x30 }, { STB0899_IDCCOMP , 0xfd }, { STB0899_QDCCOMP , 0xff }, { STB0899_POWERI , 0x0c }, @@ -166,12 +166,12 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = { { STB0899_NIRL , 0x80 }, { STB0899_ISYMB , 0x1d }, { STB0899_QSYMB , 0xa6 }, - { STB0899_SFRH , 0x2f }, - { STB0899_SFRM , 0x68 }, - { STB0899_SFRL , 0x40 }, - { STB0899_SFRUPH , 0x2f }, - { STB0899_SFRUPM , 0x68 }, - { STB0899_SFRUPL , 0x40 }, + { STB0899_SFRH , 0x2f }, + { STB0899_SFRM , 0x68 }, + { STB0899_SFRL , 0x40 }, + { STB0899_SFRUPH , 0x2f }, + { STB0899_SFRUPM , 0x68 }, + { STB0899_SFRUPL , 0x40 }, { STB0899_EQUAI1 , 0x02 }, { STB0899_EQUAQ1 , 0xff }, { STB0899_EQUAI2 , 0x04 }, @@ -183,7 +183,7 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = { { STB0899_EQUAI5 , 0x08 }, { STB0899_EQUAQ5 , 0xf5 }, { STB0899_DSTATUS2 , 0x00 }, - { STB0899_VSTATUS , 0x00 }, + { STB0899_VSTATUS , 0x00 }, { STB0899_VERROR , 0x86 }, { STB0899_IQSWAP , 0x2a }, { STB0899_ECNT1M , 0x00 }, @@ -192,26 +192,26 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = { { STB0899_ECNT2L , 0x00 }, { STB0899_ECNT3M , 0x0a }, { STB0899_ECNT3L , 0xad }, - { STB0899_FECAUTO1 , 0x06 }, + { STB0899_FECAUTO1 , 0x06 }, { STB0899_FECM , 0x01 }, - { STB0899_VTH12 , 0xb0 }, - { STB0899_VTH23 , 0x7a }, + { STB0899_VTH12 , 0xb0 }, + { STB0899_VTH23 , 0x7a }, { STB0899_VTH34 , 0x58 }, - { STB0899_VTH56 , 0x38 }, - { STB0899_VTH67 , 0x34 }, - { STB0899_VTH78 , 0x24 }, - { STB0899_PRVIT , 0xff }, - { STB0899_VITSYNC , 0x19 }, - { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ - { STB0899_TSULC , 0x42 }, - { STB0899_RSLLC , 0x41 }, + { STB0899_VTH56 , 0x38 }, + { STB0899_VTH67 , 0x34 }, + { STB0899_VTH78 , 0x24 }, + { STB0899_PRVIT , 0xff }, + { STB0899_VITSYNC , 0x19 }, + { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ + { STB0899_TSULC , 0x42 }, + { STB0899_RSLLC , 0x41 }, { STB0899_TSLPL , 0x12 }, - { STB0899_TSCFGH , 0x0c }, - { STB0899_TSCFGM , 0x00 }, - { STB0899_TSCFGL , 0x00 }, + { STB0899_TSCFGH , 0x0c }, + { STB0899_TSCFGM , 0x00 }, + { STB0899_TSCFGL , 0x00 }, { STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */ - { STB0899_RSSYNCDEL , 0x00 }, - { STB0899_TSINHDELH , 0x02 }, + { STB0899_RSSYNCDEL , 0x00 }, + { STB0899_TSINHDELH , 0x02 }, { STB0899_TSINHDELM , 0x00 }, { STB0899_TSINHDELL , 0x00 }, { STB0899_TSLLSTKM , 0x1b }, @@ -222,18 +222,18 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = { { STB0899_PCKLENLL , 0xcc }, { STB0899_RSPCKLEN , 0xbd }, { STB0899_TSSTATUS , 0x90 }, - { STB0899_ERRCTRL1 , 0xb6 }, - { STB0899_ERRCTRL2 , 0x95 }, - { STB0899_ERRCTRL3 , 0x8d }, + { STB0899_ERRCTRL1 , 0xb6 }, + { STB0899_ERRCTRL2 , 0x95 }, + { STB0899_ERRCTRL3 , 0x8d }, { STB0899_DMONMSK1 , 0x27 }, { STB0899_DMONMSK0 , 0x03 }, - { STB0899_DEMAPVIT , 0x5c }, + { STB0899_DEMAPVIT , 0x5c }, { STB0899_PLPARM , 0x19 }, - { STB0899_PDELCTRL , 0x48 }, - { STB0899_PDELCTRL2 , 0x00 }, - { STB0899_BBHCTRL1 , 0x00 }, - { STB0899_BBHCTRL2 , 0x00 }, - { STB0899_HYSTTHRESH , 0x77 }, + { STB0899_PDELCTRL , 0x48 }, + { STB0899_PDELCTRL2 , 0x00 }, + { STB0899_BBHCTRL1 , 0x00 }, + { STB0899_BBHCTRL2 , 0x00 }, + { STB0899_HYSTTHRESH , 0x77 }, { STB0899_MATCSTM , 0x00 }, { STB0899_MATCSTL , 0x00 }, { STB0899_UPLCSTM , 0x00 }, @@ -270,7 +270,7 @@ static struct stb0899_config vp1041_stb0899_config = { .init_s2_fec = stb0899_s2_init_4, .init_tst = stb0899_s1_init_5, - .demod_address = 0x68, /* 0xd0 >> 1 */ + .demod_address = 0x68, /* 0xd0 >> 1 */ .xtal_freq = 27000000, .inversion = IQ_SWAP_ON, diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c index 23999a8cef37..be860ec129b6 100644 --- a/drivers/media/pci/meye/meye.c +++ b/drivers/media/pci/meye/meye.c @@ -1536,7 +1536,7 @@ static const struct v4l2_ioctl_ops meye_ioctl_ops = { static const struct video_device meye_template = { .name = "meye", .fops = &meye_fops, - .ioctl_ops = &meye_ioctl_ops, + .ioctl_ops = &meye_ioctl_ops, .release = video_device_release_empty, }; diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index 9965d3531c80..9d6688a82b50 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -323,7 +323,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x20, + .empress_addr = 0x20, .inputs = {{ .type = SAA7134_INPUT_COMPOSITE1, @@ -454,7 +454,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x20, + .empress_addr = 0x20, .tda9887_conf = TDA9887_PRESENT, .gpiomask = 0x820000, .inputs = {{ @@ -849,7 +849,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x20, + .empress_addr = 0x20, .inputs = {{ .type = SAA7134_INPUT_COMPOSITE1, .vmux = 4, @@ -1006,7 +1006,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x20, + .empress_addr = 0x20, .inputs = {{ .type = SAA7134_INPUT_COMPOSITE1, .vmux = 1, @@ -1767,7 +1767,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .rds_addr = 0x10, + .rds_addr = 0x10, .tda9887_conf = TDA9887_PRESENT, .inputs = {{ .type = SAA7134_INPUT_TV, @@ -2412,7 +2412,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x21, + .empress_addr = 0x21, .inputs = {{ .type = SAA7134_INPUT_COMPOSITE0, .vmux = 0, @@ -3978,13 +3978,13 @@ struct saa7134_board saa7134_boards[] = { [SAA7134_BOARD_BEHOLD_407] = { /* Beholder Intl. Ltd. 2008 */ /*Dmitry Belimov */ - .name = "Beholder BeholdTV 407", - .audio_clock = 0x00187de7, - .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT, + .name = "Beholder BeholdTV 407", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, .gpiomask = 0x00008000, .inputs = {{ .type = SAA7134_INPUT_SVIDEO, @@ -4006,13 +4006,13 @@ struct saa7134_board saa7134_boards[] = { [SAA7134_BOARD_BEHOLD_407FM] = { /* Beholder Intl. Ltd. 2008 */ /*Dmitry Belimov */ - .name = "Beholder BeholdTV 407 FM", - .audio_clock = 0x00187de7, - .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT, + .name = "Beholder BeholdTV 407 FM", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, .gpiomask = 0x00008000, .inputs = {{ .type = SAA7134_INPUT_SVIDEO, @@ -4103,7 +4103,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .rds_addr = 0x10, + .rds_addr = 0x10, .tda9887_conf = TDA9887_PRESENT, .gpiomask = 0x00008000, .inputs = {{ @@ -4166,7 +4166,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .rds_addr = 0x10, + .rds_addr = 0x10, .tda9887_conf = TDA9887_PRESENT, .gpiomask = 0x00008000, .inputs = {{ @@ -4196,7 +4196,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .rds_addr = 0x10, + .rds_addr = 0x10, .tda9887_conf = TDA9887_PRESENT, .gpiomask = 0x00008000, .inputs = {{ @@ -4366,7 +4366,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .rds_addr = 0x10, + .rds_addr = 0x10, .tda9887_conf = TDA9887_PRESENT, .inputs = {{ .type = SAA7134_INPUT_TV, @@ -4394,7 +4394,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .rds_addr = 0x10, + .rds_addr = 0x10, .tda9887_conf = TDA9887_PRESENT, .inputs = {{ .type = SAA7134_INPUT_TV, @@ -4422,7 +4422,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .rds_addr = 0x10, + .rds_addr = 0x10, .tda9887_conf = TDA9887_PRESENT, .inputs = {{ .type = SAA7134_INPUT_TV, @@ -4450,7 +4450,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .rds_addr = 0x10, + .rds_addr = 0x10, .tda9887_conf = TDA9887_PRESENT, .inputs = {{ .type = SAA7134_INPUT_TV, @@ -4481,7 +4481,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x20, + .empress_addr = 0x20, .tda9887_conf = TDA9887_PRESENT, .inputs = { { .type = SAA7134_INPUT_TV, @@ -4517,7 +4517,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .empress_addr = 0x20, + .empress_addr = 0x20, .tda9887_conf = TDA9887_PRESENT, .inputs = { { .type = SAA7134_INPUT_TV, @@ -4554,8 +4554,8 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .rds_addr = 0x10, - .empress_addr = 0x20, + .rds_addr = 0x10, + .empress_addr = 0x20, .tda9887_conf = TDA9887_PRESENT, .inputs = { { .type = SAA7134_INPUT_TV, @@ -5297,7 +5297,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .rds_addr = 0x10, + .rds_addr = 0x10, .tda9887_conf = TDA9887_PRESENT, .gpiomask = 0x00008000, .inputs = {{ diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c index b55f9a1d9a63..a7a63d608dde 100644 --- a/drivers/media/pci/saa7134/saa7134-dvb.c +++ b/drivers/media/pci/saa7134/saa7134-dvb.c @@ -1389,7 +1389,7 @@ static int dvb_init(struct saa7134_dev *dev) if (configure_tda827x_fe(dev, &lifeview_trio_config, &tda827x_cfg_0) < 0) goto detach_frontend; - } else { /* satellite */ + } else { /* satellite */ fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); if (fe0->dvb.frontend) { if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63, @@ -1659,7 +1659,7 @@ static int dvb_init(struct saa7134_dev *dev) if (configure_tda827x_fe(dev, &asus_tiger_3in1_config, &tda827x_cfg_2) < 0) goto detach_frontend; - } else { /* satellite */ + } else { /* satellite */ fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); if (fe0->dvb.frontend) { diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 1ae5d2dac3bf..052e101d898c 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -2043,14 +2043,14 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { struct video_device saa7134_video_template = { .name = "saa7134-video", .fops = &video_fops, - .ioctl_ops = &video_ioctl_ops, + .ioctl_ops = &video_ioctl_ops, .tvnorms = SAA7134_NORMS, }; struct video_device saa7134_radio_template = { .name = "saa7134-radio", .fops = &radio_fops, - .ioctl_ops = &radio_ioctl_ops, + .ioctl_ops = &radio_ioctl_ops, }; static const struct v4l2_ctrl_ops saa7134_ctrl_ops = { diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h index 39c36e6aefbe..d99e937a98c1 100644 --- a/drivers/media/pci/saa7134/saa7134.h +++ b/drivers/media/pci/saa7134/saa7134.h @@ -261,8 +261,8 @@ struct saa7134_card_ir { #define SAA7134_BOARD_SABRENT_TV_PCB05 115 #define SAA7134_BOARD_10MOONSTVMASTER3 116 #define SAA7134_BOARD_AVERMEDIA_SUPER_007 117 -#define SAA7134_BOARD_BEHOLD_401 118 -#define SAA7134_BOARD_BEHOLD_403 119 +#define SAA7134_BOARD_BEHOLD_401 118 +#define SAA7134_BOARD_BEHOLD_403 119 #define SAA7134_BOARD_BEHOLD_403FM 120 #define SAA7134_BOARD_BEHOLD_405 121 #define SAA7134_BOARD_BEHOLD_405FM 122 @@ -581,7 +581,7 @@ struct saa7134_dev { /* config info */ unsigned int board; unsigned int tuner_type; - unsigned int radio_type; + unsigned int radio_type; unsigned char tuner_addr; unsigned char radio_addr; @@ -592,7 +592,7 @@ struct saa7134_dev { struct i2c_adapter i2c_adap; struct i2c_client i2c_client; unsigned char eedata[256]; - int has_rds; + int has_rds; /* video overlay */ struct v4l2_framebuffer ovbuf; diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c index 39357eddee32..5817d9cde4d0 100644 --- a/drivers/media/pci/saa7146/hexium_gemini.c +++ b/drivers/media/pci/saa7146/hexium_gemini.c @@ -70,8 +70,8 @@ struct hexium struct video_device video_dev; struct i2c_adapter i2c_adapter; - int cur_input; /* current input */ - v4l2_std_id cur_std; /* current standard */ + int cur_input; /* current input */ + v4l2_std_id cur_std; /* current standard */ }; /* Samsung KS0127B decoder default registers */ @@ -138,19 +138,19 @@ static struct hexium_data hexium_input_select[] = { are currently *not* supported*/ static struct saa7146_standard hexium_standards[] = { { - .name = "PAL", .id = V4L2_STD_PAL, - .v_offset = 28, .v_field = 288, - .h_offset = 1, .h_pixels = 680, + .name = "PAL", .id = V4L2_STD_PAL, + .v_offset = 28, .v_field = 288, + .h_offset = 1, .h_pixels = 680, .v_max_out = 576, .h_max_out = 768, }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 28, .v_field = 240, - .h_offset = 1, .h_pixels = 640, + .name = "NTSC", .id = V4L2_STD_NTSC, + .v_offset = 28, .v_field = 240, + .h_offset = 1, .h_pixels = 640, .v_max_out = 480, .h_max_out = 640, }, { - .name = "SECAM", .id = V4L2_STD_SECAM, - .v_offset = 28, .v_field = 288, - .h_offset = 1, .h_pixels = 720, + .name = "SECAM", .id = V4L2_STD_SECAM, + .v_offset = 28, .v_field = 288, + .h_offset = 1, .h_pixels = 720, .v_max_out = 576, .h_max_out = 768, } }; diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c index 461e421080f3..0a05176c18ab 100644 --- a/drivers/media/pci/saa7146/hexium_orion.c +++ b/drivers/media/pci/saa7146/hexium_orion.c @@ -188,19 +188,19 @@ static struct { static struct saa7146_standard hexium_standards[] = { { - .name = "PAL", .id = V4L2_STD_PAL, - .v_offset = 16, .v_field = 288, - .h_offset = 1, .h_pixels = 680, + .name = "PAL", .id = V4L2_STD_PAL, + .v_offset = 16, .v_field = 288, + .h_offset = 1, .h_pixels = 680, .v_max_out = 576, .h_max_out = 768, }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 16, .v_field = 240, - .h_offset = 1, .h_pixels = 640, + .name = "NTSC", .id = V4L2_STD_NTSC, + .v_offset = 16, .v_field = 240, + .h_offset = 1, .h_pixels = 640, .v_max_out = 480, .h_max_out = 640, }, { - .name = "SECAM", .id = V4L2_STD_SECAM, - .v_offset = 16, .v_field = 288, - .h_offset = 1, .h_pixels = 720, + .name = "SECAM", .id = V4L2_STD_SECAM, + .v_offset = 16, .v_field = 288, + .h_offset = 1, .h_pixels = 720, .v_max_out = 576, .h_max_out = 768, } }; diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c index 2526fc051b65..6b5582b7c595 100644 --- a/drivers/media/pci/saa7146/mxb.c +++ b/drivers/media/pci/saa7146/mxb.c @@ -793,24 +793,24 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa static struct saa7146_standard standard[] = { { - .name = "PAL-BG", .id = V4L2_STD_PAL_BG, - .v_offset = 0x17, .v_field = 288, - .h_offset = 0x14, .h_pixels = 680, + .name = "PAL-BG", .id = V4L2_STD_PAL_BG, + .v_offset = 0x17, .v_field = 288, + .h_offset = 0x14, .h_pixels = 680, .v_max_out = 576, .h_max_out = 768, }, { - .name = "PAL-I", .id = V4L2_STD_PAL_I, - .v_offset = 0x17, .v_field = 288, - .h_offset = 0x14, .h_pixels = 680, + .name = "PAL-I", .id = V4L2_STD_PAL_I, + .v_offset = 0x17, .v_field = 288, + .h_offset = 0x14, .h_pixels = 680, .v_max_out = 576, .h_max_out = 768, }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 0x16, .v_field = 240, - .h_offset = 0x06, .h_pixels = 708, + .name = "NTSC", .id = V4L2_STD_NTSC, + .v_offset = 0x16, .v_field = 240, + .h_offset = 0x06, .h_pixels = 708, .v_max_out = 480, .h_max_out = 640, }, { - .name = "SECAM", .id = V4L2_STD_SECAM, - .v_offset = 0x14, .v_field = 288, - .h_offset = 0x14, .h_pixels = 720, + .name = "SECAM", .id = V4L2_STD_SECAM, + .v_offset = 0x14, .v_field = 288, + .h_offset = 0x14, .h_pixels = 720, .v_max_out = 576, .h_max_out = 768, } }; diff --git a/drivers/media/pci/ttpci/av7110.h b/drivers/media/pci/ttpci/av7110.h index 9bfbb1471717..8606ef5ebbe2 100644 --- a/drivers/media/pci/ttpci/av7110.h +++ b/drivers/media/pci/ttpci/av7110.h @@ -52,7 +52,7 @@ extern int av7110_debug; enum {AV_PES_STREAM, PS_STREAM, TS_STREAM, PES_STREAM}; enum av7110_video_mode { - AV7110_VIDEO_MODE_PAL = 0, + AV7110_VIDEO_MODE_PAL = 0, AV7110_VIDEO_MODE_NTSC = 1 }; diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c index 6b0e09ca01dc..abc98f1ad26c 100644 --- a/drivers/media/pci/ttpci/budget-av.c +++ b/drivers/media/pci/ttpci/budget-av.c @@ -1181,14 +1181,14 @@ static u8 read_pwm(struct budget_av *budget_av) #define SUBID_DVBS_KNC1_PLUS 0x0011 #define SUBID_DVBS_TYPHOON 0x4f56 #define SUBID_DVBS_CINERGY1200 0x1154 -#define SUBID_DVBS_CYNERGY1200N 0x1155 +#define SUBID_DVBS_CYNERGY1200N 0x1155 #define SUBID_DVBS_TV_STAR 0x0014 #define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015 #define SUBID_DVBS_TV_STAR_CI 0x0016 #define SUBID_DVBS2_KNC1 0x0018 #define SUBID_DVBS2_KNC1_OEM 0x0019 -#define SUBID_DVBS_EASYWATCH_1 0x001a -#define SUBID_DVBS_EASYWATCH_2 0x001b +#define SUBID_DVBS_EASYWATCH_1 0x001a +#define SUBID_DVBS_EASYWATCH_2 0x001b #define SUBID_DVBS2_EASYWATCH 0x001d #define SUBID_DVBS_EASYWATCH 0x001e diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c index f67ed118f273..ec8f92540f7c 100644 --- a/drivers/media/pci/ttpci/budget-ci.c +++ b/drivers/media/pci/ttpci/budget-ci.c @@ -1050,70 +1050,70 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = { { STB0899_DEV_ID , 0x81 }, { STB0899_DISCNTRL1 , 0x32 }, - { STB0899_DISCNTRL2 , 0x80 }, - { STB0899_DISRX_ST0 , 0x04 }, - { STB0899_DISRX_ST1 , 0x00 }, - { STB0899_DISPARITY , 0x00 }, + { STB0899_DISCNTRL2 , 0x80 }, + { STB0899_DISRX_ST0 , 0x04 }, + { STB0899_DISRX_ST1 , 0x00 }, + { STB0899_DISPARITY , 0x00 }, { STB0899_DISSTATUS , 0x20 }, - { STB0899_DISF22 , 0x8c }, - { STB0899_DISF22RX , 0x9a }, + { STB0899_DISF22 , 0x8c }, + { STB0899_DISF22RX , 0x9a }, { STB0899_SYSREG , 0x0b }, - { STB0899_ACRPRESC , 0x11 }, - { STB0899_ACRDIV1 , 0x0a }, - { STB0899_ACRDIV2 , 0x05 }, - { STB0899_DACR1 , 0x00 }, - { STB0899_DACR2 , 0x00 }, - { STB0899_OUTCFG , 0x00 }, - { STB0899_MODECFG , 0x00 }, + { STB0899_ACRPRESC , 0x11 }, + { STB0899_ACRDIV1 , 0x0a }, + { STB0899_ACRDIV2 , 0x05 }, + { STB0899_DACR1 , 0x00 }, + { STB0899_DACR2 , 0x00 }, + { STB0899_OUTCFG , 0x00 }, + { STB0899_MODECFG , 0x00 }, { STB0899_IRQSTATUS_3 , 0x30 }, { STB0899_IRQSTATUS_2 , 0x00 }, { STB0899_IRQSTATUS_1 , 0x00 }, { STB0899_IRQSTATUS_0 , 0x00 }, - { STB0899_IRQMSK_3 , 0xf3 }, - { STB0899_IRQMSK_2 , 0xfc }, - { STB0899_IRQMSK_1 , 0xff }, + { STB0899_IRQMSK_3 , 0xf3 }, + { STB0899_IRQMSK_2 , 0xfc }, + { STB0899_IRQMSK_1 , 0xff }, { STB0899_IRQMSK_0 , 0xff }, { STB0899_IRQCFG , 0x00 }, - { STB0899_I2CCFG , 0x88 }, - { STB0899_I2CRPT , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */ + { STB0899_I2CCFG , 0x88 }, + { STB0899_I2CRPT , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */ { STB0899_IOPVALUE5 , 0x00 }, { STB0899_IOPVALUE4 , 0x20 }, { STB0899_IOPVALUE3 , 0xc9 }, { STB0899_IOPVALUE2 , 0x90 }, { STB0899_IOPVALUE1 , 0x40 }, { STB0899_IOPVALUE0 , 0x00 }, - { STB0899_GPIO00CFG , 0x82 }, - { STB0899_GPIO01CFG , 0x82 }, - { STB0899_GPIO02CFG , 0x82 }, - { STB0899_GPIO03CFG , 0x82 }, - { STB0899_GPIO04CFG , 0x82 }, - { STB0899_GPIO05CFG , 0x82 }, - { STB0899_GPIO06CFG , 0x82 }, - { STB0899_GPIO07CFG , 0x82 }, - { STB0899_GPIO08CFG , 0x82 }, - { STB0899_GPIO09CFG , 0x82 }, - { STB0899_GPIO10CFG , 0x82 }, - { STB0899_GPIO11CFG , 0x82 }, - { STB0899_GPIO12CFG , 0x82 }, - { STB0899_GPIO13CFG , 0x82 }, - { STB0899_GPIO14CFG , 0x82 }, - { STB0899_GPIO15CFG , 0x82 }, - { STB0899_GPIO16CFG , 0x82 }, - { STB0899_GPIO17CFG , 0x82 }, - { STB0899_GPIO18CFG , 0x82 }, - { STB0899_GPIO19CFG , 0x82 }, - { STB0899_GPIO20CFG , 0x82 }, - { STB0899_SDATCFG , 0xb8 }, - { STB0899_SCLTCFG , 0xba }, - { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ - { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ - { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ - { STB0899_DIRCLKCFG , 0x82 }, - { STB0899_CLKOUT27CFG , 0x7e }, - { STB0899_STDBYCFG , 0x82 }, - { STB0899_CS0CFG , 0x82 }, - { STB0899_CS1CFG , 0x82 }, - { STB0899_DISEQCOCFG , 0x20 }, + { STB0899_GPIO00CFG , 0x82 }, + { STB0899_GPIO01CFG , 0x82 }, + { STB0899_GPIO02CFG , 0x82 }, + { STB0899_GPIO03CFG , 0x82 }, + { STB0899_GPIO04CFG , 0x82 }, + { STB0899_GPIO05CFG , 0x82 }, + { STB0899_GPIO06CFG , 0x82 }, + { STB0899_GPIO07CFG , 0x82 }, + { STB0899_GPIO08CFG , 0x82 }, + { STB0899_GPIO09CFG , 0x82 }, + { STB0899_GPIO10CFG , 0x82 }, + { STB0899_GPIO11CFG , 0x82 }, + { STB0899_GPIO12CFG , 0x82 }, + { STB0899_GPIO13CFG , 0x82 }, + { STB0899_GPIO14CFG , 0x82 }, + { STB0899_GPIO15CFG , 0x82 }, + { STB0899_GPIO16CFG , 0x82 }, + { STB0899_GPIO17CFG , 0x82 }, + { STB0899_GPIO18CFG , 0x82 }, + { STB0899_GPIO19CFG , 0x82 }, + { STB0899_GPIO20CFG , 0x82 }, + { STB0899_SDATCFG , 0xb8 }, + { STB0899_SCLTCFG , 0xba }, + { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ + { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ + { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ + { STB0899_DIRCLKCFG , 0x82 }, + { STB0899_CLKOUT27CFG , 0x7e }, + { STB0899_STDBYCFG , 0x82 }, + { STB0899_CS0CFG , 0x82 }, + { STB0899_CS1CFG , 0x82 }, + { STB0899_DISEQCOCFG , 0x20 }, { STB0899_GPIO32CFG , 0x82 }, { STB0899_GPIO33CFG , 0x82 }, { STB0899_GPIO34CFG , 0x82 }, @@ -1122,35 +1122,35 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = { { STB0899_GPIO37CFG , 0x82 }, { STB0899_GPIO38CFG , 0x82 }, { STB0899_GPIO39CFG , 0x82 }, - { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ - { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ - { STB0899_FILTCTRL , 0x00 }, - { STB0899_SYSCTRL , 0x00 }, - { STB0899_STOPCLK1 , 0x20 }, - { STB0899_STOPCLK2 , 0x00 }, + { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ + { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ + { STB0899_FILTCTRL , 0x00 }, + { STB0899_SYSCTRL , 0x00 }, + { STB0899_STOPCLK1 , 0x20 }, + { STB0899_STOPCLK2 , 0x00 }, { STB0899_INTBUFSTATUS , 0x00 }, - { STB0899_INTBUFCTRL , 0x0a }, + { STB0899_INTBUFCTRL , 0x0a }, { 0xffff , 0xff }, }; static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = { - { STB0899_DEMOD , 0x00 }, - { STB0899_RCOMPC , 0xc9 }, - { STB0899_AGC1CN , 0x41 }, - { STB0899_AGC1REF , 0x10 }, + { STB0899_DEMOD , 0x00 }, + { STB0899_RCOMPC , 0xc9 }, + { STB0899_AGC1CN , 0x41 }, + { STB0899_AGC1REF , 0x10 }, { STB0899_RTC , 0x7a }, - { STB0899_TMGCFG , 0x4e }, - { STB0899_AGC2REF , 0x34 }, - { STB0899_TLSR , 0x84 }, - { STB0899_CFD , 0xc7 }, + { STB0899_TMGCFG , 0x4e }, + { STB0899_AGC2REF , 0x34 }, + { STB0899_TLSR , 0x84 }, + { STB0899_CFD , 0xc7 }, { STB0899_ACLC , 0x87 }, - { STB0899_BCLC , 0x94 }, - { STB0899_EQON , 0x41 }, - { STB0899_LDT , 0xdd }, - { STB0899_LDT2 , 0xc9 }, - { STB0899_EQUALREF , 0xb4 }, - { STB0899_TMGRAMP , 0x10 }, - { STB0899_TMGTHD , 0x30 }, + { STB0899_BCLC , 0x94 }, + { STB0899_EQON , 0x41 }, + { STB0899_LDT , 0xdd }, + { STB0899_LDT2 , 0xc9 }, + { STB0899_EQUALREF , 0xb4 }, + { STB0899_TMGRAMP , 0x10 }, + { STB0899_TMGTHD , 0x30 }, { STB0899_IDCCOMP , 0xfb }, { STB0899_QDCCOMP , 0x03 }, { STB0899_POWERI , 0x3b }, @@ -1169,12 +1169,12 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = { { STB0899_NIRL , 0x05 }, { STB0899_ISYMB , 0x17 }, { STB0899_QSYMB , 0xfa }, - { STB0899_SFRH , 0x2f }, - { STB0899_SFRM , 0x68 }, - { STB0899_SFRL , 0x40 }, - { STB0899_SFRUPH , 0x2f }, - { STB0899_SFRUPM , 0x68 }, - { STB0899_SFRUPL , 0x40 }, + { STB0899_SFRH , 0x2f }, + { STB0899_SFRM , 0x68 }, + { STB0899_SFRL , 0x40 }, + { STB0899_SFRUPH , 0x2f }, + { STB0899_SFRUPM , 0x68 }, + { STB0899_SFRUPL , 0x40 }, { STB0899_EQUAI1 , 0xfd }, { STB0899_EQUAQ1 , 0x04 }, { STB0899_EQUAI2 , 0x0f }, @@ -1186,7 +1186,7 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = { { STB0899_EQUAI5 , 0xbd }, { STB0899_EQUAQ5 , 0xf7 }, { STB0899_DSTATUS2 , 0x00 }, - { STB0899_VSTATUS , 0x00 }, + { STB0899_VSTATUS , 0x00 }, { STB0899_VERROR , 0xff }, { STB0899_IQSWAP , 0x2a }, { STB0899_ECNT1M , 0x00 }, @@ -1195,26 +1195,26 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = { { STB0899_ECNT2L , 0x00 }, { STB0899_ECNT3M , 0x00 }, { STB0899_ECNT3L , 0x00 }, - { STB0899_FECAUTO1 , 0x06 }, + { STB0899_FECAUTO1 , 0x06 }, { STB0899_FECM , 0x01 }, - { STB0899_VTH12 , 0xf0 }, - { STB0899_VTH23 , 0xa0 }, + { STB0899_VTH12 , 0xf0 }, + { STB0899_VTH23 , 0xa0 }, { STB0899_VTH34 , 0x78 }, - { STB0899_VTH56 , 0x4e }, - { STB0899_VTH67 , 0x48 }, - { STB0899_VTH78 , 0x38 }, - { STB0899_PRVIT , 0xff }, - { STB0899_VITSYNC , 0x19 }, - { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ - { STB0899_TSULC , 0x42 }, - { STB0899_RSLLC , 0x40 }, + { STB0899_VTH56 , 0x4e }, + { STB0899_VTH67 , 0x48 }, + { STB0899_VTH78 , 0x38 }, + { STB0899_PRVIT , 0xff }, + { STB0899_VITSYNC , 0x19 }, + { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ + { STB0899_TSULC , 0x42 }, + { STB0899_RSLLC , 0x40 }, { STB0899_TSLPL , 0x12 }, - { STB0899_TSCFGH , 0x0c }, - { STB0899_TSCFGM , 0x00 }, - { STB0899_TSCFGL , 0x0c }, + { STB0899_TSCFGH , 0x0c }, + { STB0899_TSCFGM , 0x00 }, + { STB0899_TSCFGL , 0x0c }, { STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */ - { STB0899_RSSYNCDEL , 0x00 }, - { STB0899_TSINHDELH , 0x02 }, + { STB0899_RSSYNCDEL , 0x00 }, + { STB0899_TSINHDELH , 0x02 }, { STB0899_TSINHDELM , 0x00 }, { STB0899_TSINHDELL , 0x00 }, { STB0899_TSLLSTKM , 0x00 }, @@ -1225,18 +1225,18 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = { { STB0899_PCKLENLL , 0xcc }, { STB0899_RSPCKLEN , 0xcc }, { STB0899_TSSTATUS , 0x80 }, - { STB0899_ERRCTRL1 , 0xb6 }, - { STB0899_ERRCTRL2 , 0x96 }, - { STB0899_ERRCTRL3 , 0x89 }, + { STB0899_ERRCTRL1 , 0xb6 }, + { STB0899_ERRCTRL2 , 0x96 }, + { STB0899_ERRCTRL3 , 0x89 }, { STB0899_DMONMSK1 , 0x27 }, { STB0899_DMONMSK0 , 0x03 }, - { STB0899_DEMAPVIT , 0x5c }, + { STB0899_DEMAPVIT , 0x5c }, { STB0899_PLPARM , 0x1f }, - { STB0899_PDELCTRL , 0x48 }, - { STB0899_PDELCTRL2 , 0x00 }, - { STB0899_BBHCTRL1 , 0x00 }, - { STB0899_BBHCTRL2 , 0x00 }, - { STB0899_HYSTTHRESH , 0x77 }, + { STB0899_PDELCTRL , 0x48 }, + { STB0899_PDELCTRL2 , 0x00 }, + { STB0899_BBHCTRL1 , 0x00 }, + { STB0899_BBHCTRL2 , 0x00 }, + { STB0899_HYSTTHRESH , 0x77 }, { STB0899_MATCSTM , 0x00 }, { STB0899_MATCSTL , 0x00 }, { STB0899_UPLCSTM , 0x00 }, @@ -1275,7 +1275,7 @@ static struct stb0899_config tt3200_config = { .postproc = NULL, - .demod_address = 0x68, + .demod_address = 0x68, .xtal_freq = 27000000, .inversion = IQ_SWAP_ON, diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c index d07840072337..10fefdf2f1e2 100644 --- a/drivers/media/pci/zoran/zoran_driver.c +++ b/drivers/media/pci/zoran/zoran_driver.c @@ -2792,21 +2792,21 @@ zoran_mmap (struct file *file, } static const struct v4l2_ioctl_ops zoran_ioctl_ops = { - .vidioc_querycap = zoran_querycap, + .vidioc_querycap = zoran_querycap, .vidioc_s_selection = zoran_s_selection, .vidioc_g_selection = zoran_g_selection, - .vidioc_enum_input = zoran_enum_input, - .vidioc_g_input = zoran_g_input, - .vidioc_s_input = zoran_s_input, - .vidioc_enum_output = zoran_enum_output, - .vidioc_g_output = zoran_g_output, - .vidioc_s_output = zoran_s_output, + .vidioc_enum_input = zoran_enum_input, + .vidioc_g_input = zoran_g_input, + .vidioc_s_input = zoran_s_input, + .vidioc_enum_output = zoran_enum_output, + .vidioc_g_output = zoran_g_output, + .vidioc_s_output = zoran_s_output, .vidioc_g_fbuf = zoran_g_fbuf, .vidioc_s_fbuf = zoran_s_fbuf, - .vidioc_g_std = zoran_g_std, - .vidioc_s_std = zoran_s_std, - .vidioc_g_jpegcomp = zoran_g_jpegcomp, - .vidioc_s_jpegcomp = zoran_s_jpegcomp, + .vidioc_g_std = zoran_g_std, + .vidioc_s_std = zoran_s_std, + .vidioc_g_jpegcomp = zoran_g_jpegcomp, + .vidioc_s_jpegcomp = zoran_s_jpegcomp, .vidioc_overlay = zoran_overlay, .vidioc_reqbufs = zoran_reqbufs, .vidioc_querybuf = zoran_querybuf, @@ -2814,18 +2814,18 @@ static const struct v4l2_ioctl_ops zoran_ioctl_ops = { .vidioc_dqbuf = zoran_dqbuf, .vidioc_streamon = zoran_streamon, .vidioc_streamoff = zoran_streamoff, - .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap, - .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out, - .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay, - .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap, + .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap, + .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out, + .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay, + .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap, .vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out, .vidioc_g_fmt_vid_overlay = zoran_g_fmt_vid_overlay, - .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap, .vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out, .vidioc_s_fmt_vid_overlay = zoran_s_fmt_vid_overlay, - .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap, - .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out, - .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay, + .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap, + .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out, + .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; diff --git a/drivers/media/pci/zoran/zr36057.h b/drivers/media/pci/zoran/zr36057.h index c9ffef15532d..c8acb21dcb5c 100644 --- a/drivers/media/pci/zoran/zr36057.h +++ b/drivers/media/pci/zoran/zr36057.h @@ -103,8 +103,8 @@ #define ZR36057_ICR_IntPinEn (1<<24) #define ZR36057_I2CBR 0x044 /* I2C Bus Register */ -#define ZR36057_I2CBR_SDA (1<<1) -#define ZR36057_I2CBR_SCL (1<<0) +#define ZR36057_I2CBR_SDA (1<<1) +#define ZR36057_I2CBR_SCL (1<<0) #define ZR36057_JMC 0x100 /* JPEG Mode and Control */ #define ZR36057_JMC_JPG (1 << 31) diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 347fba8177b5..7f3080437be6 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -23,7 +23,7 @@ obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe/ obj-$(CONFIG_VIDEO_TI_CAL) += ti-vpe/ obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o -obj-$(CONFIG_VIDEO_CODA) += coda/ +obj-$(CONFIG_VIDEO_CODA) += coda/ obj-$(CONFIG_VIDEO_SH_VEU) += sh_veu.o @@ -33,8 +33,8 @@ obj-$(CONFIG_VIDEO_MEM2MEM_DEINTERLACE) += m2m-deinterlace.o obj-$(CONFIG_VIDEO_MUX) += video-mux.o -obj-$(CONFIG_VIDEO_S3C_CAMIF) += s3c-camif/ -obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS) += exynos4-is/ +obj-$(CONFIG_VIDEO_S3C_CAMIF) += s3c-camif/ +obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS) += exynos4-is/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/ @@ -45,13 +45,13 @@ obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC) += exynos-gsc/ obj-$(CONFIG_VIDEO_STI_BDISP) += sti/bdisp/ obj-$(CONFIG_VIDEO_STI_HVA) += sti/hva/ obj-$(CONFIG_DVB_C8SECTPFE) += sti/c8sectpfe/ -obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += sti/cec/ +obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += sti/cec/ obj-$(CONFIG_VIDEO_STI_DELTA) += sti/delta/ obj-$(CONFIG_VIDEO_TEGRA_HDMI_CEC) += tegra-cec/ -obj-y += stm32/ +obj-y += stm32/ obj-y += blackfin/ @@ -62,9 +62,9 @@ obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o obj-$(CONFIG_SOC_CAMERA) += soc_camera/ obj-$(CONFIG_VIDEO_RCAR_DRIF) += rcar_drif.o -obj-$(CONFIG_VIDEO_RENESAS_FCP) += rcar-fcp.o +obj-$(CONFIG_VIDEO_RENESAS_FCP) += rcar-fcp.o obj-$(CONFIG_VIDEO_RENESAS_FDP1) += rcar_fdp1.o -obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o +obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/ obj-$(CONFIG_VIDEO_ROCKCHIP_RGA) += rockchip/rga/ diff --git a/drivers/media/platform/arv.c b/drivers/media/platform/arv.c index 1351374bb1ef..1e865fea803c 100644 --- a/drivers/media/platform/arv.c +++ b/drivers/media/platform/arv.c @@ -56,7 +56,7 @@ #define VERSION "0.0.5" -#define ar_inl(addr) inl((unsigned long)(addr)) +#define ar_inl(addr) inl((unsigned long)(addr)) #define ar_outl(val, addr) outl((unsigned long)(val), (unsigned long)(addr)) extern struct cpuinfo_m32r boot_cpu_data; @@ -210,8 +210,8 @@ static void init_iic(void) * ICU Setting (iic) */ /* I2C Setting */ - ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */ - ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */ + ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */ + ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */ ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */ /* I2C CLK */ @@ -222,7 +222,7 @@ static void init_iic(void) ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */ else ar_outl(244, PLDI2CFREQ); /* default: BCLK = 50MHz */ - ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */ + ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */ } /************************************************************************** @@ -300,9 +300,9 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) ar_outl(ARDATA32, M32R_DMA0CSA_PORTL); ar_outl(ARDATA32, M32R_DMA0RSA_PORTL); ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* destination addr. */ - ar_outl(ar->line_buff, M32R_DMA0RDA_PORTL); /* reload address */ - ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); /* byte count (bytes) */ - ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */ + ar_outl(ar->line_buff, M32R_DMA0RDA_PORTL); /* reload address */ + ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); /* byte count (bytes) */ + ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */ /* * Okay, kick AR LSI to invoke an interrupt @@ -364,7 +364,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos) /* * convert YUV422 to YUV422P - * +--------------------+ + * +--------------------+ * | Y0,Y1,... | * | ..............Yn | * +--------------------+ @@ -533,9 +533,9 @@ static void ar_interrupt(int irq, void *dev) line_count = ar_inl(ARVHCOUNT); /* line number */ if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) { /* operations for interlace mode */ - if (line_count < (AR_HEIGHT_VGA / 2)) /* even line */ + if (line_count < (AR_HEIGHT_VGA / 2)) /* even line */ line_number = (line_count << 1); - else /* odd line */ + else /* odd line */ line_number = (((line_count - (AR_HEIGHT_VGA / 2)) << 1) + 1); } else { @@ -568,7 +568,7 @@ static void ar_interrupt(int irq, void *dev) * if captured all line of a frame, disable AR interrupt * and wake a process up. */ - if (line_number == (ar->height - 1)) { /* end of line */ + if (line_number == (ar->height - 1)) { /* end of line */ ar->start_capture = 0; @@ -718,14 +718,14 @@ static const struct v4l2_file_operations ar_fops = { }; static const struct v4l2_ioctl_ops ar_ioctl_ops = { - .vidioc_querycap = ar_querycap, - .vidioc_g_input = ar_g_input, - .vidioc_s_input = ar_s_input, - .vidioc_enum_input = ar_enum_input, - .vidioc_enum_fmt_vid_cap = ar_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = ar_g_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = ar_s_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = ar_try_fmt_vid_cap, + .vidioc_querycap = ar_querycap, + .vidioc_g_input = ar_g_input, + .vidioc_s_input = ar_s_input, + .vidioc_enum_input = ar_enum_input, + .vidioc_enum_fmt_vid_cap = ar_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = ar_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = ar_s_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = ar_try_fmt_vid_cap, }; #define ALIGN4(x) ((((int)(x)) & 0x3) == 0) @@ -776,9 +776,9 @@ static int __init ar_init(void) video_set_drvdata(&ar->vdev, ar); if (vga) { - ar->width = AR_WIDTH_VGA; - ar->height = AR_HEIGHT_VGA; - ar->size = AR_SIZE_VGA; + ar->width = AR_WIDTH_VGA; + ar->height = AR_HEIGHT_VGA; + ar->size = AR_SIZE_VGA; ar->frame_bytes = AR_FRAME_BYTES_VGA; ar->line_bytes = AR_LINE_BYTES_VGA; if (vga_interlace) @@ -786,9 +786,9 @@ static int __init ar_init(void) else ar->mode = AR_MODE_NORMAL; } else { - ar->width = AR_WIDTH_QVGA; - ar->height = AR_HEIGHT_QVGA; - ar->size = AR_SIZE_QVGA; + ar->width = AR_WIDTH_QVGA; + ar->height = AR_HEIGHT_QVGA; + ar->size = AR_SIZE_QVGA; ar->frame_bytes = AR_FRAME_BYTES_QVGA; ar->line_bytes = AR_LINE_BYTES_QVGA; ar->mode = AR_MODE_INTERLACE; diff --git a/drivers/media/platform/coda/coda_regs.h b/drivers/media/platform/coda/coda_regs.h index 35e620c7f1f4..3b650b8aabe9 100644 --- a/drivers/media/platform/coda/coda_regs.h +++ b/drivers/media/platform/coda/coda_regs.h @@ -125,7 +125,7 @@ #define CODA9_MODE_ENCODE_H264 8 #define CODA9_MODE_ENCODE_MP4 11 #define CODA9_MODE_ENCODE_MJPG 13 -#define CODA_MODE_INVALID 0xffff +#define CODA_MODE_INVALID 0xffff #define CODA_REG_BIT_INT_ENABLE 0x170 #define CODA_INT_INTERRUPT_ENABLE (1 << 3) #define CODA_REG_BIT_INT_REASON 0x174 diff --git a/drivers/media/platform/davinci/dm355_ccdc_regs.h b/drivers/media/platform/davinci/dm355_ccdc_regs.h index a753ce262583..20ba390763b5 100644 --- a/drivers/media/platform/davinci/dm355_ccdc_regs.h +++ b/drivers/media/platform/davinci/dm355_ccdc_regs.h @@ -107,7 +107,7 @@ #define CCDC_RAW_IP_MODE 0 #define CCDC_VDHDOUT_INPUT 0 #define CCDC_YCINSWP_RAW (0 << 4) -#define CCDC_EXWEN_DISABLE 0 +#define CCDC_EXWEN_DISABLE 0 #define CCDC_DATAPOL_NORMAL 0 #define CCDC_CCDCFG_FIDMD_LATCH_VSYNC 0 #define CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC (1 << 6) @@ -152,7 +152,7 @@ #define CCDC_ALAW_GAMMA_WD_MASK 7 #define CCDC_REC656IF_BT656_EN 3 -#define CCDC_FMTCFG_FMTMODE_MASK 3 +#define CCDC_FMTCFG_FMTMODE_MASK 3 #define CCDC_FMTCFG_FMTMODE_SHIFT 1 #define CCDC_FMTCFG_LNUM_MASK 3 #define CCDC_FMTCFG_LNUM_SHIFT 4 @@ -196,7 +196,7 @@ #define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15) #define CCDC_LATCH_ON_VSYNC_ENABLE (0 << 15) #define CCDC_FPC_ENABLE (1 << 15) -#define CCDC_FPC_FPC_NUM_MASK 0x7FFF +#define CCDC_FPC_FPC_NUM_MASK 0x7FFF #define CCDC_DATA_PACK_ENABLE (1 << 11) #define CCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF #define CCDC_FMT_HORZ_FMTSPH_MASK 0x1FFF diff --git a/drivers/media/platform/davinci/dm644x_ccdc_regs.h b/drivers/media/platform/davinci/dm644x_ccdc_regs.h index bece0bd9c9de..ffd89c7ea2b6 100644 --- a/drivers/media/platform/davinci/dm644x_ccdc_regs.h +++ b/drivers/media/platform/davinci/dm644x_ccdc_regs.h @@ -97,7 +97,7 @@ #define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15) #define CCDC_FPC_ENABLE (1 << 15) #define CCDC_FPC_DISABLE 0 -#define CCDC_FPC_FPC_NUM_MASK 0x7FFF +#define CCDC_FPC_FPC_NUM_MASK 0x7FFF #define CCDC_DATA_PACK_ENABLE (1 << 11) #define CCDC_FMTCFG_VPIN_MASK 7 #define CCDC_FMTCFG_VPIN_SHIFT 12 @@ -143,7 +143,7 @@ #define CCDC_REC656IF_BT656_EN 3 #define CCDC_SYN_MODE_VD_POL_NEGATIVE (1 << 2) #define CCDC_CCDCFG_Y8POS_SHIFT 11 -#define CCDC_CCDCFG_BW656_10BIT (1 << 5) +#define CCDC_CCDCFG_BW656_10BIT (1 << 5) #define CCDC_SDOFST_FIELD_INTERLEAVED 0x249 #define CCDC_NO_CULLING 0xffff00ff #endif diff --git a/drivers/media/platform/davinci/isif_regs.h b/drivers/media/platform/davinci/isif_regs.h index a3564abe08ae..97d3ba1614d6 100644 --- a/drivers/media/platform/davinci/isif_regs.h +++ b/drivers/media/platform/davinci/isif_regs.h @@ -35,7 +35,7 @@ #define LINCFG0 0x44 #define LINCFG1 0x48 #define CCOLP 0x4c -#define CRGAIN 0x50 +#define CRGAIN 0x50 #define CGRGAIN 0x54 #define CGBGAIN 0x58 #define CBGAIN 0x5c @@ -46,7 +46,7 @@ #define VDINT0 0x70 #define VDINT1 0x74 #define VDINT2 0x78 -#define MISC 0x7c +#define MISC 0x7c #define CGAMMAWD 0x80 #define REC656IF 0x84 #define CCDCFG 0x88 @@ -191,7 +191,7 @@ #define ISIF_VD_POL_SHIFT 2 #define ISIF_DATAPOL_NORMAL 0 #define ISIF_DATAPOL_SHIFT 6 -#define ISIF_EXWEN_DISABLE 0 +#define ISIF_EXWEN_DISABLE 0 #define ISIF_EXWEN_SHIFT 5 #define ISIF_FRM_FMT_SHIFT 7 #define ISIF_DATASFT_SHIFT 8 diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 498f69b53de3..7d08f0f283a5 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -1794,7 +1794,7 @@ static int vpfe_probe(struct platform_device *pdev) vfd->fops = &vpfe_fops; vfd->ioctl_ops = &vpfe_ioctl_ops; vfd->tvnorms = 0; - vfd->v4l2_dev = &vpfe_dev->v4l2_dev; + vfd->v4l2_dev = &vpfe_dev->v4l2_dev; snprintf(vfd->name, sizeof(vfd->name), "%s_V%d.%d.%d", CAPTURE_DRV_NAME, diff --git a/drivers/media/platform/davinci/vpif.h b/drivers/media/platform/davinci/vpif.h index 9956e6788693..2466c7c77deb 100644 --- a/drivers/media/platform/davinci/vpif.h +++ b/drivers/media/platform/davinci/vpif.h @@ -226,11 +226,11 @@ static inline void vpif_clr_bit(u32 reg, u32 bit) (VPIF_INT_BOTH << VPIF_CH1_INT_CTRL_SHIFT)), VPIF_CH1_CTRL)) /* enabled interrupt on both the fields on vpid_ch0_ctrl register */ -#define channel2_intr_assert() (regw((regr(VPIF_CH2_CTRL)|\ +#define channel2_intr_assert() (regw((regr(VPIF_CH2_CTRL)|\ (VPIF_INT_BOTH << VPIF_CH2_INT_CTRL_SHIFT)), VPIF_CH2_CTRL)) /* enabled interrupt on both the fields on vpid_ch1_ctrl register */ -#define channel3_intr_assert() (regw((regr(VPIF_CH3_CTRL)|\ +#define channel3_intr_assert() (regw((regr(VPIF_CH3_CTRL)|\ (VPIF_INT_BOTH << VPIF_CH3_INT_CTRL_SHIFT)), VPIF_CH3_CTRL)) #define VPIF_CH_FID_MASK (0x20) diff --git a/drivers/media/platform/davinci/vpss.c b/drivers/media/platform/davinci/vpss.c index f2d27b932999..b73886519f4f 100644 --- a/drivers/media/platform/davinci/vpss.c +++ b/drivers/media/platform/davinci/vpss.c @@ -59,9 +59,9 @@ MODULE_AUTHOR("Texas Instruments"); #define DM365_ISP5_INTSEL1 0x10 #define DM365_ISP5_INTSEL2 0x14 #define DM365_ISP5_INTSEL3 0x18 -#define DM365_ISP5_CCDCMUX 0x20 -#define DM365_ISP5_PG_FRAME_SIZE 0x28 -#define DM365_VPBE_CLK_CTRL 0x00 +#define DM365_ISP5_CCDCMUX 0x20 +#define DM365_ISP5_PG_FRAME_SIZE 0x28 +#define DM365_VPBE_CLK_CTRL 0x00 #define VPSS_CLK_CTRL 0x01c40044 #define VPSS_CLK_CTRL_VENCCLKEN BIT(3) @@ -78,8 +78,8 @@ MODULE_AUTHOR("Texas Instruments"); #define DM365_ISP5_INTSEL3_DEFAULT 0x00000015 /* masks and shifts for DM365*/ -#define DM365_CCDC_PG_VD_POL_SHIFT 0 -#define DM365_CCDC_PG_HD_POL_SHIFT 1 +#define DM365_CCDC_PG_VD_POL_SHIFT 0 +#define DM365_CCDC_PG_HD_POL_SHIFT 1 #define CCD_SRC_SEL_MASK (BIT_MASK(5) | BIT_MASK(4)) #define CCD_SRC_SEL_SHIFT 4 diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c index 7ae239f2b0fd..d8d8c9902b19 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.c +++ b/drivers/media/platform/exynos4-is/fimc-core.c @@ -1246,7 +1246,7 @@ static struct platform_driver fimc_driver = { .driver = { .of_match_table = fimc_of_match, .name = FIMC_DRIVER_NAME, - .pm = &fimc_pm_ops, + .pm = &fimc_pm_ops, } }; diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c index c8a12493f395..5f5c34ed4359 100644 --- a/drivers/media/platform/m2m-deinterlace.c +++ b/drivers/media/platform/m2m-deinterlace.c @@ -384,16 +384,16 @@ static void deinterlace_device_run(void *priv) * 4 possible field conversions are possible at the moment: * V4L2_FIELD_SEQ_TB --> V4L2_FIELD_INTERLACED_TB: * two separate fields in the same input buffer are interlaced - * in the output buffer using weaving. Top field comes first. + * in the output buffer using weaving. Top field comes first. * V4L2_FIELD_SEQ_TB --> V4L2_FIELD_NONE: - * top field from the input buffer is copied to the output buffer - * using line doubling. Bottom field from the input buffer is discarded. + * top field from the input buffer is copied to the output buffer + * using line doubling. Bottom field from the input buffer is discarded. * V4L2_FIELD_SEQ_BT --> V4L2_FIELD_INTERLACED_BT: * two separate fields in the same input buffer are interlaced - * in the output buffer using weaving. Bottom field comes first. + * in the output buffer using weaving. Bottom field comes first. * V4L2_FIELD_SEQ_BT --> V4L2_FIELD_NONE: - * bottom field from the input buffer is copied to the output buffer - * using line doubling. Top field from the input buffer is discarded. + * bottom field from the input buffer is copied to the output buffer + * using line doubling. Top field from the input buffer is discarded. */ switch (dst_q_data->fmt->fourcc) { case V4L2_PIX_FMT_YUV420: diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c index 6f1b0c799e58..7278a1ef2931 100644 --- a/drivers/media/platform/omap/omap_vout.c +++ b/drivers/media/platform/omap/omap_vout.c @@ -1774,8 +1774,8 @@ static int vidioc_g_fbuf(struct file *file, void *fh, } static const struct v4l2_ioctl_ops vout_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, + .vidioc_querycap = vidioc_querycap, + .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, .vidioc_g_fmt_vid_out = vidioc_g_fmt_vid_out, .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out, .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out, @@ -1795,12 +1795,12 @@ static const struct v4l2_ioctl_ops vout_ioctl_ops = { }; static const struct v4l2_file_operations omap_vout_fops = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, .poll = omap_vout_poll, .unlocked_ioctl = video_ioctl2, - .mmap = omap_vout_mmap, - .open = omap_vout_open, - .release = omap_vout_release, + .mmap = omap_vout_mmap, + .open = omap_vout_open, + .release = omap_vout_release, }; /* Init functions used during driver initialization */ diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c index 871da2a2a91c..4dccf29e9d78 100644 --- a/drivers/media/platform/sh_vou.c +++ b/drivers/media/platform/sh_vou.c @@ -1181,7 +1181,7 @@ static int sh_vou_release(struct file *file) /* sh_vou display ioctl operations */ static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = { - .vidioc_querycap = sh_vou_querycap, + .vidioc_querycap = sh_vou_querycap, .vidioc_enum_fmt_vid_out = sh_vou_enum_fmt_vid_out, .vidioc_g_fmt_vid_out = sh_vou_g_fmt_vid_out, .vidioc_s_fmt_vid_out = sh_vou_s_fmt_vid_out, diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index ea9308796741..5ef635e72e10 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c @@ -26,7 +26,7 @@ * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool. */ -#include /* Modules */ +#include /* Modules */ #include /* Initdata */ #include /* request_region */ #include /* msleep */ diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index f445327f282d..9e12c6027359 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c @@ -15,7 +15,7 @@ * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool. */ -#include /* Modules */ +#include /* Modules */ #include /* Initdata */ #include /* request_region */ #include /* udelay */ diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index 7575e5370a49..ec5c88801402 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c @@ -30,7 +30,7 @@ * Changed API to V4L2 */ -#include /* Modules */ +#include /* Modules */ #include /* Initdata */ #include /* request_region */ #include /* udelay */ @@ -503,7 +503,7 @@ static unsigned int cadet_poll(struct file *file, struct poll_table_struct *wait static const struct v4l2_file_operations cadet_fops = { .owner = THIS_MODULE, .open = cadet_open, - .release = cadet_release, + .release = cadet_release, .read = cadet_read, .unlocked_ioctl = video_ioctl2, .poll = cadet_poll, diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index ddc12b16f77c..3ff4c4e1435f 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c @@ -22,7 +22,7 @@ * Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool. */ -#include /* Modules */ +#include /* Modules */ #include /* Initdata */ #include /* request_region */ #include /* udelay */ @@ -102,9 +102,9 @@ struct gemtek { u32 bu2614data; }; -#define BU2614_FREQ_BITS 16 /* D0..D15, Frequency data */ +#define BU2614_FREQ_BITS 16 /* D0..D15, Frequency data */ #define BU2614_PORT_BITS 3 /* P0..P2, Output port control data */ -#define BU2614_VOID_BITS 4 /* unused */ +#define BU2614_VOID_BITS 4 /* unused */ #define BU2614_FMES_BITS 1 /* CT, Frequency measurement beginning data */ #define BU2614_STDF_BITS 3 /* R0..R2, Standard frequency data */ #define BU2614_SWIN_BITS 1 /* S, Switch between FMIN / AMIN */ @@ -113,7 +113,7 @@ struct gemtek { #define BU2614_FMUN_BITS 1 /* GT, Frequency measurement time & unlock */ #define BU2614_TEST_BITS 1 /* TS, Test data is input */ -#define BU2614_FREQ_SHIFT 0 +#define BU2614_FREQ_SHIFT 0 #define BU2614_PORT_SHIFT (BU2614_FREQ_BITS + BU2614_FREQ_SHIFT) #define BU2614_VOID_SHIFT (BU2614_PORT_BITS + BU2614_PORT_SHIFT) #define BU2614_FMES_SHIFT (BU2614_VOID_BITS + BU2614_VOID_SHIFT) diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index 09cfbc373c92..abeaedd8d437 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c @@ -12,7 +12,7 @@ * Fully tested with actual hardware and the v4l2-compliance tool. */ -#include /* Modules */ +#include /* Modules */ #include /* Initdata */ #include /* request_region */ #include /* udelay */ diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 28a89466cddc..fc4e63d36e4c 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -17,7 +17,7 @@ */ #include /* __setup */ -#include /* Modules */ +#include /* Modules */ #include /* Initdata */ #include /* request_region */ #include /* udelay */ @@ -110,7 +110,7 @@ static inline int fmi_getsigstr(struct fmi *fmi) val = fmi->mute ? 0x00 : 0x08; /* mute/unmute */ outb(val, fmi->io); outb(val | 0x10, fmi->io); - msleep(143); /* was schedule_timeout(HZ/7) */ + msleep(143); /* was schedule_timeout(HZ/7) */ res = (int)inb(fmi->io + 1); outb(val, fmi->io); diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index de79d5569c2a..7b07d42a9909 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -7,7 +7,7 @@ */ #include -#include /* Modules */ +#include /* Modules */ #include /* Initdata */ #include #include /* request_region */ diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index bc7e69e7e32e..afb763256fd6 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c @@ -417,7 +417,7 @@ static const struct v4l2_ioctl_ops tea5764_ioctl_ops = { static const struct video_device tea5764_radio_template = { .name = "TEA5764 FM-Radio", .fops = &tea5764_fops, - .ioctl_ops = &tea5764_ioctl_ops, + .ioctl_ops = &tea5764_ioctl_ops, .release = video_device_release_empty, }; diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index be10a802e3a9..4f116ea294fb 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c @@ -20,7 +20,7 @@ * Converted to V4L2 API by Mauro Carvalho Chehab */ -#include /* Modules */ +#include /* Modules */ #include /* Initdata */ #include /* request_region */ #include /* kernel radio structs */ @@ -45,12 +45,12 @@ static int radio_nr = -1; module_param(radio_nr, int, 0444); MODULE_PARM_DESC(radio_nr, "Radio device number"); -#define WRT_DIS 0x00 +#define WRT_DIS 0x00 #define CLK_OFF 0x00 #define IIC_DATA 0x01 #define IIC_CLK 0x02 #define DATA 0x04 -#define CLK_ON 0x08 +#define CLK_ON 0x08 #define WRT_EN 0x10 static struct radio_isa_card *terratec_alloc(void) diff --git a/drivers/media/radio/tea575x.c b/drivers/media/radio/tea575x.c index 4dc2067bce14..7412fe1b10c6 100644 --- a/drivers/media/radio/tea575x.c +++ b/drivers/media/radio/tea575x.c @@ -498,7 +498,7 @@ static const struct v4l2_ioctl_ops tea575x_ioctl_ops = { }; static const struct video_device tea575x_radio = { - .ioctl_ops = &tea575x_ioctl_ops, + .ioctl_ops = &tea575x_ioctl_ops, .release = video_device_release_empty, }; diff --git a/drivers/media/rc/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c index 61f679fec45c..e73057945bd1 100644 --- a/drivers/media/rc/keymaps/rc-behold-columbus.c +++ b/drivers/media/rc/keymaps/rc-behold-columbus.c @@ -30,12 +30,12 @@ static struct rc_map_table behold_columbus[] = { /* 0x01 0x02 0x03 0x0D * * 1 2 3 Stereo * - * * + * * * 0x04 0x05 0x06 0x19 * * 4 5 6 Snapshot * - * * + * * * 0x07 0x08 0x09 0x10 * - * 7 8 9 Zoom * + * 7 8 9 Zoom * * */ { 0x01, KEY_1 }, { 0x02, KEY_2 }, diff --git a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c index 30495673cddd..e443192dbe14 100644 --- a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c +++ b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c @@ -37,7 +37,7 @@ static struct rc_map_table winfast_usbii_deluxe[] = { { 0x60, KEY_CHANNELDOWN}, /* CHANNELDOWN */ { 0x61, KEY_LAST}, /* LAST CHANNEL (RECALL) */ - { 0x72, KEY_VIDEO}, /* INPUT MODES (TV/FM) */ + { 0x72, KEY_VIDEO}, /* INPUT MODES (TV/FM) */ { 0x70, KEY_POWER2}, /* TV ON/OFF */ diff --git a/drivers/media/tuners/mxl5005s.c b/drivers/media/tuners/mxl5005s.c index 57c6d9061072..355ef2959b7d 100644 --- a/drivers/media/tuners/mxl5005s.c +++ b/drivers/media/tuners/mxl5005s.c @@ -1677,10 +1677,10 @@ static u16 MXL5005_TunerConfig(struct dvb_frontend *fe, u8 AGC_Mode, /* AGC Mode - Dual AGC: 0, Single AGC: 1 */ u16 TOP, /* 0: Dual AGC; Value: take over point */ u16 IF_OUT_LOAD, /* IF Out Load Resistor (200 / 300 Ohms) */ - u8 CLOCK_OUT, /* 0: turn off clk out; 1: turn on clock out */ + u8 CLOCK_OUT, /* 0: turn off clk out; 1: turn on clock out */ u8 DIV_OUT, /* 0: Div-1; 1: Div-4 */ - u8 CAPSELECT, /* 0: disable On-Chip pulling cap; 1: enable */ - u8 EN_RSSI, /* 0: disable RSSI; 1: enable RSSI */ + u8 CAPSELECT, /* 0: disable On-Chip pulling cap; 1: enable */ + u8 EN_RSSI, /* 0: disable RSSI; 1: enable RSSI */ /* Modulation Type; */ /* 0 - Default; 1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */ diff --git a/drivers/media/tuners/tda827x.h b/drivers/media/tuners/tda827x.h index 264e80bd7e24..a08d3f9fcea1 100644 --- a/drivers/media/tuners/tda827x.h +++ b/drivers/media/tuners/tda827x.h @@ -36,7 +36,7 @@ struct tda827x_config /* interface to tda829x driver */ enum tda8290_lna config; - int switch_addr; + int switch_addr; void (*agcf)(struct dvb_frontend *fe); }; diff --git a/drivers/media/tuners/tda9887.c b/drivers/media/tuners/tda9887.c index c0e815f8b951..9777da03e308 100644 --- a/drivers/media/tuners/tda9887.c +++ b/drivers/media/tuners/tda9887.c @@ -31,7 +31,7 @@ struct tda9887_priv { struct tuner_i2c_props i2c_props; struct list_head hybrid_tuner_instance_list; - unsigned char data[4]; + unsigned char data[4]; unsigned int config; unsigned int mode; unsigned int audmode; @@ -94,7 +94,7 @@ struct tvnorm { #define cAudioGain6 0x80 // bit c7 #define cTopMask 0x1f // bit c0:4 -#define cTopDefault 0x10 // bit c0:4 +#define cTopDefault 0x10 // bit c0:4 //// third reg (e) #define cAudioIF_4_5 0x00 // bit e0:1 diff --git a/drivers/media/tuners/tuner-simple.c b/drivers/media/tuners/tuner-simple.c index cf44d3657f55..36b88f820239 100644 --- a/drivers/media/tuners/tuner-simple.c +++ b/drivers/media/tuners/tuner-simple.c @@ -53,7 +53,7 @@ MODULE_PARM_DESC(dtv_input, "specify dtv rf input, 0 for autoselect"); /* tv tuner system standard selection for Philips FQ1216ME this value takes the low bits of control byte 2 from datasheet "1999 Nov 16" (supersedes "1999 Mar 23") - standard BG DK I L L` + standard BG DK I L L` picture carrier 38.90 38.90 38.90 38.90 33.95 colour 34.47 34.47 34.47 34.47 38.38 sound 1 33.40 32.40 32.90 32.40 40.45 diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c index 8cda36a0b20b..fca85e08ebd7 100644 --- a/drivers/media/tuners/tuner-xc2028.c +++ b/drivers/media/tuners/tuner-xc2028.c @@ -87,7 +87,7 @@ struct firmware_properties { v4l2_std_id std_req; __u16 int_freq; unsigned int scode_table; - int scode_nr; + int scode_nr; }; enum xc2028_state { @@ -137,7 +137,7 @@ struct xc2028_data { ibuf, isize); \ if (isize != _rc) \ tuner_err("i2c input error: rc = %d (should be %d)\n", \ - _rc, (int)isize); \ + _rc, (int)isize); \ if (priv->ctrl.msleep) \ msleep(priv->ctrl.msleep); \ _rc; \ @@ -172,7 +172,7 @@ static int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val) return 0; } -#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0) +#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0) static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq) { if (type & BASE) diff --git a/drivers/media/tuners/tuner-xc2028.h b/drivers/media/tuners/tuner-xc2028.h index cd96288aff54..03fd6d4233a4 100644 --- a/drivers/media/tuners/tuner-xc2028.h +++ b/drivers/media/tuners/tuner-xc2028.h @@ -48,7 +48,7 @@ struct xc2028_ctrl { struct xc2028_config { struct i2c_adapter *i2c_adap; - u8 i2c_addr; + u8 i2c_addr; struct xc2028_ctrl *ctrl; }; diff --git a/drivers/media/usb/au0828/au0828-cards.h b/drivers/media/usb/au0828/au0828-cards.h index 1f4412ee6da4..dbd8a90ee76f 100644 --- a/drivers/media/usb/au0828/au0828-cards.h +++ b/drivers/media/usb/au0828/au0828-cards.h @@ -17,7 +17,7 @@ #define AU0828_BOARD_UNKNOWN 0 #define AU0828_BOARD_HAUPPAUGE_HVR950Q 1 -#define AU0828_BOARD_HAUPPAUGE_HVR850 2 +#define AU0828_BOARD_HAUPPAUGE_HVR850 2 #define AU0828_BOARD_DVICO_FUSIONHDTV7 3 #define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL 4 #define AU0828_BOARD_HAUPPAUGE_WOODBURY 5 diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c index a240153821e0..c765d546114d 100644 --- a/drivers/media/usb/au0828/au0828-video.c +++ b/drivers/media/usb/au0828/au0828-video.c @@ -1797,7 +1797,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { static const struct video_device au0828_video_template = { .fops = &au0828_v4l_fops, .release = video_device_release_empty, - .ioctl_ops = &video_ioctl_ops, + .ioctl_ops = &video_ioctl_ops, .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_M, }; diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h index 9e3c1237a274..004eadef55c7 100644 --- a/drivers/media/usb/au0828/au0828.h +++ b/drivers/media/usb/au0828/au0828.h @@ -190,7 +190,7 @@ struct au0828_dev { struct i2c_adapter i2c_adap; struct i2c_algorithm i2c_algo; struct i2c_client i2c_client; - u32 i2c_rc; + u32 i2c_rc; /* Digital */ struct au0828_dvb dvb; @@ -293,8 +293,8 @@ struct au0828_dev { /* ----------------------------------------------------------- */ #define au0828_read(dev, reg) au0828_readreg(dev, reg) #define au0828_write(dev, reg, value) au0828_writereg(dev, reg, value) -#define au0828_andor(dev, reg, mask, value) \ - au0828_writereg(dev, reg, \ +#define au0828_andor(dev, reg, mask, value) \ + au0828_writereg(dev, reg, \ (au0828_readreg(dev, reg) & ~(mask)) | ((value) & (mask))) #define au0828_set(dev, reg, bit) au0828_andor(dev, (reg), (bit), (bit)) diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c index 6089036049d9..f3a1e5b1e57c 100644 --- a/drivers/media/usb/cpia2/cpia2_usb.c +++ b/drivers/media/usb/cpia2/cpia2_usb.c @@ -33,13 +33,13 @@ static int frame_sizes[] = { 0, // USBIF_CMDONLY - 0, // USBIF_BULK - 128, // USBIF_ISO_1 - 384, // USBIF_ISO_2 - 640, // USBIF_ISO_3 - 768, // USBIF_ISO_4 - 896, // USBIF_ISO_5 - 1023, // USBIF_ISO_6 + 0, // USBIF_BULK + 128, // USBIF_ISO_1 + 384, // USBIF_ISO_2 + 640, // USBIF_ISO_3 + 768, // USBIF_ISO_4 + 896, // USBIF_ISO_5 + 1023, // USBIF_ISO_6 }; #define FRAMES_PER_DESC 10 diff --git a/drivers/media/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c index 06f10d7fc4b0..d96236d786d1 100644 --- a/drivers/media/usb/cx231xx/cx231xx-audio.c +++ b/drivers/media/usb/cx231xx/cx231xx-audio.c @@ -404,9 +404,9 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, } static const struct snd_pcm_hardware snd_cx231xx_hw_capture = { - .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | + .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP_VALID, .formats = SNDRV_PCM_FMTBIT_S16_LE, diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c index 0df62d3951cf..fdd3c221fa0d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-avcore.c +++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c @@ -2168,7 +2168,7 @@ int cx231xx_tuner_post_channel_change(struct cx231xx *dev) } /****************************************************************************** - * I 2 S - B L O C K C O N T R O L functions * + * I 2 S - B L O C K C O N T R O L functions * ******************************************************************************/ int cx231xx_i2s_blk_initialize(struct cx231xx *dev) { diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c index f372ad3917a8..4f43668df15d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-core.c +++ b/drivers/media/usb/cx231xx/cx231xx-core.c @@ -56,7 +56,7 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); dev->name, __func__ , ##arg); } while (0) /***************************************************************** -* Device control list functions * +* Device control list functions * ******************************************************************/ LIST_HEAD(cx231xx_devlist); diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c index 23648dab7be8..6e1bef2a45bb 100644 --- a/drivers/media/usb/cx231xx/cx231xx-i2c.c +++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c @@ -51,7 +51,7 @@ do { \ if (i2c_debug >= lvl) { \ printk(KERN_DEBUG "%s at %s: " fmt, \ dev->name, __func__ , ##args); \ - } \ + } \ } while (0) static inline int get_real_i2c_port(struct cx231xx *dev, int bus_nr) diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h index 4511dc5d199c..8f00b1d38277 100644 --- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h +++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h @@ -144,7 +144,7 @@ enum AVDEC_STATUS{ #define SOURCE_EXTERNAL 0x8 #define SOURCE_TS_BDA 0x10 #define SOURCE_TS_ENCODE 0x20 -#define SOURCE_TS_EXTERNAL 0x40 +#define SOURCE_TS_EXTERNAL 0x40 /*************************************************************************** * interface information define * diff --git a/drivers/media/usb/cx231xx/cx231xx-reg.h b/drivers/media/usb/cx231xx/cx231xx-reg.h index 750c5d37d569..db5af8d51b61 100644 --- a/drivers/media/usb/cx231xx/cx231xx-reg.h +++ b/drivers/media/usb/cx231xx/cx231xx-reg.h @@ -1433,16 +1433,16 @@ #define FLD_AC97_SHUTDOWN 0x00000001 /* Cx231xx redefine */ -#define QPSK_IAGC_CTL1 0x94c -#define QPSK_IAGC_CTL2 0x950 -#define QPSK_FEPR_FREQ 0x954 -#define QPSK_BTL_CTL1 0x958 -#define QPSK_BTL_CTL2 0x95c -#define QPSK_CTL_CTL1 0x960 -#define QPSK_CTL_CTL2 0x964 -#define QPSK_MF_FAGC_CTL 0x968 -#define QPSK_EQ_CTL 0x96c -#define QPSK_LOCK_CTL 0x970 +#define QPSK_IAGC_CTL1 0x94c +#define QPSK_IAGC_CTL2 0x950 +#define QPSK_FEPR_FREQ 0x954 +#define QPSK_BTL_CTL1 0x958 +#define QPSK_BTL_CTL2 0x95c +#define QPSK_CTL_CTL1 0x960 +#define QPSK_CTL_CTL2 0x964 +#define QPSK_MF_FAGC_CTL 0x968 +#define QPSK_EQ_CTL 0x96c +#define QPSK_LOCK_CTL 0x970 /*****************************************************************************/ #define FM1_DFT_CTL 0x9a8 diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c index 96bbb53a4a91..f0d10ac03a37 100644 --- a/drivers/media/usb/dvb-usb/az6027.c +++ b/drivers/media/usb/dvb-usb/az6027.c @@ -36,70 +36,70 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_1[] = { /* 0x0000000b, SYSREG */ { STB0899_DEV_ID , 0x30 }, { STB0899_DISCNTRL1 , 0x32 }, - { STB0899_DISCNTRL2 , 0x80 }, - { STB0899_DISRX_ST0 , 0x04 }, - { STB0899_DISRX_ST1 , 0x00 }, - { STB0899_DISPARITY , 0x00 }, + { STB0899_DISCNTRL2 , 0x80 }, + { STB0899_DISRX_ST0 , 0x04 }, + { STB0899_DISRX_ST1 , 0x00 }, + { STB0899_DISPARITY , 0x00 }, { STB0899_DISSTATUS , 0x20 }, - { STB0899_DISF22 , 0x99 }, - { STB0899_DISF22RX , 0xa8 }, + { STB0899_DISF22 , 0x99 }, + { STB0899_DISF22RX , 0xa8 }, /* SYSREG ? */ - { STB0899_ACRPRESC , 0x11 }, - { STB0899_ACRDIV1 , 0x0a }, - { STB0899_ACRDIV2 , 0x05 }, - { STB0899_DACR1 , 0x00 }, - { STB0899_DACR2 , 0x00 }, - { STB0899_OUTCFG , 0x00 }, - { STB0899_MODECFG , 0x00 }, + { STB0899_ACRPRESC , 0x11 }, + { STB0899_ACRDIV1 , 0x0a }, + { STB0899_ACRDIV2 , 0x05 }, + { STB0899_DACR1 , 0x00 }, + { STB0899_DACR2 , 0x00 }, + { STB0899_OUTCFG , 0x00 }, + { STB0899_MODECFG , 0x00 }, { STB0899_IRQSTATUS_3 , 0xfe }, { STB0899_IRQSTATUS_2 , 0x03 }, { STB0899_IRQSTATUS_1 , 0x7c }, { STB0899_IRQSTATUS_0 , 0xf4 }, - { STB0899_IRQMSK_3 , 0xf3 }, - { STB0899_IRQMSK_2 , 0xfc }, - { STB0899_IRQMSK_1 , 0xff }, + { STB0899_IRQMSK_3 , 0xf3 }, + { STB0899_IRQMSK_2 , 0xfc }, + { STB0899_IRQMSK_1 , 0xff }, { STB0899_IRQMSK_0 , 0xff }, { STB0899_IRQCFG , 0x00 }, - { STB0899_I2CCFG , 0x88 }, - { STB0899_I2CRPT , 0x58 }, + { STB0899_I2CCFG , 0x88 }, + { STB0899_I2CRPT , 0x58 }, { STB0899_IOPVALUE5 , 0x00 }, { STB0899_IOPVALUE4 , 0x33 }, { STB0899_IOPVALUE3 , 0x6d }, { STB0899_IOPVALUE2 , 0x90 }, { STB0899_IOPVALUE1 , 0x60 }, { STB0899_IOPVALUE0 , 0x00 }, - { STB0899_GPIO00CFG , 0x82 }, - { STB0899_GPIO01CFG , 0x82 }, - { STB0899_GPIO02CFG , 0x82 }, - { STB0899_GPIO03CFG , 0x82 }, - { STB0899_GPIO04CFG , 0x82 }, - { STB0899_GPIO05CFG , 0x82 }, - { STB0899_GPIO06CFG , 0x82 }, - { STB0899_GPIO07CFG , 0x82 }, - { STB0899_GPIO08CFG , 0x82 }, - { STB0899_GPIO09CFG , 0x82 }, - { STB0899_GPIO10CFG , 0x82 }, - { STB0899_GPIO11CFG , 0x82 }, - { STB0899_GPIO12CFG , 0x82 }, - { STB0899_GPIO13CFG , 0x82 }, - { STB0899_GPIO14CFG , 0x82 }, - { STB0899_GPIO15CFG , 0x82 }, - { STB0899_GPIO16CFG , 0x82 }, - { STB0899_GPIO17CFG , 0x82 }, - { STB0899_GPIO18CFG , 0x82 }, - { STB0899_GPIO19CFG , 0x82 }, - { STB0899_GPIO20CFG , 0x82 }, - { STB0899_SDATCFG , 0xb8 }, - { STB0899_SCLTCFG , 0xba }, - { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ - { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ - { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ - { STB0899_DIRCLKCFG , 0x82 }, - { STB0899_CLKOUT27CFG , 0x7e }, - { STB0899_STDBYCFG , 0x82 }, - { STB0899_CS0CFG , 0x82 }, - { STB0899_CS1CFG , 0x82 }, - { STB0899_DISEQCOCFG , 0x20 }, + { STB0899_GPIO00CFG , 0x82 }, + { STB0899_GPIO01CFG , 0x82 }, + { STB0899_GPIO02CFG , 0x82 }, + { STB0899_GPIO03CFG , 0x82 }, + { STB0899_GPIO04CFG , 0x82 }, + { STB0899_GPIO05CFG , 0x82 }, + { STB0899_GPIO06CFG , 0x82 }, + { STB0899_GPIO07CFG , 0x82 }, + { STB0899_GPIO08CFG , 0x82 }, + { STB0899_GPIO09CFG , 0x82 }, + { STB0899_GPIO10CFG , 0x82 }, + { STB0899_GPIO11CFG , 0x82 }, + { STB0899_GPIO12CFG , 0x82 }, + { STB0899_GPIO13CFG , 0x82 }, + { STB0899_GPIO14CFG , 0x82 }, + { STB0899_GPIO15CFG , 0x82 }, + { STB0899_GPIO16CFG , 0x82 }, + { STB0899_GPIO17CFG , 0x82 }, + { STB0899_GPIO18CFG , 0x82 }, + { STB0899_GPIO19CFG , 0x82 }, + { STB0899_GPIO20CFG , 0x82 }, + { STB0899_SDATCFG , 0xb8 }, + { STB0899_SCLTCFG , 0xba }, + { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ + { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ + { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ + { STB0899_DIRCLKCFG , 0x82 }, + { STB0899_CLKOUT27CFG , 0x7e }, + { STB0899_STDBYCFG , 0x82 }, + { STB0899_CS0CFG , 0x82 }, + { STB0899_CS1CFG , 0x82 }, + { STB0899_DISEQCOCFG , 0x20 }, { STB0899_GPIO32CFG , 0x82 }, { STB0899_GPIO33CFG , 0x82 }, { STB0899_GPIO34CFG , 0x82 }, @@ -108,35 +108,35 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_1[] = { { STB0899_GPIO37CFG , 0x82 }, { STB0899_GPIO38CFG , 0x82 }, { STB0899_GPIO39CFG , 0x82 }, - { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ - { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ - { STB0899_FILTCTRL , 0x00 }, - { STB0899_SYSCTRL , 0x01 }, - { STB0899_STOPCLK1 , 0x20 }, - { STB0899_STOPCLK2 , 0x00 }, + { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ + { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ + { STB0899_FILTCTRL , 0x00 }, + { STB0899_SYSCTRL , 0x01 }, + { STB0899_STOPCLK1 , 0x20 }, + { STB0899_STOPCLK2 , 0x00 }, { STB0899_INTBUFSTATUS , 0x00 }, - { STB0899_INTBUFCTRL , 0x0a }, + { STB0899_INTBUFCTRL , 0x0a }, { 0xffff , 0xff }, }; static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = { - { STB0899_DEMOD , 0x00 }, - { STB0899_RCOMPC , 0xc9 }, - { STB0899_AGC1CN , 0x01 }, - { STB0899_AGC1REF , 0x10 }, + { STB0899_DEMOD , 0x00 }, + { STB0899_RCOMPC , 0xc9 }, + { STB0899_AGC1CN , 0x01 }, + { STB0899_AGC1REF , 0x10 }, { STB0899_RTC , 0x23 }, - { STB0899_TMGCFG , 0x4e }, - { STB0899_AGC2REF , 0x34 }, - { STB0899_TLSR , 0x84 }, - { STB0899_CFD , 0xf7 }, + { STB0899_TMGCFG , 0x4e }, + { STB0899_AGC2REF , 0x34 }, + { STB0899_TLSR , 0x84 }, + { STB0899_CFD , 0xf7 }, { STB0899_ACLC , 0x87 }, - { STB0899_BCLC , 0x94 }, - { STB0899_EQON , 0x41 }, - { STB0899_LDT , 0xf1 }, - { STB0899_LDT2 , 0xe3 }, - { STB0899_EQUALREF , 0xb4 }, - { STB0899_TMGRAMP , 0x10 }, - { STB0899_TMGTHD , 0x30 }, + { STB0899_BCLC , 0x94 }, + { STB0899_EQON , 0x41 }, + { STB0899_LDT , 0xf1 }, + { STB0899_LDT2 , 0xe3 }, + { STB0899_EQUALREF , 0xb4 }, + { STB0899_TMGRAMP , 0x10 }, + { STB0899_TMGTHD , 0x30 }, { STB0899_IDCCOMP , 0xfd }, { STB0899_QDCCOMP , 0xff }, { STB0899_POWERI , 0x0c }, @@ -155,12 +155,12 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = { { STB0899_NIRL , 0x80 }, { STB0899_ISYMB , 0x1d }, { STB0899_QSYMB , 0xa6 }, - { STB0899_SFRH , 0x2f }, - { STB0899_SFRM , 0x68 }, - { STB0899_SFRL , 0x40 }, - { STB0899_SFRUPH , 0x2f }, - { STB0899_SFRUPM , 0x68 }, - { STB0899_SFRUPL , 0x40 }, + { STB0899_SFRH , 0x2f }, + { STB0899_SFRM , 0x68 }, + { STB0899_SFRL , 0x40 }, + { STB0899_SFRUPH , 0x2f }, + { STB0899_SFRUPM , 0x68 }, + { STB0899_SFRUPL , 0x40 }, { STB0899_EQUAI1 , 0x02 }, { STB0899_EQUAQ1 , 0xff }, { STB0899_EQUAI2 , 0x04 }, @@ -172,7 +172,7 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = { { STB0899_EQUAI5 , 0x08 }, { STB0899_EQUAQ5 , 0xf5 }, { STB0899_DSTATUS2 , 0x00 }, - { STB0899_VSTATUS , 0x00 }, + { STB0899_VSTATUS , 0x00 }, { STB0899_VERROR , 0x86 }, { STB0899_IQSWAP , 0x2a }, { STB0899_ECNT1M , 0x00 }, @@ -181,26 +181,26 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = { { STB0899_ECNT2L , 0x00 }, { STB0899_ECNT3M , 0x0a }, { STB0899_ECNT3L , 0xad }, - { STB0899_FECAUTO1 , 0x06 }, + { STB0899_FECAUTO1 , 0x06 }, { STB0899_FECM , 0x01 }, - { STB0899_VTH12 , 0xb0 }, - { STB0899_VTH23 , 0x7a }, + { STB0899_VTH12 , 0xb0 }, + { STB0899_VTH23 , 0x7a }, { STB0899_VTH34 , 0x58 }, - { STB0899_VTH56 , 0x38 }, - { STB0899_VTH67 , 0x34 }, - { STB0899_VTH78 , 0x24 }, - { STB0899_PRVIT , 0xff }, - { STB0899_VITSYNC , 0x19 }, - { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ - { STB0899_TSULC , 0x42 }, - { STB0899_RSLLC , 0x41 }, + { STB0899_VTH56 , 0x38 }, + { STB0899_VTH67 , 0x34 }, + { STB0899_VTH78 , 0x24 }, + { STB0899_PRVIT , 0xff }, + { STB0899_VITSYNC , 0x19 }, + { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ + { STB0899_TSULC , 0x42 }, + { STB0899_RSLLC , 0x41 }, { STB0899_TSLPL , 0x12 }, - { STB0899_TSCFGH , 0x0c }, - { STB0899_TSCFGM , 0x00 }, - { STB0899_TSCFGL , 0x00 }, + { STB0899_TSCFGH , 0x0c }, + { STB0899_TSCFGM , 0x00 }, + { STB0899_TSCFGL , 0x00 }, { STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */ - { STB0899_RSSYNCDEL , 0x00 }, - { STB0899_TSINHDELH , 0x02 }, + { STB0899_RSSYNCDEL , 0x00 }, + { STB0899_TSINHDELH , 0x02 }, { STB0899_TSINHDELM , 0x00 }, { STB0899_TSINHDELL , 0x00 }, { STB0899_TSLLSTKM , 0x1b }, @@ -211,18 +211,18 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = { { STB0899_PCKLENLL , 0xcc }, { STB0899_RSPCKLEN , 0xbd }, { STB0899_TSSTATUS , 0x90 }, - { STB0899_ERRCTRL1 , 0xb6 }, - { STB0899_ERRCTRL2 , 0x95 }, - { STB0899_ERRCTRL3 , 0x8d }, + { STB0899_ERRCTRL1 , 0xb6 }, + { STB0899_ERRCTRL2 , 0x95 }, + { STB0899_ERRCTRL3 , 0x8d }, { STB0899_DMONMSK1 , 0x27 }, { STB0899_DMONMSK0 , 0x03 }, - { STB0899_DEMAPVIT , 0x5c }, + { STB0899_DEMAPVIT , 0x5c }, { STB0899_PLPARM , 0x19 }, - { STB0899_PDELCTRL , 0x48 }, - { STB0899_PDELCTRL2 , 0x00 }, - { STB0899_BBHCTRL1 , 0x00 }, - { STB0899_BBHCTRL2 , 0x00 }, - { STB0899_HYSTTHRESH , 0x77 }, + { STB0899_PDELCTRL , 0x48 }, + { STB0899_PDELCTRL2 , 0x00 }, + { STB0899_BBHCTRL1 , 0x00 }, + { STB0899_BBHCTRL2 , 0x00 }, + { STB0899_HYSTTHRESH , 0x77 }, { STB0899_MATCSTM , 0x00 }, { STB0899_MATCSTL , 0x00 }, { STB0899_UPLCSTM , 0x00 }, @@ -261,7 +261,7 @@ static struct stb0899_config az6027_stb0899_config = { .init_s2_fec = stb0899_s2_init_4, .init_tst = stb0899_s1_init_5, - .demod_address = 0xd0, /* 0x68, 0xd0 >> 1 */ + .demod_address = 0xd0, /* 0x68, 0xd0 >> 1 */ .xtal_freq = 27000000, .inversion = IQ_SWAP_ON, @@ -1181,9 +1181,9 @@ static struct dvb_usb_device_properties az6027_properties = { /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver az6027_usb_driver = { .name = "dvb_usb_az6027", - .probe = az6027_usb_probe, - .disconnect = az6027_usb_disconnect, - .id_table = az6027_usb_table, + .probe = az6027_usb_probe, + .disconnect = az6027_usb_disconnect, + .id_table = az6027_usb_table, }; module_usb_driver(az6027_usb_driver); diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.c b/drivers/media/usb/gspca/stv06xx/stv06xx.c index 2715218fe436..6080a35310ca 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx.c @@ -579,7 +579,7 @@ static int stv06xx_config(struct gspca_dev *gspca_dev, /* -- module initialisation -- */ static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 }, /* QuickCam Express */ + {USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 }, /* QuickCam Express */ {USB_DEVICE(0x046d, 0x0850), .driver_info = BRIDGE_STV610 }, /* LEGO cam / QuickCam Web */ {USB_DEVICE(0x046d, 0x0870), .driver_info = BRIDGE_STV602 }, /* Dexxa WebCam USB */ {USB_DEVICE(0x046D, 0x08F0), .driver_info = BRIDGE_ST6422 }, /* QuickCam Messenger */ diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c index 7fb036d6a86e..5e5f63f2652b 100644 --- a/drivers/media/usb/hdpvr/hdpvr-video.c +++ b/drivers/media/usb/hdpvr/hdpvr-video.c @@ -941,18 +941,18 @@ static int hdpvr_s_ctrl(struct v4l2_ctrl *ctrl) return 0; case V4L2_CID_MPEG_VIDEO_ENCODING: return 0; -/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */ -/* if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */ -/* opt->gop_mode |= 0x2; */ -/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */ -/* opt->gop_mode); */ -/* } */ -/* if (ctrl->value == 128 && opt->gop_mode & 0x2) { */ -/* opt->gop_mode &= ~0x2; */ -/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */ -/* opt->gop_mode); */ -/* } */ -/* break; */ +/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */ +/* if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */ +/* opt->gop_mode |= 0x2; */ +/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */ +/* opt->gop_mode); */ +/* } */ +/* if (ctrl->value == 128 && opt->gop_mode & 0x2) { */ +/* opt->gop_mode &= ~0x2; */ +/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */ +/* opt->gop_mode); */ +/* } */ +/* break; */ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: { uint peak_bitrate = dev->video_bitrate_peak->val / 100000; uint bitrate = dev->video_bitrate->val / 100000; @@ -1154,7 +1154,7 @@ static void hdpvr_device_release(struct video_device *vdev) static const struct video_device hdpvr_video_template = { .fops = &hdpvr_fops, .release = hdpvr_device_release, - .ioctl_ops = &hdpvr_ioctl_ops, + .ioctl_ops = &hdpvr_ioctl_ops, .tvnorms = V4L2_STD_ALL, }; diff --git a/drivers/media/usb/hdpvr/hdpvr.h b/drivers/media/usb/hdpvr/hdpvr.h index 96e36a8e5f43..1d65b4185f57 100644 --- a/drivers/media/usb/hdpvr/hdpvr.h +++ b/drivers/media/usb/hdpvr/hdpvr.h @@ -232,15 +232,15 @@ enum { /* :0 s 38 d3 0000 0000 0001 1 = 00 */ -/* ret = usb_control_msg(dev->udev, */ -/* usb_sndctrlpipe(dev->udev, 0), */ -/* 0xd3, 0x38, */ -/* 0, 0, */ -/* "\0", 1, */ -/* 1000); */ - -/* info("control request returned %d", ret); */ -/* msleep(5000); */ +/* ret = usb_control_msg(dev->udev, */ +/* usb_sndctrlpipe(dev->udev, 0), */ +/* 0xd3, 0x38, */ +/* 0, 0, */ +/* "\0", 1, */ +/* 1000); */ + +/* info("control request returned %d", ret); */ +/* msleep(5000); */ /* :0 s b8 81 1400 0003 0005 5 < diff --git a/drivers/media/usb/pwc/pwc.h b/drivers/media/usb/pwc/pwc.h index 3c73bdaae450..67010010d2a2 100644 --- a/drivers/media/usb/pwc/pwc.h +++ b/drivers/media/usb/pwc/pwc.h @@ -50,7 +50,7 @@ /* Version block */ #define PWC_VERSION "10.0.15" -#define PWC_NAME "pwc" +#define PWC_NAME "pwc" #define PFX PWC_NAME ": " @@ -120,10 +120,10 @@ #define MAX_ISO_BUFS 3 #define ISO_FRAMES_PER_DESC 10 #define ISO_MAX_FRAME_SIZE 960 -#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE) +#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE) /* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */ -#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE) +#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE) /* Absolute minimum and maximum number of buffers available for mmap() */ #define MIN_FRAMES 2 diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index d07349cf9489..f13e4b01b5a5 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -61,7 +61,7 @@ struct smsusb_device_t { struct usb_device *udev; struct smscore_device_t *coredev; - struct smsusb_urb_t surbs[MAX_URBS]; + struct smsusb_urb_t surbs[MAX_URBS]; int response_alignment; int buffer_size; diff --git a/drivers/media/usb/stk1160/Makefile b/drivers/media/usb/stk1160/Makefile index 8e6c22fb1803..b943db01ccf7 100644 --- a/drivers/media/usb/stk1160/Makefile +++ b/drivers/media/usb/stk1160/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -stk1160-y := stk1160-core.o \ +stk1160-y := stk1160-core.o \ stk1160-v4l.o \ stk1160-video.o \ stk1160-i2c.o \ diff --git a/drivers/media/usb/stkwebcam/stk-sensor.c b/drivers/media/usb/stkwebcam/stk-sensor.c index c1d4505f84ea..9a7dbeff1337 100644 --- a/drivers/media/usb/stkwebcam/stk-sensor.c +++ b/drivers/media/usb/stkwebcam/stk-sensor.c @@ -397,12 +397,12 @@ int stk_sensor_init(struct stk_camera *dev) /* V4L2_PIX_FMT_UYVY */ static struct regval ov_fmt_uyvy[] = { {REG_TSLB, TSLB_YLAST|0x08 }, - { 0x4f, 0x80 }, /* "matrix coefficient 1" */ - { 0x50, 0x80 }, /* "matrix coefficient 2" */ + { 0x4f, 0x80 }, /* "matrix coefficient 1" */ + { 0x50, 0x80 }, /* "matrix coefficient 2" */ { 0x51, 0 }, /* vb */ - { 0x52, 0x22 }, /* "matrix coefficient 4" */ - { 0x53, 0x5e }, /* "matrix coefficient 5" */ - { 0x54, 0x80 }, /* "matrix coefficient 6" */ + { 0x52, 0x22 }, /* "matrix coefficient 4" */ + { 0x53, 0x5e }, /* "matrix coefficient 5" */ + { 0x54, 0x80 }, /* "matrix coefficient 6" */ {REG_COM13, COM13_UVSAT|COM13_CMATRIX}, {REG_COM15, COM15_R00FF }, {0xff, 0xff}, /* END MARKER */ @@ -410,12 +410,12 @@ static struct regval ov_fmt_uyvy[] = { /* V4L2_PIX_FMT_YUYV */ static struct regval ov_fmt_yuyv[] = { {REG_TSLB, 0 }, - { 0x4f, 0x80 }, /* "matrix coefficient 1" */ - { 0x50, 0x80 }, /* "matrix coefficient 2" */ + { 0x4f, 0x80 }, /* "matrix coefficient 1" */ + { 0x50, 0x80 }, /* "matrix coefficient 2" */ { 0x51, 0 }, /* vb */ - { 0x52, 0x22 }, /* "matrix coefficient 4" */ - { 0x53, 0x5e }, /* "matrix coefficient 5" */ - { 0x54, 0x80 }, /* "matrix coefficient 6" */ + { 0x52, 0x22 }, /* "matrix coefficient 4" */ + { 0x53, 0x5e }, /* "matrix coefficient 5" */ + { 0x54, 0x80 }, /* "matrix coefficient 6" */ {REG_COM13, COM13_UVSAT|COM13_CMATRIX}, {REG_COM15, COM15_R00FF }, {0xff, 0xff}, /* END MARKER */ @@ -426,13 +426,13 @@ static struct regval ov_fmt_rgbr[] = { { REG_RGB444, 0 }, /* No RGB444 please */ {REG_TSLB, 0x00}, { REG_COM1, 0x0 }, - { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */ - { 0x4f, 0xb3 }, /* "matrix coefficient 1" */ - { 0x50, 0xb3 }, /* "matrix coefficient 2" */ + { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */ + { 0x4f, 0xb3 }, /* "matrix coefficient 1" */ + { 0x50, 0xb3 }, /* "matrix coefficient 2" */ { 0x51, 0 }, /* vb */ - { 0x52, 0x3d }, /* "matrix coefficient 4" */ - { 0x53, 0xa7 }, /* "matrix coefficient 5" */ - { 0x54, 0xe4 }, /* "matrix coefficient 6" */ + { 0x52, 0x3d }, /* "matrix coefficient 4" */ + { 0x53, 0xa7 }, /* "matrix coefficient 5" */ + { 0x54, 0xe4 }, /* "matrix coefficient 6" */ { REG_COM13, COM13_GAMMA }, { REG_COM15, COM15_RGB565|COM15_R00FF }, { 0xff, 0xff }, @@ -443,13 +443,13 @@ static struct regval ov_fmt_rgbp[] = { { REG_RGB444, 0 }, /* No RGB444 please */ {REG_TSLB, TSLB_BYTEORD }, { REG_COM1, 0x0 }, - { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */ - { 0x4f, 0xb3 }, /* "matrix coefficient 1" */ - { 0x50, 0xb3 }, /* "matrix coefficient 2" */ + { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */ + { 0x4f, 0xb3 }, /* "matrix coefficient 1" */ + { 0x50, 0xb3 }, /* "matrix coefficient 2" */ { 0x51, 0 }, /* vb */ - { 0x52, 0x3d }, /* "matrix coefficient 4" */ - { 0x53, 0xa7 }, /* "matrix coefficient 5" */ - { 0x54, 0xe4 }, /* "matrix coefficient 6" */ + { 0x52, 0x3d }, /* "matrix coefficient 4" */ + { 0x53, 0xa7 }, /* "matrix coefficient 5" */ + { 0x54, 0xe4 }, /* "matrix coefficient 6" */ { REG_COM13, COM13_GAMMA }, { REG_COM15, COM15_RGB565|COM15_R00FF }, { 0xff, 0xff }, diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 108577c50097..fd387bf3f02d 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -963,11 +963,11 @@ static int uvc_parse_vendor_control(struct uvc_device *dev, * Size of this descriptor, in bytes: 24+p+n*2 * ---------------------------------------------------------- * 23+p+n bmControlsType N Bitmap - * Individual bits in the set are defined: - * 0: Absolute - * 1: Relative + * Individual bits in the set are defined: + * 0: Absolute + * 1: Relative * - * This bitset is mapped exactly the same as bmControls. + * This bitset is mapped exactly the same as bmControls. * ---------------------------------------------------------- * 23+p+n*2 bReserved 1 Boolean * ---------------------------------------------------------- @@ -2481,7 +2481,7 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, - .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def }, + .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def }, /* Dell SP2008WFP Monitor */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -2490,7 +2490,7 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, - .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def }, + .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def }, /* Dell Alienware X51 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -2526,7 +2526,7 @@ static const struct usb_device_id uvc_ids[] = { .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX + .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX | UVC_QUIRK_BUILTIN_ISIGHT) }, /* Apple Built-In iSight via iBridge */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE diff --git a/drivers/media/usb/uvc/uvc_isight.c b/drivers/media/usb/uvc/uvc_isight.c index fb940cfae575..5059fbf41020 100644 --- a/drivers/media/usb/uvc/uvc_isight.c +++ b/drivers/media/usb/uvc/uvc_isight.c @@ -27,11 +27,11 @@ * * Offset Size (bytes) Description * ------------------------------------------------------------------ - * 0x00 1 Header length - * 0x01 1 Flags (UVC-compliant) - * 0x02 4 Always equal to '11223344' - * 0x06 8 Always equal to 'deadbeefdeadface' - * 0x0e 16 Unknown + * 0x00 1 Header length + * 0x01 1 Flags (UVC-compliant) + * 0x02 4 Always equal to '11223344' + * 0x06 8 Always equal to 'deadbeefdeadface' + * 0x0e 16 Unknown * * The header can be prefixed by an optional, unknown-purpose byte. */ diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 8d79691b1dce..e48d59046086 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -33,7 +33,7 @@ static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct v4l2_clip32 { struct v4l2_rect c; - compat_caddr_t next; + compat_caddr_t next; }; struct v4l2_window32 { @@ -582,7 +582,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user struct v4l2_framebuffer32 { __u32 capability; __u32 flags; - compat_caddr_t base; + compat_caddr_t base; struct { __u32 width; __u32 height; @@ -857,7 +857,7 @@ static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up) #define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32) #define VIDIOC_G_EDID32 _IOWR('V', 40, struct v4l2_edid32) #define VIDIOC_S_EDID32 _IOWR('V', 41, struct v4l2_edid32) -#define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32) +#define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32) #define VIDIOC_G_EXT_CTRLS32 _IOWR('V', 71, struct v4l2_ext_controls32) #define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32) #define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32) diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 1d7c2ea78c3e..59d2100eeff6 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -46,37 +46,37 @@ struct std_descr { }; static const struct std_descr standards[] = { - { V4L2_STD_NTSC, "NTSC" }, - { V4L2_STD_NTSC_M, "NTSC-M" }, - { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" }, + { V4L2_STD_NTSC, "NTSC" }, + { V4L2_STD_NTSC_M, "NTSC-M" }, + { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" }, { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" }, - { V4L2_STD_NTSC_443, "NTSC-443" }, - { V4L2_STD_PAL, "PAL" }, - { V4L2_STD_PAL_BG, "PAL-BG" }, - { V4L2_STD_PAL_B, "PAL-B" }, - { V4L2_STD_PAL_B1, "PAL-B1" }, - { V4L2_STD_PAL_G, "PAL-G" }, - { V4L2_STD_PAL_H, "PAL-H" }, - { V4L2_STD_PAL_I, "PAL-I" }, - { V4L2_STD_PAL_DK, "PAL-DK" }, - { V4L2_STD_PAL_D, "PAL-D" }, - { V4L2_STD_PAL_D1, "PAL-D1" }, - { V4L2_STD_PAL_K, "PAL-K" }, - { V4L2_STD_PAL_M, "PAL-M" }, - { V4L2_STD_PAL_N, "PAL-N" }, - { V4L2_STD_PAL_Nc, "PAL-Nc" }, - { V4L2_STD_PAL_60, "PAL-60" }, - { V4L2_STD_SECAM, "SECAM" }, - { V4L2_STD_SECAM_B, "SECAM-B" }, - { V4L2_STD_SECAM_G, "SECAM-G" }, - { V4L2_STD_SECAM_H, "SECAM-H" }, - { V4L2_STD_SECAM_DK, "SECAM-DK" }, - { V4L2_STD_SECAM_D, "SECAM-D" }, - { V4L2_STD_SECAM_K, "SECAM-K" }, - { V4L2_STD_SECAM_K1, "SECAM-K1" }, - { V4L2_STD_SECAM_L, "SECAM-L" }, - { V4L2_STD_SECAM_LC, "SECAM-Lc" }, - { 0, "Unknown" } + { V4L2_STD_NTSC_443, "NTSC-443" }, + { V4L2_STD_PAL, "PAL" }, + { V4L2_STD_PAL_BG, "PAL-BG" }, + { V4L2_STD_PAL_B, "PAL-B" }, + { V4L2_STD_PAL_B1, "PAL-B1" }, + { V4L2_STD_PAL_G, "PAL-G" }, + { V4L2_STD_PAL_H, "PAL-H" }, + { V4L2_STD_PAL_I, "PAL-I" }, + { V4L2_STD_PAL_DK, "PAL-DK" }, + { V4L2_STD_PAL_D, "PAL-D" }, + { V4L2_STD_PAL_D1, "PAL-D1" }, + { V4L2_STD_PAL_K, "PAL-K" }, + { V4L2_STD_PAL_M, "PAL-M" }, + { V4L2_STD_PAL_N, "PAL-N" }, + { V4L2_STD_PAL_Nc, "PAL-Nc" }, + { V4L2_STD_PAL_60, "PAL-60" }, + { V4L2_STD_SECAM, "SECAM" }, + { V4L2_STD_SECAM_B, "SECAM-B" }, + { V4L2_STD_SECAM_G, "SECAM-G" }, + { V4L2_STD_SECAM_H, "SECAM-H" }, + { V4L2_STD_SECAM_DK, "SECAM-DK" }, + { V4L2_STD_SECAM_D, "SECAM-D" }, + { V4L2_STD_SECAM_K, "SECAM-K" }, + { V4L2_STD_SECAM_K1, "SECAM-K1" }, + { V4L2_STD_SECAM_L, "SECAM-L" }, + { V4L2_STD_SECAM_LC, "SECAM-Lc" }, + { 0, "Unknown" } }; /* video4linux standard ID conversion to standard name @@ -2544,7 +2544,7 @@ struct v4l2_ioctl_info { #define INFO_FL_CLEAR(v4l2_struct, field) \ ((offsetof(struct v4l2_struct, field) + \ sizeof(((struct v4l2_struct *)0)->field)) << 16) -#define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16) +#define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16) #define IOCTL_INFO_STD(_ioctl, _vidioc, _debug, _flags) \ [_IOC_NR(_ioctl)] = { \ diff --git a/include/media/drv-intf/cx2341x.h b/include/media/drv-intf/cx2341x.h index 9635eebaab09..33a97bfcea58 100644 --- a/include/media/drv-intf/cx2341x.h +++ b/include/media/drv-intf/cx2341x.h @@ -29,8 +29,8 @@ enum cx2341x_port { enum cx2341x_cap { CX2341X_CAP_HAS_SLICED_VBI = 1 << 0, - CX2341X_CAP_HAS_TS = 1 << 1, - CX2341X_CAP_HAS_AC3 = 1 << 2, + CX2341X_CAP_HAS_TS = 1 << 1, + CX2341X_CAP_HAS_AC3 = 1 << 2, }; struct cx2341x_mpeg_params { @@ -204,92 +204,92 @@ void cx2341x_handler_set_busy(struct cx2341x_handler *cxhdl, int busy); /* Firmware API commands */ /* MPEG decoder API, specific to the cx23415 */ -#define CX2341X_DEC_PING_FW 0x00 -#define CX2341X_DEC_START_PLAYBACK 0x01 -#define CX2341X_DEC_STOP_PLAYBACK 0x02 -#define CX2341X_DEC_SET_PLAYBACK_SPEED 0x03 -#define CX2341X_DEC_STEP_VIDEO 0x05 -#define CX2341X_DEC_SET_DMA_BLOCK_SIZE 0x08 +#define CX2341X_DEC_PING_FW 0x00 +#define CX2341X_DEC_START_PLAYBACK 0x01 +#define CX2341X_DEC_STOP_PLAYBACK 0x02 +#define CX2341X_DEC_SET_PLAYBACK_SPEED 0x03 +#define CX2341X_DEC_STEP_VIDEO 0x05 +#define CX2341X_DEC_SET_DMA_BLOCK_SIZE 0x08 #define CX2341X_DEC_GET_XFER_INFO 0x09 #define CX2341X_DEC_GET_DMA_STATUS 0x0a #define CX2341X_DEC_SCHED_DMA_FROM_HOST 0x0b -#define CX2341X_DEC_PAUSE_PLAYBACK 0x0d -#define CX2341X_DEC_HALT_FW 0x0e -#define CX2341X_DEC_SET_STANDARD 0x10 +#define CX2341X_DEC_PAUSE_PLAYBACK 0x0d +#define CX2341X_DEC_HALT_FW 0x0e +#define CX2341X_DEC_SET_STANDARD 0x10 #define CX2341X_DEC_GET_VERSION 0x11 -#define CX2341X_DEC_SET_STREAM_INPUT 0x14 -#define CX2341X_DEC_GET_TIMING_INFO 0x15 -#define CX2341X_DEC_SET_AUDIO_MODE 0x16 +#define CX2341X_DEC_SET_STREAM_INPUT 0x14 +#define CX2341X_DEC_GET_TIMING_INFO 0x15 +#define CX2341X_DEC_SET_AUDIO_MODE 0x16 #define CX2341X_DEC_SET_EVENT_NOTIFICATION 0x17 #define CX2341X_DEC_SET_DISPLAY_BUFFERS 0x18 -#define CX2341X_DEC_EXTRACT_VBI 0x19 -#define CX2341X_DEC_SET_DECODER_SOURCE 0x1a +#define CX2341X_DEC_EXTRACT_VBI 0x19 +#define CX2341X_DEC_SET_DECODER_SOURCE 0x1a #define CX2341X_DEC_SET_PREBUFFERING 0x1e /* MPEG encoder API */ -#define CX2341X_ENC_PING_FW 0x80 -#define CX2341X_ENC_START_CAPTURE 0x81 -#define CX2341X_ENC_STOP_CAPTURE 0x82 -#define CX2341X_ENC_SET_AUDIO_ID 0x89 -#define CX2341X_ENC_SET_VIDEO_ID 0x8b -#define CX2341X_ENC_SET_PCR_ID 0x8d -#define CX2341X_ENC_SET_FRAME_RATE 0x8f -#define CX2341X_ENC_SET_FRAME_SIZE 0x91 -#define CX2341X_ENC_SET_BIT_RATE 0x95 -#define CX2341X_ENC_SET_GOP_PROPERTIES 0x97 -#define CX2341X_ENC_SET_ASPECT_RATIO 0x99 -#define CX2341X_ENC_SET_DNR_FILTER_MODE 0x9b -#define CX2341X_ENC_SET_DNR_FILTER_PROPS 0x9d -#define CX2341X_ENC_SET_CORING_LEVELS 0x9f -#define CX2341X_ENC_SET_SPATIAL_FILTER_TYPE 0xa1 -#define CX2341X_ENC_SET_VBI_LINE 0xb7 -#define CX2341X_ENC_SET_STREAM_TYPE 0xb9 -#define CX2341X_ENC_SET_OUTPUT_PORT 0xbb -#define CX2341X_ENC_SET_AUDIO_PROPERTIES 0xbd -#define CX2341X_ENC_HALT_FW 0xc3 +#define CX2341X_ENC_PING_FW 0x80 +#define CX2341X_ENC_START_CAPTURE 0x81 +#define CX2341X_ENC_STOP_CAPTURE 0x82 +#define CX2341X_ENC_SET_AUDIO_ID 0x89 +#define CX2341X_ENC_SET_VIDEO_ID 0x8b +#define CX2341X_ENC_SET_PCR_ID 0x8d +#define CX2341X_ENC_SET_FRAME_RATE 0x8f +#define CX2341X_ENC_SET_FRAME_SIZE 0x91 +#define CX2341X_ENC_SET_BIT_RATE 0x95 +#define CX2341X_ENC_SET_GOP_PROPERTIES 0x97 +#define CX2341X_ENC_SET_ASPECT_RATIO 0x99 +#define CX2341X_ENC_SET_DNR_FILTER_MODE 0x9b +#define CX2341X_ENC_SET_DNR_FILTER_PROPS 0x9d +#define CX2341X_ENC_SET_CORING_LEVELS 0x9f +#define CX2341X_ENC_SET_SPATIAL_FILTER_TYPE 0xa1 +#define CX2341X_ENC_SET_VBI_LINE 0xb7 +#define CX2341X_ENC_SET_STREAM_TYPE 0xb9 +#define CX2341X_ENC_SET_OUTPUT_PORT 0xbb +#define CX2341X_ENC_SET_AUDIO_PROPERTIES 0xbd +#define CX2341X_ENC_HALT_FW 0xc3 #define CX2341X_ENC_GET_VERSION 0xc4 -#define CX2341X_ENC_SET_GOP_CLOSURE 0xc5 -#define CX2341X_ENC_GET_SEQ_END 0xc6 -#define CX2341X_ENC_SET_PGM_INDEX_INFO 0xc7 +#define CX2341X_ENC_SET_GOP_CLOSURE 0xc5 +#define CX2341X_ENC_GET_SEQ_END 0xc6 +#define CX2341X_ENC_SET_PGM_INDEX_INFO 0xc7 #define CX2341X_ENC_SET_VBI_CONFIG 0xc8 -#define CX2341X_ENC_SET_DMA_BLOCK_SIZE 0xc9 +#define CX2341X_ENC_SET_DMA_BLOCK_SIZE 0xc9 #define CX2341X_ENC_GET_PREV_DMA_INFO_MB_10 0xca #define CX2341X_ENC_GET_PREV_DMA_INFO_MB_9 0xcb -#define CX2341X_ENC_SCHED_DMA_TO_HOST 0xcc -#define CX2341X_ENC_INITIALIZE_INPUT 0xcd -#define CX2341X_ENC_SET_FRAME_DROP_RATE 0xd0 -#define CX2341X_ENC_PAUSE_ENCODER 0xd2 -#define CX2341X_ENC_REFRESH_INPUT 0xd3 +#define CX2341X_ENC_SCHED_DMA_TO_HOST 0xcc +#define CX2341X_ENC_INITIALIZE_INPUT 0xcd +#define CX2341X_ENC_SET_FRAME_DROP_RATE 0xd0 +#define CX2341X_ENC_PAUSE_ENCODER 0xd2 +#define CX2341X_ENC_REFRESH_INPUT 0xd3 #define CX2341X_ENC_SET_COPYRIGHT 0xd4 -#define CX2341X_ENC_SET_EVENT_NOTIFICATION 0xd5 -#define CX2341X_ENC_SET_NUM_VSYNC_LINES 0xd6 -#define CX2341X_ENC_SET_PLACEHOLDER 0xd7 -#define CX2341X_ENC_MUTE_VIDEO 0xd9 -#define CX2341X_ENC_MUTE_AUDIO 0xda +#define CX2341X_ENC_SET_EVENT_NOTIFICATION 0xd5 +#define CX2341X_ENC_SET_NUM_VSYNC_LINES 0xd6 +#define CX2341X_ENC_SET_PLACEHOLDER 0xd7 +#define CX2341X_ENC_MUTE_VIDEO 0xd9 +#define CX2341X_ENC_MUTE_AUDIO 0xda #define CX2341X_ENC_SET_VERT_CROP_LINE 0xdb -#define CX2341X_ENC_MISC 0xdc +#define CX2341X_ENC_MISC 0xdc /* OSD API, specific to the cx23415 */ -#define CX2341X_OSD_GET_FRAMEBUFFER 0x41 -#define CX2341X_OSD_GET_PIXEL_FORMAT 0x42 -#define CX2341X_OSD_SET_PIXEL_FORMAT 0x43 -#define CX2341X_OSD_GET_STATE 0x44 -#define CX2341X_OSD_SET_STATE 0x45 -#define CX2341X_OSD_GET_OSD_COORDS 0x46 -#define CX2341X_OSD_SET_OSD_COORDS 0x47 -#define CX2341X_OSD_GET_SCREEN_COORDS 0x48 -#define CX2341X_OSD_SET_SCREEN_COORDS 0x49 -#define CX2341X_OSD_GET_GLOBAL_ALPHA 0x4a -#define CX2341X_OSD_SET_GLOBAL_ALPHA 0x4b -#define CX2341X_OSD_SET_BLEND_COORDS 0x4c -#define CX2341X_OSD_GET_FLICKER_STATE 0x4f -#define CX2341X_OSD_SET_FLICKER_STATE 0x50 -#define CX2341X_OSD_BLT_COPY 0x52 -#define CX2341X_OSD_BLT_FILL 0x53 -#define CX2341X_OSD_BLT_TEXT 0x54 -#define CX2341X_OSD_SET_FRAMEBUFFER_WINDOW 0x56 -#define CX2341X_OSD_SET_CHROMA_KEY 0x60 -#define CX2341X_OSD_GET_ALPHA_CONTENT_INDEX 0x61 -#define CX2341X_OSD_SET_ALPHA_CONTENT_INDEX 0x62 +#define CX2341X_OSD_GET_FRAMEBUFFER 0x41 +#define CX2341X_OSD_GET_PIXEL_FORMAT 0x42 +#define CX2341X_OSD_SET_PIXEL_FORMAT 0x43 +#define CX2341X_OSD_GET_STATE 0x44 +#define CX2341X_OSD_SET_STATE 0x45 +#define CX2341X_OSD_GET_OSD_COORDS 0x46 +#define CX2341X_OSD_SET_OSD_COORDS 0x47 +#define CX2341X_OSD_GET_SCREEN_COORDS 0x48 +#define CX2341X_OSD_SET_SCREEN_COORDS 0x49 +#define CX2341X_OSD_GET_GLOBAL_ALPHA 0x4a +#define CX2341X_OSD_SET_GLOBAL_ALPHA 0x4b +#define CX2341X_OSD_SET_BLEND_COORDS 0x4c +#define CX2341X_OSD_GET_FLICKER_STATE 0x4f +#define CX2341X_OSD_SET_FLICKER_STATE 0x50 +#define CX2341X_OSD_BLT_COPY 0x52 +#define CX2341X_OSD_BLT_FILL 0x53 +#define CX2341X_OSD_BLT_TEXT 0x54 +#define CX2341X_OSD_SET_FRAMEBUFFER_WINDOW 0x56 +#define CX2341X_OSD_SET_CHROMA_KEY 0x60 +#define CX2341X_OSD_GET_ALPHA_CONTENT_INDEX 0x61 +#define CX2341X_OSD_SET_ALPHA_CONTENT_INDEX 0x62 #endif /* CX2341X_H */ diff --git a/include/media/drv-intf/msp3400.h b/include/media/drv-intf/msp3400.h index 1e6e80213a77..db98ce49e17b 100644 --- a/include/media/drv-intf/msp3400.h +++ b/include/media/drv-intf/msp3400.h @@ -80,17 +80,17 @@ */ /* SCART input to DSP selection */ -#define MSP_IN_SCART1 0 /* Pin SC1_IN */ -#define MSP_IN_SCART2 1 /* Pin SC2_IN */ -#define MSP_IN_SCART3 2 /* Pin SC3_IN */ -#define MSP_IN_SCART4 3 /* Pin SC4_IN */ -#define MSP_IN_MONO 6 /* Pin MONO_IN */ -#define MSP_IN_MUTE 7 /* Mute DSP input */ -#define MSP_SCART_TO_DSP(in) (in) +#define MSP_IN_SCART1 0 /* Pin SC1_IN */ +#define MSP_IN_SCART2 1 /* Pin SC2_IN */ +#define MSP_IN_SCART3 2 /* Pin SC3_IN */ +#define MSP_IN_SCART4 3 /* Pin SC4_IN */ +#define MSP_IN_MONO 6 /* Pin MONO_IN */ +#define MSP_IN_MUTE 7 /* Mute DSP input */ +#define MSP_SCART_TO_DSP(in) (in) /* Tuner input to demodulator and DSP selection */ -#define MSP_IN_TUNER1 0 /* Analog Sound IF input pin ANA_IN1 */ -#define MSP_IN_TUNER2 1 /* Analog Sound IF input pin ANA_IN2 */ -#define MSP_TUNER_TO_DSP(in) ((in) << 3) +#define MSP_IN_TUNER1 0 /* Analog Sound IF input pin ANA_IN1 */ +#define MSP_IN_TUNER2 1 /* Analog Sound IF input pin ANA_IN2 */ +#define MSP_TUNER_TO_DSP(in) ((in) << 3) /* The msp has up to 5 DSP outputs, each output can independently select a DSP input. @@ -109,30 +109,30 @@ DSP. This is currently not implemented. Also not implemented is the multi-channel capable I2S3 input of the 44x0G. If someone can demonstrate a need for one of those features then additional support can be added. */ -#define MSP_DSP_IN_TUNER 0 /* Tuner DSP input */ -#define MSP_DSP_IN_SCART 2 /* SCART DSP input */ -#define MSP_DSP_IN_I2S1 5 /* I2S1 DSP input */ -#define MSP_DSP_IN_I2S2 6 /* I2S2 DSP input */ -#define MSP_DSP_IN_I2S3 7 /* I2S3 DSP input */ -#define MSP_DSP_IN_MAIN_AVC 11 /* MAIN AVC processed DSP input */ -#define MSP_DSP_IN_MAIN 12 /* MAIN DSP input */ -#define MSP_DSP_IN_AUX 13 /* AUX DSP input */ -#define MSP_DSP_TO_MAIN(in) ((in) << 4) -#define MSP_DSP_TO_AUX(in) ((in) << 8) -#define MSP_DSP_TO_SCART1(in) ((in) << 12) -#define MSP_DSP_TO_SCART2(in) ((in) << 16) -#define MSP_DSP_TO_I2S(in) ((in) << 20) +#define MSP_DSP_IN_TUNER 0 /* Tuner DSP input */ +#define MSP_DSP_IN_SCART 2 /* SCART DSP input */ +#define MSP_DSP_IN_I2S1 5 /* I2S1 DSP input */ +#define MSP_DSP_IN_I2S2 6 /* I2S2 DSP input */ +#define MSP_DSP_IN_I2S3 7 /* I2S3 DSP input */ +#define MSP_DSP_IN_MAIN_AVC 11 /* MAIN AVC processed DSP input */ +#define MSP_DSP_IN_MAIN 12 /* MAIN DSP input */ +#define MSP_DSP_IN_AUX 13 /* AUX DSP input */ +#define MSP_DSP_TO_MAIN(in) ((in) << 4) +#define MSP_DSP_TO_AUX(in) ((in) << 8) +#define MSP_DSP_TO_SCART1(in) ((in) << 12) +#define MSP_DSP_TO_SCART2(in) ((in) << 16) +#define MSP_DSP_TO_I2S(in) ((in) << 20) /* Output SCART select: the SCART outputs can select which input to use. */ -#define MSP_SC_IN_SCART1 0 /* SCART1 input, bypassing the DSP */ -#define MSP_SC_IN_SCART2 1 /* SCART2 input, bypassing the DSP */ -#define MSP_SC_IN_SCART3 2 /* SCART3 input, bypassing the DSP */ -#define MSP_SC_IN_SCART4 3 /* SCART4 input, bypassing the DSP */ -#define MSP_SC_IN_DSP_SCART1 4 /* DSP SCART1 input */ -#define MSP_SC_IN_DSP_SCART2 5 /* DSP SCART2 input */ -#define MSP_SC_IN_MONO 6 /* MONO input, bypassing the DSP */ -#define MSP_SC_IN_MUTE 7 /* MUTE output */ +#define MSP_SC_IN_SCART1 0 /* SCART1 input, bypassing the DSP */ +#define MSP_SC_IN_SCART2 1 /* SCART2 input, bypassing the DSP */ +#define MSP_SC_IN_SCART3 2 /* SCART3 input, bypassing the DSP */ +#define MSP_SC_IN_SCART4 3 /* SCART4 input, bypassing the DSP */ +#define MSP_SC_IN_DSP_SCART1 4 /* DSP SCART1 input */ +#define MSP_SC_IN_DSP_SCART2 5 /* DSP SCART2 input */ +#define MSP_SC_IN_MONO 6 /* MONO input, bypassing the DSP */ +#define MSP_SC_IN_MUTE 7 /* MUTE output */ #define MSP_SC_TO_SCART1(in) (in) #define MSP_SC_TO_SCART2(in) ((in) << 4) diff --git a/include/media/drv-intf/saa7146.h b/include/media/drv-intf/saa7146.h index 769c6cf7eb4c..a7bf2c4a2e4d 100644 --- a/include/media/drv-intf/saa7146.h +++ b/include/media/drv-intf/saa7146.h @@ -118,7 +118,7 @@ struct saa7146_dev { struct module *module; - struct v4l2_device v4l2_dev; + struct v4l2_device v4l2_dev; struct v4l2_ctrl_handler ctrl_handler; /* different device locks */ diff --git a/include/media/i2c/bt819.h b/include/media/i2c/bt819.h index 8025f4bc2bb6..1bcf0dbeb516 100644 --- a/include/media/i2c/bt819.h +++ b/include/media/i2c/bt819.h @@ -30,7 +30,7 @@ Note: these ioctls that internal to the kernel and are never called from userspace. */ -#define BT819_FIFO_RESET_LOW _IO('b', 0) -#define BT819_FIFO_RESET_HIGH _IO('b', 1) +#define BT819_FIFO_RESET_LOW _IO('b', 0) +#define BT819_FIFO_RESET_HIGH _IO('b', 1) #endif diff --git a/include/media/i2c/m52790.h b/include/media/i2c/m52790.h index 7ddffae31a67..8d9db3cf6fab 100644 --- a/include/media/i2c/m52790.h +++ b/include/media/i2c/m52790.h @@ -23,57 +23,57 @@ /* Input routing switch 1 */ -#define M52790_SW1_IN_MASK 0x0003 -#define M52790_SW1_IN_TUNER 0x0000 -#define M52790_SW1_IN_V2 0x0001 -#define M52790_SW1_IN_V3 0x0002 -#define M52790_SW1_IN_V4 0x0003 +#define M52790_SW1_IN_MASK 0x0003 +#define M52790_SW1_IN_TUNER 0x0000 +#define M52790_SW1_IN_V2 0x0001 +#define M52790_SW1_IN_V3 0x0002 +#define M52790_SW1_IN_V4 0x0003 /* Selects component input instead of composite */ -#define M52790_SW1_YCMIX 0x0004 +#define M52790_SW1_YCMIX 0x0004 /* Input routing switch 2 */ -#define M52790_SW2_IN_MASK 0x0300 -#define M52790_SW2_IN_TUNER 0x0000 -#define M52790_SW2_IN_V2 0x0100 -#define M52790_SW2_IN_V3 0x0200 -#define M52790_SW2_IN_V4 0x0300 +#define M52790_SW2_IN_MASK 0x0300 +#define M52790_SW2_IN_TUNER 0x0000 +#define M52790_SW2_IN_V2 0x0100 +#define M52790_SW2_IN_V3 0x0200 +#define M52790_SW2_IN_V4 0x0300 /* Selects component input instead of composite */ -#define M52790_SW2_YCMIX 0x0400 +#define M52790_SW2_YCMIX 0x0400 /* Output routing switch 1 */ /* Enable 6dB amplifier for composite out */ -#define M52790_SW1_V_AMP 0x0008 +#define M52790_SW1_V_AMP 0x0008 /* Enable 6dB amplifier for component out */ -#define M52790_SW1_YC_AMP 0x0010 +#define M52790_SW1_YC_AMP 0x0010 /* Audio output mode */ -#define M52790_SW1_AUDIO_MASK 0x00c0 -#define M52790_SW1_AUDIO_MUTE 0x0000 -#define M52790_SW1_AUDIO_R 0x0040 -#define M52790_SW1_AUDIO_L 0x0080 +#define M52790_SW1_AUDIO_MASK 0x00c0 +#define M52790_SW1_AUDIO_MUTE 0x0000 +#define M52790_SW1_AUDIO_R 0x0040 +#define M52790_SW1_AUDIO_L 0x0080 #define M52790_SW1_AUDIO_STEREO 0x00c0 /* Output routing switch 2 */ /* Enable 6dB amplifier for composite out */ -#define M52790_SW2_V_AMP 0x0800 +#define M52790_SW2_V_AMP 0x0800 /* Enable 6dB amplifier for component out */ -#define M52790_SW2_YC_AMP 0x1000 +#define M52790_SW2_YC_AMP 0x1000 /* Audio output mode */ -#define M52790_SW2_AUDIO_MASK 0xc000 -#define M52790_SW2_AUDIO_MUTE 0x0000 -#define M52790_SW2_AUDIO_R 0x4000 -#define M52790_SW2_AUDIO_L 0x8000 +#define M52790_SW2_AUDIO_MASK 0xc000 +#define M52790_SW2_AUDIO_MUTE 0x0000 +#define M52790_SW2_AUDIO_R 0x4000 +#define M52790_SW2_AUDIO_L 0x8000 #define M52790_SW2_AUDIO_STEREO 0xc000 @@ -83,9 +83,9 @@ #define M52790_IN_V3 (M52790_SW1_IN_V3 | M52790_SW2_IN_V3) #define M52790_IN_V4 (M52790_SW1_IN_V4 | M52790_SW2_IN_V4) -#define M52790_OUT_STEREO (M52790_SW1_AUDIO_STEREO | \ +#define M52790_OUT_STEREO (M52790_SW1_AUDIO_STEREO | \ M52790_SW2_AUDIO_STEREO) -#define M52790_OUT_AMP_STEREO (M52790_SW1_AUDIO_STEREO | \ +#define M52790_OUT_AMP_STEREO (M52790_SW1_AUDIO_STEREO | \ M52790_SW1_V_AMP | \ M52790_SW2_AUDIO_STEREO | \ M52790_SW2_V_AMP) diff --git a/include/media/i2c/saa7115.h b/include/media/i2c/saa7115.h index 53954c90e7f6..a0cda423509d 100644 --- a/include/media/i2c/saa7115.h +++ b/include/media/i2c/saa7115.h @@ -36,15 +36,15 @@ #define SAA7115_SVIDEO3 9 /* outputs */ -#define SAA7115_IPORT_ON 1 -#define SAA7115_IPORT_OFF 0 +#define SAA7115_IPORT_ON 1 +#define SAA7115_IPORT_OFF 0 /* SAA7111 specific outputs. */ -#define SAA7111_VBI_BYPASS 2 +#define SAA7111_VBI_BYPASS 2 #define SAA7111_FMT_YUV422 0x00 -#define SAA7111_FMT_RGB 0x40 -#define SAA7111_FMT_CCIR 0x80 -#define SAA7111_FMT_YUV411 0xc0 +#define SAA7111_FMT_RGB 0x40 +#define SAA7111_FMT_CCIR 0x80 +#define SAA7111_FMT_YUV411 0xc0 /* config flags */ /* diff --git a/include/media/i2c/upd64031a.h b/include/media/i2c/upd64031a.h index 48ec03c4ef23..1eba24dfee48 100644 --- a/include/media/i2c/upd64031a.h +++ b/include/media/i2c/upd64031a.h @@ -18,9 +18,9 @@ #define _UPD64031A_H_ /* Ghost reduction modes */ -#define UPD64031A_GR_ON 0 -#define UPD64031A_GR_OFF 1 -#define UPD64031A_GR_THROUGH 3 +#define UPD64031A_GR_ON 0 +#define UPD64031A_GR_OFF 1 +#define UPD64031A_GR_THROUGH 3 /* Direct 3D/YCS Connection */ #define UPD64031A_3DYCS_DISABLE (0 << 2) diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 7fc0bc6b8007..e0d95a7c5d48 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -50,7 +50,7 @@ /* These three macros assume that the debug level is set with a module parameter called 'debug'. */ #define v4l_dbg(level, debug, client, fmt, arg...) \ - do { \ + do { \ if (debug >= (level)) \ v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \ } while (0) @@ -80,9 +80,9 @@ /* These three macros assume that the debug level is set with a module parameter called 'debug'. */ #define v4l2_dbg(level, debug, dev, fmt, arg...) \ - do { \ + do { \ if (debug >= (level)) \ - v4l2_printk(KERN_DEBUG, dev, fmt , ## arg); \ + v4l2_printk(KERN_DEBUG, dev, fmt , ## arg); \ } while (0) /** @@ -266,7 +266,7 @@ struct v4l2_priv_tun_config { }; #define TUNER_SET_CONFIG _IOW('d', 92, struct v4l2_priv_tun_config) -#define VIDIOC_INT_RESET _IOW ('d', 102, u32) +#define VIDIOC_INT_RESET _IOW ('d', 102, u32) /* ------------------------------------------------------------------------- */ diff --git a/include/uapi/linux/dvb/video.h b/include/uapi/linux/dvb/video.h index 4d51f98182bb..df3d7028c807 100644 --- a/include/uapi/linux/dvb/video.h +++ b/include/uapi/linux/dvb/video.h @@ -83,11 +83,11 @@ typedef enum { #define VIDEO_CMD_CONTINUE (3) /* Flags for VIDEO_CMD_FREEZE */ -#define VIDEO_CMD_FREEZE_TO_BLACK (1 << 0) +#define VIDEO_CMD_FREEZE_TO_BLACK (1 << 0) /* Flags for VIDEO_CMD_STOP */ -#define VIDEO_CMD_STOP_TO_BLACK (1 << 0) -#define VIDEO_CMD_STOP_IMMEDIATELY (1 << 1) +#define VIDEO_CMD_STOP_TO_BLACK (1 << 0) +#define VIDEO_CMD_STOP_IMMEDIATELY (1 << 1) /* Play input formats: */ /* The decoder has no special format requirements */ @@ -124,8 +124,8 @@ struct video_command { /* FIELD_UNKNOWN can be used if the hardware does not know whether the Vsync is for an odd, even or progressive (i.e. non-interlaced) field. */ -#define VIDEO_VSYNC_FIELD_UNKNOWN (0) -#define VIDEO_VSYNC_FIELD_ODD (1) +#define VIDEO_VSYNC_FIELD_UNKNOWN (0) +#define VIDEO_VSYNC_FIELD_ODD (1) #define VIDEO_VSYNC_FIELD_EVEN (2) #define VIDEO_VSYNC_FIELD_PROGRESSIVE (3) @@ -133,8 +133,8 @@ struct video_event { __s32 type; #define VIDEO_EVENT_SIZE_CHANGED 1 #define VIDEO_EVENT_FRAME_RATE_CHANGED 2 -#define VIDEO_EVENT_DECODER_STOPPED 3 -#define VIDEO_EVENT_VSYNC 4 +#define VIDEO_EVENT_DECODER_STOPPED 3 +#define VIDEO_EVENT_VSYNC 4 /* unused, make sure to use atomic time for y2038 if it ever gets used */ long timestamp; union { @@ -268,9 +268,9 @@ typedef __u16 video_attributes_t; #define VIDEO_GET_PTS _IOR('o', 57, __u64) /* Read the number of displayed frames since the decoder was started */ -#define VIDEO_GET_FRAME_COUNT _IOR('o', 58, __u64) +#define VIDEO_GET_FRAME_COUNT _IOR('o', 58, __u64) -#define VIDEO_COMMAND _IOWR('o', 59, struct video_command) -#define VIDEO_TRY_COMMAND _IOWR('o', 60, struct video_command) +#define VIDEO_COMMAND _IOWR('o', 59, struct video_command) +#define VIDEO_TRY_COMMAND _IOWR('o', 60, struct video_command) #endif /* _UAPI_DVBVIDEO_H_ */ diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h index a692623e0236..cbbb750d87d1 100644 --- a/include/uapi/linux/v4l2-controls.h +++ b/include/uapi/linux/v4l2-controls.h @@ -67,8 +67,8 @@ /* User-class control IDs */ #define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900) -#define V4L2_CID_USER_BASE V4L2_CID_BASE -#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1) +#define V4L2_CID_USER_BASE V4L2_CID_BASE +#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1) #define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) #define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) #define V4L2_CID_SATURATION (V4L2_CID_BASE+2) @@ -102,7 +102,7 @@ enum v4l2_power_line_frequency { #define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25) #define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26) #define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) -#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) +#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28) #define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29) #define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30) #define V4L2_CID_COLORFX (V4L2_CID_BASE+31) @@ -194,11 +194,11 @@ enum v4l2_colorfx { /* The MPEG controls are applicable to all codec controls * and the 'MPEG' part of the define is historical */ -#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) -#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1) +#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) +#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1) /* MPEG streams, specific to multiplexed streams */ -#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0) +#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0) enum v4l2_mpeg_stream_type { V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */ V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */ @@ -207,26 +207,26 @@ enum v4l2_mpeg_stream_type { V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */ V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */ }; -#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1) -#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2) -#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3) -#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4) -#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5) -#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6) -#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7) +#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1) +#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2) +#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3) +#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4) +#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5) +#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6) +#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7) enum v4l2_mpeg_stream_vbi_fmt { V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */ V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */ }; /* MPEG audio controls specific to multiplexed streams */ -#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100) +#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100) enum v4l2_mpeg_audio_sampling_freq { V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0, V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1, V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2, }; -#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101) +#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101) enum v4l2_mpeg_audio_encoding { V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0, V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1, @@ -234,7 +234,7 @@ enum v4l2_mpeg_audio_encoding { V4L2_MPEG_AUDIO_ENCODING_AAC = 3, V4L2_MPEG_AUDIO_ENCODING_AC3 = 4, }; -#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102) +#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102) enum v4l2_mpeg_audio_l1_bitrate { V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0, V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1, @@ -251,7 +251,7 @@ enum v4l2_mpeg_audio_l1_bitrate { V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12, V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13, }; -#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103) +#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103) enum v4l2_mpeg_audio_l2_bitrate { V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0, V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1, @@ -268,7 +268,7 @@ enum v4l2_mpeg_audio_l2_bitrate { V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12, V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13, }; -#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104) +#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104) enum v4l2_mpeg_audio_l3_bitrate { V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0, V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1, @@ -285,32 +285,32 @@ enum v4l2_mpeg_audio_l3_bitrate { V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12, V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13, }; -#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105) +#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105) enum v4l2_mpeg_audio_mode { V4L2_MPEG_AUDIO_MODE_STEREO = 0, V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1, V4L2_MPEG_AUDIO_MODE_DUAL = 2, V4L2_MPEG_AUDIO_MODE_MONO = 3, }; -#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106) +#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106) enum v4l2_mpeg_audio_mode_extension { V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0, V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1, V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2, V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3, }; -#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107) +#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107) enum v4l2_mpeg_audio_emphasis { V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0, V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1, V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2, }; -#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108) +#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108) enum v4l2_mpeg_audio_crc { V4L2_MPEG_AUDIO_CRC_NONE = 0, V4L2_MPEG_AUDIO_CRC_CRC16 = 1, }; -#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109) +#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109) #define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110) #define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111) enum v4l2_mpeg_audio_ac3_bitrate { @@ -346,33 +346,33 @@ enum v4l2_mpeg_audio_dec_playback { #define V4L2_CID_MPEG_AUDIO_DEC_MULTILINGUAL_PLAYBACK (V4L2_CID_MPEG_BASE+113) /* MPEG video controls specific to multiplexed streams */ -#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) +#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) enum v4l2_mpeg_video_encoding { V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0, V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2, }; -#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201) +#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201) enum v4l2_mpeg_video_aspect { V4L2_MPEG_VIDEO_ASPECT_1x1 = 0, V4L2_MPEG_VIDEO_ASPECT_4x3 = 1, V4L2_MPEG_VIDEO_ASPECT_16x9 = 2, V4L2_MPEG_VIDEO_ASPECT_221x100 = 3, }; -#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202) -#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203) -#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204) -#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205) -#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206) +#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202) +#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203) +#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204) +#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205) +#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206) enum v4l2_mpeg_video_bitrate_mode { V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0, V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1, }; -#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207) -#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208) +#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207) +#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208) #define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209) -#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) -#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) +#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) +#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) #define V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE (V4L2_CID_MPEG_BASE+212) #define V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER (V4L2_CID_MPEG_BASE+213) #define V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB (V4L2_CID_MPEG_BASE+214) @@ -590,14 +590,14 @@ enum v4l2_vp8_golden_frame_sel { #define V4L2_CID_MPEG_VIDEO_VPX_PROFILE (V4L2_CID_MPEG_BASE+511) /* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ -#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) -#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) +#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) +#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) enum v4l2_mpeg_cx2341x_video_spatial_filter_mode { V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0, V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1, }; -#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1) -#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2) +#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1) +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2) enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type { V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, @@ -605,18 +605,18 @@ enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type { V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4, }; -#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3) +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3) enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type { V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0, V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1, }; -#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4) +#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4) enum v4l2_mpeg_cx2341x_video_temporal_filter_mode { V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0, V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1, }; -#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5) -#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6) +#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5) +#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6) enum v4l2_mpeg_cx2341x_video_median_filter_type { V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1, @@ -624,11 +624,11 @@ enum v4l2_mpeg_cx2341x_video_median_filter_type { V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4, }; -#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7) -#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8) +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7) +#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8) #define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9) -#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10) -#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11) +#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10) +#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11) /* MPEG-class control IDs specific to the Samsung MFC 5.1 driver as defined by V4L2 */ #define V4L2_CID_MPEG_MFC51_BASE (V4L2_CTRL_CLASS_MPEG | 0x1100) @@ -660,8 +660,8 @@ enum v4l2_mpeg_mfc51_video_force_frame_type { /* Camera class control IDs */ -#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) -#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) +#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900) +#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1) #define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1) enum v4l2_exposure_auto_type { diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index faa97fda588a..982718965180 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -107,14 +107,14 @@ enum v4l2_field { transmitted first */ }; #define V4L2_FIELD_HAS_TOP(field) \ - ((field) == V4L2_FIELD_TOP ||\ + ((field) == V4L2_FIELD_TOP ||\ (field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_INTERLACED_TB ||\ (field) == V4L2_FIELD_INTERLACED_BT ||\ (field) == V4L2_FIELD_SEQ_TB ||\ (field) == V4L2_FIELD_SEQ_BT) #define V4L2_FIELD_HAS_BOTTOM(field) \ - ((field) == V4L2_FIELD_BOTTOM ||\ + ((field) == V4L2_FIELD_BOTTOM ||\ (field) == V4L2_FIELD_INTERLACED ||\ (field) == V4L2_FIELD_INTERLACED_TB ||\ (field) == V4L2_FIELD_INTERLACED_BT ||\ @@ -467,12 +467,12 @@ struct v4l2_capability { * V I D E O I M A G E F O R M A T */ struct v4l2_pix_format { - __u32 width; + __u32 width; __u32 height; __u32 pixelformat; __u32 field; /* enum v4l2_field */ - __u32 bytesperline; /* for padding, zero if unused */ - __u32 sizeimage; + __u32 bytesperline; /* for padding, zero if unused */ + __u32 sizeimage; __u32 colorspace; /* enum v4l2_colorspace */ __u32 priv; /* private data, depends on pixelformat */ __u32 flags; /* format flags (V4L2_PIX_FMT_FLAG_*) */ @@ -1173,7 +1173,7 @@ typedef __u64 v4l2_std_id; V4L2_STD_NTSC_M_JP |\ V4L2_STD_NTSC_M_KR) /* Secam macros */ -#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ +#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ V4L2_STD_SECAM_K |\ V4L2_STD_SECAM_K1) /* All Secam Standards */ @@ -1254,7 +1254,7 @@ struct v4l2_standard { }; /* - * D V B T T I M I N G S + * D V B T T I M I N G S */ /** struct v4l2_bt_timings - BT.656/BT.1120 timing data @@ -1595,7 +1595,7 @@ struct v4l2_ext_controls { struct v4l2_ext_control *controls; }; -#define V4L2_CTRL_ID_MASK (0x0fffffff) +#define V4L2_CTRL_ID_MASK (0x0fffffff) #ifndef __KERNEL__ #define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL) #endif @@ -1667,11 +1667,11 @@ struct v4l2_querymenu { /* Control flags */ #define V4L2_CTRL_FLAG_DISABLED 0x0001 #define V4L2_CTRL_FLAG_GRABBED 0x0002 -#define V4L2_CTRL_FLAG_READ_ONLY 0x0004 -#define V4L2_CTRL_FLAG_UPDATE 0x0008 -#define V4L2_CTRL_FLAG_INACTIVE 0x0010 -#define V4L2_CTRL_FLAG_SLIDER 0x0020 -#define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040 +#define V4L2_CTRL_FLAG_READ_ONLY 0x0004 +#define V4L2_CTRL_FLAG_UPDATE 0x0008 +#define V4L2_CTRL_FLAG_INACTIVE 0x0010 +#define V4L2_CTRL_FLAG_SLIDER 0x0020 +#define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040 #define V4L2_CTRL_FLAG_VOLATILE 0x0080 #define V4L2_CTRL_FLAG_HAS_PAYLOAD 0x0100 #define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE 0x0200 @@ -1785,21 +1785,21 @@ struct v4l2_hw_freq_seek { */ struct v4l2_rds_data { - __u8 lsb; - __u8 msb; - __u8 block; + __u8 lsb; + __u8 msb; + __u8 block; } __attribute__ ((packed)); -#define V4L2_RDS_BLOCK_MSK 0x7 -#define V4L2_RDS_BLOCK_A 0 -#define V4L2_RDS_BLOCK_B 1 -#define V4L2_RDS_BLOCK_C 2 -#define V4L2_RDS_BLOCK_D 3 -#define V4L2_RDS_BLOCK_C_ALT 4 -#define V4L2_RDS_BLOCK_INVALID 7 +#define V4L2_RDS_BLOCK_MSK 0x7 +#define V4L2_RDS_BLOCK_A 0 +#define V4L2_RDS_BLOCK_B 1 +#define V4L2_RDS_BLOCK_C 2 +#define V4L2_RDS_BLOCK_D 3 +#define V4L2_RDS_BLOCK_C_ALT 4 +#define V4L2_RDS_BLOCK_INVALID 7 #define V4L2_RDS_BLOCK_CORRECTED 0x40 -#define V4L2_RDS_BLOCK_ERROR 0x80 +#define V4L2_RDS_BLOCK_ERROR 0x80 /* * A U D I O @@ -2355,8 +2355,8 @@ struct v4l2_create_buffers { #define VIDIOC_S_CROP _IOW('V', 60, struct v4l2_crop) #define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct v4l2_jpegcompression) #define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct v4l2_jpegcompression) -#define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id) -#define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format) +#define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id) +#define VIDIOC_TRY_FMT _IOWR('V', 64, struct v4l2_format) #define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct v4l2_audio) #define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct v4l2_audioout) #define VIDIOC_G_PRIORITY _IOR('V', 67, __u32) /* enum v4l2_priority */ @@ -2377,8 +2377,8 @@ struct v4l2_create_buffers { * Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. * You must be root to use these ioctls. Never use these in applications! */ -#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register) -#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register) +#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register) +#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register) #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) #define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) -- cgit v1.2.3-59-g8ed1b From 863def15b9755d9016df4d93addf3127f1dc67f4 Mon Sep 17 00:00:00 2001 From: James Chapman Date: Wed, 3 Jan 2018 22:48:04 +0000 Subject: l2tp: revert "l2tp: add peer_offset parameter" Revert commit f15bc54eeecd ("l2tp: add peer_offset parameter"). This is removed because it is adding another configurable offset and configurable offsets are being removed. Signed-off-by: James Chapman Signed-off-by: David S. Miller --- include/uapi/linux/l2tp.h | 1 - net/l2tp/l2tp_core.c | 3 +-- net/l2tp/l2tp_core.h | 13 +++---------- net/l2tp/l2tp_debugfs.c | 8 +++----- net/l2tp/l2tp_netlink.c | 21 +-------------------- 5 files changed, 8 insertions(+), 38 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h index d6fee55dbded..d84ce5c1c9aa 100644 --- a/include/uapi/linux/l2tp.h +++ b/include/uapi/linux/l2tp.h @@ -127,7 +127,6 @@ enum { L2TP_ATTR_UDP_ZERO_CSUM6_TX, /* flag */ L2TP_ATTR_UDP_ZERO_CSUM6_RX, /* flag */ L2TP_ATTR_PAD, - L2TP_ATTR_PEER_OFFSET, /* u16 */ __L2TP_ATTR_MAX, }; diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 6ff64717da1e..115918ad8eca 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -792,7 +792,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, ptr += 2 + offset; } } else - ptr += session->peer_offset; + ptr += session->offset; offset = ptr - optr; if (!pskb_may_pull(skb, offset)) @@ -1785,7 +1785,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn session->lns_mode = cfg->lns_mode; session->reorder_timeout = cfg->reorder_timeout; session->offset = cfg->offset; - session->peer_offset = cfg->peer_offset; session->l2specific_type = cfg->l2specific_type; session->l2specific_len = cfg->l2specific_len; session->cookie_len = cfg->cookie_len; diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h index c6fe7cc42a05..9534e16965cc 100644 --- a/net/l2tp/l2tp_core.h +++ b/net/l2tp/l2tp_core.h @@ -59,8 +59,7 @@ struct l2tp_session_cfg { int debug; /* bitmask of debug message * categories */ u16 vlan_id; /* VLAN pseudowire only */ - u16 offset; /* offset to tx payload */ - u16 peer_offset; /* offset to rx payload */ + u16 offset; /* offset to payload */ u16 l2specific_len; /* Layer 2 specific length */ u16 l2specific_type; /* Layer 2 specific type */ u8 cookie[8]; /* optional cookie */ @@ -87,14 +86,8 @@ struct l2tp_session { int cookie_len; u8 peer_cookie[8]; int peer_cookie_len; - u16 offset; /* offset from end of L2TP - * header to beginning of - * tx data - */ - u16 peer_offset; /* offset from end of L2TP - * header to beginning of - * rx data - */ + u16 offset; /* offset from end of L2TP header + to beginning of data */ u16 l2specific_len; u16 l2specific_type; u16 hdr_len; diff --git a/net/l2tp/l2tp_debugfs.c b/net/l2tp/l2tp_debugfs.c index 4cc30b38aba4..eb69411bcb47 100644 --- a/net/l2tp/l2tp_debugfs.c +++ b/net/l2tp/l2tp_debugfs.c @@ -180,9 +180,8 @@ static void l2tp_dfs_seq_session_show(struct seq_file *m, void *v) session->lns_mode ? "LNS" : "LAC", session->debug, jiffies_to_msecs(session->reorder_timeout)); - seq_printf(m, " offset %hu peer_offset %hu l2specific %hu/%hu\n", - session->offset, session->peer_offset, - session->l2specific_type, session->l2specific_len); + seq_printf(m, " offset %hu l2specific %hu/%hu\n", + session->offset, session->l2specific_type, session->l2specific_len); if (session->cookie_len) { seq_printf(m, " cookie %02x%02x%02x%02x", session->cookie[0], session->cookie[1], @@ -229,8 +228,7 @@ static int l2tp_dfs_seq_show(struct seq_file *m, void *v) seq_puts(m, " debug tx-pkts/bytes/errs rx-pkts/bytes/errs\n"); seq_puts(m, " SESSION ID, peer ID, PWTYPE\n"); seq_puts(m, " refcnt cnt\n"); - seq_puts(m, " offset OFFSET peer_offset OFFSET"); - seq_puts(m, " l2specific TYPE/LEN\n"); + seq_puts(m, " offset OFFSET l2specific TYPE/LEN\n"); seq_puts(m, " [ cookie ]\n"); seq_puts(m, " [ peer cookie ]\n"); seq_puts(m, " config mtu/mru/rcvseq/sendseq/dataseq/lns debug reorderto\n"); diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c index d7d4d7a7a54d..7e9c50125556 100644 --- a/net/l2tp/l2tp_netlink.c +++ b/net/l2tp/l2tp_netlink.c @@ -547,25 +547,9 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf } if (tunnel->version > 2) { - if (info->attrs[L2TP_ATTR_PEER_OFFSET]) { - struct nlattr *peer_offset; - - peer_offset = info->attrs[L2TP_ATTR_PEER_OFFSET]; - cfg.peer_offset = nla_get_u16(peer_offset); - } - - if (info->attrs[L2TP_ATTR_OFFSET]) { + if (info->attrs[L2TP_ATTR_OFFSET]) cfg.offset = nla_get_u16(info->attrs[L2TP_ATTR_OFFSET]); - /* in order to maintain compatibility with older - * versions where offset was used for both tx and - * rx side, update rx side with offset if peer_offset - * is not provided by userspace - */ - if (!info->attrs[L2TP_ATTR_PEER_OFFSET]) - cfg.peer_offset = cfg.offset; - } - if (info->attrs[L2TP_ATTR_DATA_SEQ]) cfg.data_seq = nla_get_u8(info->attrs[L2TP_ATTR_DATA_SEQ]); @@ -779,8 +763,6 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl nla_put_string(skb, L2TP_ATTR_IFNAME, session->ifname)) || (session->offset && nla_put_u16(skb, L2TP_ATTR_OFFSET, session->offset)) || - (session->peer_offset && - nla_put_u16(skb, L2TP_ATTR_PEER_OFFSET, session->peer_offset)) || (session->cookie_len && nla_put(skb, L2TP_ATTR_COOKIE, session->cookie_len, &session->cookie[0])) || @@ -921,7 +903,6 @@ static const struct nla_policy l2tp_nl_policy[L2TP_ATTR_MAX + 1] = { [L2TP_ATTR_PW_TYPE] = { .type = NLA_U16, }, [L2TP_ATTR_ENCAP_TYPE] = { .type = NLA_U16, }, [L2TP_ATTR_OFFSET] = { .type = NLA_U16, }, - [L2TP_ATTR_PEER_OFFSET] = { .type = NLA_U16, }, [L2TP_ATTR_DATA_SEQ] = { .type = NLA_U8, }, [L2TP_ATTR_L2SPEC_TYPE] = { .type = NLA_U8, }, [L2TP_ATTR_L2SPEC_LEN] = { .type = NLA_U8, }, -- cgit v1.2.3-59-g8ed1b From 4887d8933a8dfdfa6602e0faaa0e31cd343ccefe Mon Sep 17 00:00:00 2001 From: James Chapman Date: Wed, 3 Jan 2018 22:48:07 +0000 Subject: l2tp: add comment in API header that L2TP_ATTR_OFFSET is not used Signed-off-by: James Chapman Signed-off-by: David S. Miller --- include/uapi/linux/l2tp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h index d84ce5c1c9aa..f78eef4cc56a 100644 --- a/include/uapi/linux/l2tp.h +++ b/include/uapi/linux/l2tp.h @@ -94,7 +94,7 @@ enum { L2TP_ATTR_NONE, /* no data */ L2TP_ATTR_PW_TYPE, /* u16, enum l2tp_pwtype */ L2TP_ATTR_ENCAP_TYPE, /* u16, enum l2tp_encap_type */ - L2TP_ATTR_OFFSET, /* u16 */ + L2TP_ATTR_OFFSET, /* u16 (not used) */ L2TP_ATTR_DATA_SEQ, /* u16 */ L2TP_ATTR_L2SPEC_TYPE, /* u8, enum l2tp_l2spec_type */ L2TP_ATTR_L2SPEC_LEN, /* u8, enum l2tp_l2spec_type */ -- cgit v1.2.3-59-g8ed1b From 02dd3291b2f095bbc88e1d2628fd5bf2e92de69b Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Wed, 3 Jan 2018 11:26:14 +0100 Subject: bpf: finally expose xdp_rxq_info to XDP bpf-programs Now all XDP driver have been updated to setup xdp_rxq_info and assign this to xdp_buff->rxq. Thus, it is now safe to enable access to some of the xdp_rxq_info struct members. This patch extend xdp_md and expose UAPI to userspace for ingress_ifindex and rx_queue_index. Access happens via bpf instruction rewrite, that load data directly from struct xdp_rxq_info. * ingress_ifindex map to xdp_rxq_info->dev->ifindex * rx_queue_index map to xdp_rxq_info->queue_index Signed-off-by: Jesper Dangaard Brouer Acked-by: Alexei Starovoitov Acked-by: John Fastabend Signed-off-by: Alexei Starovoitov --- include/uapi/linux/bpf.h | 3 +++ net/core/filter.c | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index f2f8b36e2ad4..405317f9c064 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -899,6 +899,9 @@ struct xdp_md { __u32 data; __u32 data_end; __u32 data_meta; + /* Below access go though struct xdp_rxq_info */ + __u32 ingress_ifindex; /* rxq->dev->ifindex */ + __u32 rx_queue_index; /* rxq->queue_index */ }; enum sk_action { diff --git a/net/core/filter.c b/net/core/filter.c index 130b842c3a15..acdb94c0e97f 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -4304,6 +4304,25 @@ static u32 xdp_convert_ctx_access(enum bpf_access_type type, si->dst_reg, si->src_reg, offsetof(struct xdp_buff, data_end)); break; + case offsetof(struct xdp_md, ingress_ifindex): + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct xdp_buff, rxq), + si->dst_reg, si->src_reg, + offsetof(struct xdp_buff, rxq)); + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct xdp_rxq_info, dev), + si->dst_reg, si->dst_reg, + offsetof(struct xdp_rxq_info, dev)); + *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg, + bpf_target_off(struct net_device, + ifindex, 4, target_size)); + break; + case offsetof(struct xdp_md, rx_queue_index): + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct xdp_buff, rxq), + si->dst_reg, si->src_reg, + offsetof(struct xdp_buff, rxq)); + *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg, + bpf_target_off(struct xdp_rxq_info, + queue_index, 4, target_size)); + break; } return insn - insn_buf; -- cgit v1.2.3-59-g8ed1b From e58f33cc84bc089c430ac955f3cad6380ae98591 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Thu, 7 Dec 2017 16:28:23 +0100 Subject: netfilter: add defines for arp/decnet max hooks The kernel already has defines for this, but they are in uapi exposed headers. Including these from netns.h causes build errors and also adds unneeded dependencies on heads that we don't need. So move these defines to netfilter_defs.h and place the uapi ones in ifndef __KERNEL__ to keep them for userspace. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter_defs.h | 6 ++++++ include/uapi/linux/netfilter_arp.h | 3 +++ include/uapi/linux/netfilter_decnet.h | 4 +++- 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/include/linux/netfilter_defs.h b/include/linux/netfilter_defs.h index dc6111adea06..fdcdf2bf34df 100644 --- a/include/linux/netfilter_defs.h +++ b/include/linux/netfilter_defs.h @@ -7,4 +7,10 @@ /* Largest hook number + 1, see uapi/linux/netfilter_decnet.h */ #define NF_MAX_HOOKS 8 +/* in/out/forward only */ +#define NF_ARP_NUMHOOKS 3 + +/* max hook is NF_DN_ROUTE (6), also see uapi/linux/netfilter_decnet.h */ +#define NF_DN_NUMHOOKS 7 + #endif diff --git a/include/uapi/linux/netfilter_arp.h b/include/uapi/linux/netfilter_arp.h index 81b6a4cbcb72..791dfc5ae907 100644 --- a/include/uapi/linux/netfilter_arp.h +++ b/include/uapi/linux/netfilter_arp.h @@ -15,6 +15,9 @@ #define NF_ARP_IN 0 #define NF_ARP_OUT 1 #define NF_ARP_FORWARD 2 + +#ifndef __KERNEL__ #define NF_ARP_NUMHOOKS 3 +#endif #endif /* __LINUX_ARP_NETFILTER_H */ diff --git a/include/uapi/linux/netfilter_decnet.h b/include/uapi/linux/netfilter_decnet.h index 9089c38f6abe..61f1c7dfd033 100644 --- a/include/uapi/linux/netfilter_decnet.h +++ b/include/uapi/linux/netfilter_decnet.h @@ -24,6 +24,9 @@ #define NFC_DN_IF_IN 0x0004 /* Output device. */ #define NFC_DN_IF_OUT 0x0008 + +/* kernel define is in netfilter_defs.h */ +#define NF_DN_NUMHOOKS 7 #endif /* ! __KERNEL__ */ /* DECnet Hooks */ @@ -41,7 +44,6 @@ #define NF_DN_HELLO 5 /* Input Routing Packets */ #define NF_DN_ROUTE 6 -#define NF_DN_NUMHOOKS 7 enum nf_dn_hook_priorities { NF_DN_PRI_FIRST = INT_MIN, -- cgit v1.2.3-59-g8ed1b From 625c556118f3c2fd28bb8ef6da18c53bd4037be4 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Sat, 9 Dec 2017 21:01:08 +0100 Subject: netfilter: connlimit: split xt_connlimit into front and backend This allows to reuse xt_connlimit infrastructure from nf_tables. The upcoming nf_tables frontend can just pass in an nftables register as input key, this allows limiting by any nft-supported key, including concatenations. For xt_connlimit, pass in the zone and the ip/ipv6 address. With help from Yi-Hung Wei. Signed-off-by: Florian Westphal Acked-by: Yi-Hung Wei Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_conntrack_count.h | 17 ++ include/uapi/linux/netfilter/xt_connlimit.h | 2 +- net/netfilter/Kconfig | 3 + net/netfilter/Makefile | 2 + net/netfilter/nf_conncount.c | 373 ++++++++++++++++++++++++++++ net/netfilter/xt_connlimit.c | 369 ++------------------------- 6 files changed, 420 insertions(+), 346 deletions(-) create mode 100644 include/net/netfilter/nf_conntrack_count.h create mode 100644 net/netfilter/nf_conncount.c (limited to 'include/uapi/linux') diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h new file mode 100644 index 000000000000..adf8db44cf86 --- /dev/null +++ b/include/net/netfilter/nf_conntrack_count.h @@ -0,0 +1,17 @@ +#ifndef _NF_CONNTRACK_COUNT_H +#define _NF_CONNTRACK_COUNT_H + +struct nf_conncount_data; + +struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family, + unsigned int keylen); +void nf_conncount_destroy(struct net *net, unsigned int family, + struct nf_conncount_data *data); + +unsigned int nf_conncount_count(struct net *net, + struct nf_conncount_data *data, + const u32 *key, + unsigned int family, + const struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_zone *zone); +#endif diff --git a/include/uapi/linux/netfilter/xt_connlimit.h b/include/uapi/linux/netfilter/xt_connlimit.h index 07e5e9d47882..d4d1943dcd11 100644 --- a/include/uapi/linux/netfilter/xt_connlimit.h +++ b/include/uapi/linux/netfilter/xt_connlimit.h @@ -27,7 +27,7 @@ struct xt_connlimit_info { __u32 flags; /* Used internally by the kernel */ - struct xt_connlimit_data *data __attribute__((aligned(8))); + struct nf_conncount_data *data __attribute__((aligned(8))); }; #endif /* _XT_CONNLIMIT_H */ diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 263609a7e010..af3d9f721b3f 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -68,6 +68,8 @@ config NF_LOG_NETDEV select NF_LOG_COMMON if NF_CONNTRACK +config NETFILTER_CONNCOUNT + tristate config NF_CONNTRACK_MARK bool 'Connection mark tracking support' @@ -1126,6 +1128,7 @@ config NETFILTER_XT_MATCH_CONNLIMIT tristate '"connlimit" match support' depends on NF_CONNTRACK depends on NETFILTER_ADVANCED + select NETFILTER_CONNCOUNT ---help--- This match allows you to match against the number of parallel connections to a server per client IP address (or address block). diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index f78ed2470831..490a55e7166d 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -67,6 +67,8 @@ obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o # SYNPROXY obj-$(CONFIG_NETFILTER_SYNPROXY) += nf_synproxy_core.o +obj-$(CONFIG_NETFILTER_CONNCOUNT) += nf_conncount.o + # generic packet duplication from netdev family obj-$(CONFIG_NF_DUP_NETDEV) += nf_dup_netdev.o diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c new file mode 100644 index 000000000000..a95518261168 --- /dev/null +++ b/net/netfilter/nf_conncount.c @@ -0,0 +1,373 @@ +/* + * count the number of connections matching an arbitrary key. + * + * (C) 2017 Red Hat GmbH + * Author: Florian Westphal + * + * split from xt_connlimit.c: + * (c) 2000 Gerd Knorr + * Nov 2002: Martin Bene : + * only ignore TIME_WAIT or gone connections + * (C) CC Computer Consultants GmbH, 2007 + */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CONNCOUNT_SLOTS 256U + +#ifdef CONFIG_LOCKDEP +#define CONNCOUNT_LOCK_SLOTS 8U +#else +#define CONNCOUNT_LOCK_SLOTS 256U +#endif + +#define CONNCOUNT_GC_MAX_NODES 8 +#define MAX_KEYLEN 5 + +/* we will save the tuples of all connections we care about */ +struct nf_conncount_tuple { + struct hlist_node node; + struct nf_conntrack_tuple tuple; +}; + +struct nf_conncount_rb { + struct rb_node node; + struct hlist_head hhead; /* connections/hosts in same subnet */ + u32 key[MAX_KEYLEN]; +}; + +static spinlock_t nf_conncount_locks[CONNCOUNT_LOCK_SLOTS] __cacheline_aligned_in_smp; + +struct nf_conncount_data { + unsigned int keylen; + struct rb_root root[CONNCOUNT_SLOTS]; +}; + +static u_int32_t conncount_rnd __read_mostly; +static struct kmem_cache *conncount_rb_cachep __read_mostly; +static struct kmem_cache *conncount_conn_cachep __read_mostly; + +static inline bool already_closed(const struct nf_conn *conn) +{ + if (nf_ct_protonum(conn) == IPPROTO_TCP) + return conn->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT || + conn->proto.tcp.state == TCP_CONNTRACK_CLOSE; + else + return 0; +} + +static int key_diff(const u32 *a, const u32 *b, unsigned int klen) +{ + return memcmp(a, b, klen * sizeof(u32)); +} + +static bool add_hlist(struct hlist_head *head, + const struct nf_conntrack_tuple *tuple) +{ + struct nf_conncount_tuple *conn; + + conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); + if (conn == NULL) + return false; + conn->tuple = *tuple; + hlist_add_head(&conn->node, head); + return true; +} + +static unsigned int check_hlist(struct net *net, + struct hlist_head *head, + const struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_zone *zone, + bool *addit) +{ + const struct nf_conntrack_tuple_hash *found; + struct nf_conncount_tuple *conn; + struct hlist_node *n; + struct nf_conn *found_ct; + unsigned int length = 0; + + *addit = true; + + /* check the saved connections */ + hlist_for_each_entry_safe(conn, n, head, node) { + found = nf_conntrack_find_get(net, zone, &conn->tuple); + if (found == NULL) { + hlist_del(&conn->node); + kmem_cache_free(conncount_conn_cachep, conn); + continue; + } + + found_ct = nf_ct_tuplehash_to_ctrack(found); + + if (nf_ct_tuple_equal(&conn->tuple, tuple)) { + /* + * Just to be sure we have it only once in the list. + * We should not see tuples twice unless someone hooks + * this into a table without "-p tcp --syn". + */ + *addit = false; + } else if (already_closed(found_ct)) { + /* + * we do not care about connections which are + * closed already -> ditch it + */ + nf_ct_put(found_ct); + hlist_del(&conn->node); + kmem_cache_free(conncount_conn_cachep, conn); + continue; + } + + nf_ct_put(found_ct); + length++; + } + + return length; +} + +static void tree_nodes_free(struct rb_root *root, + struct nf_conncount_rb *gc_nodes[], + unsigned int gc_count) +{ + struct nf_conncount_rb *rbconn; + + while (gc_count) { + rbconn = gc_nodes[--gc_count]; + rb_erase(&rbconn->node, root); + kmem_cache_free(conncount_rb_cachep, rbconn); + } +} + +static unsigned int +count_tree(struct net *net, struct rb_root *root, + const u32 *key, u8 keylen, + u8 family, + const struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_zone *zone) +{ + struct nf_conncount_rb *gc_nodes[CONNCOUNT_GC_MAX_NODES]; + struct rb_node **rbnode, *parent; + struct nf_conncount_rb *rbconn; + struct nf_conncount_tuple *conn; + unsigned int gc_count; + bool no_gc = false; + + restart: + gc_count = 0; + parent = NULL; + rbnode = &(root->rb_node); + while (*rbnode) { + int diff; + bool addit; + + rbconn = rb_entry(*rbnode, struct nf_conncount_rb, node); + + parent = *rbnode; + diff = key_diff(key, rbconn->key, keylen); + if (diff < 0) { + rbnode = &((*rbnode)->rb_left); + } else if (diff > 0) { + rbnode = &((*rbnode)->rb_right); + } else { + /* same source network -> be counted! */ + unsigned int count; + count = check_hlist(net, &rbconn->hhead, tuple, zone, &addit); + + tree_nodes_free(root, gc_nodes, gc_count); + if (!addit) + return count; + + if (!add_hlist(&rbconn->hhead, tuple)) + return 0; /* hotdrop */ + + return count + 1; + } + + if (no_gc || gc_count >= ARRAY_SIZE(gc_nodes)) + continue; + + /* only used for GC on hhead, retval and 'addit' ignored */ + check_hlist(net, &rbconn->hhead, tuple, zone, &addit); + if (hlist_empty(&rbconn->hhead)) + gc_nodes[gc_count++] = rbconn; + } + + if (gc_count) { + no_gc = true; + tree_nodes_free(root, gc_nodes, gc_count); + /* tree_node_free before new allocation permits + * allocator to re-use newly free'd object. + * + * This is a rare event; in most cases we will find + * existing node to re-use. (or gc_count is 0). + */ + goto restart; + } + + /* no match, need to insert new node */ + rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); + if (rbconn == NULL) + return 0; + + conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); + if (conn == NULL) { + kmem_cache_free(conncount_rb_cachep, rbconn); + return 0; + } + + conn->tuple = *tuple; + memcpy(rbconn->key, key, sizeof(u32) * keylen); + + INIT_HLIST_HEAD(&rbconn->hhead); + hlist_add_head(&conn->node, &rbconn->hhead); + + rb_link_node(&rbconn->node, parent, rbnode); + rb_insert_color(&rbconn->node, root); + return 1; +} + +unsigned int nf_conncount_count(struct net *net, + struct nf_conncount_data *data, + const u32 *key, + unsigned int family, + const struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_zone *zone) +{ + struct rb_root *root; + int count; + u32 hash; + + hash = jhash2(key, data->keylen, conncount_rnd) % CONNCOUNT_SLOTS; + root = &data->root[hash]; + + spin_lock_bh(&nf_conncount_locks[hash % CONNCOUNT_LOCK_SLOTS]); + + count = count_tree(net, root, key, data->keylen, family, tuple, zone); + + spin_unlock_bh(&nf_conncount_locks[hash % CONNCOUNT_LOCK_SLOTS]); + + return count; +} +EXPORT_SYMBOL_GPL(nf_conncount_count); + +struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family, + unsigned int keylen) +{ + struct nf_conncount_data *data; + int ret, i; + + if (keylen % sizeof(u32) || + keylen / sizeof(u32) > MAX_KEYLEN || + keylen == 0) + return ERR_PTR(-EINVAL); + + net_get_random_once(&conncount_rnd, sizeof(conncount_rnd)); + + data = kmalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return ERR_PTR(-ENOMEM); + + ret = nf_ct_netns_get(net, family); + if (ret < 0) { + kfree(data); + return ERR_PTR(ret); + } + + for (i = 0; i < ARRAY_SIZE(data->root); ++i) + data->root[i] = RB_ROOT; + + data->keylen = keylen / sizeof(u32); + + return data; +} +EXPORT_SYMBOL_GPL(nf_conncount_init); + +static void destroy_tree(struct rb_root *r) +{ + struct nf_conncount_tuple *conn; + struct nf_conncount_rb *rbconn; + struct hlist_node *n; + struct rb_node *node; + + while ((node = rb_first(r)) != NULL) { + rbconn = rb_entry(node, struct nf_conncount_rb, node); + + rb_erase(node, r); + + hlist_for_each_entry_safe(conn, n, &rbconn->hhead, node) + kmem_cache_free(conncount_conn_cachep, conn); + + kmem_cache_free(conncount_rb_cachep, rbconn); + } +} + +void nf_conncount_destroy(struct net *net, unsigned int family, + struct nf_conncount_data *data) +{ + unsigned int i; + + nf_ct_netns_put(net, family); + + for (i = 0; i < ARRAY_SIZE(data->root); ++i) + destroy_tree(&data->root[i]); + + kfree(data); +} +EXPORT_SYMBOL_GPL(nf_conncount_destroy); + +static int __init nf_conncount_modinit(void) +{ + int i; + + BUILD_BUG_ON(CONNCOUNT_LOCK_SLOTS > CONNCOUNT_SLOTS); + BUILD_BUG_ON((CONNCOUNT_SLOTS % CONNCOUNT_LOCK_SLOTS) != 0); + + for (i = 0; i < CONNCOUNT_LOCK_SLOTS; ++i) + spin_lock_init(&nf_conncount_locks[i]); + + conncount_conn_cachep = kmem_cache_create("nf_conncount_tuple", + sizeof(struct nf_conncount_tuple), + 0, 0, NULL); + if (!conncount_conn_cachep) + return -ENOMEM; + + conncount_rb_cachep = kmem_cache_create("nf_conncount_rb", + sizeof(struct nf_conncount_rb), + 0, 0, NULL); + if (!conncount_rb_cachep) { + kmem_cache_destroy(conncount_conn_cachep); + return -ENOMEM; + } + + return 0; +} + +static void __exit nf_conncount_modexit(void) +{ + kmem_cache_destroy(conncount_conn_cachep); + kmem_cache_destroy(conncount_rb_cachep); +} + +module_init(nf_conncount_modinit); +module_exit(nf_conncount_modexit); +MODULE_AUTHOR("Jan Engelhardt "); +MODULE_AUTHOR("Florian Westphal "); +MODULE_DESCRIPTION("netfilter: count number of connections matching a key"); +MODULE_LICENSE("GPL"); diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index a6214f235333..b1b17b9353e1 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c @@ -12,292 +12,30 @@ * GPL (C) 1999 Rusty Russell (rusty@rustcorp.com.au). */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include -#include -#include -#include -#include -#include -#include -#include + #include -#include #include -#include -#include #include #include + #include #include #include #include - -#define CONNLIMIT_SLOTS 256U - -#ifdef CONFIG_LOCKDEP -#define CONNLIMIT_LOCK_SLOTS 8U -#else -#define CONNLIMIT_LOCK_SLOTS 256U -#endif - -#define CONNLIMIT_GC_MAX_NODES 8 - -/* we will save the tuples of all connections we care about */ -struct xt_connlimit_conn { - struct hlist_node node; - struct nf_conntrack_tuple tuple; -}; - -struct xt_connlimit_rb { - struct rb_node node; - struct hlist_head hhead; /* connections/hosts in same subnet */ - union nf_inet_addr addr; /* search key */ -}; - -static spinlock_t xt_connlimit_locks[CONNLIMIT_LOCK_SLOTS] __cacheline_aligned_in_smp; - -struct xt_connlimit_data { - struct rb_root climit_root[CONNLIMIT_SLOTS]; -}; - -static u_int32_t connlimit_rnd __read_mostly; -static struct kmem_cache *connlimit_rb_cachep __read_mostly; -static struct kmem_cache *connlimit_conn_cachep __read_mostly; - -static inline unsigned int connlimit_iphash(__be32 addr) -{ - return jhash_1word((__force __u32)addr, - connlimit_rnd) % CONNLIMIT_SLOTS; -} - -static inline unsigned int -connlimit_iphash6(const union nf_inet_addr *addr) -{ - return jhash2((u32 *)addr->ip6, ARRAY_SIZE(addr->ip6), - connlimit_rnd) % CONNLIMIT_SLOTS; -} - -static inline bool already_closed(const struct nf_conn *conn) -{ - if (nf_ct_protonum(conn) == IPPROTO_TCP) - return conn->proto.tcp.state == TCP_CONNTRACK_TIME_WAIT || - conn->proto.tcp.state == TCP_CONNTRACK_CLOSE; - else - return 0; -} - -static int -same_source(const union nf_inet_addr *addr, - const union nf_inet_addr *u3, u_int8_t family) -{ - if (family == NFPROTO_IPV4) - return ntohl(addr->ip) - ntohl(u3->ip); - - return memcmp(addr->ip6, u3->ip6, sizeof(addr->ip6)); -} - -static bool add_hlist(struct hlist_head *head, - const struct nf_conntrack_tuple *tuple, - const union nf_inet_addr *addr) -{ - struct xt_connlimit_conn *conn; - - conn = kmem_cache_alloc(connlimit_conn_cachep, GFP_ATOMIC); - if (conn == NULL) - return false; - conn->tuple = *tuple; - hlist_add_head(&conn->node, head); - return true; -} - -static unsigned int check_hlist(struct net *net, - struct hlist_head *head, - const struct nf_conntrack_tuple *tuple, - const struct nf_conntrack_zone *zone, - bool *addit) -{ - const struct nf_conntrack_tuple_hash *found; - struct xt_connlimit_conn *conn; - struct hlist_node *n; - struct nf_conn *found_ct; - unsigned int length = 0; - - *addit = true; - - /* check the saved connections */ - hlist_for_each_entry_safe(conn, n, head, node) { - found = nf_conntrack_find_get(net, zone, &conn->tuple); - if (found == NULL) { - hlist_del(&conn->node); - kmem_cache_free(connlimit_conn_cachep, conn); - continue; - } - - found_ct = nf_ct_tuplehash_to_ctrack(found); - - if (nf_ct_tuple_equal(&conn->tuple, tuple)) { - /* - * Just to be sure we have it only once in the list. - * We should not see tuples twice unless someone hooks - * this into a table without "-p tcp --syn". - */ - *addit = false; - } else if (already_closed(found_ct)) { - /* - * we do not care about connections which are - * closed already -> ditch it - */ - nf_ct_put(found_ct); - hlist_del(&conn->node); - kmem_cache_free(connlimit_conn_cachep, conn); - continue; - } - - nf_ct_put(found_ct); - length++; - } - - return length; -} - -static void tree_nodes_free(struct rb_root *root, - struct xt_connlimit_rb *gc_nodes[], - unsigned int gc_count) -{ - struct xt_connlimit_rb *rbconn; - - while (gc_count) { - rbconn = gc_nodes[--gc_count]; - rb_erase(&rbconn->node, root); - kmem_cache_free(connlimit_rb_cachep, rbconn); - } -} - -static unsigned int -count_tree(struct net *net, struct rb_root *root, - const struct nf_conntrack_tuple *tuple, - const union nf_inet_addr *addr, - u8 family, const struct nf_conntrack_zone *zone) -{ - struct xt_connlimit_rb *gc_nodes[CONNLIMIT_GC_MAX_NODES]; - struct rb_node **rbnode, *parent; - struct xt_connlimit_rb *rbconn; - struct xt_connlimit_conn *conn; - unsigned int gc_count; - bool no_gc = false; - - restart: - gc_count = 0; - parent = NULL; - rbnode = &(root->rb_node); - while (*rbnode) { - int diff; - bool addit; - - rbconn = rb_entry(*rbnode, struct xt_connlimit_rb, node); - - parent = *rbnode; - diff = same_source(addr, &rbconn->addr, family); - if (diff < 0) { - rbnode = &((*rbnode)->rb_left); - } else if (diff > 0) { - rbnode = &((*rbnode)->rb_right); - } else { - /* same source network -> be counted! */ - unsigned int count; - count = check_hlist(net, &rbconn->hhead, tuple, zone, &addit); - - tree_nodes_free(root, gc_nodes, gc_count); - if (!addit) - return count; - - if (!add_hlist(&rbconn->hhead, tuple, addr)) - return 0; /* hotdrop */ - - return count + 1; - } - - if (no_gc || gc_count >= ARRAY_SIZE(gc_nodes)) - continue; - - /* only used for GC on hhead, retval and 'addit' ignored */ - check_hlist(net, &rbconn->hhead, tuple, zone, &addit); - if (hlist_empty(&rbconn->hhead)) - gc_nodes[gc_count++] = rbconn; - } - - if (gc_count) { - no_gc = true; - tree_nodes_free(root, gc_nodes, gc_count); - /* tree_node_free before new allocation permits - * allocator to re-use newly free'd object. - * - * This is a rare event; in most cases we will find - * existing node to re-use. (or gc_count is 0). - */ - goto restart; - } - - /* no match, need to insert new node */ - rbconn = kmem_cache_alloc(connlimit_rb_cachep, GFP_ATOMIC); - if (rbconn == NULL) - return 0; - - conn = kmem_cache_alloc(connlimit_conn_cachep, GFP_ATOMIC); - if (conn == NULL) { - kmem_cache_free(connlimit_rb_cachep, rbconn); - return 0; - } - - conn->tuple = *tuple; - rbconn->addr = *addr; - - INIT_HLIST_HEAD(&rbconn->hhead); - hlist_add_head(&conn->node, &rbconn->hhead); - - rb_link_node(&rbconn->node, parent, rbnode); - rb_insert_color(&rbconn->node, root); - return 1; -} - -static int count_them(struct net *net, - struct xt_connlimit_data *data, - const struct nf_conntrack_tuple *tuple, - const union nf_inet_addr *addr, - u_int8_t family, - const struct nf_conntrack_zone *zone) -{ - struct rb_root *root; - int count; - u32 hash; - - if (family == NFPROTO_IPV6) - hash = connlimit_iphash6(addr); - else - hash = connlimit_iphash(addr->ip); - root = &data->climit_root[hash]; - - spin_lock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]); - - count = count_tree(net, root, tuple, addr, family, zone); - - spin_unlock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]); - - return count; -} +#include static bool connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) { struct net *net = xt_net(par); const struct xt_connlimit_info *info = par->matchinfo; - union nf_inet_addr addr; struct nf_conntrack_tuple tuple; const struct nf_conntrack_tuple *tuple_ptr = &tuple; const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; enum ip_conntrack_info ctinfo; const struct nf_conn *ct; unsigned int connections; + u32 key[5]; ct = nf_ct_get(skb, &ctinfo); if (ct != NULL) { @@ -310,6 +48,7 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) if (xt_family(par) == NFPROTO_IPV6) { const struct ipv6hdr *iph = ipv6_hdr(skb); + union nf_inet_addr addr; unsigned int i; memcpy(&addr.ip6, (info->flags & XT_CONNLIMIT_DADDR) ? @@ -317,22 +56,24 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) for (i = 0; i < ARRAY_SIZE(addr.ip6); ++i) addr.ip6[i] &= info->mask.ip6[i]; + memcpy(key, &addr, sizeof(addr.ip6)); + key[4] = zone->id; } else { const struct iphdr *iph = ip_hdr(skb); - addr.ip = (info->flags & XT_CONNLIMIT_DADDR) ? + key[0] = (info->flags & XT_CONNLIMIT_DADDR) ? iph->daddr : iph->saddr; - addr.ip &= info->mask.ip; + key[0] &= info->mask.ip; + key[1] = zone->id; } - connections = count_them(net, info->data, tuple_ptr, &addr, - xt_family(par), zone); + connections = nf_conncount_count(net, info->data, key, + xt_family(par), tuple_ptr, zone); if (connections == 0) /* kmalloc failed, drop it entirely */ goto hotdrop; - return (connections > info->limit) ^ - !!(info->flags & XT_CONNLIMIT_INVERT); + return (connections > info->limit) ^ !!(info->flags & XT_CONNLIMIT_INVERT); hotdrop: par->hotdrop = true; @@ -342,61 +83,27 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) static int connlimit_mt_check(const struct xt_mtchk_param *par) { struct xt_connlimit_info *info = par->matchinfo; - unsigned int i; - int ret; + unsigned int keylen; - net_get_random_once(&connlimit_rnd, sizeof(connlimit_rnd)); - - ret = nf_ct_netns_get(par->net, par->family); - if (ret < 0) { - pr_info("cannot load conntrack support for " - "address family %u\n", par->family); - return ret; - } + keylen = sizeof(u32); + if (par->family == NFPROTO_IPV6) + keylen += sizeof(struct in6_addr); + else + keylen += sizeof(struct in_addr); /* init private data */ - info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL); - if (info->data == NULL) { - nf_ct_netns_put(par->net, par->family); - return -ENOMEM; - } - - for (i = 0; i < ARRAY_SIZE(info->data->climit_root); ++i) - info->data->climit_root[i] = RB_ROOT; + info->data = nf_conncount_init(par->net, par->family, keylen); + if (IS_ERR(info->data)) + return PTR_ERR(info->data); return 0; } -static void destroy_tree(struct rb_root *r) -{ - struct xt_connlimit_conn *conn; - struct xt_connlimit_rb *rbconn; - struct hlist_node *n; - struct rb_node *node; - - while ((node = rb_first(r)) != NULL) { - rbconn = rb_entry(node, struct xt_connlimit_rb, node); - - rb_erase(node, r); - - hlist_for_each_entry_safe(conn, n, &rbconn->hhead, node) - kmem_cache_free(connlimit_conn_cachep, conn); - - kmem_cache_free(connlimit_rb_cachep, rbconn); - } -} - static void connlimit_mt_destroy(const struct xt_mtdtor_param *par) { const struct xt_connlimit_info *info = par->matchinfo; - unsigned int i; - - nf_ct_netns_put(par->net, par->family); - - for (i = 0; i < ARRAY_SIZE(info->data->climit_root); ++i) - destroy_tree(&info->data->climit_root[i]); - kfree(info->data); + nf_conncount_destroy(par->net, par->family, info->data); } static struct xt_match connlimit_mt_reg __read_mostly = { @@ -413,40 +120,12 @@ static struct xt_match connlimit_mt_reg __read_mostly = { static int __init connlimit_mt_init(void) { - int ret, i; - - BUILD_BUG_ON(CONNLIMIT_LOCK_SLOTS > CONNLIMIT_SLOTS); - BUILD_BUG_ON((CONNLIMIT_SLOTS % CONNLIMIT_LOCK_SLOTS) != 0); - - for (i = 0; i < CONNLIMIT_LOCK_SLOTS; ++i) - spin_lock_init(&xt_connlimit_locks[i]); - - connlimit_conn_cachep = kmem_cache_create("xt_connlimit_conn", - sizeof(struct xt_connlimit_conn), - 0, 0, NULL); - if (!connlimit_conn_cachep) - return -ENOMEM; - - connlimit_rb_cachep = kmem_cache_create("xt_connlimit_rb", - sizeof(struct xt_connlimit_rb), - 0, 0, NULL); - if (!connlimit_rb_cachep) { - kmem_cache_destroy(connlimit_conn_cachep); - return -ENOMEM; - } - ret = xt_register_match(&connlimit_mt_reg); - if (ret != 0) { - kmem_cache_destroy(connlimit_conn_cachep); - kmem_cache_destroy(connlimit_rb_cachep); - } - return ret; + return xt_register_match(&connlimit_mt_reg); } static void __exit connlimit_mt_exit(void) { xt_unregister_match(&connlimit_mt_reg); - kmem_cache_destroy(connlimit_conn_cachep); - kmem_cache_destroy(connlimit_rb_cachep); } module_init(connlimit_mt_init); -- cgit v1.2.3-59-g8ed1b From f6931f5f5b713705c3cc91e4f9c222f2b181e2ef Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Wed, 6 Dec 2017 16:18:16 +0100 Subject: netfilter: meta: secpath support replacement for iptables "-m policy --dir in --policy {ipsec,none}". Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- include/uapi/linux/netfilter/nf_tables.h | 2 ++ net/netfilter/nft_meta.c | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index a3ee277b17a1..2efbf9744c2a 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -777,6 +777,7 @@ enum nft_exthdr_attributes { * @NFT_META_OIFGROUP: packet output interface group * @NFT_META_CGROUP: socket control group (skb->sk->sk_classid) * @NFT_META_PRANDOM: a 32bit pseudo-random number + * @NFT_META_SECPATH: boolean, secpath_exists (!!skb->sp) */ enum nft_meta_keys { NFT_META_LEN, @@ -804,6 +805,7 @@ enum nft_meta_keys { NFT_META_OIFGROUP, NFT_META_CGROUP, NFT_META_PRANDOM, + NFT_META_SECPATH, }; /** diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index 5a60eb23a7ed..1a91e676f13e 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -210,6 +210,11 @@ void nft_meta_get_eval(const struct nft_expr *expr, *dest = prandom_u32_state(state); break; } +#ifdef CONFIG_XFRM + case NFT_META_SECPATH: + nft_reg_store8(dest, !!skb->sp); + break; +#endif default: WARN_ON(1); goto err; @@ -308,6 +313,11 @@ int nft_meta_get_init(const struct nft_ctx *ctx, prandom_init_once(&nft_prandom_state); len = sizeof(u32); break; +#ifdef CONFIG_XFRM + case NFT_META_SECPATH: + len = sizeof(u8); + break; +#endif default: return -EOPNOTSUPP; } @@ -318,6 +328,38 @@ int nft_meta_get_init(const struct nft_ctx *ctx, } EXPORT_SYMBOL_GPL(nft_meta_get_init); +static int nft_meta_get_validate(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nft_data **data) +{ +#ifdef CONFIG_XFRM + const struct nft_meta *priv = nft_expr_priv(expr); + unsigned int hooks; + + if (priv->key != NFT_META_SECPATH) + return 0; + + switch (ctx->afi->family) { + case NFPROTO_NETDEV: + hooks = 1 << NF_NETDEV_INGRESS; + break; + case NFPROTO_IPV4: + case NFPROTO_IPV6: + case NFPROTO_INET: + hooks = (1 << NF_INET_PRE_ROUTING) | + (1 << NF_INET_LOCAL_IN) | + (1 << NF_INET_FORWARD); + break; + default: + return -EOPNOTSUPP; + } + + return nft_chain_validate_hooks(ctx->chain, hooks); +#else + return 0; +#endif +} + int nft_meta_set_validate(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nft_data **data) @@ -434,6 +476,7 @@ static const struct nft_expr_ops nft_meta_get_ops = { .eval = nft_meta_get_eval, .init = nft_meta_get_init, .dump = nft_meta_get_dump, + .validate = nft_meta_get_validate, }; static const struct nft_expr_ops nft_meta_set_ops = { -- cgit v1.2.3-59-g8ed1b From 90964016e5d34758033e75884e41d68ccb93212e Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 7 Jan 2018 01:03:56 +0100 Subject: netfilter: nf_conntrack: add IPS_OFFLOAD status bit This new bit tells us that the conntrack entry is owned by the flow table offload infrastructure. # cat /proc/net/nf_conntrack ipv4 2 tcp 6 src=10.141.10.2 dst=147.75.205.195 sport=36392 dport=443 src=147.75.205.195 dst=192.168.2.195 sport=443 dport=36392 [OFFLOAD] mark=0 zone=0 use=2 Note the [OFFLOAD] tag in the listing. The timer of such conntrack entries look like stopped from userspace. In practise, to make sure the conntrack entry does not go away, the conntrack timer is periodically set to an arbitrary large value that gets refreshed on every iteration from the garbage collector, so it never expires- and they display no internal state in the case of TCP flows. This allows us to save a bitcheck from the packet path via nf_ct_is_expired(). Conntrack entries that have been offloaded to the flow table infrastructure cannot be deleted/flushed via ctnetlink. The flow table infrastructure is also responsible for releasing this conntrack entry. Signed-off-by: Pablo Neira Ayuso --- include/uapi/linux/netfilter/nf_conntrack_common.h | 6 +++++- net/netfilter/nf_conntrack_core.c | 20 ++++++++++++++++++++ net/netfilter/nf_conntrack_netlink.c | 15 ++++++++++++++- net/netfilter/nf_conntrack_proto_tcp.c | 3 +++ net/netfilter/nf_conntrack_standalone.c | 12 ++++++++---- 5 files changed, 50 insertions(+), 6 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/netfilter/nf_conntrack_common.h b/include/uapi/linux/netfilter/nf_conntrack_common.h index 3fea7709a441..fc8c15a24a43 100644 --- a/include/uapi/linux/netfilter/nf_conntrack_common.h +++ b/include/uapi/linux/netfilter/nf_conntrack_common.h @@ -101,12 +101,16 @@ enum ip_conntrack_status { IPS_HELPER_BIT = 13, IPS_HELPER = (1 << IPS_HELPER_BIT), + /* Conntrack has been offloaded to flow table. */ + IPS_OFFLOAD_BIT = 14, + IPS_OFFLOAD = (1 << IPS_OFFLOAD_BIT), + /* Be careful here, modifying these bits can make things messy, * so don't let users modify them directly. */ IPS_UNCHANGEABLE_MASK = (IPS_NAT_DONE_MASK | IPS_NAT_MASK | IPS_EXPECTED | IPS_CONFIRMED | IPS_DYING | - IPS_SEQ_ADJUST | IPS_TEMPLATE), + IPS_SEQ_ADJUST | IPS_TEMPLATE | IPS_OFFLOAD), __IPS_MAX_BIT = 14, }; diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 85f643c1e227..6a64d528d076 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -901,6 +901,9 @@ static unsigned int early_drop_list(struct net *net, hlist_nulls_for_each_entry_rcu(h, n, head, hnnode) { tmp = nf_ct_tuplehash_to_ctrack(h); + if (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) + continue; + if (nf_ct_is_expired(tmp)) { nf_ct_gc_expired(tmp); continue; @@ -975,6 +978,18 @@ static bool gc_worker_can_early_drop(const struct nf_conn *ct) return false; } +#define DAY (86400 * HZ) + +/* Set an arbitrary timeout large enough not to ever expire, this save + * us a check for the IPS_OFFLOAD_BIT from the packet path via + * nf_ct_is_expired(). + */ +static void nf_ct_offload_timeout(struct nf_conn *ct) +{ + if (nf_ct_expires(ct) < DAY / 2) + ct->timeout = nfct_time_stamp + DAY; +} + static void gc_worker(struct work_struct *work) { unsigned int min_interval = max(HZ / GC_MAX_BUCKETS_DIV, 1u); @@ -1011,6 +1026,11 @@ static void gc_worker(struct work_struct *work) tmp = nf_ct_tuplehash_to_ctrack(h); scanned++; + if (test_bit(IPS_OFFLOAD_BIT, &tmp->status)) { + nf_ct_offload_timeout(tmp); + continue; + } + if (nf_ct_is_expired(tmp)) { nf_ct_gc_expired(tmp); expired_count++; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 316bbdc4a158..7c7921a53b13 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1110,6 +1110,14 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = { .len = NF_CT_LABELS_MAX_SIZE }, }; +static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data) +{ + if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) + return 0; + + return ctnetlink_filter_match(ct, data); +} + static int ctnetlink_flush_conntrack(struct net *net, const struct nlattr * const cda[], u32 portid, int report) @@ -1122,7 +1130,7 @@ static int ctnetlink_flush_conntrack(struct net *net, return PTR_ERR(filter); } - nf_ct_iterate_cleanup_net(net, ctnetlink_filter_match, filter, + nf_ct_iterate_cleanup_net(net, ctnetlink_flush_iterate, filter, portid, report); kfree(filter); @@ -1168,6 +1176,11 @@ static int ctnetlink_del_conntrack(struct net *net, struct sock *ctnl, ct = nf_ct_tuplehash_to_ctrack(h); + if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) { + nf_ct_put(ct); + return -EBUSY; + } + if (cda[CTA_ID]) { u_int32_t id = ntohl(nla_get_be32(cda[CTA_ID])); if (id != (u32)(unsigned long)ct) { diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 684cc29010a0..e97cdc1cf98c 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -305,6 +305,9 @@ static bool tcp_invert_tuple(struct nf_conntrack_tuple *tuple, /* Print out the private part of the conntrack. */ static void tcp_print_conntrack(struct seq_file *s, struct nf_conn *ct) { + if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) + return; + seq_printf(s, "%s ", tcp_conntrack_names[ct->proto.tcp.state]); } #endif diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 5a101caa3e12..46d32baad095 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -309,10 +309,12 @@ static int ct_seq_show(struct seq_file *s, void *v) WARN_ON(!l4proto); ret = -ENOSPC; - seq_printf(s, "%-8s %u %-8s %u %ld ", + seq_printf(s, "%-8s %u %-8s %u ", l3proto_name(l3proto->l3proto), nf_ct_l3num(ct), - l4proto_name(l4proto->l4proto), nf_ct_protonum(ct), - nf_ct_expires(ct) / HZ); + l4proto_name(l4proto->l4proto), nf_ct_protonum(ct)); + + if (!test_bit(IPS_OFFLOAD_BIT, &ct->status)) + seq_printf(s, "%ld ", nf_ct_expires(ct) / HZ); if (l4proto->print_conntrack) l4proto->print_conntrack(s, ct); @@ -339,7 +341,9 @@ static int ct_seq_show(struct seq_file *s, void *v) if (seq_print_acct(s, ct, IP_CT_DIR_REPLY)) goto release; - if (test_bit(IPS_ASSURED_BIT, &ct->status)) + if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) + seq_puts(s, "[OFFLOAD] "); + else if (test_bit(IPS_ASSURED_BIT, &ct->status)) seq_puts(s, "[ASSURED] "); if (seq_has_overflowed(s)) -- cgit v1.2.3-59-g8ed1b From 3b49e2e94e6ebb8b23d0955d9e898254455734f8 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 7 Jan 2018 01:04:07 +0100 Subject: netfilter: nf_tables: add flow table netlink frontend This patch introduces a netlink control plane to create, delete and dump flow tables. Flow tables are identified by name, this name is used from rules to refer to an specific flow table. Flow tables use the rhashtable class and a generic garbage collector to remove expired entries. This also adds the infrastructure to add different flow table types, so we can add one for each layer 3 protocol family. Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_flow_table.h | 23 + include/net/netfilter/nf_tables.h | 48 ++ include/uapi/linux/netfilter/nf_tables.h | 53 +++ net/netfilter/nf_tables_api.c | 747 ++++++++++++++++++++++++++++++- 4 files changed, 870 insertions(+), 1 deletion(-) create mode 100644 include/net/netfilter/nf_flow_table.h (limited to 'include/uapi/linux') diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h new file mode 100644 index 000000000000..3a0779589281 --- /dev/null +++ b/include/net/netfilter/nf_flow_table.h @@ -0,0 +1,23 @@ +#ifndef _NF_FLOW_TABLE_H +#define _NF_FLOW_TABLE_H + +#include + +struct nf_flowtable; + +struct nf_flowtable_type { + struct list_head list; + int family; + void (*gc)(struct work_struct *work); + const struct rhashtable_params *params; + nf_hookfn *hook; + struct module *owner; +}; + +struct nf_flowtable { + struct rhashtable rhashtable; + const struct nf_flowtable_type *type; + struct delayed_work gc_work; +}; + +#endif /* _FLOW_OFFLOAD_H */ diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index e3ec02fd0f67..dd238950df81 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #define NFT_JUMP_STACK_SIZE 16 @@ -943,6 +944,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv); * @chains: chains in the table * @sets: sets in the table * @objects: stateful objects in the table + * @flowtables: flow tables in the table * @hgenerator: handle generator state * @use: number of chain references to this table * @flags: table flag (see enum nft_table_flags) @@ -954,6 +956,7 @@ struct nft_table { struct list_head chains; struct list_head sets; struct list_head objects; + struct list_head flowtables; u64 hgenerator; u32 use; u16 flags:14, @@ -1084,6 +1087,44 @@ struct nft_object_ops { int nft_register_obj(struct nft_object_type *obj_type); void nft_unregister_obj(struct nft_object_type *obj_type); +/** + * struct nft_flowtable - nf_tables flow table + * + * @list: flow table list node in table list + * @table: the table the flow table is contained in + * @name: name of this flow table + * @hooknum: hook number + * @priority: hook priority + * @ops_len: number of hooks in array + * @genmask: generation mask + * @use: number of references to this flow table + * @data: rhashtable and garbage collector + * @ops: array of hooks + */ +struct nft_flowtable { + struct list_head list; + struct nft_table *table; + char *name; + int hooknum; + int priority; + int ops_len; + u32 genmask:2, + use:30; + /* runtime data below here */ + struct nf_hook_ops *ops ____cacheline_aligned; + struct nf_flowtable data; +}; + +struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table, + const struct nlattr *nla, + u8 genmask); +void nft_flow_table_iterate(struct net *net, + void (*iter)(struct nf_flowtable *flowtable, void *data), + void *data); + +void nft_register_flowtable_type(struct nf_flowtable_type *type); +void nft_unregister_flowtable_type(struct nf_flowtable_type *type); + /** * struct nft_traceinfo - nft tracing information and state * @@ -1317,4 +1358,11 @@ struct nft_trans_obj { #define nft_trans_obj(trans) \ (((struct nft_trans_obj *)trans->data)->obj) +struct nft_trans_flowtable { + struct nft_flowtable *flowtable; +}; + +#define nft_trans_flowtable(trans) \ + (((struct nft_trans_flowtable *)trans->data)->flowtable) + #endif /* _NET_NF_TABLES_H */ diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 2efbf9744c2a..591b53bce070 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -92,6 +92,9 @@ enum nft_verdicts { * @NFT_MSG_GETOBJ: get a stateful object (enum nft_obj_attributes) * @NFT_MSG_DELOBJ: delete a stateful object (enum nft_obj_attributes) * @NFT_MSG_GETOBJ_RESET: get and reset a stateful object (enum nft_obj_attributes) + * @NFT_MSG_NEWFLOWTABLE: add new flow table (enum nft_flowtable_attributes) + * @NFT_MSG_GETFLOWTABLE: get flow table (enum nft_flowtable_attributes) + * @NFT_MSG_DELFLOWTABLE: delete flow table (enum nft_flowtable_attributes) */ enum nf_tables_msg_types { NFT_MSG_NEWTABLE, @@ -116,6 +119,9 @@ enum nf_tables_msg_types { NFT_MSG_GETOBJ, NFT_MSG_DELOBJ, NFT_MSG_GETOBJ_RESET, + NFT_MSG_NEWFLOWTABLE, + NFT_MSG_GETFLOWTABLE, + NFT_MSG_DELFLOWTABLE, NFT_MSG_MAX, }; @@ -1309,6 +1315,53 @@ enum nft_object_attributes { }; #define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1) +/** + * enum nft_flowtable_attributes - nf_tables flow table netlink attributes + * + * @NFTA_FLOWTABLE_TABLE: name of the table containing the expression (NLA_STRING) + * @NFTA_FLOWTABLE_NAME: name of this flow table (NLA_STRING) + * @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32) + * @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32) + */ +enum nft_flowtable_attributes { + NFTA_FLOWTABLE_UNSPEC, + NFTA_FLOWTABLE_TABLE, + NFTA_FLOWTABLE_NAME, + NFTA_FLOWTABLE_HOOK, + NFTA_FLOWTABLE_USE, + __NFTA_FLOWTABLE_MAX +}; +#define NFTA_FLOWTABLE_MAX (__NFTA_FLOWTABLE_MAX - 1) + +/** + * enum nft_flowtable_hook_attributes - nf_tables flow table hook netlink attributes + * + * @NFTA_FLOWTABLE_HOOK_NUM: netfilter hook number (NLA_U32) + * @NFTA_FLOWTABLE_HOOK_PRIORITY: netfilter hook priority (NLA_U32) + * @NFTA_FLOWTABLE_HOOK_DEVS: input devices this flow table is bound to (NLA_NESTED) + */ +enum nft_flowtable_hook_attributes { + NFTA_FLOWTABLE_HOOK_UNSPEC, + NFTA_FLOWTABLE_HOOK_NUM, + NFTA_FLOWTABLE_HOOK_PRIORITY, + NFTA_FLOWTABLE_HOOK_DEVS, + __NFTA_FLOWTABLE_HOOK_MAX +}; +#define NFTA_FLOWTABLE_HOOK_MAX (__NFTA_FLOWTABLE_HOOK_MAX - 1) + +/** + * enum nft_device_attributes - nf_tables device netlink attributes + * + * @NFTA_DEVICE_NAME: name of this device (NLA_STRING) + */ +enum nft_devices_attributes { + NFTA_DEVICE_UNSPEC, + NFTA_DEVICE_NAME, + __NFTA_DEVICE_MAX +}; +#define NFTA_DEVICE_MAX (__NFTA_DEVICE_MAX - 1) + + /** * enum nft_trace_attributes - nf_tables trace netlink attributes * diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index fa564dac66a2..db0933256ec9 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,7 @@ static LIST_HEAD(nf_tables_expressions); static LIST_HEAD(nf_tables_objects); +static LIST_HEAD(nf_tables_flowtables); /** * nft_register_afinfo - register nf_tables address family info @@ -345,6 +347,40 @@ static int nft_delobj(struct nft_ctx *ctx, struct nft_object *obj) return err; } +static int nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type, + struct nft_flowtable *flowtable) +{ + struct nft_trans *trans; + + trans = nft_trans_alloc(ctx, msg_type, + sizeof(struct nft_trans_flowtable)); + if (trans == NULL) + return -ENOMEM; + + if (msg_type == NFT_MSG_NEWFLOWTABLE) + nft_activate_next(ctx->net, flowtable); + + nft_trans_flowtable(trans) = flowtable; + list_add_tail(&trans->list, &ctx->net->nft.commit_list); + + return 0; +} + +static int nft_delflowtable(struct nft_ctx *ctx, + struct nft_flowtable *flowtable) +{ + int err; + + err = nft_trans_flowtable_add(ctx, NFT_MSG_DELFLOWTABLE, flowtable); + if (err < 0) + return err; + + nft_deactivate_next(ctx->net, flowtable); + ctx->table->use--; + + return err; +} + /* * Tables */ @@ -728,6 +764,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk, INIT_LIST_HEAD(&table->chains); INIT_LIST_HEAD(&table->sets); INIT_LIST_HEAD(&table->objects); + INIT_LIST_HEAD(&table->flowtables); table->flags = flags; nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); @@ -749,10 +786,11 @@ err1: static int nft_flush_table(struct nft_ctx *ctx) { - int err; + struct nft_flowtable *flowtable, *nft; struct nft_chain *chain, *nc; struct nft_object *obj, *ne; struct nft_set *set, *ns; + int err; list_for_each_entry(chain, &ctx->table->chains, list) { if (!nft_is_active_next(ctx->net, chain)) @@ -778,6 +816,12 @@ static int nft_flush_table(struct nft_ctx *ctx) goto out; } + list_for_each_entry_safe(flowtable, nft, &ctx->table->flowtables, list) { + err = nft_delflowtable(ctx, flowtable); + if (err < 0) + goto out; + } + list_for_each_entry_safe(obj, ne, &ctx->table->objects, list) { err = nft_delobj(ctx, obj); if (err < 0) @@ -4839,6 +4883,605 @@ static void nf_tables_obj_notify(const struct nft_ctx *ctx, ctx->afi->family, ctx->report, GFP_KERNEL); } +/* + * Flow tables + */ +void nft_register_flowtable_type(struct nf_flowtable_type *type) +{ + nfnl_lock(NFNL_SUBSYS_NFTABLES); + list_add_tail_rcu(&type->list, &nf_tables_flowtables); + nfnl_unlock(NFNL_SUBSYS_NFTABLES); +} +EXPORT_SYMBOL_GPL(nft_register_flowtable_type); + +void nft_unregister_flowtable_type(struct nf_flowtable_type *type) +{ + nfnl_lock(NFNL_SUBSYS_NFTABLES); + list_del_rcu(&type->list); + nfnl_unlock(NFNL_SUBSYS_NFTABLES); +} +EXPORT_SYMBOL_GPL(nft_unregister_flowtable_type); + +static const struct nla_policy nft_flowtable_policy[NFTA_FLOWTABLE_MAX + 1] = { + [NFTA_FLOWTABLE_TABLE] = { .type = NLA_STRING, + .len = NFT_NAME_MAXLEN - 1 }, + [NFTA_FLOWTABLE_NAME] = { .type = NLA_STRING, + .len = NFT_NAME_MAXLEN - 1 }, + [NFTA_FLOWTABLE_HOOK] = { .type = NLA_NESTED }, +}; + +struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table, + const struct nlattr *nla, + u8 genmask) +{ + struct nft_flowtable *flowtable; + + list_for_each_entry(flowtable, &table->flowtables, list) { + if (!nla_strcmp(nla, flowtable->name) && + nft_active_genmask(flowtable, genmask)) + return flowtable; + } + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL_GPL(nf_tables_flowtable_lookup); + +#define NFT_FLOWTABLE_DEVICE_MAX 8 + +static int nf_tables_parse_devices(const struct nft_ctx *ctx, + const struct nlattr *attr, + struct net_device *dev_array[], int *len) +{ + const struct nlattr *tmp; + struct net_device *dev; + char ifname[IFNAMSIZ]; + int rem, n = 0, err; + + nla_for_each_nested(tmp, attr, rem) { + if (nla_type(tmp) != NFTA_DEVICE_NAME) { + err = -EINVAL; + goto err1; + } + + nla_strlcpy(ifname, tmp, IFNAMSIZ); + dev = dev_get_by_name(ctx->net, ifname); + if (!dev) { + err = -ENOENT; + goto err1; + } + + dev_array[n++] = dev; + if (n == NFT_FLOWTABLE_DEVICE_MAX) { + err = -EFBIG; + goto err1; + } + } + if (!len) + return -EINVAL; + + err = 0; +err1: + *len = n; + return err; +} + +static const struct nla_policy nft_flowtable_hook_policy[NFTA_FLOWTABLE_HOOK_MAX + 1] = { + [NFTA_FLOWTABLE_HOOK_NUM] = { .type = NLA_U32 }, + [NFTA_FLOWTABLE_HOOK_PRIORITY] = { .type = NLA_U32 }, + [NFTA_FLOWTABLE_HOOK_DEVS] = { .type = NLA_NESTED }, +}; + +static int nf_tables_flowtable_parse_hook(const struct nft_ctx *ctx, + const struct nlattr *attr, + struct nft_flowtable *flowtable) +{ + struct net_device *dev_array[NFT_FLOWTABLE_DEVICE_MAX]; + struct nlattr *tb[NFTA_FLOWTABLE_HOOK_MAX + 1]; + struct nf_hook_ops *ops; + int hooknum, priority; + int err, n = 0, i; + + err = nla_parse_nested(tb, NFTA_FLOWTABLE_HOOK_MAX, attr, + nft_flowtable_hook_policy, NULL); + if (err < 0) + return err; + + if (!tb[NFTA_FLOWTABLE_HOOK_NUM] || + !tb[NFTA_FLOWTABLE_HOOK_PRIORITY] || + !tb[NFTA_FLOWTABLE_HOOK_DEVS]) + return -EINVAL; + + hooknum = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_NUM])); + if (hooknum >= ctx->afi->nhooks) + return -EINVAL; + + priority = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_PRIORITY])); + + err = nf_tables_parse_devices(ctx, tb[NFTA_FLOWTABLE_HOOK_DEVS], + dev_array, &n); + if (err < 0) + goto err1; + + ops = kzalloc(sizeof(struct nf_hook_ops) * n, GFP_KERNEL); + if (!ops) { + err = -ENOMEM; + goto err1; + } + + flowtable->ops = ops; + flowtable->ops_len = n; + + for (i = 0; i < n; i++) { + flowtable->ops[i].pf = NFPROTO_NETDEV; + flowtable->ops[i].hooknum = hooknum; + flowtable->ops[i].priority = priority; + flowtable->ops[i].priv = &flowtable->data.rhashtable; + flowtable->ops[i].hook = flowtable->data.type->hook; + flowtable->ops[i].dev = dev_array[i]; + } + + err = 0; +err1: + for (i = 0; i < n; i++) + dev_put(dev_array[i]); + + return err; +} + +static const struct nf_flowtable_type * +__nft_flowtable_type_get(const struct nft_af_info *afi) +{ + const struct nf_flowtable_type *type; + + list_for_each_entry(type, &nf_tables_flowtables, list) { + if (afi->family == type->family) + return type; + } + return NULL; +} + +static const struct nf_flowtable_type * +nft_flowtable_type_get(const struct nft_af_info *afi) +{ + const struct nf_flowtable_type *type; + + type = __nft_flowtable_type_get(afi); + if (type != NULL && try_module_get(type->owner)) + return type; + +#ifdef CONFIG_MODULES + if (type == NULL) { + nfnl_unlock(NFNL_SUBSYS_NFTABLES); + request_module("nf-flowtable-%u", afi->family); + nfnl_lock(NFNL_SUBSYS_NFTABLES); + if (__nft_flowtable_type_get(afi)) + return ERR_PTR(-EAGAIN); + } +#endif + return ERR_PTR(-ENOENT); +} + +void nft_flow_table_iterate(struct net *net, + void (*iter)(struct nf_flowtable *flowtable, void *data), + void *data) +{ + struct nft_flowtable *flowtable; + const struct nft_af_info *afi; + const struct nft_table *table; + + rcu_read_lock(); + list_for_each_entry_rcu(afi, &net->nft.af_info, list) { + list_for_each_entry_rcu(table, &afi->tables, list) { + list_for_each_entry_rcu(flowtable, &table->flowtables, list) { + iter(&flowtable->data, data); + } + } + } + rcu_read_unlock(); +} +EXPORT_SYMBOL_GPL(nft_flow_table_iterate); + +static void nft_unregister_flowtable_net_hooks(struct net *net, + struct nft_flowtable *flowtable) +{ + int i; + + for (i = 0; i < flowtable->ops_len; i++) { + if (!flowtable->ops[i].dev) + continue; + + nf_unregister_net_hook(net, &flowtable->ops[i]); + } +} + +static int nf_tables_newflowtable(struct net *net, struct sock *nlsk, + struct sk_buff *skb, + const struct nlmsghdr *nlh, + const struct nlattr * const nla[], + struct netlink_ext_ack *extack) +{ + const struct nfgenmsg *nfmsg = nlmsg_data(nlh); + const struct nf_flowtable_type *type; + u8 genmask = nft_genmask_next(net); + int family = nfmsg->nfgen_family; + struct nft_flowtable *flowtable; + struct nft_af_info *afi; + struct nft_table *table; + struct nft_ctx ctx; + int err, i, k; + + if (!nla[NFTA_FLOWTABLE_TABLE] || + !nla[NFTA_FLOWTABLE_NAME] || + !nla[NFTA_FLOWTABLE_HOOK]) + return -EINVAL; + + afi = nf_tables_afinfo_lookup(net, family, true); + if (IS_ERR(afi)) + return PTR_ERR(afi); + + table = nf_tables_table_lookup(afi, nla[NFTA_FLOWTABLE_TABLE], genmask); + if (IS_ERR(table)) + return PTR_ERR(table); + + flowtable = nf_tables_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME], + genmask); + if (IS_ERR(flowtable)) { + err = PTR_ERR(flowtable); + if (err != -ENOENT) + return err; + } else { + if (nlh->nlmsg_flags & NLM_F_EXCL) + return -EEXIST; + + return 0; + } + + nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); + + flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL); + if (!flowtable) + return -ENOMEM; + + flowtable->table = table; + flowtable->name = nla_strdup(nla[NFTA_FLOWTABLE_NAME], GFP_KERNEL); + if (!flowtable->name) { + err = -ENOMEM; + goto err1; + } + + type = nft_flowtable_type_get(afi); + if (IS_ERR(type)) { + err = PTR_ERR(type); + goto err2; + } + + flowtable->data.type = type; + err = rhashtable_init(&flowtable->data.rhashtable, type->params); + if (err < 0) + goto err3; + + err = nf_tables_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK], + flowtable); + if (err < 0) + goto err3; + + for (i = 0; i < flowtable->ops_len; i++) { + err = nf_register_net_hook(net, &flowtable->ops[i]); + if (err < 0) + goto err4; + } + + err = nft_trans_flowtable_add(&ctx, NFT_MSG_NEWFLOWTABLE, flowtable); + if (err < 0) + goto err5; + + INIT_DEFERRABLE_WORK(&flowtable->data.gc_work, type->gc); + queue_delayed_work(system_power_efficient_wq, + &flowtable->data.gc_work, HZ); + + list_add_tail_rcu(&flowtable->list, &table->flowtables); + table->use++; + + return 0; +err5: + i = flowtable->ops_len; +err4: + for (k = i - 1; k >= 0; k--) + nf_unregister_net_hook(net, &flowtable->ops[i]); + + kfree(flowtable->ops); +err3: + module_put(type->owner); +err2: + kfree(flowtable->name); +err1: + kfree(flowtable); + return err; +} + +static int nf_tables_delflowtable(struct net *net, struct sock *nlsk, + struct sk_buff *skb, + const struct nlmsghdr *nlh, + const struct nlattr * const nla[], + struct netlink_ext_ack *extack) +{ + const struct nfgenmsg *nfmsg = nlmsg_data(nlh); + u8 genmask = nft_genmask_next(net); + int family = nfmsg->nfgen_family; + struct nft_flowtable *flowtable; + struct nft_af_info *afi; + struct nft_table *table; + struct nft_ctx ctx; + + afi = nf_tables_afinfo_lookup(net, family, true); + if (IS_ERR(afi)) + return PTR_ERR(afi); + + table = nf_tables_table_lookup(afi, nla[NFTA_FLOWTABLE_TABLE], genmask); + if (IS_ERR(table)) + return PTR_ERR(table); + + flowtable = nf_tables_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME], + genmask); + if (IS_ERR(flowtable)) + return PTR_ERR(flowtable); + if (flowtable->use > 0) + return -EBUSY; + + nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); + + return nft_delflowtable(&ctx, flowtable); +} + +static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net, + u32 portid, u32 seq, int event, + u32 flags, int family, + struct nft_flowtable *flowtable) +{ + struct nlattr *nest, *nest_devs; + struct nfgenmsg *nfmsg; + struct nlmsghdr *nlh; + int i; + + event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event); + nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags); + if (nlh == NULL) + goto nla_put_failure; + + nfmsg = nlmsg_data(nlh); + nfmsg->nfgen_family = family; + nfmsg->version = NFNETLINK_V0; + nfmsg->res_id = htons(net->nft.base_seq & 0xffff); + + if (nla_put_string(skb, NFTA_FLOWTABLE_TABLE, flowtable->table->name) || + nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) || + nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use))) + goto nla_put_failure; + + nest = nla_nest_start(skb, NFTA_FLOWTABLE_HOOK); + if (nla_put_be32(skb, NFTA_FLOWTABLE_HOOK_NUM, htonl(flowtable->hooknum)) || + nla_put_be32(skb, NFTA_FLOWTABLE_HOOK_PRIORITY, htonl(flowtable->priority))) + goto nla_put_failure; + + nest_devs = nla_nest_start(skb, NFTA_FLOWTABLE_HOOK_DEVS); + if (!nest_devs) + goto nla_put_failure; + + for (i = 0; i < flowtable->ops_len; i++) { + if (flowtable->ops[i].dev && + nla_put_string(skb, NFTA_DEVICE_NAME, + flowtable->ops[i].dev->name)) + goto nla_put_failure; + } + nla_nest_end(skb, nest_devs); + nla_nest_end(skb, nest); + + nlmsg_end(skb, nlh); + return 0; + +nla_put_failure: + nlmsg_trim(skb, nlh); + return -1; +} + +struct nft_flowtable_filter { + char *table; +}; + +static int nf_tables_dump_flowtable(struct sk_buff *skb, + struct netlink_callback *cb) +{ + const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); + struct nft_flowtable_filter *filter = cb->data; + unsigned int idx = 0, s_idx = cb->args[0]; + struct net *net = sock_net(skb->sk); + int family = nfmsg->nfgen_family; + struct nft_flowtable *flowtable; + const struct nft_af_info *afi; + const struct nft_table *table; + + rcu_read_lock(); + cb->seq = net->nft.base_seq; + + list_for_each_entry_rcu(afi, &net->nft.af_info, list) { + if (family != NFPROTO_UNSPEC && family != afi->family) + continue; + + list_for_each_entry_rcu(table, &afi->tables, list) { + list_for_each_entry_rcu(flowtable, &table->flowtables, list) { + if (!nft_is_active(net, flowtable)) + goto cont; + if (idx < s_idx) + goto cont; + if (idx > s_idx) + memset(&cb->args[1], 0, + sizeof(cb->args) - sizeof(cb->args[0])); + if (filter && filter->table[0] && + strcmp(filter->table, table->name)) + goto cont; + + if (nf_tables_fill_flowtable_info(skb, net, NETLINK_CB(cb->skb).portid, + cb->nlh->nlmsg_seq, + NFT_MSG_NEWFLOWTABLE, + NLM_F_MULTI | NLM_F_APPEND, + afi->family, flowtable) < 0) + goto done; + + nl_dump_check_consistent(cb, nlmsg_hdr(skb)); +cont: + idx++; + } + } + } +done: + rcu_read_unlock(); + + cb->args[0] = idx; + return skb->len; +} + +static int nf_tables_dump_flowtable_done(struct netlink_callback *cb) +{ + struct nft_flowtable_filter *filter = cb->data; + + if (!filter) + return 0; + + kfree(filter->table); + kfree(filter); + + return 0; +} + +static struct nft_flowtable_filter * +nft_flowtable_filter_alloc(const struct nlattr * const nla[]) +{ + struct nft_flowtable_filter *filter; + + filter = kzalloc(sizeof(*filter), GFP_KERNEL); + if (!filter) + return ERR_PTR(-ENOMEM); + + if (nla[NFTA_FLOWTABLE_TABLE]) { + filter->table = nla_strdup(nla[NFTA_FLOWTABLE_TABLE], + GFP_KERNEL); + if (!filter->table) { + kfree(filter); + return ERR_PTR(-ENOMEM); + } + } + return filter; +} + +static int nf_tables_getflowtable(struct net *net, struct sock *nlsk, + struct sk_buff *skb, + const struct nlmsghdr *nlh, + const struct nlattr * const nla[], + struct netlink_ext_ack *extack) +{ + const struct nfgenmsg *nfmsg = nlmsg_data(nlh); + u8 genmask = nft_genmask_cur(net); + int family = nfmsg->nfgen_family; + struct nft_flowtable *flowtable; + const struct nft_af_info *afi; + const struct nft_table *table; + struct sk_buff *skb2; + int err; + + if (nlh->nlmsg_flags & NLM_F_DUMP) { + struct netlink_dump_control c = { + .dump = nf_tables_dump_flowtable, + .done = nf_tables_dump_flowtable_done, + }; + + if (nla[NFTA_FLOWTABLE_TABLE]) { + struct nft_flowtable_filter *filter; + + filter = nft_flowtable_filter_alloc(nla); + if (IS_ERR(filter)) + return -ENOMEM; + + c.data = filter; + } + return netlink_dump_start(nlsk, skb, nlh, &c); + } + + if (!nla[NFTA_FLOWTABLE_NAME]) + return -EINVAL; + + afi = nf_tables_afinfo_lookup(net, family, false); + if (IS_ERR(afi)) + return PTR_ERR(afi); + + table = nf_tables_table_lookup(afi, nla[NFTA_FLOWTABLE_TABLE], genmask); + if (IS_ERR(table)) + return PTR_ERR(table); + + flowtable = nf_tables_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME], + genmask); + if (IS_ERR(table)) + return PTR_ERR(flowtable); + + skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb2) + return -ENOMEM; + + err = nf_tables_fill_flowtable_info(skb2, net, NETLINK_CB(skb).portid, + nlh->nlmsg_seq, + NFT_MSG_NEWFLOWTABLE, 0, family, + flowtable); + if (err < 0) + goto err; + + return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid); +err: + kfree_skb(skb2); + return err; +} + +static void nf_tables_flowtable_notify(struct nft_ctx *ctx, + struct nft_flowtable *flowtable, + int event) +{ + struct sk_buff *skb; + int err; + + if (ctx->report && + !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES)) + return; + + skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (skb == NULL) + goto err; + + err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid, + ctx->seq, event, 0, + ctx->afi->family, flowtable); + if (err < 0) { + kfree_skb(skb); + goto err; + } + + nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES, + ctx->report, GFP_KERNEL); + return; +err: + nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS); +} + +static void nft_flowtable_destroy(void *ptr, void *arg) +{ + kfree(ptr); +} + +static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable) +{ + cancel_delayed_work_sync(&flowtable->data.gc_work); + kfree(flowtable->name); + rhashtable_free_and_destroy(&flowtable->data.rhashtable, + nft_flowtable_destroy, NULL); + module_put(flowtable->data.type->owner); +} + static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net, u32 portid, u32 seq) { @@ -4869,6 +5512,49 @@ nla_put_failure: return -EMSGSIZE; } +static void nft_flowtable_event(unsigned long event, struct net_device *dev, + struct nft_flowtable *flowtable) +{ + int i; + + for (i = 0; i < flowtable->ops_len; i++) { + if (flowtable->ops[i].dev != dev) + continue; + + nf_unregister_net_hook(dev_net(dev), &flowtable->ops[i]); + flowtable->ops[i].dev = NULL; + break; + } +} + +static int nf_tables_flowtable_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct nft_flowtable *flowtable; + struct nft_table *table; + struct nft_af_info *afi; + + if (event != NETDEV_UNREGISTER) + return 0; + + nfnl_lock(NFNL_SUBSYS_NFTABLES); + list_for_each_entry(afi, &dev_net(dev)->nft.af_info, list) { + list_for_each_entry(table, &afi->tables, list) { + list_for_each_entry(flowtable, &table->flowtables, list) { + nft_flowtable_event(event, dev, flowtable); + } + } + } + nfnl_unlock(NFNL_SUBSYS_NFTABLES); + + return NOTIFY_DONE; +} + +static struct notifier_block nf_tables_flowtable_notifier = { + .notifier_call = nf_tables_flowtable_event, +}; + static void nf_tables_gen_notify(struct net *net, struct sk_buff *skb, int event) { @@ -5021,6 +5707,21 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { .attr_count = NFTA_OBJ_MAX, .policy = nft_obj_policy, }, + [NFT_MSG_NEWFLOWTABLE] = { + .call_batch = nf_tables_newflowtable, + .attr_count = NFTA_FLOWTABLE_MAX, + .policy = nft_flowtable_policy, + }, + [NFT_MSG_GETFLOWTABLE] = { + .call = nf_tables_getflowtable, + .attr_count = NFTA_FLOWTABLE_MAX, + .policy = nft_flowtable_policy, + }, + [NFT_MSG_DELFLOWTABLE] = { + .call_batch = nf_tables_delflowtable, + .attr_count = NFTA_FLOWTABLE_MAX, + .policy = nft_flowtable_policy, + }, }; static void nft_chain_commit_update(struct nft_trans *trans) @@ -5066,6 +5767,9 @@ static void nf_tables_commit_release(struct nft_trans *trans) case NFT_MSG_DELOBJ: nft_obj_destroy(nft_trans_obj(trans)); break; + case NFT_MSG_DELFLOWTABLE: + nf_tables_flowtable_destroy(nft_trans_flowtable(trans)); + break; } kfree(trans); } @@ -5183,6 +5887,21 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans), NFT_MSG_DELOBJ); break; + case NFT_MSG_NEWFLOWTABLE: + nft_clear(net, nft_trans_flowtable(trans)); + nf_tables_flowtable_notify(&trans->ctx, + nft_trans_flowtable(trans), + NFT_MSG_NEWFLOWTABLE); + nft_trans_destroy(trans); + break; + case NFT_MSG_DELFLOWTABLE: + list_del_rcu(&nft_trans_flowtable(trans)->list); + nf_tables_flowtable_notify(&trans->ctx, + nft_trans_flowtable(trans), + NFT_MSG_DELFLOWTABLE); + nft_unregister_flowtable_net_hooks(net, + nft_trans_flowtable(trans)); + break; } } @@ -5220,6 +5939,9 @@ static void nf_tables_abort_release(struct nft_trans *trans) case NFT_MSG_NEWOBJ: nft_obj_destroy(nft_trans_obj(trans)); break; + case NFT_MSG_NEWFLOWTABLE: + nf_tables_flowtable_destroy(nft_trans_flowtable(trans)); + break; } kfree(trans); } @@ -5309,6 +6031,17 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb) nft_clear(trans->ctx.net, nft_trans_obj(trans)); nft_trans_destroy(trans); break; + case NFT_MSG_NEWFLOWTABLE: + trans->ctx.table->use--; + list_del_rcu(&nft_trans_flowtable(trans)->list); + nft_unregister_flowtable_net_hooks(net, + nft_trans_flowtable(trans)); + break; + case NFT_MSG_DELFLOWTABLE: + trans->ctx.table->use++; + nft_clear(trans->ctx.net, nft_trans_flowtable(trans)); + nft_trans_destroy(trans); + break; } } @@ -5865,6 +6598,7 @@ EXPORT_SYMBOL_GPL(__nft_release_basechain); /* Called by nft_unregister_afinfo() from __net_exit path, nfnl_lock is held. */ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi) { + struct nft_flowtable *flowtable, *nf; struct nft_table *table, *nt; struct nft_chain *chain, *nc; struct nft_object *obj, *ne; @@ -5878,6 +6612,9 @@ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi) list_for_each_entry_safe(table, nt, &afi->tables, list) { list_for_each_entry(chain, &table->chains, list) nf_tables_unregister_hook(net, table, chain); + list_for_each_entry(flowtable, &table->flowtables, list) + nf_unregister_net_hooks(net, flowtable->ops, + flowtable->ops_len); /* No packets are walking on these chains anymore. */ ctx.table = table; list_for_each_entry(chain, &table->chains, list) { @@ -5888,6 +6625,11 @@ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi) nf_tables_rule_destroy(&ctx, rule); } } + list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) { + list_del(&flowtable->list); + table->use--; + nf_tables_flowtable_destroy(flowtable); + } list_for_each_entry_safe(set, ns, &table->sets, list) { list_del(&set->list); table->use--; @@ -5932,6 +6674,8 @@ static int __init nf_tables_module_init(void) if (err < 0) goto err3; + register_netdevice_notifier(&nf_tables_flowtable_notifier); + pr_info("nf_tables: (c) 2007-2009 Patrick McHardy \n"); return register_pernet_subsys(&nf_tables_net_ops); err3: @@ -5946,6 +6690,7 @@ static void __exit nf_tables_module_exit(void) { unregister_pernet_subsys(&nf_tables_net_ops); nfnetlink_subsys_unregister(&nf_tables_subsys); + unregister_netdevice_notifier(&nf_tables_flowtable_notifier); rcu_barrier(); nf_tables_core_module_exit(); kfree(info); -- cgit v1.2.3-59-g8ed1b From a3c90f7a2323b331ae816d5b0633e68148e25d04 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 7 Jan 2018 01:04:26 +0100 Subject: netfilter: nf_tables: flow offload expression Add new instruction for the nf_tables VM that allows us to specify what flows are offloaded into a given flow table via name. This new instruction creates the flow entry and adds it to the flow table. Only established flows, ie. we have seen traffic in both directions, are added to the flow table. You can still decide to offload entries at a later stage via packet counting or checking the ct status in case you want to offload assured conntracks. This new extension depends on the conntrack subsystem. Signed-off-by: Pablo Neira Ayuso --- include/uapi/linux/netfilter/nf_tables.h | 11 ++ net/netfilter/Kconfig | 7 + net/netfilter/Makefile | 1 + net/netfilter/nft_flow_offload.c | 264 +++++++++++++++++++++++++++++++ 4 files changed, 283 insertions(+) create mode 100644 net/netfilter/nft_flow_offload.c (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 591b53bce070..53e8dd2a3a03 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -957,6 +957,17 @@ enum nft_ct_attributes { }; #define NFTA_CT_MAX (__NFTA_CT_MAX - 1) +/** + * enum nft_flow_attributes - ct offload expression attributes + * @NFTA_FLOW_TABLE_NAME: flow table name (NLA_STRING) + */ +enum nft_offload_attributes { + NFTA_FLOW_UNSPEC, + NFTA_FLOW_TABLE_NAME, + __NFTA_FLOW_MAX, +}; +#define NFTA_FLOW_MAX (__NFTA_FLOW_MAX - 1) + enum nft_limit_type { NFT_LIMIT_PKTS, NFT_LIMIT_PKT_BYTES diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 272803079bf2..0ee0fcf3abbf 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -505,6 +505,13 @@ config NFT_CT This option adds the "ct" expression that you can use to match connection tracking information such as the flow state. +config NFT_FLOW_OFFLOAD + depends on NF_CONNTRACK + tristate "Netfilter nf_tables hardware flow offload module" + help + This option adds the "flow_offload" expression that you can use to + choose what flows are placed into the hardware. + config NFT_SET_RBTREE tristate "Netfilter nf_tables rbtree set module" help diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 061365875cde..5d9b8b959e58 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -86,6 +86,7 @@ obj-$(CONFIG_NFT_META) += nft_meta.o obj-$(CONFIG_NFT_RT) += nft_rt.o obj-$(CONFIG_NFT_NUMGEN) += nft_numgen.o obj-$(CONFIG_NFT_CT) += nft_ct.o +obj-$(CONFIG_NFT_FLOW_OFFLOAD) += nft_flow_offload.o obj-$(CONFIG_NFT_LIMIT) += nft_limit.o obj-$(CONFIG_NFT_NAT) += nft_nat.o obj-$(CONFIG_NFT_OBJREF) += nft_objref.o diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c new file mode 100644 index 000000000000..dd38785dfed9 --- /dev/null +++ b/net/netfilter/nft_flow_offload.c @@ -0,0 +1,264 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for ipv4 options. */ +#include +#include +#include +#include +#include + +struct nft_flow_offload { + struct nft_flowtable *flowtable; +}; + +static int nft_flow_route(const struct nft_pktinfo *pkt, + const struct nf_conn *ct, + struct nf_flow_route *route, + enum ip_conntrack_dir dir) +{ + struct dst_entry *this_dst = skb_dst(pkt->skb); + struct dst_entry *other_dst = NULL; + struct flowi fl; + + memset(&fl, 0, sizeof(fl)); + switch (nft_pf(pkt)) { + case NFPROTO_IPV4: + fl.u.ip4.daddr = ct->tuplehash[!dir].tuple.dst.u3.ip; + break; + case NFPROTO_IPV6: + fl.u.ip6.daddr = ct->tuplehash[!dir].tuple.dst.u3.in6; + break; + } + + nf_route(nft_net(pkt), &other_dst, &fl, false, nft_pf(pkt)); + if (!other_dst) + return -ENOENT; + + route->tuple[dir].dst = this_dst; + route->tuple[dir].ifindex = nft_in(pkt)->ifindex; + route->tuple[!dir].dst = other_dst; + route->tuple[!dir].ifindex = nft_out(pkt)->ifindex; + + return 0; +} + +static bool nft_flow_offload_skip(struct sk_buff *skb) +{ + struct ip_options *opt = &(IPCB(skb)->opt); + + if (unlikely(opt->optlen)) + return true; + if (skb_sec_path(skb)) + return true; + + return false; +} + +static void nft_flow_offload_eval(const struct nft_expr *expr, + struct nft_regs *regs, + const struct nft_pktinfo *pkt) +{ + struct nft_flow_offload *priv = nft_expr_priv(expr); + struct nf_flowtable *flowtable = &priv->flowtable->data; + enum ip_conntrack_info ctinfo; + struct nf_flow_route route; + struct flow_offload *flow; + enum ip_conntrack_dir dir; + struct nf_conn *ct; + int ret; + + if (nft_flow_offload_skip(pkt->skb)) + goto out; + + ct = nf_ct_get(pkt->skb, &ctinfo); + if (!ct) + goto out; + + switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) { + case IPPROTO_TCP: + case IPPROTO_UDP: + break; + default: + goto out; + } + + if (test_bit(IPS_HELPER_BIT, &ct->status)) + goto out; + + if (ctinfo == IP_CT_NEW || + ctinfo == IP_CT_RELATED) + goto out; + + if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status)) + goto out; + + dir = CTINFO2DIR(ctinfo); + if (nft_flow_route(pkt, ct, &route, dir) < 0) + goto err_flow_route; + + flow = flow_offload_alloc(ct, &route); + if (!flow) + goto err_flow_alloc; + + ret = flow_offload_add(flowtable, flow); + if (ret < 0) + goto err_flow_add; + + return; + +err_flow_add: + flow_offload_free(flow); +err_flow_alloc: + dst_release(route.tuple[!dir].dst); +err_flow_route: + clear_bit(IPS_OFFLOAD_BIT, &ct->status); +out: + regs->verdict.code = NFT_BREAK; +} + +static int nft_flow_offload_validate(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nft_data **data) +{ + unsigned int hook_mask = (1 << NF_INET_FORWARD); + + return nft_chain_validate_hooks(ctx->chain, hook_mask); +} + +static int nft_flow_offload_init(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nlattr * const tb[]) +{ + struct nft_flow_offload *priv = nft_expr_priv(expr); + u8 genmask = nft_genmask_next(ctx->net); + struct nft_flowtable *flowtable; + + if (!tb[NFTA_FLOW_TABLE_NAME]) + return -EINVAL; + + flowtable = nf_tables_flowtable_lookup(ctx->table, + tb[NFTA_FLOW_TABLE_NAME], + genmask); + if (IS_ERR(flowtable)) + return PTR_ERR(flowtable); + + priv->flowtable = flowtable; + flowtable->use++; + + return nf_ct_netns_get(ctx->net, ctx->afi->family); +} + +static void nft_flow_offload_destroy(const struct nft_ctx *ctx, + const struct nft_expr *expr) +{ + struct nft_flow_offload *priv = nft_expr_priv(expr); + + priv->flowtable->use--; + nf_ct_netns_put(ctx->net, ctx->afi->family); +} + +static int nft_flow_offload_dump(struct sk_buff *skb, const struct nft_expr *expr) +{ + struct nft_flow_offload *priv = nft_expr_priv(expr); + + if (nla_put_string(skb, NFTA_FLOW_TABLE_NAME, priv->flowtable->name)) + goto nla_put_failure; + + return 0; + +nla_put_failure: + return -1; +} + +static struct nft_expr_type nft_flow_offload_type; +static const struct nft_expr_ops nft_flow_offload_ops = { + .type = &nft_flow_offload_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_flow_offload)), + .eval = nft_flow_offload_eval, + .init = nft_flow_offload_init, + .destroy = nft_flow_offload_destroy, + .validate = nft_flow_offload_validate, + .dump = nft_flow_offload_dump, +}; + +static struct nft_expr_type nft_flow_offload_type __read_mostly = { + .name = "flow_offload", + .ops = &nft_flow_offload_ops, + .maxattr = NFTA_FLOW_MAX, + .owner = THIS_MODULE, +}; + +static void flow_offload_iterate_cleanup(struct flow_offload *flow, void *data) +{ + struct net_device *dev = data; + + if (dev && flow->tuplehash[0].tuple.iifidx != dev->ifindex) + return; + + flow_offload_dead(flow); +} + +static void nft_flow_offload_iterate_cleanup(struct nf_flowtable *flowtable, + void *data) +{ + nf_flow_table_iterate(flowtable, flow_offload_iterate_cleanup, data); +} + +static int flow_offload_netdev_event(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct net_device *dev = netdev_notifier_info_to_dev(ptr); + + if (event != NETDEV_DOWN) + return NOTIFY_DONE; + + nft_flow_table_iterate(dev_net(dev), nft_flow_offload_iterate_cleanup, dev); + + return NOTIFY_DONE; +} + +static struct notifier_block flow_offload_netdev_notifier = { + .notifier_call = flow_offload_netdev_event, +}; + +static int __init nft_flow_offload_module_init(void) +{ + int err; + + register_netdevice_notifier(&flow_offload_netdev_notifier); + + err = nft_register_expr(&nft_flow_offload_type); + if (err < 0) + goto register_expr; + + return 0; + +register_expr: + unregister_netdevice_notifier(&flow_offload_netdev_notifier); + return err; +} + +static void __exit nft_flow_offload_module_exit(void) +{ + struct net *net; + + nft_unregister_expr(&nft_flow_offload_type); + unregister_netdevice_notifier(&flow_offload_netdev_notifier); + rtnl_lock(); + for_each_net(net) + nft_flow_table_iterate(net, nft_flow_offload_iterate_cleanup, NULL); + rtnl_unlock(); +} + +module_init(nft_flow_offload_module_init); +module_exit(nft_flow_offload_module_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Pablo Neira Ayuso "); +MODULE_ALIAS_NFT_EXPR("flow_offload"); -- cgit v1.2.3-59-g8ed1b From 23fe846f9a48d5375722b3bd060e0a02ad1ca7f1 Mon Sep 17 00:00:00 2001 From: Guillaume Nault Date: Fri, 5 Jan 2018 19:47:14 +0100 Subject: l2tp: adjust comments about L2TPv3 offsets The "offset" option has been removed by commit 900631ee6a26 ("l2tp: remove configurable payload offset"). Signed-off-by: Guillaume Nault Acked-by: James Chapman Signed-off-by: David S. Miller --- include/uapi/linux/l2tp.h | 2 +- net/l2tp/l2tp_core.c | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h index f78eef4cc56a..71e62795104d 100644 --- a/include/uapi/linux/l2tp.h +++ b/include/uapi/linux/l2tp.h @@ -65,7 +65,7 @@ struct sockaddr_l2tpip6 { * TUNNEL_MODIFY - CONN_ID, udpcsum * TUNNEL_GETSTATS - CONN_ID, (stats) * TUNNEL_GET - CONN_ID, (...) - * SESSION_CREATE - SESSION_ID, PW_TYPE, offset, data_seq, cookie, peer_cookie, offset, l2spec + * SESSION_CREATE - SESSION_ID, PW_TYPE, data_seq, cookie, peer_cookie, l2spec * SESSION_DELETE - SESSION_ID * SESSION_MODIFY - SESSION_ID, data_seq * SESSION_GET - SESSION_ID, (...) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 786cd7f6a5e8..62285fc6eb59 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -662,10 +662,9 @@ discard: * |x|S|x|x|x|x|x|x| Sequence Number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * - * Cookie value, sublayer format and offset (pad) are negotiated with - * the peer when the session is set up. Unlike L2TPv2, we do not need - * to parse the packet header to determine if optional fields are - * present. + * Cookie value and sublayer format are negotiated with the peer when + * the session is set up. Unlike L2TPv2, we do not need to parse the + * packet header to determine if optional fields are present. * * Caller must already have parsed the frame and determined that it is * a data (not control) frame before coming here. Fields up to the -- cgit v1.2.3-59-g8ed1b From c5a9f6f0ab4054082dd5ce9bbdaa8e8ff05cf365 Mon Sep 17 00:00:00 2001 From: Eugenia Emantayev Date: Mon, 17 Jul 2017 13:47:07 +0300 Subject: net/core: Add drop counters to VF statistics Modern hardware can decide to drop packets going to/from a VF. Add receive and transmit drop counters to be displayed at hypervisor layer in iproute2 per VF statistics. Signed-off-by: Eugenia Emantayev Signed-off-by: Saeed Mahameed --- include/linux/if_link.h | 2 ++ include/uapi/linux/if_link.h | 2 ++ net/core/rtnetlink.c | 10 +++++++++- 3 files changed, 13 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 4c54611e03e9..622658dfbf0a 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -13,6 +13,8 @@ struct ifla_vf_stats { __u64 tx_bytes; __u64 broadcast; __u64 multicast; + __u64 rx_dropped; + __u64 tx_dropped; }; struct ifla_vf_info { diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 19fc02660e0c..f8f04fed6186 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -732,6 +732,8 @@ enum { IFLA_VF_STATS_BROADCAST, IFLA_VF_STATS_MULTICAST, IFLA_VF_STATS_PAD, + IFLA_VF_STATS_RX_DROPPED, + IFLA_VF_STATS_TX_DROPPED, __IFLA_VF_STATS_MAX, }; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index c688dc564b11..5421a3fd3ba1 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -904,6 +904,10 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev, nla_total_size_64bit(sizeof(__u64)) + /* IFLA_VF_STATS_MULTICAST */ nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_RX_DROPPED */ + nla_total_size_64bit(sizeof(__u64)) + + /* IFLA_VF_STATS_TX_DROPPED */ + nla_total_size_64bit(sizeof(__u64)) + nla_total_size(sizeof(struct ifla_vf_trust))); return size; } else @@ -1258,7 +1262,11 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb, nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST, vf_stats.broadcast, IFLA_VF_STATS_PAD) || nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST, - vf_stats.multicast, IFLA_VF_STATS_PAD)) { + vf_stats.multicast, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED, + vf_stats.rx_dropped, IFLA_VF_STATS_PAD) || + nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED, + vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) { nla_nest_cancel(skb, vfstats); goto nla_put_vf_failure; } -- cgit v1.2.3-59-g8ed1b From 7c0143153cd33a0a267908ca419e2adc40ee513a Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Tue, 19 Dec 2017 13:28:30 +0200 Subject: USB: clarify USB_DT_USB_SSP_CAP_SIZE(ssac) definition USB_DT_USB_SSP_CAP_SIZE(ssac) gives the size of the SSP capability descriptor. The descriptor consists of 12 bytes plus a array of SSA entries. The number of SSA entries is stored in a SSAC value in the first 12 bytes, The USB3.1 specification 9.6.2.5 defines SSAC as zero based: "The number of Sublink Speed Attributes = SSAC + 1." This is not intuitive and has already caused some confusion. Make a small modifiaction to the USB_DT_USB_SSP_CAP_SIZE(ssac) definition to make it a bit clearer Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/usb/ch9.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h index c4c79aa331bd..d5a5caec8fbc 100644 --- a/include/uapi/linux/usb/ch9.h +++ b/include/uapi/linux/usb/ch9.h @@ -1077,9 +1077,9 @@ struct usb_ptm_cap_descriptor { #define USB_DT_USB_PTM_ID_SIZE 3 /* * The size of the descriptor for the Sublink Speed Attribute Count - * (SSAC) specified in bmAttributes[4:0]. + * (SSAC) specified in bmAttributes[4:0]. SSAC is zero-based */ -#define USB_DT_USB_SSP_CAP_SIZE(ssac) (16 + ssac * 4) +#define USB_DT_USB_SSP_CAP_SIZE(ssac) (12 + (ssac + 1) * 4) /*-------------------------------------------------------------------------*/ -- cgit v1.2.3-59-g8ed1b From ccfdec9089229503d3a305e02accac01817d293e Mon Sep 17 00:00:00 2001 From: Felix Walter Date: Fri, 5 Jan 2018 14:33:31 +0100 Subject: macsec: Add support for GCM-AES-256 cipher suite This adds support for the GCM-AES-256 cipher suite as specified in IEEE 802.1AEbn-2011. The prepared cipher suite selection mechanism is used, with GCM-AES-128 being the default cipher suite as defined in the standard. Signed-off-by: Felix Walter Cc: Sabrina Dubroca Signed-off-by: David S. Miller --- drivers/net/macsec.c | 72 ++++++++++++++++++++++++++++++++++-------- include/uapi/linux/if_macsec.h | 11 +++++-- 2 files changed, 67 insertions(+), 16 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 1d025ab9568f..f522715c6595 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -393,7 +393,12 @@ static struct macsec_cb *macsec_skb_cb(struct sk_buff *skb) #define MACSEC_PORT_SCB (0x0000) #define MACSEC_UNDEF_SCI ((__force sci_t)0xffffffffffffffffULL) -#define DEFAULT_SAK_LEN 16 +#define MACSEC_GCM_AES_128_SAK_LEN 16 +#define MACSEC_GCM_AES_256_SAK_LEN 32 + +#define MAX_SAK_LEN MACSEC_GCM_AES_256_SAK_LEN + +#define DEFAULT_SAK_LEN MACSEC_GCM_AES_128_SAK_LEN #define DEFAULT_SEND_SCI true #define DEFAULT_ENCRYPT false #define DEFAULT_ENCODING_SA 0 @@ -1600,7 +1605,7 @@ static const struct nla_policy macsec_genl_sa_policy[NUM_MACSEC_SA_ATTR] = { [MACSEC_SA_ATTR_KEYID] = { .type = NLA_BINARY, .len = MACSEC_KEYID_LEN, }, [MACSEC_SA_ATTR_KEY] = { .type = NLA_BINARY, - .len = MACSEC_MAX_KEY_LEN, }, + .len = MAX_SAK_LEN, }, }; static int parse_sa_config(struct nlattr **attrs, struct nlattr **tb_sa) @@ -2362,15 +2367,26 @@ static int nla_put_secy(struct macsec_secy *secy, struct sk_buff *skb) { struct macsec_tx_sc *tx_sc = &secy->tx_sc; struct nlattr *secy_nest = nla_nest_start(skb, MACSEC_ATTR_SECY); + u64 csid; if (!secy_nest) return 1; + switch (secy->key_len) { + case MACSEC_GCM_AES_128_SAK_LEN: + csid = MACSEC_CIPHER_ID_GCM_AES_128; + break; + case MACSEC_GCM_AES_256_SAK_LEN: + csid = MACSEC_CIPHER_ID_GCM_AES_256; + break; + default: + goto cancel; + } + if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci, MACSEC_SECY_ATTR_PAD) || nla_put_u64_64bit(skb, MACSEC_SECY_ATTR_CIPHER_SUITE, - MACSEC_DEFAULT_CIPHER_ID, - MACSEC_SECY_ATTR_PAD) || + csid, MACSEC_SECY_ATTR_PAD) || nla_put_u8(skb, MACSEC_SECY_ATTR_ICV_LEN, secy->icv_len) || nla_put_u8(skb, MACSEC_SECY_ATTR_OPER, secy->operational) || nla_put_u8(skb, MACSEC_SECY_ATTR_PROTECT, secy->protect_frames) || @@ -3015,8 +3031,8 @@ static void macsec_setup(struct net_device *dev) eth_zero_addr(dev->broadcast); } -static void macsec_changelink_common(struct net_device *dev, - struct nlattr *data[]) +static int macsec_changelink_common(struct net_device *dev, + struct nlattr *data[]) { struct macsec_secy *secy; struct macsec_tx_sc *tx_sc; @@ -3056,6 +3072,22 @@ static void macsec_changelink_common(struct net_device *dev, if (data[IFLA_MACSEC_VALIDATION]) secy->validate_frames = nla_get_u8(data[IFLA_MACSEC_VALIDATION]); + + if (data[IFLA_MACSEC_CIPHER_SUITE]) { + switch (nla_get_u64(data[IFLA_MACSEC_CIPHER_SUITE])) { + case MACSEC_CIPHER_ID_GCM_AES_128: + case MACSEC_DEFAULT_CIPHER_ALT: + secy->key_len = MACSEC_GCM_AES_128_SAK_LEN; + break; + case MACSEC_CIPHER_ID_GCM_AES_256: + secy->key_len = MACSEC_GCM_AES_256_SAK_LEN; + break; + default: + return -EINVAL; + } + } + + return 0; } static int macsec_changelink(struct net_device *dev, struct nlattr *tb[], @@ -3071,9 +3103,7 @@ static int macsec_changelink(struct net_device *dev, struct nlattr *tb[], data[IFLA_MACSEC_PORT]) return -EINVAL; - macsec_changelink_common(dev, data); - - return 0; + return macsec_changelink_common(dev, data); } static void macsec_del_dev(struct macsec_dev *macsec) @@ -3270,8 +3300,11 @@ static int macsec_newlink(struct net *net, struct net_device *dev, if (err) goto unlink; - if (data) - macsec_changelink_common(dev, data); + if (data) { + err = macsec_changelink_common(dev, data); + if (err) + goto del_dev; + } err = register_macsec_dev(real_dev, dev); if (err < 0) @@ -3320,7 +3353,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[], } switch (csid) { - case MACSEC_DEFAULT_CIPHER_ID: + case MACSEC_CIPHER_ID_GCM_AES_128: + case MACSEC_CIPHER_ID_GCM_AES_256: case MACSEC_DEFAULT_CIPHER_ALT: if (icv_len < MACSEC_MIN_ICV_LEN || icv_len > MACSEC_STD_ICV_LEN) @@ -3390,12 +3424,24 @@ static int macsec_fill_info(struct sk_buff *skb, { struct macsec_secy *secy = &macsec_priv(dev)->secy; struct macsec_tx_sc *tx_sc = &secy->tx_sc; + u64 csid; + + switch (secy->key_len) { + case MACSEC_GCM_AES_128_SAK_LEN: + csid = MACSEC_CIPHER_ID_GCM_AES_128; + break; + case MACSEC_GCM_AES_256_SAK_LEN: + csid = MACSEC_CIPHER_ID_GCM_AES_256; + break; + default: + goto nla_put_failure; + } if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci, IFLA_MACSEC_PAD) || nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) || nla_put_u64_64bit(skb, IFLA_MACSEC_CIPHER_SUITE, - MACSEC_DEFAULT_CIPHER_ID, IFLA_MACSEC_PAD) || + csid, IFLA_MACSEC_PAD) || nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) || nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) || nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) || diff --git a/include/uapi/linux/if_macsec.h b/include/uapi/linux/if_macsec.h index 719d243471f4..2e522835a4af 100644 --- a/include/uapi/linux/if_macsec.h +++ b/include/uapi/linux/if_macsec.h @@ -18,12 +18,17 @@ #define MACSEC_GENL_NAME "macsec" #define MACSEC_GENL_VERSION 1 -#define MACSEC_MAX_KEY_LEN 128 +#define MACSEC_MAX_KEY_LEN 256 #define MACSEC_KEYID_LEN 16 -#define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL -#define MACSEC_DEFAULT_CIPHER_ALT 0x0080C20001000001ULL +/* cipher IDs as per IEEE802.1AEbn-2011 */ +#define MACSEC_CIPHER_ID_GCM_AES_128 0x0080C20001000001ULL +#define MACSEC_CIPHER_ID_GCM_AES_256 0x0080C20001000002ULL + +#define MACSEC_DEFAULT_CIPHER_ID MACSEC_CIPHER_ID_GCM_AES_128 +/* deprecated cipher ID for GCM-AES-128 */ +#define MACSEC_DEFAULT_CIPHER_ALT 0x0080020001000001ULL #define MACSEC_MIN_ICV_LEN 8 #define MACSEC_MAX_ICV_LEN 32 -- cgit v1.2.3-59-g8ed1b From faa9b39f0e9ddfa8c83725b3f230784976dd3c7f Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Fri, 5 Jan 2018 17:44:54 -0500 Subject: virtio_net: propagate linkspeed/duplex settings from the hypervisor The ability to set speed and duplex for virtio_net is useful in various scenarios as described here: 16032be virtio_net: add ethtool support for set and get of settings However, it would be nice to be able to set this from the hypervisor, such that virtio_net doesn't require custom guest ethtool commands. Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows the hypervisor to export a linkspeed and duplex setting. The user can subsequently overwrite it later if desired via: 'ethtool -s'. Note that VIRTIO_NET_F_SPEED_DUPLEX is defined as bit 63, the intention is that device feature bits are to grow down from bit 63, since the transports are starting from bit 24 and growing up. Signed-off-by: Jason Baron Cc: "Michael S. Tsirkin" Cc: Jason Wang Cc: virtio-dev@lists.oasis-open.org Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 23 ++++++++++++++++++++++- include/uapi/linux/virtio_net.h | 13 +++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index ed8299343728..12dfc5fee58e 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -1906,6 +1906,24 @@ static void virtnet_init_settings(struct net_device *dev) vi->duplex = DUPLEX_UNKNOWN; } +static void virtnet_update_settings(struct virtnet_info *vi) +{ + u32 speed; + u8 duplex; + + if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_SPEED_DUPLEX)) + return; + + speed = virtio_cread32(vi->vdev, offsetof(struct virtio_net_config, + speed)); + if (ethtool_validate_speed(speed)) + vi->speed = speed; + duplex = virtio_cread8(vi->vdev, offsetof(struct virtio_net_config, + duplex)); + if (ethtool_validate_duplex(duplex)) + vi->duplex = duplex; +} + static const struct ethtool_ops virtnet_ethtool_ops = { .get_drvinfo = virtnet_get_drvinfo, .get_link = ethtool_op_get_link, @@ -2159,6 +2177,7 @@ static void virtnet_config_changed_work(struct work_struct *work) vi->status = v; if (vi->status & VIRTIO_NET_S_LINK_UP) { + virtnet_update_settings(vi); netif_carrier_on(vi->dev); netif_tx_wake_all_queues(vi->dev); } else { @@ -2707,6 +2726,7 @@ static int virtnet_probe(struct virtio_device *vdev) schedule_work(&vi->config_work); } else { vi->status = VIRTIO_NET_S_LINK_UP; + virtnet_update_settings(vi); netif_carrier_on(dev); } @@ -2808,7 +2828,8 @@ static struct virtio_device_id id_table[] = { VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \ VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \ VIRTIO_NET_F_CTRL_MAC_ADDR, \ - VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS + VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \ + VIRTIO_NET_F_SPEED_DUPLEX static unsigned int features[] = { VIRTNET_FEATURES, diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h index fc353b518288..5de6ed37695b 100644 --- a/include/uapi/linux/virtio_net.h +++ b/include/uapi/linux/virtio_net.h @@ -57,6 +57,8 @@ * Steering */ #define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */ +#define VIRTIO_NET_F_SPEED_DUPLEX 63 /* Device set linkspeed and duplex */ + #ifndef VIRTIO_NET_NO_LEGACY #define VIRTIO_NET_F_GSO 6 /* Host handles pkts w/ any GSO type */ #endif /* VIRTIO_NET_NO_LEGACY */ @@ -76,6 +78,17 @@ struct virtio_net_config { __u16 max_virtqueue_pairs; /* Default maximum transmit unit advice */ __u16 mtu; + /* + * speed, in units of 1Mb. All values 0 to INT_MAX are legal. + * Any other value stands for unknown. + */ + __u32 speed; + /* + * 0x00 - half duplex + * 0x01 - full duplex + * Any other value stands for unknown. + */ + __u8 duplex; } __attribute__((packed)); /* -- cgit v1.2.3-59-g8ed1b From 232d07b74a33b9f5d48516dc1d8ce41723ada593 Mon Sep 17 00:00:00 2001 From: Jon Maloy Date: Mon, 8 Jan 2018 21:03:30 +0100 Subject: tipc: improve groupcast scope handling When a member joins a group, it also indicates a binding scope. This makes it possible to create both node local groups, invisible to other nodes, as well as cluster global groups, visible everywhere. In order to avoid that different members end up having permanently differing views of group size and memberhip, we must inhibit locally and globally bound members from joining the same group. We do this by using the binding scope as an additional separator between groups. I.e., a member must ignore all membership events from sockets using a different scope than itself, and all lookups for message destinations must require an exact match between the message's lookup scope and the potential target's binding scope. Apart from making it possible to create local groups using the same identity on different nodes, a side effect of this is that it now also becomes possible to create a cluster global group with the same identity across the same nodes, without interfering with the local groups. Acked-by: Ying Xue Signed-off-by: Jon Maloy Signed-off-by: David S. Miller --- include/uapi/linux/tipc.h | 7 ++-- net/tipc/group.c | 13 ++++--- net/tipc/name_table.c | 40 ++++++++++----------- net/tipc/name_table.h | 4 +-- net/tipc/server.c | 4 +-- net/tipc/server.h | 6 ++-- net/tipc/socket.c | 88 ++++++++++++++++++++++++++++------------------- net/tipc/subscr.c | 10 ++++-- net/tipc/subscr.h | 2 +- 9 files changed, 99 insertions(+), 75 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h index 35f79d1f8c3a..14bacc7e6cef 100644 --- a/include/uapi/linux/tipc.h +++ b/include/uapi/linux/tipc.h @@ -117,10 +117,9 @@ static inline unsigned int tipc_node(__u32 addr) /* * Publication scopes when binding port names and port name sequences */ - -#define TIPC_ZONE_SCOPE 1 -#define TIPC_CLUSTER_SCOPE 2 -#define TIPC_NODE_SCOPE 3 +#define TIPC_ZONE_SCOPE 1 +#define TIPC_CLUSTER_SCOPE 2 +#define TIPC_NODE_SCOPE 3 /* * Limiting values for messages diff --git a/net/tipc/group.c b/net/tipc/group.c index cf996bd6ec98..1908773c9fca 100644 --- a/net/tipc/group.c +++ b/net/tipc/group.c @@ -87,7 +87,6 @@ struct tipc_group { int subid; u32 type; u32 instance; - u32 domain; u32 scope; u32 portid; u16 member_cnt; @@ -158,6 +157,8 @@ int tipc_group_size(struct tipc_group *grp) struct tipc_group *tipc_group_create(struct net *net, u32 portid, struct tipc_group_req *mreq) { + u32 filter = TIPC_SUB_PORTS | TIPC_SUB_NO_STATUS; + bool global = mreq->scope != TIPC_NODE_SCOPE; struct tipc_group *grp; u32 type = mreq->type; @@ -171,15 +172,14 @@ struct tipc_group *tipc_group_create(struct net *net, u32 portid, grp->members = RB_ROOT; grp->net = net; grp->portid = portid; - grp->domain = addr_domain(net, mreq->scope); grp->type = type; grp->instance = mreq->instance; grp->scope = mreq->scope; grp->loopback = mreq->flags & TIPC_GROUP_LOOPBACK; grp->events = mreq->flags & TIPC_GROUP_MEMBER_EVTS; - if (tipc_topsrv_kern_subscr(net, portid, type, - TIPC_SUB_PORTS | TIPC_SUB_NO_STATUS, - 0, ~0, &grp->subid)) + filter |= global ? TIPC_SUB_CLUSTER_SCOPE : TIPC_SUB_NODE_SCOPE; + if (tipc_topsrv_kern_subscr(net, portid, type, 0, ~0, + filter, &grp->subid)) return grp; kfree(grp); return NULL; @@ -732,6 +732,9 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, if (!grp) return; + if (grp->scope == TIPC_NODE_SCOPE && node != tipc_own_addr(grp->net)) + return; + m = tipc_group_find_member(grp, node, port); switch (msg_type(hdr)) { diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 60af9885f160..64cdd3c302b0 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -328,7 +328,8 @@ static struct publication *tipc_nameseq_insert_publ(struct net *net, list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { tipc_subscrp_report_overlap(s, publ->lower, publ->upper, TIPC_PUBLISHED, publ->ref, - publ->node, created_subseq); + publ->node, publ->scope, + created_subseq); } return publ; } @@ -398,7 +399,8 @@ found: list_for_each_entry_safe(s, st, &nseq->subscriptions, nameseq_list) { tipc_subscrp_report_overlap(s, publ->lower, publ->upper, TIPC_WITHDRAWN, publ->ref, - publ->node, removed_subseq); + publ->node, publ->scope, + removed_subseq); } return publ; @@ -435,6 +437,7 @@ static void tipc_nameseq_subscribe(struct name_seq *nseq, sseq->upper, TIPC_PUBLISHED, crs->ref, crs->node, + crs->scope, must_report); must_report = 0; } @@ -598,7 +601,7 @@ not_found: return ref; } -bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 domain, +bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 scope, struct list_head *dsts, int *dstcnt, u32 exclude, bool all) { @@ -608,9 +611,6 @@ bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 domain, struct name_seq *seq; struct sub_seq *sseq; - if (!tipc_in_scope(domain, self)) - return false; - *dstcnt = 0; rcu_read_lock(); seq = nametbl_find_seq(net, type); @@ -621,7 +621,7 @@ bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 domain, if (likely(sseq)) { info = sseq->info; list_for_each_entry(publ, &info->zone_list, zone_list) { - if (!tipc_in_scope(domain, publ->node)) + if (publ->scope != scope) continue; if (publ->ref == exclude && publ->node == self) continue; @@ -639,13 +639,14 @@ exit: return !list_empty(dsts); } -int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, - u32 limit, struct list_head *dports) +int tipc_nametbl_mc_lookup(struct net *net, u32 type, u32 lower, u32 upper, + u32 scope, bool exact, struct list_head *dports) { - struct name_seq *seq; - struct sub_seq *sseq; struct sub_seq *sseq_stop; struct name_info *info; + struct publication *p; + struct name_seq *seq; + struct sub_seq *sseq; int res = 0; rcu_read_lock(); @@ -657,15 +658,12 @@ int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, sseq = seq->sseqs + nameseq_locate_subseq(seq, lower); sseq_stop = seq->sseqs + seq->first_free; for (; sseq != sseq_stop; sseq++) { - struct publication *publ; - if (sseq->lower > upper) break; - info = sseq->info; - list_for_each_entry(publ, &info->node_list, node_list) { - if (publ->scope <= limit) - tipc_dest_push(dports, 0, publ->ref); + list_for_each_entry(p, &info->node_list, node_list) { + if (p->scope == scope || (!exact && p->scope < scope)) + tipc_dest_push(dports, 0, p->ref); } if (info->cluster_list_size != info->node_list_size) @@ -682,7 +680,7 @@ exit: * - Determines if any node local ports overlap */ void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower, - u32 upper, u32 domain, + u32 upper, u32 scope, struct tipc_nlist *nodes) { struct sub_seq *sseq, *stop; @@ -701,7 +699,7 @@ void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower, for (; sseq != stop && sseq->lower <= upper; sseq++) { info = sseq->info; list_for_each_entry(publ, &info->zone_list, zone_list) { - if (tipc_in_scope(domain, publ->node)) + if (publ->scope == scope) tipc_nlist_add(nodes, publ->node); } } @@ -713,7 +711,7 @@ exit: /* tipc_nametbl_build_group - build list of communication group members */ void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp, - u32 type, u32 domain) + u32 type, u32 scope) { struct sub_seq *sseq, *stop; struct name_info *info; @@ -731,7 +729,7 @@ void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp, for (; sseq != stop; sseq++) { info = sseq->info; list_for_each_entry(p, &info->zone_list, zone_list) { - if (!tipc_in_scope(domain, p->node)) + if (p->scope != scope) continue; tipc_group_add_member(grp, p->node, p->ref, p->lower); } diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h index 73a148c85c15..b595d8aa00f0 100644 --- a/net/tipc/name_table.h +++ b/net/tipc/name_table.h @@ -100,8 +100,8 @@ struct name_table { int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb); u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node); -int tipc_nametbl_mc_translate(struct net *net, u32 type, u32 lower, u32 upper, - u32 limit, struct list_head *dports); +int tipc_nametbl_mc_lookup(struct net *net, u32 type, u32 lower, u32 upper, + u32 scope, bool exact, struct list_head *dports); void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp, u32 type, u32 domain); void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower, diff --git a/net/tipc/server.c b/net/tipc/server.c index 950c54cbcf3a..8ee5e86b7870 100644 --- a/net/tipc/server.c +++ b/net/tipc/server.c @@ -489,8 +489,8 @@ void tipc_conn_terminate(struct tipc_server *s, int conid) } } -bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, - u32 filter, u32 lower, u32 upper, int *conid) +bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower, + u32 upper, u32 filter, int *conid) { struct tipc_subscriber *scbr; struct tipc_subscr sub; diff --git a/net/tipc/server.h b/net/tipc/server.h index ea1effbff23e..17f49ee44cfd 100644 --- a/net/tipc/server.h +++ b/net/tipc/server.h @@ -41,6 +41,8 @@ #include #define TIPC_SERVER_NAME_LEN 32 +#define TIPC_SUB_CLUSTER_SCOPE 0x20 +#define TIPC_SUB_NODE_SCOPE 0x40 #define TIPC_SUB_NO_STATUS 0x80 /** @@ -84,8 +86,8 @@ struct tipc_server { int tipc_conn_sendmsg(struct tipc_server *s, int conid, struct sockaddr_tipc *addr, void *data, size_t len); -bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, - u32 filter, u32 lower, u32 upper, int *conid); +bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower, + u32 upper, u32 filter, int *conid); void tipc_topsrv_kern_unsubscr(struct net *net, int conid); /** diff --git a/net/tipc/socket.c b/net/tipc/socket.c index e3a02f1fcab5..b24dab3996c9 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -928,21 +928,22 @@ static int tipc_send_group_anycast(struct socket *sock, struct msghdr *m, struct list_head *cong_links = &tsk->cong_links; int blks = tsk_blocks(GROUP_H_SIZE + dlen); struct tipc_group *grp = tsk->group; + struct tipc_msg *hdr = &tsk->phdr; struct tipc_member *first = NULL; struct tipc_member *mbr = NULL; struct net *net = sock_net(sk); u32 node, port, exclude; - u32 type, inst, domain; struct list_head dsts; + u32 type, inst, scope; int lookups = 0; int dstcnt, rc; bool cong; INIT_LIST_HEAD(&dsts); - type = dest->addr.name.name.type; + type = msg_nametype(hdr); inst = dest->addr.name.name.instance; - domain = addr_domain(net, dest->scope); + scope = msg_lookup_scope(hdr); exclude = tipc_group_exclude(grp); while (++lookups < 4) { @@ -950,7 +951,7 @@ static int tipc_send_group_anycast(struct socket *sock, struct msghdr *m, /* Look for a non-congested destination member, if any */ while (1) { - if (!tipc_nametbl_lookup(net, type, inst, domain, &dsts, + if (!tipc_nametbl_lookup(net, type, inst, scope, &dsts, &dstcnt, exclude, false)) return -EHOSTUNREACH; tipc_dest_pop(&dsts, &node, &port); @@ -1079,22 +1080,23 @@ static int tipc_send_group_mcast(struct socket *sock, struct msghdr *m, { struct sock *sk = sock->sk; DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name); - struct tipc_name_seq *seq = &dest->addr.nameseq; struct tipc_sock *tsk = tipc_sk(sk); struct tipc_group *grp = tsk->group; + struct tipc_msg *hdr = &tsk->phdr; struct net *net = sock_net(sk); - u32 domain, exclude, dstcnt; + u32 type, inst, scope, exclude; struct list_head dsts; + u32 dstcnt; INIT_LIST_HEAD(&dsts); - if (seq->lower != seq->upper) - return -ENOTSUPP; - - domain = addr_domain(net, dest->scope); + type = msg_nametype(hdr); + inst = dest->addr.name.name.instance; + scope = msg_lookup_scope(hdr); exclude = tipc_group_exclude(grp); - if (!tipc_nametbl_lookup(net, seq->type, seq->lower, domain, - &dsts, &dstcnt, exclude, true)) + + if (!tipc_nametbl_lookup(net, type, inst, scope, &dsts, + &dstcnt, exclude, true)) return -EHOSTUNREACH; if (dstcnt == 1) { @@ -1116,24 +1118,29 @@ static int tipc_send_group_mcast(struct socket *sock, struct msghdr *m, void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, struct sk_buff_head *inputq) { - u32 scope = TIPC_CLUSTER_SCOPE; u32 self = tipc_own_addr(net); + u32 type, lower, upper, scope; struct sk_buff *skb, *_skb; - u32 lower = 0, upper = ~0; - struct sk_buff_head tmpq; u32 portid, oport, onode; + struct sk_buff_head tmpq; struct list_head dports; - struct tipc_msg *msg; - int user, mtyp, hsz; + struct tipc_msg *hdr; + int user, mtyp, hlen; + bool exact; __skb_queue_head_init(&tmpq); INIT_LIST_HEAD(&dports); skb = tipc_skb_peek(arrvq, &inputq->lock); for (; skb; skb = tipc_skb_peek(arrvq, &inputq->lock)) { - msg = buf_msg(skb); - user = msg_user(msg); - mtyp = msg_type(msg); + hdr = buf_msg(skb); + user = msg_user(hdr); + mtyp = msg_type(hdr); + hlen = skb_headroom(skb) + msg_hdr_sz(hdr); + oport = msg_origport(hdr); + onode = msg_orignode(hdr); + type = msg_nametype(hdr); + if (mtyp == TIPC_GRP_UCAST_MSG || user == GROUP_PROTOCOL) { spin_lock_bh(&inputq->lock); if (skb_peek(arrvq) == skb) { @@ -1144,21 +1151,31 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, spin_unlock_bh(&inputq->lock); continue; } - hsz = skb_headroom(skb) + msg_hdr_sz(msg); - oport = msg_origport(msg); - onode = msg_orignode(msg); - if (onode == self) - scope = TIPC_NODE_SCOPE; - - /* Create destination port list and message clones: */ - if (!msg_in_group(msg)) { - lower = msg_namelower(msg); - upper = msg_nameupper(msg); + + /* Group messages require exact scope match */ + if (msg_in_group(hdr)) { + lower = 0; + upper = ~0; + scope = msg_lookup_scope(hdr); + exact = true; + } else { + /* TIPC_NODE_SCOPE means "any scope" in this context */ + if (onode == self) + scope = TIPC_NODE_SCOPE; + else + scope = TIPC_CLUSTER_SCOPE; + exact = false; + lower = msg_namelower(hdr); + upper = msg_nameupper(hdr); } - tipc_nametbl_mc_translate(net, msg_nametype(msg), lower, upper, - scope, &dports); + + /* Create destination port list: */ + tipc_nametbl_mc_lookup(net, type, lower, upper, + scope, exact, &dports); + + /* Clone message per destination */ while (tipc_dest_pop(&dports, NULL, &portid)) { - _skb = __pskb_copy(skb, hsz, GFP_ATOMIC); + _skb = __pskb_copy(skb, hlen, GFP_ATOMIC); if (_skb) { msg_set_destport(buf_msg(_skb), portid); __skb_queue_tail(&tmpq, _skb); @@ -2731,7 +2748,6 @@ void tipc_sk_rht_destroy(struct net *net) static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq) { struct net *net = sock_net(&tsk->sk); - u32 domain = addr_domain(net, mreq->scope); struct tipc_group *grp = tsk->group; struct tipc_msg *hdr = &tsk->phdr; struct tipc_name_seq seq; @@ -2739,6 +2755,8 @@ static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq) if (mreq->type < TIPC_RESERVED_TYPES) return -EACCES; + if (mreq->scope > TIPC_NODE_SCOPE) + return -EINVAL; if (grp) return -EACCES; grp = tipc_group_create(net, tsk->portid, mreq); @@ -2751,7 +2769,7 @@ static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq) seq.type = mreq->type; seq.lower = mreq->instance; seq.upper = seq.lower; - tipc_nametbl_build_group(net, grp, mreq->type, domain); + tipc_nametbl_build_group(net, grp, mreq->type, mreq->scope); rc = tipc_sk_publish(tsk, mreq->scope, &seq); if (rc) { tipc_group_delete(net, grp); diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index 1052341a0ea9..44df528ed6ab 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -118,15 +118,19 @@ void tipc_subscrp_convert_seq(struct tipc_name_seq *in, int swap, void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower, u32 found_upper, u32 event, u32 port_ref, - u32 node, int must) + u32 node, u32 scope, int must) { + u32 filter = htohl(sub->evt.s.filter, sub->swap); struct tipc_name_seq seq; tipc_subscrp_convert_seq(&sub->evt.s.seq, sub->swap, &seq); if (!tipc_subscrp_check_overlap(&seq, found_lower, found_upper)) return; - if (!must && - !(htohl(sub->evt.s.filter, sub->swap) & TIPC_SUB_PORTS)) + if (!must && !(filter & TIPC_SUB_PORTS)) + return; + if (filter & TIPC_SUB_CLUSTER_SCOPE && scope == TIPC_NODE_SCOPE) + return; + if (filter & TIPC_SUB_NODE_SCOPE && scope != TIPC_NODE_SCOPE) return; tipc_subscrp_send_event(sub, found_lower, found_upper, event, port_ref, diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h index ee52957dc952..f3edca775d9f 100644 --- a/net/tipc/subscr.h +++ b/net/tipc/subscr.h @@ -71,7 +71,7 @@ int tipc_subscrp_check_overlap(struct tipc_name_seq *seq, u32 found_lower, u32 found_upper); void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower, u32 found_upper, u32 event, - u32 port_ref, u32 node, int must); + u32 port_ref, u32 node, u32 scope, int must); void tipc_subscrp_convert_seq(struct tipc_name_seq *in, int swap, struct tipc_name_seq *out); u32 tipc_subscrp_convert_seq_type(u32 type, int swap); -- cgit v1.2.3-59-g8ed1b From 152194fe9c3f03232b9c0d0264793a7fa4af82f8 Mon Sep 17 00:00:00 2001 From: Deepa Dinamani Date: Sun, 7 Jan 2018 17:44:42 -0800 Subject: Input: extend usable life of event timestamps to 2106 on 32 bit systems The input events use struct timeval to store event time, unfortunately this structure is not y2038 safe and is being replaced in kernel with y2038 safe structures. Because of ABI concerns we can not change the size or the layout of structure input_event, so we opt to re-interpreting the 'seconds' part of timestamp as an unsigned value, effectively doubling the range of values, to year 2106. Newer glibc that has support for 32 bit applications to use 64 bit time_t supplies __USE_TIME_BITS64 define [1], that we can use to present the userspace with updated input_event layout. The updated layout will cause the compile time breakage, alerting applications and distributions maintainers to the issue. Existing 32 binaries will continue working without any changes until 2038. Ultimately userspace applications should switch to using monotonic or boot time clocks, as realtime clock is not very well suited for input event timestamps as it can go backwards (see a80b83b7b8 "Input: evdev - add CLOCK_BOOTTIME support" by by John Stultz). With monotonic clock the practical range of reported times will always fit into the pair of 32 bit values, as we do not expect any system to stay up for a hundred years without a single reboot. [1] https://sourceware.org/glibc/wiki/Y2038ProofnessDesign Suggested-by: Arnd Bergmann Signed-off-by: Deepa Dinamani Acked-by: Peter Hutterer Patchwork-Id: 10148083 Signed-off-by: Dmitry Torokhov --- drivers/input/evdev.c | 20 +++++++++++++------- drivers/input/input-compat.c | 8 ++++---- drivers/input/input-compat.h | 3 ++- drivers/input/misc/uinput.c | 4 ++-- include/uapi/linux/input.h | 11 +++++++++++ 5 files changed, 32 insertions(+), 14 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 925571475005..116088fc3621 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -135,10 +135,7 @@ static void __evdev_flush_queue(struct evdev_client *client, unsigned int type) continue; } else if (head != i) { /* move entry to fill the gap */ - client->buffer[head].time = ev->time; - client->buffer[head].type = ev->type; - client->buffer[head].code = ev->code; - client->buffer[head].value = ev->value; + client->buffer[head] = *ev; } num++; @@ -157,6 +154,7 @@ static void __evdev_queue_syn_dropped(struct evdev_client *client) { struct input_event ev; ktime_t time; + struct timespec64 ts; time = client->clk_type == EV_CLK_REAL ? ktime_get_real() : @@ -164,7 +162,9 @@ static void __evdev_queue_syn_dropped(struct evdev_client *client) ktime_get() : ktime_get_boottime(); - ev.time = ktime_to_timeval(time); + ts = ktime_to_timespec64(time); + ev.input_event_sec = ts.tv_sec; + ev.input_event_usec = ts.tv_nsec / NSEC_PER_USEC; ev.type = EV_SYN; ev.code = SYN_DROPPED; ev.value = 0; @@ -241,7 +241,10 @@ static void __pass_event(struct evdev_client *client, */ client->tail = (client->head - 2) & (client->bufsize - 1); - client->buffer[client->tail].time = event->time; + client->buffer[client->tail].input_event_sec = + event->input_event_sec; + client->buffer[client->tail].input_event_usec = + event->input_event_usec; client->buffer[client->tail].type = EV_SYN; client->buffer[client->tail].code = SYN_DROPPED; client->buffer[client->tail].value = 0; @@ -262,12 +265,15 @@ static void evdev_pass_values(struct evdev_client *client, struct evdev *evdev = client->evdev; const struct input_value *v; struct input_event event; + struct timespec64 ts; bool wakeup = false; if (client->revoked) return; - event.time = ktime_to_timeval(ev_time[client->clk_type]); + ts = ktime_to_timespec64(ev_time[client->clk_type]); + event.input_event_sec = ts.tv_sec; + event.input_event_usec = ts.tv_nsec / NSEC_PER_USEC; /* Interrupts are disabled, just acquire the lock. */ spin_lock(&client->buffer_lock); diff --git a/drivers/input/input-compat.c b/drivers/input/input-compat.c index 2186f71c9fe5..fda8d6d2a268 100644 --- a/drivers/input/input-compat.c +++ b/drivers/input/input-compat.c @@ -24,8 +24,8 @@ int input_event_from_user(const char __user *buffer, sizeof(struct input_event_compat))) return -EFAULT; - event->time.tv_sec = compat_event.time.tv_sec; - event->time.tv_usec = compat_event.time.tv_usec; + event->input_event_sec = compat_event.sec; + event->input_event_usec = compat_event.usec; event->type = compat_event.type; event->code = compat_event.code; event->value = compat_event.value; @@ -44,8 +44,8 @@ int input_event_to_user(char __user *buffer, if (in_compat_syscall() && !COMPAT_USE_64BIT_TIME) { struct input_event_compat compat_event; - compat_event.time.tv_sec = event->time.tv_sec; - compat_event.time.tv_usec = event->time.tv_usec; + compat_event.sec = event->input_event_sec; + compat_event.usec = event->input_event_usec; compat_event.type = event->type; compat_event.code = event->code; compat_event.value = event->value; diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h index 1563160a7af3..08cd755e73fd 100644 --- a/drivers/input/input-compat.h +++ b/drivers/input/input-compat.h @@ -18,7 +18,8 @@ #ifdef CONFIG_COMPAT struct input_event_compat { - struct compat_timeval time; + compat_ulong_t sec; + compat_ulong_t usec; __u16 type; __u16 code; __s32 value; diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index d521aecbc078..cb4bdbd3e9e2 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -90,8 +90,8 @@ static int uinput_dev_event(struct input_dev *dev, udev->buff[udev->head].code = code; udev->buff[udev->head].value = value; ktime_get_ts64(&ts); - udev->buff[udev->head].time.tv_sec = ts.tv_sec; - udev->buff[udev->head].time.tv_usec = ts.tv_nsec / NSEC_PER_USEC; + udev->buff[udev->head].input_event_sec = ts.tv_sec; + udev->buff[udev->head].input_event_usec = ts.tv_nsec / NSEC_PER_USEC; udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE; wake_up_interruptible(&udev->waitq); diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h index 8c5a0bf6ee35..7288a7c573cc 100644 --- a/include/uapi/linux/input.h +++ b/include/uapi/linux/input.h @@ -21,10 +21,21 @@ /* * The event structure itself + * Note that __USE_TIME_BITS64 is defined by libc based on + * application's request to use 64 bit time_t. */ struct input_event { +#if (__BITS_PER_LONG != 32 || !defined(__USE_TIME_BITS64)) && !defined(__KERNEL) struct timeval time; +#define input_event_sec time.tv_sec +#define input_event_usec time.tv_usec +#else + __kernel_ulong_t __sec; + __kernel_ulong_t __usec; +#define input_event_sec __sec +#define input_event_usec __usec +#endif __u16 type; __u16 code; __s32 value; -- cgit v1.2.3-59-g8ed1b From 202a8ff545ccdaa5ac2000d9201df3453c8816be Mon Sep 17 00:00:00 2001 From: Ahmed Abdelsalam Date: Sun, 7 Jan 2018 19:22:02 +0100 Subject: netfilter: add IPv6 segment routing header 'srh' match It allows matching packets based on Segment Routing Header (SRH) information. The implementation considers revision 7 of the SRH draft. https://tools.ietf.org/html/draft-ietf-6man-segment-routing-header-07 Currently supported match options include: (1) Next Header (2) Hdr Ext Len (3) Segments Left (4) Last Entry (5) Tag value of SRH Signed-off-by: Ahmed Abdelsalam Signed-off-by: Pablo Neira Ayuso --- include/uapi/linux/netfilter_ipv6/ip6t_srh.h | 57 ++++++++++ net/ipv6/netfilter/Kconfig | 9 ++ net/ipv6/netfilter/Makefile | 1 + net/ipv6/netfilter/ip6t_srh.c | 161 +++++++++++++++++++++++++++ 4 files changed, 228 insertions(+) create mode 100644 include/uapi/linux/netfilter_ipv6/ip6t_srh.h create mode 100644 net/ipv6/netfilter/ip6t_srh.c (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/netfilter_ipv6/ip6t_srh.h b/include/uapi/linux/netfilter_ipv6/ip6t_srh.h new file mode 100644 index 000000000000..f3cc0ef514a7 --- /dev/null +++ b/include/uapi/linux/netfilter_ipv6/ip6t_srh.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _IP6T_SRH_H +#define _IP6T_SRH_H + +#include +#include + +/* Values for "mt_flags" field in struct ip6t_srh */ +#define IP6T_SRH_NEXTHDR 0x0001 +#define IP6T_SRH_LEN_EQ 0x0002 +#define IP6T_SRH_LEN_GT 0x0004 +#define IP6T_SRH_LEN_LT 0x0008 +#define IP6T_SRH_SEGS_EQ 0x0010 +#define IP6T_SRH_SEGS_GT 0x0020 +#define IP6T_SRH_SEGS_LT 0x0040 +#define IP6T_SRH_LAST_EQ 0x0080 +#define IP6T_SRH_LAST_GT 0x0100 +#define IP6T_SRH_LAST_LT 0x0200 +#define IP6T_SRH_TAG 0x0400 +#define IP6T_SRH_MASK 0x07FF + +/* Values for "mt_invflags" field in struct ip6t_srh */ +#define IP6T_SRH_INV_NEXTHDR 0x0001 +#define IP6T_SRH_INV_LEN_EQ 0x0002 +#define IP6T_SRH_INV_LEN_GT 0x0004 +#define IP6T_SRH_INV_LEN_LT 0x0008 +#define IP6T_SRH_INV_SEGS_EQ 0x0010 +#define IP6T_SRH_INV_SEGS_GT 0x0020 +#define IP6T_SRH_INV_SEGS_LT 0x0040 +#define IP6T_SRH_INV_LAST_EQ 0x0080 +#define IP6T_SRH_INV_LAST_GT 0x0100 +#define IP6T_SRH_INV_LAST_LT 0x0200 +#define IP6T_SRH_INV_TAG 0x0400 +#define IP6T_SRH_INV_MASK 0x07FF + +/** + * struct ip6t_srh - SRH match options + * @ next_hdr: Next header field of SRH + * @ hdr_len: Extension header length field of SRH + * @ segs_left: Segments left field of SRH + * @ last_entry: Last entry field of SRH + * @ tag: Tag field of SRH + * @ mt_flags: match options + * @ mt_invflags: Invert the sense of match options + */ + +struct ip6t_srh { + __u8 next_hdr; + __u8 hdr_len; + __u8 segs_left; + __u8 last_entry; + __u16 tag; + __u16 mt_flags; + __u16 mt_invflags; +}; + +#endif /*_IP6T_SRH_H*/ diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 806e95375ec8..b6f5edf926d2 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig @@ -240,6 +240,15 @@ config IP6_NF_MATCH_RT To compile it as a module, choose M here. If unsure, say N. +config IP6_NF_MATCH_SRH + tristate '"srh" Segment Routing header match support' + depends on NETFILTER_ADVANCED + help + srh matching allows you to match packets based on the segment + routing header of the packet. + + To compile it as a module, choose M here. If unsure, say N. + # The targets config IP6_NF_TARGET_HL tristate '"HL" hoplimit target support' diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index 95611c4b39b0..d984057b8395 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_IP6_NF_MATCH_MH) += ip6t_mh.o obj-$(CONFIG_IP6_NF_MATCH_OPTS) += ip6t_hbh.o obj-$(CONFIG_IP6_NF_MATCH_RPFILTER) += ip6t_rpfilter.o obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o +obj-$(CONFIG_IP6_NF_MATCH_SRH) += ip6t_srh.o # targets obj-$(CONFIG_IP6_NF_TARGET_MASQUERADE) += ip6t_MASQUERADE.o diff --git a/net/ipv6/netfilter/ip6t_srh.c b/net/ipv6/netfilter/ip6t_srh.c new file mode 100644 index 000000000000..9642164107ce --- /dev/null +++ b/net/ipv6/netfilter/ip6t_srh.c @@ -0,0 +1,161 @@ +/* Kernel module to match Segment Routing Header (SRH) parameters. */ + +/* Author: + * Ahmed Abdelsalam + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Test a struct->mt_invflags and a boolean for inequality */ +#define NF_SRH_INVF(ptr, flag, boolean) \ + ((boolean) ^ !!((ptr)->mt_invflags & (flag))) + +static bool srh_mt6(const struct sk_buff *skb, struct xt_action_param *par) +{ + const struct ip6t_srh *srhinfo = par->matchinfo; + struct ipv6_sr_hdr *srh; + struct ipv6_sr_hdr _srh; + int hdrlen, srhoff = 0; + + if (ipv6_find_hdr(skb, &srhoff, IPPROTO_ROUTING, NULL, NULL) < 0) + return false; + srh = skb_header_pointer(skb, srhoff, sizeof(_srh), &_srh); + if (!srh) + return false; + + hdrlen = ipv6_optlen(srh); + if (skb->len - srhoff < hdrlen) + return false; + + if (srh->type != IPV6_SRCRT_TYPE_4) + return false; + + if (srh->segments_left > srh->first_segment) + return false; + + /* Next Header matching */ + if (srhinfo->mt_flags & IP6T_SRH_NEXTHDR) + if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_NEXTHDR, + !(srh->nexthdr == srhinfo->next_hdr))) + return false; + + /* Header Extension Length matching */ + if (srhinfo->mt_flags & IP6T_SRH_LEN_EQ) + if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_LEN_EQ, + !(srh->hdrlen == srhinfo->hdr_len))) + return false; + + if (srhinfo->mt_flags & IP6T_SRH_LEN_GT) + if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_LEN_GT, + !(srh->hdrlen > srhinfo->hdr_len))) + return false; + + if (srhinfo->mt_flags & IP6T_SRH_LEN_LT) + if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_LEN_LT, + !(srh->hdrlen < srhinfo->hdr_len))) + return false; + + /* Segments Left matching */ + if (srhinfo->mt_flags & IP6T_SRH_SEGS_EQ) + if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_SEGS_EQ, + !(srh->segments_left == srhinfo->segs_left))) + return false; + + if (srhinfo->mt_flags & IP6T_SRH_SEGS_GT) + if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_SEGS_GT, + !(srh->segments_left > srhinfo->segs_left))) + return false; + + if (srhinfo->mt_flags & IP6T_SRH_SEGS_LT) + if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_SEGS_LT, + !(srh->segments_left < srhinfo->segs_left))) + return false; + + /** + * Last Entry matching + * Last_Entry field was introduced in revision 6 of the SRH draft. + * It was called First_Segment in the previous revision + */ + if (srhinfo->mt_flags & IP6T_SRH_LAST_EQ) + if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_LAST_EQ, + !(srh->first_segment == srhinfo->last_entry))) + return false; + + if (srhinfo->mt_flags & IP6T_SRH_LAST_GT) + if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_LAST_GT, + !(srh->first_segment > srhinfo->last_entry))) + return false; + + if (srhinfo->mt_flags & IP6T_SRH_LAST_LT) + if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_LAST_LT, + !(srh->first_segment < srhinfo->last_entry))) + return false; + + /** + * Tag matchig + * Tag field was introduced in revision 6 of the SRH draft. + */ + if (srhinfo->mt_flags & IP6T_SRH_TAG) + if (NF_SRH_INVF(srhinfo, IP6T_SRH_INV_TAG, + !(srh->tag == srhinfo->tag))) + return false; + return true; +} + +static int srh_mt6_check(const struct xt_mtchk_param *par) +{ + const struct ip6t_srh *srhinfo = par->matchinfo; + + if (srhinfo->mt_flags & ~IP6T_SRH_MASK) { + pr_err("unknown srh match flags %X\n", srhinfo->mt_flags); + return -EINVAL; + } + + if (srhinfo->mt_invflags & ~IP6T_SRH_INV_MASK) { + pr_err("unknown srh invflags %X\n", srhinfo->mt_invflags); + return -EINVAL; + } + + return 0; +} + +static struct xt_match srh_mt6_reg __read_mostly = { + .name = "srh", + .family = NFPROTO_IPV6, + .match = srh_mt6, + .matchsize = sizeof(struct ip6t_srh), + .checkentry = srh_mt6_check, + .me = THIS_MODULE, +}; + +static int __init srh_mt6_init(void) +{ + return xt_register_match(&srh_mt6_reg); +} + +static void __exit srh_mt6_exit(void) +{ + xt_unregister_match(&srh_mt6_reg); +} + +module_init(srh_mt6_init); +module_exit(srh_mt6_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Xtables: IPv6 Segment Routing Header match"); +MODULE_AUTHOR("Ahmed Abdelsalam "); -- cgit v1.2.3-59-g8ed1b From fdabc3fe998203038a78763c1b3d6ace517e0eea Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 15 Dec 2017 15:31:30 -0600 Subject: PCI: Add #defines for Completion Timeout Disable feature Add #defines for the Completion Timeout Disable feature and use them. No functional change intended. Signed-off-by: Bjorn Helgaas Acked-by: Michael Ellerman --- arch/powerpc/platforms/powernv/eeh-powernv.c | 6 +++--- include/uapi/linux/pci_regs.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'include/uapi/linux') diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 4650fb294e7a..2f7cd0ef3cdc 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -1654,14 +1654,14 @@ static int pnv_eeh_restore_vf_config(struct pci_dn *pdn) eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL, 2, devctl); - /* Disable Completion Timeout */ + /* Disable Completion Timeout if possible */ eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP2, 4, &cap2); - if (cap2 & 0x10) { + if (cap2 & PCI_EXP_DEVCAP2_COMP_TMOUT_DIS) { eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL2, 4, &cap2); - cap2 |= 0x10; + cap2 |= PCI_EXP_DEVCTL2_COMP_TMOUT_DIS; eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL2, 4, cap2); diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index 70c2b2ade048..9dc67643fc18 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -622,6 +622,7 @@ * safely. */ #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ +#define PCI_EXP_DEVCAP2_COMP_TMOUT_DIS 0x00000010 /* Completion Timeout Disable supported */ #define PCI_EXP_DEVCAP2_ARI 0x00000020 /* Alternative Routing-ID */ #define PCI_EXP_DEVCAP2_ATOMIC_ROUTE 0x00000040 /* Atomic Op routing */ #define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100 /* Atomic 64-bit compare */ @@ -631,6 +632,7 @@ #define PCI_EXP_DEVCAP2_OBFF_WAKE 0x00080000 /* Re-use WAKE# for OBFF */ #define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ #define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f /* Completion Timeout Value */ +#define PCI_EXP_DEVCTL2_COMP_TMOUT_DIS 0x0010 /* Completion Timeout Disable */ #define PCI_EXP_DEVCTL2_ARI 0x0020 /* Alternative Routing-ID */ #define PCI_EXP_DEVCTL2_ATOMIC_REQ 0x0040 /* Set Atomic requests */ #define PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK 0x0080 /* Block atomic egress */ -- cgit v1.2.3-59-g8ed1b From 902d6a4c2a4f411582689e53fb101895ffe99028 Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Wed, 10 Jan 2018 20:51:57 -0700 Subject: netfilter: nf_defrag: Skip defrag if NOTRACK is set conntrack defrag is needed only if some module like CONNTRACK or NAT explicitly requests it. For plain forwarding scenarios, defrag is not needed and can be skipped if NOTRACK is set in a rule. Since conntrack defrag is currently higher priority than raw table, setting NOTRACK is not sufficient. We need to move raw to a higher priority for iptables only. This is achieved by introducing a module parameter "raw_before_defrag" which allows to change the priority of raw table to place it before defrag. By default, the parameter is disabled and the priority of raw table is NF_IP_PRI_RAW to support legacy behavior. If the module parameter is enabled, then the priority of the raw table is set to NF_IP_PRI_RAW_BEFORE_DEFRAG. Signed-off-by: Subash Abhinov Kasiviswanathan Signed-off-by: Pablo Neira Ayuso --- include/uapi/linux/netfilter_ipv4.h | 1 + include/uapi/linux/netfilter_ipv6.h | 1 + net/ipv4/netfilter/iptable_raw.c | 13 ++++++++++++- net/ipv4/netfilter/nf_defrag_ipv4.c | 2 +- net/ipv6/netfilter/ip6table_raw.c | 13 ++++++++++++- net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | 3 +++ 6 files changed, 30 insertions(+), 3 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/netfilter_ipv4.h b/include/uapi/linux/netfilter_ipv4.h index e6b1a84f5dd3..c3b060775e13 100644 --- a/include/uapi/linux/netfilter_ipv4.h +++ b/include/uapi/linux/netfilter_ipv4.h @@ -57,6 +57,7 @@ enum nf_ip_hook_priorities { NF_IP_PRI_FIRST = INT_MIN, + NF_IP_PRI_RAW_BEFORE_DEFRAG = -450, NF_IP_PRI_CONNTRACK_DEFRAG = -400, NF_IP_PRI_RAW = -300, NF_IP_PRI_SELINUX_FIRST = -225, diff --git a/include/uapi/linux/netfilter_ipv6.h b/include/uapi/linux/netfilter_ipv6.h index 2f9724611cc2..dc624fd24d25 100644 --- a/include/uapi/linux/netfilter_ipv6.h +++ b/include/uapi/linux/netfilter_ipv6.h @@ -62,6 +62,7 @@ enum nf_ip6_hook_priorities { NF_IP6_PRI_FIRST = INT_MIN, + NF_IP6_PRI_RAW_BEFORE_DEFRAG = -450, NF_IP6_PRI_CONNTRACK_DEFRAG = -400, NF_IP6_PRI_RAW = -300, NF_IP6_PRI_SELINUX_FIRST = -225, diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index a869d1fea7d9..29b64d3024e0 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c @@ -3,6 +3,7 @@ * * Copyright (C) 2003 Jozsef Kadlecsik */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include #include @@ -12,7 +13,11 @@ static int __net_init iptable_raw_table_init(struct net *net); -static const struct xt_table packet_raw = { +static bool raw_before_defrag __read_mostly; +MODULE_PARM_DESC(raw_before_defrag, "Enable raw table before defrag"); +module_param(raw_before_defrag, bool, 0000); + +static struct xt_table packet_raw = { .name = "raw", .valid_hooks = RAW_VALID_HOOKS, .me = THIS_MODULE, @@ -64,6 +69,12 @@ static int __init iptable_raw_init(void) { int ret; + if (raw_before_defrag) { + packet_raw.priority = NF_IP_PRI_RAW_BEFORE_DEFRAG; + + pr_info("Enabling raw table before defrag\n"); + } + rawtable_ops = xt_hook_ops_alloc(&packet_raw, iptable_raw_hook); if (IS_ERR(rawtable_ops)) return PTR_ERR(rawtable_ops); diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c index 37fe1616ca0b..cbd987f6b1f8 100644 --- a/net/ipv4/netfilter/nf_defrag_ipv4.c +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c @@ -80,7 +80,7 @@ static unsigned int ipv4_conntrack_defrag(void *priv, #endif #endif /* Gather fragments. */ - if (ip_is_fragment(ip_hdr(skb))) { + if (skb->_nfct != IP_CT_UNTRACKED && ip_is_fragment(ip_hdr(skb))) { enum ip_defrag_users user = nf_ct_defrag_user(state->hook, skb); diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index d4bc56443dc1..3df7383f96d0 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c @@ -3,6 +3,7 @@ * * Copyright (C) 2003 Jozsef Kadlecsik */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include #include @@ -11,7 +12,11 @@ static int __net_init ip6table_raw_table_init(struct net *net); -static const struct xt_table packet_raw = { +static bool raw_before_defrag __read_mostly; +MODULE_PARM_DESC(raw_before_defrag, "Enable raw table before defrag"); +module_param(raw_before_defrag, bool, 0000); + +static struct xt_table packet_raw = { .name = "raw", .valid_hooks = RAW_VALID_HOOKS, .me = THIS_MODULE, @@ -63,6 +68,12 @@ static int __init ip6table_raw_init(void) { int ret; + if (raw_before_defrag) { + packet_raw.priority = NF_IP6_PRI_RAW_BEFORE_DEFRAG; + + pr_info("Enabling raw table before defrag\n"); + } + /* Register hooks */ rawtable_ops = xt_hook_ops_alloc(&packet_raw, ip6table_raw_hook); if (IS_ERR(rawtable_ops)) diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c index b326da59257f..87b503a8f5ef 100644 --- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c +++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c @@ -65,6 +65,9 @@ static unsigned int ipv6_defrag(void *priv, return NF_ACCEPT; #endif + if (skb->_nfct == IP_CT_UNTRACKED) + return NF_ACCEPT; + err = nf_ct_frag6_gather(state->net, skb, nf_ct6_defrag_user(state->hook, skb)); /* queued */ -- cgit v1.2.3-59-g8ed1b From daaf24c634ab951cad3dcef28492001ef9c931d0 Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Thu, 11 Jan 2018 17:39:09 +0100 Subject: bpf: simplify xdp_convert_ctx_access for xdp_rxq_info As pointed out by Daniel Borkmann, using bpf_target_off() is not necessary for xdp_rxq_info when extracting queue_index and ifindex, as these members are u32 like BPF_W. Also fix trivial spelling mistake introduced in same commit. Fixes: 02dd3291b2f0 ("bpf: finally expose xdp_rxq_info to XDP bpf-programs") Reported-by: Daniel Borkmann Signed-off-by: Jesper Dangaard Brouer Signed-off-by: Daniel Borkmann --- include/uapi/linux/bpf.h | 2 +- net/core/filter.c | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 405317f9c064..395d261948de 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -899,7 +899,7 @@ struct xdp_md { __u32 data; __u32 data_end; __u32 data_meta; - /* Below access go though struct xdp_rxq_info */ + /* Below access go through struct xdp_rxq_info */ __u32 ingress_ifindex; /* rxq->dev->ifindex */ __u32 rx_queue_index; /* rxq->queue_index */ }; diff --git a/net/core/filter.c b/net/core/filter.c index d4b190e63b79..db2ee8c7e1bd 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -4310,16 +4310,15 @@ static u32 xdp_convert_ctx_access(enum bpf_access_type type, si->dst_reg, si->dst_reg, offsetof(struct xdp_rxq_info, dev)); *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg, - bpf_target_off(struct net_device, - ifindex, 4, target_size)); + offsetof(struct net_device, ifindex)); break; case offsetof(struct xdp_md, rx_queue_index): *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct xdp_buff, rxq), si->dst_reg, si->src_reg, offsetof(struct xdp_buff, rxq)); *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg, - bpf_target_off(struct xdp_rxq_info, - queue_index, 4, target_size)); + offsetof(struct xdp_rxq_info, + queue_index)); break; } -- cgit v1.2.3-59-g8ed1b From ad6eb31ef90355993eb55ff77e0e855ae7d91e4c Mon Sep 17 00:00:00 2001 From: James Morse Date: Mon, 8 Jan 2018 15:38:09 +0000 Subject: firmware: arm_sdei: Add driver for Software Delegated Exceptions The Software Delegated Exception Interface (SDEI) is an ARM standard for registering callbacks from the platform firmware into the OS. This is typically used to implement firmware notifications (such as firmware-first RAS) or promote an IRQ that has been promoted to a firmware-assisted NMI. Add the code for detecting the SDEI version and the framework for registering and unregistering events. Subsequent patches will add the arch-specific backend code and the necessary power management hooks. Only shared events are supported, power management, private events and discovery for ACPI systems will be added by later patches. Signed-off-by: James Morse Signed-off-by: Catalin Marinas --- MAINTAINERS | 9 + arch/arm64/include/asm/sdei.h | 8 + drivers/firmware/Kconfig | 8 + drivers/firmware/Makefile | 1 + drivers/firmware/arm_sdei.c | 619 ++++++++++++++++++++++++++++++++++++++++++ include/linux/arm_sdei.h | 79 ++++++ include/uapi/linux/arm_sdei.h | 73 +++++ 7 files changed, 797 insertions(+) create mode 100644 arch/arm64/include/asm/sdei.h create mode 100644 drivers/firmware/arm_sdei.c create mode 100644 include/linux/arm_sdei.h create mode 100644 include/uapi/linux/arm_sdei.h (limited to 'include/uapi/linux') diff --git a/MAINTAINERS b/MAINTAINERS index 82ad0eabce4f..c06885c4c0f1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12618,6 +12618,15 @@ L: linux-media@vger.kernel.org S: Supported F: drivers/media/pci/solo6x10/ +SOFTWARE DELEGATED EXCEPTION INTERFACE (SDEI) +M: James Morse +L: linux-arm-kernel@lists.infradead.org +S: Maintained +F: Documentation/devicetree/bindings/arm/firmware/sdei.txt +F: drivers/firmware/arm_sdei.c +F: include/linux/sdei.h +F: include/uapi/linux/sdei.h + SOFTWARE RAID (Multiple Disks) SUPPORT M: Shaohua Li L: linux-raid@vger.kernel.org diff --git a/arch/arm64/include/asm/sdei.h b/arch/arm64/include/asm/sdei.h new file mode 100644 index 000000000000..59f26b6e673d --- /dev/null +++ b/arch/arm64/include/asm/sdei.h @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2017 Arm Ltd. +#ifndef __ASM_SDEI_H +#define __ASM_SDEI_H + +/* Later patches add the arch specific bits */ + +#endif /* __ASM_SDEI_H */ diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index fa87a055905e..e77f77caa0f3 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -48,6 +48,14 @@ config ARM_SCPI_POWER_DOMAIN This enables support for the SCPI power domains which can be enabled or disabled via the SCP firmware +config ARM_SDE_INTERFACE + bool "ARM Software Delegated Exception Interface (SDEI)" + depends on ARM64 + help + The Software Delegated Exception Interface (SDEI) is an ARM + standard for registering callbacks from the platform firmware + into the OS. This is typically used to implement RAS notifications. + config EDD tristate "BIOS Enhanced Disk Drive calls determine boot disk" depends on X86 diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index feaa890197f3..b248238ddc6a 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_ARM_PSCI_FW) += psci.o obj-$(CONFIG_ARM_PSCI_CHECKER) += psci_checker.o obj-$(CONFIG_ARM_SCPI_PROTOCOL) += arm_scpi.o obj-$(CONFIG_ARM_SCPI_POWER_DOMAIN) += scpi_pm_domain.o +obj-$(CONFIG_ARM_SDE_INTERFACE) += arm_sdei.o obj-$(CONFIG_DMI) += dmi_scan.o obj-$(CONFIG_DMI_SYSFS) += dmi-sysfs.o obj-$(CONFIG_EDD) += edd.o diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c new file mode 100644 index 000000000000..8da173cc7e43 --- /dev/null +++ b/drivers/firmware/arm_sdei.c @@ -0,0 +1,619 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2017 Arm Ltd. +#define pr_fmt(fmt) "sdei: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The call to use to reach the firmware. + */ +static asmlinkage void (*sdei_firmware_call)(unsigned long function_id, + unsigned long arg0, unsigned long arg1, + unsigned long arg2, unsigned long arg3, + unsigned long arg4, struct arm_smccc_res *res); + +/* entry point from firmware to arch asm code */ +static unsigned long sdei_entry_point; + +struct sdei_event { + struct list_head list; + u32 event_num; + u8 type; + u8 priority; + + /* This pointer is handed to firmware as the event argument. */ + struct sdei_registered_event *registered; +}; + +/* Take the mutex for any API call or modification. Take the mutex first. */ +static DEFINE_MUTEX(sdei_events_lock); + +/* and then hold this when modifying the list */ +static DEFINE_SPINLOCK(sdei_list_lock); +static LIST_HEAD(sdei_list); + +static int sdei_to_linux_errno(unsigned long sdei_err) +{ + switch (sdei_err) { + case SDEI_NOT_SUPPORTED: + return -EOPNOTSUPP; + case SDEI_INVALID_PARAMETERS: + return -EINVAL; + case SDEI_DENIED: + return -EPERM; + case SDEI_PENDING: + return -EINPROGRESS; + case SDEI_OUT_OF_RESOURCE: + return -ENOMEM; + } + + /* Not an error value ... */ + return sdei_err; +} + +/* + * If x0 is any of these values, then the call failed, use sdei_to_linux_errno() + * to translate. + */ +static int sdei_is_err(struct arm_smccc_res *res) +{ + switch (res->a0) { + case SDEI_NOT_SUPPORTED: + case SDEI_INVALID_PARAMETERS: + case SDEI_DENIED: + case SDEI_PENDING: + case SDEI_OUT_OF_RESOURCE: + return true; + } + + return false; +} + +static int invoke_sdei_fn(unsigned long function_id, unsigned long arg0, + unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4, + u64 *result) +{ + int err = 0; + struct arm_smccc_res res; + + if (sdei_firmware_call) { + sdei_firmware_call(function_id, arg0, arg1, arg2, arg3, arg4, + &res); + if (sdei_is_err(&res)) + err = sdei_to_linux_errno(res.a0); + } else { + /* + * !sdei_firmware_call means we failed to probe or called + * sdei_mark_interface_broken(). -EIO is not an error returned + * by sdei_to_linux_errno() and is used to suppress messages + * from this driver. + */ + err = -EIO; + res.a0 = SDEI_NOT_SUPPORTED; + } + + if (result) + *result = res.a0; + + return err; +} + +static struct sdei_event *sdei_event_find(u32 event_num) +{ + struct sdei_event *e, *found = NULL; + + lockdep_assert_held(&sdei_events_lock); + + spin_lock(&sdei_list_lock); + list_for_each_entry(e, &sdei_list, list) { + if (e->event_num == event_num) { + found = e; + break; + } + } + spin_unlock(&sdei_list_lock); + + return found; +} + +int sdei_api_event_context(u32 query, u64 *result) +{ + return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_CONTEXT, query, 0, 0, 0, 0, + result); +} +NOKPROBE_SYMBOL(sdei_api_event_context); + +static int sdei_api_event_get_info(u32 event, u32 info, u64 *result) +{ + return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_GET_INFO, event, info, 0, + 0, 0, result); +} + +static struct sdei_event *sdei_event_create(u32 event_num, + sdei_event_callback *cb, + void *cb_arg) +{ + int err; + u64 result; + struct sdei_event *event; + struct sdei_registered_event *reg; + + lockdep_assert_held(&sdei_events_lock); + + event = kzalloc(sizeof(*event), GFP_KERNEL); + if (!event) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&event->list); + event->event_num = event_num; + + err = sdei_api_event_get_info(event_num, SDEI_EVENT_INFO_EV_PRIORITY, + &result); + if (err) { + kfree(event); + return ERR_PTR(err); + } + event->priority = result; + + err = sdei_api_event_get_info(event_num, SDEI_EVENT_INFO_EV_TYPE, + &result); + if (err) { + kfree(event); + return ERR_PTR(err); + } + event->type = result; + + if (event->type == SDEI_EVENT_TYPE_SHARED) { + reg = kzalloc(sizeof(*reg), GFP_KERNEL); + if (!reg) { + kfree(event); + return ERR_PTR(-ENOMEM); + } + + reg->event_num = event_num; + reg->priority = event->priority; + + reg->callback = cb; + reg->callback_arg = cb_arg; + event->registered = reg; + } + + if (sdei_event_find(event_num)) { + kfree(event->registered); + kfree(event); + event = ERR_PTR(-EBUSY); + } else { + spin_lock(&sdei_list_lock); + list_add(&event->list, &sdei_list); + spin_unlock(&sdei_list_lock); + } + + return event; +} + +static void sdei_event_destroy(struct sdei_event *event) +{ + lockdep_assert_held(&sdei_events_lock); + + spin_lock(&sdei_list_lock); + list_del(&event->list); + spin_unlock(&sdei_list_lock); + + if (event->type == SDEI_EVENT_TYPE_SHARED) + kfree(event->registered); + + kfree(event); +} + +static int sdei_api_get_version(u64 *version) +{ + return invoke_sdei_fn(SDEI_1_0_FN_SDEI_VERSION, 0, 0, 0, 0, 0, version); +} + +int sdei_mask_local_cpu(void) +{ + int err; + + WARN_ON_ONCE(preemptible()); + + err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PE_MASK, 0, 0, 0, 0, 0, NULL); + if (err && err != -EIO) { + pr_warn_once("failed to mask CPU[%u]: %d\n", + smp_processor_id(), err); + return err; + } + + return 0; +} + +static void _ipi_mask_cpu(void *ignored) +{ + sdei_mask_local_cpu(); +} + +int sdei_unmask_local_cpu(void) +{ + int err; + + WARN_ON_ONCE(preemptible()); + + err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PE_UNMASK, 0, 0, 0, 0, 0, NULL); + if (err && err != -EIO) { + pr_warn_once("failed to unmask CPU[%u]: %d\n", + smp_processor_id(), err); + return err; + } + + return 0; +} + +static void _ipi_unmask_cpu(void *ignored) +{ + sdei_unmask_local_cpu(); +} + +static void _ipi_private_reset(void *ignored) +{ + int err; + + err = invoke_sdei_fn(SDEI_1_0_FN_SDEI_PRIVATE_RESET, 0, 0, 0, 0, 0, + NULL); + if (err && err != -EIO) + pr_warn_once("failed to reset CPU[%u]: %d\n", + smp_processor_id(), err); +} + +static int sdei_api_shared_reset(void) +{ + return invoke_sdei_fn(SDEI_1_0_FN_SDEI_SHARED_RESET, 0, 0, 0, 0, 0, + NULL); +} + +static void sdei_mark_interface_broken(void) +{ + pr_err("disabling SDEI firmware interface\n"); + on_each_cpu(&_ipi_mask_cpu, NULL, true); + sdei_firmware_call = NULL; +} + +static int sdei_platform_reset(void) +{ + int err; + + on_each_cpu(&_ipi_private_reset, NULL, true); + err = sdei_api_shared_reset(); + if (err) { + pr_err("Failed to reset platform: %d\n", err); + sdei_mark_interface_broken(); + } + + return err; +} + +static int sdei_api_event_enable(u32 event_num) +{ + return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_ENABLE, event_num, 0, 0, 0, + 0, NULL); +} + +int sdei_event_enable(u32 event_num) +{ + int err = -EINVAL; + struct sdei_event *event; + + mutex_lock(&sdei_events_lock); + event = sdei_event_find(event_num); + if (!event) { + mutex_unlock(&sdei_events_lock); + return -ENOENT; + } + + if (event->type == SDEI_EVENT_TYPE_SHARED) + err = sdei_api_event_enable(event->event_num); + mutex_unlock(&sdei_events_lock); + + return err; +} +EXPORT_SYMBOL(sdei_event_enable); + +static int sdei_api_event_disable(u32 event_num) +{ + return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_DISABLE, event_num, 0, 0, + 0, 0, NULL); +} + +int sdei_event_disable(u32 event_num) +{ + int err = -EINVAL; + struct sdei_event *event; + + mutex_lock(&sdei_events_lock); + event = sdei_event_find(event_num); + if (!event) { + mutex_unlock(&sdei_events_lock); + return -ENOENT; + } + + if (event->type == SDEI_EVENT_TYPE_SHARED) + err = sdei_api_event_disable(event->event_num); + mutex_unlock(&sdei_events_lock); + + return err; +} +EXPORT_SYMBOL(sdei_event_disable); + +static int sdei_api_event_unregister(u32 event_num) +{ + return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_UNREGISTER, event_num, 0, + 0, 0, 0, NULL); +} + +static int _sdei_event_unregister(struct sdei_event *event) +{ + lockdep_assert_held(&sdei_events_lock); + + if (event->type == SDEI_EVENT_TYPE_SHARED) + return sdei_api_event_unregister(event->event_num); + + return -EINVAL; +} + +int sdei_event_unregister(u32 event_num) +{ + int err; + struct sdei_event *event; + + WARN_ON(in_nmi()); + + mutex_lock(&sdei_events_lock); + event = sdei_event_find(event_num); + do { + if (!event) { + pr_warn("Event %u not registered\n", event_num); + err = -ENOENT; + break; + } + + err = _sdei_event_unregister(event); + if (err) + break; + + sdei_event_destroy(event); + } while (0); + mutex_unlock(&sdei_events_lock); + + return err; +} +EXPORT_SYMBOL(sdei_event_unregister); + +static int sdei_api_event_register(u32 event_num, unsigned long entry_point, + void *arg, u64 flags, u64 affinity) +{ + return invoke_sdei_fn(SDEI_1_0_FN_SDEI_EVENT_REGISTER, event_num, + (unsigned long)entry_point, (unsigned long)arg, + flags, affinity, NULL); +} + +static int _sdei_event_register(struct sdei_event *event) +{ + lockdep_assert_held(&sdei_events_lock); + + if (event->type == SDEI_EVENT_TYPE_SHARED) + return sdei_api_event_register(event->event_num, + sdei_entry_point, + event->registered, + SDEI_EVENT_REGISTER_RM_ANY, 0); + + return -EINVAL; +} + +int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg) +{ + int err; + struct sdei_event *event; + + WARN_ON(in_nmi()); + + mutex_lock(&sdei_events_lock); + do { + if (sdei_event_find(event_num)) { + pr_warn("Event %u already registered\n", event_num); + err = -EBUSY; + break; + } + + event = sdei_event_create(event_num, cb, arg); + if (IS_ERR(event)) { + err = PTR_ERR(event); + pr_warn("Failed to create event %u: %d\n", event_num, + err); + break; + } + + err = _sdei_event_register(event); + if (err) { + sdei_event_destroy(event); + pr_warn("Failed to register event %u: %d\n", event_num, + err); + } + } while (0); + mutex_unlock(&sdei_events_lock); + + return err; +} +EXPORT_SYMBOL(sdei_event_register); + +static void sdei_smccc_smc(unsigned long function_id, + unsigned long arg0, unsigned long arg1, + unsigned long arg2, unsigned long arg3, + unsigned long arg4, struct arm_smccc_res *res) +{ + arm_smccc_smc(function_id, arg0, arg1, arg2, arg3, arg4, 0, 0, res); +} + +static void sdei_smccc_hvc(unsigned long function_id, + unsigned long arg0, unsigned long arg1, + unsigned long arg2, unsigned long arg3, + unsigned long arg4, struct arm_smccc_res *res) +{ + arm_smccc_hvc(function_id, arg0, arg1, arg2, arg3, arg4, 0, 0, res); +} + +static int sdei_get_conduit(struct platform_device *pdev) +{ + const char *method; + struct device_node *np = pdev->dev.of_node; + + sdei_firmware_call = NULL; + if (np) { + if (of_property_read_string(np, "method", &method)) { + pr_warn("missing \"method\" property\n"); + return CONDUIT_INVALID; + } + + if (!strcmp("hvc", method)) { + sdei_firmware_call = &sdei_smccc_hvc; + return CONDUIT_HVC; + } else if (!strcmp("smc", method)) { + sdei_firmware_call = &sdei_smccc_smc; + return CONDUIT_SMC; + } + + pr_warn("invalid \"method\" property: %s\n", method); + } + + return CONDUIT_INVALID; +} + +static int sdei_probe(struct platform_device *pdev) +{ + int err; + u64 ver = 0; + int conduit; + + conduit = sdei_get_conduit(pdev); + if (!sdei_firmware_call) + return 0; + + err = sdei_api_get_version(&ver); + if (err == -EOPNOTSUPP) + pr_err("advertised but not implemented in platform firmware\n"); + if (err) { + pr_err("Failed to get SDEI version: %d\n", err); + sdei_mark_interface_broken(); + return err; + } + + pr_info("SDEIv%d.%d (0x%x) detected in firmware.\n", + (int)SDEI_VERSION_MAJOR(ver), (int)SDEI_VERSION_MINOR(ver), + (int)SDEI_VERSION_VENDOR(ver)); + + if (SDEI_VERSION_MAJOR(ver) != 1) { + pr_warn("Conflicting SDEI version detected.\n"); + sdei_mark_interface_broken(); + return -EINVAL; + } + + err = sdei_platform_reset(); + if (err) + return err; + + sdei_entry_point = sdei_arch_get_entry_point(conduit); + if (!sdei_entry_point) { + /* Not supported due to hardware or boot configuration */ + sdei_mark_interface_broken(); + return 0; + } + + on_each_cpu(&_ipi_unmask_cpu, NULL, false); + + return 0; +} + +static const struct of_device_id sdei_of_match[] = { + { .compatible = "arm,sdei-1.0" }, + {} +}; + +static struct platform_driver sdei_driver = { + .driver = { + .name = "sdei", + .of_match_table = sdei_of_match, + }, + .probe = sdei_probe, +}; + +static bool __init sdei_present_dt(void) +{ + struct platform_device *pdev; + struct device_node *np, *fw_np; + + fw_np = of_find_node_by_name(NULL, "firmware"); + if (!fw_np) + return false; + + np = of_find_matching_node(fw_np, sdei_of_match); + of_node_put(fw_np); + if (!np) + return false; + + pdev = of_platform_device_create(np, sdei_driver.driver.name, NULL); + of_node_put(np); + if (IS_ERR(pdev)) + return false; + + return true; +} + +static int __init sdei_init(void) +{ + if (sdei_present_dt()) + platform_driver_register(&sdei_driver); + + return 0; +} + +subsys_initcall_sync(sdei_init); + +int sdei_event_handler(struct pt_regs *regs, + struct sdei_registered_event *arg) +{ + int err; + mm_segment_t orig_addr_limit; + u32 event_num = arg->event_num; + + orig_addr_limit = get_fs(); + set_fs(USER_DS); + + err = arg->callback(event_num, regs, arg->callback_arg); + if (err) + pr_err_ratelimited("event %u on CPU %u failed with error: %d\n", + event_num, smp_processor_id(), err); + + set_fs(orig_addr_limit); + + return err; +} +NOKPROBE_SYMBOL(sdei_event_handler); diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h new file mode 100644 index 000000000000..942afbd544b7 --- /dev/null +++ b/include/linux/arm_sdei.h @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2017 Arm Ltd. +#ifndef __LINUX_ARM_SDEI_H +#define __LINUX_ARM_SDEI_H + +#include + +enum sdei_conduit_types { + CONDUIT_INVALID = 0, + CONDUIT_SMC, + CONDUIT_HVC, +}; + +#include + +/* Arch code should override this to set the entry point from firmware... */ +#ifndef sdei_arch_get_entry_point +#define sdei_arch_get_entry_point(conduit) (0) +#endif + +/* + * When an event occurs sdei_event_handler() will call a user-provided callback + * like this in NMI context on the CPU that received the event. + */ +typedef int (sdei_event_callback)(u32 event, struct pt_regs *regs, void *arg); + +/* + * Register your callback to claim an event. The event must be described + * by firmware. + */ +int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg); + +/* + * Calls to sdei_event_unregister() may return EINPROGRESS. Keep calling + * it until it succeeds. + */ +int sdei_event_unregister(u32 event_num); + +int sdei_event_enable(u32 event_num); +int sdei_event_disable(u32 event_num); + +#ifdef CONFIG_ARM_SDE_INTERFACE +/* For use by arch code when CPU hotplug notifiers are not appropriate. */ +int sdei_mask_local_cpu(void); +int sdei_unmask_local_cpu(void); +#else +static inline int sdei_mask_local_cpu(void) { return 0; } +static inline int sdei_unmask_local_cpu(void) { return 0; } +#endif /* CONFIG_ARM_SDE_INTERFACE */ + + +/* + * This struct represents an event that has been registered. The driver + * maintains a list of all events, and which ones are registered. (Private + * events have one entry in the list, but are registered on each CPU). + * A pointer to this struct is passed to firmware, and back to the event + * handler. The event handler can then use this to invoke the registered + * callback, without having to walk the list. + * + * For CPU private events, this structure is per-cpu. + */ +struct sdei_registered_event { + /* For use by arch code: */ + struct pt_regs interrupted_regs; + + sdei_event_callback *callback; + void *callback_arg; + u32 event_num; + u8 priority; +}; + +/* The arch code entry point should then call this when an event arrives. */ +int notrace sdei_event_handler(struct pt_regs *regs, + struct sdei_registered_event *arg); + +/* arch code may use this to retrieve the extra registers. */ +int sdei_api_event_context(u32 query, u64 *result); + +#endif /* __LINUX_ARM_SDEI_H */ diff --git a/include/uapi/linux/arm_sdei.h b/include/uapi/linux/arm_sdei.h new file mode 100644 index 000000000000..af0630ba5437 --- /dev/null +++ b/include/uapi/linux/arm_sdei.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* Copyright (C) 2017 Arm Ltd. */ +#ifndef _UAPI_LINUX_ARM_SDEI_H +#define _UAPI_LINUX_ARM_SDEI_H + +#define SDEI_1_0_FN_BASE 0xC4000020 +#define SDEI_1_0_MASK 0xFFFFFFE0 +#define SDEI_1_0_FN(n) (SDEI_1_0_FN_BASE + (n)) + +#define SDEI_1_0_FN_SDEI_VERSION SDEI_1_0_FN(0x00) +#define SDEI_1_0_FN_SDEI_EVENT_REGISTER SDEI_1_0_FN(0x01) +#define SDEI_1_0_FN_SDEI_EVENT_ENABLE SDEI_1_0_FN(0x02) +#define SDEI_1_0_FN_SDEI_EVENT_DISABLE SDEI_1_0_FN(0x03) +#define SDEI_1_0_FN_SDEI_EVENT_CONTEXT SDEI_1_0_FN(0x04) +#define SDEI_1_0_FN_SDEI_EVENT_COMPLETE SDEI_1_0_FN(0x05) +#define SDEI_1_0_FN_SDEI_EVENT_COMPLETE_AND_RESUME SDEI_1_0_FN(0x06) +#define SDEI_1_0_FN_SDEI_EVENT_UNREGISTER SDEI_1_0_FN(0x07) +#define SDEI_1_0_FN_SDEI_EVENT_STATUS SDEI_1_0_FN(0x08) +#define SDEI_1_0_FN_SDEI_EVENT_GET_INFO SDEI_1_0_FN(0x09) +#define SDEI_1_0_FN_SDEI_EVENT_ROUTING_SET SDEI_1_0_FN(0x0A) +#define SDEI_1_0_FN_SDEI_PE_MASK SDEI_1_0_FN(0x0B) +#define SDEI_1_0_FN_SDEI_PE_UNMASK SDEI_1_0_FN(0x0C) +#define SDEI_1_0_FN_SDEI_INTERRUPT_BIND SDEI_1_0_FN(0x0D) +#define SDEI_1_0_FN_SDEI_INTERRUPT_RELEASE SDEI_1_0_FN(0x0E) +#define SDEI_1_0_FN_SDEI_PRIVATE_RESET SDEI_1_0_FN(0x11) +#define SDEI_1_0_FN_SDEI_SHARED_RESET SDEI_1_0_FN(0x12) + +#define SDEI_VERSION_MAJOR_SHIFT 48 +#define SDEI_VERSION_MAJOR_MASK 0x7fff +#define SDEI_VERSION_MINOR_SHIFT 32 +#define SDEI_VERSION_MINOR_MASK 0xffff +#define SDEI_VERSION_VENDOR_SHIFT 0 +#define SDEI_VERSION_VENDOR_MASK 0xffffffff + +#define SDEI_VERSION_MAJOR(x) (x>>SDEI_VERSION_MAJOR_SHIFT & SDEI_VERSION_MAJOR_MASK) +#define SDEI_VERSION_MINOR(x) (x>>SDEI_VERSION_MINOR_SHIFT & SDEI_VERSION_MINOR_MASK) +#define SDEI_VERSION_VENDOR(x) (x>>SDEI_VERSION_VENDOR_SHIFT & SDEI_VERSION_VENDOR_MASK) + +/* SDEI return values */ +#define SDEI_SUCCESS 0 +#define SDEI_NOT_SUPPORTED -1 +#define SDEI_INVALID_PARAMETERS -2 +#define SDEI_DENIED -3 +#define SDEI_PENDING -5 +#define SDEI_OUT_OF_RESOURCE -10 + +/* EVENT_REGISTER flags */ +#define SDEI_EVENT_REGISTER_RM_ANY 0 +#define SDEI_EVENT_REGISTER_RM_PE 1 + +/* EVENT_STATUS return value bits */ +#define SDEI_EVENT_STATUS_RUNNING 2 +#define SDEI_EVENT_STATUS_ENABLED 1 +#define SDEI_EVENT_STATUS_REGISTERED 0 + +/* EVENT_COMPLETE status values */ +#define SDEI_EV_HANDLED 0 +#define SDEI_EV_FAILED 1 + +/* GET_INFO values */ +#define SDEI_EVENT_INFO_EV_TYPE 0 +#define SDEI_EVENT_INFO_EV_SIGNALED 1 +#define SDEI_EVENT_INFO_EV_PRIORITY 2 +#define SDEI_EVENT_INFO_EV_ROUTING_MODE 3 +#define SDEI_EVENT_INFO_EV_ROUTING_AFF 4 + +/* and their results */ +#define SDEI_EVENT_TYPE_PRIVATE 0 +#define SDEI_EVENT_TYPE_SHARED 1 +#define SDEI_EVENT_PRIORITY_NORMAL 0 +#define SDEI_EVENT_PRIORITY_CRITICAL 1 + +#endif /* _UAPI_LINUX_ARM_SDEI_H */ -- cgit v1.2.3-59-g8ed1b From a38845729ea3985db5d2544ec3ef3dc8f6313a27 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 11 Jan 2018 20:29:09 -0800 Subject: bpf: offload: add map offload infrastructure BPF map offload follow similar path to program offload. At creation time users may specify ifindex of the device on which they want to create the map. Map will be validated by the kernel's .map_alloc_check callback and device driver will be called for the actual allocation. Map will have an empty set of operations associated with it (save for alloc and free callbacks). The real device callbacks are kept in map->offload->dev_ops because they have slightly different signatures. Map operations are called in process context so the driver may communicate with HW freely, msleep(), wait() etc. Map alloc and free callbacks are muxed via existing .ndo_bpf, and are always called with rtnl lock held. Maps and programs are guaranteed to be destroyed before .ndo_uninit (i.e. before unregister_netdev() returns). Map callbacks are invoked with bpf_devs_lock *read* locked, drivers must take care of exclusive locking if necessary. All offload-specific branches are marked with unlikely() (through bpf_map_is_dev_bound()), given that branch penalty will be negligible compared to IO anyway, and we don't want to penalize SW path unnecessarily. Signed-off-by: Jakub Kicinski Reviewed-by: Quentin Monnet Signed-off-by: Daniel Borkmann --- include/linux/bpf.h | 59 +++++++++++++ include/linux/netdevice.h | 6 ++ include/uapi/linux/bpf.h | 1 + kernel/bpf/offload.c | 188 +++++++++++++++++++++++++++++++++++++++-- kernel/bpf/syscall.c | 44 ++++++++-- kernel/bpf/verifier.c | 7 ++ tools/include/uapi/linux/bpf.h | 1 + 7 files changed, 293 insertions(+), 13 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 9fff1ace1d8e..5c2c104dc2c5 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -74,6 +74,33 @@ struct bpf_map { char name[BPF_OBJ_NAME_LEN]; }; +struct bpf_offloaded_map; + +struct bpf_map_dev_ops { + int (*map_get_next_key)(struct bpf_offloaded_map *map, + void *key, void *next_key); + int (*map_lookup_elem)(struct bpf_offloaded_map *map, + void *key, void *value); + int (*map_update_elem)(struct bpf_offloaded_map *map, + void *key, void *value, u64 flags); + int (*map_delete_elem)(struct bpf_offloaded_map *map, void *key); +}; + +struct bpf_offloaded_map { + struct bpf_map map; + struct net_device *netdev; + const struct bpf_map_dev_ops *dev_ops; + void *dev_priv; + struct list_head offloads; +}; + +static inline struct bpf_offloaded_map *map_to_offmap(struct bpf_map *map) +{ + return container_of(map, struct bpf_offloaded_map, map); +} + +extern const struct bpf_map_ops bpf_map_offload_ops; + /* function argument constraints */ enum bpf_arg_type { ARG_DONTCARE = 0, /* unused argument in helper function */ @@ -369,6 +396,7 @@ int __bpf_prog_charge(struct user_struct *user, u32 pages); void __bpf_prog_uncharge(struct user_struct *user, u32 pages); void bpf_prog_free_id(struct bpf_prog *prog, bool do_idr_lock); +void bpf_map_free_id(struct bpf_map *map, bool do_idr_lock); struct bpf_map *bpf_map_get_with_uref(u32 ufd); struct bpf_map *__bpf_map_get(struct fd f); @@ -556,6 +584,15 @@ void bpf_prog_offload_destroy(struct bpf_prog *prog); int bpf_prog_offload_info_fill(struct bpf_prog_info *info, struct bpf_prog *prog); +int bpf_map_offload_lookup_elem(struct bpf_map *map, void *key, void *value); +int bpf_map_offload_update_elem(struct bpf_map *map, + void *key, void *value, u64 flags); +int bpf_map_offload_delete_elem(struct bpf_map *map, void *key); +int bpf_map_offload_get_next_key(struct bpf_map *map, + void *key, void *next_key); + +bool bpf_offload_dev_match(struct bpf_prog *prog, struct bpf_map *map); + #if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL) int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr); @@ -563,6 +600,14 @@ static inline bool bpf_prog_is_dev_bound(struct bpf_prog_aux *aux) { return aux->offload_requested; } + +static inline bool bpf_map_is_dev_bound(struct bpf_map *map) +{ + return unlikely(map->ops == &bpf_map_offload_ops); +} + +struct bpf_map *bpf_map_offload_map_alloc(union bpf_attr *attr); +void bpf_map_offload_map_free(struct bpf_map *map); #else static inline int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr) @@ -574,6 +619,20 @@ static inline bool bpf_prog_is_dev_bound(struct bpf_prog_aux *aux) { return false; } + +static inline bool bpf_map_is_dev_bound(struct bpf_map *map) +{ + return false; +} + +static inline struct bpf_map *bpf_map_offload_map_alloc(union bpf_attr *attr) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static inline void bpf_map_offload_map_free(struct bpf_map *map) +{ +} #endif /* CONFIG_NET && CONFIG_BPF_SYSCALL */ #if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL) && defined(CONFIG_INET) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index ef7b348e8498..0b3ab42d50fe 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -804,6 +804,8 @@ enum bpf_netdev_command { BPF_OFFLOAD_VERIFIER_PREP, BPF_OFFLOAD_TRANSLATE, BPF_OFFLOAD_DESTROY, + BPF_OFFLOAD_MAP_ALLOC, + BPF_OFFLOAD_MAP_FREE, }; struct bpf_prog_offload_ops; @@ -834,6 +836,10 @@ struct netdev_bpf { struct { struct bpf_prog *prog; } offload; + /* BPF_OFFLOAD_MAP_ALLOC, BPF_OFFLOAD_MAP_FREE */ + struct { + struct bpf_offloaded_map *offmap; + }; }; }; diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 395d261948de..7c2259e8bc54 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -245,6 +245,7 @@ union bpf_attr { * BPF_F_NUMA_NODE is set). */ char map_name[BPF_OBJ_NAME_LEN]; + __u32 map_ifindex; /* ifindex of netdev to create on */ }; struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */ diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c index cdd1e19a668b..453785fa1881 100644 --- a/kernel/bpf/offload.c +++ b/kernel/bpf/offload.c @@ -24,11 +24,13 @@ #include #include -/* Protects bpf_prog_offload_devs and offload members of all progs. +/* Protects bpf_prog_offload_devs, bpf_map_offload_devs and offload members + * of all progs. * RTNL lock cannot be taken when holding this lock. */ static DECLARE_RWSEM(bpf_devs_lock); static LIST_HEAD(bpf_prog_offload_devs); +static LIST_HEAD(bpf_map_offload_devs); static int bpf_dev_offload_check(struct net_device *netdev) { @@ -250,11 +252,186 @@ int bpf_prog_offload_info_fill(struct bpf_prog_info *info, const struct bpf_prog_ops bpf_offload_prog_ops = { }; +static int bpf_map_offload_ndo(struct bpf_offloaded_map *offmap, + enum bpf_netdev_command cmd) +{ + struct netdev_bpf data = {}; + struct net_device *netdev; + + ASSERT_RTNL(); + + data.command = cmd; + data.offmap = offmap; + /* Caller must make sure netdev is valid */ + netdev = offmap->netdev; + + return netdev->netdev_ops->ndo_bpf(netdev, &data); +} + +struct bpf_map *bpf_map_offload_map_alloc(union bpf_attr *attr) +{ + struct net *net = current->nsproxy->net_ns; + struct bpf_offloaded_map *offmap; + int err; + + if (!capable(CAP_SYS_ADMIN)) + return ERR_PTR(-EPERM); + if (attr->map_type != BPF_MAP_TYPE_HASH) + return ERR_PTR(-EINVAL); + + offmap = kzalloc(sizeof(*offmap), GFP_USER); + if (!offmap) + return ERR_PTR(-ENOMEM); + + bpf_map_init_from_attr(&offmap->map, attr); + + rtnl_lock(); + down_write(&bpf_devs_lock); + offmap->netdev = __dev_get_by_index(net, attr->map_ifindex); + err = bpf_dev_offload_check(offmap->netdev); + if (err) + goto err_unlock; + + err = bpf_map_offload_ndo(offmap, BPF_OFFLOAD_MAP_ALLOC); + if (err) + goto err_unlock; + + list_add_tail(&offmap->offloads, &bpf_map_offload_devs); + up_write(&bpf_devs_lock); + rtnl_unlock(); + + return &offmap->map; + +err_unlock: + up_write(&bpf_devs_lock); + rtnl_unlock(); + kfree(offmap); + return ERR_PTR(err); +} + +static void __bpf_map_offload_destroy(struct bpf_offloaded_map *offmap) +{ + WARN_ON(bpf_map_offload_ndo(offmap, BPF_OFFLOAD_MAP_FREE)); + /* Make sure BPF_MAP_GET_NEXT_ID can't find this dead map */ + bpf_map_free_id(&offmap->map, true); + list_del_init(&offmap->offloads); + offmap->netdev = NULL; +} + +void bpf_map_offload_map_free(struct bpf_map *map) +{ + struct bpf_offloaded_map *offmap = map_to_offmap(map); + + rtnl_lock(); + down_write(&bpf_devs_lock); + if (offmap->netdev) + __bpf_map_offload_destroy(offmap); + up_write(&bpf_devs_lock); + rtnl_unlock(); + + kfree(offmap); +} + +int bpf_map_offload_lookup_elem(struct bpf_map *map, void *key, void *value) +{ + struct bpf_offloaded_map *offmap = map_to_offmap(map); + int ret = -ENODEV; + + down_read(&bpf_devs_lock); + if (offmap->netdev) + ret = offmap->dev_ops->map_lookup_elem(offmap, key, value); + up_read(&bpf_devs_lock); + + return ret; +} + +int bpf_map_offload_update_elem(struct bpf_map *map, + void *key, void *value, u64 flags) +{ + struct bpf_offloaded_map *offmap = map_to_offmap(map); + int ret = -ENODEV; + + if (unlikely(flags > BPF_EXIST)) + return -EINVAL; + + down_read(&bpf_devs_lock); + if (offmap->netdev) + ret = offmap->dev_ops->map_update_elem(offmap, key, value, + flags); + up_read(&bpf_devs_lock); + + return ret; +} + +int bpf_map_offload_delete_elem(struct bpf_map *map, void *key) +{ + struct bpf_offloaded_map *offmap = map_to_offmap(map); + int ret = -ENODEV; + + down_read(&bpf_devs_lock); + if (offmap->netdev) + ret = offmap->dev_ops->map_delete_elem(offmap, key); + up_read(&bpf_devs_lock); + + return ret; +} + +int bpf_map_offload_get_next_key(struct bpf_map *map, void *key, void *next_key) +{ + struct bpf_offloaded_map *offmap = map_to_offmap(map); + int ret = -ENODEV; + + down_read(&bpf_devs_lock); + if (offmap->netdev) + ret = offmap->dev_ops->map_get_next_key(offmap, key, next_key); + up_read(&bpf_devs_lock); + + return ret; +} + +bool bpf_offload_dev_match(struct bpf_prog *prog, struct bpf_map *map) +{ + struct bpf_offloaded_map *offmap; + struct bpf_prog_offload *offload; + bool ret; + + if (!!bpf_prog_is_dev_bound(prog->aux) != !!bpf_map_is_dev_bound(map)) + return false; + if (!bpf_prog_is_dev_bound(prog->aux)) + return true; + + down_read(&bpf_devs_lock); + offload = prog->aux->offload; + offmap = map_to_offmap(map); + + ret = offload && offload->netdev == offmap->netdev; + up_read(&bpf_devs_lock); + + return ret; +} + +static void bpf_offload_orphan_all_progs(struct net_device *netdev) +{ + struct bpf_prog_offload *offload, *tmp; + + list_for_each_entry_safe(offload, tmp, &bpf_prog_offload_devs, offloads) + if (offload->netdev == netdev) + __bpf_prog_offload_destroy(offload->prog); +} + +static void bpf_offload_orphan_all_maps(struct net_device *netdev) +{ + struct bpf_offloaded_map *offmap, *tmp; + + list_for_each_entry_safe(offmap, tmp, &bpf_map_offload_devs, offloads) + if (offmap->netdev == netdev) + __bpf_map_offload_destroy(offmap); +} + static int bpf_offload_notification(struct notifier_block *notifier, ulong event, void *ptr) { struct net_device *netdev = netdev_notifier_info_to_dev(ptr); - struct bpf_prog_offload *offload, *tmp; ASSERT_RTNL(); @@ -265,11 +442,8 @@ static int bpf_offload_notification(struct notifier_block *notifier, break; down_write(&bpf_devs_lock); - list_for_each_entry_safe(offload, tmp, &bpf_prog_offload_devs, - offloads) { - if (offload->netdev == netdev) - __bpf_prog_offload_destroy(offload->prog); - } + bpf_offload_orphan_all_progs(netdev); + bpf_offload_orphan_all_maps(netdev); up_write(&bpf_devs_lock); break; default: diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index a3f726bb42ea..c691b9e972e3 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -94,6 +94,11 @@ static int check_uarg_tail_zero(void __user *uaddr, return 0; } +const struct bpf_map_ops bpf_map_offload_ops = { + .map_alloc = bpf_map_offload_map_alloc, + .map_free = bpf_map_offload_map_free, +}; + static struct bpf_map *find_and_alloc_map(union bpf_attr *attr) { const struct bpf_map_ops *ops; @@ -111,6 +116,8 @@ static struct bpf_map *find_and_alloc_map(union bpf_attr *attr) if (err) return ERR_PTR(err); } + if (attr->map_ifindex) + ops = &bpf_map_offload_ops; map = ops->map_alloc(attr); if (IS_ERR(map)) return map; @@ -208,16 +215,25 @@ static int bpf_map_alloc_id(struct bpf_map *map) return id > 0 ? 0 : id; } -static void bpf_map_free_id(struct bpf_map *map, bool do_idr_lock) +void bpf_map_free_id(struct bpf_map *map, bool do_idr_lock) { unsigned long flags; + /* Offloaded maps are removed from the IDR store when their device + * disappears - even if someone holds an fd to them they are unusable, + * the memory is gone, all ops will fail; they are simply waiting for + * refcnt to drop to be freed. + */ + if (!map->id) + return; + if (do_idr_lock) spin_lock_irqsave(&map_idr_lock, flags); else __acquire(&map_idr_lock); idr_remove(&map_idr, map->id); + map->id = 0; if (do_idr_lock) spin_unlock_irqrestore(&map_idr_lock, flags); @@ -397,7 +413,7 @@ static int bpf_obj_name_cpy(char *dst, const char *src) return 0; } -#define BPF_MAP_CREATE_LAST_FIELD map_name +#define BPF_MAP_CREATE_LAST_FIELD map_ifindex /* called via syscall */ static int map_create(union bpf_attr *attr) { @@ -585,8 +601,10 @@ static int map_lookup_elem(union bpf_attr *attr) if (!value) goto free_key; - if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || - map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { + if (bpf_map_is_dev_bound(map)) { + err = bpf_map_offload_lookup_elem(map, key, value); + } else if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH || + map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) { err = bpf_percpu_hash_copy(map, key, value); } else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) { err = bpf_percpu_array_copy(map, key, value); @@ -673,7 +691,10 @@ static int map_update_elem(union bpf_attr *attr) goto free_value; /* Need to create a kthread, thus must support schedule */ - if (map->map_type == BPF_MAP_TYPE_CPUMAP) { + if (bpf_map_is_dev_bound(map)) { + err = bpf_map_offload_update_elem(map, key, value, attr->flags); + goto out; + } else if (map->map_type == BPF_MAP_TYPE_CPUMAP) { err = map->ops->map_update_elem(map, key, value, attr->flags); goto out; } @@ -750,6 +771,11 @@ static int map_delete_elem(union bpf_attr *attr) goto err_put; } + if (bpf_map_is_dev_bound(map)) { + err = bpf_map_offload_delete_elem(map, key); + goto out; + } + preempt_disable(); __this_cpu_inc(bpf_prog_active); rcu_read_lock(); @@ -757,7 +783,7 @@ static int map_delete_elem(union bpf_attr *attr) rcu_read_unlock(); __this_cpu_dec(bpf_prog_active); preempt_enable(); - +out: if (!err) trace_bpf_map_delete_elem(map, ufd, key); kfree(key); @@ -807,9 +833,15 @@ static int map_get_next_key(union bpf_attr *attr) if (!next_key) goto free_key; + if (bpf_map_is_dev_bound(map)) { + err = bpf_map_offload_get_next_key(map, key, next_key); + goto out; + } + rcu_read_lock(); err = map->ops->map_get_next_key(map, key, next_key); rcu_read_unlock(); +out: if (err) goto free_next_key; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 48b61caa94cb..ceabb394d2dc 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -4816,6 +4816,13 @@ static int check_map_prog_compatibility(struct bpf_verifier_env *env, return -EINVAL; } } + + if ((bpf_prog_is_dev_bound(prog->aux) || bpf_map_is_dev_bound(map)) && + !bpf_offload_dev_match(prog, map)) { + verbose(env, "offload device mismatch between prog and map\n"); + return -EINVAL; + } + return 0; } diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 4e8c60acfa32..69f96af4a569 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -245,6 +245,7 @@ union bpf_attr { * BPF_F_NUMA_NODE is set). */ char map_name[BPF_OBJ_NAME_LEN]; + __u32 map_ifindex; /* ifindex of netdev to create on */ }; struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */ -- cgit v1.2.3-59-g8ed1b From fb455baad6fc4de77d762e89dae75c2e2aa98559 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 4 Dec 2017 14:13:30 -0500 Subject: nfs: Define NFS_RDMA_PORT The NFS/RDMA port assignment is specified in Section 9 of RFC 8267. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- include/uapi/linux/nfs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/nfs.h b/include/uapi/linux/nfs.h index 057d22a48416..946cb62d64b0 100644 --- a/include/uapi/linux/nfs.h +++ b/include/uapi/linux/nfs.h @@ -12,6 +12,7 @@ #define NFS_PROGRAM 100003 #define NFS_PORT 2049 +#define NFS_RDMA_PORT 20049 #define NFS_MAXDATA 8192 #define NFS_MAXPATHLEN 1024 #define NFS_MAXNAMLEN 255 -- cgit v1.2.3-59-g8ed1b From 2290aefa2e90a43af8555ad6431d49de43259aa3 Mon Sep 17 00:00:00 2001 From: Franklin S Cooper Jr Date: Wed, 10 Jan 2018 16:25:18 +0530 Subject: can: dev: Add support for limiting configured bitrate Various CAN or CAN-FD IP may be able to run at a faster rate than what the transceiver the CAN node is connected to. This can lead to unexpected errors. However, CAN transceivers typically have fixed limitations and provide no means to discover these limitations at runtime. Therefore, add support for a can-transceiver node that can be reused by other CAN peripheral drivers to determine for both CAN and CAN-FD what the max bitrate that can be used. If the user tries to configure CAN to pass these maximum bitrates it will throw an error. Also add support for reading bitrate_max via the netlink interface. Reviewed-by: Suman Anna Signed-off-by: Franklin S Cooper Jr [nsekhar@ti.com: fix build error with !CONFIG_OF] Signed-off-by: Sekhar Nori Signed-off-by: Faiz Abbas Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 45 +++++++++++++++++++++++++++++++++++++++- include/linux/can/dev.h | 7 +++++++ include/uapi/linux/can/netlink.h | 1 + 3 files changed, 52 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 365a8cc62405..cc94604b23e0 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #define MOD_DESC "CAN device driver interface" @@ -814,6 +815,29 @@ int open_candev(struct net_device *dev) } EXPORT_SYMBOL_GPL(open_candev); +#ifdef CONFIG_OF +/* Common function that can be used to understand the limitation of + * a transceiver when it provides no means to determine these limitations + * at runtime. + */ +void of_can_transceiver(struct net_device *dev) +{ + struct device_node *dn; + struct can_priv *priv = netdev_priv(dev); + struct device_node *np = dev->dev.parent->of_node; + int ret; + + dn = of_get_child_by_name(np, "can-transceiver"); + if (!dn) + return; + + ret = of_property_read_u32(dn, "max-bitrate", &priv->bitrate_max); + if ((ret && ret != -EINVAL) || (!ret && !priv->bitrate_max)) + netdev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit.\n"); +} +EXPORT_SYMBOL_GPL(of_can_transceiver); +#endif + /* * Common close function for cleanup before the device gets closed. * @@ -913,6 +937,13 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[], priv->bitrate_const_cnt); if (err) return err; + + if (priv->bitrate_max && bt.bitrate > priv->bitrate_max) { + netdev_err(dev, "arbitration bitrate surpasses transceiver capabilities of %d bps\n", + priv->bitrate_max); + return -EINVAL; + } + memcpy(&priv->bittiming, &bt, sizeof(bt)); if (priv->do_set_bittiming) { @@ -997,6 +1028,13 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[], priv->data_bitrate_const_cnt); if (err) return err; + + if (priv->bitrate_max && dbt.bitrate > priv->bitrate_max) { + netdev_err(dev, "canfd data bitrate surpasses transceiver capabilities of %d bps\n", + priv->bitrate_max); + return -EINVAL; + } + memcpy(&priv->data_bittiming, &dbt, sizeof(dbt)); if (priv->do_set_data_bittiming) { @@ -1064,6 +1102,7 @@ static size_t can_get_size(const struct net_device *dev) if (priv->data_bitrate_const) /* IFLA_CAN_DATA_BITRATE_CONST */ size += nla_total_size(sizeof(*priv->data_bitrate_const) * priv->data_bitrate_const_cnt); + size += sizeof(priv->bitrate_max); /* IFLA_CAN_BITRATE_MAX */ return size; } @@ -1121,7 +1160,11 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev) nla_put(skb, IFLA_CAN_DATA_BITRATE_CONST, sizeof(*priv->data_bitrate_const) * priv->data_bitrate_const_cnt, - priv->data_bitrate_const)) + priv->data_bitrate_const)) || + + (nla_put(skb, IFLA_CAN_BITRATE_MAX, + sizeof(priv->bitrate_max), + &priv->bitrate_max)) ) return -EMSGSIZE; diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index 61f1cf2d9f44..055aaf5ed9af 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -46,6 +46,7 @@ struct can_priv { unsigned int bitrate_const_cnt; const u32 *data_bitrate_const; unsigned int data_bitrate_const_cnt; + u32 bitrate_max; struct can_clock clock; enum can_state state; @@ -166,6 +167,12 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx); void can_free_echo_skb(struct net_device *dev, unsigned int idx); +#ifdef CONFIG_OF +void of_can_transceiver(struct net_device *dev); +#else +static inline void of_can_transceiver(struct net_device *dev) { } +#endif + struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf); struct sk_buff *alloc_canfd_skb(struct net_device *dev, struct canfd_frame **cfd); diff --git a/include/uapi/linux/can/netlink.h b/include/uapi/linux/can/netlink.h index 96710e76d5ce..9f56fad4785b 100644 --- a/include/uapi/linux/can/netlink.h +++ b/include/uapi/linux/can/netlink.h @@ -132,6 +132,7 @@ enum { IFLA_CAN_TERMINATION_CONST, IFLA_CAN_BITRATE_CONST, IFLA_CAN_DATA_BITRATE_CONST, + IFLA_CAN_BITRATE_MAX, __IFLA_CAN_MAX }; -- cgit v1.2.3-59-g8ed1b From d9f9b9a4d05fab693fd23a9ecaa330e03ebe2c31 Mon Sep 17 00:00:00 2001 From: Arkadi Sharshevsky Date: Mon, 15 Jan 2018 08:59:03 +0100 Subject: devlink: Add support for resource abstraction Add support for hardware resource abstraction over devlink. Each resource is identified via id, furthermore it contains information regarding its size and its related sub resources. Each resource can also provide its current occupancy. In some cases the sizes of some resources can be changed, yet for those changes to take place a hot driver reload may be needed. The reload capability will be introduced in the next patch. Signed-off-by: Arkadi Sharshevsky Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- include/net/devlink.h | 96 +++++++++++ include/uapi/linux/devlink.h | 18 +++ net/core/devlink.c | 374 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 488 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/net/devlink.h b/include/net/devlink.h index 4d2c6fc94837..ceb1895d119b 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -26,6 +26,7 @@ struct devlink { struct list_head port_list; struct list_head sb_list; struct list_head dpipe_table_list; + struct list_head resource_list; struct devlink_dpipe_headers *dpipe_headers; const struct devlink_ops *ops; struct device *dev; @@ -224,6 +225,61 @@ struct devlink_dpipe_headers { unsigned int headers_count; }; +/** + * struct devlink_resource_ops - resource ops + * @occ_get: get the occupied size + * @size_validate: validate the size of the resource before update, reload + * is needed for changes to take place + */ +struct devlink_resource_ops { + u64 (*occ_get)(struct devlink *devlink); + int (*size_validate)(struct devlink *devlink, u64 size, + struct netlink_ext_ack *extack); +}; + +/** + * struct devlink_resource_size_params - resource's size parameters + * @size_min: minimum size which can be set + * @size_max: maximum size which can be set + * @size_granularity: size granularity + * @size_unit: resource's basic unit + */ +struct devlink_resource_size_params { + u64 size_min; + u64 size_max; + u64 size_granularity; + enum devlink_resource_unit unit; +}; + +/** + * struct devlink_resource - devlink resource + * @name: name of the resource + * @id: id, per devlink instance + * @size: size of the resource + * @size_new: updated size of the resource, reload is needed + * @size_valid: valid in case the total size of the resource is valid + * including its children + * @parent: parent resource + * @size_params: size parameters + * @list: parent list + * @resource_list: list of child resources + * @resource_ops: resource ops + */ +struct devlink_resource { + const char *name; + u64 id; + u64 size; + u64 size_new; + bool size_valid; + struct devlink_resource *parent; + struct devlink_resource_size_params *size_params; + struct list_head list; + struct list_head resource_list; + const struct devlink_resource_ops *resource_ops; +}; + +#define DEVLINK_RESOURCE_ID_PARENT_TOP 0 + struct devlink_ops { int (*port_type_set)(struct devlink_port *devlink_port, enum devlink_port_type port_type); @@ -333,6 +389,20 @@ extern struct devlink_dpipe_header devlink_dpipe_header_ethernet; extern struct devlink_dpipe_header devlink_dpipe_header_ipv4; extern struct devlink_dpipe_header devlink_dpipe_header_ipv6; +int devlink_resource_register(struct devlink *devlink, + const char *resource_name, + bool top_hierarchy, + u64 resource_size, + u64 resource_id, + u64 parent_resource_id, + struct devlink_resource_size_params *size_params, + const struct devlink_resource_ops *resource_ops); +void devlink_resources_unregister(struct devlink *devlink, + struct devlink_resource *resource); +int devlink_resource_size_get(struct devlink *devlink, + u64 resource_id, + u64 *p_resource_size); + #else static inline struct devlink *devlink_alloc(const struct devlink_ops *ops, @@ -469,6 +539,32 @@ devlink_dpipe_match_put(struct sk_buff *skb, return 0; } +static inline int +devlink_resource_register(struct devlink *devlink, + const char *resource_name, + bool top_hierarchy, + u64 resource_size, + u64 resource_id, + u64 parent_resource_id, + struct devlink_resource_size_params *size_params, + const struct devlink_resource_ops *resource_ops) +{ + return 0; +} + +static inline void +devlink_resources_unregister(struct devlink *devlink, + struct devlink_resource *resource) +{ +} + +static inline int +devlink_resource_size_get(struct devlink *devlink, u64 resource_id, + u64 *p_resource_size) +{ + return -EOPNOTSUPP; +} + #endif #endif /* _NET_DEVLINK_H_ */ diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index 6665df69e26a..f89950443e17 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -70,6 +70,8 @@ enum devlink_command { DEVLINK_CMD_DPIPE_ENTRIES_GET, DEVLINK_CMD_DPIPE_HEADERS_GET, DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET, + DEVLINK_CMD_RESOURCE_SET, + DEVLINK_CMD_RESOURCE_DUMP, /* add new commands above here */ __DEVLINK_CMD_MAX, @@ -202,6 +204,18 @@ enum devlink_attr { DEVLINK_ATTR_PAD, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, /* u8 */ + DEVLINK_ATTR_RESOURCE_LIST, /* nested */ + DEVLINK_ATTR_RESOURCE, /* nested */ + DEVLINK_ATTR_RESOURCE_NAME, /* string */ + DEVLINK_ATTR_RESOURCE_ID, /* u64 */ + DEVLINK_ATTR_RESOURCE_SIZE, /* u64 */ + DEVLINK_ATTR_RESOURCE_SIZE_NEW, /* u64 */ + DEVLINK_ATTR_RESOURCE_SIZE_VALID, /* u8 */ + DEVLINK_ATTR_RESOURCE_SIZE_MIN, /* u64 */ + DEVLINK_ATTR_RESOURCE_SIZE_MAX, /* u64 */ + DEVLINK_ATTR_RESOURCE_SIZE_GRAN, /* u64 */ + DEVLINK_ATTR_RESOURCE_UNIT, /* u8 */ + DEVLINK_ATTR_RESOURCE_OCC, /* u64 */ /* add new attributes above here, update the policy in devlink.c */ @@ -245,4 +259,8 @@ enum devlink_dpipe_header_id { DEVLINK_DPIPE_HEADER_IPV6, }; +enum devlink_resource_unit { + DEVLINK_RESOURCE_UNIT_ENTRY, +}; + #endif /* _UAPI_LINUX_DEVLINK_H_ */ diff --git a/net/core/devlink.c b/net/core/devlink.c index 2f71734c4ff6..89b3704fa450 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -2288,6 +2288,233 @@ static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb, counters_enable); } +struct devlink_resource * +devlink_resource_find(struct devlink *devlink, + struct devlink_resource *resource, u64 resource_id) +{ + struct list_head *resource_list; + + if (resource) + resource_list = &resource->resource_list; + else + resource_list = &devlink->resource_list; + + list_for_each_entry(resource, resource_list, list) { + struct devlink_resource *child_resource; + + if (resource->id == resource_id) + return resource; + + child_resource = devlink_resource_find(devlink, resource, + resource_id); + if (child_resource) + return child_resource; + } + return NULL; +} + +void devlink_resource_validate_children(struct devlink_resource *resource) +{ + struct devlink_resource *child_resource; + bool size_valid = true; + u64 parts_size = 0; + + if (list_empty(&resource->resource_list)) + goto out; + + list_for_each_entry(child_resource, &resource->resource_list, list) + parts_size += child_resource->size_new; + + if (parts_size > resource->size) + size_valid = false; +out: + resource->size_valid = size_valid; +} + +static int devlink_nl_cmd_resource_set(struct sk_buff *skb, + struct genl_info *info) +{ + struct devlink *devlink = info->user_ptr[0]; + struct devlink_resource *resource; + u64 resource_id; + u64 size; + int err; + + if (!info->attrs[DEVLINK_ATTR_RESOURCE_ID] || + !info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]) + return -EINVAL; + resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]); + + resource = devlink_resource_find(devlink, NULL, resource_id); + if (!resource) + return -EINVAL; + + if (!resource->resource_ops->size_validate) + return -EINVAL; + + size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]); + err = resource->resource_ops->size_validate(devlink, size, + info->extack); + if (err) + return err; + + resource->size_new = size; + devlink_resource_validate_children(resource); + if (resource->parent) + devlink_resource_validate_children(resource->parent); + return 0; +} + +static void +devlink_resource_size_params_put(struct devlink_resource *resource, + struct sk_buff *skb) +{ + struct devlink_resource_size_params *size_params; + + size_params = resource->size_params; + nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN, + size_params->size_granularity, DEVLINK_ATTR_PAD); + nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX, + size_params->size_max, DEVLINK_ATTR_PAD); + nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN, + size_params->size_min, DEVLINK_ATTR_PAD); + nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit); +} + +static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb, + struct devlink_resource *resource) +{ + struct devlink_resource *child_resource; + struct nlattr *child_resource_attr; + struct nlattr *resource_attr; + + resource_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE); + if (!resource_attr) + return -EMSGSIZE; + + if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) || + nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size, + DEVLINK_ATTR_PAD) || + nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id, + DEVLINK_ATTR_PAD)) + goto nla_put_failure; + if (resource->size != resource->size_new) + nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW, + resource->size_new, DEVLINK_ATTR_PAD); + if (resource->resource_ops && resource->resource_ops->occ_get) + nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC, + resource->resource_ops->occ_get(devlink), + DEVLINK_ATTR_PAD); + devlink_resource_size_params_put(resource, skb); + if (list_empty(&resource->resource_list)) + goto out; + + if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID, + resource->size_valid)) + goto nla_put_failure; + + child_resource_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE_LIST); + if (!child_resource_attr) + goto nla_put_failure; + + list_for_each_entry(child_resource, &resource->resource_list, list) { + if (devlink_resource_put(devlink, skb, child_resource)) + goto resource_put_failure; + } + + nla_nest_end(skb, child_resource_attr); +out: + nla_nest_end(skb, resource_attr); + return 0; + +resource_put_failure: + nla_nest_cancel(skb, child_resource_attr); +nla_put_failure: + nla_nest_cancel(skb, resource_attr); + return -EMSGSIZE; +} + +static int devlink_resource_fill(struct genl_info *info, + enum devlink_command cmd, int flags) +{ + struct devlink *devlink = info->user_ptr[0]; + struct devlink_resource *resource; + struct nlattr *resources_attr; + struct sk_buff *skb = NULL; + struct nlmsghdr *nlh; + bool incomplete; + void *hdr; + int i; + int err; + + resource = list_first_entry(&devlink->resource_list, + struct devlink_resource, list); +start_again: + err = devlink_dpipe_send_and_alloc_skb(&skb, info); + if (err) + return err; + + hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, + &devlink_nl_family, NLM_F_MULTI, cmd); + if (!hdr) { + nlmsg_free(skb); + return -EMSGSIZE; + } + + if (devlink_nl_put_handle(skb, devlink)) + goto nla_put_failure; + + resources_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE_LIST); + if (!resources_attr) + goto nla_put_failure; + + incomplete = false; + i = 0; + list_for_each_entry_from(resource, &devlink->resource_list, list) { + err = devlink_resource_put(devlink, skb, resource); + if (err) { + if (!i) + goto err_resource_put; + incomplete = true; + break; + } + i++; + } + nla_nest_end(skb, resources_attr); + genlmsg_end(skb, hdr); + if (incomplete) + goto start_again; +send_done: + nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq, + NLMSG_DONE, 0, flags | NLM_F_MULTI); + if (!nlh) { + err = devlink_dpipe_send_and_alloc_skb(&skb, info); + if (err) + goto err_skb_send_alloc; + goto send_done; + } + return genlmsg_reply(skb, info); + +nla_put_failure: + err = -EMSGSIZE; +err_resource_put: +err_skb_send_alloc: + genlmsg_cancel(skb, hdr); + nlmsg_free(skb); + return err; +} + +static int devlink_nl_cmd_resource_dump(struct sk_buff *skb, + struct genl_info *info) +{ + struct devlink *devlink = info->user_ptr[0]; + + if (list_empty(&devlink->resource_list)) + return -EOPNOTSUPP; + + return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0); +} + static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, @@ -2306,6 +2533,8 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 }, [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING }, [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 }, + [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64}, + [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64}, }; static const struct genl_ops devlink_nl_ops[] = { @@ -2466,6 +2695,20 @@ static const struct genl_ops devlink_nl_ops[] = { .flags = GENL_ADMIN_PERM, .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, }, + { + .cmd = DEVLINK_CMD_RESOURCE_SET, + .doit = devlink_nl_cmd_resource_set, + .policy = devlink_nl_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, + }, + { + .cmd = DEVLINK_CMD_RESOURCE_DUMP, + .doit = devlink_nl_cmd_resource_dump, + .policy = devlink_nl_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, + }, }; static struct genl_family devlink_nl_family __ro_after_init = { @@ -2503,6 +2746,7 @@ struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size) INIT_LIST_HEAD(&devlink->port_list); INIT_LIST_HEAD(&devlink->sb_list); INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list); + INIT_LIST_HEAD(&devlink->resource_list); mutex_init(&devlink->lock); return devlink; } @@ -2833,6 +3077,136 @@ unlock: } EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister); +/** + * devlink_resource_register - devlink resource register + * + * @devlink: devlink + * @resource_name: resource's name + * @top_hierarchy: top hierarchy + * @reload_required: reload is required for new configuration to + * apply + * @resource_size: resource's size + * @resource_id: resource's id + * @parent_reosurce_id: resource's parent id + * @size params: size parameters + * @resource_ops: resource ops + */ +int devlink_resource_register(struct devlink *devlink, + const char *resource_name, + bool top_hierarchy, + u64 resource_size, + u64 resource_id, + u64 parent_resource_id, + struct devlink_resource_size_params *size_params, + const struct devlink_resource_ops *resource_ops) +{ + struct devlink_resource *resource; + struct list_head *resource_list; + int err = 0; + + mutex_lock(&devlink->lock); + resource = devlink_resource_find(devlink, NULL, resource_id); + if (resource) { + err = -EINVAL; + goto out; + } + + resource = kzalloc(sizeof(*resource), GFP_KERNEL); + if (!resource) { + err = -ENOMEM; + goto out; + } + + if (top_hierarchy) { + resource_list = &devlink->resource_list; + } else { + struct devlink_resource *parent_resource; + + parent_resource = devlink_resource_find(devlink, NULL, + parent_resource_id); + if (parent_resource) { + resource_list = &parent_resource->resource_list; + resource->parent = parent_resource; + } else { + err = -EINVAL; + goto out; + } + } + + resource->name = resource_name; + resource->size = resource_size; + resource->size_new = resource_size; + resource->id = resource_id; + resource->resource_ops = resource_ops; + resource->size_valid = true; + resource->size_params = size_params; + INIT_LIST_HEAD(&resource->resource_list); + list_add_tail(&resource->list, resource_list); +out: + mutex_unlock(&devlink->lock); + return err; +} +EXPORT_SYMBOL_GPL(devlink_resource_register); + +/** + * devlink_resources_unregister - free all resources + * + * @devlink: devlink + * @resource: resource + */ +void devlink_resources_unregister(struct devlink *devlink, + struct devlink_resource *resource) +{ + struct devlink_resource *tmp, *child_resource; + struct list_head *resource_list; + + if (resource) + resource_list = &resource->resource_list; + else + resource_list = &devlink->resource_list; + + if (!resource) + mutex_lock(&devlink->lock); + + list_for_each_entry_safe(child_resource, tmp, resource_list, list) { + devlink_resources_unregister(devlink, child_resource); + list_del(&child_resource->list); + kfree(child_resource); + } + + if (!resource) + mutex_unlock(&devlink->lock); +} +EXPORT_SYMBOL_GPL(devlink_resources_unregister); + +/** + * devlink_resource_size_get - get and update size + * + * @devlink: devlink + * @resource_id: the requested resource id + * @p_resource_size: ptr to update + */ +int devlink_resource_size_get(struct devlink *devlink, + u64 resource_id, + u64 *p_resource_size) +{ + struct devlink_resource *resource; + int err = 0; + + mutex_lock(&devlink->lock); + resource = devlink_resource_find(devlink, NULL, resource_id); + if (!resource) { + err = -EINVAL; + goto out; + } + *p_resource_size = resource->size_new; + resource->size = resource->size_new; +out: + mutex_unlock(&devlink->lock); + return err; +} +EXPORT_SYMBOL_GPL(devlink_resource_size_get); + static int __init devlink_module_init(void) { return genl_register_family(&devlink_nl_family); -- cgit v1.2.3-59-g8ed1b From 2d8dc5bbf4e7603747875eb5cadcd67c1fa8b1bb Mon Sep 17 00:00:00 2001 From: Arkadi Sharshevsky Date: Mon, 15 Jan 2018 08:59:04 +0100 Subject: devlink: Add support for reload Add support for performing driver hot reload. Signed-off-by: Arkadi Sharshevsky Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- include/net/devlink.h | 1 + include/uapi/linux/devlink.h | 5 +++++ net/core/devlink.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/net/devlink.h b/include/net/devlink.h index ceb1895d119b..c698883fb0bb 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -281,6 +281,7 @@ struct devlink_resource { #define DEVLINK_RESOURCE_ID_PARENT_TOP 0 struct devlink_ops { + int (*reload)(struct devlink *devlink); int (*port_type_set)(struct devlink_port *devlink_port, enum devlink_port_type port_type); int (*port_split)(struct devlink *devlink, unsigned int port_index, diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index f89950443e17..555ddcaf0be2 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -73,6 +73,11 @@ enum devlink_command { DEVLINK_CMD_RESOURCE_SET, DEVLINK_CMD_RESOURCE_DUMP, + /* Hot driver reload, makes configuration changes take place. The + * devlink instance is not released during the process. + */ + DEVLINK_CMD_RELOAD, + /* add new commands above here */ __DEVLINK_CMD_MAX, DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1 diff --git a/net/core/devlink.c b/net/core/devlink.c index 89b3704fa450..4c3d85560436 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -2515,6 +2515,45 @@ static int devlink_nl_cmd_resource_dump(struct sk_buff *skb, return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0); } +static int +devlink_resources_validate(struct devlink *devlink, + struct devlink_resource *resource, + struct genl_info *info) +{ + struct list_head *resource_list; + int err = 0; + + if (resource) + resource_list = &resource->resource_list; + else + resource_list = &devlink->resource_list; + + list_for_each_entry(resource, resource_list, list) { + if (!resource->size_valid) + return -EINVAL; + err = devlink_resources_validate(devlink, resource, info); + if (err) + return err; + } + return err; +} + +static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) +{ + struct devlink *devlink = info->user_ptr[0]; + int err; + + if (!devlink->ops->reload) + return -EOPNOTSUPP; + + err = devlink_resources_validate(devlink, NULL, info); + if (err) { + NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed"); + return err; + } + return devlink->ops->reload(devlink); +} + static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING }, [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING }, @@ -2709,6 +2748,14 @@ static const struct genl_ops devlink_nl_ops[] = { .flags = GENL_ADMIN_PERM, .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, }, + { + .cmd = DEVLINK_CMD_RELOAD, + .doit = devlink_nl_cmd_reload, + .policy = devlink_nl_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | + DEVLINK_NL_FLAG_NO_LOCK, + }, }; static struct genl_family devlink_nl_family __ro_after_init = { -- cgit v1.2.3-59-g8ed1b From 56dc7cd0a87a1ff4f49ee1e67bd88e768385d51a Mon Sep 17 00:00:00 2001 From: Arkadi Sharshevsky Date: Mon, 15 Jan 2018 08:59:05 +0100 Subject: devlink: Add relation between dpipe and resource The hardware processes which are modeled via dpipe commonly use some internal hardware resources. Such relation can improve the understanding of hardware limitations. The number of resource's unit consumed per table's entry are also provided for each table. Signed-off-by: Arkadi Sharshevsky Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- include/net/devlink.h | 17 +++++++++++++++++ include/uapi/linux/devlink.h | 2 ++ net/core/devlink.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/net/devlink.h b/include/net/devlink.h index c698883fb0bb..6545b03e97f7 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -183,6 +183,9 @@ struct devlink_dpipe_table_ops; * @counters_enabled: indicates if counters are active * @counter_control_extern: indicates if counter control is in dpipe or * external tool + * @resource_valid: Indicate that the resource id is valid + * @resource_id: relative resource this table is related to + * @resource_units: number of resource's unit consumed per table's entry * @table_ops: table operations * @rcu: rcu */ @@ -192,6 +195,9 @@ struct devlink_dpipe_table { const char *name; bool counters_enabled; bool counter_control_extern; + bool resource_valid; + u64 resource_id; + u64 resource_units; struct devlink_dpipe_table_ops *table_ops; struct rcu_head rcu; }; @@ -403,6 +409,9 @@ void devlink_resources_unregister(struct devlink *devlink, int devlink_resource_size_get(struct devlink *devlink, u64 resource_id, u64 *p_resource_size); +int devlink_dpipe_table_resource_set(struct devlink *devlink, + const char *table_name, u64 resource_id, + u64 resource_units); #else @@ -566,6 +575,14 @@ devlink_resource_size_get(struct devlink *devlink, u64 resource_id, return -EOPNOTSUPP; } +static inline int +devlink_dpipe_table_resource_set(struct devlink *devlink, + const char *table_name, u64 resource_id, + u64 resource_units) +{ + return -EOPNOTSUPP; +} + #endif #endif /* _NET_DEVLINK_H_ */ diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index 555ddcaf0be2..1df65a4c2044 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -221,6 +221,8 @@ enum devlink_attr { DEVLINK_ATTR_RESOURCE_SIZE_GRAN, /* u64 */ DEVLINK_ATTR_RESOURCE_UNIT, /* u8 */ DEVLINK_ATTR_RESOURCE_OCC, /* u64 */ + DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID, /* u64 */ + DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,/* u64 */ /* add new attributes above here, update the policy in devlink.c */ diff --git a/net/core/devlink.c b/net/core/devlink.c index 4c3d85560436..dd7d6dd07bfb 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -1694,6 +1694,12 @@ static int devlink_dpipe_table_put(struct sk_buff *skb, table->counters_enabled)) goto nla_put_failure; + if (table->resource_valid) { + nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID, + table->resource_id, DEVLINK_ATTR_PAD); + nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS, + table->resource_units, DEVLINK_ATTR_PAD); + } if (devlink_dpipe_matches_put(table, skb)) goto nla_put_failure; @@ -3254,6 +3260,37 @@ out: } EXPORT_SYMBOL_GPL(devlink_resource_size_get); +/** + * devlink_dpipe_table_resource_set - set the resource id + * + * @devlink: devlink + * @table_name: table name + * @resource_id: resource id + * @resource_units: number of resource's units consumed per table's entry + */ +int devlink_dpipe_table_resource_set(struct devlink *devlink, + const char *table_name, u64 resource_id, + u64 resource_units) +{ + struct devlink_dpipe_table *table; + int err = 0; + + mutex_lock(&devlink->lock); + table = devlink_dpipe_table_find(&devlink->dpipe_table_list, + table_name); + if (!table) { + err = -EINVAL; + goto out; + } + table->resource_id = resource_id; + table->resource_units = resource_units; + table->resource_valid = true; +out: + mutex_unlock(&devlink->lock); + return err; +} +EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set); + static int __init devlink_module_init(void) { return genl_register_family(&devlink_nl_family); -- cgit v1.2.3-59-g8ed1b From 7960d1daf278cbe23bb48974fe6ae6a1e44c3c15 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 17 Jan 2018 11:46:51 +0100 Subject: net: sched: use block index as a handle instead of qdisc when block is shared As the tcm_ifindex with value TCM_IFINDEX_MAGIC_BLOCK is invalid ifindex, use it to indicate that we work with block, instead of qdisc. So if tcm_ifindex is set to TCM_IFINDEX_MAGIC_BLOCK, tcm_parent is used to carry block_index. If the block is set to be shared between at least 2 qdiscs, it is forbidden to use the qdisc handle to add/delete filters. In that case, userspace has to pass block_index. Also, for dump of the filters, in case the block is shared in between at least 2 qdiscs, the each filter is dumped with tcm_ifindex value TCM_IFINDEX_MAGIC_BLOCK and tcm_parent set to block_index. That gives the user clear indication, that the filter belongs to a shared block and not only to one qdisc under which it is dumped. Suggested-by: David Ahern Signed-off-by: Jiri Pirko Acked-by: Jamal Hadi Salim Acked-by: David Ahern Signed-off-by: David S. Miller --- include/uapi/linux/rtnetlink.h | 10 ++ net/sched/cls_api.c | 202 ++++++++++++++++++++++++----------------- 2 files changed, 128 insertions(+), 84 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h index 843e29aa3cac..da878f2e7c39 100644 --- a/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h @@ -541,9 +541,19 @@ struct tcmsg { int tcm_ifindex; __u32 tcm_handle; __u32 tcm_parent; +/* tcm_block_index is used instead of tcm_parent + * in case tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK + */ +#define tcm_block_index tcm_parent __u32 tcm_info; }; +/* For manipulation of filters in shared block, tcm_ifindex is set to + * TCM_IFINDEX_MAGIC_BLOCK, and tcm_parent is aliased to tcm_block_index + * which is the block index. + */ +#define TCM_IFINDEX_MAGIC_BLOCK (0xFFFFFFFFU) + enum { TCA_UNSPEC, TCA_KIND, diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 03e2fa092d9e..e500d11da9cd 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -865,8 +865,9 @@ static struct tcf_proto *tcf_chain_tp_find(struct tcf_chain *chain, } static int tcf_fill_node(struct net *net, struct sk_buff *skb, - struct tcf_proto *tp, struct Qdisc *q, u32 parent, - void *fh, u32 portid, u32 seq, u16 flags, int event) + struct tcf_proto *tp, struct tcf_block *block, + struct Qdisc *q, u32 parent, void *fh, + u32 portid, u32 seq, u16 flags, int event) { struct tcmsg *tcm; struct nlmsghdr *nlh; @@ -879,8 +880,13 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb, tcm->tcm_family = AF_UNSPEC; tcm->tcm__pad1 = 0; tcm->tcm__pad2 = 0; - tcm->tcm_ifindex = qdisc_dev(q)->ifindex; - tcm->tcm_parent = parent; + if (q) { + tcm->tcm_ifindex = qdisc_dev(q)->ifindex; + tcm->tcm_parent = parent; + } else { + tcm->tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK; + tcm->tcm_block_index = block->index; + } tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); if (nla_put_string(skb, TCA_KIND, tp->ops->kind)) goto nla_put_failure; @@ -903,8 +909,8 @@ nla_put_failure: static int tfilter_notify(struct net *net, struct sk_buff *oskb, struct nlmsghdr *n, struct tcf_proto *tp, - struct Qdisc *q, u32 parent, - void *fh, int event, bool unicast) + struct tcf_block *block, struct Qdisc *q, + u32 parent, void *fh, int event, bool unicast) { struct sk_buff *skb; u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; @@ -913,8 +919,8 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb, if (!skb) return -ENOBUFS; - if (tcf_fill_node(net, skb, tp, q, parent, fh, portid, n->nlmsg_seq, - n->nlmsg_flags, event) <= 0) { + if (tcf_fill_node(net, skb, tp, block, q, parent, fh, portid, + n->nlmsg_seq, n->nlmsg_flags, event) <= 0) { kfree_skb(skb); return -EINVAL; } @@ -928,8 +934,8 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb, static int tfilter_del_notify(struct net *net, struct sk_buff *oskb, struct nlmsghdr *n, struct tcf_proto *tp, - struct Qdisc *q, u32 parent, - void *fh, bool unicast, bool *last) + struct tcf_block *block, struct Qdisc *q, + u32 parent, void *fh, bool unicast, bool *last) { struct sk_buff *skb; u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; @@ -939,8 +945,8 @@ static int tfilter_del_notify(struct net *net, struct sk_buff *oskb, if (!skb) return -ENOBUFS; - if (tcf_fill_node(net, skb, tp, q, parent, fh, portid, n->nlmsg_seq, - n->nlmsg_flags, RTM_DELTFILTER) <= 0) { + if (tcf_fill_node(net, skb, tp, block, q, parent, fh, portid, + n->nlmsg_seq, n->nlmsg_flags, RTM_DELTFILTER) <= 0) { kfree_skb(skb); return -EINVAL; } @@ -959,15 +965,16 @@ static int tfilter_del_notify(struct net *net, struct sk_buff *oskb, } static void tfilter_notify_chain(struct net *net, struct sk_buff *oskb, - struct Qdisc *q, u32 parent, - struct nlmsghdr *n, + struct tcf_block *block, struct Qdisc *q, + u32 parent, struct nlmsghdr *n, struct tcf_chain *chain, int event) { struct tcf_proto *tp; for (tp = rtnl_dereference(chain->filter_chain); tp; tp = rtnl_dereference(tp->next)) - tfilter_notify(net, oskb, n, tp, q, parent, 0, event, false); + tfilter_notify(net, oskb, n, tp, block, + q, parent, 0, event, false); } /* Add/change/delete/get a filter node */ @@ -983,13 +990,11 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, bool prio_allocate; u32 parent; u32 chain_index; - struct net_device *dev; - struct Qdisc *q; + struct Qdisc *q = NULL; struct tcf_chain_info chain_info; struct tcf_chain *chain = NULL; struct tcf_block *block; struct tcf_proto *tp; - const struct Qdisc_class_ops *cops; unsigned long cl; void *fh; int err; @@ -1036,41 +1041,58 @@ replay: /* Find head of filter chain. */ - /* Find link */ - dev = __dev_get_by_index(net, t->tcm_ifindex); - if (dev == NULL) - return -ENODEV; - - /* Find qdisc */ - if (!parent) { - q = dev->qdisc; - parent = q->handle; + if (t->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) { + block = tcf_block_lookup(net, t->tcm_block_index); + if (!block) { + NL_SET_ERR_MSG(extack, "Block of given index was not found"); + err = -EINVAL; + goto errout; + } } else { - q = qdisc_lookup(dev, TC_H_MAJ(t->tcm_parent)); - if (q == NULL) - return -EINVAL; - } + const struct Qdisc_class_ops *cops; + struct net_device *dev; - /* Is it classful? */ - cops = q->ops->cl_ops; - if (!cops) - return -EINVAL; + /* Find link */ + dev = __dev_get_by_index(net, t->tcm_ifindex); + if (!dev) + return -ENODEV; - if (!cops->tcf_block) - return -EOPNOTSUPP; + /* Find qdisc */ + if (!parent) { + q = dev->qdisc; + parent = q->handle; + } else { + q = qdisc_lookup(dev, TC_H_MAJ(t->tcm_parent)); + if (!q) + return -EINVAL; + } - /* Do we search for filter, attached to class? */ - if (TC_H_MIN(parent)) { - cl = cops->find(q, parent); - if (cl == 0) - return -ENOENT; - } + /* Is it classful? */ + cops = q->ops->cl_ops; + if (!cops) + return -EINVAL; - /* And the last stroke */ - block = cops->tcf_block(q, cl, extack); - if (!block) { - err = -EINVAL; - goto errout; + if (!cops->tcf_block) + return -EOPNOTSUPP; + + /* Do we search for filter, attached to class? */ + if (TC_H_MIN(parent)) { + cl = cops->find(q, parent); + if (cl == 0) + return -ENOENT; + } + + /* And the last stroke */ + block = cops->tcf_block(q, cl, extack); + if (!block) { + err = -EINVAL; + goto errout; + } + if (tcf_block_shared(block)) { + NL_SET_ERR_MSG(extack, "This filter block is shared. Please use the block index to manipulate the filters"); + err = -EOPNOTSUPP; + goto errout; + } } chain_index = tca[TCA_CHAIN] ? nla_get_u32(tca[TCA_CHAIN]) : 0; @@ -1086,7 +1108,7 @@ replay: } if (n->nlmsg_type == RTM_DELTFILTER && prio == 0) { - tfilter_notify_chain(net, skb, q, parent, n, + tfilter_notify_chain(net, skb, block, q, parent, n, chain, RTM_DELTFILTER); tcf_chain_flush(chain); err = 0; @@ -1134,7 +1156,7 @@ replay: if (!fh) { if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) { tcf_chain_tp_remove(chain, &chain_info, tp); - tfilter_notify(net, skb, n, tp, q, parent, fh, + tfilter_notify(net, skb, n, tp, block, q, parent, fh, RTM_DELTFILTER, false); tcf_proto_destroy(tp); err = 0; @@ -1159,8 +1181,8 @@ replay: } break; case RTM_DELTFILTER: - err = tfilter_del_notify(net, skb, n, tp, q, parent, - fh, false, &last); + err = tfilter_del_notify(net, skb, n, tp, block, + q, parent, fh, false, &last); if (err) goto errout; if (last) { @@ -1169,8 +1191,8 @@ replay: } goto errout; case RTM_GETTFILTER: - err = tfilter_notify(net, skb, n, tp, q, parent, fh, - RTM_NEWTFILTER, true); + err = tfilter_notify(net, skb, n, tp, block, q, parent, + fh, RTM_NEWTFILTER, true); goto errout; default: err = -EINVAL; @@ -1183,7 +1205,7 @@ replay: if (err == 0) { if (tp_created) tcf_chain_tp_insert(chain, &chain_info, tp); - tfilter_notify(net, skb, n, tp, q, parent, fh, + tfilter_notify(net, skb, n, tp, block, q, parent, fh, RTM_NEWTFILTER, false); } else { if (tp_created) @@ -1203,6 +1225,7 @@ struct tcf_dump_args { struct tcf_walker w; struct sk_buff *skb; struct netlink_callback *cb; + struct tcf_block *block; struct Qdisc *q; u32 parent; }; @@ -1212,7 +1235,7 @@ static int tcf_node_dump(struct tcf_proto *tp, void *n, struct tcf_walker *arg) struct tcf_dump_args *a = (void *)arg; struct net *net = sock_net(a->skb->sk); - return tcf_fill_node(net, a->skb, tp, a->q, a->parent, + return tcf_fill_node(net, a->skb, tp, a->block, a->q, a->parent, n, NETLINK_CB(a->cb->skb).portid, a->cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTFILTER); @@ -1223,6 +1246,7 @@ static bool tcf_chain_dump(struct tcf_chain *chain, struct Qdisc *q, u32 parent, long index_start, long *p_index) { struct net *net = sock_net(skb->sk); + struct tcf_block *block = chain->block; struct tcmsg *tcm = nlmsg_data(cb->nlh); struct tcf_dump_args arg; struct tcf_proto *tp; @@ -1241,7 +1265,7 @@ static bool tcf_chain_dump(struct tcf_chain *chain, struct Qdisc *q, u32 parent, memset(&cb->args[1], 0, sizeof(cb->args) - sizeof(cb->args[0])); if (cb->args[1] == 0) { - if (tcf_fill_node(net, skb, tp, q, parent, 0, + if (tcf_fill_node(net, skb, tp, block, q, parent, 0, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTFILTER) <= 0) @@ -1254,6 +1278,7 @@ static bool tcf_chain_dump(struct tcf_chain *chain, struct Qdisc *q, u32 parent, arg.w.fn = tcf_node_dump; arg.skb = skb; arg.cb = cb; + arg.block = block; arg.q = q; arg.parent = parent; arg.w.stop = 0; @@ -1272,13 +1297,10 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) { struct net *net = sock_net(skb->sk); struct nlattr *tca[TCA_MAX + 1]; - struct net_device *dev; - struct Qdisc *q; + struct Qdisc *q = NULL; struct tcf_block *block; struct tcf_chain *chain; struct tcmsg *tcm = nlmsg_data(cb->nlh); - unsigned long cl = 0; - const struct Qdisc_class_ops *cops; long index_start; long index; u32 parent; @@ -1291,32 +1313,44 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) if (err) return err; - dev = __dev_get_by_index(net, tcm->tcm_ifindex); - if (!dev) - return skb->len; - - parent = tcm->tcm_parent; - if (!parent) { - q = dev->qdisc; - parent = q->handle; + if (tcm->tcm_ifindex == TCM_IFINDEX_MAGIC_BLOCK) { + block = tcf_block_lookup(net, tcm->tcm_block_index); + if (!block) + goto out; } else { - q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent)); - } - if (!q) - goto out; - cops = q->ops->cl_ops; - if (!cops) - goto out; - if (!cops->tcf_block) - goto out; - if (TC_H_MIN(tcm->tcm_parent)) { - cl = cops->find(q, tcm->tcm_parent); - if (cl == 0) + const struct Qdisc_class_ops *cops; + struct net_device *dev; + unsigned long cl = 0; + + dev = __dev_get_by_index(net, tcm->tcm_ifindex); + if (!dev) + return skb->len; + + parent = tcm->tcm_parent; + if (!parent) { + q = dev->qdisc; + parent = q->handle; + } else { + q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent)); + } + if (!q) goto out; + cops = q->ops->cl_ops; + if (!cops) + goto out; + if (!cops->tcf_block) + goto out; + if (TC_H_MIN(tcm->tcm_parent)) { + cl = cops->find(q, tcm->tcm_parent); + if (cl == 0) + goto out; + } + block = cops->tcf_block(q, cl, NULL); + if (!block) + goto out; + if (tcf_block_shared(block)) + q = NULL; } - block = cops->tcf_block(q, cl, NULL); - if (!block) - goto out; index_start = cb->args[0]; index = 0; -- cgit v1.2.3-59-g8ed1b From d47a6b0e7c492a4ba4524d557db388e34fd0a47a Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 17 Jan 2018 11:46:52 +0100 Subject: net: sched: introduce ingress/egress block index attributes for qdisc Introduce two new attributes to be used for qdisc creation and dumping. One for ingress block, one for egress block. Introduce a set of ops that qdisc which supports block sharing would implement. Passing block indexes in qdisc change is not supported yet and it is checked and forbidded. In future, these attributes are to be reused for specifying block indexes for classes as well. As of this moment however, it is not supported so a check is in place to forbid it. Suggested-by: Roopa Prabhu Signed-off-by: Jiri Pirko Acked-by: Jamal Hadi Salim Acked-by: David Ahern Signed-off-by: David S. Miller --- include/net/sch_generic.h | 7 +++++ include/uapi/linux/rtnetlink.h | 2 ++ net/sched/sch_api.c | 60 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index bf5cc0a1d0f6..cfc19d0ba2ad 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -204,6 +204,13 @@ struct Qdisc_ops { int (*dump)(struct Qdisc *, struct sk_buff *); int (*dump_stats)(struct Qdisc *, struct gnet_dump *); + void (*ingress_block_set)(struct Qdisc *sch, + u32 block_index); + void (*egress_block_set)(struct Qdisc *sch, + u32 block_index); + u32 (*ingress_block_get)(struct Qdisc *sch); + u32 (*egress_block_get)(struct Qdisc *sch); + struct module *owner; }; diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h index da878f2e7c39..9b15005955fa 100644 --- a/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h @@ -568,6 +568,8 @@ enum { TCA_DUMP_INVISIBLE, TCA_CHAIN, TCA_HW_OFFLOAD, + TCA_INGRESS_BLOCK, + TCA_EGRESS_BLOCK, __TCA_MAX }; diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 7dffa9dce28b..d512f49ee83c 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -791,6 +791,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, unsigned char *b = skb_tail_pointer(skb); struct gnet_dump d; struct qdisc_size_table *stab; + u32 block_index; __u32 qlen; cond_resched(); @@ -807,6 +808,18 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, tcm->tcm_info = refcount_read(&q->refcnt); if (nla_put_string(skb, TCA_KIND, q->ops->id)) goto nla_put_failure; + if (q->ops->ingress_block_get) { + block_index = q->ops->ingress_block_get(q); + if (block_index && + nla_put_u32(skb, TCA_INGRESS_BLOCK, block_index)) + goto nla_put_failure; + } + if (q->ops->egress_block_get) { + block_index = q->ops->egress_block_get(q); + if (block_index && + nla_put_u32(skb, TCA_EGRESS_BLOCK, block_index)) + goto nla_put_failure; + } if (q->ops->dump && q->ops->dump(q, skb) < 0) goto nla_put_failure; if (nla_put_u8(skb, TCA_HW_OFFLOAD, !!(q->flags & TCQ_F_OFFLOADED))) @@ -994,6 +1007,40 @@ skip: return err; } +static int qdisc_block_indexes_set(struct Qdisc *sch, struct nlattr **tca, + struct netlink_ext_ack *extack) +{ + u32 block_index; + + if (tca[TCA_INGRESS_BLOCK]) { + block_index = nla_get_u32(tca[TCA_INGRESS_BLOCK]); + + if (!block_index) { + NL_SET_ERR_MSG(extack, "Ingress block index cannot be 0"); + return -EINVAL; + } + if (!sch->ops->ingress_block_set) { + NL_SET_ERR_MSG(extack, "Ingress block sharing is not supported"); + return -EOPNOTSUPP; + } + sch->ops->ingress_block_set(sch, block_index); + } + if (tca[TCA_EGRESS_BLOCK]) { + block_index = nla_get_u32(tca[TCA_EGRESS_BLOCK]); + + if (!block_index) { + NL_SET_ERR_MSG(extack, "Egress block index cannot be 0"); + return -EINVAL; + } + if (!sch->ops->egress_block_set) { + NL_SET_ERR_MSG(extack, "Egress block sharing is not supported"); + return -EOPNOTSUPP; + } + sch->ops->egress_block_set(sch, block_index); + } + return 0; +} + /* lockdep annotation is needed for ingress; egress gets it only for name */ static struct lock_class_key qdisc_tx_lock; static struct lock_class_key qdisc_rx_lock; @@ -1088,6 +1135,10 @@ static struct Qdisc *qdisc_create(struct net_device *dev, netdev_info(dev, "Caught tx_queue_len zero misconfig\n"); } + err = qdisc_block_indexes_set(sch, tca, extack); + if (err) + goto err_out3; + if (ops->init) { err = ops->init(sch, tca[TCA_OPTIONS], extack); if (err != 0) @@ -1169,6 +1220,10 @@ static int qdisc_change(struct Qdisc *sch, struct nlattr **tca, NL_SET_ERR_MSG(extack, "Change operation not supported by specified qdisc"); return -EINVAL; } + if (tca[TCA_INGRESS_BLOCK] || tca[TCA_EGRESS_BLOCK]) { + NL_SET_ERR_MSG(extack, "Change of blocks is not supported"); + return -EOPNOTSUPP; + } err = sch->ops->change(sch, tca[TCA_OPTIONS], extack); if (err) return err; @@ -1894,6 +1949,11 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, } } + if (tca[TCA_INGRESS_BLOCK] || tca[TCA_EGRESS_BLOCK]) { + NL_SET_ERR_MSG(extack, "Shared blocks are not supported for classes"); + return -EOPNOTSUPP; + } + new_cl = cl; err = -EOPNOTSUPP; if (cops->change) -- cgit v1.2.3-59-g8ed1b From aff3d70a07fffc0abb53663e4a4acb059d2f36af Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Tue, 16 Jan 2018 16:31:02 +0800 Subject: tun: allow to attach ebpf socket filter This patch allows userspace to attach eBPF filter to tun. This will allow to implement VM dataplane filtering in a more efficient way compared to cBPF filter by allowing either qemu or libvirt to attach eBPF filter to tun. Signed-off-by: Jason Wang Signed-off-by: David S. Miller --- drivers/net/tun.c | 38 ++++++++++++++++++++++++++++++++++---- include/uapi/linux/if_tun.h | 1 + 2 files changed, 35 insertions(+), 4 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 76197ede22a9..170a3e89b5af 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -239,6 +239,12 @@ struct tun_struct { struct tun_pcpu_stats __percpu *pcpu_stats; struct bpf_prog __rcu *xdp_prog; struct tun_prog __rcu *steering_prog; + struct tun_prog __rcu *filter_prog; +}; + +struct veth { + __be16 h_vlan_proto; + __be16 h_vlan_TCI; }; bool tun_is_xdp_buff(void *ptr) @@ -1036,12 +1042,25 @@ static void tun_automq_xmit(struct tun_struct *tun, struct sk_buff *skb) #endif } +static unsigned int run_ebpf_filter(struct tun_struct *tun, + struct sk_buff *skb, + int len) +{ + struct tun_prog *prog = rcu_dereference(tun->filter_prog); + + if (prog) + len = bpf_prog_run_clear_cb(prog->prog, skb); + + return len; +} + /* Net device start xmit */ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) { struct tun_struct *tun = netdev_priv(dev); int txq = skb->queue_mapping; struct tun_file *tfile; + int len = skb->len; rcu_read_lock(); tfile = rcu_dereference(tun->tfiles[txq]); @@ -1067,6 +1086,15 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) sk_filter(tfile->socket.sk, skb)) goto drop; + len = run_ebpf_filter(tun, skb, len); + + /* Trim extra bytes since we may insert vlan proto & TCI + * in tun_put_user(). + */ + len -= skb_vlan_tag_present(skb) ? sizeof(struct veth) : 0; + if (len <= 0 || pskb_trim(skb, len)) + goto drop; + if (unlikely(skb_orphan_frags_rx(skb, GFP_ATOMIC))) goto drop; @@ -2054,10 +2082,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, if (vlan_hlen) { int ret; - struct { - __be16 h_vlan_proto; - __be16 h_vlan_TCI; - } veth; + struct veth veth; veth.h_vlan_proto = skb->vlan_proto; veth.h_vlan_TCI = htons(skb_vlan_tag_get(skb)); @@ -2225,6 +2250,7 @@ static void tun_free_netdev(struct net_device *dev) tun_flow_uninit(tun); security_tun_dev_free_security(tun->security); __tun_set_ebpf(tun, &tun->steering_prog, NULL); + __tun_set_ebpf(tun, &tun->filter_prog, NULL); } static void tun_setup(struct net_device *dev) @@ -3019,6 +3045,10 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, ret = tun_set_ebpf(tun, &tun->steering_prog, argp); break; + case TUNSETFILTEREBPF: + ret = tun_set_ebpf(tun, &tun->filter_prog, argp); + break; + default: ret = -EINVAL; break; diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h index fb38c1797131..ee432cd3018c 100644 --- a/include/uapi/linux/if_tun.h +++ b/include/uapi/linux/if_tun.h @@ -58,6 +58,7 @@ #define TUNSETVNETBE _IOW('T', 222, int) #define TUNGETVNETBE _IOR('T', 223, int) #define TUNSETSTEERINGEBPF _IOR('T', 224, int) +#define TUNSETFILTEREBPF _IOR('T', 225, int) /* TUNSETIFF ifr flags */ #define IFF_TUN 0x0001 -- cgit v1.2.3-59-g8ed1b From cb5f7334d479414adc6afe60105283277e297489 Mon Sep 17 00:00:00 2001 From: Jesper Dangaard Brouer Date: Wed, 17 Jan 2018 12:05:36 +0100 Subject: bpf: add comments to BPF ld/ldx sizes Doc BPF ld/ldx size defines as comments in code, as it makes in faster to lookup in a programming/review setting, than looking up the sizes in Documentation/networking/filter.txt. Signed-off-by: Jesper Dangaard Brouer Signed-off-by: Daniel Borkmann --- include/uapi/linux/bpf.h | 2 +- include/uapi/linux/bpf_common.h | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 7c2259e8bc54..74dc4dc98681 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -17,7 +17,7 @@ #define BPF_ALU64 0x07 /* alu mode in double word width */ /* ld/ldx fields */ -#define BPF_DW 0x18 /* double word */ +#define BPF_DW 0x18 /* double word (64-bit) */ #define BPF_XADD 0xc0 /* exclusive add */ /* alu/jmp fields */ diff --git a/include/uapi/linux/bpf_common.h b/include/uapi/linux/bpf_common.h index 18be90725ab0..ee97668bdadb 100644 --- a/include/uapi/linux/bpf_common.h +++ b/include/uapi/linux/bpf_common.h @@ -15,9 +15,10 @@ /* ld/ldx fields */ #define BPF_SIZE(code) ((code) & 0x18) -#define BPF_W 0x00 -#define BPF_H 0x08 -#define BPF_B 0x10 +#define BPF_W 0x00 /* 32-bit */ +#define BPF_H 0x08 /* 16-bit */ +#define BPF_B 0x10 /* 8-bit */ +/* eBPF BPF_DW 0x18 64-bit */ #define BPF_MODE(code) ((code) & 0xe0) #define BPF_IMM 0x00 #define BPF_ABS 0x20 -- cgit v1.2.3-59-g8ed1b From 52775b33bb5072fbc07b02c0cf4fe8da1f7ee7cd Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Wed, 17 Jan 2018 19:13:28 -0800 Subject: bpf: offload: report device information about offloaded maps Tell user space about device on which the map was created. Unfortunate reality of user ABI makes sharing this code with program offload difficult but the information is the same. Signed-off-by: Jakub Kicinski Acked-by: Alexei Starovoitov Signed-off-by: Daniel Borkmann --- include/linux/bpf.h | 2 ++ include/uapi/linux/bpf.h | 3 +++ kernel/bpf/offload.c | 55 ++++++++++++++++++++++++++++++++++++++++++ kernel/bpf/syscall.c | 6 +++++ tools/include/uapi/linux/bpf.h | 3 +++ 5 files changed, 69 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 025b1c2f8053..66df387106de 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -586,6 +586,8 @@ void bpf_prog_offload_destroy(struct bpf_prog *prog); int bpf_prog_offload_info_fill(struct bpf_prog_info *info, struct bpf_prog *prog); +int bpf_map_offload_info_fill(struct bpf_map_info *info, struct bpf_map *map); + int bpf_map_offload_lookup_elem(struct bpf_map *map, void *key, void *value); int bpf_map_offload_update_elem(struct bpf_map *map, void *key, void *value, u64 flags); diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 74dc4dc98681..406c19d6016b 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -938,6 +938,9 @@ struct bpf_map_info { __u32 max_entries; __u32 map_flags; char name[BPF_OBJ_NAME_LEN]; + __u32 ifindex; + __u64 netns_dev; + __u64 netns_ino; } __attribute__((aligned(8))); /* User bpf_sock_ops struct to access socket values and specify request ops diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c index 2657976aec2a..c9401075b58c 100644 --- a/kernel/bpf/offload.c +++ b/kernel/bpf/offload.c @@ -413,6 +413,61 @@ int bpf_map_offload_get_next_key(struct bpf_map *map, void *key, void *next_key) return ret; } +struct ns_get_path_bpf_map_args { + struct bpf_offloaded_map *offmap; + struct bpf_map_info *info; +}; + +static struct ns_common *bpf_map_offload_info_fill_ns(void *private_data) +{ + struct ns_get_path_bpf_map_args *args = private_data; + struct ns_common *ns; + struct net *net; + + rtnl_lock(); + down_read(&bpf_devs_lock); + + if (args->offmap->netdev) { + args->info->ifindex = args->offmap->netdev->ifindex; + net = dev_net(args->offmap->netdev); + get_net(net); + ns = &net->ns; + } else { + args->info->ifindex = 0; + ns = NULL; + } + + up_read(&bpf_devs_lock); + rtnl_unlock(); + + return ns; +} + +int bpf_map_offload_info_fill(struct bpf_map_info *info, struct bpf_map *map) +{ + struct ns_get_path_bpf_map_args args = { + .offmap = map_to_offmap(map), + .info = info, + }; + struct inode *ns_inode; + struct path ns_path; + void *res; + + res = ns_get_path_cb(&ns_path, bpf_map_offload_info_fill_ns, &args); + if (IS_ERR(res)) { + if (!info->ifindex) + return -ENODEV; + return PTR_ERR(res); + } + + ns_inode = ns_path.dentry->d_inode; + info->netns_dev = new_encode_dev(ns_inode->i_sb->s_dev); + info->netns_ino = ns_inode->i_ino; + path_put(&ns_path); + + return 0; +} + bool bpf_offload_dev_match(struct bpf_prog *prog, struct bpf_map *map) { struct bpf_offloaded_map *offmap; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 97a825ffc763..5bdb0cc84ad2 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1801,6 +1801,12 @@ static int bpf_map_get_info_by_fd(struct bpf_map *map, info.map_flags = map->map_flags; memcpy(info.name, map->name, sizeof(map->name)); + if (bpf_map_is_dev_bound(map)) { + err = bpf_map_offload_info_fill(&info, map); + if (err) + return err; + } + if (copy_to_user(uinfo, &info, info_len) || put_user(info_len, &uattr->info.info_len)) return -EFAULT; diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 7c2259e8bc54..af1f49ad8b88 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -938,6 +938,9 @@ struct bpf_map_info { __u32 max_entries; __u32 map_flags; char name[BPF_OBJ_NAME_LEN]; + __u32 ifindex; + __u64 netns_dev; + __u64 netns_ino; } __attribute__((aligned(8))); /* User bpf_sock_ops struct to access socket values and specify request ops -- cgit v1.2.3-59-g8ed1b From 3ecbfd65f50e5ff9c538c1bfa3356ef52cc66586 Mon Sep 17 00:00:00 2001 From: Harsha Sharma Date: Wed, 27 Dec 2017 00:59:00 +0530 Subject: netfilter: nf_tables: allocate handle and delete objects via handle This patch allows deletion of objects via unique handle which can be listed via '-a' option. Signed-off-by: Harsha Sharma Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_tables.h | 11 ++- include/uapi/linux/netfilter/nf_tables.h | 10 +++ net/netfilter/nf_tables_api.c | 146 ++++++++++++++++++++++++++++--- 3 files changed, 153 insertions(+), 14 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 4aca413367ee..663b015dace5 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -374,6 +374,7 @@ void nft_unregister_set(struct nft_set_type *type); * @list: table set list node * @bindings: list of set bindings * @name: name of the set + * @handle: unique handle of the set * @ktype: key type (numeric type defined by userspace, not used in the kernel) * @dtype: data type (verdict or numeric type defined by userspace) * @objtype: object type (see NFT_OBJECT_* definitions) @@ -396,6 +397,7 @@ struct nft_set { struct list_head list; struct list_head bindings; char *name; + u64 handle; u32 ktype; u32 dtype; u32 objtype; @@ -946,6 +948,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv); * @objects: stateful objects in the table * @flowtables: flow tables in the table * @hgenerator: handle generator state + * @handle: table handle * @use: number of chain references to this table * @flags: table flag (see enum nft_table_flags) * @genmask: generation mask @@ -959,6 +962,7 @@ struct nft_table { struct list_head objects; struct list_head flowtables; u64 hgenerator; + u64 handle; u32 use; u16 family:6, flags:8, @@ -983,9 +987,9 @@ int nft_verdict_dump(struct sk_buff *skb, int type, * @name: name of this stateful object * @genmask: generation mask * @use: number of references to this stateful object - * @data: object data, layout depends on type + * @handle: unique object handle * @ops: object operations - * @data: pointer to object data + * @data: object data, layout depends on type */ struct nft_object { struct list_head list; @@ -993,6 +997,7 @@ struct nft_object { struct nft_table *table; u32 genmask:2, use:30; + u64 handle; /* runtime data below here */ const struct nft_object_ops *ops ____cacheline_aligned; unsigned char data[] @@ -1074,6 +1079,7 @@ void nft_unregister_obj(struct nft_object_type *obj_type); * @ops_len: number of hooks in array * @genmask: generation mask * @use: number of references to this flow table + * @handle: unique object handle * @data: rhashtable and garbage collector * @ops: array of hooks */ @@ -1086,6 +1092,7 @@ struct nft_flowtable { int ops_len; u32 genmask:2, use:30; + u64 handle; /* runtime data below here */ struct nf_hook_ops *ops ____cacheline_aligned; struct nf_flowtable data; diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 53e8dd2a3a03..66dceee0ae30 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -174,6 +174,8 @@ enum nft_table_attributes { NFTA_TABLE_NAME, NFTA_TABLE_FLAGS, NFTA_TABLE_USE, + NFTA_TABLE_HANDLE, + NFTA_TABLE_PAD, __NFTA_TABLE_MAX }; #define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1) @@ -317,6 +319,7 @@ enum nft_set_desc_attributes { * @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32) * @NFTA_SET_USERDATA: user data (NLA_BINARY) * @NFTA_SET_OBJ_TYPE: stateful object type (NLA_U32: NFT_OBJECT_*) + * @NFTA_SET_HANDLE: set handle (NLA_U64) */ enum nft_set_attributes { NFTA_SET_UNSPEC, @@ -335,6 +338,7 @@ enum nft_set_attributes { NFTA_SET_USERDATA, NFTA_SET_PAD, NFTA_SET_OBJ_TYPE, + NFTA_SET_HANDLE, __NFTA_SET_MAX }; #define NFTA_SET_MAX (__NFTA_SET_MAX - 1) @@ -1314,6 +1318,7 @@ enum nft_ct_helper_attributes { * @NFTA_OBJ_TYPE: stateful object type (NLA_U32) * @NFTA_OBJ_DATA: stateful object data (NLA_NESTED) * @NFTA_OBJ_USE: number of references to this expression (NLA_U32) + * @NFTA_OBJ_HANDLE: object handle (NLA_U64) */ enum nft_object_attributes { NFTA_OBJ_UNSPEC, @@ -1322,6 +1327,8 @@ enum nft_object_attributes { NFTA_OBJ_TYPE, NFTA_OBJ_DATA, NFTA_OBJ_USE, + NFTA_OBJ_HANDLE, + NFTA_OBJ_PAD, __NFTA_OBJ_MAX }; #define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1) @@ -1333,6 +1340,7 @@ enum nft_object_attributes { * @NFTA_FLOWTABLE_NAME: name of this flow table (NLA_STRING) * @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32) * @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32) + * @NFTA_FLOWTABLE_HANDLE: object handle (NLA_U64) */ enum nft_flowtable_attributes { NFTA_FLOWTABLE_UNSPEC, @@ -1340,6 +1348,8 @@ enum nft_flowtable_attributes { NFTA_FLOWTABLE_NAME, NFTA_FLOWTABLE_HOOK, NFTA_FLOWTABLE_USE, + NFTA_FLOWTABLE_HANDLE, + NFTA_FLOWTABLE_PAD, __NFTA_FLOWTABLE_MAX }; #define NFTA_FLOWTABLE_MAX (__NFTA_FLOWTABLE_MAX - 1) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index b541e5094dce..1addc401ff7d 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -26,6 +26,7 @@ static LIST_HEAD(nf_tables_expressions); static LIST_HEAD(nf_tables_objects); static LIST_HEAD(nf_tables_flowtables); +static u64 table_handle; static void nft_ctx_init(struct nft_ctx *ctx, struct net *net, @@ -332,6 +333,20 @@ static struct nft_table *nft_table_lookup(const struct net *net, return NULL; } +static struct nft_table *nft_table_lookup_byhandle(const struct net *net, + const struct nlattr *nla, + u8 genmask) +{ + struct nft_table *table; + + list_for_each_entry(table, &net->nft.tables, list) { + if (be64_to_cpu(nla_get_be64(nla)) == table->handle && + nft_active_genmask(table, genmask)) + return table; + } + return NULL; +} + static struct nft_table *nf_tables_table_lookup(const struct net *net, const struct nlattr *nla, u8 family, u8 genmask) @@ -348,6 +363,22 @@ static struct nft_table *nf_tables_table_lookup(const struct net *net, return ERR_PTR(-ENOENT); } +static struct nft_table *nf_tables_table_lookup_byhandle(const struct net *net, + const struct nlattr *nla, + u8 genmask) +{ + struct nft_table *table; + + if (nla == NULL) + return ERR_PTR(-EINVAL); + + table = nft_table_lookup_byhandle(net, nla, genmask); + if (table != NULL) + return table; + + return ERR_PTR(-ENOENT); +} + static inline u64 nf_tables_alloc_handle(struct nft_table *table) { return ++table->hgenerator; @@ -394,6 +425,7 @@ static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = { [NFTA_TABLE_NAME] = { .type = NLA_STRING, .len = NFT_TABLE_MAXNAMELEN - 1 }, [NFTA_TABLE_FLAGS] = { .type = NLA_U32 }, + [NFTA_TABLE_HANDLE] = { .type = NLA_U64 }, }; static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net, @@ -415,7 +447,9 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net, if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) || nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)) || - nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use))) + nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)) || + nla_put_be64(skb, NFTA_TABLE_HANDLE, cpu_to_be64(table->handle), + NFTA_TABLE_PAD)) goto nla_put_failure; nlmsg_end(skb, nlh); @@ -674,6 +708,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk, INIT_LIST_HEAD(&table->flowtables); table->family = family; table->flags = flags; + table->handle = ++table_handle; nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla); err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE); @@ -791,11 +826,18 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk, struct nft_ctx ctx; nft_ctx_init(&ctx, net, skb, nlh, 0, NULL, NULL, nla); - if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL) + if (family == AF_UNSPEC || + (!nla[NFTA_TABLE_NAME] && !nla[NFTA_TABLE_HANDLE])) return nft_flush(&ctx, family); - table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], family, - genmask); + if (nla[NFTA_TABLE_HANDLE]) + table = nf_tables_table_lookup_byhandle(net, + nla[NFTA_TABLE_HANDLE], + genmask); + else + table = nf_tables_table_lookup(net, nla[NFTA_TABLE_NAME], + family, genmask); + if (IS_ERR(table)) return PTR_ERR(table); @@ -1539,6 +1581,7 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk, struct nft_rule *rule; int family = nfmsg->nfgen_family; struct nft_ctx ctx; + u64 handle; u32 use; int err; @@ -1547,7 +1590,12 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk, if (IS_ERR(table)) return PTR_ERR(table); - chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask); + if (nla[NFTA_CHAIN_HANDLE]) { + handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE])); + chain = nf_tables_chain_lookup_byhandle(table, handle, genmask); + } else { + chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask); + } if (IS_ERR(chain)) return PTR_ERR(chain); @@ -2503,6 +2551,7 @@ static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = { [NFTA_SET_USERDATA] = { .type = NLA_BINARY, .len = NFT_USERDATA_MAXLEN }, [NFTA_SET_OBJ_TYPE] = { .type = NLA_U32 }, + [NFTA_SET_HANDLE] = { .type = NLA_U64 }, }; static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = { @@ -2546,6 +2595,22 @@ static struct nft_set *nf_tables_set_lookup(const struct nft_table *table, return ERR_PTR(-ENOENT); } +static struct nft_set *nf_tables_set_lookup_byhandle(const struct nft_table *table, + const struct nlattr *nla, u8 genmask) +{ + struct nft_set *set; + + if (nla == NULL) + return ERR_PTR(-EINVAL); + + list_for_each_entry(set, &table->sets, list) { + if (be64_to_cpu(nla_get_be64(nla)) == set->handle && + nft_active_genmask(set, genmask)) + return set; + } + return ERR_PTR(-ENOENT); +} + static struct nft_set *nf_tables_set_lookup_byid(const struct net *net, const struct nlattr *nla, u8 genmask) @@ -2661,6 +2726,9 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx, goto nla_put_failure; if (nla_put_string(skb, NFTA_SET_NAME, set->name)) goto nla_put_failure; + if (nla_put_be64(skb, NFTA_SET_HANDLE, cpu_to_be64(set->handle), + NFTA_SET_PAD)) + goto nla_put_failure; if (set->flags != 0) if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags))) goto nla_put_failure; @@ -3069,6 +3137,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, set->udata = udata; set->timeout = timeout; set->gc_int = gc_int; + set->handle = nf_tables_alloc_handle(table); err = ops->init(set, &desc, nla); if (err < 0) @@ -3126,7 +3195,10 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk, if (err < 0) return err; - set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask); + if (nla[NFTA_SET_HANDLE]) + set = nf_tables_set_lookup_byhandle(ctx.table, nla[NFTA_SET_HANDLE], genmask); + else + set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask); if (IS_ERR(set)) return PTR_ERR(set); @@ -4256,6 +4328,21 @@ struct nft_object *nf_tables_obj_lookup(const struct nft_table *table, } EXPORT_SYMBOL_GPL(nf_tables_obj_lookup); +struct nft_object *nf_tables_obj_lookup_byhandle(const struct nft_table *table, + const struct nlattr *nla, + u32 objtype, u8 genmask) +{ + struct nft_object *obj; + + list_for_each_entry(obj, &table->objects, list) { + if (be64_to_cpu(nla_get_be64(nla)) == obj->handle && + objtype == obj->ops->type->type && + nft_active_genmask(obj, genmask)) + return obj; + } + return ERR_PTR(-ENOENT); +} + static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = { [NFTA_OBJ_TABLE] = { .type = NLA_STRING, .len = NFT_TABLE_MAXNAMELEN - 1 }, @@ -4263,6 +4350,7 @@ static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = { .len = NFT_OBJ_MAXNAMELEN - 1 }, [NFTA_OBJ_TYPE] = { .type = NLA_U32 }, [NFTA_OBJ_DATA] = { .type = NLA_NESTED }, + [NFTA_OBJ_HANDLE] = { .type = NLA_U64}, }; static struct nft_object *nft_obj_init(const struct nft_ctx *ctx, @@ -4410,6 +4498,8 @@ static int nf_tables_newobj(struct net *net, struct sock *nlsk, goto err1; } obj->table = table; + obj->handle = nf_tables_alloc_handle(table); + obj->name = nla_strdup(nla[NFTA_OBJ_NAME], GFP_KERNEL); if (!obj->name) { err = -ENOMEM; @@ -4456,7 +4546,9 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net, nla_put_string(skb, NFTA_OBJ_NAME, obj->name) || nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) || nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) || - nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset)) + nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset) || + nla_put_be64(skb, NFTA_OBJ_HANDLE, cpu_to_be64(obj->handle), + NFTA_OBJ_PAD)) goto nla_put_failure; nlmsg_end(skb, nlh); @@ -4654,7 +4746,7 @@ static int nf_tables_delobj(struct net *net, struct sock *nlsk, u32 objtype; if (!nla[NFTA_OBJ_TYPE] || - !nla[NFTA_OBJ_NAME]) + (!nla[NFTA_OBJ_NAME] && !nla[NFTA_OBJ_HANDLE])) return -EINVAL; table = nf_tables_table_lookup(net, nla[NFTA_OBJ_TABLE], family, @@ -4663,7 +4755,12 @@ static int nf_tables_delobj(struct net *net, struct sock *nlsk, return PTR_ERR(table); objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE])); - obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask); + if (nla[NFTA_OBJ_HANDLE]) + obj = nf_tables_obj_lookup_byhandle(table, nla[NFTA_OBJ_HANDLE], + objtype, genmask); + else + obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], + objtype, genmask); if (IS_ERR(obj)) return PTR_ERR(obj); if (obj->use > 0) @@ -4735,6 +4832,7 @@ static const struct nla_policy nft_flowtable_policy[NFTA_FLOWTABLE_MAX + 1] = { [NFTA_FLOWTABLE_NAME] = { .type = NLA_STRING, .len = NFT_NAME_MAXLEN - 1 }, [NFTA_FLOWTABLE_HOOK] = { .type = NLA_NESTED }, + [NFTA_FLOWTABLE_HANDLE] = { .type = NLA_U64 }, }; struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table, @@ -4752,6 +4850,20 @@ struct nft_flowtable *nf_tables_flowtable_lookup(const struct nft_table *table, } EXPORT_SYMBOL_GPL(nf_tables_flowtable_lookup); +struct nft_flowtable * +nf_tables_flowtable_lookup_byhandle(const struct nft_table *table, + const struct nlattr *nla, u8 genmask) +{ + struct nft_flowtable *flowtable; + + list_for_each_entry(flowtable, &table->flowtables, list) { + if (be64_to_cpu(nla_get_be64(nla)) == flowtable->handle && + nft_active_genmask(flowtable, genmask)) + return flowtable; + } + return ERR_PTR(-ENOENT); +} + #define NFT_FLOWTABLE_DEVICE_MAX 8 static int nf_tables_parse_devices(const struct nft_ctx *ctx, @@ -4960,6 +5072,8 @@ static int nf_tables_newflowtable(struct net *net, struct sock *nlsk, return -ENOMEM; flowtable->table = table; + flowtable->handle = nf_tables_alloc_handle(table); + flowtable->name = nla_strdup(nla[NFTA_FLOWTABLE_NAME], GFP_KERNEL); if (!flowtable->name) { err = -ENOMEM; @@ -5034,8 +5148,14 @@ static int nf_tables_delflowtable(struct net *net, struct sock *nlsk, if (IS_ERR(table)) return PTR_ERR(table); - flowtable = nf_tables_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME], - genmask); + if (nla[NFTA_FLOWTABLE_HANDLE]) + flowtable = nf_tables_flowtable_lookup_byhandle(table, + nla[NFTA_FLOWTABLE_HANDLE], + genmask); + else + flowtable = nf_tables_flowtable_lookup(table, + nla[NFTA_FLOWTABLE_NAME], + genmask); if (IS_ERR(flowtable)) return PTR_ERR(flowtable); if (flowtable->use > 0) @@ -5068,7 +5188,9 @@ static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net, if (nla_put_string(skb, NFTA_FLOWTABLE_TABLE, flowtable->table->name) || nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) || - nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use))) + nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) || + nla_put_be64(skb, NFTA_FLOWTABLE_HANDLE, cpu_to_be64(flowtable->handle), + NFTA_FLOWTABLE_PAD)) goto nla_put_failure; nest = nla_nest_start(skb, NFTA_FLOWTABLE_HOOK); -- cgit v1.2.3-59-g8ed1b From 4db5a802e565f0a60e08bd39a055f0095689802b Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 16 Jan 2018 23:01:57 +0100 Subject: l2tp: mark L2TP_ATTR_L2SPEC_LEN as not used Reviewed-by: Guillaume Nault Tested-by: Guillaume Nault Signed-off-by: Lorenzo Bianconi Signed-off-by: David S. Miller --- include/uapi/linux/l2tp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h index 71e62795104d..7d570c7bd117 100644 --- a/include/uapi/linux/l2tp.h +++ b/include/uapi/linux/l2tp.h @@ -97,7 +97,7 @@ enum { L2TP_ATTR_OFFSET, /* u16 (not used) */ L2TP_ATTR_DATA_SEQ, /* u16 */ L2TP_ATTR_L2SPEC_TYPE, /* u8, enum l2tp_l2spec_type */ - L2TP_ATTR_L2SPEC_LEN, /* u8, enum l2tp_l2spec_type */ + L2TP_ATTR_L2SPEC_LEN, /* u8 (not used) */ L2TP_ATTR_PROTO_VERSION, /* u8 */ L2TP_ATTR_IFNAME, /* string */ L2TP_ATTR_CONN_ID, /* u32 */ -- cgit v1.2.3-59-g8ed1b From c5cc1f4df6b16646f8fae7aab523c1820bf916e8 Mon Sep 17 00:00:00 2001 From: Thiago Jung Bauermann Date: Thu, 18 Jan 2018 17:50:43 -0800 Subject: powerpc/ptrace: Add memory protection key regset The AMR/IAMR/UAMOR are part of the program context. Allow it to be accessed via ptrace and through core files. Signed-off-by: Ram Pai Signed-off-by: Thiago Jung Bauermann Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/pkeys.h | 5 +++ arch/powerpc/include/uapi/asm/elf.h | 1 + arch/powerpc/kernel/ptrace.c | 66 +++++++++++++++++++++++++++++++++++++ arch/powerpc/kernel/traps.c | 7 ++++ include/uapi/linux/elf.h | 1 + 5 files changed, 80 insertions(+) (limited to 'include/uapi/linux') diff --git a/arch/powerpc/include/asm/pkeys.h b/arch/powerpc/include/asm/pkeys.h index 2298771b066b..c3cbad824e5a 100644 --- a/arch/powerpc/include/asm/pkeys.h +++ b/arch/powerpc/include/asm/pkeys.h @@ -202,6 +202,11 @@ static inline int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, return __arch_set_user_pkey_access(tsk, pkey, init_val); } +static inline bool arch_pkeys_enabled(void) +{ + return !static_branch_likely(&pkey_disabled); +} + extern void pkey_mm_init(struct mm_struct *mm); extern void thread_pkey_regs_save(struct thread_struct *thread); extern void thread_pkey_regs_restore(struct thread_struct *new_thread, diff --git a/arch/powerpc/include/uapi/asm/elf.h b/arch/powerpc/include/uapi/asm/elf.h index 5f201d40bcca..860c59291bfc 100644 --- a/arch/powerpc/include/uapi/asm/elf.h +++ b/arch/powerpc/include/uapi/asm/elf.h @@ -97,6 +97,7 @@ #define ELF_NTMSPRREG 3 /* include tfhar, tfiar, texasr */ #define ELF_NEBB 3 /* includes ebbrr, ebbhr, bescr */ #define ELF_NPMU 5 /* includes siar, sdar, sier, mmcr2, mmcr0 */ +#define ELF_NPKEY 3 /* includes amr, iamr, uamor */ typedef unsigned long elf_greg_t64; typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG]; diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index aef08e579946..ca72d7391d40 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -1787,6 +1788,61 @@ static int pmu_set(struct task_struct *target, return ret; } #endif + +#ifdef CONFIG_PPC_MEM_KEYS +static int pkey_active(struct task_struct *target, + const struct user_regset *regset) +{ + if (!arch_pkeys_enabled()) + return -ENODEV; + + return regset->n; +} + +static int pkey_get(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) +{ + BUILD_BUG_ON(TSO(amr) + sizeof(unsigned long) != TSO(iamr)); + BUILD_BUG_ON(TSO(iamr) + sizeof(unsigned long) != TSO(uamor)); + + if (!arch_pkeys_enabled()) + return -ENODEV; + + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, + &target->thread.amr, 0, + ELF_NPKEY * sizeof(unsigned long)); +} + +static int pkey_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + u64 new_amr; + int ret; + + if (!arch_pkeys_enabled()) + return -ENODEV; + + /* Only the AMR can be set from userspace */ + if (pos != 0 || count != sizeof(new_amr)) + return -EINVAL; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &new_amr, 0, sizeof(new_amr)); + if (ret) + return ret; + + /* UAMOR determines which bits of the AMR can be set from userspace. */ + target->thread.amr = (new_amr & target->thread.uamor) | + (target->thread.amr & ~target->thread.uamor); + + return 0; +} +#endif /* CONFIG_PPC_MEM_KEYS */ + /* * These are our native regset flavors. */ @@ -1821,6 +1877,9 @@ enum powerpc_regset { REGSET_EBB, /* EBB registers */ REGSET_PMR, /* Performance Monitor Registers */ #endif +#ifdef CONFIG_PPC_MEM_KEYS + REGSET_PKEY, /* AMR register */ +#endif }; static const struct user_regset native_regsets[] = { @@ -1926,6 +1985,13 @@ static const struct user_regset native_regsets[] = { .active = pmu_active, .get = pmu_get, .set = pmu_set }, #endif +#ifdef CONFIG_PPC_MEM_KEYS + [REGSET_PKEY] = { + .core_note_type = NT_PPC_PKEY, .n = ELF_NPKEY, + .size = sizeof(u64), .align = sizeof(u64), + .active = pkey_active, .get = pkey_get, .set = pkey_set + }, +#endif }; static const struct user_regset_view user_ppc_native_view = { diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 4b1a8e2ec023..122a3c883f4e 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -292,6 +292,13 @@ void _exception_pkey(int signr, struct pt_regs *regs, int code, local_irq_enable(); current->thread.trap_nr = code; + + /* + * Save all the pkey registers AMR/IAMR/UAMOR. Eg: Core dumps need + * to capture the content, if the task gets killed. + */ + thread_pkey_regs_save(¤t->thread); + memset(&info, 0, sizeof(info)); info.si_signo = signr; info.si_code = code; diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index bb6836986200..3bf73fb58045 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h @@ -396,6 +396,7 @@ typedef struct elf64_shdr { #define NT_PPC_TM_CTAR 0x10d /* TM checkpointed Target Address Register */ #define NT_PPC_TM_CPPR 0x10e /* TM checkpointed Program Priority Register */ #define NT_PPC_TM_CDSCR 0x10f /* TM checkpointed Data Stream Control Register */ +#define NT_PPC_PKEY 0x110 /* Memory Protection Keys registers */ #define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ #define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ -- cgit v1.2.3-59-g8ed1b From e8660ded7f5a9889395d33ce3d5e8c729a462bf5 Mon Sep 17 00:00:00 2001 From: Sabrina Dubroca Date: Thu, 18 Jan 2018 17:48:18 +0100 Subject: macsec: restore uAPI after addition of GCM-AES-256 Commit ccfdec908922 ("macsec: Add support for GCM-AES-256 cipher suite") changed a few values in the uapi headers for MACsec. Because of existing userspace implementations, we need to preserve the value of MACSEC_DEFAULT_CIPHER_ID. Not doing that resulted in wpa_supplicant segfaults when a secure channel was created using the default cipher. Thus, swap MACSEC_DEFAULT_CIPHER_{ID,ALT} back to their original values. Changing the maximum length of the MACSEC_SA_ATTR_KEY attribute is unnecessary, as the previous value (MACSEC_MAX_KEY_LEN, which was 128B) is large enough to carry 32-bytes keys. This patch reverts MACSEC_MAX_KEY_LEN to 128B and restores the old length check on MACSEC_SA_ATTR_KEY. Fixes: ccfdec908922 ("macsec: Add support for GCM-AES-256 cipher suite") Signed-off-by: Davide Caratti Signed-off-by: Sabrina Dubroca Signed-off-by: David S. Miller --- drivers/net/macsec.c | 12 +++++------- include/uapi/linux/if_macsec.h | 6 +++--- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index f522715c6595..7de88b33d5b9 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -396,8 +396,6 @@ static struct macsec_cb *macsec_skb_cb(struct sk_buff *skb) #define MACSEC_GCM_AES_128_SAK_LEN 16 #define MACSEC_GCM_AES_256_SAK_LEN 32 -#define MAX_SAK_LEN MACSEC_GCM_AES_256_SAK_LEN - #define DEFAULT_SAK_LEN MACSEC_GCM_AES_128_SAK_LEN #define DEFAULT_SEND_SCI true #define DEFAULT_ENCRYPT false @@ -1605,7 +1603,7 @@ static const struct nla_policy macsec_genl_sa_policy[NUM_MACSEC_SA_ATTR] = { [MACSEC_SA_ATTR_KEYID] = { .type = NLA_BINARY, .len = MACSEC_KEYID_LEN, }, [MACSEC_SA_ATTR_KEY] = { .type = NLA_BINARY, - .len = MAX_SAK_LEN, }, + .len = MACSEC_MAX_KEY_LEN, }, }; static int parse_sa_config(struct nlattr **attrs, struct nlattr **tb_sa) @@ -2374,7 +2372,7 @@ static int nla_put_secy(struct macsec_secy *secy, struct sk_buff *skb) switch (secy->key_len) { case MACSEC_GCM_AES_128_SAK_LEN: - csid = MACSEC_CIPHER_ID_GCM_AES_128; + csid = MACSEC_DEFAULT_CIPHER_ID; break; case MACSEC_GCM_AES_256_SAK_LEN: csid = MACSEC_CIPHER_ID_GCM_AES_256; @@ -3076,7 +3074,7 @@ static int macsec_changelink_common(struct net_device *dev, if (data[IFLA_MACSEC_CIPHER_SUITE]) { switch (nla_get_u64(data[IFLA_MACSEC_CIPHER_SUITE])) { case MACSEC_CIPHER_ID_GCM_AES_128: - case MACSEC_DEFAULT_CIPHER_ALT: + case MACSEC_DEFAULT_CIPHER_ID: secy->key_len = MACSEC_GCM_AES_128_SAK_LEN; break; case MACSEC_CIPHER_ID_GCM_AES_256: @@ -3355,7 +3353,7 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[], switch (csid) { case MACSEC_CIPHER_ID_GCM_AES_128: case MACSEC_CIPHER_ID_GCM_AES_256: - case MACSEC_DEFAULT_CIPHER_ALT: + case MACSEC_DEFAULT_CIPHER_ID: if (icv_len < MACSEC_MIN_ICV_LEN || icv_len > MACSEC_STD_ICV_LEN) return -EINVAL; @@ -3428,7 +3426,7 @@ static int macsec_fill_info(struct sk_buff *skb, switch (secy->key_len) { case MACSEC_GCM_AES_128_SAK_LEN: - csid = MACSEC_CIPHER_ID_GCM_AES_128; + csid = MACSEC_DEFAULT_CIPHER_ID; break; case MACSEC_GCM_AES_256_SAK_LEN: csid = MACSEC_CIPHER_ID_GCM_AES_256; diff --git a/include/uapi/linux/if_macsec.h b/include/uapi/linux/if_macsec.h index 2e522835a4af..98e4d5d7c45c 100644 --- a/include/uapi/linux/if_macsec.h +++ b/include/uapi/linux/if_macsec.h @@ -18,7 +18,7 @@ #define MACSEC_GENL_NAME "macsec" #define MACSEC_GENL_VERSION 1 -#define MACSEC_MAX_KEY_LEN 256 +#define MACSEC_MAX_KEY_LEN 128 #define MACSEC_KEYID_LEN 16 @@ -26,9 +26,9 @@ #define MACSEC_CIPHER_ID_GCM_AES_128 0x0080C20001000001ULL #define MACSEC_CIPHER_ID_GCM_AES_256 0x0080C20001000002ULL -#define MACSEC_DEFAULT_CIPHER_ID MACSEC_CIPHER_ID_GCM_AES_128 /* deprecated cipher ID for GCM-AES-128 */ -#define MACSEC_DEFAULT_CIPHER_ALT 0x0080020001000001ULL +#define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL +#define MACSEC_DEFAULT_CIPHER_ALT MACSEC_CIPHER_ID_GCM_AES_128 #define MACSEC_MIN_ICV_LEN 8 #define MACSEC_MAX_ICV_LEN 32 -- cgit v1.2.3-59-g8ed1b From b2d3bcfa26a7a8de41f358a6cae8b848673b3c6e Mon Sep 17 00:00:00 2001 From: David Decotigny Date: Thu, 18 Jan 2018 09:59:13 -0800 Subject: net: core: Expose number of link up/down transitions Expose the number of times the link has been going UP or DOWN, and update the "carrier_changes" counter to be the sum of these two events. While at it, also update the sysfs-class-net documentation to cover: carrier_changes (3.15), carrier_up_count (4.16) and carrier_down_count (4.16) Signed-off-by: David Decotigny [Florian: * rebase * add documentation * merge carrier_changes with up/down counters] Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- Documentation/ABI/testing/sysfs-class-net | 24 ++++++++++++++++++++++++ include/linux/netdevice.h | 6 ++++-- include/uapi/linux/if_link.h | 2 ++ net/core/net-sysfs.c | 25 ++++++++++++++++++++++++- net/core/rtnetlink.c | 13 +++++++++++-- net/sched/sch_generic.c | 4 ++-- 6 files changed, 67 insertions(+), 7 deletions(-) (limited to 'include/uapi/linux') diff --git a/Documentation/ABI/testing/sysfs-class-net b/Documentation/ABI/testing/sysfs-class-net index 6856da99b6f7..2f1788111cd9 100644 --- a/Documentation/ABI/testing/sysfs-class-net +++ b/Documentation/ABI/testing/sysfs-class-net @@ -259,3 +259,27 @@ Contact: netdev@vger.kernel.org Description: Symbolic link to the PHY device this network device is attached to. + +What: /sys/class/net//carrier_changes +Date: Mar 2014 +KernelVersion: 3.15 +Contact: netdev@vger.kernel.org +Description: + 32-bit unsigned integer counting the number of times the link has + seen a change from UP to DOWN and vice versa + +What: /sys/class/net//carrier_up_count +Date: Jan 2018 +KernelVersion: 4.16 +Contact: netdev@vger.kernel.org +Description: + 32-bit unsigned integer counting the number of times the link has + been up + +What: /sys/class/net//carrier_down_count +Date: Jan 2018 +KernelVersion: 4.16 +Contact: netdev@vger.kernel.org +Description: + 32-bit unsigned integer counting the number of times the link has + been down diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index ed0799a12bf2..837e9cb7e358 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1680,8 +1680,6 @@ struct net_device { unsigned long base_addr; int irq; - atomic_t carrier_changes; - /* * Some hardware also needs these fields (state,dev_list, * napi_list,unreg_list,close_list) but they are not @@ -1719,6 +1717,10 @@ struct net_device { atomic_long_t tx_dropped; atomic_long_t rx_nohandler; + /* Stats to monitor link on/off, flapping */ + atomic_t carrier_up_count; + atomic_t carrier_down_count; + #ifdef CONFIG_WIRELESS_EXT const struct iw_handler_def *wireless_handlers; struct iw_public_data *wireless_data; diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index f8f04fed6186..8616131e2c61 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -161,6 +161,8 @@ enum { IFLA_EVENT, IFLA_NEW_NETNSID, IFLA_IF_NETNSID, + IFLA_CARRIER_UP_COUNT, + IFLA_CARRIER_DOWN_COUNT, __IFLA_MAX }; diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 7bf8b85ade16..c4a28f4667b6 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -295,10 +295,31 @@ static ssize_t carrier_changes_show(struct device *dev, struct net_device *netdev = to_net_dev(dev); return sprintf(buf, fmt_dec, - atomic_read(&netdev->carrier_changes)); + atomic_read(&netdev->carrier_up_count) + + atomic_read(&netdev->carrier_down_count)); } static DEVICE_ATTR_RO(carrier_changes); +static ssize_t carrier_up_count_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct net_device *netdev = to_net_dev(dev); + + return sprintf(buf, fmt_dec, atomic_read(&netdev->carrier_up_count)); +} +static DEVICE_ATTR_RO(carrier_up_count); + +static ssize_t carrier_down_count_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct net_device *netdev = to_net_dev(dev); + + return sprintf(buf, fmt_dec, atomic_read(&netdev->carrier_down_count)); +} +static DEVICE_ATTR_RO(carrier_down_count); + /* read-write attributes */ static int change_mtu(struct net_device *dev, unsigned long new_mtu) @@ -547,6 +568,8 @@ static struct attribute *net_class_attrs[] __ro_after_init = { &dev_attr_phys_port_name.attr, &dev_attr_phys_switch_id.attr, &dev_attr_proto_down.attr, + &dev_attr_carrier_up_count.attr, + &dev_attr_carrier_down_count.attr, NULL, }; ATTRIBUTE_GROUPS(net_class); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 16d644a4f974..97874daa1336 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -990,6 +990,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev, + nla_total_size(4) /* IFLA_NEW_NETNSID */ + nla_total_size(1) /* IFLA_PROTO_DOWN */ + nla_total_size(4) /* IFLA_IF_NETNSID */ + + nla_total_size(4) /* IFLA_CARRIER_UP_COUNT */ + + nla_total_size(4) /* IFLA_CARRIER_DOWN_COUNT */ + 0; } @@ -1551,8 +1553,13 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) || nla_put_ifalias(skb, dev) || nla_put_u32(skb, IFLA_CARRIER_CHANGES, - atomic_read(&dev->carrier_changes)) || - nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down)) + atomic_read(&dev->carrier_up_count) + + atomic_read(&dev->carrier_down_count)) || + nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down) || + nla_put_u32(skb, IFLA_CARRIER_UP_COUNT, + atomic_read(&dev->carrier_up_count)) || + nla_put_u32(skb, IFLA_CARRIER_DOWN_COUNT, + atomic_read(&dev->carrier_down_count))) goto nla_put_failure; if (event != IFLA_EVENT_NONE) { @@ -1656,6 +1663,8 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = { [IFLA_EVENT] = { .type = NLA_U32 }, [IFLA_GROUP] = { .type = NLA_U32 }, [IFLA_IF_NETNSID] = { .type = NLA_S32 }, + [IFLA_CARRIER_UP_COUNT] = { .type = NLA_U32 }, + [IFLA_CARRIER_DOWN_COUNT] = { .type = NLA_U32 }, }; static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index ef8b4ecde2ac..1816bde47256 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -510,7 +510,7 @@ void netif_carrier_on(struct net_device *dev) if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) { if (dev->reg_state == NETREG_UNINITIALIZED) return; - atomic_inc(&dev->carrier_changes); + atomic_inc(&dev->carrier_up_count); linkwatch_fire_event(dev); if (netif_running(dev)) __netdev_watchdog_up(dev); @@ -529,7 +529,7 @@ void netif_carrier_off(struct net_device *dev) if (!test_and_set_bit(__LINK_STATE_NOCARRIER, &dev->state)) { if (dev->reg_state == NETREG_UNINITIALIZED) return; - atomic_inc(&dev->carrier_changes); + atomic_inc(&dev->carrier_down_count); linkwatch_fire_event(dev); } } -- cgit v1.2.3-59-g8ed1b From c1696fb85d33194cf65c7ebfc82a75696299c3a3 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Wed, 17 Jan 2018 00:01:33 +0100 Subject: GFS2: Introduce new gfs2_log_header_v2 This patch adds a new structure called gfs2_log_header_v2 which is used to store expanded fields into previously unused areas of the log headers (i.e., this change is backwards compatible). Some of these are used for debug purposes so we can backtrack when problems occur. Others are reserved for future expansion. This patch is based on a prototype from Steve Whitehouse. Signed-off-by: Bob Peterson Signed-off-by: Andreas Gruenbacher --- fs/gfs2/Kconfig | 2 ++ fs/gfs2/aops.c | 2 +- fs/gfs2/file.c | 3 +- fs/gfs2/glops.c | 13 +++---- fs/gfs2/log.c | 75 ++++++++++++++++++++++++++++++---------- fs/gfs2/log.h | 12 ++----- fs/gfs2/lops.c | 16 +++++---- fs/gfs2/lops.h | 3 ++ fs/gfs2/ops_fstype.c | 2 +- fs/gfs2/quota.c | 3 +- fs/gfs2/recovery.c | 17 +++++---- fs/gfs2/rgrp.c | 2 +- fs/gfs2/super.c | 9 ++--- fs/gfs2/trans.c | 2 +- include/uapi/linux/gfs2_ondisk.h | 26 ++++++++++++-- 15 files changed, 128 insertions(+), 59 deletions(-) (limited to 'include/uapi/linux') diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig index 43c827a7cce5..c0225d4b5435 100644 --- a/fs/gfs2/Kconfig +++ b/fs/gfs2/Kconfig @@ -3,6 +3,8 @@ config GFS2_FS depends on (64BIT || LBDAF) select FS_POSIX_ACL select CRC32 + select CRYPTO + select CRYPTO_CRC32C select QUOTACTL select FS_IOMAP help diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index ac4a1e89da1e..462c3fd55929 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -448,7 +448,7 @@ static int gfs2_jdata_writepages(struct address_space *mapping, ret = gfs2_write_cache_jdata(mapping, wbc); if (ret == 0 && wbc->sync_mode == WB_SYNC_ALL) { - gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH); + gfs2_log_flush(sdp, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL); ret = gfs2_write_cache_jdata(mapping, wbc); } return ret; diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index bd60dc682676..7a02b4e6e9f3 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -246,7 +246,8 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) } if ((flags ^ new_flags) & GFS2_DIF_JDATA) { if (new_flags & GFS2_DIF_JDATA) - gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH); + gfs2_log_flush(sdp, ip->i_gl, + GFS2_LOG_HEAD_FLUSH_NORMAL); error = filemap_fdatawrite(inode->i_mapping); if (error) goto out; diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index cdd1c5f06f45..2daab13a9e0b 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -107,7 +107,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) __gfs2_ail_flush(gl, 0, tr.tr_revokes); gfs2_trans_end(sdp); - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); } void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) @@ -128,7 +128,7 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) return; __gfs2_ail_flush(gl, fsync, max_revokes); gfs2_trans_end(sdp); - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); } /** @@ -157,7 +157,7 @@ static void rgrp_go_sync(struct gfs2_glock *gl) return; GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); - gfs2_log_flush(sdp, gl, NORMAL_FLUSH); + gfs2_log_flush(sdp, gl, GFS2_LOG_HEAD_FLUSH_NORMAL); filemap_fdatawrite_range(mapping, gl->gl_vm.start, gl->gl_vm.end); error = filemap_fdatawait_range(mapping, gl->gl_vm.start, gl->gl_vm.end); mapping_set_error(mapping, error); @@ -252,7 +252,7 @@ static void inode_go_sync(struct gfs2_glock *gl) GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); - gfs2_log_flush(gl->gl_name.ln_sbd, gl, NORMAL_FLUSH); + gfs2_log_flush(gl->gl_name.ln_sbd, gl, GFS2_LOG_HEAD_FLUSH_NORMAL); filemap_fdatawrite(metamapping); if (isreg) { struct address_space *mapping = ip->i_inode.i_mapping; @@ -303,7 +303,8 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags) } if (ip == GFS2_I(gl->gl_name.ln_sbd->sd_rindex)) { - gfs2_log_flush(gl->gl_name.ln_sbd, NULL, NORMAL_FLUSH); + gfs2_log_flush(gl->gl_name.ln_sbd, NULL, + GFS2_LOG_HEAD_FLUSH_NORMAL); gl->gl_name.ln_sbd->sd_rindex_uptodate = 0; } if (ip && S_ISREG(ip->i_inode.i_mode)) @@ -495,7 +496,7 @@ static void freeze_go_sync(struct gfs2_glock *gl) gfs2_assert_withdraw(sdp, 0); } queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work); - gfs2_log_flush(sdp, NULL, FREEZE_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE); } } diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index c27cbcebfe88..a2eb13c04591 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -653,20 +654,25 @@ out_of_blocks: /** * write_log_header - Write a journal log header buffer at sd_log_flush_head * @sdp: The GFS2 superblock + * @jd: journal descriptor of the journal to which we are writing * @seq: sequence number * @tail: tail of the log - * @flags: log header flags + * @flags: log header flags GFS2_LOG_HEAD_* * @op_flags: flags to pass to the bio * * Returns: the initialized log buffer descriptor */ -void gfs2_write_log_header(struct gfs2_sbd *sdp, u64 seq, u32 tail, - u32 flags, int op_flags) +void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, + u64 seq, u32 tail, u32 flags, int op_flags) { struct gfs2_log_header *lh; - u32 hash; + u32 hash, crc; struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); + struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; + struct timespec64 tv; + struct super_block *sb = sdp->sd_vfs; + u64 addr; lh = page_address(page); clear_page(lh); @@ -680,10 +686,39 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, u64 seq, u32 tail, lh->lh_flags = cpu_to_be32(flags); lh->lh_tail = cpu_to_be32(tail); lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head); - hash = ~crc32(~0, lh, sizeof(*lh)); + hash = ~crc32(~0, lh, LH_V1_SIZE); lh->lh_hash = cpu_to_be32(hash); - gfs2_log_write_page(sdp, page); + tv = current_kernel_time64(); + lh->lh_nsec = cpu_to_be32(tv.tv_nsec); + lh->lh_sec = cpu_to_be64(tv.tv_sec); + addr = gfs2_log_bmap(sdp); + lh->lh_addr = cpu_to_be64(addr); + lh->lh_jinode = cpu_to_be64(GFS2_I(jd->jd_inode)->i_no_addr); + + /* We may only write local statfs, quota, etc., when writing to our + own journal. The values are left 0 when recovering a journal + different from our own. */ + if (!(flags & GFS2_LOG_HEAD_RECOVERY)) { + lh->lh_statfs_addr = + cpu_to_be64(GFS2_I(sdp->sd_sc_inode)->i_no_addr); + lh->lh_quota_addr = + cpu_to_be64(GFS2_I(sdp->sd_qc_inode)->i_no_addr); + + spin_lock(&sdp->sd_statfs_spin); + lh->lh_local_total = cpu_to_be64(l_sc->sc_total); + lh->lh_local_free = cpu_to_be64(l_sc->sc_free); + lh->lh_local_dinodes = cpu_to_be64(l_sc->sc_dinodes); + spin_unlock(&sdp->sd_statfs_spin); + } + + BUILD_BUG_ON(offsetof(struct gfs2_log_header, lh_crc) != LH_V1_SIZE); + + crc = crc32c(~0, (void *)lh + LH_V1_SIZE + 4, + sb->s_blocksize - LH_V1_SIZE - 4); + lh->lh_crc = cpu_to_be32(crc); + + gfs2_log_write(sdp, page, sb->s_blocksize, 0, addr); gfs2_log_flush_bio(sdp, REQ_OP_WRITE, op_flags); log_flush_wait(sdp); } @@ -691,6 +726,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, u64 seq, u32 tail, /** * log_write_header - Get and initialize a journal header buffer * @sdp: The GFS2 superblock + * @flags: The log header flags, including log header origin * * Returns: the initialized log buffer descriptor */ @@ -710,8 +746,8 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags) op_flags = REQ_SYNC | REQ_META | REQ_PRIO; } sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); - gfs2_write_log_header(sdp, sdp->sd_log_sequence++, tail, flags, - op_flags); + gfs2_write_log_header(sdp, sdp->sd_jdesc, sdp->sd_log_sequence++, tail, + flags, op_flags); if (sdp->sd_log_tail != tail) log_pull_tail(sdp, tail); @@ -721,11 +757,11 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags) * gfs2_log_flush - flush incore transaction(s) * @sdp: the filesystem * @gl: The glock structure to flush. If NULL, flush the whole incore log + * @flags: The log header flags: GFS2_LOG_HEAD_FLUSH_* * */ -void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, - enum gfs2_flush_type type) +void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags) { struct gfs2_trans *tr; enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state); @@ -739,7 +775,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, } trace_gfs2_log_flush(sdp, 1); - if (type == SHUTDOWN_FLUSH) + if (flags & GFS2_LOG_HEAD_FLUSH_SHUTDOWN) clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); sdp->sd_log_flush_head = sdp->sd_log_head; @@ -764,11 +800,11 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, if (sdp->sd_log_head != sdp->sd_log_flush_head) { log_flush_wait(sdp); - log_write_header(sdp, 0); + log_write_header(sdp, flags); } else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ trace_gfs2_log_blocks(sdp, -1); - log_write_header(sdp, 0); + log_write_header(sdp, flags); } lops_after_commit(sdp, tr); @@ -785,7 +821,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, spin_unlock(&sdp->sd_ail_lock); gfs2_log_unlock(sdp); - if (type != NORMAL_FLUSH) { + if (!(flags & GFS2_LOG_HEAD_FLUSH_NORMAL)) { if (!sdp->sd_log_idle) { for (;;) { gfs2_ail1_start(sdp); @@ -795,12 +831,13 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, } atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ trace_gfs2_log_blocks(sdp, -1); - log_write_header(sdp, 0); + log_write_header(sdp, flags); sdp->sd_log_head = sdp->sd_log_flush_head; } - if (type == SHUTDOWN_FLUSH || type == FREEZE_FLUSH) + if (flags & (GFS2_LOG_HEAD_FLUSH_SHUTDOWN | + GFS2_LOG_HEAD_FLUSH_FREEZE)) gfs2_log_shutdown(sdp); - if (type == FREEZE_FLUSH) + if (flags & GFS2_LOG_HEAD_FLUSH_FREEZE) atomic_set(&sdp->sd_freeze_state, SFS_FROZEN); } @@ -956,7 +993,7 @@ int gfs2_logd(void *data) did_flush = false; if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { gfs2_ail1_empty(sdp); - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); did_flush = true; } @@ -964,7 +1001,7 @@ int gfs2_logd(void *data) gfs2_ail1_start(sdp); gfs2_ail1_wait(sdp); gfs2_ail1_empty(sdp); - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); did_flush = true; } diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h index 619de9a1ff4f..93b52ac1ca1f 100644 --- a/fs/gfs2/log.h +++ b/fs/gfs2/log.h @@ -65,16 +65,10 @@ extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, extern void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks); extern int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); -enum gfs2_flush_type { - NORMAL_FLUSH = 0, - SYNC_FLUSH, - SHUTDOWN_FLUSH, - FREEZE_FLUSH -}; -extern void gfs2_write_log_header(struct gfs2_sbd *sdp, u64 seq, u32 tail, - u32 flags, int op_flags); +extern void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, + u64 seq, u32 tail, u32 flags, int op_flags); extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, - enum gfs2_flush_type type); + u32 type); extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd); extern void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc); diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index c8ff7b7954f0..4a60221c678f 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -18,6 +18,7 @@ #include #include +#include "dir.h" #include "gfs2.h" #include "incore.h" #include "inode.h" @@ -138,7 +139,7 @@ static void gfs2_log_incr_head(struct gfs2_sbd *sdp) sdp->sd_log_flush_head = 0; } -static u64 gfs2_log_bmap(struct gfs2_sbd *sdp) +u64 gfs2_log_bmap(struct gfs2_sbd *sdp) { unsigned int lbn = sdp->sd_log_flush_head; struct gfs2_journal_extent *je; @@ -306,23 +307,22 @@ static struct bio *gfs2_log_get_bio(struct gfs2_sbd *sdp, u64 blkno) return gfs2_log_alloc_bio(sdp, blkno); } - /** * gfs2_log_write - write to log * @sdp: the filesystem * @page: the page to write * @size: the size of the data to write * @offset: the offset within the page + * @blkno: block number of the log entry * * Try and add the page segment to the current bio. If that fails, * submit the current bio to the device and create a new one, and * then add the page segment to that. */ -static void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page, - unsigned size, unsigned offset) +void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page, + unsigned size, unsigned offset, u64 blkno) { - u64 blkno = gfs2_log_bmap(sdp); struct bio *bio; int ret; @@ -348,7 +348,8 @@ static void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page, static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh) { - gfs2_log_write(sdp, bh->b_page, bh->b_size, bh_offset(bh)); + gfs2_log_write(sdp, bh->b_page, bh->b_size, bh_offset(bh), + gfs2_log_bmap(sdp)); } /** @@ -365,7 +366,8 @@ static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh) void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page) { struct super_block *sb = sdp->sd_vfs; - gfs2_log_write(sdp, page, sb->s_blocksize, 0); + gfs2_log_write(sdp, page, sb->s_blocksize, 0, + gfs2_log_bmap(sdp)); } static struct page *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type, diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h index e529f536c117..e4949394f054 100644 --- a/fs/gfs2/lops.h +++ b/fs/gfs2/lops.h @@ -26,6 +26,9 @@ extern const struct gfs2_log_operations gfs2_revoke_lops; extern const struct gfs2_log_operations gfs2_databuf_lops; extern const struct gfs2_log_operations *gfs2_log_ops[]; +extern u64 gfs2_log_bmap(struct gfs2_sbd *sdp); +extern void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page, + unsigned size, unsigned offset, u64 blkno); extern void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page); extern void gfs2_log_flush_bio(struct gfs2_sbd *sdp, int op, int op_flags); extern void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh); diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index ad55eb86a250..d6e620beb9db 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1382,7 +1382,7 @@ static void gfs2_kill_sb(struct super_block *sb) return; } - gfs2_log_flush(sdp, NULL, SYNC_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_SYNC); dput(sdp->sd_root_dir); dput(sdp->sd_master_dir); sdp->sd_root_dir = NULL; diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index e700fb162664..2092df19e433 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -955,7 +955,8 @@ out: gfs2_glock_dq_uninit(&ghs[qx]); inode_unlock(&ip->i_inode); kfree(ghs); - gfs2_log_flush(ip->i_gl->gl_name.ln_sbd, ip->i_gl, NORMAL_FLUSH); + gfs2_log_flush(ip->i_gl->gl_name.ln_sbd, ip->i_gl, + GFS2_LOG_HEAD_FLUSH_NORMAL); return error; } diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 975f32166dfe..b6b258998bcd 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "gfs2.h" #include "incore.h" @@ -137,7 +138,7 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, { struct gfs2_log_header *lh; struct buffer_head *bh; - u32 hash; + u32 hash, crc; int error; error = gfs2_replay_read_block(jd, blk, &bh); @@ -145,13 +146,17 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, return error; lh = (void *)bh->b_data; - hash = crc32(~0, lh, sizeof(*lh) - 4); + hash = crc32(~0, lh, LH_V1_SIZE - 4); hash = ~crc32_le_shift(hash, 4); /* assume lh_hash is zero */ + crc = crc32c(~0, (void *)lh + LH_V1_SIZE + 4, + bh->b_size - LH_V1_SIZE - 4); + error = lh->lh_header.mh_magic != cpu_to_be32(GFS2_MAGIC) || lh->lh_header.mh_type != cpu_to_be32(GFS2_METATYPE_LH) || be32_to_cpu(lh->lh_blkno) != blk || - be32_to_cpu(lh->lh_hash) != hash; + be32_to_cpu(lh->lh_hash) != hash || + (lh->lh_crc != 0 && be32_to_cpu(lh->lh_crc) != crc); brelse(bh); @@ -372,9 +377,9 @@ static void clean_journal(struct gfs2_jdesc *jd, sdp->sd_log_flush_head = head->lh_blkno; gfs2_replay_incr_blk(jd, &sdp->sd_log_flush_head); - gfs2_write_log_header(sdp, head->lh_sequence + 1, 0, - GFS2_LOG_HEAD_UNMOUNT, REQ_PREFLUSH | - REQ_FUA | REQ_META | REQ_SYNC); + gfs2_write_log_header(sdp, jd, head->lh_sequence + 1, 0, + GFS2_LOG_HEAD_UNMOUNT | GFS2_LOG_HEAD_RECOVERY, + REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC); } diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 6dea72f49316..00eab6c0525c 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -2093,7 +2093,7 @@ next_rgrp: } /* Flushing the log may release space */ if (loops == 2) - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); } return -ENOSPC; diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index d81d46e19726..fa3a19eaf0eb 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -757,7 +757,8 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc) bool flush_all = (wbc->sync_mode == WB_SYNC_ALL || gfs2_is_jdata(ip)); if (flush_all) - gfs2_log_flush(GFS2_SB(inode), ip->i_gl, NORMAL_FLUSH); + gfs2_log_flush(GFS2_SB(inode), ip->i_gl, + GFS2_LOG_HEAD_FLUSH_NORMAL); if (bdi->wb.dirty_exceeded) gfs2_ail1_flush(sdp, wbc); else @@ -853,7 +854,7 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) gfs2_quota_sync(sdp->sd_vfs, 0); gfs2_statfs_sync(sdp->sd_vfs, 0); - gfs2_log_flush(sdp, NULL, SHUTDOWN_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_SHUTDOWN); wait_event(sdp->sd_reserving_log_wait, atomic_read(&sdp->sd_reserving_log) == 0); gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); @@ -946,7 +947,7 @@ static int gfs2_sync_fs(struct super_block *sb, int wait) gfs2_quota_sync(sb, -1); if (wait) - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); return sdp->sd_log_error; } @@ -1650,7 +1651,7 @@ alloc_failed: goto out_unlock; out_truncate: - gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH); + gfs2_log_flush(sdp, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL); metamapping = gfs2_glock2aspace(ip->i_gl); if (test_bit(GLF_DIRTY, &ip->i_gl->gl_flags)) { filemap_fdatawrite(metamapping); diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index b95ebd166cac..7aec6d3434fa 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c @@ -117,7 +117,7 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) up_read(&sdp->sd_log_flush_lock); if (sdp->sd_vfs->s_flags & SB_SYNCHRONOUS) - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); if (alloced) sb_end_intwrite(sdp->sd_vfs); } diff --git a/include/uapi/linux/gfs2_ondisk.h b/include/uapi/linux/gfs2_ondisk.h index 09f0920f07e9..9a81d520f54a 100644 --- a/include/uapi/linux/gfs2_ondisk.h +++ b/include/uapi/linux/gfs2_ondisk.h @@ -403,7 +403,15 @@ struct gfs2_ea_header { * Log header structure */ -#define GFS2_LOG_HEAD_UNMOUNT 0x00000001 /* log is clean */ +#define GFS2_LOG_HEAD_UNMOUNT 0x00000001 /* log is clean */ +#define GFS2_LOG_HEAD_FLUSH_NORMAL 0x00000002 /* normal log flush */ +#define GFS2_LOG_HEAD_FLUSH_SYNC 0x00000004 /* Sync log flush */ +#define GFS2_LOG_HEAD_FLUSH_SHUTDOWN 0x00000008 /* Shutdown log flush */ +#define GFS2_LOG_HEAD_FLUSH_FREEZE 0x00000010 /* Freeze flush */ +#define GFS2_LOG_HEAD_RECOVERY 0x00000020 /* Journal recovery */ +#define GFS2_LOG_HEAD_USERSPACE 0x80000000 /* Written by gfs2-utils */ + +#define LH_V1_SIZE (offsetofend(struct gfs2_log_header, lh_hash)) struct gfs2_log_header { struct gfs2_meta_header lh_header; @@ -412,7 +420,21 @@ struct gfs2_log_header { __be32 lh_flags; /* GFS2_LOG_HEAD_... */ __be32 lh_tail; /* Block number of log tail */ __be32 lh_blkno; - __be32 lh_hash; + __be32 lh_hash; /* crc up to here with this field 0 */ + + /* Version 2 additional fields start here */ + __be32 lh_crc; /* crc32c from lh_nsec to end of block */ + __be32 lh_nsec; /* Nanoseconds of timestamp */ + __be64 lh_sec; /* Seconds of timestamp */ + __be64 lh_addr; /* Block addr of this log header (absolute) */ + __be64 lh_jinode; /* Journal inode number */ + __be64 lh_statfs_addr; /* Local statfs inode number */ + __be64 lh_quota_addr; /* Local quota change inode number */ + + /* Statfs local changes (i.e. diff from global statfs) */ + __be64 lh_local_total; + __be64 lh_local_free; + __be64 lh_local_dinodes; }; /* -- cgit v1.2.3-59-g8ed1b From 805c090750a315c5443c14e06304e19a01c697a0 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Mon, 8 Jan 2018 10:34:17 -0500 Subject: GFS2: Log the reason for log flushes in every log header This patch just adds the capability for GFS2 to track which function called gfs2_log_flush. This should make it easier to diagnose problems based on the sequence of events found in the journals. Signed-off-by: Bob Peterson Reviewed-by: Andreas Gruenbacher --- fs/gfs2/aops.c | 3 ++- fs/gfs2/file.c | 3 ++- fs/gfs2/glops.c | 18 ++++++++++++------ fs/gfs2/log.c | 14 ++++++++------ fs/gfs2/ops_fstype.c | 2 +- fs/gfs2/quota.c | 2 +- fs/gfs2/rgrp.c | 3 ++- fs/gfs2/super.c | 12 ++++++++---- fs/gfs2/trace_gfs2.h | 11 +++++++---- fs/gfs2/trans.c | 3 ++- include/uapi/linux/gfs2_ondisk.h | 21 +++++++++++++++++++++ 11 files changed, 66 insertions(+), 26 deletions(-) (limited to 'include/uapi/linux') diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 462c3fd55929..2f725b4a386b 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -448,7 +448,8 @@ static int gfs2_jdata_writepages(struct address_space *mapping, ret = gfs2_write_cache_jdata(mapping, wbc); if (ret == 0 && wbc->sync_mode == WB_SYNC_ALL) { - gfs2_log_flush(sdp, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL); + gfs2_log_flush(sdp, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_JDATA_WPAGES); ret = gfs2_write_cache_jdata(mapping, wbc); } return ret; diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 7a02b4e6e9f3..4f88e201b3f0 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -247,7 +247,8 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) if ((flags ^ new_flags) & GFS2_DIF_JDATA) { if (new_flags & GFS2_DIF_JDATA) gfs2_log_flush(sdp, ip->i_gl, - GFS2_LOG_HEAD_FLUSH_NORMAL); + GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_SET_FLAGS); error = filemap_fdatawrite(inode->i_mapping); if (error) goto out; diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 2daab13a9e0b..d8782a7a1e7d 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -107,7 +107,8 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) __gfs2_ail_flush(gl, 0, tr.tr_revokes); gfs2_trans_end(sdp); - gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_AIL_EMPTY_GL); } void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) @@ -128,7 +129,8 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) return; __gfs2_ail_flush(gl, fsync, max_revokes); gfs2_trans_end(sdp); - gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_AIL_FLUSH); } /** @@ -157,7 +159,8 @@ static void rgrp_go_sync(struct gfs2_glock *gl) return; GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); - gfs2_log_flush(sdp, gl, GFS2_LOG_HEAD_FLUSH_NORMAL); + gfs2_log_flush(sdp, gl, GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_RGRP_GO_SYNC); filemap_fdatawrite_range(mapping, gl->gl_vm.start, gl->gl_vm.end); error = filemap_fdatawait_range(mapping, gl->gl_vm.start, gl->gl_vm.end); mapping_set_error(mapping, error); @@ -252,7 +255,8 @@ static void inode_go_sync(struct gfs2_glock *gl) GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); - gfs2_log_flush(gl->gl_name.ln_sbd, gl, GFS2_LOG_HEAD_FLUSH_NORMAL); + gfs2_log_flush(gl->gl_name.ln_sbd, gl, GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_INODE_GO_SYNC); filemap_fdatawrite(metamapping); if (isreg) { struct address_space *mapping = ip->i_inode.i_mapping; @@ -304,7 +308,8 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags) if (ip == GFS2_I(gl->gl_name.ln_sbd->sd_rindex)) { gfs2_log_flush(gl->gl_name.ln_sbd, NULL, - GFS2_LOG_HEAD_FLUSH_NORMAL); + GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_INODE_GO_INVAL); gl->gl_name.ln_sbd->sd_rindex_uptodate = 0; } if (ip && S_ISREG(ip->i_inode.i_mode)) @@ -496,7 +501,8 @@ static void freeze_go_sync(struct gfs2_glock *gl) gfs2_assert_withdraw(sdp, 0); } queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work); - gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE | + GFS2_LFC_FREEZE_GO_SYNC); } } diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index a2eb13c04591..cf6b46247df4 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -757,7 +757,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags) * gfs2_log_flush - flush incore transaction(s) * @sdp: the filesystem * @gl: The glock structure to flush. If NULL, flush the whole incore log - * @flags: The log header flags: GFS2_LOG_HEAD_FLUSH_* + * @flags: The log header flags: GFS2_LOG_HEAD_FLUSH_* and debug flags * */ @@ -773,7 +773,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags) up_write(&sdp->sd_log_flush_lock); return; } - trace_gfs2_log_flush(sdp, 1); + trace_gfs2_log_flush(sdp, 1, flags); if (flags & GFS2_LOG_HEAD_FLUSH_SHUTDOWN) clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); @@ -841,7 +841,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags) atomic_set(&sdp->sd_freeze_state, SFS_FROZEN); } - trace_gfs2_log_flush(sdp, 0); + trace_gfs2_log_flush(sdp, 0, flags); up_write(&sdp->sd_log_flush_lock); kfree(tr); @@ -937,7 +937,7 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp) sdp->sd_log_flush_head = sdp->sd_log_head; - log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT); + log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT | GFS2_LFC_SHUTDOWN); gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); gfs2_assert_warn(sdp, list_empty(&sdp->sd_ail2_list)); @@ -993,7 +993,8 @@ int gfs2_logd(void *data) did_flush = false; if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { gfs2_ail1_empty(sdp); - gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_LOGD_JFLUSH_REQD); did_flush = true; } @@ -1001,7 +1002,8 @@ int gfs2_logd(void *data) gfs2_ail1_start(sdp); gfs2_ail1_wait(sdp); gfs2_ail1_empty(sdp); - gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_LOGD_AIL_FLUSH_REQD); did_flush = true; } diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index d6e620beb9db..e6a0a8a89ea7 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1382,7 +1382,7 @@ static void gfs2_kill_sb(struct super_block *sb) return; } - gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_SYNC); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_SYNC | GFS2_LFC_KILL_SB); dput(sdp->sd_root_dir); dput(sdp->sd_master_dir); sdp->sd_root_dir = NULL; diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 2092df19e433..7a98abd340ee 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -956,7 +956,7 @@ out: inode_unlock(&ip->i_inode); kfree(ghs); gfs2_log_flush(ip->i_gl->gl_name.ln_sbd, ip->i_gl, - GFS2_LOG_HEAD_FLUSH_NORMAL); + GFS2_LOG_HEAD_FLUSH_NORMAL | GFS2_LFC_DO_SYNC); return error; } diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 00eab6c0525c..078b002e0a68 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -2093,7 +2093,8 @@ next_rgrp: } /* Flushing the log may release space */ if (loops == 2) - gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_INPLACE_RESERVE); } return -ENOSPC; diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index fa3a19eaf0eb..50a297b920fc 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -758,7 +758,8 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc) if (flush_all) gfs2_log_flush(GFS2_SB(inode), ip->i_gl, - GFS2_LOG_HEAD_FLUSH_NORMAL); + GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_WRITE_INODE); if (bdi->wb.dirty_exceeded) gfs2_ail1_flush(sdp, wbc); else @@ -854,7 +855,8 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) gfs2_quota_sync(sdp->sd_vfs, 0); gfs2_statfs_sync(sdp->sd_vfs, 0); - gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_SHUTDOWN); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_SHUTDOWN | + GFS2_LFC_MAKE_FS_RO); wait_event(sdp->sd_reserving_log_wait, atomic_read(&sdp->sd_reserving_log) == 0); gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); @@ -947,7 +949,8 @@ static int gfs2_sync_fs(struct super_block *sb, int wait) gfs2_quota_sync(sb, -1); if (wait) - gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_SYNC_FS); return sdp->sd_log_error; } @@ -1651,7 +1654,8 @@ alloc_failed: goto out_unlock; out_truncate: - gfs2_log_flush(sdp, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL); + gfs2_log_flush(sdp, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_EVICT_INODE); metamapping = gfs2_glock2aspace(ip->i_gl); if (test_bit(GLF_DIRTY, &ip->i_gl->gl_flags)) { filemap_fdatawrite(metamapping); diff --git a/fs/gfs2/trace_gfs2.h b/fs/gfs2/trace_gfs2.h index f67a709589d3..b9318b49ff8f 100644 --- a/fs/gfs2/trace_gfs2.h +++ b/fs/gfs2/trace_gfs2.h @@ -353,26 +353,29 @@ TRACE_EVENT(gfs2_pin, /* Flushing the log */ TRACE_EVENT(gfs2_log_flush, - TP_PROTO(const struct gfs2_sbd *sdp, int start), + TP_PROTO(const struct gfs2_sbd *sdp, int start, u32 flags), - TP_ARGS(sdp, start), + TP_ARGS(sdp, start, flags), TP_STRUCT__entry( __field( dev_t, dev ) __field( int, start ) __field( u64, log_seq ) + __field( u32, flags ) ), TP_fast_assign( __entry->dev = sdp->sd_vfs->s_dev; __entry->start = start; __entry->log_seq = sdp->sd_log_sequence; + __entry->flags = flags; ), - TP_printk("%u,%u log flush %s %llu", + TP_printk("%u,%u log flush %s %llu %llx", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->start ? "start" : "end", - (unsigned long long)__entry->log_seq) + (unsigned long long)__entry->log_seq, + (unsigned long long)__entry->flags) ); /* Reserving/releasing blocks in the log */ diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index 7aec6d3434fa..c75cacaa349b 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c @@ -117,7 +117,8 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) up_read(&sdp->sd_log_flush_lock); if (sdp->sd_vfs->s_flags & SB_SYNCHRONOUS) - gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL | + GFS2_LFC_TRANS_END); if (alloced) sb_end_intwrite(sdp->sd_vfs); } diff --git a/include/uapi/linux/gfs2_ondisk.h b/include/uapi/linux/gfs2_ondisk.h index 9a81d520f54a..2dc10a034de1 100644 --- a/include/uapi/linux/gfs2_ondisk.h +++ b/include/uapi/linux/gfs2_ondisk.h @@ -411,6 +411,27 @@ struct gfs2_ea_header { #define GFS2_LOG_HEAD_RECOVERY 0x00000020 /* Journal recovery */ #define GFS2_LOG_HEAD_USERSPACE 0x80000000 /* Written by gfs2-utils */ +/* Log flush callers */ +#define GFS2_LFC_SHUTDOWN 0x00000100 +#define GFS2_LFC_JDATA_WPAGES 0x00000200 +#define GFS2_LFC_SET_FLAGS 0x00000400 +#define GFS2_LFC_AIL_EMPTY_GL 0x00000800 +#define GFS2_LFC_AIL_FLUSH 0x00001000 +#define GFS2_LFC_RGRP_GO_SYNC 0x00002000 +#define GFS2_LFC_INODE_GO_SYNC 0x00004000 +#define GFS2_LFC_INODE_GO_INVAL 0x00008000 +#define GFS2_LFC_FREEZE_GO_SYNC 0x00010000 +#define GFS2_LFC_KILL_SB 0x00020000 +#define GFS2_LFC_DO_SYNC 0x00040000 +#define GFS2_LFC_INPLACE_RESERVE 0x00080000 +#define GFS2_LFC_WRITE_INODE 0x00100000 +#define GFS2_LFC_MAKE_FS_RO 0x00200000 +#define GFS2_LFC_SYNC_FS 0x00400000 +#define GFS2_LFC_EVICT_INODE 0x00800000 +#define GFS2_LFC_TRANS_END 0x01000000 +#define GFS2_LFC_LOGD_JFLUSH_REQD 0x02000000 +#define GFS2_LFC_LOGD_AIL_FLUSH_REQD 0x04000000 + #define LH_V1_SIZE (offsetofend(struct gfs2_log_header, lh_hash)) struct gfs2_log_header { -- cgit v1.2.3-59-g8ed1b From 430a23689dea2e36ae5a0fc75a67301fd46b18bf Mon Sep 17 00:00:00 2001 From: Jay Cornwall Date: Thu, 4 Jan 2018 19:44:59 -0500 Subject: PCI: Add pci_enable_atomic_ops_to_root() The Atomic Operations feature (PCIe r4.0, sec 6.15) allows atomic transctions to be requested by, routed through and completed by PCIe components. Routing and completion do not require software support. Component support for each is detectable via the DEVCAP2 register. A Requester may use AtomicOps only if its PCI_EXP_DEVCTL2_ATOMIC_REQ is set. This should be set only if the Completer and all intermediate routing elements support AtomicOps. A concrete example is the AMD Fiji-class GPU (which is capable of making AtomicOp requests), below a PLX 8747 switch (advertising AtomicOp routing) with a Haswell host bridge (advertising AtomicOp completion support). Add pci_enable_atomic_ops_to_root() for per-device control over AtomicOp requests. This checks to be sure the Root Port supports completion of the desired AtomicOp sizes and the path to the Root Port supports routing the AtomicOps. Signed-off-by: Jay Cornwall Signed-off-by: Felix Kuehling [bhelgaas: changelog, comments, whitespace] Signed-off-by: Bjorn Helgaas --- drivers/pci/pci.c | 75 +++++++++++++++++++++++++++++++++++++++++++ include/linux/pci.h | 1 + include/uapi/linux/pci_regs.h | 4 ++- 3 files changed, 79 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 4a7c6864fdf4..6112dd8d68b6 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3065,6 +3065,81 @@ int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size) return 0; } +/** + * pci_enable_atomic_ops_to_root - enable AtomicOp requests to root port + * @dev: the PCI device + * @cap_mask: mask of desired AtomicOp sizes, including one or more of: + * PCI_EXP_DEVCAP2_ATOMIC_COMP32 + * PCI_EXP_DEVCAP2_ATOMIC_COMP64 + * PCI_EXP_DEVCAP2_ATOMIC_COMP128 + * + * Return 0 if all upstream bridges support AtomicOp routing, egress + * blocking is disabled on all upstream ports, and the root port supports + * the requested completion capabilities (32-bit, 64-bit and/or 128-bit + * AtomicOp completion), or negative otherwise. + */ +int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask) +{ + struct pci_bus *bus = dev->bus; + struct pci_dev *bridge; + u32 cap, ctl2; + + if (!pci_is_pcie(dev)) + return -EINVAL; + + /* + * Per PCIe r4.0, sec 6.15, endpoints and root ports may be + * AtomicOp requesters. For now, we only support endpoints as + * requesters and root ports as completers. No endpoints as + * completers, and no peer-to-peer. + */ + + switch (pci_pcie_type(dev)) { + case PCI_EXP_TYPE_ENDPOINT: + case PCI_EXP_TYPE_LEG_END: + case PCI_EXP_TYPE_RC_END: + break; + default: + return -EINVAL; + } + + while (bus->parent) { + bridge = bus->self; + + pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap); + + switch (pci_pcie_type(bridge)) { + /* Ensure switch ports support AtomicOp routing */ + case PCI_EXP_TYPE_UPSTREAM: + case PCI_EXP_TYPE_DOWNSTREAM: + if (!(cap & PCI_EXP_DEVCAP2_ATOMIC_ROUTE)) + return -EINVAL; + break; + + /* Ensure root port supports all the sizes we care about */ + case PCI_EXP_TYPE_ROOT_PORT: + if ((cap & cap_mask) != cap_mask) + return -EINVAL; + break; + } + + /* Ensure upstream ports don't block AtomicOps on egress */ + if (!bridge->has_secondary_link) { + pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2, + &ctl2); + if (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK) + return -EINVAL; + } + + bus = bus->parent; + } + + pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, + PCI_EXP_DEVCTL2_ATOMIC_REQ); + return 0; +} +EXPORT_SYMBOL(pci_enable_atomic_ops_to_root); + /** * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge * @dev: the PCI device diff --git a/include/linux/pci.h b/include/linux/pci.h index c170c9250c8b..ab3d12a7dfed 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2061,6 +2061,7 @@ void pci_request_acs(void); bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags); bool pci_acs_path_enabled(struct pci_dev *start, struct pci_dev *end, u16 acs_flags); +int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask); #define PCI_VPD_LRDT 0x80 /* Large Resource Data Type */ #define PCI_VPD_LRDT_ID(x) ((x) | PCI_VPD_LRDT) diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index 70c2b2ade048..f31b56b21714 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -624,7 +624,9 @@ #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ #define PCI_EXP_DEVCAP2_ARI 0x00000020 /* Alternative Routing-ID */ #define PCI_EXP_DEVCAP2_ATOMIC_ROUTE 0x00000040 /* Atomic Op routing */ -#define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100 /* Atomic 64-bit compare */ +#define PCI_EXP_DEVCAP2_ATOMIC_COMP32 0x00000080 /* 32b AtomicOp completion */ +#define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100 /* 64b AtomicOp completion */ +#define PCI_EXP_DEVCAP2_ATOMIC_COMP128 0x00000200 /* 128b AtomicOp completion */ #define PCI_EXP_DEVCAP2_LTR 0x00000800 /* Latency tolerance reporting */ #define PCI_EXP_DEVCAP2_OBFF_MASK 0x000c0000 /* OBFF support mechanism */ #define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000 /* New message signaling */ -- cgit v1.2.3-59-g8ed1b From e1fc742e14e01d84d9693c4aca4ab23da65811fb Mon Sep 17 00:00:00 2001 From: Jürg Billeter Date: Fri, 29 Sep 2017 14:07:17 +0200 Subject: fs: add RWF_APPEND MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the per-I/O equivalent of O_APPEND to support atomic append operations on any open file. If a file is opened with O_APPEND, pwrite() ignores the offset and always appends data to the end of the file. RWF_APPEND enables atomic append and pwrite() with offset on a single file descriptor. Signed-off-by: Jürg Billeter Signed-off-by: Al Viro --- include/linux/fs.h | 2 ++ include/uapi/linux/fs.h | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 6276f8315e5b..85c8ddc55760 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3224,6 +3224,8 @@ static inline int kiocb_set_rw_flags(struct kiocb *ki, rwf_t flags) ki->ki_flags |= IOCB_DSYNC; if (flags & RWF_SYNC) ki->ki_flags |= (IOCB_DSYNC | IOCB_SYNC); + if (flags & RWF_APPEND) + ki->ki_flags |= IOCB_APPEND; return 0; } diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 4199f8acbce5..d2a8313fabd7 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -377,7 +377,11 @@ typedef int __bitwise __kernel_rwf_t; /* per-IO, return -EAGAIN if operation would block */ #define RWF_NOWAIT ((__force __kernel_rwf_t)0x00000008) +/* per-IO O_APPEND */ +#define RWF_APPEND ((__force __kernel_rwf_t)0x00000010) + /* mask of flags supported by the kernel */ -#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT) +#define RWF_SUPPORTED (RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT |\ + RWF_APPEND) #endif /* _UAPI_LINUX_FS_H */ -- cgit v1.2.3-59-g8ed1b From de525be2ca2734865d29c4b67ddd29913b214906 Mon Sep 17 00:00:00 2001 From: Lawrence Brakmo Date: Thu, 25 Jan 2018 16:14:09 -0800 Subject: bpf: Support passing args to sock_ops bpf function Adds support for passing up to 4 arguments to sock_ops bpf functions. It reusues the reply union, so the bpf_sock_ops structures are not increased in size. Signed-off-by: Lawrence Brakmo Signed-off-by: Alexei Starovoitov --- include/linux/filter.h | 1 + include/net/tcp.h | 40 +++++++++++++++++++++++++++++++++++----- include/uapi/linux/bpf.h | 5 +++-- net/ipv4/tcp.c | 2 +- net/ipv4/tcp_nv.c | 2 +- net/ipv4/tcp_output.c | 2 +- 6 files changed, 42 insertions(+), 10 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/linux/filter.h b/include/linux/filter.h index daa5a676335f..20384c4bed25 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -1003,6 +1003,7 @@ struct bpf_sock_ops_kern { struct sock *sk; u32 op; union { + u32 args[4]; u32 reply; u32 replylong[4]; }; diff --git a/include/net/tcp.h b/include/net/tcp.h index 6092eaff61cf..093e967a2960 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -2006,7 +2006,7 @@ void tcp_cleanup_ulp(struct sock *sk); * program loaded). */ #ifdef CONFIG_BPF -static inline int tcp_call_bpf(struct sock *sk, int op) +static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args) { struct bpf_sock_ops_kern sock_ops; int ret; @@ -2019,6 +2019,8 @@ static inline int tcp_call_bpf(struct sock *sk, int op) sock_ops.sk = sk; sock_ops.op = op; + if (nargs > 0) + memcpy(sock_ops.args, args, nargs * sizeof(*args)); ret = BPF_CGROUP_RUN_PROG_SOCK_OPS(&sock_ops); if (ret == 0) @@ -2027,18 +2029,46 @@ static inline int tcp_call_bpf(struct sock *sk, int op) ret = -1; return ret; } + +static inline int tcp_call_bpf_2arg(struct sock *sk, int op, u32 arg1, u32 arg2) +{ + u32 args[2] = {arg1, arg2}; + + return tcp_call_bpf(sk, op, 2, args); +} + +static inline int tcp_call_bpf_3arg(struct sock *sk, int op, u32 arg1, u32 arg2, + u32 arg3) +{ + u32 args[3] = {arg1, arg2, arg3}; + + return tcp_call_bpf(sk, op, 3, args); +} + #else -static inline int tcp_call_bpf(struct sock *sk, int op) +static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args) { return -EPERM; } + +static inline int tcp_call_bpf_2arg(struct sock *sk, int op, u32 arg1, u32 arg2) +{ + return -EPERM; +} + +static inline int tcp_call_bpf_3arg(struct sock *sk, int op, u32 arg1, u32 arg2, + u32 arg3) +{ + return -EPERM; +} + #endif static inline u32 tcp_timeout_init(struct sock *sk) { int timeout; - timeout = tcp_call_bpf(sk, BPF_SOCK_OPS_TIMEOUT_INIT); + timeout = tcp_call_bpf(sk, BPF_SOCK_OPS_TIMEOUT_INIT, 0, NULL); if (timeout <= 0) timeout = TCP_TIMEOUT_INIT; @@ -2049,7 +2079,7 @@ static inline u32 tcp_rwnd_init_bpf(struct sock *sk) { int rwnd; - rwnd = tcp_call_bpf(sk, BPF_SOCK_OPS_RWND_INIT); + rwnd = tcp_call_bpf(sk, BPF_SOCK_OPS_RWND_INIT, 0, NULL); if (rwnd < 0) rwnd = 0; @@ -2058,7 +2088,7 @@ static inline u32 tcp_rwnd_init_bpf(struct sock *sk) static inline bool tcp_bpf_ca_needs_ecn(struct sock *sk) { - return (tcp_call_bpf(sk, BPF_SOCK_OPS_NEEDS_ECN) == 1); + return (tcp_call_bpf(sk, BPF_SOCK_OPS_NEEDS_ECN, 0, NULL) == 1); } #if IS_ENABLED(CONFIG_SMC) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 406c19d6016b..8d5874c2c4ff 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -952,8 +952,9 @@ struct bpf_map_info { struct bpf_sock_ops { __u32 op; union { - __u32 reply; - __u32 replylong[4]; + __u32 args[4]; /* Optionally passed to bpf program */ + __u32 reply; /* Returned by bpf program */ + __u32 replylong[4]; /* Optionally returned by bpf prog */ }; __u32 family; __u32 remote_ip4; /* Stored in network byte order */ diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index d7cf861bf699..88b62441e7e9 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -463,7 +463,7 @@ void tcp_init_transfer(struct sock *sk, int bpf_op) tcp_mtup_init(sk); icsk->icsk_af_ops->rebuild_header(sk); tcp_init_metrics(sk); - tcp_call_bpf(sk, bpf_op); + tcp_call_bpf(sk, bpf_op, 0, NULL); tcp_init_congestion_control(sk); tcp_init_buffer_space(sk); } diff --git a/net/ipv4/tcp_nv.c b/net/ipv4/tcp_nv.c index 0b5a05bd82e3..ddbce73edae8 100644 --- a/net/ipv4/tcp_nv.c +++ b/net/ipv4/tcp_nv.c @@ -146,7 +146,7 @@ static void tcpnv_init(struct sock *sk) * within a datacenter, where we have reasonable estimates of * RTTs */ - base_rtt = tcp_call_bpf(sk, BPF_SOCK_OPS_BASE_RTT); + base_rtt = tcp_call_bpf(sk, BPF_SOCK_OPS_BASE_RTT, 0, NULL); if (base_rtt > 0) { ca->nv_base_rtt = base_rtt; ca->nv_lower_bound_rtt = (base_rtt * 205) >> 8; /* 80% */ diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 95461f02ac9a..d12f7f71c1c4 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -3469,7 +3469,7 @@ int tcp_connect(struct sock *sk) struct sk_buff *buff; int err; - tcp_call_bpf(sk, BPF_SOCK_OPS_TCP_CONNECT_CB); + tcp_call_bpf(sk, BPF_SOCK_OPS_TCP_CONNECT_CB, 0, NULL); if (inet_csk(sk)->icsk_af_ops->rebuild_header(sk)) return -EHOSTUNREACH; /* Routing failure or similar. */ -- cgit v1.2.3-59-g8ed1b From b13d880721729384757f235166068c315326f4a1 Mon Sep 17 00:00:00 2001 From: Lawrence Brakmo Date: Thu, 25 Jan 2018 16:14:10 -0800 Subject: bpf: Adds field bpf_sock_ops_cb_flags to tcp_sock Adds field bpf_sock_ops_cb_flags to tcp_sock and bpf_sock_ops. Its primary use is to determine if there should be calls to sock_ops bpf program at various points in the TCP code. The field is initialized to zero, disabling the calls. A sock_ops BPF program can set it, per connection and as necessary, when the connection is established. It also adds support for reading and writting the field within a sock_ops BPF program. Reading is done by accessing the field directly. However, writing is done through the helper function bpf_sock_ops_cb_flags_set, in order to return an error if a BPF program is trying to set a callback that is not supported in the current kernel (i.e. running an older kernel). The helper function returns 0 if it was able to set all of the bits set in the argument, a positive number containing the bits that could not be set, or -EINVAL if the socket is not a full TCP socket. Examples of where one could call the bpf program: 1) When RTO fires 2) When a packet is retransmitted 3) When the connection terminates 4) When a packet is sent 5) When a packet is received Signed-off-by: Lawrence Brakmo Acked-by: Alexei Starovoitov Signed-off-by: Alexei Starovoitov --- include/linux/tcp.h | 11 +++++++++++ include/uapi/linux/bpf.h | 17 ++++++++++++++++- net/core/filter.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 4f93f0953c41..8f4c54986f97 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -335,6 +335,17 @@ struct tcp_sock { int linger2; + +/* Sock_ops bpf program related variables */ +#ifdef CONFIG_BPF + u8 bpf_sock_ops_cb_flags; /* Control calling BPF programs + * values defined in uapi/linux/tcp.h + */ +#define BPF_SOCK_OPS_TEST_FLAG(TP, ARG) (TP->bpf_sock_ops_cb_flags & ARG) +#else +#define BPF_SOCK_OPS_TEST_FLAG(TP, ARG) 0 +#endif + /* Receiver side RTT estimation */ struct { u32 rtt_us; diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 8d5874c2c4ff..aa128407c44d 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -642,6 +642,14 @@ union bpf_attr { * @optlen: length of optval in bytes * Return: 0 or negative error * + * int bpf_sock_ops_cb_flags_set(bpf_sock_ops, flags) + * Set callback flags for sock_ops + * @bpf_sock_ops: pointer to bpf_sock_ops_kern struct + * @flags: flags value + * Return: 0 for no error + * -EINVAL if there is no full tcp socket + * bits in flags that are not supported by current kernel + * * int bpf_skb_adjust_room(skb, len_diff, mode, flags) * Grow or shrink room in sk_buff. * @skb: pointer to skb @@ -748,7 +756,8 @@ union bpf_attr { FN(perf_event_read_value), \ FN(perf_prog_read_value), \ FN(getsockopt), \ - FN(override_return), + FN(override_return), \ + FN(sock_ops_cb_flags_set), /* integer value in 'imm' field of BPF_CALL instruction selects which helper * function eBPF program intends to call @@ -969,8 +978,14 @@ struct bpf_sock_ops { */ __u32 snd_cwnd; __u32 srtt_us; /* Averaged RTT << 3 in usecs */ + __u32 bpf_sock_ops_cb_flags; /* flags defined in uapi/linux/tcp.h */ }; +/* Definitions for bpf_sock_ops_cb_flags */ +#define BPF_SOCK_OPS_ALL_CB_FLAGS 0 /* Mask of all currently + * supported cb flags + */ + /* List of known BPF sock_ops operators. * New entries can only be added at the end */ diff --git a/net/core/filter.c b/net/core/filter.c index c356ec02b1a5..6936d19ac736 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3328,6 +3328,33 @@ static const struct bpf_func_proto bpf_getsockopt_proto = { .arg5_type = ARG_CONST_SIZE, }; +BPF_CALL_2(bpf_sock_ops_cb_flags_set, struct bpf_sock_ops_kern *, bpf_sock, + int, argval) +{ + struct sock *sk = bpf_sock->sk; + int val = argval & BPF_SOCK_OPS_ALL_CB_FLAGS; + + if (!sk_fullsock(sk)) + return -EINVAL; + +#ifdef CONFIG_INET + if (val) + tcp_sk(sk)->bpf_sock_ops_cb_flags = val; + + return argval & (~BPF_SOCK_OPS_ALL_CB_FLAGS); +#else + return -EINVAL; +#endif +} + +static const struct bpf_func_proto bpf_sock_ops_cb_flags_set_proto = { + .func = bpf_sock_ops_cb_flags_set, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; + static const struct bpf_func_proto * bpf_base_func_proto(enum bpf_func_id func_id) { @@ -3510,6 +3537,8 @@ static const struct bpf_func_proto * return &bpf_setsockopt_proto; case BPF_FUNC_getsockopt: return &bpf_getsockopt_proto; + case BPF_FUNC_sock_ops_cb_flags_set: + return &bpf_sock_ops_cb_flags_set_proto; case BPF_FUNC_sock_map_update: return &bpf_sock_map_update_proto; default: @@ -4546,6 +4575,11 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type, case offsetof(struct bpf_sock_ops, srtt_us): SOCK_OPS_GET_FIELD(srtt_us, srtt_us, struct tcp_sock); break; + + case offsetof(struct bpf_sock_ops, bpf_sock_ops_cb_flags): + SOCK_OPS_GET_FIELD(bpf_sock_ops_cb_flags, bpf_sock_ops_cb_flags, + struct tcp_sock); + break; } return insn - insn_buf; } -- cgit v1.2.3-59-g8ed1b From f89013f66d0f1a0dad44c513318efb706399a36b Mon Sep 17 00:00:00 2001 From: Lawrence Brakmo Date: Thu, 25 Jan 2018 16:14:11 -0800 Subject: bpf: Add sock_ops RTO callback Adds an optional call to sock_ops BPF program based on whether the BPF_SOCK_OPS_RTO_CB_FLAG is set in bpf_sock_ops_flags. The BPF program is passed 2 arguments: icsk_retransmits and whether the RTO has expired. Signed-off-by: Lawrence Brakmo Signed-off-by: Alexei Starovoitov --- include/uapi/linux/bpf.h | 8 +++++++- net/ipv4/tcp_timer.c | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index aa128407c44d..c8cecf9cf5bd 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -982,7 +982,8 @@ struct bpf_sock_ops { }; /* Definitions for bpf_sock_ops_cb_flags */ -#define BPF_SOCK_OPS_ALL_CB_FLAGS 0 /* Mask of all currently +#define BPF_SOCK_OPS_RTO_CB_FLAG (1<<0) +#define BPF_SOCK_OPS_ALL_CB_FLAGS 0x1 /* Mask of all currently * supported cb flags */ @@ -1019,6 +1020,11 @@ enum { * a congestion threshold. RTTs above * this indicate congestion */ + BPF_SOCK_OPS_RTO_CB, /* Called when an RTO has triggered. + * Arg1: value of icsk_retransmits + * Arg2: value of icsk_rto + * Arg3: whether RTO has expired + */ }; #define TCP_BPF_IW 1001 /* Set TCP initial congestion window */ diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 6db3124cdbda..257abdde23b0 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -213,11 +213,18 @@ static int tcp_write_timeout(struct sock *sk) icsk->icsk_user_timeout); } tcp_fastopen_active_detect_blackhole(sk, expired); + + if (BPF_SOCK_OPS_TEST_FLAG(tp, BPF_SOCK_OPS_RTO_CB_FLAG)) + tcp_call_bpf_3arg(sk, BPF_SOCK_OPS_RTO_CB, + icsk->icsk_retransmits, + icsk->icsk_rto, (int)expired); + if (expired) { /* Has it gone just too far? */ tcp_write_err(sk); return 1; } + return 0; } -- cgit v1.2.3-59-g8ed1b From 44f0e43037d3a17b043843ba67610ac7c7e37db6 Mon Sep 17 00:00:00 2001 From: Lawrence Brakmo Date: Thu, 25 Jan 2018 16:14:12 -0800 Subject: bpf: Add support for reading sk_state and more Add support for reading many more tcp_sock fields state, same as sk->sk_state rtt_min same as sk->rtt_min.s[0].v (current rtt_min) snd_ssthresh rcv_nxt snd_nxt snd_una mss_cache ecn_flags rate_delivered rate_interval_us packets_out retrans_out total_retrans segs_in data_segs_in segs_out data_segs_out lost_out sacked_out sk_txhash bytes_received (__u64) bytes_acked (__u64) Signed-off-by: Lawrence Brakmo Signed-off-by: Alexei Starovoitov --- include/uapi/linux/bpf.h | 22 ++++++++ net/core/filter.c | 143 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 154 insertions(+), 11 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index c8cecf9cf5bd..46520eae37fa 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -979,6 +979,28 @@ struct bpf_sock_ops { __u32 snd_cwnd; __u32 srtt_us; /* Averaged RTT << 3 in usecs */ __u32 bpf_sock_ops_cb_flags; /* flags defined in uapi/linux/tcp.h */ + __u32 state; + __u32 rtt_min; + __u32 snd_ssthresh; + __u32 rcv_nxt; + __u32 snd_nxt; + __u32 snd_una; + __u32 mss_cache; + __u32 ecn_flags; + __u32 rate_delivered; + __u32 rate_interval_us; + __u32 packets_out; + __u32 retrans_out; + __u32 total_retrans; + __u32 segs_in; + __u32 data_segs_in; + __u32 segs_out; + __u32 data_segs_out; + __u32 lost_out; + __u32 sacked_out; + __u32 sk_txhash; + __u64 bytes_received; + __u64 bytes_acked; }; /* Definitions for bpf_sock_ops_cb_flags */ diff --git a/net/core/filter.c b/net/core/filter.c index 6936d19ac736..a858ebc4ece4 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3855,33 +3855,43 @@ void bpf_warn_invalid_xdp_action(u32 act) } EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action); -static bool __is_valid_sock_ops_access(int off, int size) +static bool sock_ops_is_valid_access(int off, int size, + enum bpf_access_type type, + struct bpf_insn_access_aux *info) { + const int size_default = sizeof(__u32); + if (off < 0 || off >= sizeof(struct bpf_sock_ops)) return false; + /* The verifier guarantees that size > 0. */ if (off % size != 0) return false; - if (size != sizeof(__u32)) - return false; - - return true; -} -static bool sock_ops_is_valid_access(int off, int size, - enum bpf_access_type type, - struct bpf_insn_access_aux *info) -{ if (type == BPF_WRITE) { switch (off) { case offsetof(struct bpf_sock_ops, reply): + if (size != size_default) + return false; break; default: return false; } + } else { + switch (off) { + case bpf_ctx_range_till(struct bpf_sock_ops, bytes_received, + bytes_acked): + if (size != sizeof(__u64)) + return false; + break; + default: + if (size != size_default) + return false; + break; + } } - return __is_valid_sock_ops_access(off, size); + return true; } static int sk_skb_prologue(struct bpf_insn *insn_buf, bool direct_write, @@ -4498,6 +4508,32 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type, is_fullsock)); break; + case offsetof(struct bpf_sock_ops, state): + BUILD_BUG_ON(FIELD_SIZEOF(struct sock_common, skc_state) != 1); + + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( + struct bpf_sock_ops_kern, sk), + si->dst_reg, si->src_reg, + offsetof(struct bpf_sock_ops_kern, sk)); + *insn++ = BPF_LDX_MEM(BPF_B, si->dst_reg, si->dst_reg, + offsetof(struct sock_common, skc_state)); + break; + + case offsetof(struct bpf_sock_ops, rtt_min): + BUILD_BUG_ON(FIELD_SIZEOF(struct tcp_sock, rtt_min) != + sizeof(struct minmax)); + BUILD_BUG_ON(sizeof(struct minmax) < + sizeof(struct minmax_sample)); + + *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( + struct bpf_sock_ops_kern, sk), + si->dst_reg, si->src_reg, + offsetof(struct bpf_sock_ops_kern, sk)); + *insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg, + offsetof(struct tcp_sock, rtt_min) + + FIELD_SIZEOF(struct minmax_sample, t)); + break; + /* Helper macro for adding read access to tcp_sock or sock fields. */ #define SOCK_OPS_GET_FIELD(BPF_FIELD, OBJ_FIELD, OBJ) \ do { \ @@ -4580,6 +4616,91 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type, SOCK_OPS_GET_FIELD(bpf_sock_ops_cb_flags, bpf_sock_ops_cb_flags, struct tcp_sock); break; + + case offsetof(struct bpf_sock_ops, snd_ssthresh): + SOCK_OPS_GET_FIELD(snd_ssthresh, snd_ssthresh, struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, rcv_nxt): + SOCK_OPS_GET_FIELD(rcv_nxt, rcv_nxt, struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, snd_nxt): + SOCK_OPS_GET_FIELD(snd_nxt, snd_nxt, struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, snd_una): + SOCK_OPS_GET_FIELD(snd_una, snd_una, struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, mss_cache): + SOCK_OPS_GET_FIELD(mss_cache, mss_cache, struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, ecn_flags): + SOCK_OPS_GET_FIELD(ecn_flags, ecn_flags, struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, rate_delivered): + SOCK_OPS_GET_FIELD(rate_delivered, rate_delivered, + struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, rate_interval_us): + SOCK_OPS_GET_FIELD(rate_interval_us, rate_interval_us, + struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, packets_out): + SOCK_OPS_GET_FIELD(packets_out, packets_out, struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, retrans_out): + SOCK_OPS_GET_FIELD(retrans_out, retrans_out, struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, total_retrans): + SOCK_OPS_GET_FIELD(total_retrans, total_retrans, + struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, segs_in): + SOCK_OPS_GET_FIELD(segs_in, segs_in, struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, data_segs_in): + SOCK_OPS_GET_FIELD(data_segs_in, data_segs_in, struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, segs_out): + SOCK_OPS_GET_FIELD(segs_out, segs_out, struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, data_segs_out): + SOCK_OPS_GET_FIELD(data_segs_out, data_segs_out, + struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, lost_out): + SOCK_OPS_GET_FIELD(lost_out, lost_out, struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, sacked_out): + SOCK_OPS_GET_FIELD(sacked_out, sacked_out, struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, sk_txhash): + SOCK_OPS_GET_FIELD(sk_txhash, sk_txhash, struct sock); + break; + + case offsetof(struct bpf_sock_ops, bytes_received): + SOCK_OPS_GET_FIELD(bytes_received, bytes_received, + struct tcp_sock); + break; + + case offsetof(struct bpf_sock_ops, bytes_acked): + SOCK_OPS_GET_FIELD(bytes_acked, bytes_acked, struct tcp_sock); + break; } return insn - insn_buf; } -- cgit v1.2.3-59-g8ed1b From a31ad29e6a30cb0b9084a9425b819cdcd97273ce Mon Sep 17 00:00:00 2001 From: Lawrence Brakmo Date: Thu, 25 Jan 2018 16:14:14 -0800 Subject: bpf: Add BPF_SOCK_OPS_RETRANS_CB Adds support for calling sock_ops BPF program when there is a retransmission. Three arguments are used; one for the sequence number, another for the number of segments retransmitted, and the last one for the return value of tcp_transmit_skb (0 => success). Does not include syn-ack retransmissions. New op: BPF_SOCK_OPS_RETRANS_CB. Signed-off-by: Lawrence Brakmo Signed-off-by: Alexei Starovoitov --- include/uapi/linux/bpf.h | 9 ++++++++- net/ipv4/tcp_output.c | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 46520eae37fa..31c93a0bdbc2 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -1005,7 +1005,8 @@ struct bpf_sock_ops { /* Definitions for bpf_sock_ops_cb_flags */ #define BPF_SOCK_OPS_RTO_CB_FLAG (1<<0) -#define BPF_SOCK_OPS_ALL_CB_FLAGS 0x1 /* Mask of all currently +#define BPF_SOCK_OPS_RETRANS_CB_FLAG (1<<1) +#define BPF_SOCK_OPS_ALL_CB_FLAGS 0x3 /* Mask of all currently * supported cb flags */ @@ -1047,6 +1048,12 @@ enum { * Arg2: value of icsk_rto * Arg3: whether RTO has expired */ + BPF_SOCK_OPS_RETRANS_CB, /* Called when skb is retransmitted. + * Arg1: sequence number of 1st byte + * Arg2: # segments + * Arg3: return value of + * tcp_transmit_skb (0 => success) + */ }; #define TCP_BPF_IW 1001 /* Set TCP initial congestion window */ diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index d12f7f71c1c4..e9f985e42405 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2905,6 +2905,10 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs) err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); } + if (BPF_SOCK_OPS_TEST_FLAG(tp, BPF_SOCK_OPS_RETRANS_CB_FLAG)) + tcp_call_bpf_3arg(sk, BPF_SOCK_OPS_RETRANS_CB, + TCP_SKB_CB(skb)->seq, segs, err); + if (likely(!err)) { TCP_SKB_CB(skb)->sacked |= TCPCB_EVER_RETRANS; trace_tcp_retransmit_skb(sk, skb); -- cgit v1.2.3-59-g8ed1b From d44874910a26f3a8f81edf873a2473363f07f660 Mon Sep 17 00:00:00 2001 From: Lawrence Brakmo Date: Thu, 25 Jan 2018 16:14:15 -0800 Subject: bpf: Add BPF_SOCK_OPS_STATE_CB Adds support for calling sock_ops BPF program when there is a TCP state change. Two arguments are used; one for the old state and another for the new state. There is a new enum in include/uapi/linux/bpf.h that exports the TCP states that prepends BPF_ to the current TCP state names. If it is ever necessary to change the internal TCP state values (other than adding more to the end), then it will become necessary to convert from the internal TCP state value to the BPF value before calling the BPF sock_ops function. There are a set of compile checks added in tcp.c to detect if the internal and BPF values differ so we can make the necessary fixes. New op: BPF_SOCK_OPS_STATE_CB. Signed-off-by: Lawrence Brakmo Signed-off-by: Alexei Starovoitov --- include/uapi/linux/bpf.h | 29 ++++++++++++++++++++++++++++- net/ipv4/tcp.c | 24 ++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 31c93a0bdbc2..db6bdc375126 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -1006,7 +1006,8 @@ struct bpf_sock_ops { /* Definitions for bpf_sock_ops_cb_flags */ #define BPF_SOCK_OPS_RTO_CB_FLAG (1<<0) #define BPF_SOCK_OPS_RETRANS_CB_FLAG (1<<1) -#define BPF_SOCK_OPS_ALL_CB_FLAGS 0x3 /* Mask of all currently +#define BPF_SOCK_OPS_STATE_CB_FLAG (1<<2) +#define BPF_SOCK_OPS_ALL_CB_FLAGS 0x7 /* Mask of all currently * supported cb flags */ @@ -1054,6 +1055,32 @@ enum { * Arg3: return value of * tcp_transmit_skb (0 => success) */ + BPF_SOCK_OPS_STATE_CB, /* Called when TCP changes state. + * Arg1: old_state + * Arg2: new_state + */ +}; + +/* List of TCP states. There is a build check in net/ipv4/tcp.c to detect + * changes between the TCP and BPF versions. Ideally this should never happen. + * If it does, we need to add code to convert them before calling + * the BPF sock_ops function. + */ +enum { + BPF_TCP_ESTABLISHED = 1, + BPF_TCP_SYN_SENT, + BPF_TCP_SYN_RECV, + BPF_TCP_FIN_WAIT1, + BPF_TCP_FIN_WAIT2, + BPF_TCP_TIME_WAIT, + BPF_TCP_CLOSE, + BPF_TCP_CLOSE_WAIT, + BPF_TCP_LAST_ACK, + BPF_TCP_LISTEN, + BPF_TCP_CLOSING, /* Now a valid state */ + BPF_TCP_NEW_SYN_RECV, + + BPF_TCP_MAX_STATES /* Leave at the end! */ }; #define TCP_BPF_IW 1001 /* Set TCP initial congestion window */ diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 88b62441e7e9..f013ddc191e0 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2042,6 +2042,30 @@ void tcp_set_state(struct sock *sk, int state) { int oldstate = sk->sk_state; + /* We defined a new enum for TCP states that are exported in BPF + * so as not force the internal TCP states to be frozen. The + * following checks will detect if an internal state value ever + * differs from the BPF value. If this ever happens, then we will + * need to remap the internal value to the BPF value before calling + * tcp_call_bpf_2arg. + */ + BUILD_BUG_ON((int)BPF_TCP_ESTABLISHED != (int)TCP_ESTABLISHED); + BUILD_BUG_ON((int)BPF_TCP_SYN_SENT != (int)TCP_SYN_SENT); + BUILD_BUG_ON((int)BPF_TCP_SYN_RECV != (int)TCP_SYN_RECV); + BUILD_BUG_ON((int)BPF_TCP_FIN_WAIT1 != (int)TCP_FIN_WAIT1); + BUILD_BUG_ON((int)BPF_TCP_FIN_WAIT2 != (int)TCP_FIN_WAIT2); + BUILD_BUG_ON((int)BPF_TCP_TIME_WAIT != (int)TCP_TIME_WAIT); + BUILD_BUG_ON((int)BPF_TCP_CLOSE != (int)TCP_CLOSE); + BUILD_BUG_ON((int)BPF_TCP_CLOSE_WAIT != (int)TCP_CLOSE_WAIT); + BUILD_BUG_ON((int)BPF_TCP_LAST_ACK != (int)TCP_LAST_ACK); + BUILD_BUG_ON((int)BPF_TCP_LISTEN != (int)TCP_LISTEN); + BUILD_BUG_ON((int)BPF_TCP_CLOSING != (int)TCP_CLOSING); + BUILD_BUG_ON((int)BPF_TCP_NEW_SYN_RECV != (int)TCP_NEW_SYN_RECV); + BUILD_BUG_ON((int)BPF_TCP_MAX_STATES != (int)TCP_MAX_STATES); + + if (BPF_SOCK_OPS_TEST_FLAG(tcp_sk(sk), BPF_SOCK_OPS_STATE_CB_FLAG)) + tcp_call_bpf_2arg(sk, BPF_SOCK_OPS_STATE_CB, oldstate, state); + switch (state) { case TCP_ESTABLISHED: if (oldstate != TCP_ESTABLISHED) -- cgit v1.2.3-59-g8ed1b From d350a823020e71e20a10d1dfa44f1d1d653b0334 Mon Sep 17 00:00:00 2001 From: William Tu Date: Thu, 25 Jan 2018 13:20:10 -0800 Subject: net: erspan: create erspan metadata uapi header The patch adds a new uapi header file, erspan.h, and moves the 'struct erspan_metadata' from internal erspan.h to it. Signed-off-by: William Tu Acked-by: Pravin B Shelar Signed-off-by: David S. Miller --- include/net/erspan.h | 32 ++-------------------------- include/uapi/linux/erspan.h | 52 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 30 deletions(-) create mode 100644 include/uapi/linux/erspan.h (limited to 'include/uapi/linux') diff --git a/include/net/erspan.h b/include/net/erspan.h index 6d30fe898286..5daa4866412b 100644 --- a/include/net/erspan.h +++ b/include/net/erspan.h @@ -46,6 +46,8 @@ * GRE proto ERSPAN type II = 0x88BE, type III = 0x22EB */ +#include + #define ERSPAN_VERSION 0x1 /* ERSPAN type II */ #define VER_MASK 0xf000 #define VLAN_MASK 0x0fff @@ -68,29 +70,6 @@ #define HWID_OFFSET 4 #define DIR_OFFSET 3 -/* ERSPAN version 2 metadata header */ -struct erspan_md2 { - __be32 timestamp; - __be16 sgt; /* security group tag */ -#if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 hwid_upper:2, - ft:5, - p:1; - __u8 o:1, - gra:2, - dir:1, - hwid:4; -#elif defined(__BIG_ENDIAN_BITFIELD) - __u8 p:1, - ft:5, - hwid_upper:2; - __u8 hwid:4, - dir:1, - gra:2, - o:1; -#endif -}; - enum erspan_encap_type { ERSPAN_ENCAP_NOVLAN = 0x0, /* originally without VLAN tag */ ERSPAN_ENCAP_ISL = 0x1, /* originally ISL encapsulated */ @@ -100,13 +79,6 @@ enum erspan_encap_type { #define ERSPAN_V1_MDSIZE 4 #define ERSPAN_V2_MDSIZE 8 -struct erspan_metadata { - union { - __be32 index; /* Version 1 (type II)*/ - struct erspan_md2 md2; /* Version 2 (type III) */ - } u; - int version; -}; struct erspan_base_hdr { #if defined(__LITTLE_ENDIAN_BITFIELD) diff --git a/include/uapi/linux/erspan.h b/include/uapi/linux/erspan.h new file mode 100644 index 000000000000..841573019ae1 --- /dev/null +++ b/include/uapi/linux/erspan.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * ERSPAN Tunnel Metadata + * + * Copyright (c) 2018 VMware + * + * 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. + * + * Userspace API for metadata mode ERSPAN tunnel + */ +#ifndef _UAPI_ERSPAN_H +#define _UAPI_ERSPAN_H + +#include /* For __beXX in userspace */ +#include + +/* ERSPAN version 2 metadata header */ +struct erspan_md2 { + __be32 timestamp; + __be16 sgt; /* security group tag */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 hwid_upper:2, + ft:5, + p:1; + __u8 o:1, + gra:2, + dir:1, + hwid:4; +#elif defined(__BIG_ENDIAN_BITFIELD) + __u8 p:1, + ft:5, + hwid_upper:2; + __u8 hwid:4, + dir:1, + gra:2, + o:1; +#else +#error "Please fix " +#endif +}; + +struct erspan_metadata { + int version; + union { + __be32 index; /* Version 1 (type II)*/ + struct erspan_md2 md2; /* Version 2 (type III) */ + } u; +}; + +#endif /* _UAPI_ERSPAN_H */ -- cgit v1.2.3-59-g8ed1b From fc1372f89ffe1f58b589643b75f679e452350703 Mon Sep 17 00:00:00 2001 From: William Tu Date: Thu, 25 Jan 2018 13:20:11 -0800 Subject: openvswitch: add erspan version I and II support The patch adds support for openvswitch to configure erspan v1 and v2. The OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS attr is added to uapi as a binary blob to support all ERSPAN v1 and v2's fields. Note that Previous commit "openvswitch: Add erspan tunnel support." was reverted since it does not design properly. Signed-off-by: William Tu Acked-by: Pravin B Shelar Signed-off-by: David S. Miller --- include/uapi/linux/openvswitch.h | 1 + net/openvswitch/flow_netlink.c | 52 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/openvswitch.h b/include/uapi/linux/openvswitch.h index dcfab5e3b55c..713e56ce681f 100644 --- a/include/uapi/linux/openvswitch.h +++ b/include/uapi/linux/openvswitch.h @@ -363,6 +363,7 @@ enum ovs_tunnel_key_attr { OVS_TUNNEL_KEY_ATTR_IPV6_SRC, /* struct in6_addr src IPv6 address. */ OVS_TUNNEL_KEY_ATTR_IPV6_DST, /* struct in6_addr dst IPv6 address. */ OVS_TUNNEL_KEY_ATTR_PAD, + OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS, /* struct erspan_metadata */ __OVS_TUNNEL_KEY_ATTR_MAX }; diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index eb55f1b3d047..7322aa1e382e 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c @@ -49,6 +49,7 @@ #include #include #include +#include #include "flow_netlink.h" @@ -329,7 +330,8 @@ size_t ovs_tun_key_attr_size(void) + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_CSUM */ + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_OAM */ + nla_total_size(256) /* OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS */ - /* OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS is mutually exclusive with + /* OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS and + * OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS is mutually exclusive with * OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS and covered by it. */ + nla_total_size(2) /* OVS_TUNNEL_KEY_ATTR_TP_SRC */ @@ -400,6 +402,7 @@ static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] .next = ovs_vxlan_ext_key_lens }, [OVS_TUNNEL_KEY_ATTR_IPV6_SRC] = { .len = sizeof(struct in6_addr) }, [OVS_TUNNEL_KEY_ATTR_IPV6_DST] = { .len = sizeof(struct in6_addr) }, + [OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS] = { .len = OVS_ATTR_VARIABLE }, }; static const struct ovs_len_tbl @@ -631,6 +634,33 @@ static int vxlan_tun_opt_from_nlattr(const struct nlattr *attr, return 0; } +static int erspan_tun_opt_from_nlattr(const struct nlattr *a, + struct sw_flow_match *match, bool is_mask, + bool log) +{ + unsigned long opt_key_offset; + + BUILD_BUG_ON(sizeof(struct erspan_metadata) > + sizeof(match->key->tun_opts)); + + if (nla_len(a) > sizeof(match->key->tun_opts)) { + OVS_NLERR(log, "ERSPAN option length err (len %d, max %zu).", + nla_len(a), sizeof(match->key->tun_opts)); + return -EINVAL; + } + + if (!is_mask) + SW_FLOW_KEY_PUT(match, tun_opts_len, + sizeof(struct erspan_metadata), false); + else + SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, true); + + opt_key_offset = TUN_METADATA_OFFSET(nla_len(a)); + SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, nla_data(a), + nla_len(a), is_mask); + return 0; +} + static int ip_tun_from_nlattr(const struct nlattr *attr, struct sw_flow_match *match, bool is_mask, bool log) @@ -738,6 +768,20 @@ static int ip_tun_from_nlattr(const struct nlattr *attr, break; case OVS_TUNNEL_KEY_ATTR_PAD: break; + case OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS: + if (opts_type) { + OVS_NLERR(log, "Multiple metadata blocks provided"); + return -EINVAL; + } + + err = erspan_tun_opt_from_nlattr(a, match, is_mask, + log); + if (err) + return err; + + tun_flags |= TUNNEL_ERSPAN_OPT; + opts_type = type; + break; default: OVS_NLERR(log, "Unknown IP tunnel attribute %d", type); @@ -862,6 +906,10 @@ static int __ip_tun_to_nlattr(struct sk_buff *skb, else if (output->tun_flags & TUNNEL_VXLAN_OPT && vxlan_opt_to_nlattr(skb, tun_opts, swkey_tun_opts_len)) return -EMSGSIZE; + else if (output->tun_flags & TUNNEL_ERSPAN_OPT && + nla_put(skb, OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS, + swkey_tun_opts_len, tun_opts)) + return -EMSGSIZE; } return 0; @@ -2486,6 +2534,8 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, break; case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS: break; + case OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS: + break; } } -- cgit v1.2.3-59-g8ed1b From 38e01b30563a5b5ade7b54e5d739d16a2b02fe82 Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Thu, 25 Jan 2018 15:01:39 +0100 Subject: dev: advertise the new ifindex when the netns iface changes The goal is to let the user follow an interface that moves to another netns. CC: Jiri Benc CC: Christian Brauner Signed-off-by: Nicolas Dichtel Reviewed-by: Jiri Benc Signed-off-by: David S. Miller --- include/linux/rtnetlink.h | 5 +++-- include/uapi/linux/if_link.h | 1 + net/core/dev.c | 19 ++++++++++++------- net/core/rtnetlink.c | 31 ++++++++++++++++++++----------- 4 files changed, 36 insertions(+), 20 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 62d508b31f56..0514cc36ac34 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -19,10 +19,11 @@ extern int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change, gfp_t flags); void rtmsg_ifinfo_newnet(int type, struct net_device *dev, unsigned int change, - gfp_t flags, int *new_nsid); + gfp_t flags, int *new_nsid, int new_ifindex); struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev, unsigned change, u32 event, - gfp_t flags, int *new_nsid); + gfp_t flags, int *new_nsid, + int new_ifindex); void rtmsg_ifinfo_send(struct sk_buff *skb, struct net_device *dev, gfp_t flags); diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 8616131e2c61..6d9447700e18 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -163,6 +163,7 @@ enum { IFLA_IF_NETNSID, IFLA_CARRIER_UP_COUNT, IFLA_CARRIER_DOWN_COUNT, + IFLA_NEW_IFINDEX, __IFLA_MAX }; diff --git a/net/core/dev.c b/net/core/dev.c index 59987eb6511a..858501b12869 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -7360,7 +7360,7 @@ static void rollback_registered_many(struct list_head *head) if (!dev->rtnl_link_ops || dev->rtnl_link_state == RTNL_LINK_INITIALIZED) skb = rtmsg_ifinfo_build_skb(RTM_DELLINK, dev, ~0U, 0, - GFP_KERNEL, NULL); + GFP_KERNEL, NULL, 0); /* * Flush the unicast and multicast chains @@ -8473,7 +8473,7 @@ EXPORT_SYMBOL(unregister_netdev); int dev_change_net_namespace(struct net_device *dev, struct net *net, const char *pat) { - int err, new_nsid; + int err, new_nsid, new_ifindex; ASSERT_RTNL(); @@ -8529,8 +8529,16 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char call_netdevice_notifiers(NETDEV_UNREGISTER, dev); rcu_barrier(); call_netdevice_notifiers(NETDEV_UNREGISTER_FINAL, dev); + new_nsid = peernet2id_alloc(dev_net(dev), net); - rtmsg_ifinfo_newnet(RTM_DELLINK, dev, ~0U, GFP_KERNEL, &new_nsid); + /* If there is an ifindex conflict assign a new one */ + if (__dev_get_by_index(net, dev->ifindex)) + new_ifindex = dev_new_index(net); + else + new_ifindex = dev->ifindex; + + rtmsg_ifinfo_newnet(RTM_DELLINK, dev, ~0U, GFP_KERNEL, &new_nsid, + new_ifindex); /* * Flush the unicast and multicast chains @@ -8544,10 +8552,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char /* Actually switch the network namespace */ dev_net_set(dev, net); - - /* If there is an ifindex conflict assign a new one */ - if (__dev_get_by_index(net, dev->ifindex)) - dev->ifindex = dev_new_index(net); + dev->ifindex = new_ifindex; /* Send a netdev-add uevent to the new namespace */ kobject_uevent(&dev->dev.kobj, KOBJ_ADD); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index f111557958bb..e04af7b7f448 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -988,6 +988,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev, + rtnl_xdp_size() /* IFLA_XDP */ + nla_total_size(4) /* IFLA_EVENT */ + nla_total_size(4) /* IFLA_NEW_NETNSID */ + + nla_total_size(4) /* IFLA_NEW_IFINDEX */ + nla_total_size(1) /* IFLA_PROTO_DOWN */ + nla_total_size(4) /* IFLA_IF_NETNSID */ + nla_total_size(4) /* IFLA_CARRIER_UP_COUNT */ @@ -1511,7 +1512,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, struct net *src_net, int type, u32 pid, u32 seq, u32 change, unsigned int flags, u32 ext_filter_mask, - u32 event, int *new_nsid, int tgt_netnsid) + u32 event, int *new_nsid, int new_ifindex, + int tgt_netnsid) { struct ifinfomsg *ifm; struct nlmsghdr *nlh; @@ -1608,6 +1610,10 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, if (new_nsid && nla_put_s32(skb, IFLA_NEW_NETNSID, *new_nsid) < 0) goto nla_put_failure; + if (new_ifindex && + nla_put_s32(skb, IFLA_NEW_IFINDEX, new_ifindex) < 0) + goto nla_put_failure; + rcu_read_lock(); if (rtnl_fill_link_af(skb, dev, ext_filter_mask)) @@ -1853,7 +1859,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 0, flags, - ext_filter_mask, 0, NULL, + ext_filter_mask, 0, NULL, 0, netnsid); if (err < 0) { @@ -3088,7 +3094,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh, err = rtnl_fill_ifinfo(nskb, dev, net, RTM_NEWLINK, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0, 0, ext_filter_mask, - 0, NULL, netnsid); + 0, NULL, 0, netnsid); if (err < 0) { /* -EMSGSIZE implies BUG in if_nlmsg_size */ WARN_ON(err == -EMSGSIZE); @@ -3184,7 +3190,8 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev, unsigned int change, - u32 event, gfp_t flags, int *new_nsid) + u32 event, gfp_t flags, int *new_nsid, + int new_ifindex) { struct net *net = dev_net(dev); struct sk_buff *skb; @@ -3197,7 +3204,7 @@ struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev, err = rtnl_fill_ifinfo(skb, dev, dev_net(dev), type, 0, 0, change, 0, 0, event, - new_nsid, -1); + new_nsid, new_ifindex, -1); if (err < 0) { /* -EMSGSIZE implies BUG in if_nlmsg_size() */ WARN_ON(err == -EMSGSIZE); @@ -3220,14 +3227,15 @@ void rtmsg_ifinfo_send(struct sk_buff *skb, struct net_device *dev, gfp_t flags) static void rtmsg_ifinfo_event(int type, struct net_device *dev, unsigned int change, u32 event, - gfp_t flags, int *new_nsid) + gfp_t flags, int *new_nsid, int new_ifindex) { struct sk_buff *skb; if (dev->reg_state != NETREG_REGISTERED) return; - skb = rtmsg_ifinfo_build_skb(type, dev, change, event, flags, new_nsid); + skb = rtmsg_ifinfo_build_skb(type, dev, change, event, flags, new_nsid, + new_ifindex); if (skb) rtmsg_ifinfo_send(skb, dev, flags); } @@ -3235,14 +3243,15 @@ static void rtmsg_ifinfo_event(int type, struct net_device *dev, void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change, gfp_t flags) { - rtmsg_ifinfo_event(type, dev, change, rtnl_get_event(0), flags, NULL); + rtmsg_ifinfo_event(type, dev, change, rtnl_get_event(0), flags, + NULL, 0); } void rtmsg_ifinfo_newnet(int type, struct net_device *dev, unsigned int change, - gfp_t flags, int *new_nsid) + gfp_t flags, int *new_nsid, int new_ifindex) { rtmsg_ifinfo_event(type, dev, change, rtnl_get_event(0), flags, - new_nsid); + new_nsid, new_ifindex); } static int nlmsg_populate_fdb_fill(struct sk_buff *skb, @@ -4642,7 +4651,7 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi case NETDEV_CHANGELOWERSTATE: case NETDEV_CHANGE_TX_QUEUE_LEN: rtmsg_ifinfo_event(RTM_NEWLINK, dev, 0, rtnl_get_event(event), - GFP_KERNEL, NULL); + GFP_KERNEL, NULL, 0); break; default: break; -- cgit v1.2.3-59-g8ed1b From 01060e3d4e423146ecf9d308814e16a357671ddf Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 16 Jan 2018 17:37:50 -0600 Subject: PCI/DPC: Add and use DPC Status register field definitions Add definitions for DPC Status register fields and use them in the code. No functional change intended. Signed-off-by: Bjorn Helgaas Reviewed-by: Keith Busch Reviewed-by: Sinan Kaya --- drivers/pci/pcie/pcie-dpc.c | 4 ++-- include/uapi/linux/pci_regs.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'include/uapi/linux') diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c index 0f4eb6111ab4..7eb9bc7d4bfd 100644 --- a/drivers/pci/pcie/pcie-dpc.c +++ b/drivers/pci/pcie/pcie-dpc.c @@ -211,8 +211,8 @@ static irqreturn_t dpc_irq(int irq, void *context) dev_info(dev, "DPC containment event, status:%#06x source:%#06x\n", status, source); - reason = (status >> 1) & 0x3; - ext_reason = (status >> 5) & 0x3; + reason = (status & PCI_EXP_DPC_STATUS_TRIGGER_RSN) >> 1; + ext_reason = (status & PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT) >> 5; dev_warn(dev, "DPC %s detected, remove downstream devices\n", (reason == 0) ? "unmasked uncorrectable error" : diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index 70c2b2ade048..970a0dc535c4 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -979,8 +979,10 @@ #define PCI_EXP_DPC_STATUS 8 /* DPC Status */ #define PCI_EXP_DPC_STATUS_TRIGGER 0x01 /* Trigger Status */ +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN 0x06 /* Trigger Reason */ #define PCI_EXP_DPC_STATUS_INTERRUPT 0x08 /* Interrupt Status */ #define PCI_EXP_DPC_RP_BUSY 0x10 /* Root Port Busy */ +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x60 /* Trig Reason Extension */ #define PCI_EXP_DPC_SOURCE_ID 10 /* DPC Source Identifier */ -- cgit v1.2.3-59-g8ed1b From 65d5e9135f3b0281b97f1749d10dcfc7233e65ab Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 16 Jan 2018 17:34:12 -0600 Subject: PCI/DPC: Reformat DPC register definitions Reformat DPC register definitions to follow the convention that register field masks indicate the register width, e.g., a field of a 16-bit register uses a mask of 4 hex digits, with leading zeros included as needed. No functional change intended. Signed-off-by: Bjorn Helgaas Reviewed-by: Keith Busch Reviewed-by: Sinan Kaya --- include/uapi/linux/pci_regs.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index 970a0dc535c4..66d71461d2f0 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -966,28 +966,28 @@ /* Downstream Port Containment */ #define PCI_EXP_DPC_CAP 4 /* DPC Capability */ -#define PCI_EXP_DPC_IRQ 0x1f /* DPC Interrupt Message Number */ -#define PCI_EXP_DPC_CAP_RP_EXT 0x20 /* Root Port Extensions for DPC */ -#define PCI_EXP_DPC_CAP_POISONED_TLP 0x40 /* Poisoned TLP Egress Blocking Supported */ -#define PCI_EXP_DPC_CAP_SW_TRIGGER 0x80 /* Software Triggering Supported */ -#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0xF00 /* RP PIO log size */ +#define PCI_EXP_DPC_IRQ 0x001F /* Interrupt Message Number */ +#define PCI_EXP_DPC_CAP_RP_EXT 0x0020 /* Root Port Extensions */ +#define PCI_EXP_DPC_CAP_POISONED_TLP 0x0040 /* Poisoned TLP Egress Blocking Supported */ +#define PCI_EXP_DPC_CAP_SW_TRIGGER 0x0080 /* Software Triggering Supported */ +#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0x0F00 /* RP PIO Log Size */ #define PCI_EXP_DPC_CAP_DL_ACTIVE 0x1000 /* ERR_COR signal on DL_Active supported */ #define PCI_EXP_DPC_CTL 6 /* DPC control */ -#define PCI_EXP_DPC_CTL_EN_NONFATAL 0x02 /* Enable trigger on ERR_NONFATAL message */ -#define PCI_EXP_DPC_CTL_INT_EN 0x08 /* DPC Interrupt Enable */ +#define PCI_EXP_DPC_CTL_EN_NONFATAL 0x0002 /* Enable trigger on ERR_NONFATAL message */ +#define PCI_EXP_DPC_CTL_INT_EN 0x0008 /* DPC Interrupt Enable */ #define PCI_EXP_DPC_STATUS 8 /* DPC Status */ -#define PCI_EXP_DPC_STATUS_TRIGGER 0x01 /* Trigger Status */ -#define PCI_EXP_DPC_STATUS_TRIGGER_RSN 0x06 /* Trigger Reason */ -#define PCI_EXP_DPC_STATUS_INTERRUPT 0x08 /* Interrupt Status */ -#define PCI_EXP_DPC_RP_BUSY 0x10 /* Root Port Busy */ -#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x60 /* Trig Reason Extension */ +#define PCI_EXP_DPC_STATUS_TRIGGER 0x0001 /* Trigger Status */ +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN 0x0006 /* Trigger Reason */ +#define PCI_EXP_DPC_STATUS_INTERRUPT 0x0008 /* Interrupt Status */ +#define PCI_EXP_DPC_RP_BUSY 0x0010 /* Root Port Busy */ +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060 /* Trig Reason Extension */ #define PCI_EXP_DPC_SOURCE_ID 10 /* DPC Source Identifier */ #define PCI_EXP_DPC_RP_PIO_STATUS 0x0C /* RP PIO Status */ -#define PCI_EXP_DPC_RP_PIO_MASK 0x10 /* RP PIO MASK */ +#define PCI_EXP_DPC_RP_PIO_MASK 0x10 /* RP PIO Mask */ #define PCI_EXP_DPC_RP_PIO_SEVERITY 0x14 /* RP PIO Severity */ #define PCI_EXP_DPC_RP_PIO_SYSERROR 0x18 /* RP PIO SysError */ #define PCI_EXP_DPC_RP_PIO_EXCEPTION 0x1C /* RP PIO Exception */ -- cgit v1.2.3-59-g8ed1b From f2ba5a5baecf795c2150826bd0c95fc3f7f3d226 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 1 Feb 2018 21:27:22 -0800 Subject: libnvdimm, namespace: make min namespace size 4K The arbitrary 4MB minimum namespace size turns out to be too large for some environments. Quoting Cheng-mean Liu: In the case of emulated NVDIMM devices in the VM environment, there are scenarios that NVDIMM device with much smaller sizes are desired, for example, we might use a single enumerated NVDIMM DAX device for representing each container layer, which in some cases could be just a few KBs size. PAGE_SIZE is the minimum where we can still support DAX of at least a single page. Cc: Matthew Wilcox Reported-by: Cheng-mean Liu Signed-off-by: Dan Williams --- include/uapi/linux/ndctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h index 30ef1236aafa..7e27070b9440 100644 --- a/include/uapi/linux/ndctl.h +++ b/include/uapi/linux/ndctl.h @@ -209,7 +209,7 @@ enum nd_driver_flags { }; enum { - ND_MIN_NAMESPACE_SIZE = 0x00400000, + ND_MIN_NAMESPACE_SIZE = PAGE_SIZE, }; enum ars_masks { -- cgit v1.2.3-59-g8ed1b