-
Notifications
You must be signed in to change notification settings - Fork 7
/
driver.h
116 lines (100 loc) · 2.96 KB
/
driver.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* Copyright(c) 2019 Intel Corporation. All rights reserved.
*
* Author: Marcin Zielinski <marcinx.zielinski@linux.intel.com>
*/
#ifndef DRIVER_H
#define DRIVER_H
#include "ioctl.h"
#include <linux/build_bug.h>
#include <linux/cdev.h>
#include <linux/pci.h>
#include <linux/uaccess.h>
static_assert (PCIBIOS_SUCCESSFUL == 0);
/**
* enum pci_device_id_e - Kind of the diagnostic device.
* @DIAG_START: enum start marker
* @DIAG_HDA: HDA device
* @DIAG_DSP: DSP device
* @DIAG_COUNT: enum end/count marker
*/
enum diag_dev_kind_t {
DIAG_START,
DIAG_HDA = DIAG_START,
DIAG_DSP,
DIAG_COUNT
};
/**
* MAX_ALLOC_MAPS - Max allocations that can be performed on the driver.
*/
#define MAX_ALLOC_MAPS 16
/**
* struct diag_mem_map_t - Map of allocations performed on the driver.
* @kernel_virt_addr: kernel virtual memory address
* @physical: physical address
*/
struct diag_mem_map_t {
void *kernel_virt_addr;
phys_addr_t physical;
} __packed;
/**
* struct diag_dev_inst_t - Driver instance corresponding to an opened device.
* @bar: PCI Base Address Register
* @mcdev: character device
*/
struct diag_dev_inst_t {
struct diag_hda_bar_t bar;
struct cdev mcdev;
} __packed;
/**
* struct diag_driver_t - Diagnostic driver's global instance.
* @dev_id: PCI device id
* @devices: array of open devices, one per kind;
* see :c:type:`diag_dev_kind_t`
* @dev_num: device's system-wide number
* @cls: device's system-wide class
* @alloc_desc: array of descriptors of the memory allocations
performed on the driver
*/
struct diag_driver_t {
unsigned int dev_id;
struct diag_dev_inst_t devices[DIAG_COUNT];
dev_t dev_num;
struct class *cls;
struct diag_mem_map_t alloc_desc[MAX_ALLOC_MAPS];
} __packed;
/**
* copy_to_user_and_check() - Kernel to user data copy and status check.
* @to: user's buffer to copy the data to
* @from: kernel's buffer to copy the data from
* @n: count of the bytes to copy
* @on_err: value to be returned on error
*
* Return: 0 on success, see :c:data:`on_err` on error.
*/
static __always_inline long __must_check copy_to_user_and_check(
void __user *to, const void *from, uint32_t n, int on_err)
{
long ret = (long)copy_to_user(to, from, (unsigned long)n);
return (ret == 0) ? ret : on_err;
}
/**
* copy_from_user_and_check() - User to kernel data copy and status check.
* @to: kernel's buffer to copy the data to
* @from: user's buffer to copy the data from
* @n: count of the bytes to copy
* @on_err: value to be returned on error
*
* Return: 0 on success, see :c:data:`on_err` on error.
*/
static __always_inline long __must_check copy_from_user_and_check(
void *to, const void __user *from, uint32_t n, int on_err)
{
long ret = (long)copy_from_user(to, from, (unsigned long)n);
return (ret <= 0) ? ret : on_err;
}
#endif /* DRIVER_H */