Changeset 52b7b1bb in mainline
- Timestamp:
- 2010-04-01T14:08:55Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 57937dd
- Parents:
- a1769ee
- Location:
- uspace
- Files:
-
- 3 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/include/ipc/dev_iface.h
ra1769ee r52b7b1bb 35 35 36 36 typedef enum { 37 GENERIC_DEV_IFACE = DEV_IFACE_FIRST, 38 DIRECTLY_ADDRESSABLE_DEV_IFACE, 37 HW_RES_DEV_IFACE = DEV_IFACE_FIRST, 39 38 // TODO add more interfaces 40 39 DEV_IFACE_MAX … … 45 44 46 45 46 // data types related to some interface - TODO move this to separate header files 47 47 48 48 49 // HW resource provider interface 49 50 51 typedef enum { 52 GET_RESOURCE_LIST = 0, 53 ENABLE_INTERRUPT 54 } hw_res_funcs_t; 50 55 56 /** HW resource types. */ 57 typedef enum { 58 INTERRUPT, 59 REGISTER 60 } hw_res_type_t; 61 62 typedef enum { 63 LITTLE_ENDIAN = 0, 64 BIG_ENDIAN 65 } endianness_t; 66 67 /** HW resource (e.g. interrupt, memory register, i/o register etc.). */ 68 typedef struct hw_resource { 69 hw_res_type_t type; 70 union { 71 struct { 72 void *address; 73 endianness_t endianness; 74 size_t size; 75 } reg; 76 struct { 77 int irq; 78 } intr; 79 }; 80 } hw_resource_t; 81 82 typedef struct { 83 size_t count; 84 hw_resource_t *resources; 85 } hw_resource_list_t; 51 86 52 87 #endif -
uspace/lib/libdrv/Makefile
ra1769ee r52b7b1bb 35 35 36 36 SOURCES = \ 37 generic/driver.c 37 generic/driver.c \ 38 generic/dev_iface.c \ 39 generic/remote_res.h 38 40 39 41 include ../Makefile.common -
uspace/lib/libdrv/generic/dev_iface.c
ra1769ee r52b7b1bb 36 36 */ 37 37 38 #include "driver.h" 38 #include "dev_iface.h" 39 #include "remote_res.h" 40 41 static iface_dipatch_table_t remote_ifaces = { 42 .ifaces = { 43 &remote_res_iface 44 } 45 }; 46 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); 52 return remote_ifaces.ifaces[idx]; 53 } 54 55 remote_iface_func_ptr_t get_remote_method(remote_iface_t *rem_iface, ipcarg_t iface_method_idx) 56 { 57 if (iface_method_idx >= rem_iface->method_count) { 58 return NULL; 59 } 60 return rem_iface->methods[iface_method_idx]; 61 } 39 62 40 63 -
uspace/lib/libdrv/generic/driver.c
ra1769ee r52b7b1bb 35 35 /** @file 36 36 */ 37 37 38 38 #include <assert.h> 39 39 #include <ipc/services.h> … … 62 62 device_t *dev = (device_t *)malloc(sizeof(device_t)); 63 63 if (NULL != dev) { 64 memset(dev, 0, sizeof(device_t)); 65 } 66 return dev; 67 } 68 69 static device_t * driver_get_device(link_t *devices, device_handle_t handle) 70 { 64 memset(dev, 0, sizeof(device_t)); 65 } 66 return dev; 67 } 68 69 static device_t * driver_get_device(link_t *devices, device_handle_t handle) 70 { 71 71 device_t *dev = NULL; 72 72 link_t *link = devices->next; 73 73 74 74 while (link != devices) { 75 75 dev = list_get_instance(link, device_t, link); … … 78 78 } 79 79 } 80 80 81 81 return NULL; 82 82 } 83 83 84 static void driver_add_device(ipc_callid_t iid, ipc_call_t *icall) 84 static void driver_add_device(ipc_callid_t iid, ipc_call_t *icall) 85 85 { 86 86 printf("%s: driver_add_device\n", driver->name); 87 87 88 88 // result of the operation - device was added, device is not present etc. 89 ipcarg_t ret = 0; 90 device_handle_t dev_handle = IPC_GET_ARG1(*icall); 89 ipcarg_t ret = 0; 90 device_handle_t dev_handle = IPC_GET_ARG1(*icall); 91 91 device_t *dev = driver_create_device(); 92 92 dev->handle = dev_handle; … … 96 96 } 97 97 printf("%s: new device with handle = %x was added.\n", driver->name, dev_handle); 98 98 99 99 ipc_answer_1(iid, EOK, ret); 100 100 } … … 103 103 { 104 104 printf("%s: driver_connection_devman \n", driver->name); 105 105 106 106 /* Accept connection */ 107 107 ipc_answer_0(iid, EOK); 108 108 109 109 bool cont = true; 110 110 while (cont) { 111 111 ipc_call_t call; 112 112 ipc_callid_t callid = async_get_call(&call); 113 113 114 114 switch (IPC_GET_METHOD(call)) { 115 115 case IPC_M_PHONE_HUNGUP: … … 123 123 ipc_answer_0(callid, ENOENT); 124 124 } 125 } 126 } 127 128 /** 125 } 126 } 127 128 /** 129 129 * Generic client connection handler both for applications and drivers. 130 * 131 * @param driver true for driver client, false for other clients (applications, services etc.). 132 */ 133 static void driver_connection_gen(ipc_callid_t iid, ipc_call_t *icall, bool driver) { 134 /* 135 * Answer the first IPC_M_CONNECT_ME_TO call and remember the handle of the device to which the client connected. 136 */ 137 device_handle_t handle = IPC_GET_ARG1(*icall); 130 * 131 * @param driver true for driver client, false for other clients (applications, services etc.). 132 */ 133 static void driver_connection_gen(ipc_callid_t iid, ipc_call_t *icall, bool driver) 134 { 135 // Answer the first IPC_M_CONNECT_ME_TO call and remember the handle of the device to which the client connected. 136 device_handle_t handle = IPC_GET_ARG1(*icall); 138 137 device_t *dev = driver_get_device(&devices, handle); 139 138 140 139 if (dev == NULL) { 141 140 ipc_answer_0(iid, ENOENT); 142 141 return; 143 142 } 143 144 // TODO open the device (introduce some callbacks for opening and closing devices registered by the driver) 144 145 145 // TODO introduce generic device interface for opening and closing devices146 // and call its open callback here to find out wheter the device can be used by the connecting client147 148 149 146 ipc_answer_0(iid, EOK); 150 147 151 148 while (1) { 152 149 ipc_callid_t callid; 153 150 ipc_call_t call; 154 151 155 152 callid = async_get_call(&call); 156 153 ipcarg_t method = IPC_GET_METHOD(call); 157 154 switch (method) { 158 155 case IPC_M_PHONE_HUNGUP: 159 // TODO close the device 156 157 // TODO close the device 158 160 159 ipc_answer_0(callid, EOK); 161 160 return; 162 161 default: 163 if (DEV_IFACE_FIRST <= method && method < DEV_IFACE_MAX) { 164 // TODO - try to find interface, if supported 165 // otherwise return ENOTSUP 166 } else { 162 163 if (!is_valid_iface_id(method)) { 164 // this is not device's interface 167 165 ipc_answer_0(callid, ENOTSUP); 166 break; 168 167 } 168 169 // calling one of the device's interfaces 170 171 // get the device interface structure 172 void *iface = device_get_iface(dev, method); 173 if (NULL == iface) { 174 ipc_answer_0(callid, ENOTSUP); 175 break; 176 } 177 178 // get the corresponding interface for remote request handling ("remote interface") 179 remote_iface_t* rem_iface = get_remote_iface(method); 180 assert(NULL != rem_iface); 181 182 // get the method of the remote interface 183 ipcarg_t iface_method_idx = IPC_GET_ARG1(call); 184 remote_iface_func_ptr_t iface_method_ptr = get_remote_method(rem_iface, iface_method_idx); 185 if (NULL == iface_method_ptr) { 186 // the interface has not such method 187 ipc_answer_0(callid, ENOTSUP); 188 break; 189 } 190 191 // call the remote interface's method, which will receive parameters from the remote client 192 // and it will pass it to the corresponding local interface method associated with the device 193 // by its driver 194 (*iface_method_ptr)(dev, iface, callid, &call); 169 195 break; 170 196 } … … 174 200 static void driver_connection_driver(ipc_callid_t iid, ipc_call_t *icall) 175 201 { 176 driver_connection_gen(iid, icall, true); 202 driver_connection_gen(iid, icall, true); 177 203 } 178 204 179 205 static void driver_connection_client(ipc_callid_t iid, ipc_call_t *icall) 180 206 { 181 driver_connection_gen(iid, icall, false); 207 driver_connection_gen(iid, icall, false); 182 208 } 183 209 … … 199 225 break; 200 226 case DRIVER_CLIENT: 201 // handle requests from client applications 227 // handle requests from client applications 202 228 driver_connection_client(iid, icall); 203 229 break; 204 230 205 231 default: 206 /* No such interface */ 232 /* No such interface */ 207 233 ipc_answer_0(iid, ENOENT); 208 234 } … … 212 238 { 213 239 printf("%s: child_device_register\n", driver->name); 214 240 215 241 assert(NULL != child->name); 216 242 217 243 if (EOK == devman_child_device_register(child->name, &child->match_ids, parent->handle, &child->handle)) { 218 244 return true; … … 221 247 } 222 248 223 int driver_main(driver_t *drv) 249 int driver_main(driver_t *drv) 224 250 { 225 251 // remember the driver structure - driver_ops will be called by generic handler for incoming connections 226 252 driver = drv; 227 253 228 254 // register driver by device manager with generic handler for incoming connections 229 devman_driver_register(driver->name, driver_connection); 255 devman_driver_register(driver->name, driver_connection); 230 256 231 257 async_manager(); 232 258 233 259 // Never reached 234 return 0; 260 return 0; 235 261 } 236 262 -
uspace/lib/libdrv/include/driver.h
ra1769ee r52b7b1bb 39 39 #include <ipc/devman.h> 40 40 #include <ipc/dev_iface.h> 41 #include <assert.h> 41 42 42 43 struct device; … … 50 51 51 52 typedef struct { 52 int method_count;53 size_t method_count; 53 54 remote_iface_func_ptr_t *methods; 54 55 } remote_iface_t; … … 68 69 } 69 70 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); 73 74 70 75 // device 71 76 77 /** The device. */ 72 78 struct device { 79 /** Globally unique device identifier (assigned to the device by the device manager). */ 73 80 device_handle_t handle; 81 /** The phone to the parent device driver.*/ 74 82 ipcarg_t parent_phone; 83 /** The device's name.*/ 75 84 const char *name; 85 /** The list of device ids for device-to-driver matching.*/ 76 86 match_id_list_t match_ids; 87 /** The device driver's data associated with this device.*/ 77 88 void *driver_data; 89 /** The table of interfaces exported by this device. */ 78 90 void *interfaces[DEV_IFACE_COUNT]; 79 80 // TODO add more items 81 91 /** Pointer to the previous and next device in the list of devices handled by the driver */ 82 92 link_t link; 83 93 }; … … 86 96 // driver 87 97 98 /** Generic device driver operations. */ 88 99 typedef struct driver_ops { 100 /** Callback method for passing a new device to the device driver.*/ 89 101 bool (*add_device)(device_t *dev); 90 102 // TODO add other generic driver operations 91 103 } driver_ops_t; 92 104 105 /** The driver structure.*/ 93 106 typedef struct driver { 107 /** The name of the device driver. */ 94 108 const char *name; 109 /** Generic device driver operations. */ 95 110 driver_ops_t *driver_ops; 96 111 } driver_t; … … 102 117 int driver_main(driver_t *drv); 103 118 119 /** Create new device structure. 120 * 121 * @return the device structure. 122 */ 104 123 static inline device_t * create_device() 105 124 { … … 112 131 } 113 132 133 /** Delete device structure. 134 * 135 * @param dev the device structure. 136 */ 114 137 static inline void delete_device(device_t *dev) 115 138 { … … 129 152 } 130 153 154 static inline void * device_get_iface(device_t *dev, dev_inferface_id_t id) 155 { 156 assert(is_valid_iface_id(id)); 157 158 int idx = get_iface_index(id); 159 return dev->interfaces[idx]; 160 } 161 131 162 bool child_device_register(device_t *child, device_t *parent); 132 163 -
uspace/srv/drivers/root/root.c
ra1769ee r52b7b1bb 53 53 54 54 static bool root_add_device(device_t *dev); 55 static bool root_init();56 55 57 56 /** The root device driver's standard operations.
Note:
See TracChangeset
for help on using the changeset viewer.