1// Copyright 2016 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <fcntl.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <unistd.h>
9#include <string.h>
10
11
12#include <lib/fdio/io.h>
13
14// change this number to change how many bytes are being written/read
15#define TEST_LEN 1024
16
17int write_read_pattern_test(int fd, const char* pattern, uint32_t length, uint32_t offset) {
18    char in[length];
19    uint8_t pattern_len = strlen(pattern);
20    lseek(fd, offset, SEEK_SET);
21
22
23    printf("Copying pattern %s, across %i bytes at offset %i", pattern, length, offset);
24    // repeat this pattern across the buffer
25    for (uint32_t i = 0; i + pattern_len < length; i += pattern_len) {
26        memcpy(in + i, pattern, pattern_len);
27    }
28    memcpy(in + (length - (length % pattern_len)), pattern,
29                 length % pattern_len);
30    // uncomment this to print input buffer
31    // for (int i = 0; i < TEST_LEN; i++) {
32    //     printf("%02x ", ((unsigned char*)in)[i]);
33    //     if (i % 50 == 49) {
34    //         printf("\n");
35    //     }
36    // }
37    printf("\n");
38    int w = write(fd, &in, length);
39    printf("Write completed. Bytes written: 0x%02x\n", w);
40
41    // seek back to start
42    lseek(fd, offset, SEEK_SET);
43    char out[length];
44    int r = read(fd, out, length);
45    printf("Read completed. Bytes read: 0x%02x\n", r);
46    // uncomment this to print output buffer
47    // for (int i = 0; i < TEST_LEN; i++) {
48    //     printf("%02x ", ((unsigned char*)out)[i]);
49    //     if (i % 50 == 49) {
50    //         printf("\n");
51    //     }
52    // }
53    // printf("\n");
54
55    printf("memcmp result: %i\n", memcmp(in, out, length));
56
57    return memcmp(in, out, length);
58}
59
60// writes first block two blocks full of lowercase letters in order, then reads to verify.
61// then writes them full of letters in reverse order and verifies.
62int main(int argc, char** argv) {
63    printf("starting\n");
64    int fd = 0;
65    fd = open("/dev/class/pci/004/00:14:00/xhci_usb/usb_bus/usb-dev-002/usb_mass_storage", O_RDWR);
66    if (fd < 0) {
67        printf("msd_test: cannot open '%d'\n", fd);
68        return -1;
69    }
70
71    const char* abc = "abcdefghijklmnopqrstuvwxyz";
72    int status = write_read_pattern_test(fd, abc, 1024, 0);
73    if (status != 0) {
74        printf("TEST FAILURE: written data and read data do not match\n");
75        return -1;
76    } else {
77        printf("TEST PASSED\n");
78    }
79
80    const char* zyx = "zyxwvutsrqponmlkjihgfedcba";
81    status = write_read_pattern_test(fd, zyx, 512, 1024);
82    if (status != 0) {
83        printf("TEST FAILURE: written data and read data do not match\n");
84    } else {
85        printf("TEST PASSED\n");
86    }
87
88    const char* asdf = "asdf";
89    status = write_read_pattern_test(fd, asdf, 5120, 5120);
90    if (status != 0) {
91        printf("TEST FAILURE: written data and read data do not match\n");
92    } else {
93        printf("TEST PASSED\n");
94    }
95
96    return status;
97
98
99}
100