Changes in / [e5792d1:a71c158] in mainline


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

Legend:

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

    re5792d1 ra71c158  
    5050#include <as.h>
    5151#include <fibril_sync.h>
    52 #include <string.h>
    5352#include <devmap.h>
    5453#include <sys/types.h>
     
    8685static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,
    8786    const void *buf);
    88 static int disk_init(disk_t *d, int disk_id);
    89 static int drive_identify(int drive_id, void *buf);
    90 static void disk_print_summary(disk_t *d);
     87static int drive_identify(int drive_id, disk_t *d);
    9188static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus,
    9289    unsigned timeout);
     
    109106                fflush(stdout);
    110107
    111                 rc = disk_init(&disk[i], i);
     108                rc = drive_identify(i, &disk[i]);
    112109
    113110                if (rc == EOK) {
    114                         disk_print_summary(&disk[i]);
     111                        printf("%u cylinders, %u heads, %u sectors\n",
     112                            disk[i].cylinders, disk[i].heads, disk[i].sectors);
    115113                } else {
    116114                        printf("Not found.\n");
     
    149147}
    150148
    151 /** Print one-line device summary. */
    152 static void disk_print_summary(disk_t *d)
    153 {
    154         uint64_t mbytes;
    155 
    156         printf("%s: ", d->model);
    157 
    158         if (d->amode == am_chs) {
    159                 printf("CHS %u cylinders, %u heads, %u sectors",
    160                     disk->geom.cylinders, disk->geom.heads, disk->geom.sectors);
    161         } else {
    162                 printf("LBA-28");
    163         }
    164 
    165         printf(" %llu blocks", d->blocks, d->blocks / (2 * 1024));
    166 
    167         mbytes = d->blocks / (2 * 1024);
    168         if (mbytes > 0)
    169                 printf(" %llu MB.", mbytes);
    170 
    171         printf("\n");
    172 }
    173149
    174150/** Register driver and enable device I/O. */
     
    275251}
    276252
    277 /** Initialize a disk.
    278  *
    279  * Probes for a disk, determines its parameters and initializes
    280  * the disk structure.
    281  */
    282 static int disk_init(disk_t *d, int disk_id)
    283 {
    284         identify_data_t idata;
    285         uint8_t model[40];
    286         uint16_t w;
    287         uint8_t c;
    288         size_t pos, len;
    289         int rc;
    290         int i;
    291 
    292         rc = drive_identify(disk_id, &idata);
    293         if (rc != EOK) {
    294                 d->present = false;
    295                 return rc;
    296         }
    297 
    298         if ((idata.caps & cap_lba) == 0) {
    299                 /* Device only supports CHS addressing. */
    300                 d->amode = am_chs;
    301 
    302                 d->geom.cylinders = idata.cylinders;
    303                 d->geom.heads = idata.heads;
    304                 d->geom.sectors = idata.sectors;
    305 
    306                 d->blocks = d->geom.cylinders * d->geom.heads * d->geom.sectors;
    307         } else {
    308                 /* Device supports LBA-28. */
    309                 d->amode = am_lba28;
    310 
    311                 d->geom.cylinders = 0;
    312                 d->geom.heads = 0;
    313                 d->geom.sectors = 0;
    314 
    315                 d->blocks =
    316                     (uint32_t) idata.total_lba_sec0 |
    317                     ((uint32_t) idata.total_lba_sec1 << 16);
    318         }
    319 
    320         /*
    321          * Convert model name to string representation.
    322          */
    323         for (i = 0; i < 20; i++) {
    324                 w = idata.model_name[i];
    325                 model[2 * i] = w >> 8;
    326                 model[2 * i + 1] = w & 0x00ff;
    327         }
    328 
    329         len = 40;
    330         while (len > 0 && model[len - 1] == 0x20)
    331                 --len;
    332 
    333         pos = 0;
    334         for (i = 0; i < len; ++i) {
    335                 c = model[i];
    336                 if (c >= 0x80) c = '?';
    337 
    338                 chr_encode(c, d->model, &pos, 40);
    339         }
    340         d->model[pos] = '\0';
    341 
    342         d->present = true;
    343         fibril_mutex_initialize(&d->lock);
    344 
    345         return EOK;
    346 }
    347 
    348253/** Transfer a logical block from/to the device.
    349254 *
     
    389294/** Issue IDENTIFY command.
    390295 *
    391  * Reads @c identify data into the provided buffer. This is used to detect
    392  * whether an ATA device is present and if so, to determine its parameters.
     296 * This is used to detect whether an ATA device is present and if so,
     297 * to determine its parameters. The parameters are written to @a d.
    393298 *
    394299 * @param disk_id       Device ID, 0 or 1.
    395  * @param buf           Pointer to a 512-byte buffer.
    396  */
    397 static int drive_identify(int disk_id, void *buf)
     300 * @param d             Device structure to store parameters in.
     301 */
     302static int drive_identify(int disk_id, disk_t *d)
    398303{
    399304        uint16_t data;
     
    403308
    404309        drv_head = ((disk_id != 0) ? DHR_DRV : 0);
     310        d->present = false;
    405311
    406312        if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     
    424330
    425331        if ((status & SR_DRQ) != 0) {
     332//              for (i = 0; i < block_size / 2; i++) {
     333//                      data = pio_read_16(&cmd->data_port);
     334//                      ((uint16_t *) buf)[i] = data;
     335//              }
     336
    426337                for (i = 0; i < block_size / 2; i++) {
    427338                        data = pio_read_16(&cmd->data_port);
    428                         ((uint16_t *) buf)[i] = data;
     339
     340                        switch (i) {
     341                        case 1: d->cylinders = data; break;
     342                        case 3: d->heads = data; break;
     343                        case 6: d->sectors = data; break;
     344                        }
    429345                }
    430346        }
     
    432348        if ((status & SR_ERR) != 0)
    433349                return EIO;
     350
     351        d->blocks = d->cylinders * d->heads * d->sectors;
     352
     353        d->present = true;
     354        fibril_mutex_initialize(&d->lock);
    434355
    435356        return EOK;
     
    462383                return EINVAL;
    463384
    464         if (d->amode == am_chs) {
    465                 /* Compute CHS coordinates. */
    466                 c = blk_idx / (d->geom.heads * d->geom.sectors);
    467                 idx = blk_idx % (d->geom.heads * d->geom.sectors);
    468 
    469                 h = idx / d->geom.sectors;
    470                 s = 1 + (idx % d->geom.sectors);
    471         } else {
    472                 /* Compute LBA-28 coordinates. */
    473                 s = blk_idx & 0xff;             /* bits 0-7 */
    474                 c = (blk_idx >> 8) & 0xffff;    /* bits 8-23 */
    475                 h = (blk_idx >> 24) & 0x0f;     /* bits 24-27 */
    476         }
     385        /* Compute CHS. */
     386        c = blk_idx / (d->heads * d->sectors);
     387        idx = blk_idx % (d->heads * d->sectors);
     388
     389        h = idx / d->sectors;
     390        s = 1 + (idx % d->sectors);
    477391
    478392        /* New value for Drive/Head register */
    479393        drv_head =
    480394            ((disk_id != 0) ? DHR_DRV : 0) |
    481             ((d->amode != am_chs) ? DHR_LBA : 0) |
    482395            (h & 0x0f);
    483396
     
    551464                return EINVAL;
    552465
    553         if (d->amode == am_chs) {
    554                 /* Compute CHS coordinates. */
    555                 c = blk_idx / (d->geom.heads * d->geom.sectors);
    556                 idx = blk_idx % (d->geom.heads * d->geom.sectors);
    557 
    558                 h = idx / d->geom.sectors;
    559                 s = 1 + (idx % d->geom.sectors);
    560         } else {
    561                 /* Compute LBA-28 coordinates. */
    562                 s = blk_idx & 0xff;             /* bits 0-7 */
    563                 c = (blk_idx >> 8) & 0xffff;    /* bits 8-23 */
    564                 h = (blk_idx >> 24) & 0x0f;     /* bits 24-27 */
    565         }
     466        /* Compute CHS. */
     467        c = blk_idx / (d->heads * d->sectors);
     468        idx = blk_idx % (d->heads * d->sectors);
     469
     470        h = idx / d->sectors;
     471        s = 1 + (idx % d->sectors);
    566472
    567473        /* New value for Drive/Head register */
    568474        drv_head =
    569475            ((disk_id != 0) ? DHR_DRV : 0) |
    570             ((d->amode != am_chs) ? DHR_LBA : 0) |
    571476            (h & 0x0f);
    572477
  • uspace/srv/bd/ata_bd/ata_bd.h

    re5792d1 ra71c158  
    3838#include <sys/types.h>
    3939#include <fibril_sync.h>
    40 #include <string.h>
    4140
    4241enum {
     
    116115
    117116enum drive_head_bits {
    118         DHR_LBA         = 0x40, /**< Use LBA addressing mode */
    119         DHR_DRV         = 0x10  /**< Select device 1 */
     117        DHR_DRV         = 0x10
    120118};
    121119
     
    144142};
    145143
    146 /** Data returned from @c identify command. */
    147 typedef struct {
    148         uint16_t gen_conf;
    149         uint16_t cylinders;
    150         uint16_t _res2;
    151         uint16_t heads;
    152         uint16_t _vs4;
    153         uint16_t _vs5;
    154         uint16_t sectors;
    155         uint16_t _vs7;
    156         uint16_t _vs8;
    157         uint16_t _vs9;
    158         uint16_t serial_number[10];
    159         uint16_t _vs20;
    160         uint16_t _vs21;
    161         uint16_t vs_bytes;
    162         uint16_t firmware_rev[4];
    163         uint16_t model_name[20];
    164         uint16_t max_rw_multiple;
    165         uint16_t _res48;
    166         uint16_t caps;
    167         uint16_t _res50;
    168         uint16_t pio_timing;
    169         uint16_t dma_timing;
    170         uint16_t validity;
    171         uint16_t cur_cyl;
    172         uint16_t cur_heads;
    173         uint16_t cur_sectors;
    174         uint16_t cur_capacity0;
    175         uint16_t cur_capacity1;
    176         uint16_t mss;
    177         uint16_t total_lba_sec0;
    178         uint16_t total_lba_sec1;
    179         uint16_t sw_dma;
    180         uint16_t mw_dma;
    181         uint16_t pio_modes;
    182         uint16_t min_mw_dma_cycle;
    183         uint16_t rec_mw_dma_cycle;
    184         uint16_t min_raw_pio_cycle;
    185         uint16_t min_iordy_pio_cycle;
    186         uint16_t _res69;
    187         uint16_t _res70;
    188         uint16_t _res71[1 + 127 - 71];
    189         uint16_t _vs128[1 + 159 - 128];
    190         uint16_t _res160[1 + 255 - 160];
    191 } identify_data_t;
    192 
    193 enum 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. */
    201 enum addr_mode {
    202         am_chs,
    203         am_lba28
    204 };
    205 
    206144typedef struct {
    207145        bool present;
    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 
     146        unsigned heads;
     147        unsigned cylinders;
     148        unsigned sectors;
    219149        uint64_t blocks;
    220 
    221         char model[STR_BOUNDS(40) + 1];
    222150
    223151        fibril_mutex_t lock;
Note: See TracChangeset for help on using the changeset viewer.