Revision a9c01830
b/hw/sd.c | ||
---|---|---|
32 | 32 |
#include "hw.h" |
33 | 33 |
#include "block.h" |
34 | 34 |
#include "sd.h" |
35 |
#include "bitmap.h" |
|
35 | 36 |
|
36 | 37 |
//#define DEBUG_SD 1 |
37 | 38 |
|
... | ... | |
81 | 82 |
uint8_t sd_status[64]; |
82 | 83 |
uint32_t vhs; |
83 | 84 |
int wp_switch; |
84 |
int *wp_groups;
|
|
85 |
unsigned long *wp_groups;
|
|
85 | 86 |
uint64_t size; |
86 | 87 |
int blk_len; |
87 | 88 |
uint32_t erase_start; |
... | ... | |
415 | 416 |
if (sd->wp_groups) |
416 | 417 |
g_free(sd->wp_groups); |
417 | 418 |
sd->wp_switch = bdrv ? bdrv_is_read_only(bdrv) : 0; |
418 |
sd->wp_groups = (int *) g_malloc0(sizeof(int) * sect);
|
|
419 |
sd->wp_groups = bitmap_new(sect);
|
|
419 | 420 |
memset(sd->function_group, 0, sizeof(int) * 6); |
420 | 421 |
sd->erase_start = 0; |
421 | 422 |
sd->erase_end = 0; |
... | ... | |
484 | 485 |
sd->erase_end = 0; |
485 | 486 |
sd->csd[14] |= 0x40; |
486 | 487 |
|
487 |
for (i = start; i <= end; i ++)
|
|
488 |
if (sd->wp_groups[i])
|
|
488 |
for (i = start; i <= end; i++) {
|
|
489 |
if (test_bit(i, sd->wp_groups)) {
|
|
489 | 490 |
sd->card_status |= WP_ERASE_SKIP; |
491 |
} |
|
492 |
} |
|
490 | 493 |
} |
491 | 494 |
|
492 | 495 |
static uint32_t sd_wpbits(SDState *sd, uint64_t addr) |
... | ... | |
496 | 499 |
|
497 | 500 |
wpnum = addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT); |
498 | 501 |
|
499 |
for (i = 0; i < 32; i ++, wpnum ++, addr += WPGROUP_SIZE)
|
|
500 |
if (addr < sd->size && sd->wp_groups[wpnum])
|
|
502 |
for (i = 0; i < 32; i++, wpnum++, addr += WPGROUP_SIZE) {
|
|
503 |
if (addr < sd->size && test_bit(wpnum, sd->wp_groups)) {
|
|
501 | 504 |
ret |= (1 << i); |
505 |
} |
|
506 |
} |
|
502 | 507 |
|
503 | 508 |
return ret; |
504 | 509 |
} |
... | ... | |
536 | 541 |
|
537 | 542 |
static inline int sd_wp_addr(SDState *sd, uint32_t addr) |
538 | 543 |
{ |
539 |
return sd->wp_groups[addr >>
|
|
540 |
(HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)];
|
|
544 |
return test_bit(addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT),
|
|
545 |
sd->wp_groups);
|
|
541 | 546 |
} |
542 | 547 |
|
543 | 548 |
static void sd_lock_command(SDState *sd) |
... | ... | |
560 | 565 |
sd->card_status |= LOCK_UNLOCK_FAILED; |
561 | 566 |
return; |
562 | 567 |
} |
563 |
memset(sd->wp_groups, 0, sizeof(int) * (sd->size >>
|
|
564 |
(HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)));
|
|
568 |
bitmap_zero(sd->wp_groups,
|
|
569 |
(sd->size >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)) + 1);
|
|
565 | 570 |
sd->csd[14] &= ~0x10; |
566 | 571 |
sd->card_status &= ~CARD_IS_LOCKED; |
567 | 572 |
sd->pwd_len = 0; |
... | ... | |
1007 | 1012 |
} |
1008 | 1013 |
|
1009 | 1014 |
sd->state = sd_programming_state; |
1010 |
sd->wp_groups[addr >> (HWBLOCK_SHIFT +
|
|
1011 |
SECTOR_SHIFT + WPGROUP_SHIFT)] = 1;
|
|
1015 |
set_bit(addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT),
|
|
1016 |
sd->wp_groups);
|
|
1012 | 1017 |
/* Bzzzzzzztt .... Operation complete. */ |
1013 | 1018 |
sd->state = sd_transfer_state; |
1014 | 1019 |
return sd_r1b; |
... | ... | |
1027 | 1032 |
} |
1028 | 1033 |
|
1029 | 1034 |
sd->state = sd_programming_state; |
1030 |
sd->wp_groups[addr >> (HWBLOCK_SHIFT +
|
|
1031 |
SECTOR_SHIFT + WPGROUP_SHIFT)] = 0;
|
|
1035 |
clear_bit(addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT),
|
|
1036 |
sd->wp_groups);
|
|
1032 | 1037 |
/* Bzzzzzzztt .... Operation complete. */ |
1033 | 1038 |
sd->state = sd_transfer_state; |
1034 | 1039 |
return sd_r1b; |
Also available in: Unified diff