Changeset f3386d7 in mainline for uspace/drv/block/ata_bd/ata_bd.c


Ignore:
Timestamp:
2013-07-15T20:44:54Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f8d3df3
Parents:
273c976 (diff), a940f1d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

mainline changes

File:
1 moved

Legend:

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

    r273c976 rf3386d7  
    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
     
    4848 */
    4949
    50 #include <stdio.h>
    5150#include <ddi.h>
     51#include <ddf/log.h>
    5252#include <async.h>
    5353#include <as.h>
     
    6161#include <errno.h>
    6262#include <stdbool.h>
     63#include <stdio.h>
    6364#include <byteorder.h>
    6465#include <task.h>
     
    6768#include "ata_hw.h"
    6869#include "ata_bd.h"
     70#include "main.h"
    6971
    7072#define NAME       "ata_bd"
     
    8082static const size_t identify_data_size = 512;
    8183
    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 
    87 /** I/O base addresses for legacy (ISA-compatible) controllers. */
    88 static ata_base_t legacy_base[LEGACY_CTLS] = {
    89         { 0x1f0, 0x3f0 },
    90         { 0x170, 0x370 },
    91         { 0x1e8, 0x3e8 },
    92         { 0x168, 0x368 }
    93 };
    94 
    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];
    100 
    101 static void print_syntax(void);
    102 static int ata_bd_init(void);
    103 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *);
     84static int ata_bd_init_io(ata_ctrl_t *ctrl);
     85static void ata_bd_fini_io(ata_ctrl_t *ctrl);
    10486
    10587static int ata_bd_open(bd_srvs_t *, bd_srv_t *);
     
    11799static int ata_rcmd_write(disk_t *disk, uint64_t ba, size_t cnt,
    118100    const void *buf);
    119 static int disk_init(disk_t *d, int disk_id);
    120 static int drive_identify(disk_t *disk, void *buf);
    121 static int identify_pkt_dev(disk_t *disk, void *buf);
     101static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id);
     102static int ata_identify_dev(disk_t *disk, void *buf);
     103static int ata_identify_pkt_dev(disk_t *disk, void *buf);
    122104static int ata_cmd_packet(disk_t *disk, const void *cpkt, size_t cpkt_size,
    123105    void *obuf, size_t obuf_size);
     
    129111static void disk_print_summary(disk_t *d);
    130112static 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);
    134 
    135 static bd_ops_t ata_bd_ops = {
     113static void coord_sc_program(ata_ctrl_t *ctrl, const block_coord_t *bc,
     114    uint16_t scnt);
     115static int wait_status(ata_ctrl_t *ctrl, unsigned set, unsigned n_reset,
     116    uint8_t *pstatus, unsigned timeout);
     117
     118bd_ops_t ata_bd_ops = {
    136119        .open = ata_bd_open,
    137120        .close = ata_bd_close,
     
    153136}
    154137
    155 int main(int argc, char **argv)
    156 {
    157         char name[16];
     138/** Initialize ATA controller. */
     139int ata_ctrl_init(ata_ctrl_t *ctrl, ata_base_t *res)
     140{
    158141        int i, rc;
    159142        int n_disks;
    160         unsigned ctl_num;
    161         char *eptr;
    162 
    163         printf(NAME ": ATA disk driver\n");
    164 
    165         if (argc > 1) {
    166                 ctl_num = strtoul(argv[1], &eptr, 0);
    167                 if (*eptr != '\0' || ctl_num == 0 || ctl_num > 4) {
    168                         printf("Invalid argument.\n");
    169                         print_syntax();
    170                         return -1;
    171                 }
    172         } else {
    173                 ctl_num = 1;
    174         }
    175 
    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)
    183                 return -1;
     143
     144        ddf_msg(LVL_DEBUG, "ata_ctrl_init()");
     145
     146        fibril_mutex_initialize(&ctrl->lock);
     147        ctrl->cmd_physical = res->cmd;
     148        ctrl->ctl_physical = res->ctl;
     149
     150        ddf_msg(LVL_NOTE, "I/O address %p/%p", (void *) ctrl->cmd_physical,
     151            (void *) ctrl->ctl_physical);
     152
     153        rc = ata_bd_init_io(ctrl);
     154        if (rc != EOK)
     155                return rc;
    184156
    185157        for (i = 0; i < MAX_DISKS; i++) {
    186                 printf("Identify drive %d... ", i);
    187                 fflush(stdout);
    188 
    189                 rc = disk_init(&ata_disk[i], i);
     158                ddf_msg(LVL_NOTE, "Identify drive %d...", i);
     159
     160                rc = disk_init(ctrl, &ctrl->disk[i], i);
    190161
    191162                if (rc == EOK) {
    192                         disk_print_summary(&ata_disk[i]);
     163                        disk_print_summary(&ctrl->disk[i]);
    193164                } else {
    194                         printf("Not found.\n");
     165                        ddf_msg(LVL_NOTE, "Not found.");
    195166                }
    196167        }
     
    200171        for (i = 0; i < MAX_DISKS; i++) {
    201172                /* Skip unattached drives. */
    202                 if (ata_disk[i].present == false)
     173                if (ctrl->disk[i].present == false)
    203174                        continue;
    204                
    205                 snprintf(name, 16, "%s/ata%udisk%d", NAMESPACE, ctl_num, i);
    206                 rc = loc_service_register(name, &ata_disk[i].service_id);
     175
     176                rc = ata_fun_create(&ctrl->disk[i]);
    207177                if (rc != EOK) {
    208                         printf(NAME ": Unable to register device %s.\n", name);
     178                        ddf_msg(LVL_ERROR, "Unable to create function for "
     179                            "disk %d.", i);
     180                        goto error;
     181                }
     182                ++n_disks;
     183        }
     184
     185        if (n_disks == 0) {
     186                ddf_msg(LVL_WARN, "No disks detected.");
     187                rc = EIO;
     188                goto error;
     189        }
     190
     191        return EOK;
     192error:
     193        for (i = 0; i < MAX_DISKS; i++) {
     194                if (ata_fun_remove(&ctrl->disk[i]) != EOK) {
     195                        ddf_msg(LVL_ERROR, "Unable to clean up function for "
     196                            "disk %d.", i);
     197                }
     198        }
     199        ata_bd_fini_io(ctrl);
     200        return rc;
     201}
     202
     203/** Remove ATA controller. */
     204int ata_ctrl_remove(ata_ctrl_t *ctrl)
     205{
     206        int i, rc;
     207
     208        ddf_msg(LVL_DEBUG, ": ata_ctrl_remove()");
     209
     210        fibril_mutex_lock(&ctrl->lock);
     211
     212        for (i = 0; i < MAX_DISKS; i++) {
     213                rc = ata_fun_remove(&ctrl->disk[i]);
     214                if (rc != EOK) {
     215                        ddf_msg(LVL_ERROR, "Unable to clean up function for "
     216                            "disk %d.", i);
    209217                        return rc;
    210218                }
    211                 ++n_disks;
    212         }
    213 
    214         if (n_disks == 0) {
    215                 printf("No disks detected.\n");
    216                 return -1;
    217         }
    218 
    219         printf("%s: Accepting connections\n", NAME);
    220         task_retval(0);
    221         async_manager();
    222 
    223         /* Not reached */
    224         return 0;
    225 }
    226 
    227 
    228 static void print_syntax(void)
    229 {
    230         printf("Syntax: " NAME " <controller_number>\n");
    231         printf("Controller number = 1..4\n");
     219        }
     220
     221        ata_bd_fini_io(ctrl);
     222        fibril_mutex_unlock(&ctrl->lock);
     223
     224        return EOK;
     225}
     226
     227/** Surprise removal of ATA controller. */
     228int ata_ctrl_gone(ata_ctrl_t *ctrl)
     229{
     230        int i, rc;
     231
     232        ddf_msg(LVL_DEBUG, "ata_ctrl_gone()");
     233
     234        fibril_mutex_lock(&ctrl->lock);
     235
     236        for (i = 0; i < MAX_DISKS; i++) {
     237                rc = ata_fun_unbind(&ctrl->disk[i]);
     238                if (rc != EOK) {
     239                        ddf_msg(LVL_ERROR, "Unable to clean up function for "
     240                            "disk %d.", i);
     241                        return rc;
     242                }
     243        }
     244
     245        ata_bd_fini_io(ctrl);
     246        fibril_mutex_unlock(&ctrl->lock);
     247
     248        return EOK;
    232249}
    233250
     
    236253{
    237254        uint64_t mbytes;
    238 
    239         printf("%s: ", d->model);
     255        char *atype = NULL;
     256        char *cap = NULL;
     257        int rc;
    240258
    241259        if (d->dev_type == ata_reg_dev) {
    242260                switch (d->amode) {
    243261                case am_chs:
    244                         printf("CHS %u cylinders, %u heads, %u sectors",
    245                             d->geom.cylinders, d->geom.heads,
     262                        rc = asprintf(&atype, "CHS %u cylinders, %u heads, "
     263                            "%u sectors", d->geom.cylinders, d->geom.heads,
    246264                            d->geom.sectors);
     265                        if (rc < 0) {
     266                                /* Out of memory */
     267                                atype = NULL;
     268                        }
    247269                        break;
    248270                case am_lba28:
    249                         printf("LBA-28");
     271                        atype = str_dup("LBA-28");
    250272                        break;
    251273                case am_lba48:
    252                         printf("LBA-48");
     274                        atype = str_dup("LBA-48");
    253275                        break;
    254276                }
    255277        } else {
    256                 printf("PACKET");
    257         }
    258 
    259         printf(" %" PRIu64 " blocks", d->blocks);
     278                atype = str_dup("PACKET");
     279        }
     280
     281        if (atype == NULL)
     282                return;
    260283
    261284        mbytes = d->blocks / (2 * 1024);
    262         if (mbytes > 0)
    263                 printf(" %" PRIu64 " MB.", mbytes);
    264 
    265         printf("\n");
    266 }
    267 
    268 /** Register driver and enable device I/O. */
    269 static int ata_bd_init(void)
    270 {
    271         async_set_client_connection(ata_bd_connection);
    272         int rc = loc_server_register(NAME);
     285        if (mbytes > 0) {
     286                rc = asprintf(&cap, " %" PRIu64 " MB.", mbytes);
     287                if (rc < 0) {
     288                        cap = NULL;
     289                        goto cleanup;
     290                }
     291        }
     292
     293        ddf_msg(LVL_NOTE, "%s: %s %" PRIu64 " blocks%s", d->model, atype,
     294            d->blocks, cap);
     295cleanup:
     296        free(atype);
     297        free(cap);
     298}
     299
     300/** Enable device I/O. */
     301static int ata_bd_init_io(ata_ctrl_t *ctrl)
     302{
     303        int rc;
     304        void *vaddr;
     305
     306        rc = pio_enable((void *) ctrl->cmd_physical, sizeof(ata_cmd_t), &vaddr);
    273307        if (rc != EOK) {
    274                 printf("%s: Unable to register driver.\n", NAME);
     308                ddf_msg(LVL_ERROR, "Cannot initialize device I/O space.");
    275309                return rc;
    276310        }
    277        
    278         void *vaddr;
    279         rc = pio_enable((void *) cmd_physical, sizeof(ata_cmd_t), &vaddr);
     311
     312        ctrl->cmd = vaddr;
     313
     314        rc = pio_enable((void *) ctrl->ctl_physical, sizeof(ata_ctl_t), &vaddr);
    280315        if (rc != EOK) {
    281                 printf("%s: Could not initialize device I/O space.\n", NAME);
     316                ddf_msg(LVL_ERROR, "Cannot initialize device I/O space.");
    282317                return rc;
    283318        }
    284        
    285         cmd = vaddr;
    286        
    287         rc = pio_enable((void *) ctl_physical, sizeof(ata_ctl_t), &vaddr);
    288         if (rc != EOK) {
    289                 printf("%s: Could not initialize device I/O space.\n", NAME);
    290                 return rc;
    291         }
    292        
    293         ctl = vaddr;
    294        
    295         return EOK;
    296 }
    297 
    298 /** Block device connection handler */
    299 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    300 {
    301         service_id_t dsid;
    302         int i;
    303         disk_t *disk;
    304 
    305         /* Get the device service ID. */
    306         dsid = IPC_GET_ARG1(*icall);
    307 
    308         /* Determine which disk device is the client connecting to. */
    309         disk = NULL;
    310         for (i = 0; i < MAX_DISKS; i++)
    311                 if (ata_disk[i].service_id == dsid)
    312                         disk = &ata_disk[i];
    313 
    314         if (disk == NULL || disk->present == false) {
    315                 async_answer_0(iid, EINVAL);
    316                 return;
    317         }
    318 
    319         bd_conn(iid, icall, &disk->bds);
     319
     320        ctrl->ctl = vaddr;
     321
     322        return EOK;
     323}
     324
     325/** Clean up device I/O. */
     326static void ata_bd_fini_io(ata_ctrl_t *ctrl)
     327{
     328        (void) ctrl;
     329        /* XXX TODO */
    320330}
    321331
     
    325335 * the disk structure.
    326336 */
    327 static int disk_init(disk_t *d, int disk_id)
     337static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id)
    328338{
    329339        identify_data_t idata;
     
    337347        unsigned i;
    338348
     349        d->ctrl = ctrl;
    339350        d->disk_id = disk_id;
    340351        d->present = false;
    341         fibril_mutex_initialize(&d->lock);
    342 
    343         bd_srvs_init(&d->bds);
    344         d->bds.ops = &ata_bd_ops;
    345         d->bds.sarg = d;
     352        d->afun = NULL;
    346353
    347354        /* Try identify command. */
    348         rc = drive_identify(d, &idata);
     355        rc = ata_identify_dev(d, &idata);
    349356        if (rc == EOK) {
    350357                /* Success. It's a register (non-packet) device. */
    351                 printf("ATA register-only device found.\n");
     358                ddf_msg(LVL_NOTE, "ATA register-only device found.");
    352359                d->dev_type = ata_reg_dev;
    353360        } else if (rc == EIO) {
     
    362369                 * the byte count registers. So, only check these.
    363370                 */
    364                 bc = ((uint16_t)pio_read_8(&cmd->cylinder_high) << 8) |
    365                     pio_read_8(&cmd->cylinder_low);
     371                bc = ((uint16_t)pio_read_8(&ctrl->cmd->cylinder_high) << 8) |
     372                    pio_read_8(&ctrl->cmd->cylinder_low);
    366373
    367374                if (bc == PDEV_SIGNATURE_BC) {
    368                         rc = identify_pkt_dev(d, &idata);
     375                        rc = ata_identify_pkt_dev(d, &idata);
    369376                        if (rc == EOK) {
    370377                                /* We have a packet device. */
     
    452459                rc = ata_pcmd_inquiry(d, &inq_data, sizeof(inq_data));
    453460                if (rc != EOK) {
    454                         printf("Device inquiry failed.\n");
     461                        ddf_msg(LVL_ERROR, "Device inquiry failed.");
    455462                        d->present = false;
    456463                        return EIO;
     
    459466                /* Check device type. */
    460467                if (INQUIRY_PDEV_TYPE(inq_data.pdev_type) != PDEV_TYPE_CDROM)
    461                         printf("Warning: Peripheral device type is not CD-ROM.\n");
     468                        ddf_msg(LVL_WARN, "Peripheral device type is not CD-ROM.");
    462469
    463470                /* Assume 2k block size for now. */
     
    563570}
    564571
    565 /** 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.
    566633 *
    567634 * Reads @c identify data into the provided buffer. This is used to detect
     
    574641 *                      not present). EIO if device responds with error.
    575642 */
    576 static int drive_identify(disk_t *disk, void *buf)
    577 {
    578         uint16_t data;
     643static int ata_identify_dev(disk_t *disk, void *buf)
     644{
     645        ata_ctrl_t *ctrl = disk->ctrl;
    579646        uint8_t status;
    580647        uint8_t drv_head;
    581         size_t i;
    582648
    583649        drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
    584650
    585         if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     651        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    586652                return ETIMEOUT;
    587653
    588         pio_write_8(&cmd->drive_head, drv_head);
     654        pio_write_8(&ctrl->cmd->drive_head, drv_head);
    589655
    590656        /*
     
    593659         * set after issuing the command.
    594660         */
    595         if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     661        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    596662                return ETIMEOUT;
    597663
    598         pio_write_8(&cmd->command, CMD_IDENTIFY_DRIVE);
    599 
    600         if (wait_status(0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
     664        pio_write_8(&ctrl->cmd->command, CMD_IDENTIFY_DRIVE);
     665
     666        if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
    601667                return ETIMEOUT;
    602668
     
    605671         * the caller to check for one.
    606672         */
    607         if ((status & SR_ERR) != 0) {
    608                 return EIO;
    609         }
    610 
    611         if (wait_status(SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
     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         */
     680        if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)
    612681                return ETIMEOUT;
    613682
    614         /* Read data from the disk buffer. */
    615 
    616         for (i = 0; i < identify_data_size / 2; i++) {
    617                 data = pio_read_16(&cmd->data_port);
    618                 ((uint16_t *) buf)[i] = data;
    619         }
    620 
    621         return EOK;
     683        return ata_pio_data_in(disk, buf, identify_data_size,
     684            identify_data_size, 1);
    622685}
    623686
     
    630693 * @param buf           Pointer to a 512-byte buffer.
    631694 */
    632 static int identify_pkt_dev(disk_t *disk, void *buf)
    633 {
    634         uint16_t data;
    635         uint8_t status;
     695static int ata_identify_pkt_dev(disk_t *disk, void *buf)
     696{
     697        ata_ctrl_t *ctrl = disk->ctrl;
    636698        uint8_t drv_head;
    637         size_t i;
    638699
    639700        drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
    640701
    641         if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    642                 return EIO;
    643 
    644         pio_write_8(&cmd->drive_head, drv_head);
     702        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     703                return EIO;
     704
     705        pio_write_8(&ctrl->cmd->drive_head, drv_head);
    645706
    646707        /* 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)
    653                 return EIO;
    654 
    655         /* Read data from the device buffer. */
    656 
    657         if ((status & SR_DRQ) != 0) {
    658                 for (i = 0; i < identify_data_size / 2; i++) {
    659                         data = pio_read_16(&cmd->data_port);
    660                         ((uint16_t *) buf)[i] = data;
    661                 }
    662         }
    663 
    664         if ((status & SR_ERR) != 0)
    665                 return EIO;
    666 
    667         return EOK;
     708        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
     709                return EIO;
     710
     711        pio_write_8(&ctrl->cmd->command, CMD_IDENTIFY_PKT_DEV);
     712
     713        return ata_pio_data_in(disk, buf, identify_data_size,
     714            identify_data_size, 1);
    668715}
    669716
     
    681728    void *obuf, size_t obuf_size)
    682729{
     730        ata_ctrl_t *ctrl = disk->ctrl;
    683731        size_t i;
    684732        uint8_t status;
     
    687735        uint16_t val;
    688736
    689         fibril_mutex_lock(&disk->lock);
     737        fibril_mutex_lock(&ctrl->lock);
    690738
    691739        /* New value for Drive/Head register */
     
    693741            ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
    694742
    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) {
    703                 fibril_mutex_unlock(&disk->lock);
     743        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) {
     744                fibril_mutex_unlock(&ctrl->lock);
     745                return EIO;
     746        }
     747
     748        pio_write_8(&ctrl->cmd->drive_head, drv_head);
     749
     750        if (wait_status(ctrl, 0, ~(SR_BSY|SR_DRQ), NULL, TIMEOUT_BSY) != EOK) {
     751                fibril_mutex_unlock(&ctrl->lock);
    704752                return EIO;
    705753        }
    706754
    707755        /* 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) {
    714                 fibril_mutex_unlock(&disk->lock);
     756        pio_write_8(&ctrl->cmd->cylinder_low, 0xfe);
     757        pio_write_8(&ctrl->cmd->cylinder_high, 0xff);
     758
     759        pio_write_8(&ctrl->cmd->command, CMD_PACKET);
     760
     761        if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
     762                fibril_mutex_unlock(&ctrl->lock);
    715763                return EIO;
    716764        }
     
    718766        /* Write command packet. */
    719767        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) {
    723                 fibril_mutex_unlock(&disk->lock);
     768                pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) cpkt)[i]);
     769
     770        if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
     771                fibril_mutex_unlock(&ctrl->lock);
    724772                return EIO;
    725773        }
    726774
    727775        if ((status & SR_DRQ) == 0) {
    728                 fibril_mutex_unlock(&disk->lock);
     776                fibril_mutex_unlock(&ctrl->lock);
    729777                return EIO;
    730778        }
    731779
    732780        /* Read byte count. */
    733         data_size = (uint16_t) pio_read_8(&cmd->cylinder_low) +
    734             ((uint16_t) pio_read_8(&cmd->cylinder_high) << 8);
     781        data_size = (uint16_t) pio_read_8(&ctrl->cmd->cylinder_low) +
     782            ((uint16_t) pio_read_8(&ctrl->cmd->cylinder_high) << 8);
    735783
    736784        /* Check whether data fits into output buffer. */
    737785        if (data_size > obuf_size) {
    738786                /* Output buffer is too small to store data. */
    739                 fibril_mutex_unlock(&disk->lock);
     787                fibril_mutex_unlock(&ctrl->lock);
    740788                return EIO;
    741789        }
     
    743791        /* Read data from the device buffer. */
    744792        for (i = 0; i < (data_size + 1) / 2; i++) {
    745                 val = pio_read_16(&cmd->data_port);
     793                val = pio_read_16(&ctrl->cmd->data_port);
    746794                ((uint16_t *) obuf)[i] = val;
    747795        }
    748796
    749         if (status & SR_ERR) {
    750                 fibril_mutex_unlock(&disk->lock);
    751                 return EIO;
    752         }
    753 
    754         fibril_mutex_unlock(&disk->lock);
     797        fibril_mutex_unlock(&ctrl->lock);
     798
     799        if (status & SR_ERR)
     800                return EIO;
    755801
    756802        return EOK;
     
    849895        cp.oldformat = 0x40; /* 0x01 = multi-session mode (shifted to MSB) */
    850896       
    851         rc = ata_cmd_packet(0, &cp, sizeof(cp), obuf, obuf_size);
     897        rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size);
    852898        if (rc != EOK)
    853899                return rc;
     
    856902}
    857903
    858 /** Read a physical from the device.
     904/** Read a physical block from the device.
    859905 *
    860906 * @param disk          Disk
     
    868914    void *buf)
    869915{
    870         size_t i;
    871         uint16_t data;
    872         uint8_t status;
     916        ata_ctrl_t *ctrl = disk->ctrl;
    873917        uint8_t drv_head;
    874918        block_coord_t bc;
     919        int rc;
    875920
    876921        /* Silence warning. */
     
    887932            (bc.h & 0x0f);
    888933
    889         fibril_mutex_lock(&disk->lock);
     934        fibril_mutex_lock(&ctrl->lock);
    890935
    891936        /* Program a Read Sectors operation. */
    892937
    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) {
    901                 fibril_mutex_unlock(&disk->lock);
     938        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
     939                fibril_mutex_unlock(&ctrl->lock);
     940                return EIO;
     941        }
     942
     943        pio_write_8(&ctrl->cmd->drive_head, drv_head);
     944
     945        if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
     946                fibril_mutex_unlock(&ctrl->lock);
    902947                return EIO;
    903948        }
    904949
    905950        /* Program block coordinates into the device. */
    906         coord_sc_program(&bc, 1);
    907 
    908         pio_write_8(&cmd->command, disk->amode == am_lba48 ?
     951        coord_sc_program(ctrl, &bc, 1);
     952
     953        pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ?
    909954            CMD_READ_SECTORS_EXT : CMD_READ_SECTORS);
    910955
    911         if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
    912                 fibril_mutex_unlock(&disk->lock);
    913                 return EIO;
    914         }
    915 
    916         if ((status & SR_DRQ) != 0) {
    917                 /* Read data from the device buffer. */
    918 
    919                 for (i = 0; i < disk->block_size / 2; i++) {
    920                         data = pio_read_16(&cmd->data_port);
    921                         ((uint16_t *) buf)[i] = data;
    922                 }
    923         }
    924 
    925         if ((status & SR_ERR) != 0)
    926                 return EIO;
    927 
    928         fibril_mutex_unlock(&disk->lock);
    929         return EOK;
     956        rc = ata_pio_data_in(disk, buf, blk_cnt * disk->block_size,
     957            disk->block_size, blk_cnt);
     958
     959        fibril_mutex_unlock(&ctrl->lock);
     960
     961        return rc;
    930962}
    931963
     
    942974    const void *buf)
    943975{
    944         size_t i;
    945         uint8_t status;
     976        ata_ctrl_t *ctrl = disk->ctrl;
    946977        uint8_t drv_head;
    947978        block_coord_t bc;
     979        int rc;
    948980
    949981        /* Silence warning. */
     
    960992            (bc.h & 0x0f);
    961993
    962         fibril_mutex_lock(&disk->lock);
     994        fibril_mutex_lock(&ctrl->lock);
    963995
    964996        /* Program a Write Sectors operation. */
    965997
    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) {
    974                 fibril_mutex_unlock(&disk->lock);
     998        if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
     999                fibril_mutex_unlock(&ctrl->lock);
     1000                return EIO;
     1001        }
     1002
     1003        pio_write_8(&ctrl->cmd->drive_head, drv_head);
     1004
     1005        if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
     1006                fibril_mutex_unlock(&ctrl->lock);
    9751007                return EIO;
    9761008        }
    9771009
    9781010        /* Program block coordinates into the device. */
    979         coord_sc_program(&bc, 1);
    980 
    981         pio_write_8(&cmd->command, disk->amode == am_lba48 ?
     1011        coord_sc_program(ctrl, &bc, 1);
     1012
     1013        pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ?
    9821014            CMD_WRITE_SECTORS_EXT : CMD_WRITE_SECTORS);
    9831015
    984         if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
    985                 fibril_mutex_unlock(&disk->lock);
    986                 return EIO;
    987         }
    988 
    989         if ((status & SR_DRQ) != 0) {
    990                 /* Write data to the device buffer. */
    991 
    992                 for (i = 0; i < disk->block_size / 2; i++) {
    993                         pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]);
    994                 }
    995         }
    996 
    997         fibril_mutex_unlock(&disk->lock);
    998 
    999         if (status & SR_ERR)
    1000                 return EIO;
    1001 
    1002         return EOK;
     1016        rc = ata_pio_data_out(disk, buf, cnt * disk->block_size,
     1017            disk->block_size, cnt);
     1018
     1019        fibril_mutex_unlock(&ctrl->lock);
     1020        return rc;
    10031021}
    10041022
     
    10601078 *
    10611079 * 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 {
     1080 *
     1081 * @param ctrl          Controller
     1082 * @param bc            Block coordinates
     1083 * @param scnt          Sector count
     1084 */
     1085static void coord_sc_program(ata_ctrl_t *ctrl, const block_coord_t *bc,
     1086    uint16_t scnt)
     1087{
     1088        ata_cmd_t *cmd = ctrl->cmd;
     1089
    10651090        if (bc->amode == am_lba48) {
    10661091                /* Write high-order bits. */
     
    10801105/** Wait until some status bits are set and some are reset.
    10811106 *
    1082  * Example: wait_status(SR_DRDY, ~SR_BSY) waits for SR_DRDY to become
     1107 * Example: wait_status(ctrl, SR_DRDY, ~SR_BSY, ...) waits for SR_DRDY to become
    10831108 * set and SR_BSY to become reset.
    10841109 *
     1110 * @param ctrl          Controller
    10851111 * @param set           Combination if bits which must be all set.
    10861112 * @param n_reset       Negated combination of bits which must be all reset.
     
    10901116 * @return              EOK on success, EIO on timeout.
    10911117 */
    1092 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus,
    1093     unsigned timeout)
     1118static int wait_status(ata_ctrl_t *ctrl, unsigned set, unsigned n_reset,
     1119    uint8_t *pstatus, unsigned timeout)
    10941120{
    10951121        uint8_t status;
    10961122        int cnt;
    10971123
    1098         status = pio_read_8(&cmd->status);
     1124        status = pio_read_8(&ctrl->cmd->status);
    10991125
    11001126        /*
     
    11101136                if (cnt <= 0) break;
    11111137
    1112                 status = pio_read_8(&cmd->status);
     1138                status = pio_read_8(&ctrl->cmd->status);
    11131139        }
    11141140
     
    11191145                if (cnt <= 0) break;
    11201146
    1121                 status = pio_read_8(&cmd->status);
     1147                status = pio_read_8(&ctrl->cmd->status);
    11221148        }
    11231149
Note: See TracChangeset for help on using the changeset viewer.