Ignore:
Timestamp:
2017-10-04T17:39:48Z (7 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c188c62
Parents:
7e55bed7
Message:

Convert CUDA driver to DDF.

File:
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/adb/cuda_adb/cuda_adb.c

    r7e55bed7 re27e36e  
    3737 */
    3838
     39#include <assert.h>
     40#include <ddf/driver.h>
     41#include <ddf/log.h>
     42#include <ddi.h>
     43#include <errno.h>
     44#include <ipc/adb.h>
     45#include <libarch/ddi.h>
     46#include <stdbool.h>
     47#include <stddef.h>
     48#include <sysinfo.h>
     49#include <stdint.h>
    3950#include <stdio.h>
    4051#include <stdlib.h>
    41 #include <stddef.h>
    42 #include <stdint.h>
    43 #include <stdbool.h>
    44 #include <ddi.h>
    45 #include <libarch/ddi.h>
    46 #include <loc.h>
    47 #include <sysinfo.h>
    48 #include <errno.h>
    49 #include <ipc/adb.h>
    50 #include <assert.h>
     52
    5153#include "cuda_adb.h"
    5254#include "cuda_hw.h"
     
    5456#define NAME  "cuda_adb"
    5557
    56 static void cuda_connection(ipc_callid_t, ipc_call_t *, void *);
     58static void cuda_dev_connection(ipc_callid_t, ipc_call_t *, void *);
    5759static int cuda_init(cuda_t *);
    5860static void cuda_irq_handler(ipc_callid_t, ipc_call_t *, void *);
     
    107109};
    108110
    109 int main(int argc, char *argv[])
    110 {
    111         service_id_t service_id;
    112         cuda_t cinst;
     111static int cuda_dev_create(cuda_t *cuda, const char *name, adb_dev_t **rdev)
     112{
     113        adb_dev_t *dev = NULL;
     114        ddf_fun_t *fun;
    113115        int rc;
    114         int i;
    115 
    116         printf(NAME ": VIA-CUDA Apple Desktop Bus driver\n");
    117 
    118         for (i = 0; i < ADB_MAX_ADDR; ++i) {
    119                 cinst.adb_dev[i].client_sess = NULL;
    120                 cinst.adb_dev[i].service_id = 0;
    121         }
    122 
    123         async_set_fallback_port_handler(cuda_connection, &cinst);
    124         rc = loc_server_register(NAME);
    125         if (rc < 0) {
    126                 printf(NAME ": Unable to register server.\n");
     116
     117        fun = ddf_fun_create(cuda->dev, fun_exposed, name);
     118        if (fun == NULL) {
     119                ddf_msg(LVL_ERROR, "Failed creating function '%s'.", name);
     120                rc = ENOMEM;
     121                goto error;
     122        }
     123
     124        dev = ddf_fun_data_alloc(fun, sizeof(adb_dev_t));
     125        if (dev == NULL) {
     126                ddf_msg(LVL_ERROR, "Failed allocating memory for '%s'.", name);
     127                rc = ENOMEM;
     128                goto error;
     129        }
     130
     131        dev->fun = fun;
     132        list_append(&dev->lcuda, &cuda->devs);
     133
     134        ddf_fun_set_conn_handler(fun, cuda_dev_connection);
     135
     136        rc = ddf_fun_bind(fun);
     137        if (rc != EOK) {
     138                ddf_msg(LVL_ERROR, "Failed binding function '%s'.", name);
     139                goto error;
     140        }
     141
     142        *rdev = dev;
     143        return EOK;
     144error:
     145        if (fun != NULL)
     146                ddf_fun_destroy(fun);
     147        return rc;
     148}
     149
     150int cuda_add(cuda_t *cuda)
     151{
     152        adb_dev_t *kbd = NULL;
     153        adb_dev_t *mouse = NULL;
     154        int rc;
     155
     156        rc = cuda_dev_create(cuda, "kbd", &kbd);
     157        if (rc != EOK)
     158                goto error;
     159
     160        rc = cuda_dev_create(cuda, "mouse", &mouse);
     161        if (rc != EOK)
     162                goto error;
     163
     164        cuda->addr_dev[2] = kbd;
     165        cuda->addr_dev[8] = kbd;
     166
     167        cuda->addr_dev[9] = mouse;
     168
     169
     170        rc = cuda_init(cuda);
     171        if (rc != EOK) {
     172                ddf_msg(LVL_ERROR, "Failed initializing CUDA hardware.");
    127173                return rc;
    128174        }
    129175
    130         rc = loc_service_register("adb/kbd", &service_id);
    131         if (rc != EOK) {
    132                 printf(NAME ": Unable to register service %s.\n", "adb/kbd");
    133                 return rc;
    134         }
    135 
    136         cinst.adb_dev[2].service_id = service_id;
    137         cinst.adb_dev[8].service_id = service_id;
    138 
    139         rc = loc_service_register("adb/mouse", &service_id);
    140         if (rc != EOK) {
    141                 printf(NAME ": Unable to register service %s.\n", "adb/mouse");
    142                 return rc;
    143         }
    144 
    145         cinst.adb_dev[9].service_id = service_id;
    146 
    147         if (cuda_init(&cinst) != EOK) {
    148                 printf("cuda_init() failed\n");
    149                 return 1;
    150         }
    151 
    152         task_retval(0);
    153         async_manager();
    154 
    155         return 0;
    156 }
    157 
    158 /** Character device connection handler */
    159 static void cuda_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    160 {
     176        return EOK;
     177error:
     178        return rc;
     179}
     180
     181int cuda_remove(cuda_t *cuda)
     182{
     183        return ENOTSUP;
     184}
     185
     186int cuda_gone(cuda_t *cuda)
     187{
     188        return ENOTSUP;
     189}
     190
     191/** Device connection handler */
     192static void cuda_dev_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     193{
     194        adb_dev_t *dev = (adb_dev_t *) ddf_fun_data_get((ddf_fun_t *) arg);
    161195        ipc_callid_t callid;
    162196        ipc_call_t call;
    163197        sysarg_t method;
    164         service_id_t dsid;
    165         cuda_t *cuda = (cuda_t *) arg;
    166         int dev_addr, i;
    167 
    168         /* Get the device handle. */
    169         dsid = IPC_GET_ARG2(*icall);
    170 
    171         /* Determine which disk device is the client connecting to. */
    172         dev_addr = -1;
    173         for (i = 0; i < ADB_MAX_ADDR; i++) {
    174                 if (cuda->adb_dev[i].service_id == dsid)
    175                         dev_addr = i;
    176         }
    177 
    178         if (dev_addr < 0) {
    179                 async_answer_0(iid, EINVAL);
    180                 return;
    181         }
    182198
    183199        /* Answer the IPC_M_CONNECT_ME_TO call. */
     
    197213                    async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
    198214                if (sess != NULL) {
    199                         if (cuda->adb_dev[dev_addr].client_sess == NULL) {
    200                                 cuda->adb_dev[dev_addr].client_sess = sess;
    201 
    202                                 /*
    203                                  * A hack so that we send the data to the session
    204                                  * regardless of which address the device is on.
    205                                  */
    206                                 for (i = 0; i < ADB_MAX_ADDR; ++i) {
    207                                         if (cuda->adb_dev[i].service_id == dsid)
    208                                                 cuda->adb_dev[i].client_sess = sess;
    209                                 }
    210 
    211                                 async_answer_0(callid, EOK);
    212                         } else
    213                                 async_answer_0(callid, ELIMIT);
    214                 } else
     215                        dev->client_sess = sess;
     216                        async_answer_0(callid, EOK);
     217                } else {
    215218                        async_answer_0(callid, EINVAL);
     219                }
    216220        }
    217221}
     
    307311
    308312        if ((b & TREQ) != 0) {
    309                 printf("cuda_irq_listen: no TREQ?!\n");
     313                ddf_msg(LVL_WARN, "cuda_irq_listen: no TREQ?!");
    310314                return;
    311315        }
     
    437441        uint8_t reg_no;
    438442        uint16_t reg_val;
     443        adb_dev_t *dev;
    439444        unsigned i;
    440445
     
    443448
    444449        if (size != 3) {
    445                 printf("unrecognized packet, size=%zu\n", size);
     450                ddf_msg(LVL_WARN, "Unrecognized packet, size=%zu", size);
    446451                for (i = 0; i < size; ++i) {
    447                         printf(" 0x%02x", data[i]);
     452                        ddf_msg(LVL_WARN, " 0x%02x", data[i]);
    448453                }
    449                 putchar('\n');
    450454                return;
    451455        }
    452456
    453457        if (reg_no != 0) {
    454                 printf("unrecognized packet, size=%zu\n", size);
     458                ddf_msg(LVL_WARN, "Unrecognized packet, size=%zu", size);
    455459                for (i = 0; i < size; ++i) {
    456                         printf(" 0x%02x", data[i]);
     460                        ddf_msg(LVL_WARN, " 0x%02x", data[i]);
    457461                }
    458                 putchar('\n');
    459462                return;
    460463        }
     
    462465        reg_val = ((uint16_t) data[1] << 8) | (uint16_t) data[2];
    463466
    464         if (cuda->adb_dev[dev_addr].client_sess == NULL)
    465                 return;
    466 
    467         async_exch_t *exch =
    468             async_exchange_begin(cuda->adb_dev[dev_addr].client_sess);
     467        ddf_msg(LVL_DEBUG, "Received ADB packet for device address %d",
     468            dev_addr);
     469        dev = cuda->addr_dev[dev_addr];
     470        if (dev == NULL)
     471                return;
     472
     473        async_exch_t *exch = async_exchange_begin(dev->client_sess);
    469474        async_msg_1(exch, ADB_REG_NOTIF, reg_val);
    470475        async_exchange_end(exch);
Note: See TracChangeset for help on using the changeset viewer.