[syslinux:firmware] firmware, diskio: Create struct disk_private

syslinux-bot for Matt Fleming matt.fleming at intel.com
Fri Nov 9 09:06:17 PST 2012


Commit-ID:  0376c8d3b618c53914c44dd0c90b03e1f66c4bdc
Gitweb:     http://www.syslinux.org/commit/0376c8d3b618c53914c44dd0c90b03e1f66c4bdc
Author:     Matt Fleming <matt.fleming at intel.com>
AuthorDate: Wed, 28 Mar 2012 13:57:54 +0100
Committer:  Matt Fleming <matt.fleming at intel.com>
CommitDate: Wed, 28 Mar 2012 14:38:34 +0100

firmware, diskio: Create struct disk_private

We need a way of passing firmware-specific information to the disk I/O
subsystem. Split the BIOS code into diskio_bios.c so that we don't
include any disk BIOS symbols in the EFI executable. This way, the
code in core/fs/diskio.c is firmware independent.

Signed-off-by: Matt Fleming <matt.fleming at intel.com>

---
 com32/include/syslinux/firmware.h   |    2 +
 core/fs/diskio.c                    |  388 +----------------------------------
 core/fs/{diskio.c => diskio_bios.c} |  103 ++++------
 core/fs/fs.c                        |    9 +-
 core/include/disk.h                 |   19 ++-
 core/include/fs.h                   |    1 -
 efi/Makefile                        |    3 +-
 efi/diskio.c                        |   17 +-
 efi/main.c                          |    4 +-
 9 files changed, 72 insertions(+), 474 deletions(-)

diff --git a/com32/include/syslinux/firmware.h b/com32/include/syslinux/firmware.h
index e23a1b3..ceb006f 100644
--- a/com32/include/syslinux/firmware.h
+++ b/com32/include/syslinux/firmware.h
@@ -24,6 +24,8 @@ struct adv_ops {
 	int (*write)(void);
 };
 
+struct disk_private;
+
 struct firmware {
 	void (*init)(void);
 	int (*scan_memory)(scan_memory_callback_t, void *);
diff --git a/core/fs/diskio.c b/core/fs/diskio.c
index 1644eae..9e1f63f 100644
--- a/core/fs/diskio.c
+++ b/core/fs/diskio.c
@@ -10,288 +10,6 @@
 
 #include <syslinux/firmware.h>
 
-#define RETRY_COUNT 6
-
-static inline sector_t chs_max(const struct disk *disk)
-{
-    return (sector_t)disk->secpercyl << 10;
-}
-
-static int chs_rdwr_sectors(struct disk *disk, void *buf,
-			    sector_t lba, size_t count, bool is_write)
-{
-    char *ptr = buf;
-    char *tptr;
-    size_t chunk, freeseg;
-    int sector_shift = disk->sector_shift;
-    uint32_t xlba = lba + disk->part_start; /* Truncated LBA (CHS is << 2 TB) */
-    uint32_t t;
-    uint32_t c, h, s;
-    com32sys_t ireg, oreg;
-    size_t done = 0;
-    size_t bytes;
-    int retry;
-    uint32_t maxtransfer = disk->maxtransfer;
-
-    if (lba + disk->part_start >= chs_max(disk))
-	return 0;		/* Impossible CHS request */
-
-    memset(&ireg, 0, sizeof ireg);
-
-    ireg.eax.b[1] = 0x02 + is_write;
-    ireg.edx.b[0] = disk->disk_number;
-
-    while (count) {
-	chunk = count;
-	if (chunk > maxtransfer)
-	    chunk = maxtransfer;
-
-	freeseg = (0x10000 - ((size_t)ptr & 0xffff)) >> sector_shift;
-
-	if ((size_t)buf <= 0xf0000 && freeseg) {
-	    /* Can do a direct load */
-	    tptr = ptr;
-	} else {
-	    /* Either accessing high memory or we're crossing a 64K line */
-	    tptr = core_xfer_buf;
-	    freeseg = (0x10000 - ((size_t)tptr & 0xffff)) >> sector_shift;
-	}
-	if (chunk > freeseg)
-	    chunk = freeseg;
-
-	s = xlba % disk->s;
-	t = xlba / disk->s;
-	h = t % disk->h;
-	c = t / disk->h;
-
-	if (chunk > (disk->s - s))
-	    chunk = disk->s - s;
-
-	bytes = chunk << sector_shift;
-
-	if (tptr != ptr && is_write)
-	    memcpy(tptr, ptr, bytes);
-
-	ireg.eax.b[0] = chunk;
-	ireg.ecx.b[1] = c;
-	ireg.ecx.b[0] = ((c & 0x300) >> 2) | (s+1);
-	ireg.edx.b[1] = h;
-	ireg.ebx.w[0] = OFFS(tptr);
-	ireg.es       = SEG(tptr);
-
-	retry = RETRY_COUNT;
-
-        for (;;) {
-	    if (c < 1024) {
-		dprintf("CHS[%02x]: %u @ %llu (%u/%u/%u) %04x:%04x %s %p\n",
-			ireg.edx.b[0], chunk, xlba, c, h, s+1,
-			ireg.es, ireg.ebx.w[0],
-			(ireg.eax.b[1] & 1) ? "<-" : "->",
-			ptr);
-
-		__intcall(0x13, &ireg, &oreg);
-		if (!(oreg.eflags.l & EFLAGS_CF))
-		    break;
-
-		dprintf("CHS: error AX = %04x\n", oreg.eax.w[0]);
-
-		if (retry--)
-		    continue;
-
-		/*
-		 * For any starting value, this will always end with
-		 * ..., 1, 0
-		 */
-		chunk >>= 1;
-		if (chunk) {
-		    maxtransfer = chunk;
-		    retry = RETRY_COUNT;
-		    ireg.eax.b[0] = chunk;
-		    continue;
-		}
-	    }
-
-	    printf("CHS: Error %04x %s sector %llu (%u/%u/%u)\n",
-		   oreg.eax.w[0],
-		   is_write ? "writing" : "reading",
-		   lba, c, h, s+1);
-	    return done;	/* Failure */
-	}
-
-	bytes = chunk << sector_shift;
-
-	if (tptr != ptr && !is_write)
-	    memcpy(ptr, tptr, bytes);
-
-	/* If we dropped maxtransfer, it eventually worked, so remember it */
-	disk->maxtransfer = maxtransfer;
-
-	ptr   += bytes;
-	xlba  += chunk;
-	count -= chunk;
-	done  += chunk;
-    }
-
-    return done;
-}
-
-struct edd_rdwr_packet {
-    uint16_t size;
-    uint16_t blocks;
-    far_ptr_t buf;
-    uint64_t lba;
-};
-
-static int edd_rdwr_sectors(struct disk *disk, void *buf,
-			    sector_t lba, size_t count, bool is_write)
-{
-    static __lowmem struct edd_rdwr_packet pkt;
-    char *ptr = buf;
-    char *tptr;
-    size_t chunk, freeseg;
-    int sector_shift = disk->sector_shift;
-    com32sys_t ireg, oreg, reset;
-    size_t done = 0;
-    size_t bytes;
-    int retry;
-    uint32_t maxtransfer = disk->maxtransfer;
-
-    memset(&ireg, 0, sizeof ireg);
-
-    ireg.eax.b[1] = 0x42 + is_write;
-    ireg.edx.b[0] = disk->disk_number;
-    ireg.ds       = SEG(&pkt);
-    ireg.esi.w[0] = OFFS(&pkt);
-
-    memset(&reset, 0, sizeof reset);
-
-    lba += disk->part_start;
-    while (count) {
-	chunk = count;
-	if (chunk > maxtransfer)
-	    chunk = maxtransfer;
-
-	freeseg = (0x10000 - ((size_t)ptr & 0xffff)) >> sector_shift;
-
-	if ((size_t)ptr <= 0xf0000 && freeseg) {
-	    /* Can do a direct load */
-	    tptr = ptr;
-	} else {
-	    /* Either accessing high memory or we're crossing a 64K line */
-	    tptr = core_xfer_buf;
-	    freeseg = (0x10000 - ((size_t)tptr & 0xffff)) >> sector_shift;
-	}
-	if (chunk > freeseg)
-	    chunk = freeseg;
-
-	bytes = chunk << sector_shift;
-
-	if (tptr != ptr && is_write)
-	    memcpy(tptr, ptr, bytes);
-
-	retry = RETRY_COUNT;
-
-	for (;;) {
-	    pkt.size   = sizeof pkt;
-	    pkt.blocks = chunk;
-	    pkt.buf    = FAR_PTR(tptr);
-	    pkt.lba    = lba;
-
-	    dprintf("EDD[%02x]: %u @ %llu %04x:%04x %s %p\n",
-		    ireg.edx.b[0], pkt.blocks, pkt.lba,
-		    pkt.buf.seg, pkt.buf.offs,
-		    (ireg.eax.b[1] & 1) ? "<-" : "->",
-		    ptr);
-
-	    __intcall(0x13, &ireg, &oreg);
-	    if (!(oreg.eflags.l & EFLAGS_CF))
-		break;
-
-	    dprintf("EDD: error AX = %04x\n", oreg.eax.w[0]);
-
-	    if (retry--)
-		continue;
-
-	    /*
-	     * Some systems seem to get "stuck" in an error state when
-	     * using EBIOS.  Doesn't happen when using CBIOS, which is
-	     * good, since some other systems get timeout failures
-	     * waiting for the floppy disk to spin up.
-	     */
-	    __intcall(0x13, &reset, NULL);
-
-	    /* For any starting value, this will always end with ..., 1, 0 */
-	    chunk >>= 1;
-	    if (chunk) {
-		maxtransfer = chunk;
-		retry = RETRY_COUNT;
-		continue;
-	    }
-
-	    /*
-	     * Total failure.  There are systems which identify as
-	     * EDD-capable but aren't; the known such systems return
-	     * error code AH=1 (invalid function), but let's not
-	     * assume that for now.
-	     *
-	     * Try to fall back to CHS.  If the LBA is absurd, the
-	     * chs_max() test in chs_rdwr_sectors() will catch it.
-	     */
-	    done = chs_rdwr_sectors(disk, buf, lba - disk->part_start,
-				    count, is_write);
-	    if (done == (count << sector_shift)) {
-		/* Successful, assume this is a CHS disk */
-		disk->rdwr_sectors = chs_rdwr_sectors;
-		return done;
-	    }
-	    printf("EDD: Error %04x %s sector %llu\n",
-		   oreg.eax.w[0],
-		   is_write ? "writing" : "reading",
-		   lba);
-	    return done;	/* Failure */
-	}
-
-	bytes = chunk << sector_shift;
-
-	if (tptr != ptr && !is_write)
-	    memcpy(ptr, tptr, bytes);
-
-	/* If we dropped maxtransfer, it eventually worked, so remember it */
-	disk->maxtransfer = maxtransfer;
-
-	ptr   += bytes;
-	lba   += chunk;
-	count -= chunk;
-	done  += chunk;
-    }
-    return done;
-}
-
-struct edd_disk_params {
-    uint16_t  len;
-    uint16_t  flags;
-    uint32_t  phys_c;
-    uint32_t  phys_h;
-    uint32_t  phys_s;
-    uint64_t  sectors;
-    uint16_t  sector_size;
-    far_ptr_t dpte;
-    uint16_t  devpath_key;
-    uint8_t   devpath_len;
-    uint8_t   _pad1[3];
-    char      bus_type[4];
-    char      if_type[8];
-    uint8_t   if_path[8];
-    uint8_t   dev_path[16];
-    uint8_t   _pad2;
-    uint8_t   devpath_csum;	/* Depends on devpath_len! */
-} __attribute__((packed));
-
-static inline bool is_power_of_2(uint32_t x)
-{
-    return !(x & (x-1));
-}
-
 void getoneblk(struct disk *disk, char *buf, block_t block, int block_size)
 {
     int sec_per_block = block_size / disk->sector_size;
@@ -299,116 +17,12 @@ void getoneblk(struct disk *disk, char *buf, block_t block, int block_size)
     disk->rdwr_sectors(disk, buf, block * sec_per_block, sec_per_block, 0);
 }
 
-
-struct disk *bios_disk_init(com32sys_t *regs)
-{
-    static struct disk disk;
-    static __lowmem struct edd_disk_params edd_params;
-    com32sys_t ireg, oreg;
-    uint8_t devno = regs->edx.b[0];
-    bool cdrom = regs->edx.b[1];
-    sector_t part_start = regs->ecx.l | ((sector_t)regs->ebx.l << 32);
-    uint16_t bsHeads = regs->esi.w[0];
-    uint16_t bsSecPerTrack = regs->edi.w[0];
-    uint32_t MaxTransfer = regs->ebp.l;
-    bool ebios;
-    int sector_size;
-    unsigned int hard_max_transfer;
-
-    memset(&ireg, 0, sizeof ireg);
-    ireg.edx.b[0] = devno;
-
-    if (cdrom) {
-	/*
-	 * The query functions don't work right on some CD-ROM stacks.
-	 * Known affected systems: ThinkPad T22, T23.
-	 */
-	sector_size = 2048;
-	ebios = true;
-	hard_max_transfer = 32;
-    } else {
-	sector_size = 512;
-	ebios = false;
-	hard_max_transfer = 63;
-
-	/* CBIOS parameters */
-	disk.h = bsHeads;
-	disk.s = bsSecPerTrack;
-
-	if ((int8_t)devno < 0) {
-	    /* Get hard disk geometry from BIOS */
-	    
-	    ireg.eax.b[1] = 0x08;
-	    __intcall(0x13, &ireg, &oreg);
-	    
-	    if (!(oreg.eflags.l & EFLAGS_CF)) {
-		disk.h = oreg.edx.b[1] + 1;
-		disk.s = oreg.ecx.b[0] & 63;
-	    }
-	}
-
-	/* Get EBIOS support */
-	ireg.eax.b[1] = 0x41;
-	ireg.ebx.w[0] = 0x55aa;
-	ireg.eflags.b[0] = 0x3;	/* CF set */
-
-	__intcall(0x13, &ireg, &oreg);
-	
-	if (!(oreg.eflags.l & EFLAGS_CF) &&
-	    oreg.ebx.w[0] == 0xaa55 && (oreg.ecx.b[0] & 1)) {
-	    ebios = true;
-	    hard_max_transfer = 127;
-
-	    /* Query EBIOS parameters */
-	    /* The memset() is needed once this function can be called
-	       more than once */
-	    /* memset(&edd_params, 0, sizeof edd_params);  */
-	    edd_params.len = sizeof edd_params;
-
-	    ireg.eax.b[1] = 0x48;
-	    ireg.ds = SEG(&edd_params);
-	    ireg.esi.w[0] = OFFS(&edd_params);
-	    __intcall(0x13, &ireg, &oreg);
-
-	    if (!(oreg.eflags.l & EFLAGS_CF) && oreg.eax.b[1] == 0) {
-		if (edd_params.len < sizeof edd_params)
-		    memset((char *)&edd_params + edd_params.len, 0,
-			   sizeof edd_params - edd_params.len);
-
-		if (edd_params.sector_size >= 512 &&
-		    is_power_of_2(edd_params.sector_size))
-		    sector_size = edd_params.sector_size;
-	    }
-	}
-
-    }
-
-    disk.disk_number   = devno;
-    disk.sector_size   = sector_size;
-    disk.sector_shift  = ilog2(sector_size);
-    disk.part_start    = part_start;
-    disk.secpercyl     = disk.h * disk.s;
-    disk.rdwr_sectors  = ebios ? edd_rdwr_sectors : chs_rdwr_sectors;
-
-    if (!MaxTransfer || MaxTransfer > hard_max_transfer)
-	MaxTransfer = hard_max_transfer;
-
-    disk.maxtransfer   = MaxTransfer;
-
-    dprintf("disk %02x cdrom %d type %d sector %u/%u offset %llu limit %u\n",
-	    devno, cdrom, ebios, sector_size, disk.sector_shift,
-	    part_start, disk.maxtransfer);
-
-    return &disk;
-}
-
-
 /*
  * Initialize the device structure.
  *
  * NOTE: the disk cache needs to be revamped to support multiple devices...
  */
-struct device * device_init(void *args)
+struct device * device_init(struct disk_private *args)
 {
     static struct device dev;
     static __hugebss char diskcache[128*1024];
diff --git a/core/fs/diskio.c b/core/fs/diskio_bios.c
similarity index 92%
copy from core/fs/diskio.c
copy to core/fs/diskio_bios.c
index 1644eae..52d2017 100644
--- a/core/fs/diskio.c
+++ b/core/fs/diskio_bios.c
@@ -1,15 +1,8 @@
-#include <dprintf.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdbool.h>
-#include <klibc/compiler.h>
 #include <core.h>
+#include <com32.h>
 #include <fs.h>
-#include <disk.h>
 #include <ilog2.h>
 
-#include <syslinux/firmware.h>
-
 #define RETRY_COUNT 6
 
 static inline sector_t chs_max(const struct disk *disk)
@@ -17,6 +10,38 @@ static inline sector_t chs_max(const struct disk *disk)
     return (sector_t)disk->secpercyl << 10;
 }
 
+struct edd_rdwr_packet {
+    uint16_t size;
+    uint16_t blocks;
+    far_ptr_t buf;
+    uint64_t lba;
+};
+
+struct edd_disk_params {
+    uint16_t  len;
+    uint16_t  flags;
+    uint32_t  phys_c;
+    uint32_t  phys_h;
+    uint32_t  phys_s;
+    uint64_t  sectors;
+    uint16_t  sector_size;
+    far_ptr_t dpte;
+    uint16_t  devpath_key;
+    uint8_t   devpath_len;
+    uint8_t   _pad1[3];
+    char      bus_type[4];
+    char      if_type[8];
+    uint8_t   if_path[8];
+    uint8_t   dev_path[16];
+    uint8_t   _pad2;
+    uint8_t   devpath_csum;	/* Depends on devpath_len! */
+} __attribute__((packed));
+
+static inline bool is_power_of_2(uint32_t x)
+{
+    return !(x & (x-1));
+}
+
 static int chs_rdwr_sectors(struct disk *disk, void *buf,
 			    sector_t lba, size_t count, bool is_write)
 {
@@ -135,13 +160,6 @@ static int chs_rdwr_sectors(struct disk *disk, void *buf,
     return done;
 }
 
-struct edd_rdwr_packet {
-    uint16_t size;
-    uint16_t blocks;
-    far_ptr_t buf;
-    uint64_t lba;
-};
-
 static int edd_rdwr_sectors(struct disk *disk, void *buf,
 			    sector_t lba, size_t count, bool is_write)
 {
@@ -267,42 +285,10 @@ static int edd_rdwr_sectors(struct disk *disk, void *buf,
     return done;
 }
 
-struct edd_disk_params {
-    uint16_t  len;
-    uint16_t  flags;
-    uint32_t  phys_c;
-    uint32_t  phys_h;
-    uint32_t  phys_s;
-    uint64_t  sectors;
-    uint16_t  sector_size;
-    far_ptr_t dpte;
-    uint16_t  devpath_key;
-    uint8_t   devpath_len;
-    uint8_t   _pad1[3];
-    char      bus_type[4];
-    char      if_type[8];
-    uint8_t   if_path[8];
-    uint8_t   dev_path[16];
-    uint8_t   _pad2;
-    uint8_t   devpath_csum;	/* Depends on devpath_len! */
-} __attribute__((packed));
-
-static inline bool is_power_of_2(uint32_t x)
-{
-    return !(x & (x-1));
-}
-
-void getoneblk(struct disk *disk, char *buf, block_t block, int block_size)
-{
-    int sec_per_block = block_size / disk->sector_size;
-
-    disk->rdwr_sectors(disk, buf, block * sec_per_block, sec_per_block, 0);
-}
-
-
-struct disk *bios_disk_init(com32sys_t *regs)
+struct disk *bios_disk_init(struct disk_private *priv)
 {
     static struct disk disk;
+    com32sys_t *regs = priv->regs;
     static __lowmem struct edd_disk_params edd_params;
     com32sys_t ireg, oreg;
     uint8_t devno = regs->edx.b[0];
@@ -399,23 +385,14 @@ struct disk *bios_disk_init(com32sys_t *regs)
 	    devno, cdrom, ebios, sector_size, disk.sector_shift,
 	    part_start, disk.maxtransfer);
 
+    disk.private = priv;
     return &disk;
 }
 
-
-/*
- * Initialize the device structure.
- *
- * NOTE: the disk cache needs to be revamped to support multiple devices...
- */
-struct device * device_init(void *args)
+void pm_fs_init(com32sys_t *regs)
 {
-    static struct device dev;
-    static __hugebss char diskcache[128*1024];
-
-    dev.disk = firmware->disk_init(args);
-    dev.cache_data = diskcache;
-    dev.cache_size = sizeof diskcache;
+	static struct disk_private priv;
 
-    return &dev;
+	priv.regs = regs;
+	fs_init((const struct fs_ops **)regs->eax.l, &priv);
 }
diff --git a/core/fs/fs.c b/core/fs/fs.c
index c2d17dc..e6f3537 100644
--- a/core/fs/fs.c
+++ b/core/fs/fs.c
@@ -433,7 +433,7 @@ void pm_close_file(com32sys_t *regs)
  */
 __bss16 uint16_t SectorSize, SectorShift;
 
-void fs_init(const struct fs_ops **ops, void *args)
+void fs_init(const struct fs_ops **ops, struct disk_private *priv)
 {
     static struct fs_info fs;	/* The actual filesystem buffer */
     int blk_shift = -1;
@@ -457,7 +457,7 @@ void fs_init(const struct fs_ops **ops, void *args)
 	    fs.fs_dev = NULL;
 	} else {
 	    if (!dev)
-		dev = device_init(args);
+		dev = device_init(priv);
 	    fs.fs_dev = dev;
 	}
 	/* invoke the fs-specific init code */
@@ -489,8 +489,3 @@ void fs_init(const struct fs_ops **ops, void *args)
     SectorShift = fs.sector_shift;
     SectorSize  = fs.sector_size;
 }
-
-void pm_fs_init(com32sys_t *regs)
-{
-	fs_init(regs->eax.l, regs);
-}
diff --git a/core/include/disk.h b/core/include/disk.h
index d0d50ed..2aec11c 100644
--- a/core/include/disk.h
+++ b/core/include/disk.h
@@ -4,16 +4,29 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <stdbool.h>
+#include <core.h>
 
 typedef uint64_t sector_t;
 typedef uint64_t block_t;
 
+#ifdef SYSLINUX_EFI
+struct disk_private {
+	EFI_HANDLE dev_handle;
+	EFI_BLOCK_IO *bio;
+	EFI_DISK_IO *dio;
+};
+#else
+struct disk_private {
+	com32sys_t *regs;
+};
+#endif
+
 /*
  * struct disk: contains the information about a specific disk and also
  * contains the I/O function.
  */
 struct disk {
-    void *private;		/* Firmware-private disk info */
+    struct disk_private *private;	/* Firmware-private disk info */
     unsigned int disk_number;	/* in BIOS style */
     unsigned int sector_size;	/* gener512B or 2048B */
     unsigned int sector_shift;
@@ -32,7 +45,7 @@ extern void read_sectors(char *, sector_t, int);
 extern void getoneblk(struct disk *, char *, block_t, int);
 
 /* diskio.c */
-struct disk *bios_disk_init(com32sys_t *);
-struct device *device_init(void *);
+struct disk *bios_disk_init(struct disk_private *);
+struct device *device_init(struct disk_private *);
 
 #endif /* DISK_H */
diff --git a/core/include/fs.h b/core/include/fs.h
index a554a46..decada6 100644
--- a/core/include/fs.h
+++ b/core/include/fs.h
@@ -181,7 +181,6 @@ static inline struct file *handle_to_file(uint16_t handle)
 
 extern char *PATH;
 
-/* fs.c */
 void pm_mangle_name(com32sys_t *);
 void pm_searchdir(com32sys_t *);
 void mangle_name(char *, const char *);
diff --git a/efi/Makefile b/efi/Makefile
index b67af60..338f451 100644
--- a/efi/Makefile
+++ b/efi/Makefile
@@ -20,7 +20,8 @@ CORE_COBJ := $(patsubst %.c,%.o,$(CORE_CSRC))
 
 # Don't include console objects
 CORE_OBJS = $(filter-out $(core)/hello.o $(core)/rawcon.o \
-	$(core)/plaincon.o $(core)/strcasecmp.o $(core)/bios.o,$(CORE_COBJ))
+	$(core)/plaincon.o $(core)/strcasecmp.o $(core)/bios.o \
+	$(core)/fs/diskio_bios.o,$(CORE_COBJ))
 LIB_OBJS = $(addprefix $(com32)/lib/,$(MINLIBOBJS))
 
 CSRC = $(wildcard *.c)
diff --git a/efi/diskio.c b/efi/diskio.c
index 89779a5..5e7898a 100644
--- a/efi/diskio.c
+++ b/efi/diskio.c
@@ -5,11 +5,6 @@
 #include <dprintf.h>
 #include "efi.h"
 
-struct disk_efi_private {
-	EFI_BLOCK_IO *bio;
-	EFI_DISK_IO *dio;
-};
-
 static inline EFI_STATUS read_blocks(EFI_BLOCK_IO *bio, uint32_t id, 
 				     sector_t lba, UINTN bytes, void *buf)
 {
@@ -25,7 +20,7 @@ static inline EFI_STATUS write_blocks(EFI_BLOCK_IO *bio, uint32_t id,
 static int efi_rdwr_sectors(struct disk *disk, void *buf,
 			    sector_t lba, size_t count, bool is_write)
 {
-	struct disk_efi_private *priv = disk->private;
+	struct disk_private *priv = disk->private;
 	EFI_BLOCK_IO *bio = priv->bio;
 	EFI_DISK_IO *dio = priv->dio;
 	EFI_STATUS status;
@@ -45,10 +40,10 @@ static int efi_rdwr_sectors(struct disk *disk, void *buf,
 	return count << disk->sector_shift;
 }
 
-struct disk *efi_disk_init(EFI_HANDLE handle)
+struct disk *efi_disk_init(struct disk_private *priv)
 {
-    static struct disk_efi_private priv;
     static struct disk disk;
+    EFI_HANDLE handle = priv->dev_handle;
     unsigned int hard_max_transfer;
     EFI_BLOCK_IO *bio;
     EFI_DISK_IO *dio;
@@ -78,9 +73,9 @@ struct disk *efi_disk_init(EFI_HANDLE handle)
     Print(L"sector_size=%d, disk_number=%d\n", disk.sector_size,
 	  disk.disk_number);
 
-    priv.bio = bio;
-    priv.dio = dio;
-    disk.private = &priv;
+    priv->bio = bio;
+    priv->dio = dio;
+    disk.private = priv;
 #if 0
 
     disk.part_start    = part_start;
diff --git a/efi/main.c b/efi/main.c
index e01b35e..9893767 100644
--- a/efi/main.c
+++ b/efi/main.c
@@ -687,6 +687,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *table)
 	EFI_STATUS status = EFI_SUCCESS;
 	struct fs_ops *ops[] = { &vfat_fs_ops, NULL };
 	unsigned long len = (unsigned long)__bss_end - (unsigned long)__bss_start;
+	static struct disk_private priv;
 
 	memset(__bss_start, 0, len);
 	InitializeLib(image, table);
@@ -711,7 +712,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *table)
 	/* TODO: once all errors are captured in efi_errno, bail out if necessary */
 
 	/* XXX figure out what file system we're on */
-	fs_init(ops, info->DeviceHandle);
+	priv.dev_handle = info->DeviceHandle;
+	fs_init(ops, &priv);
 	load_env32();
 
 out:


More information about the Syslinux-commits mailing list