Changeset 96cbd18 in mainline


Ignore:
Timestamp:
2013-06-21T18:54:29Z (12 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
89ac5513, ccf282f
Parents:
7901ac8
Message:

Encapsulate controller state in ata_bd.

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

Legend:

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

    r7901ac8 r96cbd18  
    11/*
    2  * Copyright (c) 2009 Jiri Svoboda
     2 * Copyright (c) 2013 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3535 * @brief ATA disk driver
    3636 *
    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.
     37 * This driver supports CHS, 28-bit and 48-bit LBA addressing, as well as
     38 * PACKET devices. It only uses PIO transfers. There is no support DMA
     39 * or any other fancy features such as S.M.A.R.T, removable devices, etc.
    4040 *
    4141 * This driver is based on the ATA-1, ATA-2, ATA-3 and ATA/ATAPI-4 through 7
     
    8080static const size_t identify_data_size = 512;
    8181
    82 /** I/O base address of the command registers. */
    83 static uintptr_t cmd_physical;
    84 /** I/O base address of the control registers. */
    85 static uintptr_t ctl_physical;
    86 
    8782/** I/O base addresses for legacy (ISA-compatible) controllers. */
    8883static ata_base_t legacy_base[LEGACY_CTLS] = {
     
    9388};
    9489
    95 static ata_cmd_t *cmd;
    96 static ata_ctl_t *ctl;
    97 
    98 /** Per-disk state. */
    99 static disk_t ata_disk[MAX_DISKS];
     90/** Controller */
     91static ata_ctrl_t ata_ctrl;
    10092
    10193static void print_syntax(void);
    102 static int ata_bd_init(void);
     94static int ata_bd_init(ata_ctrl_t *ctrl);
    10395static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *);
    10496
     
    117109static int ata_rcmd_write(disk_t *disk, uint64_t ba, size_t cnt,
    118110    const void *buf);
    119 static int disk_init(disk_t *d, int disk_id);
     111static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id);
    120112static int drive_identify(disk_t *disk, void *buf);
    121113static int identify_pkt_dev(disk_t *disk, void *buf);
     
    129121static void disk_print_summary(disk_t *d);
    130122static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc);
    131 static void coord_sc_program(const block_coord_t *bc, uint16_t scnt);
    132 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus,
    133     unsigned timeout);
     123static void coord_sc_program(ata_ctrl_t *ctrl, const block_coord_t *bc,
     124    uint16_t scnt);
     125static int wait_status(ata_ctrl_t *ctrl, unsigned set, unsigned n_reset,
     126    uint8_t *pstatus, unsigned timeout);
    134127
    135128static bd_ops_t ata_bd_ops = {
     
    160153        unsigned ctl_num;
    161154        char *eptr;
     155        ata_ctrl_t *ctrl = &ata_ctrl;
    162156
    163157        printf(NAME ": ATA disk driver\n");
     
    174168        }
    175169
    176         cmd_physical = legacy_base[ctl_num - 1].cmd;
    177         ctl_physical = legacy_base[ctl_num - 1].ctl;
    178 
    179         printf("I/O address %p/%p\n", (void *) cmd_physical,
    180             (void *) ctl_physical);
    181 
    182         if (ata_bd_init() != EOK)
     170        ctrl->cmd_physical = legacy_base[ctl_num - 1].cmd;
     171        ctrl->ctl_physical = legacy_base[ctl_num - 1].ctl;
     172
     173        printf("I/O address %p/%p\n", (void *) ctrl->cmd_physical,
     174            (void *) ctrl->ctl_physical);
     175
     176        if (ata_bd_init(ctrl) != EOK)
    183177                return -1;
    184178
     
    187181                fflush(stdout);
    188182
    189                 rc = disk_init(&ata_disk[i], i);
     183                rc = disk_init(ctrl, &ctrl->disk[i], i);
    190184
    191185                if (rc == EOK) {
    192                         disk_print_summary(&ata_disk[i]);
     186                        disk_print_summary(&ctrl->disk[i]);
    193187                } else {
    194188                        printf("Not found.\n");
     
    200194        for (i = 0; i < MAX_DISKS; i++) {
    201195                /* Skip unattached drives. */
    202                 if (ata_disk[i].present == false)
     196                if (ctrl->disk[i].present == false)
    203197                        continue;
    204198               
    205199                snprintf(name, 16, "%s/ata%udisk%d", NAMESPACE, ctl_num, i);
    206                 rc = loc_service_register(name, &ata_disk[i].service_id);
     200                rc = loc_service_register(name, &ctrl->disk[i].service_id);
    207201                if (rc != EOK) {
    208202                        printf(NAME ": Unable to register device %s.\n", name);
     
    267261
    268262/** Register driver and enable device I/O. */
    269 static int ata_bd_init(void)
     263static int ata_bd_init(ata_ctrl_t *ctrl)
    270264{
    271265        async_set_client_connection(ata_bd_connection);
     
    277271       
    278272        void *vaddr;
    279         rc = pio_enable((void *) cmd_physical, sizeof(ata_cmd_t), &vaddr);
     273        rc = pio_enable((void *) ctrl->cmd_physical, sizeof(ata_cmd_t), &vaddr);
    280274        if (rc != EOK) {
    281275                printf("%s: Could not initialize device I/O space.\n", NAME);
     
    283277        }
    284278       
    285         cmd = vaddr;
     279        ctrl->cmd = vaddr;
    286280       
    287         rc = pio_enable((void *) ctl_physical, sizeof(ata_ctl_t), &vaddr);
     281        rc = pio_enable((void *) ctrl->ctl_physical, sizeof(ata_ctl_t), &vaddr);
    288282        if (rc != EOK) {
    289283                printf("%s: Could not initialize device I/O space.\n", NAME);
     
    291285        }
    292286       
    293         ctl = vaddr;
     287        ctrl->ctl = vaddr;
    294288       
    295289        return EOK;
     
    309303        disk = NULL;
    310304        for (i = 0; i < MAX_DISKS; i++)
    311                 if (ata_disk[i].service_id == dsid)
    312                         disk = &ata_disk[i];
     305                if (ata_ctrl.disk[i].service_id == dsid)
     306                        disk = &ata_ctrl.disk[i];
    313307
    314308        if (disk == NULL || disk->present == false) {
     
    325319 * the disk structure.
    326320 */
    327 static int disk_init(disk_t *d, int disk_id)
     321static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id)
    328322{
    329323        identify_data_t idata;
     
    337331        unsigned i;
    338332
     333        d->ctrl = ctrl;
    339334        d->disk_id = disk_id;
    340335        d->present = false;
     
    362357                 * the byte count registers. So, only check these.
    363358                 */
    364                 bc = ((uint16_t)pio_read_8(&cmd->cylinder_high) << 8) |
    365                     pio_read_8(&cmd->cylinder_low);
     359                bc = ((uint16_t)pio_read_8(&ctrl->cmd->cylinder_high) << 8) |
     360                    pio_read_8(&ctrl->cmd->cylinder_low);
    366361
    367362                if (bc == PDEV_SIGNATURE_BC) {
     
    576571static int drive_identify(disk_t *disk, void *buf)
    577572{
     573        ata_ctrl_t *ctrl = disk->ctrl;
    578574        uint16_t data;
    579575        uint8_t status;
     
    583579        drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
    584580
    585         if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     581        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    586582                return ETIMEOUT;
    587583
    588         pio_write_8(&cmd->drive_head, drv_head);
     584        pio_write_8(&ctrl->cmd->drive_head, drv_head);
    589585
    590586        /*
     
    593589         * set after issuing the command.
    594590         */
    595         if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     591        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    596592                return ETIMEOUT;
    597593
    598         pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
    599 
    600         if (wait_status(0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
     594        pio_write_8(&ctrl->cmd->command, CMD_IDENTIFY_DRIVE);
     595
     596        if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
    601597                return ETIMEOUT;
    602598
     
    609605        }
    610606
    611         if (wait_status(SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
     607        if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
    612608                return ETIMEOUT;
    613609
     
    615611
    616612        for (i = 0; i < identify_data_size / 2; i++) {
    617                 data = pio_read_16(&cmd->data_port);
     613                data = pio_read_16(&ctrl->cmd->data_port);
    618614                ((uint16_t *) buf)[i] = data;
    619615        }
     
    632628static int identify_pkt_dev(disk_t *disk, void *buf)
    633629{
     630        ata_ctrl_t *ctrl = disk->ctrl;
    634631        uint16_t data;
    635632        uint8_t status;
     
    639636        drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
    640637
    641         if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    642                 return EIO;
    643 
    644         pio_write_8(&cmd->drive_head, drv_head);
     638        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     639                return EIO;
     640
     641        pio_write_8(&ctrl->cmd->drive_head, drv_head);
    645642
    646643        /* For ATAPI commands we do not need to wait for DRDY. */
    647         if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    648                 return EIO;
    649 
    650         pio_write_8(&cmd->command, CMD_IDENTIFY_PKT_DEV);
    651 
    652         if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK)
     644        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     645                return EIO;
     646
     647        pio_write_8(&ctrl->cmd->command, CMD_IDENTIFY_PKT_DEV);
     648
     649        if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK)
    653650                return EIO;
    654651
     
    657654        if ((status & SR_DRQ) != 0) {
    658655                for (i = 0; i < identify_data_size / 2; i++) {
    659                         data = pio_read_16(&cmd->data_port);
     656                        data = pio_read_16(&ctrl->cmd->data_port);
    660657                        ((uint16_t *) buf)[i] = data;
    661658                }
     
    681678    void *obuf, size_t obuf_size)
    682679{
     680        ata_ctrl_t *ctrl = disk->ctrl;
    683681        size_t i;
    684682        uint8_t status;
     
    693691            ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
    694692
    695         if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) {
    696                 fibril_mutex_unlock(&disk->lock);
    697                 return EIO;
    698         }
    699 
    700         pio_write_8(&cmd->drive_head, drv_head);
    701 
    702         if (wait_status(0, ~(SR_BSY|SR_DRQ), NULL, TIMEOUT_BSY) != EOK) {
     693        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) {
     694                fibril_mutex_unlock(&disk->lock);
     695                return EIO;
     696        }
     697
     698        pio_write_8(&ctrl->cmd->drive_head, drv_head);
     699
     700        if (wait_status(ctrl, 0, ~(SR_BSY|SR_DRQ), NULL, TIMEOUT_BSY) != EOK) {
    703701                fibril_mutex_unlock(&disk->lock);
    704702                return EIO;
     
    706704
    707705        /* Byte count <- max. number of bytes we can read in one transfer. */
    708         pio_write_8(&cmd->cylinder_low, 0xfe);
    709         pio_write_8(&cmd->cylinder_high, 0xff);
    710 
    711         pio_write_8(&cmd->command, CMD_PACKET);
    712 
    713         if (wait_status(SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
     706        pio_write_8(&ctrl->cmd->cylinder_low, 0xfe);
     707        pio_write_8(&ctrl->cmd->cylinder_high, 0xff);
     708
     709        pio_write_8(&ctrl->cmd->command, CMD_PACKET);
     710
     711        if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
    714712                fibril_mutex_unlock(&disk->lock);
    715713                return EIO;
     
    718716        /* Write command packet. */
    719717        for (i = 0; i < (cpkt_size + 1) / 2; i++)
    720                 pio_write_16(&cmd->data_port, ((uint16_t *) cpkt)[i]);
    721 
    722         if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
     718                pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) cpkt)[i]);
     719
     720        if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
    723721                fibril_mutex_unlock(&disk->lock);
    724722                return EIO;
     
    731729
    732730        /* Read byte count. */
    733         data_size = (uint16_t) pio_read_8(&cmd->cylinder_low) +
    734             ((uint16_t) pio_read_8(&cmd->cylinder_high) << 8);
     731        data_size = (uint16_t) pio_read_8(&ctrl->cmd->cylinder_low) +
     732            ((uint16_t) pio_read_8(&ctrl->cmd->cylinder_high) << 8);
    735733
    736734        /* Check whether data fits into output buffer. */
     
    743741        /* Read data from the device buffer. */
    744742        for (i = 0; i < (data_size + 1) / 2; i++) {
    745                 val = pio_read_16(&cmd->data_port);
     743                val = pio_read_16(&ctrl->cmd->data_port);
    746744                ((uint16_t *) obuf)[i] = val;
    747745        }
     
    868866    void *buf)
    869867{
     868        ata_ctrl_t *ctrl = disk->ctrl;
    870869        size_t i;
    871870        uint16_t data;
     
    891890        /* Program a Read Sectors operation. */
    892891
    893         if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
    894                 fibril_mutex_unlock(&disk->lock);
    895                 return EIO;
    896         }
    897 
    898         pio_write_8(&cmd->drive_head, drv_head);
    899 
    900         if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
     892        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
     893                fibril_mutex_unlock(&disk->lock);
     894                return EIO;
     895        }
     896
     897        pio_write_8(&ctrl->cmd->drive_head, drv_head);
     898
     899        if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
    901900                fibril_mutex_unlock(&disk->lock);
    902901                return EIO;
     
    904903
    905904        /* Program block coordinates into the device. */
    906         coord_sc_program(&bc, 1);
    907 
    908         pio_write_8(&cmd->command, disk->amode == am_lba48 ?
     905        coord_sc_program(ctrl, &bc, 1);
     906
     907        pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ?
    909908            CMD_READ_SECTORS_EXT : CMD_READ_SECTORS);
    910909
    911         if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
     910        if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
    912911                fibril_mutex_unlock(&disk->lock);
    913912                return EIO;
     
    918917
    919918                for (i = 0; i < disk->block_size / 2; i++) {
    920                         data = pio_read_16(&cmd->data_port);
     919                        data = pio_read_16(&ctrl->cmd->data_port);
    921920                        ((uint16_t *) buf)[i] = data;
    922921                }
     
    942941    const void *buf)
    943942{
     943        ata_ctrl_t *ctrl = disk->ctrl;
    944944        size_t i;
    945945        uint8_t status;
     
    964964        /* Program a Write Sectors operation. */
    965965
    966         if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
    967                 fibril_mutex_unlock(&disk->lock);
    968                 return EIO;
    969         }
    970 
    971         pio_write_8(&cmd->drive_head, drv_head);
    972 
    973         if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
     966        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
     967                fibril_mutex_unlock(&disk->lock);
     968                return EIO;
     969        }
     970
     971        pio_write_8(&ctrl->cmd->drive_head, drv_head);
     972
     973        if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
    974974                fibril_mutex_unlock(&disk->lock);
    975975                return EIO;
     
    977977
    978978        /* Program block coordinates into the device. */
    979         coord_sc_program(&bc, 1);
    980 
    981         pio_write_8(&cmd->command, disk->amode == am_lba48 ?
     979        coord_sc_program(ctrl, &bc, 1);
     980
     981        pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ?
    982982            CMD_WRITE_SECTORS_EXT : CMD_WRITE_SECTORS);
    983983
    984         if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
     984        if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
    985985                fibril_mutex_unlock(&disk->lock);
    986986                return EIO;
     
    991991
    992992                for (i = 0; i < disk->block_size / 2; i++) {
    993                         pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
     993                        pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) buf)[i]);
    994994                }
    995995        }
     
    10601060 *
    10611061 * Note that bc->h must be programmed separately into the device/head register.
    1062  */
    1063 static void coord_sc_program(const block_coord_t *bc, uint16_t scnt)
    1064 {
     1062 *
     1063 * @param ctrl          Controller
     1064 * @param bc            Block coordinates
     1065 * @param scnt          Sector count
     1066 */
     1067static void coord_sc_program(ata_ctrl_t *ctrl, const block_coord_t *bc,
     1068    uint16_t scnt)
     1069{
     1070        ata_cmd_t *cmd = ctrl->cmd;
     1071
    10651072        if (bc->amode == am_lba48) {
    10661073                /* Write high-order bits. */
     
    10801087/** Wait until some status bits are set and some are reset.
    10811088 *
    1082  * Example: wait_status(SR_DRDY, ~SR_BSY) waits for SR_DRDY to become
     1089 * Example: wait_status(ctrl, SR_DRDY, ~SR_BSY, ...) waits for SR_DRDY to become
    10831090 * set and SR_BSY to become reset.
    10841091 *
     1092 * @param ctrl          Controller
    10851093 * @param set           Combination if bits which must be all set.
    10861094 * @param n_reset       Negated combination of bits which must be all reset.
     
    10901098 * @return              EOK on success, EIO on timeout.
    10911099 */
    1092 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus,
    1093     unsigned timeout)
     1100static int wait_status(ata_ctrl_t *ctrl, unsigned set, unsigned n_reset,
     1101    uint8_t *pstatus, unsigned timeout)
    10941102{
    10951103        uint8_t status;
    10961104        int cnt;
    10971105
    1098         status = pio_read_8(&cmd->status);
     1106        status = pio_read_8(&ctrl->cmd->status);
    10991107
    11001108        /*
     
    11101118                if (cnt <= 0) break;
    11111119
    1112                 status = pio_read_8(&cmd->status);
     1120                status = pio_read_8(&ctrl->cmd->status);
    11131121        }
    11141122
     
    11191127                if (cnt <= 0) break;
    11201128
    1121                 status = pio_read_8(&cmd->status);
     1129                status = pio_read_8(&ctrl->cmd->status);
    11221130        }
    11231131
  • uspace/srv/bd/ata_bd/ata_bd.h

    r7901ac8 r96cbd18  
    9595typedef struct {
    9696        bool present;
     97        struct ata_ctrl *ctrl;
    9798
    9899        /** Device type */
     
    122123} disk_t;
    123124
     125/** ATA controller */
     126typedef struct ata_ctrl {
     127        /** I/O base address of the command registers */
     128        uintptr_t cmd_physical;
     129        /** I/O base address of the control registers */
     130        uintptr_t ctl_physical;
     131
     132        /** Command registers */
     133        ata_cmd_t *cmd;
     134        /** Control registers */
     135        ata_ctl_t *ctl;
     136
     137        /** Per-disk state. */
     138        disk_t disk[MAX_DISKS];
     139} ata_ctrl_t;
     140
    124141#endif
    125142
Note: See TracChangeset for help on using the changeset viewer.