Changeset 41811af in mainline for uspace/lib/block/libblock.c
- Timestamp:
- 2011-06-10T10:14:26Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ab547063
- Parents:
- 9536e6e (diff), 390d80d (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
r9536e6e r41811af 2 2 * Copyright (c) 2008 Jakub Jermar 3 3 * Copyright (c) 2008 Martin Decky 4 * Copyright (c) 2011 Martin Sucha 4 5 * All rights reserved. 5 6 * … … 61 62 static LIST_INITIALIZE(dcl_head); 62 63 63 #define CACHE_BUCKETS_LOG2 64 #define CACHE_BUCKETS 64 #define CACHE_BUCKETS_LOG2 10 65 #define CACHE_BUCKETS (1 << CACHE_BUCKETS_LOG2) 65 66 66 67 typedef struct { 67 68 fibril_mutex_t lock; 68 size_t lblock_size; 69 unsigned blocks_cluster; 70 unsigned block_count; 71 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. */ 72 73 hash_table_t block_hash; 73 74 link_t free_head; … … 78 79 link_t link; 79 80 devmap_handle_t devmap_handle; 80 int dev_phone;81 async_sess_t *sess; 81 82 fibril_mutex_t comm_area_lock; 82 83 void *comm_area; … … 84 85 void *bb_buf; 85 86 aoff64_t bb_addr; 86 size_t pblock_size; 87 size_t pblock_size; /**< Physical block size. */ 87 88 cache_t *cache; 88 89 } devcon_t; 89 90 90 static int read_blocks(devcon_t * devcon, aoff64_t ba, size_t cnt);91 static int write_blocks(devcon_t * devcon, aoff64_t ba, size_t cnt);92 static int get_block_size( int dev_phone, size_t *bsize);93 static int get_num_blocks( int dev_phone, aoff64_t *nblocks);94 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); 95 96 96 97 static devcon_t *devcon_search(devmap_handle_t devmap_handle) 97 98 { 98 99 link_t *cur; 99 100 100 101 fibril_mutex_lock(&dcl_lock); 102 101 103 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { 102 104 devcon_t *devcon = list_get_instance(cur, devcon_t, link); … … 106 108 } 107 109 } 110 108 111 fibril_mutex_unlock(&dcl_lock); 109 112 return NULL; 110 113 } 111 114 112 static int devcon_add(devmap_handle_t devmap_handle, int dev_phone, size_t bsize,113 void *comm_area, size_t comm_size)115 static int devcon_add(devmap_handle_t devmap_handle, async_sess_t *sess, 116 size_t bsize, void *comm_area, size_t comm_size) 114 117 { 115 118 link_t *cur; 116 119 devcon_t *devcon; 117 120 118 121 if (comm_size < bsize) 119 122 return EINVAL; 120 123 121 124 devcon = malloc(sizeof(devcon_t)); 122 125 if (!devcon) … … 125 128 link_initialize(&devcon->link); 126 129 devcon->devmap_handle = devmap_handle; 127 devcon-> dev_phone = dev_phone;130 devcon->sess = sess; 128 131 fibril_mutex_initialize(&devcon->comm_area_lock); 129 132 devcon->comm_area = comm_area; … … 133 136 devcon->pblock_size = bsize; 134 137 devcon->cache = NULL; 135 138 136 139 fibril_mutex_lock(&dcl_lock); 137 140 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { … … 155 158 } 156 159 157 int block_init(devmap_handle_t devmap_handle, size_t comm_size) 158 { 159 int rc; 160 int dev_phone; 161 void *comm_area; 162 size_t bsize; 163 164 comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE, 160 int block_init(exch_mgmt_t mgmt, devmap_handle_t devmap_handle, 161 size_t comm_size) 162 { 163 void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE, 165 164 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 166 if (!comm_area) {165 if (!comm_area) 167 166 return ENOMEM; 168 }169 170 dev_phone = devmap_device_connect(devmap_handle,IPC_FLAG_BLOCKING);171 if ( dev_phone < 0) {167 168 async_sess_t *sess = devmap_device_connect(mgmt, devmap_handle, 169 IPC_FLAG_BLOCKING); 170 if (!sess) { 172 171 munmap(comm_area, comm_size); 173 return dev_phone; 174 } 175 176 rc = async_share_out_start(dev_phone, comm_area, 172 return ENOENT; 173 } 174 175 async_exch_t *exch = async_exchange_begin(sess); 176 int rc = async_share_out_start(exch, comm_area, 177 177 AS_AREA_READ | AS_AREA_WRITE); 178 if (rc != EOK) { 179 munmap(comm_area, comm_size); 180 async_hangup(dev_phone); 181 return rc; 182 } 183 184 if (get_block_size(dev_phone, &bsize) != EOK) { 185 munmap(comm_area, comm_size); 186 async_hangup(dev_phone); 187 return rc; 188 } 189 190 rc = devcon_add(devmap_handle, dev_phone, bsize, comm_area, comm_size); 178 async_exchange_end(exch); 179 191 180 if (rc != EOK) { 192 181 munmap(comm_area, comm_size); 193 async_hangup( dev_phone);182 async_hangup(sess); 194 183 return rc; 195 184 } 196 185 186 size_t bsize; 187 rc = get_block_size(sess, &bsize); 188 189 if (rc != EOK) { 190 munmap(comm_area, comm_size); 191 async_hangup(sess); 192 return rc; 193 } 194 195 rc = devcon_add(devmap_handle, sess, bsize, comm_area, comm_size); 196 if (rc != EOK) { 197 munmap(comm_area, comm_size); 198 async_hangup(sess); 199 return rc; 200 } 201 197 202 return EOK; 198 203 } … … 205 210 if (devcon->cache) 206 211 (void) block_cache_fini(devmap_handle); 207 212 208 213 devcon_remove(devcon); 209 214 210 215 if (devcon->bb_buf) 211 216 free(devcon->bb_buf); 212 217 213 218 munmap(devcon->comm_area, devcon->comm_size); 214 async_hangup(devcon-> dev_phone);215 216 free(devcon); 219 async_hangup(devcon->sess); 220 221 free(devcon); 217 222 } 218 223 … … 807 812 assert(devcon); 808 813 809 return get_block_size(devcon-> dev_phone, bsize);814 return get_block_size(devcon->sess, bsize); 810 815 } 811 816 … … 819 824 int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks) 820 825 { 821 devcon_t *devcon; 822 823 devcon = devcon_search(devmap_handle); 824 assert(devcon); 825 826 return get_num_blocks(devcon->dev_phone, nblocks); 826 devcon_t *devcon = devcon_search(devmap_handle); 827 assert(devcon); 828 829 return get_num_blocks(devcon->sess, nblocks); 830 } 831 832 /** Read bytes directly from the device (bypass cache) 833 * 834 * @param devmap_handle Device handle of the block device. 835 * @param abs_offset Absolute offset in bytes where to start reading 836 * @param bytes Number of bytes to read 837 * @param data Buffer that receives the data 838 * 839 * @return EOK on success or negative error code on failure. 840 */ 841 int block_read_bytes_direct(devmap_handle_t devmap_handle, aoff64_t abs_offset, 842 size_t bytes, void *data) 843 { 844 int rc; 845 size_t phys_block_size; 846 size_t buf_size; 847 void *buffer; 848 aoff64_t first_block; 849 aoff64_t last_block; 850 size_t blocks; 851 size_t offset; 852 853 rc = block_get_bsize(devmap_handle, &phys_block_size); 854 if (rc != EOK) { 855 return rc; 856 } 857 858 /* calculate data position and required space */ 859 first_block = abs_offset / phys_block_size; 860 offset = abs_offset % phys_block_size; 861 last_block = (abs_offset + bytes - 1) / phys_block_size; 862 blocks = last_block - first_block + 1; 863 buf_size = blocks * phys_block_size; 864 865 /* read the data into memory */ 866 buffer = malloc(buf_size); 867 if (buffer == NULL) { 868 return ENOMEM; 869 } 870 871 rc = block_read_direct(devmap_handle, first_block, blocks, buffer); 872 if (rc != EOK) { 873 free(buffer); 874 return rc; 875 } 876 877 /* copy the data from the buffer */ 878 memcpy(data, buffer + offset, bytes); 879 free(buffer); 880 881 return EOK; 827 882 } 828 883 … … 838 893 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 839 894 { 840 int rc;841 842 as sert(devcon);843 rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba),895 assert(devcon); 896 897 async_exch_t *exch = async_exchange_begin(devcon->sess); 898 int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba), 844 899 UPPER32(ba), cnt); 900 async_exchange_end(exch); 901 845 902 if (rc != EOK) { 846 903 printf("Error %d reading %zu blocks starting at block %" PRIuOFF64 … … 851 908 #endif 852 909 } 910 853 911 return rc; 854 912 } … … 865 923 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 866 924 { 867 int rc;868 869 as sert(devcon);870 rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba),925 assert(devcon); 926 927 async_exch_t *exch = async_exchange_begin(devcon->sess); 928 int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba), 871 929 UPPER32(ba), cnt); 930 async_exchange_end(exch); 931 872 932 if (rc != EOK) { 873 933 printf("Error %d writing %zu blocks starting at block %" PRIuOFF64 … … 877 937 #endif 878 938 } 939 879 940 return rc; 880 941 } 881 942 882 943 /** Get block size used by the device. */ 883 static int get_block_size( int dev_phone, size_t *bsize)944 static int get_block_size(async_sess_t *sess, size_t *bsize) 884 945 { 885 946 sysarg_t bs; 886 int rc; 887 888 rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs); 947 948 async_exch_t *exch = async_exchange_begin(sess); 949 int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs); 950 async_exchange_end(exch); 951 889 952 if (rc == EOK) 890 953 *bsize = (size_t) bs; 891 954 892 955 return rc; 893 956 } 894 957 895 958 /** Get total number of blocks on block device. */ 896 static int get_num_blocks(int dev_phone, aoff64_t *nblocks) 897 { 898 sysarg_t nb_l, nb_h; 899 int rc; 900 901 rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h); 902 if (rc == EOK) { 959 static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks) 960 { 961 sysarg_t nb_l; 962 sysarg_t nb_h; 963 964 async_exch_t *exch = async_exchange_begin(sess); 965 int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h); 966 async_exchange_end(exch); 967 968 if (rc == EOK) 903 969 *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h); 904 } 905 970 906 971 return rc; 907 972 }
Note:
See TracChangeset
for help on using the changeset viewer.