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

Changeset 7f8b581 in mainline


Ignore:
Timestamp:
2010-04-29T21:26:17Z (11 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

Location:
uspace
Files:
3 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);
  • uspace/lib/libdrv/include/driver.h

    rcfe7716 r7f8b581  
    3737
    3838#include <adt/list.h>
     39#include <ipc/ipc.h>
    3940#include <ipc/devman.h>
    4041#include <ipc/dev_iface.h>
     
    165166// interrupts
    166167
    167 static irq_cmd_t default_cmds[] = {
    168         {
    169                 .cmd = CMD_ACCEPT
    170         }
    171 };
    172 
    173 static irq_code_t default_pseudocode = {
    174         sizeof(default_cmds) / sizeof(irq_cmd_t),
    175         default_cmds
    176 };
    177 
    178168typedef void interrupt_handler_t(device_t *dev, ipc_callid_t iid, ipc_call_t *icall);
    179169
     
    270260}
    271261
     262int register_interrupt_handler(device_t *dev, int irq, interrupt_handler_t *handler, irq_code_t *pseudocode);
     263int unregister_interrupt_handler(device_t *dev, int irq);
     264
    272265#endif
    273266
  • uspace/srv/drivers/serial/serial.c

    rcfe7716 r7f8b581  
    267267}
    268268
     269static void serial_interrupt_handler(device_t *dev, ipc_callid_t iid, ipc_call_t *icall)
     270{
     271        // TODO
     272}
     273
     274static inline int serial_register_interrupt_handler(device_t *dev)
     275{
     276        serial_dev_data_t *data = (serial_dev_data_t *)dev->driver_data;
     277       
     278        return register_interrupt_handler(dev, data->irq, serial_interrupt_handler, NULL);
     279       
     280}
     281
    269282static int serial_add_device(device_t *dev)
    270283{
     
    290303        serial_initialize_port(dev);
    291304       
    292         // TODO register interrupt handler
     305        // register interrupt handler
     306        if (0 != serial_register_interrupt_handler(dev)) {
     307               
     308        }
    293309       
    294310        // enable interrupt
Note: See TracChangeset for help on using the changeset viewer.