From 86378340313a4d511121f74ef98f6f263df21ba0 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sat, 17 Jun 2006 23:20:54 +0000 Subject: [PATCH] Made the temporary buffer part of the TCP senddata() API, to ease the transition away from uIP. Prepared ipv4.c for transition away from uIP. --- src/include/gpxe/tcp.h | 14 ++++++++++--- src/net/ipv4.c | 9 +++++++-- src/net/tcp.c | 18 ++++++++--------- src/net/tcp/ftp.c | 11 ++++++----- src/net/tcp/iscsi.c | 45 +++++++++++++++++++++++++----------------- src/net/uip/uipopt.h | 2 ++ 6 files changed, 61 insertions(+), 38 deletions(-) diff --git a/src/include/gpxe/tcp.h b/src/include/gpxe/tcp.h index 6c07f4ae..fb0c89a7 100644 --- a/src/include/gpxe/tcp.h +++ b/src/include/gpxe/tcp.h @@ -66,6 +66,8 @@ struct tcp_operations { * Transmit data * * @v conn TCP connection + * @v buf Temporary data buffer + * @v len Length of temporary data buffer * * The application should transmit whatever it currently wants * to send using tcp_send(). If retransmissions are required, @@ -73,8 +75,16 @@ struct tcp_operations { * regenerate the data. The easiest way to implement this is * to ensure that senddata() never changes the application's * state. + * + * The application may use the temporary data buffer to + * construct the data to be sent. Note that merely filling + * the buffer will do nothing; the application must call + * tcp_send() in order to actually transmit the data. Use of + * the buffer is not compulsory; the application may call + * tcp_send() on any block of data. */ - void ( * senddata ) ( struct tcp_connection *conn ); + void ( * senddata ) ( struct tcp_connection *conn, void *buf, + size_t len ); }; /** @@ -88,8 +98,6 @@ struct tcp_connection { struct tcp_operations *tcp_op; }; -extern void *tcp_buffer; -extern size_t tcp_buflen; extern void tcp_connect ( struct tcp_connection *conn ); extern void tcp_send ( struct tcp_connection *conn, const void *data, size_t len ); diff --git a/src/net/ipv4.c b/src/net/ipv4.c index 47b8cb7f..1e2befd3 100644 --- a/src/net/ipv4.c +++ b/src/net/ipv4.c @@ -176,8 +176,9 @@ int ipv4_uip_tx ( struct pk_buff *pkb ) { * This handles IP packets by handing them off to the uIP protocol * stack. */ -static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused, - const void *ll_source __unused ) { +static int ipv4_uip_rx ( struct pk_buff *pkb, + struct net_device *netdev __unused, + const void *ll_source __unused ) { /* Transfer to uIP buffer. Horrendously space-inefficient, * but will do as a proof-of-concept for now. @@ -250,7 +251,11 @@ struct net_protocol ipv4_protocol = { .name = "IP", .net_proto = htons ( ETH_P_IP ), .net_addr_len = sizeof ( struct in_addr ), +#if USE_UIP + .rx = ipv4_uip_rx, +#else .rx = ipv4_rx, +#endif .ntoa = ipv4_ntoa, }; diff --git a/src/net/tcp.c b/src/net/tcp.c index e73708dc..afb1838a 100644 --- a/src/net/tcp.c +++ b/src/net/tcp.c @@ -40,11 +40,10 @@ * * @code * - * static void my_senddata ( struct tcp_connection *conn ) { - * int len; - * - * len = snprintf ( tcp_buffer, tcp_buflen, "FETCH %s\r\n", filename ); - * tcp_send ( conn, tcp_buffer + already_sent, len - already_sent ); + * static void my_senddata ( struct tcp_connection *conn, void *buf, + * size_t len ) { + * len = snprintf ( buf, len, "FETCH %s\r\n", filename ); + * tcp_send ( conn, buf + already_sent, len - already_sent ); * } * * @endcode @@ -53,13 +52,12 @@ * variably-sized data. * * Note that you cannot use this simple mechanism if you want to be - * able to construct single data blocks of more than #tcp_buflen - * bytes. + * able to construct single data blocks of more than #len bytes. */ -void *tcp_buffer = uip_buf + ( 40 + UIP_LLH_LEN ); +static void *tcp_buffer = uip_buf + ( 40 + UIP_LLH_LEN ); /** Size of #tcp_buffer */ -size_t tcp_buflen = UIP_BUFSIZE - ( 40 + UIP_LLH_LEN ); +static size_t tcp_buflen = UIP_BUFSIZE - ( 40 + UIP_LLH_LEN ); /** * Open a TCP connection @@ -148,7 +146,7 @@ void uip_tcp_appcall ( void ) { op->newdata ( conn, ( void * ) uip_appdata, uip_len ); if ( ( uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll() ) && op->senddata ) - op->senddata ( conn ); + op->senddata ( conn, tcp_buffer, tcp_buflen ); } /* Present here to allow everything to link. Will go into separate diff --git a/src/net/tcp/ftp.c b/src/net/tcp/ftp.c index ee6c7eb3..b0f9fef9 100644 --- a/src/net/tcp/ftp.c +++ b/src/net/tcp/ftp.c @@ -220,20 +220,21 @@ static void ftp_acked ( struct tcp_connection *conn, size_t len ) { * Construct data to send on FTP control channel * * @v conn TCP connection + * @v buf Temporary data buffer + * @v len Length of temporary data buffer */ -static void ftp_senddata ( struct tcp_connection *conn ) { +static void ftp_senddata ( struct tcp_connection *conn, + void *buf, size_t len ) { struct ftp_request *ftp = tcp_to_ftp ( conn ); const struct ftp_string *string; - size_t len; /* Send the as-yet-unACKed portion of the string for the * current state. */ string = &ftp_strings[ftp->state]; - len = snprintf ( tcp_buffer, tcp_buflen, string->format, + len = snprintf ( buf, len, string->format, ftp_string_data ( ftp, string->data_offset ) ); - tcp_send ( conn, tcp_buffer + ftp->already_sent, - len - ftp->already_sent ); + tcp_send ( conn, buf + ftp->already_sent, len - ftp->already_sent ); } /** diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c index 49ccb026..a9a56886 100644 --- a/src/net/tcp/iscsi.c +++ b/src/net/tcp/iscsi.c @@ -222,24 +222,27 @@ static void iscsi_data_out_done ( struct iscsi_session *iscsi ) { * Send iSCSI data-out data segment * * @v iscsi iSCSI session + * @v buf Temporary data buffer + * @v len Length of temporary data buffer */ -static void iscsi_tx_data_out ( struct iscsi_session *iscsi ) { +static void iscsi_tx_data_out ( struct iscsi_session *iscsi, + void *buf, size_t len ) { struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out; unsigned long offset; - unsigned long len; + unsigned long remaining; offset = ( iscsi->transfer_offset + ntohl ( data_out->offset ) + iscsi->tx_offset ); - len = ( ISCSI_DATA_LEN ( data_out->lengths ) - iscsi->tx_offset ); + remaining = ( ISCSI_DATA_LEN ( data_out->lengths ) - iscsi->tx_offset); assert ( iscsi->command != NULL ); assert ( iscsi->command->data_out != NULL ); assert ( ( offset + len ) <= iscsi->command->data_out_len ); - if ( len > tcp_buflen ) - len = tcp_buflen; - copy_from_user ( tcp_buffer, iscsi->command->data_out, offset, len ); + if ( remaining < len ) + len = remaining; + copy_from_user ( buf, iscsi->command->data_out, offset, len ); - tcp_send ( &iscsi->tcp, tcp_buffer, len ); + tcp_send ( &iscsi->tcp, buf, len ); } /**************************************************************************** @@ -336,15 +339,15 @@ static void iscsi_start_login ( struct iscsi_session *iscsi, int first ) { * Transmit data segment of an iSCSI login request PDU * * @v iscsi iSCSI session + * @v buf Temporary data buffer + * @v len Length of temporary data buffer * * For login requests, the data segment consists of the login strings. */ -static void iscsi_tx_login_request ( struct iscsi_session *iscsi ) { - int len; - - len = iscsi_build_login_request_strings ( iscsi, tcp_buffer, - tcp_buflen ); - tcp_send ( &iscsi->tcp, tcp_buffer + iscsi->tx_offset, +static void iscsi_tx_login_request ( struct iscsi_session *iscsi, + void *buf, size_t len ) { + len = iscsi_build_login_request_strings ( iscsi, buf, len ); + tcp_send ( &iscsi->tcp, buf + iscsi->tx_offset, len - iscsi->tx_offset ); } @@ -422,19 +425,22 @@ static void iscsi_start_tx ( struct iscsi_session *iscsi ) { * Transmit data segment of an iSCSI PDU * * @v iscsi iSCSI session + * @v buf Temporary data buffer + * @v len Length of temporary data buffer * * Handle transmission of part of a PDU data segment. iscsi::tx_bhs * will be valid when this is called. */ -static void iscsi_tx_data ( struct iscsi_session *iscsi ) { +static void iscsi_tx_data ( struct iscsi_session *iscsi, + void *buf, size_t len ) { struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; switch ( common->opcode & ISCSI_OPCODE_MASK ) { case ISCSI_OPCODE_DATA_OUT: - iscsi_tx_data_out ( iscsi ); + iscsi_tx_data_out ( iscsi, buf, len ); break; case ISCSI_OPCODE_LOGIN_REQUEST: - iscsi_tx_login_request ( iscsi ); + iscsi_tx_login_request ( iscsi, buf, len ); break; default: assert ( 0 ); @@ -524,10 +530,13 @@ static void iscsi_acked ( struct tcp_connection *conn, size_t len ) { * Transmit iSCSI PDU * * @v iscsi iSCSI session + * @v buf Temporary data buffer + * @v len Length of temporary data buffer * * Constructs data to be sent for the current TX state */ -static void iscsi_senddata ( struct tcp_connection *conn ) { +static void iscsi_senddata ( struct tcp_connection *conn, + void *buf, size_t len ) { struct iscsi_session *iscsi = tcp_to_iscsi ( conn ); struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; static const char pad[] = { '\0', '\0', '\0' }; @@ -545,7 +554,7 @@ static void iscsi_senddata ( struct tcp_connection *conn ) { assert ( 0 ); break; case ISCSI_TX_DATA: - iscsi_tx_data ( iscsi ); + iscsi_tx_data ( iscsi, buf, len ); break; case ISCSI_TX_DATA_PADDING: tcp_send ( conn, pad, ( ISCSI_DATA_PAD_LEN ( common->lengths ) diff --git a/src/net/uip/uipopt.h b/src/net/uip/uipopt.h index b17b8905..fc120718 100644 --- a/src/net/uip/uipopt.h +++ b/src/net/uip/uipopt.h @@ -569,4 +569,6 @@ extern void uip_tcp_appcall ( void ); #define UIP_IPADDR2 254 #define UIP_IPADDR3 1 +#define USE_UIP 1 + #endif /* __UIPOPT_H__ */