Changeset 8048c648 in mainline for uspace/lib/drv/include/driver.h
- Timestamp:
- 2011-01-14T10:08:47Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f40a1e2
- Parents:
- 44bb20b (diff), 6610565b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/include/driver.h
r44bb20b r8048c648 41 41 #include <ipc/devman.h> 42 42 #include <ipc/dev_iface.h> 43 #include <device/hw_res.h>44 #include <device/char.h>45 43 #include <assert.h> 46 44 #include <ddi.h> … … 49 47 #include <malloc.h> 50 48 49 #include "dev_iface.h" 50 51 51 struct device; 52 52 typedef struct device device_t; 53 53 54 /* device interface */ 54 /* 55 * Device class 56 */ 55 57 56 /* 57 * First two parameters: device and interface structure registered by the 58 * devices driver. 59 */ 60 typedef void remote_iface_func_t(device_t *, void *, ipc_callid_t, 61 ipc_call_t *); 62 typedef remote_iface_func_t *remote_iface_func_ptr_t; 63 typedef void remote_handler_t(device_t *, ipc_callid_t, ipc_call_t *); 64 65 typedef struct { 66 size_t method_count; 67 remote_iface_func_ptr_t *methods; 68 } remote_iface_t; 69 70 typedef struct { 71 remote_iface_t *ifaces[DEV_IFACE_COUNT]; 72 } iface_dipatch_table_t; 73 74 75 static inline bool is_valid_iface_idx(int idx) 76 { 77 return 0 <= idx && idx < DEV_IFACE_MAX; 78 } 79 80 remote_iface_t *get_remote_iface(int); 81 remote_iface_func_ptr_t get_remote_method(remote_iface_t *, sysarg_t); 82 83 84 /* device class */ 85 86 /** Devices operations. */ 58 /** Devices operations */ 87 59 typedef struct device_ops { 88 60 /** … … 110 82 111 83 112 /* device */ 84 /* 85 * Device 86 */ 113 87 114 /** The device.*/88 /** Device structure */ 115 89 struct device { 116 90 /** … … 121 95 122 96 /** 123 * The phone to the parent device driver (if it is different from this124 * driver) .97 * Phone to the parent device driver (if it is different from this 98 * driver) 125 99 */ 126 100 int parent_phone; 127 101 128 /** Parent device if handled by this driver, NULL otherwise .*/102 /** Parent device if handled by this driver, NULL otherwise */ 129 103 device_t *parent; 130 /** The device's name.*/104 /** Device name */ 131 105 const char *name; 132 /** The list of device ids for device-to-driver matching.*/106 /** List of device ids for device-to-driver matching */ 133 107 match_id_list_t match_ids; 134 /** The device driver's data associated with this device.*/108 /** Driver-specific data associated with this device */ 135 109 void *driver_data; 136 /** The implementation of operations provided by this device .*/110 /** The implementation of operations provided by this device */ 137 111 device_ops_t *ops; 138 112 139 /** 140 * Pointer to the previous and next device in the list of devices 141 * handled by the driver. 142 */ 113 /** Link in the list of devices handled by the driver */ 143 114 link_t link; 144 115 }; 145 116 117 /* 118 * Driver 119 */ 146 120 147 /* driver */ 148 149 /** Generic device driver operations. */ 121 /** Generic device driver operations */ 150 122 typedef struct driver_ops { 151 /** Callback method for passing a new device to the device driver .*/123 /** Callback method for passing a new device to the device driver */ 152 124 int (*add_device)(device_t *dev); 153 /* TODO add other generic driver operations */125 /* TODO: add other generic driver operations */ 154 126 } driver_ops_t; 155 127 156 /** The driver structure.*/128 /** Driver structure */ 157 129 typedef struct driver { 158 /** The name of the device driver.*/130 /** Name of the device driver */ 159 131 const char *name; 160 /** Generic device driver operations .*/132 /** Generic device driver operations */ 161 133 driver_ops_t *driver_ops; 162 134 } driver_t; … … 168 140 * @return The device structure. 169 141 */ 170 static inline device_t *create_device(void) 171 { 172 device_t *dev = malloc(sizeof(device_t)); 173 if (NULL != dev) { 174 memset(dev, 0, sizeof(device_t)); 175 init_match_ids(&dev->match_ids); 176 } 177 return dev; 178 } 142 extern device_t *create_device(void); 143 extern void delete_device(device_t *); 144 extern void *device_get_ops(device_t *, dev_inferface_idx_t); 179 145 180 /** Delete device structure. 181 * 182 * @param dev The device structure. 146 extern int child_device_register(device_t *, device_t *); 147 extern int child_device_register_wrapper(device_t *, const char *, const char *, 148 int, devman_handle_t *); 149 150 /* 151 * Interrupts 183 152 */ 184 static inline void delete_device(device_t *dev)185 {186 clean_match_ids(&dev->match_ids);187 if (NULL != dev->name)188 free(dev->name);189 free(dev);190 }191 192 static inline void *device_get_iface(device_t *dev, dev_inferface_idx_t idx)193 {194 assert(is_valid_iface_idx(idx));195 if (NULL == dev->ops)196 return NULL;197 return dev->ops->interfaces[idx];198 }199 200 int child_device_register(device_t *, device_t *);201 int child_device_register_wrapper(device_t *, const char *, const char *, int,202 devman_handle_t *);203 204 205 /* interrupts */206 153 207 154 typedef void interrupt_handler_t(device_t *, ipc_callid_t, ipc_call_t *); … … 221 168 } interrupt_context_list_t; 222 169 223 static inline interrupt_context_t *create_interrupt_context(void) 224 { 225 interrupt_context_t *ctx; 226 227 ctx = (interrupt_context_t *) malloc(sizeof(interrupt_context_t)); 228 if (NULL != ctx) 229 memset(ctx, 0, sizeof(interrupt_context_t)); 230 231 return ctx; 232 } 170 extern interrupt_context_t *create_interrupt_context(void); 171 extern void delete_interrupt_context(interrupt_context_t *); 172 extern void init_interrupt_context_list(interrupt_context_list_t *); 173 extern void add_interrupt_context(interrupt_context_list_t *, 174 interrupt_context_t *); 175 extern void remove_interrupt_context(interrupt_context_list_t *, 176 interrupt_context_t *); 177 extern interrupt_context_t *find_interrupt_context_by_id( 178 interrupt_context_list_t *, int); 179 extern interrupt_context_t *find_interrupt_context( 180 interrupt_context_list_t *, device_t *, int); 233 181 234 static inline void delete_interrupt_context(interrupt_context_t *ctx) 235 { 236 if (NULL != ctx) 237 free(ctx); 238 } 182 extern int register_interrupt_handler(device_t *, int, interrupt_handler_t *, 183 irq_code_t *); 184 extern int unregister_interrupt_handler(device_t *, int); 239 185 240 static inline void init_interrupt_context_list(interrupt_context_list_t *list) 241 { 242 memset(list, 0, sizeof(interrupt_context_list_t)); 243 fibril_mutex_initialize(&list->mutex); 244 list_initialize(&list->contexts); 245 } 246 247 static inline void 248 add_interrupt_context(interrupt_context_list_t *list, interrupt_context_t *ctx) 249 { 250 fibril_mutex_lock(&list->mutex); 251 ctx->id = list->curr_id++; 252 list_append(&ctx->link, &list->contexts); 253 fibril_mutex_unlock(&list->mutex); 254 } 255 256 static inline void 257 remove_interrupt_context(interrupt_context_list_t *list, 258 interrupt_context_t *ctx) 259 { 260 fibril_mutex_lock(&list->mutex); 261 list_remove(&ctx->link); 262 fibril_mutex_unlock(&list->mutex); 263 } 264 265 static inline interrupt_context_t * 266 find_interrupt_context_by_id(interrupt_context_list_t *list, int id) 267 { 268 fibril_mutex_lock(&list->mutex); 269 270 link_t *link = list->contexts.next; 271 interrupt_context_t *ctx; 272 273 while (link != &list->contexts) { 274 ctx = list_get_instance(link, interrupt_context_t, link); 275 if (id == ctx->id) { 276 fibril_mutex_unlock(&list->mutex); 277 return ctx; 278 } 279 link = link->next; 280 } 281 282 fibril_mutex_unlock(&list->mutex); 283 return NULL; 284 } 285 286 static inline interrupt_context_t * 287 find_interrupt_context(interrupt_context_list_t *list, device_t *dev, int irq) 288 { 289 fibril_mutex_lock(&list->mutex); 290 291 link_t *link = list->contexts.next; 292 interrupt_context_t *ctx; 293 294 while (link != &list->contexts) { 295 ctx = list_get_instance(link, interrupt_context_t, link); 296 if (irq == ctx->irq && dev == ctx->dev) { 297 fibril_mutex_unlock(&list->mutex); 298 return ctx; 299 } 300 link = link->next; 301 } 302 303 fibril_mutex_unlock(&list->mutex); 304 return NULL; 305 } 306 307 int register_interrupt_handler(device_t *, int, interrupt_handler_t *, 308 irq_code_t *); 309 int unregister_interrupt_handler(device_t *, int); 310 311 312 /* default handler for client requests */ 313 314 static inline remote_handler_t *device_get_default_handler(device_t *dev) 315 { 316 if (NULL == dev->ops) 317 return NULL; 318 return dev->ops->default_handler; 319 } 320 321 static inline int add_device_to_class(device_t *dev, const char *class_name) 322 { 323 return devman_add_device_to_class(dev->handle, class_name); 324 } 186 extern remote_handler_t *device_get_default_handler(device_t *); 187 extern int add_device_to_class(device_t *, const char *); 325 188 326 189 #endif
Note:
See TracChangeset
for help on using the changeset viewer.