Changeset c028b22 in mainline for uspace/lib/block/libblock.c
- Timestamp:
- 2011-07-08T17:01:01Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cc1a727
- Parents:
- 4e36219 (diff), 026793d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/libblock.c
r4e36219 rc028b22 60 60 static FIBRIL_MUTEX_INITIALIZE(dcl_lock); 61 61 /** Device connection list head. */ 62 static LIST_INITIALIZE(dcl _head);63 64 #define CACHE_BUCKETS_LOG2 65 #define CACHE_BUCKETS 62 static LIST_INITIALIZE(dcl); 63 64 #define CACHE_BUCKETS_LOG2 10 65 #define CACHE_BUCKETS (1 << CACHE_BUCKETS_LOG2) 66 66 67 67 typedef struct { 68 68 fibril_mutex_t lock; 69 size_t lblock_size; 70 unsigned blocks_cluster; 71 unsigned block_count; 72 unsigned blocks_cached; 69 size_t lblock_size; /**< Logical block size. */ 70 unsigned blocks_cluster; /**< Physical blocks per block_t */ 71 unsigned block_count; /**< Total number of blocks. */ 72 unsigned blocks_cached; /**< Number of cached blocks. */ 73 73 hash_table_t block_hash; 74 li nk_t free_head;74 list_t free_list; 75 75 enum cache_mode mode; 76 76 } cache_t; … … 79 79 link_t link; 80 80 devmap_handle_t devmap_handle; 81 int dev_phone;81 async_sess_t *sess; 82 82 fibril_mutex_t comm_area_lock; 83 83 void *comm_area; … … 85 85 void *bb_buf; 86 86 aoff64_t bb_addr; 87 size_t pblock_size; 87 size_t pblock_size; /**< Physical block size. */ 88 88 cache_t *cache; 89 89 } devcon_t; 90 90 91 static int read_blocks(devcon_t * devcon, aoff64_t ba, size_t cnt);92 static int write_blocks(devcon_t * devcon, aoff64_t ba, size_t cnt);93 static int get_block_size( int dev_phone, size_t *bsize);94 static int get_num_blocks( int dev_phone, aoff64_t *nblocks);95 static aoff64_t ba_ltop(devcon_t * devcon, aoff64_t lba);91 static int read_blocks(devcon_t *, aoff64_t, size_t); 92 static int write_blocks(devcon_t *, aoff64_t, size_t); 93 static int get_block_size(async_sess_t *, size_t *); 94 static int get_num_blocks(async_sess_t *, aoff64_t *); 95 static aoff64_t ba_ltop(devcon_t *, aoff64_t); 96 96 97 97 static devcon_t *devcon_search(devmap_handle_t devmap_handle) 98 98 { 99 link_t *cur;100 101 99 fibril_mutex_lock(&dcl_lock); 102 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { 100 101 list_foreach(dcl, cur) { 103 102 devcon_t *devcon = list_get_instance(cur, devcon_t, link); 104 103 if (devcon->devmap_handle == devmap_handle) { … … 107 106 } 108 107 } 108 109 109 fibril_mutex_unlock(&dcl_lock); 110 110 return NULL; 111 111 } 112 112 113 static int devcon_add(devmap_handle_t devmap_handle, int dev_phone, size_t bsize, 114 void *comm_area, size_t comm_size) 115 { 116 link_t *cur; 113 static int devcon_add(devmap_handle_t devmap_handle, async_sess_t *sess, 114 size_t bsize, void *comm_area, size_t comm_size) 115 { 117 116 devcon_t *devcon; 118 117 119 118 if (comm_size < bsize) 120 119 return EINVAL; 121 120 122 121 devcon = malloc(sizeof(devcon_t)); 123 122 if (!devcon) … … 126 125 link_initialize(&devcon->link); 127 126 devcon->devmap_handle = devmap_handle; 128 devcon-> dev_phone = dev_phone;127 devcon->sess = sess; 129 128 fibril_mutex_initialize(&devcon->comm_area_lock); 130 129 devcon->comm_area = comm_area; … … 134 133 devcon->pblock_size = bsize; 135 134 devcon->cache = NULL; 136 135 137 136 fibril_mutex_lock(&dcl_lock); 138 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) {137 list_foreach(dcl, cur) { 139 138 devcon_t *d = list_get_instance(cur, devcon_t, link); 140 139 if (d->devmap_handle == devmap_handle) { … … 144 143 } 145 144 } 146 list_append(&devcon->link, &dcl _head);145 list_append(&devcon->link, &dcl); 147 146 fibril_mutex_unlock(&dcl_lock); 148 147 return EOK; … … 156 155 } 157 156 158 int block_init(devmap_handle_t devmap_handle, size_t comm_size) 159 { 160 int rc; 161 int dev_phone; 162 void *comm_area; 163 size_t bsize; 164 165 comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE, 157 int block_init(exch_mgmt_t mgmt, devmap_handle_t devmap_handle, 158 size_t comm_size) 159 { 160 void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE, 166 161 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 167 if (!comm_area) {162 if (!comm_area) 168 163 return ENOMEM; 169 }170 171 dev_phone = devmap_device_connect(devmap_handle,IPC_FLAG_BLOCKING);172 if ( dev_phone < 0) {164 165 async_sess_t *sess = devmap_device_connect(mgmt, devmap_handle, 166 IPC_FLAG_BLOCKING); 167 if (!sess) { 173 168 munmap(comm_area, comm_size); 174 return dev_phone; 175 } 176 177 rc = async_share_out_start(dev_phone, comm_area, 169 return ENOENT; 170 } 171 172 async_exch_t *exch = async_exchange_begin(sess); 173 int rc = async_share_out_start(exch, comm_area, 178 174 AS_AREA_READ | AS_AREA_WRITE); 179 if (rc != EOK) { 180 munmap(comm_area, comm_size); 181 async_hangup(dev_phone); 182 return rc; 183 } 184 185 if (get_block_size(dev_phone, &bsize) != EOK) { 186 munmap(comm_area, comm_size); 187 async_hangup(dev_phone); 188 return rc; 189 } 190 191 rc = devcon_add(devmap_handle, dev_phone, bsize, comm_area, comm_size); 175 async_exchange_end(exch); 176 192 177 if (rc != EOK) { 193 178 munmap(comm_area, comm_size); 194 async_hangup( dev_phone);179 async_hangup(sess); 195 180 return rc; 196 181 } 197 182 183 size_t bsize; 184 rc = get_block_size(sess, &bsize); 185 186 if (rc != EOK) { 187 munmap(comm_area, comm_size); 188 async_hangup(sess); 189 return rc; 190 } 191 192 rc = devcon_add(devmap_handle, sess, bsize, comm_area, comm_size); 193 if (rc != EOK) { 194 munmap(comm_area, comm_size); 195 async_hangup(sess); 196 return rc; 197 } 198 198 199 return EOK; 199 200 } … … 206 207 if (devcon->cache) 207 208 (void) block_cache_fini(devmap_handle); 208 209 209 210 devcon_remove(devcon); 210 211 211 212 if (devcon->bb_buf) 212 213 free(devcon->bb_buf); 213 214 214 215 munmap(devcon->comm_area, devcon->comm_size); 215 async_hangup(devcon-> dev_phone);216 217 free(devcon); 216 async_hangup(devcon->sess); 217 218 free(devcon); 218 219 } 219 220 … … 290 291 291 292 fibril_mutex_initialize(&cache->lock); 292 list_initialize(&cache->free_ head);293 list_initialize(&cache->free_list); 293 294 cache->lblock_size = size; 294 295 cache->block_count = blocks; … … 331 332 * bother with the cache and block locks because we are single-threaded. 332 333 */ 333 while (!list_empty(&cache->free_ head)) {334 block_t *b = list_get_instance( cache->free_head.next,334 while (!list_empty(&cache->free_list)) { 335 block_t *b = list_get_instance(list_first(&cache->free_list), 335 336 block_t, free_link); 336 337 … … 363 364 if (cache->blocks_cached < CACHE_LO_WATERMARK) 364 365 return true; 365 if (!list_empty(&cache->free_ head))366 if (!list_empty(&cache->free_list)) 366 367 return false; 367 368 return true; … … 452 453 unsigned long temp_key; 453 454 recycle: 454 if (list_empty(&cache->free_ head)) {455 if (list_empty(&cache->free_list)) { 455 456 fibril_mutex_unlock(&cache->lock); 456 457 rc = ENOMEM; 457 458 goto out; 458 459 } 459 l = cache->free_head.next;460 l = list_first(&cache->free_list); 460 461 b = list_get_instance(l, block_t, free_link); 461 462 … … 472 473 */ 473 474 list_remove(&b->free_link); 474 list_append(&b->free_link, &cache->free_ head);475 list_append(&b->free_link, &cache->free_list); 475 476 fibril_mutex_unlock(&cache->lock); 476 477 fibril_mutex_lock(&devcon->comm_area_lock); … … 664 665 goto retry; 665 666 } 666 list_append(&block->free_link, &cache->free_ head);667 list_append(&block->free_link, &cache->free_list); 667 668 } 668 669 fibril_mutex_unlock(&block->lock); … … 808 809 assert(devcon); 809 810 810 return get_block_size(devcon-> dev_phone, bsize);811 return get_block_size(devcon->sess, bsize); 811 812 } 812 813 … … 820 821 int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks) 821 822 { 822 devcon_t *devcon; 823 824 devcon = devcon_search(devmap_handle); 825 assert(devcon); 826 827 return get_num_blocks(devcon->dev_phone, nblocks); 823 devcon_t *devcon = devcon_search(devmap_handle); 824 assert(devcon); 825 826 return get_num_blocks(devcon->sess, nblocks); 828 827 } 829 828 … … 891 890 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 892 891 { 893 int rc;894 895 as sert(devcon);896 rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba),892 assert(devcon); 893 894 async_exch_t *exch = async_exchange_begin(devcon->sess); 895 int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba), 897 896 UPPER32(ba), cnt); 897 async_exchange_end(exch); 898 898 899 if (rc != EOK) { 899 900 printf("Error %d reading %zu blocks starting at block %" PRIuOFF64 … … 904 905 #endif 905 906 } 907 906 908 return rc; 907 909 } … … 918 920 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 919 921 { 920 int rc;921 922 as sert(devcon);923 rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba),922 assert(devcon); 923 924 async_exch_t *exch = async_exchange_begin(devcon->sess); 925 int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba), 924 926 UPPER32(ba), cnt); 927 async_exchange_end(exch); 928 925 929 if (rc != EOK) { 926 930 printf("Error %d writing %zu blocks starting at block %" PRIuOFF64 … … 930 934 #endif 931 935 } 936 932 937 return rc; 933 938 } 934 939 935 940 /** Get block size used by the device. */ 936 static int get_block_size( int dev_phone, size_t *bsize)941 static int get_block_size(async_sess_t *sess, size_t *bsize) 937 942 { 938 943 sysarg_t bs; 939 int rc; 940 941 rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs); 944 945 async_exch_t *exch = async_exchange_begin(sess); 946 int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs); 947 async_exchange_end(exch); 948 942 949 if (rc == EOK) 943 950 *bsize = (size_t) bs; 944 951 945 952 return rc; 946 953 } 947 954 948 955 /** Get total number of blocks on block device. */ 949 static int get_num_blocks(int dev_phone, aoff64_t *nblocks) 950 { 951 sysarg_t nb_l, nb_h; 952 int rc; 953 954 rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h); 955 if (rc == EOK) { 956 static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks) 957 { 958 sysarg_t nb_l; 959 sysarg_t nb_h; 960 961 async_exch_t *exch = async_exchange_begin(sess); 962 int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h); 963 async_exchange_end(exch); 964 965 if (rc == EOK) 956 966 *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h); 957 } 958 967 959 968 return rc; 960 969 }
Note:
See TracChangeset
for help on using the changeset viewer.