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_apply_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))
这个宏看上去有点好玩,就是说只有好的,没有坏的就认为是好….