예제 #1
0
static ssize_t subdev_read_block(struct bdev *_dev, void *buf, bnum_t block, uint count)
{
	subdev_t *subdev = (subdev_t *)_dev;

	return bio_read_block(subdev->parent, buf, block + subdev->offset, count);
}
예제 #2
0
파일: debug.c 프로젝트: 0xBADCA7/lk
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;
}