Ignore:
File:
1 edited

Legend:

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

    rfafb8e5 r5c55eb7  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2012 Petr Jerman
    34 * All rights reserved.
     
    3233
    3334#include <as.h>
     35#include <bd_srv.h>
    3436#include <errno.h>
    3537#include <stdio.h>
     
    3941#include <device/hw_res_parsed.h>
    4042#include <pci_dev_iface.h>
    41 #include <ahci_iface.h>
    4243#include "ahci.h"
    4344#include "ahci_hw.h"
     
    109110        }
    110111
    111 static errno_t get_sata_device_name(ddf_fun_t *, size_t, char *);
    112 static errno_t get_num_blocks(ddf_fun_t *, uint64_t *);
    113 static errno_t get_block_size(ddf_fun_t *, size_t *);
    114 static errno_t read_blocks(ddf_fun_t *, uint64_t, size_t, void *);
    115 static errno_t write_blocks(ddf_fun_t *, uint64_t, size_t, void *);
     112static errno_t ahci_read_blocks(sata_dev_t *, uint64_t, size_t, void *);
     113static errno_t ahci_write_blocks(sata_dev_t *, uint64_t, size_t, void *);
    116114
    117115static errno_t ahci_identify_device(sata_dev_t *);
     
    131129static int sata_devices_count = 0;
    132130
    133 /*----------------------------------------------------------------------------*/
    134 /*-- AHCI Interface ----------------------------------------------------------*/
    135 /*----------------------------------------------------------------------------*/
    136 
    137 static ahci_iface_t ahci_interface = {
    138         .get_sata_device_name = &get_sata_device_name,
    139         .get_num_blocks = &get_num_blocks,
    140         .get_block_size = &get_block_size,
    141         .read_blocks = &read_blocks,
    142         .write_blocks = &write_blocks
    143 };
    144 
    145 static ddf_dev_ops_t ahci_ops = {
    146         .interfaces[AHCI_DEV_IFACE] = &ahci_interface
     131static errno_t ahci_bd_open(bd_srvs_t *, bd_srv_t *);
     132static errno_t ahci_bd_close(bd_srv_t *);
     133static errno_t ahci_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
     134static errno_t ahci_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
     135static errno_t ahci_bd_get_block_size(bd_srv_t *, size_t *);
     136static errno_t ahci_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
     137
     138static void ahci_bd_connection(ipc_call_t *, void *);
     139
     140static bd_ops_t ahci_bd_ops = {
     141        .open = ahci_bd_open,
     142        .close = ahci_bd_close,
     143        .read_blocks = ahci_bd_read_blocks,
     144        .write_blocks = ahci_bd_write_blocks,
     145        .get_block_size = ahci_bd_get_block_size,
     146        .get_num_blocks = ahci_bd_get_num_blocks
    147147};
    148148
     
    156156};
    157157
    158 /** Get SATA structure from DDF function. */
    159 static sata_dev_t *fun_sata_dev(ddf_fun_t *fun)
    160 {
    161         return ddf_fun_data_get(fun);
    162 }
    163 
    164 /** Get AHCI structure from DDF device. */
    165 static ahci_dev_t *dev_ahci_dev(ddf_dev_t *dev)
    166 {
    167         return ddf_dev_data_get(dev);
    168 }
    169 
    170 /** Get SATA device name.
    171  *
    172  * @param fun                  Device function handling the call.
    173  * @param sata_dev_name_length Length of the sata_dev_name buffer.
    174  * @param sata_dev_name        Buffer for SATA device name.
    175  *
    176  * @return EOK.
    177  *
    178  */
    179 static errno_t get_sata_device_name(ddf_fun_t *fun,
    180     size_t sata_dev_name_length, char *sata_dev_name)
    181 {
    182         sata_dev_t *sata = fun_sata_dev(fun);
    183         str_cpy(sata_dev_name, sata_dev_name_length, sata->model);
    184         return EOK;
    185 }
    186 
    187 /** Get Number of blocks in SATA device.
    188  *
    189  * @param fun    Device function handling the call.
    190  * @param blocks Return number of blocks in SATA device.
    191  *
    192  * @return EOK.
    193  *
    194  */
    195 static errno_t get_num_blocks(ddf_fun_t *fun, uint64_t *num_blocks)
    196 {
    197         sata_dev_t *sata = fun_sata_dev(fun);
    198         *num_blocks = sata->blocks;
    199         return EOK;
    200 }
    201 
    202 /** Get SATA device block size.
    203  *
    204  * @param fun        Device function handling the call.
    205  * @param block_size Return block size.
    206  *
    207  * @return EOK.
    208  *
    209  */
    210 static errno_t get_block_size(ddf_fun_t *fun, size_t *block_size)
    211 {
    212         sata_dev_t *sata = fun_sata_dev(fun);
    213         *block_size = sata->block_size;
    214         return EOK;
    215 }
    216 
    217 /** Read data blocks into SATA device.
    218  *
    219  * @param fun      Device function handling the call.
     158/** Get SATA structure from block device service structure. */
     159static sata_dev_t *bd_srv_sata(bd_srv_t *bd)
     160{
     161        return (sata_dev_t *) bd->srvs->sarg;
     162}
     163
     164/** Read data blocks from SATA device.
     165 *
     166 * @param sata     SATA device
    220167 * @param blocknum Number of first block.
    221168 * @param count    Number of blocks to read.
    222169 * @param buf      Buffer for data.
    223170 *
    224  * @return EOK if succeed, error code otherwise
    225  *
    226  */
    227 static errno_t read_blocks(ddf_fun_t *fun, uint64_t blocknum,
     171 * @return EOK on success, error code otherwise
     172 *
     173 */
     174static errno_t ahci_read_blocks(sata_dev_t *sata, uint64_t blocknum,
    228175    size_t count, void *buf)
    229176{
    230         sata_dev_t *sata = fun_sata_dev(fun);
    231 
    232177        uintptr_t phys;
    233178        void *ibuf = AS_AREA_ANY;
     
    258203}
    259204
    260 /** Write data blocks into SATA device.
    261  *
    262  * @param fun      Device function handling the call.
     205/** Write data blocks to SATA device.
     206 *
     207 * @param sata     SATA device
    263208 * @param blocknum Number of first block.
    264209 * @param count    Number of blocks to write.
    265210 * @param buf      Buffer with data.
    266211 *
    267  * @return EOK if succeed, error code otherwise
    268  *
    269  */
    270 static errno_t write_blocks(ddf_fun_t *fun, uint64_t blocknum,
     212 * @return EOK on success, error code otherwise
     213 */
     214static errno_t ahci_write_blocks(sata_dev_t *sata, uint64_t blocknum,
    271215    size_t count, void *buf)
    272216{
    273         sata_dev_t *sata = fun_sata_dev(fun);
    274 
    275217        uintptr_t phys;
    276218        void *ibuf = AS_AREA_ANY;
     
    298240}
    299241
    300 /*----------------------------------------------------------------------------*/
    301 /*-- AHCI Commands -----------------------------------------------------------*/
    302 /*----------------------------------------------------------------------------*/
     242/** Open device. */
     243static errno_t ahci_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
     244{
     245        return EOK;
     246}
     247
     248/** Close device. */
     249static errno_t ahci_bd_close(bd_srv_t *bd)
     250{
     251        return EOK;
     252}
     253
     254/** Read blocks from partition. */
     255static errno_t ahci_bd_read_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
     256    void *buf, size_t size)
     257{
     258        sata_dev_t *sata = bd_srv_sata(bd);
     259
     260        if (size < cnt * sata->block_size)
     261                return EINVAL;
     262
     263        return ahci_read_blocks(sata, ba, cnt, buf);
     264}
     265
     266/** Write blocks to partition. */
     267static errno_t ahci_bd_write_blocks(bd_srv_t *bd, aoff64_t ba, size_t cnt,
     268    const void *buf, size_t size)
     269{
     270        sata_dev_t *sata = bd_srv_sata(bd);
     271
     272        if (size < cnt * sata->block_size)
     273                return EINVAL;
     274
     275        return ahci_write_blocks(sata, ba, cnt, (void *)buf);
     276}
     277
     278/** Get device block size. */
     279static errno_t ahci_bd_get_block_size(bd_srv_t *bd, size_t *rsize)
     280{
     281        sata_dev_t *sata = bd_srv_sata(bd);
     282
     283        *rsize = sata->block_size;
     284        return EOK;
     285}
     286
     287/** Get number of blocks on device. */
     288static errno_t ahci_bd_get_num_blocks(bd_srv_t *bd, aoff64_t *rnb)
     289{
     290        sata_dev_t *sata = bd_srv_sata(bd);
     291
     292        *rnb = sata->blocks;
     293        return EOK;
     294}
     295
     296static void ahci_bd_connection(ipc_call_t *icall, void *arg)
     297{
     298        sata_dev_t *sata;
     299
     300        sata = (sata_dev_t *) ddf_fun_data_get((ddf_fun_t *)arg);
     301        bd_conn(icall, &sata->bds);
     302}
     303
     304/*
     305 * AHCI Commands
     306 */
    303307
    304308/** Wait for interrupt event.
     
    421425 * @param sata SATA device structure.
    422426 *
    423  * @return EOK if succeed, error code otherwise.
     427 * @return EOK on success, error code otherwise.
    424428 *
    425429 */
     
    602606 * @param sata SATA device structure.
    603607 *
    604  * @return EOK if succeed, error code otherwise
     608 * @return EOK on success, error code otherwise
    605609 *
    606610 */
     
    731735 * @param blocknum Block number to read.
    732736 *
    733  * @return EOK if succeed, error code otherwise
     737 * @return EOK on success, error code otherwise
    734738 *
    735739 */
     
    760764 * @param blocknum Block number to write.
    761765 *
    762  * @return EOK if succeed, error code otherwise
     766 * @return EOK on success, error code otherwise
    763767 *
    764768 */
     
    819823 * @param blocknum Block number to write.
    820824 *
    821  * @return EOK if succeed, error code otherwise
     825 * @return EOK on success, error code otherwise
    822826 *
    823827 */
     
    842846}
    843847
    844 /*----------------------------------------------------------------------------*/
    845 /*-- Interrupts handling -----------------------------------------------------*/
    846 /*----------------------------------------------------------------------------*/
     848/*
     849 * Interrupts handling
     850 */
    847851
    848852static irq_pio_range_t ahci_ranges[] = {
     
    891895 *
    892896 * @param icall The IPC call structure.
    893  * @param dev   DDF device structure.
    894  *
    895  */
    896 static void ahci_interrupt(ipc_call_t *icall, ddf_dev_t *dev)
    897 {
    898         ahci_dev_t *ahci = dev_ahci_dev(dev);
     897 * @param arg   Argument (ahci_dev_t *)
     898 */
     899static void ahci_interrupt(ipc_call_t *icall, void *arg)
     900{
     901        ahci_dev_t *ahci = (ahci_dev_t *)arg;
    899902        unsigned int port = ipc_get_arg1(icall);
    900903        ahci_port_is_t pxis = ipc_get_arg2(icall);
     
    919922}
    920923
    921 /*----------------------------------------------------------------------------*/
    922 /*-- AHCI and SATA device creating and initializing routines -----------------*/
    923 /*----------------------------------------------------------------------------*/
     924/*
     925 * AHCI and SATA device creating and initializing routines
     926 */
    924927
    925928/** Allocate SATA device structure with buffers for hardware.
     
    927930 * @param port AHCI port structure
    928931 *
    929  * @return SATA device structure if succeed, NULL otherwise.
     932 * @return SATA device structure on success, NULL otherwise.
    930933 *
    931934 */
     
    10351038 * @param port_num Number of AHCI port with existing SATA device.
    10361039 *
    1037  * @return EOK if succeed, error code otherwise.
     1040 * @return EOK on success, error code otherwise.
    10381041 *
    10391042 */
     
    10421045{
    10431046        ddf_fun_t *fun = NULL;
     1047        bool bound = false;
    10441048        errno_t rc;
    10451049
     
    10821086        }
    10831087
    1084         ddf_fun_set_ops(fun, &ahci_ops);
     1088        fun = sata->fun;
     1089
     1090        bd_srvs_init(&sata->bds);
     1091        sata->bds.ops = &ahci_bd_ops;
     1092        sata->bds.sarg = (void *)sata;
     1093
     1094        /* Set up a connection handler. */
     1095        ddf_fun_set_conn_handler(fun, ahci_bd_connection);
     1096
     1097        ddf_msg(LVL_NOTE, "Device %s - %s, blocks: %" PRIu64
     1098            " block_size: %zu\n", sata_dev_name, sata->model, sata->blocks,
     1099            sata->block_size);
    10851100
    10861101        rc = ddf_fun_bind(fun);
     
    10901105        }
    10911106
     1107        bound = true;
     1108
     1109        rc = ddf_fun_add_to_category(fun, "disk");
     1110        if (rc != EOK) {
     1111                ddf_msg(LVL_ERROR, "Failed adding function %s to category "
     1112                    "'disk'.", sata_dev_name);
     1113                goto error;
     1114        }
     1115
    10921116        return EOK;
    10931117
    10941118error:
     1119        if (bound)
     1120                ddf_fun_unbind(fun);
    10951121        sata->is_invalid_device = true;
    10961122        if (fun != NULL)
     
    11291155 * @param dev DDF device structure.
    11301156 *
    1131  * @return AHCI device structure if succeed, NULL otherwise.
     1157 * @return AHCI device structure on success, NULL otherwise.
    11321158 *
    11331159 */
     
    11861212        cap_irq_handle_t irq_cap;
    11871213        errno_t rc = register_interrupt_handler(dev,
    1188             hw_res_parsed.irqs.irqs[0], ahci_interrupt, &ct, &irq_cap);
     1214            hw_res_parsed.irqs.irqs[0], ahci_interrupt, (void *)ahci, &ct,
     1215            &irq_cap);
    11891216        if (rc != EOK) {
    11901217                ddf_msg(LVL_ERROR, "Failed registering interrupt handler.");
     
    12521279 * @param dev DDF device structure.
    12531280 *
    1254  * @return EOK if succeed, error code otherwise.
     1281 * @return EOK on success, error code otherwise.
    12551282 *
    12561283 */
     
    12731300}
    12741301
    1275 /*----------------------------------------------------------------------------*/
    1276 /*-- Helpers and utilities ---------------------------------------------------*/
    1277 /*----------------------------------------------------------------------------*/
     1302/*
     1303 * Helpers and utilities
     1304 */
    12781305
    12791306/** Convert SATA model name
     
    13131340}
    13141341
    1315 /*----------------------------------------------------------------------------*/
    1316 /*-- AHCI Main routine -------------------------------------------------------*/
    1317 /*----------------------------------------------------------------------------*/
     1342/*
     1343 * AHCI Main routine
     1344 */
    13181345
    13191346int main(int argc, char *argv[])
Note: See TracChangeset for help on using the changeset viewer.