Changeset 882bc4b in mainline


Ignore:
Timestamp:
2013-07-05T08:19:00Z (11 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ca4730a5
Parents:
d8b47eca
Message:

Factor out ATA PIO data in/out protocols, per standard.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/block/ata_bd/ata_bd.c

    rd8b47eca r882bc4b  
    100100    const void *buf);
    101101static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id);
    102 static int drive_identify(disk_t *disk, void *buf);
    103 static int identify_pkt_dev(disk_t *disk, void *buf);
     102static int ata_identify_dev(disk_t *disk, void *buf);
     103static int ata_identify_pkt_dev(disk_t *disk, void *buf);
    104104static int ata_cmd_packet(disk_t *disk, const void *cpkt, size_t cpkt_size,
    105105    void *obuf, size_t obuf_size);
     
    353353
    354354        /* Try identify command. */
    355         rc = drive_identify(d, &idata);
     355        rc = ata_identify_dev(d, &idata);
    356356        if (rc == EOK) {
    357357                /* Success. It's a register (non-packet) device. */
     
    373373
    374374                if (bc == PDEV_SIGNATURE_BC) {
    375                         rc = identify_pkt_dev(d, &idata);
     375                        rc = ata_identify_pkt_dev(d, &idata);
    376376                        if (rc == EOK) {
    377377                                /* We have a packet device. */
     
    570570}
    571571
    572 /** Issue IDENTIFY command.
     572/** PIO data-in command protocol. */
     573static int ata_pio_data_in(disk_t *disk, void *obuf, size_t obuf_size,
     574    size_t blk_size, size_t nblocks)
     575{
     576        ata_ctrl_t *ctrl = disk->ctrl;
     577        uint16_t data;
     578        size_t i;
     579        uint8_t status;
     580
     581        /* XXX Support multiple blocks */
     582        assert(nblocks == 1);
     583        assert(blk_size % 2 == 0);
     584
     585        if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK)
     586                return EIO;
     587
     588        if ((status & SR_DRQ) != 0) {
     589                /* Read data from the device buffer. */
     590
     591                for (i = 0; i < blk_size / 2; i++) {
     592                        data = pio_read_16(&ctrl->cmd->data_port);
     593                        ((uint16_t *) obuf)[i] = data;
     594                }
     595        }
     596
     597        if ((status & SR_ERR) != 0)
     598                return EIO;
     599
     600        return EOK;
     601}
     602
     603/** PIO data-out command protocol. */
     604static int ata_pio_data_out(disk_t *disk, const void *buf, size_t buf_size,
     605    size_t blk_size, size_t nblocks)
     606{
     607        ata_ctrl_t *ctrl = disk->ctrl;
     608        size_t i;
     609        uint8_t status;
     610
     611        /* XXX Support multiple blocks */
     612        assert(nblocks == 1);
     613        assert(blk_size % 2 == 0);
     614
     615        if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK)
     616                return EIO;
     617
     618        if ((status & SR_DRQ) != 0) {
     619                /* Write data to the device buffer. */
     620
     621                for (i = 0; i < blk_size / 2; i++) {
     622                        pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) buf)[i]);
     623                }
     624        }
     625
     626        if (status & SR_ERR)
     627                return EIO;
     628
     629        return EOK;
     630}
     631
     632/** Issue IDENTIFY DEVICE command.
    573633 *
    574634 * Reads @c identify data into the provided buffer. This is used to detect
     
    581641 *                      not present). EIO if device responds with error.
    582642 */
    583 static int drive_identify(disk_t *disk, void *buf)
     643static int ata_identify_dev(disk_t *disk, void *buf)
    584644{
    585645        ata_ctrl_t *ctrl = disk->ctrl;
    586         uint16_t data;
    587646        uint8_t status;
    588647        uint8_t drv_head;
    589         size_t i;
    590648
    591649        drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
     
    613671         * the caller to check for one.
    614672         */
    615         if ((status & SR_ERR) != 0) {
    616                 return EIO;
    617         }
    618 
     673        if ((status & SR_ERR) != 0)
     674                return EIO;
     675
     676        /*
     677         * For probing purposes we need to wait for some status bit to become
     678         * active - otherwise we could be fooled just by receiving all zeroes.
     679         */
    619680        if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
    620681                return ETIMEOUT;
    621682
    622         /* Read data from the disk buffer. */
    623 
    624         for (i = 0; i < identify_data_size / 2; i++) {
    625                 data = pio_read_16(&ctrl->cmd->data_port);
    626                 ((uint16_t *) buf)[i] = data;
    627         }
    628 
    629         return EOK;
     683        return ata_pio_data_in(disk, buf, identify_data_size,
     684            identify_data_size, 1);
    630685}
    631686
     
    638693 * @param buf           Pointer to a 512-byte buffer.
    639694 */
    640 static int identify_pkt_dev(disk_t *disk, void *buf)
     695static int ata_identify_pkt_dev(disk_t *disk, void *buf)
    641696{
    642697        ata_ctrl_t *ctrl = disk->ctrl;
    643         uint16_t data;
    644         uint8_t status;
    645698        uint8_t drv_head;
    646         size_t i;
    647699
    648700        drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
     
    659711        pio_write_8(&ctrl->cmd->command, CMD_IDENTIFY_PKT_DEV);
    660712
    661         if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK)
    662                 return EIO;
    663 
    664         /* Read data from the device buffer. */
    665 
    666         if ((status & SR_DRQ) != 0) {
    667                 for (i = 0; i < identify_data_size / 2; i++) {
    668                         data = pio_read_16(&ctrl->cmd->data_port);
    669                         ((uint16_t *) buf)[i] = data;
    670                 }
    671         }
    672 
    673         if ((status & SR_ERR) != 0)
    674                 return EIO;
    675 
    676         return EOK;
     713        return ata_pio_data_in(disk, buf, identify_data_size,
     714            identify_data_size, 1);
    677715}
    678716
     
    864902}
    865903
    866 /** Read a physical from the device.
     904/** Read a physical block from the device.
    867905 *
    868906 * @param disk          Disk
     
    877915{
    878916        ata_ctrl_t *ctrl = disk->ctrl;
    879         size_t i;
    880         uint16_t data;
    881         uint8_t status;
    882917        uint8_t drv_head;
    883918        block_coord_t bc;
     919        int rc;
    884920
    885921        /* Silence warning. */
     
    918954            CMD_READ_SECTORS_EXT : CMD_READ_SECTORS);
    919955
    920         if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
    921                 fibril_mutex_unlock(&ctrl->lock);
    922                 return EIO;
    923         }
    924 
    925         if ((status & SR_DRQ) != 0) {
    926                 /* Read data from the device buffer. */
    927 
    928                 for (i = 0; i < disk->block_size / 2; i++) {
    929                         data = pio_read_16(&ctrl->cmd->data_port);
    930                         ((uint16_t *) buf)[i] = data;
    931                 }
    932         }
     956        rc = ata_pio_data_in(disk, buf, blk_cnt * disk->block_size,
     957            disk->block_size, blk_cnt);
    933958
    934959        fibril_mutex_unlock(&ctrl->lock);
    935960
    936         if ((status & SR_ERR) != 0)
    937                 return EIO;
    938 
    939         return EOK;
     961        return rc;
    940962}
    941963
     
    953975{
    954976        ata_ctrl_t *ctrl = disk->ctrl;
    955         size_t i;
    956         uint8_t status;
    957977        uint8_t drv_head;
    958978        block_coord_t bc;
     979        int rc;
    959980
    960981        /* Silence warning. */
     
    9931014            CMD_WRITE_SECTORS_EXT : CMD_WRITE_SECTORS);
    9941015
    995         if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
    996                 fibril_mutex_unlock(&ctrl->lock);
    997                 return EIO;
    998         }
    999 
    1000         if ((status & SR_DRQ) != 0) {
    1001                 /* Write data to the device buffer. */
    1002 
    1003                 for (i = 0; i < disk->block_size / 2; i++) {
    1004                         pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) buf)[i]);
    1005                 }
    1006         }
     1016        rc = ata_pio_data_out(disk, buf, cnt * disk->block_size,
     1017            disk->block_size, cnt);
    10071018
    10081019        fibril_mutex_unlock(&ctrl->lock);
    1009 
    1010         if (status & SR_ERR)
    1011                 return EIO;
    1012 
    1013         return EOK;
     1020        return rc;
    10141021}
    10151022
Note: See TracChangeset for help on using the changeset viewer.