Subversion Repositories HelenOS

Rev

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

Rev 4572 Rev 4583
Line 78... Line 78...
78
    off_t bb_off;
78
    off_t bb_off;
79
    size_t bb_size;
79
    size_t bb_size;
80
    cache_t *cache;
80
    cache_t *cache;
81
} devcon_t;
81
} devcon_t;
82
 
82
 
83
static int write_block(devcon_t *devcon, bn_t boff, size_t block_size,
83
static int read_block(devcon_t *devcon, bn_t boff, size_t block_size);
84
    const void *src);
84
static int write_block(devcon_t *devcon, bn_t boff, size_t block_size);
85
 
85
 
86
static devcon_t *devcon_search(dev_handle_t dev_handle)
86
static devcon_t *devcon_search(dev_handle_t dev_handle)
87
{
87
{
88
    link_t *cur;
88
    link_t *cur;
89
 
89
 
Line 209... Line 209...
209
        return EEXIST;
209
        return EEXIST;
210
    bb_buf = malloc(size);
210
    bb_buf = malloc(size);
211
    if (!bb_buf)
211
    if (!bb_buf)
212
        return ENOMEM;
212
        return ENOMEM;
213
   
213
   
214
    off_t bufpos = 0;
-
 
215
    size_t buflen = 0;
-
 
216
    rc = block_read(dev_handle, &bufpos, &buflen, &off,
-
 
217
        bb_buf, size, size);
214
    rc = read_block(devcon, 0, size);
218
    if (rc != EOK) {
215
    if (rc != EOK) {
219
            free(bb_buf);
216
            free(bb_buf);
220
        return rc;
217
        return rc;
221
    }
218
    }
-
 
219
 
-
 
220
    memcpy(bb_buf, devcon->com_area, size);
-
 
221
 
222
    devcon->bb_buf = bb_buf;
222
    devcon->bb_buf = bb_buf;
223
    devcon->bb_off = off;
223
    devcon->bb_off = off;
224
    devcon->bb_size = size;
224
    devcon->bb_size = size;
225
 
225
 
226
    return EOK;
226
    return EOK;
Line 337... Line 337...
337
    } else {
337
    } else {
338
        /*
338
        /*
339
         * The block was not found in the cache.
339
         * The block was not found in the cache.
340
         */
340
         */
341
        int rc;
341
        int rc;
342
        off_t bufpos = 0;
-
 
343
        size_t buflen = 0;
-
 
344
        off_t pos = boff * cache->block_size;
-
 
345
        bool sync = false;
342
        bool sync = false;
346
 
343
 
347
        if (cache_can_grow(cache)) {
344
        if (cache_can_grow(cache)) {
348
            /*
345
            /*
349
             * We can grow the cache by allocating new blocks.
346
             * We can grow the cache by allocating new blocks.
Line 397... Line 394...
397
        if (!(flags & BLOCK_FLAGS_NOREAD)) {
394
        if (!(flags & BLOCK_FLAGS_NOREAD)) {
398
            /*
395
            /*
399
             * The block contains old or no data. We need to read
396
             * The block contains old or no data. We need to read
400
             * the new contents from the device.
397
             * the new contents from the device.
401
             */
398
             */
402
            rc = block_read(dev_handle, &bufpos, &buflen, &pos,
-
 
403
                b->data, cache->block_size, cache->block_size);
399
            rc = read_block(devcon, b->boff, cache->block_size);
404
            assert(rc == EOK);
400
            assert(rc == EOK);
-
 
401
            memcpy(b->data, devcon->com_area, cache->block_size);
405
        }
402
        }
406
 
403
 
407
        fibril_mutex_unlock(&b->lock);
404
        fibril_mutex_unlock(&b->lock);
408
    }
405
    }
409
    return b;
406
    return b;
Line 432... Line 429...
432
         * Last reference to the block was dropped, put the block on the
429
         * Last reference to the block was dropped, put the block on the
433
         * free list.
430
         * free list.
434
         */
431
         */
435
        list_append(&block->free_link, &cache->free_head);
432
        list_append(&block->free_link, &cache->free_head);
436
        if (cache->mode != CACHE_MODE_WB && block->dirty) {
433
        if (cache->mode != CACHE_MODE_WB && block->dirty) {
437
            rc = write_block(devcon, block->boff, block->size,
434
            memcpy(devcon->com_area, block->data, block->size);
438
                block->data);
435
            rc = write_block(devcon, block->boff, block->size);
439
            assert(rc == EOK);
436
            assert(rc == EOK);
440
 
437
 
441
            block->dirty = false;
438
            block->dirty = false;
442
        }
439
        }
443
    }
440
    }
444
    fibril_mutex_unlock(&block->lock);
441
    fibril_mutex_unlock(&block->lock);
445
    fibril_mutex_unlock(&cache->lock);
442
    fibril_mutex_unlock(&cache->lock);
446
}
443
}
447
 
444
 
448
/** Read data from a block device.
445
/** Read sequential data from a block device.
449
 *
446
 *
450
 * @param dev_handle    Device handle of the block device.
447
 * @param dev_handle    Device handle of the block device.
451
 * @param bufpos    Pointer to the first unread valid offset within the
448
 * @param bufpos    Pointer to the first unread valid offset within the
452
 *          communication buffer.
449
 *          communication buffer.
453
 * @param buflen    Pointer to the number of unread bytes that are ready in
450
 * @param buflen    Pointer to the number of unread bytes that are ready in
Line 457... Line 454...
457
 * @param size      Size of the destination buffer.
454
 * @param size      Size of the destination buffer.
458
 * @param block_size    Block size to be used for the transfer.
455
 * @param block_size    Block size to be used for the transfer.
459
 *
456
 *
460
 * @return      EOK on success or a negative return code on failure.
457
 * @return      EOK on success or a negative return code on failure.
461
 */
458
 */
462
int
-
 
463
block_read(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen, off_t *pos,
459
int block_seqread(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen,
464
    void *dst, size_t size, size_t block_size)
460
    off_t *pos, void *dst, size_t size, size_t block_size)
465
{
461
{
466
    off_t offset = 0;
462
    off_t offset = 0;
467
    size_t left = size;
463
    size_t left = size;
468
    devcon_t *devcon = devcon_search(dev_handle);
464
    devcon_t *devcon = devcon_search(dev_handle);
469
    assert(devcon);
465
    assert(devcon);
Line 488... Line 484...
488
            left -= rd;
484
            left -= rd;
489
        }
485
        }
490
       
486
       
491
        if (*bufpos == (off_t) *buflen) {
487
        if (*bufpos == (off_t) *buflen) {
492
            /* Refill the communication buffer with a new block. */
488
            /* Refill the communication buffer with a new block. */
493
            ipcarg_t retval;
489
            int rc;
494
            int rc = async_req_2_1(devcon->dev_phone, BD_READ_BLOCK,
-
 
-
 
490
 
495
                *pos / block_size, block_size, &retval);
491
            rc = read_block(devcon, *pos / block_size, block_size);
496
            if ((rc != EOK) || (retval != EOK))
492
            if (rc != EOK)
497
                return (rc != EOK ? rc : (int) retval);
493
                return rc;
498
           
494
           
499
            *bufpos = 0;
495
            *bufpos = 0;
500
            *buflen = block_size;
496
            *buflen = block_size;
501
        }
497
        }
502
    }
498
    }
503
   
499
   
504
    return EOK;
500
    return EOK;
505
}
501
}
506
 
502
 
-
 
503
/** Read block from block device.
-
 
504
 *
-
 
505
 * @param devcon    Device connection.
-
 
506
 * @param boff      Block index.
-
 
507
 * @param block_size    Block size.
-
 
508
 * @param src       Buffer for storing the data.
-
 
509
 *
-
 
510
 * @return      EOK on success or negative error code on failure.
-
 
511
 */
-
 
512
static int read_block(devcon_t *devcon, bn_t boff, size_t block_size)
-
 
513
{
-
 
514
    ipcarg_t retval;
-
 
515
    int rc;
-
 
516
 
-
 
517
    assert(devcon);
-
 
518
    rc = async_req_2_1(devcon->dev_phone, BD_READ_BLOCK, boff, block_size,
-
 
519
        &retval);
-
 
520
    if ((rc != EOK) || (retval != EOK))
-
 
521
        return (rc != EOK ? rc : (int) retval);
-
 
522
 
-
 
523
    return EOK;
-
 
524
}
-
 
525
 
507
/** Write block to block device.
526
/** Write block to block device.
508
 *
527
 *
509
 * @param devcon    Device connection.
528
 * @param devcon    Device connection.
510
 * @param boff      Block index.
529
 * @param boff      Block index.
511
 * @param block_size    Block size.
530
 * @param block_size    Block size.
512
 * @param src       Buffer containing the data to write.
531
 * @param src       Buffer containing the data to write.
513
 *
532
 *
514
 * @return      EOK on success or negative error code on failure.
533
 * @return      EOK on success or negative error code on failure.
515
 */
534
 */
516
static int write_block(devcon_t *devcon, bn_t boff, size_t block_size,
535
static int write_block(devcon_t *devcon, bn_t boff, size_t block_size)
517
    const void *src)
-
 
518
{
536
{
519
    ipcarg_t retval;
537
    ipcarg_t retval;
520
    int rc;
538
    int rc;
521
 
539
 
522
    assert(devcon);
540
    assert(devcon);
523
    memcpy(devcon->com_area, src, block_size);
-
 
524
   
-
 
525
    rc = async_req_2_1(devcon->dev_phone, BD_WRITE_BLOCK,
541
    rc = async_req_2_1(devcon->dev_phone, BD_WRITE_BLOCK, boff, block_size,
526
        boff, block_size, &retval);
542
        &retval);
527
    if ((rc != EOK) || (retval != EOK))
543
    if ((rc != EOK) || (retval != EOK))
528
        return (rc != EOK ? rc : (int) retval);
544
        return (rc != EOK ? rc : (int) retval);
529
 
545
 
530
    return EOK;
546
    return EOK;
531
}
547
}