Changeset 40559a96 in mainline


Ignore:
Timestamp:
2011-01-06T17:51:26Z (13 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
096234b
Parents:
122b753
Message:

get rid of I/O buffers

Location:
uspace/srv/hw/netif/dp8390
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hw/netif/dp8390/dp8390.c

    r122b753 r40559a96  
    5454static void dp_pio16_getblock(dpeth_t *dep, int page, size_t offset, size_t size, void *dst);
    5555static 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);
     56static void dp_pio8_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size);
     57static void dp_pio16_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size);
     58static void dp_pio8_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size);
     59static void dp_pio16_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size);
    6160static void conf_hw(dpeth_t *dep);
    6261static void reply(dpeth_t *dep, int err, int may_block);
     
    218217        }
    219218*/
     219        void *buf = packet_get_data(packet);
    220220        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;
    225221       
    226222        if (size < ETH_MIN_PACK_SIZE || size > ETH_MAX_PACK_SIZE_TAGGED) {
     
    229225        }
    230226       
    231         (dep->de_user2nicf)(dep, &dep->de_write_iovec, 0,
     227        (dep->de_user2nicf)(dep, buf, 0,
    232228            dep->de_sendq[sendq_head].sq_sendpage * DP_PAGESIZE,
    233229            size);
     
    680676                return ENOMEM;
    681677       
    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);
    686679       
    687680        last = page + (length - 1) / DP_PAGESIZE;
     
    689682                count = (dep->de_stoppage - page) * DP_PAGESIZE - sizeof(dp_rcvhdr_t);
    690683               
    691                 /* Save read_iovec since we need it twice. */
    692                 dep->de_tmp_iovec = dep->de_read_iovec;
    693684                (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);
    695686                (dep->de_nic2userf)(dep, dep->de_startpage * DP_PAGESIZE,
    696                     &dep->de_read_iovec, count, length - count);
     687                    buf, count, length - count);
    697688        } else {
    698689                (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);
    700691        }
    701692       
     
    717708}
    718709
    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        
     710static void dp_pio8_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size)
     711{
    725712        outb_reg0(dep, DP_ISR, ISR_RDC);
    726713       
    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);
    729716        outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
    730717        outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
    731718        outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
    732719       
    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;
    760723        for (i = 0; i < 100; i++) {
    761724                if (inb_reg0(dep, DP_ISR) & ISR_RDC)
     
    764727       
    765728        if (i == 100)
    766                 fprintf(stderr, "dp8390: remote dma failed 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
     732static void dp_pio16_user2nic(dpeth_t *dep, void *buf, size_t offset, int nic_addr, size_t size)
    770733{
    771734        void *vir_user;
    772735        size_t ecount;
    773         int i;
    774         size_t bytes;
    775         //uint8_t two_bytes[2];
    776736        uint16_t two_bytes;
    777         int odd_byte;
    778        
    779         ecount = (count + 1) & ~1;
    780         odd_byte = 0;
     737       
     738        ecount = size & ~1;
    781739       
    782740        outb_reg0(dep, DP_ISR, ISR_RDC);
     
    787745        outb_reg0(dep, DP_CR, CR_DM_RW | CR_PS_P0 | CR_STA);
    788746       
    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);
    852759                outw(dep->de_data_port, two_bytes);
    853        
     760        }
     761       
     762        unsigned int i;
    854763        for (i = 0; i < 100; i++) {
    855                 if (inb_reg0(dep, DP_ISR) &ISR_RDC)
     764                if (inb_reg0(dep, DP_ISR) & ISR_RDC)
    856765                        break;
    857766        }
     
    861770}
    862771
    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);
     772static 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);
    871776        outb_reg0(dep, DP_RSAR0, nic_addr & 0xFF);
    872777        outb_reg0(dep, DP_RSAR1, nic_addr >> 8);
    873778        outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
    874779       
    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
     783static void dp_pio16_nic2user(dpeth_t *dep, int nic_addr, void *buf, size_t offset, size_t size)
    904784{
    905785        void *vir_user;
    906786        size_t ecount;
    907         int i;
    908         size_t bytes;
    909         //uint8_t two_bytes[2];
    910787        uint16_t two_bytes;
    911         int odd_byte;
    912        
    913         ecount = (count + 1) & ~1;
    914         odd_byte = 0;
     788       
     789        ecount = size & ~1;
    915790       
    916791        outb_reg0(dep, DP_RBCR0, ecount & 0xFF);
     
    920795        outb_reg0(dep, DP_CR, CR_DM_RR | CR_PS_P0 | CR_STA);
    921796       
    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        }
    994811}
    995812
    996813static void conf_hw(dpeth_t *dep)
    997814{
    998 //      static eth_stat_t empty_stat = {0, 0, 0, 0, 0, 0        /* ,... */};
    999        
    1000815//      int ifnr;
    1001816//      dp_conf_t *dcp;
     
    1018833        dep->de_mode = DEM_ENABLED;
    1019834        dep->de_flags = DEF_EMPTY;
    1020 //      dep->de_stat = empty_stat;
    1021835}
    1022836
  • uspace/srv/hw/netif/dp8390/dp8390.h

    r122b753 r40559a96  
    189189 *  @returns The read value.
    190190 */
    191 #define inb_reg0(dep, reg)  (inb(dep->de_dp8390_port+reg))
     191#define inb_reg0(dep, reg)  (inb(dep->de_dp8390_port + reg))
    192192
    193193/** Writes 1 byte zero page register.
     
    196196 *  @param[in] data The value to be written.
    197197 */
    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))
    199199
    200200/** Reads 1 byte from the first page register.
     
    203203 *  @returns The read value.
    204204 */
    205 #define inb_reg1(dep, reg)  (inb(dep->de_dp8390_port+reg))
     205#define inb_reg1(dep, reg)  (inb(dep->de_dp8390_port + reg))
    206206
    207207/** Writes 1 byte first page register.
     
    210210 *  @param[in] data The value to be written.
    211211 */
    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))
    213213
    214214/* Software interface to the dp8390 driver */
    215215
    216216struct dpeth;
    217 struct iovec_dat;
    218217
    219218typedef void (*dp_initf_t)(struct dpeth *dep);
    220219typedef 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);
     220typedef void (*dp_user2nicf_t)(struct dpeth *dep, void *buf, size_t offset, int nic_addr, size_t size);
     221typedef void (*dp_nic2userf_t)(struct dpeth *dep, int nic_addr, void *buf, size_t offset, size_t size);
    223222typedef void (*dp_getblock_t)(struct dpeth *dep, int page, size_t offset, size_t size, void *dst);
    224 
    225 #define IOVEC_NR  1
    226 
    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;
    232223
    233224#define SENDQ_NR     1  /* Maximum size of the send queue */
     
    295286        int de_mode;
    296287        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;
    300288        size_t de_read_s;
    301289//      int de_client;
  • uspace/srv/hw/netif/dp8390/dp8390_port.h

    r122b753 r40559a96  
    7878#define outw(port, value)  pio_write_16((ioport16_t *) (port), (value))
    7979
    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 
    10880/* Bits in 'DL_MODE' field of DL requests. */
    10981#define DL_NOMODE       0x0
     
    169141} eth_stat_t;
    170142
    171 /* ether.h */
    172143/** Minimum Ethernet packet size in bytes.
    173144 */
     
    186157} ether_addr_t;
    187158
    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 
    200159#endif
    201160
Note: See TracChangeset for help on using the changeset viewer.