static rtems_task Init(rtems_task_argument argument) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_bdbuf_buffer *bd = NULL; dev_t dev = 0; rtems_disk_device *dd = NULL; printk("\n\n*** TEST BLOCK 9 ***\n"); sc = rtems_disk_io_initialize(); ASSERT_SC(sc); sc = disk_register(BLOCK_SIZE, BLOCK_COUNT, &dev); ASSERT_SC(sc); dd = rtems_disk_obtain(dev); assert(dd != NULL); check_read(dd, BLOCK_READ_IO_ERROR, RTEMS_IO_ERROR); check_read(dd, BLOCK_READ_UNSATISFIED, RTEMS_UNSATISFIED); check_read(dd, BLOCK_READ_SUCCESSFUL, RTEMS_SUCCESSFUL); check_read(dd, BLOCK_WRITE_IO_ERROR, RTEMS_SUCCESSFUL); /* Check write IO error */ sc = rtems_bdbuf_read(dd, BLOCK_WRITE_IO_ERROR, &bd); ASSERT_SC(sc); bd->buffer [0] = 1; sc = rtems_bdbuf_sync(bd); ASSERT_SC(sc); sc = rtems_bdbuf_read(dd, BLOCK_WRITE_IO_ERROR, &bd); ASSERT_SC(sc); assert(bd->buffer [0] == 0); sc = rtems_bdbuf_release(bd); ASSERT_SC(sc); /* Check write to deleted disk */ sc = rtems_bdbuf_read(dd, BLOCK_READ_SUCCESSFUL, &bd); ASSERT_SC(sc); sc = rtems_disk_delete(dev); ASSERT_SC(sc); sc = rtems_bdbuf_sync(bd); ASSERT_SC(sc); sc = rtems_disk_release(dd); ASSERT_SC(sc); printk("*** END OF TEST BLOCK 9 ***\n"); exit(0); }
static rtems_task bdbuf_test4_1_thread1(rtems_task_argument arg) { rtems_status_code rc; rtems_bdbuf_buffer *bd = NULL; /* * Step 1: * Call rtems_bdbuf_read(#N) in thread #1; */ rc = rtems_bdbuf_read(test_dd, TEST_BLK_NUM_N, &bd); if (rc != RTEMS_SUCCESSFUL) { TEST_FAILED(); } CONTINUE_MAIN(1); /* * Step 3: * Call rtems_bdbuf_sync(#N) */ rc = rtems_bdbuf_sync(bd); if (rc != RTEMS_SUCCESSFUL) { TEST_FAILED(); } CONTINUE_MAIN(1); THREAD_END(); }
static void bdbuf_tests_task_0_test_6 (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; /* * 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++) { dev_t device = rtems_filesystem_make_dev_t (tc->major, tc->minor); 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 < 4) && 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_sync[%d]: ", tc->name, i); bd = (rtems_bdbuf_buffer*) rtems_chain_get (&buffers); passed = bdbuf_test_print_sc (rtems_bdbuf_sync (bd), true); } tc->passed = passed; tc->test = 0; }
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 void do_sync(char task, rtems_bdbuf_buffer *bd) { rtems_status_code sc = RTEMS_SUCCESSFUL; printk("%c: sync\n", task); sc = rtems_bdbuf_sync(bd); ASSERT_SC(sc); printk("%c: sync done\n", task); }
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 rtems_status_code rtems_bdpart_new_record( rtems_disk_device *dd, rtems_blkdev_bnum index, rtems_bdbuf_buffer **block ) { rtems_status_code sc = RTEMS_SUCCESSFUL; /* Synchronize previous block if necessary */ if (*block != NULL) { sc = rtems_bdbuf_sync( *block); if (sc != RTEMS_SUCCESSFUL) { return sc; } } /* Read the new record block (this accounts for disk block sizes > 512) */ sc = rtems_bdbuf_read( dd, index, block); if (sc != RTEMS_SUCCESSFUL) { return sc; } /* just in case block did not get filled in */ if ( *block == NULL ) { return RTEMS_INVALID_ADDRESS; } /* Clear record */ memset( (*block)->buffer, 0, RTEMS_BDPART_BLOCK_SIZE); /* Write signature */ (*block)->buffer [RTEMS_BDPART_MBR_OFFSET_SIGNATURE_0] = RTEMS_BDPART_MBR_SIGNATURE_0; (*block)->buffer [RTEMS_BDPART_MBR_OFFSET_SIGNATURE_1] = RTEMS_BDPART_MBR_SIGNATURE_1; return RTEMS_SUCCESSFUL; }
rtems_status_code rtems_bdpart_write( const char *disk_name, const rtems_bdpart_format *format, const rtems_bdpart_partition *pt, size_t count ) { rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_status_code esc = RTEMS_SUCCESSFUL; bool dos_compatibility = format != NULL && format->type == RTEMS_BDPART_FORMAT_MBR && format->mbr.dos_compatibility; rtems_bdbuf_buffer *block = NULL; rtems_blkdev_bnum disk_end = 0; rtems_blkdev_bnum record_space = dos_compatibility ? RTEMS_BDPART_MBR_CYLINDER_SIZE : 1; size_t ppc = 0; /* Primary partition count */ size_t i = 0; uint8_t *data = NULL; int fd = -1; rtems_disk_device *dd = NULL; /* Check if we have something to do */ if (count == 0) { /* Nothing to do */ return RTEMS_SUCCESSFUL; } /* Check parameter */ if (format == NULL || pt == NULL) { return RTEMS_INVALID_ADDRESS; } /* Get disk data */ sc = rtems_bdpart_get_disk_data( disk_name, &fd, &dd, &disk_end); if (sc != RTEMS_SUCCESSFUL) { return sc; } /* Align end of disk on cylinder boundary if necessary */ if (dos_compatibility) { disk_end -= (disk_end % record_space); } /* Check that we have a consistent partition table */ for (i = 0; i < count; ++i) { const rtems_bdpart_partition *p = pt + i; /* Check that begin and end are proper within the disk */ if (p->begin >= disk_end || p->end > disk_end) { esc = RTEMS_INVALID_NUMBER; goto cleanup; } /* Check that begin and end are valid */ if (p->begin >= p->end) { esc = RTEMS_INVALID_NUMBER; goto cleanup; } /* Check that partitions do not overlap */ if (i > 0 && pt [i - 1].end > p->begin) { esc = RTEMS_INVALID_NUMBER; goto cleanup; } } /* Check format */ if (format->type != RTEMS_BDPART_FORMAT_MBR) { esc = RTEMS_NOT_IMPLEMENTED; goto cleanup; } /* * Set primary partition count. If we have more than four partitions we need * an extended partition which will contain the partitions of number four and * above as logical partitions. If we have four or less partitions we can * use the primary partition table. */ ppc = count <= 4 ? count : 3; /* * Check that the first primary partition starts at head one and sector one * under the virtual one head and 63 sectors geometry if necessary. */ if (dos_compatibility && pt [0].begin != RTEMS_BDPART_MBR_CYLINDER_SIZE) { esc = RTEMS_INVALID_NUMBER; goto cleanup; } /* * Check that we have enough space for the EBRs. The partitions with number * four and above are logical partitions if we have more than four partitions * in total. The logical partitions are contained in the extended partition. * Each logical partition is described via one EBR preceding the partition. * The space for the EBR and maybe some space which is needed for DOS * compatibility resides between the partitions. So there have to be gaps of * the appropriate size between the partitions. */ for (i = ppc; i < count; ++i) { if ((pt [i].begin - pt [i - 1].end) < record_space) { esc = RTEMS_INVALID_NUMBER; goto cleanup; } } /* Check that we can convert the parition descriptions to the MBR format */ for (i = 0; i < count; ++i) { uint8_t type = 0; const rtems_bdpart_partition *p = pt + i; /* Check type */ if (!rtems_bdpart_to_mbr_partition_type( p->type, &type)) { esc = RTEMS_INVALID_ID; goto cleanup; } /* Check flags */ if (p->flags > 0xffU) { esc = RTEMS_INVALID_ID; goto cleanup; } /* Check ID */ /* TODO */ } /* New MBR */ sc = rtems_bdpart_new_record( dd, 0, &block); if (sc != RTEMS_SUCCESSFUL) { esc = sc; goto cleanup; } /* Write disk ID */ rtems_uint32_to_little_endian( format->mbr.disk_id, block->buffer + RTEMS_BDPART_MBR_OFFSET_DISK_ID ); /* Write primary partition table */ data = block->buffer + RTEMS_BDPART_MBR_OFFSET_TABLE_0; for (i = 0; i < ppc; ++i) { const rtems_bdpart_partition *p = pt + i; /* Write partition entry */ rtems_bdpart_write_mbr_partition( data, p->begin, p->end - p->begin, rtems_bdpart_mbr_partition_type( p->type), (uint8_t) p->flags ); data += RTEMS_BDPART_MBR_TABLE_ENTRY_SIZE; } /* Write extended partition with logical partitions if necessary */ if (ppc != count) { rtems_blkdev_bnum ebr = 0; /* Extended boot record block index */ /* Begin of extended partition */ rtems_blkdev_bnum ep_begin = pt [ppc].begin - record_space; /* Write extended partition */ rtems_bdpart_write_mbr_partition( data, ep_begin, disk_end - ep_begin, RTEMS_BDPART_MBR_EXTENDED, 0 ); /* Write logical partitions */ for (i = ppc; i < count; ++i) { const rtems_bdpart_partition *p = pt + i; /* Write second partition entry */ if (i > ppc) { rtems_blkdev_bnum begin = p->begin - record_space; rtems_bdpart_write_mbr_partition( block->buffer + RTEMS_BDPART_MBR_OFFSET_TABLE_1, begin - ep_begin, disk_end - begin, RTEMS_BDPART_MBR_EXTENDED, 0 ); } /* New EBR */ ebr = p->begin - record_space; sc = rtems_bdpart_new_record( dd, ebr, &block); if (sc != RTEMS_SUCCESSFUL) { esc = sc; goto cleanup; } /* Write first partition entry */ rtems_bdpart_write_mbr_partition( block->buffer + RTEMS_BDPART_MBR_OFFSET_TABLE_0, record_space, p->end - p->begin, rtems_bdpart_mbr_partition_type( p->type), (uint8_t) p->flags ); } } cleanup: if (fd >= 0) { close( fd); } if (block != NULL) { rtems_bdbuf_sync( block); } return esc; }