Changeset 2791fbb7 in mainline


Ignore:
Timestamp:
2024-05-16T16:17:49Z (4 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
59c0f478
Parents:
64cf7a3
Message:

Move generic ATA code out to libata

Location:
uspace
Files:
3 added
6 edited
1 moved

Legend:

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

    r64cf7a3 r2791fbb7  
    3333/**
    3434 * @file
    35  * @brief ATA disk driver
    36  *
    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.
    40  *
    41  * This driver is based on the ATA-1, ATA-2, ATA-3 and ATA/ATAPI-4 through 7
    42  * standards, as published by the ANSI, NCITS and INCITS standards bodies,
    43  * which are freely available. This driver contains no vendor-specific
    44  * code at this moment.
    45  *
    46  * The driver services a single controller which can have up to two disks
    47  * attached.
     35 * @brief ISA ATA driver
     36 *
     37 * The driver services a single IDE channel.
    4838 */
    4939
     
    5343#include <async.h>
    5444#include <as.h>
    55 #include <bd_srv.h>
    5645#include <fibril_synch.h>
    57 #include <scsi/mmc.h>
    58 #include <scsi/sbc.h>
    59 #include <scsi/spc.h>
    6046#include <stdint.h>
    6147#include <stdbool.h>
     
    6551#include <inttypes.h>
    6652#include <errno.h>
    67 #include <byteorder.h>
    68 #include <macros.h>
    69 
    70 #include "ata_hw.h"
     53
    7154#include "ata_bd.h"
    7255#include "main.h"
    7356
    7457#define NAME       "ata_bd"
    75 
    76 /**
    77  * Size of data returned from Identify Device or Identify Packet Device
    78  * command.
    79  */
    80 static const size_t identify_data_size = 512;
    8158
    8259static errno_t ata_bd_init_io(ata_ctrl_t *ctrl);
     
    8461static errno_t ata_bd_init_irq(ata_ctrl_t *ctrl);
    8562static void ata_bd_fini_irq(ata_ctrl_t *ctrl);
    86 
    87 static errno_t ata_bd_open(bd_srvs_t *, bd_srv_t *);
    88 static errno_t ata_bd_close(bd_srv_t *);
    89 static errno_t ata_bd_read_blocks(bd_srv_t *, uint64_t ba, size_t cnt, void *buf,
    90     size_t);
    91 static errno_t ata_bd_read_toc(bd_srv_t *, uint8_t session, void *buf, size_t);
    92 static errno_t ata_bd_write_blocks(bd_srv_t *, uint64_t ba, size_t cnt,
    93     const void *buf, size_t);
    94 static errno_t ata_bd_get_block_size(bd_srv_t *, size_t *);
    95 static errno_t ata_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
    96 static errno_t ata_bd_sync_cache(bd_srv_t *, aoff64_t, size_t);
    97 
    98 static errno_t ata_rcmd_read(disk_t *disk, uint64_t ba, size_t cnt,
    99     void *buf);
    100 static errno_t ata_rcmd_write(disk_t *disk, uint64_t ba, size_t cnt,
    101     const void *buf);
    102 static errno_t ata_rcmd_flush_cache(disk_t *disk);
    103 static errno_t disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id);
    104 static errno_t ata_identify_dev(disk_t *disk, void *buf);
    105 static errno_t ata_identify_pkt_dev(disk_t *disk, void *buf);
    106 static errno_t ata_cmd_packet(disk_t *disk, const void *cpkt, size_t cpkt_size,
    107     void *obuf, size_t obuf_size, size_t *rcvd_size);
    108 static errno_t ata_pcmd_inquiry(disk_t *disk, void *obuf, size_t obuf_size,
    109     size_t *rcvd_size);
    110 static errno_t ata_pcmd_read_12(disk_t *disk, uint64_t ba, size_t cnt,
    111     void *obuf, size_t obuf_size);
    112 static errno_t ata_pcmd_read_capacity(disk_t *disk, uint64_t *nblocks,
    113     size_t *block_size);
    114 static errno_t ata_pcmd_read_toc(disk_t *disk, uint8_t ses,
    115     void *obuf, size_t obuf_size);
    116 static void disk_print_summary(disk_t *d);
    117 static size_t ata_disk_maxnb(disk_t *d);
    118 static errno_t coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc);
    119 static void coord_sc_program(ata_ctrl_t *ctrl, const block_coord_t *bc,
    120     uint16_t scnt);
    121 static errno_t wait_status(ata_ctrl_t *ctrl, unsigned set, unsigned n_reset,
    122     uint8_t *pstatus, unsigned timeout);
    123 static errno_t wait_irq(ata_ctrl_t *ctrl, uint8_t *pstatus, unsigned timeout);
    12463static void ata_irq_handler(ipc_call_t *call, ddf_dev_t *dev);
    12564
    126 bd_ops_t ata_bd_ops = {
    127         .open = ata_bd_open,
    128         .close = ata_bd_close,
    129         .read_blocks = ata_bd_read_blocks,
    130         .read_toc = ata_bd_read_toc,
    131         .write_blocks = ata_bd_write_blocks,
    132         .get_block_size = ata_bd_get_block_size,
    133         .get_num_blocks = ata_bd_get_num_blocks,
    134         .sync_cache = ata_bd_sync_cache
    135 };
     65static void ata_write_data_16(void *, uint16_t *, size_t);
     66static void ata_read_data_16(void *, uint16_t *, size_t);
     67static void ata_write_cmd_8(void *, uint16_t, uint8_t);
     68static uint8_t ata_read_cmd_8(void *, uint16_t);
     69static void ata_write_ctl_8(void *, uint16_t, uint8_t);
     70static uint8_t ata_read_ctl_8(void *, uint16_t);
     71static errno_t ata_irq_enable(void *);
     72static errno_t ata_irq_disable(void *);
     73static errno_t ata_add_device(void *, unsigned, void *);
     74static errno_t ata_remove_device(void *, unsigned);
     75static void ata_msg_debug(void *, char *);
     76static void ata_msg_note(void *, char *);
     77static void ata_msg_warn(void *, char *);
     78static void ata_msg_error(void *, char *);
    13679
    13780static const irq_pio_range_t ata_irq_ranges[] = {
     
    15497};
    15598
    156 static disk_t *bd_srv_disk(bd_srv_t *bd)
    157 {
    158         return (disk_t *)bd->srvs->sarg;
    159 }
    160 
    161 static int disk_dev_idx(disk_t *disk)
    162 {
    163         return (disk->disk_id & 1);
    164 }
    165 
    16699/** Initialize ATA controller. */
    167100errno_t ata_ctrl_init(ata_ctrl_t *ctrl, ata_hwres_t *res)
    168101{
    169         int i;
    170         errno_t rc;
    171         int n_disks;
     102        errno_t rc;
    172103        bool irq_inited = false;
     104        ata_params_t params;
    173105
    174106        ddf_msg(LVL_DEBUG, "ata_ctrl_init()");
    175107
    176108        fibril_mutex_initialize(&ctrl->lock);
    177         fibril_mutex_initialize(&ctrl->irq_lock);
    178         fibril_condvar_initialize(&ctrl->irq_cv);
    179109        ctrl->cmd_physical = res->cmd;
    180110        ctrl->ctl_physical = res->ctl;
     
    184114            (void *) ctrl->ctl_physical);
    185115
     116        ddf_msg(LVL_DEBUG, "Init I/O");
    186117        rc = ata_bd_init_io(ctrl);
    187118        if (rc != EOK)
    188119                return rc;
    189120
     121        ddf_msg(LVL_DEBUG, "Init IRQ");
    190122        rc = ata_bd_init_irq(ctrl);
     123        if (rc != EOK) {
     124                ddf_msg(LVL_NOTE, "init IRQ failed");
     125                return rc;
     126        }
     127
     128        irq_inited = true;
     129
     130        ddf_msg(LVL_DEBUG, "ata_ctrl_init(): Initialize ATA channel");
     131
     132        params.arg = (void *)ctrl;
     133        params.have_irq = (ctrl->irq >= 0) ? true : false;
     134        params.write_data_16 = ata_write_data_16;
     135        params.read_data_16 = ata_read_data_16;
     136        params.write_cmd_8 = ata_write_cmd_8;
     137        params.read_cmd_8 = ata_read_cmd_8;
     138        params.write_ctl_8 = ata_write_ctl_8;
     139        params.read_ctl_8 = ata_read_ctl_8;
     140        params.irq_enable = ata_irq_enable;
     141        params.irq_disable = ata_irq_disable;
     142        params.add_device = ata_add_device;
     143        params.remove_device = ata_remove_device;
     144        params.msg_debug = ata_msg_debug;
     145        params.msg_note = ata_msg_note;
     146        params.msg_warn = ata_msg_warn;
     147        params.msg_error = ata_msg_error;
     148
     149        rc = ata_channel_create(&params, &ctrl->channel);
    191150        if (rc != EOK)
    192                 return rc;
    193 
    194         irq_inited = true;
    195 
    196         for (i = 0; i < MAX_DISKS; i++) {
    197                 ddf_msg(LVL_DEBUG, "Identify drive %d...", i);
    198 
    199                 rc = disk_init(ctrl, &ctrl->disk[i], i);
    200 
    201                 if (rc == EOK) {
    202                         disk_print_summary(&ctrl->disk[i]);
    203                 } else {
    204                         ddf_msg(LVL_DEBUG, "Not found.");
    205                 }
    206         }
    207 
    208         n_disks = 0;
    209 
    210         for (i = 0; i < MAX_DISKS; i++) {
    211                 /* Skip unattached drives. */
    212                 if (ctrl->disk[i].present == false)
    213                         continue;
    214 
    215                 rc = ata_fun_create(&ctrl->disk[i]);
    216                 if (rc != EOK) {
    217                         ddf_msg(LVL_ERROR, "Unable to create function for "
    218                             "disk %d.", i);
    219                         goto error;
    220                 }
    221                 ++n_disks;
    222         }
    223 
    224         if (n_disks == 0) {
    225                 ddf_msg(LVL_WARN, "No disks detected.");
    226                 rc = ENOENT;
    227151                goto error;
    228         }
    229 
     152
     153        rc = ata_channel_initialize(ctrl->channel);
     154        if (rc != EOK)
     155                goto error;
     156
     157        ddf_msg(LVL_DEBUG, "ata_ctrl_init: DONE");
    230158        return EOK;
    231159error:
    232         for (i = 0; i < MAX_DISKS; i++) {
    233                 if (ata_fun_remove(&ctrl->disk[i]) != EOK) {
    234                         ddf_msg(LVL_ERROR, "Unable to clean up function for "
    235                             "disk %d.", i);
    236                 }
    237         }
    238160        if (irq_inited)
    239161                ata_bd_fini_irq(ctrl);
     
    245167errno_t ata_ctrl_remove(ata_ctrl_t *ctrl)
    246168{
    247         int i;
    248169        errno_t rc;
    249170
     
    252173        fibril_mutex_lock(&ctrl->lock);
    253174
    254         for (i = 0; i < MAX_DISKS; i++) {
    255                 rc = ata_fun_remove(&ctrl->disk[i]);
    256                 if (rc != EOK) {
    257                         ddf_msg(LVL_ERROR, "Unable to clean up function for "
    258                             "disk %d.", i);
    259                         return rc;
    260                 }
     175        rc = ata_channel_destroy(ctrl->channel);
     176        if (rc != EOK) {
     177                fibril_mutex_unlock(&ctrl->lock);
     178                return rc;
    261179        }
    262180
     
    271189errno_t ata_ctrl_gone(ata_ctrl_t *ctrl)
    272190{
    273         int i;
    274191        errno_t rc;
    275192
     
    278195        fibril_mutex_lock(&ctrl->lock);
    279196
    280         for (i = 0; i < MAX_DISKS; i++) {
    281                 rc = ata_fun_unbind(&ctrl->disk[i]);
    282                 if (rc != EOK) {
    283                         ddf_msg(LVL_ERROR, "Unable to clean up function for "
    284                             "disk %d.", i);
    285                         return rc;
    286                 }
     197        rc = ata_channel_destroy(ctrl->channel);
     198        if (rc != EOK) {
     199                fibril_mutex_unlock(&ctrl->lock);
     200                return rc;
    287201        }
    288202
     
    293207}
    294208
    295 /** Print one-line device summary. */
    296 static void disk_print_summary(disk_t *d)
    297 {
    298         uint64_t mbytes;
    299         char *atype = NULL;
    300         char *cap = NULL;
    301         int rc;
    302 
    303         if (d->dev_type == ata_reg_dev) {
    304                 switch (d->amode) {
    305                 case am_chs:
    306                         rc = asprintf(&atype, "CHS %u cylinders, %u heads, "
    307                             "%u sectors", d->geom.cylinders, d->geom.heads,
    308                             d->geom.sectors);
    309                         if (rc < 0) {
    310                                 /* Out of memory */
    311                                 atype = NULL;
    312                         }
    313                         break;
    314                 case am_lba28:
    315                         atype = str_dup("LBA-28");
    316                         break;
    317                 case am_lba48:
    318                         atype = str_dup("LBA-48");
    319                         break;
    320                 }
    321         } else {
    322                 atype = str_dup("PACKET");
    323         }
    324 
    325         if (atype == NULL)
    326                 return;
    327 
    328         mbytes = d->blocks / (2 * 1024);
    329         if (mbytes > 0) {
    330                 rc = asprintf(&cap, " %" PRIu64 " MB.", mbytes);
    331                 if (rc < 0) {
    332                         cap = NULL;
    333                         goto cleanup;
    334                 }
    335         }
    336 
    337         ddf_msg(LVL_NOTE, "%s: %s %" PRIu64 " blocks%s", d->model, atype,
    338             d->blocks, cap);
    339 cleanup:
    340         free(atype);
    341         free(cap);
    342 }
    343 
    344209/** Enable device I/O. */
    345210static errno_t ata_bd_init_io(ata_ctrl_t *ctrl)
     
    377242{
    378243        irq_code_t irq_code;
    379         async_sess_t *parent_sess;
    380244        irq_pio_range_t *ranges;
    381245        irq_cmd_t *cmds;
     
    413277        }
    414278
    415         parent_sess = ddf_dev_parent_sess_get(ctrl->dev);
    416 
    417         rc = hw_res_enable_interrupt(parent_sess, ctrl->irq);
    418         if (rc != EOK) {
    419                 ddf_msg(LVL_ERROR, "Error enabling IRQ.");
    420                 (void) unregister_interrupt_handler(ctrl->dev,
    421                     ctrl->ihandle);
    422                 goto error;
    423         }
    424 
     279        ddf_msg(LVL_DEBUG, "Interrupt handler registered");
    425280        free(ranges);
    426281        free(cmds);
     
    447302}
    448303
    449 /** Initialize a disk.
    450  *
    451  * Probes for a disk, determines its parameters and initializes
    452  * the disk structure.
    453  */
    454 static errno_t disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id)
    455 {
    456         identify_data_t idata;
    457         uint8_t model[40];
    458         scsi_std_inquiry_data_t inq_data;
    459         size_t isize;
    460         uint16_t w;
    461         uint8_t c;
    462         uint16_t bc;
    463         uint64_t nblocks;
    464         size_t block_size;
    465         size_t pos, len;
    466         errno_t rc;
    467         unsigned i;
    468 
    469         d->ctrl = ctrl;
    470         d->disk_id = disk_id;
    471         d->present = false;
    472         d->afun = NULL;
    473 
    474         /* Try identify command. */
    475         rc = ata_identify_dev(d, &idata);
    476         if (rc == EOK) {
    477                 /* Success. It's a register (non-packet) device. */
    478                 ddf_msg(LVL_DEBUG, "ATA register-only device found.");
    479                 d->dev_type = ata_reg_dev;
    480         } else if (rc == EIO) {
    481                 /*
    482                  * There is something, but not a register device. Check to see
    483                  * whether the IDENTIFY command left the packet signature in
    484                  * the registers in case this is a packet device.
    485                  *
    486                  * According to the ATA specification, the LBA low and
    487                  * interrupt reason registers should be set to 0x01. However,
    488                  * there are many devices that do not follow this and only set
    489                  * the byte count registers. So, only check these.
    490                  */
    491                 bc = ((uint16_t)pio_read_8(&ctrl->cmd->cylinder_high) << 8) |
    492                     pio_read_8(&ctrl->cmd->cylinder_low);
    493 
    494                 if (bc == PDEV_SIGNATURE_BC) {
    495                         rc = ata_identify_pkt_dev(d, &idata);
    496                         if (rc == EOK) {
    497                                 /* We have a packet device. */
    498                                 d->dev_type = ata_pkt_dev;
    499                         } else {
    500                                 return EIO;
    501                         }
    502                 } else {
    503                         /* Nope. Something's there, but not recognized. */
    504                         return EIO;
    505                 }
    506         } else {
    507                 /* Operation timed out. That means there is no device there. */
    508                 return EIO;
    509         }
    510 
    511         if (d->dev_type == ata_pkt_dev) {
    512                 /* Packet device */
    513                 d->amode = 0;
    514 
    515                 d->geom.cylinders = 0;
    516                 d->geom.heads = 0;
    517                 d->geom.sectors = 0;
    518 
    519                 d->blocks = 0;
    520         } else if ((idata.caps & rd_cap_lba) == 0) {
    521                 /* Device only supports CHS addressing. */
    522                 d->amode = am_chs;
    523 
    524                 d->geom.cylinders = idata.cylinders;
    525                 d->geom.heads = idata.heads;
    526                 d->geom.sectors = idata.sectors;
    527 
    528                 d->blocks = d->geom.cylinders * d->geom.heads * d->geom.sectors;
    529         } else if ((idata.cmd_set1 & cs1_addr48) == 0) {
    530                 /* Device only supports LBA-28 addressing. */
    531                 d->amode = am_lba28;
    532 
    533                 d->geom.cylinders = 0;
    534                 d->geom.heads = 0;
    535                 d->geom.sectors = 0;
    536 
    537                 d->blocks =
    538                     (uint32_t) idata.total_lba28_0 |
    539                     ((uint32_t) idata.total_lba28_1 << 16);
    540         } else {
    541                 /* Device supports LBA-48 addressing. */
    542                 d->amode = am_lba48;
    543 
    544                 d->geom.cylinders = 0;
    545                 d->geom.heads = 0;
    546                 d->geom.sectors = 0;
    547 
    548                 d->blocks =
    549                     (uint64_t) idata.total_lba48_0 |
    550                     ((uint64_t) idata.total_lba48_1 << 16) |
    551                     ((uint64_t) idata.total_lba48_2 << 32) |
    552                     ((uint64_t) idata.total_lba48_3 << 48);
    553         }
    554 
    555         /*
    556          * Convert model name to string representation.
    557          */
    558         for (i = 0; i < 20; i++) {
    559                 w = idata.model_name[i];
    560                 model[2 * i] = w >> 8;
    561                 model[2 * i + 1] = w & 0x00ff;
    562         }
    563 
    564         len = 40;
    565         while (len > 0 && model[len - 1] == 0x20)
    566                 --len;
    567 
    568         pos = 0;
    569         for (i = 0; i < len; ++i) {
    570                 c = model[i];
    571                 if (c >= 0x80)
    572                         c = '?';
    573 
    574                 chr_encode(c, d->model, &pos, 40);
    575         }
    576         d->model[pos] = '\0';
    577 
    578         if (d->dev_type == ata_pkt_dev) {
    579                 /* Send inquiry. */
    580                 rc = ata_pcmd_inquiry(d, &inq_data, sizeof(inq_data), &isize);
    581                 if (rc != EOK || isize < sizeof(inq_data)) {
    582                         ddf_msg(LVL_ERROR, "Device inquiry failed.");
    583                         d->present = false;
    584                         return EIO;
    585                 }
    586 
    587                 /* Check device type. */
    588                 if (INQUIRY_PDEV_TYPE(inq_data.pqual_devtype) != SCSI_DEV_CD_DVD)
    589                         ddf_msg(LVL_WARN, "Peripheral device type is not CD-ROM.");
    590 
    591                 rc = ata_pcmd_read_capacity(d, &nblocks, &block_size);
    592                 if (rc != EOK) {
    593                         ddf_msg(LVL_ERROR, "Read capacity command failed.");
    594                         d->present = false;
    595                         return EIO;
    596                 }
    597 
    598                 d->blocks = nblocks;
    599                 d->block_size = block_size;
    600         } else {
    601                 /* Assume register Read always uses 512-byte blocks. */
    602                 d->block_size = 512;
    603         }
    604 
    605         d->present = true;
    606         return EOK;
    607 }
    608 
    609 static errno_t ata_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
    610 {
    611         return EOK;
    612 }
    613 
    614 static errno_t ata_bd_close(bd_srv_t *bd)
    615 {
    616         return EOK;
    617 }
    618 
    619 /** Read multiple blocks from the device. */
    620 static errno_t ata_bd_read_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt,
    621     void *buf, size_t size)
    622 {
    623         disk_t *disk = bd_srv_disk(bd);
    624         size_t maxnb;
    625         size_t nb;
    626         errno_t rc;
    627 
    628         if (size < cnt * disk->block_size) {
    629                 rc = EINVAL;
    630                 goto error;
    631         }
    632 
    633         /* Maximum number of blocks to transfer at the same time */
    634         maxnb = ata_disk_maxnb(disk);
    635         while (cnt > 0) {
    636                 nb = min(maxnb, cnt);
    637                 if (disk->dev_type == ata_reg_dev) {
    638                         rc = ata_rcmd_read(disk, ba, nb, buf);
    639                 } else {
    640                         rc = ata_pcmd_read_12(disk, ba, nb, buf,
    641                             disk->block_size);
    642                 }
    643 
    644                 if (rc != EOK)
    645                         goto error;
    646 
    647                 ba += nb;
    648                 cnt -= nb;
    649                 buf += disk->block_size * nb;
    650         }
    651 
    652         return EOK;
    653 error:
    654         ddf_msg(LVL_DEBUG, "ata_bd_read_blocks: rc=%d", rc);
    655         return rc;
    656 }
    657 
    658 /** Read TOC from device. */
    659 static errno_t ata_bd_read_toc(bd_srv_t *bd, uint8_t session, void *buf, size_t size)
    660 {
    661         disk_t *disk = bd_srv_disk(bd);
    662 
    663         return ata_pcmd_read_toc(disk, session, buf, size);
    664 }
    665 
    666 /** Write multiple blocks to the device. */
    667 static errno_t ata_bd_write_blocks(bd_srv_t *bd, uint64_t ba, size_t cnt,
    668     const void *buf, size_t size)
    669 {
    670         disk_t *disk = bd_srv_disk(bd);
    671         size_t maxnb;
    672         size_t nb;
    673         errno_t rc;
    674 
    675         if (disk->dev_type != ata_reg_dev)
    676                 return ENOTSUP;
    677 
    678         if (size < cnt * disk->block_size)
    679                 return EINVAL;
    680 
    681         /* Maximum number of blocks to transfer at the same time */
    682         maxnb = ata_disk_maxnb(disk);
    683         while (cnt > 0) {
    684                 nb = min(maxnb, cnt);
    685                 rc = ata_rcmd_write(disk, ba, nb, buf);
    686                 if (rc != EOK)
    687                         return rc;
    688 
    689                 ba += nb;
    690                 cnt -= nb;
    691                 buf += disk->block_size * nb;
    692         }
    693 
    694         return EOK;
    695 }
    696 
    697 /** Get device block size. */
    698 static errno_t ata_bd_get_block_size(bd_srv_t *bd, size_t *rbsize)
    699 {
    700         disk_t *disk = bd_srv_disk(bd);
    701 
    702         *rbsize = disk->block_size;
    703         return EOK;
    704 }
    705 
    706 /** Get device number of blocks. */
    707 static errno_t ata_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
    708 {
    709         disk_t *disk = bd_srv_disk(bd);
    710 
    711         *rnb = disk->blocks;
    712         return EOK;
    713 }
    714 
    715 /** Flush cache. */
    716 static errno_t ata_bd_sync_cache(bd_srv_t *bd, uint64_t ba, size_t cnt)
    717 {
    718         disk_t *disk = bd_srv_disk(bd);
    719 
    720         /* ATA cannot flush just some blocks, we just flush everything. */
    721         (void)ba;
    722         (void)cnt;
    723 
    724         return ata_rcmd_flush_cache(disk);
    725 }
    726 
    727 /** PIO data-in command protocol. */
    728 static errno_t ata_pio_data_in(disk_t *disk, void *obuf, size_t obuf_size,
    729     size_t blk_size, size_t nblocks)
    730 {
    731         ata_ctrl_t *ctrl = disk->ctrl;
    732         uint16_t data;
    733         size_t i;
    734         size_t bidx;
    735         uint8_t status;
    736         errno_t rc;
    737 
    738         assert(nblocks > 0);
    739         assert(blk_size % 2 == 0);
    740 
    741         bidx = 0;
    742         while (nblocks > 0) {
    743                 if (ctrl->irq >= 0)
    744                         rc = wait_irq(ctrl, &status, TIMEOUT_BSY);
    745                 else
    746                         rc = wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY);
    747 
    748                 if (rc != EOK) {
    749                         ddf_msg(LVL_DEBUG, "wait_irq/wait_status failed");
    750                         return EIO;
    751                 }
    752 
    753                 if ((status & SR_DRQ) == 0) {
    754                         ddf_msg(LVL_DEBUG, "DRQ == 0");
    755                         break;
    756                 }
    757 
    758                 /* Read data from the device buffer. */
    759                 for (i = 0; i < blk_size / 2; i++) {
    760                         data = pio_read_16(&ctrl->cmd->data_port);
    761                         ((uint16_t *) obuf)[bidx++] = data;
    762                 }
    763 
    764                 --nblocks;
    765         }
    766 
    767         if ((status & SR_ERR) != 0) {
    768                 ddf_msg(LVL_DEBUG, "status & SR_ERR != 0");
    769                 return EIO;
    770         }
    771         if (nblocks > 0) {
    772                 ddf_msg(LVL_DEBUG, "remaining nblocks = %zu", nblocks);
    773                 return EIO;
    774         }
    775 
    776         return EOK;
    777 }
    778 
    779 /** PIO data-out command protocol. */
    780 static errno_t ata_pio_data_out(disk_t *disk, const void *buf, size_t buf_size,
    781     size_t blk_size, size_t nblocks)
    782 {
    783         ata_ctrl_t *ctrl = disk->ctrl;
    784         size_t i;
    785         size_t bidx;
    786         uint8_t status;
    787         errno_t rc;
    788 
    789         assert(nblocks > 0);
    790         assert(blk_size % 2 == 0);
    791 
    792         rc = wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY);
    793         if (rc != EOK)
    794                 return EIO;
    795 
    796         bidx = 0;
    797         while (nblocks > 0) {
    798                 if ((status & SR_DRQ) == 0) {
    799                         ddf_msg(LVL_DEBUG, "pio_data_out: unexpected DRQ=0");
    800                         break;
    801                 }
    802 
    803                 /* Write data to the device buffer. */
    804                 for (i = 0; i < blk_size / 2; i++) {
    805                         pio_write_16(&ctrl->cmd->data_port,
    806                             ((uint16_t *) buf)[bidx++]);
    807                 }
    808 
    809                 if (ctrl->irq >= 0)
    810                         rc = wait_irq(ctrl, &status, TIMEOUT_BSY);
    811                 else
    812                         rc = wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY);
    813                 if (rc != EOK)
    814                         return EIO;
    815 
    816                 --nblocks;
    817         }
    818 
    819         if (status & SR_ERR)
    820                 return EIO;
    821         if (nblocks > 0)
    822                 return EIO;
    823 
    824         return EOK;
    825 }
    826 
    827 /** PIO non-data command protocol. */
    828 static errno_t ata_pio_nondata(disk_t *disk)
    829 {
    830         ata_ctrl_t *ctrl = disk->ctrl;
    831         uint8_t status;
    832         errno_t rc;
    833 
    834         if (ctrl->irq >= 0)
    835                 rc = wait_irq(ctrl, &status, TIMEOUT_BSY);
    836         else
    837                 rc = wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY);
    838 
    839         if (rc != EOK)
    840                 return EIO;
    841 
    842         if (status & SR_ERR)
    843                 return EIO;
    844 
    845         return EOK;
    846 }
    847 
    848 /** Issue IDENTIFY DEVICE command.
    849  *
    850  * Reads @c identify data into the provided buffer. This is used to detect
    851  * whether an ATA device is present and if so, to determine its parameters.
    852  *
    853  * @param disk          Disk
    854  * @param buf           Pointer to a 512-byte buffer.
    855  *
    856  * @return              ETIMEOUT on timeout (this can mean the device is
    857  *                      not present). EIO if device responds with error.
    858  */
    859 static errno_t ata_identify_dev(disk_t *disk, void *buf)
    860 {
    861         ata_ctrl_t *ctrl = disk->ctrl;
    862         uint8_t status;
    863         uint8_t drv_head;
    864 
    865         drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
    866 
    867         if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    868                 return ETIMEOUT;
    869 
    870         pio_write_8(&ctrl->cmd->drive_head, drv_head);
    871 
    872         /*
    873          * Do not wait for DRDY to be set in case this is a packet device.
    874          * We determine whether the device is present by waiting for DRQ to be
    875          * set after issuing the command.
    876          */
    877         if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    878                 return ETIMEOUT;
    879 
    880         pio_write_8(&ctrl->cmd->command, CMD_IDENTIFY_DRIVE);
    881 
    882         /*
    883          * For probing purposes we need to wait for some status bit to become
    884          * active - otherwise we could be fooled just by receiving all zeroes.
    885          */
    886         if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK) {
    887                 if ((status & SR_ERR) == 0) {
    888                         /* Probably no device at all */
    889                         return ETIMEOUT;
    890                 }
    891         }
    892 
    893         return ata_pio_data_in(disk, buf, identify_data_size,
    894             identify_data_size, 1);
    895 }
    896 
    897 /** Issue Identify Packet Device command.
    898  *
    899  * Reads @c identify data into the provided buffer. This is used to detect
    900  * whether an ATAPI device is present and if so, to determine its parameters.
    901  *
    902  * @param disk          Disk
    903  * @param buf           Pointer to a 512-byte buffer.
    904  */
    905 static errno_t ata_identify_pkt_dev(disk_t *disk, void *buf)
    906 {
    907         ata_ctrl_t *ctrl = disk->ctrl;
    908         uint8_t drv_head;
    909 
    910         drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
    911 
    912         if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    913                 return EIO;
    914 
    915         pio_write_8(&ctrl->cmd->drive_head, drv_head);
    916 
    917         /* For ATAPI commands we do not need to wait for DRDY. */
    918         if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)
    919                 return EIO;
    920 
    921         pio_write_8(&ctrl->cmd->command, CMD_IDENTIFY_PKT_DEV);
    922 
    923         return ata_pio_data_in(disk, buf, identify_data_size,
    924             identify_data_size, 1);
    925 }
    926 
    927 /** Issue packet command (i. e. write a command packet to the device).
    928  *
    929  * Only data-in commands are supported (e.g. inquiry, read).
    930  *
    931  * @param disk          Disk
    932  * @param obuf          Buffer for storing data read from device
    933  * @param obuf_size     Size of obuf in bytes
    934  * @param rcvd_size     Place to store number of bytes read or @c NULL
    935  *
    936  * @return EOK on success, EIO on error.
    937  */
    938 static errno_t ata_cmd_packet(disk_t *disk, const void *cpkt, size_t cpkt_size,
    939     void *obuf, size_t obuf_size, size_t *rcvd_size)
    940 {
    941         ata_ctrl_t *ctrl = disk->ctrl;
    942         size_t i;
    943         uint8_t status;
    944         uint8_t drv_head;
    945         size_t data_size;
    946         size_t remain;
    947         size_t bidx;
    948         uint16_t val;
    949         errno_t rc;
    950 
    951         fibril_mutex_lock(&ctrl->lock);
    952 
    953         /* New value for Drive/Head register */
    954         drv_head =
    955             ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0);
    956 
    957         if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) {
    958                 fibril_mutex_unlock(&ctrl->lock);
    959                 return EIO;
    960         }
    961 
    962         pio_write_8(&ctrl->cmd->drive_head, drv_head);
    963 
    964         if (wait_status(ctrl, 0, ~(SR_BSY | SR_DRQ), NULL, TIMEOUT_BSY) != EOK) {
    965                 fibril_mutex_unlock(&ctrl->lock);
    966                 return EIO;
    967         }
    968 
    969         /* Byte count <- max. number of bytes we can read in one transfer. */
    970         pio_write_8(&ctrl->cmd->cylinder_low, 0xfe);
    971         pio_write_8(&ctrl->cmd->cylinder_high, 0xff);
    972 
    973         pio_write_8(&ctrl->cmd->command, CMD_PACKET);
    974 
    975         if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {
    976                 fibril_mutex_unlock(&ctrl->lock);
    977                 return EIO;
    978         }
    979 
    980         /* Write command packet. */
    981         for (i = 0; i < (cpkt_size + 1) / 2; i++)
    982                 pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) cpkt)[i]);
    983 
    984         bidx = 0;
    985         remain = obuf_size;
    986         while (remain > 0) {
    987                 if (ctrl->irq >= 0)
    988                         rc = wait_irq(ctrl, &status, TIMEOUT_BSY);
    989                 else
    990                         rc = wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY);
    991 
    992                 if (rc != EOK) {
    993                         fibril_mutex_unlock(&ctrl->lock);
    994                         return EIO;
    995                 }
    996 
    997                 if ((status & SR_DRQ) == 0)
    998                         break;
    999 
    1000                 /* Read byte count. */
    1001                 data_size = (uint16_t) pio_read_8(&ctrl->cmd->cylinder_low) +
    1002                     ((uint16_t) pio_read_8(&ctrl->cmd->cylinder_high) << 8);
    1003 
    1004                 /* Check whether data fits into output buffer. */
    1005                 if (data_size > obuf_size) {
    1006                         /* Output buffer is too small to store data. */
    1007                         fibril_mutex_unlock(&ctrl->lock);
    1008                         return EIO;
    1009                 }
    1010 
    1011                 /* Read data from the device buffer. */
    1012                 for (i = 0; i < (data_size + 1) / 2; i++) {
    1013                         val = pio_read_16(&ctrl->cmd->data_port);
    1014                         ((uint16_t *) obuf)[bidx++] = val;
    1015                 }
    1016 
    1017                 remain -= data_size;
    1018         }
    1019 
    1020         if (ctrl->irq >= 0)
    1021                 rc = wait_irq(ctrl, &status, TIMEOUT_BSY);
    1022         else
    1023                 rc = wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY);
    1024 
    1025         fibril_mutex_unlock(&ctrl->lock);
    1026 
    1027         if (status & SR_ERR)
    1028                 return EIO;
    1029 
    1030         if (rcvd_size != NULL)
    1031                 *rcvd_size = obuf_size - remain;
    1032         return EOK;
    1033 }
    1034 
    1035 /** Issue ATAPI Inquiry.
    1036  *
    1037  * @param disk          Disk
    1038  * @param obuf          Buffer for storing inquiry data read from device
    1039  * @param obuf_size     Size of obuf in bytes
    1040  *
    1041  * @return EOK on success, EIO on error.
    1042  */
    1043 static errno_t ata_pcmd_inquiry(disk_t *disk, void *obuf, size_t obuf_size,
    1044     size_t *rcvd_size)
    1045 {
    1046         uint8_t cpb[12];
    1047         scsi_cdb_inquiry_t *cp = (scsi_cdb_inquiry_t *)cpb;
    1048         errno_t rc;
    1049 
    1050         memset(cpb, 0, sizeof(cpb));
    1051 
    1052         /*
    1053          * For SFF 8020 compliance the inquiry must be padded to 12 bytes
    1054          * and allocation length must fit in one byte.
    1055          */
    1056         cp->op_code = SCSI_CMD_INQUIRY;
    1057 
    1058         /* Allocation length */
    1059         cp->alloc_len = host2uint16_t_be(min(obuf_size, 0xff));
    1060 
    1061         rc = ata_cmd_packet(disk, cpb, sizeof(cpb), obuf, obuf_size, rcvd_size);
    1062         if (rc != EOK)
    1063                 return rc;
    1064 
    1065         return EOK;
    1066 }
    1067 
    1068 /** Issue ATAPI read capacity(10) command.
    1069  *
    1070  * @param disk          Disk
    1071  * @param nblocks       Place to store number of blocks
    1072  * @param block_size    Place to store block size
    1073  *
    1074  * @return EOK on success, EIO on error.
    1075  */
    1076 static errno_t ata_pcmd_read_capacity(disk_t *disk, uint64_t *nblocks,
    1077     size_t *block_size)
    1078 {
    1079         scsi_cdb_read_capacity_10_t cdb;
    1080         scsi_read_capacity_10_data_t data;
    1081         size_t rsize;
    1082         errno_t rc;
    1083 
    1084         memset(&cdb, 0, sizeof(cdb));
    1085         cdb.op_code = SCSI_CMD_READ_CAPACITY_10;
    1086 
    1087         rc = ata_cmd_packet(disk, &cdb, sizeof(cdb), &data, sizeof(data), &rsize);
    1088         if (rc != EOK)
    1089                 return rc;
    1090 
    1091         if (rsize != sizeof(data))
    1092                 return EIO;
    1093 
    1094         *nblocks = uint32_t_be2host(data.last_lba) + 1;
    1095         *block_size = uint32_t_be2host(data.block_size);
    1096 
    1097         return EOK;
    1098 }
    1099 
    1100 /** Issue ATAPI read(12) command.
    1101  *
    1102  * Output buffer must be large enough to hold the data, otherwise the
    1103  * function will fail.
    1104  *
    1105  * @param disk          Disk
    1106  * @param ba            Starting block address
    1107  * @param cnt           Number of blocks to read
    1108  * @param obuf          Buffer for storing inquiry data read from device
    1109  * @param obuf_size     Size of obuf in bytes
    1110  *
    1111  * @return EOK on success, EIO on error.
    1112  */
    1113 static errno_t ata_pcmd_read_12(disk_t *disk, uint64_t ba, size_t cnt,
    1114     void *obuf, size_t obuf_size)
    1115 {
    1116         scsi_cdb_read_12_t cp;
    1117         errno_t rc;
    1118 
    1119         if (ba > UINT32_MAX)
    1120                 return EINVAL;
    1121 
    1122         memset(&cp, 0, sizeof(cp));
    1123 
    1124         cp.op_code = SCSI_CMD_READ_12;
    1125         cp.lba = host2uint32_t_be(ba);
    1126         cp.xfer_len = host2uint32_t_be(cnt);
    1127 
    1128         rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size, NULL);
    1129         if (rc != EOK)
    1130                 return rc;
    1131 
    1132         return EOK;
    1133 }
    1134 
    1135 /** Issue ATAPI read TOC command.
    1136  *
    1137  * Read TOC in 'multi-session' format (first and last session number
    1138  * with last session LBA).
    1139  *
    1140  * http://suif.stanford.edu/~csapuntz/specs/INF-8020.PDF page 171
    1141  *
    1142  * Output buffer must be large enough to hold the data, otherwise the
    1143  * function will fail.
    1144  *
    1145  * @param disk          Disk
    1146  * @param session       Starting session
    1147  * @param obuf          Buffer for storing inquiry data read from device
    1148  * @param obuf_size     Size of obuf in bytes
    1149  *
    1150  * @return EOK on success, EIO on error.
    1151  */
    1152 static errno_t ata_pcmd_read_toc(disk_t *disk, uint8_t session, void *obuf,
    1153     size_t obuf_size)
    1154 {
    1155         uint8_t cpb[12];
    1156         scsi_cdb_read_toc_t *cp = (scsi_cdb_read_toc_t *)cpb;
    1157         errno_t rc;
    1158 
    1159         memset(cpb, 0, sizeof(cpb));
    1160 
    1161         cp->op_code = SCSI_CMD_READ_TOC;
    1162         cp->msf = 0;
    1163         cp->format = 0x01; /* 0x01 = multi-session mode */
    1164         cp->track_sess_no = session;
    1165         cp->alloc_len = host2uint16_t_be(obuf_size);
    1166         cp->control = 0x40; /* 0x01 = multi-session mode (shifted to MSB) */
    1167 
    1168         rc = ata_cmd_packet(disk, cpb, sizeof(cpb), obuf, obuf_size, NULL);
    1169         if (rc != EOK)
    1170                 return rc;
    1171 
    1172         return EOK;
    1173 }
    1174 
    1175 /** Read a physical block from the device.
    1176  *
    1177  * @param disk          Disk
    1178  * @param ba            Address the first block.
    1179  * @param cnt           Number of blocks to transfer.
    1180  * @param buf           Buffer for holding the data.
    1181  *
    1182  * @return EOK on success, EIO on error.
    1183  */
    1184 static errno_t ata_rcmd_read(disk_t *disk, uint64_t ba, size_t blk_cnt,
    1185     void *buf)
    1186 {
    1187         ata_ctrl_t *ctrl = disk->ctrl;
    1188         uint8_t drv_head;
    1189         block_coord_t bc;
    1190         errno_t rc;
    1191 
    1192         /* Silence warning. */
    1193         memset(&bc, 0, sizeof(bc));
    1194 
    1195         /* Compute block coordinates. */
    1196         if (coord_calc(disk, ba, &bc) != EOK) {
    1197                 ddf_msg(LVL_NOTE, "ata_rcmd_read() -> coord_calc failed");
    1198                 return EINVAL;
    1199         }
    1200 
    1201         /* New value for Drive/Head register */
    1202         drv_head =
    1203             ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0) |
    1204             ((disk->amode != am_chs) ? DHR_LBA : 0) |
    1205             (bc.h & 0x0f);
    1206 
    1207         fibril_mutex_lock(&ctrl->lock);
    1208 
    1209         /* Program a Read Sectors operation. */
    1210 
    1211         if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
    1212                 fibril_mutex_unlock(&ctrl->lock);
    1213                 ddf_msg(LVL_NOTE, "ata_rcmd_read() -> wait_status failed");
    1214                 return EIO;
    1215         }
    1216 
    1217         pio_write_8(&ctrl->cmd->drive_head, drv_head);
    1218 
    1219         if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
    1220                 fibril_mutex_unlock(&ctrl->lock);
    1221                 ddf_msg(LVL_NOTE, "ata_rcmd_read() -> wait_status 2 failed");
    1222                 return EIO;
    1223         }
    1224 
    1225         /* Program block coordinates into the device. */
    1226         coord_sc_program(ctrl, &bc, blk_cnt);
    1227 
    1228         pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ?
    1229             CMD_READ_SECTORS_EXT : CMD_READ_SECTORS);
    1230 
    1231         rc = ata_pio_data_in(disk, buf, blk_cnt * disk->block_size,
    1232             disk->block_size, blk_cnt);
    1233 
    1234         fibril_mutex_unlock(&ctrl->lock);
    1235 
    1236         if (rc != EOK)
    1237                 ddf_msg(LVL_NOTE, "ata_rcmd_read() -> pio_data_in->%d", rc);
    1238         return rc;
    1239 }
    1240 
    1241 /** Write a physical block to the device.
    1242  *
    1243  * @param disk          Disk
    1244  * @param ba            Address of the first block.
    1245  * @param cnt           Number of blocks to transfer.
    1246  * @param buf           Buffer holding the data to write.
    1247  *
    1248  * @return EOK on success, EIO on error.
    1249  */
    1250 static errno_t ata_rcmd_write(disk_t *disk, uint64_t ba, size_t cnt,
    1251     const void *buf)
    1252 {
    1253         ata_ctrl_t *ctrl = disk->ctrl;
    1254         uint8_t drv_head;
    1255         block_coord_t bc;
    1256         errno_t rc;
    1257 
    1258         /* Silence warning. */
    1259         memset(&bc, 0, sizeof(bc));
    1260 
    1261         /* Compute block coordinates. */
    1262         if (coord_calc(disk, ba, &bc) != EOK)
    1263                 return EINVAL;
    1264 
    1265         /* New value for Drive/Head register */
    1266         drv_head =
    1267             ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0) |
    1268             ((disk->amode != am_chs) ? DHR_LBA : 0) |
    1269             (bc.h & 0x0f);
    1270 
    1271         fibril_mutex_lock(&ctrl->lock);
    1272 
    1273         /* Program a Write Sectors operation. */
    1274 
    1275         if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
    1276                 fibril_mutex_unlock(&ctrl->lock);
    1277                 return EIO;
    1278         }
    1279 
    1280         pio_write_8(&ctrl->cmd->drive_head, drv_head);
    1281 
    1282         if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
    1283                 fibril_mutex_unlock(&ctrl->lock);
    1284                 return EIO;
    1285         }
    1286 
    1287         /* Program block coordinates into the device. */
    1288         coord_sc_program(ctrl, &bc, cnt);
    1289 
    1290         pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ?
    1291             CMD_WRITE_SECTORS_EXT : CMD_WRITE_SECTORS);
    1292 
    1293         rc = ata_pio_data_out(disk, buf, cnt * disk->block_size,
    1294             disk->block_size, cnt);
    1295 
    1296         fibril_mutex_unlock(&ctrl->lock);
    1297         return rc;
    1298 }
    1299 
    1300 /** Flush cached data to nonvolatile storage.
    1301  *
    1302  * @param disk          Disk
    1303  *
    1304  * @return EOK on success, EIO on error.
    1305  */
    1306 static errno_t ata_rcmd_flush_cache(disk_t *disk)
    1307 {
    1308         ata_ctrl_t *ctrl = disk->ctrl;
    1309         uint8_t drv_head;
    1310         errno_t rc;
    1311 
    1312         /* New value for Drive/Head register */
    1313         drv_head =
    1314             (disk_dev_idx(disk) != 0) ? DHR_DRV : 0;
    1315 
    1316         fibril_mutex_lock(&ctrl->lock);
    1317 
    1318         /* Program a Flush Cache operation. */
    1319 
    1320         if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {
    1321                 fibril_mutex_unlock(&ctrl->lock);
    1322                 return EIO;
    1323         }
    1324 
    1325         pio_write_8(&ctrl->cmd->drive_head, drv_head);
    1326 
    1327         if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {
    1328                 fibril_mutex_unlock(&ctrl->lock);
    1329                 return EIO;
    1330         }
    1331 
    1332         pio_write_8(&ctrl->cmd->command, CMD_FLUSH_CACHE);
    1333 
    1334         rc = ata_pio_nondata(disk);
    1335 
    1336         fibril_mutex_unlock(&ctrl->lock);
    1337         return rc;
    1338 }
    1339 
    1340 /** Get the maximum number of blocks to be transferred in one I/O
    1341  *
    1342  * @param d Disk
    1343  * @return Maximum number of blocks
    1344  */
    1345 static size_t ata_disk_maxnb(disk_t *d)
    1346 {
    1347         size_t maxnb;
    1348 
    1349         maxnb = 0;
    1350 
    1351         if (d->dev_type == ata_pkt_dev) {
    1352                 /* Could be more depending on SCSI command support */
    1353                 maxnb = 0x100;
    1354         } else {
    1355                 switch (d->amode) {
    1356                 case am_chs:
    1357                 case am_lba28:
    1358                         maxnb = 0x100;
    1359                         break;
    1360                 case am_lba48:
    1361                         maxnb = 0x10000;
    1362                         break;
    1363                 }
    1364         }
    1365 
    1366         /*
    1367          * If using DMA, this needs to be further restricted not to
    1368          * exceed DMA buffer size.
    1369          */
    1370         return maxnb;
    1371 }
    1372 
    1373 /** Calculate block coordinates.
    1374  *
    1375  * Calculates block coordinates in the best coordinate system supported
    1376  * by the device. These can be later programmed into the device using
    1377  * @c coord_sc_program().
    1378  *
    1379  * @return EOK on success or EINVAL if block index is past end of device.
    1380  */
    1381 static errno_t coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc)
    1382 {
    1383         uint64_t c;
    1384         uint64_t idx;
    1385 
    1386         /* Check device bounds. */
    1387         if (ba >= d->blocks)
    1388                 return EINVAL;
    1389 
    1390         bc->amode = d->amode;
    1391 
    1392         switch (d->amode) {
    1393         case am_chs:
    1394                 /* Compute CHS coordinates. */
    1395                 c = ba / (d->geom.heads * d->geom.sectors);
    1396                 idx = ba % (d->geom.heads * d->geom.sectors);
    1397 
    1398                 bc->cyl_lo = c & 0xff;
    1399                 bc->cyl_hi = (c >> 8) & 0xff;
    1400                 bc->h      = (idx / d->geom.sectors) & 0x0f;
    1401                 bc->sector = (1 + (idx % d->geom.sectors)) & 0xff;
    1402                 break;
    1403 
    1404         case am_lba28:
    1405                 /* Compute LBA-28 coordinates. */
    1406                 bc->c0 = ba & 0xff;             /* bits 0-7 */
    1407                 bc->c1 = (ba >> 8) & 0xff;      /* bits 8-15 */
    1408                 bc->c2 = (ba >> 16) & 0xff;     /* bits 16-23 */
    1409                 bc->h  = (ba >> 24) & 0x0f;     /* bits 24-27 */
    1410                 break;
    1411 
    1412         case am_lba48:
    1413                 /* Compute LBA-48 coordinates. */
    1414                 bc->c0 = ba & 0xff;             /* bits 0-7 */
    1415                 bc->c1 = (ba >> 8) & 0xff;      /* bits 8-15 */
    1416                 bc->c2 = (ba >> 16) & 0xff;     /* bits 16-23 */
    1417                 bc->c3 = (ba >> 24) & 0xff;     /* bits 24-31 */
    1418                 bc->c4 = (ba >> 32) & 0xff;     /* bits 32-39 */
    1419                 bc->c5 = (ba >> 40) & 0xff;     /* bits 40-47 */
    1420                 bc->h  = 0;
    1421                 break;
    1422         }
    1423 
    1424         return EOK;
    1425 }
    1426 
    1427 /** Program block coordinates and sector count into ATA registers.
    1428  *
    1429  * Note that bc->h must be programmed separately into the device/head register.
    1430  *
    1431  * @param ctrl          Controller
    1432  * @param bc            Block coordinates
    1433  * @param scnt          Sector count
    1434  */
    1435 static void coord_sc_program(ata_ctrl_t *ctrl, const block_coord_t *bc,
    1436     uint16_t scnt)
    1437 {
    1438         ata_cmd_t *cmd = ctrl->cmd;
    1439 
    1440         if (bc->amode == am_lba48) {
    1441                 /* Write high-order bits. */
    1442                 pio_write_8(&cmd->sector_count, scnt >> 8);
    1443                 pio_write_8(&cmd->sector_number, bc->c3);
    1444                 pio_write_8(&cmd->cylinder_low, bc->c4);
    1445                 pio_write_8(&cmd->cylinder_high, bc->c5);
    1446         }
    1447 
    1448         /* Write low-order bits. */
    1449         pio_write_8(&cmd->sector_count, scnt & 0x00ff);
    1450         pio_write_8(&cmd->sector_number, bc->c0);
    1451         pio_write_8(&cmd->cylinder_low, bc->c1);
    1452         pio_write_8(&cmd->cylinder_high, bc->c2);
    1453 }
    1454 
    1455 /** Wait until some status bits are set and some are reset.
    1456  *
    1457  * Example: wait_status(ctrl, SR_DRDY, ~SR_BSY, ...) waits for SR_DRDY to become
    1458  * set and SR_BSY to become reset.
    1459  *
    1460  * @param ctrl          Controller
    1461  * @param set           Combination if bits which must be all set.
    1462  * @param n_reset       Negated combination of bits which must be all reset.
    1463  * @param pstatus       Pointer where to store last read status or NULL.
    1464  * @param timeout       Timeout in 10ms units.
    1465  *
    1466  * @return              EOK on success, EIO on timeout.
    1467  */
    1468 static errno_t wait_status(ata_ctrl_t *ctrl, unsigned set, unsigned n_reset,
    1469     uint8_t *pstatus, unsigned timeout)
    1470 {
    1471         uint8_t status;
    1472         int cnt;
    1473 
    1474         status = pio_read_8(&ctrl->cmd->status);
    1475 
    1476         /*
    1477          * This is crude, yet simple. First try with 1us delays
    1478          * (most likely the device will respond very fast). If not,
    1479          * start trying every 10 ms.
    1480          */
    1481 
    1482         cnt = 100;
    1483         while ((status & ~n_reset) != 0 || (status & set) != set) {
    1484                 --cnt;
    1485                 if (cnt <= 0)
    1486                         break;
    1487 
    1488                 status = pio_read_8(&ctrl->cmd->status);
    1489         }
    1490 
    1491         cnt = timeout;
    1492         while ((status & ~n_reset) != 0 || (status & set) != set) {
    1493                 fibril_usleep(10000);
    1494                 --cnt;
    1495                 if (cnt <= 0)
    1496                         break;
    1497 
    1498                 status = pio_read_8(&ctrl->cmd->status);
    1499         }
    1500 
    1501         if (pstatus)
    1502                 *pstatus = status;
    1503 
    1504         if (cnt == 0)
    1505                 return EIO;
    1506 
    1507         return EOK;
    1508 }
    1509 
    1510 /** Wait for IRQ and return status.
    1511  *
    1512  * @param ctrl          Controller
    1513  * @param pstatus       Pointer where to store last read status or NULL.
    1514  * @param timeout       Timeout in 10ms units.
    1515  *
    1516  * @return              EOK on success, EIO on timeout.
    1517  */
    1518 static errno_t wait_irq(ata_ctrl_t *ctrl, uint8_t *pstatus, unsigned timeout)
    1519 {
    1520         fibril_mutex_lock(&ctrl->irq_lock);
    1521         while (!ctrl->irq_fired)
    1522                 fibril_condvar_wait(&ctrl->irq_cv, &ctrl->irq_lock);
    1523 
    1524         ctrl->irq_fired = false;
    1525         *pstatus = ctrl->irq_status;
    1526         fibril_mutex_unlock(&ctrl->irq_lock);
    1527         return EOK;
    1528 }
    1529 
    1530304/** Interrupt handler.
    1531305 *
     
    1540314
    1541315        status = ipc_get_arg1(call);
    1542 
    1543         fibril_mutex_lock(&ctrl->irq_lock);
    1544         ctrl->irq_fired = true;
    1545         ctrl->irq_status = status;
    1546         fibril_mutex_unlock(&ctrl->irq_lock);
    1547         fibril_condvar_broadcast(&ctrl->irq_cv);
     316        ata_channel_irq(ctrl->channel, status);
    1548317
    1549318        parent_sess = ddf_dev_parent_sess_get(dev);
     
    1551320}
    1552321
     322/** Write the data register callback handler.
     323 *
     324 * @param arg Argument (ata_ctrl_t *)
     325 * @param data Data
     326 * @param nwords Number of words to write
     327 */
     328static void ata_write_data_16(void *arg, uint16_t *data, size_t nwords)
     329{
     330        ata_ctrl_t *ctrl = (ata_ctrl_t *)arg;
     331        size_t i;
     332
     333        for (i = 0; i < nwords; i++)
     334                pio_write_16(&ctrl->cmd->data_port, data[i]);
     335}
     336
     337/** Read the data register callback handler.
     338 *
     339 * @param arg Argument (ata_ctrl_t *)
     340 * @param buf Destination buffer
     341 * @param nwords Number of words to read
     342 */
     343static void ata_read_data_16(void *arg, uint16_t *buf, size_t nwords)
     344{
     345        ata_ctrl_t *ctrl = (ata_ctrl_t *)arg;
     346        size_t i;
     347
     348        for (i = 0; i < nwords; i++)
     349                buf[i] = pio_read_16(&ctrl->cmd->data_port);
     350}
     351
     352/** Write command register callback handler.
     353 *
     354 * @param arg Argument (ata_ctrl_t *)
     355 * @param off Register offset
     356 * @param value Value to write to command register
     357 */
     358static void ata_write_cmd_8(void *arg, uint16_t off, uint8_t value)
     359{
     360        ata_ctrl_t *ctrl = (ata_ctrl_t *)arg;
     361
     362        pio_write_8(((ioport8_t *)ctrl->cmd) + off, value);
     363}
     364
     365/** Read command register callback handler.
     366 *
     367 * @param arg Argument (ata_ctrl_t *)
     368 * @param off Register offset
     369 * @return value Value read from command register
     370 */
     371static uint8_t ata_read_cmd_8(void *arg, uint16_t off)
     372{
     373        ata_ctrl_t *ctrl = (ata_ctrl_t *)arg;
     374
     375        return pio_read_8(((ioport8_t *)ctrl->cmd) + off);
     376}
     377
     378/** Write control register callback handler.
     379 *
     380 * @param arg Argument (ata_ctrl_t *)
     381 * @param off Register offset
     382 * @param value Value to write to control register
     383 */
     384static void ata_write_ctl_8(void *arg, uint16_t off, uint8_t value)
     385{
     386        ata_ctrl_t *ctrl = (ata_ctrl_t *)arg;
     387
     388        pio_write_8(((ioport8_t *)ctrl->ctl) + off, value);
     389}
     390
     391/** Read control register callback handler.
     392 *
     393 * @param arg Argument (ata_ctrl_t *)
     394 * @param off Register offset
     395 * @return value Value read from control register
     396 */
     397static uint8_t ata_read_ctl_8(void *arg, uint16_t off)
     398{
     399        ata_ctrl_t *ctrl = (ata_ctrl_t *)arg;
     400
     401        return pio_read_8(((ioport8_t *)ctrl->ctl) + off);
     402}
     403
     404/** Enable IRQ callback handler
     405 *
     406 * @param arg Argument (ata_ctrl_t *)
     407 * @return EOK on success or an error code
     408 */
     409static errno_t ata_irq_enable(void *arg)
     410{
     411        ata_ctrl_t *ctrl = (ata_ctrl_t *)arg;
     412        async_sess_t *parent_sess;
     413        errno_t rc;
     414
     415        ddf_msg(LVL_DEBUG, "Enable IRQ");
     416
     417        parent_sess = ddf_dev_parent_sess_get(ctrl->dev);
     418
     419        rc = hw_res_enable_interrupt(parent_sess, ctrl->irq);
     420        if (rc != EOK) {
     421                ddf_msg(LVL_ERROR, "Error enabling IRQ.");
     422                (void) unregister_interrupt_handler(ctrl->dev,
     423                    ctrl->ihandle);
     424                return rc;
     425        }
     426
     427        return EOK;
     428}
     429
     430/** Disable IRQ callback handler
     431 *
     432 * @param arg Argument (ata_ctrl_t *)
     433 * @return EOK on success or an error code
     434 */
     435static errno_t ata_irq_disable(void *arg)
     436{
     437        ata_ctrl_t *ctrl = (ata_ctrl_t *)arg;
     438        async_sess_t *parent_sess;
     439        errno_t rc;
     440
     441        ddf_msg(LVL_DEBUG, "Disable IRQ");
     442
     443        parent_sess = ddf_dev_parent_sess_get(ctrl->dev);
     444
     445        rc = hw_res_disable_interrupt(parent_sess, ctrl->irq);
     446        if (rc != EOK) {
     447                ddf_msg(LVL_ERROR, "Error enabling IRQ.");
     448                (void) unregister_interrupt_handler(ctrl->dev,
     449                    ctrl->ihandle);
     450                return rc;
     451        }
     452
     453        return EOK;
     454}
     455
     456/** Add ATA device callback handler.
     457 *
     458 * @param arg Argument (ata_ctrl_t *)
     459 * @param idx Device index
     460 * $param charg Connection handler argument
     461 * @return EOK on success or an error code
     462 */
     463static errno_t ata_add_device(void *arg, unsigned idx, void *charg)
     464{
     465        ata_ctrl_t *ctrl = (ata_ctrl_t *)arg;
     466        return ata_fun_create(ctrl, idx, charg);
     467}
     468
     469/** Remove ATA device callback handler.
     470 *
     471 * @param arg Argument (ata_ctrl_t *)
     472 * @param idx Device index
     473 * @return EOK on success or an error code
     474 */
     475static errno_t ata_remove_device(void *arg, unsigned idx)
     476{
     477        ata_ctrl_t *ctrl = (ata_ctrl_t *)arg;
     478        return ata_fun_remove(ctrl, idx);
     479}
     480
     481/** Debug message callback handler.
     482 *
     483 * @param arg Argument (ata_ctrl_t *)
     484 * @param msg Message
     485 */
     486static void ata_msg_debug(void *arg, char *msg)
     487{
     488        (void)arg;
     489        ddf_msg(LVL_DEBUG, "%s", msg);
     490}
     491
     492/** Notice message callback handler.
     493 *
     494 * @param arg Argument (ata_ctrl_t *)
     495 * @param msg Message
     496 */
     497static void ata_msg_note(void *arg, char *msg)
     498{
     499        (void)arg;
     500        ddf_msg(LVL_NOTE, "%s", msg);
     501}
     502
     503/** Warning message callback handler.
     504 *
     505 * @param arg Argument (ata_ctrl_t *)
     506 * @param msg Message
     507 */
     508static void ata_msg_warn(void *arg, char *msg)
     509{
     510        (void)arg;
     511        ddf_msg(LVL_WARN, "%s", msg);
     512}
     513
     514/** Error message callback handler.
     515 *
     516 * @param arg Argument (ata_ctrl_t *)
     517 * @param msg Message
     518 */
     519static void ata_msg_error(void *arg, char *msg)
     520{
     521        (void)arg;
     522        ddf_msg(LVL_ERROR, "%s", msg);
     523}
     524
    1553525/**
    1554526 * @}
  • uspace/drv/block/ata_bd/ata_bd.h

    r64cf7a3 r2791fbb7  
    3636#define __ATA_BD_H__
    3737
    38 #include <async.h>
    39 #include <bd_srv.h>
     38#include <ata/ata.h>
     39#include <ata/ata_hw.h>
    4040#include <ddf/driver.h>
    4141#include <fibril_synch.h>
    4242#include <stdbool.h>
    43 #include <str.h>
    4443#include <stdint.h>
    45 #include <stddef.h>
    46 #include "ata_hw.h"
    4744
    4845#define NAME "ata_bd"
     
    5451        int irq;        /**< IRQ */
    5552} ata_hwres_t;
    56 
    57 /** Timeout definitions. Unit is 10 ms. */
    58 enum ata_timeout {
    59         TIMEOUT_PROBE   =  100, /*  1 s */
    60         TIMEOUT_BSY     =  100, /*  1 s */
    61         TIMEOUT_DRDY    = 1000  /* 10 s */
    62 };
    63 
    64 enum ata_dev_type {
    65         ata_reg_dev,    /* Register device (no packet feature set support) */
    66         ata_pkt_dev     /* Packet device (supports packet feature set). */
    67 };
    68 
    69 /** Register device block addressing mode. */
    70 enum rd_addr_mode {
    71         am_chs,         /**< CHS block addressing */
    72         am_lba28,       /**< LBA-28 block addressing */
    73         am_lba48        /**< LBA-48 block addressing */
    74 };
    75 
    76 /** Block coordinates */
    77 typedef struct {
    78         enum rd_addr_mode amode;
    79 
    80         union {
    81                 /** CHS coordinates */
    82                 struct {
    83                         uint8_t sector;
    84                         uint8_t cyl_lo;
    85                         uint8_t cyl_hi;
    86                 };
    87                 /** LBA coordinates */
    88                 struct {
    89                         uint8_t c0;
    90                         uint8_t c1;
    91                         uint8_t c2;
    92                         uint8_t c3;
    93                         uint8_t c4;
    94                         uint8_t c5;
    95                 };
    96         };
    97 
    98         /** Lower 4 bits for device/head register */
    99         uint8_t h;
    100 } block_coord_t;
    101 
    102 /** ATA device state structure. */
    103 typedef struct {
    104         bool present;
    105         struct ata_ctrl *ctrl;
    106         struct ata_fun *afun;
    107 
    108         /** Device type */
    109         enum ata_dev_type dev_type;
    110 
    111         /** Addressing mode to use (if register device) */
    112         enum rd_addr_mode amode;
    113 
    114         /*
    115          * Geometry. Only valid if operating in CHS mode.
    116          */
    117         struct {
    118                 unsigned heads;
    119                 unsigned cylinders;
    120                 unsigned sectors;
    121         } geom;
    122 
    123         uint64_t blocks;
    124         size_t block_size;
    125 
    126         char model[STR_BOUNDS(40) + 1];
    127 
    128         int disk_id;
    129 } disk_t;
    13053
    13154/** ATA controller */
     
    14770        cap_irq_handle_t ihandle;
    14871
    149         /** Per-disk state. */
    150         disk_t disk[MAX_DISKS];
    151 
    15272        /** Synchronize controller access */
    15373        fibril_mutex_t lock;
    154         /** Synchronize access to irq_fired/irq_status */
    155         fibril_mutex_t irq_lock;
    156         /** Signalled by IRQ handler */
    157         fibril_condvar_t irq_cv;
    158         /** Set to true when interrupt occurs */
    159         bool irq_fired;
    16074        /** Value of status register read by interrupt handler */
    16175        uint8_t irq_status;
     76
     77        /** Libata ATA channel */
     78        ata_channel_t *channel;
     79        struct ata_fun *fun[2];
    16280} ata_ctrl_t;
    16381
    16482typedef struct ata_fun {
    16583        ddf_fun_t *fun;
    166         disk_t *disk;
    167         bd_srvs_t bds;
     84        void *charg;
    16885} ata_fun_t;
    16986
     
    17289extern errno_t ata_ctrl_gone(ata_ctrl_t *);
    17390
    174 extern bd_ops_t ata_bd_ops;
    175 
    17691#endif
    17792
  • uspace/drv/block/ata_bd/main.c

    r64cf7a3 r2791fbb7  
    157157}
    158158
    159 static char *ata_fun_name(disk_t *disk)
     159static char *ata_fun_name(unsigned idx)
    160160{
    161161        char *fun_name;
    162162
    163         if (asprintf(&fun_name, "d%u", disk->disk_id) < 0)
     163        if (asprintf(&fun_name, "d%u", idx) < 0)
    164164                return NULL;
    165165
     
    167167}
    168168
    169 errno_t ata_fun_create(disk_t *disk)
    170 {
    171         ata_ctrl_t *ctrl = disk->ctrl;
     169errno_t ata_fun_create(ata_ctrl_t *ctrl, unsigned idx, void *charg)
     170{
    172171        errno_t rc;
    173172        char *fun_name = NULL;
     
    176175        bool bound = false;
    177176
    178         fun_name = ata_fun_name(disk);
     177        fun_name = ata_fun_name(idx);
    179178        if (fun_name == NULL) {
    180179                ddf_msg(LVL_ERROR, "Out of memory.");
     
    199198
    200199        afun->fun = fun;
    201         afun->disk = disk;
    202 
    203         bd_srvs_init(&afun->bds);
    204         afun->bds.ops = &ata_bd_ops;
    205         afun->bds.sarg = disk;
     200        afun->charg = charg;
    206201
    207202        /* Set up a connection handler. */
     
    225220
    226221        free(fun_name);
    227         disk->afun = afun;
    228222        return EOK;
    229223error:
     
    238232}
    239233
    240 errno_t ata_fun_remove(disk_t *disk)
     234errno_t ata_fun_remove(ata_ctrl_t *ctrl, unsigned idx)
    241235{
    242236        errno_t rc;
    243237        char *fun_name;
    244 
    245         if (disk->afun == NULL)
    246                 return EOK;
    247 
    248         fun_name = ata_fun_name(disk);
     238        ata_fun_t *afun = ctrl->fun[idx];
     239
     240        fun_name = ata_fun_name(idx);
    249241        if (fun_name == NULL) {
    250242                ddf_msg(LVL_ERROR, "Out of memory.");
     
    253245        }
    254246
    255         ddf_msg(LVL_DEBUG, "ata_fun_remove(%p, '%s')", disk, fun_name);
    256         rc = ddf_fun_offline(disk->afun->fun);
     247        ddf_msg(LVL_DEBUG, "ata_fun_remove(%p, '%s')", afun, fun_name);
     248        rc = ddf_fun_offline(afun->fun);
    257249        if (rc != EOK) {
    258250                ddf_msg(LVL_ERROR, "Error offlining function '%s'.", fun_name);
     
    260252        }
    261253
    262         rc = ddf_fun_unbind(disk->afun->fun);
     254        rc = ddf_fun_unbind(afun->fun);
    263255        if (rc != EOK) {
    264256                ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", fun_name);
     
    266258        }
    267259
    268         ddf_fun_destroy(disk->afun->fun);
    269         disk->afun = NULL;
     260        ddf_fun_destroy(afun->fun);
    270261        free(fun_name);
    271262        return EOK;
     
    276267}
    277268
    278 errno_t ata_fun_unbind(disk_t *disk)
     269errno_t ata_fun_unbind(ata_ctrl_t *ctrl, unsigned idx)
    279270{
    280271        errno_t rc;
    281272        char *fun_name;
    282 
    283         if (disk->afun == NULL)
    284                 return EOK;
    285 
    286         fun_name = ata_fun_name(disk);
     273        ata_fun_t *afun = ctrl->fun[idx];
     274
     275        fun_name = ata_fun_name(idx);
    287276        if (fun_name == NULL) {
    288277                ddf_msg(LVL_ERROR, "Out of memory.");
     
    291280        }
    292281
    293         ddf_msg(LVL_DEBUG, "ata_fun_unbind(%p, '%s')", disk, fun_name);
    294         rc = ddf_fun_unbind(disk->afun->fun);
     282        ddf_msg(LVL_DEBUG, "ata_fun_unbind(%p, '%s')", afun, fun_name);
     283        rc = ddf_fun_unbind(afun->fun);
    295284        if (rc != EOK) {
    296285                ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", fun_name);
     
    298287        }
    299288
    300         ddf_fun_destroy(disk->afun->fun);
    301         disk->afun = NULL;
     289        ddf_fun_destroy(afun->fun);
    302290        free(fun_name);
    303291        return EOK;
     
    338326}
    339327
    340 /** Block device connection handler */
    341328static void ata_bd_connection(ipc_call_t *icall, void *arg)
    342329{
     
    344331
    345332        afun = (ata_fun_t *) ddf_fun_data_get((ddf_fun_t *)arg);
    346         bd_conn(icall, &afun->bds);
     333        ata_connection(icall, afun->charg);
    347334}
    348335
  • uspace/drv/block/ata_bd/main.h

    r64cf7a3 r2791fbb7  
    11/*
    2  * Copyright (c) 2013 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3838#include "ata_bd.h"
    3939
    40 extern errno_t ata_fun_create(disk_t *);
    41 extern errno_t ata_fun_remove(disk_t *);
    42 extern errno_t ata_fun_unbind(disk_t *);
     40extern errno_t ata_fun_create(ata_ctrl_t *, unsigned, void *);
     41extern errno_t ata_fun_remove(ata_ctrl_t *, unsigned);
     42extern errno_t ata_fun_unbind(ata_ctrl_t *, unsigned);
    4343
    4444#endif
  • uspace/drv/block/ata_bd/meson.build

    r64cf7a3 r2791fbb7  
    2727#
    2828
    29 deps = [ 'scsi' ]
     29deps = [ 'ata', 'scsi' ]
    3030src = files('ata_bd.c', 'main.c')
  • uspace/lib/ata/include/ata/ata_hw.h

    r64cf7a3 r2791fbb7  
    11/*
    2  * Copyright (c) 2009 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup ata_bd
     29/** @addtogroup libata
    3030 * @{
    3131 */
     
    3333 */
    3434
    35 #ifndef __ATA_HW_H__
    36 #define __ATA_HW_H__
    37 
     35#ifndef LIBATA_ATA_HW_H
     36#define LIBATA_ATA_HW_H
     37
     38#include <stddef.h>
    3839#include <stdint.h>
    3940
     
    4849
    4950enum {
    50         MAX_DISKS       = 2
     51        MAX_DEVICES     = 2
    5152};
    5253
     
    9697        };
    9798} ata_ctl_t;
     99
     100#define REG_SECTOR_COUNT offsetof(ata_cmd_t, sector_count)
     101#define REG_SECTOR_NUMBER offsetof(ata_cmd_t, sector_number)
     102#define REG_CYLINDER_LOW offsetof(ata_cmd_t, cylinder_low)
     103#define REG_CYLINDER_HIGH offsetof(ata_cmd_t, cylinder_high)
     104#define REG_DRIVE_HEAD offsetof(ata_cmd_t, drive_head)
     105#define REG_STATUS offsetof(ata_cmd_t, status)
     106#define REG_COMMAND offsetof(ata_cmd_t, command)
    98107
    99108enum devctl_bits {
  • uspace/lib/meson.build

    r64cf7a3 r2791fbb7  
    111111        'virtio',
    112112
     113        'ata',
    113114        'ieee80211',
    114115        'ddev',
Note: See TracChangeset for help on using the changeset viewer.