diff --git a/src/arch/i386/interface/pxe/pxe_tftp.c b/src/arch/i386/interface/pxe/pxe_tftp.c index aab376e8..f4801bad 100644 --- a/src/arch/i386/interface/pxe/pxe_tftp.c +++ b/src/arch/i386/interface/pxe/pxe_tftp.c @@ -71,6 +71,17 @@ static void pxe_tftp_close ( struct pxe_tftp_connection *pxe_tftp, int rc ) { pxe_tftp->rc = rc; } +/** + * Check flow control window + * + * @v pxe_tftp PXE TFTP connection + * @ret len Length of window + */ +static size_t pxe_tftp_xfer_window ( struct pxe_tftp_connection *pxe_tftp ) { + + return pxe_tftp->blksize; +} + /** * Receive new data * @@ -128,6 +139,8 @@ static int pxe_tftp_xfer_deliver ( struct pxe_tftp_connection *pxe_tftp, static struct interface_operation pxe_tftp_xfer_ops[] = { INTF_OP ( xfer_deliver, struct pxe_tftp_connection *, pxe_tftp_xfer_deliver ), + INTF_OP ( xfer_window, struct pxe_tftp_connection *, + pxe_tftp_xfer_window ), INTF_OP ( intf_close, struct pxe_tftp_connection *, pxe_tftp_close ), }; @@ -167,19 +180,19 @@ static int pxe_tftp_open ( uint32_t ipaddress, unsigned int port, /* Reset PXE TFTP connection structure */ memset ( &pxe_tftp, 0, sizeof ( pxe_tftp ) ); intf_init ( &pxe_tftp.xfer, &pxe_tftp_xfer_desc, NULL ); + if ( blksize < TFTP_DEFAULT_BLKSIZE ) + blksize = TFTP_DEFAULT_BLKSIZE; + pxe_tftp.blksize = blksize; pxe_tftp.rc = -EINPROGRESS; /* Construct URI string */ address.s_addr = ipaddress; if ( ! port ) port = htons ( TFTP_PORT ); - if ( blksize < TFTP_DEFAULT_BLKSIZE ) - blksize = TFTP_DEFAULT_BLKSIZE; - snprintf ( uri_string, sizeof ( uri_string ), - "tftp%s://%s:%d%s%s?blksize=%zd", - sizeonly ? "size" : "", - inet_ntoa ( address ), ntohs ( port ), - ( ( filename[0] == '/' ) ? "" : "/" ), filename, blksize ); + snprintf ( uri_string, sizeof ( uri_string ), "tftp%s://%s:%d%s%s", + sizeonly ? "size" : "", inet_ntoa ( address ), + ntohs ( port ), ( ( filename[0] == '/' ) ? "" : "/" ), + filename ); DBG ( " %s", uri_string ); /* Open PXE TFTP connection */ diff --git a/src/include/ipxe/tftp.h b/src/include/ipxe/tftp.h index 38be0d4d..aecafa2a 100644 --- a/src/include/ipxe/tftp.h +++ b/src/include/ipxe/tftp.h @@ -80,6 +80,4 @@ union tftp_any { struct tftp_oack oack; }; -extern void tftp_set_request_blksize ( unsigned int blksize ); - #endif /* _IPXE_TFTP_H */ diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c index a6c64b4a..d686aac9 100644 --- a/src/net/udp/tftp.c +++ b/src/net/udp/tftp.c @@ -287,24 +287,6 @@ static int tftp_presize ( struct tftp_request *tftp, size_t filesize ) { return 0; } -/** - * TFTP requested blocksize - * - * This is treated as a global configuration parameter. - */ -static unsigned int tftp_request_blksize = TFTP_MAX_BLKSIZE; - -/** - * Set TFTP request blocksize - * - * @v blksize Requested block size - */ -void tftp_set_request_blksize ( unsigned int blksize ) { - if ( blksize < TFTP_DEFAULT_BLKSIZE ) - blksize = TFTP_DEFAULT_BLKSIZE; - tftp_request_blksize = blksize; -} - /** * MTFTP multicast receive address * @@ -345,6 +327,7 @@ static int tftp_send_rrq ( struct tftp_request *tftp ) { const char *path; size_t len; struct io_buffer *iobuf; + size_t blksize; /* Strip initial '/' if present. If we were opened via the * URI interface, then there will be an initial '/', since a @@ -370,6 +353,11 @@ static int tftp_send_rrq ( struct tftp_request *tftp ) { if ( ! iobuf ) return -ENOMEM; + /* Determine block size */ + blksize = xfer_window ( &tftp->xfer ); + if ( blksize > TFTP_MAX_BLKSIZE ) + blksize = TFTP_MAX_BLKSIZE; + /* Build request */ rrq = iob_put ( iobuf, sizeof ( *rrq ) ); rrq->opcode = htons ( TFTP_RRQ ); @@ -378,8 +366,8 @@ static int tftp_send_rrq ( struct tftp_request *tftp ) { if ( tftp->flags & TFTP_FL_RRQ_SIZES ) { iob_put ( iobuf, snprintf ( iobuf->tail, iob_tailroom ( iobuf ), - "blksize%c%d%ctsize%c0", 0, - tftp_request_blksize, 0, 0 ) + 1 ); + "blksize%c%zd%ctsize%c0", + 0, blksize, 0, 0 ) + 1 ); } if ( tftp->flags & TFTP_FL_RRQ_MULTICAST ) { iob_put ( iobuf, snprintf ( iobuf->tail,