先贴源代码:
/** * 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) { struct char_device_struct *cd; dev_t to = from + count; dev_t n, next; for (n = from; n < to; n = next) { next = MKDEV(MAJOR(n)+1, 0); if (next > to) next = to; cd = __register_chrdev_region(MAJOR(n), MINOR(n), next - n, name); if (IS_ERR(cd)) goto fail; } return 0; fail: to = n; for (n = from; n < to; n = next) { next = MKDEV(MAJOR(n)+1, 0); kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n)); } return PTR_ERR(cd); }
next = MKDEV(MAJOR(n)+1, 0); if (next > to) next = to;
这个地方一直不理解,仔细思考后自己写了一个测试程序,基本弄清设计意图:
一个设备号由主从设备号构成,主设备号占12位,从设备号占20位,一个主设备可以对应很多个从设备。
每次最多处理20位长度的从设备号,所以要分多次循环处理(仅仅存在于理论上!),而且要考虑其实设备号不是从0号从设备开始。
以下是用于理解的测试代码:
#include<iostream>
using namespace std;
#define MINORBITS 20
#define MINORMASK ((1U << MINORBITS) - 1)
#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK))
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
#define INPUT_MAJOR 13
void test(void)
{
unsigned int from;
unsigned int to;
unsigned int count;
unsigned int n;
unsigned int next;
from = MKDEV(INPUT_MAJOR, 0);
count = 10000000;
to = from + count;
for (n = from; n < to; n = next)
{
next = MKDEV(MAJOR(n)+1, 0);
printf("next0:0x%x\n",next);
if (next > to)
next = to;
printf("n:0x%x\n",n);
printf("MKDEV(MAJOR(e), 0):0x%x\n",MKDEV(14, 0));
printf("MKDEV(MAJOR(n)+1, 0):0x%x\n",MKDEV(MAJOR(n)+1, 0));
printf("MAJOR(n)+1:0x%x\n",MAJOR(n)+1);
printf("MAJOR(n):0x%x\n",MAJOR(n));
printf("n:0x%x\n",n);
printf("next:0x%x\n",next);
printf("0x%x 0x%x 0x%x \n",MAJOR(n), MINOR(n), next - n);
}
}
int main(void)
{
test();
return 0;
}