Commit 1f650869 authored by Alessandro Rubini's avatar Alessandro Rubini

fmc bus and users: add fmc_version support

Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 1f5d9c08
......@@ -112,13 +112,19 @@ driver. For this reason the device structure includes a complete copy
of the EEPROM (actually, the carrier driver may choose to only return
the leading part of it).
This is the current structure defining a device. Please note that stuff
is still being defined as I write this, so the structures are going to
change (if in doubt, please check the header file in the repository rather
than this document):
This is the current structure defining a device. Please note that all
the machinery is in place but some details may still change in the future.
For this reason, there is a version field at the beginning of the structure.
As usual, the minor number will change for compatible changes (like a new
flag) and the minor number will increase when an incompatible change
happens (for example, a change in layout of some @i{fmc} data structures).
Device writers should just set it to the
value @t{FMC_VERSION}, and be ready to get back @t{-EINVAL} at
registration time.
@smallexample
struct fmc_device {
unsigned long version; /* to be set to FMC_VERSION */
struct fmc_device_id id; /* for the match function */
struct fmc_operations *op; /* carrier-provided */
int irq; /* according to host bus. 0 == none */
......
......@@ -14,6 +14,20 @@
#include <linux/fmc.h>
#include "spec.h"
static int fmc_check_version(unsigned long version, const char *name)
{
if (__FMC_MAJOR(version) != FMC_MAJOR) {
pr_err("%s: \"%s\" has wrong major (has %li, expected %i)\n",
__func__, name, __FMC_MAJOR(version), FMC_MAJOR);
return -EINVAL;
}
if (__FMC_MINOR(version) != FMC_MINOR)
pr_info("%s: \"%s\" has wrong minor (has %li, expected %i)\n",
__func__, name, __FMC_MINOR(version), FMC_MINOR);
return 0;
}
static int fmc_match(struct device *dev, struct device_driver *drv)
{
//struct fmc_driver *fdrv = to_fmc_driver(drv);
......@@ -75,6 +89,8 @@ struct device fmc_bus = {
/* Functions for client modules */
int fmc_driver_register(struct fmc_driver *drv)
{
if (fmc_check_version(drv->version, drv->driver.name))
return -EINVAL;
drv->driver.bus = &fmc_bus_type;
return driver_register(&drv->driver);
}
......@@ -88,6 +104,8 @@ EXPORT_SYMBOL(fmc_driver_unregister);
int fmc_device_register(struct fmc_device *fdev)
{
if (fmc_check_version(fdev->version, fdev->carrier_name))
return -EINVAL;
device_initialize(&fdev->dev);
if (!fdev->dev.release)
fdev->dev.release = __fmc_release;
......
......@@ -47,6 +47,7 @@ int t_remove(struct fmc_device *fmc)
}
static struct fmc_driver t_drv = {
.version = FMC_VERSION,
.driver.name = KBUILD_MODNAME,
.probe = t_probe,
.remove = t_remove,
......
......@@ -138,6 +138,7 @@ int fwe_remove(struct fmc_device *fmc)
}
static struct fmc_driver fwe_drv = {
.version = FMC_VERSION,
.driver.name = KBUILD_MODNAME,
.probe = fwe_probe,
.remove = fwe_remove,
......
......@@ -18,6 +18,17 @@
struct fmc_device;
struct fmc_driver;
/*
* This bus abstraction is developed separately from drivers, so we need
* to check the version of the data structures we receive.
*/
#define FMC_MAJOR 1
#define FMC_MINOR 0
#define FMC_VERSION ((FMC_MAJOR << 16) | FMC_MINOR)
#define __FMC_MAJOR(x) ((x) >> 16)
#define __FMC_MINOR(x) ((x) & 0xffff)
struct fmc_device_id {
/* FIXME: the device ID must be defined according to eeprom contents */
uint64_t unique_id;
......@@ -27,6 +38,7 @@ struct fmc_device_id {
/* The driver is a pretty simple thing */
struct fmc_driver {
unsigned long version;
struct device_driver driver;
int (*probe)(struct fmc_device *);
int (*remove)(struct fmc_device *);
......@@ -61,6 +73,7 @@ struct fmc_operations {
/* The device reports all information needed to access hw */
struct fmc_device {
unsigned long version;
unsigned long flags;
struct fmc_device_id id; /* for the match function */
struct fmc_operations *op; /* carrier-provided */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment