块设备驱动详解 IDE(转)

转自百度文库点击打开链接


IDE 驱动分析

本次分析以linux2.6.32 内核为基础,重点分析ide 硬盘驱动的实现。通过前面
子系统的分析,不难发现任何一个底层驱动的实现都离不开其他内核模块的支持。
同时内核对各个模块的加载有着一定的先后顺序,要想对一个子系统进行深入分析,
首先必须对整个子系统的构架有个充分的了解,更通俗的来讲就是当使用make
menuconfig 来配置内核模块的时候,要清楚的知道这些module 之间的层次关系,
以及这些module 分别对应于内核中的那些.c 文件。而这些信息也正是由kconfig 和
makefile 文件得到的。具体到ide 硬盘驱动,我们首先来看看/driver/ide 目录下的
kconfig 文件….
menuconfig IDE
tristate "ATA/ATAPI/MFM/RLL support"
depends on HAVE_IDE
depends on BLOCK
if IDE
….

endif # IDE
也就是说这里的IDE 是一切ide 驱动的基础,对应到文件就是ide-core.c
ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o \
ide-io-std.o ide-eh.o
然后就到了硬盘驱动的配置:
config IDE_GD
tristate "generic ATA/ATAPI disk support",对应到makefile 中的文件就是ide-gd.c、
ide-gd_mod.c
config CONFIG_IDE_GD_ATA 对应到makefile 中的文件就是ide-disk.o
ide-disk_ioctl.o
最后,就是与硬件平台相关的了,对于ARM 体系结构,属于generic IDE driver,
同样对应的文件即是ide-generic.o
config IDE_GENERIC
tristate "generic/default IDE chipset support"
depends on ALPHA || X86 || IA64 || M32R || MIPS || ARCH_RPC || ARCH_SHARK
default ARM && (ARCH_RPC || ARCH_SHARK)
help
This is the generic IDE driver. This driver attaches to the
fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and
so on). Please note that if this driver is built into the
kernel or loaded before other ATA (IDE or libata) drivers
and the controller is located at legacy ports, this driver
may grab those ports and thus can prevent the controller
specific driver from attaching.
Also, currently, IDE generic doesn't allow IRQ sharing
meaning that the IRQs it grabs won't be available to other
controllers sharing those IRQs which usually makes drivers
for those controllers fail. Generally, it's not a good idea
to load IDE generic driver on modern systems.
If unsure, say N.
好了,看完这些个以后,大致清楚了IDE 子系统分为那3 个层次了。那么接下来的事
情就是对这三块一一进行分析……
IDE 总线
这里有个小问题,就是ide-core.c 这个文件搜索整个内核都不存在,只能从ide.c
这个文件入手了。
还是那个module_init(ide_init),那么我们就先看看ide_init,源码如下:
365 /*
366 * This is gets invoked once during initialization, to set *everything* up
367 */
368 static int __init ide_init(void)
369 {
370 int ret;
371
372 printk(KERN_INFO "Uniform Multi-Platform E-IDE driver\n");
373
374 ret = bus_register(&ide_bus_type);
375 if (ret < 0) {
376 printk(KERN_WARNING "IDE: bus_register error: %d\n", ret);
377 return ret;
378 }
379
380 ide_port_class = class_create(THIS_MODULE, "ide_port");
381 if (IS_ERR(ide_port_class)) {
382 ret = PTR_ERR(ide_port_class);
383 goto out_port_class;
384 }
385
386 ide_acpi_init();
387
388 proc_ide_create();
389
390 return 0;
391
392 out_port_class:
393 bus_unregister(&ide_bus_type);
394
395 return ret;
396 }
374 行,又见了总线注册bus_register,早在plateform 总线中我们就对他进行了解剖,
是设备模型中总线的发源地。在这里我们只是简单看一下这个bus_type 类型的
ide_bus_type。
struct bus_type ide_bus_type = {
.name = "ide",
.match = ide_bus_match,
.uevent = ide_uevent,
.probe = generic_ide_probe,
.remove = generic_ide_remove,
.shutdown = generic_ide_shutdown,
.dev_attrs = ide_dev_attrs,
.suspend = generic_ide_suspend,
.resume = generic_ide_resume,
};
既然有总线了,那肯定是为设备和驱动服务的,当有设备或者驱动注册的时候
就会引发总线的一系列动作,包括match、probe 的调用。这部分具体的代码我们等
到后面在分析…
380 行注册一个类,同时在/sys/class/下创建相应类目录
386 行ACPI 表示高级配置和电源管理接口,这里与我们无关。
388 行proc 文件系统相关内容,忽略…
392-397 出错处理。
Ide_init()这个函数比较简单,就是完成了一次总线注册。总线我们找到了,那
么设备和驱动是什么时候加载进来的呢?下面就到ide_generic.c 这个文件下面找找
答案了….还是那个module_init()。看看里面的代码:
87 static int __init ide_generic_init(void)
88 {
89 struct ide_hw hw, *hws[] = { &hw };
90 unsigned long io_addr;
91 int i, rc = 0, primary = 0, secondary = 0;
92
93 ide_generic_check_pci_legacy_iobases(&primary, &secondary);
94
95 if (!probe_mask) {
96 printk(KERN_INFODRV_NAME": please use\"probe_mask=0x3f\" "
97 "module parameter for probing all legacy ISA IDE ports\n");
98
99 if (primary == 0)
100 probe_mask |= 0x1;
101
102 if (secondary == 0)
103 probe_mask |= 0x2;
104 } else
105 printk(KERN_INFO DRV_NAME ": enforcing probing of I/O ports "
106 upon user request\n);
107
108 for (i = 0; i < ARRAY_SIZE(legacy_bases); i++) {
109 io_addr = legacy_bases[i];
110
111 if ((probe_mask & (1 << i)) && io_addr) {
112 if (!request_region(io_addr, 8, DRV_NAME)) {
113 printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX "
114 not free.\n,
115 DRV_NAME, io_addr, io_addr + 7);
116 rc = -EBUSY;
117 continue;
118 }
119
120 if (!request_region(io_addr + 0x206, 1, DRV_NAME)) {
121 printk(KERN_ERR "%s: I/O resource 0x%lX "
122 not free.\n,
123 DRV_NAME, io_addr + 0x206);
124 release_region(io_addr, 8);
125 rc = -EBUSY;
126 continue;
127 }
128
129 memset(&hw, 0, sizeof(hw));
130 ide_std_init_ports(&hw, io_addr, io_addr + 0x206);
131 #ifdef CONFIG_IA64
132 hw.irq = isa_irq_to_vector(legacy_irqs[i]);
133 #else
134 hw.irq = legacy_irqs[i];
135 #endif
136 rc = ide_host_add(&ide_generic_port_info, hws, 1, NULL);
137 if (rc) {
138 release_region(io_addr + 0x206, 1);
139 release_region(io_addr, 8);
140 }
141 }
142 }
143
144 return rc;
145 }
146
在这段代码的分析中关键要弄清一系列的数据结构,我们边走边说。进来就遇
到ide_hw,他描述的是接口的一些寄存器地址,中断号等信息。
175 struct ide_hw {
176 union {
177 struct ide_io_ports io_ports;
178 unsigned long io_ports_array[IDE_NR_PORTS];
179 };
180
181 int irq; /* our irq number */
182 struct device *dev, *parent;
183 unsigned long config;
184 };
185
176-179 行io_ports 与io_ports_array 以联合体的形式存在,ide_io_ports 实际上
与IDE 接口所定义的内部寄存器偏移相对应的,结合下面这张表再来看ide_io_ports
就显得比较清晰了。
IDE 寄存器地址分配表
58 struct ide_io_ports {
59 unsigned long data_addr;
60
61 union {
62 unsigned long error_addr; /* read: error */
63 unsigned long feature_addr; /* write: feature */
64 };
65
66 unsigned long nsect_addr;
67 unsigned long lbal_addr;
68 unsigned long lbam_addr;
69 unsigned long lbah_addr;
70
71 unsigned long device_addr;
72
73 union {
74 unsigned long status_addr; /* 聽read: status 聽*/
75 unsigned long command_addr; /* write: command */
76 };
77
78 unsigned long ctl_addr;
79
80 unsigned long irq_addr;
81 };
82
59-76 行与上面的表中的寄存器是一一对应的;
78 行记录了控制基础器的地址,是单独列出的;
80 行记录中断地址也成为单独的一项纪录在案;
回到ide_hw 结构上来,181-183 行就分别记录了接口的中断号,所对应的device 以
及配置值。
看完ide_hw 的内容,我们进入ide_generic_init 的分析:
93 行是定义了PCI 总线的,由pci 总线驱动的。我们这里和PCI 扯不上关系,
就直接略过了。
95 行probe_mask 这个是个模块参数对应的变量,关于内核参数和模块参数的
相关内容请参考《内核对子系统或者模块的初始化.pdf 》,这里我们只需知道
module_param(probe_mask, int, 0);说白了就是初始化probe_mask=0。既然我们加载
的时候没有指定新的模块参数就直接使用probe_mask=0 了,那么96-107 行就直接
是probe_mask=0x03;
108 行是个for 循环,执行次数和legacy_bases 数组元素的个数有关,legacy_bases
是在同一个文件中定义的数组里面指定了接口的基地址,基于ARM 体系我们来看
看他的定义:
static const u16 legacy_bases[] = { 0x1f0 };
static const int legacy_irqs[] = { IRQ_HARDDISK };
很显然这里的for 也就只能执行一次了。
112-127 行就是根据legacy_bases 指定的地址来申请地址空间,112 行申请的是
命令寄存器地址空间共8 个,120 行申请的是控制寄存器地址空间,只有1 个;
130 行调用了ide_std_init_ports 传递的参数是hw,命令和控制寄存器地址。一
看名字和参数就不难想到,他其实就是把这些个刚申请了空间的地址填写到ide_hw
所对应的项目中。为了保险还是看下源码(红色部分表明了函数的调用关系,方便阅
读):
[ide_generic_init]->[ide_std_init_ports]
186 static inline void ide_std_init_ports(struct ide_hw *hw,
187 unsigned long io_addr,
188 unsigned long ctl_addr)
189 {
190 unsigned int i;
191
192 for (i = 0; i <= 7; i++)
193 hw->io_ports_array[i] = io_addr++;
194
195 hw->io_ports.ctl_addr = ctl_addr;
196 }
197
193 行就是完成了命令寄存器的填充,看到他同时我们也就不难理解刚刚提到的
那个io_ports_array 和io_ports 为什么定义成联合体的原因了,就是为了赋值方便。
1285 struct ide_port_info {
1286 char *name;
1287
1288 int (*init_chipset)(struct pci_dev *);
1289
1290 void (*get_lock)(irq_handler_t, void *);
1291 void (*release_lock)(void);
1292
1293 void (*init_iops)(ide_hwif_t *);
1294 void (*init_hwif)(ide_hwif_t *);
1295 int (*init_dma)(ide_hwif_t *,
1296 const struct ide_port_info *);
1297
1298 const struct ide_tp_ops *tp_ops;
1299 const struct ide_port_ops *port_ops;
1300 const struct ide_dma_ops *dma_ops;
1301
1302 struct ide_pci_enablebit enablebits[2];
1303
1304 hwif_chipset_t chipset;
1305
1306 u16 max_sectors; /* if < than the default one */
1307
1308 u32 host_flags;
1309
1310 int irq_flags;
1311
1312 u8 pio_mask;
1313 u8 swdma_mask;
1314 u8 mwdma_mask;
1315 u8 udma_mask;
1316 };
1317
回到ide_generic_init…..
131-135 行我们只关心134 行,就是将中断号填入hw 中的irq 段。
136 行调用ide_host_add,这个函数中又将引入一系列的数据结构,后面我们将会各
个击破…进入函数之前还是先看看传递的实参都有哪些。
首先,ide_generic_port_info,这是个ide_port_info 结构:
这个结构比较简单,记录着端口的详细信息。包含了接口芯片类型,以及初始化的
一些方法。特别注意1298-1300 行的几个指针,这里暂时提一下留个印象后面碰到
了我们再详细说他。同时这里的ide_generic_port_info 比较简单,仅仅初始化了两项:
static const struct ide_port_info ide_generic_port_info = {
.host_flags = IDE_HFLAG_NO_DMA,
.chipset = ide_generic,
};
再看第二个参数是个指针的指针,hws 是个指针数组,初始化为 *hws[] =
{ &hw };第三个参数是要添加的port 数量,这里指定为1;第四个参数为NULL,
我们后面再谈….
好了,该是进军ide_host_add 的时候了。先贴源码;
[ide_generic_init]->[ide_host_add]
1475 int ide_host_add(const struct ide_port_info *d, struct ide_hw **hws,
1476 unsigned int n_ports, struct ide_host **hostp)
1477 {
1478 struct ide_host *host;
1479 int rc;
1480
1481 host = ide_host_alloc(d, hws, n_ports);
1482 if (host == NULL)
1483 return -ENOMEM;
1484
1485 rc = ide_host_register(host, d, hws);
1486 if (rc) {
1487 ide_host_free(host);
1488 return rc;
1489 }
1490
1491 if (hostp)
1492 *hostp = host;
1493
1494 return 0;
1495 }
1496
开篇引入一个新的数据结构ide_host,再看看函数名,也是和host 相关的。那
就先来看看ide_host 吧…
773 struct ide_host {
774 ide_hwif_t *ports[MAX_HOST_PORTS + 1];
775 unsigned int n_ports;
776 struct device *dev[2];
777
778 int (*init_chipset)(struct pci_dev *);
779
780 void (*get_lock)(irq_handler_t, void *);
781 void (*release_lock)(void);
782
783 irq_handler_t irq_handler;
784
785 unsigned long host_flags;
786
787 int irq_flags;
788
789 void *host_priv;
790 ide_hwif_t *cur_port; /* for hosts requiring serialization */
791
792 /* used for hosts requiring serialization */
793 volatile unsigned long host_busy;
794 };
795
回到int ide_host_add,1481 行调用ide_host_alloc(),从函数名和返回值来看,应
该是分配一个ide_host 结构。源码如下:
[ide_generic_init]->[ide_host_add]->[ ide_host_alloc]
1285 struct ide_host *ide_host_alloc(const struct ide_port_info *d,
1286 struct ide_hw **hws, unsigned int n_ports)
1287 {
1288 struct ide_host *host;
1289 struct device *dev = hws[0] ? hws[0]->dev : NULL;
1290 int node = dev ? dev_to_node(dev) : -1;
1291 int i;
1292
1293 host = kzalloc_node(sizeof(*host), GFP_KERNEL, node);
1294 if (host == NULL)
1295 return NULL;
1296
1297 for (i = 0; i < n_ports; i++) {
1298 ide_hwif_t *hwif;
1299 int idx;
1300
1301 if (hws[i] == NULL)
1302 continue;
1303
1304 hwif = kzalloc_node(sizeof(*hwif), GFP_KERNEL, node);
1305 if (hwif == NULL)
1306 continue;
1307
1308 if (ide_port_alloc_devices(hwif, node) < 0) {
1309 kfree(hwif);
1310 continue;
1311 }
1312
1313 idx = ide_find_port_slot(d);
1314 if (idx < 0) {
1315 printk(KERN_ERR "%s: no free slot for interface\n",
1316 d ? d->name : "ide");
1317 ide_port_free_devices(hwif);
1318 kfree(hwif);
1319 continue;
1320 }
1321
1322 ide_init_port_data(hwif, idx);
1323
1324 hwif->host = host;
1325
1326 host->ports[i] = hwif;
1327 host->n_ports++;
1328 }
1329
1330 if (host->n_ports == 0) {
1331 kfree(host);
1332 return NULL;
1333 }
1334
1335 host->dev[0] = dev;
1336
1337 if (d) {
1338 host->init_chipset = d->init_chipset;
1339 host->get_lock = d->get_lock;
1340 host->release_lock = d->release_lock;
1341 host->host_flags = d->host_flags;
1342 host->irq_flags = d->irq_flags;
1343 }
1344
1345 return host;
1346 }
1347
1289 行获取ide_hw 中指定的device 指针,前面的初始化中并未看到对该项的设置。
1290 行是和内存分配相关的,牵连到内存的非一致存储结构(NUMA)问题,这里
不详细分析,相关内容可以参考《linux 情景分析》中的内存管理相关内容。
1297 行又是个for 循环,有几个接口就循环几次,这里仅仅循环一次。
1308 行调用了ide_port_alloc_devices(),跟踪进入….
[ide_generic_init]->[ide_host_add]->[ ide_host_alloc]->[ ide_port_alloc_devices]
1253 static int ide_port_alloc_devices(ide_hwif_t *hwif, int node)
1254 {
1255 int i;
1256
1257 for (i = 0; i < MAX_DRIVES; i++) {
1258 ide_drive_t *drive;
1259
1260 drive = kzalloc_node(sizeof(*drive), GFP_KERNEL, node);
1261 if (drive == NULL)
1262 goto out_nomem;
1263
1264 /*
1265 * In order to keep things simple we have an id
1266 * block for all drives at all times. If the device
1267 * is pre ATA or refuses ATA/ATAPI identify we
1268 * will add faked data to this.
1269 *
1270 * Also note that 0 everywhere means "can't do X"
1271 */
1272 drive->id = kzalloc_node(SECTOR_SIZE, GFP_KERNEL, node);
1273 if (drive->id == NULL)
1274 goto out_nomem;
1275
1276 hwif->devices[i] = drive;
1277 }
1278 return 0;
1279
1280 out_nomem:
1281 ide_port_free_devices(hwif);
1282 return -ENOMEM;
1283 }
1284
1258 行又涉及到一个重要的数据结构ide_drive_t,我们知道前面我们定义了
ide_hwif_t 和hwif_s 都是与实际的ide 接口相对应,然而对于ide 接口的设备来所,
真正的驱动器是在设备内部,为了描述这个设备内部驱动器的属性比如:介质类型
(ide,CDROM 等)、传输位数(16bit、32bit 等)等就定义了一个ide_drive_s 的数
据结构,实际上也就是ide_drive_t。同时根据IDE SPCE 我们了解到每个IDE 接口
能支持两个ide 设备,分别对应主设备和从设备,这两个设备驱动器对应的信息都
要记录在接口中,那么在这里呢就成了MAX_DRIVES。有了这个背景后上面的一
段代码就不难理解了。另外,在阅读linux 内核的时候我们应该注意很多单词词义
上的区别,比如:drive 指示的是驱动器,是硬件设备;driver 指示的是软件驱动等,
理解这些对我们驱动程序的阅读时是很有帮助的。
1272 行这里还是重点提一下,毕竟代码的作者也注释了不少。我是这么理解的,就
是说每个硬盘有一些他自己的识别信息比如厂商号,磁头、柱面的大小等等,有的
硬盘有单独的扇区来存放,但有的没有。那么为了方便我们索性都弄个ID 字段伪
造一个,大小就是一个扇区的大小这里是512 字节。记录在ide_drive_t 里边。
回到ide_host_alloc()中来,继续向前走…
1313 行又遇到一个ide_find_port_slot(),源码如下:
[ide_generic_init]->[ide_host_add]->[ ide_host_alloc]->[ ide_find_port_slot]
1195 /**
1196 * ide_find_port_slot - find free port slot
1197 * @d: IDE port info
1198 *
1199 * Return the new port slot index or -ENOENT if we are out of free slots.
1200 */
1201
1202 static int ide_find_port_slot(const struct ide_port_info *d)
1203 {
1204 int idx = -ENOENT;
1205 u8bootable=(d&&(d->host_flags &
IDE_HFLAG_NON_BOOTABLE)) ? 0 : 1;
1206 u8 i = (d && (d->host_flags & IDE_HFLAG_QD_2ND_PORT)) ? 1 : 0;
1207
1208 /*
1209 * Claim an unassigned slot.
1210 *
1211 * Give preference to claiming other slots before claiming ide0/ide1,
1212 * just in case there's another interface yet-to-be-scanned
1213 * which uses ports 0x1f0/0x170 (the ide0/ide1 defaults).
1214 *
1215 * Unless there is a bootable card that does not use the standard
1216 * ports 0x1f0/0x170 (the ide0/ide1 defaults).
1217 */
1218 mutex_lock(&ide_cfg_mtx);
1219 if (bootable) {
1220 if ((ide_indexes | i) != (1 << MAX_HWIFS) - 1)
1221 idx = ffz(ide_indexes | i);
1222 } else {
1223 if ((ide_indexes | 3) != (1 << MAX_HWIFS) - 1)
1224 idx = ffz(ide_indexes | 3);
1225 else if ((ide_indexes & 3) != 3)
1226 idx = ffz(ide_indexes);
1227 }
1228 if (idx >= 0)
1229 ide_indexes |= (1 << idx);
1230 mutex_unlock(&ide_cfg_mtx);
1231
1232 return idx;
1233 }
1234
在linux 中一共支持9 个ide 接口即“ide0~ide9”,这些接口名称是按他注册的
先后次序来进行分配的,不同的接口对应到设备文件中的主设备号等信息是不一样
了。既然这样那么哪些接口是已经注册占用了的,是肯定需要记录下来的,那么就
产生了后面我们将要看到的ide_indexes 这个静态变量,她实际上就正好是个位图,
这样的处理方式在内核中已经屡见不鲜了。如果bit0 有ide0 占用了那么bit0 就被设
置为1。有了这个背景后我们再来看de_find_port_slot 就容易多了。
1205 行是个关于启动问题的,一般来讲用作底层引导的驱动盘我们一般是放在ide0、
ide1 的位置,这里要是指明说我是不能boot 的,那好bootable=0,后面再来修理你,
谁叫你这么坦白呢?内核都告诉我们有些时候我们还是不能太诚实….
1206 行和1205 行一样的伎俩, 不过这里的意思是/* set for the second port of
QD65xx */,好像是说第一个接口ide0 是不行的了。
1220 行要是前面人家说了ide0 不要,那么就用(ide_indexes | i)把bit0 屏蔽起来,
当然我们要说的这个就没这么变态了,我们的要求不高generic 就行,毕竟我们的名
字就叫ide_generic。这句话连贯起来说就是如果不是所有的接口都被占用了(每一位
都为1),那么就利用ffz 去找吧。
1221 行ffz()这个函数就是在传入的实参中查找第一个0,然后返回他的位偏移。比
如ffz(10110100B)的话,返回的就是2。这里实际上就是找个空位。
Linux 当编写驱动程序时,一般情况下不能使用C 标准库的函数。Linux 内核也提供
了与标准库函数功能相同的一些函数,但二者还是稍有差别。和这个函数有点像的
几个我一同在这里贴出来。
1222-1226 行前面已经把关键的讲到了这里就不在重复。
1229 行既然这个空位找了,那我们就不客气了地占住了。
回到ide_host_alloc()中来,继续向前走…
1322 行又遇到一个 ide_init_port_data(hwif, idx);,源码如下:
[ide_generic_init]->[ide_host_add]->[ ide_host_alloc]->[ ide_init_port_data]
1160 static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
1161 {
1162 /* fill in any non-zero initial values */
1163 hwif->index = index;
1164 hwif->major = ide_hwif_to_major[index];
1165
1166 hwif->name[0] = 'i';
1167 hwif->name[1] = 'd';
1168 hwif->name[2] = 'e';
1169 hwif->name[3] = '0' + index;
1170
1171 spin_lock_init(&hwif->lock);
1172
1173 init_timer(&hwif->timer);
1174 hwif->timer.function = &ide_timer_expiry;
1175 hwif->timer.data = (unsigned long)hwif;
1176
1177 init_completion(&hwif->gendev_rel_comp);
1178
1179 hwif->tp_ops = &default_tp_ops;
1180
1181 ide_port_init_devices_data(hwif);
1182 }
1183
1162-1170 行很容易理解,找到了ide 接口的序号,就用index 来初始化接口的相关
字段
1173-1175 行这是和定时器有关的设置,目的很明确。我们知道任何一个对IDE 接
口的操作,都会有中断来响应ide 操作的状态,但是当设备出错时也许就会有问题
了,所以这里设置一个定时器的回调函数和相应函数的入口参数,并对其进行初始

1179 行很久以前提到过这个字段,现在就对他初始化为默认值了,这个操作是所有
ide 特性的接口所共有的。如下所示:
248 const struct ide_tp_ops default_tp_ops = {
249 .exec_command = ide_exec_command,
250 .read_status = ide_read_status,
251 .read_altstatus = ide_read_altstatus,
252 .write_devctl = ide_write_devctl,
253
254 .dev_select = ide_dev_select,
255 .tf_load = ide_tf_load,
256 .tf_read = ide_tf_read,
257
258 .input_data = ide_input_data,
259 .output_data = ide_output_data,
260 };
具体的后面用到再说。
1181 行有调用了ide_port_init_devices_data,我们知道前面我们为接口的device 分配
了空间,还尚未初始化。这里就是要对这个device 中的每一项单独进行设置。具体
代码如下:
[ide_generic_init]->[ide_host_add]->[ ide_host_alloc]->[ ide_init_port_data]
->[ ide_port_init_devices_data]
1130 static void ide_port_init_devices_data(ide_hwif_t *hwif)
1131 {
1132 ide_drive_t *drive;
1133 int i;
1134
1135 ide_port_for_each_dev(i, drive, hwif) {
1136 u8 j = (hwif->index * MAX_DRIVES) + i;
1137 u16 *saved_id = drive->id;
1138
1139 memset(drive, 0, sizeof(*drive));
1140 memset(saved_id, 0, SECTOR_SIZE);
1141 drive->id = saved_id;
1142
1143 drive->media = ide_disk;
1144 drive->select = (i << 4) | ATA_DEVICE_OBS;
1145 drive->hwif = hwif;
1146 drive->ready_stat = ATA_DRDY;
1147 drive->bad_wstat = BAD_W_STAT;
1148 drive->special_flags = IDE_SFLAG_RECALIBRATE |
1149 IDE_SFLAG_SET_GEOMETRY;
1150 drive->name[0] = 'h';
1151 drive->name[1] = 'd';
1152 drive->name[2] = 'a' + j;
1153 drive->max_failures = IDE_DEFAULT_MAX_FAILURES;
1154
1155 INIT_LIST_HEAD(&drive->list);
1156 init_completion(&drive->gendev_rel_comp);
1157 }
1158 }
1135 行是个宏定义
#define ide_port_for_each_dev(i, dev, port) \
for ((i) = 0; ((dev) = (port)->devices[i]) || (i) < MAX_DRIVES;
1139-1141 行是对这些结构清零,特别是id 字段。后面的这些就很简单了…这里随
便提一下硬盘在linux 中使用“hda”、“ hdb”来描述的。hda 表示第一个接口上面
的硬盘设备。
从ide_port_init_devices_data 返回以后ide_init_port_data 也就安全结束了。但是
ide_host_alloc 的故事并没有完,回到故事中来….
1324-1327 行这又是linux 惯用的招式,目的就是你心中放着我,我心中存着你。
接口属于哪个host 总要记下吧!对host 来讲你是我所管辖的端口,你是谁我总要记
录在案。
1330 行要是分配host 的时候你都没有端口,那还浪费表情作甚。直接kfree 掉,然
后返回。
1335 行一路走过来好像一直没有关注接口下面的这个linux 设备模型中的device,
但是这里还是关联到了host->dev[0]。相信这个device 日后还是有机会出头的。
1337-1342 行搞了这么久host 还不知道自己是谁多没意思。那就用接口信息里面的
几个相关项来对他进行设置,好歹让人家知道自己的init_chipset,初始化接口芯片
组的方法…
1345 行如果一切正常没有争议,那分配的这个host 就返回了,ide_host_alloc 也就用
他的曲折一生换回了一个鲜活的host….
久违了的ide_host_add,我们终于回来了。
1485 行ide_host_register(host, d, hws);注册ide_host。不是别人正是我们刚刚alloc 的
那个host 精灵。跟踪源码:
[ide_generic_init]->[ide_host_add]->[ ide_host_register]
1373 int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
1374 struct ide_hw **hws)
1375 {
1376 ide_hwif_t *hwif, *mate = NULL;
1377 int i, j = 0;
1378
1379 ide_host_for_each_port(i, hwif, host) {
1380 if (hwif == NULL) {
1381 mate = NULL;
1382 continue;
1383 }
1384
1385 ide_init_port_hw(hwif, hws[i]);
1386 ide_port_apply_params(hwif);
1387
1388 if ((i & 1) && mate) {
1389 hwif->mate = mate;
1390 mate->mate = hwif;
1391 }
1392
1393 mate = (i & 1) ? NULL : hwif;
1394
1395 ide_init_port(hwif, i & 1, d);
1396 ide_port_cable_detect(hwif);
1397
1398 hwif->port_flags |= IDE_PFLAG_PROBING;
1399
1400 ide_port_init_devices(hwif);
1401 }
1402
1403 ide_host_for_each_port(i, hwif, host) {
1404 if (hwif == NULL)
1405 continue;
1406
1407 if (ide_probe_port(hwif) == 0)
1408 hwif->present = 1;
1409
1410 hwif->port_flags &= ~IDE_PFLAG_PROBING;
1411
1412 if ((hwif->host_flags & IDE_HFLAG_4DRIVES) == 0 ||
1413 hwif->mate == NULL || hwif->mate->present == 0) {
1414 if (ide_register_port(hwif)) {
1415 ide_disable_port(hwif);
1416 continue;
1417 }
1418 }
1419
1420 if (hwif->present)
1421 ide_port_tune_devices(hwif);
1422 }
1423
1424 ide_host_enable_irqs(host);
1425
1426 ide_host_for_each_port(i, hwif, host) {
1427 if (hwif == NULL)
1428 continue;
1429
1430 if (hwif_init(hwif) == 0) {
1431 printk(KERN_INFO "%s: failed to initialize IDE "
1432 "interface\n", hwif->name);
1433 device_unregister(&hwif->gendev);
1434 ide_disable_port(hwif);
1435 continue;
1436 }
1437
1438 if (hwif->present)
1439 if (ide_port_setup_devices(hwif) == 0) {
1440 hwif->present = 0;
1441 continue;
1442 }
1443
1444 j++;
1445
1446 ide_acpi_init_port(hwif);
1447
1448 if (hwif->present)
1449 ide_acpi_port_init_devices(hwif);
1450 }
1451
1452 ide_host_for_each_port(i, hwif, host) {
1453 if (hwif == NULL)
1454 continue;
1455
1456 if (hwif->present)
1457 hwif_register_devices(hwif);
1458 }
1459
1460 ide_host_for_each_port(i, hwif, host) {
1461 if (hwif == NULL)
1462 continue;
1463
1464 ide_sysfs_register_port(hwif);
1465 ide_proc_register_port(hwif);
1466
1467 if (hwif->present)
1468 ide_proc_port_register_devices(hwif);
1469 }
1470
1471 return j ? 0 : -1;
1472 }
1473
1379 行ide_host_for_each_port(i, hwif, host)还是个宏定义,看了名字就知道取host
结构中的port 来做实验。MAX_HOST_PORTS 最大也就4 个。
#define ide_host_for_each_port(i, port, host) \
for ((i) = 0; ((port) = (host)->ports[i]) || (i) < MAX_HOST_PORTS; (i)++)
1380-1383 行要是取出来的port 是个空的,那没得商量直接进入下一轮
1385 行 ide_init_port_hw(hwif, hws[i]);,不说hws 已经很多年来,依稀记得很久以前
还在ide_generic_init 中的时候,我们就对ide_hw 这个结构进行过设置,那时说的是
ide 寄存器的地址等等都放在里面。现在他又要上阵了,源码如下:
[ide_generic_init]->[ide_host_add]->[ ide_host_register]->[ide_init_port_hw]
1184 static void ide_init_port_hw(ide_hwif_t *hwif, struct ide_hw *hw)
1185 {
1186 memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports));
1187 hwif->irq = hw->irq;
1188 hwif->dev = hw->dev;
1189 hwif->gendev.parent = hw->parent ? hw->parent : hw->dev;
1190 hwif->config_data = hw->config;
1191 }
和ide_host_register 相比ide_init_port_hw 就单纯多了。其实,单纯并不是说她
没有脑子。Ide-hw 里面有的hwif_s 里面全有,那么为什么我们还大费心思的整出那
么多的数据结构不嫌累的慌。其实我想这里主要是为了下面移植的时候好方便接口,
Hwif 太过复杂,设置起来也容易出错。所有就干脆先构建一个ide_hw,对驱动开发
者来讲只需填充一下ide_hw 即可,对于hwif_s 我们大可不必知道,就能完成ide
驱动的移植了。
好了,闲话少叙仍旧回到ide_host_register 中来….
1386 行ide_port_apply_params(hwif);这是关于模块参数的,模块加载的时候可以指
定一定的参数,这个在《内核对子系统或者模块的初始化.pdf 》中已经有了说明。
这里呢我们还是不妨进去看看,还是比较简单的:
[ide_generic_init]->[ide_host_add]->[ ide_host_register]-> [ide_port_apply_params]
350 void ide_port_apply_params(ide_hwif_t *hwif)
351 {
352 ide_drive_t *drive;
353 int i;
354
355 if (ide_ignore_cable & (1 << hwif->index)) {
356 printk(KERN_INFO "ide: ignoring cable detection for %s\n",
357 hwif->name);
358 hwif->cbl = ATA_CBL_PATA40_SHORT;
359 }
360
361 ide_port_for_each_dev(i, drive, hwif)
362 ide_dev_apply_params(drive, i);
363 }
364
重点来关注一下362 行,
[ide_generic_init]->[ide_host_add]->[ide_host_register]->[ide_port_apply_params]->[ ide_dev_appl
y_params]
276 static void ide_dev_apply_params(ide_drive_t *drive, u8 unit)
277 {
278 int i = drive->hwif->index * MAX_DRIVES + unit;
279
280 if (ide_nodma & (1 << i)) {
281 printk(KERN_INFO "ide: disallowing DMA for %s\n", drive->name);
282 drive->dev_flags |= IDE_DFLAG_NODMA;
283 }
284 if (ide_noflush & (1 << i)) {
285 printk(KERN_INFO "ide: disabling flush requests for %s\n",
286 drive->name);
287 drive->dev_flags |= IDE_DFLAG_NOFLUSH;
288 }
289 if (ide_nohpa & (1 << i)) {
290 printk(KERN_INFO "ide: disabling Host Protected Area for %s\n",
291 drive->name);
292 drive->dev_flags |= IDE_DFLAG_NOHPA;
293 }
294 if (ide_noprobe & (1 << i)) {
295 printk(KERN_INFO "ide: skipping probe for %s\n", drive->name);
296 drive->dev_flags |= IDE_DFLAG_NOPROBE;
297 }
298 if (ide_nowerr & (1 << i)) {
299 printk(KERN_INFO "ide: ignoring the ATA_DF bit for %s\n",
300 drive->name);
301 drive->bad_wstat = BAD_R_STAT;
302 }
303 if (ide_cdroms & (1 << i)) {
304 printk(KERN_INFO "ide: forcing %s as a CD-ROM\n", drive->name);
305 drive->dev_flags |= IDE_DFLAG_PRESENT;
306 drive->media = ide_cdrom;
307 /* an ATAPI device ignores DRDY */
308 drive->ready_stat = 0;
309 }
310 if (ide_disks & (1 << i)) {
311 drive->cyl = drive->bios_cyl = ide_disks_chs[i].cyl;
312 drive->head = drive->bios_head = ide_disks_chs[i].head;
313 drive->sect = drive->bios_sect = ide_disks_chs[i].sect;
314
315 printk(KERN_INFO "ide: forcing %s as a disk (%d/%d/%d)\n",
316 drive->name,
317 drive->cyl, drive->head, drive->sect);
318
319 drive->dev_flags |= IDE_DFLAG_FORCED_GEOM |
IDE_DFLAG_PRESENT;
320 drive->media = ide_disk;
321 drive->ready_stat = ATA_DRDY;
322 }
323 }
这里就可以很明显的看到,就是利用命令行的一些参数来设置驱动器中的一些
参数。重新回来….
1388-1393 行出现了一个mate,英文意思是配对。在我们现在分析的这个情景当中
那么将出现mate=hwif 的情况,具体什么作用后面再次遇到了在分析,暂时记住它。
1395 行调用ide_init_port(hwif, i & 1, d),跟踪源码如下:
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [ide_init_port]
1051 static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
1052 const struct ide_port_info *d)
1053 {
1054 hwif->channel = port;
1055
1056 hwif->chipset = d->chipset ? d->chipset : ide_pci;
1057
1058 if (d->init_iops)
1059 d->init_iops(hwif);
1060
1061 /* ->host_flags may be set by ->init_iops (or even earlier...) */
1062 hwif->host_flags |= d->host_flags;
1063 hwif->pio_mask = d->pio_mask;
1064
1065 if (d->tp_ops)
1066 hwif->tp_ops = d->tp_ops;
1067
1068 /* ->set_pio_mode for DTC2278 is currently limited to port 0 */
1069 if ((hwif->host_flags & IDE_HFLAG_DTC2278) == 0 || hwif->channel ==
0)
1070 hwif->port_ops = d->port_ops;
1071
1072 hwif->swdma_mask = d->swdma_mask;
1073 hwif->mwdma_mask = d->mwdma_mask;
1074 hwif->ultra_mask = d->udma_mask;
1075
1076 if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) {
1077 int rc;
1078
1079 hwif->dma_ops = d->dma_ops;
1080
1081 if (d->init_dma)
1082 rc = d->init_dma(hwif, d);
1083 else
1084 rc = ide_hwif_setup_dma(hwif, d);
1085
1086 if (rc < 0) {
1087 printk(KERN_INFO "%s: DMA disabled\n", hwif->name);
1088
1089 hwif->dma_ops = NULL;
1090 hwif->dma_base = 0;
1091 hwif->swdma_mask = 0;
1092 hwif->mwdma_mask = 0;
1093 hwif->ultra_mask = 0;
1094 }
1095 }
1096
1097 if ((d->host_flags & IDE_HFLAG_SERIALIZE) ||
1098 ((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) &&
hwif->dma_base))
1099 hwif->host->host_flags |= IDE_HFLAG_SERIALIZE;
1100
1101 if (d->max_sectors)
1102 hwif->rqsize = d->max_sectors;
1103 else {
1104 if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
1105 (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
1106 hwif->rqsize = 256;
1107 else
1108 hwif->rqsize = 65536;
1109 }
1110
1111 /* call chipset specific routine for each enabled port */
1112 if (d->init_hwif)
1113 d->init_hwif(hwif);
1114 }
1115
1054 行设置接口的通道号,只能出现0 和1
1056 行设置这个接口所用的芯片,这里是ide_generic。如果没有设置的话就默认为
pci
1058-1075 行比较简单,其中1066 行的设置之前我们已经对其赋上了默认值。
1076 判断是否支持dma,要是支持肯定是要设置相应的hwif->dma_ops,然后调用
init_dma 方法初始化。后面的内容相对比较简单,略过。
回到ide_host_register 函数中,继续往下看…
1396 行 调用ide_port_cable_detect(hwif);代码如下:
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [ide_port_cable_detect]
1116 static void ide_port_cable_detect(ide_hwif_t *hwif)
1117 {
1118 const struct ide_port_ops *port_ops = hwif->port_ops;
1119
1120 if (port_ops && port_ops->cable_detect && (hwif->ultra_mask & 0x78)) {
1121 if (hwif->cbl != ATA_CBL_PATA40_SHORT)
1122 hwif->cbl = port_ops->cable_detect(hwif);
1123 }
1124 }
1118 行在这之前我们尚未对port_ops 设置,所以与我们无关。这里也就无法调用
cable_detect。
接着ide_host_register….
1400 行有调用了ide_port_init_devices(ide_hwif_t *hwif),老规矩进去瞅瞅…
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [ide_port_init_devices]
1028 static void ide_port_init_devices(ide_hwif_t *hwif)
1029 {
1030 const struct ide_port_ops *port_ops = hwif->port_ops;
1031 ide_drive_t *drive;
1032 int i;
1033
1034 ide_port_for_each_dev(i, drive, hwif) {
1035 drive->dn = i + hwif->channel * 2;
1036
1037 if (hwif->host_flags & IDE_HFLAG_IO_32BIT)
1038 drive->io_32bit = 1;
1039 if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
1040 drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
1041 if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS)
1042 drive->dev_flags |= IDE_DFLAG_UNMASK;
1043 if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
1044 drive->dev_flags |= IDE_DFLAG_NO_UNMASK;
1045
1046 if (port_ops && port_ops->init_dev)
1047 port_ops->init_dev(drive);
1048 }
1049 }
又是和port 中的device 有关….
1034 行还是老规矩,遍历hwif_s 结构中的device 结构。
1035 行看注释好像是说扩展用的
1037-1044 行根据host_flags 对ide_drive_t 的相关的字段进行设置。这信息都来自
ide_port_info 这个数据结构。
1046-1047 行前面已经谈到了。
回到ide_host_register,1403 行又来了新的一轮ide_host_for_each_port(),
要是hwif 不为空,就可以调用ide_probe_port(hwif)了。
1407 行 ide_probe_port 的代码如下所示:
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [ide_probe_port]
678 static int ide_probe_port(ide_hwif_t *hwif)
679 {
680 ide_drive_t *drive;
681 unsigned int irqd;
682 int i, rc = -ENODEV;
683
684 BUG_ON(hwif->present);
685
686 if ((hwif->devices[0]->dev_flags & IDE_DFLAG_NOPROBE) &&
687 (hwif->devices[1]->dev_flags & IDE_DFLAG_NOPROBE))
688 return -EACCES;
689
690 /*
691 * We must always disable IRQ, as probe_for_drive will assert IRQ, but
692 * we'll install our IRQ driver much later...
693 */
694 irqd = hwif->irq;
695 if (irqd)
696 disable_irq(hwif->irq);
697
698 rc = ide_port_wait_ready(hwif);
699 if (rc == -ENODEV) {
700 printk(KERN_INFO "%s: no devices on the port\n", hwif->name);
701 goto out;
702 } else if (rc == -EBUSY)
703 printk(KERN_ERR "%s: not ready before the probe\n", hwif->name);
704 else
705 rc = -ENODEV;
706
707 /*
708 * Second drive should only exist if first drive was found,
709 * but a lot of cdrom drives are configured as single slaves.
710 */
711 ide_port_for_each_dev(i, drive, hwif) {
712 (void) probe_for_drive(drive);
713 if (drive->dev_flags & IDE_DFLAG_PRESENT)
714 rc = 0;
715 }
716 out:
717 /*
718 * Use cached IRQ number. It might be (and is...) changed by probe
719 * code above
720 */
721 if (irqd)
722 enable_irq(irqd);
723
724 return rc;
725 }
726
686-688 行如果定义了IDE_DFLAG_NOPROBE 当然这个过程就免了
694-696 行关于中断的,这里暂时不使能中断,因为probe 的过程中可能引起中断置
位。
698 行调用了ide_port_wait_ready(hwif);,跟踪源码:
[ide_generic_init]->[ide_host_add]->[ide_host_register]->
[ide_probe_port]->[ ide_port_wait_ready]
571 /**
572 * ide_port_wait_ready - wait for port to become ready
573 * @hwif: IDE port
574 *
575 * This is needed on some PPCs and a bunch of BIOS-less embedded
576 * platforms. Typical cases are:
577 *
578 * - The firmware hard reset the disk before booting the kernel,
579 * the drive is still doing it's poweron-reset sequence, that
580 * can take up to 30 seconds.
581 *
582 * #NAME?
583 * still in POST state (same as above actually).
584 *
585 * #NAME?
586 * their reset sequence even when they are non-selected slave
587 * devices, thus preventing discovery of the main HD.
588 *
589 * Doing this wait-for-non-busy should not harm any existing
590 * configuration and fix some issues like the above.
591 *
592 * BenH.
593 *
594 * Returns 0 on success, error code (< 0) otherwise.
595 */
596
597 static int ide_port_wait_ready(ide_hwif_t *hwif)
598 {
599 const struct ide_tp_ops *tp_ops = hwif->tp_ops;
600 ide_drive_t *drive;
601 int i, rc;
602
603 printk(KERN_DEBUG "Probing IDE interface %s...\n", hwif->name);
604
605 /* Let HW settle down a bit from whatever init state we
606 * come from */
607 mdelay(2);
608
609 /* Wait for BSY bit to go away, spec timeout is 30 seconds,
610 * I know of at least one disk who takes 31 seconds, I use 35
611 * here to be safe
612 */
613 rc = ide_wait_not_busy(hwif, 35000);
614 if (rc)
615 return rc;
616
617 /* Now make sure both master & slave are ready */
618 ide_port_for_each_dev(i, drive, hwif) {
619 /* Ignore disks that we will not probe for later. */
620 if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 ||
621 (drive->dev_flags & IDE_DFLAG_PRESENT)) {
622 tp_ops->dev_select(drive);
623 tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
624 mdelay(2);
625 rc = ide_wait_not_busy(hwif, 35000);
626 if (rc)
627 goto out;
628 } else
629 printk(KERN_DEBUG "%s: ide_wait_not_busy() skipped\n",
630 drive->name);
631 }
632 out:
633 /* Exit function with master reselected (let's be sane) */
634 if (i)
635 tp_ops->dev_select(hwif->devices[0]);
636
637 return rc;
638 }
639
根据前面的一段注释我们可以知道,针对像power pc 或者一些没有底层bios 引
导的系统,可能上点以后设备可能在不停地自动复位,这个过程长达30S 钟。所有
这里就需要首先查询设备的忙状态。
613 行这里设置了一个35S 的超时等待。不妨进去看一下源码:
[ide_generic_init]->[ide_host_add]->[ide_host_register]->
[ide_probe_port]->[ ide_port_wait_ready]->[ ide_wait_not_busy]
503 /*
504 * ide_wait_not_busy() waits for the currently selected device on the hwif
505 * to report a non-busy status, see comments in ide_probe_port().
506 */
507 int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout)
508 {
509 u8 stat = 0;
510
511 while (timeout--) {
512 /*
513 * Turn this into a schedule() sleep once I'm sure
514 * about locking issues (2.5 work ?).
515 */
516 mdelay(1);
517 stat = hwif->tp_ops->read_status(hwif);
518 if ((stat & ATA_BUSY) == 0)
519 return 0;
520 /*
521 * Assume a value of 0xff means nothing is connected to
522 * the interface and it doesn't implement the pull-down
523 * resistor on D7.
524 */
525 if (stat == 0xff)
526 return -ENODEV;
527 touch_softlockup_watchdog();
528 touch_nmi_watchdog();
529 }
530 return -EBUSY;
531 }
这里517 行有个对tp_ops 的调用,这个结构我们之前已经将其设置为
default_tp_ops。这里只要知道他读回的是设备的状态值,后面在讲到硬盘操作的时
候再来一起看看。
525 行这里注释也说得很清楚,如果读到的数据是0xff 可能设备就没连接上,直接
就返回了。
回到ide_port_wait_ready 中,618-631 行就是为了确保主从设备都准备好了。这
里就是选择驱动器,然后写控制命令,然后在查询忙状态,以确保所有设备都进入
了准备状态。
返回到ide_probe_port,如果一切顺利的话,就会到711 行。然后会调用712 行的(void)
probe_for_drive(drive);源码如下:
[ide_generic_init]->[ide_host_add]->[ide_host_register]->
[ide_probe_port]->[ probe_for_drives]
461 /**
462 * probe_for_drives - upper level drive probe
463 * @drive: drive to probe for
464 *
465 * probe_for_drive() tests for existence of a given drive using do_probe()
466 * and presents things to the user as needed.
467 *
468 * Returns: 0 no device was found
469 * 1 device was found
470 * (note: IDE_DFLAG_PRESENT might still be not set)
471 */
472
473 static u8 probe_for_drive(ide_drive_t *drive)
474 {
475 char *m;
476 int rc;
477 u8 cmd;
478
479 drive->dev_flags &= ~IDE_DFLAG_ID_READ;
480
481 m = (char *)&drive->id[ATA_ID_PROD];
482 strcpy(m, "UNKNOWN");
483
484 /* skip probing? */
485 if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0) {
486 /* if !(success||timed-out) */
487 cmd = ATA_CMD_ID_ATA;
488 rc = do_probe(drive, cmd);
489 if (rc >= 2) {
490 /* look for ATAPI device */
491 cmd = ATA_CMD_ID_ATAPI;
492 rc = do_probe(drive, cmd);
493 }
494
495 if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
496 return 0;
497
498 /* identification failed? */
499 if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
500 if (drive->media == ide_disk) {
501 printk(KERN_INFO "%s: non-IDE drive, CHS=%d/%d/%d\n",
502 drive->name, drive->cyl,
503 drive->head, drive->sect);
504 } else if (drive->media == ide_cdrom) {
505 printk(KERN_INFO "%s: ATAPI cdrom (?)\n", drive->name);
506 } else {
507 /* nuke it */
508 printk(KERN_WARNING "%s: Unknown device on bus refused
identification. Ignoring.\n", drive->name);
509 drive->dev_flags &= ~IDE_DFLAG_PRESENT;
510 }
511 } else {
512 if (cmd == ATA_CMD_ID_ATAPI)
513 ide_classify_atapi_dev(drive);
514 else
515 ide_classify_ata_dev(drive);
516 }
517 }
518
519 if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
520 return 0;
521
522 /* The drive wasn't being helpful. Add generic info only */
523 if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
524 generic_id(drive);
525 return 1;
526 }
527
528 if (drive->media == ide_disk) {
529 ide_disk_init_chs(drive);
530 ide_disk_init_mult_count(drive);
531 }
532
533 return 1;
534 }
481 行关于那个id,前面已经说过了,这里的ATA_ID_PROD 和数据存放在物理硬
盘中的扇区偏移有关,相当于产品名这里初始化为“UNKNOW”
485-493 就是实际的枚举过程了,相应的会调用do_probe 函数,我们一点点来看。
首先,487 行指定命令为ATA_CMD_ID_ATA;默认的ATA 接口,488 行就调用了
do_probe。这里是整个枚举的关键地方,我们跟踪到源码里面来详细分析一下:
[ide_generic_init]->[ide_host_add]->[ide_host_register]->
[ide_probe_port]->[ probe_for_drives]->[do_probe]
359 /**
360 * do_probe - probe an IDE device
361 * @drive: drive to probe
362 * @cmd: command to use
363 *
364 * do_probe() has the difficult job of finding a drive if it exists,
365 * without getting hung up if it doesn't exist, without trampling on
366 * ethernet cards, and without leaving any IRQs dangling to haunt us later.
367 *
368 * If a drive is "known" to exist (from CMOS or kernel parameters),
369 * but does not respond right away, the probe will "hang in there"
370 * for the maximum wait time (about 30 seconds), otherwise it will
371 * exit much more quickly.
372 *
373 * Returns: 0 device was identified
374 * 1 device timed-out (no response to identify request)
375 * 2 device aborted the command (refused to identify itself)
376 * 3 bad status from device (possible for ATAPI drives)
377 * 4 probe was not attempted because failure was obvious
378 */
379
380 static int do_probe (ide_drive_t *drive, u8 cmd)
381 {
382 ide_hwif_t *hwif = drive->hwif;
383 const struct ide_tp_ops *tp_ops = hwif->tp_ops;
384 u16 *id = drive->id;
385 int rc;
386 u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat;
387
388 /* avoid waiting for inappropriate probes */
389 if (present && drive->media != ide_disk && cmd == ATA_CMD_ID_ATA)
390 return 4;
391
392 #ifdef DEBUG
393 printk(KERN_INFO "probing for %s: present=%d, media=%d,
probetype=%s\n",
394 drive->name, present, drive->media,
395 (cmd == ATA_CMD_ID_ATA) ? "ATA" : "ATAPI");
396 #endif
397
398 /* needed for some systems
399 * (e.g. crw9624 as drive0 with disk as slave)
400 */
401 msleep(50);
402 tp_ops->dev_select(drive);
403 msleep(50);
404
405 if (ide_read_device(drive) != drive->select && present == 0) {
406 if (drive->dn & 1) {
407 /* exit with drive0 selected */
408 tp_ops->dev_select(hwif->devices[0]);
409 /* allow ATA_BUSY to assert & clear */
410 msleep(50);
411 }
412 /* no i/f present: mmm.. this should be a 4 -ml */
413 return 3;
414 }
415
416 stat = tp_ops->read_status(hwif);
417
418 if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
419 present || cmd == ATA_CMD_ID_ATAPI) {
420 rc = ide_dev_read_id(drive, cmd, id, 0);
421 if (rc)
422 /* failed: try again */
423 rc = ide_dev_read_id(drive, cmd, id, 0);
424
425 stat = tp_ops->read_status(hwif);
426
427 if (stat == (ATA_BUSY | ATA_DRDY))
428 return 4;
429
430 if (rc == 1 && cmd == ATA_CMD_ID_ATAPI) {
431 printk(KERN_ERR "%s: no response (status = 0x%02x), "
432 resetting drive\n, drive->name, stat);
433 msleep(50);
434 tp_ops->dev_select(drive);
435 msleep(50);
436 tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
437 (void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0);
438 rc = ide_dev_read_id(drive, cmd, id, 0);
439 }
440
441 /* ensure drive IRQ is clear */
442 stat = tp_ops->read_status(hwif);
443
444 if (rc == 1)
445 printk(KERN_ERR "%s: no response (status = 0x%02x)\n",
446 drive->name, stat);
447 } else {
448 /* not present or maybe ATAPI */
449 rc = 3;
450 }
451 if (drive->dn & 1) {
452 /* exit with drive0 selected */
453 tp_ops->dev_select(hwif->devices[0]);
454 msleep(50);
455 /* ensure drive irq is clear */
456 (void)tp_ops->read_status(hwif);
457 }
458 return rc;
459 }
460
382-400 行做了一些有效性的判断,
401-403 行选择驱动器,延时主要是为了满足部分设备时序上的要求。那么
tp_ops->dev_select(drive);对应的函数应该还是之前的default_tp_ops 里面的方法。
该数据结构定义在ide-io-std.c 文件中,这里再次列出来:
const struct ide_tp_ops default_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
.write_devctl = ide_write_devctl,
.dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
.input_data = ide_input_data,
.output_data = ide_output_data,
};
前面我们曾遇到过read_status 和dev_select 我们均没有说,这里就来分析一下他
们的实现。
先来看一下dev_select 方法对应的函数为ide_dev_select。代码如下:
[ide-io-std.c]
76 void ide_dev_select(ide_drive_t *drive)
77 {
78 ide_hwif_t *hwif = drive->hwif;
79 u8 select = drive->select | ATA_DEVICE_OBS;
80
81 if (hwif->host_flags & IDE_HFLAG_MMIO)
82 writeb(select, (void __iomem *)hwif->io_ports.device_addr);
83 else
84 outb(select, hwif->io_ports.device_addr);
85 }
在分析上面这个函数之前我们先来看看选择硬盘驱动器这个驱动的硬件操作过
程。实际上就是将一个数据写入到驱动/磁头寄存器所对应的地址中,数据每一位的
具体含义如下:
驱动/磁头选择寄存器定义
有了这个背景以后我们再来看ide_dev_select 的代码…..
78 行在ide_port_init_devices_data()的时候我们就已经对drive->hwif 这个字段赋
值了,现在只是取出来用。
79 行,从后面我们不难看到select 是将要写入驱动/磁头选择寄存器的数据,按
上表的格式的话D7 和D5 应该恒为1。在这里ATA_DEVICE_OBS 定义为:
ATA_DEVICE_OBS = (1 << 7) | (1 << 5), /* obs bits in dev reg */
drive->select 的内容自然就决定了其他位的情况。而对drive->select 的赋值仍然是在
ide_port_init_devices_data()中进行了的。
1144 drive->select = (i << 4) | ATA_DEVICE_OBS;
第四位正好是驱动器的选择位。
81 行有一个判断是IO 内存还是IO 端口,IDE_HFLAG_MMIO 表示的是IO 内
存方式。这些是和cpu 体系结构相关的,我们知道在X86 平台下面我们对IO 端口
和内存的访问是两组不同的指令,但是在S3C2440 中我们却是一样对待的,所以就
有了两种不同的访问方式,关于IO 内存和IO 端口的相关内容请参考《IO 端口和IO
内存.doc》。其实前面我们注意到,在前面分配端口的时候只使用的是request_region
申请的IO 资源,并未进行内存映射,同时IDE_HFLAG_MMIO 在ide_port_info 中
也并未设置,所有这里采用了IO 端口的方式进行访问。如果移植到S3C2440 等平
台上的话就需request_mem_region()申请IO 内存资源,ioremap()映射到虚拟内存,
然后利用writeb 进行访问,也就是设置IDE_HFLAG_MMIO。
82 行就是具体的硬件操作了,写入的地址hwif->io_ports.device_addr 也是我们
之前就设置好了的,顺便说一句如果内存映射writeb 那么对应的应该是虚拟地址,
如果是IO 端口那么outb 对应的是实端口地址。
既然前面已经提到了read_status 方法,就一起来看看他的所对应的实现
ide_read_status,源码如下:
[ide-io-std.c]
49 u8 ide_read_status(ide_hwif_t *hwif)
50 {
51 if (hwif->host_flags & IDE_HFLAG_MMIO)
52 return readb((void __iomem *)hwif->io_ports.status_addr);
53 else
54 return inb(hwif->io_ports.status_addr);
55 }
这个函数就比较简单了,这里状态寄存器和命令寄存器是共用的一个地址。读操作
时是状态信息,写操作时写入的是操作命令。对应的数据格式如下:
Ø 状态寄存器数据格式:
Ø 命令寄存器指令:
其他的一些命令我们以后遇到了再说。下面还是回到do_probe()中来…..
405 行调用ide_read_device,跟进代码如下:
[ide_generic_init]->[ide_host_add]->[ide_host_register]->
[ide_probe_port]->[ probe_for_drives]->[do_probe]->[ide_read_device]
350 static u8 ide_read_device(ide_drive_t *drive)
351 {
352 struct ide_taskfile tf;
353
354 drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_DEVICE);
355
356 return tf.device;
357 }
354 行调用了tp_ops->tf_read 方法,下面还是看一下他的源码:
[ide-io-std.c]
115 void ide_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid)
116 {
117 ide_hwif_t *hwif = drive->hwif;
118 struct ide_io_ports *io_ports = &hwif->io_ports;
119 u8 (*tf_inb)(unsigned long port);
120 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
121
122 if (mmio)
123 tf_inb = ide_mm_inb;
124 else
125 tf_inb = ide_inb;
126
127 if (valid & IDE_VALID_ERROR)
128 tf->error = tf_inb(io_ports->feature_addr);
129 if (valid & IDE_VALID_NSECT)
130 tf->nsect = tf_inb(io_ports->nsect_addr);
131 if (valid & IDE_VALID_LBAL)
132 tf->lbal = tf_inb(io_ports->lbal_addr);
133 if (valid & IDE_VALID_LBAM)
134 tf->lbam = tf_inb(io_ports->lbam_addr);
135 if (valid & IDE_VALID_LBAH)
136 tf->lbah = tf_inb(io_ports->lbah_addr);
137 if (valid & IDE_VALID_DEVICE)
138 tf->device = tf_inb(io_ports->device_addr);
139 }
120-125 行定义一个tf_inb,我们关注tf_inb = ide_mm_inb;这个内存IO 的操作。
ide_mm_inb 实际上就是封装了一个readb 操作,代码如下:
static u8 ide_mm_inb(unsigned long port)
{
return (u8) readb((void __iomem *) port);
}
127-138 根据传入的不同的valid 决定读哪个寄存器, 这里传入的是
IDE_VALID_DEVICE 那么我们只关注138 行。
138 行这里读的是驱动器/磁头寄存器,它对应的数据格式我们之前已经说过,这里
不再重复。
这里出现了一个ide_taskfile 结构,我们不妨来看一下,他与IDE 内部寄存器是一一
对应的。源代码如下:
271 struct ide_taskfile {
272 u8 data; /* 0: data byte (for TASKFILE ioctl) */
273 union { /* 1: */
274 u8 error; /* read: error */
275 u8 feature; /* write: feature */
276 };
277 u8 nsect; /* 2: number of sectors */
278 u8 lbal; /* 3: LBA low */
279 u8 lbam; /* 4: LBA mid */
280 u8 lbah; /* 5: LBA high */
281 u8 device; /* 6: device select */
282 union { /* 7: */
283 u8 status; /* read: status */
284 u8 command; /* write: command */
285 };
286 };
好了ide_tf_read 返回后,ide_read_device 也就跟着返回了,实际操作就是读当前驱
动器/磁头寄存器中的数据。回到do_probe 函数….
还是看405 行,读出来的内容与写入的相比较,如果对不上就执行406-413 行,与
我们关系不大,跳过…..
416 行读状态寄存器,这个我们上面已经说过来不再重复….
418 行是个宏定义
#define OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good))
这个宏看上去有点好玩,就是说只有好的,没有坏的就认为是好….
对应到我们程序的上下文就是“现在的状态是准备好,而且不忙,那么就返回1”
420 行调用ide_dev_read_id(drive, cmd, id, 0),跟踪一下源码如下:
[ide_generic_init]->[ide_host_add]->[ide_host_register]->
[ide_probe_port]->[ probe_for_drives]->[do_probe]->[ ide_dev_read_id]
236 /**
237 * ide_dev_read_id - send ATA/ATAPI IDENTIFY command
238 * @drive: drive to identify
239 * @cmd: command to use
240 * @id: buffer for IDENTIFY data
241 * @irq_ctx: flag set when called from the IRQ context
242 *
243 * Sends an ATA(PI) IDENTIFY request to a drive and waits for a response.
244 *
245 * Returns: 0 device was identified
246 * 1 device timed-out (no response to identify request)
247 * 2 device aborted the command (refused to identify itself)
248 */
249
250 int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id, int irq_ctx)
251 {
252 ide_hwif_t *hwif = drive->hwif;
253 struct ide_io_ports *io_ports = &hwif->io_ports;
254 const struct ide_tp_ops *tp_ops = hwif->tp_ops;
255 int use_altstatus = 0, rc;
256 unsigned long timeout;
257 u8 s = 0, a = 0;
258
259 /*
260 * Disable device IRQ. Otherwise we'll get spurious interrupts
261 * during the identify phase that the IRQ handler isn't expecting.
262 */
263 if (io_ports->ctl_addr)
264 tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
265
266 /* take a deep breath */
267 if (irq_ctx)
268 mdelay(50);
269 else
270 msleep(50);
271
272 if (io_ports->ctl_addr &&
273 (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) {
274 a = tp_ops->read_altstatus(hwif);
275 s = tp_ops->read_status(hwif);
276 if ((a ^ s) & ~ATA_IDX)
277 /* ancient Seagate drives, broken interfaces */
278 printk(KERN_INFO "%s: probing with STATUS(0x%02x) "
279 "instead of ALTSTATUS(0x%02x)\n",
280 drive->name, s, a);
281 else
282 /* use non-intrusive polling */
283 use_altstatus = 1;
284 }
285
286 /* set features register for atapi
287 * identify command to be sure of reply
288 */
289 if (cmd == ATA_CMD_ID_ATAPI) {
290 struct ide_taskfile tf;
291
292 memset(&tf, 0, sizeof(tf));
293 /* disable DMA & overlap */
294 tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE);
295 }
296
297 /* ask drive for ID */
298 tp_ops->exec_command(hwif, cmd);
299
300 timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE :
WAIT_PIDENTIFY) / 2;
301
302 /* wait for IRQ and ATA_DRQ */
303 if (irq_ctx) {
304 rc = __ide_wait_stat(drive, ATA_DRQ, BAD_R_STAT, timeout, &s);
305 if (rc)
306 return 1;
307 } else {
308 rc = ide_busy_sleep(drive, timeout, use_altstatus);
309 if (rc)
310 return 1;
311
312 msleep(50);
313 s = tp_ops->read_status(hwif);
314 }
315
316 if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
317 /* drive returned ID */
318 do_identify(drive, cmd, id);
319 /* drive responded with ID */
320 rc = 0;
321 /* clear drive IRQ */
322 (void)tp_ops->read_status(hwif);
323 } else {
324 /* drive refused ID */
325 rc = 2;
326 }
327 return rc;
328 }
既然函数有详细的注释我们就先来看看注释好了,实际上他就是发送一个
Identify Drive 命令控制字为0xEC。传输回来512 个字节的块数据,在这里就存放
在我们之前所说的drive->id 字段中。另外,数据的具体组织格式在IDE SPCE 有规
定,这里我们参考ATA5 的标准进行分析。具体的内容比较多但为了方便还是贴出
来,见下表:




注释的最后提到了返回值:
0:表示成功识别
1:表示识别超时
2:表示驱动器不允许该命令
有了这些背景之后我们再来看看源码:
263-264 行道理很简单这里我们在识别的过程中不使用中断,所有调用写控制寄存
器命令来关闭中断,我们还是来看一下write_devctl 对应的操作,代码如下:
void ide_write_devctl(ide_hwif_t *hwif, u8 ctl)
{
if (hwif->host_flags & IDE_HFLAG_MMIO)
writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
else
outb(ctl, hwif->io_ports.ctl_addr);
}
代码比较简单,这里我们主要来看看控制寄存器的地址分配和控制命令的数据格
式。
第二组寄存器的地址分配表
将该寄存器的SRST 位设置为1,可以使硬盘驱动器处于复位状态。IEN 表示
是否允许中断,其中0 为允许。分别来看一下ATA_NIEN、TA_DEVCTL_OBS 这两
个的定义就比较清楚了。
ATA_NIEN = (1 << 1), /* disable-irq flag */
ATA_DEVCTL_OBS = (1 << 3), /* obsolete bit in devctl reg */
267-270 行始终都是延时50mS,不知为何这样处理…
274 行调用ad_altstatus 所对应的代码如下:
58 u8 ide_read_altstatus(ide_hwif_t *hwif)
59 {
60 if (hwif->host_flags & IDE_HFLAG_MMIO)
61 return readb((void __iomem *)hwif->io_ports.ctl_addr);
62 else
63 return inb(hwif->io_ports.ctl_addr);
64 }
这里读的是控制寄存器地址,实际上从上面那张第二组寄存器的地址分配表
中我们不难得到实际读到的应该是交换状态寄存器(只读寄存器)的值。
272-248 行如果这两个寄存器读的数据不一致的话就以STATUS 寄存器中的值为
准,不再读取交换状态寄存器的值。
289-295 行ATAPI 接口的和我们无关,略过….
298 行就是真正执行命令了,调用exec_command 实际上就是向命令寄存器写数据。
300 行设置一个超时的时间,对于ATA 接口定义为30s。
303-314 行就是等待设备准备好了,这里根据中断上下文的不同,共提供了两种方
法,这里我们选择308 行。即调用ide_busy_sleep,下面看下源码:
[ide_generic_init]->[ide_host_add]->[ide_host_register]->
[ide_probe_port]->[ probe_for_drives]->[do_probe]->[ ide_dev_read_id]->[ ide_busy_sleep]
330 int ide_busy_sleep(ide_drive_t *drive, unsigned long timeout, int altstatus)
331 {
332 ide_hwif_t *hwif = drive->hwif;
333 u8 stat;
334
335 timeout += jiffies;
336
337 do {
338 msleep(50); /* give drive a breather */
339 stat = altstatus ? hwif->tp_ops->read_altstatus(hwif)
340 : hwif->tp_ops->read_status(hwif);
341 if ((stat & ATA_BUSY) == 0)
342 return 0;
343 } while (time_before(jiffies, timeout));
344
345 printk(KERN_ERR "%s: timeout in %s\n", drive->name, __func__);
346
347 return 1; /* drive timed-out */
348 }
这段代码比较简单就不在详细述说,实际上就是每隔50ms 查询一次设备状态,
要是状态不为忙就返回0,否则30s 过去了一直为忙状态。那对不起您超时了,直
接返回1。
312-313 行很明显就是稍微延时一下,以满足设备操作时序上的要求,毕竟不是所
有的设备都能做到反应这么迅速。前面已经不忙了,那么这里就再读出设备的状态
来,一边后面做进一步的判断。
316 行前面已经说过了要是设备的状态说“我不忙了前面的操作也没发生错误
(#define BAD_R_STAT (ATA_BUSY | ATA_ERR)),而且准备好了
( ATA_DRQ= (1 << 3), /* data request i/o */)”
那么好,我们就要开始读这些identify 数据了。在说do_identify 之前稍稍打断一
下,说点关于硬盘的闲话。我们知道硬盘内部的读写是个机械操作的过程,和我们
这些CPU 的指令操作的速度肯定是没办法比,为此呢,对硬盘的读写之前我们始终
会去读它当前的状态信息,当然最重要的两个就是busy和ready。但是什么时候busy,
什么时候又是ready 呢?一般来讲比如当我们读硬盘扇区的时候,先回告诉硬盘要
读的扇区的位置,无论是LBA 方式还是CHS 方式都必须设置硬盘中的几个地址寄
存器(暂时这么叫)。这个地址写到硬盘里面去了以后,硬盘里面的控制器就知道了,
哦你原来要找的使这个地址啊。然后控制器就调度硬盘的盘片转啊转啊,终于转到
这个地址了。然后就高兴地告诉主机,主机、主机我准备好了,告诉俺是让俺读数
据呢还是写呢?当然这是相当理想的情况,要是哪个缺德的家伙写了个硬盘根本寻
址不到的地址,或者硬盘那个扇区坏了,那可不好硬盘就好发脾气了,你忽悠俺,
当然发脾气也坏不到哪去,顶多就是不设置准备标志位,然后给出错误状态信息供
主机查询。好了ready 已经说了,主机知道控制器准备好了,当然也很高兴,就又
开始下达任务了,比如给我去读10 个扇区的数据回来。这个时候硬盘控制器一听高
兴的啊,又有事干了,并且设置忙标志位,然后开始一个字节字节的从磁盘盘片上
搬到硬盘的cash 中。这个过程结束以后硬盘的机械动作也就完成了,然后忙标志位
就被清除了。主机一看不忙了,就知道硬盘的事情又干完了,剩下的事就是主机和
cash 了,当然这个速度就是很快的了,最后就一个字节一个字节的往主机里面读,
完成了数据的读取。当然这只是针对PIO 访问模式,DMA 方式又另当别论了……
好像有点扯远了,回到主题上面,接下来该是318 行的 do_identify(drive, cmd,
id);还是来先看源代码怎么说。
[ide_generic_init]->[ide_host_add]->[ide_host_register]->
[ide_probe_port]->[ probe_for_drives]->[do_probe]->[ ide_dev_read_id]->[do_identify]
180 /**
181 * do_identify - identify a drive
182 * @drive: drive to identify
183 * @cmd: command used
184 * @id: buffer for IDENTIFY data
185 *
186 * Called when we have issued a drive identify command to
187 * read and parse the results. This function is run with
188 * interrupts disabled.
189 */
190
191 static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
192 {
193 ide_hwif_t *hwif = drive->hwif;
194 char *m = (char *)&id[ATA_ID_PROD];
195 unsigned long flags;
196 int bswap = 1;
197
198 /* local CPU only; some systems need this */
199 local_irq_save(flags);
200 /* read 512 bytes of id info */
201 hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
202 local_irq_restore(flags);
203
204 drive->dev_flags |= IDE_DFLAG_ID_READ;
205 #ifdef DEBUG
206 printk(KERN_INFO "%s: dumping identify data\n", drive->name);
207 ide_dump_identify((u8 *)id);
208 #endif
209 ide_fix_driveid(id);
210
211 /*
212 * ATA_CMD_ID_ATA returns little-endian info,
213 * ATA_CMD_ID_ATAPI *usually* returns little-endian info.
214 */
215 if (cmd == ATA_CMD_ID_ATAPI) {
216 if ((m[0] == 'N' && m[1] == 'E') || /* NEC */
217 (m[0] == 'F' && m[1] == 'X') || /* Mitsumi */
218 (m[0] == 'P' && m[1] == 'i')) /* Pioneer */
219 /* Vertos drives may still be weird */
220 bswap ^= 1;
221 }
222
223 ide_fixstring(m, ATA_ID_PROD_LEN, bswap);
224 ide_fixstring((char*)&id[ATA_ID_FW_REV],ATA_ID_FW_REV_LEN, bswap);
225 ide_fixstring((char *)&id[ATA_ID_SERNO], ATA_ID_SERNO_LEN, bswap);
226
227 /* we depend on this a lot! */
228 m[ATA_ID_PROD_LEN - 1] = '\0';
229
230 if (strstr(m, "E X A B Y T E N E S T"))
231 drive->dev_flags &= ~IDE_DFLAG_PRESENT;
232 else
233 drive->dev_flags |= IDE_DFLAG_PRESENT;
234 }
194 行这里是个指向字符串的指针,其中ATA_ID_PROD= 27,我们参考前面所给的
那个id 扇区表,来看一下。
实际上是驱动器的ASCII 描述。
199-202 行这里为了保证读取的完整性,使用了 local_irq_save(flags);进行保护。
201 行就会调用 hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);进行数据
输入了 ,相应的源代码如下:
[ide_io_std.c]
156 /*
157 * This is used for most PIO data transfers *from* the IDE interface
158 *
159 * These routines will round up any request for an odd number of bytes,
160 * so if an odd len is specified, be sure that there's at least one
161 * extra byte allocated for the buffer.
162 */
163 void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
164 unsigned int len)
165 {
166 ide_hwif_t *hwif = drive->hwif;
167 struct ide_io_ports *io_ports = &hwif->io_ports;
168 unsigned long data_addr = io_ports->data_addr;
169 unsigned int words = (len + 1) >> 1;
170 u8 io_32bit = drive->io_32bit;
171 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
172
173 if (io_32bit) {
174 unsigned long uninitialized_var(flags);
175
176 if ((io_32bit & 2) && !mmio) {
177 local_irq_save(flags);
178 ata_vlb_sync(io_ports->nsect_addr);
179 }
180
181 words >>= 1;
182 if (mmio)
183 __ide_mm_insl((void __iomem *)data_addr, buf, words);
184 else
185 insl(data_addr, buf, words);
186
187 if ((io_32bit & 2) && !mmio)
188 local_irq_restore(flags);
189
190 if (((len + 1) & 3) < 2)
191 return;
192
193 buf += len & ~3;
194 words = 1;
195 }
196
197 if (mmio)
198 __ide_mm_insw((void __iomem *)data_addr, buf, words);
199 else
200 insw(data_addr, buf, words);
201 }
169 行这个函数当中的数据是以16bit 的形式访问的,所有当访问数据长度是奇数字
节的时候,我们就多读一个字节,这是很容易理解的。
170 行如果定义了32bit 的形式访问的话,后面就采用相应的方式来处理数据。
171 行IO 内存和IO 端口相关的前面说过不再重复。
173-195 行是32bit 相关的,与我们无关跳过。
197-200 行我们只关心198 行,原因大家都知道。重点来看看__ide_mm_insw,源代
码如下:
[ide_iops.h]
8 static __inline__ void __ide_mm_insw(void __iomem *port, void *addr, u32 count)
9 {
10 while (count--) {
11 *(u16 *)addr = readw(port);
12 addr += 2;
13 }
14 }
与IDE 接口进行的数据交换全是通过数据寄存器进行的,这段代码就很简单了,
就不详细说了。
好了,ide_input_data 返回后,我们继续将目光投向do_identify。
204 行一直走过来我们已经与drive->dev_flags 碰了不少面了,但是每次都没打过招
呼。那么我们现在就来认识一下他,早在do_probe,我们就见到过这样一个定义
u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat;
IDE_DFLAG_PRESENT 实际上就是暗示设备是否在ide 总线上,这里又出现一个
IDE_DFLAG_ID_READ 标示,就表示这个驱动器的id 信息我们已经读取出来了。
所以我们很容就能想到,dev-flags 实际上就是设备当前状态的一个标示。随着代码
的深入我们有预感还会和他相遇…..
205-208 行看到#ifdef DEBUG 我们就皆大欢喜,不用管它了…
209 行 ide_fix_driveid(id)看意思好像是要修改drive id 的数据,那我们就进去看他
怎么修改吧。
[ide_iops.c]
48 void ide_fix_driveid(u16 *id)
49 {
50 #ifndef __LITTLE_ENDIAN
51 # ifdef __BIG_ENDIAN
52 int i;
53
54 for (i = 0; i < 256; i++)
55 id[i] = __le16_to_cpu(id[i]);
56 # else
57 # error "Please fix <asm/byteorder.h>"
58 # endif
59 #endif
60 }
50-51 行一眼就看到了我们所熟悉的大小端模式了,毕竟我们的linux 要支持太多的
体系结构,不同的cpu 数据在内存中存放的格式可能不一样。但是我们硬盘以小端
形式存放的,就是高字节存放在高地址空间,低字节存放在低位地址空间,这里强
制类型转换为大端格式。
215-221 行是ATAPI 相关的,这里跳过…
223-225 行又是修改什么string,那我们就干脆一起看了,源码如下:
[ide_generic_init]->[ide_host_add]->[ide_host_register]->
[ide_probe_port]->[ probe_for_drives]->[do_probe]->[ ide_dev_read_id]->[do_identify]->
[ide_fixstring]
62 /*
63 * ide_fixstring() cleans up and (optionally) byte-swaps a text string,
64 * removing leading/trailing blanks and compressing internal blanks.
65 * It is primarily used to tidy up the model name/number fields as
66 * returned by the ATA_CMD_ID_ATA[PI] commands.
67 */
68
69 void ide_fixstring(u8 *s, const int bytecount, const int byteswap)
70 {
71 u8 *p, *end = &s[bytecount & ~1]; /* bytecount must be even */
72
73 if (byteswap) {
74 /* convert from big-endian to host byte order */
75 for (p = s ; p != end ; p += 2)
76 be16_to_cpus((u16 *) p);
77 }
78
79 /* strip leading blanks */
80 p = s;
81 while (s != end && *s == ' ')
82 ++s;
83 /* compress internal blanks and strip trailing blanks */
84 while (s != end && *s) {
85 if (*s++ != ' ' || (s != end && *s && *s != ' '))
86 *p++ = *(s-1);
87 }
88 /* wipe out trailing garbage */
89 while (p != end)
90 *p++ = '\0';
91 }
73-77 行前面已经提到这个问题了,又是端格式的问题。就是将大端格式转换为主
机格式。
79-90 行这就比较简单了,实际上作的工作就是将s 所对应的字符串中前面的空格字
符删除,并将多余的位置置为空,为了更形象举个例子吧。比如s=“ lin ux ”,
经过整理后就成了s=“linux”,多余的位就全部设置为0 了,就这么简单。
继续回到do_identify 中,来看ide_fixstring 的调用关系,
223 行相关的前面定义m 的时候已经说过;
224 行定义ATA_ID_FW_REV= 23,对应的是8 个字符的固件版本号;
225 行定义 ATA_ID_SERNO= 10,对应20 个字节的Serial number;
230 行strstr,这是一个字符串的操作函数。这里给出函数原型和相应注释。
原型:extern char *strstr(char *haystack, char *needle);
用法:#include <string.h>
功能:从字符串haystack中寻找needle第一次出现的位置(不比较结束
符NULL)。
说明:返回指向第一次出现needle位置的指针,如果没找到则返回NULL。
这里就是看读到的product id 是否有"E X A B Y T E N E S T",如果包含那么就
利用do_identify() marks EXABYTENEST device as non-present and frees drive->id。
当do_identify 默默填满drive->id,并做相应的处理后,也就是他该返回的时候。
依依不舍的回到ide_dev_read_id,这时候发现他也走到了生命的尽头,一切都结束
了,是时候回到do_probe 了…..
421-423 行这两句有点像大学的考试,第一次挂了,第二次再来一次。再不行那
就不能理解了,直接批上无可救药。
425 行还是读一下设备的状态。
427 行这句话就让人费解了,什么玩意,说自己准备好了,然后还打上个忙的旗
号,那肯定是疯了,直接返回得了。
430-439 行我们再说ide_dev_read_id 的时候已经说到了,只有他返回0 才是正常
的,1 表示超时。那么设备肯定是有问题了,当然这肯定不是我们希望的,这段代
码就是关于超时了的,并且是ATAPI 接口的,略过。
442 行再次查询设备状态,烦不烦啦,但是没有办法,前面的操作中我们禁止了
IDE 的中断,但是中断标志还是存在的,就像我们很多MCU 一样,中断被屏蔽了
但是相应的标志位还是会置位的。当重新使能中断的时候这些之前的标志位还是应
该清除掉的,否则再次会引发中断。对ide 接口的状态寄存器读,会清零中断标志。
所以为了确保清除irq 我们不得不这么做啊…..
451-457 行重新选择主驱动器,并清除IRQ 标志。
一路走来,感觉和do_probe 一起走了好久好久,现在他总算快要离我们而去了,
还是回忆一下和他走过的快乐时光,do_probe 做的最有意义的一件事情就是调用
ide_dev_read_id 完成了硬盘identify 数据的读取。离开do_probe , 回到
probe_for_drives 中来的时候发现我们还只是刚刚开始…..
489-493 行我想我们没有研究的必要了,毕竟是和ATAPI,出错有关了。
495 行判断一下设备的存在性,要是设备都不在了,驱动在这唱独角戏也就没啥意
思了….
499-526 行是在identification 失败后才执行的处理,我们一路走来是看着他长大的,
那么这段代码也就没有分析的必要了。
528 行这个判断人家指名道姓问是不是ide 硬盘,我们肯定得应声啦。
529 行调用ide_disk_init_chs(),代码如下:
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [ide_probe_port]->[ probe_for_drives]
->[ ide_disk_init_chs]
60 static void ide_disk_init_chs(ide_drive_t *drive)
61 {
62 u16 *id = drive->id;
63
64 /* Extract geometry if we did not already have one for the drive */
65 if (!drive->cyl || !drive->head || !drive->sect) {
66 drive->cyl = drive->bios_cyl = id[ATA_ID_CYLS];
67 drive->head = drive->bios_head = id[ATA_ID_HEADS];
68 drive->sect = drive->bios_sect = id[ATA_ID_SECTORS];
69 }
70
71 /* Handle logical geometry translation by the drive */
72 if (ata_id_current_chs_valid(id)) {
73 drive->cyl = id[ATA_ID_CUR_CYLS];
74 drive->head = id[ATA_ID_CUR_HEADS];
75 drive->sect = id[ATA_ID_CUR_SECTORS];
76 }
77
78 /* Use physical geometry if what we have still makes no sense */
79 if (drive->head > 16 && id[ATA_ID_HEADS] && id[ATA_ID_HEADS] <= 16) {
80 drive->cyl = id[ATA_ID_CYLS];
81 drive->head = id[ATA_ID_HEADS];
82 drive->sect = id[ATA_ID_SECTORS];
83 }
84 }
这段代码就是利用我们刚才读取到的id 信息来设置drive 中的磁头、柱面、扇
区等参数,具体的对应关系参考上面讲到的那个id 数据的组织的那张表。相信理解
起来难度不大。
回到do_probe 中来,最后一句我们就解脱了,调用ide_disk_init_mult_count,
看下源代码:
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [ide_probe_port]->[ probe_for_drives]
->[ ide_disk_init_mult_count]
86 static void ide_disk_init_mult_count(ide_drive_t *drive)
87 {
88 u16 *id = drive->id;
89 u8 max_multsect = id[ATA_ID_MAX_MULTSECT] & 0xff;
90
91 if (max_multsect) {
92 if ((max_multsect / 2) > 1)
93 id[ATA_ID_MULTSECT] = max_multsect | 0x100;
94 else
95 id[ATA_ID_MULTSECT] &= ~0x1ff;
96
97 drive->mult_req = id[ATA_ID_MULTSECT] & 0xff;
98
99 if (drive->mult_req)
100 drive->special_flags |= IDE_SFLAG_SET_MULTMODE;
101 }
102 }
我们知道对硬盘扇区的读写是可以多个扇区一起连续操作的,但是由于内部cash 的
容量限制这个扇区数量,所以这里就有了max_multsect 的说法。
89 行ATA_ID_MAX_MULTSECT= 47,对应到spce 中为:
Maximum sectors per inter-rupt on Read multiple and Write multiple
100 行将这个特别的特性(多扇区操作),记录在flage 当中。
离开probe_for_drive 的时候难免有些伤感,重新回到久违了的ide_probe_port,
好像也走到了尽头,最后722 行使能了禁用已久的中断…..
重新回到ide_host_register 函数,接着往下走….
1408 行既然ide_probe_port 成功返回了,那么这个接口上肯定是挂接了硬盘,是物
理存在的,所以说hwif->present=1 也就合情合理了。
1410 行这个接口既然probe 完成了也就没有必要再说人家是在probing 了。
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1414 行调用ide_register_port(),跟踪一下源码:
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [ide_register_port]
543 static int ide_register_port(ide_hwif_t *hwif)
544 {
545 int ret;
546
547 /* register with global device tree */
548 dev_set_name(&hwif->gendev, hwif->name);
549 dev_set_drvdata(&hwif->gendev, hwif);
550 if (hwif->gendev.parent == NULL)
551 hwif->gendev.parent = hwif->dev;
552 hwif->gendev.release = hwif_release_dev;
553
554 ret = device_register(&hwif->gendev);
555 if (ret < 0) {
556 printk(KERN_WARNING "IDE: %s: device_register error: %d\n",
557 __func__, ret);
558 goto out;
559 }
560
561 hwif->portdev = device_create(ide_port_class, &hwif->gendev,
562 MKDEV(0, 0), hwif, hwif->name);
563 if (IS_ERR(hwif->portdev)) {
564 ret = PTR_ERR(hwif->portdev);
565 device_unregister(&hwif->gendev);
566 }
567 out:
568 return ret;
569 }
548 和549 行是和设备模型有关的内容,关于设备模型可以说是整个linux 设备驱动
的灵魂和精髓。网上也有很多关于设备模型的详细分析,这里推荐网上华清远见的
一位牛人博客fun_abc 的《Linux 那些事儿之我是Sysfs.pdf》。这里就不对这两个函
数进行详细分析了。
550-553 行比较简单。
554 行调用device_register 注册刚刚初始化的gendev,
561 行为什么主次设备号均为0
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
回到ide_host_register,接着往下看….
1420-1421 行如果设备当前还在系统中,就调用ide_port_tune_devices(hwif);代码如
下;
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [ide_port_tune_devices]
727 static void ide_port_tune_devices(ide_hwif_t *hwif)
728 {
729 const struct ide_port_ops *port_ops = hwif->port_ops;
730 ide_drive_t *drive;
731 int i;
732
733 ide_port_for_each_present_dev(i, drive, hwif) {
734 ide_check_nien_quirk_list(drive);
735
736 if (port_ops && port_ops->quirkproc)
737 port_ops->quirkproc(drive);
738 }
739
740 ide_port_for_each_present_dev(i, drive, hwif) {
741 ide_set_max_pio(drive);
742
743 drive->dev_flags |= IDE_DFLAG_NICE1;
744
745 if (hwif->dma_ops)
746 ide_set_dma(drive);
747 }
748 }
734 行从名字中看到quirk 是跟有些变态的设备相关的,具体到代码里面看一下:
229 void ide_check_nien_quirk_list(ide_drive_t *drive)
230 {
231 const char **list, *m = (char *)&drive->id[ATA_ID_PROD];
232
233 for (list = nien_quirk_list; *list != NULL; list++)
234 if (strstr(m, *list) != NULL) {
235 drive->dev_flags |= IDE_DFLAG_NIEN_QUIRK;
236 return;
237 }
238 }
233 行nien_quirk_list 定义为:
static const char *nien_quirk_list[] = {
"QUANTUM FIREBALLlct08 08",
"QUANTUM FIREBALLP KA6.4",
"QUANTUM FIREBALLP KA9.1",
"QUANTUM FIREBALLP KX13.6",
"QUANTUM FIREBALLP KX20.5",
"QUANTUM FIREBALLP KX27.3",
"QUANTUM FIREBALLP LM20.4",
"QUANTUM FIREBALLP LM20.5",
"FUJITSU MHZ2160BH G2",
NULL
};
回到ide_port_tune_devices 中来,736-739 行就跳过了。
741 行ide_set_max_pio,不妨来看下源代码,如下:
[ide_generic_init]->[ide_host_add]->[ide_host_register]->
[ide_port_tune_devices]->[ ide_set_max_pio]
1508 static inline void ide_set_max_pio(ide_drive_t *drive)
1509 {
1510 ide_set_pio(drive, 255);
1511 }
就是直接调用ide_set_pio,跟进代码:
[ide_generic_init]->[ide_host_add]->[ide_host_register]->
[ide_port_tune_devices]->[ ide_set_max_pio]->[ ide_set_pio]
176 /* req_pio == "255" for auto-tune */
177 void ide_set_pio(ide_drive_t *drive, u8 req_pio)
178 {
179 ide_hwif_t *hwif = drive->hwif;
180 const struct ide_port_ops *port_ops = hwif->port_ops;
181 u8 host_pio, pio;
182
183 if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
184 (hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
185 return;
186
187 BUG_ON(hwif->pio_mask == 0x00);
188
189 host_pio = fls(hwif->pio_mask) - 1;
190
191 pio = ide_get_best_pio_mode(drive, req_pio, host_pio);
192
193 /*
194 * TODO:
195 * - report device max PIO mode
196 * - check req_pio != 255 against device max PIO mode
197 */
198 printk(KERN_DEBUG "%s: host max PIO%d wanted PIO%d%s selected
PIO%d\n",
199 drive->name, host_pio, req_pio,
200 req_pio == 255 ? "(auto-tune)" : "", pio);
201
202 (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio);
203 }
183-185 行的判断,一路走来我们也许发现了这个port_ops 始终是没有被设置的,
也就是说下面的所做的事情对我们来说就是没有意义的了,直接返回。
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
回到ide_host_register,继续1424 行的内容,这里调用ide_host_enable_irqs(host);代
码如下:
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [ide_host_enable_irqs]
832 static void ide_host_enable_irqs(struct ide_host *host)
833 {
834 ide_hwif_t *hwif;
835 int i;
836
837 ide_host_for_each_port(i, hwif, host) {
838 if (hwif == NULL)
839 continue;
840
841 /* clear any pending IRQs */
842 hwif->tp_ops->read_status(hwif);
843
844 /* unmask IRQs */
845 if (hwif->io_ports.ctl_addr)
846 hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
847 }
848 }
842 行通过读取状态寄存器的值来清除中断标志
846 行写控制寄存器使能中断
这段代码比较简单就不在多说了,接着回到ide_host_register…..
1426-1428 行的代码又出现了…..
1430 行hwif_init 初始化接口,跟踪源码如下;
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [hwif_init]
969 static int hwif_init(ide_hwif_t *hwif)
970 {
971 if (!hwif->irq) {
972 printk(KERN_ERR "%s: disabled, no IRQ\n", hwif->name);
973 return 0;
974 }
975
976 if (register_blkdev(hwif->major, hwif->name))
977 return 0;
978
979 if (!hwif->sg_max_nents)
980 hwif->sg_max_nents = PRD_ENTRIES;
981
982 hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
983 GFP_KERNEL);
984 if (!hwif->sg_table) {
985 printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
986 goto out;
987 }
988
989 sg_init_table(hwif->sg_table, hwif->sg_max_nents);
990
991 if (init_irq(hwif)) {
992 printk(KERN_ERR "%s: disabled, unable to get IRQ %d\n",
993 hwif->name, hwif->irq);
994 goto out;
995 }
996
997 blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
998 THIS_MODULE, ata_probe, ata_lock, hwif);
999 return 1;
1000
1001 out:
1002 unregister_blkdev(hwif->major, hwif->name);
1003 return 0;
1004 }
976 行调用register_blkdev(),每当看到register 就觉得他异常的高级,这里当然也不
例外。大名鼎鼎的块设备就是在这里和IDE 硬盘发生了关系,一下子IDE 硬盘驱动
的身价也就太高了不少。这个函数估计再往下讲估计要扯到十万八千里了,反正来
日方长,那天有心情了再来好好看他,下面回到IDE 上来。
980 行为了这一行,代码的作者写了N 长的一段注释贴出来看一下:
98 /*
99 * Our Physical Region Descriptor (PRD) table should be large enough
100 * to handle the biggest I/O request we are likely to see. Since requests
101 * can have no more than 256 sectors, and since the typical blocksize is
102 * two or more sectors, we could get by with a limit of 128 entries here for
103 * the usual worst case. Most requests seem to include some contiguous blocks,
104 * further reducing the number of table entries required.
105 *
106 * The driver reverts to PIO mode for individual requests that exceed
107 * this limit (possible with 512 byte blocksizes, eg. MSDOS f/s), so handling
108 * 100% of all crazy scenarios here is not necessary.
109 *
110 * As it turns out though, we must allocate a full 4KB page for this,
111 * so the two PRD tables (ide0 & ide1) will each get half of that,
112 * allowing each to have about 256 entries (8 bytes each) from this.
113 */
114 #define PRD_BYTES 8
115 #define PRD_ENTRIES 256
99 行有个Physical Region Descriptor,这是什么东西?下面先来了解一下她,一般来
讲硬盘的每次读写都会牵涉到DMA 的过程,而文件系统对硬盘的I/O 请求不是连
续的,数据所在的物理内存页也是不连续的,如果能够将这些不连续的内存页组合
到一起,再启用DMA 操作,那么这些数据就能够一次传输完成,这样也就能高效
的传输数据。以Silicon Image 3114 为例,可以将不连续的物理内存页和该页的长度
组合放到physical region descriptor table 里,physical region descriptor table 结构如
下:
有了这个背景以后接着往下看注释,就是说块设备一般最大的IO 请求不会超过256
扇区大小,而且一般来说这些请求都是又连续的,所以为其分配256 个表项是能够
满足的。同时每个表项含有8 个字节,就是上面我们所看到的那个physical region
descriptor table 结构图。
好了说完这些可能还是不知道他是干什么的,那也许是你还没有认识她的另一
半scatter/gather 的缘故。引用牛人的一段话来讲述scatter/gather 的故事……
“她是一种用于高性能IO 的标准技术。通常意味着一种DMA 传输方式,对于一
个给定的数据块,她老人家可能在内存中存在于一些离散的缓冲区,换言之,就是说一
些不连续的内存缓冲区一起保存一个数据块,如果没有scatter/gather 呢,那么当我们
要建立一个从内存到磁盘的传输,那么操作系统通常会为每一个buffer 做一次传输,
或者干脆就是把这些不连续的buffer 里边的冬冬全都移动到另一个很大的buffer 里
边,然后再开始传输.那么这两种方法显然都是效率不高的.毫无疑问,如果 操作系统/
驱动程序/硬件 能够把这些来自内存中离散位置的数据收集起来(gather up)并转移
她们到适当位置整个这个步骤是一个单一的操作的话,效率肯定就会更高.反之,如果
要从磁盘向内存中传输,而有一个单一的操作能够把数据块直接分散开来(scatter)到
达内存中需要的位置,而不再需要中间的那个块移动,或者别的方法,那么显然,效率总
会更高.”
在DMA 传输数据的过程中,要求源物理地址和目标物理地址必须是连续的。
但是在某些计算机体系中,如IA 架构,连续的存储器地址在物理上不一定是连续
的,所以DMA 传输要分成多次完成。如果在传输完一块物理上连续的数据后引起
一次中断,然后再由主机进行下一块物理上连续的数据传输,那么这种方式就为
block DMA 方式。Scatter-gather DMA 方式则不同,它使用一个链表描述物理上不连
续的存储空间,然后把链表首地址告诉DMA master。DMA master 在传输完一块物
理连续的数据后,不用发起中断,而是根据链表来传输下一块物理上连续的数据,
直到传输完毕后再发起一次中断。很显然,scatter-gather DMA 方式比block DMA
方式效率高。
一个小小的等号,引发了一连串的谜团,谁才是他真正的幕后黑手,答案就是
DMA。好了言归正传,接下来….
982 行有了前面的历史背景明显理解这句话也不是什么难事, 就是分配
PRD_ENTRIES 个散列链表。其定义如下:
/* Scatter-gather list used to build the above */
struct scatterlist *sg_table;
int sg_max_nents; /* Maximum number of entries in it */
989 行调用了sg_init_table(),函数内容很简单,不再详述…..
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [hwif_init]->[ sg_init_table]
83 void sg_init_table(struct scatterlist *sgl, unsigned int nents)
84 {
85 memset(sgl, 0, sizeof(*sgl) * nents);
86 #ifdef CONFIG_DEBUG_SG
87 {
88 unsigned int i;
89 for (i = 0; i < nents; i++)
90 sgl[i].sg_magic = SG_MAGIC;
91 }
92 #endif
93 sg_mark_end(&sgl[nents - 1]);
94 }
991 行init_irq(),一看名字就知道是个不好惹得主,没办法还是得看,源码如下:
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [hwif_init]->[ init_irq]
850 /*
851 * This routine sets up the IRQ for an IDE interface.
852 */
853 static int init_irq (ide_hwif_t *hwif)
854 {
855 struct ide_io_ports *io_ports = &hwif->io_ports;
856 struct ide_host *host = hwif->host;
857 irq_handler_t irq_handler = host->irq_handler;
858 int sa = host->irq_flags;
859
860 if (irq_handler == NULL)
861 irq_handler = ide_intr;
862
863 if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
864 goto out_up;
865
866 #if !defined(__mc68000__)
867 printk(KERN_INFO "%s at 0x%03lx-0x%03lx,0x%03lx on irq %d",
hwif->name,
868 io_ports->data_addr, io_ports->status_addr,
869 io_ports->ctl_addr, hwif->irq);
870 #else
871 printk(KERN_INFO "%s at 0x%08lx on irq %d", hwif->name,
872 io_ports->data_addr, hwif->irq);
873 #endif /* __mc68000__ */
874 if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE)
875 printk(KERN_CONT " (serialized)");
876 printk(KERN_CONT "\n");
877
878 return 0;
879 out_up:
880 return 1;
881 }
860-861 行如果没有指定中断向量,那么就使用内核默认的。你瞧内核多为我们省
心啊。为了减轻这个阶段的压力我们暂时缓口气,不去研究它了。后面会有机会的,
跑不了….
863 行估计写过驱动程序的大家都知道request_irq() 注册中断服务,这里就不深究
他了。要想仔细研究中断的看ldd3 去。
867-869 行这里会在加载的时候打印我们地址的一些信息。
看完init_irq(),回到hwif_init….
997 行blk_register_region 又是块设备那边的事情了,这里飘过…
又到了ide_host_register 时间,如果hwif_init 一路顺风的话现在该返回1 了,这
样也就到了1438 行了。
1439 行如果还想在道上混的话, 这句话估计还是要认识一下的。
ide_port_setup_devices();看下源代码:
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [ide_port_setup_devices]
807 /*
808 * For any present drive:
809 * - allocate the block device queue
810 */
811 static int ide_port_setup_devices(ide_hwif_t *hwif)
812 {
813 ide_drive_t *drive;
814 int i, j = 0;
815
816 mutex_lock(&ide_cfg_mtx);
817 ide_port_for_each_present_dev(i, drive, hwif) {
818 if (ide_init_queue(drive)) {
819 printk(KERN_ERR "ide: failed to init %s\n",
820 drive->name);
821 drive->dev_flags &= ~IDE_DFLAG_PRESENT;
822 continue;
823 }
824
825 j++;
826 }
827 mutex_unlock(&ide_cfg_mtx);
828
829 return j;
830 }
818 行这里为块设备分配请求队列,来看下源码:
[ide_generic_init]->[ide_host_add]->[ide_host_register]->
[ide_port_setup_devices]->[ ide_init_queue]
750 /*
751 * init request queue
752 */
753 static int ide_init_queue(ide_drive_t *drive)
754 {
755 struct request_queue *q;
756 ide_hwif_t *hwif = drive->hwif;
757 int max_sectors = 256;
758 int max_sg_entries = PRD_ENTRIES;
759
760 /*
761 * Our default set up assumes the normal IDE case,
762 * that is 64K segmenting, standard PRD setup
763 * and LBA28. Some drivers then impose their own
764 * limits and LBA48 we could raise it but as yet
765 * do not.
766 */
767
768 q = blk_init_queue_node(do_ide_request, NULL, hwif_to_node(hwif));
769 if (!q)
770 return 1;
771
772 q->queuedata = drive;
773 blk_queue_segment_boundary(q, 0xffff);
774
775 if (hwif->rqsize < max_sectors)
776 max_sectors = hwif->rqsize;
777 blk_queue_max_sectors(q, max_sectors);
778
779 #ifdef CONFIG_PCI
780 /* When we have an IOMMU, we may have a problem where pci_map_sg()
781 * creates segments that don't completely match our boundary
782 * requirements and thus need to be broken up again. Because it
783 * doesn't align properly either, we may actually have to break up
784 * to more segments than what was we got in the first place, a max
785 * worst case is twice as many.
786 * This will be fixed once we teach pci_map_sg() about our boundary
787 * requirements, hopefully soon. *FIXME*
788 */
789 if (!PCI_DMA_BUS_IS_PHYS)
790 max_sg_entries >>= 1;
791 #endif /* CONFIG_PCI */
792
793 blk_queue_max_hw_segments(q, max_sg_entries);
794 blk_queue_max_phys_segments(q, max_sg_entries);
795
796 /* assign drive queue */
797 drive->queue = q;
798
799 /* needs drive->queue to be set */
800 ide_toggle_bounce(drive, 1);
801
802 return 0;
803 }
可以说这个函数所做的所有工作纯粹是为了与块设备的接口。所以很多都调用
了块设备那边的函数,这些内容以后将放在块设备驱动中详细分析。这里我们还是
来简单看一下。
768 行可以说把整个IDE 驱动带入了高潮,因为以后块设备对IDE 的设备的所有操
作会全部落实到do_ide_request,那么这个函数也将作为我们后续分析硬盘设备的读
写过程的一个突破口,另外上层块设备的操作与do_ide_request 是靠设备节点联系
起来的。hwif_to_node 这个函数不是块设备的内容,这里还是可以小心地窥视一
番……
static inline int hwif_to_node(ide_hwif_t *hwif)
{
return hwif->dev ? dev_to_node(hwif->dev) : -1;
}
772 行把驱动器记录下面后面传入do_ide_request 的参数就只剩下她,这可得记好了。
797 行这里把分配的这个请求队列记录到驱动器中这是一一对应的。
关于ide_init_queue 其他的内容和块设备关系较大,后面我们遇到了在来说效果会更
明显一些。
ide_init_queue 返回后,ide_port_setup_devices 也就没有什么可分析的了。继续回到
ide_host_register 中….
1446-1449 行ACPI 表示高级配置和电源管理接口(Advanced Configuration and Power
Management Interface)相关,跳过…
1457 行看到这个函数名字hwif_register_devices(hwif);的时候有点小小的激动,因为
在这个时候看到register_devices 这样的字眼,估计这个长长的故事该走到尽头了。
在讲述这个故事结局的时候还是先来把1464-1469 行解决了。
1464-1469 行看名字就知道是proc 和sysfs 文件系统的内容,好了不用在这里纠结了。
回到1457 行去看个究竟….
[ide_generic_init]->[ide_host_add]->[ide_host_register]-> [hwif_register_devices]
1006 static void hwif_register_devices(ide_hwif_t *hwif)
1007 {
1008 ide_drive_t *drive;
1009 unsigned int i;
1010
1011 ide_port_for_each_present_dev(i, drive, hwif) {
1012 struct device *dev = &drive->gendev;
1013 int ret;
1014
1015 dev_set_name(dev, "%u.%u", hwif->index, i);
1016 dev_set_drvdata(dev, drive);
1017 dev->parent = &hwif->gendev;
1018 dev->bus = &ide_bus_type;
1019 dev->release = drive_release_dev;
1020
1021 ret = device_register(dev);
1022 if (ret < 0)
1023 printk(KERN_WARNING "IDE: %s: device_register error: "
1024 "%d\n", __func__, ret);
1025 }
1026 }
1012 行drive->gendev 这个我们并不陌生,前面我们已经遇到了,并为他创建了设
备节点了。
1015-1019 行就是初始化这个drive->gendev,为真正的device_register 准备。
1021 行这句话看的我们心里比吃了蜜还甜,让我们总算到了总线枚举阶段。回忆刚
开篇时我们讲到ide 总线注册时候的mach 和probe,就知道下面该是总线表现的时
候了。
离开hwif_register_devices 以后所有关于ide_generic_init 的故事就彻底结束了,
带着悲喜交加的心情离开ide-generic.c,喜因为总是结束了这个ide_generic_init 的咒
语,悲因为ide 的故事才刚刚开始呢!广告之后不要走开,后面的故事会更加精彩…..
总线枚举
[/linux/driver/ide/Ide.c]
155 struct bus_type ide_bus_type = {
156 .name = "ide",
157 .match = ide_bus_match,
158 .uevent = ide_uevent,
159 .probe = generic_ide_probe,
160 .remove = generic_ide_remove,
161 .shutdown = generic_ide_shutdown,
162 .dev_attrs = ide_dev_attrs,
163 .suspend = generic_ide_suspend,
164 .resume = generic_ide_resume,
165 };
前一节我们已经讲到,如果设备注册,将引发相应的总线发生mach,probe 等动作。
那么对应到ide-bus-type 也就是157 和159 行。
157 行mach 方法对应的函数为ide_bus_mach。来看一下源程序:
[/linux/driver/ide/Ide.c]
112 static int ide_bus_match(struct device *dev, struct device_driver *drv)
113 {
114 return 1;
115 }
这个函数简单的让人难以想象….
159 行probe 方法对应的函数为generic_ide_probe。源代码如下:
[/linux/driver/ide/Ide.c]
127 static int generic_ide_probe(struct device *dev)
128 {
129 ide_drive_t *drive = to_ide_device(dev);
130 struct ide_driver *drv = to_ide_driver(dev->driver);
131
132 return drv->probe ? drv->probe(drive) : -ENODEV;
133 }
表面上看这个函数复杂不到哪去,但谁又知道单纯的她背后又藏着什么不可告
人的秘密呢。这个函数的重点在132 行,从ide_driver 结构中我们不难得出这是个
ide 接口所对应的驱动,他实际上就是调用ide_driver 中probe 来进行枚举。在之前
的分析中我们尚未发现这个ide-driver 的相关的内容,而是一直在做drive 方面的工
作。这从设备模型的角度上来讲也就是是为了实现device 的注册,至始至终并未涉
及到device_driver 相关的设置。基于device_driver 在设备模型中的重要地位,这里,
跟踪相应的device_driver 的注册过程就成了当务之急,当然弄清了device_driver 的
注册也就很容易看出这个ide_driver 的真实身份。
在详细了解device_driver 的注册过程之前,我们先来聊点题外话。前面我们说
过,每当一个设备或者驱动注册到系统中来的时候,都会调用相应总线的mach 和
probe 方法,这句话好像重复了千遍了,估计以后还会讲到。回顾前面的例子,当
ide_generic 设备注册进来以后,我们转到了对总线中probe 的分析,然后遇到了
dev->driver 这个bug。因为在前面的代码中,还尚未对他进行赋值。那么是否真的
132 行就会因为drv->probe=NULL,而提前返回-ENODEV 夭折了呢?其实答案并非
如此,详细跟踪device_register 的代码我们可以发现,当设备注册进来的时候,总
线会为该设备寻找总线上所挂接的每一个设备驱动,并且最终调用一个叫做
really_probe(),极为性感的函数。性感到什么程度我们不妨贴出他的部分内容片段。
104 static int really_probe(struct device *dev, struct device_driver *drv)
105 {
106 int ret = 0;
107
108 atomic_inc(&probe_count);
109 pr_debug("bus: '%s': %s: probing driver %s with device %s\n",
110 drv->bus->name, __func__, drv->name, dev_name(dev));
111 WARN_ON(!list_empty(&dev->devres_head));
112
113 dev->driver = drv;
114 if (driver_sysfs_add(dev)) {
115 printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n",
116 __func__, dev_name(dev));
117 goto probe_failed;
118 }
119
120 if (dev->bus->probe) {
121 ret = dev->bus->probe(dev);
122 if (ret)
123 goto probe_failed;
124 } else if (drv->probe) {
125 ret = drv->probe(dev);
126 if (ret)
127 goto probe_failed;
128 }
129
130 driver_bound(dev);
131 ret = 1;
132 pr_debug("bus: '%s': %s: bound device %s to driver %s\n",
133 drv->bus->name, __func__, dev_name(dev), drv->name);
134 goto done;
135
136 probe_failed:
137 devres_release_all(dev);
138 driver_sysfs_remove(dev);
139 dev->driver = NULL;
140
141 if (ret != -ENODEV && ret != -ENXIO) {
142 /* driver matched but the probe failed */
143 printk(KERN_WARNING
144 "%s: probe of %s failed with error %d\n",
145 drv->name, dev_name(dev), ret);
146 }
147 /*
148 * Ignore errors returned by ->probe so that the next driver can try
149 * its luck.
150 */
151 ret = 0;
152 done:
153 atomic_dec(&probe_count);
154 wake_up(&probe_waitqueue);
155 return ret;
156 }
毫无悬念,113 dev->driver = drv 揭开了我们之前的种种困惑。也就是这个时候
device 和device_driver 发生了关系,但是我可以很严肃的告诉你这是一种极其不负
责任的做法。因为这时的device_driver 还并未接受时间以及任何probe 的考验,是
否真是device 命中注定的那个她,还不一定。接下来就是共同经历风雨的时候了,
便调用了总线的probe 函数,如果总线没有probe 就调用驱动本身的,而我们这里
就是通过总线的probe 来调用的驱动的probe 方法。当然如果一路走来,两个人都
彼此心心相惜,那么就领证也就是130 driver_bound(dev);。当然天下没有这么好的
美事,随便拉来的一个device_driver 就成了他梦寐以求的白雪公主。现代社会讲究
一夫一妻,linux 也不例外,而且每个device 也只可能对应到总线上唯一一个
device_driver,那么刚才说的这种不负责任的做法是很有肯能goto probe_failed 的,
那么随来为这段该死的错误埋单了呢,当然就到了139 行dev->driver = NULL;,然
后他们就彻底分手了。然后device 又开始寻找新的device_driver,当然我们不能和
他学,这也太不负责了。直到找遍了总线上所有的device_driver 都没有找到能相守
到老的那儿她,这时候device 才明白。哦,原来自己生命生命中的另一半还未成来
到这个世界,那么就只好等待,等待在等待….
看完这段颇像现代都市迷乱恋情的代码,才深深感觉到linux 更像一部经典的言情
小说。Linux 作者的文学造诣远远高于他的C 语言功底。说不准N 年后又被某个导
演相中了拍成电影,或许能流传千古….
好了言归正传,说了那么多联系到我们现在的这种情景的话,gendev 所对应的驱动
还尚未注册。所以probe 失败也就是在所难免的了。好接下来的时间就到了
device_driver 表演的时候了….
Ide_driver 的注册
前面的故事中大家都知道,linux 的设备驱动是以模块的形式加载的。那么Ide-
_driver 的注册肯定也不例外。按照常规也应该有一个module_init()。早在开始讲述
ide 故事的时候我们就看过kconfig 和makefile 这份内核地图了,在里面我们列出了
我们所关心的.c 文件。并且看到其中的generic ATA/ATAPI disk support 感觉到了和
我们接下来要说的generic disk 有莫大的关系,他所对应的文件ide_gd.c。那么接下
来的时间我们就尝试去认识一下,如果一切如我们所料,应该能够见到熟悉的
module_init()。进入ide_gd.c….
果然428 行我们见到了module_init(ide_gd_init),跟踪一下….
[/linux/driver/ide/ide-gd.c]
413 static int __init ide_gd_init(void)
414 {
415 printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n");
416 return driver_register(&ide_gd_driver.gen_driver);
417 }
函数精炼到了极致,416 行给我们的感觉是刚见面就意味着别离。也罢,先还是来
看看ide_gd_driver….
[/linux/driver/ide/ide-gd.c]
163 static struct ide_driver ide_gd_driver = {
164 .gen_driver = {
165 .owner = THIS_MODULE,
166 .name = "ide-gd",
167 .bus = &ide_bus_type,
168 },
169 .probe = ide_gd_probe,
170 .remove = ide_gd_remove,
171 .resume = ide_gd_resume,
172 .shutdown = ide_gd_shutdown,
173 .version = IDE_GD_VERSION,
174 .do_request = ide_gd_do_request,
175 #ifdef CONFIG_IDE_PROC_FS
176 .proc_entries = ide_disk_proc_entries,
177 .proc_devsets = ide_disk_proc_devsets,
178 #endif
179 };
咋一看,不是别人,正是前面折腾的死去活来的ide_driver。既然都见面了也不在乎
多看她一眼…..
[/linux/driver/ide/ide.h]
1009 /*
1010 * Subdrivers support.
1011 *
1012 * The gendriver.owner field should be set to the module owner of this driver.
1013 * The gendriver.name field should be set to the name of this driver
1014 */
1015 struct ide_driver {
1016 const char *version;
1017 ide_startstop_t (*do_request)(ide_drive_t *, struct request *, sector_t);
1018 struct device_driver gen_driver;
1019 int (*probe)(ide_drive_t *);
1020 void (*remove)(ide_drive_t *);
1021 void (*resume)(ide_drive_t *);
1022 void (*shutdown)(ide_drive_t *);
1023 #ifdef CONFIG_IDE_PROC_FS
1024 ide_proc_entry_t * (*proc_entries)(ide_drive_t *);
1025 const struct ide_proc_devset * (*proc_devsets)(ide_drive_t *);
1026 #endif
1027 };
好了注册的过程是设备模型的内容,我们就此打住。其实过程和刚才所讲的
device_register 是差不多的,只是这个时候是device_driver 主动勾引device 了,然后
依然会调用really_probe 这个大媒婆,剩下的内容就和刚才所讲的一致了。继续炒
剩饭每当一个设备或者驱动注册到系统中来的时候,都会调用相应总线的mach 和
probe 方法。回到前面总线probe 中…..
130 行struct ide_driver *drv = to_ide_driver(dev->driver)这还是linux 中那个惯用的伎
俩#define to_ide_driver(drv) container_of(drv, struct ide_driver, gen_driver),但还是屡
试不爽。
132 行 return drv->probe ? drv->probe(drive) : -ENODEV;就正式调用了ide_driver 中
的probe 方法。好了镜头转向ide_gd_probe,源代码如下:
[/linux/driver/ide/ide-gd.c]
335 static int ide_gd_probe(ide_drive_t *drive)
336 {
337 const struct ide_disk_ops *disk_ops = NULL;
338 struct ide_disk_obj *idkp;
339 struct gendisk *g;
340
341 /* strstr("foo", "") is non-NULL */
342 if (!strstr("ide-gd", drive->driver_req))
343 goto failed;
344
345 #ifdef CONFIG_IDE_GD_ATA
346 if (drive->media == ide_disk)
347 disk_ops = &ide_ata_disk_ops;
348 #endif
349 #ifdef CONFIG_IDE_GD_ATAPI
350 if (drive->media == ide_floppy)
351 disk_ops = &ide_atapi_disk_ops;
352 #endif
353 if (disk_ops == NULL)
354 goto failed;
355
356 if (disk_ops->check(drive, DRV_NAME) == 0) {
357 printk(KERN_ERR PFX "%s: not supported by this driver\n",
358 drive->name);
359 goto failed;
360 }
361
362 idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
363 if (!idkp) {
364 printk(KERN_ERR PFX "%s: can't allocate a disk structure\n",
365 drive->name);
366 goto failed;
367 }
368
369 g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
370 if (!g)
371 goto out_free_idkp;
372
373 ide_init_disk(g, drive);
374
375 idkp->dev.parent = &drive->gendev;
376 idkp->dev.release = ide_disk_release;
377 dev_set_name(&idkp->dev, dev_name(&drive->gendev));
378
379 if (device_register(&idkp->dev))
380 goto out_free_disk;
381
382 idkp->drive = drive;
383 idkp->driver = &ide_gd_driver;
384 idkp->disk = g;
385
386 g->private_data = &idkp->driver;
387
388 drive->driver_data = idkp;
389 drive->debug_mask = debug_mask;
390 drive->disk_ops = disk_ops;
391
392 disk_ops->setup(drive);
393
394 set_capacity(g, ide_gd_capacity(drive));
395
396 g->minors = IDE_DISK_MINORS;
397 g->driverfs_dev = &drive->gendev;
398 g->flags |= GENHD_FL_EXT_DEVT;
399 if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
400 g->flags = GENHD_FL_REMOVABLE;
401 g->fops = &ide_gd_ops;
402 add_disk(g);
403 return 0;
404
405 out_free_disk:
406 put_disk(g);
407 out_free_idkp:
408 kfree(idkp);
409 failed:
410 return -ENODEV;
411 }
341-343 行在ide-drive-t 中保存着驱动器对驱动的特殊要求,这里如果驱动器要求的
不是ide-gd,那么ide_gd_driver 也就没有必要再自作多情了。至于ide-gd 在哪设置
的至今还是个谜团。
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
345-347 行毫无疑问使我们关心的了….
[ide-disk.c]
758 const struct ide_disk_ops ide_ata_disk_ops = {
759 .check = ide_disk_check,
760 .set_capacity = ide_disk_set_capacity,
761 .get_capacity = ide_disk_get_capacity,
762 .setup = ide_disk_setup,
763 .flush = ide_disk_flush,
764 .init_media = ide_disk_init_media,
765 .set_doorlock = ide_disk_set_doorlock,
766 .do_request = ide_do_rw_disk,
767 .ioctl = ide_disk_ioctl,
768 };
这里全是为硬盘驱动所定义的方法,后面我们用到了再详细分析…..
356 行调用了上面ide_disk_check,下面来看下源代码:
[ide-disk.c]
647 static int ide_disk_check(ide_drive_t *drive, const char *s)
648 {
649 return 1;
650 }
这里认为检测一直是通过的。
362 行出现了一个新的数据结构类型,ide_disk_obj,相应的定义如下:
[ide-gd.h]
16 struct ide_disk_obj {
17 ide_drive_t *drive;
18 struct ide_driver *driver;
19 struct gendisk *disk;
20 struct device dev;
21 unsigned int openers; /* protected by BKL for now */
22
23 /* used for blk_{fs,pc}_request() requests */
24 struct ide_atapi_pc queued_pc;
25
26 /* Last error information */
27 u8 sense_key, asc, ascq;
28
29 int progress_indication;
30
31 /* Device information */
32 /* Current format */
33 int blocks, block_size, bs_factor;
34 /* Last format capacity descriptor */
35 u8 cap_desc[8];
36 /* Copy of the flexible disk page */
37 u8 flexible_disk_page[32];
38 };
从上面的这个数据结构我们看到,前面我们介绍的几大重要的数据结构在这里齐亮
相,到底他有多么神奇的魅力,后面我们再来说,这里给出来留点印象。
Kzalloc 相当于kmalloc 和memset 的作用,就是申请空间然后初始化为0。
369 行这个函数alloc_disk_node 是块设备相关的内容,这里我们就不深入进去了,
姑且理解成kzalloc。
373 行调用ide_init_disk,前面在ide_disk_obj 中我们定义了一个gendisk 结构的指针
叫disk,这里出现一个init_disk。东西不能看的太透彻,否则就会失去美感。代码
也一样,这里就不去刨根问题的搞清gendisk 是个什么意思,就跟着感觉走…不过
还是去看一下ide_init_disk 源码:
[ide_gd_probe]->[ide_init_disk]
942 void ide_init_disk(struct gendisk *disk, ide_drive_t *drive)
943 {
944 ide_hwif_t *hwif = drive->hwif;
945 unsigned int unit = drive->dn & 1;
946
947 disk->major = hwif->major;
948 disk->first_minor = unit << PARTN_BITS;
949 sprintf(disk->disk_name, "hd%c", 'a' + hwif->index * MAX_DRIVES + unit);
950 disk->queue = drive->queue;
951 }
上面这段代码总他来看比较简单,就是设置当前这个gendisk 所对应的主次设备号,
名字以及请求队列等相关的内容。
375-377 行gendisk 设置以后,ide_disk_object 这个老大可千万别忘了。他可是ide
驱动这边土生土长的结够啊。
379 行又出现了一个device_register,这里和我们之前讲的那个主,貌似有点区别,
并未指明总线等相关信息,这里实际上只是在sysfs 中留下自己的身影。
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
382-390 行这些初始化的内容比较简单,留个印象。
392 行看名字就知道不是什么好惹的主,还是来详细分析一下:
[ide_gd_probe]->[ ide_disk_setup]
652 static void ide_disk_setup(ide_drive_t *drive)
653 {
654 struct ide_disk_obj *idkp = drive->driver_data;
655 struct request_queue *q = drive->queue;
656 ide_hwif_t *hwif = drive->hwif;
657 u16 *id = drive->id;
658 char *m = (char *)&id[ATA_ID_PROD];
659 unsigned long long capacity;
660
661 ide_proc_register_driver(drive, idkp->driver);
662
663 if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0)
664 return;
665
666 if (drive->dev_flags & IDE_DFLAG_REMOVABLE) {
667 /*
668 * Removable disks (eg. SYQUEST); ignore 'WD' drives
669 */
670 if (m[0] != 'W' || m[1] != 'D')
671 drive->dev_flags |= IDE_DFLAG_DOORLOCKING;
672 }
673
674 (void)set_addressing(drive, 1);
675
676 if (drive->dev_flags & IDE_DFLAG_LBA48) {
677 int max_s = 2048;
678
679 if (max_s > hwif->rqsize)
680 max_s = hwif->rqsize;
681
682 blk_queue_max_sectors(q, max_s);
683 }
684
685 printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name,
686 queue_max_sectors(q) / 2);
687
688 if (ata_id_is_ssd(id))
689 queue_flag_set_unlocked(QUEUE_FLAG_NONROT, q);
690
691 /* calculate drive capacity, and select LBA if possible */
692 ide_disk_get_capacity(drive);
693
694 /*
695 * if possible, give fdisk access to more of the drive,
696 * by correcting bios_cyls:
697 */
698 capacity = ide_gd_capacity(drive);
699
700 if ((drive->dev_flags & IDE_DFLAG_FORCED_GEOM) == 0) {
701 if (ata_id_lba48_enabled(drive->id)) {
702 /* compatibility */
703 drive->bios_sect = 63;
704 drive->bios_head = 255;
705 }
706
707 if (drive->bios_sect && drive->bios_head) {
708 unsigned int cap0 = capacity; /* truncate to 32 bits */
709 unsigned int cylsz, cyl;
710
711 if (cap0 != capacity)
712 drive->bios_cyl = 65535;
713 else {
714 cylsz = drive->bios_sect * drive->bios_head;
715 cyl = cap0 / cylsz;
716 if (cyl > 65535)
717 cyl = 65535;
718 if (cyl > drive->bios_cyl)
719 drive->bios_cyl = cyl;
720 }
721 }
722 }
723 printk(KERN_INFO "%s: %llu sectors (%llu MB)",
724 drive->name, capacity, sectors_to_MB(capacity));
725
726 /* Only print cache size when it was specified */
727 if (id[ATA_ID_BUF_SIZE])
728 printk(KERN_CONT " w/%dKiB Cache", id[ATA_ID_BUF_SIZE] / 2);
729
730 printk(KERN_CONT ", CHS=%d/%d/%d\n",
731 drive->bios_cyl, drive->bios_head, drive->bios_sect);
732
733 /* write cache enabled? */
734 if ((id[ATA_ID_CSFO] & 1) || ata_id_wcache_enabled(id))
735 drive->dev_flags |= IDE_DFLAG_WCACHE;
736
737 set_wcache(drive, 1);
738
739 if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 &&
740 (drive->head == 0 || drive->head > 16)) {
741 printk(KERN_ERR "%s: invalid geometry: %d physical heads?\n",
742 drive->name, drive->head);
743 drive->dev_flags &= ~IDE_DFLAG_ATTACH;
744 } else
745 drive->dev_flags |= IDE_DFLAG_ATTACH;
746 }
661 行proc 文件系统相关的内容,略过.
663-664 行在前面我们说过drive->dev_flags 这个flags,现在派上用场了。如果设备
之前的读ID 失败了,那么后面的操作就没有意义了,直接返回….
666-672 行这里关于移动设备的,除去WD 的设备,其他的只要removeable 一律戴
上drive->dev_flags |= IDE_DFLAG_DOORLOCKING;的帽子。
674 行set_addressing 设置设备的访问方式。看下源代码:
[ide_gd_probe]->[ ide_disk_setup]->[ set_addressing]
614 /*
615 * drive->addressing:
616 * 0: 28-bit
617 * 1: 48-bit
618 * 2: 48-bit capable doing 28-bit
619 */
620 static int set_addressing(ide_drive_t *drive, int arg)
621 {
622 if (arg < 0 || arg > 2)
623 return -EINVAL;
624
625 if (arg && ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
626 ata_id_lba48_enabled(drive->id) == 0))
627 return -EIO;
628
629 if (arg == 2)
630 arg = 0;
631
632 if (arg)
633 drive->dev_flags |= IDE_DFLAG_LBA48;
634 else
635 drive->dev_flags &= ~IDE_DFLAG_LBA48;
636
637 return 0;
638 }
这段函数实际就是根据获得的id 信息,设置驱动器是否支持LAB48 位的访问模式。
677-680 行这几行就是LBA48 模式下,请求所允许的最大的扇区数。
682 行调用 blk_queue_max_sectors 设置请求队列支持的最大扇区数,下面来看一下
代码:
[ide_gd_probe]->[ ide_disk_setup]->[ blk_queue_max_sectors]
207 /**
208 * blk_queue_max_sectors - set max sectors for a request for this queue
209 * @q: the request queue for the device
210 * @max_sectors: max sectors in the usual 512b unit
211 *
212 * Description:
213 * Enables a low level driver to set an upper limit on the size of
214 * received requests.
215 **/
216 void blk_queue_max_sectors(struct request_queue *q, unsigned int max_sectors)
217 {
218 if ((max_sectors << 9) < PAGE_CACHE_SIZE) {
219 max_sectors = 1 << (PAGE_CACHE_SHIFT - 9);
220 printk(KERN_INFO "%s: set to minimum %d\n",
221 __func__, max_sectors);
222 }
223
224 if (BLK_DEF_MAX_SECTORS > max_sectors)
225 q->limits.max_hw_sectors = q->limits.max_sectors = max_sectors;
226 else {
227 q->limits.max_sectors = BLK_DEF_MAX_SECTORS;
228 q->limits.max_hw_sectors = max_sectors;
229 }
230 }
这里如果max_sectors 得容量不足一页内存大小,就将以页的大小作为最大的限
制容量。我们知道一个扇区的大小一般我们定义为512 字节,所以max_sectors 换算
成以字节为单位就左移了9 位。如果接口允许的扇区比块设备的
BLK_DEF_MAX_SECTORS默认扇区数目大,那么就用BLK_DEF_MAX_SECTORS;
作为最大扇区,否则接口和块设备允许的扇区数目全部max_sectors 限制。回到
ide_disk_setup 中来….
688-689 行固态硬盘相关的内容。
692 行读取硬盘的容量,详细看一下源码:
[ide_gd_probe]->[ ide_disk_setup] ->[ ide_disk_get_capacity]
355 static int ide_disk_get_capacity(ide_drive_t *drive)
356 {
357 u16 *id = drive->id;
358 int lba;
359
360 if (ata_id_lba48_enabled(id)) {
361 /* drive speaks 48-bit LBA */
362 lba = 1;
363 drive->capacity64 = ata_id_u64(id, ATA_ID_LBA_CAPACITY_2);
364 } else if (ata_id_has_lba(id) && ata_id_is_lba_capacity_ok(id)) {
365 /* drive speaks 28-bit LBA */
366 lba = 1;
367 drive->capacity64 = ata_id_u32(id, ATA_ID_LBA_CAPACITY);
368 } else {
369 /* drive speaks boring old 28-bit CHS */
370 lba = 0;
371 drive->capacity64 = drive->cyl * drive->head * drive->sect;
372 }
373
374 drive->probed_capacity = drive->capacity64;
375
376 if (lba) {
377 drive->dev_flags |= IDE_DFLAG_LBA;
378
379 /*
380 * If this device supports the Host Protected Area feature set,
381 * then we may need to change our opinion about its capacity.
382 */
383 if (ata_id_hpa_enabled(id))
384 idedisk_check_hpa(drive);
385 }
386
387 /* limit drive capacity to 137GB if LBA48 cannot be used */
388 if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 &&
389 drive->capacity64 > 1ULL << 28) {
390 printk(KERN_WARNING "%s: cannot use LBA48 - full capacity "
391 "%llu sectors (%llu MB)\n",
392 drive->name, (unsigned long long)drive->capacity64,
393 sectors_to_MB(drive->capacity64));
394 drive->probed_capacity = drive->capacity64 = 1ULL << 28;
395 }
396
397 if ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) &&
398 (drive->dev_flags & IDE_DFLAG_LBA48)) {
399 if (drive->capacity64 > 1ULL << 28) {
400 printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode"
401 " will be used for accessing sectors "
402 "> %u\n", drive->name, 1 << 28);
403 } else
404 drive->dev_flags &= ~IDE_DFLAG_LBA48;
405 }
406
407 return 0;
408 }
360-372 根据硬盘访问模式的不同,得出相应的硬盘容量。
377 行设置后面的访问方式为lba,关于硬盘的两种常用的访问方式LBA 和C/H/S,
网上有详细的说明,这里就不再多说了。由于chs 支持的容量很小,所以现在的硬
盘大都是利用LBA 线性地址来访问的。
383-384 行Host protected area。主要的工作原理就是设置读取的硬盘最大的扇区号,
从而把高端的内容隐藏起来,这个最大的扇区号能够写在硬盘的某一个地方,即使
你把这个硬盘挂到其它机器上,正常情况下你也看不到隐藏的内容,就算是通过
Fdisk 或PowerQuest PartitionMagic 之类的分区工具软件也发现不了这部空间,另外
HPA 是在ATA/ATAPI-4 里面定义的一个区域,在BIOS 可见空间之后,所以通过
BIOS 依然访问不到(个别机型可通过BIOS 设置访问)。在HPA 技术最高等级的安
全性下,无法访问、看到、删除HPA 分区,甚至无法克隆。所以这里我们需要调整
刚才所获取的硬盘容量大小。
388-395 行这段代码意思就很明显了,要是不采用lba48 访问的话,访问容量限制在
28 位寻址空间。
397-405 行代码相对简单,我们就不详述了。继续回到ide_disk_setup。
700-722 行与boot 信息相关的内容,略过。
737 行set_wcache(drive, 1),跟踪源码:
[ide_gd_probe]->[ ide_disk_setup] ->[ ide_disk_get_capacity]->[ set_wcache]
559 static int set_wcache(ide_drive_t *drive, int arg)
560 {
561 int err = 1;
562
563 if (arg < 0 || arg > 1)
564 return -EINVAL;
565
566 if (ata_id_flush_enabled(drive->id)) {
567 err = ide_do_setfeature(drive,
568 arg ? SETFEATURES_WC_ON : SETFEATURES_WC_OFF, 0);
569 if (err == 0) {
570 if (arg)
571 drive->dev_flags |= IDE_DFLAG_WCACHE;
572 else
573 drive->dev_flags &= ~IDE_DFLAG_WCACHE;
574 }
575 }
576
577 update_ordered(drive);
578
579 return err;
580 }
这段函数说的最有意义的一句话也就在567-568 行了,因为有个 ide_do_setfeature
显得他高级了不少。跟进去….
[ide_gd_probe]->[ ide_disk_setup]
->[ ide_disk_get_capacity]->[ set_wcache]->[ ide_do_setfeature]
506 static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect)
507 {
508 struct ide_cmd cmd;
509
510 memset(&cmd, 0, sizeof(cmd));
511 cmd.tf.feature = feature;
512 cmd.tf.nsect = nsect;
513 cmd.tf.command = ATA_CMD_SET_FEATURES;
514 cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
515 cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
516
517 return ide_no_data_taskfile(drive, &cmd);
518 }
这里出现了一个ide_cmd 还是来看一下他长什么样子。
288 struct ide_cmd {
289 struct ide_taskfile tf;
290 struct ide_taskfile hob;
291 struct {
292 struct {
293 u8 tf;
294 u8 hob;
295 } out, in;
296 } valid;
297
298 u16 tf_flags;
299 u8 ftf_flags; /* for TASKFILE ioctl */
300 int protocol;
301
302 int sg_nents; /* number of sg entries */
303 int orig_sg_nents;
304 int sg_dma_direction; /* DMA transfer direction */
305
306 unsigned int nbytes;
307 unsigned int nleft;
308 unsigned int last_xfer_len;
309
310 struct scatterlist *cursg;
311 unsigned int cursg_ofs;
312
313 struct request *rq; /* copy of request */
314 };
前面是大名鼎鼎的ide_taskfile 这个在前面已经说过了。另外还有一个在块设备中享
有名气的request,既然人家是块设备那边的,这里也就没有必要在背后说了。记下
他就行。
然后就说到了517 行ide_no_data_taskfile(drive, &cmd);开始处理这个setfeature 了,
由于不是数据传输所以taskfile 对应的是no_data;进去瞧瞧..
[ide-taskfile.c]
462 int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd)
463 {
464 cmd->protocol = ATA_PROT_NODATA;
465
466 return ide_raw_taskfile(drive, cmd, NULL, 0);
467 }
466 行光看名字就知道他拽的不行了, 基于前面的no_data 的声明这里就设置了
cmd->protocol = ATA_PROT_NODATA; ,进到ide_raw_taskfile 里面看个究竟。
[ide-taskfile.c]
426 int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
427 u16 nsect)
428 {
429 struct request *rq;
430 int error;
431
432 rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
433 rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
434
435 if (cmd->tf_flags & IDE_TFLAG_WRITE)
436 rq->cmd_flags |= REQ_RW;
437
438 /*
439 * (ks) We transfer currently only whole sectors.
440 * This is suffient for now. But, it would be great,
441 * if we would find a solution to transfer any size.
442 * To support special commands like READ LONG.
443 */
444 if (nsect) {
445 error = blk_rq_map_kern(drive->queue, rq, buf,
446 nsect * SECTOR_SIZE, __GFP_WAIT);
447 if (error)
448 goto put_req;
449 }
450
451 rq->special = cmd;
452 cmd->rq = rq;
453
454 error = blk_execute_rq(drive->queue, NULL, rq, 0);
455
456 put_req:
457 blk_put_request(rq);
458 return error;
459 }
432 行块设备那边的函数,你大可理解为申请request,这里就不细说。
433-436 行rq 就把这边ide disk 的一些请求通过这种关联的方式带回到了块设备层,
同样444-449 行如果说这次taskfile 中有数据传输的请求,那么也将两者关联起来,
而并非函数名称所说的真正是去map。
454 行rq 设置好了就交给块设备层去处理吧,当然就调用了blk_execute_rq,这些事
情就是块设备那边的事情了。那么我们该做的事情就真的是完了吗,您也不想想我
们现在看的可是IDE 底层的驱动啊,真正任何一次发送命令或者其他的操作最终都
是要作用到硬件上才算真正完成了。可见blk_execute_rq 背后还有一个更大的不可
告人的秘密…..
还记得很久很久以前,当我们还在讲述ide_generic 的那段青涩往事的时候,讲
过一个 static int ide_init_queue(ide_drive_t *drive) 函数,他里面调用了一个q =
blk_init_queue_node(do_ide_request, NULL, hwif_to_node(hwif));。对没错就是他
do_ide_request,当时我们还单独把它提出来说迟早有一天他会翻身做人的。没想到
到了今天,他总算是快解放了。好了,闲话少叙。blk_execute_rq 我们可以不去研究
但是他最终不管通过何种方式迟早会调用到do_ide_request。那么接下来的日子我们
就把目光投向这个天使般的精灵….
[ide-io.c]
433 /*
434 * Issue a new request to a device.
435 */
436 void do_ide_request(struct request_queue *q)
437 {
438 ide_drive_t *drive = q->queuedata;
439 ide_hwif_t *hwif = drive->hwif;
440 struct ide_host *host = hwif->host;
441 struct request *rq = NULL;
442 ide_startstop_t startstop;
443
444 /*
445 * drive is doing pre-flush, ordered write, post-flush sequence. even
446 * though that is 3 requests, it must be seen as a single transaction.
447 * we must not preempt this drive until that is complete
448 */
449 if (blk_queue_flushing(q))
450 /*
451 * small race where queue could get replugged during
452 * the 3-request flush cycle, just yank the plug since
453 * we want it to finish asap
454 */
455 blk_remove_plug(q);
456
457 spin_unlock_irq(q->queue_lock);
458
459 /* HLD do_request() callback might sleep, make sure it's okay */
460 might_sleep();
461
462 if (ide_lock_host(host, hwif))
463 goto plug_device_2;
464
465 spin_lock_irq(&hwif->lock);
466
467 if (!ide_lock_port(hwif)) {
468 ide_hwif_t *prev_port;
469
470 WARN_ON_ONCE(hwif->rq);
471 repeat:
472 prev_port = hwif->host->cur_port;
473 if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
474 time_after(drive->sleep, jiffies)) {
475 ide_unlock_port(hwif);
476 goto plug_device;
477 }
478
479 if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) &&
480 hwif != prev_port) {
481 ide_drive_t *cur_dev =
482 prev_port ? prev_port->cur_dev : NULL;
483
484 /*
485 * set nIEN for previous port, drives in the
486 * quirk list may not like intr setups/cleanups
487 */
488 if (cur_dev &&
489 (cur_dev->dev_flags & IDE_DFLAG_NIEN_QUIRK) == 0)
490 prev_port->tp_ops->write_devctl(prev_port,
491 ATA_NIEN |
492 ATA_DEVCTL_OBS);
493
494 hwif->host->cur_port = hwif;
495 }
496 hwif->cur_dev = drive;
497 drive->dev_flags&=~(IDE_DFLAG_SLEEPING| IDE_DFLAG_PARKED);
498
499 spin_unlock_irq(&hwif->lock);
500 spin_lock_irq(q->queue_lock);
501 /*
502 * we know that the queue isn't empty, but this can happen
503 * if the q->prep_rq_fn() decides to kill a request
504 */
505 if (!rq)
506 rq = blk_fetch_request(drive->queue);
507
508 spin_unlock_irq(q->queue_lock);
509 spin_lock_irq(&hwif->lock);
510
511 if (!rq) {
512 ide_unlock_port(hwif);
513 goto out;
514 }
515
516 /*
517 * Sanity: don't accept a request that isn't a PM request
518 * if we are currently power managed. This is very important as
519 * blk_stop_queue() doesn't prevent the blk_fetch_request()
520 * above to return us whatever is in the queue. Since we call
521 * ide_do_request() ourselves, we end up taking requests while
522 * the queue is blocked...
523 *
524 * We let requests forced at head of queue with ide-preempt
525 * though. I hope that doesn't happen too much, hopefully not
526 * unless the subdriver triggers such a thing in its own PM
527 * state machine.
528 */
529 if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
530 blk_pm_request(rq) == 0 &&
531 (rq->cmd_flags & REQ_PREEMPT) == 0) {
532 /* there should be no pending command at this point */
533 ide_unlock_port(hwif);
534 goto plug_device;
535 }
536
537 hwif->rq = rq;
538
539 spin_unlock_irq(&hwif->lock);
540 startstop = start_request(drive, rq);
541 spin_lock_irq(&hwif->lock);
542
543 if (startstop == ide_stopped) {
544 rq = hwif->rq;
545 hwif->rq = NULL;
546 goto repeat;
547 }
548 } else
549 goto plug_device;
550 out:
551 spin_unlock_irq(&hwif->lock);
552 if (rq == NULL)
553 ide_unlock_host(host);
554 spin_lock_irq(q->queue_lock);
555 return;
556
557 plug_device:
558 spin_unlock_irq(&hwif->lock);
559 ide_unlock_host(host);
560 plug_device_2:
561 spin_lock_irq(q->queue_lock);
562
563 if (rq)
564 blk_requeue_request(q, rq);
565 if (!elv_queue_empty(q))
566 blk_plug_device(q);
567 }
故事发展到今天,已经很难让她和块设备层之间不发生“龌龊”的关系。但是
作为明理的我们就应该始终保持一颗清醒的头脑,无论块设备那边有多的诱惑和神
秘感,我们都要对ide 驱动从一而终,和块设备保持高度的警惕。有多少的好奇等
我们看完ide 再说。保持这个态度来看代码:
453-455 行这里是块设备相关的,这里我们只需要了解他是用来取消当前请求队列
阻塞标志位的。
460 行表示这个do_ide_request 可能会睡眠。
410 行ide_lock_host,现在IDE 驱动的host 要干活了,所以设置一个busy,然后对
应的接口也就相应的lock 上。代码如下:
[ide-io.c]
410 static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif)
411 {
412 int rc = 0;
413
414 if (host->host_flags & IDE_HFLAG_SERIALIZE) {
415 rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy);
416 if (rc == 0) {
417 if (host->get_lock)
418 host->get_lock(ide_intr, hwif);
419 }
420 }
421 return rc;
422 }
472-477 行如果设备要睡眠,这算是吃了个闭门羹,自找没趣就直接返回吧。
479-495 行这里比较简单就不多说了,其中有一段是关于NIEN_QUIRK 的,这些怪
癖的驱动器前面也罗列出来了。
505-506 行道理很简单,有了队列当然最终我们希望的是request,那么这个函数就
从队列中取出了。
511-514 行检察一下有效性。
529-535 行这是一段关于电源管理的内容,飘过…..
540 行start_request,故事的高潮就要上演了,在迎接这一令人兴奋的时刻,我们先
来解决ide_do_request 剩下来的几行代码。
557-567 行这是关于request 出错的处理,不是我们希望的,如果请求失败就重新请
求。正常的出口是在550 行的OUT。
基于start_request 显赫的江湖地位,接下来的时间我们就来细说….
[ide.c]
297 /**
298 * start_request - start of I/O and command issuing for IDE
299 *
300 * start_request() initiates handling of a new I/O request. It
301 * accepts commands and I/O (read/write) requests.
302 *
303 * FIXME: this function needs a rename
304 */
305
306 static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
307 {
308 ide_startstop_t startstop;
309
310 BUG_ON(!blk_rq_started(rq));
311
312 #ifdef DEBUG
313 printk("%s: start_request: current=0x%08lx\n",
314 drive->hwif->name, (unsigned long) rq);
315 #endif
316
317 /* bail early if we've exceeded max_failures */
318 if (drive->max_failures && (drive->failures > drive->max_failures)) {
319 rq->cmd_flags |= REQ_FAILED;
320 goto kill_rq;
321 }
322
323 if (blk_pm_request(rq))
324 ide_check_pm_state(drive, rq);
325
326 drive->hwif->tp_ops->dev_select(drive);
327 if (ide_wait_stat(&startstop, drive, drive->ready_stat,
328 ATA_BUSY | ATA_DRQ, WAIT_READY)) {
329 printk(KERN_ERR "%s: drive not ready for command\n", drive->name);
330 return startstop;
331 }
332
333 if (drive->special_flags == 0) {
334 struct ide_driver *drv;
335
336 /*
337 * We reset the drive so we need to issue a SETFEATURES.
338 * Do it _after_ do_special() restored device parameters.
339 */
340 if (drive->current_speed == 0xff)
341 ide_config_drive_speed(drive, drive->desired_speed);
342
343 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
344 return execute_drive_cmd(drive, rq);
345 else if (blk_pm_request(rq)) {
346 struct request_pm_state *pm = rq->special;
347 #ifdef DEBUG_PM
348 printk("%s: start_power_step(step: %d)\n",
349 drive->name, pm->pm_step);
350 #endif
351 startstop = ide_start_power_step(drive, rq);
352 if (startstop == ide_stopped &&
353 pm->pm_step == IDE_PM_COMPLETED)
354 ide_complete_pm_rq(drive, rq);
355 return startstop;
356 } else if (!rq->rq_disk && blk_special_request(rq))
357 /*
358 * TODO: Once all ULDs have been modified to
359 * check for specific op codes rather than
360 * blindly accepting any special request, the
361 * check for ->rq_disk above may be replaced
362 * by a more suitable mechanism or even
363 * dropped entirely.
364 */
365 return ide_special_rq(drive, rq);
366
367 drv = *(struct ide_driver **)rq->rq_disk->private_data;
368
369 return drv->do_request(drive, rq, blk_rq_pos(rq));
370 }
371 return do_special(drive);
372 kill_rq:
373 ide_kill_rq(drive, rq);
374 return ide_stopped;
375 }
318-321 行前面我们说过,对于失败了的request 我们采取的措施是重新提交。那么
这里就是失败允许的次数了,如果失败max_failures 就直接标上无可救药返回。
323-324 行还是关于电源管理的,略过。
326 行选择驱动器,我们知道一个IDE 接口上面可以挂接两个IDE 设备,访问主设
备还是从设备由选择驱动器命令完成。
327 行等待设备准备好,调用ide_wait_stat,源码如下:
[ide-iops.c]
159 /*
160 * In case of error returns error value after doing "*startstop = ide_error()".
161 * The caller should return the updated value of "startstop" in this case,
162 * "startstop" is unchanged when the function returns 0.
163 */
164 int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good,
165 u8 bad, unsigned long timeout)
166 {
167 int err;
168 u8 stat;
169
170 /* bail early if we've exceeded max_failures */
171 if (drive->max_failures && (drive->failures > drive->max_failures)) {
172 *startstop = ide_stopped;
173 return 1;
174 }
175
176 err = __ide_wait_stat(drive, good, bad, timeout, &stat);
177
178 if (err) {
179 char *s = (err == -EBUSY) ? "status timeout" : "status error";
180 *startstop = ide_error(drive, s, stat);
181 }
182
183 return err;
184 }
这里最关键的是176 行,这个函数我们之前遇到过但是没有分析过。这里为了表示
对她的歉意,现在补上这一课。看代码:
[ide-iops.c]
94 /*
95 * This routine busy-waits for the drive status to be not "busy".
96 * It then checks the status for all of the "good" bits and none
97 * of the "bad" bits, and if all is okay it returns 0. All other
98 * cases return error -- caller may then invoke ide_error().
99 *
100 * This routine should get fixed to not hog the cpu during extra long waits..
101 * That could be done by busy-waiting for the first jiffy or two, and then
102 * setting a timer to wake up at half second intervals thereafter,
103 * until timeout is achieved, before timing out.
104 */
105 int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad,
106 unsigned long timeout, u8 *rstat)
107 {
108 ide_hwif_t *hwif = drive->hwif;
109 const struct ide_tp_ops *tp_ops = hwif->tp_ops;
110 unsigned long flags;
111 int i;
112 u8 stat;
113
114 udelay(1); /* spec allows drive 400ns to assert "BUSY" */
115 stat = tp_ops->read_status(hwif);
116
117 if (stat & ATA_BUSY) {
118 local_save_flags(flags);
119 local_irq_enable_in_hardirq();
120 timeout += jiffies;
121 while ((stat = tp_ops->read_status(hwif)) & ATA_BUSY) {
122 if (time_after(jiffies, timeout)) {
123 /*
124 * One last read after the timeout in case
125 * heavy interrupt load made us not make any
126 * progress during the timeout..
127 */
128 stat = tp_ops->read_status(hwif);
129 if ((stat & ATA_BUSY) == 0)
130 break;
131
132 local_irq_restore(flags);
133 *rstat = stat;
134 return -EBUSY;
135 }
136 }
137 local_irq_restore(flags);
138 }
139 /*
140 * Allow status to settle, then read it again.
141 * A few rare drives vastly violate the 400ns spec here,
142 * so we'll wait up to 10usec for a "good" status
143 * rather than expensively fail things immediately.
144 * This fix courtesy of Matthew Faupel & Niccolo Rigacci.
145 */
146 for (i = 0; i < 10; i++) {
147 udelay(1);
148 stat = tp_ops->read_status(hwif);
149
150 if (OK_STAT(stat, good, bad)) {
151 *rstat = stat;
152 return 0;
153 }
154 }
155 *rstat = stat;
156 return -EFAULT;
157 }
119 行这里把这个提出来说是因为这里使能了中断,也就是说后面在查询这个设备
状态的过程中,其他的任务也是在执行的。
121 行读取设备状态判断是否超时。
128-129 行由于这个查询设备状态的过程中如果系统任务比较繁重,也就是可能
读取设备状态这个过程已经很久没有执行,为了避免这种悲剧的发生,这里有必要
在判断一次。
146-154 行这些是为了防止时序上的原因可能引发的超时,如果这些都没能将设备
带入一个良好的状态,我们就认为是设备出现了错误。然后带着错误的状态就返回
了。
回到ide_wait_stat 回到178-181 行,按理说这是一段出错的代码,前面我们对出错
的情况都是没有分析过的。但是这里我们单独把这个错误提出来分析一下,因为这
对调试ide 驱动是很意义的。
180 行ide_error,看函数源码:
[Ide-eh.c]
100 /**
101 * ide_error - handle an error on the IDE
102 * @drive: drive the error occurred on
103 * @msg: message to report
104 * @stat: status bits
105 *
106 * ide_error() takes action based on the error returned by the drive.
107 * For normal I/O that may well include retries. We deal with
108 * both new-style (taskfile) and old style command handling here.
109 * In the case of taskfile command handling there is work left to
110 * do
111 */
112
113 ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat)
114 {
115 struct request *rq;
116 u8 err;
117
118 err = ide_dump_status(drive, msg, stat);
119
120 rq = drive->hwif->rq;
121 if (rq == NULL)
122 return ide_stopped;
123
124 /* retry only "normal" I/O: */
125 if (!blk_fs_request(rq)) {
126 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
127 struct ide_cmd *cmd = rq->special;
128
129 if (cmd)
130 ide_complete_cmd(drive, cmd, stat, err);
131 } else if (blk_pm_request(rq)) {
132 rq->errors = 1;
133 ide_complete_pm_rq(drive, rq);
134 return ide_stopped;
135 }
136 rq->errors = err;
137 ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
138 return ide_stopped;
139 }
140
141 return __ide_error(drive, rq, stat, err);
142 }
118 这里这个如果是状态的错误,会将状态数据翻译成出错的信息详细打印出来。
125-135 行会尝试对正常的IO 请求进行重试。
141 行会对这些出错进行详细处理。这部分的内容可以再设备出现错误时提供错误
定位信息,具体的程序代码比较简单就不详细分析了。继续回到start_request 中来。
344 行是我们关注的重点,进去看看:
[ide-io.c]
241 /**
242 * execute_drive_command - issue special drive command
243 * @drive: the drive to issue the command on
244 * @rq: the request structure holding the command
245 *
246 * execute_drive_cmd() issues a special drive command, usually
247 * initiated by ioctl() from the external hdparm program. The
248 * command can be a drive command, drive task or taskfile
249 * operation. Weirdly you can call it with NULL to wait for
250 * all commands to finish. Don't do this as that is due to change
251 */
252
253 static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
254 struct request *rq)
255 {
256 struct ide_cmd *cmd = rq->special;
257
258 if (cmd) {
259 if (cmd->protocol == ATA_PROT_PIO) {
260 ide_init_sg_cmd(cmd, blk_rq_sectors(rq) << 9);
261 ide_map_sg(drive, cmd);
262 }
263
264 return do_rw_taskfile(drive, cmd);
265 }
266
267 /*
268 * NULL is actually a valid way of waiting for
269 * all current requests to be flushed from the queue.
270 */
271 #ifdef DEBUG
272 printk("%s: DRIVE_CMD (null)\n", drive->name);
273 #endif
274 rq->errors = 0;
275 ide_complete_rq(drive, 0, blk_rq_bytes(rq));
276
277 return ide_stopped;
278 }
264 行成了这个函数的核心,对应了cmd 的处理。
[ide-taskfile.c]
77 ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
78 {
79 ide_hwif_t *hwif = drive->hwif;
80 struct ide_cmd *cmd = &hwif->cmd;
81 struct ide_taskfile *tf = &cmd->tf;
82 ide_handler_t *handler = NULL;
83 const struct ide_tp_ops *tp_ops = hwif->tp_ops;
84 const struct ide_dma_ops *dma_ops = hwif->dma_ops;
85
86 if (orig_cmd->protocol == ATA_PROT_PIO &&
87 (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) &&
88 drive->mult_count == 0) {
89 pr_err("%s: multimode not set!\n", drive->name);
90 return ide_stopped;
91 }
92
93 if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
94 orig_cmd->ftf_flags |= IDE_FTFLAG_SET_IN_FLAGS;
95
96 memcpy(cmd, orig_cmd, sizeof(*cmd));
97
98 if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
99 ide_tf_dump(drive->name, cmd);
100 tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
101
102 if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
103 u8 data[2] = { cmd->tf.data, cmd->hob.data };
104
105 tp_ops->output_data(drive, cmd, data, 2);
106 }
107
108 if (cmd->valid.out.tf & IDE_VALID_DEVICE) {
109 u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ?
110 0xE0 : 0xEF;
111
112 if (!(cmd->ftf_flags & IDE_FTFLAG_FLAGGED))
113 cmd->tf.device &= HIHI;
114 cmd->tf.device |= drive->select;
115 }
116
117 tp_ops->tf_load(drive, &cmd->hob, cmd->valid.out.hob);
118 tp_ops->tf_load(drive, &cmd->tf, cmd->valid.out.tf);
119 }
120
121 switch (cmd->protocol) {
122 case ATA_PROT_PIO:
123 if (cmd->tf_flags & IDE_TFLAG_WRITE) {
124 tp_ops->exec_command(hwif, tf->command);
125 ndelay(400); /* FIXME */
126 return pre_task_out_intr(drive, cmd);
127 }
128 handler = task_pio_intr;
129 /* fall-through */
130 case ATA_PROT_NODATA:
131 if (handler == NULL)
132 handler = task_no_data_intr;
133 ide_execute_command(drive, cmd, handler, WAIT_WORSTCASE);
134 return ide_started;
135 case ATA_PROT_DMA:
136 if (ide_dma_prepare(drive, cmd))
137 return ide_stopped;
138 hwif->expiry = dma_ops->dma_timer_expiry;
139 ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD);
140 dma_ops->dma_start(drive);
141 default:
142 return ide_started;
143 }
144 }
一路走来根据我们分析的情景来看,这里我们只需要关心130-134 行的代码,应为
我们的协议对应为ATA_PROT_NODATA。
先看133 行再来解释132 行,源码如下:
[ide-iops.c]
468 /**
469 * ide_execute_command - execute an IDE command
470 * @drive: IDE drive to issue the command against
471 * @cmd: command
472 * @handler: handler for next phase
473 * @timeout: timeout for command
474 *
475 * Helper function to issue an IDE command. This handles the
476 * atomicity requirements, command timing and ensures that the
477 * handler and IRQ setup do not race. All IDE command kick off
478 * should go via this function or do equivalent locking.
479 */
480
481 void ide_execute_command(ide_drive_t *drive, struct ide_cmd *cmd,
482 ide_handler_t *handler, unsigned timeout)
483 {
484 ide_hwif_t *hwif = drive->hwif;
485 unsigned long flags;
486
487 spin_lock_irqsave(&hwif->lock, flags);
488 if ((cmd->protocol != ATAPI_PROT_DMA &&
489 cmd->protocol != ATAPI_PROT_PIO) ||
490 (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT))
491 __ide_set_handler(drive, handler, timeout);
492 hwif->tp_ops->exec_command(hwif, cmd->tf.command);
493 /*
494 * Drive takes 400nS to respond, we must avoid the IRQ being
495 * serviced before that.
496 *
497 * FIXME: we could skip this delay with care on non shared devices
498 */
499 ndelay(400);
500 spin_unlock_irqrestore(&hwif->lock, flags);
501 }
明眼人一下就看到了492 行,的确就是这儿我们的命令作用到了硬件上。关于tp-ops
中的exec_command 我们之前已经说过了。是否我们写入了一个命令就结束了我们
这段艰难的旅程呢?其实事情远不是我们想的那么简单,内核也不是我们想想的那
么不负责任。写入了命令是否硬盘就执行成功了呢?这个工作就交给491 行这为使
者来做了。
[Ide-iops.c]
435 /*
436 * This should get invoked any time we exit the driver to
437 * wait for an interrupt response from a drive. handler() points
438 * at the appropriate code to handle the next interrupt, and a
439 * timer is started to prevent us from waiting forever in case
440 * something goes wrong (see the ide_timer_expiry() handler later on).
441 *
442 * See also ide_execute_command
443 */
444 void __ide_set_handler(ide_drive_t *drive, ide_handler_t *handler,
445 unsigned int timeout)
446 {
447 ide_hwif_t *hwif = drive->hwif;
448
449 BUG_ON(hwif->handler);
450 hwif->handler = handler;
451 hwif->timer.expires = jiffies + timeout;
452 hwif->req_gen_timer = hwif->req_gen;
453 add_timer(&hwif->timer);
454 }
这段代码可以说没有一个我们不熟悉的C 语言语法,也许人家是大智若愚。下面我
们就从两个方面来说说他的智体现在哪些方面。
按照先后顺序我们来先说450 行,也就是
智慧一:
Linux 内核代码之所以如此精辟,我觉得很主要的一个原因是容易让人产生健
忘,这样前面说的后面联系不上,猛然回头一看的时候,很容易让人产生扑朔迷离
的感觉,从而衬托出他的一种境界。当然,要说清楚这里的这个故事就得回到N 年
以前我们讲到的一个传说。早在ide-generic 中add-host 的时候我们通过层层调用最
终通过request_irq 申请了一个ide 中断,当说到对应的中断向量是ide_intr 的时候我
们妥协了,说以后有用到的时候再来分析。今天总算到了他开花结果的时候了,进
去开开眼界:
[ide-io.c]
753 /**
754 * ide_intr - default IDE interrupt handler
755 * @irq: interrupt number
756 * @dev_id: hwif
757 * @regs: unused weirdness from the kernel irq layer
758 *
759 * This is the default IRQ handler for the IDE layer. You should
760 * not need to override it. If you do be aware it is subtle in
761 * places
762 *
763 * hwif is the interface in the group currently performing
764 * a command. hwif->cur_dev is the drive and hwif->handler is
765 * the IRQ handler to call. As we issue a command the handlers
766 * step through multiple states, reassigning the handler to the
767 * next step in the process. Unlike a smart SCSI controller IDE
768 * expects the main processor to sequence the various transfer
769 * stages. We also manage a poll timer to catch up with most
770 * timeout situations. There are still a few where the handlers
771 * don't ever decide to give up.
772 *
773 * The handler eventually returns ide_stopped to indicate the
774 * request completed. At this point we issue the next request
775 * on the port and the process begins again.
776 */
777
778 irqreturn_t ide_intr (int irq, void *dev_id)
779 {
780 ide_hwif_t *hwif = (ide_hwif_t *)dev_id;
781 struct ide_host *host = hwif->host;
782 ide_drive_t *uninitialized_var(drive);
783 ide_handler_t *handler;
784 unsigned long flags;
785 ide_startstop_t startstop;
786 irqreturn_t irq_ret = IRQ_NONE;
787 int plug_device = 0;
788 struct request *uninitialized_var(rq_in_flight);
789
790 if (host->host_flags & IDE_HFLAG_SERIALIZE) {
791 if (hwif != host->cur_port)
792 goto out_early;
793 }
794
795 spin_lock_irqsave(&hwif->lock, flags);
796
797 if (hwif->port_ops && hwif->port_ops->test_irq &&
798 hwif->port_ops->test_irq(hwif) == 0)
799 goto out;
800
801 handler = hwif->handler;
802
803 if (handler == NULL || hwif->polling) {
804 /*
805 * Not expecting an interrupt from this drive.
806 * That means this could be:
807 * (1) an interrupt from another PCI device
808 * sharing the same PCI INT# as us.
809 * or (2) a drive just entered sleep or standby mode,
810 * and is interrupting to let us know.
811 * or (3) a spurious interrupt of unknown origin.
812 *
813 * For PCI, we cannot tell the difference,
814 * so in that case we just ignore it and hope it goes away.
815 */
816 if ((host->irq_flags & IRQF_SHARED) == 0) {
817 /*
818 * Probably not a shared PCI interrupt,
819 * so we can safely try to do something about it:
820 */
821 unexpected_intr(irq, hwif);
822 } else {
823 /*
824 * Whack the status register, just in case
825 * we have a leftover pending IRQ.
826 */
827 (void)hwif->tp_ops->read_status(hwif);
828 }
829 goto out;
830 }
831
832 drive = hwif->cur_dev;
833
834 if (!drive_is_ready(drive))
835 /*
836 * This happens regularly when we share a PCI IRQ with
837 * another device. Unfortunately, it can also happen
838 * with some buggy drives that trigger the IRQ before
839 * their status register is up to date. Hopefully we have
840 * enough advance overhead that the latter isn't a problem.
841 */
842 goto out;
843
844 hwif->handler = NULL;
845 hwif->expiry = NULL;
846 hwif->req_gen++;
847 del_timer(&hwif->timer);
848 spin_unlock(&hwif->lock);
849
850 if (hwif->port_ops && hwif->port_ops->clear_irq)
851 hwif->port_ops->clear_irq(drive);
852
853 if (drive->dev_flags & IDE_DFLAG_UNMASK)
854 local_irq_enable_in_hardirq();
855
856 /* service this interrupt, may set handler for next interrupt */
857 startstop = handler(drive);
858
859 spin_lock_irq(&hwif->lock);
860 /*
861 * Note that handler() may have set things up for another
862 * interrupt to occur soon, but it cannot happen until
863 * we exit from this routine, because it will be the
864 * same irq as is currently being serviced here, and Linux
865 * won't allow another of the same (on any CPU) until we return.
866 */
867 if (startstop == ide_stopped && hwif->polling == 0) {
868 BUG_ON(hwif->handler);
869 rq_in_flight = hwif->rq;
870 hwif->rq = NULL;
871 ide_unlock_port(hwif);
872 plug_device = 1;
873 }
874 irq_ret = IRQ_HANDLED;
875 out:
876 spin_unlock_irqrestore(&hwif->lock, flags);
877 out_early:
878 if (plug_device) {
879 ide_unlock_host(hwif->host);
880 ide_requeue_and_plug(drive, rq_in_flight);
881 }
882
883 return irq_ret;
884 }
从这段堪称和代码长度相媲美的注释来看,就足以让我们对他产生了恐惧。但是没
有办法,不管前面是多大的火焰山,还是等扛过去呀。来看代码:
首先不说别的但从注释来看,这是整个ide 所共享的一个中断向量。我们知道一般
共享的中断向量都会有个dev_id 来区分,不然岂不是乱了伦理。这里就是用hwif
来区分了。
801 行 handler = hwif->handler;和我们上面__ide_set_handler 的450 hwif->handler=
handler;相比是不是有种说不出的赤裸裸的美感呀。既然这么爽那么我们干脆就上到
底把ide_intr 的857 行一起看了857 startstop = handler(drive); 。这个时候你也许就感
叹了,哎呀我的个妈呀,原来他们是有预谋有组织的在活动啊,的确内核他就喜欢
干这样的勾当。说到这其实不想再往下说了,应该说已经解释清楚了智慧一想表达
的观点。但是看到精美的内核代码,还是不禁多说两句…..
844 行注意一个细节,hwif->handler = NULL;因为这个中断函数是大家公共的,所以
当一个任务执行完了以后hwif->handler 是要被清除的,如果不清除这个向量在出现
程序中803-830 行所对应的这些情景的时候就会引发错误的操作,这是不允许的。
803-830 行对应的情景代码的作者已经给了详细的注释,相信理解起来不算困难。
对于这个函数就说这么多了,接下来我们回到__ide_set_handler。
智慧二:
451-453 典型的定时器的操作,写过linux 驱动代码的不会不知到这个大名鼎鼎的
timer,同样知道timer 的不会不知道他应该对应的有一个timer_handle。好的,这就
对头了,与刚才的情况一样,让我们继续穿越时空来到上个世纪的ide-generic 初始
化。在ide_init_port_data 函数中调用了这么一段,相信都已经忘怀了,还是贴出他
相关的一小段。
1173 init_timer(&hwif->timer);
1174 hwif->timer.function = &ide_timer_expiry;
1175 hwif->timer.data = (unsigned long)hwif;
这段代码以一种很黄很暴力的方式告诉我们,如果你的设备超时了,那么不客气我
就要调用ide_timer_expiry 来解决了。不知道ide_timer_expiry 和武汉的城管相比谁
更加不得人心,那么我们还是来进去看看吧,不入虎穴,焉得虎子….
[ide-io.c]
607 /**
608 * ide_timer_expiry - handle lack of an IDE interrupt
609 * @data: timer callback magic (hwif)
610 *
611 * An IDE command has timed out before the expected drive return
612 * occurred. At this point we attempt to clean up the current
613 * mess. If the current handler includes an expiry handler then
614 * we invoke the expiry handler, and providing it is happy the
615 * work is done. If that fails we apply generic recovery rules
616 * invoking the handler and checking the drive DMA status. We
617 * have an excessively incestuous relationship with the DMA
618 * logic that wants cleaning up.
619 */
620
621 void ide_timer_expiry (unsigned long data)
622 {
623 ide_hwif_t *hwif = (ide_hwif_t *)data;
624 ide_drive_t *uninitialized_var(drive);
625 ide_handler_t *handler;
626 unsigned long flags;
627 int wait = -1;
628 int plug_device = 0;
629 struct request *uninitialized_var(rq_in_flight);
630
631 spin_lock_irqsave(&hwif->lock, flags);
632
633 handler = hwif->handler;
634
635 if (handler == NULL || hwif->req_gen != hwif->req_gen_timer) {
636 /*
637 * Either a marginal timeout occurred
638 * (got the interrupt just as timer expired),
639 * or we were "sleeping" to give other devices a chance.
640 * Either way, we don't really want to complain about anything.
641 */
642 } else {
643 ide_expiry_t *expiry = hwif->expiry;
644 ide_startstop_t startstop = ide_stopped;
645
646 drive = hwif->cur_dev;
647
648 if (expiry) {
649 wait = expiry(drive);
650 if (wait > 0) { /* continue */
651 /* reset timer */
652 hwif->timer.expires = jiffies + wait;
653 hwif->req_gen_timer = hwif->req_gen;
654 add_timer(&hwif->timer);
655 spin_unlock_irqrestore(&hwif->lock, flags);
656 return;
657 }
658 }
659 hwif->handler = NULL;
660 hwif->expiry = NULL;
661 /*
662 * We need to simulate a real interrupt when invoking
663 * the handler() function, which means we need to
664 * globally mask the specific IRQ:
665 */
666 spin_unlock(&hwif->lock);
667 /* disable_irq_nosync ?? */
668 disable_irq(hwif->irq);
669 /* local CPU only, as if we were handling an interrupt */
670 local_irq_disable();
671 if (hwif->polling) {
672 startstop = handler(drive);
673 } else if (drive_is_ready(drive)) {
674 if (drive->waiting_for_dma)
675 hwif->dma_ops->dma_lost_irq(drive);
676 if (hwif->port_ops && hwif->port_ops->clear_irq)
677 hwif->port_ops->clear_irq(drive);
678
679 printk(KERN_WARNING "%s: lost interrupt\n",
680 drive->name);
681 startstop = handler(drive);
682 } else {
683 if (drive->waiting_for_dma)
684 startstop = ide_dma_timeout_retry(drive, wait);
685 else
686 startstop = ide_error(drive, "irq timeout",
687 hwif->tp_ops->read_status(hwif));
688 }
689 spin_lock_irq(&hwif->lock);
690 enable_irq(hwif->irq);
691 if (startstop == ide_stopped && hwif->polling == 0) {
692 rq_in_flight = hwif->rq;
693 hwif->rq = NULL;
694 ide_unlock_port(hwif);
695 plug_device = 1;
696 }
697 }
698 spin_unlock_irqrestore(&hwif->lock, flags);
699
700 if (plug_device) {
701 ide_unlock_host(hwif->host);
702 ide_requeue_and_plug(drive, rq_in_flight);
703 }
704 }
637-641 行看到我说这几行,你可能有两个反应。第一是写错了,第二是有病。因
为这时一段注释,说这段注释没有别的意思,就是因为第一眼看到他感觉这段话着
实有点好笑。他大概的意思好像是说,“首先对于这个设备的超时我表示遗憾,我们
也尽量去给这个设备新做人的机会,应为我们也不愿意看到他出现超时”。是不是颇
有点老师的风范。
好了言归正传,648-658 行我们确实看到了驱动给了设备新做人的机会。
659 行前面也说过了,处理完中断这个hwif->handler 是要清空的,但是这里超时就
是因为等待的中断没有到来,说以这里补上这个操作也是理所当然的了。
后面的代码也就比较简单了,既然超时了能补救的就补上,出了错的就报告错误的
信息,一切都是本着对设备负责的态度。
苦海无边,该是回头的时候了。这样我们还是回到do_rw_taskfile 中来,毕竟一
切因果孽缘都始于她。说了这么久的handle 还是来看一下task_no_data_intr,不然
就对不起她了。
[ide-taskfile.c]
147 static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
148 {
149 ide_hwif_t *hwif = drive->hwif;
150 struct ide_cmd *cmd = &hwif->cmd;
151 struct ide_taskfile *tf = &cmd->tf;
152 int custom = (cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
153 int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ?
5 : 1;
154 u8 stat;
155
156 local_irq_enable_in_hardirq();
157
158 while (1) {
159 stat = hwif->tp_ops->read_status(hwif);
160 if ((stat & ATA_BUSY) == 0 || retries-- == 0)
161 break;
162 udelay(10);
163 };
164
165 if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) {
166 if (custom && tf->command == ATA_CMD_SET_MULTI) {
167 drive->mult_req = drive->mult_count = 0;
168 drive->special_flags |= IDE_SFLAG_RECALIBRATE;
169 (void)ide_dump_status(drive, __func__, stat);
170 return ide_stopped;
171 } else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS){
172 if ((stat & (ATA_ERR | ATA_DRQ)) == 0) {
173 ide_set_handler(drive, &task_no_data_intr,
174 WAIT_WORSTCASE);
175 return ide_started;
176 }
177 }
178 return ide_error(drive, "task_no_data_intr", stat);
179 }
180
181 if (custom && tf->command == ATA_CMD_SET_MULTI)
182 drive->mult_count = drive->mult_req;
183
184 if (custom == 0 || tf->command == ATA_CMD_IDLEIMMEDIATE ||
185 tf->command == ATA_CMD_CHK_POWER) {
186 struct request *rq = hwif->rq;
187
188 if (blk_pm_request(rq))
189 ide_complete_pm_rq(drive, rq);
190 else
191 ide_finish_cmd(drive, cmd, stat);
192 }
193
194 return ide_stopped;
195 }
我们知道对于nodata 的命令等其实最终是完成一些状态的判断等工作,根据不同的
命令返回状态的不同进行相应的处理,一旦出错就调用169、178 等行的出错处理。
最后,我们来看一下191 行的处理。
[ide-taskfile.c]
324 void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat)
325 {
326 struct request *rq = drive->hwif->rq;
327 u8 err = ide_read_error(drive), nsect = cmd->tf.nsect;
328 u8 set_xfer = !!(cmd->tf_flags & IDE_TFLAG_SET_XFER);
329
330 ide_complete_cmd(drive, cmd, stat, err);
331 rq->errors = err;
332
333 if (err == 0 && set_xfer) {
334 ide_set_xfer_rate(drive, nsect);
335 ide_driveid_update(drive);
336 }
337
338 ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
339 }
这个函数包含了两个方面的内容一个就是结束设备本身的命令操作,另外就是结束
块设备那边的request。分别对应代码的330 和338 行。
[ide-io.c]
74 void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
75 {
76 const struct ide_tp_ops *tp_ops = drive->hwif->tp_ops;
77 struct ide_taskfile *tf = &cmd->tf;
78 struct request *rq = cmd->rq;
79 u8 tf_cmd = tf->command;
80
81 tf->error = err;
82 tf->status = stat;
83
84 if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
85 u8 data[2];
86
87 tp_ops->input_data(drive, cmd, data, 2);
88
89 cmd->tf.data = data[0];
90 cmd->hob.data = data[1];
91 }
92
93 ide_tf_readback(drive, cmd);
94
95 if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) &&
96 tf_cmd == ATA_CMD_IDLEIMMEDIATE) {
97 if (tf->lbal != 0xc4) {
98 printk(KERN_ERR "%s: head unload failed!\n",
99 drive->name);
100 ide_tf_dump(drive->name, cmd);
101 } else
102 drive->dev_flags |= IDE_DFLAG_PARKED;
103 }
104
105 if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
106 struct ide_cmd *orig_cmd = rq->special;
107
108 if (cmd->tf_flags & IDE_TFLAG_DYN)
109 kfree(orig_cmd);
110 else
111 memcpy(orig_cmd, cmd, sizeof(*cmd));
112 }
113 }
这部分代码就不在详细说明了。
走来这么久整个ide 驱动的构架也就基本上说完了,还是回到我们的这个故事的
起点ide_disk_setup。
接下来的事情就比较简单了,从ide_disk_setup 返回以后重新回到ide_gd_probe。
接下来就到了402 行,add_disk(g);这个函数是块设备那边的一个接口,会将这个重
要的gendisk 结构注册到块设备中,然后IDE 设备也就开启了一个新的时代……
真正的数数据传输
故事发展到今天,看到了块设备的注册以后,也将近了尾声。在剩下的日子里
面我们了解一下块设备的IO 请求是如何作用在硬件上面的。
前面我们说过do_ide_request 是整个IDE 接口驱动处理IO 请求的开始,然后会
调用然后会调用start_request 来处理这个任务。在上面我们分析中我们只看了
343-344 行,因为前面的调用中是处理REQ_TYPE_ATA_TASKFILE 事务的,我们
执行了execute_drive_cmd 就直接返回了。对于硬盘的数据传输等过程我们就没有那
么早返回了,所以应该看到369 行return drv->do_request(drive, rq, blk_rq_pos(rq)),
对应到我们要说的disk 来说,就是在ide-gd.c 中注册的ide_gd_driver。
[ide-gd.c]
163 static struct ide_driver ide_gd_driver = {
164 .gen_driver = {
165 .owner = THIS_MODULE,
166 .name = "ide-gd",
167 .bus = &ide_bus_type,
168 },
169 .probe = ide_gd_probe,
170 .remove = ide_gd_remove,
171 .resume = ide_gd_resume,
172 .shutdown = ide_gd_shutdown,
173 .version = IDE_GD_VERSION,
174 .do_request = ide_gd_do_request,
175 #ifdef CONFIG_IDE_PROC_FS
176 .proc_entries = ide_disk_proc_entries,
177 .proc_devsets = ide_disk_proc_devsets,
178 #endif
179 };
目光转向174 行
[ide-gd.c]
157 static ide_startstop_t ide_gd_do_request(ide_drive_t *drive,
158 struct request *rq, sector_t sector)
159 {
160 return drive->disk_ops->do_request(drive, rq, sector);
161 }
这里实际上就是调用了disk_ops 的do_request 来处理request。在前面ide_gd_probe
中我们已经为ide_drive_t 中的disk_ops 赋值为 &ide_ata_disk_ops;。那么很自然这
场戏的主角就要上台了。
[ide-disk.c]
const struct ide_disk_ops ide_ata_disk_ops = {
.check = ide_disk_check,
.set_capacity = ide_disk_set_capacity,
.get_capacity = ide_disk_get_capacity,
.setup = ide_disk_setup,
.flush = ide_disk_flush,
.init_media = ide_disk_init_media,
.set_doorlock = ide_disk_set_doorlock,
.do_request = ide_do_rw_disk,
.ioctl = ide_disk_ioctl,
};
对应do_request 方法的是ide_do_rw_disk,这个函数就是我们ide 硬盘处理数据的关
键函数了。源码如下:
[ide-disk.c]
175 /*
176 * 268435455 == 137439 MB or 28bit limit
177 * 320173056 == 163929 MB or 48bit addressing
178 * 1073741822 == 549756 MB or 48bit addressing fake drive
179 */
180
181 static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
182 sector_t block)
183 {
184 ide_hwif_t *hwif = drive->hwif;
185
186 BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED);
187 BUG_ON(!blk_fs_request(rq));
188
189 ledtrig_ide_activity();
190
191 pr_debug("%s: %sing: block=%llu, sectors=%u, buffer=0x%08lx\n",
192 drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
193 (unsigned long long)block, blk_rq_sectors(rq),
194 (unsigned long)rq->buffer);
195
196 if (hwif->rw_disk)
197 hwif->rw_disk(drive, rq);
198
199 return __ide_do_rw_disk(drive, rq, block);
200 }
Linux 的代码中总是在关键时候吊下胃口,这里同样是高高兴兴来看数据传输表演
的,他偏偏又转到__ide_do_rw_disk(drive, rq, block)处理。没办法谁叫我们好奇呢?
跟踪源码:
77 /*
78 * __ide_do_rw_disk() issues READ and WRITE commands to a disk,
79 * using LBA if supported, or CHS otherwise, to address sectors.
80 */
81 static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
82 sector_t block)
83 {
84 ide_hwif_t *hwif = drive->hwif;
85 u16 nsectors = (u16)blk_rq_sectors(rq);
86 u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
87 u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
88 struct ide_cmd cmd;
89 struct ide_taskfile *tf = &cmd.tf;
90 ide_startstop_t rc;
91
92 if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma)
{
93 if (block + blk_rq_sectors(rq) > 1ULL << 28)
94 dma = 0;
95 else
96 lba48 = 0;
97 }
98
99 memset(&cmd, 0, sizeof(cmd));
100 cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
101 cmd.valid.in.tf = IDE_VALID_IN_TF | IDE_VALID_DEVICE;
102
103 if (drive->dev_flags & IDE_DFLAG_LBA) {
104 if (lba48) {
105 pr_debug("%s: LBA=0x%012llx\n", drive->name,
106 (unsigned long long)block);
107
108 tf->nsect = nsectors & 0xff;
109 tf->lbal = (u8) block;
110 tf->lbam = (u8)(block >> 8);
111 tf->lbah = (u8)(block >> 16);
112 tf->device = ATA_LBA;
113
114 tf = &cmd.hob;
115 tf->nsect = (nsectors >> 8) & 0xff;
116 tf->lbal = (u8)(block >> 24);
117 if (sizeof(block) != 4) {
118 tf->lbam = (u8)((u64)block >> 32);
119 tf->lbah = (u8)((u64)block >> 40);
120 }
121
122 cmd.valid.out.hob = IDE_VALID_OUT_HOB;
123 cmd.valid.in.hob = IDE_VALID_IN_HOB;
124 cmd.tf_flags |= IDE_TFLAG_LBA48;
125 } else {
126 tf->nsect = nsectors & 0xff;
127 tf->lbal = block;
128 tf->lbam = block >>= 8;
129 tf->lbah = block >>= 8;
130 tf->device = ((block >> 8) & 0xf) | ATA_LBA;
131 }
132 } else {
133 unsigned int sect, head, cyl, track;
134
135 track = (int)block / drive->sect;
136 sect = (int)block % drive->sect + 1;
137 head = track % drive->head;
138 cyl = track / drive->head;
139
140 pr_debug("%s: CHS=%u/%u/%u\n", drive->name, cyl, head, sect);
141
142 tf->nsect = nsectors & 0xff;
143 tf->lbal = sect;
144 tf->lbam = cyl;
145 tf->lbah = cyl >> 8;
146 tf->device = head;
147 }
148
149 cmd.tf_flags |= IDE_TFLAG_FS;
150
151 if (rq_data_dir(rq))
152 cmd.tf_flags |= IDE_TFLAG_WRITE;
153
154 ide_tf_set_cmd(drive, &cmd, dma);
155 cmd.rq = rq;
156
157 if (dma == 0) {
158 ide_init_sg_cmd(&cmd, nsectors << 9);
159 ide_map_sg(drive, &cmd);
160 }
161
162 rc = do_rw_taskfile(drive, &cmd);
163
164 if (rc == ide_stopped && dma) {
165 /* fallback to PIO */
166 cmd.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK;
167 ide_tf_set_cmd(drive, &cmd, 0);
168 ide_init_sg_cmd(&cmd, nsectors << 9);
169 rc = do_rw_taskfile(drive, &cmd);
170 }
171
172 return rc;
173 }
103-105 行这段代码就是针对利用LBA 方式访问的,也是我们用的最多的一段代码。
这段里面主要就是设置了cmd,您可别小瞧了这个ide_cmd 他就是__ide_do_rw_disk
的通信员,上面有什么请求最后都是转换成cmd 下达给硬件,也就是调用162 行的
rc = do_rw_taskfile(drive, &cmd); 前面我们对其进行过简单分析,这里不妨再来看一
下:
[ide-taskfile.c]
77 ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
78 {
79 ide_hwif_t *hwif = drive->hwif;
80 struct ide_cmd *cmd = &hwif->cmd;
81 struct ide_taskfile *tf = &cmd->tf;
82 ide_handler_t *handler = NULL;
83 const struct ide_tp_ops *tp_ops = hwif->tp_ops;
84 const struct ide_dma_ops *dma_ops = hwif->dma_ops;
85
86 if (orig_cmd->protocol == ATA_PROT_PIO &&
87 (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) &&
88 drive->mult_count == 0) {
89 pr_err("%s: multimode not set!\n", drive->name);
90 return ide_stopped;
91 }
92
93 if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
94 orig_cmd->ftf_flags |= IDE_FTFLAG_SET_IN_FLAGS;
95
96 memcpy(cmd, orig_cmd, sizeof(*cmd));
97
98 if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
99 ide_tf_dump(drive->name, cmd);
100 tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
101
102 if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
103 u8 data[2] = { cmd->tf.data, cmd->hob.data };
104
105 tp_ops->output_data(drive, cmd, data, 2);
106 }
107
108 if (cmd->valid.out.tf & IDE_VALID_DEVICE) {
109 u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ?
110 0xE0 : 0xEF;
111
112 if (!(cmd->ftf_flags & IDE_FTFLAG_FLAGGED))
113 cmd->tf.device &= HIHI;
114 cmd->tf.device |= drive->select;
115 }
116
117 tp_ops->tf_load(drive, &cmd->hob, cmd->valid.out.hob);
118 tp_ops->tf_load(drive, &cmd->tf, cmd->valid.out.tf);
119 }
120
121 switch (cmd->protocol) {
122 case ATA_PROT_PIO:
123 if (cmd->tf_flags & IDE_TFLAG_WRITE) {
124 tp_ops->exec_command(hwif, tf->command);
125 ndelay(400); /* FIXME */
126 return pre_task_out_intr(drive, cmd);
127 }
128 handler = task_pio_intr;
129 /* fall-through */
130 case ATA_PROT_NODATA:
131 if (handler == NULL)
132 handler = task_no_data_intr;
133 ide_execute_command(drive, cmd, handler, WAIT_WORSTCASE);
134 return ide_started;
135 case ATA_PROT_DMA:
136 if (ide_dma_prepare(drive, cmd))
137 return ide_stopped;
138 hwif->expiry = dma_ops->dma_timer_expiry;
139 ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD);
140 dma_ops->dma_start(drive);
141 default:
142 return ide_started;
143 }
对于我们使用PIO 方式的数据传输来说,最关心的莫过于122-129 行,前面我们说
的是130-134 行。但是这里我们要注意一个问题,就是PIO 方式的读写在这里就分
开了。对于写方式走的是126 行return pre_task_out_intr(drive, cmd); 对于读方式会
设置一个handler 以后就跳到133 行,这是最基本的C 语言语法了,好了我们按顺
序来看。首先是pre_task_out_intr,源码如下;
[ide-taskfile.c]
403 static ide_startstop_t pre_task_out_intr(ide_drive_t *drive,
404 struct ide_cmd *cmd)
405 {
406 ide_startstop_t startstop;
407
408 if (ide_wait_stat(&startstop, drive, ATA_DRQ,
409 drive->bad_wstat, WAIT_DRQ)) {
410 pr_err("%s: no DRQ after issuing %sWRITE%s\n", drive->name,
411 (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "",
412 (drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
413 return startstop;
414 }
415
416 if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0)
417 local_irq_disable();
418
419 ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
420
421 ide_pio_datablock(drive, cmd, 1);
422
423 return ide_started;
424 }
408 行这个前面讲硬盘的RDY 和BUSY 的时候已经说的很详细了,就不再多说。
剩下的问题就落实到419 行, ide_set_handler(drive, &task_pio_intr,
WAIT_WORSTCASE);赤裸裸地将&task_pio_intr 中断向量给了前面所说的那个NB
的共享中断向量,当然这里也就把我们前面说到的那个用于超时的timer 进行了设
置,前面说过这里就不详述了。关于这个向量的具体内容等我们看完读操作那边的
函数再来分析,两者所用的handler 是一样的。
421 行这一行可以说是我们PIO 传输的关键中的关键,空话就不说了,直接看代码:
[ide-taskfile.c]
281 static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd,
282 unsigned int write)
283 {
284 unsigned int nr_bytes;
285
286 u8 saved_io_32bit = drive->io_32bit;
287
288 if (cmd->tf_flags & IDE_TFLAG_FS)
289 cmd->rq->errors = 0;
290
291 if (cmd->tf_flags & IDE_TFLAG_IO_16BIT)
292 drive->io_32bit = 0;
293
294 touch_softlockup_watchdog();
295
296 if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
297 nr_bytes = min_t(unsigned, cmd->nleft, drive->mult_count << 9);
298 else
299 nr_bytes = SECTOR_SIZE;
300
301 ide_pio_bytes(drive, cmd, write, nr_bytes);
302
303 drive->io_32bit = saved_io_32bit;
304 }
毫无疑问301 行成了万花丛中的一点红,真实的数据传输就要到来了:
[ide-taskfile.c]
222 void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
223 unsigned int write, unsigned int len)
224 {
225 ide_hwif_t *hwif = drive->hwif;
226 struct scatterlist *sg = hwif->sg_table;
227 struct scatterlist *cursg = cmd->cursg;
228 unsigned long uninitialized_var(flags);
229 struct page *page;
230 unsigned int offset;
231 u8 *buf;
232
233 cursg = cmd->cursg;
234 if (cursg == NULL)
235 cursg = cmd->cursg = sg;
236
237 while (len) {
238 unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
239 int page_is_high;
240
241 if (nr_bytes > PAGE_SIZE)
242 nr_bytes = PAGE_SIZE;
243
244 page = sg_page(cursg);
245 offset = cursg->offset + cmd->cursg_ofs;
246
247 /* get the current page and offset */
248 page = nth_page(page, (offset >> PAGE_SHIFT));
249 offset %= PAGE_SIZE;
250
251 page_is_high = PageHighMem(page);
252 if (page_is_high)
253 local_irq_save(flags);
254
255 buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
256
257 cmd->nleft -= nr_bytes;
258 cmd->cursg_ofs += nr_bytes;
259
260 if (cmd->cursg_ofs == cursg->length) {
261 cursg = cmd->cursg = sg_next(cmd->cursg);
262 cmd->cursg_ofs = 0;
263 }
264
265 /* do the actual data transfer */
266 if (write)
267 hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes);
268 else
269 hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes);
270
271 kunmap_atomic(buf, KM_BIO_SRC_IRQ);
272
273 if (page_is_high)
274 local_irq_restore(flags);
275
276 len -= nr_bytes;
277 }
278 }
266-269 行就是真正数据传送的关键了,这个函数完成了以后,硬盘会将数据从cash
中一个个写到硬盘的物理扇区上,等到写完以后会引发一个中断,经过七七四十九
难过后,最终会调用task_pio_intr 来进行善后工作。总的来讲这个函数比较简单就
不在详细分析了。
然而, 在读硬盘中使用的是ide_execute_command , 这个我们前面处理
ATA_PROT_NODATA 的时候已经说过了,比较简单,可以自己进去看一下,就是
执行力一个命令。这里就不再展开说了,最后的问题就集中到了task_pio_intr,下
面就来一睹芳容….
[ide-taskfile.c]
341 /*
342 * Handler for command with PIO data phase.
343 */
344 static ide_startstop_t task_pio_intr(ide_drive_t *drive)
345 {
346 ide_hwif_t *hwif = drive->hwif;
347 struct ide_cmd *cmd = &drive->hwif->cmd;
348 u8 stat = hwif->tp_ops->read_status(hwif);
349 u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
350
351 if (write == 0) {
352 /* Error? */
353 if (stat & ATA_ERR)
354 goto out_err;
355
356 /* Didn't want any data? Odd. */
357 if ((stat & ATA_DRQ) == 0) {
358 /* Command all done? */
359 if (OK_STAT(stat, ATA_DRDY, ATA_BUSY))
360 goto out_end;
361
362 /* Assume it was a spurious irq */
363 goto out_wait;
364 }
365 } else {
366 if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
367 goto out_err;
368
369 /* Deal with unexpected ATA data phase. */
370 if (((stat & ATA_DRQ) == 0) ^ (cmd->nleft == 0))
371 goto out_err;
372 }
373
374 if (write && cmd->nleft == 0)
375 goto out_end;
376
377 /* Still data left to transfer. */
378 ide_pio_datablock(drive, cmd, write);
379
380 /* Are we done? Check status and finish transfer. */
381 if (write == 0 && cmd->nleft == 0) {
382 stat = wait_drive_not_busy(drive);
383 if (!OK_STAT(stat, 0, BAD_STAT))
384 goto out_err;
385
386 goto out_end;
387 }
388 out_wait:
389 /* Still data left to transfer. */
390 ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
391 return ide_started;
392 out_end:
393 if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
394 ide_finish_cmd(drive, cmd, stat);
395 else
396 ide_complete_rq(drive, 0, blk_rq_sectors(cmd->rq) << 9);
397 return ide_stopped;
398 out_err:
399 ide_error_cmd(drive, cmd);
400 return ide_error(drive, __func__, stat);
401 }
378 行ide_pio_datablock 是为读数据而设置的,读数据时只有请求的数据全部写入
cash 以后会触发中断,也就是在这个中断处理当中,读函数实现了自己的价值。函
数中的其他内容就是一些善后的工作了,前面能说的都已经说过了,这里就不重复
了。
关于IDE 的驱动,重点的内容都已经分析完了,存在很多不足和错误之处,这
里旨在给出一个分析linux 驱动的方法。分析完一个子系统的驱动,其他的子系统
也就大同小异了。
2010-8-18
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值