Changes in uspace/lib/block/libblock.c [79ae36dd:c7bbf029] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/libblock.c
r79ae36dd rc7bbf029 2 2 * Copyright (c) 2008 Jakub Jermar 3 3 * Copyright (c) 2008 Martin Decky 4 * Copyright (c) 2011 Martin Sucha5 4 * All rights reserved. 6 5 * … … 62 61 static LIST_INITIALIZE(dcl_head); 63 62 64 #define CACHE_BUCKETS_LOG2 65 #define CACHE_BUCKETS 63 #define CACHE_BUCKETS_LOG2 10 64 #define CACHE_BUCKETS (1 << CACHE_BUCKETS_LOG2) 66 65 67 66 typedef struct { 68 67 fibril_mutex_t lock; 69 size_t lblock_size; 70 unsigned blocks_cluster; 71 unsigned block_count; 72 unsigned blocks_cached; 68 size_t lblock_size; /**< Logical block size. */ 69 unsigned blocks_cluster; /**< Physical blocks per block_t */ 70 unsigned block_count; /**< Total number of blocks. */ 71 unsigned blocks_cached; /**< Number of cached blocks. */ 73 72 hash_table_t block_hash; 74 73 link_t free_head; … … 79 78 link_t link; 80 79 devmap_handle_t devmap_handle; 81 async_sess_t *sess;80 int dev_phone; 82 81 fibril_mutex_t comm_area_lock; 83 82 void *comm_area; … … 85 84 void *bb_buf; 86 85 aoff64_t bb_addr; 87 size_t pblock_size; 86 size_t pblock_size; /**< Physical block size. */ 88 87 cache_t *cache; 89 88 } devcon_t; 90 89 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);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); 96 95 97 96 static devcon_t *devcon_search(devmap_handle_t devmap_handle) 98 97 { 99 98 link_t *cur; 100 99 101 100 fibril_mutex_lock(&dcl_lock); 102 103 101 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { 104 102 devcon_t *devcon = list_get_instance(cur, devcon_t, link); … … 108 106 } 109 107 } 110 111 108 fibril_mutex_unlock(&dcl_lock); 112 109 return NULL; 113 110 } 114 111 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)112 static int devcon_add(devmap_handle_t devmap_handle, int dev_phone, size_t bsize, 113 void *comm_area, size_t comm_size) 117 114 { 118 115 link_t *cur; 119 116 devcon_t *devcon; 120 117 121 118 if (comm_size < bsize) 122 119 return EINVAL; 123 120 124 121 devcon = malloc(sizeof(devcon_t)); 125 122 if (!devcon) … … 128 125 link_initialize(&devcon->link); 129 126 devcon->devmap_handle = devmap_handle; 130 devcon-> sess = sess;127 devcon->dev_phone = dev_phone; 131 128 fibril_mutex_initialize(&devcon->comm_area_lock); 132 129 devcon->comm_area = comm_area; … … 136 133 devcon->pblock_size = bsize; 137 134 devcon->cache = NULL; 138 135 139 136 fibril_mutex_lock(&dcl_lock); 140 137 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { … … 158 155 } 159 156 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, 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, 164 165 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 165 if (!comm_area) 166 if (!comm_area) { 166 167 return ENOMEM; 167 168 async_sess_t *sess = devmap_device_connect(mgmt, devmap_handle, 169 170 if ( !sess) {168 } 169 170 dev_phone = devmap_device_connect(devmap_handle, IPC_FLAG_BLOCKING); 171 if (dev_phone < 0) { 171 172 munmap(comm_area, comm_size); 172 return ENOENT; 173 } 174 175 async_exch_t *exch = async_exchange_begin(sess); 176 int rc = async_share_out_start(exch, comm_area, 173 return dev_phone; 174 } 175 176 rc = async_share_out_start(dev_phone, comm_area, 177 177 AS_AREA_READ | AS_AREA_WRITE); 178 async_exchange_end(exch); 179 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); 180 191 if (rc != EOK) { 181 192 munmap(comm_area, comm_size); 182 async_hangup( sess);193 async_hangup(dev_phone); 183 194 return rc; 184 195 } 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 196 202 197 return EOK; 203 198 } … … 210 205 if (devcon->cache) 211 206 (void) block_cache_fini(devmap_handle); 212 207 213 208 devcon_remove(devcon); 214 209 215 210 if (devcon->bb_buf) 216 211 free(devcon->bb_buf); 217 212 218 213 munmap(devcon->comm_area, devcon->comm_size); 219 async_hangup(devcon-> sess);220 221 free(devcon); 214 async_hangup(devcon->dev_phone); 215 216 free(devcon); 222 217 } 223 218 … … 812 807 assert(devcon); 813 808 814 return get_block_size(devcon-> sess, bsize);809 return get_block_size(devcon->dev_phone, bsize); 815 810 } 816 811 … … 824 819 int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks) 825 820 { 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; 821 devcon_t *devcon; 822 823 devcon = devcon_search(devmap_handle); 824 assert(devcon); 825 826 return get_num_blocks(devcon->dev_phone, nblocks); 882 827 } 883 828 … … 893 838 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 894 839 { 895 assert(devcon);896 897 as ync_exch_t *exch = async_exchange_begin(devcon->sess);898 int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba),840 int rc; 841 842 assert(devcon); 843 rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba), 899 844 UPPER32(ba), cnt); 900 async_exchange_end(exch);901 902 845 if (rc != EOK) { 903 846 printf("Error %d reading %zu blocks starting at block %" PRIuOFF64 … … 908 851 #endif 909 852 } 910 911 853 return rc; 912 854 } … … 923 865 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 924 866 { 925 assert(devcon);926 927 as ync_exch_t *exch = async_exchange_begin(devcon->sess);928 int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba),867 int rc; 868 869 assert(devcon); 870 rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba), 929 871 UPPER32(ba), cnt); 930 async_exchange_end(exch);931 932 872 if (rc != EOK) { 933 873 printf("Error %d writing %zu blocks starting at block %" PRIuOFF64 … … 937 877 #endif 938 878 } 939 940 879 return rc; 941 880 } 942 881 943 882 /** Get block size used by the device. */ 944 static int get_block_size( async_sess_t *sess, size_t *bsize)883 static int get_block_size(int dev_phone, size_t *bsize) 945 884 { 946 885 sysarg_t 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 886 int rc; 887 888 rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs); 952 889 if (rc == EOK) 953 890 *bsize = (size_t) bs; 954 891 955 892 return rc; 956 893 } 957 894 958 895 /** Get total number of blocks on block device. */ 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) 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) { 969 903 *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h); 970 904 } 905 971 906 return rc; 972 907 }
Note:
See TracChangeset
for help on using the changeset viewer.