diff options
Diffstat (limited to 'firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c')
-rw-r--r-- | firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c | 96 |
1 files changed, 88 insertions, 8 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c index bbef9d2920..56c7554640 100644 --- a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c +++ b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c | |||
@@ -26,6 +26,35 @@ | |||
26 | #include <nand-target.h> | 26 | #include <nand-target.h> |
27 | #include <ftl-target.h> | 27 | #include <ftl-target.h> |
28 | #include <string.h> | 28 | #include <string.h> |
29 | #include "kernel.h" | ||
30 | #include "panic.h" | ||
31 | |||
32 | |||
33 | |||
34 | //#define FTL_FORCEMOUNT | ||
35 | |||
36 | |||
37 | |||
38 | #ifdef FTL_FORCEMOUNT | ||
39 | #ifndef FTL_READONLY | ||
40 | #define FTL_READONLY | ||
41 | #endif | ||
42 | #endif | ||
43 | |||
44 | |||
45 | #ifdef FTL_READONLY | ||
46 | uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer) | ||
47 | { | ||
48 | (void)sector; | ||
49 | (void)count; | ||
50 | (void)buffer; | ||
51 | return 1; | ||
52 | } | ||
53 | uint32_t ftl_sync(void) | ||
54 | { | ||
55 | return 0; | ||
56 | } | ||
57 | #endif | ||
29 | 58 | ||
30 | 59 | ||
31 | 60 | ||
@@ -371,6 +400,8 @@ uint8_t ftl_erasectr_dirt[8]; | |||
371 | 400 | ||
372 | #endif | 401 | #endif |
373 | 402 | ||
403 | static struct mutex ftl_mtx; | ||
404 | |||
374 | 405 | ||
375 | 406 | ||
376 | /* Finds a device info page for the specified bank and returns its number. | 407 | /* Finds a device info page for the specified bank and returns its number. |
@@ -653,6 +684,7 @@ void ftl_vfl_schedule_block_for_remap(uint32_t bank, uint32_t block) | |||
653 | { | 684 | { |
654 | if (ftl_vfl_check_remap_scheduled(bank, block) == 1) | 685 | if (ftl_vfl_check_remap_scheduled(bank, block) == 1) |
655 | return; | 686 | return; |
687 | panicf("FTL: Scheduling bank %d block %d for remap!", bank, block); | ||
656 | if (ftl_vfl_cxt[bank].scheduledstart == ftl_vfl_cxt[bank].spareused) | 688 | if (ftl_vfl_cxt[bank].scheduledstart == ftl_vfl_cxt[bank].spareused) |
657 | return; | 689 | return; |
658 | ftl_vfl_cxt[bank].remaptable[--ftl_vfl_cxt[bank].scheduledstart] = block; | 690 | ftl_vfl_cxt[bank].remaptable[--ftl_vfl_cxt[bank].scheduledstart] = block; |
@@ -738,6 +770,7 @@ uint32_t ftl_vfl_remap_block(uint32_t bank, uint32_t block) | |||
738 | { | 770 | { |
739 | uint32_t i; | 771 | uint32_t i; |
740 | uint32_t newblock = 0, newidx; | 772 | uint32_t newblock = 0, newidx; |
773 | panicf("FTL: Remapping bank %d block %d!", bank, block); | ||
741 | if (bank >= ftl_banks || block >= (*ftl_nand_type).blocks) return 0; | 774 | if (bank >= ftl_banks || block >= (*ftl_nand_type).blocks) return 0; |
742 | for (i = 0; i < ftl_vfl_cxt[bank].sparecount; i++) | 775 | for (i = 0; i < ftl_vfl_cxt[bank].sparecount; i++) |
743 | if (ftl_vfl_cxt[bank].remaptable[i] == 0) | 776 | if (ftl_vfl_cxt[bank].remaptable[i] == 0) |
@@ -949,7 +982,9 @@ uint32_t ftl_open(void) | |||
949 | else | 982 | else |
950 | { | 983 | { |
951 | /* This will trip if there was an unclean unmount before. */ | 984 | /* This will trip if there was an unclean unmount before. */ |
985 | #ifndef FTL_FORCEMOUNT | ||
952 | break; | 986 | break; |
987 | #endif | ||
953 | } | 988 | } |
954 | } | 989 | } |
955 | 990 | ||
@@ -1030,6 +1065,8 @@ uint32_t ftl_read(uint32_t sector, uint32_t count, void* buffer) | |||
1030 | 1065 | ||
1031 | if (count == 0) return 0; | 1066 | if (count == 0) return 0; |
1032 | 1067 | ||
1068 | mutex_lock(&ftl_mtx); | ||
1069 | |||
1033 | for (i = 0; i < count; i++) | 1070 | for (i = 0; i < count; i++) |
1034 | { | 1071 | { |
1035 | uint32_t block = (sector + i) / ppb; | 1072 | uint32_t block = (sector + i) / ppb; |
@@ -1054,6 +1091,9 @@ uint32_t ftl_read(uint32_t sector, uint32_t count, void* buffer) | |||
1054 | memset(&((uint8_t*)buffer)[i << 11], 0, 0x800); | 1091 | memset(&((uint8_t*)buffer)[i << 11], 0, 0x800); |
1055 | } | 1092 | } |
1056 | } | 1093 | } |
1094 | |||
1095 | mutex_unlock(&ftl_mtx); | ||
1096 | |||
1057 | return error; | 1097 | return error; |
1058 | } | 1098 | } |
1059 | 1099 | ||
@@ -1609,11 +1649,17 @@ uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer) | |||
1609 | 1649 | ||
1610 | if (count == 0) return 0; | 1650 | if (count == 0) return 0; |
1611 | 1651 | ||
1652 | mutex_lock(&ftl_mtx); | ||
1653 | |||
1612 | if (ftl_cxt.clean_flag == 1) | 1654 | if (ftl_cxt.clean_flag == 1) |
1613 | { | 1655 | { |
1614 | for (i = 0; i < 3; i++) | 1656 | for (i = 0; i < 3; i++) |
1615 | { | 1657 | { |
1616 | if (ftl_next_ctrl_pool_page() != 0) return 1; | 1658 | if (ftl_next_ctrl_pool_page() != 0) |
1659 | { | ||
1660 | mutex_unlock(&ftl_mtx); | ||
1661 | return 1; | ||
1662 | } | ||
1617 | memset(ftl_buffer, 0xFF, 0x800); | 1663 | memset(ftl_buffer, 0xFF, 0x800); |
1618 | memset(&ftl_sparebuffer, 0xFF, 0x40); | 1664 | memset(&ftl_sparebuffer, 0xFF, 0x40); |
1619 | ftl_sparebuffer.meta.usn = ftl_cxt.usn; | 1665 | ftl_sparebuffer.meta.usn = ftl_cxt.usn; |
@@ -1622,7 +1668,11 @@ uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer) | |||
1622 | &ftl_sparebuffer) == 0) | 1668 | &ftl_sparebuffer) == 0) |
1623 | break; | 1669 | break; |
1624 | } | 1670 | } |
1625 | if (i == 3) return 1; | 1671 | if (i == 3) |
1672 | { | ||
1673 | mutex_unlock(&ftl_mtx); | ||
1674 | return 1; | ||
1675 | } | ||
1626 | ftl_cxt.clean_flag = 0; | 1676 | ftl_cxt.clean_flag = 0; |
1627 | } | 1677 | } |
1628 | 1678 | ||
@@ -1632,7 +1682,11 @@ uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer) | |||
1632 | uint32_t page = (sector + i) % ppb; | 1682 | uint32_t page = (sector + i) % ppb; |
1633 | 1683 | ||
1634 | struct ftl_log_type* logentry = ftl_allocate_log_entry(block); | 1684 | struct ftl_log_type* logentry = ftl_allocate_log_entry(block); |
1635 | if (logentry == (struct ftl_log_type*)0) return 1; | 1685 | if (logentry == (struct ftl_log_type*)0) |
1686 | { | ||
1687 | mutex_unlock(&ftl_mtx); | ||
1688 | return 1; | ||
1689 | } | ||
1636 | if (page == 0 && count - i >= ppb) | 1690 | if (page == 0 && count - i >= ppb) |
1637 | { | 1691 | { |
1638 | uint32_t vblock = (*logentry).scatteredvblock; | 1692 | uint32_t vblock = (*logentry).scatteredvblock; |
@@ -1641,7 +1695,11 @@ uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer) | |||
1641 | { | 1695 | { |
1642 | ftl_release_pool_block(vblock); | 1696 | ftl_release_pool_block(vblock); |
1643 | vblock = ftl_allocate_pool_block(); | 1697 | vblock = ftl_allocate_pool_block(); |
1644 | if (vblock == 0) return 1; | 1698 | if (vblock == 0) |
1699 | { | ||
1700 | mutex_unlock(&ftl_mtx); | ||
1701 | return 1; | ||
1702 | } | ||
1645 | } | 1703 | } |
1646 | ftl_cxt.nextblockusn++; | 1704 | ftl_cxt.nextblockusn++; |
1647 | for (j = 0; j < ppb; j++) | 1705 | for (j = 0; j < ppb; j++) |
@@ -1665,7 +1723,11 @@ uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer) | |||
1665 | { | 1723 | { |
1666 | ftl_remove_scattered_block(logentry); | 1724 | ftl_remove_scattered_block(logentry); |
1667 | logentry = ftl_allocate_log_entry(block); | 1725 | logentry = ftl_allocate_log_entry(block); |
1668 | if (logentry == (struct ftl_log_type*)0) return 1; | 1726 | if (logentry == (struct ftl_log_type*)0) |
1727 | { | ||
1728 | mutex_unlock(&ftl_mtx); | ||
1729 | return 1; | ||
1730 | } | ||
1669 | } | 1731 | } |
1670 | memset(&ftl_sparebuffer, 0xFF, 0x40); | 1732 | memset(&ftl_sparebuffer, 0xFF, 0x40); |
1671 | ftl_sparebuffer.user.lpn = sector + i; | 1733 | ftl_sparebuffer.user.lpn = sector + i; |
@@ -1699,6 +1761,7 @@ uint32_t ftl_write(uint32_t sector, uint32_t count, const void* buffer) | |||
1699 | ftl_save_erasectr_page(i); | 1761 | ftl_save_erasectr_page(i); |
1700 | } | 1762 | } |
1701 | } | 1763 | } |
1764 | mutex_unlock(&ftl_mtx); | ||
1702 | return 0; | 1765 | return 0; |
1703 | } | 1766 | } |
1704 | #endif | 1767 | #endif |
@@ -1745,6 +1808,7 @@ uint32_t ftl_sync(void) | |||
1745 | which will just do nothing if everything was already clean. */ | 1808 | which will just do nothing if everything was already clean. */ |
1746 | uint32_t ftl_init(void) | 1809 | uint32_t ftl_init(void) |
1747 | { | 1810 | { |
1811 | mutex_init(&ftl_mtx); | ||
1748 | uint32_t i; | 1812 | uint32_t i; |
1749 | uint32_t result = 0; | 1813 | uint32_t result = 0; |
1750 | uint32_t foundsignature, founddevinfo, blockwiped, repaired, skip; | 1814 | uint32_t foundsignature, founddevinfo, blockwiped, repaired, skip; |
@@ -1755,6 +1819,7 @@ uint32_t ftl_init(void) | |||
1755 | ftl_nand_type = nand_get_device_type(0); | 1819 | ftl_nand_type = nand_get_device_type(0); |
1756 | foundsignature = 0; | 1820 | foundsignature = 0; |
1757 | blockwiped = 1; | 1821 | blockwiped = 1; |
1822 | mutex_unlock(&ftl_mtx); | ||
1758 | for (i = 0; i < (*ftl_nand_type).pagesperblock; i++) | 1823 | for (i = 0; i < (*ftl_nand_type).pagesperblock; i++) |
1759 | { | 1824 | { |
1760 | result = nand_read_page(0, i, ftl_buffer, (uint32_t*)0, 1, 1); | 1825 | result = nand_read_page(0, i, ftl_buffer, (uint32_t*)0, 1, 1); |
@@ -1772,10 +1837,23 @@ uint32_t ftl_init(void) | |||
1772 | 1837 | ||
1773 | repaired = 0; | 1838 | repaired = 0; |
1774 | skip = 0; | 1839 | skip = 0; |
1775 | if (founddevinfo == 0) return 1; | 1840 | if (founddevinfo == 0) |
1776 | if (foundsignature != 0 && (result & 0x11F) != 0) return 1; | 1841 | { |
1842 | mutex_unlock(&ftl_mtx); | ||
1843 | return 1; | ||
1844 | } | ||
1845 | if (foundsignature != 0 && (result & 0x11F) != 0) | ||
1846 | { | ||
1847 | mutex_unlock(&ftl_mtx); | ||
1848 | return 1; | ||
1849 | } | ||
1777 | if (ftl_vfl_open() == 0) | 1850 | if (ftl_vfl_open() == 0) |
1778 | if (ftl_open() == 0) return 0; | 1851 | if (ftl_open() == 0) |
1852 | { | ||
1853 | mutex_unlock(&ftl_mtx); | ||
1854 | return 0; | ||
1855 | } | ||
1856 | |||
1779 | 1857 | ||
1780 | /* Something went terribly wrong. We may want to allow the user to erase | 1858 | /* Something went terribly wrong. We may want to allow the user to erase |
1781 | block zero in that condition, to make norboot reinitialize the FTL. | 1859 | block zero in that condition, to make norboot reinitialize the FTL. |
@@ -1785,5 +1863,7 @@ uint32_t ftl_init(void) | |||
1785 | nand_block_erase(0, 0); | 1863 | nand_block_erase(0, 0); |
1786 | */ | 1864 | */ |
1787 | 1865 | ||
1866 | |||
1867 | mutex_unlock(&ftl_mtx); | ||
1788 | return 1; | 1868 | return 1; |
1789 | } | 1869 | } |