Changeset d5a720cf in mainline
- Timestamp:
- 2008-11-02T19:28:38Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a6d97fb9
- Parents:
- 6132b59
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libblock/libblock.c
r6132b59 rd5a720cf 275 275 276 276 devcon->cache = cache; 277 return EOK;278 }279 280 /** Read data from a block device.281 *282 * @param dev_handle Device handle of the block device.283 * @param bufpos Pointer to the first unread valid offset within the284 * communication buffer.285 * @param buflen Pointer to the number of unread bytes that are ready in286 * the communication buffer.287 * @param pos Device position to be read.288 * @param dst Destination buffer.289 * @param size Size of the destination buffer.290 * @param block_size Block size to be used for the transfer.291 *292 * @return EOK on success or a negative return code on failure.293 */294 int295 block_read(int dev_handle, off_t *bufpos, size_t *buflen, off_t *pos, void *dst,296 size_t size, size_t block_size)297 {298 off_t offset = 0;299 size_t left = size;300 devcon_t *devcon = devcon_search(dev_handle);301 assert(devcon);302 303 while (left > 0) {304 size_t rd;305 306 if (*bufpos + left < *buflen)307 rd = left;308 else309 rd = *buflen - *bufpos;310 311 if (rd > 0) {312 /*313 * Copy the contents of the communication buffer to the314 * destination buffer.315 */316 memcpy(dst + offset, devcon->com_area + *bufpos, rd);317 offset += rd;318 *bufpos += rd;319 *pos += rd;320 left -= rd;321 }322 323 if (*bufpos == *buflen) {324 /* Refill the communication buffer with a new block. */325 ipcarg_t retval;326 int rc = async_req_2_1(devcon->dev_phone, RD_READ_BLOCK,327 *pos / block_size, block_size, &retval);328 if ((rc != EOK) || (retval != EOK))329 return (rc != EOK ? rc : retval);330 331 *bufpos = 0;332 *buflen = block_size;333 }334 }335 336 277 return EOK; 337 278 } … … 437 378 } 438 379 380 /** Release a reference to a block. 381 * 382 * If the last reference is dropped, the block is put on the free list. If the 383 * last reference is dropped and the block is dirty, it is first synced with the 384 * block device. 385 * 386 * @param block Block of which a reference is to be released. 387 */ 439 388 void block_put(block_t *block) 440 389 { 441 390 devcon_t *devcon = devcon_search(block->dev_handle); 391 cache_t *cache; 392 393 assert(devcon); 394 assert(devcon->cache); 395 396 cache = devcon->cache; 397 futex_down(&cache->lock); 398 futex_down(&block->lock); 399 if (!--block->refcnt) { 400 /* 401 * Last reference to the block was dropped, put the block on the 402 * free list. 403 */ 404 list_append(&block->free_link, &cache->free_head); 405 /* Unlock the cache, but not the block. */ 406 futex_up(&cache->lock); 407 if (block->dirty) { 408 /* 409 * The block is dirty and there is no one using it 410 * at the moment, write it back to the device. 411 */ 412 413 /* TODO: block_write() */ 414 block->dirty = false; 415 } 416 } else { 417 futex_up(&cache->lock); 418 } 419 futex_up(&block->lock); 420 } 421 422 /** Read data from a block device. 423 * 424 * @param dev_handle Device handle of the block device. 425 * @param bufpos Pointer to the first unread valid offset within the 426 * communication buffer. 427 * @param buflen Pointer to the number of unread bytes that are ready in 428 * the communication buffer. 429 * @param pos Device position to be read. 430 * @param dst Destination buffer. 431 * @param size Size of the destination buffer. 432 * @param block_size Block size to be used for the transfer. 433 * 434 * @return EOK on success or a negative return code on failure. 435 */ 436 int 437 block_read(int dev_handle, off_t *bufpos, size_t *buflen, off_t *pos, void *dst, 438 size_t size, size_t block_size) 439 { 440 off_t offset = 0; 441 size_t left = size; 442 devcon_t *devcon = devcon_search(dev_handle); 443 assert(devcon); 444 445 while (left > 0) { 446 size_t rd; 447 448 if (*bufpos + left < *buflen) 449 rd = left; 450 else 451 rd = *buflen - *bufpos; 452 453 if (rd > 0) { 454 /* 455 * Copy the contents of the communication buffer to the 456 * destination buffer. 457 */ 458 memcpy(dst + offset, devcon->com_area + *bufpos, rd); 459 offset += rd; 460 *bufpos += rd; 461 *pos += rd; 462 left -= rd; 463 } 464 465 if (*bufpos == *buflen) { 466 /* Refill the communication buffer with a new block. */ 467 ipcarg_t retval; 468 int rc = async_req_2_1(devcon->dev_phone, RD_READ_BLOCK, 469 *pos / block_size, block_size, &retval); 470 if ((rc != EOK) || (retval != EOK)) 471 return (rc != EOK ? rc : retval); 472 473 *bufpos = 0; 474 *buflen = block_size; 475 } 476 } 477 478 return EOK; 442 479 } 443 480
Note:
See TracChangeset
for help on using the changeset viewer.