Changeset 7a56e33e in mainline


Ignore:
Timestamp:
2011-01-29T05:10:07Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
88743b5
Parents:
ae0300b5
Message:

Detection of ATA packet devices.

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

Legend:

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

    rae0300b5 r7a56e33e  
    112112static int disk_init(disk_t *d, int disk_id);
    113113static int drive_identify(int drive_id, void *buf);
     114static int identify_pkt_dev(int dev_idx, void *buf);
    114115static void disk_print_summary(disk_t *d);
    115116static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc);
     
    204205        printf("%s: ", d->model);
    205206
    206         switch (d->amode) {
    207         case am_chs:
    208                 printf("CHS %u cylinders, %u heads, %u sectors",
    209                     disk->geom.cylinders, disk->geom.heads, disk->geom.sectors);
    210                 break;
    211         case am_lba28:
    212                 printf("LBA-28");
    213                 break;
    214         case am_lba48:
    215                 printf("LBA-48");
    216                 break;
     207        if (d->dev_type == ata_reg_dev) {
     208                switch (d->amode) {
     209                case am_chs:
     210                        printf("CHS %u cylinders, %u heads, %u sectors",
     211                            disk->geom.cylinders, disk->geom.heads,
     212                            disk->geom.sectors);
     213                        break;
     214                case am_lba28:
     215                        printf("LBA-28");
     216                        break;
     217                case am_lba48:
     218                        printf("LBA-48");
     219                        break;
     220                }
     221        } else {
     222                printf("PACKET");
    217223        }
    218224
     
    360366        unsigned i;
    361367
     368        d->present = false;
     369
     370        /* Try identify command. */
    362371        rc = drive_identify(disk_id, &idata);
    363         if (rc != EOK) {
    364                 d->present = false;
    365                 return rc;
    366         }
    367 
    368         if ((idata.caps & cap_lba) == 0) {
     372        if (rc == EOK) {
     373                /* Success. It's a register (non-packet) device. */
     374                printf("ATA register-only device found.\n");
     375                d->present = true;
     376                d->dev_type = ata_reg_dev;
     377        } else if (rc == EIO) {
     378                /*
     379                 * There is something, but not a register device.
     380                 * It could be a packet device.
     381                 */
     382                rc = identify_pkt_dev(disk_id, &idata);
     383                if (rc == EOK) {
     384                        /* We have a packet device. */
     385                        d->present = true;
     386                        d->dev_type = ata_pkt_dev;
     387                } else {
     388                        /* Nope. Something's there, but not recognized. */
     389                }
     390        } else {
     391                /* Operation timed out. That means there is no device there. */
     392        }
     393
     394        if (d->present == false)
     395                return EIO;
     396
     397        printf("device caps: 0x%04x\n", idata.caps);
     398        if (d->dev_type == ata_pkt_dev) {
     399                /* Packet device */
     400                d->amode = 0;
     401
     402                d->geom.cylinders = 0;
     403                d->geom.heads = 0;
     404                d->geom.sectors = 0;
     405
     406                d->blocks = 0;
     407        } else if ((idata.caps & rd_cap_lba) == 0) {
    369408                /* Device only supports CHS addressing. */
    370409                d->amode = am_chs;
     
    474513 * @param disk_id       Device ID, 0 or 1.
    475514 * @param buf           Pointer to a 512-byte buffer.
     515 *
     516 * @return              ETIMEOUT on timeout (this can mean the device is
     517 *                      not present). EIO if device responds with error.
    476518 */
    477519static int drive_identify(int disk_id, void *buf)
     
    485527
    486528        if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    487                 return EIO;
     529                return ETIMEOUT;
    488530
    489531        pio_write_8(&cmd->drive_head, drv_head);
     
    494536         */
    495537        if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    496                 return EIO;
     538                return ETIMEOUT;
    497539
    498540        pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
    499541
    500542        if (wait_status(0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
    501                 return EIO;
     543                return ETIMEOUT;
    502544
    503545        /* Read data from the disk buffer. */
     546
     547        if ((status & SR_DRQ) != 0) {
     548                for (i = 0; i < block_size / 2; i++) {
     549                        data = pio_read_16(&cmd->data_port);
     550                        ((uint16_t *) buf)[i] = data;
     551                }
     552        }
     553
     554        if ((status & SR_ERR) != 0) {
     555                return EIO;
     556        }
     557
     558        return EOK;
     559}
     560
     561/** Issue Identify Packet Device command.
     562 *
     563 * Reads @c identify data into the provided buffer. This is used to detect
     564 * whether an ATAPI device is present and if so, to determine its parameters.
     565 *
     566 * @param dev_idx       Device index, 0 or 1.
     567 * @param buf           Pointer to a 512-byte buffer.
     568 */
     569static int identify_pkt_dev(int dev_idx, void *buf)
     570{
     571        uint16_t data;
     572        uint8_t status;
     573        uint8_t drv_head;
     574        size_t i;
     575
     576        drv_head = ((dev_idx != 0) ? DHR_DRV : 0);
     577
     578        if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     579                return EIO;
     580
     581        pio_write_8(&cmd->drive_head, drv_head);
     582
     583        /* For ATAPI commands we do not need to wait for DRDY. */
     584        if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     585                return EIO;
     586
     587        pio_write_8(&cmd->command, CMD_IDENTIFY_PKT_DEV);
     588
     589        if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK)
     590                return EIO;
     591
     592        /* Read data from the device buffer. */
    504593
    505594        if ((status & SR_DRQ) != 0) {
  • uspace/srv/bd/ata_bd/ata_bd.h

    rae0300b5 r7a56e33e  
    5353};
    5454
    55 /** Block addressing mode. */
    56 enum addr_mode {
     55enum ata_dev_type {
     56        ata_reg_dev,    /* Register device (no packet feature set support) */
     57        ata_pkt_dev     /* Packet device (supports packet feature set). */
     58};
     59
     60/** Register device block addressing mode. */
     61enum rd_addr_mode {
    5762        am_chs,         /**< CHS block addressing */
    5863        am_lba28,       /**< LBA-28 block addressing */
     
    6267/** Block coordinates */
    6368typedef struct {
    64         /** Addressing mode used */
    65         enum addr_mode amode;
     69        enum rd_addr_mode amode;
    6670
    6771        union {
     
    9094typedef struct {
    9195        bool present;
    92         enum addr_mode amode;
     96
     97        /** Device type */
     98        enum ata_dev_type dev_type;
     99
     100        /** Addressing mode to use (if register device) */
     101        enum rd_addr_mode amode;
    93102
    94103        /*
  • uspace/srv/bd/ata_bd/ata_hw.h

    rae0300b5 r7a56e33e  
    134134        CMD_WRITE_SECTORS       = 0x30,
    135135        CMD_WRITE_SECTORS_EXT   = 0x34,
     136        CMD_IDENTIFY_PKT_DEV    = 0xA1,
    136137        CMD_IDENTIFY_DRIVE      = 0xEC
    137138};
    138139
    139 /** Data returned from @c identify command. */
     140/** Data returned from identify device and identify packet device command. */
    140141typedef struct {
    141142        uint16_t gen_conf;
     
    159160        uint16_t max_rw_multiple;
    160161        uint16_t _res48;
    161         uint16_t caps;
     162        uint16_t caps;          /* Different meaning for packet device */
    162163        uint16_t _res50;
    163164        uint16_t pio_timing;
     
    214215} identify_data_t;
    215216
    216 enum ata_caps {
    217         cap_iordy       = 0x0800,
    218         cap_iordy_cbd   = 0x0400,
    219         cap_lba         = 0x0200,
    220         cap_dma         = 0x0100
     217/** Capability bits for register device. */
     218enum ata_regdev_caps {
     219        rd_cap_iordy            = 0x0800,
     220        rd_cap_iordy_cbd        = 0x0400,
     221        rd_cap_lba              = 0x0200,
     222        rd_cap_dma              = 0x0100
     223};
     224
     225/** Capability bits for packet device. */
     226enum ata_pktdev_caps {
     227        pd_cap_ildma            = 0x8000,
     228        pd_cap_cmdqueue         = 0x4000,
     229        pd_cap_overlap          = 0x2000,
     230        pd_cap_need_softreset   = 0x1000,       /* Obsolete (ATAPI-6) */
     231        pd_cap_iordy            = 0x0800,
     232        pd_cap_iordy_dis        = 0x0400,
     233        pd_cap_lba              = 0x0200,       /* Must be on */
     234        pd_cap_dma              = 0x0100
    221235};
    222236
Note: See TracChangeset for help on using the changeset viewer.