Newer
Older
* Copyright 2011 CERN
* Author: Federico Vaga <federico.vaga@gmail.com>
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* GNU GPLv2 or later
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/zio.h>
#include <linux/zio-buffer.h>
#include "zio-internal.h"
struct zio_status zio_global_status;
static struct zio_status *zstat = &zio_global_status; /* Always use ptr */
/*
* We use a local slab for control structures.
*/
static struct kmem_cache *zio_ctrl_slab;
struct zio_control *zio_alloc_control(gfp_t gfp)
{
struct zio_control *ctrl;
ctrl = kmem_cache_alloc(zio_ctrl_slab, gfp);
if (!ctrl)
return NULL;
memset(ctrl, 0, sizeof(*ctrl));
ctrl->major_version = ZIO_MAJOR_VERSION;
ctrl->minor_version = ZIO_MINOR_VERSION;
if (ntohl(1) == 1)
ctrl->flags |= ZIO_CONTROL_BIG_ENDIAN;
else
ctrl->flags |= ZIO_CONTROL_LITTLE_ENDIAN;
return ctrl;
}
void zio_free_control(struct zio_control *ctrl)
{
kmem_cache_free(zio_ctrl_slab, ctrl);
}
int __init zio_slab_init(void)
{
zio_ctrl_slab = KMEM_CACHE(zio_control, 0);
if (!zio_ctrl_slab)
return -ENOMEM;
return 0;
}
void zio_slab_exit(void) /* not __exit: called from zio_init on failures */
{
if (zio_ctrl_slab)
kmem_cache_destroy(zio_ctrl_slab);
return;
}
struct zio_device *zio_find_device(char *name, uint32_t dev_id)
{
struct zio_object_list_item *cur;
struct zio_device *zdev;
if (!name)
return NULL;
list_for_each_entry(cur, &zstat->all_devices.list, list) {
pr_debug("%s:%d %s=%s\n", __func__, __LINE__, cur->name, name);
zdev = to_zio_dev(&cur->obj_head->dev);
if (strcmp(cur->name, name) == 0 && zdev->dev_id == dev_id)
return zdev; /* found */
}
return NULL;
}
EXPORT_SYMBOL(zio_find_device);
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
static int __init zio_init(void)
{
int err;
/* Some compile-time checks, so developers are free to hack around */
BUILD_BUG_ON(_ZIO_DEV_ATTR_STD_NUM != ARRAY_SIZE(zio_zdev_attr_names));
BUILD_BUG_ON(_ZIO_BUF_ATTR_STD_NUM != ARRAY_SIZE(zio_zbuf_attr_names));
BUILD_BUG_ON(_ZIO_TRG_ATTR_STD_NUM != ARRAY_SIZE(zio_trig_attr_names));
BUILD_BUG_ON(ZIO_NR_MINORS > MINORMASK + 1);
err = zio_slab_init();
if (err)
return err;
/* Register ZIO bus */
err = bus_register(&zio_bus_type);
if (err)
goto out;
/* Initialize char device */
err = zio_register_cdev();
if (err)
goto out_cdev;
spin_lock_init(&zstat->lock);
INIT_LIST_HEAD(&zstat->all_devices.list);
zstat->all_devices.zobj_type = ZIO_DEV;
INIT_LIST_HEAD(&zstat->all_trigger_types.list);
zstat->all_trigger_types.zobj_type = ZIO_TRG;
INIT_LIST_HEAD(&zstat->all_buffer_types.list);
zstat->all_buffer_types.zobj_type = ZIO_BUF;
err = zio_default_buffer_init();
if (err)
pr_warning("%s: cannot register default buffer\n", __func__);
err = zio_default_trigger_init();
if (err)
pr_warning("%s: cannot register default trigger\n", __func__);
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
pr_info("zio-core had been loaded\n");
return 0;
out_cdev:
bus_unregister(&zio_bus_type);
out:
zio_slab_exit();
return err;
}
static void __exit zio_exit(void)
{
zio_default_trigger_exit();
zio_default_buffer_exit();
/* Remove char device */
zio_unregister_cdev();
/* Remove ZIO bus */
bus_unregister(&zio_bus_type);
zio_slab_exit();
pr_info("zio-core had been unloaded\n");
return;
}
subsys_initcall(zio_init);
module_exit(zio_exit);
MODULE_AUTHOR("Federico Vaga and Alessandro Rubini");
/* Federico wrote the core, Alessandro wrote default trigger and buffer */
MODULE_DESCRIPTION("ZIO - ZIO Input Output");
MODULE_LICENSE("GPL");