diff options
Diffstat (limited to 'firmware/common')
-rw-r--r-- | firmware/common/disk.c | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/firmware/common/disk.c b/firmware/common/disk.c index 554ee3cd41..267b9f1ebf 100644 --- a/firmware/common/disk.c +++ b/firmware/common/disk.c | |||
@@ -78,18 +78,26 @@ | |||
78 | (((uint16_t)array[pos+0] << 0) | \ | 78 | (((uint16_t)array[pos+0] << 0) | \ |
79 | ((uint16_t)array[pos+1] << 8)) | 79 | ((uint16_t)array[pos+1] << 8)) |
80 | 80 | ||
81 | /* space for 4 partitions on 2 drives */ | ||
82 | static struct partinfo part[NUM_DRIVES*MAX_PARTITIONS_PER_DRIVE]; | 81 | static struct partinfo part[NUM_DRIVES*MAX_PARTITIONS_PER_DRIVE]; |
83 | /* mounted to which drive (-1 if none) */ | 82 | static struct volumeinfo volumes[NUM_VOLUMES]; |
84 | static int vol_drive[NUM_VOLUMES]; | 83 | |
84 | /* check if the entry points to a free volume */ | ||
85 | static bool is_free_volume(const struct volumeinfo *vi) | ||
86 | { | ||
87 | return vi->drive < 0; | ||
88 | } | ||
89 | |||
90 | /* mark a volume entry as free */ | ||
91 | static void mark_free_volume(struct volumeinfo *vi) | ||
92 | { | ||
93 | vi->drive = -1; | ||
94 | } | ||
85 | 95 | ||
86 | static int get_free_volume(void) | 96 | static int get_free_volume(void) |
87 | { | 97 | { |
88 | for (int i = 0; i < NUM_VOLUMES; i++) | 98 | for (int i = 0; i < NUM_VOLUMES; i++) |
89 | { | 99 | if (is_free_volume(&volumes[i])) |
90 | if (vol_drive[i] == -1) /* unassigned? */ | ||
91 | return i; | 100 | return i; |
92 | } | ||
93 | 101 | ||
94 | return -1; /* none found */ | 102 | return -1; /* none found */ |
95 | } | 103 | } |
@@ -320,7 +328,7 @@ int disk_mount(int drive) | |||
320 | fat_get_bytes_per_sector(IF_MV(volume)) / SECTOR_SIZE; | 328 | fat_get_bytes_per_sector(IF_MV(volume)) / SECTOR_SIZE; |
321 | #endif | 329 | #endif |
322 | mounted = 1; | 330 | mounted = 1; |
323 | vol_drive[volume] = drive; /* remember the drive for this volume */ | 331 | volumes[volume].drive = drive; |
324 | volume_onmount_internal(IF_MV(volume)); | 332 | volume_onmount_internal(IF_MV(volume)); |
325 | } | 333 | } |
326 | 334 | ||
@@ -343,7 +351,7 @@ int disk_mount(int drive) | |||
343 | pinfo[i].start *= j; | 351 | pinfo[i].start *= j; |
344 | pinfo[i].size *= j; | 352 | pinfo[i].size *= j; |
345 | mounted++; | 353 | mounted++; |
346 | vol_drive[volume] = drive; /* remember the drive for this volume */ | 354 | volumes[volume].drive = drive; |
347 | disk_sector_multiplier[drive] = j; | 355 | disk_sector_multiplier[drive] = j; |
348 | volume_onmount_internal(IF_MV(volume)); | 356 | volume_onmount_internal(IF_MV(volume)); |
349 | volume = get_free_volume(); /* prepare next entry */ | 357 | volume = get_free_volume(); /* prepare next entry */ |
@@ -354,7 +362,7 @@ int disk_mount(int drive) | |||
354 | if (!fat_mount(IF_MV(volume,) IF_MD(drive,) pinfo[i].start)) | 362 | if (!fat_mount(IF_MV(volume,) IF_MD(drive,) pinfo[i].start)) |
355 | { | 363 | { |
356 | mounted++; | 364 | mounted++; |
357 | vol_drive[volume] = drive; /* remember the drive for this volume */ | 365 | volumes[volume].drive = drive; |
358 | volume_onmount_internal(IF_MV(volume)); | 366 | volume_onmount_internal(IF_MV(volume)); |
359 | volume = get_free_volume(); /* prepare next entry */ | 367 | volume = get_free_volume(); /* prepare next entry */ |
360 | } | 368 | } |
@@ -376,8 +384,9 @@ int disk_mount_all(void) | |||
376 | volume_onunmount_internal(IF_MV(-1)); | 384 | volume_onunmount_internal(IF_MV(-1)); |
377 | fat_init(); | 385 | fat_init(); |
378 | 386 | ||
387 | /* mark all volumes as free */ | ||
379 | for (int i = 0; i < NUM_VOLUMES; i++) | 388 | for (int i = 0; i < NUM_VOLUMES; i++) |
380 | vol_drive[i] = -1; /* mark all as unassigned */ | 389 | mark_free_volume(&volumes[i]); |
381 | 390 | ||
382 | for (int i = 0; i < NUM_DRIVES; i++) | 391 | for (int i = 0; i < NUM_DRIVES; i++) |
383 | { | 392 | { |
@@ -402,13 +411,13 @@ int disk_unmount(int drive) | |||
402 | 411 | ||
403 | for (int i = 0; i < NUM_VOLUMES; i++) | 412 | for (int i = 0; i < NUM_VOLUMES; i++) |
404 | { | 413 | { |
405 | if (vol_drive[i] == drive) | 414 | struct volumeinfo *vi = &volumes[i]; |
406 | { /* force releasing resources */ | 415 | /* unmount any volumes on the drive */ |
407 | vol_drive[i] = -1; /* mark unused */ | 416 | if (vi->drive == drive) |
408 | 417 | { | |
418 | mark_free_volume(vi); /* FIXME: should do this after unmount? */ | ||
409 | volume_onunmount_internal(IF_MV(i)); | 419 | volume_onunmount_internal(IF_MV(i)); |
410 | fat_unmount(IF_MV(i)); | 420 | fat_unmount(IF_MV(i)); |
411 | |||
412 | unmounted++; | 421 | unmounted++; |
413 | } | 422 | } |
414 | } | 423 | } |
@@ -517,20 +526,20 @@ static int volume_properties(int volume, enum volume_info_type infotype) | |||
517 | 526 | ||
518 | if (CHECK_VOL(volume)) | 527 | if (CHECK_VOL(volume)) |
519 | { | 528 | { |
520 | int vd = vol_drive[volume]; | 529 | struct volumeinfo *vi = &volumes[volume]; |
521 | switch (infotype) | 530 | switch (infotype) |
522 | { | 531 | { |
523 | #ifdef HAVE_HOTSWAP | 532 | #ifdef HAVE_HOTSWAP |
524 | case VP_REMOVABLE: | 533 | case VP_REMOVABLE: |
525 | res = storage_removable(vd) ? 1 : 0; | 534 | res = storage_removable(vi->drive) ? 1 : 0; |
526 | break; | 535 | break; |
527 | case VP_PRESENT: | 536 | case VP_PRESENT: |
528 | res = storage_present(vd) ? 1 : 0; | 537 | res = storage_present(vi->drive) ? 1 : 0; |
529 | break; | 538 | break; |
530 | #endif | 539 | #endif |
531 | #if defined(HAVE_MULTIDRIVE) || defined(HAVE_DIRCACHE) | 540 | #if defined(HAVE_MULTIDRIVE) || defined(HAVE_DIRCACHE) |
532 | case VP_DRIVE: | 541 | case VP_DRIVE: |
533 | res = vd; | 542 | res = vi->drive; |
534 | break; | 543 | break; |
535 | #endif | 544 | #endif |
536 | } | 545 | } |