虽然scsi disk不难,但是如果你以为scsi disk这个模块每个函数都像init_sd()一样简单,那么我只能说你属于那种被蜘蛛咬了就以为自己是蜘蛛侠,被雷电劈了就以为自己是闪电侠,摸了一次高压电就以为自己是沈殿霞.你不服?咱们来看sd_probe,这个函数就不是那么简单.
1566 /**
1567 * sd_probe - called during driver initialization and whenever a
1568 * new scsi device is attached to the system. It is called once
1569 * for each scsi device (not just disks) present.
1570 * @dev: pointer to device object
1571 *
1572 * Returns 0 if successful (or not interested in this scsi device
1573 * (e.g. scanner)); 1 when there is an error.
1574 *
1575 * Note: this function is invoked from the scsi mid-level.
1576 * This function sets up the mapping between a given
1577 * <host,channel,id,lun> (found in sdp) and new device name
1578 * (e.g. /dev/sda). More precisely it is the block device major
1579 * and minor number that is chosen here.
1580 *
1581 * Assume sd_attach is not re-entrant (for time being)
1582 * Also think about sd_attach() and sd_remove() running coincidentally.
1583 **/
1584 static int sd_probe(struct device *dev)
1585 {
1586 struct scsi_device *sdp = to_scsi_device(dev);
1587 struct scsi_disk *sdkp;
1588 struct gendisk *gd;
1589 u32 index;
1590 int error;
1591
1592 error = -ENODEV;
1593 if (sdp->type != TYPE_DISK && sdp->type != TYPE_MOD && sdp->type != TYPE_RBC)
1594 goto out;
1595
1596 SCSI_LOG_HLQUEUE(3, sdev_printk(KERN_INFO, sdp,
1597 "sd_attach/n"));
1598
1599 error = -ENOMEM;
1600 sdkp = kzalloc(sizeof(*sdkp), GFP_KERNEL);
1601 if (!sdkp)
1602 goto out;
1603
1604 gd = alloc_disk(16);
1605 if (!gd)
1606 goto out_free;
1607
1608 if (!idr_pre_get(&sd_index_idr, GFP_KERNEL))
1609 goto out_put;
1610
1611 spin_lock(&sd_index_lock);
1612 error = idr_get_new(&sd_index_idr, NULL, &index);
1613 spin_unlock(&sd_index_lock);
1614
1615 if (index >= SD_MAX_DISKS)
1616 error = -EBUSY;
1617 if (error)
1618 goto out_put;
1619
1620 sdkp->device = sdp;
1621 sdkp->driver = &sd_template;
1622 sdkp->disk = gd;
1623 sdkp->index = index;
1624 sdkp->openers = 0;
1625
1626 if (!sdp->timeout) {
1627 if (sdp->type != TYPE_MOD)
1628 sdp->timeout = SD_TIMEOUT;
1629 else
1630 sdp->timeout = SD_MOD_TIMEOUT;
1631 }
1632
1633 class_device_initialize(&sdkp->cdev);
1634 sdkp->cdev.dev = &sdp->sdev_gendev;
1635 sdkp->cdev.class = &sd_disk_class;
1636 strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);
1637
1638 if (class_device_add(&sdkp->cdev))
1639 goto out_put;
1640
1641 get_device(&sdp->sdev_gendev);
1642
1643 gd->major = sd_major((index & 0xf0) >> 4);
1644 gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
1645 gd->minors = 16;
1646 gd->fops = &sd_fops;
1647
1648 if (index < 26) {
1649 sprintf(gd->disk_name, "sd%c", 'a' + index % 26);
1650 } else if (index < (26 + 1) * 26) {
1651 sprintf(gd->disk_name, "sd%c%c",
1652 'a' + index / 26 - 1,'a' + index % 26);
1653 } else {
1654 const unsigned int m1 = (index / 26 - 1) / 26 - 1;
1655 const unsigned int m2 = (index / 26 - 1) % 26;
1656 const unsigned int m3 = index % 26;
1657 sprintf(gd->disk_name, "sd%c%c%c",
1658 'a' + m1, 'a' + m2, 'a' + m3);
1659 }
1660
1661 gd->private_data = &sdkp->driver;
1662 gd->queue = sdkp->device->request_queue;
1663
1664 sd_revalidate_disk(gd);
1665
1666 gd->driverfs_dev = &sdp->sdev_gendev;
1667 gd->flags = GENHD_FL_DRIVERFS;
1668 if (sdp->removable)
1669 gd->flags |= GENHD_FL_REMOVABLE;
1670
1671 dev_set_drvdata(dev, sdkp);
1672 add_disk(gd);
1673
1674 sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk/n",
1675 sdp->removable ? "removable " : "");
1676
1677 return 0;
1678
1679 out_put:
1680 put_disk(gd);
1681 out_free:
1682 kfree(sdkp);
1683 out:
1684 return error;
1685 }
如果我们不看新闻联播,我们又怎么知道自己生活在幸福中呢?如果我们不看probe,我们又怎么知道设备驱动的故事是如何展开的呢?
首先,我们为scsi device准备一个指针,struct scsi_device *sdp,为scsi disk准备一个指针,struct scsi_disk *sdkp,此外,甭管是scsi硬盘还是ide硬盘,都少不了一个结构体struct gendisk,这里咱们准备了一个指针struct gendisk *gd.
一路走来的兄弟们一定知道,sd_probe将会由scsi核心层调用,或者也叫scsi mid-level来调用.scsi mid-level在调用sd_probe之前,已经为这个scsi设备准备好了struct device,struct scsi_device,已经为它们做好了初始化,所以这里struct device *dev作为参数传递进来咱们就可以直接引用它的成员了.
这不,1593行,就开始判断sdp->type,这是struct scsi_device结构体中的成员char type,它用来表征这个scsi设备是哪种类型的,scsi设备五花八门,而只有这里列出来的这三种是sd_mod所支持的.这其中我们最熟悉的当属TYPE_DISK,它就是普通的scsi磁盘,而TYPE_MOD表示的是磁光盘(Magneto-Optical disk),一种采用激光和磁场共同作用的磁光方式存储技术实现的介质,外观和3.5英寸软盘相似,量你也不知道,所以不多说了.另外,TYPE_RBC也算在咱们名下,RBC表示Reduced Block Commands,中文叫命令集,这个也不必多说.
1600行,为sdkp申请内存.struct scsi_disk定义于include/scsi/sd.h:
34 struct scsi_disk {
35 struct scsi_driver *driver; /* always &sd_template */
36 struct scsi_device *device;
37 struct class_device cdev;
38 struct gendisk *disk;
39 unsigned int openers; /* protected by BKL for now, yuck */
40 sector_t capacity; /* size in 512-byte sectors */
41 u32 index;
42 u8 media_present;
43 u8 write_prot;
44 unsigned WCE : 1; /* state of disk WCE bit */
45 unsigned RCD : 1; /* state of disk RCD bit, unused */
46 unsigned DPOFUA : 1; /* state of disk DPOFUA bit */
47 };
看起来,似乎描述一个scsi disk很简单,其实你不要忘了,前面我们还提到另一个结构体struct gendisk,这个结构体来自一个神秘的地方,include/linux/genhd.h:
113 struct gendisk {
114 int major; /* major number of driver */
115 int first_minor;
116 int minors; /* maximum number of minors, =1 for
117 * disks that can't be partitioned. */
118 char disk_name[32]; /* name of major driver */
119 struct hd_struct **part; /* [indexed by minor] */
120 int part_uevent_suppress;
121 struct block_device_operations *fops;
122 struct request_queue *queue;
123 void *private_data;
124 sector_t capacity;
125
126 int flags;
127 struct device *driverfs_dev;
128 struct kobject kobj;
129 struct kobject *holder_dir;
130 struct kobject *slave_dir;
131
132 struct timer_rand_state *random;
133 int policy;
134
135 atomic_t sync_io; /* RAID */
136 unsigned long stamp;
137 int in_flight;
138 #ifdef CONFIG_SMP
139 struct disk_stats *dkstats;
140 #else
141 struct disk_stats dkstats;
142 #endif
143 struct work_struct async_notify;
144 };
于是,struct scsi_disk和struct gendisk联手来为我们描述一块磁盘,scsi_disk是scsi专用,而gendisk中的gen表示general,过了英语四级的都知道,这表示通用,即scsi呀,ide呀,大家伙都能利用的.
于是1604行,alloc_disk就是为我们分配一个gendisk.
但是接下来1608行的sd_index_idr就有些学问了.
下面我们必须用专门一段文字来描述idr了.首先在89行我们看到下面这么一句,
89 static DEFINE_IDR(sd_index_idr);
这被叫做定义一个IDR.印象中大四上刚开学的时候,江湖中开始流传一篇文章叫做”idr”- integer ID management,专门对idr进行了一些介绍,这篇文章最早是发表在LWN(Linux Weekly News)上面.怎奈少不更事的我一直沉迷于上网,聊天,灌水,玩游戏,所以直到今天,依然不知道为什么这玩意儿叫做idr,只是懵懵懂懂的感觉它是一个用来管理一些小整数的工具,具体来说,就是内核中定义了一些函数,几乎所有的函数都被定义在一个文件中,即lib/idr.c,关于它的实现咱们自然不必多说,说多了就未免喧宾夺主了,我们只看它的实际效果.
实际上我们一共调用了三个来自lib/idr.c的函数,或者更确切的说是四个,因为上面这个宏DEFINE_IDR也是一个函数的包装,总的来说,如果我们需要使用idr工具,我们就需要首先调用idr_init函数,或者使用它的马夹DEFINE_IDR,这算是初始化,也叫做创建一个idr对象,其实就是申请一个struct idr结构体变量.然后使用两个函数,一个是idr_pre_get(),一个是idr_get_new(),当我们日后觉得这个idr已经没有利用价值了,我们则可以调用另一个函数,idr_remove()来完成过河拆桥的工作.
我们看到1608行调用idr_pre_get(),其第一个参数就是我们之前初始化的&sd_index_idr,第二个参数是一个掩码,和我们以往每一次申请内存时一样,通常传递的就是GFP_KERNEL.这个函数有点与众不同的是,它返回0表示出错,返回非0才表示正常,典型的抽疯式函数.
而1612行,idr_get_new(),就是获得下一个available的ID号,保存在第三个参数中,即我们这里的index,第二个参数不是太常用,传递个NULL就可以了.一切正常将返回0.
而index必须小于SD_MAX_DISKS,这个宏定义于include/scsi/sd.h:
12 * This is limited by the naming scheme enforced in sd_probe,
13 * add another character to it if you really need more disks.
14 */
15 #define SD_MAX_DISKS (((26 * 26) + 26 + 1) * 26)
比这个宏还大就肯定出错了.关于这个宏,曾几何时,我也和你一样,丈二和尚摸不着头脑,我也曾彷徨,也曾犹豫,也曾困惑,后来有一天我终于明白了,26代表的是英文字母的个数,而下面我们马上就能看到,Linux中对scsi disk的命名规则正是利用了26个英文字母.
不信你就看1643到1659行,这一段同时也正是idr的精华.最终你会发现,gd->disk_name一定是在sda-sdz之间,或者是在sdaa到sdzz之间,或者是在sdaaa到sdzzz之间.算一下,是不是正好数量为SD_MAX_DISKS个.而index的取值范围则是[0,SD_MAX_DISKS)之间,只取整数.举例来说,如果你只有一块硬盘,那么你能看到的是,/dev/sda,如果你有多块硬盘,比如像我下面这个例子中的一样,
localhost:~ # fdisk -l
Disk /dev/sda: 146.1 GB, 146163105792 bytes
255 heads, 63 sectors/track, 17769 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Device Boot Start End Blocks Id System
/dev/sda1 1 266 2136613+ 83 Linux
/dev/sda2 2879 17769 119611957+ 83 Linux
/dev/sda3 * 267 1572 10490445 83 Linux
/dev/sda4 1573 2878 10490445 82 Linux swap / Solaris
Partition table entries are not in disk order
Disk /dev/sdb: 5368 MB, 5368709120 bytes
166 heads, 62 sectors/track, 1018 cylinders
Units = cylinders of 10292 * 512 = 5269504 bytes
Device Boot Start End Blocks Id System
Disk /dev/sdc: 5368 MB, 5368709120 bytes
166 heads, 62 sectors/track, 1018 cylinders
Units = cylinders of 10292 * 512 = 5269504 bytes
Device Boot Start End Blocks Id System
Disk /dev/sdd: 5368 MB, 5368709120 bytes
166 heads, 62 sectors/track, 1018 cylinders
Units = cylinders of 10292 * 512 = 5269504 bytes
Device Boot Start End Blocks Id System
Disk /dev/sde: 5368 MB, 5368709120 bytes
166 heads, 62 sectors/track, 1018 cylinders
Units = cylinders of 10292 * 512 = 5269504 bytes
Device Boot Start End Blocks Id System
这个例子中我的机器里是5块scsi硬盘,那么它们的名字分别是sda,sdb,sdc,sdd,sde,但是如果你他妈的比较变态,一台机器里接了30块硬盘,那么没啥说的,它们就会依次被命名为sda,sdb,…,sdx,sdy,sdz,这还不够,只有26块,接下来的硬盘名称就叫做sdaa,sdab,sdac,sdad,总共凑满30块.但如果你觉得这还不够变态,你非要挑战极限,你非要play zhuangbility,那么在用完了sdaa到sdzz之后,Linux还允许你用sdaaa,sdaab,…,一直到sdzzz.总之,在Linux中,你最多可以使用的硬盘数撑死就是SD_MAX_DISKS个.当然,我还是奉劝你,别这么干,毕竟孔子曾经曰过:”莫装B,装B遭雷劈!”
算了我们言归正传,1643行,gd->major被赋了值,自从在张江软件园某不知名的小公司里笔试过那道”不用临时变量交换两个变量的值”之后,我曾深刻的反省自己为何当初没有好好学习谭浩强老师那本<<C程序设计>>中的位运算.痛定思痛之后,我终于能看懂眼前这代码了,当然首先我们得明白这个sd_major为何物?
247 /*
248 * Device no to disk mapping:
249 *
250 * major disc2 disc p1
251 * |............|.............|....|....| <- dev_t
252 * 31 20 19 8 7 4 3 0
253 *
254 * Inside a major, we have 16k disks, however mapped non-
255 * contiguously. The first 16 disks are for major0, the next
256 * ones with major1, ... Disk 256 is for major0 again, disk 272
257 * for major1, ...
258 * As we stay compatible with our numbering scheme, we can reuse
259 * the well-know SCSI majors 8, 65--71, 136--143.
260 */
261 static int sd_major(int major_idx)
262 {
263 switch (major_idx) {
264 case 0:
265 return SCSI_DISK0_MAJOR;
266 case 1 ... 7:
267 return SCSI_DISK1_MAJOR + major_idx - 1;
268 case 8 ... 15:
269 return SCSI_DISK8_MAJOR + major_idx - 8;
270 default:
271 BUG();
272 return 0; /* shut up gcc */
273 }
274 }
看起来挺复杂,其实不然,我们前面说过,scsi disk的主设备号是已经固定好了的,它就是瓜分了8,65-71,128-135这几个号,这里SCSI_DISK0_MAJOR就是8,SCSI_DISK1_MAJOR就是65,SCSI_DISK8_MAJOR就是128.sd_major()接受的参数就是index的bit4到bit7,而它取值范围自然就是0到15,这也正是sd_major()中switch/case语句判断的范围,即实际上major_idx就是主设备号的一个索引,就说是在这个16个主设备号中它算老几.而first_minor就是对应于本index的第一个次设备号,我们可以用代入法得到,当index为0,则first_minor为0,当index为1,则first_minor为16,当index为2,则first_minor为32.另一方面,minor本身表示本index下有多少个次设备号,这个大家都是一样的,都是16.我们通过下面这个例子也能看到:
[root@localhost ~]# cat /proc/partitions
major minor #blocks name
8 0 285474816 sda
8 1 2104483 sda1
8 2 16779892 sda2
8 3 1 sda3
8 5 20972826 sda5
8 6 20482843 sda6
8 7 20482843 sda7
8 8 10241406 sda8
8 9 20482843 sda9
8 10 20482843 sda10
8 11 20482843 sda11
8 12 20482843 sda12
8 13 20482843 sda13
8 14 20482843 sda14
8 15 20482843 sda15
8 16 5242880 sdb
8 32 5242880 sdc
8 48 5242880 sdd
8 64 5242880 sde
很显然,对于sda,其次设备是从0开始,对于sdb,次设备号从16开始,对于sdc,则从32开始,sdd则从48开始,每个index或者说每个disk_name下面有16个次设备号.也因此一块SCSI硬盘就是最多15个分区.
除此之外,sd_probe中主要就是些简单的赋值了.当然也不全是,比如1633行到1639行这一段,它的效果就是让这个设备出现在了sysfs中class子目录下面,比如下面这个例子:
localhost:~ # cat /sys/class/scsi_device/
0:0:8:0/ 0:2:0:0/ 1:0:0:0/ 1:0:0:1/ 1:0:0:2/ 1:0:0:3/
每一个scsi设备都在这个占了一个子目录.
1641行这个get_device不用多说,访问一个struct device的第一步,增加引用计数.以后不用的时候自然会有一个相对的函数put_device被调用.
1671行,dev_set_drvdata,就是设置dev->driver_data等于sdkp,即让struct device的指针dev和struct scsi_disk的指针sdkp给联系起来.这就是所谓的朋友多了路好走,关系网建立得越大,日后使用起来就越方便.
最后,特别提醒两个赋值.第一个是,1621行,让sdkp->driver等于&sd_template,另一个是1646行,让gd->fops等于&sd_fops.这两行赋值对咱们整个故事的意义,不亚于1979年那个春天有一位老人在中国的南海边划了一个圈对中国的重大意义.在咱们讲完sd_probe之后,这两个赋值将引领我们展开下面的故事.
关于sd_probe,眼瞅着就要完了,但是很显然,有两个函数我们还没有提到,它们就是1664行的sd_revalidate_disk()以及1672行的add_disk(),这两个函数是如此的重要,以至于我们有必要在下一节专门来讲述它们.