Ignore:
File:
1 edited

Legend:

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

    r5c55eb7 rfafb8e5  
    11/*
    2  * Copyright (c) 2025 Jiri Svoboda
    32 * Copyright (c) 2012 Petr Jerman
    43 * All rights reserved.
     
    3332
    3433#include <as.h>
    35 #include <bd_srv.h>
    3634#include <errno.h>
    3735#include <stdio.h>
     
    4139#include <device/hw_res_parsed.h>
    4240#include <pci_dev_iface.h>
     41#include <ahci_iface.h>
    4342#include "ahci.h"
    4443#include "ahci_hw.h"
     
    110109        }
    111110
    112 static errno_t ahci_read_blocks(sata_dev_t *, uint64_t, size_t, void *);
    113 static errno_t ahci_write_blocks(sata_dev_t *, uint64_t, size_t, void *);
     111static errno_t get_sata_device_name(ddf_fun_t *, size_t, char *);
     112static errno_t get_num_blocks(ddf_fun_t *, uint64_t *);
     113static errno_t get_block_size(ddf_fun_t *, size_t *);
     114static errno_t read_blocks(ddf_fun_t *, uint64_t, size_t, void *);
     115static errno_t write_blocks(ddf_fun_t *, uint64_t, size_t, void *);
    114116
    115117static errno_t ahci_identify_device(sata_dev_t *);
     
    129131static int sata_devices_count = 0;
    130132
    131 static errno_t ahci_bd_open(bd_srvs_t *, bd_srv_t *);
    132 static errno_t ahci_bd_close(bd_srv_t *);
    133 static errno_t ahci_bd_read_blocks(bd_srv_t *, aoff64_t, size_t, void *, size_t);
    134 static errno_t ahci_bd_write_blocks(bd_srv_t *, aoff64_t, size_t, const void *, size_t);
    135 static errno_t ahci_bd_get_block_size(bd_srv_t *, size_t *);
    136 static errno_t ahci_bd_get_num_blocks(bd_srv_t *, aoff64_t *);
    137 
    138 static void ahci_bd_connection(ipc_call_t *, void *);
    139 
    140 static 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
     133/*----------------------------------------------------------------------------*/
     134/*-- AHCI Interface ----------------------------------------------------------*/
     135/*----------------------------------------------------------------------------*/
     136
     137static 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
     145static ddf_dev_ops_t ahci_ops = {
     146        .interfaces[AHCI_DEV_IFACE] = &ahci_interface
    147147};
    148148
     
    156156};
    157157
    158 /** Get SATA structure from block device service structure. */
    159 static 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
     158/** Get SATA structure from DDF function. */
     159static 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. */
     165static 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 */
     179static 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 */
     195static 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 */
     210static 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.
    167220 * @param blocknum Number of first block.
    168221 * @param count    Number of blocks to read.
    169222 * @param buf      Buffer for data.
    170223 *
    171  * @return EOK on success, error code otherwise
    172  *
    173  */
    174 static errno_t ahci_read_blocks(sata_dev_t *sata, uint64_t blocknum,
     224 * @return EOK if succeed, error code otherwise
     225 *
     226 */
     227static errno_t read_blocks(ddf_fun_t *fun, uint64_t blocknum,
    175228    size_t count, void *buf)
    176229{
     230        sata_dev_t *sata = fun_sata_dev(fun);
     231
    177232        uintptr_t phys;
    178233        void *ibuf = AS_AREA_ANY;
     
    203258}
    204259
    205 /** Write data blocks to SATA device.
    206  *
    207  * @param sata     SATA device
     260/** Write data blocks into SATA device.
     261 *
     262 * @param fun      Device function handling the call.
    208263 * @param blocknum Number of first block.
    209264 * @param count    Number of blocks to write.
    210265 * @param buf      Buffer with data.
    211266 *
    212  * @return EOK on success, error code otherwise
    213  */
    214 static errno_t ahci_write_blocks(sata_dev_t *sata, uint64_t blocknum,
     267 * @return EOK if succeed, error code otherwise
     268 *
     269 */
     270static errno_t write_blocks(ddf_fun_t *fun, uint64_t blocknum,
    215271    size_t count, void *buf)
    216272{
     273        sata_dev_t *sata = fun_sata_dev(fun);
     274
    217275        uintptr_t phys;
    218276        void *ibuf = AS_AREA_ANY;
     
    240298}
    241299
    242 /** Open device. */
    243 static errno_t ahci_bd_open(bd_srvs_t *bds, bd_srv_t *bd)
    244 {
    245         return EOK;
    246 }
    247 
    248 /** Close device. */
    249 static errno_t ahci_bd_close(bd_srv_t *bd)
    250 {
    251         return EOK;
    252 }
    253 
    254 /** Read blocks from partition. */
    255 static 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. */
    267 static 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. */
    279 static 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. */
    288 static 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 
    296 static 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  */
     300/*----------------------------------------------------------------------------*/
     301/*-- AHCI Commands -----------------------------------------------------------*/
     302/*----------------------------------------------------------------------------*/
    307303
    308304/** Wait for interrupt event.
     
    425421 * @param sata SATA device structure.
    426422 *
    427  * @return EOK on success, error code otherwise.
     423 * @return EOK if succeed, error code otherwise.
    428424 *
    429425 */
     
    606602 * @param sata SATA device structure.
    607603 *
    608  * @return EOK on success, error code otherwise
     604 * @return EOK if succeed, error code otherwise
    609605 *
    610606 */
     
    735731 * @param blocknum Block number to read.
    736732 *
    737  * @return EOK on success, error code otherwise
     733 * @return EOK if succeed, error code otherwise
    738734 *
    739735 */
     
    764760 * @param blocknum Block number to write.
    765761 *
    766  * @return EOK on success, error code otherwise
     762 * @return EOK if succeed, error code otherwise
    767763 *
    768764 */
     
    823819 * @param blocknum Block number to write.
    824820 *
    825  * @return EOK on success, error code otherwise
     821 * @return EOK if succeed, error code otherwise
    826822 *
    827823 */
     
    846842}
    847843
    848 /*
    849  * Interrupts handling
    850  */
     844/*----------------------------------------------------------------------------*/
     845/*-- Interrupts handling -----------------------------------------------------*/
     846/*----------------------------------------------------------------------------*/
    851847
    852848static irq_pio_range_t ahci_ranges[] = {
     
    895891 *
    896892 * @param icall The IPC call structure.
    897  * @param arg   Argument (ahci_dev_t *)
    898  */
    899 static void ahci_interrupt(ipc_call_t *icall, void *arg)
    900 {
    901         ahci_dev_t *ahci = (ahci_dev_t *)arg;
     893 * @param dev   DDF device structure.
     894 *
     895 */
     896static void ahci_interrupt(ipc_call_t *icall, ddf_dev_t *dev)
     897{
     898        ahci_dev_t *ahci = dev_ahci_dev(dev);
    902899        unsigned int port = ipc_get_arg1(icall);
    903900        ahci_port_is_t pxis = ipc_get_arg2(icall);
     
    922919}
    923920
    924 /*
    925  * AHCI and SATA device creating and initializing routines
    926  */
     921/*----------------------------------------------------------------------------*/
     922/*-- AHCI and SATA device creating and initializing routines -----------------*/
     923/*----------------------------------------------------------------------------*/
    927924
    928925/** Allocate SATA device structure with buffers for hardware.
     
    930927 * @param port AHCI port structure
    931928 *
    932  * @return SATA device structure on success, NULL otherwise.
     929 * @return SATA device structure if succeed, NULL otherwise.
    933930 *
    934931 */
     
    10381035 * @param port_num Number of AHCI port with existing SATA device.
    10391036 *
    1040  * @return EOK on success, error code otherwise.
     1037 * @return EOK if succeed, error code otherwise.
    10411038 *
    10421039 */
     
    10451042{
    10461043        ddf_fun_t *fun = NULL;
    1047         bool bound = false;
    10481044        errno_t rc;
    10491045
     
    10861082        }
    10871083
    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);
     1084        ddf_fun_set_ops(fun, &ahci_ops);
    11001085
    11011086        rc = ddf_fun_bind(fun);
     
    11051090        }
    11061091
    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 
    11161092        return EOK;
    11171093
    11181094error:
    1119         if (bound)
    1120                 ddf_fun_unbind(fun);
    11211095        sata->is_invalid_device = true;
    11221096        if (fun != NULL)
     
    11551129 * @param dev DDF device structure.
    11561130 *
    1157  * @return AHCI device structure on success, NULL otherwise.
     1131 * @return AHCI device structure if succeed, NULL otherwise.
    11581132 *
    11591133 */
     
    12121186        cap_irq_handle_t irq_cap;
    12131187        errno_t rc = register_interrupt_handler(dev,
    1214             hw_res_parsed.irqs.irqs[0], ahci_interrupt, (void *)ahci, &ct,
    1215             &irq_cap);
     1188            hw_res_parsed.irqs.irqs[0], ahci_interrupt, &ct, &irq_cap);
    12161189        if (rc != EOK) {
    12171190                ddf_msg(LVL_ERROR, "Failed registering interrupt handler.");
     
    12791252 * @param dev DDF device structure.
    12801253 *
    1281  * @return EOK on success, error code otherwise.
     1254 * @return EOK if succeed, error code otherwise.
    12821255 *
    12831256 */
     
    13001273}
    13011274
    1302 /*
    1303  * Helpers and utilities
    1304  */
     1275/*----------------------------------------------------------------------------*/
     1276/*-- Helpers and utilities ---------------------------------------------------*/
     1277/*----------------------------------------------------------------------------*/
    13051278
    13061279/** Convert SATA model name
     
    13401313}
    13411314
    1342 /*
    1343  * AHCI Main routine
    1344  */
     1315/*----------------------------------------------------------------------------*/
     1316/*-- AHCI Main routine -------------------------------------------------------*/
     1317/*----------------------------------------------------------------------------*/
    13451318
    13461319int main(int argc, char *argv[])
Note: See TracChangeset for help on using the changeset viewer.