Changeset 40559a96 in mainline
- Timestamp:
- 2011-01-06T17:51:26Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 096234b
- Parents:
- 122b753
- Location:
- uspace/srv/hw/netif/dp8390
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hw/netif/dp8390/dp8390.c
r122b753 r40559a96 54 54 static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst); 55 55 static int dp_pkt2user(dpeth_t *dep, int page, int length); 56 static void dp_pio8_user2nic(dpeth_t *dep, iovec_dat_t *iovp, size_t offset, int nic_addr, size_t count); 57 static void dp_pio16_user2nic(dpeth_t *dep, iovec_dat_t *iovp, size_t offset, int nic_addr, size_t count); 58 static void dp_pio8_nic2user(dpeth_t *dep, int nic_addr, iovec_dat_t *iovp, size_t offset, size_t count); 59 static void dp_pio16_nic2user(dpeth_t *dep, int nic_addr, iovec_dat_t *iovp, size_t offset, size_t count); 60 static void dp_next_iovec(iovec_dat_t *iovp); 56 static void dp_pio8_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size); 57 static void dp_pio16_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size); 58 static void dp_pio8_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size); 59 static void dp_pio16_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size); 61 60 static void conf_hw(dpeth_t *dep); 62 61 static void reply(dpeth_t *dep, int err, int may_block); … … 218 217 } 219 218 */ 219 void *buf = packet_get_data(packet); 220 220 size = packet_get_data_length(packet); 221 dep->de_write_iovec.iod_iovec[0].iov_addr = (void *) packet_get_data(packet);222 dep->de_write_iovec.iod_iovec[0].iov_size = size;223 dep->de_write_iovec.iod_iovec_s = 1;224 dep->de_write_iovec.iod_iovec_addr = NULL;225 221 226 222 if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) { … … 229 225 } 230 226 231 (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,227 (dep->de_user2nicf)(dep, buf, 0, 232 228 dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE, 233 229 size); … … 680 676 return ENOMEM; 681 677 682 dep->de_read_iovec.iod_iovec[0].iov_addr = (void *) packet_suffix(packet, length); 683 dep->de_read_iovec.iod_iovec[0].iov_size = length; 684 dep->de_read_iovec.iod_iovec_s = 1; 685 dep->de_read_iovec.iod_iovec_addr = NULL; 678 void *buf = packet_suffix(packet, length); 686 679 687 680 last = page + (length - 1) / DP_PAGESIZE; … … 689 682 count = (dep->de_stoppage - page) * DP_PAGESIZE - sizeof(dp_rcvhdr_t); 690 683 691 /* Save read_iovec since we need it twice. */692 dep->de_tmp_iovec = dep->de_read_iovec;693 684 (dep->de_nic2userf)(dep, page * DP_PAGESIZE + 694 sizeof(dp_rcvhdr_t), &dep->de_tmp_iovec, 0, count);685 sizeof(dp_rcvhdr_t), buf, 0, count); 695 686 (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE, 696 &dep->de_read_iovec, count, length - count);687 buf, count, length - count); 697 688 } else { 698 689 (dep->de_nic2userf)(dep, page * DP_PAGESIZE + 699 sizeof(dp_rcvhdr_t), &dep->de_read_iovec, 0, length);690 sizeof(dp_rcvhdr_t), buf, 0, length); 700 691 } 701 692 … … 717 708 } 718 709 719 static void dp_pio8_user2nic(dpeth_t *dep, iovec_dat_t *iovp, size_t offset, int nic_addr, size_t count) 720 { 721 // phys_bytes phys_user; 722 int i; 723 size_t bytes; 724 710 static void dp_pio8_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size) 711 { 725 712 outb_reg0(dep, DP_ISR, ISR_RDC); 726 713 727 outb_reg0(dep, DP_RBCR0, count& 0xFF);728 outb_reg0(dep, DP_RBCR1, count>> 8);714 outb_reg0(dep, DP_RBCR0, size & 0xFF); 715 outb_reg0(dep, DP_RBCR1, size >> 8); 729 716 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 730 717 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 731 718 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 732 719 733 i = 0; 734 while (count > 0) { 735 if (i >= IOVEC_NR) { 736 dp_next_iovec(iovp); 737 i = 0; 738 continue; 739 } 740 741 assert(i < iovp->iod_iovec_s); 742 743 if (offset >= iovp->iod_iovec[i].iov_size) { 744 offset -= iovp->iod_iovec[i].iov_size; 745 i++; 746 continue; 747 } 748 749 bytes = iovp->iod_iovec[i].iov_size - offset; 750 if (bytes > count) 751 bytes = count; 752 753 do_vir_outsb(dep->de_data_port, iovp->iod_iovec[i].iov_addr + offset, bytes); 754 count -= bytes; 755 offset += bytes; 756 } 757 758 assert(count == 0); 759 720 outsb(dep->de_data_port, buf + offset, size); 721 722 unsigned int i; 760 723 for (i = 0; i < 100; i++) { 761 724 if (inb_reg0(dep, DP_ISR) & ISR_RDC) … … 764 727 765 728 if (i == 100) 766 fprintf(stderr, "dp8390: remote dmafailed to complete\n");767 } 768 769 static void dp_pio16_user2nic(dpeth_t *dep, iovec_dat_t *iovp, size_t offset, int nic_addr, size_t count)729 fprintf(stderr, "dp8390: remote DMA failed to complete\n"); 730 } 731 732 static void dp_pio16_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size) 770 733 { 771 734 void *vir_user; 772 735 size_t ecount; 773 int i;774 size_t bytes;775 //uint8_t two_bytes[2];776 736 uint16_t two_bytes; 777 int odd_byte; 778 779 ecount = (count + 1) & ~1; 780 odd_byte = 0; 737 738 ecount = size & ~1; 781 739 782 740 outb_reg0(dep, DP_ISR, ISR_RDC); … … 787 745 outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA); 788 746 789 i = 0; 790 while (count > 0) { 791 if (i >= IOVEC_NR) { 792 dp_next_iovec(iovp); 793 i = 0; 794 continue; 795 } 796 797 assert(i < iovp->iod_iovec_s); 798 799 if (offset >= iovp->iod_iovec[i].iov_size) { 800 offset -= iovp->iod_iovec[i].iov_size; 801 i++; 802 continue; 803 } 804 805 bytes = iovp->iod_iovec[i].iov_size - offset; 806 if (bytes > count) 807 bytes = count; 808 809 vir_user = iovp->iod_iovec[i].iov_addr + offset; 810 811 if (odd_byte) { 812 memcpy(&(((uint8_t *) &two_bytes)[1]), vir_user, 1); 813 814 //outw(dep->de_data_port, *(uint16_t *) two_bytes); 815 outw(dep->de_data_port, two_bytes); 816 count--; 817 offset++; 818 bytes--; 819 vir_user++; 820 odd_byte= 0; 821 822 if (!bytes) 823 continue; 824 } 825 826 ecount= bytes & ~1; 827 if (ecount != 0) { 828 do_vir_outsw(dep->de_data_port, vir_user, ecount); 829 count -= ecount; 830 offset += ecount; 831 bytes -= ecount; 832 vir_user += ecount; 833 } 834 835 if (bytes) { 836 assert(bytes == 1); 837 838 memcpy(&(((uint8_t *) &two_bytes)[0]), vir_user, 1); 839 840 count--; 841 offset++; 842 bytes--; 843 vir_user++; 844 odd_byte= 1; 845 } 846 } 847 848 assert(count == 0); 849 850 if (odd_byte) 851 //outw(dep->de_data_port, *(uint16_t *) two_bytes); 747 vir_user = buf + offset; 748 if (ecount != 0) { 749 outsw(dep->de_data_port, vir_user, ecount); 750 size -= ecount; 751 offset += ecount; 752 vir_user += ecount; 753 } 754 755 if (size) { 756 assert(size == 1); 757 758 memcpy(&(((uint8_t *) &two_bytes)[0]), vir_user, 1); 852 759 outw(dep->de_data_port, two_bytes); 853 760 } 761 762 unsigned int i; 854 763 for (i = 0; i < 100; i++) { 855 if (inb_reg0(dep, DP_ISR) & ISR_RDC)764 if (inb_reg0(dep, DP_ISR) & ISR_RDC) 856 765 break; 857 766 } … … 861 770 } 862 771 863 static void dp_pio8_nic2user(dpeth_t *dep, int nic_addr, iovec_dat_t *iovp, size_t offset, size_t count) 864 { 865 // phys_bytes phys_user; 866 int i; 867 size_t bytes; 868 869 outb_reg0(dep, DP_RBCR0, count & 0xFF); 870 outb_reg0(dep, DP_RBCR1, count >> 8); 772 static void dp_pio8_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size) 773 { 774 outb_reg0(dep, DP_RBCR0, size & 0xFF); 775 outb_reg0(dep, DP_RBCR1, size >> 8); 871 776 outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF); 872 777 outb_reg0(dep, DP_RSAR1, nic_addr >> 8); 873 778 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 874 779 875 i = 0; 876 while (count > 0) { 877 if (i >= IOVEC_NR) { 878 dp_next_iovec(iovp); 879 i= 0; 880 continue; 881 } 882 883 assert(i < iovp->iod_iovec_s); 884 885 if (offset >= iovp->iod_iovec[i].iov_size) { 886 offset -= iovp->iod_iovec[i].iov_size; 887 i++; 888 continue; 889 } 890 891 bytes = iovp->iod_iovec[i].iov_size - offset; 892 if (bytes > count) 893 bytes = count; 894 895 do_vir_insb(dep->de_data_port, iovp->iod_iovec[i].iov_addr + offset, bytes); 896 count -= bytes; 897 offset += bytes; 898 } 899 900 assert(count == 0); 901 } 902 903 static void dp_pio16_nic2user(dpeth_t *dep, int nic_addr, iovec_dat_t *iovp, size_t offset, size_t count) 780 insb(dep->de_data_port, buf + offset, size); 781 } 782 783 static void dp_pio16_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size) 904 784 { 905 785 void *vir_user; 906 786 size_t ecount; 907 int i;908 size_t bytes;909 //uint8_t two_bytes[2];910 787 uint16_t two_bytes; 911 int odd_byte; 912 913 ecount = (count + 1) & ~1; 914 odd_byte = 0; 788 789 ecount = size & ~1; 915 790 916 791 outb_reg0(dep, DP_RBCR0, ecount & 0xFF); … … 920 795 outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA); 921 796 922 i = 0; 923 while (count > 0) { 924 if (i >= IOVEC_NR) { 925 dp_next_iovec(iovp); 926 i = 0; 927 continue; 928 } 929 930 assert(i < iovp->iod_iovec_s); 931 932 if (offset >= iovp->iod_iovec[i].iov_size) { 933 offset -= iovp->iod_iovec[i].iov_size; 934 i++; 935 continue; 936 } 937 938 bytes = iovp->iod_iovec[i].iov_size - offset; 939 if (bytes > count) 940 bytes = count; 941 942 vir_user = iovp->iod_iovec[i].iov_addr + offset; 943 944 if (odd_byte) { 945 memcpy(vir_user, &(((uint8_t *) &two_bytes)[1]), 1); 946 947 count--; 948 offset++; 949 bytes--; 950 vir_user++; 951 odd_byte= 0; 952 953 if (!bytes) 954 continue; 955 } 956 957 ecount= bytes & ~1; 958 if (ecount != 0) { 959 do_vir_insw(dep->de_data_port, vir_user, ecount); 960 count -= ecount; 961 offset += ecount; 962 bytes -= ecount; 963 vir_user += ecount; 964 } 965 966 if (bytes) { 967 assert(bytes == 1); 968 969 //*(uint16_t *) two_bytes= inw(dep->de_data_port); 970 two_bytes = inw(dep->de_data_port); 971 memcpy(vir_user, &(((uint8_t *) &two_bytes)[0]), 1); 972 973 count--; 974 offset++; 975 bytes--; 976 vir_user++; 977 odd_byte= 1; 978 } 979 } 980 981 assert(count == 0); 982 } 983 984 static void dp_next_iovec(iovec_dat_t *iovp) 985 { 986 assert(iovp->iod_iovec_s > IOVEC_NR); 987 988 iovp->iod_iovec_s -= IOVEC_NR; 989 iovp->iod_iovec_addr += IOVEC_NR * sizeof(iovec_t); 990 991 memcpy(iovp->iod_iovec, iovp->iod_iovec_addr, 992 (iovp->iod_iovec_s > IOVEC_NR ? IOVEC_NR : iovp->iod_iovec_s) * 993 sizeof(iovec_t)); 797 vir_user = buf + offset; 798 if (ecount != 0) { 799 insw(dep->de_data_port, vir_user, ecount); 800 size -= ecount; 801 offset += ecount; 802 vir_user += ecount; 803 } 804 805 if (size) { 806 assert(size == 1); 807 808 two_bytes = inw(dep->de_data_port); 809 memcpy(vir_user, &(((uint8_t *) &two_bytes)[0]), 1); 810 } 994 811 } 995 812 996 813 static void conf_hw(dpeth_t *dep) 997 814 { 998 // static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0 /* ,... */};999 1000 815 // int ifnr; 1001 816 // dp_conf_t *dcp; … … 1018 833 dep->de_mode = DEM_ENABLED; 1019 834 dep->de_flags = DEF_EMPTY; 1020 // dep->de_stat = empty_stat;1021 835 } 1022 836 -
uspace/srv/hw/netif/dp8390/dp8390.h
r122b753 r40559a96 189 189 * @returns The read value. 190 190 */ 191 #define inb_reg0(dep, reg) (inb(dep->de_dp8390_port +reg))191 #define inb_reg0(dep, reg) (inb(dep->de_dp8390_port + reg)) 192 192 193 193 /** Writes 1 byte zero page register. … … 196 196 * @param[in] data The value to be written. 197 197 */ 198 #define outb_reg0(dep, reg, data) (outb(dep->de_dp8390_port +reg, data))198 #define outb_reg0(dep, reg, data) (outb(dep->de_dp8390_port + reg, data)) 199 199 200 200 /** Reads 1 byte from the first page register. … … 203 203 * @returns The read value. 204 204 */ 205 #define inb_reg1(dep, reg) (inb(dep->de_dp8390_port +reg))205 #define inb_reg1(dep, reg) (inb(dep->de_dp8390_port + reg)) 206 206 207 207 /** Writes 1 byte first page register. … … 210 210 * @param[in] data The value to be written. 211 211 */ 212 #define outb_reg1(dep, reg, data) (outb(dep->de_dp8390_port +reg, data))212 #define outb_reg1(dep, reg, data) (outb(dep->de_dp8390_port + reg, data)) 213 213 214 214 /* Software interface to the dp8390 driver */ 215 215 216 216 struct dpeth; 217 struct iovec_dat;218 217 219 218 typedef void (*dp_initf_t)(struct dpeth *dep); 220 219 typedef void (*dp_stopf_t)(struct dpeth *dep); 221 typedef void (*dp_user2nicf_t)(struct dpeth *dep, struct iovec_dat *iovp, size_t offset, int nic_addr, size_t count);222 typedef void (*dp_nic2userf_t)(struct dpeth *dep, int nic_addr, struct iovec_dat *iovp, size_t offset, size_t count);220 typedef void (*dp_user2nicf_t)(struct dpeth *dep, void *buf, size_t offset, int nic_addr, size_t size); 221 typedef void (*dp_nic2userf_t)(struct dpeth *dep, int nic_addr, void *buf, size_t offset, size_t size); 223 222 typedef void (*dp_getblock_t)(struct dpeth *dep, int page, size_t offset, size_t size, void *dst); 224 225 #define IOVEC_NR 1226 227 typedef struct iovec_dat {228 iovec_t iod_iovec[IOVEC_NR];229 int iod_iovec_s;230 void *iod_iovec_addr;231 } iovec_dat_t;232 223 233 224 #define SENDQ_NR 1 /* Maximum size of the send queue */ … … 295 286 int de_mode; 296 287 eth_stat_t de_stat; 297 iovec_dat_t de_read_iovec;298 iovec_dat_t de_write_iovec;299 iovec_dat_t de_tmp_iovec;300 288 size_t de_read_s; 301 289 // int de_client; -
uspace/srv/hw/netif/dp8390/dp8390_port.h
r122b753 r40559a96 78 78 #define outw(port, value) pio_write_16((ioport16_t *) (port), (value)) 79 79 80 /** Reads a memory block byte by byte.81 * @param[in] port The address to be written.82 * @param[in] dst The destination address.83 * @param[in] bytes The block size in bytes.84 */85 #define do_vir_insb(port, dst, bytes) insb((port), (void *)(dst), (bytes))86 87 /** Reads a memory block word by word (2 bytes).88 * @param[in] port The address to be written.89 * @param[in] dst The destination address.90 * @param[in] bytes The block size in bytes.91 */92 #define do_vir_insw(port, dst, bytes) insw((port), (void *)(dst), (bytes))93 94 /** Writes a memory block byte by byte.95 * @param[in] port The address to be written.96 * @param[in] src The source address.97 * @param[in] bytes The block size in bytes.98 */99 #define do_vir_outsb(port, src, bytes) outsb((port), (void *)(src), (bytes))100 101 /** Writes a memory block word by word (2 bytes).102 * @param[in] port The address to be written.103 * @param[in] src The source address.104 * @param[in] bytes The block size in bytes.105 */106 #define do_vir_outsw(port, src, bytes) outsw((port), (void *)(src), (bytes))107 108 80 /* Bits in 'DL_MODE' field of DL requests. */ 109 81 #define DL_NOMODE 0x0 … … 169 141 } eth_stat_t; 170 142 171 /* ether.h */172 143 /** Minimum Ethernet packet size in bytes. 173 144 */ … … 186 157 } ether_addr_t; 187 158 188 /** Type definition of the input/output vector.189 */190 typedef struct {191 /** Address of an I/O buffer.192 */193 void *iov_addr;194 195 /** Size of an I/O buffer.196 */197 size_t iov_size;198 } iovec_t;199 200 159 #endif 201 160
Note:
See TracChangeset
for help on using the changeset viewer.