diff --git a/src/arch/i386/interface/pxe/pxe_tftp.c b/src/arch/i386/interface/pxe/pxe_tftp.c index 97077d37..715a0b61 100644 --- a/src/arch/i386/interface/pxe/pxe_tftp.c +++ b/src/arch/i386/interface/pxe/pxe_tftp.c @@ -113,12 +113,6 @@ static int pxe_tftp_xfer_deliver_iob ( struct xfer_interface *xfer __unused, /* Calculate new buffer position */ pxe_tftp.offset += len; - /* Mildly ugly hack; assume that the first non-zero seek - * indicates the block size. - */ - if ( pxe_tftp.blksize == 0 ) - pxe_tftp.blksize = pxe_tftp.offset; - /* Record maximum offset as the file size */ if ( pxe_tftp.max_offset < pxe_tftp.offset ) pxe_tftp.max_offset = pxe_tftp.offset; @@ -265,10 +259,12 @@ PXENV_EXIT_t pxenv_tftp_open ( struct s_PXENV_TFTP_OPEN *tftp_open ) { /* Wait for OACK to arrive so that we have the block size */ while ( ( ( rc = pxe_tftp.rc ) == -EINPROGRESS ) && - ( pxe_tftp.blksize == 0 ) ) { + ( pxe_tftp.max_offset == 0 ) ) { step(); } + pxe_tftp.blksize = xfer_window ( &pxe_tftp.xfer ); tftp_open->PacketSize = pxe_tftp.blksize; + DBG ( " blksize=%d", tftp_open->PacketSize ); /* EINPROGRESS is normal; we don't wait for the whole transfer */ if ( rc == -EINPROGRESS ) @@ -571,6 +567,7 @@ PXENV_EXIT_t pxenv_tftp_get_fsize ( struct s_PXENV_TFTP_GET_FSIZE step(); } tftp_get_fsize->FileSize = pxe_tftp.max_offset; + DBG ( " fsize=%d", tftp_get_fsize->FileSize ); /* EINPROGRESS is normal; we don't wait for the whole transfer */ if ( rc == -EINPROGRESS ) diff --git a/src/net/udp/tftp.c b/src/net/udp/tftp.c index b262b108..889362a1 100644 --- a/src/net/udp/tftp.c +++ b/src/net/udp/tftp.c @@ -986,11 +986,29 @@ static void tftp_xfer_close ( struct xfer_interface *xfer, int rc ) { tftp_done ( tftp, rc ); } +/** + * Check flow control window + * + * @v xfer Data transfer interface + * @ret len Length of window + */ +static size_t tftp_xfer_window ( struct xfer_interface *xfer ) { + struct tftp_request *tftp = + container_of ( xfer, struct tftp_request, xfer ); + + /* We abuse this data-xfer method to convey the blocksize to + * the caller. This really should be done using some kind of + * stat() method, but we don't yet have the facility to do + * that. + */ + return tftp->blksize; +} + /** TFTP data transfer interface operations */ static struct xfer_interface_operations tftp_xfer_operations = { .close = tftp_xfer_close, .vredirect = ignore_xfer_vredirect, - .window = unlimited_xfer_window, + .window = tftp_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = xfer_deliver_as_raw, .deliver_raw = ignore_xfer_deliver_raw,