Changeset 7cfe5c0 in mainline for uspace/lib/block/block.c
- Timestamp:
- 2012-08-20T19:16:24Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6b99156
- Parents:
- b9cb911 (diff), 01e397ac (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 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/block.c
rb9cb911 r7cfe5c0 37 37 */ 38 38 39 #include "libblock.h"40 39 #include "../../srv/vfs/vfs.h" 41 40 #include <ipc/loc.h> 42 #include <ipc/bd.h>43 41 #include <ipc/services.h> 44 42 #include <errno.h> … … 47 45 #include <as.h> 48 46 #include <assert.h> 47 #include <bd.h> 49 48 #include <fibril_synch.h> 50 49 #include <adt/list.h> … … 56 55 #include <sys/typefmt.h> 57 56 #include <stacktrace.h> 57 #include "block.h" 58 58 59 59 /** Lock protecting the device connection list */ … … 78 78 service_id_t service_id; 79 79 async_sess_t *sess; 80 fibril_mutex_t comm_area_lock; 81 void *comm_area; 82 size_t comm_size; 80 bd_t *bd; 83 81 void *bb_buf; 84 82 aoff64_t bb_addr; … … 87 85 } devcon_t; 88 86 89 static int read_blocks(devcon_t *, aoff64_t, size_t); 90 static int write_blocks(devcon_t *, aoff64_t, size_t); 91 static int get_block_size(async_sess_t *, size_t *); 92 static int get_num_blocks(async_sess_t *, aoff64_t *); 87 static int read_blocks(devcon_t *, aoff64_t, size_t, void *, size_t); 88 static int write_blocks(devcon_t *, aoff64_t, size_t, void *, size_t); 93 89 static aoff64_t ba_ltop(devcon_t *, aoff64_t); 94 90 … … 110 106 111 107 static int devcon_add(service_id_t service_id, async_sess_t *sess, 112 size_t bsize, void *comm_area, size_t comm_size)108 size_t bsize, bd_t *bd) 113 109 { 114 110 devcon_t *devcon; 115 116 if (comm_size < bsize)117 return EINVAL;118 111 119 112 devcon = malloc(sizeof(devcon_t)); … … 124 117 devcon->service_id = service_id; 125 118 devcon->sess = sess; 126 fibril_mutex_initialize(&devcon->comm_area_lock); 127 devcon->comm_area = comm_area; 128 devcon->comm_size = comm_size; 119 devcon->bd = bd; 129 120 devcon->bb_buf = NULL; 130 121 devcon->bb_addr = 0; … … 156 147 size_t comm_size) 157 148 { 158 void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE, 159 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 160 if (!comm_area) 161 return ENOMEM; 162 149 bd_t *bd; 150 163 151 async_sess_t *sess = loc_service_connect(mgmt, service_id, 164 152 IPC_FLAG_BLOCKING); 165 153 if (!sess) { 166 munmap(comm_area, comm_size);167 154 return ENOENT; 168 155 } 169 156 170 async_exch_t *exch = async_exchange_begin(sess); 171 int rc = async_share_out_start(exch, comm_area, 172 AS_AREA_READ | AS_AREA_WRITE); 173 async_exchange_end(exch); 174 157 int rc = bd_open(sess, &bd); 175 158 if (rc != EOK) { 176 munmap(comm_area, comm_size);177 159 async_hangup(sess); 178 160 return rc; … … 180 162 181 163 size_t bsize; 182 rc = get_block_size(sess, &bsize); 183 164 rc = bd_get_block_size(bd, &bsize); 184 165 if (rc != EOK) { 185 munmap(comm_area, comm_size);166 bd_close(bd); 186 167 async_hangup(sess); 187 168 return rc; 188 169 } 189 170 190 rc = devcon_add(service_id, sess, bsize, comm_area, comm_size);171 rc = devcon_add(service_id, sess, bsize, bd); 191 172 if (rc != EOK) { 192 munmap(comm_area, comm_size);173 bd_close(bd); 193 174 async_hangup(sess); 194 175 return rc; … … 211 192 free(devcon->bb_buf); 212 193 213 munmap(devcon->comm_area, devcon->comm_size);194 bd_close(devcon->bd); 214 195 async_hangup(devcon->sess); 215 196 … … 231 212 return ENOMEM; 232 213 233 fibril_mutex_lock(&devcon->comm_area_lock); 234 rc = read_blocks(devcon, 0, 1); 214 rc = read_blocks(devcon, 0, 1, bb_buf, devcon->pblock_size); 235 215 if (rc != EOK) { 236 fibril_mutex_unlock(&devcon->comm_area_lock);237 216 free(bb_buf); 238 217 return rc; 239 218 } 240 memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);241 fibril_mutex_unlock(&devcon->comm_area_lock);242 219 243 220 devcon->bb_buf = bb_buf; … … 342 319 list_remove(&b->free_link); 343 320 if (b->dirty) { 344 memcpy(devcon->comm_area, b->data, b->size);345 rc = write_blocks(devcon, b->pba, cache->blocks_cluster);321 rc = write_blocks(devcon, b->pba, cache->blocks_cluster, 322 b->data, b->size); 346 323 if (rc != EOK) 347 324 return rc; … … 476 453 list_append(&b->free_link, &cache->free_list); 477 454 fibril_mutex_unlock(&cache->lock); 478 fibril_mutex_lock(&devcon->comm_area_lock);479 memcpy(devcon->comm_area, b->data, b->size);480 455 rc = write_blocks(devcon, b->pba, 481 cache->blocks_cluster); 482 fibril_mutex_unlock(&devcon->comm_area_lock); 456 cache->blocks_cluster, b->data, b->size); 483 457 if (rc != EOK) { 484 458 /* … … 546 520 * the new contents from the device. 547 521 */ 548 fibril_mutex_lock(&devcon->comm_area_lock); 549 rc = read_blocks(devcon, b->pba, cache->blocks_cluster); 550 memcpy(b->data, devcon->comm_area, cache->lblock_size); 551 fibril_mutex_unlock(&devcon->comm_area_lock); 522 rc = read_blocks(devcon, b->pba, cache->blocks_cluster, 523 b->data, cache->lblock_size); 552 524 if (rc != EOK) 553 525 b->toxic = true; … … 607 579 if (block->dirty && (block->refcnt == 1) && 608 580 (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) { 609 fibril_mutex_lock(&devcon->comm_area_lock); 610 memcpy(devcon->comm_area, block->data, block->size); 611 rc = write_blocks(devcon, block->pba, cache->blocks_cluster); 612 fibril_mutex_unlock(&devcon->comm_area_lock); 581 rc = write_blocks(devcon, block->pba, cache->blocks_cluster, 582 block->data, block->size); 613 583 block->dirty = false; 614 584 } … … 675 645 * 676 646 * @param service_id Service ID of the block device. 647 * @param buf Buffer for holding one block 677 648 * @param bufpos Pointer to the first unread valid offset within the 678 649 * communication buffer. … … 686 657 * @return EOK on success or a negative return code on failure. 687 658 */ 688 int block_seqread(service_id_t service_id, size_t *bufpos, size_t *buflen,689 aoff64_t *pos, void *dst, size_t size)659 int block_seqread(service_id_t service_id, void *buf, size_t *bufpos, 660 size_t *buflen, aoff64_t *pos, void *dst, size_t size) 690 661 { 691 662 size_t offset = 0; … … 698 669 block_size = devcon->pblock_size; 699 670 700 fibril_mutex_lock(&devcon->comm_area_lock);701 671 while (left > 0) { 702 672 size_t rd; … … 712 682 * destination buffer. 713 683 */ 714 memcpy(dst + offset, devcon->comm_area+ *bufpos, rd);684 memcpy(dst + offset, buf + *bufpos, rd); 715 685 offset += rd; 716 686 *bufpos += rd; … … 723 693 int rc; 724 694 725 rc = read_blocks(devcon, *pos / block_size, 1); 695 rc = read_blocks(devcon, *pos / block_size, 1, buf, 696 devcon->pblock_size); 726 697 if (rc != EOK) { 727 fibril_mutex_unlock(&devcon->comm_area_lock);728 698 return rc; 729 699 } … … 733 703 } 734 704 } 735 fibril_mutex_unlock(&devcon->comm_area_lock);736 705 737 706 return EOK; … … 750 719 { 751 720 devcon_t *devcon; 752 int rc;753 721 754 722 devcon = devcon_search(service_id); 755 723 assert(devcon); 756 757 fibril_mutex_lock(&devcon->comm_area_lock); 758 759 rc = read_blocks(devcon, ba, cnt); 760 if (rc == EOK) 761 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt); 762 763 fibril_mutex_unlock(&devcon->comm_area_lock); 764 765 return rc; 724 725 return read_blocks(devcon, ba, cnt, buf, devcon->pblock_size * cnt); 766 726 } 767 727 … … 779 739 { 780 740 devcon_t *devcon; 781 int rc;782 741 783 742 devcon = devcon_search(service_id); 784 743 assert(devcon); 785 786 fibril_mutex_lock(&devcon->comm_area_lock); 787 788 memcpy(devcon->comm_area, data, devcon->pblock_size * cnt); 789 rc = write_blocks(devcon, ba, cnt); 790 791 fibril_mutex_unlock(&devcon->comm_area_lock); 792 793 return rc; 744 745 return write_blocks(devcon, ba, cnt, (void *)data, devcon->pblock_size * cnt); 794 746 } 795 747 … … 807 759 devcon = devcon_search(service_id); 808 760 assert(devcon); 809 810 return get_block_size(devcon->sess, bsize);761 762 return bd_get_block_size(devcon->bd, bsize); 811 763 } 812 764 … … 823 775 assert(devcon); 824 776 825 return get_num_blocks(devcon->sess, nblocks);777 return bd_get_num_blocks(devcon->bd, nblocks); 826 778 } 827 779 … … 890 842 { 891 843 devcon_t *devcon = devcon_search(service_id); 892 assert(devcon);893 894 844 toc_block_t *toc = NULL; 895 896 fibril_mutex_lock(&devcon->comm_area_lock); 897 898 async_exch_t *exch = async_exchange_begin(devcon->sess); 899 int rc = async_req_1_0(exch, BD_READ_TOC, session); 900 async_exchange_end(exch); 901 902 if (rc == EOK) { 903 toc = (toc_block_t *) malloc(sizeof(toc_block_t)); 904 if (toc != NULL) { 905 memset(toc, 0, sizeof(toc_block_t)); 906 memcpy(toc, devcon->comm_area, 907 min(devcon->pblock_size, sizeof(toc_block_t))); 908 } 909 } 910 911 912 fibril_mutex_unlock(&devcon->comm_area_lock); 845 int rc; 846 847 assert(devcon); 848 849 toc = (toc_block_t *) malloc(sizeof(toc_block_t)); 850 if (toc == NULL) 851 return NULL; 852 853 rc = bd_read_toc(devcon->bd, session, toc, sizeof(toc_block_t)); 854 if (rc != EOK) { 855 free(toc); 856 return NULL; 857 } 913 858 914 859 return toc; … … 924 869 * @return EOK on success or negative error code on failure. 925 870 */ 926 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 927 { 928 assert(devcon); 929 930 async_exch_t *exch = async_exchange_begin(devcon->sess); 931 int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba), 932 UPPER32(ba), cnt); 933 async_exchange_end(exch); 934 871 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *buf, 872 size_t size) 873 { 874 assert(devcon); 875 876 int rc = bd_read_blocks(devcon->bd, ba, cnt, buf, size); 935 877 if (rc != EOK) { 936 878 printf("Error %d reading %zu blocks starting at block %" PRIuOFF64 … … 954 896 * @return EOK on success or negative error code on failure. 955 897 */ 956 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 957 { 958 assert(devcon); 959 960 async_exch_t *exch = async_exchange_begin(devcon->sess); 961 int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba), 962 UPPER32(ba), cnt); 963 async_exchange_end(exch); 964 898 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *data, 899 size_t size) 900 { 901 assert(devcon); 902 903 int rc = bd_write_blocks(devcon->bd, ba, cnt, data, size); 965 904 if (rc != EOK) { 966 905 printf("Error %d writing %zu blocks starting at block %" PRIuOFF64 … … 974 913 } 975 914 976 /** Get block size used by the device. */977 static int get_block_size(async_sess_t *sess, size_t *bsize)978 {979 sysarg_t bs;980 981 async_exch_t *exch = async_exchange_begin(sess);982 int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs);983 async_exchange_end(exch);984 985 if (rc == EOK)986 *bsize = (size_t) bs;987 988 return rc;989 }990 991 /** Get total number of blocks on block device. */992 static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks)993 {994 sysarg_t nb_l;995 sysarg_t nb_h;996 997 async_exch_t *exch = async_exchange_begin(sess);998 int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h);999 async_exchange_end(exch);1000 1001 if (rc == EOK)1002 *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h);1003 1004 return rc;1005 }1006 1007 915 /** Convert logical block address to physical block address. */ 1008 916 static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
Note:
See TracChangeset
for help on using the changeset viewer.