Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset a99cf073 in mainline


Ignore:
Timestamp:
2009-08-22T15:08:43Z (12 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
Children:
4ef117f8
Parents:
b94334f
Message:

Add LBA-28 addressing support.

Location:
uspace/srv/bd/ata_bd
Files:
2 edited

Legend:

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

    rb94334f ra99cf073  
    8888static int disk_init(disk_t *d, int disk_id);
    8989static int drive_identify(int drive_id, void *buf);
     90static void disk_print_summary(disk_t *d);
    9091static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus,
    9192    unsigned timeout);
     
    111112
    112113                if (rc == EOK) {
    113                         printf("%s: %u cylinders, %u heads, %u sectors.\n",
    114                             disk[i].model, disk[i].cylinders, disk[i].heads,
    115                             disk[i].sectors);
     114                        disk_print_summary(&disk[i]);
    116115                } else {
    117116                        printf("Not found.\n");
     
    150149}
    151150
     151/** Print one-line device summary. */
     152static void disk_print_summary(disk_t *d)
     153{
     154        printf("%s: ", d->model);
     155
     156        if (d->amode == am_chs) {
     157                printf("CHS %u cylinders, %u heads, %u sectors",
     158                    disk->geom.cylinders, disk->geom.heads, disk->geom.sectors);
     159        } else {
     160                printf("LBA-28");
     161        }
     162
     163        printf(" %llu blocks.\n", d->blocks);
     164}
    152165
    153166/** Register driver and enable device I/O. */
     
    275288        }
    276289
    277         d->cylinders = idata.cylinders;
    278         d->heads = idata.heads;
    279         d->sectors = idata.sectors;
    280 
    281         d->blocks = d->cylinders * d->heads * d->sectors;
     290        if ((idata.caps & cap_lba) == 0) {
     291                /* Device only supports CHS addressing. */
     292                d->amode = am_chs;
     293
     294                d->geom.cylinders = idata.cylinders;
     295                d->geom.heads = idata.heads;
     296                d->geom.sectors = idata.sectors;
     297
     298                d->blocks = d->geom.cylinders * d->geom.heads * d->geom.sectors;
     299        } else {
     300                /* Device supports LBA-28. */
     301                d->amode = am_lba28;
     302
     303                d->geom.cylinders = 0;
     304                d->geom.heads = 0;
     305                d->geom.sectors = 0;
     306
     307                d->blocks =
     308                    (uint32_t) idata.total_lba_sec0 |
     309                    ((uint32_t) idata.total_lba_sec1 << 16);
     310        }
    282311
    283312        /*
     
    425454                return EINVAL;
    426455
    427         /* Compute CHS. */
    428         c = blk_idx / (d->heads * d->sectors);
    429         idx = blk_idx % (d->heads * d->sectors);
    430 
    431         h = idx / d->sectors;
    432         s = 1 + (idx % d->sectors);
     456        if (d->amode == am_chs) {
     457                /* Compute CHS coordinates. */
     458                c = blk_idx / (d->geom.heads * d->geom.sectors);
     459                idx = blk_idx % (d->geom.heads * d->geom.sectors);
     460
     461                h = idx / d->geom.sectors;
     462                s = 1 + (idx % d->geom.sectors);
     463        } else {
     464                /* Compute LBA-28 coordinates. */
     465                s = blk_idx & 0xff;             /* bits 0-7 */
     466                c = (blk_idx >> 8) & 0xffff;    /* bits 8-23 */
     467                h = (blk_idx >> 24) & 0x0f;     /* bits 24-27 */
     468        }
    433469
    434470        /* New value for Drive/Head register */
    435471        drv_head =
    436472            ((disk_id != 0) ? DHR_DRV : 0) |
     473            ((d->amode != am_chs) ? DHR_LBA : 0) |
    437474            (h & 0x0f);
    438475
     
    506543                return EINVAL;
    507544
    508         /* Compute CHS. */
    509         c = blk_idx / (d->heads * d->sectors);
    510         idx = blk_idx % (d->heads * d->sectors);
    511 
    512         h = idx / d->sectors;
    513         s = 1 + (idx % d->sectors);
     545        if (d->amode == am_chs) {
     546                /* Compute CHS coordinates. */
     547                c = blk_idx / (d->geom.heads * d->geom.sectors);
     548                idx = blk_idx % (d->geom.heads * d->geom.sectors);
     549
     550                h = idx / d->geom.sectors;
     551                s = 1 + (idx % d->geom.sectors);
     552        } else {
     553                /* Compute LBA-28 coordinates. */
     554                s = blk_idx & 0xff;             /* bits 0-7 */
     555                c = (blk_idx >> 8) & 0xffff;    /* bits 8-23 */
     556                h = (blk_idx >> 24) & 0x0f;     /* bits 24-27 */
     557        }
    514558
    515559        /* New value for Drive/Head register */
    516560        drv_head =
    517561            ((disk_id != 0) ? DHR_DRV : 0) |
     562            ((d->amode != am_chs) ? DHR_LBA : 0) |
    518563            (h & 0x0f);
    519564
  • uspace/srv/bd/ata_bd/ata_bd.h

    rb94334f ra99cf073  
    116116
    117117enum drive_head_bits {
    118         DHR_DRV         = 0x10
     118        DHR_LBA         = 0x40, /**< Use LBA addressing mode */
     119        DHR_DRV         = 0x10  /**< Select device 1 */
    119120};
    120121
     
    190191} identify_data_t;
    191192
     193enum ata_caps {
     194        cap_iordy       = 0x0800,
     195        cap_iordy_cbd   = 0x0400,
     196        cap_lba         = 0x0200,
     197        cap_dma         = 0x0100
     198};
     199
     200/** Block addressing mode. */
     201enum addr_mode {
     202        am_chs,
     203        am_lba28
     204};
     205
    192206typedef struct {
    193207        bool present;
    194         unsigned heads;
    195         unsigned cylinders;
    196         unsigned sectors;
     208        enum addr_mode amode;
     209
     210        /*
     211         * Geometry. Only valid if operating in CHS mode.
     212         */
     213        struct {
     214                unsigned heads;
     215                unsigned cylinders;
     216                unsigned sectors;
     217        } geom;
     218
    197219        uint64_t blocks;
    198220
Note: See TracChangeset for help on using the changeset viewer.