Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 943aaf1b in mainline


Ignore:
Timestamp:
2017-10-02T20:52:27Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
Children:
7e55bed7, 94868e1
Parents:
6886705
Message:

Eliminate global variables in CUDA driver.

Location:
uspace/srv/hw/bus/cuda_adb
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hw/bus/cuda_adb/cuda_adb.c

    r6886705 r943aaf1b  
    5454#define NAME  "cuda_adb"
    5555
    56 static void cuda_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    57 static int cuda_init(void);
    58 static void cuda_irq_handler(ipc_callid_t iid, ipc_call_t *call, void *arg);
    59 
    60 static void cuda_irq_listen(void);
    61 static void cuda_irq_receive(void);
    62 static void cuda_irq_rcv_end(void *buf, size_t *len);
    63 static void cuda_irq_send_start(void);
    64 static void cuda_irq_send(void);
    65 
    66 static void cuda_packet_handle(uint8_t *buf, size_t len);
    67 static void cuda_send_start(void);
    68 static void cuda_autopoll_set(bool enable);
    69 
    70 static void adb_packet_handle(uint8_t *data, size_t size, bool autopoll);
     56static void cuda_connection(ipc_callid_t, ipc_call_t *, void *);
     57static int cuda_init(cuda_instance_t *);
     58static void cuda_irq_handler(ipc_callid_t, ipc_call_t *, void *);
     59
     60static void cuda_irq_listen(cuda_instance_t *);
     61static void cuda_irq_receive(cuda_instance_t *);
     62static void cuda_irq_rcv_end(cuda_instance_t *, void *, size_t *);
     63static void cuda_irq_send_start(cuda_instance_t *);
     64static void cuda_irq_send(cuda_instance_t *);
     65
     66static void cuda_packet_handle(cuda_instance_t *, uint8_t *, size_t);
     67static void cuda_send_start(cuda_instance_t *);
     68static void cuda_autopoll_set(cuda_instance_t *, bool);
     69
     70static void adb_packet_handle(cuda_instance_t *, uint8_t *, size_t, bool);
    7171
    7272static irq_pio_range_t cuda_ranges[] = {
     
    107107};
    108108
    109 static cuda_instance_t cinst;
    110 
    111 static cuda_instance_t *instance = &cinst;
    112 static cuda_t *dev;
    113 
    114 static adb_dev_t adb_dev[ADB_MAX_ADDR];
    115 
    116109int main(int argc, char *argv[])
    117110{
    118111        service_id_t service_id;
     112        cuda_instance_t cinst;
    119113        int rc;
    120114        int i;
     
    123117       
    124118        for (i = 0; i < ADB_MAX_ADDR; ++i) {
    125                 adb_dev[i].client_sess = NULL;
    126                 adb_dev[i].service_id = 0;
    127         }
    128 
    129         async_set_fallback_port_handler(cuda_connection, NULL);
     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);
    130124        rc = loc_server_register(NAME);
    131125        if (rc < 0) {
     
    140134        }
    141135
    142         adb_dev[2].service_id = service_id;
    143         adb_dev[8].service_id = service_id;
     136        cinst.adb_dev[2].service_id = service_id;
     137        cinst.adb_dev[8].service_id = service_id;
    144138
    145139        rc = loc_service_register("adb/mouse", &service_id);
     
    149143        }
    150144
    151         adb_dev[9].service_id = service_id;
    152 
    153         if (cuda_init() < 0) {
     145        cinst.adb_dev[9].service_id = service_id;
     146
     147        if (cuda_init(&cinst) < 0) {
    154148                printf("cuda_init() failed\n");
    155149                return 1;
     
    169163        sysarg_t method;
    170164        service_id_t dsid;
     165        cuda_instance_t *cuda = (cuda_instance_t *) arg;
    171166        int dev_addr, i;
    172167
     
    177172        dev_addr = -1;
    178173        for (i = 0; i < ADB_MAX_ADDR; i++) {
    179                 if (adb_dev[i].service_id == dsid)
     174                if (cuda->adb_dev[i].service_id == dsid)
    180175                        dev_addr = i;
    181176        }
     
    202197                    async_callback_receive_start(EXCHANGE_SERIALIZE, &call);
    203198                if (sess != NULL) {
    204                         if (adb_dev[dev_addr].client_sess == NULL) {
    205                                 adb_dev[dev_addr].client_sess = sess;
     199                        if (cuda->adb_dev[dev_addr].client_sess == NULL) {
     200                                cuda->adb_dev[dev_addr].client_sess = sess;
    206201                               
    207202                                /*
     
    210205                                 */
    211206                                for (i = 0; i < ADB_MAX_ADDR; ++i) {
    212                                         if (adb_dev[i].service_id == dsid)
    213                                                 adb_dev[i].client_sess = sess;
     207                                        if (cuda->adb_dev[i].service_id == dsid)
     208                                                cuda->adb_dev[i].client_sess = sess;
    214209                                }
    215210                               
     
    222217}
    223218
    224 
    225 static int cuda_init(void)
    226 {
    227         if (sysinfo_get_value("cuda.address.physical", &(instance->cuda_physical)) != EOK)
     219static int cuda_init(cuda_instance_t *cuda)
     220{
     221        if (sysinfo_get_value("cuda.address.physical", &(cuda->cuda_physical)) != EOK)
    228222                return -1;
    229223       
    230224        void *vaddr;
    231         if (pio_enable((void *) instance->cuda_physical, sizeof(cuda_t), &vaddr) != 0)
     225        if (pio_enable((void *) cuda->cuda_physical, sizeof(cuda_t), &vaddr) != 0)
    232226                return -1;
    233227       
    234         dev = vaddr;
    235 
    236         instance->cuda = dev;
    237         instance->xstate = cx_listen;
    238         instance->bidx = 0;
    239         instance->snd_bytes = 0;
    240 
    241         fibril_mutex_initialize(&instance->dev_lock);
     228        cuda->regs = vaddr;
     229        cuda->xstate = cx_listen;
     230        cuda->bidx = 0;
     231        cuda->snd_bytes = 0;
     232
     233        fibril_mutex_initialize(&cuda->dev_lock);
    242234
    243235        /* Disable all interrupts from CUDA. */
    244         pio_write_8(&dev->ier, IER_CLR | ALL_INT);
    245 
    246         cuda_irq_code.ranges[0].base = (uintptr_t) instance->cuda_physical;
    247         cuda_irq_code.cmds[0].addr = (void *) &((cuda_t *) instance->cuda_physical)->ifr;
    248         async_irq_subscribe(10, cuda_irq_handler, NULL, &cuda_irq_code);
     236        pio_write_8(&cuda->regs->ier, IER_CLR | ALL_INT);
     237
     238        cuda_irq_code.ranges[0].base = (uintptr_t) cuda->cuda_physical;
     239        cuda_irq_code.cmds[0].addr = (void *) &((cuda_t *) cuda->cuda_physical)->ifr;
     240        async_irq_subscribe(10, cuda_irq_handler, cuda, &cuda_irq_code);
    249241
    250242        /* Enable SR interrupt. */
    251         pio_write_8(&dev->ier, TIP | TREQ);
    252         pio_write_8(&dev->ier, IER_SET | SR_INT);
     243        pio_write_8(&cuda->regs->ier, TIP | TREQ);
     244        pio_write_8(&cuda->regs->ier, IER_SET | SR_INT);
    253245
    254246        /* Enable ADB autopolling. */
    255         cuda_autopoll_set(true);
     247        cuda_autopoll_set(cuda, true);
    256248
    257249        return 0;
     
    261253{
    262254        uint8_t rbuf[CUDA_RCV_BUF_SIZE];
     255        cuda_instance_t *cuda = (cuda_instance_t *)arg;
    263256        size_t len;
    264257        bool handle;
     
    267260        len = 0;
    268261
    269         fibril_mutex_lock(&instance->dev_lock);
    270 
    271         switch (instance->xstate) {
     262        fibril_mutex_lock(&cuda->dev_lock);
     263
     264        switch (cuda->xstate) {
    272265        case cx_listen:
    273                 cuda_irq_listen();
     266                cuda_irq_listen(cuda);
    274267                break;
    275268        case cx_receive:
    276                 cuda_irq_receive();
     269                cuda_irq_receive(cuda);
    277270                break;
    278271        case cx_rcv_end:
    279                 cuda_irq_rcv_end(rbuf, &len);
     272                cuda_irq_rcv_end(cuda, rbuf, &len);
    280273                handle = true;
    281274                break;
    282275        case cx_send_start:
    283                 cuda_irq_send_start();
     276                cuda_irq_send_start(cuda);
    284277                break;
    285278        case cx_send:
    286                 cuda_irq_send();
     279                cuda_irq_send(cuda);
    287280                break;
    288281        }
    289282       
    290283        /* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */
    291         pio_write_8(&instance->cuda->ifr, SR_INT);
    292 
    293         fibril_mutex_unlock(&instance->dev_lock);
     284        pio_write_8(&cuda->regs->ifr, SR_INT);
     285
     286        fibril_mutex_unlock(&cuda->dev_lock);
    294287
    295288        /* Handle an incoming packet. */
    296289        if (handle)
    297                 cuda_packet_handle(rbuf, len);
     290                cuda_packet_handle(cuda, rbuf, len);
    298291}
    299292
     
    301294 *
    302295 * Start packet reception.
    303  */
    304 static void cuda_irq_listen(void)
    305 {
    306         uint8_t b = pio_read_8(&dev->b);
     296 *
     297 * @param cuda CUDA instance
     298 */
     299static void cuda_irq_listen(cuda_instance_t *cuda)
     300{
     301        uint8_t b = pio_read_8(&cuda->regs->b);
    307302       
    308303        if ((b & TREQ) != 0) {
     
    311306        }
    312307       
    313         pio_write_8(&dev->b, b & ~TIP);
    314         instance->xstate = cx_receive;
     308        pio_write_8(&cuda->regs->b, b & ~TIP);
     309        cuda->xstate = cx_receive;
    315310}
    316311
     
    318313 *
    319314 * Receive next byte of packet.
    320  */
    321 static void cuda_irq_receive(void)
    322 {
    323         uint8_t data = pio_read_8(&dev->sr);
    324         if (instance->bidx < CUDA_RCV_BUF_SIZE)
    325                 instance->rcv_buf[instance->bidx++] = data;
    326        
    327         uint8_t b = pio_read_8(&dev->b);
     315 *
     316 * @param cuda CUDA instance
     317 */
     318static void cuda_irq_receive(cuda_instance_t *cuda)
     319{
     320        uint8_t data = pio_read_8(&cuda->regs->sr);
     321        if (cuda->bidx < CUDA_RCV_BUF_SIZE)
     322                cuda->rcv_buf[cuda->bidx++] = data;
     323       
     324        uint8_t b = pio_read_8(&cuda->regs->b);
    328325       
    329326        if ((b & TREQ) == 0) {
    330                 pio_write_8(&dev->b, b ^ TACK);
     327                pio_write_8(&cuda->regs->b, b ^ TACK);
    331328        } else {
    332                 pio_write_8(&dev->b, b | TACK | TIP);
    333                 instance->xstate = cx_rcv_end;
     329                pio_write_8(&cuda->regs->b, b | TACK | TIP);
     330                cuda->xstate = cx_rcv_end;
    334331        }
    335332}
     
    339336 * Terminate packet reception. Either go back to listen state or start
    340337 * receiving another packet if CUDA has one for us.
    341  */
    342 static void cuda_irq_rcv_end(void *buf, size_t *len)
    343 {
    344         uint8_t b = pio_read_8(&dev->b);
     338 *
     339 * @param cuda CUDA instance
     340 * @param buf Buffer for storing received packet
     341 * @param len Place to store length of received packet
     342 */
     343static void cuda_irq_rcv_end(cuda_instance_t *cuda, void *buf, size_t *len)
     344{
     345        uint8_t b = pio_read_8(&cuda->regs->b);
    345346       
    346347        if ((b & TREQ) == 0) {
    347                 instance->xstate = cx_receive;
    348                 pio_write_8(&dev->b, b & ~TIP);
     348                cuda->xstate = cx_receive;
     349                pio_write_8(&cuda->regs->b, b & ~TIP);
    349350        } else {
    350                 instance->xstate = cx_listen;
    351                 cuda_send_start();
    352         }
    353        
    354         memcpy(buf, instance->rcv_buf, instance->bidx);
    355         *len = instance->bidx;
    356         instance->bidx = 0;
     351                cuda->xstate = cx_listen;
     352                cuda_send_start(cuda);
     353        }
     354       
     355        memcpy(buf, cuda->rcv_buf, cuda->bidx);
     356        *len = cuda->bidx;
     357        cuda->bidx = 0;
    357358}
    358359
     
    360361 *
    361362 * Process result of sending first byte (and send second on success).
    362  */
    363 static void cuda_irq_send_start(void)
     363 *
     364 * @param cuda CUDA instance
     365 */
     366static void cuda_irq_send_start(cuda_instance_t *cuda)
    364367{
    365368        uint8_t b;
    366369
    367         b = pio_read_8(&dev->b);
     370        b = pio_read_8(&cuda->regs->b);
    368371
    369372        if ((b & TREQ) == 0) {
    370373                /* Collision */
    371                 pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT);
    372                 pio_read_8(&dev->sr);
    373                 pio_write_8(&dev->b, pio_read_8(&dev->b) | TIP | TACK);
    374                 instance->xstate = cx_listen;
    375                 return;
    376         }
    377 
    378         pio_write_8(&dev->sr, instance->snd_buf[1]);
    379         pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK);
    380         instance->bidx = 2;
    381 
    382         instance->xstate = cx_send;
     374                pio_write_8(&cuda->regs->acr, pio_read_8(&cuda->regs->acr) &
     375                    ~SR_OUT);
     376                pio_read_8(&cuda->regs->sr);
     377                pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) |
     378                    TIP | TACK);
     379                cuda->xstate = cx_listen;
     380                return;
     381        }
     382
     383        pio_write_8(&cuda->regs->sr, cuda->snd_buf[1]);
     384        pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) ^ TACK);
     385        cuda->bidx = 2;
     386
     387        cuda->xstate = cx_send;
    383388}
    384389
     
    386391 *
    387392 * Send next byte or terminate transmission.
    388  */
    389 static void cuda_irq_send(void)
    390 {
    391         if (instance->bidx < instance->snd_bytes) {
     393 *
     394 * @param cuda CUDA instance
     395 */
     396static void cuda_irq_send(cuda_instance_t *cuda)
     397{
     398        if (cuda->bidx < cuda->snd_bytes) {
    392399                /* Send next byte. */
    393                 pio_write_8(&dev->sr, instance->snd_buf[instance->bidx++]);
    394                 pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK);
     400                pio_write_8(&cuda->regs->sr,
     401                    cuda->snd_buf[cuda->bidx++]);
     402                pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) ^ TACK);
    395403                return;
    396404        }
    397405
    398406        /* End transfer. */
    399         instance->snd_bytes = 0;
    400         instance->bidx = 0;
    401 
    402         pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT);
    403         pio_read_8(&dev->sr);
    404         pio_write_8(&dev->b, pio_read_8(&dev->b) | TACK | TIP);
    405 
    406         instance->xstate = cx_listen;
     407        cuda->snd_bytes = 0;
     408        cuda->bidx = 0;
     409
     410        pio_write_8(&cuda->regs->acr, pio_read_8(&cuda->regs->acr) & ~SR_OUT);
     411        pio_read_8(&cuda->regs->sr);
     412        pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) | TACK | TIP);
     413
     414        cuda->xstate = cx_listen;
    407415        /* TODO: Match reply with request. */
    408416}
    409417
    410 static void cuda_packet_handle(uint8_t *data, size_t len)
     418static void cuda_packet_handle(cuda_instance_t *cuda, uint8_t *data, size_t len)
    411419{
    412420        if (data[0] != PT_ADB)
     
    415423                return;
    416424
    417         adb_packet_handle(data + 2, len - 2, (data[1] & 0x40) != 0);
    418 }
    419 
    420 static void adb_packet_handle(uint8_t *data, size_t size, bool autopoll)
     425        adb_packet_handle(cuda, data + 2, len - 2, (data[1] & 0x40) != 0);
     426}
     427
     428static void adb_packet_handle(cuda_instance_t *cuda, uint8_t *data,
     429    size_t size, bool autopoll)
    421430{
    422431        uint8_t dev_addr;
     
    448457        reg_val = ((uint16_t) data[1] << 8) | (uint16_t) data[2];
    449458
    450         if (adb_dev[dev_addr].client_sess == NULL)
     459        if (cuda->adb_dev[dev_addr].client_sess == NULL)
    451460                return;
    452461
    453462        async_exch_t *exch =
    454             async_exchange_begin(adb_dev[dev_addr].client_sess);
     463            async_exchange_begin(cuda->adb_dev[dev_addr].client_sess);
    455464        async_msg_1(exch, ADB_REG_NOTIF, reg_val);
    456465        async_exchange_end(exch);
    457466}
    458467
    459 static void cuda_autopoll_set(bool enable)
    460 {
    461         instance->snd_buf[0] = PT_CUDA;
    462         instance->snd_buf[1] = CPT_AUTOPOLL;
    463         instance->snd_buf[2] = enable ? 0x01 : 0x00;
    464         instance->snd_bytes = 3;
    465         instance->bidx = 0;
    466 
    467         cuda_send_start();
    468 }
    469 
    470 static void cuda_send_start(void)
    471 {
    472         cuda_t *dev = instance->cuda;
    473 
    474         assert(instance->xstate == cx_listen);
    475 
    476         if (instance->snd_bytes == 0)
     468static void cuda_autopoll_set(cuda_instance_t *cuda, bool enable)
     469{
     470        cuda->snd_buf[0] = PT_CUDA;
     471        cuda->snd_buf[1] = CPT_AUTOPOLL;
     472        cuda->snd_buf[2] = enable ? 0x01 : 0x00;
     473        cuda->snd_bytes = 3;
     474        cuda->bidx = 0;
     475
     476        cuda_send_start(cuda);
     477}
     478
     479static void cuda_send_start(cuda_instance_t *cuda)
     480{
     481        assert(cuda->xstate == cx_listen);
     482
     483        if (cuda->snd_bytes == 0)
    477484                return;
    478485
    479486        /* Check for incoming data. */
    480         if ((pio_read_8(&dev->b) & TREQ) == 0)
    481                 return;
    482 
    483         pio_write_8(&dev->acr, pio_read_8(&dev->acr) | SR_OUT);
    484         pio_write_8(&dev->sr, instance->snd_buf[0]);
    485         pio_write_8(&dev->b, pio_read_8(&dev->b) & ~TIP);
    486 
    487         instance->xstate = cx_send_start;
     487        if ((pio_read_8(&cuda->regs->b) & TREQ) == 0)
     488                return;
     489
     490        pio_write_8(&cuda->regs->acr, pio_read_8(&cuda->regs->acr) | SR_OUT);
     491        pio_write_8(&cuda->regs->sr, cuda->snd_buf[0]);
     492        pio_write_8(&cuda->regs->b, pio_read_8(&cuda->regs->b) & ~TIP);
     493
     494        cuda->xstate = cx_send_start;
    488495}
    489496
  • uspace/srv/hw/bus/cuda_adb/cuda_adb.h

    r6886705 r943aaf1b  
    4141#include <stddef.h>
    4242#include <stdint.h>
     43#include "cuda_hw.h"
    4344
    4445enum {
     
    6061
    6162typedef struct {
    62         struct cuda *cuda;
     63        struct cuda *regs;
    6364        uintptr_t cuda_physical;
    6465
     
    6970        enum cuda_xfer_state xstate;
    7071        fibril_mutex_t dev_lock;
     72
     73        adb_dev_t adb_dev[ADB_MAX_ADDR];
    7174} cuda_instance_t;
    7275
Note: See TracChangeset for help on using the changeset viewer.