static void task_high(rtems_task_argument arg) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_bdbuf_buffer *bd = NULL; sc = rtems_task_suspend(RTEMS_SELF); ASSERT_SC(sc); printk("H: try access: 0\n"); sc = rtems_bdbuf_get(dd, 0, &bd); ASSERT_SC(sc); printk("H: access: 0\n"); printk("H: release: 0\n"); sc = rtems_bdbuf_release(bd); ASSERT_SC(sc); printk("H: release done: 0\n"); printk("*** END OF TEST BLOCK 4 ***\n"); exit(0); }
static void task_low(rtems_task_argument arg) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_bdbuf_buffer *bd = NULL; printk("L: try access: 0\n"); sc = rtems_bdbuf_get(dd, 0, &bd); ASSERT_SC(sc); printk("L: access: 0\n"); rtems_test_assert(bd->group->bds_per_group == 2); printk("L: release: 0\n"); sc = rtems_bdbuf_release(bd); ASSERT_SC(sc); printk("L: release done: 0\n"); rtems_test_endk(); exit(0); }
static rtems_task bdbuf_test3_2_thread3(rtems_task_argument arg) { rtems_status_code rc; rtems_bdbuf_buffer *bd = NULL; WAIT_MAIN_SYNC(3); /* * Step 3: * In thread #3 call get(#N3) */ rc = rtems_bdbuf_get(test_dd, TEST_BLK_NUM_N3, &bd); if (rc != RTEMS_SUCCESSFUL) { TEST_FAILED(); } printk("Thread #3 DEBLOCK\n"); CONTINUE_MAIN(3); rc = rtems_bdbuf_release_modified(bd); if (rc != RTEMS_SUCCESSFUL) { TEST_FAILED(); } THREAD_END(); }
int rtems_rfs_buffer_bdbuf_request (rtems_rfs_file_system* fs, rtems_rfs_buffer_block block, bool read, rtems_rfs_buffer** buffer) { rtems_status_code sc; int rc = 0; if (read) sc = rtems_bdbuf_read (rtems_rfs_fs_device (fs), block, buffer); else sc = rtems_bdbuf_get (rtems_rfs_fs_device (fs), block, buffer); if (sc != RTEMS_SUCCESSFUL) { #if RTEMS_RFS_BUFFER_ERRORS printf ("rtems-rfs: buffer-bdbuf-request: block=%lu: bdbuf-%s: %d: %s\n", block, read ? "read" : "get", sc, rtems_status_text (sc)); #endif rc = EIO; } return rc; }
static rtems_task bdbuf_test3_1_thread2(rtems_task_argument arg) { rtems_status_code rc; rtems_bdbuf_buffer *bd = NULL; WAIT_MAIN_SYNC(2); /* * Step 4: * In thread #2 call read/get(#M) * [We ask for block number #M - there is no such entry in AVL, * and all the lists are empty (ready, lru, modified), as a result * this thread blocks on * rtems_bdbuf_wait(pool, &pool->waiting, &pool->wait_waiters)] */ rc = rtems_bdbuf_get(test_dev, TEST_BLK_NUM_M, &bd); if (rc != RTEMS_SUCCESSFUL) { TEST_FAILED(); } CONTINUE_MAIN(2); /* * Release buffer. */ rc = rtems_bdbuf_release_modified(bd); if (rc != RTEMS_SUCCESSFUL) { TEST_FAILED(); } THREAD_END(); }
static void task_high(rtems_task_argument arg) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_bdbuf_buffer *bd = NULL; change_block_size(); printk("H: try access: 0\n"); sc = rtems_bdbuf_get(dd, 0, &bd); ASSERT_SC(sc); printk("H: access: 0\n"); rtems_test_assert(bd->group->bds_per_group == 1); printk("H: release: 0\n"); sc = rtems_bdbuf_release(bd); ASSERT_SC(sc); printk("H: release done: 0\n"); rtems_task_delete(RTEMS_SELF); }
static void bdbuf_tests_task_0_test_7 (bdbuf_task_control* tc) { rtems_status_code sc; bool passed; int i; rtems_bdbuf_buffer* bd; rtems_chain_control buffers; dev_t device; /* * Set task control's passed to false to handle a timeout. */ tc->passed = false; passed = true; /* * Clear any disk settings. */ bdbuf_clear_disk_driver_watch (tc); bdbuf_set_disk_driver_action (tc, BDBUF_DISK_NOOP); device = rtems_filesystem_make_dev_t (tc->major, tc->minor); /* * Get the blocks 0 -> 4 and hold them. */ rtems_chain_initialize_empty (&buffers); for (i = 0; (i < 5) && passed; i++) { bdbuf_test_printf ("%s: rtems_bdbuf_read[%d]: ", tc->name, i); sc = rtems_bdbuf_get (device, i, &bd); if (!bdbuf_test_print_sc (sc, true)) passed = false; rtems_chain_append (&buffers, &bd->link); } for (i = 0; (i < 5) && passed; i++) { bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[%d]: ", tc->name, i); bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers); passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true); } if (passed) { bdbuf_test_printf ("%s: rtems_bdbuf_syncdev[%d:%d]: ", tc->name, i, rtems_filesystem_dev_major_t (device), rtems_filesystem_dev_minor_t (device)); passed = bdbuf_test_print_sc (rtems_bdbuf_syncdev (device), true); } tc->passed = passed; tc->test = 0; }
static ssize_t rtems_blkdev_imfs_write( rtems_libio_t *iop, const void *buffer, size_t count ) { int rv; rtems_blkdev_imfs_context *ctx = IMFS_generic_get_context_by_iop(iop); rtems_disk_device *dd = &ctx->dd; ssize_t remaining = (ssize_t) count; off_t offset = iop->offset; ssize_t block_size = (ssize_t) rtems_disk_get_block_size(dd); rtems_blkdev_bnum block = (rtems_blkdev_bnum) (offset / block_size); ssize_t block_offset = (ssize_t) (offset % block_size); const char *src = buffer; while (remaining > 0) { rtems_status_code sc; rtems_bdbuf_buffer *bd; if (block_offset == 0 && remaining >= block_size) { sc = rtems_bdbuf_get(dd, block, &bd); } else { sc = rtems_bdbuf_read(dd, block, &bd); } if (sc == RTEMS_SUCCESSFUL) { ssize_t copy = block_size - block_offset; if (copy > remaining) { copy = remaining; } memcpy((char *) bd->buffer + block_offset, src, (size_t) copy); sc = rtems_bdbuf_release_modified(bd); if (sc == RTEMS_SUCCESSFUL) { block_offset = 0; remaining -= copy; src += copy; ++block; } else { remaining = -1; } } else { remaining = -1; } } if (remaining >= 0) { iop->offset += count; rv = (ssize_t) count; } else { errno = EIO; rv = -1; } return rv; }
static rtems_task Init(rtems_task_argument argument) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_bdbuf_buffer *bd = NULL; dev_t dev = 0; printk("\n\n*** TEST BLOCK 3 ***\n"); sc = rtems_disk_io_initialize(); ASSERT_SC(sc); sc = ramdisk_register(BLOCK_SIZE, BLOCK_COUNT, false, "/dev/rda", &dev); ASSERT_SC(sc); dd = rtems_disk_obtain(dev); rtems_test_assert(dd != NULL); sc = rtems_task_create( rtems_build_name(' ', 'L', 'O', 'W'), PRIORITY_LOW, 0, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES, &task_id_low ); ASSERT_SC(sc); sc = rtems_task_start(task_id_low, task_low, 0); ASSERT_SC(sc); sc = rtems_task_create( rtems_build_name('H', 'I', 'G', 'H'), PRIORITY_HIGH, 0, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES, &task_id_high ); ASSERT_SC(sc); sc = rtems_task_start(task_id_high, task_high, 0); ASSERT_SC(sc); sc = rtems_bdbuf_get(dd, 0, &bd); ASSERT_SC(sc); sc = rtems_bdbuf_sync(bd); ASSERT_SC(sc); printk("I: sync done: 0\n"); sync_done = true; sc = rtems_task_suspend(RTEMS_SELF); ASSERT_SC(sc); }
static rtems_bdbuf_buffer *do_get_mod(char task) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_bdbuf_buffer *bd = NULL; printk("%c: try get modified\n", task); sc = rtems_bdbuf_get(dev, 0, &bd); ASSERT_SC(sc); sc = rtems_bdbuf_release_modified(bd); ASSERT_SC(sc); sc = rtems_bdbuf_get(dev, 0, &bd); ASSERT_SC(sc); printk("%c: get modified\n", task); return bd; }
static void task_high(rtems_task_argument arg) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_bdbuf_buffer *bd = NULL; rtems_test_assert(!sync_done); printk("H: try access: A0\n"); sc = rtems_bdbuf_get(dd_a, 0, &bd); ASSERT_SC(sc); rtems_test_assert(sync_done); printk("H: access: A0\n"); printk("H: release: A0\n"); sc = rtems_bdbuf_release(bd); ASSERT_SC(sc); printk("H: release done: A0\n"); printk("H: try access: B0\n"); sc = rtems_bdbuf_get(dd_b, 0, &bd); ASSERT_SC(sc); printk("H: access: B0\n"); /* If we reach this code, we have likely a bug */ printk("H: release: B0\n"); sc = rtems_bdbuf_release(bd); ASSERT_SC(sc); printk("H: release done: B0\n"); rtems_task_delete(RTEMS_SELF); }
static rtems_task bdbuf_test3_1_thread1(rtems_task_argument arg) { rtems_status_code rc; rtems_bdbuf_buffer *bd = NULL; /* * Step 1: * Call rtems_bdbuf_get(#N) to get an empty block db; * [this call will remove a buffer from ready list and insert * it in AVL tree with ACCESS state. * Step 2: * Call release_modified(bd); * [Now we have one entry in modified list and it is still * in AVL tree with MODIFIED state] * Step 3: * Call read(#N) to get the same buffer. * [An entry is found in AVL tree, removed from modified list and * returned with state ACCESS_MODIFIED] */ rc = rtems_bdbuf_get(test_dev, TEST_BLK_NUM_N, &bd); if (rc != RTEMS_SUCCESSFUL) { TEST_FAILED(); } rc = rtems_bdbuf_release_modified(bd); if (rc != RTEMS_SUCCESSFUL) { TEST_FAILED(); } rc = rtems_bdbuf_read(test_dev, TEST_BLK_NUM_N, &bd); if (rc != RTEMS_SUCCESSFUL) { TEST_FAILED(); } CONTINUE_MAIN(1); /* Step 5: * Call rtems_bdbuf_release(#N). * As the result buffer will be used by bdbuf to get * buffer #M for thread #2. */ rc = rtems_bdbuf_release(bd); if (rc != RTEMS_SUCCESSFUL) { TEST_FAILED(); } THREAD_END(); }
int fat_buf_release(fat_fs_info_t *fs_info) { rtems_status_code sc = RTEMS_SUCCESSFUL; uint8_t i; bool sec_of_fat; if (fs_info->c.state == FAT_CACHE_EMPTY) return RC_OK; sec_of_fat = ((fs_info->c.blk_num >= fs_info->vol.fat_loc) && (fs_info->c.blk_num < fs_info->vol.rdir_loc)); if (fs_info->c.modified) { if (sec_of_fat && !fs_info->vol.mirror) memcpy(fs_info->sec_buf, fs_info->c.buf->buffer, fs_info->vol.bps); sc = rtems_bdbuf_release_modified(fs_info->c.buf); if (sc != RTEMS_SUCCESSFUL) rtems_set_errno_and_return_minus_one(EIO); fs_info->c.modified = 0; if (sec_of_fat && !fs_info->vol.mirror) { rtems_bdbuf_buffer *b; for (i = 1; i < fs_info->vol.fats; i++) { sc = rtems_bdbuf_get(fs_info->vol.dd, fs_info->c.blk_num + fs_info->vol.fat_length * i, &b); if ( sc != RTEMS_SUCCESSFUL) rtems_set_errno_and_return_minus_one(ENOMEM); memcpy(b->buffer, fs_info->sec_buf, fs_info->vol.bps); sc = rtems_bdbuf_release_modified(b); if ( sc != RTEMS_SUCCESSFUL) rtems_set_errno_and_return_minus_one(ENOMEM); } } } else { sc = rtems_bdbuf_release(fs_info->c.buf); if (sc != RTEMS_SUCCESSFUL) rtems_set_errno_and_return_minus_one(EIO); } fs_info->c.state = FAT_CACHE_EMPTY; return RC_OK; }
static rtems_bdbuf_buffer *do_get(char task) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_bdbuf_buffer *bd = NULL; printk("%c: try get\n", task); sc = rtems_bdbuf_get(dd, 0, &bd); ASSERT_SC(sc); printk("%c: get\n", task); return bd; }
/* rtems_blkdev_generic_write -- * Generic block device write primitive. Implemented using block device * buffer management primitives. */ rtems_device_driver rtems_blkdev_generic_write( rtems_device_major_number major __attribute__((unused)), rtems_device_minor_number minor __attribute__((unused)), void * arg) { rtems_status_code rc = RTEMS_SUCCESSFUL; rtems_libio_rw_args_t *args = arg; rtems_libio_t *iop = args->iop; rtems_disk_device *dd = iop->data1; uint32_t block_size = dd->block_size; char *buf = args->buffer; uint32_t count = args->count; rtems_blkdev_bnum block = (rtems_blkdev_bnum) (args->offset / block_size); uint32_t blkofs = (uint32_t) (args->offset % block_size); args->bytes_moved = 0; while (count > 0) { rtems_bdbuf_buffer *diskbuf; uint32_t copy; if ((blkofs == 0) && (count >= block_size)) rc = rtems_bdbuf_get(dd, block, &diskbuf); else rc = rtems_bdbuf_read(dd, block, &diskbuf); if (rc != RTEMS_SUCCESSFUL) break; copy = block_size - blkofs; if (copy > count) copy = count; memcpy((char *)diskbuf->buffer + blkofs, buf, copy); args->bytes_moved += copy; rc = rtems_bdbuf_release_modified(diskbuf); if (rc != RTEMS_SUCCESSFUL) break; count -= copy; buf += copy; blkofs = 0; block++; } return rc; }
/** * Get the blocks 0 -> 4 and release them. Task 0 should be holding * each one. */ static void bdbuf_tests_ranged_get_release (bdbuf_task_control* tc, bool wake_master, int lower, int upper) { rtems_status_code sc; bool passed; int i; rtems_bdbuf_buffer* bd; /* * Set task control's passed to false to handle a timeout. */ tc->passed = false; passed = true; for (i = lower; (i < upper) && passed; i++) { dev_t device = rtems_filesystem_make_dev_t (tc->major, tc->minor); bdbuf_test_printf ("%s: rtems_bdbuf_get[%d]: blocking ...\n", tc->name, i); sc = rtems_bdbuf_get (device, i, &bd); bdbuf_test_printf ("%s: rtems_bdbuf_get[%d]: ", tc->name, i); if (!bdbuf_test_print_sc (sc, true)) { passed = false; break; } bdbuf_test_printf ("%s: rtems_bdbuf_release[%d]: ", tc->name, i); sc = rtems_bdbuf_release (bd); if (!bdbuf_test_print_sc (sc, true)) { passed = false; break; } /* * Wake the master to tell it we have finished. */ if (wake_master) bdbuf_send_wait_event (tc->name, "wake master", tc->master); } tc->passed = passed; tc->test = 0; }
static void task_low(rtems_task_argument arg) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_bdbuf_buffer *bd = NULL; printk("L: try access: 0\n"); sc = rtems_bdbuf_get(dd, 0, &bd); ASSERT_SC(sc); printk("L: access: 0\n"); sc = rtems_task_resume(task_id_high); ASSERT_SC(sc); sc = rtems_bdbuf_sync(bd); ASSERT_SC(sc); printk("L: sync done: 0\n"); rtems_test_assert(false); }
static void task_low(rtems_task_argument arg) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_bdbuf_buffer *bd = NULL; rtems_test_assert(!sync_done); printk("L: try access: A0\n"); sc = rtems_bdbuf_get(dd_a, 0, &bd); ASSERT_SC(sc); rtems_test_assert(sync_done); printk("L: access: A0\n"); rtems_test_assert(bd->dd == dd_a); rtems_test_endk(); exit(0); }
static void task_low(rtems_task_argument arg) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_bdbuf_buffer *bd = NULL; rtems_test_assert(!sync_done); printk("L: try access: 0\n"); sc = rtems_bdbuf_get(dd, 0, &bd); ASSERT_SC(sc); rtems_test_assert(sync_done); printk("L: access: 0\n"); rtems_test_assert(bd->block == 0); printk("*** END OF TEST BLOCK 3 ***\n"); exit(0); }
/** * Get the block 0 buffer twice. The first time it is requested it * will be taken from the empty list and returned to the LRU list. * The second time it will be removed from the LRU list. */ static void bdbuf_tests_task_0_test_1 (bdbuf_task_control* tc) { rtems_status_code sc; bool passed; int i; rtems_bdbuf_buffer* bd; /* * Set task control's passed to false to handle a timeout. */ tc->passed = false; passed = true; for (i = 0; (i < 2) && passed; i++) { dev_t device = rtems_filesystem_make_dev_t (tc->major, tc->minor); bdbuf_test_printf ("%s: rtems_bdbuf_get[0]: ", tc->name); sc = rtems_bdbuf_get (device, 0, &bd); if (!bdbuf_test_print_sc (sc, true)) { passed = false; break; } bdbuf_test_printf ("%s: rtems_bdbuf_release[0]: ", tc->name); sc = rtems_bdbuf_release (bd); if (!bdbuf_test_print_sc (sc, true)) { passed = false; break; } } tc->passed = passed; tc->test = 0; }
/** * Get the blocks 0 -> 4 and hold them. Wake the master to tell it was have the * buffers then wait for the master to tell us to release a single buffer. * Task 1 will be block waiting for each buffer. It is a higher priority. */ static void bdbuf_tests_task_0_test_2 (bdbuf_task_control* tc) { rtems_status_code sc; bool passed; int i; rtems_bdbuf_buffer* bd; rtems_chain_control buffers; /* * Set task control's passed to false to handle a timeout. */ tc->passed = false; passed = true; /* * Get the blocks 0 -> 4 and hold them. */ rtems_chain_initialize_empty (&buffers); for (i = 0; (i < 5) && passed; i++) { bdbuf_test_printf ("%s: rtems_bdbuf_get[%d]: ", tc->name, i); sc = rtems_bdbuf_get (tc->dd, i, &bd); if (!bdbuf_test_print_sc (sc, true)) passed = false; rtems_chain_append (&buffers, &bd->link); } /* * Wake the master to tell it we have the buffers. */ bdbuf_send_wait_event (tc->name, "wake master", tc->master); if (passed) { /* * For each buffer we hold wait until the master wakes us * and then return it. Task 2 will block waiting for this * buffer. It is a higher priority task. */ for (i = 0; (i < 5) && passed; i++) { sc = bdbuf_wait (tc->name, BDBUF_SECONDS (5)); if (sc != RTEMS_SUCCESSFUL) { bdbuf_test_printf ("%s: wait failed: ", tc->name); bdbuf_test_print_sc (sc, true); passed = false; break; } else { bdbuf_test_printf ("%s: rtems_bdbuf_release[%d]: unblocks task 1\n", tc->name, i); bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers); sc = rtems_bdbuf_release (bd); bdbuf_test_printf ("%s: rtems_bdbuf_release[%d]: ", tc->name, i); if (!bdbuf_test_print_sc (sc, true)) { passed = false; break; } } } } tc->passed = passed; tc->test = 0; }
static void execute_test(unsigned i) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_bdbuf_buffer *bd = NULL; bool suspend = false; print( 1, "[%05u]T(%c,%c,%s,%c)L(%c,%s,%c)H(%c,%s,%c)\n", i, trig_style_desc [trig], get_type_desc [trig_get], blk_kind_desc [trig_blk], rel_type_desc [trig_rel], get_type_desc [low_get], blk_kind_desc [low_blk], rel_type_desc [low_rel], get_type_desc [high_get], blk_kind_desc [high_blk], rel_type_desc [high_rel] ); set_task_prio(task_id_low, PRIORITY_LOW); finish_low = false; finish_high = false; sc = rtems_task_resume(task_id_low); ASSERT_SC(sc); sc = rtems_task_resume(task_id_high); ASSERT_SC(sc); sc = rtems_bdbuf_get(dd_b, 0, &bd); rtems_test_assert(sc == RTEMS_SUCCESSFUL && bd->dd == dd_b && bd->block == 0); sc = rtems_bdbuf_release(bd); ASSERT_SC(sc); switch (trig) { case SUSP: suspend = true; break; case CONT: suspend = false; break; default: rtems_test_assert(false); break; } print(2, "TG\n"); bd = get(trig_get, trig_blk); if (suspend) { print(2, "S\n"); resume = RESUME_IMMEDIATE; sc = rtems_task_suspend(RTEMS_SELF); ASSERT_SC(sc); } resume = RESUME_FINISH; print(2, "TR\n"); rel(bd, trig_rel); sc = rtems_task_suspend(RTEMS_SELF); ASSERT_SC(sc); print(2, "F\n"); sc = rtems_bdbuf_syncdev(dd_a); ASSERT_SC(sc); sc = rtems_bdbuf_syncdev(dd_b); ASSERT_SC(sc); }
int fat_buf_access(fat_fs_info_t *fs_info, uint32_t blk, int op_type, rtems_bdbuf_buffer **buf) { rtems_status_code sc = RTEMS_SUCCESSFUL; uint8_t i; bool sec_of_fat; if (fs_info->c.state == FAT_CACHE_EMPTY) { if (op_type == FAT_OP_TYPE_READ) sc = rtems_bdbuf_read(fs_info->vol.dd, blk, &fs_info->c.buf); else sc = rtems_bdbuf_get(fs_info->vol.dd, blk, &fs_info->c.buf); if (sc != RTEMS_SUCCESSFUL) rtems_set_errno_and_return_minus_one(EIO); fs_info->c.blk_num = blk; fs_info->c.modified = 0; fs_info->c.state = FAT_CACHE_ACTUAL; } sec_of_fat = ((fs_info->c.blk_num >= fs_info->vol.fat_loc) && (fs_info->c.blk_num < fs_info->vol.rdir_loc)); if (fs_info->c.blk_num != blk) { if (fs_info->c.modified) { if (sec_of_fat && !fs_info->vol.mirror) memcpy(fs_info->sec_buf, fs_info->c.buf->buffer, fs_info->vol.bps); sc = rtems_bdbuf_release_modified(fs_info->c.buf); fs_info->c.state = FAT_CACHE_EMPTY; fs_info->c.modified = 0; if (sc != RTEMS_SUCCESSFUL) rtems_set_errno_and_return_minus_one(EIO); if (sec_of_fat && !fs_info->vol.mirror) { rtems_bdbuf_buffer *b; for (i = 1; i < fs_info->vol.fats; i++) { sc = rtems_bdbuf_get(fs_info->vol.dd, fs_info->c.blk_num + fs_info->vol.fat_length * i, &b); if ( sc != RTEMS_SUCCESSFUL) rtems_set_errno_and_return_minus_one(ENOMEM); memcpy(b->buffer, fs_info->sec_buf, fs_info->vol.bps); sc = rtems_bdbuf_release_modified(b); if ( sc != RTEMS_SUCCESSFUL) rtems_set_errno_and_return_minus_one(ENOMEM); } } } else { sc = rtems_bdbuf_release(fs_info->c.buf); fs_info->c.state = FAT_CACHE_EMPTY; if (sc != RTEMS_SUCCESSFUL) rtems_set_errno_and_return_minus_one(EIO); } if (op_type == FAT_OP_TYPE_READ) sc = rtems_bdbuf_read(fs_info->vol.dd, blk, &fs_info->c.buf); else sc = rtems_bdbuf_get(fs_info->vol.dd, blk, &fs_info->c.buf); if (sc != RTEMS_SUCCESSFUL) rtems_set_errno_and_return_minus_one(EIO); fs_info->c.blk_num = blk; fs_info->c.state = FAT_CACHE_ACTUAL; } *buf = fs_info->c.buf; return RC_OK; }
static rtems_task Init(rtems_task_argument argument) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_task_priority cur_prio = 0; rtems_bdbuf_buffer *bd = NULL; dev_t dev = 0; rtems_test_begink(); sc = rtems_disk_io_initialize(); ASSERT_SC(sc); sc = ramdisk_register(BLOCK_SIZE_A, BLOCK_COUNT, false, "/dev/rda", &dev); ASSERT_SC(sc); dd = rtems_disk_obtain(dev); rtems_test_assert(dd != NULL); sc = rtems_task_create( rtems_build_name(' ', 'L', 'O', 'W'), PRIORITY_LOW, 0, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES, &task_id_low ); ASSERT_SC(sc); sc = rtems_task_start(task_id_low, task_low, 0); ASSERT_SC(sc); sc = rtems_task_create( rtems_build_name(' ', 'M', 'I', 'D'), PRIORITY_MID, 0, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES, &task_id_mid ); ASSERT_SC(sc); sc = rtems_task_start(task_id_mid, task_mid, 0); ASSERT_SC(sc); sc = rtems_task_create( rtems_build_name('H', 'I', 'G', 'H'), PRIORITY_HIGH, 0, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES, &task_id_high ); ASSERT_SC(sc); sc = rtems_task_start(task_id_high, task_high, 0); ASSERT_SC(sc); sc = rtems_task_suspend(task_id_mid); ASSERT_SC(sc); sc = rtems_task_suspend(task_id_high); ASSERT_SC(sc); sc = rtems_bdbuf_get(dd, 1, &bd); ASSERT_SC(sc); sc = rtems_bdbuf_release(bd); ASSERT_SC(sc); printk("I: try access: 0\n"); sc = rtems_bdbuf_get(dd, 0, &bd); ASSERT_SC(sc); printk("I: access: 0\n"); sc = rtems_task_set_priority(RTEMS_SELF, PRIORITY_IDLE, &cur_prio); ASSERT_SC(sc); sc = rtems_task_resume(task_id_high); ASSERT_SC(sc); sc = rtems_task_resume(task_id_mid); ASSERT_SC(sc); sc = rtems_task_set_priority(RTEMS_SELF, PRIORITY_INIT, &cur_prio); ASSERT_SC(sc); printk("I: release: 0\n"); sc = rtems_bdbuf_release(bd); ASSERT_SC(sc); printk("I: release done: 0\n"); rtems_task_delete(RTEMS_SELF); }
static void bdbuf_tests_task_0_test_8 (bdbuf_task_control* tc) { rtems_status_code sc; bool passed; int i; rtems_bdbuf_buffer* bd; rtems_chain_control buffers; rtems_chain_node* node; rtems_chain_node* pnode; /* * Set task control's passed to false to handle a timeout. */ tc->passed = false; passed = true; /* * Clear any disk settings. */ bdbuf_clear_disk_driver_watch (tc); bdbuf_set_disk_driver_action (tc, BDBUF_DISK_NOOP); /* * Get the blocks 0 -> 4 and hold them. */ rtems_chain_initialize_empty (&buffers); for (i = 0; (i < 5) && passed; i++) { bdbuf_test_printf ("%s: rtems_bdbuf_read[%d]: ", tc->name, i); sc = rtems_bdbuf_get (tc->dd, i, &bd); if (!bdbuf_test_print_sc (sc, true)) passed = false; rtems_chain_append (&buffers, &bd->link); } node = rtems_chain_tail (&buffers); node = node->previous; bd = (rtems_bdbuf_buffer*) node; pnode = node->previous; rtems_chain_extract (node); node = pnode; bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[4]: ", tc->name); passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true); bd = (rtems_bdbuf_buffer*) node; pnode = node->previous; rtems_chain_extract (node); node = pnode; bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[3]: ", tc->name); passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true); for (i = 0; (i < 3) && passed; i++) { bdbuf_test_printf ("%s: rtems_bdbuf_release_modified[%d]: ", tc->name, i); bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers); passed = bdbuf_test_print_sc (rtems_bdbuf_release_modified (bd), true); } if (passed) { /* * Check the block order. */ bdbuf_set_disk_driver_action (tc, BDBUF_DISK_BLOCKS_INORDER); bdbuf_test_printf ("%s: rtems_bdbuf_syncdev[%d:%d]: checking order\n", tc->name, i, tc->major, tc->minor); sc = rtems_bdbuf_syncdev (tc->dd); bdbuf_test_printf ("%s: rtems_bdbuf_syncdev[%d:%d]: ", tc->name, i, tc->major, tc->minor); passed = bdbuf_test_print_sc (sc, true); } tc->passed = passed; tc->test = 0; }