Changeset a1f48f6 in mainline for uspace/srv/bd/ata_bd/ata_bd.c


Ignore:
Timestamp:
2009-08-22T18:36:30Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1c1657c
Parents:
4ef117f8
Message:

Add LBA-48 addressing support.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/ata_bd/ata_bd.c

    r4ef117f8 ra1f48f6  
    3535 * @brief ATA disk driver
    3636 *
    37  * This driver currently works only with CHS addressing and uses PIO.
    38  * Currently based on the (now obsolete) ATA-1, ATA-2 standards.
     37 * This driver supports CHS, 28-bit and 48-bit LBA addressing. It only uses
     38 * PIO transfers. There is no support DMA, the PACKET feature set or any other
     39 * fancy features such as S.M.A.R.T, removable devices, etc.
     40 *
     41 * This driver is based on the ATA-1, ATA-2, ATA-3 and ATA/ATAPI-4 through 7
     42 * standards, as published by the ANSI, NCITS and INCITS standards bodies,
     43 * which are freely available. This driver contains no vendor-specific
     44 * code at this moment.
    3945 *
    4046 * The driver services a single controller which can have up to two disks
     
    100106        printf(NAME ": ATA disk driver\n");
    101107
    102         printf("I/O address 0x%x\n", cmd_physical);
     108        printf("I/O address 0x%p/0x%p\n", ctl_physical, cmd_physical);
    103109
    104110        if (ata_bd_init() != EOK)
     
    156162        printf("%s: ", d->model);
    157163
    158         if (d->amode == am_chs) {
     164        switch (d->amode) {
     165        case am_chs:
    159166                printf("CHS %u cylinders, %u heads, %u sectors",
    160167                    disk->geom.cylinders, disk->geom.heads, disk->geom.sectors);
    161         } else {
     168                break;
     169        case am_lba28:
    162170                printf("LBA-28");
     171                break;
     172        case am_lba48:
     173                printf("LBA-48");
     174                break;
    163175        }
    164176
     
    288300        size_t pos, len;
    289301        int rc;
    290         int i;
     302        unsigned i;
    291303
    292304        rc = drive_identify(disk_id, &idata);
     
    305317
    306318                d->blocks = d->geom.cylinders * d->geom.heads * d->geom.sectors;
    307         } else {
    308                 /* Device supports LBA-28. */
     319        } else if ((idata.cmd_set1 & cs1_addr48) == 0) {
     320                /* Device only supports LBA-28 addressing. */
    309321                d->amode = am_lba28;
    310322
     
    314326
    315327                d->blocks =
    316                     (uint32_t) idata.total_lba_sec0 |
    317                     ((uint32_t) idata.total_lba_sec1 << 16);
     328                     (uint32_t) idata.total_lba28_0 |
     329                    ((uint32_t) idata.total_lba28_1 << 16);
     330        } else {
     331                /* Device supports LBA-48 addressing. */
     332                d->amode = am_lba48;
     333
     334                d->geom.cylinders = 0;
     335                d->geom.heads = 0;
     336                d->geom.sectors = 0;
     337
     338                d->blocks =
     339                     (uint64_t) idata.total_lba48_0 |
     340                    ((uint64_t) idata.total_lba48_1 << 16) |
     341                    ((uint64_t) idata.total_lba48_2 << 32) |
     342                    ((uint64_t) idata.total_lba48_3 << 48);
    318343        }
    319344
     
    451476        uint16_t data;
    452477        uint8_t status;
    453         uint64_t c, h, s;
     478        uint64_t c, h, s, c1, s1;
    454479        uint64_t idx;
    455480        uint8_t drv_head;
     
    462487                return EINVAL;
    463488
    464         if (d->amode == am_chs) {
     489        switch (d->amode) {
     490        case am_chs:
    465491                /* Compute CHS coordinates. */
    466492                c = blk_idx / (d->geom.heads * d->geom.sectors);
     
    469495                h = idx / d->geom.sectors;
    470496                s = 1 + (idx % d->geom.sectors);
    471         } else {
     497                break;
     498
     499        case am_lba28:
    472500                /* Compute LBA-28 coordinates. */
    473501                s = blk_idx & 0xff;             /* bits 0-7 */
    474502                c = (blk_idx >> 8) & 0xffff;    /* bits 8-23 */
    475503                h = (blk_idx >> 24) & 0x0f;     /* bits 24-27 */
     504                break;
     505
     506        case am_lba48:
     507                /* Compute LBA-48 coordinates. */
     508                s = blk_idx & 0xff;             /* bits 0-7 */
     509                c = (blk_idx >> 8) & 0xffff;    /* bits 8-23 */
     510                s1 = (blk_idx >> 24) & 0xff;    /* bits 24-31 */
     511                c1 = (blk_idx >> 32) & 0xffff;  /* bits 32-47 */
     512                h = 0;
     513                break;
    476514        }
    477515
     
    498536        }
    499537
     538        if (d->amode == am_lba48) {
     539                /* Write high-order bits. */
     540                pio_write_8(&cmd->sector_count, 0);
     541                pio_write_8(&cmd->sector_number, s1);
     542                pio_write_8(&cmd->cylinder_low, c1 & 0xff);
     543                pio_write_8(&cmd->cylinder_high, c1 >> 16);
     544        }
     545
     546        /* Write low-order bits. */
    500547        pio_write_8(&cmd->sector_count, 1);
    501548        pio_write_8(&cmd->sector_number, s);
     
    540587        size_t i;
    541588        uint8_t status;
    542         uint64_t c, h, s;
     589        uint64_t c, h, s, c1, s1;
    543590        uint64_t idx;
    544591        uint8_t drv_head;
     
    551598                return EINVAL;
    552599
    553         if (d->amode == am_chs) {
     600        switch (d->amode) {
     601        case am_chs:
    554602                /* Compute CHS coordinates. */
    555603                c = blk_idx / (d->geom.heads * d->geom.sectors);
     
    558606                h = idx / d->geom.sectors;
    559607                s = 1 + (idx % d->geom.sectors);
    560         } else {
     608                break;
     609
     610        case am_lba28:
    561611                /* Compute LBA-28 coordinates. */
    562612                s = blk_idx & 0xff;             /* bits 0-7 */
    563613                c = (blk_idx >> 8) & 0xffff;    /* bits 8-23 */
    564614                h = (blk_idx >> 24) & 0x0f;     /* bits 24-27 */
     615                break;
     616
     617        case am_lba48:
     618                /* Compute LBA-48 coordinates. */
     619                s = blk_idx & 0xff;             /* bits 0-7 */
     620                c = (blk_idx >> 8) & 0xffff;    /* bits 8-23 */
     621                s1 = (blk_idx >> 24) & 0xff;    /* bits 24-31 */
     622                c1 = (blk_idx >> 32) & 0xffff;  /* bits 32-47 */
     623                h = 0;
     624                break;
    565625        }
    566626
     
    587647        }
    588648
     649        if (d->amode == am_lba48) {
     650                /* Write high-order bits. */
     651                pio_write_8(&cmd->sector_count, 0);
     652                pio_write_8(&cmd->sector_number, s1);
     653                pio_write_8(&cmd->cylinder_low, c1 & 0xff);
     654                pio_write_8(&cmd->cylinder_high, c1 >> 16);
     655        }
     656
     657        /* Write low-order bits. */
    589658        pio_write_8(&cmd->sector_count, 1);
    590659        pio_write_8(&cmd->sector_number, s);
Note: See TracChangeset for help on using the changeset viewer.