Changeset 3843ecb in mainline


Ignore:
Timestamp:
2010-04-09T13:54:06Z (15 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
892e4e1
Parents:
3a5909f
Message:

device classes as interface sets

Location:
uspace
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/generic/device/hw_res.c

    r3a5909f r3843ecb  
    3737#include <async.h>
    3838#include <malloc.h>
    39  
    4039
    4140bool get_hw_resources(int dev_phone, hw_resource_list_t *hw_resources)
    4241{
    4342        ipcarg_t count = 0;
    44         int rc = async_req_1_1(dev_phone, HW_RES_DEV_IFACE, GET_RESOURCE_LIST, &count);
     43        int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE), GET_RESOURCE_LIST, &count);
    4544        hw_resources->count = count;
    4645        if (EOK != rc) {
     
    6665bool enable_interrupt(int dev_phone)
    6766{
    68         int rc = async_req_1_0(dev_phone, HW_RES_DEV_IFACE, ENABLE_INTERRUPT);
     67        int rc = async_req_1_0(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE), ENABLE_INTERRUPT);
    6968        return rc == EOK;
    7069}
  • uspace/lib/libc/include/device/hw_res.h

    r3a5909f r3843ecb  
    3939#include <bool.h>
    4040
     41/** HW resource (e.g. interrupt, memory register, i/o register etc.). */
     42typedef struct hw_resource {
     43        hw_res_type_t type;
     44        union {
     45                struct {
     46                        uint64_t address;
     47                        endianness_t endianness;                       
     48                        size_t size;                   
     49                } mem_range;
     50                struct {
     51                        uint64_t address;
     52                        endianness_t endianness;                       
     53                        size_t size;                   
     54                } io_range;
     55                struct {
     56                        int irq;                       
     57                } interrupt;           
     58        } res; 
     59} hw_resource_t;
     60
     61typedef struct hw_resource_list {
     62        size_t count;
     63        hw_resource_t *resources;       
     64} hw_resource_list_t;
     65
     66static inline void clean_hw_resource_list(hw_resource_list_t *hw_res)
     67{
     68        if(NULL != hw_res->resources) {
     69                free(hw_res->resources);
     70                hw_res->resources = NULL;
     71        }
     72        hw_res->count = 0;     
     73}
     74
    4175
    4276bool get_hw_resources(int dev_phone, hw_resource_list_t *hw_resources);
  • uspace/lib/libc/include/ipc/dev_iface.h

    r3a5909f r3843ecb  
    3535#include <libarch/types.h>
    3636
    37 #define DEV_IFACE_FIRST IPC_FIRST_USER_METHOD
    38 
    3937typedef enum { 
    40         HW_RES_DEV_IFACE = DEV_IFACE_FIRST,     
     38        HW_RES_DEV_IFACE = 0,   
    4139        // TODO add more interfaces
    4240        DEV_IFACE_MAX
    43 } dev_inferface_id_t;
     41} dev_inferface_idx_t;
    4442
     43#define DEV_IFACE_ID(idx) ((idx) + IPC_FIRST_USER_METHOD)
     44#define DEV_IFACE_IDX(id) ((id) - IPC_FIRST_USER_METHOD)
    4545
    46 #define DEV_IFACE_COUNT (DEV_IFACE_MAX - DEV_IFACE_FIRST)
     46#define DEV_IFACE_COUNT DEV_IFACE_MAX
    4747
    48 
    49 // data types related to some interface - TODO move this to separate header files
    5048
    5149
     
    6967} endianness_t;
    7068
    71 /** HW resource (e.g. interrupt, memory register, i/o register etc.). */
    72 typedef struct hw_resource {
    73         hw_res_type_t type;
    74         union {
    75                 struct {
    76                         uint64_t address;
    77                         endianness_t endianness;                       
    78                         size_t size;                   
    79                 } mem_range;
    80                 struct {
    81                         uint64_t address;
    82                         endianness_t endianness;                       
    83                         size_t size;                   
    84                 } io_range;
    85                 struct {
    86                         int irq;                       
    87                 } interrupt;           
    88         } res; 
    89 } hw_resource_t;
    90 
    91 typedef struct hw_resource_list {
    92         size_t count;
    93         hw_resource_t *resources;       
    94 } hw_resource_list_t;
    95 
    96 static inline void clean_hw_resource_list(hw_resource_list_t *hw_res)
    97 {
    98         if(NULL != hw_res->resources) {
    99                 free(hw_res->resources);
    100                 hw_res->resources = NULL;
    101         }
    102         hw_res->count = 0;     
    103 }
    104 
    10569#endif
  • uspace/lib/libdrv/generic/dev_iface.c

    r3a5909f r3843ecb  
    4545};
    4646
    47 remote_iface_t* get_remote_iface(dev_inferface_id_t id)
    48 {
    49         assert(is_valid_iface_id(id));
    50        
    51         int idx = get_iface_index(id);
     47remote_iface_t* get_remote_iface(int idx)
     48{       
     49        assert(is_valid_iface_idx(idx));       
    5250        return remote_ifaces.ifaces[idx];       
    5351}
  • uspace/lib/libdrv/generic/driver.c

    r3a5909f r3843ecb  
    177177                callid = async_get_call(&call);
    178178                ipcarg_t method = IPC_GET_METHOD(call);
     179                int iface_idx;
     180               
    179181                switch  (method) {
    180182                case IPC_M_PHONE_HUNGUP:
     
    184186                        ipc_answer_0(callid, EOK);
    185187                        return;
    186                 default:
    187 
    188                         if (!is_valid_iface_id(method)) {
     188                default:               
     189                        // convert ipc interface id to interface index
     190                       
     191                        iface_idx = DEV_IFACE_IDX(method);
     192                       
     193                        if (!is_valid_iface_idx(iface_idx)) {
    189194                                // this is not device's interface
    190195                                printf("%s: driver_connection_gen error - invalid interface id %x.", driver->name, method);
     
    196201                       
    197202                        // get the device interface structure
    198                         void *iface = device_get_iface(dev, method);
     203                        void *iface = device_get_iface(dev, iface_idx);
    199204                        if (NULL == iface) {
    200205                                printf("%s: driver_connection_gen error - ", driver->name);
     
    205210
    206211                        // get the corresponding interface for remote request handling ("remote interface")
    207                         remote_iface_t* rem_iface = get_remote_iface(method);
     212                        remote_iface_t* rem_iface = get_remote_iface(iface_idx);
    208213                        assert(NULL != rem_iface);
    209214
  • uspace/lib/libdrv/include/driver.h

    r3a5909f r3843ecb  
    3939#include <ipc/devman.h>
    4040#include <ipc/dev_iface.h>
     41#include <device/hw_res.h>
    4142#include <assert.h>
    4243
     
    5960} iface_dipatch_table_t;
    6061
    61 static inline int get_iface_index(dev_inferface_id_t id)
     62
     63static inline bool is_valid_iface_idx(int idx)
    6264{
    63         return id - DEV_IFACE_FIRST;
     65        return 0 <= idx && idx < DEV_IFACE_MAX;
    6466}
    6567
    66 static inline bool is_valid_iface_id(dev_inferface_id_t id)
    67 {
    68         return DEV_IFACE_FIRST <= id && id < DEV_IFACE_MAX;
    69 }
     68remote_iface_t* get_remote_iface(int idx);
     69remote_iface_func_ptr_t get_remote_method(remote_iface_t *rem_iface, ipcarg_t iface_method_idx);
    7070
    71 remote_iface_t* get_remote_iface(dev_inferface_id_t id);
    72 remote_iface_func_ptr_t get_remote_method(remote_iface_t *rem_iface, ipcarg_t iface_method_idx);
     71
     72// device class
     73
     74/** Devices belonging to the same class should implement the same set of interfaces.*/
     75typedef struct device_class {
     76        /** Unique identification of the class. */
     77        int id;
     78        /** The table of interfaces implemented by the device. */
     79        void *interfaces[DEV_IFACE_COUNT];     
     80} device_class_t;
    7381
    7482
     
    8997        /** The device driver's data associated with this device.*/
    9098        void *driver_data;
    91         /** The table of interfaces exported by this device. */
    92         void *interfaces[DEV_IFACE_COUNT];
     99        /** Device class consist of class id and table of interfaces supported by the device.*/
     100        device_class_t *class;
    93101        /** Pointer to the previous and next device in the list of devices handled by the driver */
    94102        link_t link;
     
    146154}
    147155
    148 static inline void device_set_iface (device_t *dev, dev_inferface_id_t id, void *iface)
     156static inline void * device_get_iface(device_t *dev, dev_inferface_idx_t idx)
    149157{
    150         assert(is_valid_iface_id(id));
     158        assert(is_valid_iface_idx(idx));       
    151159
    152         int idx = get_iface_index(id);
    153         dev->interfaces[idx] = iface;
    154 }
    155 
    156 static inline void * device_get_iface(device_t *dev, dev_inferface_id_t id)
    157 {
    158         assert(is_valid_iface_id(id));
    159        
    160         int idx = get_iface_index(id);
    161         return dev->interfaces[idx];   
     160        return dev->class->interfaces[idx];     
    162161}
    163162
  • uspace/srv/devman/main.c

    r3a5909f r3843ecb  
    121121}
    122122
     123/**
     124 * Receive device match ID from the device's parent driver and add it to the list of devices match ids.
     125 *
     126 * @param match_ids the list of the device's match ids.
     127 *
     128 * @return 0 on success, negative error code otherwise.
     129 */
    123130static int devman_receive_match_id(match_id_list_t *match_ids) {
    124131       
     
    159166}
    160167
     168/**
     169 * Receive device match IDs from the device's parent driver
     170 * and add them to the list of devices match ids.
     171 *
     172 * @param match_count the number of device's match ids to be received.
     173 * @param match_ids the list of the device's match ids.
     174 *
     175 * @return 0 on success, negative error code otherwise.
     176 */
    161177static int devman_receive_match_ids(ipcarg_t match_count, match_id_list_t *match_ids)
    162178{       
     
    171187}
    172188
    173 static void devman_add_child(ipc_callid_t callid, ipc_call_t *call, driver_t *driver)
     189/** Handle child device registration.
     190 *
     191 * Child devices are registered by their parent's device driver.
     192 */
     193static void devman_add_child(ipc_callid_t callid, ipc_call_t *call)
    174194{
    175195        // printf(NAME ": devman_add_child\n");
     
    211231}
    212232
     233/**
     234 * Initialize driver which has registered itself as running and ready.
     235 *
     236 * The initialization is done in a separate fibril to avoid deadlocks
     237 * (if the driver needed to be served by devman during the driver's initialization).
     238 */
    213239static int init_running_drv(void *drv)
    214240{
     
    219245}
    220246
    221 /** Function for handling connections to device manager.
    222  *
     247/** Function for handling connections from a driver to the device manager.
    223248 */
    224249static void devman_connection_driver(ipc_callid_t iid, ipc_call_t *icall)
     
    231256                return;
    232257       
     258        // Initialize the driver as running (e.g. pass assigned devices to it) in a separate fibril;
     259        // the separate fibril is used to enable the driver
     260        // to use devman service during the driver's initialization.
    233261        fid_t fid = fibril_create(init_running_drv, driver);
    234262        if (fid == 0) {
    235263                printf(NAME ": Error creating fibril for the initialization of the newly registered running driver.\n");
    236                 exit(1);
     264                return;
    237265        }
    238266        fibril_add_ready(fid);
     
    254282                        continue;
    255283                case DEVMAN_ADD_CHILD_DEVICE:
    256                         devman_add_child(callid, &call, driver);
     284                        devman_add_child(callid, &call);
    257285                        break;
    258286                default:
     
    299327       
    300328        if (driver->phone <= 0) {
    301                 printf(NAME ": devman_forward: cound not forward to driver %s (the driver's phone is %x).\n", driver->name, driver->phone);
     329                printf(NAME ": devman_forward: cound not forward to driver %s ", driver->name);
     330                printf("the driver's phone is %x).\n", driver->phone);
    302331                return;
    303332        }
  • uspace/srv/drivers/pciintel/pci.c

    r3a5909f r3843ecb  
    5858#define NAME "pciintel"
    5959
    60 
    6160#define CONF_ADDR(bus, dev, fn, reg)   ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
     61
     62
     63static hw_resource_list_t * pciintel_get_child_resources(device_t *dev)
     64{
     65        pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data;
     66        if (NULL == dev_data) {
     67                return NULL;
     68        }
     69        return &dev_data->hw_resources;
     70}
     71
     72static bool pciintel_enable_child_interrupt(device_t *dev)
     73{
     74        // TODO
     75       
     76        return false;
     77}
     78
     79static resource_iface_t pciintel_child_res_iface = {
     80        &pciintel_get_child_resources,
     81        &pciintel_enable_child_interrupt       
     82};
     83
     84static device_class_t pci_child_class;
    6285
    6386
     
    373396                        pci_read_interrupt(dev);
    374397                       
    375                         // TODO initialize device interfaces                   
     398                        dev->class = &pci_child_class;                 
    376399                       
    377400                        printf(NAME ": adding new child device %s.\n", dev->name);
     
    464487}
    465488
     489static void pciintel_init()
     490{
     491        pci_child_class.id = 0; // TODO
     492        pci_child_class.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_res_iface;
     493}
     494
    466495int main(int argc, char *argv[])
    467496{
    468         printf(NAME ": HelenOS pci bus driver (intel method 1).\n");   
     497        printf(NAME ": HelenOS pci bus driver (intel method 1).\n");
     498        pciintel_init();
    469499        return driver_main(&pci_driver);
    470500}
  • uspace/srv/drivers/pciintel/pci.h

    r3a5909f r3843ecb  
    110110}
    111111
    112 static inline bool pci_clean_resource_list(device_t *dev)
     112static inline void pci_clean_resource_list(device_t *dev)
    113113{
    114114        pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data;
  • uspace/srv/drivers/rootia32/rootia32.c

    r3a5909f r3843ecb  
    5151#include <ipc/dev_iface.h>
    5252#include <resource.h>
     53#include <device/hw_res.h>
    5354
    5455#define NAME "rootia32"
     
    111112};
    112113
     114// initialized in root_ia32_init() function
     115static device_class_t rootia32_child_class;
     116
    113117static bool rootia32_add_child(
    114118        device_t *parent, const char *name, const char *str_match_id,
     
    136140        add_match_id(&child->match_ids, match_id);     
    137141       
    138         // add an interface to the device
    139         device_set_iface(child, HW_RES_DEV_IFACE, &child_res_iface);
     142        // set class to the device
     143        child->class = &rootia32_child_class;
    140144       
    141145        // register child  device
     
    181185}
    182186
     187static void root_ia32_init() {
     188        // initialize child device class               
     189        rootia32_child_class.id = 0;    // TODO
     190        rootia32_child_class.interfaces[HW_RES_DEV_IFACE] = &child_res_iface;
     191}
     192
    183193int main(int argc, char *argv[])
    184194{
    185195        printf(NAME ": HelenOS root device driver\n"); 
     196        root_ia32_init();
    186197        return driver_main(&rootia32_driver);
    187198}
Note: See TracChangeset for help on using the changeset viewer.