PXENV_TFTP_READ
[PXE TFTP API]

TFTP READ. More...


Data Structures

struct  s_PXENV_TFTP_READ
 Parameter block for pxenv_tftp_read(). More...

Defines

#define PXENV_TFTP_READ   0x0022
 PXE API function code for pxenv_tftp_read().

Typedefs

typedef struct s_PXENV_TFTP_READ PXENV_TFTP_READ_t

Functions

PXENV_EXIT_t pxenv_tftp_read (struct s_PXENV_TFTP_READ *tftp_read)
 TFTP READ.


Detailed Description

TFTP READ.

Define Documentation

#define PXENV_TFTP_READ   0x0022

PXE API function code for pxenv_tftp_read().

Definition at line 636 of file pxe_api.h.

Referenced by pxe_api_call().


Typedef Documentation

Definition at line 646 of file pxe_api.h.


Function Documentation

PXENV_EXIT_t pxenv_tftp_read ( struct s_PXENV_TFTP_READ tftp_read  ) 

TFTP READ.

Parameters:
tftp_read Pointer to a struct s_PXENV_TFTP_READ
s_PXENV_TFTP_READ::Buffer Address of data buffer
Return values:
PXENV_EXIT_SUCCESS Data was read successfully
PXENV_EXIT_FAILURE Data was not read
s_PXENV_TFTP_READ::Status PXE status code
s_PXENV_TFTP_READ::PacketNumber TFTP packet number
s_PXENV_TFTP_READ::BufferSize Length of data written into buffer
Reads a single packet from a connection previously opened with pxenv_tftp_open() into the data buffer pointed to by s_PXENV_TFTP_READ::Buffer. You must have previously opened a connection with pxenv_tftp_open(). The data written into s_PXENV_TFTP_READ::Buffer is just the file data; the various network headers have already been removed.

The buffer must be large enough to contain a packet of the size negotiated via the s_PXENV_TFTP_OPEN::PacketSize field in the pxenv_tftp_open() call. It is worth noting that the PXE specification does not require the caller to fill in s_PXENV_TFTP_READ::BufferSize before calling pxenv_tftp_read(), so the PXE stack is free to ignore whatever value the caller might place there and just assume that the buffer is large enough. That said, it may be worth the caller always filling in s_PXENV_TFTP_READ::BufferSize to guard against PXE stacks that mistake it for an input parameter.

The length of the TFTP data packet will be returned via s_PXENV_TFTP_READ::BufferSize. If this length is less than the blksize negotiated via s_PXENV_TFTP_OPEN::PacketSize in the call to pxenv_tftp_open(), this indicates that the block is the last block in the file. Note that zero is a valid length for s_PXENV_TFTP_READ::BufferSize, and will occur when the length of the file is a multiple of the blksize.

The PXE specification doesn't actually state that calls to pxenv_tftp_read() will return the data packets in strict sequential order, though most PXE stacks will probably do so. The sequence number of the packet will be returned in s_PXENV_TFTP_READ::PacketNumber. The first packet in the file has a sequence number of one, not zero.

To guard against flawed PXE stacks, the caller should probably set s_PXENV_TFTP_READ::PacketNumber to one less than the expected returned value (i.e. set it to zero for the first call to pxenv_tftp_read() and then re-use the returned s_PXENV_TFTP_READ parameter block for subsequent calls without modifying s_PXENV_TFTP_READ::PacketNumber between calls). The caller should also guard against potential problems caused by flawed implementations returning the occasional duplicate packet, by checking that the value returned in s_PXENV_TFTP_READ::PacketNumber is as expected (i.e. one greater than that returned from the previous call to pxenv_tftp_read()).

On x86, you must set the s_PXE::StatusCallout field to a nonzero value before calling this function in protected mode. You cannot call this function with a 32-bit stack segment. (See the relevant implementation note for more details.)

Definition at line 365 of file pxe_tftp.c.

References pxe_tftp_connection::blkidx, pxe_tftp_connection::blksize, pxe_tftp_connection::buffer, s_PXENV_TFTP_READ::Buffer, s_PXENV_TFTP_READ::BufferSize, DBG, EINPROGRESS, pxe_tftp_connection::offset, s_SEGOFF16::offset, s_PXENV_TFTP_READ::PacketNumber, PXENV_EXIT_FAILURE, PXENV_EXIT_SUCCESS, PXENV_STATUS, pxe_tftp_connection::rc, real_to_user(), s_SEGOFF16::segment, pxe_tftp_connection::size, pxe_tftp_connection::start, s_PXENV_TFTP_READ::Status, step(), and UNULL.

Referenced by pxe_api_call().

00365                                                                      {
00366         int rc;
00367 
00368         DBG ( "PXENV_TFTP_READ to %04x:%04x",
00369               tftp_read->Buffer.segment, tftp_read->Buffer.offset );
00370 
00371         /* Read single block into buffer */
00372         pxe_tftp.buffer = real_to_user ( tftp_read->Buffer.segment,
00373                                          tftp_read->Buffer.offset );
00374         pxe_tftp.size = pxe_tftp.blksize;
00375         pxe_tftp.start = pxe_tftp.offset;
00376         while ( ( ( rc = pxe_tftp.rc ) == -EINPROGRESS ) &&
00377                 ( pxe_tftp.offset == pxe_tftp.start ) )
00378                 step();
00379         pxe_tftp.buffer = UNULL;
00380         tftp_read->BufferSize = ( pxe_tftp.offset - pxe_tftp.start );
00381         tftp_read->PacketNumber = ++pxe_tftp.blkidx;
00382 
00383         /* EINPROGRESS is normal if we haven't reached EOF yet */
00384         if ( rc == -EINPROGRESS )
00385                 rc = 0;
00386 
00387         tftp_read->Status = PXENV_STATUS ( rc );
00388         return ( rc ? PXENV_EXIT_FAILURE : PXENV_EXIT_SUCCESS );
00389 }


Generated on Tue Apr 6 20:01:59 2010 for gPXE by  doxygen 1.5.7.1