|
@@ -183,6 +183,15 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
|
|
return cd;
|
|
return cd;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * register_chrdev_region() - register a range of device numbers
|
|
|
|
+ * @from: the first in the desired range of device numbers; must include
|
|
|
|
+ * the major number.
|
|
|
|
+ * @count: the number of consecutive device numbers required
|
|
|
|
+ * @name: the name of the device or driver.
|
|
|
|
+ *
|
|
|
|
+ * Return value is zero on success, a negative error code on failure.
|
|
|
|
+ */
|
|
int register_chrdev_region(dev_t from, unsigned count, const char *name)
|
|
int register_chrdev_region(dev_t from, unsigned count, const char *name)
|
|
{
|
|
{
|
|
struct char_device_struct *cd;
|
|
struct char_device_struct *cd;
|
|
@@ -208,6 +217,17 @@ fail:
|
|
return PTR_ERR(cd);
|
|
return PTR_ERR(cd);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * alloc_chrdev_region() - register a range of char device numbers
|
|
|
|
+ * @dev: output parameter for first assigned number
|
|
|
|
+ * @baseminor: first of the requested range of minor numbers
|
|
|
|
+ * @count: the number of minor numbers required
|
|
|
|
+ * @name: the name of the associated device or driver
|
|
|
|
+ *
|
|
|
|
+ * Allocates a range of char device numbers. The major number will be
|
|
|
|
+ * chosen dynamically, and returned (along with the first minor number)
|
|
|
|
+ * in @dev. Returns zero or a negative error code.
|
|
|
|
+ */
|
|
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
|
|
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
|
|
const char *name)
|
|
const char *name)
|
|
{
|
|
{
|
|
@@ -277,6 +297,15 @@ out2:
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * unregister_chrdev_region() - return a range of device numbers
|
|
|
|
+ * @from: the first in the range of numbers to unregister
|
|
|
|
+ * @count: the number of device numbers to unregister
|
|
|
|
+ *
|
|
|
|
+ * This function will unregister a range of @count device numbers,
|
|
|
|
+ * starting with @from. The caller should normally be the one who
|
|
|
|
+ * allocated those numbers in the first place...
|
|
|
|
+ */
|
|
void unregister_chrdev_region(dev_t from, unsigned count)
|
|
void unregister_chrdev_region(dev_t from, unsigned count)
|
|
{
|
|
{
|
|
dev_t to = from + count;
|
|
dev_t to = from + count;
|
|
@@ -414,6 +443,16 @@ static int exact_lock(dev_t dev, void *data)
|
|
return cdev_get(p) ? 0 : -1;
|
|
return cdev_get(p) ? 0 : -1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * cdev_add() - add a char device to the system
|
|
|
|
+ * @p: the cdev structure for the device
|
|
|
|
+ * @dev: the first device number for which this device is responsible
|
|
|
|
+ * @count: the number of consecutive minor numbers corresponding to this
|
|
|
|
+ * device
|
|
|
|
+ *
|
|
|
|
+ * cdev_add() adds the device represented by @p to the system, making it
|
|
|
|
+ * live immediately. A negative error code is returned on failure.
|
|
|
|
+ */
|
|
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
|
|
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
|
|
{
|
|
{
|
|
p->dev = dev;
|
|
p->dev = dev;
|
|
@@ -426,6 +465,13 @@ static void cdev_unmap(dev_t dev, unsigned count)
|
|
kobj_unmap(cdev_map, dev, count);
|
|
kobj_unmap(cdev_map, dev, count);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * cdev_del() - remove a cdev from the system
|
|
|
|
+ * @p: the cdev structure to be removed
|
|
|
|
+ *
|
|
|
|
+ * cdev_del() removes @p from the system, possibly freeing the structure
|
|
|
|
+ * itself.
|
|
|
|
+ */
|
|
void cdev_del(struct cdev *p)
|
|
void cdev_del(struct cdev *p)
|
|
{
|
|
{
|
|
cdev_unmap(p->dev, p->count);
|
|
cdev_unmap(p->dev, p->count);
|
|
@@ -454,6 +500,11 @@ static struct kobj_type ktype_cdev_dynamic = {
|
|
.release = cdev_dynamic_release,
|
|
.release = cdev_dynamic_release,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * cdev_alloc() - allocate a cdev structure
|
|
|
|
+ *
|
|
|
|
+ * Allocates and returns a cdev structure, or NULL on failure.
|
|
|
|
+ */
|
|
struct cdev *cdev_alloc(void)
|
|
struct cdev *cdev_alloc(void)
|
|
{
|
|
{
|
|
struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
|
|
struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
|
|
@@ -465,6 +516,14 @@ struct cdev *cdev_alloc(void)
|
|
return p;
|
|
return p;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * cdev_init() - initialize a cdev structure
|
|
|
|
+ * @cdev: the structure to initialize
|
|
|
|
+ * @fops: the file_operations for this device
|
|
|
|
+ *
|
|
|
|
+ * Initializes @cdev, remembering @fops, making it ready to add to the
|
|
|
|
+ * system with cdev_add().
|
|
|
|
+ */
|
|
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
|
|
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
|
|
{
|
|
{
|
|
memset(cdev, 0, sizeof *cdev);
|
|
memset(cdev, 0, sizeof *cdev);
|