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

Changeset 7f8b581 in mainline for uspace/lib/libdrv/generic/driver.c


Ignore:
Timestamp:
2010-04-29T21:26:17Z (12 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master
Children:
2300b9d
Parents:
cfe7716
Message:

provide a mechanism which enables the driver to register several interrupt handlers for several devices and irqs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libdrv/generic/driver.c

    rcfe7716 r7f8b581  
    5555#include "driver.h"
    5656
     57// driver structure
     58
    5759static driver_t *driver;
     60
     61// devices
     62
    5863LIST_INITIALIZE(devices);
    5964FIBRIL_MUTEX_INITIALIZE(devices_mutex);
     65
     66// interrupts
     67
     68static interrupt_context_list_t interrupt_contexts;
     69
     70static irq_cmd_t default_cmds[] = {
     71        {
     72                .cmd = CMD_ACCEPT
     73        }
     74};
     75
     76static irq_code_t default_pseudocode = {
     77        sizeof(default_cmds) / sizeof(irq_cmd_t),
     78        default_cmds
     79};
     80
     81
     82static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall)
     83{
     84        int id = (int)IPC_GET_METHOD(*icall);
     85        interrupt_context_t *ctx = find_interrupt_context_by_id(&interrupt_contexts, id);
     86        (*ctx->handler)(ctx->dev, iid, icall); 
     87}
     88
     89int register_interrupt_handler(device_t *dev, int irq, interrupt_handler_t *handler, irq_code_t *pseudocode)
     90{
     91        interrupt_context_t *ctx = create_interrupt_context();
     92       
     93        ctx->dev = dev;
     94        ctx->irq = irq;
     95        ctx->handler = handler;
     96       
     97        add_interrupt_context(&interrupt_contexts, ctx);
     98       
     99        if (NULL == pseudocode) {
     100                pseudocode = &default_pseudocode;
     101        }
     102       
     103        int res = ipc_register_irq(irq, dev->handle, ctx->id, pseudocode);
     104        if (0 != res) {
     105                remove_interrupt_context(&interrupt_contexts, ctx);
     106                delete_interrupt_context(ctx);
     107        }
     108        return res;     
     109}
     110
     111int unregister_interrupt_handler(device_t *dev, int irq)
     112{
     113        interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts, dev, irq);
     114        int res = ipc_unregister_irq(irq, dev->handle);
     115        if (NULL != ctx) {
     116                remove_interrupt_context(&interrupt_contexts, ctx);
     117                delete_interrupt_context(ctx);         
     118        }
     119        return res;
     120}
    60121
    61122static void add_to_devices_list(device_t *dev)
     
    283344        driver = drv;
    284345
     346        // initialize the list of interrupt contexts
     347        init_interrupt_context_list(&interrupt_contexts);
     348       
     349        // set generic interrupt handler
     350        async_set_interrupt_received(driver_irq_handler);
     351       
    285352        // register driver by device manager with generic handler for incoming connections
    286353        devman_driver_register(driver->name, driver_connection);
Note: See TracChangeset for help on using the changeset viewer.