linux IDE驱动分析之IDE总线、驱动注册(三)

IDE总线、驱动注册(三)

 

好了,闲话少叙仍旧回到ide_host_register中来.

1386ide_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行设置接口的通道号,只能出现01

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_flagside_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_statusdev_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是将要写入驱动/磁头选择寄存器的数据,按上表的格式的话D7D5应该恒为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_MMIOide_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))

这个宏看上去有点好玩,就是说只有好的,没有坏的就认为是好.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值