Changeset 03c971f in mainline for uspace/drv


Ignore:
Timestamp:
2013-08-15T14:20:16Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bb2a5b2
Parents:
f2c19b0 (diff), 2921602 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Mainline changes.

Location:
uspace/drv
Files:
4 added
21 edited
3 moved

Legend:

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

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

    rf2c19b0 r03c971f  
    3636#define __ATA_BD_H__
    3737
     38#include <async.h>
    3839#include <bd_srv.h>
     40#include <ddf/driver.h>
    3941#include <sys/types.h>
    4042#include <fibril_synch.h>
    4143#include <str.h>
     44#include "ata_hw.h"
     45
     46#define NAME "ata_bd"
    4247
    4348/** Base addresses for ATA I/O blocks. */
     
    95100typedef struct {
    96101        bool present;
     102        struct ata_ctrl *ctrl;
     103        struct ata_fun *afun;
    97104
    98105        /** Device type */
     
    116123        char model[STR_BOUNDS(40) + 1];
    117124
     125        int disk_id;
     126} disk_t;
     127
     128/** ATA controller */
     129typedef struct ata_ctrl {
     130        /** DDF device */
     131        ddf_dev_t *dev;
     132        /** I/O base address of the command registers */
     133        uintptr_t cmd_physical;
     134        /** I/O base address of the control registers */
     135        uintptr_t ctl_physical;
     136
     137        /** Command registers */
     138        ata_cmd_t *cmd;
     139        /** Control registers */
     140        ata_ctl_t *ctl;
     141
     142        /** Per-disk state. */
     143        disk_t disk[MAX_DISKS];
     144
    118145        fibril_mutex_t lock;
    119         service_id_t service_id;
    120         int disk_id;
     146} ata_ctrl_t;
     147
     148typedef struct ata_fun {
     149        ddf_fun_t *fun;
     150        disk_t *disk;
    121151        bd_srvs_t bds;
    122 } disk_t;
     152} ata_fun_t;
     153
     154extern int ata_ctrl_init(ata_ctrl_t *, ata_base_t *);
     155extern int ata_ctrl_remove(ata_ctrl_t *);
     156extern int ata_ctrl_gone(ata_ctrl_t *);
     157
     158extern bd_ops_t ata_bd_ops;
    123159
    124160#endif
  • uspace/drv/bus/isa/isa.dev

    rf2c19b0 r03c971f  
    3131        match 100 isa/cmos-rtc
    3232        io_range 70 2
     33
     34ata-c1:
     35        match 100 isa/ata_bd
     36        io_range 0x1f0 8
     37        io_range 0x3f0 8
     38
     39ata-c2:
     40        match 100 isa/ata_bd
     41        io_range 0x170 8
     42        io_range 0x370 8
     43
     44ata-c3:
     45        match 100 isa/ata_bd
     46        io_range 0x1e8 8
     47        io_range 0x3e8 8
     48
     49ata-c4:
     50        match 100 isa/ata_bd
     51        io_range 0x168 8
     52        io_range 0x368 8
  • uspace/drv/bus/usb/ehci/main.c

    rf2c19b0 r03c971f  
    3333 * Main routines of EHCI driver.
    3434 */
     35
    3536#include <ddf/driver.h>
    3637#include <ddf/interrupt.h>
    3738#include <device/hw_res.h>
    3839#include <errno.h>
     40#include <stdbool.h>
    3941#include <str_error.h>
    4042
     
    7072static int ehci_dev_add(ddf_dev_t *device)
    7173{
     74        ddf_fun_t *hc_fun = NULL;
     75        bool fun_bound = false;
     76
    7277        assert(device);
    73 #define CHECK_RET_RETURN(ret, message...) \
    74 if (ret != EOK) { \
    75         usb_log_error(message); \
    76         return ret; \
    77 }
    7878
    7979        uintptr_t reg_base = 0;
     
    8181        int irq = 0;
    8282
    83         int ret = get_my_registers(device, &reg_base, &reg_size, &irq);
    84         CHECK_RET_RETURN(ret,
    85             "Failed to get memory addresses for %" PRIun ": %s.\n",
    86             ddf_dev_get_handle(device), str_error(ret));
     83        int rc = get_my_registers(device, &reg_base, &reg_size, &irq);
     84        if (rc != EOK) {
     85                usb_log_error("Failed to get memory addresses for %" PRIun
     86                    ": %s.\n", ddf_dev_get_handle(device), str_error(rc));
     87                goto error;
     88        }
     89
    8790        usb_log_info("Memory mapped regs at 0x%" PRIxn " (size %zu), IRQ %d.\n",
    8891            reg_base, reg_size, irq);
    8992
    90         ret = disable_legacy(device, reg_base, reg_size);
    91         CHECK_RET_RETURN(ret,
    92             "Failed to disable legacy USB: %s.\n", str_error(ret));
     93        rc = disable_legacy(device, reg_base, reg_size);
     94        if (rc != EOK) {
     95                usb_log_error("Failed to disable legacy USB: %s.\n",
     96                    str_error(rc));
     97                goto error;
     98        }
    9399
    94         ddf_fun_t *hc_fun = ddf_fun_create(device, fun_exposed, "ehci_hc");
     100        hc_fun = ddf_fun_create(device, fun_exposed, "ehci_hc");
    95101        if (hc_fun == NULL) {
    96102                usb_log_error("Failed to create EHCI function.\n");
    97                 return ENOMEM;
     103                rc = ENOMEM;
     104                goto error;
    98105        }
     106
    99107        hcd_t *ehci_hc = ddf_fun_data_alloc(hc_fun, sizeof(hcd_t));
    100108        if (ehci_hc == NULL) {
    101109                usb_log_error("Failed to alloc generic HC driver.\n");
    102                 return ENOMEM;
     110                rc = ENOMEM;
     111                goto error;
    103112        }
     113
    104114        /* High Speed, no bandwidth */
    105115        hcd_init(ehci_hc, USB_SPEED_HIGH, 0, NULL);
    106116        ddf_fun_set_ops(hc_fun,  &hc_ops);
    107117
    108         ret = ddf_fun_bind(hc_fun);
    109         CHECK_RET_RETURN(ret,
    110             "Failed to bind EHCI function: %s.\n",
    111             str_error(ret));
    112         ret = ddf_fun_add_to_category(hc_fun, USB_HC_CATEGORY);
    113         CHECK_RET_RETURN(ret,
    114             "Failed to add EHCI to HC class: %s.\n",
    115             str_error(ret));
     118        rc = ddf_fun_bind(hc_fun);
     119        if (rc != EOK) {
     120                usb_log_error("Failed to bind EHCI function: %s.\n",
     121                    str_error(rc));
     122                goto error;
     123        }
     124
     125        fun_bound = true;
     126
     127        rc = ddf_fun_add_to_category(hc_fun, USB_HC_CATEGORY);
     128        if (rc != EOK) {
     129                usb_log_error("Failed to add EHCI to HC class: %s.\n",
     130                    str_error(rc));
     131                goto error;
     132        }
    116133
    117134        usb_log_info("Controlling new EHCI device `%s' (handle %" PRIun ").\n",
     
    119136
    120137        return EOK;
    121 #undef CHECK_RET_RETURN
     138error:
     139        if (fun_bound)
     140                ddf_fun_unbind(hc_fun);
     141        if (hc_fun != NULL)
     142                ddf_fun_destroy(hc_fun);
     143        return rc;
    122144}
    123145
  • uspace/drv/bus/usb/ehci/res.c

    rf2c19b0 r03c971f  
    145145                return ENOMEM;
    146146
    147 #define CHECK_RET_HANGUP_RETURN(ret, message...) \
    148         if (ret != EOK) { \
    149                 usb_log_error(message); \
    150                 async_hangup(parent_sess); \
    151                 return ret; \
    152         } else (void)0
    153 
    154147        /* Read the first EEC. i.e. Legacy Support register */
    155148        uint32_t usblegsup;
    156         int ret = pci_config_space_read_32(parent_sess,
     149        int rc = pci_config_space_read_32(parent_sess,
    157150            eecp + USBLEGSUP_OFFSET, &usblegsup);
    158         CHECK_RET_HANGUP_RETURN(ret,
    159             "Failed to read USBLEGSUP: %s.\n", str_error(ret));
     151        if (rc != EOK) {
     152                usb_log_error("Failed to read USBLEGSUP: %s.\n",
     153                    str_error(rc));
     154                goto error;
     155        }
     156
    160157        usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
    161158
     
    163160         * byte. (OS Control semaphore)*/
    164161        usb_log_debug("Requesting OS control.\n");
    165         ret = pci_config_space_write_8(parent_sess,
     162        rc = pci_config_space_write_8(parent_sess,
    166163            eecp + USBLEGSUP_OFFSET + 3, 1);
    167         CHECK_RET_HANGUP_RETURN(ret, "Failed to request OS EHCI control: %s.\n",
    168             str_error(ret));
     164        if (rc != EOK) {
     165                usb_log_error("Failed to request OS EHCI control: %s.\n",
     166                    str_error(rc));
     167                goto error;
     168        }
    169169
    170170        size_t wait = 0;
    171171        /* Wait for BIOS to release control. */
    172         ret = pci_config_space_read_32(
     172        rc = pci_config_space_read_32(
    173173            parent_sess, eecp + USBLEGSUP_OFFSET, &usblegsup);
     174        if (rc != EOK) {
     175                usb_log_error("Failed reading PCI config space: %s.\n",
     176                    str_error(rc));
     177                goto error;
     178        }
     179
    174180        while ((wait < DEFAULT_WAIT) && (usblegsup & USBLEGSUP_BIOS_CONTROL)) {
    175181                async_usleep(WAIT_STEP);
    176                 ret = pci_config_space_read_32(parent_sess,
     182                rc = pci_config_space_read_32(parent_sess,
    177183                    eecp + USBLEGSUP_OFFSET, &usblegsup);
     184                if (rc != EOK) {
     185                        usb_log_error("Failed reading PCI config space: %s.\n",
     186                            str_error(rc));
     187                        goto error;
     188                }
    178189                wait += WAIT_STEP;
    179190        }
     
    188199        usb_log_warning( "BIOS failed to release control after "
    189200            "%zu usecs, force it.\n", wait);
    190         ret = pci_config_space_write_32(parent_sess,
     201        rc = pci_config_space_write_32(parent_sess,
    191202            eecp + USBLEGSUP_OFFSET, USBLEGSUP_OS_CONTROL);
    192         CHECK_RET_HANGUP_RETURN(ret, "Failed to force OS control: "
    193             "%s.\n", str_error(ret));
     203        if (rc != EOK) {
     204                usb_log_error("Failed to force OS control: "
     205                    "%s.\n", str_error(rc));
     206                goto error;
     207        }
     208
    194209        /*
    195210         * Check capability type here, value of 01h identifies the capability
     
    201216                /* Read the second EEC Legacy Support and Control register */
    202217                uint32_t usblegctlsts;
    203                 ret = pci_config_space_read_32(parent_sess,
     218                rc = pci_config_space_read_32(parent_sess,
    204219                    eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
    205                 CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS: %s.\n",
    206                     str_error(ret));
     220                if (rc != EOK) {
     221                        usb_log_error("Failed to get USBLEGCTLSTS: %s.\n",
     222                            str_error(rc));
     223                        goto error;
     224                }
     225
    207226                usb_log_debug("USBLEGCTLSTS: %" PRIx32 ".\n", usblegctlsts);
    208227                /*
     
    211230                 * interfering. NOTE: Three upper bits are WC
    212231                 */
    213                 ret = pci_config_space_write_32(parent_sess,
     232                rc = pci_config_space_write_32(parent_sess,
    214233                    eecp + USBLEGCTLSTS_OFFSET, 0xe0000000);
    215                 CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret);
     234                if (rc != EOK) {
     235                        usb_log_error("Failed(%d) zero USBLEGCTLSTS.\n", rc);
     236                        goto error;
     237                }
     238
    216239                udelay(10);
    217                 ret = pci_config_space_read_32(parent_sess,
     240                rc = pci_config_space_read_32(parent_sess,
    218241                    eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts);
    219                 CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS 2: %s.\n",
    220                     str_error(ret));
     242                if (rc != EOK) {
     243                        usb_log_error("Failed to get USBLEGCTLSTS 2: %s.\n",
     244                            str_error(rc));
     245                        goto error;
     246                }
     247
    221248                usb_log_debug("Zeroed USBLEGCTLSTS: %" PRIx32 ".\n",
    222249                    usblegctlsts);
     
    224251
    225252        /* Read again Legacy Support register */
    226         ret = pci_config_space_read_32(parent_sess,
     253        rc = pci_config_space_read_32(parent_sess,
    227254            eecp + USBLEGSUP_OFFSET, &usblegsup);
    228         CHECK_RET_HANGUP_RETURN(ret, "Failed to read USBLEGSUP: %s.\n",
    229             str_error(ret));
     255        if (rc != EOK) {
     256                usb_log_error("Failed to read USBLEGSUP: %s.\n",
     257                    str_error(rc));
     258                goto error;
     259        }
     260
    230261        usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup);
    231262        async_hangup(parent_sess);
    232263        return EOK;
    233 #undef CHECK_RET_HANGUP_RETURN
     264error:
     265        async_hangup(parent_sess);
     266        return rc;
    234267}
    235268
     
    239272        usb_log_debug("Disabling EHCI legacy support.\n");
    240273
    241 #define CHECK_RET_RETURN(ret, message...) \
    242         if (ret != EOK) { \
    243                 usb_log_error(message); \
    244                 return ret; \
    245         } else (void)0
    246 
    247274        /* Map EHCI registers */
    248275        void *regs = NULL;
    249         int ret = pio_enable((void*)reg_base, reg_size, &regs);
    250         CHECK_RET_RETURN(ret, "Failed to map registers %p: %s.\n",
    251             (void *) reg_base, str_error(ret));
     276        int rc = pio_enable((void*)reg_base, reg_size, &regs);
     277        if (rc != EOK) {
     278                usb_log_error("Failed to map registers %p: %s.\n",
     279                    (void *) reg_base, str_error(rc));
     280                return rc;
     281        }
    252282
    253283        usb_log_debug2("Registers mapped at: %p.\n", regs);
     
    263293        usb_log_debug("Value of EECP: %x.\n", eecp);
    264294
    265         ret = disable_extended_caps(device, eecp);
    266         CHECK_RET_RETURN(ret, "Failed to disable extended capabilities: %s.\n",
    267             str_error(ret));
    268 
    269 #undef CHECK_RET_RETURN
     295        rc = disable_extended_caps(device, eecp);
     296        if (rc != EOK) {
     297                usb_log_error("Failed to disable extended capabilities: %s.\n",
     298                    str_error(rc));
     299                return rc;
     300        }
    270301
    271302        /*
     
    306337            usbcmd, *usbcmd, usbsts, *usbsts, usbint, *usbint, usbconf,*usbconf);
    307338
    308         return ret;
     339        return rc;
    309340}
    310341
  • uspace/drv/bus/usb/ohci/hc.c

    rf2c19b0 r03c971f  
    3535
    3636#include <errno.h>
     37#include <stdbool.h>
    3738#include <str_error.h>
    3839#include <adt/list.h>
     
    8384};
    8485
     86enum {
     87        /** Number of PIO ranges used in IRQ code */
     88        hc_irq_pio_range_count =
     89            sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t),
     90
     91        /** Number of commands used in IRQ code */
     92        hc_irq_cmd_count =
     93            sizeof(ohci_irq_commands) / sizeof(irq_cmd_t)
     94};
     95
    8596static void hc_gain_control(hc_t *instance);
    8697static void hc_start(hc_t *instance);
     
    89100static int interrupt_emulator(hc_t *instance);
    90101static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    91 
    92 /** Get number of PIO ranges used in IRQ code.
    93  * @return Number of ranges.
    94  */
    95 size_t hc_irq_pio_range_count(void)
    96 {
    97         return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t);
    98 }
    99 
    100 /** Get number of commands used in IRQ code.
    101  * @return Number of commands.
    102  */
    103 size_t hc_irq_cmd_count(void)
    104 {
    105         return sizeof(ohci_irq_commands) / sizeof(irq_cmd_t);
    106 }
    107102
    108103/** Generate IRQ code.
     
    137132}
    138133
     134/** Register interrupt handler.
     135 *
     136 * @param[in] device Host controller DDF device
     137 * @param[in] reg_base Register range base
     138 * @param[in] reg_size Register range size
     139 * @param[in] irq Interrupt number
     140 * @paran[in] handler Interrupt handler
     141 *
     142 * @return EOK on success or negative error code
     143 */
     144int hc_register_irq_handler(ddf_dev_t *device, uintptr_t reg_base, size_t reg_size,
     145    int irq, interrupt_handler_t handler)
     146{
     147        int rc;
     148
     149        irq_pio_range_t irq_ranges[hc_irq_pio_range_count];
     150        irq_cmd_t irq_cmds[hc_irq_cmd_count];
     151
     152        irq_code_t irq_code = {
     153                .rangecount = hc_irq_pio_range_count,
     154                .ranges = irq_ranges,
     155                .cmdcount = hc_irq_cmd_count,
     156                .cmds = irq_cmds
     157        };
     158
     159        rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
     160            sizeof(irq_cmds), reg_base, reg_size);
     161        if (rc != EOK) {
     162                usb_log_error("Failed to generate IRQ code: %s.\n",
     163                    str_error(rc));
     164                return rc;
     165        }
     166
     167        /* Register handler to avoid interrupt lockup */
     168        rc = register_interrupt_handler(device, irq, handler, &irq_code);
     169        if (rc != EOK) {
     170                usb_log_error("Failed to register interrupt handler: %s.\n",
     171                    str_error(rc));
     172                return rc;
     173        }
     174
     175        return EOK;
     176}
     177
    139178/** Announce OHCI root hub to the DDF
    140179 *
     
    145184int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun)
    146185{
     186        bool addr_reqd = false;
     187        bool ep_added = false;
     188        bool fun_bound = false;
     189        int rc;
     190
    147191        assert(instance);
    148192        assert(hub_fun);
     
    150194        /* Try to get address 1 for root hub. */
    151195        instance->rh.address = 1;
    152         int ret = usb_device_manager_request_address(
     196        rc = usb_device_manager_request_address(
    153197            &instance->generic.dev_manager, &instance->rh.address, false,
    154198            USB_SPEED_FULL);
    155         if (ret != EOK) {
     199        if (rc != EOK) {
    156200                usb_log_error("Failed to get OHCI root hub address: %s\n",
    157                     str_error(ret));
    158                 return ret;
    159         }
    160 
    161 #define CHECK_RET_UNREG_RETURN(ret, message...) \
    162 if (ret != EOK) { \
    163         usb_log_error(message); \
    164         usb_endpoint_manager_remove_ep( \
    165             &instance->generic.ep_manager, instance->rh.address, 0, \
    166             USB_DIRECTION_BOTH, NULL, NULL); \
    167         usb_device_manager_release_address( \
    168             &instance->generic.dev_manager, instance->rh.address); \
    169         return ret; \
    170 } else (void)0
    171 
    172         ret = usb_endpoint_manager_add_ep(
     201                    str_error(rc));
     202                goto error;
     203        }
     204
     205        addr_reqd = true;
     206
     207        rc = usb_endpoint_manager_add_ep(
    173208            &instance->generic.ep_manager, instance->rh.address, 0,
    174209            USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64,
    175210            0, NULL, NULL);
    176         CHECK_RET_UNREG_RETURN(ret,
    177             "Failed to register root hub control endpoint: %s.\n",
    178             str_error(ret));
    179 
    180         ret = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100);
    181         CHECK_RET_UNREG_RETURN(ret,
    182             "Failed to add root hub match-id: %s.\n", str_error(ret));
    183 
    184         ret = ddf_fun_bind(hub_fun);
    185         CHECK_RET_UNREG_RETURN(ret,
    186             "Failed to bind root hub function: %s.\n", str_error(ret));
    187 
    188         ret = usb_device_manager_bind_address(&instance->generic.dev_manager,
     211        if (rc != EOK) {
     212                usb_log_error("Failed to register root hub control endpoint: %s.\n",
     213                    str_error(rc));
     214                goto error;
     215        }
     216
     217        ep_added = true;
     218
     219        rc = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100);
     220        if (rc != EOK) {
     221                usb_log_error("Failed to add root hub match-id: %s.\n",
     222                    str_error(rc));
     223                goto error;
     224        }
     225
     226        rc = ddf_fun_bind(hub_fun);
     227        if (rc != EOK) {
     228                usb_log_error("Failed to bind root hub function: %s.\n",
     229                    str_error(rc));
     230                goto error;
     231        }
     232
     233        fun_bound = true;
     234
     235        rc = usb_device_manager_bind_address(&instance->generic.dev_manager,
    189236            instance->rh.address, ddf_fun_get_handle(hub_fun));
    190         if (ret != EOK)
     237        if (rc != EOK) {
    191238                usb_log_warning("Failed to bind root hub address: %s.\n",
    192                     str_error(ret));
    193 
    194         return EOK;
    195 #undef CHECK_RET_RELEASE
     239                    str_error(rc));
     240        }
     241
     242        return EOK;
     243error:
     244        if (fun_bound)
     245                ddf_fun_unbind(hub_fun);
     246        if (ep_added) {
     247                usb_endpoint_manager_remove_ep(
     248                    &instance->generic.ep_manager, instance->rh.address, 0,
     249                    USB_DIRECTION_BOTH, NULL, NULL);
     250        }
     251        if (addr_reqd) {
     252                usb_device_manager_release_address(
     253                    &instance->generic.dev_manager, instance->rh.address);
     254        }
     255        return rc;
    196256}
    197257
     
    208268        assert(instance);
    209269
    210 #define CHECK_RET_RETURN(ret, message...) \
    211 if (ret != EOK) { \
    212         usb_log_error(message); \
    213         return ret; \
    214 } else (void)0
    215 
    216         int ret =
     270        int rc =
    217271            pio_enable((void*)regs, reg_size, (void**)&instance->registers);
    218         CHECK_RET_RETURN(ret,
    219             "Failed to gain access to device registers: %s.\n", str_error(ret));
     272        if (rc != EOK) {
     273                usb_log_error("Failed to gain access to device registers: %s.\n",
     274                    str_error(rc));
     275                return rc;
     276        }
    220277
    221278        list_initialize(&instance->pending_batches);
     
    228285        instance->generic.ep_remove_hook = ohci_endpoint_fini;
    229286
    230         ret = hc_init_memory(instance);
    231         CHECK_RET_RETURN(ret, "Failed to create OHCI memory structures: %s.\n",
    232             str_error(ret));
    233 #undef CHECK_RET_RETURN
     287        rc = hc_init_memory(instance);
     288        if (rc != EOK) {
     289                usb_log_error("Failed to create OHCI memory structures: %s.\n",
     290                    str_error(rc));
     291                return rc;
     292        }
    234293
    235294        fibril_mutex_initialize(&instance->guard);
  • uspace/drv/bus/usb/ohci/hc.h

    rf2c19b0 r03c971f  
    3535#define DRV_OHCI_HC_H
    3636
     37#include <ddf/interrupt.h>
    3738#include <fibril.h>
    3839#include <fibril_synch.h>
     
    7475} hc_t;
    7576
    76 size_t hc_irq_pio_range_count(void);
    77 size_t hc_irq_cmd_count(void);
    7877int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t,
    7978    size_t);
     79int hc_register_irq_handler(ddf_dev_t *, uintptr_t, size_t, int, interrupt_handler_t);
    8080int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
    8181int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts);
  • uspace/drv/bus/usb/ohci/ohci.c

    rf2c19b0 r03c971f  
    143143int device_setup_ohci(ddf_dev_t *device)
    144144{
     145        bool ih_registered = false;
     146        bool hc_inited = false;
     147        int rc;
     148
    145149        if (device == NULL)
    146150                return EBADMEM;
     
    152156        }
    153157
    154 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
    155 if (ret != EOK) { \
    156         if (instance->hc_fun) { \
    157                 ddf_fun_destroy(instance->hc_fun); \
    158         } \
    159         if (instance->rh_fun) { \
    160                 ddf_fun_destroy(instance->rh_fun); \
    161         } \
    162         usb_log_error(message); \
    163         return ret; \
    164 } else (void)0
    165 
    166158        instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc");
    167         int ret = instance->hc_fun ? EOK : ENOMEM;
    168         CHECK_RET_DEST_FREE_RETURN(ret,
    169             "Failed to create OHCI HC function: %s.\n", str_error(ret));
     159        if (instance->hc_fun == NULL) {
     160                usb_log_error("Failed to create OHCI HC function: %s.\n",
     161                    str_error(ENOMEM));
     162                rc = ENOMEM;
     163                goto error;
     164        }
     165
    170166        ddf_fun_set_ops(instance->hc_fun, &hc_ops);
    171167        ddf_fun_data_implant(instance->hc_fun, &instance->hc);
    172168
    173169        instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh");
    174         ret = instance->rh_fun ? EOK : ENOMEM;
    175         CHECK_RET_DEST_FREE_RETURN(ret,
    176             "Failed to create OHCI RH function: %s.\n", str_error(ret));
     170        if (instance->rh_fun == NULL) {
     171                usb_log_error("Failed to create OHCI RH function: %s.\n",
     172                    str_error(ENOMEM));
     173                rc = ENOMEM;
     174                goto error;
     175        }
     176
    177177        ddf_fun_set_ops(instance->rh_fun, &rh_ops);
    178178
     
    181181        int irq = 0;
    182182
    183         ret = get_my_registers(device, &reg_base, &reg_size, &irq);
    184         CHECK_RET_DEST_FREE_RETURN(ret,
    185             "Failed to get register memory addresses for %" PRIun ": %s.\n",
    186             ddf_dev_get_handle(device), str_error(ret));
     183        rc = get_my_registers(device, &reg_base, &reg_size, &irq);
     184        if (rc != EOK) {
     185                usb_log_error("Failed to get register memory addresses "
     186                    "for %" PRIun ": %s.\n", ddf_dev_get_handle(device),
     187                    str_error(rc));
     188                goto error;
     189        }
     190
    187191        usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
    188192            (void *) reg_base, reg_size, irq);
    189193
    190         const size_t ranges_count = hc_irq_pio_range_count();
    191         const size_t cmds_count = hc_irq_cmd_count();
    192         irq_pio_range_t irq_ranges[ranges_count];
    193         irq_cmd_t irq_cmds[cmds_count];
    194         irq_code_t irq_code = {
    195                 .rangecount = ranges_count,
    196                 .ranges = irq_ranges,
    197                 .cmdcount = cmds_count,
    198                 .cmds = irq_cmds
    199         };
    200 
    201         ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
    202             sizeof(irq_cmds), reg_base, reg_size);
    203         CHECK_RET_DEST_FREE_RETURN(ret,
    204             "Failed to generate IRQ code: %s.\n", str_error(ret));
    205 
    206 
    207         /* Register handler to avoid interrupt lockup */
    208         ret = register_interrupt_handler(device, irq, irq_handler, &irq_code);
    209         CHECK_RET_DEST_FREE_RETURN(ret,
    210             "Failed to register interrupt handler: %s.\n", str_error(ret));
     194        rc = hc_register_irq_handler(device, reg_base, reg_size, irq, irq_handler);
     195        if (rc != EOK) {
     196                usb_log_error("Failed to register interrupt handler: %s.\n",
     197                    str_error(rc));
     198                goto error;
     199        }
     200
     201        ih_registered = true;
    211202
    212203        /* Try to enable interrupts */
    213204        bool interrupts = false;
    214         ret = enable_interrupts(device);
    215         if (ret != EOK) {
     205        rc = enable_interrupts(device);
     206        if (rc != EOK) {
    216207                usb_log_warning("Failed to enable interrupts: %s."
    217                     " Falling back to polling\n", str_error(ret));
     208                    " Falling back to polling\n", str_error(rc));
    218209                /* We don't need that handler */
    219210                unregister_interrupt_handler(device, irq);
     211                ih_registered = false;
    220212        } else {
    221213                usb_log_debug("Hw interrupts enabled.\n");
     
    223215        }
    224216
    225         ret = hc_init(&instance->hc, reg_base, reg_size, interrupts);
    226         CHECK_RET_DEST_FREE_RETURN(ret,
    227             "Failed to init ohci_hcd: %s.\n", str_error(ret));
    228 
    229 #define CHECK_RET_FINI_RETURN(ret, message...) \
    230 if (ret != EOK) { \
    231         hc_fini(&instance->hc); \
    232         unregister_interrupt_handler(device, irq); \
    233         CHECK_RET_DEST_FREE_RETURN(ret, message); \
    234 } else (void)0
    235 
    236 
    237         ret = ddf_fun_bind(instance->hc_fun);
    238         CHECK_RET_FINI_RETURN(ret,
    239             "Failed to bind OHCI device function: %s.\n", str_error(ret));
    240 
    241         ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
    242         CHECK_RET_FINI_RETURN(ret,
    243             "Failed to add OHCI to HC class: %s.\n", str_error(ret));
    244 
    245         ret = hc_register_hub(&instance->hc, instance->rh_fun);
    246         CHECK_RET_FINI_RETURN(ret,
    247             "Failed to register OHCI root hub: %s.\n", str_error(ret));
    248         return ret;
    249 
    250 #undef CHECK_RET_FINI_RETURN
     217        rc = hc_init(&instance->hc, reg_base, reg_size, interrupts);
     218        if (rc != EOK) {
     219                usb_log_error("Failed to init ohci_hcd: %s.\n", str_error(rc));
     220                goto error;
     221        }
     222
     223        hc_inited = true;
     224
     225        rc = ddf_fun_bind(instance->hc_fun);
     226        if (rc != EOK) {
     227                usb_log_error("Failed to bind OHCI device function: %s.\n",
     228                    str_error(rc));
     229                goto error;
     230        }
     231
     232        rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
     233        if (rc != EOK) {
     234                usb_log_error("Failed to add OHCI to HC category: %s.\n",
     235                    str_error(rc));
     236                goto error;
     237        }
     238
     239        rc = hc_register_hub(&instance->hc, instance->rh_fun);
     240        if (rc != EOK) {
     241                usb_log_error("Failed to register OHCI root hub: %s.\n",
     242                    str_error(rc));
     243                goto error;
     244        }
     245
     246        return EOK;
     247
     248error:
     249        if (hc_inited)
     250                hc_fini(&instance->hc);
     251        if (ih_registered)
     252                unregister_interrupt_handler(device, irq);
     253        if (instance->hc_fun != NULL)
     254                ddf_fun_destroy(instance->hc_fun);
     255        if (instance->rh_fun != NULL)
     256                ddf_fun_destroy(instance->rh_fun);
     257        return rc;
    251258}
    252259/**
  • uspace/drv/bus/usb/uhci/hc.c

    rf2c19b0 r03c971f  
    9090static int hc_debug_checker(void *arg);
    9191
    92 
    93 /** Get number of PIO ranges used in IRQ code.
    94  * @return Number of ranges.
    95  */
    96 size_t hc_irq_pio_range_count(void)
    97 {
    98         return sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t);
    99 }
    100 
    101 /** Get number of commands used in IRQ code.
    102  * @return Number of commands.
    103  */
    104 size_t hc_irq_cmd_count(void)
    105 {
    106         return sizeof(uhci_irq_commands) / sizeof(irq_cmd_t);
    107 }
     92enum {
     93        /** Number of PIO ranges used in IRQ code */
     94        hc_irq_pio_range_count =
     95            sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t),
     96
     97        /* Number of commands used in IRQ code */
     98        hc_irq_cmd_count =
     99            sizeof(uhci_irq_commands) / sizeof(irq_cmd_t)
     100};
    108101
    109102/** Generate IRQ code.
     
    133126        cmds[0].addr = &registers->usbsts;
    134127        cmds[3].addr = &registers->usbsts;
     128
     129        return EOK;
     130}
     131
     132/** Register interrupt handler.
     133 *
     134 * @param[in] device Host controller DDF device
     135 * @param[in] reg_base Register range base
     136 * @param[in] reg_size Register range size
     137 * @param[in] irq Interrupt number
     138 * @paran[in] handler Interrupt handler
     139 *
     140 * @return EOK on success or negative error code
     141 */
     142int hc_register_irq_handler(ddf_dev_t *device, uintptr_t reg_base, size_t reg_size,
     143    int irq, interrupt_handler_t handler)
     144{
     145        int rc;
     146        irq_pio_range_t irq_ranges[hc_irq_pio_range_count];
     147        irq_cmd_t irq_cmds[hc_irq_cmd_count];
     148        rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
     149            sizeof(irq_cmds), reg_base, reg_size);
     150        if (rc != EOK) {
     151                usb_log_error("Failed to generate IRQ commands: %s.\n",
     152                    str_error(rc));
     153                return rc;
     154        }
     155
     156        irq_code_t irq_code = {
     157                .rangecount = hc_irq_pio_range_count,
     158                .ranges = irq_ranges,
     159                .cmdcount = hc_irq_cmd_count,
     160                .cmds = irq_cmds
     161        };
     162
     163        /* Register handler to avoid interrupt lockup */
     164        rc = register_interrupt_handler(device, irq, handler, &irq_code);
     165        if (rc != EOK) {
     166                usb_log_error("Failed to register interrupt handler: %s.\n",
     167                    str_error(rc));
     168                return rc;
     169        }
    135170
    136171        return EOK;
     
    209244{
    210245        assert(reg_size >= sizeof(uhci_regs_t));
    211         int ret;
    212 
    213 #define CHECK_RET_RETURN(ret, message...) \
    214         if (ret != EOK) { \
    215                 usb_log_error(message); \
    216                 return ret; \
    217         } else (void) 0
     246        int rc;
    218247
    219248        instance->hw_interrupts = interrupts;
     
    222251        /* allow access to hc control registers */
    223252        uhci_regs_t *io;
    224         ret = pio_enable(regs, reg_size, (void **)&io);
    225         CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p: %s.\n",
    226             io, str_error(ret));
     253        rc = pio_enable(regs, reg_size, (void **)&io);
     254        if (rc != EOK) {
     255                usb_log_error("Failed to gain access to registers at %p: %s.\n",
     256                    io, str_error(rc));
     257                return rc;
     258        }
     259
    227260        instance->registers = io;
    228261        usb_log_debug(
    229262            "Device registers at %p (%zuB) accessible.\n", io, reg_size);
    230263
    231         ret = hc_init_mem_structures(instance);
    232         CHECK_RET_RETURN(ret,
    233             "Failed to initialize UHCI memory structures: %s.\n",
    234             str_error(ret));
    235 
    236 #undef CHECK_RET_RETURN
     264        rc = hc_init_mem_structures(instance);
     265        if (rc != EOK) {
     266                usb_log_error("Failed to initialize UHCI memory structures: %s.\n",
     267                    str_error(rc));
     268                return rc;
     269        }
    237270
    238271        hcd_init(&instance->generic, USB_SPEED_FULL,
     
    397430
    398431        return EOK;
    399 #undef CHECK_RET_CLEAR_RETURN
    400432}
    401433
  • uspace/drv/bus/usb/uhci/hc.h

    rf2c19b0 r03c971f  
    3636#define DRV_UHCI_HC_H
    3737
     38#include <ddf/interrupt.h>
    3839#include <fibril.h>
    3940#include <usb/host/hcd.h>
     
    119120} hc_t;
    120121
    121 size_t hc_irq_pio_range_count(void);
    122 size_t hc_irq_cmd_count(void);
     122int hc_register_irq_handler(ddf_dev_t *, uintptr_t, size_t, int, interrupt_handler_t);
    123123int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t,
    124124    size_t);
  • uspace/drv/bus/usb/uhci/uhci.c

    rf2c19b0 r03c971f  
    3838
    3939#include <errno.h>
     40#include <stdbool.h>
    4041#include <str_error.h>
    4142#include <ddf/interrupt.h>
     
    149150int device_setup_uhci(ddf_dev_t *device)
    150151{
     152        bool ih_registered = false;
     153        bool hc_inited = false;
     154        bool fun_bound = false;
     155        int rc;
     156
    151157        if (!device)
    152158                return EBADMEM;
     
    158164        }
    159165
    160 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
    161 if (ret != EOK) { \
    162         if (instance->hc_fun) \
    163                 ddf_fun_destroy(instance->hc_fun); \
    164         if (instance->rh_fun) {\
    165                 ddf_fun_destroy(instance->rh_fun); \
    166         } \
    167         usb_log_error(message); \
    168         return ret; \
    169 } else (void)0
    170 
    171         instance->rh_fun = NULL;
    172166        instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci_hc");
    173         int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
    174         CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n");
     167        if (instance->hc_fun == NULL) {
     168                usb_log_error("Failed to create UHCI HC function.\n");
     169                rc = ENOMEM;
     170                goto error;
     171        }
     172
    175173        ddf_fun_set_ops(instance->hc_fun, &hc_ops);
    176174        ddf_fun_data_implant(instance->hc_fun, &instance->hc.generic);
    177175
    178176        instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci_rh");
    179         ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
    180         CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n");
     177        if (instance->rh_fun == NULL) {
     178                usb_log_error("Failed to create UHCI RH function.\n");
     179                rc = ENOMEM;
     180                goto error;
     181        }
     182
    181183        ddf_fun_set_ops(instance->rh_fun, &rh_ops);
    182184        ddf_fun_data_implant(instance->rh_fun, &instance->rh);
     
    186188        int irq = 0;
    187189
    188         ret = get_my_registers(device, &reg_base, &reg_size, &irq);
    189         CHECK_RET_DEST_FREE_RETURN(ret,
    190             "Failed to get I/O addresses for %" PRIun ": %s.\n",
    191             ddf_dev_get_handle(device), str_error(ret));
     190        rc = get_my_registers(device, &reg_base, &reg_size, &irq);
     191        if (rc != EOK) {
     192                usb_log_error("Failed to get I/O addresses for %" PRIun ": %s.\n",
     193                    ddf_dev_get_handle(device), str_error(rc));
     194                goto error;
     195        }
    192196        usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n",
    193197            (void *) reg_base, reg_size, irq);
    194198
    195         ret = disable_legacy(device);
    196         CHECK_RET_DEST_FREE_RETURN(ret,
    197             "Failed to disable legacy USB: %s.\n", str_error(ret));
    198 
    199         const size_t ranges_count = hc_irq_pio_range_count();
    200         const size_t cmds_count = hc_irq_cmd_count();
    201         irq_pio_range_t irq_ranges[ranges_count];
    202         irq_cmd_t irq_cmds[cmds_count];
    203         ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
    204             sizeof(irq_cmds), reg_base, reg_size);
    205         CHECK_RET_DEST_FREE_RETURN(ret,
    206             "Failed to generate IRQ commands: %s.\n", str_error(ret));
    207 
    208         irq_code_t irq_code = {
    209                 .rangecount = ranges_count,
    210                 .ranges = irq_ranges,
    211                 .cmdcount = cmds_count,
    212                 .cmds = irq_cmds
    213         };
    214 
    215         /* Register handler to avoid interrupt lockup */
    216         ret = register_interrupt_handler(device, irq, irq_handler, &irq_code);
    217         CHECK_RET_DEST_FREE_RETURN(ret,
    218             "Failed to register interrupt handler: %s.\n", str_error(ret));
     199        rc = disable_legacy(device);
     200        if (rc != EOK) {
     201                usb_log_error("Failed to disable legacy USB: %s.\n",
     202                    str_error(rc));
     203                goto error;
     204        }
     205
     206        rc = hc_register_irq_handler(device, reg_base, reg_size, irq, irq_handler);
     207        if (rc != EOK) {
     208                usb_log_error("Failed to register interrupt handler: %s.\n",
     209                    str_error(rc));
     210                goto error;
     211        }
     212
     213        ih_registered = true;
    219214
    220215        bool interrupts = false;
    221         ret = enable_interrupts(device);
    222         if (ret != EOK) {
     216        rc = enable_interrupts(device);
     217        if (rc != EOK) {
    223218                usb_log_warning("Failed to enable interrupts: %s."
    224                     " Falling back to polling.\n", str_error(ret));
     219                    " Falling back to polling.\n", str_error(rc));
    225220        } else {
    226221                usb_log_debug("Hw interrupts enabled.\n");
     
    228223        }
    229224
    230         ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts);
    231         CHECK_RET_DEST_FREE_RETURN(ret,
    232             "Failed to init uhci_hcd: %s.\n", str_error(ret));
    233 
    234 #define CHECK_RET_FINI_RETURN(ret, message...) \
    235 if (ret != EOK) { \
    236         hc_fini(&instance->hc); \
    237         CHECK_RET_DEST_FREE_RETURN(ret, message); \
    238         return ret; \
    239 } else (void)0
    240 
    241         ret = ddf_fun_bind(instance->hc_fun);
    242         CHECK_RET_FINI_RETURN(ret, "Failed to bind UHCI device function: %s.\n",
    243             str_error(ret));
    244 
    245         ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
    246         CHECK_RET_FINI_RETURN(ret,
    247             "Failed to add UHCI to HC class: %s.\n", str_error(ret));
    248 
    249         ret = rh_init(&instance->rh, instance->rh_fun,
     225        rc = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts);
     226        if (rc != EOK) {
     227                usb_log_error("Failed to init uhci_hcd: %s.\n", str_error(rc));
     228                goto error;
     229        }
     230
     231        hc_inited = true;
     232
     233        rc = ddf_fun_bind(instance->hc_fun);
     234        if (rc != EOK) {
     235                usb_log_error("Failed to bind UHCI device function: %s.\n",
     236                    str_error(rc));
     237                goto error;
     238        }
     239
     240        fun_bound = true;
     241
     242        rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
     243        if (rc != EOK) {
     244                usb_log_error("Failed to add UHCI to HC class: %s.\n",
     245                    str_error(rc));
     246                goto error;
     247        }
     248
     249        rc = rh_init(&instance->rh, instance->rh_fun,
    250250            (uintptr_t)instance->hc.registers + 0x10, 4);
    251         CHECK_RET_FINI_RETURN(ret,
    252             "Failed to setup UHCI root hub: %s.\n", str_error(ret));
    253 
    254         ret = ddf_fun_bind(instance->rh_fun);
    255         CHECK_RET_FINI_RETURN(ret,
    256             "Failed to register UHCI root hub: %s.\n", str_error(ret));
     251        if (rc != EOK) {
     252                usb_log_error("Failed to setup UHCI root hub: %s.\n",
     253                    str_error(rc));
     254                goto error;
     255        }
     256
     257        rc = ddf_fun_bind(instance->rh_fun);
     258        if (rc != EOK) {
     259                usb_log_error("Failed to register UHCI root hub: %s.\n",
     260                    str_error(rc));
     261                goto error;
     262        }
    257263
    258264        return EOK;
    259 #undef CHECK_RET_FINI_RETURN
     265
     266error:
     267        if (fun_bound)
     268                ddf_fun_unbind(instance->hc_fun);
     269        if (hc_inited)
     270                hc_fini(&instance->hc);
     271        if (ih_registered)
     272                unregister_interrupt_handler(device, irq);
     273        if (instance->hc_fun != NULL)
     274                ddf_fun_destroy(instance->hc_fun);
     275        if (instance->rh_fun != NULL) {
     276                ddf_fun_destroy(instance->rh_fun);
     277        }
     278        return rc;
    260279}
    261280/**
  • uspace/drv/bus/usb/uhcirh/main.c

    rf2c19b0 r03c971f  
    9393        size_t io_size = 0;
    9494        uhci_root_hub_t *rh = NULL;
    95         int ret = EOK;
     95        int rc;
    9696
    97 #define CHECK_RET_FREE_RH_RETURN(ret, message...) \
    98 if (ret != EOK) { \
    99         usb_log_error(message); \
    100         return ret; \
    101 } else (void)0
     97        rc = hc_get_my_registers(device, &io_regs, &io_size);
     98        if (rc != EOK) {
     99                usb_log_error( "Failed to get registers from HC: %s.\n",
     100                    str_error(rc));
     101                return rc;
     102        }
    102103
    103         ret = hc_get_my_registers(device, &io_regs, &io_size);
    104         CHECK_RET_FREE_RH_RETURN(ret,
    105             "Failed to get registers from HC: %s.\n", str_error(ret));
    106104        usb_log_debug("I/O regs at %p (size %zuB).\n",
    107105            (void *) io_regs, io_size);
    108106
    109107        rh = ddf_dev_data_alloc(device, sizeof(uhci_root_hub_t));
    110         ret = (rh == NULL) ? ENOMEM : EOK;
    111         CHECK_RET_FREE_RH_RETURN(ret,
    112             "Failed to allocate rh driver instance.\n");
     108        if (rh == NULL) {
     109                usb_log_error("Failed to allocate rh driver instance.\n");
     110                return ENOMEM;
     111        }
    113112
    114         ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device);
    115         CHECK_RET_FREE_RH_RETURN(ret,
    116             "Failed(%d) to initialize rh driver instance: %s.\n",
    117             ret, str_error(ret));
     113        rc = uhci_root_hub_init(rh, (void*)io_regs, io_size, device);
     114        if (rc != EOK) {
     115                usb_log_error("Failed(%d) to initialize rh driver instance: "
     116                    "%s.\n", rc, str_error(rc));
     117                return rc;
     118        }
    118119
    119120        usb_log_info("Controlling root hub '%s' (%" PRIun ").\n",
    120121            ddf_dev_get_name(device), ddf_dev_get_handle(device));
     122
    121123        return EOK;
    122124}
  • uspace/drv/bus/usb/uhcirh/port.c

    rf2c19b0 r03c971f  
    150150{
    151151        uhci_port_t *instance = port;
     152        int rc;
    152153        assert(instance);
    153154
    154155        unsigned allowed_failures = MAX_ERROR_COUNT;
    155 #define CHECK_RET_FAIL(ret, msg...) \
    156         if (ret != EOK) { \
    157                 usb_log_error(msg); \
    158                 if (!(allowed_failures-- > 0)) { \
    159                         usb_log_fatal( \
    160                            "Maximum number of failures reached, " \
    161                            "bailing out.\n"); \
    162                         return ret; \
    163                 } \
    164                 continue; \
    165         } else (void)0
    166156
    167157        while (1) {
     
    182172                    instance->id_string, port_status);
    183173
    184                 int ret = usb_hc_connection_open(&instance->hc_connection);
    185                 CHECK_RET_FAIL(ret, "%s: Failed to connect to HC %s.\n",
    186                     instance->id_string, str_error(ret));
     174                rc = usb_hc_connection_open(&instance->hc_connection);
     175                if (rc != EOK) {
     176                        usb_log_error("%s: Failed to connect to HC %s.\n",
     177                            instance->id_string, str_error(rc));
     178                        if (!(allowed_failures-- > 0))
     179                                goto fatal_error;
     180                        continue;
     181                }
    187182
    188183                /* Remove any old device */
     
    204199                }
    205200
    206                 ret = usb_hc_connection_close(&instance->hc_connection);
    207                 CHECK_RET_FAIL(ret, "%s: Failed to disconnect from hc: %s.\n",
    208                     instance->id_string, str_error(ret));
    209         }
    210         return EOK;
     201                rc = usb_hc_connection_close(&instance->hc_connection);
     202                if (rc != EOK) {
     203                        usb_log_error("%s: Failed to disconnect from HC %s.\n",
     204                            instance->id_string, str_error(rc));
     205                        if (!(allowed_failures-- > 0))
     206                                goto fatal_error;
     207                        continue;
     208                }
     209        }
     210
     211        return EOK;
     212
     213fatal_error:
     214        usb_log_fatal("Maximum number of failures reached, bailing out.\n");
     215        return rc;
    211216}
    212217
  • uspace/drv/bus/usb/vhc/hub/virthubops.c

    rf2c19b0 r03c971f  
    299299    size_t *act_size)
    300300{
    301         int rc;
     301        int rc = ENOTSUP;
    302302        size_t port = request->index - 1;
    303303        usb_hub_class_feature_t feature = request->value;
  • uspace/drv/char/i8042/i8042.c

    rf2c19b0 r03c971f  
    6363#define i8042_AUX_DISABLE    0x20
    6464#define i8042_KBD_TRANSLATE  0x40  /* Use this to switch to XT scancodes */
    65 
    66 #define CHECK_RET_DESTROY(ret, msg...) \
    67         do { \
    68                 if (ret != EOK) { \
    69                         ddf_msg(LVL_ERROR, msg); \
    70                         if (dev->kbd_fun) { \
    71                                 dev->kbd_fun->driver_data = NULL; \
    72                                 ddf_fun_destroy(dev->kbd_fun); \
    73                         } \
    74                         if (dev->aux_fun) { \
    75                                 dev->aux_fun->driver_data = NULL; \
    76                                 ddf_fun_destroy(dev->aux_fun); \
    77                         } \
    78                 } \
    79         } while (0)
    80 
    81 #define CHECK_RET_UNBIND_DESTROY(ret, msg...) \
    82         do { \
    83                 if (ret != EOK) { \
    84                         ddf_msg(LVL_ERROR, msg); \
    85                         if (dev->kbd_fun) { \
    86                                 ddf_fun_unbind(dev->kbd_fun); \
    87                                 dev->kbd_fun->driver_data = NULL; \
    88                                 ddf_fun_destroy(dev->kbd_fun); \
    89                         } \
    90                         if (dev->aux_fun) { \
    91                                 ddf_fun_unbind(dev->aux_fun); \
    92                                 dev->aux_fun->driver_data = NULL; \
    93                                 ddf_fun_destroy(dev->aux_fun); \
    94                         } \
    95                 } \
    96         } while (0)
    9765
    9866void default_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
  • uspace/drv/char/i8042/main.c

    rf2c19b0 r03c971f  
    4545#include <async.h>
    4646#include "i8042.h"
    47 
    48 #define CHECK_RET_RETURN(ret, message...) \
    49         do { \
    50                 if (ret != EOK) { \
    51                         ddf_msg(LVL_ERROR, message); \
    52                         return ret; \
    53                 } \
    54         } while (0)
    5547
    5648/** Get address of I/O registers.
     
    112104static int i8042_dev_add(ddf_dev_t *device)
    113105{
    114         if (!device)
    115                 return EINVAL;
    116        
    117106        uintptr_t io_regs = 0;
    118107        size_t io_size = 0;
    119108        int kbd = 0;
    120109        int mouse = 0;
     110        int rc;
    121111       
    122         int ret = get_my_registers(device, &io_regs, &io_size, &kbd, &mouse);
    123         CHECK_RET_RETURN(ret, "Failed to get registers: %s.",
    124             str_error(ret));
     112        if (!device)
     113                return EINVAL;
     114       
     115        rc = get_my_registers(device, &io_regs, &io_size, &kbd, &mouse);
     116        if (rc != EOK) {
     117                ddf_msg(LVL_ERROR, "Failed to get registers: %s.",
     118                    str_error(rc));
     119                return rc;
     120        }
     121       
    125122        ddf_msg(LVL_DEBUG, "I/O regs at %p (size %zuB), IRQ kbd %d, IRQ mouse %d.",
    126123            (void *) io_regs, io_size, kbd, mouse);
    127124       
    128125        i8042_t *i8042 = ddf_dev_data_alloc(device, sizeof(i8042_t));
    129         ret = (i8042 == NULL) ? ENOMEM : EOK;
    130         CHECK_RET_RETURN(ret, "Failed to allocate i8042 driver instance.");
     126        if (i8042 == NULL) {
     127                ddf_msg(LVL_ERROR, "Out of memory.");
     128                return ENOMEM;
     129        }
    131130       
    132         ret = i8042_init(i8042, (void *) io_regs, io_size, kbd, mouse, device);
    133         CHECK_RET_RETURN(ret, "Failed to initialize i8042 driver: %s.",
    134             str_error(ret));
     131        rc = i8042_init(i8042, (void *) io_regs, io_size, kbd, mouse, device);
     132        if (rc != EOK) {
     133                ddf_msg(LVL_ERROR, "Failed to initialize i8042 driver: %s.",
     134                    str_error(rc));
     135                return rc;
     136        }
    135137       
    136138        ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").",
  • uspace/drv/char/ns8250/ns8250.c

    rf2c19b0 r03c971f  
    160160        /** I/O registers **/
    161161        ns8250_regs_t *regs;
    162         /** Is there any client connected to the device? */
    163         bool client_connected;
     162        /** Are there any clients connected to the device? */
     163        unsigned client_connections;
    164164        /** The irq assigned to this device. */
    165165        int irq;
     
    236236 *
    237237 * @param fun           The serial port function
    238  * @param buf           The ouput buffer for read data.
     238 * @param buf           The output buffer for read data.
    239239 * @param count         The number of bytes to be read.
    240240 *
     
    420420                        ns->irq = res->res.interrupt.irq;
    421421                        irq = true;
    422                         ddf_msg(LVL_NOTE, "Device %s was asigned irq = 0x%x.",
     422                        ddf_msg(LVL_NOTE, "Device %s was assigned irq = 0x%x.",
    423423                            ddf_dev_get_name(ns->dev), ns->irq);
    424424                        break;
     
    433433                        }
    434434                        ioport = true;
    435                         ddf_msg(LVL_NOTE, "Device %s was asigned I/O address = "
     435                        ddf_msg(LVL_NOTE, "Device %s was assigned I/O address = "
    436436                            "0x%x.", ddf_dev_get_name(ns->dev), ns->io_addr);
    437437                        break;
     
    753753                        uint8_t val = ns8250_read_8(regs);
    754754                       
    755                         if (ns->client_connected) {
     755                        if (ns->client_connections > 0) {
    756756                                bool buf_was_empty = buf_is_empty(&ns->input_buffer);
    757757                                if (!buf_push_back(&ns->input_buffer, val)) {
     
    827827        ddf_fun_t *fun = NULL;
    828828        bool need_cleanup = false;
     829        bool need_unreg_intr_handler = false;
    829830        int rc;
    830831       
     
    869870                goto fail;
    870871        }
     872        need_unreg_intr_handler = true;
    871873       
    872874        /* Enable interrupt. */
     
    903905        if (fun != NULL)
    904906                ddf_fun_destroy(fun);
     907        if (need_unreg_intr_handler)
     908                ns8250_unregister_interrupt_handler(ns);
    905909        if (need_cleanup)
    906910                ns8250_dev_cleanup(ns);
     
    914918       
    915919        fibril_mutex_lock(&ns->mutex);
    916         if (ns->client_connected) {
     920        if (ns->client_connections > 0) {
    917921                fibril_mutex_unlock(&ns->mutex);
    918922                return EBUSY;
     
    948952       
    949953        fibril_mutex_lock(&ns->mutex);
    950         if (ns->client_connected) {
    951                 res = ELIMIT;
    952         } else if (ns->removed) {
     954        if (ns->removed) {
    953955                res = ENXIO;
    954956        } else {
    955957                res = EOK;
    956                 ns->client_connected = true;
     958                ns->client_connections++;
    957959        }
    958960        fibril_mutex_unlock(&ns->mutex);
     
    974976        fibril_mutex_lock(&data->mutex);
    975977       
    976         assert(data->client_connected);
    977        
    978         data->client_connected = false;
    979         buf_clear(&data->input_buffer);
     978        assert(data->client_connections > 0);
     979       
     980        if (!(--data->client_connections))
     981                buf_clear(&data->input_buffer);
    980982       
    981983        fibril_mutex_unlock(&data->mutex);
  • uspace/drv/char/ps2mouse/main.c

    rf2c19b0 r03c971f  
    8080static int mouse_add(ddf_dev_t *device)
    8181{
     82        int rc;
     83
    8284        if (!device)
    8385                return EINVAL;
    8486
    85 #define CHECK_RET_RETURN(ret, message...) \
    86 if (ret != EOK) { \
    87         ddf_msg(LVL_ERROR, message); \
    88         return ret; \
    89 } else (void)0
     87        ps2_mouse_t *mouse = ddf_dev_data_alloc(device, sizeof(ps2_mouse_t));
     88        if (mouse == NULL) {
     89                ddf_msg(LVL_ERROR, "Failed to allocate mouse driver instance.");
     90                return ENOMEM;
     91        }
    9092
    91         ps2_mouse_t *mouse = ddf_dev_data_alloc(device, sizeof(ps2_mouse_t));
    92         int ret = (mouse == NULL) ? ENOMEM : EOK;
    93         CHECK_RET_RETURN(ret, "Failed to allocate mouse driver instance.");
    94 
    95         ret = ps2_mouse_init(mouse, device);
    96         CHECK_RET_RETURN(ret,
    97             "Failed to initialize mouse driver: %s.", str_error(ret));
     93        rc = ps2_mouse_init(mouse, device);
     94        if (rc != EOK) {
     95                ddf_msg(LVL_ERROR, "Failed to initialize mouse driver: %s.",
     96                    str_error(rc));
     97                return rc;
     98        }
    9899
    99100        ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").",
  • uspace/drv/char/ps2mouse/ps2mouse.c

    rf2c19b0 r03c971f  
    7070#define PS2_BUTTON_MASK(button) (1 << button)
    7171
    72 #define MOUSE_READ_BYTE_TEST(sess, value) \
     72#define MOUSE_READ_BYTE_TEST(sess, value_) \
    7373do { \
     74        uint8_t value = (value_); \
    7475        uint8_t data = 0; \
    7576        const ssize_t size = chardev_read(sess, &data, 1); \
     
    7879                return size < 0 ? size : EIO; \
    7980        } \
    80         if (data != (value)) { \
     81        if (data != value) { \
    8182                ddf_msg(LVL_DEBUG, "Failed testing byte: got %hhx vs. %hhx)", \
    82                     data, (value)); \
     83                    data, value); \
    8384                return EIO; \
    8485        } \
    8586} while (0)
    8687
    87 #define MOUSE_WRITE_BYTE(sess, value) \
     88#define MOUSE_WRITE_BYTE(sess, value_) \
    8889do { \
     90        uint8_t value = (value_); \
    8991        uint8_t data = (value); \
    9092        const ssize_t size = chardev_write(sess, &data, 1); \
  • uspace/drv/char/xtkbd/main.c

    rf2c19b0 r03c971f  
    8080static int xt_kbd_add(ddf_dev_t *device)
    8181{
     82        int rc;
     83
    8284        if (!device)
    8385                return EINVAL;
    8486
    85 #define CHECK_RET_RETURN(ret, message...) \
    86 if (ret != EOK) { \
    87         ddf_msg(LVL_ERROR, message); \
    88         return ret; \
    89 } else (void)0
     87        xt_kbd_t *kbd = ddf_dev_data_alloc(device, sizeof(xt_kbd_t));
     88        if (kbd == NULL) {
     89                ddf_msg(LVL_ERROR, "Failed to allocate XT/KBD driver instance.");
     90                return ENOMEM;
     91        }
    9092
    91         xt_kbd_t *kbd = ddf_dev_data_alloc(device, sizeof(xt_kbd_t));
    92         int ret = (kbd == NULL) ? ENOMEM : EOK;
    93         CHECK_RET_RETURN(ret, "Failed to allocate XT/KBD driver instance.");
    94 
    95         ret = xt_kbd_init(kbd, device);
    96         CHECK_RET_RETURN(ret,
    97             "Failed to initialize XT_KBD driver: %s.", str_error(ret));
     93        rc = xt_kbd_init(kbd, device);
     94        if (rc != EOK) {
     95                ddf_msg(LVL_ERROR, "Failed to initialize XT_KBD driver: %s.",
     96                    str_error(rc));
     97                return rc;
     98        }
    9899
    99100        ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").",
  • uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c

    rf2c19b0 r03c971f  
    4848
    4949typedef struct {
     50        const char *name;
     51        match_id_t match_id;
    5052        hw_resource_list_t hw_resources;
    5153} rootamdm37x_fun_t;
    5254
    53 /* See amdm37x TRM page. 3316 for these values */
    54 #define OHCI_BASE_ADDRESS  0x48064400
    55 #define OHCI_SIZE  1024
    56 #define EHCI_BASE_ADDRESS  0x48064800
    57 #define EHCI_SIZE  1024
     55/* See amdm37x TRM page 3316 for these values */
     56#define OHCI_BASE_ADDRESS   0x48064400
     57#define OHCI_SIZE   1024
     58#define EHCI_BASE_ADDRESS   0x48064800
     59#define EHCI_SIZE   1024
     60
     61/* See amdm37x TRM page 1813 for these values */
     62#define DSS_BASE_ADDRESS   0x48050000
     63#define DSS_SIZE   512
     64#define DISPC_BASE_ADDRESS   0x48050400
     65#define DISPC_SIZE   1024
     66#define VIDEO_ENC_BASE_ADDRESS   0x48050C00
     67#define VIDEO_ENC_SIZE   256
     68
    5869
    5970static hw_resource_t ohci_res[] = {
     
    8899};
    89100
    90 static const rootamdm37x_fun_t ohci = {
    91         .hw_resources = {
    92             .resources = ohci_res,
    93             .count = sizeof(ohci_res)/sizeof(ohci_res[0]),
    94         }
    95 };
    96 
    97 static const rootamdm37x_fun_t ehci = {
    98         .hw_resources = {
    99             .resources = ehci_res,
    100             .count = sizeof(ehci_res) / sizeof(ehci_res[0]),
    101         }
    102 };
     101static hw_resource_t disp_res[] = {
     102        {
     103                .type = MEM_RANGE,
     104                .res.io_range = {
     105                        .address = DSS_BASE_ADDRESS,
     106                        .size = DSS_SIZE,
     107                        .endianness = LITTLE_ENDIAN
     108                },
     109        },
     110        {
     111                .type = MEM_RANGE,
     112                .res.io_range = {
     113                        .address = DISPC_BASE_ADDRESS,
     114                        .size = DISPC_SIZE,
     115                        .endianness = LITTLE_ENDIAN
     116                },
     117        },
     118        {
     119                .type = MEM_RANGE,
     120                .res.io_range = {
     121                        .address = VIDEO_ENC_BASE_ADDRESS,
     122                        .size = VIDEO_ENC_SIZE,
     123                        .endianness = LITTLE_ENDIAN
     124                },
     125        },
     126        {
     127                .type = INTERRUPT,
     128                .res.interrupt = { .irq = 25 },
     129        },
     130};
     131
     132static const rootamdm37x_fun_t amdm37x_funcs[] = {
     133{
     134        .name = "ohci",
     135        .match_id = { .id = "usb/host=ohci", .score = 90 },
     136        .hw_resources = { .resources = ohci_res, .count = ARRAY_SIZE(ohci_res) }
     137},
     138{
     139        .name = "ehci",
     140        .match_id = { .id = "usb/host=ehci", .score = 90 },
     141        .hw_resources = { .resources = ehci_res, .count = ARRAY_SIZE(ehci_res) }
     142},
     143{
     144        .name = "fb",
     145        .match_id = { .id = "amdm37x&dispc", .score = 90 },
     146        .hw_resources = { .resources = disp_res, .count = ARRAY_SIZE(disp_res) }
     147},
     148};
     149
    103150
    104151static hw_resource_list_t *rootamdm37x_get_resources(ddf_fun_t *fnode);
     
    114161};
    115162
    116 static int rootamdm37x_add_fun(ddf_dev_t *dev, const char *name,
    117     const char *str_match_id, const rootamdm37x_fun_t *fun)
    118 {
    119         ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name);
    120        
     163static int rootamdm37x_add_fun(ddf_dev_t *dev, const rootamdm37x_fun_t *fun)
     164{
     165        assert(dev);
     166        assert(fun);
     167
     168        ddf_msg(LVL_DEBUG, "Adding new function '%s'.", fun->name);
     169
    121170        /* Create new device function. */
    122         ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name);
     171        ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, fun->name);
    123172        if (fnode == NULL)
    124173                return ENOMEM;
    125174       
    126175        /* Add match id */
    127         int ret = ddf_fun_add_match_id(fnode, str_match_id, 100);
     176        int ret = ddf_fun_add_match_id(fnode,
     177            fun->match_id.id, fun->match_id.score);
    128178        if (ret != EOK) {
    129179                ddf_fun_destroy(fnode);
     
    146196        ret = ddf_fun_bind(fnode);
    147197        if (ret != EOK) {
    148                 ddf_msg(LVL_ERROR, "Failed binding function %s.", name);
     198                ddf_msg(LVL_ERROR, "Failed binding function %s.", fun->name);
    149199                ddf_fun_destroy(fnode);
    150200                return ret;
     
    189239
    190240        /* Register functions */
    191         if (rootamdm37x_add_fun(dev, "ohci", "usb/host=ohci", &ohci) != EOK)
    192                 ddf_msg(LVL_ERROR, "Failed to add OHCI function for "
    193                     "BeagleBoard-xM platform.");
    194         if (rootamdm37x_add_fun(dev, "ehci", "usb/host=ehci", &ehci) != EOK)
    195                 ddf_msg(LVL_ERROR, "Failed to add EHCI function for "
    196                     "BeagleBoard-xM platform.");
    197         if (rootamdm37x_add_fun(dev, "dispc", "amdm37x&dispc", &ehci) != EOK)
    198                 ddf_msg(LVL_ERROR, "Failed to add dispc function for "
    199                     "BeagleBoard-xM platform.");
    200 
     241        for (unsigned i = 0; i < ARRAY_SIZE(amdm37x_funcs); ++i) {
     242                if (rootamdm37x_add_fun(dev, &amdm37x_funcs[i]) != EOK)
     243                        ddf_msg(LVL_ERROR, "Failed to add %s function for "
     244                            "BeagleBoard-xM platform.", amdm37x_funcs[i].name);
     245        }
    201246        return EOK;
    202247}
  • uspace/drv/infrastructure/rootamdm37x/uhh.h

    rf2c19b0 r03c971f  
    8585#define UHH_DEBUG_CSR_EHCI_SIMULATION_MODE_FLAG  (1 << 6)
    8686#define UHH_DEBUG_CSR_OHCI_CNTSEL_FLAG  (1 << 7)
    87 #define UHH_DEBUG_CSR_OHCI_GLOBAL_sUSPEND_FLAG  (1 << 16)
     87#define UHH_DEBUG_CSR_OHCI_GLOBAL_SUSPEND_FLAG  (1 << 16)
    8888#define UHH_DEBUG_CSR_OHCI_CCS1_FLAG  (1 << 17)
    8989#define UHH_DEBUG_CSR_OHCI_CCS2_FLAG  (1 << 18)
  • uspace/drv/nic/rtl8139/driver.c

    rf2c19b0 r03c971f  
    620620                if (size == 0 || size > RTL8139_FRAME_MAX_LENGTH) {
    621621                        ddf_msg(LVL_ERROR, "Receiver error -> receiver reset (size: %4" PRIu16 ", "
    622                             "header 0x%4" PRIx16 ". Offset: %d)", size, frame_header,
     622                            "header 0x%4" PRIx32 ". Offset: %" PRIu16 ")", size, frame_header,
    623623                            rx_offset);
    624624                        goto rx_err;
Note: See TracChangeset for help on using the changeset viewer.