Changeset 17fd1d4 in mainline
- Timestamp:
- 2009-06-03T18:59:31Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c20aa06
- Parents:
- 05b9912
- Location:
- uspace/srv/fs/devfs
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/devfs/devfs.c
r05b9912 r17fd1d4 29 29 /** @addtogroup fs 30 30 * @{ 31 */ 31 */ 32 32 33 33 /** … … 75 75 devfs_lookup(callid, &call); 76 76 break; 77 case VFS_OPEN_NODE: 78 devfs_open_node(callid, &call); 79 break; 80 case VFS_DEVICE: 81 devfs_device(callid, &call); 82 break; 77 83 case VFS_READ: 78 84 devfs_read(callid, &call); … … 83 89 case VFS_TRUNCATE: 84 90 devfs_truncate(callid, &call); 91 break; 92 case VFS_CLOSE: 93 devfs_close(callid, &call); 94 break; 95 case VFS_SYNC: 96 devfs_sync(callid, &call); 85 97 break; 86 98 case VFS_DESTROY: … … 123 135 } 124 136 125 /** 137 /** 126 138 * @} 127 139 */ -
uspace/srv/fs/devfs/devfs_ops.c
r05b9912 r17fd1d4 42 42 #include <string.h> 43 43 #include <libfs.h> 44 #include <libadt/hash_table.h> 44 45 #include "devfs.h" 45 46 #include "devfs_ops.h" … … 47 48 #define PLB_GET_CHAR(pos) (devfs_reg.plb_ro[pos % PLB_SIZE]) 48 49 50 /** Opened devices structure */ 51 typedef struct { 52 dev_handle_t handle; 53 int phone; 54 size_t refcount; 55 link_t link; 56 } device_t; 57 58 /** Hash table of opened devices */ 59 static hash_table_t devices; 60 61 #define DEVICES_KEYS 1 62 #define DEVICES_KEY_HANDLE 0 63 #define DEVICES_BUCKETS 256 64 65 /* Implementation of hash table interface for the nodes hash table. */ 66 static hash_index_t devices_hash(unsigned long key[]) 67 { 68 return key[DEVICES_KEY_HANDLE] % DEVICES_BUCKETS; 69 } 70 71 static int devices_compare(unsigned long key[], hash_count_t keys, link_t *item) 72 { 73 device_t *dev = hash_table_get_instance(item, device_t, link); 74 return (dev->handle == (dev_handle_t) key[DEVICES_KEY_HANDLE]); 75 } 76 77 static void devices_remove_callback(link_t *item) 78 { 79 free(hash_table_get_instance(item, device_t, link)); 80 } 81 82 static hash_table_operations_t devices_ops = { 83 .hash = devices_hash, 84 .compare = devices_compare, 85 .remove_callback = devices_remove_callback 86 }; 87 49 88 bool devfs_init(void) 50 89 { 90 if (!hash_table_create(&devices, DEVICES_BUCKETS, 91 DEVICES_KEYS, &devices_ops)) 92 return false; 93 51 94 if (devmap_get_phone(DEVMAP_CLIENT, IPC_FLAG_BLOCKING) < 0) 52 95 return false; … … 104 147 } 105 148 106 /* This is a read-only filesystem */ 107 if ((lflag & L_CREATE) || (lflag & L_LINK) || (lflag & L_UNLINK)) { 149 if ((lflag & L_LINK) || (lflag & L_UNLINK)) { 108 150 ipc_answer_0(rid, ENOTSUP); 109 151 return; … … 124 166 } else { 125 167 if (lflag & L_FILE) { 126 count_t len;168 size_t len; 127 169 if (last >= first) 128 170 len = last - first + 1; … … 136 178 } 137 179 138 count_t i;180 size_t i; 139 181 for (i = 0; i < len; i++) 140 182 name[i] = PLB_GET_CHAR(first + i); … … 149 191 } 150 192 193 if (lflag & L_OPEN) { 194 unsigned long key[] = { 195 [DEVICES_KEY_HANDLE] = (unsigned long) handle 196 }; 197 198 link_t *lnk = hash_table_find(&devices, key); 199 if (lnk == NULL) { 200 int phone = devmap_device_connect(handle, 0); 201 if (phone < 0) { 202 free(name); 203 ipc_answer_0(rid, ENOENT); 204 return; 205 } 206 207 device_t *dev = (device_t *) malloc(sizeof(device_t)); 208 if (dev == NULL) { 209 free(name); 210 ipc_answer_0(rid, ENOMEM); 211 return; 212 } 213 214 dev->handle = handle; 215 dev->phone = phone; 216 dev->refcount = 1; 217 218 hash_table_insert(&devices, key, &dev->link); 219 } else { 220 device_t *dev = hash_table_get_instance(lnk, device_t, link); 221 dev->refcount++; 222 } 223 } 224 151 225 free(name); 152 226 … … 157 231 } 158 232 233 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request) 234 { 235 dev_handle_t handle = IPC_GET_ARG2(*request); 236 237 unsigned long key[] = { 238 [DEVICES_KEY_HANDLE] = (unsigned long) handle 239 }; 240 241 link_t *lnk = hash_table_find(&devices, key); 242 if (lnk == NULL) { 243 int phone = devmap_device_connect(handle, 0); 244 if (phone < 0) { 245 ipc_answer_0(rid, ENOENT); 246 return; 247 } 248 249 device_t *dev = (device_t *) malloc(sizeof(device_t)); 250 if (dev == NULL) { 251 ipc_answer_0(rid, ENOMEM); 252 return; 253 } 254 255 dev->handle = handle; 256 dev->phone = phone; 257 dev->refcount = 1; 258 259 hash_table_insert(&devices, key, &dev->link); 260 } else { 261 device_t *dev = hash_table_get_instance(lnk, device_t, link); 262 dev->refcount++; 263 } 264 265 ipc_answer_3(rid, EOK, 0, 1, L_FILE); 266 } 267 268 void devfs_device(ipc_callid_t rid, ipc_call_t *request) 269 { 270 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 271 272 if (index != 0) { 273 unsigned long key[] = { 274 [DEVICES_KEY_HANDLE] = (unsigned long) index 275 }; 276 277 link_t *lnk = hash_table_find(&devices, key); 278 if (lnk == NULL) { 279 ipc_answer_0(rid, ENOENT); 280 return; 281 } 282 283 ipc_answer_1(rid, EOK, (ipcarg_t) index); 284 } else 285 ipc_answer_0(rid, ENOTSUP); 286 } 287 159 288 void devfs_read(ipc_callid_t rid, ipc_call_t *request) 160 289 { … … 163 292 164 293 if (index != 0) { 165 ipc_answer_1(rid, ENOENT, 0); 166 return; 167 } 168 169 /* 170 * Receive the read request. 171 */ 172 ipc_callid_t callid; 173 size_t size; 174 if (!ipc_data_read_receive(&callid, &size)) { 175 ipc_answer_0(callid, EINVAL); 176 ipc_answer_0(rid, EINVAL); 177 return; 178 } 179 180 size_t bytes = 0; 181 if (index != 0) { 182 (void) ipc_data_read_finalize(callid, NULL, bytes); 294 unsigned long key[] = { 295 [DEVICES_KEY_HANDLE] = (unsigned long) index 296 }; 297 298 link_t *lnk = hash_table_find(&devices, key); 299 if (lnk == NULL) { 300 ipc_answer_0(rid, ENOENT); 301 return; 302 } 303 304 device_t *dev = hash_table_get_instance(lnk, device_t, link); 305 306 ipc_callid_t callid; 307 if (!ipc_data_read_receive(&callid, NULL)) { 308 ipc_answer_0(callid, EINVAL); 309 ipc_answer_0(rid, EINVAL); 310 return; 311 } 312 313 /* Make a request at the driver */ 314 ipc_call_t answer; 315 aid_t msg = async_send_3(dev->phone, IPC_GET_METHOD(*request), 316 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 317 IPC_GET_ARG3(*request), &answer); 318 319 /* Forward the IPC_M_DATA_READ request to the driver */ 320 ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 321 322 /* Wait for reply from the driver. */ 323 ipcarg_t rc; 324 async_wait_for(msg, &rc); 325 size_t bytes = IPC_GET_ARG1(answer); 326 327 /* Driver reply is the final result of the whole operation */ 328 ipc_answer_1(rid, rc, bytes); 183 329 } else { 184 count_t count = devmap_device_get_count(); 330 ipc_callid_t callid; 331 size_t size; 332 if (!ipc_data_read_receive(&callid, &size)) { 333 ipc_answer_0(callid, EINVAL); 334 ipc_answer_0(rid, EINVAL); 335 return; 336 } 337 338 size_t count = devmap_device_get_count(); 185 339 dev_desc_t *desc = malloc(count * sizeof(dev_desc_t)); 186 340 if (desc == NULL) { 187 ipc_answer_0(callid, ENO ENT);188 ipc_answer_1(rid, ENO ENT, 0);189 return; 190 } 191 192 count_t max = devmap_device_get_devices(count, desc);341 ipc_answer_0(callid, ENOMEM); 342 ipc_answer_1(rid, ENOMEM, 0); 343 return; 344 } 345 346 size_t max = devmap_device_get_devices(count, desc); 193 347 194 348 if (pos < max) { … … 201 355 202 356 free(desc); 203 bytes = 1; 204 } 205 206 ipc_answer_1(rid, EOK, bytes); 357 358 ipc_answer_1(rid, EOK, 1); 359 } 207 360 } 208 361 … … 212 365 off_t pos = (off_t) IPC_GET_ARG3(*request); 213 366 214 /* 215 * Receive the write request. 216 */ 217 ipc_callid_t callid; 218 size_t size; 219 if (!ipc_data_write_receive(&callid, &size)) { 220 ipc_answer_0(callid, EINVAL); 221 ipc_answer_0(rid, EINVAL); 222 return; 223 } 224 225 // TODO 226 ipc_answer_0(callid, ENOENT); 227 ipc_answer_2(rid, ENOENT, 0, 0); 367 if (index != 0) { 368 unsigned long key[] = { 369 [DEVICES_KEY_HANDLE] = (unsigned long) index 370 }; 371 372 link_t *lnk = hash_table_find(&devices, key); 373 if (lnk == NULL) { 374 ipc_answer_0(rid, ENOENT); 375 return; 376 } 377 378 device_t *dev = hash_table_get_instance(lnk, device_t, link); 379 380 ipc_callid_t callid; 381 if (!ipc_data_write_receive(&callid, NULL)) { 382 ipc_answer_0(callid, EINVAL); 383 ipc_answer_0(rid, EINVAL); 384 return; 385 } 386 387 /* Make a request at the driver */ 388 ipc_call_t answer; 389 aid_t msg = async_send_3(dev->phone, IPC_GET_METHOD(*request), 390 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 391 IPC_GET_ARG3(*request), &answer); 392 393 /* Forward the IPC_M_DATA_WRITE request to the driver */ 394 ipc_forward_fast(callid, dev->phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); 395 396 /* Wait for reply from the driver. */ 397 ipcarg_t rc; 398 async_wait_for(msg, &rc); 399 size_t bytes = IPC_GET_ARG1(answer); 400 401 /* Driver reply is the final result of the whole operation */ 402 ipc_answer_1(rid, rc, bytes); 403 } else { 404 /* Read-only filesystem */ 405 ipc_answer_0(rid, ENOTSUP); 406 } 228 407 } 229 408 … … 231 410 { 232 411 ipc_answer_0(rid, ENOTSUP); 412 } 413 414 void devfs_close(ipc_callid_t rid, ipc_call_t *request) 415 { 416 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 417 418 if (index != 0) { 419 unsigned long key[] = { 420 [DEVICES_KEY_HANDLE] = (unsigned long) index 421 }; 422 423 link_t *lnk = hash_table_find(&devices, key); 424 if (lnk == NULL) { 425 ipc_answer_0(rid, ENOENT); 426 return; 427 } 428 429 device_t *dev = hash_table_get_instance(lnk, device_t, link); 430 dev->refcount--; 431 432 if (dev->refcount == 0) { 433 ipc_hangup(dev->phone); 434 hash_table_remove(&devices, key, DEVICES_KEYS); 435 } 436 437 ipc_answer_0(rid, EOK); 438 } else 439 ipc_answer_0(rid, ENOTSUP); 440 } 441 442 void devfs_sync(ipc_callid_t rid, ipc_call_t *request) 443 { 444 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 445 446 if (index != 0) { 447 unsigned long key[] = { 448 [DEVICES_KEY_HANDLE] = (unsigned long) index 449 }; 450 451 link_t *lnk = hash_table_find(&devices, key); 452 if (lnk == NULL) { 453 ipc_answer_0(rid, ENOENT); 454 return; 455 } 456 457 device_t *dev = hash_table_get_instance(lnk, device_t, link); 458 459 /* Make a request at the driver */ 460 ipc_call_t answer; 461 aid_t msg = async_send_2(dev->phone, IPC_GET_METHOD(*request), 462 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer); 463 464 /* Wait for reply from the driver */ 465 ipcarg_t rc; 466 async_wait_for(msg, &rc); 467 468 /* Driver reply is the final result of the whole operation */ 469 ipc_answer_0(rid, rc); 470 } else 471 ipc_answer_0(rid, ENOTSUP); 233 472 } 234 473 … … 240 479 /** 241 480 * @} 242 */ 481 */ -
uspace/srv/fs/devfs/devfs_ops.h
r05b9912 r17fd1d4 29 29 /** @addtogroup fs 30 30 * @{ 31 */ 31 */ 32 32 33 33 #ifndef DEVFS_DEVFS_OPS_H_ … … 42 42 extern void devfs_mount(ipc_callid_t, ipc_call_t *); 43 43 extern void devfs_lookup(ipc_callid_t, ipc_call_t *); 44 extern void devfs_open_node(ipc_callid_t, ipc_call_t *); 45 extern void devfs_device(ipc_callid_t, ipc_call_t *); 46 extern void devfs_sync(ipc_callid_t, ipc_call_t *); 44 47 extern void devfs_read(ipc_callid_t, ipc_call_t *); 45 48 extern void devfs_write(ipc_callid_t, ipc_call_t *); 46 49 extern void devfs_truncate(ipc_callid_t, ipc_call_t *); 50 extern void devfs_close(ipc_callid_t, ipc_call_t *); 47 51 extern void devfs_destroy(ipc_callid_t, ipc_call_t *); 48 52
Note:
See TracChangeset
for help on using the changeset viewer.