forked from Xilinx/SLASH
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathslash_main.c
More file actions
134 lines (118 loc) · 4.13 KB
/
Copy pathslash_main.c
File metadata and controls
134 lines (118 loc) · 4.13 KB
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
* Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* @file slash_main.c
*
* Module entry point for the SLASH kernel driver.
*
* SLASH is a partial-reconfiguration design for AMD Alveo V80 FPGAs.
* This module manages two PCI physical functions exposed by the design:
*
* - PF1 (QDMA) — queue-based DMA for bulk data transfer.
* - PF2 (Control) — BAR access for register-level MMIO.
*
* It also provides a hotplug subsystem for removing, resetting (SBR),
* and rescanning PCI devices — needed when the FPGA bitstream changes
* and the device must be re-enumerated.
*
* Initialization order matters:
*
* 1. **QDMA** — libqdma must be initialized and its PCI driver
* registered before any PCI probe runs, because PF1 and PF2
* may probe concurrently once drivers are registered.
*
* 2. **Hotplug** — the /dev/slash_hotplug misc device must exist
* before PCI probe registers devices into the tracking list.
*
* 3. **PCIe** — registering the PF2 PCI driver triggers probe for
* any devices already present on the bus.
*
* Teardown is the reverse: PCIe first (unbinds devices), then hotplug
* (frees tracking list), then QDMA (shuts down libqdma).
*/
#include "slash.h"
#include "slash_compat.h"
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/printk.h>
#include "slash_pcie.h"
#include "slash_hotplug_driver.h"
#include "slash_qdma.h"
#ifndef SLASH_VERSION_STR
#define SLASH_VERSION_STR "unknown"
#endif
/** Number of worker threads for libqdma's internal processing. */
static unsigned int qdma_num_threads = 8;
/** Optional debugfs mount path for libqdma diagnostics (unused). */
static char *qdma_debugfs_path = NULL;
/**
* slash_init() - Module initialization.
*
* Brings up the three subsystems in dependency order.
* On failure, tears down any subsystems that were already initialized.
*
* Return: 0 on success, negative errno on failure.
*/
static int __init slash_init(void)
{
int err;
pr_info("slash: module init\n");
/* 1. QDMA first — libqdma + PF1 PCI driver. */
err = slash_qdma_init(qdma_num_threads, NULL);
if (err) {
pr_err("slash: libqdma init failed: %d\n", err);
return err;
}
/* 2. Hotplug — /dev/slash_hotplug misc device. */
err = slash_hotplug_init();
if (err) {
pr_err("slash: hotplug init failed: %d\n", err);
slash_qdma_exit();
return err;
}
/* 3. PCIe — PF2 PCI driver (triggers probe for present devices). */
err = slash_pcie_init();
if (err) {
pr_err("slash: PCIe init failed: %d\n", err);
slash_hotplug_exit();
return err;
}
pr_info("slash: module init complete\n");
return 0;
}
/**
* slash_exit() - Module cleanup.
*
* Tears down subsystems in reverse initialization order.
*/
static void __exit slash_exit(void)
{
pr_info("slash: module exit\n");
slash_pcie_exit();
slash_hotplug_exit();
slash_qdma_exit();
pr_info("slash: module exit complete\n");
}
module_init(slash_init);
module_exit(slash_exit);
module_param(qdma_num_threads, uint, 0644);
MODULE_PARM_DESC(qdma_num_threads, "Number of libqdma worker threads (default: 8)");
module_param(qdma_debugfs_path, charp, 0644);
MODULE_PARM_DESC(qdma_debugfs_path, "debugfs mount path for libqdma (default: disabled)");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("AMD Inc.");
MODULE_DESCRIPTION("SLASH/VRT module");
MODULE_VERSION(SLASH_VERSION_STR);
SLASH_MODULE_IMPORT_NS(DMA_BUF);