+2004-03-12 Yoshinori K. Okuji <okuji@enbug.org>
+
+ From Sergey Matveychuk <sem@ciam.ru>:
+ * lib/device.c (get_drive_geometry): Do not open the same device
+ more than once unnecessarily.
+ (get_drive_geometry) [__FreeBSD_version >= 500040]: Use new
+ ioctl methods.
+ (get_floppy_disk_name) [__FreeBSD__ >= 4]: Use /dev/fd%d rather
+ than /dev/rfd%d.
+ (get_ide_disk_name) [__FreeBSD__ >= 4]: Use /dev/ad%d rather
+ than /dev/rad%d.
+ (get_scsi_disk_name) [__FreeBSD__ >= 4]: Use /dev/da%d rather
+ than /dev/rda%d.
+ * grub/asmstub.c (get_diskinfo): Check if ERRNO is EPERM as
+ well.
+
2004-02-28 Jeroen Dekkers <jeroen@dekkers.cx>
* docs/grub.texi (partnew): Change @var{to} to @var{len}.
/* asmstub.c - a version of shared_src/asm.S that works under Unix */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc.
+ * Copyright (C) 1999,2000,2001,2002,2004 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
if (disks[drive].flags == -1)
{
- if (read_only || errno == EACCES || errno == EROFS)
+ if (read_only || errno == EACCES || errno == EROFS || errno == EPERM)
{
disks[drive].flags = open (devname, O_RDONLY);
if (disks[drive].flags == -1)
# include <sys/ioctl.h> /* ioctl */
# include <sys/disklabel.h>
# include <sys/cdio.h> /* CDIOCCLRDEBUG */
+# if defined(__FreeBSD__)
+# include <sys/param.h>
+# if __FreeBSD_version >= 500040
+# include <sys/disk.h>
+# endif
+# endif /* __FreeBSD__ */
#endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ */
#ifdef HAVE_OPENDISK
{
int fd;
- fd = open (map[drive], O_RDONLY);
- assert (fd >= 0);
+ if (geom->flags == -1)
+ {
+ fd = open (map[drive], O_RDONLY);
+ assert (fd >= 0);
+ }
+ else
+ fd = geom->flags;
#if defined(__linux__)
/* Linux */
geom->sectors = hdg.sectors;
geom->total_sectors = nr;
- close (fd);
- return;
+ goto success;
}
+#elif defined(__FreeBSD__) && __FreeBSD_version >= 500040
+ /* FreeBSD version 5 and later */
+ {
+ u_int sector_size;
+ off_t media_size;
+ uint_t tmp;
+
+ if(ioctl (fd, DIOCGSECTORSIZE, §or_size) != 0)
+ sector_size = 512;
+
+ if (ioctl (fd, DIOCGMEDIASIZE, &media_size) != 0)
+ goto fail;
+
+ geometry->total_sectors = media_size / sector_size;
+
+ if (ioctl (fd, DIOCGFWSECTORS, &tmp) == 0)
+ geometry->sectors = tmp;
+ else
+ geometry->sectors = 63;
+ if (ioctl (fd, DIOCGFWHEADS, &tmp) == 0)
+ geometry->heads = tmp;
+ else if (geometry->total_sectors <= 63 * 1 * 1024)
+ geometry->heads = 1;
+ else if (geometry->total_sectors <= 63 * 16 * 1024)
+ geometry->heads = 16;
+ else
+ geometry->heads = 255;
+
+ geometry->cylinders = (geometry->total_sectors
+ / geometry->heads
+ / geometry->sectors);
+
+ goto success;
+ }
+
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
/* FreeBSD, NetBSD or OpenBSD */
{
geom->sectors = hdg.d_nsectors;
geom->total_sectors = hdg.d_secperunit;
- close (fd);
- return;
+ goto success;
}
#else
geom->total_sectors = geom->cylinders * geom->heads * geom->sectors;
}
- close (fd);
+ success:
+ if (geom->flags == -1)
+ close (fd);
}
#ifdef __linux__
sprintf (name, "/dev/fd%d", unit);
#elif defined(__FreeBSD__)
/* FreeBSD */
+# if __FreeBSD__ >= 4
+ sprintf (name, "/dev/fd%d", unit);
+# else /* __FreeBSD__ < 4 */
sprintf (name, "/dev/rfd%d", unit);
+# endif /* __FreeBSD__ < 4 */
#elif defined(__NetBSD__)
/* NetBSD */
/* opendisk() doesn't work for floppies. */
#elif defined(__FreeBSD__)
/* FreeBSD */
# if __FreeBSD__ >= 4
- sprintf (name, "/dev/rad%d", unit);
+ sprintf (name, "/dev/ad%d", unit);
# else /* __FreeBSD__ <= 3 */
sprintf (name, "/dev/rwd%d", unit);
# endif /* __FreeBSD__ <= 3 */
sprintf (name, "/dev/sd%d", unit);
#elif defined(__FreeBSD__)
/* FreeBSD */
+# if __FreeBSD__ >= 4
+ sprintf (name, "/dev/da%d", unit);
+# else /* __FreeBSD__ < 4 */
sprintf (name, "/dev/rda%d", unit);
+# endif /* __FreeBSD__ < 4 */
#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
/* NetBSD */
char shortname[16];