Exemple #1
0
// returns the number of blocks where the write was not successful.
static ssize_t write_test(bdev_t *device)
{
    uint8_t *test_buffer = memalign(DMA_ALIGNMENT, device->block_size);

    for (bnum_t bnum = 0; bnum < device->block_count; bnum++) {
        memset(test_buffer, get_signature(bnum), device->block_size);
        ssize_t err = bio_write_block(device, test_buffer, bnum, 1);
        if (err < 0) {
            free(test_buffer);
            return err;
        }
    }

    size_t num_errors = 0;
    uint8_t expected_pattern[1];
    for (bnum_t bnum = 0; bnum < device->block_count; bnum++) {
        expected_pattern[0] = get_signature(bnum);
        if (!is_valid_block(device, bnum, expected_pattern, sizeof(expected_pattern))) {
            num_errors++;
        }
    }

    free(test_buffer);

    return num_errors;
}
Exemple #2
0
static bool test_erase_block(bdev_t *device, uint32_t block_addr)
{
    bool success = false;
    uint8_t valid_byte[1];

    uint8_t *block_contents = memalign(DMA_ALIGNMENT, device->block_size);
    memset(block_contents, ~(device->erase_byte), device->block_size);

    ssize_t err = bio_write_block(device, block_contents, block_addr, 1);
    if (err != (ssize_t)device->block_size) {
        goto finish;
    }

    valid_byte[0] = ~(device->erase_byte);
    if (!is_valid_block(device, block_addr, valid_byte, 1)) {
        goto finish;
    }

    err = bio_erase(device, block_addr * device->block_size, 1);
    if (err <= 0) {
        goto finish;
    }

    valid_byte[0] = device->erase_byte;
    if (is_valid_block(device, block_addr, valid_byte, 1)) {
        success = true;
    }

finish:
    free(block_contents);
    return success;
}
static ssize_t subdev_write_block(struct bdev *_dev, const void *buf, bnum_t block, uint count)
{
	subdev_t *subdev = (subdev_t *)_dev;

	return bio_write_block(subdev->parent, buf, block + subdev->offset, count);
}
Exemple #4
0
static status_t memory_mapped_test(bdev_t *device)
{
    status_t retcode = NO_ERROR;

    uint8_t *test_buffer = memalign(DMA_ALIGNMENT, device->block_size);
    if (!test_buffer) {
        printf("Could not allocate %zu bytes for a temporary buffer. "
               "Aborting.\n", device->block_size);
        return ERR_NO_MEMORY;
    }

    uint8_t *reference_buffer = memalign(DMA_ALIGNMENT, device->block_size);
    if (!reference_buffer) {
        printf("Could not allocate %zu bytes for a temporary reference "
               "buffer. Aborting.\n", device->block_size);
        free(test_buffer);
        return ERR_NO_MEMORY;
    }

    // Erase the first page of the Device.
    ssize_t err = bio_erase(device, 0, device->block_size);
    if (err < (ssize_t)device->block_size) {
        printf("Expected to erase at least %zu bytes but only erased %ld. "
               "Not continuing to test memory mapped mode.\n",
               device->block_size, err);
        retcode = ERR_IO;
        goto finish;
    }

    // Write a pattern to the first page of the device.
    uint8_t pattern_seed = (uint8_t)(rand() % 256);

    for (size_t i = 0; i < device->block_size; i++) {
        test_buffer[i] = (uint8_t)((pattern_seed + i) % 256);
    }

    err = bio_write_block(device, test_buffer, 0, 1);
    if (err != (ssize_t)device->block_size) {
        printf("Error while writing test pattern to device. Expected to write "
               "%zu bytes but actually wrote %ld. Not continuing to test memory "
               "mapped mode.\n", device->block_size, err);
        retcode = ERR_IO;
        goto finish;
    }

    // Put the device into linear mode if possible.
    uint8_t *devaddr;
    int ioctl_result = bio_ioctl(device, BIO_IOCTL_GET_MEM_MAP, (void *)&devaddr);
    if (ioctl_result == ERR_NOT_SUPPORTED) {
        printf("Device does not support linear mode. Aborting.\n");
        retcode = ERR_NOT_SUPPORTED;
        goto finish;
    } else if (ioctl_result != NO_ERROR) {
        printf("BIO_IOCTL_GET_MEM_MAP returned error %d. Aborting.\n",
               ioctl_result);
        retcode = ioctl_result;
        goto finish;
    }

    uint8_t *testptr = test_buffer;
    for (uint i = 0; i < device->block_size; i++) {
        if (*testptr != *devaddr) {
            printf("Data mismatch at position %d. Expected %d got %d. "
                   "Aborting.\n", i, *testptr, *devaddr);
            goto finish;
        }
        testptr++;
        devaddr++;
    }

    // Put the device back into command mode.
    ioctl_result = bio_ioctl(device, BIO_IOCTL_PUT_MEM_MAP, NULL);
    if (ioctl_result != NO_ERROR) {
        printf("BIO_IOCTL_GET_MEM_MAP returned error %d. Aborting.\n",
               ioctl_result);
        retcode = ioctl_result;
        goto finish;
    }

    // Read the first page into memory using command mode and compare it with
    // what we wrote back earlier.
    err = bio_read_block(device, reference_buffer, 0, 1);
    if (err != (ssize_t)device->block_size) {
        printf("Expected to read %zu bytes, actually read %ld. Aborting.\n",
               device->block_size, err);
        retcode = ERR_IO;
        goto finish;
    }

    uint8_t *expected = test_buffer;
    uint8_t *actual = reference_buffer;
    for (uint i = 0; i < device->block_size; i++) {
        if (*actual != *expected) {
            printf("Data mismatch at position %d. Expected %d got %d. "
                   "Aborting.\n", i, *expected, *actual);
            goto finish;
        }
        expected++;
        actual++;
    }

finish:
    free(test_buffer);
    free(reference_buffer);
    return retcode;
}