Subversion Repositories HelenOS

Rev

Rev 3542 | Rev 3544 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3542 Rev 3543
Line 275... Line 275...
275
 
275
 
276
    devcon->cache = cache;
276
    devcon->cache = cache;
277
    return EOK;
277
    return EOK;
278
}
278
}
279
 
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 the
-
 
284
 *          communication buffer.
-
 
285
 * @param buflen    Pointer to the number of unread bytes that are ready in
-
 
286
 *          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
int
-
 
295
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
        else
-
 
309
            rd = *buflen - *bufpos;
-
 
310
       
-
 
311
        if (rd > 0) {
-
 
312
            /*
-
 
313
             * Copy the contents of the communication buffer to the
-
 
314
             * 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
    return EOK;
-
 
337
}
-
 
338
 
-
 
339
static bool cache_can_grow(cache_t *cache)
280
static bool cache_can_grow(cache_t *cache)
340
{
281
{
341
    return true;
282
    return true;
342
}
283
}
343
 
284
 
Line 434... Line 375...
434
 
375
 
435
    futex_up(&cache->lock);
376
    futex_up(&cache->lock);
436
    return b;
377
    return b;
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
void block_put(block_t *block)
388
void block_put(block_t *block)
440
{
389
{
-
 
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);
441
   
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
 
444
/** @}
481
/** @}
445
 */
482
 */