Changes in uspace/lib/block/libblock.c [5716e9a:79ae36dd] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/libblock.c
r5716e9a r79ae36dd 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 * … … 51 52 #include <macros.h> 52 53 #include <mem.h> 54 #include <malloc.h> 55 #include <stdio.h> 53 56 #include <sys/typefmt.h> 54 57 #include <stacktrace.h> … … 59 62 static LIST_INITIALIZE(dcl_head); 60 63 61 #define CACHE_BUCKETS_LOG2 62 #define CACHE_BUCKETS 64 #define CACHE_BUCKETS_LOG2 10 65 #define CACHE_BUCKETS (1 << CACHE_BUCKETS_LOG2) 63 66 64 67 typedef struct { 65 68 fibril_mutex_t lock; 66 size_t lblock_size; 67 unsigned blocks_cluster; 68 unsigned block_count; 69 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. */ 70 73 hash_table_t block_hash; 71 74 link_t free_head; … … 76 79 link_t link; 77 80 devmap_handle_t devmap_handle; 78 int dev_phone;81 async_sess_t *sess; 79 82 fibril_mutex_t comm_area_lock; 80 83 void *comm_area; … … 82 85 void *bb_buf; 83 86 aoff64_t bb_addr; 84 size_t pblock_size; 87 size_t pblock_size; /**< Physical block size. */ 85 88 cache_t *cache; 86 89 } devcon_t; 87 90 88 static int read_blocks(devcon_t * devcon, aoff64_t ba, size_t cnt);89 static int write_blocks(devcon_t * devcon, aoff64_t ba, size_t cnt);90 static int get_block_size( int dev_phone, size_t *bsize);91 static int get_num_blocks( int dev_phone, aoff64_t *nblocks);92 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); 93 96 94 97 static devcon_t *devcon_search(devmap_handle_t devmap_handle) 95 98 { 96 99 link_t *cur; 97 100 98 101 fibril_mutex_lock(&dcl_lock); 102 99 103 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { 100 104 devcon_t *devcon = list_get_instance(cur, devcon_t, link); … … 104 108 } 105 109 } 110 106 111 fibril_mutex_unlock(&dcl_lock); 107 112 return NULL; 108 113 } 109 114 110 static int devcon_add(devmap_handle_t devmap_handle, int dev_phone, size_t bsize,111 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) 112 117 { 113 118 link_t *cur; 114 119 devcon_t *devcon; 115 120 116 121 if (comm_size < bsize) 117 122 return EINVAL; 118 123 119 124 devcon = malloc(sizeof(devcon_t)); 120 125 if (!devcon) … … 123 128 link_initialize(&devcon->link); 124 129 devcon->devmap_handle = devmap_handle; 125 devcon-> dev_phone = dev_phone;130 devcon->sess = sess; 126 131 fibril_mutex_initialize(&devcon->comm_area_lock); 127 132 devcon->comm_area = comm_area; … … 131 136 devcon->pblock_size = bsize; 132 137 devcon->cache = NULL; 133 138 134 139 fibril_mutex_lock(&dcl_lock); 135 140 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { … … 153 158 } 154 159 155 int block_init(devmap_handle_t devmap_handle, size_t comm_size) 156 { 157 int rc; 158 int dev_phone; 159 void *comm_area; 160 size_t bsize; 161 162 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, 163 164 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 164 if (!comm_area) {165 if (!comm_area) 165 166 return ENOMEM; 166 }167 168 dev_phone = devmap_device_connect(devmap_handle,IPC_FLAG_BLOCKING);169 if ( dev_phone < 0) {167 168 async_sess_t *sess = devmap_device_connect(mgmt, devmap_handle, 169 IPC_FLAG_BLOCKING); 170 if (!sess) { 170 171 munmap(comm_area, comm_size); 171 return dev_phone; 172 } 173 174 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, 175 177 AS_AREA_READ | AS_AREA_WRITE); 176 if (rc != EOK) { 177 munmap(comm_area, comm_size); 178 async_hangup(dev_phone); 179 return rc; 180 } 181 182 if (get_block_size(dev_phone, &bsize) != EOK) { 183 munmap(comm_area, comm_size); 184 async_hangup(dev_phone); 185 return rc; 186 } 187 188 rc = devcon_add(devmap_handle, dev_phone, bsize, comm_area, comm_size); 178 async_exchange_end(exch); 179 189 180 if (rc != EOK) { 190 181 munmap(comm_area, comm_size); 191 async_hangup( dev_phone);182 async_hangup(sess); 192 183 return rc; 193 184 } 194 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 195 202 return EOK; 196 203 } … … 203 210 if (devcon->cache) 204 211 (void) block_cache_fini(devmap_handle); 205 212 206 213 devcon_remove(devcon); 207 214 208 215 if (devcon->bb_buf) 209 216 free(devcon->bb_buf); 210 217 211 218 munmap(devcon->comm_area, devcon->comm_size); 212 async_hangup(devcon-> dev_phone);213 214 free(devcon); 219 async_hangup(devcon->sess); 220 221 free(devcon); 215 222 } 216 223 … … 805 812 assert(devcon); 806 813 807 return get_block_size(devcon-> dev_phone, bsize);814 return get_block_size(devcon->sess, bsize); 808 815 } 809 816 … … 817 824 int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks) 818 825 { 819 devcon_t *devcon; 820 821 devcon = devcon_search(devmap_handle); 822 assert(devcon); 823 824 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; 825 882 } 826 883 … … 836 893 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 837 894 { 838 int rc;839 840 as sert(devcon);841 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), 842 899 UPPER32(ba), cnt); 900 async_exchange_end(exch); 901 843 902 if (rc != EOK) { 844 903 printf("Error %d reading %zu blocks starting at block %" PRIuOFF64 … … 849 908 #endif 850 909 } 910 851 911 return rc; 852 912 } … … 863 923 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 864 924 { 865 int rc;866 867 as sert(devcon);868 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), 869 929 UPPER32(ba), cnt); 930 async_exchange_end(exch); 931 870 932 if (rc != EOK) { 871 933 printf("Error %d writing %zu blocks starting at block %" PRIuOFF64 … … 875 937 #endif 876 938 } 939 877 940 return rc; 878 941 } 879 942 880 943 /** Get block size used by the device. */ 881 static int get_block_size( int dev_phone, size_t *bsize)944 static int get_block_size(async_sess_t *sess, size_t *bsize) 882 945 { 883 946 sysarg_t bs; 884 int rc; 885 886 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 887 952 if (rc == EOK) 888 953 *bsize = (size_t) bs; 889 954 890 955 return rc; 891 956 } 892 957 893 958 /** Get total number of blocks on block device. */ 894 static int get_num_blocks(int dev_phone, aoff64_t *nblocks) 895 { 896 sysarg_t nb_l, nb_h; 897 int rc; 898 899 rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h); 900 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) 901 969 *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h); 902 } 903 970 904 971 return rc; 905 972 }
Note:
See TracChangeset
for help on using the changeset viewer.