diff options
Diffstat (limited to 'libhw/w5500.c')
-rw-r--r-- | libhw/w5500.c | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/libhw/w5500.c b/libhw/w5500.c index cd96696..64b373b 100644 --- a/libhw/w5500.c +++ b/libhw/w5500.c @@ -128,6 +128,9 @@ static const char *w5500_state_str(uint8_t state) { LO_IMPLEMENTATION_C(io_closer, struct _w5500_socket, w5500_tcplist, static) LO_IMPLEMENTATION_C(net_stream_listener, struct _w5500_socket, w5500_tcplist, static) +LO_IMPLEMENTATION_C(io_reader, struct _w5500_socket, w5500_tcp, static) +LO_IMPLEMENTATION_C(io_writer, struct _w5500_socket, w5500_tcp, static) +LO_IMPLEMENTATION_C(io_readwriter, struct _w5500_socket, w5500_tcp, static) LO_IMPLEMENTATION_C(io_closer, struct _w5500_socket, w5500_tcp, static) LO_IMPLEMENTATION_C(io_bidi_closer, struct _w5500_socket, w5500_tcp, static) LO_IMPLEMENTATION_C(net_stream_conn, struct _w5500_socket, w5500_tcp, static) @@ -593,10 +596,14 @@ static int w5500_tcplist_close(struct _w5500_socket *socket) { /* tcp_conn methods ***********************************************************/ -static ssize_t w5500_tcp_write(struct _w5500_socket *socket, void *buf, size_t count) { +static ssize_t w5500_tcp_writev(struct _w5500_socket *socket, const struct iovec *iov, int iovcnt) { + assert(iov); + assert(iovcnt > 0); + size_t count = 0; + for (int i = 0; i < iovcnt; i++) + count += iov[i].iov_len; debugf("tcp_conn.write(%zu)", count); ASSERT_SELF(stream_conn, TCP); - assert(count == 0 || buf); if (count == 0) return 0; @@ -646,7 +653,7 @@ static ssize_t w5500_tcp_write(struct _w5500_socket *socket, void *buf, size_t c if ((size_t)freesize > count-done) freesize = count-done; uint16_t ptr = uint16be_unmarshal(w5500ll_read_sock_reg(chip->spidev, socknum, tx_write_pointer)); - w5500ll_write(chip->spidev, ptr, CTL_BLOCK_SOCK(socknum, TX), &((char *)buf)[done], freesize); + w5500ll_writev(chip->spidev, ptr, CTL_BLOCK_SOCK(socknum, TX), iov, iovcnt, done, freesize); w5500ll_write_sock_reg(chip->spidev, socknum, tx_write_pointer, uint16be_marshal(ptr+freesize)); /* Submit the queue. */ @@ -682,10 +689,14 @@ static void w5500_tcp_alarm_handler(void *_arg) { cr_sema_signal_from_intrhandler(&socket->read_sema); } -static ssize_t w5500_tcp_read(struct _w5500_socket *socket, void *buf, size_t count) { - debugf("tcp_conn.read()"); +static ssize_t w5500_tcp_readv(struct _w5500_socket *socket, const struct iovec *iov, int iovcnt) { + assert(iov); + assert(iovcnt > 0); + size_t count = 0; + for (int i = 0; i < iovcnt; i++) + count += iov[i].iov_len; + debugf("tcp_conn.read(%zu)", count); ASSERT_SELF(stream_conn, TCP); - assert(count == 0 || buf); if (count == 0) return 0; @@ -743,7 +754,7 @@ static ssize_t w5500_tcp_read(struct _w5500_socket *socket, void *buf, size_t co /* Read the data. */ if ((size_t)avail > count) avail = count; - w5500ll_read(chip->spidev, ptr, CTL_BLOCK_SOCK(socknum, RX), buf, avail); + w5500ll_readv(chip->spidev, ptr, CTL_BLOCK_SOCK(socknum, RX), iov, iovcnt, avail); /* Tell the chip that we read the data. */ w5500ll_write_sock_reg(chip->spidev, socknum, rx_read_pointer, uint16be_marshal(ptr+avail)); w5500_socket_cmd(socket, CMD_RECV); @@ -827,7 +838,10 @@ static ssize_t w5500_udp_sendto(struct _w5500_socket *socket, void *buf, size_t w5500ll_write_sock_reg(chip->spidev, socknum, remote_port, uint16be_marshal(port)); /* Queue data to be sent. */ uint16_t ptr = uint16be_unmarshal(w5500ll_read_sock_reg(chip->spidev, socknum, tx_write_pointer)); - w5500ll_write(chip->spidev, ptr, CTL_BLOCK_SOCK(socknum, TX), buf, count); + w5500ll_writev(chip->spidev, ptr, CTL_BLOCK_SOCK(socknum, TX), &((struct iovec){ + .iov_base = buf, + .iov_len = count, + }), 1, 0, 0); w5500ll_write_sock_reg(chip->spidev, socknum, tx_write_pointer, uint16be_marshal(ptr+count)); /* Submit the queue. */ w5500_socket_cmd(socket, CMD_SEND); @@ -902,7 +916,10 @@ static ssize_t w5500_udp_recvfrom(struct _w5500_socket *socket, void *buf, size_ * can't find in the datasheet where it describes * this; this is based off of socket.c:recvfrom(). */ uint8_t hdr[8]; - w5500ll_read(chip->spidev, ptr, CTL_BLOCK_SOCK(socknum, RX), hdr, sizeof(hdr)); + w5500ll_readv(chip->spidev, ptr, CTL_BLOCK_SOCK(socknum, RX), &((struct iovec){ + .iov_base = hdr, + .iov_len = sizeof(hdr), + }), 1, 0); if (ret_node) { ret_node->octets[0] = hdr[0]; ret_node->octets[1] = hdr[1]; @@ -916,7 +933,10 @@ static ssize_t w5500_udp_recvfrom(struct _w5500_socket *socket, void *buf, size_ /* Now read the actual data. */ if (count > len) count = len; - w5500ll_read(chip->spidev, ptr+8, CTL_BLOCK_SOCK(socknum, RX), buf, len); + w5500ll_readv(chip->spidev, ptr+8, CTL_BLOCK_SOCK(socknum, RX), &((struct iovec){ + .iov_base = buf, + .iov_len = len, + }), 1, 0); /* Tell the chip that we read the data. */ w5500ll_write_sock_reg(chip->spidev, socknum, rx_read_pointer, uint16be_marshal(ptr+8+len)); w5500_socket_cmd(socket, CMD_RECV); |