reorganized grub-emu sources to suite upcoming automake build system

This commit is contained in:
BVK Chaitanya 2010-04-27 10:50:28 +05:30
parent bc4a2d832b
commit 840b61d8f0
20 changed files with 378 additions and 22 deletions

View file

@ -1,384 +0,0 @@
/* console.c -- Ncurses console for GRUB. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2005,2007,2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
/* For compatibility. */
#ifndef A_NORMAL
# define A_NORMAL 0
#endif /* ! A_NORMAL */
#ifndef A_STANDOUT
# define A_STANDOUT 0
#endif /* ! A_STANDOUT */
#include <grub/util/console.h>
#include <grub/term.h>
#include <grub/types.h>
#if defined(HAVE_NCURSES_CURSES_H)
# include <ncurses/curses.h>
#elif defined(HAVE_NCURSES_H)
# include <ncurses.h>
#elif defined(HAVE_CURSES_H)
# include <curses.h>
#endif
static int grub_console_attr = A_NORMAL;
grub_uint8_t grub_console_cur_color = 7;
static grub_uint8_t grub_console_standard_color = 0x7;
static grub_uint8_t grub_console_normal_color = 0x7;
static grub_uint8_t grub_console_highlight_color = 0x70;
#define NUM_COLORS 8
static grub_uint8_t color_map[NUM_COLORS] =
{
COLOR_BLACK,
COLOR_BLUE,
COLOR_GREEN,
COLOR_CYAN,
COLOR_RED,
COLOR_MAGENTA,
COLOR_YELLOW,
COLOR_WHITE
};
static int use_color;
static void
grub_ncurses_putchar (grub_uint32_t c)
{
/* Better than nothing. */
switch (c)
{
case GRUB_TERM_DISP_LEFT:
c = '<';
break;
case GRUB_TERM_DISP_UP:
c = '^';
break;
case GRUB_TERM_DISP_RIGHT:
c = '>';
break;
case GRUB_TERM_DISP_DOWN:
c = 'v';
break;
case GRUB_TERM_DISP_HLINE:
c = '-';
break;
case GRUB_TERM_DISP_VLINE:
c = '|';
break;
case GRUB_TERM_DISP_UL:
case GRUB_TERM_DISP_UR:
case GRUB_TERM_DISP_LL:
case GRUB_TERM_DISP_LR:
c = '+';
break;
default:
/* ncurses does not support Unicode. */
if (c > 0x7f)
c = '?';
break;
}
addch (c | grub_console_attr);
}
static grub_ssize_t
grub_ncurses_getcharwidth (grub_uint32_t code __attribute__ ((unused)))
{
return 1;
}
static void
grub_ncurses_setcolorstate (grub_term_color_state state)
{
switch (state)
{
case GRUB_TERM_COLOR_STANDARD:
grub_console_cur_color = grub_console_standard_color;
grub_console_attr = A_NORMAL;
break;
case GRUB_TERM_COLOR_NORMAL:
grub_console_cur_color = grub_console_normal_color;
grub_console_attr = A_NORMAL;
break;
case GRUB_TERM_COLOR_HIGHLIGHT:
grub_console_cur_color = grub_console_highlight_color;
grub_console_attr = A_STANDOUT;
break;
default:
break;
}
if (use_color)
{
grub_uint8_t fg, bg;
fg = (grub_console_cur_color & 7);
bg = (grub_console_cur_color >> 4) & 7;
grub_console_attr = (grub_console_cur_color & 8) ? A_BOLD : A_NORMAL;
color_set ((bg << 3) + fg, 0);
}
}
/* XXX: This function is never called. */
static void
grub_ncurses_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
{
grub_console_normal_color = normal_color;
grub_console_highlight_color = highlight_color;
}
static void
grub_ncurses_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
{
*normal_color = grub_console_normal_color;
*highlight_color = grub_console_highlight_color;
}
static int saved_char = ERR;
static int
grub_ncurses_checkkey (void)
{
int c;
/* Check for SAVED_CHAR. This should not be true, because this
means checkkey is called twice continuously. */
if (saved_char != ERR)
return saved_char;
wtimeout (stdscr, 100);
c = getch ();
/* If C is not ERR, then put it back in the input queue. */
if (c != ERR)
{
saved_char = c;
return c;
}
return -1;
}
static int
grub_ncurses_getkey (void)
{
int c;
/* If checkkey has already got a character, then return it. */
if (saved_char != ERR)
{
c = saved_char;
saved_char = ERR;
}
else
{
wtimeout (stdscr, -1);
c = getch ();
}
switch (c)
{
case KEY_LEFT:
c = 2;
break;
case KEY_RIGHT:
c = 6;
break;
case KEY_UP:
c = 16;
break;
case KEY_DOWN:
c = 14;
break;
case KEY_IC:
c = 24;
break;
case KEY_DC:
c = 4;
break;
case KEY_BACKSPACE:
/* XXX: For some reason ncurses on xterm does not return
KEY_BACKSPACE. */
case 127:
c = 8;
break;
case KEY_HOME:
c = 1;
break;
case KEY_END:
c = 5;
break;
case KEY_NPAGE:
c = 3;
break;
case KEY_PPAGE:
c = 7;
break;
}
return c;
}
static grub_uint16_t
grub_ncurses_getxy (void)
{
int x;
int y;
getyx (stdscr, y, x);
return (x << 8) | y;
}
static grub_uint16_t
grub_ncurses_getwh (void)
{
int x;
int y;
getmaxyx (stdscr, y, x);
return (x << 8) | y;
}
static void
grub_ncurses_gotoxy (grub_uint8_t x, grub_uint8_t y)
{
move (y, x);
}
static void
grub_ncurses_cls (void)
{
clear ();
refresh ();
}
static void
grub_ncurses_setcursor (int on)
{
curs_set (on ? 1 : 0);
}
static void
grub_ncurses_refresh (void)
{
refresh ();
}
static grub_err_t
grub_ncurses_init (void)
{
initscr ();
raw ();
noecho ();
scrollok (stdscr, TRUE);
nonl ();
intrflush (stdscr, FALSE);
keypad (stdscr, TRUE);
if (has_colors ())
{
start_color ();
if ((COLORS >= NUM_COLORS) && (COLOR_PAIRS >= NUM_COLORS * NUM_COLORS))
{
int i, j, n;
n = 0;
for (i = 0; i < NUM_COLORS; i++)
for (j = 0; j < NUM_COLORS; j++)
init_pair(n++, color_map[j], color_map[i]);
use_color = 1;
}
}
return 0;
}
static grub_err_t
grub_ncurses_fini (void)
{
endwin ();
return 0;
}
static struct grub_term_input grub_ncurses_term_input =
{
.name = "console",
.checkkey = grub_ncurses_checkkey,
.getkey = grub_ncurses_getkey,
};
static struct grub_term_output grub_ncurses_term_output =
{
.name = "console",
.init = grub_ncurses_init,
.fini = grub_ncurses_fini,
.putchar = grub_ncurses_putchar,
.getcharwidth = grub_ncurses_getcharwidth,
.getxy = grub_ncurses_getxy,
.getwh = grub_ncurses_getwh,
.gotoxy = grub_ncurses_gotoxy,
.cls = grub_ncurses_cls,
.setcolorstate = grub_ncurses_setcolorstate,
.setcolor = grub_ncurses_setcolor,
.getcolor = grub_ncurses_getcolor,
.setcursor = grub_ncurses_setcursor,
.refresh = grub_ncurses_refresh
};
void
grub_console_init (void)
{
grub_term_register_output ("console", &grub_ncurses_term_output);
grub_term_register_input ("console", &grub_ncurses_term_input);
}
void
grub_console_fini (void)
{
grub_ncurses_fini ();
}

View file

@ -1,640 +0,0 @@
/* getroot.c - Get root device */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2000,2001,2002,2003,2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>
#ifdef __CYGWIN__
# include <sys/fcntl.h>
# include <sys/cygwin.h>
# include <limits.h>
# define DEV_CYGDRIVE_MAJOR 98
#endif
#ifdef __GNU__
#include <hurd.h>
#include <hurd/lookup.h>
#include <hurd/fs.h>
#endif
#include <grub/util/misc.h>
#include <grub/util/hostdisk.h>
#include <grub/util/getroot.h>
static void
strip_extra_slashes (char *dir)
{
char *p = dir;
while ((p = strchr (p, '/')) != 0)
{
if (p[1] == '/')
{
memmove (p, p + 1, strlen (p));
continue;
}
else if (p[1] == '\0')
{
if (p > dir)
p[0] = '\0';
break;
}
p++;
}
}
static char *
xgetcwd (void)
{
size_t size = 10;
char *path;
path = xmalloc (size);
while (! getcwd (path, size))
{
size <<= 1;
path = xrealloc (path, size);
}
return path;
}
#ifdef __CYGWIN__
/* Convert POSIX path to Win32 path,
remove drive letter, replace backslashes. */
static char *
get_win32_path (const char *path)
{
char winpath[PATH_MAX];
cygwin_conv_to_full_win32_path (path, winpath);
int len = strlen (winpath);
if (len > 2 && winpath[1] == ':')
{
len -= 2;
memmove (winpath, winpath + 2, len + 1);
}
int i;
for (i = 0; i < len; i++)
if (winpath[i] == '\\')
winpath[i] = '/';
return xstrdup (winpath);
}
#endif
char *
grub_get_prefix (const char *dir)
{
char *saved_cwd;
char *abs_dir, *prev_dir;
char *prefix;
struct stat st, prev_st;
/* Save the current directory. */
saved_cwd = xgetcwd ();
if (chdir (dir) < 0)
grub_util_error ("cannot change directory to `%s'", dir);
abs_dir = xgetcwd ();
strip_extra_slashes (abs_dir);
prev_dir = xstrdup (abs_dir);
if (stat (".", &prev_st) < 0)
grub_util_error ("cannot stat `%s'", dir);
if (! S_ISDIR (prev_st.st_mode))
grub_util_error ("`%s' is not a directory", dir);
while (1)
{
if (chdir ("..") < 0)
grub_util_error ("cannot change directory to the parent");
if (stat (".", &st) < 0)
grub_util_error ("cannot stat current directory");
if (! S_ISDIR (st.st_mode))
grub_util_error ("current directory is not a directory???");
if (prev_st.st_dev != st.st_dev || prev_st.st_ino == st.st_ino)
break;
free (prev_dir);
prev_dir = xgetcwd ();
prev_st = st;
}
strip_extra_slashes (prev_dir);
prefix = xmalloc (strlen (abs_dir) - strlen (prev_dir) + 2);
prefix[0] = '/';
strcpy (prefix + 1, abs_dir + strlen (prev_dir));
strip_extra_slashes (prefix);
if (chdir (saved_cwd) < 0)
grub_util_error ("cannot change directory to `%s'", dir);
#ifdef __CYGWIN__
if (st.st_dev != (DEV_CYGDRIVE_MAJOR << 16))
{
/* Reached some mount point not below /cygdrive.
GRUB does not know Cygwin's emulated mounts,
convert to Win32 path. */
grub_util_info ("Cygwin prefix = %s", prefix);
char * wprefix = get_win32_path (prefix);
free (prefix);
prefix = wprefix;
}
#endif
free (saved_cwd);
free (abs_dir);
free (prev_dir);
grub_util_info ("prefix = %s", prefix);
return prefix;
}
#ifdef __MINGW32__
static char *
find_root_device (const char *dir __attribute__ ((unused)),
dev_t dev __attribute__ ((unused)))
{
return 0;
}
#elif ! defined(__CYGWIN__)
static char *
find_root_device (const char *dir, dev_t dev)
{
DIR *dp;
char *saved_cwd;
struct dirent *ent;
dp = opendir (dir);
if (! dp)
return 0;
saved_cwd = xgetcwd ();
grub_util_info ("changing current directory to %s", dir);
if (chdir (dir) < 0)
{
free (saved_cwd);
closedir (dp);
return 0;
}
while ((ent = readdir (dp)) != 0)
{
struct stat st;
/* Avoid:
- dotfiles (like "/dev/.tmp.md0") since they could be duplicates.
- dotdirs (like "/dev/.static") since they could contain duplicates. */
if (ent->d_name[0] == '.')
continue;
if (lstat (ent->d_name, &st) < 0)
/* Ignore any error. */
continue;
if (S_ISLNK (st.st_mode))
/* Don't follow symbolic links. */
continue;
if (S_ISDIR (st.st_mode))
{
/* Find it recursively. */
char *res;
res = find_root_device (ent->d_name, dev);
if (res)
{
if (chdir (saved_cwd) < 0)
grub_util_error ("cannot restore the original directory");
free (saved_cwd);
closedir (dp);
return res;
}
}
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__)
if (S_ISCHR (st.st_mode) && st.st_rdev == dev)
#else
if (S_ISBLK (st.st_mode) && st.st_rdev == dev)
#endif
{
#ifdef __linux__
/* Skip device names like /dev/dm-0, which are short-hand aliases
to more descriptive device names, e.g. those under /dev/mapper */
if (ent->d_name[0] == 'd' &&
ent->d_name[1] == 'm' &&
ent->d_name[2] == '-' &&
ent->d_name[3] >= '0' &&
ent->d_name[3] <= '9')
continue;
#endif
/* Found! */
char *res;
char *cwd;
#if defined(__NetBSD__)
/* Convert this block device to its character (raw) device. */
const char *template = "%s/r%s";
#else
/* Keep the device name as it is. */
const char *template = "%s/%s";
#endif
cwd = xgetcwd ();
res = xmalloc (strlen (cwd) + strlen (ent->d_name) + 3);
sprintf (res, template, cwd, ent->d_name);
strip_extra_slashes (res);
free (cwd);
/* /dev/root is not a real block device keep looking, takes care
of situation where root filesystem is on the same partition as
grub files */
if (strcmp(res, "/dev/root") == 0)
continue;
if (chdir (saved_cwd) < 0)
grub_util_error ("cannot restore the original directory");
free (saved_cwd);
closedir (dp);
return res;
}
}
if (chdir (saved_cwd) < 0)
grub_util_error ("cannot restore the original directory");
free (saved_cwd);
closedir (dp);
return 0;
}
#else /* __CYGWIN__ */
/* Read drive/partition serial number from mbr/boot sector,
return 0 on read error, ~0 on unknown serial. */
static unsigned
get_bootsec_serial (const char *os_dev, int mbr)
{
/* Read boot sector. */
int fd = open (os_dev, O_RDONLY);
if (fd < 0)
return 0;
unsigned char buf[0x200];
int n = read (fd, buf, sizeof (buf));
close (fd);
if (n != sizeof(buf))
return 0;
/* Check signature. */
if (!(buf[0x1fe] == 0x55 && buf[0x1ff] == 0xaa))
return ~0;
/* Serial number offset depends on boot sector type. */
if (mbr)
n = 0x1b8;
else if (memcmp (buf + 0x03, "NTFS", 4) == 0)
n = 0x048;
else if (memcmp (buf + 0x52, "FAT32", 5) == 0)
n = 0x043;
else if (memcmp (buf + 0x36, "FAT", 3) == 0)
n = 0x027;
else
return ~0;
unsigned serial = *(unsigned *)(buf + n);
if (serial == 0)
return ~0;
return serial;
}
static char *
find_cygwin_root_device (const char *path, dev_t dev)
{
/* No root device for /cygdrive. */
if (dev == (DEV_CYGDRIVE_MAJOR << 16))
return 0;
/* Convert to full POSIX and Win32 path. */
char fullpath[PATH_MAX], winpath[PATH_MAX];
cygwin_conv_to_full_posix_path (path, fullpath);
cygwin_conv_to_full_win32_path (fullpath, winpath);
/* If identical, this is no real filesystem path. */
if (strcmp (fullpath, winpath) == 0)
return 0;
/* Check for floppy drive letter. */
if (winpath[0] && winpath[1] == ':' && strchr ("AaBb", winpath[0]))
return xstrdup (strchr ("Aa", winpath[0]) ? "/dev/fd0" : "/dev/fd1");
/* Cygwin returns the partition serial number in stat.st_dev.
This is never identical to the device number of the emulated
/dev/sdXN device, so above find_root_device () does not work.
Search the partition with the same serial in boot sector instead. */
char devpath[sizeof ("/dev/sda15") + 13]; /* Size + Paranoia. */
int d;
for (d = 'a'; d <= 'z'; d++)
{
sprintf (devpath, "/dev/sd%c", d);
if (get_bootsec_serial (devpath, 1) == 0)
continue;
int p;
for (p = 1; p <= 15; p++)
{
sprintf (devpath, "/dev/sd%c%d", d, p);
unsigned ser = get_bootsec_serial (devpath, 0);
if (ser == 0)
break;
if (ser != (unsigned)~0 && dev == (dev_t)ser)
return xstrdup (devpath);
}
}
return 0;
}
#endif /* __CYGWIN__ */
char *
grub_guess_root_device (const char *dir)
{
char *os_dev;
#ifdef __GNU__
file_t file;
mach_port_t *ports;
int *ints;
loff_t *offsets;
char *data;
error_t err;
mach_msg_type_number_t num_ports = 0, num_ints = 0, num_offsets = 0, data_len = 0;
size_t name_len;
file = file_name_lookup (dir, 0, 0);
if (file == MACH_PORT_NULL)
return 0;
err = file_get_storage_info (file,
&ports, &num_ports,
&ints, &num_ints,
&offsets, &num_offsets,
&data, &data_len);
if (num_ints < 1)
grub_util_error ("Storage info for `%s' does not include type", dir);
if (ints[0] != STORAGE_DEVICE)
grub_util_error ("Filesystem of `%s' is not stored on local disk", dir);
if (num_ints < 5)
grub_util_error ("Storage info for `%s' does not include name", dir);
name_len = ints[4];
if (name_len < data_len)
grub_util_error ("Bogus name length for storage info for `%s'", dir);
if (data[name_len - 1] != '\0')
grub_util_error ("Storage name for `%s' not NUL-terminated", dir);
os_dev = xmalloc (strlen ("/dev/") + data_len);
memcpy (os_dev, "/dev/", strlen ("/dev/"));
memcpy (os_dev + strlen ("/dev/"), data, data_len);
if (ports && num_ports > 0)
{
mach_msg_type_number_t i;
for (i = 0; i < num_ports; i++)
{
mach_port_t port = ports[i];
if (port != MACH_PORT_NULL)
mach_port_deallocate (mach_task_self(), port);
}
munmap ((caddr_t) ports, num_ports * sizeof (*ports));
}
if (ints && num_ints > 0)
munmap ((caddr_t) ints, num_ints * sizeof (*ints));
if (offsets && num_offsets > 0)
munmap ((caddr_t) offsets, num_offsets * sizeof (*offsets));
if (data && data_len > 0)
munmap (data, data_len);
mach_port_deallocate (mach_task_self (), file);
#else /* !__GNU__ */
struct stat st;
if (stat (dir, &st) < 0)
grub_util_error ("cannot stat `%s'", dir);
#ifdef __CYGWIN__
/* Cygwin specific function. */
os_dev = find_cygwin_root_device (dir, st.st_dev);
#else
/* This might be truly slow, but is there any better way? */
os_dev = find_root_device ("/dev", st.st_dev);
#endif
#endif /* !__GNU__ */
return os_dev;
}
static int
grub_util_is_dmraid (const char *os_dev)
{
if (! strncmp (os_dev, "/dev/mapper/nvidia_", 19))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/isw_", 16))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/hpt37x_", 19))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/hpt45x_", 19))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/via_", 16))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/lsi_", 16))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/pdc_", 16))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/jmicron_", 20))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/asr_", 16))
return 1;
else if (! strncmp (os_dev, "/dev/mapper/sil_", 16))
return 1;
return 0;
}
int
grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused)))
{
#ifdef __linux__
/* Check for LVM. */
if (!strncmp (os_dev, "/dev/mapper/", 12)
&& ! grub_util_is_dmraid (os_dev)
&& strncmp (os_dev, "/dev/mapper/mpath", 17) != 0)
return GRUB_DEV_ABSTRACTION_LVM;
/* Check for RAID. */
if (!strncmp (os_dev, "/dev/md", 7))
return GRUB_DEV_ABSTRACTION_RAID;
#endif
/* No abstraction found. */
return GRUB_DEV_ABSTRACTION_NONE;
}
char *
grub_util_get_grub_dev (const char *os_dev)
{
char *grub_dev;
switch (grub_util_get_dev_abstraction (os_dev))
{
case GRUB_DEV_ABSTRACTION_LVM:
{
unsigned short i, len;
grub_size_t offset = sizeof ("/dev/mapper/") - 1;
len = strlen (os_dev) - offset + 1;
grub_dev = xmalloc (len);
for (i = 0; i < len; i++, offset++)
{
grub_dev[i] = os_dev[offset];
if (os_dev[offset] == '-' && os_dev[offset + 1] == '-')
offset++;
}
}
break;
case GRUB_DEV_ABSTRACTION_RAID:
if (os_dev[7] == '_' && os_dev[8] == 'd')
{
/* This a partitionable RAID device of the form /dev/md_dNNpMM. */
char *p, *q;
p = strdup (os_dev + sizeof ("/dev/md_d") - 1);
q = strchr (p, 'p');
if (q)
*q = ',';
grub_dev = xasprintf ("md%s", p);
free (p);
}
else if (os_dev[7] == '/' && os_dev[8] == 'd')
{
/* This a partitionable RAID device of the form /dev/md/dNNpMM. */
char *p, *q;
p = strdup (os_dev + sizeof ("/dev/md/d") - 1);
q = strchr (p, 'p');
if (q)
*q = ',';
grub_dev = xasprintf ("md%s", p);
free (p);
}
else if (os_dev[7] >= '0' && os_dev[7] <= '9')
{
char *p , *q;
p = strdup (os_dev + sizeof ("/dev/md") - 1);
q = strchr (p, 'p');
if (q)
*q = ',';
grub_dev = xasprintf ("md%s", p);
free (p);
}
else if (os_dev[7] == '/' && os_dev[8] >= '0' && os_dev[8] <= '9')
{
char *p , *q;
p = strdup (os_dev + sizeof ("/dev/md/") - 1);
q = strchr (p, 'p');
if (q)
*q = ',';
grub_dev = xasprintf ("md%s", p);
free (p);
}
else
grub_util_error ("unknown kind of RAID device `%s'", os_dev);
break;
default: /* GRUB_DEV_ABSTRACTION_NONE */
grub_dev = grub_util_biosdisk_get_grub_dev (os_dev);
}
return grub_dev;
}
const char *
grub_util_check_block_device (const char *blk_dev)
{
struct stat st;
if (stat (blk_dev, &st) < 0)
grub_util_error ("cannot stat `%s'", blk_dev);
if (S_ISBLK (st.st_mode))
return (blk_dev);
else
return 0;
}
const char *
grub_util_check_char_device (const char *blk_dev)
{
struct stat st;
if (stat (blk_dev, &st) < 0)
grub_util_error ("cannot stat `%s'", blk_dev);
if (S_ISCHR (st.st_mode))
return (blk_dev);
else
return 0;
}

View file

@ -1,263 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <sys/stat.h>
#include <getopt.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <grub/mm.h>
#include <grub/setjmp.h>
#include <grub/fs.h>
#include <grub/util/hostdisk.h>
#include <grub/dl.h>
#include <grub/util/console.h>
#include <grub/util/misc.h>
#include <grub/kernel.h>
#include <grub/normal.h>
#include <grub/util/getroot.h>
#include <grub/env.h>
#include <grub/partition.h>
#include <grub/i18n.h>
#define ENABLE_RELOCATABLE 0
#include "progname.h"
/* Used for going back to the main function. */
static jmp_buf main_env;
/* Store the prefix specified by an argument. */
static char *prefix = NULL;
grub_addr_t
grub_arch_modules_addr (void)
{
return 0;
}
#if GRUB_NO_MODULES
grub_err_t
grub_arch_dl_check_header (void *ehdr)
{
(void) ehdr;
return GRUB_ERR_BAD_MODULE;
}
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{
(void) mod;
(void) ehdr;
return GRUB_ERR_BAD_MODULE;
}
#endif
void
grub_reboot (void)
{
longjmp (main_env, 1);
}
void
grub_halt (
#ifdef GRUB_MACHINE_PCBIOS
int no_apm __attribute__ ((unused))
#endif
)
{
grub_reboot ();
}
void
grub_machine_init (void)
{
}
void
grub_machine_set_prefix (void)
{
grub_env_set ("prefix", prefix);
free (prefix);
prefix = 0;
}
void
grub_machine_fini (void)
{
grub_console_fini ();
}
static struct option options[] =
{
{"root-device", required_argument, 0, 'r'},
{"device-map", required_argument, 0, 'm'},
{"directory", required_argument, 0, 'd'},
{"hold", optional_argument, 0, 'H'},
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{"verbose", no_argument, 0, 'v'},
{ 0, 0, 0, 0 }
};
static int
usage (int status)
{
if (status)
fprintf (stderr,
"Try `%s --help' for more information.\n", program_name);
else
printf (
"Usage: %s [OPTION]...\n"
"\n"
"GRUB emulator.\n"
"\n"
" -r, --root-device=DEV use DEV as the root device [default=guessed]\n"
" -m, --device-map=FILE use FILE as the device map [default=%s]\n"
" -d, --directory=DIR use GRUB files in the directory DIR [default=%s]\n"
" -v, --verbose print verbose messages\n"
" -H, --hold[=SECONDS] wait until a debugger will attach\n"
" -h, --help display this message and exit\n"
" -V, --version print version information and exit\n"
"\n"
"Report bugs to <%s>.\n", program_name, DEFAULT_DEVICE_MAP, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT);
return status;
}
void grub_hostfs_init (void);
void grub_hostfs_fini (void);
void grub_host_init (void);
void grub_host_fini (void);
#if GRUB_NO_MODULES
void grub_init_all (void);
void grub_fini_all (void);
#endif
int
main (int argc, char *argv[])
{
char *root_dev = 0;
char *dir = DEFAULT_DIRECTORY;
char *dev_map = DEFAULT_DEVICE_MAP;
volatile int hold = 0;
int opt;
set_program_name (argv[0]);
while ((opt = getopt_long (argc, argv, "r:d:m:vH:hV", options, 0)) != -1)
switch (opt)
{
case 'r':
root_dev = optarg;
break;
case 'd':
dir = optarg;
break;
case 'm':
dev_map = optarg;
break;
case 'v':
verbosity++;
break;
case 'H':
hold = (optarg ? atoi (optarg) : -1);
break;
case 'h':
return usage (0);
case 'V':
printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
return 0;
default:
return usage (1);
}
if (optind < argc)
{
fprintf (stderr, "Unknown extra argument `%s'.\n", argv[optind]);
return usage (1);
}
/* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */
if (hold && verbosity > 0)
printf ("Run \"gdb %s %d\", and set ARGS.HOLD to zero.\n",
program_name, (int) getpid ());
while (hold)
{
if (hold > 0)
hold--;
sleep (1);
}
signal (SIGINT, SIG_IGN);
grub_console_init ();
grub_host_init ();
grub_hostfs_init ();
/* XXX: This is a bit unportable. */
grub_util_biosdisk_init (dev_map);
#if GRUB_NO_MODULES
grub_init_all ();
#endif
/* Make sure that there is a root device. */
if (! root_dev)
{
char *device_name = grub_guess_root_device (dir);
if (! device_name)
grub_util_error ("cannot find a device for %s", dir);
root_dev = grub_util_get_grub_dev (device_name);
if (! root_dev)
{
grub_util_info ("guessing the root device failed, because of `%s'",
grub_errmsg);
grub_util_error ("cannot guess the root device. Specify the option `--root-device'");
}
}
if (strcmp (root_dev, "host") == 0)
dir = xstrdup (dir);
else
dir = grub_get_prefix (dir);
prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1);
sprintf (prefix, "(%s)%s", root_dev, dir);
free (dir);
/* Start GRUB! */
if (setjmp (main_env) == 0)
grub_main ();
#if GRUB_NO_MODULES
grub_fini_all ();
#endif
grub_hostfs_fini ();
grub_host_fini ();
grub_machine_fini ();
return 0;
}

View file

@ -19,6 +19,7 @@
#include <config.h>
#include <grub/types.h>
#include <grub/emu/misc.h>
#include <grub/util/misc.h>
#include <grub/device.h>
#include <grub/disk.h>
@ -26,8 +27,8 @@
#include <grub/fs.h>
#include <grub/partition.h>
#include <grub/msdos_partition.h>
#include <grub/util/hostdisk.h>
#include <grub/util/getroot.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/getroot.h>
#include <grub/term.h>
#include <grub/env.h>
#include <grub/raid.h>

File diff suppressed because it is too large Load diff

View file

@ -1,175 +0,0 @@
/* hostfs.c - Dummy filesystem to provide access to the hosts filesystem */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2007,2008,2009,2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#define _BSD_SOURCE
#include <grub/fs.h>
#include <grub/file.h>
#include <grub/disk.h>
#include <grub/misc.h>
#include <grub/dl.h>
#include <grub/util/misc.h>
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
/* dirent.d_type is a BSD extension, not part of POSIX */
#include <sys/stat.h>
#include <string.h>
static int
is_dir (const char *path, const char *name)
{
int len1 = strlen(path);
int len2 = strlen(name);
char pathname[len1 + 1 + len2 + 1 + 13];
strcpy (pathname, path);
/* Avoid UNC-path "//name" on Cygwin. */
if (len1 > 0 && pathname[len1 - 1] != '/')
strcat (pathname, "/");
strcat (pathname, name);
struct stat st;
if (stat (pathname, &st))
return 0;
return S_ISDIR (st.st_mode);
}
static grub_err_t
grub_hostfs_dir (grub_device_t device, const char *path,
int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
DIR *dir;
/* Check if the disk is our dummy disk. */
if (grub_strcmp (device->disk->name, "host"))
return grub_error (GRUB_ERR_BAD_FS, "not a hostfs");
dir = opendir (path);
if (! dir)
return grub_error (GRUB_ERR_BAD_FILENAME,
"can't open the hostfs directory `%s'", path);
while (1)
{
struct dirent *de;
struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
de = readdir (dir);
if (! de)
break;
info.dir = !! is_dir (path, de->d_name);
hook (de->d_name, &info);
}
closedir (dir);
return GRUB_ERR_NONE;
}
/* Open a file named NAME and initialize FILE. */
static grub_err_t
grub_hostfs_open (struct grub_file *file, const char *name)
{
FILE *f;
f = fopen (name, "rb");
if (! f)
return grub_error (GRUB_ERR_BAD_FILENAME,
"can't open `%s'", name);
file->data = f;
#ifdef __MINGW32__
file->size = grub_util_get_disk_size (name);
#else
fseeko (f, 0, SEEK_END);
file->size = ftello (f);
fseeko (f, 0, SEEK_SET);
#endif
return GRUB_ERR_NONE;
}
static grub_ssize_t
grub_hostfs_read (grub_file_t file, char *buf, grub_size_t len)
{
FILE *f;
f = (FILE *) file->data;
if (fseeko (f, file->offset, SEEK_SET) != 0)
{
grub_error (GRUB_ERR_OUT_OF_RANGE, "fseeko: %s", strerror (errno));
return -1;
}
unsigned int s = fread (buf, 1, len, f);
if (s != len)
grub_error (GRUB_ERR_FILE_READ_ERROR, "fread: %s", strerror (errno));
return (signed) s;
}
static grub_err_t
grub_hostfs_close (grub_file_t file)
{
FILE *f;
f = (FILE *) file->data;
fclose (f);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_hostfs_label (grub_device_t device __attribute ((unused)),
char **label __attribute ((unused)))
{
*label = 0;
return GRUB_ERR_NONE;
}
static struct grub_fs grub_hostfs_fs =
{
.name = "hostfs",
.dir = grub_hostfs_dir,
.open = grub_hostfs_open,
.read = grub_hostfs_read,
.close = grub_hostfs_close,
.label = grub_hostfs_label,
.next = 0
};
GRUB_MOD_INIT(hostfs)
{
grub_fs_register (&grub_hostfs_fs);
}
GRUB_MOD_FINI(hostfs)
{
grub_fs_unregister (&grub_hostfs_fs);
}

View file

@ -1,76 +0,0 @@
/* pci.c - Generic PCI interfaces. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2007,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/pci.h>
#include <grub/dl.h>
#include <grub/util/misc.h>
grub_pci_address_t
grub_pci_make_address (grub_pci_device_t dev, int reg)
{
grub_pci_address_t ret;
ret.dev = dev;
ret.pos = reg;
return ret;
}
void
grub_pci_iterate (grub_pci_iteratefunc_t hook)
{
struct pci_device_iterator *iter;
struct pci_slot_match slot;
struct pci_device *dev;
slot.domain = PCI_MATCH_ANY;
slot.bus = PCI_MATCH_ANY;
slot.dev = PCI_MATCH_ANY;
slot.func = PCI_MATCH_ANY;
iter = pci_slot_match_iterator_create (&slot);
while ((dev = pci_device_next (iter)))
hook (dev, dev->vendor_id | (dev->device_id << 16));
pci_iterator_destroy (iter);
}
void *
grub_pci_device_map_range (grub_pci_device_t dev, grub_addr_t base,
grub_size_t size)
{
void *addr;
int err;
err = pci_device_map_range (dev, base, size, PCI_DEV_MAP_FLAG_WRITABLE, &addr);
if (err)
grub_util_error ("mapping 0x%x failed (error %d)\n", base, err);
return addr;
}
void
grub_pci_device_unmap_range (grub_pci_device_t dev, void *mem,
grub_size_t size)
{
pci_device_unmap_range (dev, mem, size);
}
GRUB_MOD_INIT (pci)
{
pci_system_init ();
}
GRUB_MOD_FINI (pci)
{
pci_system_cleanup ();
}

View file

@ -1,237 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2005,2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#define grub_video_render_target grub_video_fbrender_target
#include <grub/err.h>
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/video.h>
#include <grub/video_fb.h>
#include <SDL/SDL.h>
static SDL_Surface *window = 0;
static struct grub_video_render_target *sdl_render_target;
static struct grub_video_mode_info mode_info;
static grub_err_t
grub_video_sdl_set_palette (unsigned int start, unsigned int count,
struct grub_video_palette_data *palette_data);
static grub_err_t
grub_video_sdl_init (void)
{
window = 0;
if (SDL_Init (SDL_INIT_VIDEO) < 0)
return grub_error (GRUB_ERR_BAD_DEVICE, "Couldn't init SDL: %s",
SDL_GetError ());
grub_memset (&mode_info, 0, sizeof (mode_info));
return grub_video_fb_init ();
}
static grub_err_t
grub_video_sdl_fini (void)
{
SDL_Quit ();
window = 0;
grub_memset (&mode_info, 0, sizeof (mode_info));
return grub_video_fb_fini ();
}
static inline unsigned int
get_mask_size (grub_uint32_t mask)
{
unsigned i;
for (i = 0; mask > 1U << i; i++);
return i;
}
static grub_err_t
grub_video_sdl_setup (unsigned int width, unsigned int height,
unsigned int mode_type, unsigned int mode_mask)
{
int depth;
int flags = 0;
grub_err_t err;
/* Decode depth from mode_type. If it is zero, then autodetect. */
depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
>> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
if (depth == 0)
depth = 32;
if (width == 0 && height == 0)
{
width = 800;
height = 600;
}
if ((mode_type & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED)
|| !(mode_mask & GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED))
flags |= SDL_DOUBLEBUF;
window = SDL_SetVideoMode (width, height, depth, flags | SDL_HWSURFACE);
if (! window)
window = SDL_SetVideoMode (width, height, depth, flags | SDL_SWSURFACE);
if (! window)
return grub_error (GRUB_ERR_BAD_DEVICE, "Couldn't open window: %s",
SDL_GetError ());
grub_memset (&sdl_render_target, 0, sizeof (sdl_render_target));
mode_info.width = window->w;
mode_info.height = window->h;
mode_info.mode_type = 0;
if (window->flags & SDL_DOUBLEBUF)
mode_info.mode_type
|= GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED;
if (window->format->palette)
mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
else
mode_info.mode_type |= GRUB_VIDEO_MODE_TYPE_RGB;
mode_info.bpp = window->format->BitsPerPixel;
mode_info.bytes_per_pixel = window->format->BytesPerPixel;
mode_info.pitch = window->pitch;
/* In index color mode, number of colors. In RGB mode this is 256. */
if (window->format->palette)
mode_info.number_of_colors
= 1 << window->format->BitsPerPixel;
else
mode_info.number_of_colors = 256;
if (! window->format->palette)
{
mode_info.red_mask_size
= get_mask_size (window->format->Rmask >> window->format->Rshift);
mode_info.red_field_pos = window->format->Rshift;
mode_info.green_mask_size
= get_mask_size (window->format->Gmask >> window->format->Gshift);
mode_info.green_field_pos = window->format->Gshift;
mode_info.blue_mask_size
= get_mask_size (window->format->Bmask >> window->format->Bshift);
mode_info.blue_field_pos = window->format->Bshift;
mode_info.reserved_mask_size
= get_mask_size (window->format->Amask >> window->format->Ashift);
mode_info.reserved_field_pos = window->format->Ashift;
mode_info.blit_format
= grub_video_get_blit_format (&mode_info);
}
err = grub_video_fb_create_render_target_from_pointer (&sdl_render_target,
&mode_info,
window->pixels);
if (err)
return err;
/* Copy default palette to initialize emulated palette. */
grub_video_sdl_set_palette (0, (sizeof (grub_video_fbstd_colors)
/ sizeof (grub_video_fbstd_colors[0])),
grub_video_fbstd_colors);
/* Reset render target to SDL one. */
return grub_video_fb_set_active_render_target (sdl_render_target);
}
static grub_err_t
grub_video_sdl_set_palette (unsigned int start, unsigned int count,
struct grub_video_palette_data *palette_data)
{
unsigned i;
if (window->format->palette)
{
SDL_Color *tmp = grub_malloc (count * sizeof (tmp[0]));
for (i = 0; i < count; i++)
{
tmp[i].r = palette_data[i].r;
tmp[i].g = palette_data[i].g;
tmp[i].b = palette_data[i].b;
tmp[i].unused = palette_data[i].a;
}
SDL_SetColors (window, tmp, start, count);
grub_free (tmp);
}
return grub_video_fb_set_palette (start, count, palette_data);
}
static grub_err_t
grub_video_sdl_swap_buffers (void)
{
if (SDL_Flip (window) < 0)
return grub_error (GRUB_ERR_BAD_DEVICE, "couldn't swap buffers: %s",
SDL_GetError ());
return GRUB_ERR_NONE;
}
static grub_err_t
grub_video_sdl_set_active_render_target (struct grub_video_render_target *target)
{
if (target == GRUB_VIDEO_RENDER_TARGET_DISPLAY)
return grub_video_fb_set_active_render_target (sdl_render_target);
return grub_video_fb_set_active_render_target (target);
}
static struct grub_video_adapter grub_video_sdl_adapter =
{
.name = "SDL Video Driver",
.init = grub_video_sdl_init,
.fini = grub_video_sdl_fini,
.setup = grub_video_sdl_setup,
.get_info = grub_video_fb_get_info,
.set_palette = grub_video_sdl_set_palette,
.get_palette = grub_video_fb_get_palette,
.set_viewport = grub_video_fb_set_viewport,
.get_viewport = grub_video_fb_get_viewport,
.map_color = grub_video_fb_map_color,
.map_rgb = grub_video_fb_map_rgb,
.map_rgba = grub_video_fb_map_rgba,
.unmap_color = grub_video_fb_unmap_color,
.fill_rect = grub_video_fb_fill_rect,
.blit_bitmap = grub_video_fb_blit_bitmap,
.blit_render_target = grub_video_fb_blit_render_target,
.scroll = grub_video_fb_scroll,
.swap_buffers = grub_video_sdl_swap_buffers,
.create_render_target = grub_video_fb_create_render_target,
.delete_render_target = grub_video_fb_delete_render_target,
.set_active_render_target = grub_video_sdl_set_active_render_target,
.get_active_render_target = grub_video_fb_get_active_render_target,
.next = 0
};
GRUB_MOD_INIT(sdl)
{
grub_video_register (&grub_video_sdl_adapter);
}
GRUB_MOD_FINI(sdl)
{
grub_video_unregister (&grub_video_sdl_adapter);
}

View file

@ -1,46 +0,0 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/datetime.h>
#include <time.h>
grub_err_t
grub_get_datetime (struct grub_datetime *datetime)
{
struct tm *mytm;
time_t mytime;
mytime = time (&mytime);
mytm = gmtime (&mytime);
datetime->year = mytm->tm_year + 1900;
datetime->month = mytm->tm_mon + 1;
datetime->day = mytm->tm_mday;
datetime->hour = mytm->tm_hour;
datetime->minute = mytm->tm_min;
datetime->second = mytm->tm_sec;
return GRUB_ERR_NONE;
}
grub_err_t
grub_set_datetime (struct grub_datetime *datetime __attribute__ ((unused)))
{
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"no clock setting routine available");
}

View file

@ -1,195 +0,0 @@
/* usb.c -- libusb USB support for GRUB. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <usb.h>
#include <grub/usb.h>
#include <grub/dl.h>
static struct grub_usb_controller_dev usb_controller =
{
.name = "libusb"
};
static struct grub_usb_device *grub_usb_devs[128];
struct usb_bus *busses;
static grub_err_t
grub_libusb_devices (void)
{
struct usb_bus *bus;
int last = 0;
busses = usb_get_busses();
for (bus = busses; bus; bus = bus->next)
{
struct usb_device *usbdev;
struct grub_usb_device *dev;
for (usbdev = bus->devices; usbdev; usbdev = usbdev->next)
{
struct usb_device_descriptor *desc = &usbdev->descriptor;
grub_err_t err;
if (! desc->bcdUSB)
continue;
dev = grub_malloc (sizeof (*dev));
if (! dev)
return grub_errno;
dev->data = usbdev;
/* Fill in all descriptors. */
err = grub_usb_device_initialize (dev);
if (err)
{
grub_errno = GRUB_ERR_NONE;
continue;
}
/* Register the device. */
grub_usb_devs[last++] = dev;
}
}
return GRUB_USB_ERR_NONE;
}
int
grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
{
int i;
for (i = 0; i < 128; i++)
{
if (grub_usb_devs[i])
{
if (hook (grub_usb_devs[i]))
return 1;
}
}
return 0;
}
grub_usb_err_t
grub_usb_root_hub (grub_usb_controller_t controller __attribute__((unused)))
{
return GRUB_USB_ERR_NONE;
}
grub_usb_err_t
grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype,
grub_uint8_t request, grub_uint16_t value,
grub_uint16_t index, grub_size_t size, char *data)
{
usb_dev_handle *devh;
struct usb_device *d = dev->data;
devh = usb_open (d);
if (usb_control_msg (devh, reqtype, request,
value, index, data, size, 20) < 0)
{
usb_close (devh);
return GRUB_USB_ERR_STALL;
}
usb_close (devh);
return GRUB_USB_ERR_NONE;
}
grub_usb_err_t
grub_usb_bulk_read (grub_usb_device_t dev,
int endpoint, grub_size_t size, char *data)
{
usb_dev_handle *devh;
struct usb_device *d = dev->data;
devh = usb_open (d);
if (usb_claim_interface (devh, 0) < 1)
{
usb_close (devh);
return GRUB_USB_ERR_STALL;
}
if (usb_bulk_read (devh, endpoint, data, size, 20) < 1)
{
usb_close (devh);
return GRUB_USB_ERR_STALL;
}
usb_release_interface (devh, 0);
usb_close (devh);
return GRUB_USB_ERR_NONE;
}
grub_usb_err_t
grub_usb_bulk_write (grub_usb_device_t dev,
int endpoint, grub_size_t size, char *data)
{
usb_dev_handle *devh;
struct usb_device *d = dev->data;
devh = usb_open (d);
if (usb_claim_interface (devh, 0) < 0)
goto fail;
if (usb_bulk_write (devh, endpoint, data, size, 20) < 0)
goto fail;
if (usb_release_interface (devh, 0) < 0)
goto fail;
usb_close (devh);
return GRUB_USB_ERR_NONE;
fail:
usb_close (devh);
return GRUB_USB_ERR_STALL;
}
GRUB_MOD_INIT (libusb)
{
usb_init();
usb_find_busses();
usb_find_devices();
if (grub_libusb_devices ())
return;
grub_usb_controller_dev_register (&usb_controller);
return;
}
GRUB_MOD_FINI (libusb)
{
return;
}