Changeset 52b7b1bb in mainline for uspace/lib/libdrv/generic/driver.c
- 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
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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
Note:
See TracChangeset
for help on using the changeset viewer.