Rev 9337 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
9325 | Boppan | 1 | #include |
2 | #include |
||
3 | #include |
||
4 | #include |
||
9337 | Boppan | 5 | |
9325 | Boppan | 6 | #include "umka.h" |
7 | #include "trace.h" |
||
8 | #include "vdisk.h" |
||
9 | |||
10 | typedef struct { |
||
11 | FILE *file; |
||
12 | uint32_t sect_size; |
||
13 | uint64_t sect_cnt; |
||
14 | unsigned cache_size; |
||
15 | int adjust_cache_size; |
||
16 | } vdisk_t; |
||
17 | |||
18 | void *vdisk_init(const char *fname, int adjust_cache_size, size_t cache_size) { |
||
19 | FILE *f = fopen(fname, "r+"); |
||
20 | if (!f) { |
||
21 | printf("vdisk: can't open file '%s': %s\n", fname, strerror(errno)); |
||
22 | return NULL; |
||
23 | } |
||
9342 | Boppan | 24 | fseek(f, 0, SEEK_END); |
25 | off_t fsize = ftell(f); |
||
26 | fseek(f, 0, SEEK_SET); |
||
9325 | Boppan | 27 | size_t sect_size = 512; |
28 | if (strstr(fname, "s4096") != NULL || strstr(fname, "s4k") != NULL) { |
||
29 | sect_size = 4096; |
||
30 | } |
||
31 | vdisk_t *vdisk = (vdisk_t*)malloc(sizeof(vdisk_t)); |
||
32 | *vdisk = (vdisk_t){.file = f, |
||
33 | .sect_size = sect_size, |
||
34 | .sect_cnt = (uint64_t)fsize / sect_size, |
||
35 | .cache_size = cache_size, |
||
36 | .adjust_cache_size = adjust_cache_size}; |
||
37 | return vdisk; |
||
38 | } |
||
39 | |||
40 | STDCALL void |
||
41 | vdisk_close(void *userdata) { |
||
42 | COVERAGE_OFF(); |
||
43 | vdisk_t *vdisk = userdata; |
||
44 | fclose(vdisk->file); |
||
45 | free(vdisk); |
||
46 | COVERAGE_ON(); |
||
47 | } |
||
48 | |||
49 | STDCALL int |
||
50 | vdisk_read(void *userdata, void *buffer, off_t startsector, |
||
51 | size_t *numsectors) { |
||
52 | COVERAGE_OFF(); |
||
53 | vdisk_t *vdisk = userdata; |
||
9342 | Boppan | 54 | fseek(vdisk->file, startsector * vdisk->sect_size, SEEK_SET); |
9325 | Boppan | 55 | fread(buffer, *numsectors * vdisk->sect_size, 1, vdisk->file); |
56 | COVERAGE_ON(); |
||
57 | return ERROR_SUCCESS; |
||
58 | } |
||
59 | |||
60 | STDCALL int |
||
61 | vdisk_write(void *userdata, void *buffer, off_t startsector, |
||
62 | size_t *numsectors) { |
||
63 | COVERAGE_OFF(); |
||
64 | vdisk_t *vdisk = userdata; |
||
9342 | Boppan | 65 | fseek(vdisk->file, startsector * vdisk->sect_size, SEEK_SET); |
9325 | Boppan | 66 | fwrite(buffer, *numsectors * vdisk->sect_size, 1, vdisk->file); |
67 | COVERAGE_ON(); |
||
68 | return ERROR_SUCCESS; |
||
69 | } |
||
70 | |||
71 | STDCALL int |
||
72 | vdisk_querymedia(void *userdata, diskmediainfo_t *minfo) { |
||
73 | COVERAGE_OFF(); |
||
74 | vdisk_t *vdisk = userdata; |
||
75 | minfo->flags = 0u; |
||
76 | minfo->sector_size = vdisk->sect_size; |
||
77 | minfo->capacity = vdisk->sect_cnt; |
||
78 | COVERAGE_ON(); |
||
79 | return ERROR_SUCCESS; |
||
80 | } |
||
81 | |||
82 | STDCALL size_t |
||
83 | vdisk_adjust_cache_size(void *userdata, size_t suggested_size) { |
||
84 | vdisk_t *vdisk = userdata; |
||
85 | if (vdisk->adjust_cache_size) { |
||
86 | return vdisk->cache_size; |
||
87 | } else { |
||
88 | return suggested_size; |
||
89 | } |
||
90 | } |
||
91 | |||
92 | diskfunc_t vdisk_functions = { |
||
93 | .strucsize = sizeof(diskfunc_t), |
||
94 | .close = vdisk_close, |
||
95 | .closemedia = NULL, |
||
96 | .querymedia = vdisk_querymedia, |
||
97 | .read = vdisk_read, |
||
98 | .write = vdisk_write, |
||
99 | .flush = NULL, |
||
100 | .adjust_cache_size = vdisk_adjust_cache_size, |
||
101 | }; |