1 #include "pxe.h" 2 #if GPXE 3 4 static void gpxe_close_file(struct inode *inode) 5 { 6 struct pxe_pvt_inode *socket = PVT(inode); 7 static __lowmem struct s_PXENV_FILE_CLOSE file_close; 8 9 file_close.FileHandle = socket->tftp_remoteport; 10 pxe_call(PXENV_FILE_CLOSE, &file_close); 11 } 12 13 /** 14 * Get a fresh packet from a gPXE socket 15 * @param: inode -> Inode pointer 16 * 17 */ 18 static void gpxe_get_packet(struct inode *inode) 19 { 20 struct pxe_pvt_inode *socket = PVT(inode); 21 static __lowmem struct s_PXENV_FILE_READ file_read; 22 int err; 23 24 while (1) { 25 file_read.FileHandle = socket->tftp_remoteport; 26 file_read.Buffer = FAR_PTR(packet_buf); 27 file_read.BufferSize = PKTBUF_SIZE; 28 err = pxe_call(PXENV_FILE_READ, &file_read); 29 if (!err) /* successed */ 30 break; 31 32 if (file_read.Status != PXENV_STATUS_TFTP_OPEN) 33 kaboom(); 34 } 35 36 memcpy(socket->tftp_pktbuf, packet_buf, file_read.BufferSize); 37 38 socket->tftp_dataptr = socket->tftp_pktbuf; 39 socket->tftp_bytesleft = file_read.BufferSize; 40 socket->tftp_filepos += file_read.BufferSize; 41 42 if (socket->tftp_bytesleft == 0) 43 inode->size = socket->tftp_filepos; 44 45 /* if we're done here, close the file */ 46 if (inode->size > socket->tftp_filepos) 47 return; 48 49 /* Got EOF, close it */ 50 socket->tftp_goteof = 1; 51 gpxe_close_file(inode); 52 } 53 54 /** 55 * Open a url using gpxe 56 * 57 * @param:inode, the inode to store our state in 58 * @param:url, the url we want to open 59 * 60 * @out: open_file_t structure, stores in file->open_file 61 * @out: the lenght of this file, stores in file->file_len 62 * 63 */ 64 void gpxe_open(struct inode *inode, const char *url) 65 { 66 static __lowmem struct s_PXENV_FILE_OPEN file_open; 67 static char lowurl[2*FILENAME_MAX]; 68 struct pxe_pvt_inode *socket = PVT(inode); 69 int err; 70 71 socket->tftp_pktbuf = malloc(PKTBUF_SIZE); 72 if (!socket->tftp_pktbuf) 73 return; 74 75 snprintf(lowurl, sizeof lowurl, "%s", url); 76 file_open.Status = PXENV_STATUS_BAD_FUNC; 77 file_open.FileName = FAR_PTR(lowurl); 78 err = pxe_call(PXENV_FILE_OPEN, &file_open); 79 if (err) 80 return; 81 82 socket->fill_buffer = gpxe_get_packet; 83 socket->close = gpxe_close_file; 84 socket->tftp_remoteport = file_open.FileHandle; 85 inode->size = -1; /* This is not an error */ 86 } 87 88 #endif /* GPXE */ 89