Changeset eb649786 in rtems for cpukit/libblock
- Timestamp:
- 10/08/09 07:07:36 (14 years ago)
- Branches:
- 4.10, 4.11, 5, master
- Children:
- c1fc5d4
- Parents:
- cdf0be6
- Location:
- cpukit/libblock
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
cpukit/libblock/include/rtems/bdbuf.h
rcdf0be6 reb649786 191 191 192 192 dev_t dev; /**< device number */ 193 193 194 rtems_blkdev_bnum block; /**< block number on the device */ 194 195 … … 205 206 volatile uint32_t hold_timer; /**< Timer to indicate how long a buffer 206 207 * has been held in the cache modified. */ 208 209 int references; /**< Allow reference counting by owner. */ 210 void* user; /**< User data. */ 207 211 } rtems_bdbuf_buffer; 208 212 -
cpukit/libblock/src/bdbuf.c
rcdf0be6 reb649786 38 38 #include <errno.h> 39 39 #include <assert.h> 40 41 #if RTEMS_BDBUF_TRACE42 40 #include <stdio.h> 43 #endif44 41 45 42 #include "rtems/bdbuf.h" … … 56 53 typedef struct rtems_bdbuf_swapout_transfer 57 54 { 58 rtems_chain_control bds; /**< The transfer list of BDs. */ 59 dev_t dev; /**< The device the transfer is for. */ 60 rtems_blkdev_request* write_req; /**< The write request array. */ 55 rtems_chain_control bds; /**< The transfer list of BDs. */ 56 dev_t dev; /**< The device the transfer is for. */ 57 rtems_blkdev_request* write_req; /**< The write request array. */ 58 uint32_t bufs_per_bd; /**< Number of buffers per bd. */ 61 59 } rtems_bdbuf_swapout_transfer; 62 60 … … 152 150 #define RTEMS_BLKDEV_FATAL_BDBUF_CACHE_WAIT_2 RTEMS_BLKDEV_FATAL_ERROR(16) 153 151 #define RTEMS_BLKDEV_FATAL_BDBUF_CACHE_WAIT_3 RTEMS_BLKDEV_FATAL_ERROR(17) 154 #define RTEMS_BLKDEV_FATAL_BDBUF_CACHE_WAKE RTEMS_BLKDEV_FATAL_ERROR(18) 155 #define RTEMS_BLKDEV_FATAL_BDBUF_SO_WAKE RTEMS_BLKDEV_FATAL_ERROR(19) 156 #define RTEMS_BLKDEV_FATAL_BDBUF_SO_NOMEM RTEMS_BLKDEV_FATAL_ERROR(20) 157 #define RTEMS_BLKDEV_FATAL_BDBUF_SO_WK_CREATE RTEMS_BLKDEV_FATAL_ERROR(21) 158 #define RTEMS_BLKDEV_FATAL_BDBUF_SO_WK_START RTEMS_BLKDEV_FATAL_ERROR(22) 159 #define BLKDEV_FATAL_BDBUF_SWAPOUT_RE RTEMS_BLKDEV_FATAL_ERROR(23) 160 #define BLKDEV_FATAL_BDBUF_SWAPOUT_TS RTEMS_BLKDEV_FATAL_ERROR(24) 152 #define RTEMS_BLKDEV_FATAL_BDBUF_CACHE_WAIT_TO RTEMS_BLKDEV_FATAL_ERROR(18) 153 #define RTEMS_BLKDEV_FATAL_BDBUF_CACHE_WAKE RTEMS_BLKDEV_FATAL_ERROR(19) 154 #define RTEMS_BLKDEV_FATAL_BDBUF_SO_WAKE RTEMS_BLKDEV_FATAL_ERROR(20) 155 #define RTEMS_BLKDEV_FATAL_BDBUF_SO_NOMEM RTEMS_BLKDEV_FATAL_ERROR(21) 156 #define RTEMS_BLKDEV_FATAL_BDBUF_SO_WK_CREATE RTEMS_BLKDEV_FATAL_ERROR(22) 157 #define RTEMS_BLKDEV_FATAL_BDBUF_SO_WK_START RTEMS_BLKDEV_FATAL_ERROR(23) 158 #define BLKDEV_FATAL_BDBUF_SWAPOUT_RE RTEMS_BLKDEV_FATAL_ERROR(24) 159 #define BLKDEV_FATAL_BDBUF_SWAPOUT_TS RTEMS_BLKDEV_FATAL_ERROR(25) 161 160 162 161 /** … … 194 193 RTEMS_NO_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL) 195 194 195 /** 196 * Waiter timeout. Set to non-zero to find some info on a waiter that is 197 * waiting too long. 198 */ 199 #define RTEMS_BDBUF_WAIT_TIMEOUT RTEMS_NO_TIMEOUT 200 #if !defined (RTEMS_BDBUF_WAIT_TIMEOUT) 201 #define RTEMS_BDBUF_WAIT_TIMEOUT \ 202 (TOD_MICROSECONDS_TO_TICKS (20000000)) 203 #endif 204 196 205 /* 197 206 * The swap out task. … … 204 213 static rtems_bdbuf_cache bdbuf_cache; 205 214 206 /**207 * Print a message to the bdbuf trace output and flush it.208 *209 * @param format The format string. See printf for details.210 * @param ... The arguments for the format text.211 * @return int The number of bytes written to the output.212 */213 215 #if RTEMS_BDBUF_TRACE 216 /** 217 * If true output the trace message. 218 */ 214 219 bool rtems_bdbuf_tracer; 215 static void 216 rtems_bdbuf_printf (const char *format, ...) 217 { 218 va_list args; 219 va_start (args, format); 220 if (rtems_bdbuf_tracer) 221 { 222 fprintf (stdout, "bdbuf:"); 223 vfprintf (stdout, format, args); 224 fflush (stdout); 225 } 226 } 220 221 /** 222 * Return the number of items on the list. 223 * 224 * @param list The chain control. 225 * @return uint32_t The number of items on the list. 226 */ 227 uint32_t 228 rtems_bdbuf_list_count (rtems_chain_control* list) 229 { 230 rtems_chain_node* node = rtems_chain_first (list); 231 uint32_t count = 0; 232 while (!rtems_chain_is_tail (list, node)) 233 { 234 count++; 235 node = rtems_chain_next (node); 236 } 237 return count; 238 } 239 240 /** 241 * Show the usage for the bdbuf cache. 242 */ 243 void 244 rtems_bdbuf_show_usage (void) 245 { 246 uint32_t group; 247 uint32_t total = 0; 248 uint32_t val; 249 for (group = 0; group < bdbuf_cache.group_count; group++) 250 total += bdbuf_cache.groups[group].users; 251 printf ("bdbuf:group users=%lu", total); 252 val = rtems_bdbuf_list_count (&bdbuf_cache.ready); 253 printf (", ready=%lu", val); 254 total = val; 255 val = rtems_bdbuf_list_count (&bdbuf_cache.lru); 256 printf (", lru=%lu", val); 257 total += val; 258 val = rtems_bdbuf_list_count (&bdbuf_cache.modified); 259 printf (", mod=%lu", val); 260 total += val; 261 val = rtems_bdbuf_list_count (&bdbuf_cache.sync); 262 printf (", sync=%lu", val); 263 total += val; 264 printf (", total=%lu\n", total); 265 } 266 267 /** 268 * Show the users for a group of a bd. 269 * 270 * @param where A label to show the context of output. 271 * @param bd The bd to show the users of. 272 */ 273 void 274 rtems_bdbuf_show_users (const char* where, rtems_bdbuf_buffer* bd) 275 { 276 const char* states[] = 277 { "EM", "RA", "CH", "AC", "MD", "AM", "SY", "TR" }; 278 printf ("bdbuf:users: %15s: [%ld (%s)] %ld:%ld = %lu %s\n", 279 where, 280 bd->block, states[bd->state], 281 bd->group - bdbuf_cache.groups, 282 bd - bdbuf_cache.bds, 283 bd->group->users, 284 bd->group->users > 8 ? "<<<<<<<" : ""); 285 } 286 #else 287 #define rtems_bdbuf_tracer (0) 288 #define rtems_bdbuf_show_usage() 289 #define rtems_bdbuf_show_users(_w, _b) 227 290 #endif 228 291 … … 333 396 p = q; 334 397 } 335 398 336 399 q->avl.left = q->avl.right = NULL; 337 400 q->avl.bal = 0; … … 723 786 724 787 /** 788 * Change the block number for the block size to the block number for the media 789 * block size. We have to use 64bit maths. There is no short cut here. 790 * 791 * @param block The logical block number in the block size terms. 792 * @param block_size The block size. 793 * @param media_block_size The block size of the media. 794 * @return rtems_blkdev_bnum The media block number. 795 */ 796 static rtems_blkdev_bnum 797 rtems_bdbuf_media_block (rtems_blkdev_bnum block, 798 size_t block_size, 799 size_t media_block_size) 800 { 801 return (((uint64_t) block) * block_size) / media_block_size; 802 } 803 804 /** 725 805 * Lock the mutex. A single task can nest calls. 726 806 * … … 838 918 rtems_bdbuf_unlock_cache (); 839 919 840 sc = rtems_semaphore_obtain (*sema, RTEMS_WAIT, RTEMS_NO_TIMEOUT); 920 sc = rtems_semaphore_obtain (*sema, RTEMS_WAIT, RTEMS_BDBUF_WAIT_TIMEOUT); 921 922 if (sc == RTEMS_TIMEOUT) 923 rtems_fatal_error_occurred (RTEMS_BLKDEV_FATAL_BDBUF_CACHE_WAIT_TO); 841 924 842 925 if (sc != RTEMS_UNSATISFIED) … … 963 1046 size_t bufs_per_bd; 964 1047 1048 if (rtems_bdbuf_tracer) 1049 printf ("bdbuf:realloc: %lu: %ld -> %ld\n", 1050 group - bdbuf_cache.groups, group->bds_per_group, 1051 new_bds_per_group); 1052 965 1053 bufs_per_bd = bdbuf_cache.max_bds_per_group / group->bds_per_group; 966 1054 … … 969 1057 b++, bd += bufs_per_bd) 970 1058 { 971 if ((bd->state == RTEMS_BDBUF_STATE_MODIFIED) || 972 (bd->state == RTEMS_BDBUF_STATE_ACCESS) || 973 (bd->state == RTEMS_BDBUF_STATE_ACCESS_MODIFIED) || 974 (bd->state == RTEMS_BDBUF_STATE_SYNC) || 975 (bd->state == RTEMS_BDBUF_STATE_TRANSFER)) 976 rtems_fatal_error_occurred ((bd->state << 16) | 977 RTEMS_BLKDEV_FATAL_BDBUF_CONSISTENCY_8); 978 979 if ((bd->state == RTEMS_BDBUF_STATE_CACHED) || 980 (bd->state == RTEMS_BDBUF_STATE_READ_AHEAD)) 981 { 982 if (rtems_bdbuf_avl_remove (&bdbuf_cache.tree, bd) != 0) 1059 switch (bd->state) 1060 { 1061 case RTEMS_BDBUF_STATE_EMPTY: 1062 break; 1063 case RTEMS_BDBUF_STATE_CACHED: 1064 case RTEMS_BDBUF_STATE_READ_AHEAD: 1065 if (rtems_bdbuf_avl_remove (&bdbuf_cache.tree, bd) != 0) 1066 rtems_fatal_error_occurred ((bd->state << 16) | 1067 RTEMS_BLKDEV_FATAL_BDBUF_CONSISTENCY_1); 1068 break; 1069 default: 983 1070 rtems_fatal_error_occurred ((bd->state << 16) | 984 RTEMS_BLKDEV_FATAL_BDBUF_CONSISTENCY_ 1);1071 RTEMS_BLKDEV_FATAL_BDBUF_CONSISTENCY_8); 985 1072 } 986 1073 … … 1015 1102 { 1016 1103 rtems_bdbuf_buffer* bd = (rtems_bdbuf_buffer*) node; 1104 1105 if (rtems_bdbuf_tracer) 1106 printf ("bdbuf:next-bd: %lu (%ld:%ld) %ld -> %ld\n", 1107 bd - bdbuf_cache.bds, 1108 bd->group - bdbuf_cache.groups, bd->group->users, 1109 bd->group->bds_per_group, bds_per_group); 1017 1110 1018 1111 /* … … 1058 1151 rtems_status_code sc; 1059 1152 1060 #if RTEMS_BDBUF_TRACE 1061 rtems_bdbuf_printf ("init\n"); 1062 #endif 1153 if (rtems_bdbuf_tracer) 1154 printf ("bdbuf:init\n"); 1063 1155 1064 1156 /* … … 1168 1260 1169 1261 /* 1262 * Compute the various number of elements in the cache. 1263 */ 1264 bdbuf_cache.buffer_min_count = 1265 bdbuf_config.size / bdbuf_config.buffer_min; 1266 bdbuf_cache.max_bds_per_group = 1267 bdbuf_config.buffer_max / bdbuf_config.buffer_min; 1268 bdbuf_cache.group_count = 1269 bdbuf_cache.buffer_min_count / bdbuf_cache.max_bds_per_group; 1270 1271 /* 1170 1272 * Allocate the memory for the buffer descriptors. 1171 1273 */ 1172 1274 bdbuf_cache.bds = calloc (sizeof (rtems_bdbuf_buffer), 1173 bdbuf_c onfig.size / bdbuf_config.buffer_min);1275 bdbuf_cache.buffer_min_count); 1174 1276 if (!bdbuf_cache.bds) 1175 1277 { … … 1182 1284 return RTEMS_NO_MEMORY; 1183 1285 } 1184 1185 /*1186 * Compute the various number of elements in the cache.1187 */1188 bdbuf_cache.buffer_min_count =1189 bdbuf_config.size / bdbuf_config.buffer_min;1190 bdbuf_cache.max_bds_per_group =1191 bdbuf_config.buffer_max / bdbuf_config.buffer_min;1192 bdbuf_cache.group_count =1193 bdbuf_cache.buffer_min_count / bdbuf_cache.max_bds_per_group;1194 1286 1195 1287 /* … … 1214 1306 * aligned. It is possible to free the memory allocated by rtems_memalign() 1215 1307 * with free(). Return 0 if allocated. 1308 * 1309 * The memory allocate allows a 1216 1310 */ 1217 1311 if (rtems_memalign ((void **) &bdbuf_cache.buffers, … … 1248 1342 bd->waiters = 0; 1249 1343 bd->hold_timer = 0; 1344 bd->references = 0; 1345 bd->user = NULL; 1250 1346 1251 1347 rtems_chain_append (&bdbuf_cache.ready, &bd->link); … … 1445 1541 { 1446 1542 /* 1447 * Remove the buffer from the AVL tree. 1543 * Remove the buffer from the AVL tree if the state says it is in the 1544 * cache or a read ahead buffer. The buffer could be in the empty 1545 * state as a result of reallocations. 1448 1546 */ 1449 if (rtems_bdbuf_avl_remove (&bdbuf_cache.tree, bd) != 0) 1450 rtems_fatal_error_occurred (RTEMS_BLKDEV_FATAL_BDBUF_CONSISTENCY_2); 1547 switch (bd->state) 1548 { 1549 case RTEMS_BDBUF_STATE_CACHED: 1550 case RTEMS_BDBUF_STATE_READ_AHEAD: 1551 if (rtems_bdbuf_avl_remove (&bdbuf_cache.tree, bd) != 0) 1552 rtems_fatal_error_occurred (RTEMS_BLKDEV_FATAL_BDBUF_CONSISTENCY_2); 1553 break; 1554 default: 1555 break; 1556 } 1451 1557 } 1452 1558 else … … 1523 1629 if (bd->group->bds_per_group != bds_per_group) 1524 1630 { 1631 /* 1632 * Remove the buffer from the AVL tree. 1633 */ 1634 if (rtems_bdbuf_avl_remove (&bdbuf_cache.tree, bd) != 0) 1635 rtems_fatal_error_occurred (RTEMS_BLKDEV_FATAL_BDBUF_CONSISTENCY_2); 1525 1636 bd->state = RTEMS_BDBUF_STATE_EMPTY; 1526 1637 rtems_chain_extract (&bd->link); … … 1534 1645 /* 1535 1646 * If the buffer is for read ahead and it exists in the AVL cache or is being 1536 * accessed or being transfered then return NULL. 1647 * accessed or being transfered then return NULL stopping further read ahead 1648 * requests. 1537 1649 */ 1538 1650 if (read_ahead) … … 1557 1669 case RTEMS_BDBUF_STATE_ACCESS_MODIFIED: 1558 1670 bd->waiters++; 1559 rtems_bdbuf_wait (&bdbuf_cache.access, 1560 &bdbuf_cache.access_waiters); 1671 rtems_bdbuf_wait (&bdbuf_cache.access, &bdbuf_cache.access_waiters); 1561 1672 bd->waiters--; 1562 1673 break; … … 1565 1676 case RTEMS_BDBUF_STATE_TRANSFER: 1566 1677 bd->waiters++; 1567 rtems_bdbuf_wait (&bdbuf_cache.transfer, 1568 &bdbuf_cache.transfer_waiters); 1678 rtems_bdbuf_wait (&bdbuf_cache.transfer, &bdbuf_cache.transfer_waiters); 1569 1679 bd->waiters--; 1570 1680 break; … … 1590 1700 rtems_disk_device* dd; 1591 1701 rtems_bdbuf_buffer* bd; 1702 rtems_blkdev_bnum media_block; 1592 1703 size_t bds_per_group; 1593 1704 … … 1602 1713 return RTEMS_INVALID_ID; 1603 1714 1604 if (block >= dd->size) 1605 { 1606 rtems_disk_release (dd); 1607 return RTEMS_INVALID_ADDRESS; 1715 /* 1716 * Compute the media block number. Drivers work with media block number not 1717 * the block number a BD may have as this depends on the block size set by 1718 * the user. 1719 */ 1720 media_block = rtems_bdbuf_media_block (block, 1721 dd->block_size, 1722 dd->media_block_size); 1723 if (media_block >= dd->size) 1724 { 1725 rtems_disk_release(dd); 1726 return RTEMS_INVALID_NUMBER; 1608 1727 } 1609 1728 … … 1614 1733 return RTEMS_INVALID_NUMBER; 1615 1734 } 1616 1735 1736 media_block += dd->start; 1737 1617 1738 rtems_bdbuf_lock_cache (); 1618 1739 1619 #if RTEMS_BDBUF_TRACE 1620 /* Print the block index relative to the physical disk */ 1621 rtems_bdbuf_printf ("get: %d (dev = %08x)\n", block + dd->start, device); 1622 #endif 1623 1624 bd = rtems_bdbuf_get_buffer (dd, bds_per_group, block + dd->start, false); 1625 1740 /* 1741 * Print the block index relative to the physical disk. 1742 */ 1743 if (rtems_bdbuf_tracer) 1744 printf ("bdbuf:get: %lu (%lu) (dev = %08x)\n", 1745 media_block, block, (unsigned int) device); 1746 1747 bd = rtems_bdbuf_get_buffer (dd, bds_per_group, media_block, false); 1748 1749 /* 1750 * This could be considered a bug in the caller because you should not be 1751 * getting an already modified buffer but user may have modified a byte in a 1752 * block then decided to seek the start and write the whole block and the 1753 * file system will have no record of this so just gets the block to fill. 1754 */ 1626 1755 if (bd->state == RTEMS_BDBUF_STATE_MODIFIED) 1627 1756 bd->state = RTEMS_BDBUF_STATE_ACCESS_MODIFIED; 1628 1757 else 1758 { 1629 1759 bd->state = RTEMS_BDBUF_STATE_ACCESS; 1630 1631 /* 1632 * Indicate a buffer in this group is being used. 1633 */ 1634 bd->group->users++; 1635 1760 /* 1761 * Indicate a buffer in this group is being used. 1762 */ 1763 bd->group->users++; 1764 } 1765 1766 if (rtems_bdbuf_tracer) 1767 { 1768 rtems_bdbuf_show_users ("get", bd); 1769 rtems_bdbuf_show_usage (); 1770 } 1771 1636 1772 rtems_bdbuf_unlock_cache (); 1637 1773 … … 1674 1810 rtems_blkdev_request* req; 1675 1811 size_t bds_per_group; 1812 rtems_blkdev_bnum media_block; 1813 rtems_blkdev_bnum media_block_count; 1676 1814 1677 1815 if (!bdbuf_cache.initialised) … … 1694 1832 return RTEMS_INVALID_ID; 1695 1833 1696 if (block >= dd->size) { 1834 /* 1835 * Compute the media block number. Drivers work with media block number not 1836 * the block number a BD may have as this depends on the block size set by 1837 * the user. 1838 */ 1839 media_block = rtems_bdbuf_media_block (block, 1840 dd->block_size, 1841 dd->media_block_size); 1842 if (media_block >= dd->size) 1843 { 1697 1844 rtems_disk_release(dd); 1698 1845 return RTEMS_INVALID_NUMBER; … … 1706 1853 } 1707 1854 1708 #if RTEMS_BDBUF_TRACE 1709 /* Print the block index relative to the physical disk */ 1710 rtems_bdbuf_printf ("read: %d (dev = %08x)\n", block + dd->start, device); 1711 #endif 1712 1713 req->bufnum = 0; 1855 /* 1856 * Print the block index relative to the physical disk and the user block 1857 * number 1858 */ 1859 if (rtems_bdbuf_tracer) 1860 printf ("bdbuf:read: %lu (%lu) (dev = %08x)\n", 1861 media_block + dd->start, block, (unsigned int) device); 1714 1862 1715 1863 /* … … 1720 1868 * Limit the blocks read by the size of the disk. 1721 1869 */ 1722 if ((rtems_bdbuf_configuration.max_read_ahead_blocks + block) < dd->size)1870 if ((rtems_bdbuf_configuration.max_read_ahead_blocks + media_block) < dd->size) 1723 1871 read_ahead_count = rtems_bdbuf_configuration.max_read_ahead_blocks; 1724 1872 else 1725 read_ahead_count = dd->size - block; 1873 read_ahead_count = dd->size - media_block; 1874 1875 media_block_count = dd->block_size / dd->media_block_size; 1876 1877 req->bufnum = 0; 1726 1878 1727 1879 rtems_bdbuf_lock_cache (); … … 1737 1889 * caller. 1738 1890 */ 1739 bd = rtems_bdbuf_get_buffer (dd, bds_per_group, 1740 block + dd->start + req->bufnum, 1891 bd = rtems_bdbuf_get_buffer (dd, bds_per_group, media_block + dd->start, 1741 1892 req->bufnum == 0 ? false : true); 1742 1893 … … 1762 1913 */ 1763 1914 bd->group->users++; 1915 1916 if (rtems_bdbuf_tracer) 1917 rtems_bdbuf_show_users ("reading", bd); 1764 1918 1765 1919 /* … … 1772 1926 */ 1773 1927 req->bufs[req->bufnum].user = bd; 1774 req->bufs[req->bufnum].block = bd->block;1928 req->bufs[req->bufnum].block = media_block + dd->start; 1775 1929 req->bufs[req->bufnum].length = dd->block_size; 1776 1930 req->bufs[req->bufnum].buffer = bd->buffer; 1777 1931 req->bufnum++; 1932 1933 /* 1934 * Move the media block count by the number of media blocks in the 1935 * disk device's set block size. 1936 */ 1937 media_block += media_block_count; 1778 1938 } 1779 1939 … … 1798 1958 int result; 1799 1959 uint32_t b; 1960 bool wake_transfer; 1800 1961 1801 1962 /* … … 1838 1999 } 1839 2000 2001 wake_transfer = false; 2002 1840 2003 rtems_bdbuf_lock_cache (); 1841 2004 … … 1843 2006 { 1844 2007 bd = req->bufs[b].user; 1845 bd->error = req->error; 2008 if (!bd->error) 2009 bd->error = req->error; 1846 2010 bd->state = RTEMS_BDBUF_STATE_READ_AHEAD; 1847 2011 bd->group->users--; 2012 2013 if (rtems_bdbuf_tracer) 2014 rtems_bdbuf_show_users ("read-ahead", bd); 2015 1848 2016 rtems_chain_prepend (&bdbuf_cache.ready, &bd->link); 1849 2017 1850 2018 /* 1851 * If there is an error remove the BD from the AVL tree as it does is1852 * invalid, then wake any threads that may be waiting. A thread may have1853 * beenwaiting for this block and assumed it was in the tree.2019 * If there is an error remove the BD from the AVL tree as it is invalid, 2020 * then wake any threads that may be waiting. A thread may have been 2021 * waiting for this block and assumed it was in the tree. 1854 2022 */ 1855 2023 if (bd->error) … … 1861 2029 1862 2030 if (bd->waiters) 1863 rtems_bdbuf_wake (bdbuf_cache.access, &bdbuf_cache.access_waiters);1864 else1865 { 1866 if (rtems_chain_has_only_one_node (&bdbuf_cache.ready))1867 rtems_bdbuf_wake (bdbuf_cache.waiting, &bdbuf_cache.wait_waiters);1868 }1869 }1870 2031 wake_transfer = true; 2032 } 2033 2034 if (wake_transfer) 2035 rtems_bdbuf_wake (bdbuf_cache.transfer, &bdbuf_cache.transfer_waiters); 2036 else 2037 rtems_bdbuf_wake (bdbuf_cache.waiting, &bdbuf_cache.wait_waiters); 2038 1871 2039 bd = req->bufs[0].user; 1872 2040 1873 2041 /* 1874 * One less user. We do this here then increment again so the case of the 1875 * buffer in the the cache and no read leaves the user counts at the 1876 * correct level. 2042 * One less user for the BD we return. The loop above is only for the read 2043 * head buffers. We do this here then increment again so the case of the 2044 * buffer in the cache or modified and no read leaves the user counts at 2045 * the correct level. 1877 2046 */ 1878 2047 bd->group->users--; 2048 2049 if (rtems_bdbuf_tracer) 2050 rtems_bdbuf_show_users ("read-done", bd); 1879 2051 } 1880 2052 … … 1893 2065 } 1894 2066 2067 if (rtems_bdbuf_tracer) 2068 { 2069 rtems_bdbuf_show_users ("read", bd); 2070 rtems_bdbuf_show_usage (); 2071 } 2072 1895 2073 rtems_bdbuf_unlock_cache (); 1896 2074 rtems_disk_release (dd); … … 1912 2090 rtems_bdbuf_lock_cache (); 1913 2091 1914 #if RTEMS_BDBUF_TRACE 1915 rtems_bdbuf_printf ("release: %d\n", bd->block); 1916 #endif 2092 if (rtems_bdbuf_tracer) 2093 printf ("bdbuf:release: %lu\n", bd->block); 1917 2094 1918 2095 if (bd->state == RTEMS_BDBUF_STATE_ACCESS_MODIFIED) … … 1922 2099 else 1923 2100 { 1924 /* 1925 * If this is a read ahead buffer place the ready queue. Buffers are taken 1926 * from here first. If we prepend then get from the queue the buffers 1927 * furthermost from the read buffer will be used. 1928 */ 1929 if (bd->state == RTEMS_BDBUF_STATE_READ_AHEAD) 1930 rtems_chain_prepend (&bdbuf_cache.ready, &bd->link); 1931 else 1932 { 1933 bd->state = RTEMS_BDBUF_STATE_CACHED; 1934 rtems_chain_append (&bdbuf_cache.lru, &bd->link); 1935 } 2101 bd->state = RTEMS_BDBUF_STATE_CACHED; 2102 rtems_chain_append (&bdbuf_cache.lru, &bd->link); 1936 2103 1937 2104 /* … … 1941 2108 } 1942 2109 2110 if (rtems_bdbuf_tracer) 2111 rtems_bdbuf_show_users ("release", bd); 2112 1943 2113 /* 1944 2114 * If there are threads waiting to access the buffer wake them. Wake any 1945 * waiters if this is the first buffer to placed back onto thequeue.2115 * waiters if this buffer is placed back onto the LRU queue. 1946 2116 */ 1947 2117 if (bd->waiters) 1948 2118 rtems_bdbuf_wake (bdbuf_cache.access, &bdbuf_cache.access_waiters); 1949 2119 else 1950 { 1951 if (bd->state == RTEMS_BDBUF_STATE_READ_AHEAD) 1952 { 1953 if (rtems_chain_has_only_one_node (&bdbuf_cache.ready)) 1954 rtems_bdbuf_wake (bdbuf_cache.waiting, &bdbuf_cache.wait_waiters); 1955 } 1956 else 1957 { 1958 if (rtems_chain_has_only_one_node (&bdbuf_cache.lru)) 1959 rtems_bdbuf_wake (bdbuf_cache.waiting, &bdbuf_cache.wait_waiters); 1960 } 1961 } 2120 rtems_bdbuf_wake (bdbuf_cache.waiting, &bdbuf_cache.wait_waiters); 2121 2122 if (rtems_bdbuf_tracer) 2123 rtems_bdbuf_show_usage (); 1962 2124 1963 2125 rtems_bdbuf_unlock_cache (); … … 1977 2139 rtems_bdbuf_lock_cache (); 1978 2140 1979 #if RTEMS_BDBUF_TRACE 1980 rtems_bdbuf_printf ("release modified: %d\n", bd->block); 1981 #endif 2141 if (rtems_bdbuf_tracer) 2142 printf ("bdbuf:release modified: %lu\n", bd->block); 1982 2143 1983 2144 bd->hold_timer = rtems_bdbuf_configuration.swap_block_hold; 2145 2146 if (rtems_bdbuf_tracer) 2147 rtems_bdbuf_show_users ("release-modified", bd); 1984 2148 1985 2149 rtems_bdbuf_append_modified (bd); … … 1988 2152 rtems_bdbuf_wake (bdbuf_cache.access, &bdbuf_cache.access_waiters); 1989 2153 2154 if (rtems_bdbuf_tracer) 2155 rtems_bdbuf_show_usage (); 2156 1990 2157 rtems_bdbuf_unlock_cache (); 1991 2158 … … 1998 2165 bool available; 1999 2166 2000 #if RTEMS_BDBUF_TRACE 2001 rtems_bdbuf_printf ("sync: %d\n", bd->block); 2002 #endif 2167 if (rtems_bdbuf_tracer) 2168 printf ("bdbuf:sync: %lu\n", bd->block); 2003 2169 2004 2170 if (!bdbuf_cache.initialised) … … 2032 2198 case RTEMS_BDBUF_STATE_TRANSFER: 2033 2199 bd->waiters++; 2034 rtems_bdbuf_wait (&bdbuf_cache.transfer, 2035 &bdbuf_cache.transfer_waiters); 2200 rtems_bdbuf_wait (&bdbuf_cache.transfer, &bdbuf_cache.transfer_waiters); 2036 2201 bd->waiters--; 2037 2202 break; … … 2054 2219 rtems_event_set out; 2055 2220 2056 #if RTEMS_BDBUF_TRACE 2057 rtems_bdbuf_printf ("syncdev: %08x\n", dev); 2058 #endif 2221 if (rtems_bdbuf_tracer) 2222 printf ("bdbuf:syncdev: %08x\n", (unsigned int) dev); 2059 2223 2060 2224 if (!bdbuf_cache.initialised) … … 2106 2270 /** 2107 2271 * Call back handler called by the low level driver when the transfer has 2108 * completed. This function may be invoked from interrupt handler .2272 * completed. This function may be invoked from interrupt handlers. 2109 2273 * 2110 2274 * @param arg Arbitrary argument specified in block device request … … 2135 2299 rtems_bdbuf_swapout_write (rtems_bdbuf_swapout_transfer* transfer) 2136 2300 { 2137 rtems_disk_device* dd; 2138 2139 #if RTEMS_BDBUF_TRACE 2140 rtems_bdbuf_printf ("swapout transfer: %08x\n", transfer->dev); 2141 #endif 2301 rtems_disk_device* dd; 2302 2303 if (rtems_bdbuf_tracer) 2304 printf ("bdbuf:swapout transfer: %08x\n", (unsigned int) transfer->dev); 2142 2305 2143 2306 /* … … 2158 2321 */ 2159 2322 uint32_t last_block = 0; 2323 2324 /* 2325 * Number of buffers per bd. This is used to detect the next 2326 * block. 2327 */ 2328 uint32_t bufs_per_bd = dd->block_size / bdbuf_config.buffer_min; 2160 2329 2161 2330 /* … … 2186 2355 */ 2187 2356 2188 #if RTEMS_BDBUF_TRACE 2189 rtems_bdbuf_printf ("swapout write: bd:%d, bufnum:%d mode:%s\n", 2190 bd->block, transfer->write_req->bufnum, 2191 dd->phys_dev->capabilities & 2192 RTEMS_BLKDEV_CAP_MULTISECTOR_CONT ? "MULIT" : "SCAT"); 2193 #endif 2194 2357 if (rtems_bdbuf_tracer) 2358 printf ("bdbuf:swapout write: bd:%lu, bufnum:%lu mode:%s\n", 2359 bd->block, transfer->write_req->bufnum, 2360 dd->phys_dev->capabilities & 2361 RTEMS_BLKDEV_CAP_MULTISECTOR_CONT ? "MULIT" : "SCAT"); 2362 2195 2363 if ((dd->phys_dev->capabilities & RTEMS_BLKDEV_CAP_MULTISECTOR_CONT) && 2196 2364 transfer->write_req->bufnum && 2197 (bd->block != (last_block + 1)))2365 (bd->block != (last_block + bufs_per_bd))) 2198 2366 { 2199 2367 rtems_chain_prepend (&transfer->bds, &bd->link); … … 2226 2394 uint32_t b; 2227 2395 2228 #if RTEMS_BDBUF_TRACE 2229 rtems_bdbuf_printf ("swapout write: writing bufnum:%d\n",2230 2231 #endif 2396 if (rtems_bdbuf_tracer) 2397 printf ("bdbuf:swapout write: writing bufnum:%lu\n", 2398 transfer->write_req->bufnum); 2399 2232 2400 /* 2233 2401 * Perform the transfer. No cache locks, no preemption, only the disk … … 2280 2448 */ 2281 2449 bd->group->users--; 2282 2450 2451 if (rtems_bdbuf_tracer) 2452 rtems_bdbuf_show_users ("write", bd); 2453 2283 2454 rtems_chain_append (&bdbuf_cache.lru, &bd->link); 2284 2455 … … 2286 2457 rtems_bdbuf_wake (bdbuf_cache.transfer, &bdbuf_cache.transfer_waiters); 2287 2458 else 2288 { 2289 if (rtems_chain_has_only_one_node (&bdbuf_cache.lru)) 2290 rtems_bdbuf_wake (bdbuf_cache.waiting, &bdbuf_cache.wait_waiters); 2291 } 2459 rtems_bdbuf_wake (bdbuf_cache.waiting, &bdbuf_cache.wait_waiters); 2292 2460 } 2293 2461 } 2294 2462 2463 if (rtems_bdbuf_tracer) 2464 rtems_bdbuf_show_usage (); 2465 2295 2466 rtems_bdbuf_unlock_cache (); 2296 2467 … … 2452 2623 * If a sync is active do not use a worker because the current code does not 2453 2624 * cleaning up after. We need to know the buffers have been written when 2454 * syncing to release sync lock and currently worker threads do not return to2455 * here. We do not know the worker is the last in a sequence of sync writes2456 * until after we have it running so we do not know to tell it to release the2457 * lock. The simplest solution is to get the main swap out task perform all2458 * sync operations.2625 * syncing to the release sync lock and currently worker threads do not 2626 * return to here. We do not know the worker is the last in a sequence of 2627 * sync writes until after we have it running so we do not know to tell it to 2628 * release the lock. The simplest solution is to get the main swap out task 2629 * perform all sync operations. 2459 2630 */ 2460 2631 if (bdbuf_cache.sync_active) -
cpukit/libblock/src/blkdev.c
rcdf0be6 reb649786 264 264 rtems_disk_device *dd; 265 265 size_t *arg_size = argp; 266 int rc = 0; 266 267 267 268 dd = rtems_disk_obtain(dev); … … 292 293 default: 293 294 errno = EINVAL; 294 r eturn-1;295 rc = -1; 295 296 break; 296 297 } … … 298 299 rtems_disk_release(dd); 299 300 300 return 0;301 } 301 return rc; 302 } -
cpukit/libblock/src/diskdevs.c
rcdf0be6 reb649786 315 315 dd->start = start; 316 316 dd->size = size; 317 dd->block_size = pdd->block_size;317 dd->block_size = dd->media_block_size = pdd->block_size; 318 318 dd->ioctl = pdd->ioctl; 319 319 -
cpukit/libblock/src/flashdisk.c
rcdf0be6 reb649786 2054 2054 { 2055 2055 rtems_blkdev_sg_buffer* sg = req->bufs; 2056 uint32_t b ;2056 uint32_t buf; 2057 2057 int ret = 0; 2058 2058 2059 for (b = 0; b < req->bufnum; b++, sg++) 2060 { 2061 uint32_t length = sg->length; 2062 2063 if (sg->length != fd->block_size) 2064 { 2065 rtems_fdisk_error ("fdisk-read: length is not the block size: "\ 2066 "bd:%d fd:%d", sg->length, fd->block_size); 2067 2068 if (length > fd->block_size) 2069 length = fd->block_size; 2070 } 2071 2072 ret = rtems_fdisk_read_block (fd, sg->block, sg->buffer); 2073 2074 if (ret) 2075 break; 2059 for (buf = 0; (ret == 0) && (buf < req->bufnum); buf++, sg++) 2060 { 2061 uint8_t* data; 2062 uint32_t fb; 2063 uint32_t b; 2064 fb = sg->length / fd->block_size; 2065 data = sg->buffer; 2066 for (b = 0; b < fb; b++, data += fd->block_size) 2067 { 2068 ret = rtems_fdisk_read_block (fd, sg->block + b, data); 2069 if (ret) 2070 break; 2071 } 2076 2072 } 2077 2073 … … 2094 2090 { 2095 2091 rtems_blkdev_sg_buffer* sg = req->bufs; 2096 uint32_t b ;2092 uint32_t buf; 2097 2093 int ret = 0; 2098 2094 2099 for (b = 0; b < req->bufnum; b++, sg++) 2100 { 2101 if (sg->length != fd->block_size) 2102 { 2103 rtems_fdisk_error ("fdisk-write: length is not the block size: " \ 2104 "bd:%d fd:%d", sg->length, fd->block_size); 2105 } 2106 2107 ret = rtems_fdisk_write_block (fd, sg->block, sg->buffer); 2108 2109 if (ret) 2110 break; 2095 for (buf = 0; (ret == 0) && (buf < req->bufnum); buf++, sg++) 2096 { 2097 uint8_t* data; 2098 uint32_t fb; 2099 uint32_t b; 2100 fb = sg->length / fd->block_size; 2101 data = sg->buffer; 2102 for (b = 0; b < fb; b++, data += fd->block_size) 2103 { 2104 ret = rtems_fdisk_write_block (fd, sg->block + b, data); 2105 if (ret) 2106 break; 2107 } 2111 2108 } 2112 2109 … … 2358 2355 else 2359 2356 { 2357 errno = 0; 2360 2358 switch (req) 2361 2359 { … … 2411 2409 2412 2410 default: 2413 r eturn rtems_blkdev_ioctl (dev, req, argp);2411 rtems_blkdev_ioctl (dev, req, argp); 2414 2412 break; 2415 2413 } -
cpukit/libblock/src/nvdisk.c
rcdf0be6 reb649786 574 574 { 575 575 rtems_blkdev_sg_buffer* sg = req->bufs; 576 uint32_t b; 577 int32_t remains; 576 uint32_t bufs; 578 577 int ret = 0; 579 578 … … 582 581 #endif 583 582 584 remains = req->bufnum * nvd->block_size; 585 586 for (b = 0; b < req->bufnum; b++, sg++) 587 { 588 uint32_t length = sg->length; 589 590 if (remains <= 0) 591 rtems_nvdisk_error ("nvdisk-read: remains size <= 0"); 592 593 if (sg->length != nvd->block_size) 583 for (bufs = 0; (ret == 0) && (bufs < req->bufnum); bufs++, sg++) 584 { 585 uint8_t* data; 586 uint32_t nvb; 587 uint32_t b; 588 nvb = sg->length / nvd->block_size; 589 data = sg->buffer; 590 for (b = 0; b < nvb; b++, data += nvd->block_size) 594 591 { 595 rtems_nvdisk_error ("nvdisk-read: length is not the block size: "\ 596 "bd:%d nvd:%d", sg->length, nvd->block_size); 597 598 if (length > nvd->block_size) 599 length = nvd->block_size; 592 ret = rtems_nvdisk_read_block (nvd, sg->block + b, data); 593 if (ret) 594 break; 600 595 } 601 602 ret = rtems_nvdisk_read_block (nvd, sg->block, sg->buffer);603 604 if (ret)605 break;606 607 remains -= length;608 596 } 609 597 … … 626 614 { 627 615 rtems_blkdev_sg_buffer* sg = req->bufs; 628 uint32_t b ;616 uint32_t bufs; 629 617 int ret = 0; 630 618 … … 633 621 #endif 634 622 635 for (b = 0; b < req->bufnum; b++, sg++) 636 { 637 if (sg->length != nvd->block_size) 623 for (bufs = 0; (ret == 0) && (bufs < req->bufnum); bufs++, sg++) 624 { 625 uint8_t* data; 626 uint32_t nvb; 627 uint32_t b; 628 nvb = sg->length / nvd->block_size; 629 data = sg->buffer; 630 for (b = 0; b < nvb; b++, data += nvd->block_size) 638 631 { 639 rtems_nvdisk_error ("nvdisk-write: length is not the block size: " \ 640 "bd:%d nvd:%d", sg->length, nvd->block_size); 632 ret = rtems_nvdisk_write_block (nvd, sg->block + b, data); 633 if (ret) 634 break; 641 635 } 642 643 ret = rtems_nvdisk_write_block (nvd, sg->block, sg->buffer);644 645 if (ret)646 break;647 636 } 648 637 … … 717 706 else 718 707 { 708 errno = 0; 719 709 switch (req) 720 710 { … … 745 735 746 736 default: 747 r eturn rtems_blkdev_ioctl (dev, req, argp);737 rtems_blkdev_ioctl (dev, req, argp); 748 738 break; 749 739 } -
cpukit/libblock/src/ramdisk.c
rcdf0be6 reb649786 42 42 /* Internal RAM disk descriptor */ 43 43 struct ramdisk { 44 uint32_t block_size; /* RAM disk block size */44 uint32_t block_size; /* RAM disk block size, the media size */ 45 45 rtems_blkdev_bnum block_num; /* Number of blocks on this RAM disk */ 46 46 void *area; /* RAM disk memory area */ … … 95 95 ramdisk_read(struct ramdisk *rd, rtems_blkdev_request *req) 96 96 { 97 char *from;97 uint8_t *from = rd->area; 98 98 uint32_t i; 99 99 rtems_blkdev_sg_buffer *sg; 100 uint32_t remains; 101 102 #if RTEMS_RAMDISK_TRACE 103 rtems_ramdisk_printf (rd, "ramdisk read: start=%d, blocks=%d remains=%d", 104 req->bufs[0].block, req->bufnum, 105 rd->block_size * req->count); 106 #endif 107 108 remains = rd->block_size * req->bufnum; 109 sg = req->bufs; 110 for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++) 111 { 112 uint32_t count = sg->length; 113 from = ((char *)rd->area + (sg->block * rd->block_size)); 114 if (count > remains) 115 count = remains; 116 memcpy(sg->buffer, from, count); 117 remains -= count; 118 from += count; 100 101 #if RTEMS_RAMDISK_TRACE 102 rtems_ramdisk_printf (rd, "ramdisk read: start=%d, blocks=%d", 103 req->bufs[0].block, req->bufnum); 104 #endif 105 106 for (i = 0, sg = req->bufs; i < req->bufnum; i++, sg++) 107 { 108 #if RTEMS_RAMDISK_TRACE 109 rtems_ramdisk_printf (rd, "ramdisk read: buf=%d block=%d length=%d off=%d addr=%p", 110 i, sg->block, sg->length, sg->block * rd->block_size, 111 from + (sg->block * rd->block_size)); 112 #endif 113 memcpy(sg->buffer, from + (sg->block * rd->block_size), sg->length); 119 114 } 120 115 req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0); … … 136 131 ramdisk_write(struct ramdisk *rd, rtems_blkdev_request *req) 137 132 { 138 char *to;133 uint8_t *to = rd->area; 139 134 uint32_t i; 140 135 rtems_blkdev_sg_buffer *sg; 141 uint32_t remains; 142 143 #if RTEMS_RAMDISK_TRACE 144 rtems_ramdisk_printf (rd, "ramdisk write: start=%d, blocks=%d remains=%d", 145 req->bufs[0].block, req->bufnum, 146 rd->block_size * req->bufnum); 147 #endif 148 remains = rd->block_size * req->bufnum; 149 sg = req->bufs; 150 for (i = 0; (remains > 0) && (i < req->bufnum); i++, sg++) 151 { 152 uint32_t count = sg->length; 153 to = ((char *)rd->area + (sg->block * rd->block_size)); 154 if (count > remains) 155 count = remains; 156 memcpy(to, sg->buffer, count); 157 remains -= count; 158 to += count; 136 137 #if RTEMS_RAMDISK_TRACE 138 rtems_ramdisk_printf (rd, "ramdisk write: start=%d, blocks=%d", 139 req->bufs[0].block, req->bufnum); 140 #endif 141 for (i = 0, sg = req->bufs; i < req->bufnum; i++, sg++) 142 { 143 #if RTEMS_RAMDISK_TRACE 144 rtems_ramdisk_printf (rd, "ramdisk write: buf=%d block=%d length=%d off=%d addr=%p", 145 i, sg->block, sg->length, sg->block * rd->block_size, 146 to + (sg->block * rd->block_size)); 147 #endif 148 memcpy(to + (sg->block * rd->block_size), sg->buffer, sg->length); 159 149 } 160 150 req->req_done(req->done_arg, RTEMS_SUCCESSFUL, 0);
Note: See TracChangeset
for help on using the changeset viewer.