Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Simple PCIe FMC carrier SPEC - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Simple PCIe FMC carrier SPEC - Software
Commits
a3ac4129
Commit
a3ac4129
authored
Mar 01, 2012
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added name generation, but not loading yet
Signed-off-by:
Alessandro Rubini
<
rubini@gnudd.com
>
parent
da26bab5
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
138 additions
and
18 deletions
+138
-18
spec-core.c
kernel/spec-core.c
+130
-15
spec.h
kernel/spec.h
+8
-3
No files found.
kernel/spec-core.c
View file @
a3ac4129
...
...
@@ -10,46 +10,161 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/sched.h>
#include <linux/ctype.h>
#include <linux/pci.h>
#include <linux/io.h>
#include "spec.h"
static
char
*
spec_name
s
[
SPEC_MAX_BOARDS
]
;
static
int
spec_n_names
;
static
char
*
spec_name
=
"%b"
;
module_param_named
(
name
,
spec_name
,
charp
,
0444
)
;
module_param_array_named
(
name
,
spec_names
,
charp
,
&
spec_n_names
,
0444
);
DEFINE_PCI_DEVICE_TABLE
(
spec_idtable
)
=
{
{
PCI_DEVICE
(
PCI_VENDOR_ID_CERN
,
PCI_DEVICE_ID_SPEC
)
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_GENNUM
,
PCI_DEVICE_ID_GN4124
)
},
{
0
,},
};
/* The loader is laid out as a kernel thread, to simplify stuff */
/*
* A procedure to build the names associated with the device. This
* copies the spec_name. With "spec-" prefix, expanding %P
* (vendor:device), %p (subv:subd), %b (bus:devfn). Then ".bin" is
* the gateware, "-lm32.bin" is the lm32 compiled code and ".ko"
* is the kernel module.
* Example for device in bus 2, slot 0:
* command: "insmod spec name=%b"
* gateware: "spec-0002:0000.bin"
* program: "spec-0002:0000-cpu.bin" -- will be .elf, hopefully
* other module requested: "spec-0002:0000.ko"
*/
static
int
spec_build_names
(
struct
spec_dev
*
dev
)
{
struct
pci_dev
*
pdev
=
dev
->
pdev
;
char
basename
[
64
];
char
*
si
,
*
so
;
int
i
;
static
char
*
templates
[]
=
{
[
SPEC_NAME_FW
]
=
"spec-%s.bin"
,
[
SPEC_NAME_PROG
]
=
"spec-%s-cpu.bin"
,
/* will be .elf */
[
SPEC_NAME_SUBMOD
]
=
"spec-%s.ko"
,
};
for
(
si
=
spec_name
,
so
=
basename
;
*
si
;
si
++
)
{
if
(
so
-
basename
>=
sizeof
(
basename
))
return
-
ENOSPC
;
if
(
*
si
!=
'%'
)
{
*
so
++
=
*
si
;
continue
;
}
si
++
;
/* eat '%' */
if
(
so
-
basename
+
9
>=
sizeof
(
basename
))
return
-
ENOSPC
;
switch
(
*
si
)
{
case
'P'
:
/* PCI vendor:device */
;
so
+=
sprintf
(
so
,
"%04x:%04x"
,
pdev
->
vendor
,
pdev
->
device
);
break
;
case
'p'
:
/* PCI subvendor:subdevice */
;
so
+=
sprintf
(
so
,
"%04x:%04x"
,
pdev
->
subsystem_vendor
,
pdev
->
subsystem_device
);
break
;
case
'b'
:
/* BUS id */
so
+=
sprintf
(
so
,
"%04x:%04x"
,
pdev
->
bus
->
number
,
pdev
->
devfn
);
break
;
case
'%'
:
*
so
++
=
'%'
;
default:
return
-
EINVAL
;
}
}
/* terminate and remove trailing spaces (includes newlines) */
*
so
=
'\0'
;
while
(
isspace
(
*--
so
))
*
so
=
'\0'
;
printk
(
"%s: basename is
\"
%s
\"\n
"
,
__func__
,
basename
);
/* build the actual things */
for
(
i
=
0
;
i
<
SPEC_NAMES
;
i
++
)
dev
->
names
[
i
]
=
kasprintf
(
GFP_KERNEL
,
templates
[
i
],
basename
);
return
0
;
}
/* FIXME */
/* A procedure to load the three names */
static
int
spec_load_files
(
struct
spec_dev
*
dev
)
{
printk
(
"%s: not implemented
\n
"
,
__func__
);
return
0
;
}
static
struct
list_head
spec_list
;
/* The probe can be called in atomic context, so all loading is delayed */
static
int
spec_probe
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
id
)
static
int
spec_probe
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
id
)
{
struct
spec_dev
*
dev
;
int
i
;
printk
(
"%s
\n
"
,
__func__
);
/* FIXME */
printk
(
"%s: current %i (%s)
\n
"
,
__func__
,
current
->
pid
,
current
->
comm
);
dev
=
kzalloc
(
sizeof
(
*
dev
),
GFP_KERNEL
);
if
(
!
dev
)
return
-
ENOMEM
;
dev
->
pdev
=
pdev
;
/* Remap our 3 bars */
for
(
i
=
0
;
i
<
3
;
i
++
)
{
struct
resource
*
r
=
pdev
->
resource
+
(
2
*
i
);
if
(
!
r
->
start
)
continue
;
dev
->
area
[
i
]
=
r
;
if
(
r
->
flags
&
IORESOURCE_MEM
)
dev
->
remap
[
i
]
=
ioremap
(
r
->
start
,
r
->
end
+
1
-
r
->
start
);
}
/* Build the names */
if
(
spec_build_names
(
dev
)
<
0
)
{
dev_warn
(
&
pdev
->
dev
,
"can't build names with
\"
%s
\"\n
"
,
spec_name
);
/* go on anyways */
}
/* The probe function can sleep, so load firmware directly */
spec_load_files
(
dev
);
/* Done */
pci_set_drvdata
(
pdev
,
dev
);
list_add
(
&
dev
->
list
,
&
spec_list
);
return
0
;
}
static
void
spec_remove
(
struct
pci_dev
*
pdev
)
{
struct
spec_dev
*
dev
=
pci_get_drvdata
(
pdev
);
int
i
;
printk
(
"%s
\n
"
,
__func__
);
for
(
i
=
0
;
i
<
3
;
i
++
)
{
iounmap
(
dev
->
remap
[
i
]);
dev
->
remap
[
i
]
=
NULL
;
dev
->
area
[
i
]
=
NULL
;
}
list_del
(
&
dev
->
list
);
pci_set_drvdata
(
pdev
,
NULL
);
for
(
i
=
0
;
i
<
SPEC_NAMES
;
i
++
)
kfree
(
dev
->
names
[
i
]);
kfree
(
dev
);
/* FIXME */
}
DEFINE_PCI_DEVICE_TABLE
(
spec_idtable
)
=
{
{
PCI_DEVICE
(
PCI_VENDOR_ID_CERN
,
PCI_DEVICE_ID_SPEC
)
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_GENNUM
,
PCI_DEVICE_ID_GN4124
)
},
{
0
,},
};
static
struct
pci_driver
spec_driver
=
{
.
name
=
"spec"
,
.
id_table
=
spec_idtable
,
...
...
kernel/spec.h
View file @
a3ac4129
...
...
@@ -21,14 +21,19 @@
#define SPEC_MAX_BOARDS 8
enum
spec_names
{
SPEC_NAME_FW
,
SPEC_NAME_PROG
,
SPEC_NAME_SUBMOD
,
SPEC_NAMES
,
};
/* Our device structure */
struct
spec_dev
{
struct
pci_driver
*
pci_driver
;
struct
pci_dev
*
pdev
;
struct
resource
*
area
[
3
];
/* bar 0, 2, 4 */
void
*
remap
[
3
];
/* ioremap of bar 0, 2, 4 */
char
*
fw_name
;
char
*
elf_name
;
char
*
names
[
SPEC_NAMES
];
char
*
submod_name
;
struct
work_struct
work
;
const
struct
firmware
*
fw
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment