#include "pxe.h" #if GPXE static void gpxe_close_file(struct inode *inode) { struct pxe_pvt_inode *socket = PVT(inode); static __lowmem struct s_PXENV_FILE_CLOSE file_close; file_close.FileHandle = socket->tftp_remoteport; pxe_call(PXENV_FILE_CLOSE, &file_close); } /** * Get a fresh packet from a gPXE socket * @param: inode -> Inode pointer * */ static void gpxe_get_packet(struct inode *inode) { struct pxe_pvt_inode *socket = PVT(inode); static __lowmem struct s_PXENV_FILE_READ file_read; int err; while (1) { file_read.FileHandle = socket->tftp_remoteport; file_read.Buffer = FAR_PTR(packet_buf); file_read.BufferSize = PKTBUF_SIZE; err = pxe_call(PXENV_FILE_READ, &file_read); if (!err) /* successed */ break; if (file_read.Status != PXENV_STATUS_TFTP_OPEN) kaboom(); } memcpy(socket->tftp_pktbuf, packet_buf, file_read.BufferSize); socket->tftp_dataptr = socket->tftp_pktbuf; socket->tftp_bytesleft = file_read.BufferSize; socket->tftp_filepos += file_read.BufferSize; if (socket->tftp_bytesleft == 0) inode->size = socket->tftp_filepos; /* if we're done here, close the file */ if (inode->size > socket->tftp_filepos) return; /* Got EOF, close it */ socket->tftp_goteof = 1; gpxe_close_file(inode); } /** * Open a url using gpxe * * @param:inode, the inode to store our state in * @param:url, the url we want to open * * @out: open_file_t structure, stores in file->open_file * @out: the lenght of this file, stores in file->file_len * */ void gpxe_open(struct inode *inode, const char *url) { static __lowmem struct s_PXENV_FILE_OPEN file_open; static char lowurl[2*FILENAME_MAX]; struct pxe_pvt_inode *socket = PVT(inode); int err; socket->tftp_pktbuf = malloc(PKTBUF_SIZE); if (!socket->tftp_pktbuf) return; snprintf(lowurl, sizeof lowurl, "%s", url); file_open.Status = PXENV_STATUS_BAD_FUNC; file_open.FileName = FAR_PTR(lowurl); err = pxe_call(PXENV_FILE_OPEN, &file_open); if (err) return; socket->fill_buffer = gpxe_get_packet; socket->close = gpxe_close_file; socket->tftp_remoteport = file_open.FileHandle; inode->size = -1; /* This is not an error */ } #endif /* GPXE */