merge with mainline

This commit is contained in:
BVK Chaitanya 2010-06-10 21:47:25 +05:30
commit d2039c36f2
70 changed files with 3727 additions and 570 deletions

View file

@ -3,6 +3,8 @@
30_os-prober 30_os-prober
40_custom 40_custom
aclocal.m4 aclocal.m4
ascii.bitmaps
ascii.h
autom4te.cache autom4te.cache
build_env.mk build_env.mk
.bzrignore .bzrignore
@ -48,6 +50,8 @@ grub_script_check_init.c
grub_script_check_init.h grub_script_check_init.h
grub_script.tab.c grub_script.tab.c
grub_script.tab.h grub_script.tab.h
grub_script.yy.c
grub_script.yy.h
grub-set-default grub-set-default
grub-setup grub-setup
grub_setup_init.c grub_setup_init.c

495
ChangeLog
View file

@ -1,3 +1,498 @@
2010-06-08 Grégoire Sutre <gregoire.sutre@gmail.com>
Make --version uniform and avoid hard-coded program name.
* util/grub-mkimage.c (main): Use `program_name' instead of
hard-coded string.
* util/i386/pc/grub-setup.c (main): Likewise.
* util/sparc64/ieee1275/grub-setup.c (parse_options): Likewise.
* util/grub-install.in: Save the basename of $0 in $self, and use the
latter in informational messages. Use the same format for --version
as the binary programs.
* util/grub-mkconfig.in: Likewise.
* util/grub-mkrescue.in: Likewise.
* util/grub-reboot.in: Likewise.
* util/grub-set-default.in: Likewise.
* util/i386/efi/grub-install.in: Likewise.
* util/ieee1275/grub-install.in: Likewise.
* util/powerpc/ieee1275/grub-mkrescue.in: Likewise.
2010-06-08 Grégoire Sutre <gregoire.sutre@gmail.com>
* util/i386/pc/grub-setup.c (setup): Use absolute offsets for start of
embedding area. Use <= instead of == when checking for non-emptiness.
2010-06-08 Grégoire Sutre <gregoire.sutre@gmail.com>
* configure.ac: Add `.' to the directories searched for unifont.
2010-06-08 Colin Watson <cjwatson@ubuntu.com>
* .bzrignore: Add ascii.bitmaps, ascii.h, grub_script.yy.c, and
grub_script.yy.h.
2010-06-08 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (History): Expand to cover GRUB 2.
(Serial terminal): Refer to `terminal_input' and `terminal_output'
commands, not `terminal'.
(serial): Likewise.
(terminal_input): New section.
(terminal_output): New section.
(uppermem): New section (stub).
(Obtaining and Building GRUB): Refer to Bazaar, not Subversion.
2010-06-08 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (Security): Menu entries are unrestricted by
default, not restricted to superusers as I had previously thought.
Reword to account for this.
2010-06-07 Colin Watson <cjwatson@ubuntu.com>
* kern/emu/misc.c (device_mapper_null_log): New function.
(grub_device_mapper_supported): New function.
* include/grub/emu/misc.h (grub_device_mapper_supported): Add
prototype.
* kern/emu/hostdisk.c (find_partition_start): Check whether
device-mapper is supported before trying to use it.
* util/deviceiter.c (grub_util_iterate_devices): Likewise.
2010-06-07 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (Naming convention): Use GRUB 2 syntax.
(File name syntax): Likewise.
(help): --all is no longer supported in GRUB 2. Be more precise
about pattern matching.
2010-06-07 Colin Watson <cjwatson@ubuntu.com>
* normal/completion.c (grub_normal_do_completion): When completing
arguments to "set" and the current word contains an equals sign,
skip to after the equals sign before starting completion.
2010-06-07 Colin Watson <cjwatson@ubuntu.com>
* fs/i386/pc/pxe.c (grub_pxe_open): Fix parsing of gateway_ip.
2010-06-07 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (Network): New section.
(Device syntax): The network device is called `(pxe)' in GRUB 2, not
`(nd)' as in GRUB Legacy.
(pxe_unload): New section.
2010-06-07 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (Troubleshooting): `echo' is not usually available
in the rescue shell, so recommend using `set' instead. Thanks,
Jordan Uggla.
2010-06-07 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (Filesystem): Refer to `search' instead of `find'.
(password): New section.
(password_pbkdf2): New section.
(search): New section.
(Security): New section.
(Troubleshooting): New section, currently very incomplete.
(Invoking grub-mkpasswd-pbkdf2): New section.
(Internals): New section, currently very incomplete.
2010-06-07 Colin Watson <cjwatson@ubuntu.com>
* util/grub.d/00_header.in: Add some more quoting (of
"${prev_saved_entry}" and "${boot_once}") needed to make savedefault
work again.
Reported by: Mario 'BitKoenig' Holbe (Debian bug #584812).
2010-06-07 Colin Watson <cjwatson@ubuntu.com>
* util/grub-mkpasswd-pbkdf2.c (main): Rename top-level `c' variable
to `count', fixing variable shadowing that broke the -c option.
2010-06-05 Colin Watson <cjwatson@ubuntu.com>
* util/grub.d/00_header.in: Quote values assigned to `saved_entry',
in case they contain spaces.
2010-06-04 Colin Watson <cjwatson@ubuntu.com>
* util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Prepend
"part_" to partmap module names, in line with grub-install.
Reported by: Jindřich Makovička (Debian bug #584426).
2010-06-04 Colin Watson <cjwatson@ubuntu.com>
* util/grub-mkimage.c: Make target-related error messages slightly
more helpful; -O talks about "format". Explicitly point to the use
of -O if no target is specified.
Reported by: Didier Raboud (Debian bug #584415).
2010-06-03 Colin Watson <cjwatson@ubuntu.com>
* INSTALL: Document several build requirements for optional features
(libdevmapper, ncurses, libusb, SDL, FreeType, GNU Unifont).
2010-06-02 Grégoire Sutre <gregoire.sutre@gmail.com>
* kern/emu/hostdisk.c (convert_system_partition_to_system_disk)
[__NetBSD__]: Handle all device names matching /dev/r[a-z]+[0-9][a-z].
(find_partition_start) [__NetBSD__]: Correct error messages for NetBSD.
2010-06-02 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (Simple configuration): Fix copy-and-paste typo.
Thanks to Jordan Uggla for spotting this.
2010-06-02 Aleš Nesrsta <starous@volny.cz>
Finally make USB usable.
* bus/usb/ohci.c (grub_ohci_reg_t): Add missing values.
(GRUB_OHCI_RHUB_PORT_POWER_MASK): New macro.
(GRUB_OHCI_RHUB_PORT_ALL_POWERED): Likewise.
(GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK): Likewise.
(GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT): Likewise.
(GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT): Likewise.
(GRUB_OHCI_FSMPS): Likewise.
(GRUB_OHCI_PERIODIC_START): Likewise.
(GRUB_OHCI_FRAME_INTERVAL): Likewise.
(GRUB_OHCI_SET_PORT_ENABLE): Likewise.
(GRUB_OHCI_CLEAR_PORT_ENABLE): Likewise.
(GRUB_OHCI_SET_PORT_RESET): Likewise.
(GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE): Likewise.
* bus/usb/ohci.c (grub_ohci_pci_iter): Various important fixups.
(grub_ohci_transaction): Likewise.
(grub_ohci_transfer): Improve condition detection algorithms.
Handle toggle property. Program the transactions correctly.
Improve error handling. Various important fixups.
(grub_ohci_portstatus): Put register writes in right order.
* bus/usb/uhci.c (grub_free_queue): Compute last_trans.
(grub_uhci_transfer): Don't show "failed" message on success.
* bus/usb/usb.c (grub_usb_set_configuration): Zero-fill whole "toggle"
array.
(grub_usb_device_initialize): Read first 8 bytes of descriptor to
determine its size.
* bus/usb/usbtrans.c (grub_usb_control_msg): Use descdev.maxsize0 even
before initialization is completed. Use IN direction for empty
transfers. Use last_trans and compute toggle.
* include/grub/usbtrans.h (grub_usb_transfer): New field last_trans.
(GRUB_USB_FEATURE_ENDP_HALT): Correct the value.
(GRUB_USB_FEATURE_DEV_REMOTE_WU): Likewise.
(GRUB_USB_FEATURE_TEST_MODE): Likewise.
* include/grub/usb.h (grub_usb_err_t): New value GRUB_USB_ERR_UNRECOVERABLE.
(grub_usb_device): Increase toggle to 256.
(grub_usbms_subclass_t): New values GRUB_USBMS_SUBCLASS_RBC,
GRUB_USBMS_SUBCLASS_MMC2, GRUB_USBMS_SUBCLASS_UFI and
GRUB_USBMS_SUBCLASS_SFF8070.
* include/grub/scsicmd.h (grub_scsi_test_unit_ready): New structure.
(grub_scsi_inquiry): New member page and alloc_length.
(grub_scsi_request_sense): New structure.
(grub_scsi_request_sense_data): Likewise.
(grub_scsi_read_capacity): New fields logical_block_addr, PMI and
control.
* disk/scsi.c (grub_scsi_request_sense): New function.
(grub_scsi_test_unit_ready): Likewise.
(grub_scsi_inquiry): Fill new fields.
(grub_scsi_read_capacity): Likewise.
(grub_scsi_read10): Add request sense at the end.
(grub_scsi_read12): Likewise.
(grub_scsi_write10): Likewise.
(grub_scsi_write12): Likewise.
(grub_scsi_open): Add Test Unit Ready.
* disk/usbms.c (grub_usbms_finddevs): Check configcnt.
Support additional subclasses. Con't clear halt yet. Activate the
proper config. Calculate LUNs correctly.
(grub_usbms_transfer): Various important fixups.
2010-06-02 Vladimir Serbinenko <phcoder@gmail.com>
* bus/pci.c (grub_pci_iterate) [GRUB_MACHINE_MIPS_YEELOONG]: Skip ghosts.
* bus/usb/ohci.c (grub_ohci_portstatus): Handle R/WC correctly.
(grub_ohci_fini_hw): New function.
(grub_ohci_restore_hw): Likewise.
(GRUB_MOD_INIT(ohci)): Register preboot hook.
(GRUB_MOD_FINI(ohci)): Shutdown OHCI.
* term/usb_keyboard.c: Remove include of grub/machine/console.h.
2010-06-02 Vladimir Serbinenko <phcoder@gmail.com>
Dedicated DMA allocations.
* bus/pci.c (grub_memalign_dma32): New function
(grub_dma_free): Likewise.
(grub_dma_get_virt): Likewise.
(grub_dma_get_phys): Likewise.
* bus/usb/ohci.c (grub_ohci): New members hcca_addr and hcca_chunk.
(grub_ohci_pci_iter): Use dma32_alloc.
(grub_ohci_transfer): Likewise.
* bus/usb/usbtrans.c (grub_usb_control_msg): Likewise.
(grub_usb_bulk_readwrite): Likewise.
* include/grub/pci.h: Add declarations.
2010-06-02 Vladimir Serbinenko <phcoder@gmail.com>
CS5536 support.
* bus/cs5536.c: New file.
* bus/usb/ohci.c (grub_ohci_pci_iter): Check for CS5536.
* conf/i386.rmk (pkglib_MODULES): Add cs5536.mod.
(cs5536_mod_SOURCES): New variable.
(cs5536_mod_CFLAGS): Likewise.
(cs5536_mod_LDFLAGS): Likewise.
* conf/mips-yeeloong.rmk (kernel_img_HEADERS): Add cs5536.h and
machine/pci.h.
(kernel_img_SOURCES): Add bus/cs5536.c.
(pkglib_MODULES): Add usb.mod, usbtest.mod, ohci.mod, usbms.mod and
usb_keyboard.mod.
(usb_mod_SOURCES): New variable.
(usb_mod_CFLAGS): New variable.
(usb_mod_LDFLAGS): New variable.
(usbtest_mod_SOURCES): New variable.
(usbtest_mod_CFLAGS): New variable.
(usbtest_mod_LDFLAGS): New variable.
(ohci_mod_SOURCES): New variable.
(ohci_mod_CFLAGS): New variable.
(ohci_mod_LDFLAGS): New variable.
(usbms_mod_SOURCES): New variable.
(usbms_mod_CFLAGS): New variable.
(usbms_mod_LDFLAGS): New variable.
(usb_keyboard_mod_SOURCES): New variable.
(usb_keyboard_mod_CFLAGS): New variable.
(usb_keyboard_mod_LDFLAGS): New variable.
* include/grub/smbus.h: New file.
* include/grub/cs5536.h: New file.
2010-06-02 Colin Watson <cjwatson@ubuntu.com>
* util/grub.d/00_header.in: Add safety check to make sure that
${locale_dir} exists before trying to probe it.
2010-06-02 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (SCO UnixWare): Remove, at Vladimir's request and
per the GNU Coding Standards; this is now too obscure to be worth
documenting.
(QNX): Likewise.
(chainloader): Remove cross-reference to `SCO UnixWare'.
2010-06-02 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (Chain-loading): New section.
(DOS/Windows): New section, borrowed from GRUB Legacy with details
adjusted for GRUB 2.
(SCO UnixWare): Likewise.
(QNX): Likewise.
(chainloader): Add reference to `Block list syntax'.
(drivemap): New section.
(parttool): New section.
2010-06-02 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (GNU GRUB manual): Remove reference to `Invoking
the grub shell'.
(Installation): Add reference to `Making a GRUB bootable CD-ROM'.
(Installing GRUB using grub-install): Remove reference to the grub
shell; mention `grub-mkimage' and `grub-setup' instead.
(Invoking grub-install): Likewise.
(Interface): Add reference to `Menu entry editor'.
(serial): Remove `--device' option.
2010-06-02 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (Configuration): New section, documenting
configuration file generation using grub-mkconfig. I've left a slot
for documenting the full shell scripting format but have not yet
started on writing that up.
(Invoking grub-mkconfig): New section.
2010-06-02 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (direntry): Remove grub-terminfo reference.
(GNU GRUB manual): Likewise.
(General commands): Update description of `terminfo' for GRUB 2.
2010-06-02 Colin Watson <cjwatson@ubuntu.com>
* commands/gptsync.c (grub_cmd_gptsync): Fix typos.
(GRUB_MOD_INIT): Fix capitalisation.
* docs/grub.texi (Command-line and menu entry commands): Document
gettext and gptsync commands.
2010-06-02 Colin Watson <cjwatson@ubuntu.com>
* conf/any-emu.rmk (kernel_img_SOURCES) [!x86]: Include
kern/$(target_cpu)/cache.S even if TARGET_NO_MODULES = yes.
2010-06-01 Colin Watson <cjwatson@ubuntu.com>
Add btrfs probing support, currently only in the single-device case.
* kern/emu/getroot.c (find_root_device_from_mountinfo): New
function.
(grub_guess_root_device): Call find_root_device_from_mountinfo
before looking in /dev.
2010-05-31 Vladimir Serbinenko <phcoder@gmail.com>
* disk/i386/pc/biosdisk.c (grub_biosdisk_open): Use
GRUB_DISK_SIZE_UNKNOWN.
* disk/ieee1275/ofdisk.c (grub_ofdisk_open): Likewise.
2010-05-31 Jiro SEKIBA <jir@unicus.jp>
* include/grub/disk.h (GRUB_DISK_SIZE_UNKNOWN): New macro.
* fs/nilfs.c: Support 2nd super block in case 1st one is accidently
corrupted or not synced properly.
2010-05-31 Vladimir Serbinenko <phcoder@gmail.com>
* normal/main.c (grub_normal_add_menu_entry): Avoid going out of args.
Reported by: Seth Goldberg.
2010-05-31 Vladimir Serbinenko <phcoder@gmail.com>
* loader/multiboot_mbi2.c (grub_multiboot_make_mbi): Fix incorrect
addition of dest.
Reported by: Seth Goldberg.
2010-05-31 Vladimir Serbinenko <phcoder@gmail.com>
* commands/setpci.c (grub_setpci_iter): Fix an incorrect function check.
Reported by: Seth Goldberg.
2010-05-31 Vladimir Serbinenko <phcoder@gmail.com>
* loader/multiboot_elfxx.c (grub_multiboot_load_elfXX) [__mips]: Check
64-bit address as signed on MIPS.
2010-05-28 Colin Watson <cjwatson@ubuntu.com>
* configure.ac: AC_PROG_LEX sets LEX to ":" if lex is missing, not
to the empty string.
2010-05-28 BVK Chaitanya <bvk.groups@gmail.com>
Fix grub-emu issues on NetBSD, with gcc 4.1.3.
* conf/any-emu.rmk: Remove unnecessary COMMON_CFLAGS.
* include/grub/emu/misc.h (canonicalize_file_name): New Prototype.
* kern/misc.c (__enable_execute_stack): Disable on
GRUB_MACHINE_EMU.
2010-05-28 Colin Watson <cjwatson@ubuntu.com>
Make grub-probe work with symbolic links under /dev/mapper as well
as with real block devices. The Linux world seems to be (at best)
in transition here, and GRUB shouldn't get caught in the middle.
* kern/emu/getroot.c (find_root_device): Follow symbolic links under
/dev/mapper.
2010-05-27 Colin Watson <cjwatson@ubuntu.com>
* util/grub-script-check.c (main): Ensure defined behaviour on empty
input files (in which case exit zero).
2010-05-27 Colin Watson <cjwatson@ubuntu.com>
* kern/emu/misc.c (canonicalize_file_name): realpath can still
return NULL for various reasons even if it has a maximum-length
buffer: for example, there might be a symlink loop, or the path
might exceed PATH_MAX. If this happens, return NULL.
2010-05-27 Robert Millan <rmh@gnu.org>
* util/grub-mkconfig_lib.in (prepare_grub_to_access_device): Insert
partmap module to handle cross-partmap setups.
Reported by Orestes Mas. Gràcies!
2010-05-27 Colin Watson <cjwatson@ubuntu.com>
* util/grub-mkrescue.in: Initialise override_dir rather than
assuming that it's unset or empty in the environment.
2010-05-26 Grégoire Sutre <gregoire.sutre@gmail.com>
* kern/emu/hostdisk.c (find_partition_start) [__NetBSD__]: Renamed
variable index into p_index to suppress a warning with -Wshadow.
2010-05-25 BVK Chaitanya <bvk.groups@gmail.com>
* INSTALL: Added flex >= 2.5.35 requirement.
2010-05-23 Vladimir Serbinenko <phcoder@gmail.com>
* commands/usbtest.c (grub_usb_get_string): Properly support UTF-16.
2010-05-23 Vladimir Serbinenko <phcoder@gmail.com>
cmostest support.
* commands/i386/cmostest.c: New file.
* conf/i386-coreboot.rmk (pkglib_MODULES): Add cmostest.mod.
(cmostest_mod_SOURCES): New variable.
(cmostest_mod_CFLAGS): Likewise.
(cmostest_mod_LDFLAGS): Likewise.
* conf/i386-pc.rmk: Likewise.
* docs/grub.texi (Vendor power-on keys): New section.
* util/grub-mkconfig.in: export GRUB_DEFAULT_BUTTON,
GRUB_HIDDEN_TIMEOUT_BUTTON, GRUB_TIMEOUT_BUTTON
and GRUB_BUTTON_CMOS_ADDRESS.
* util/grub.d/00_header.in: Handle powering-on by separate button.
2010-05-23 Vladimir Serbinenko <phcoder@gmail.com>
* gfxmenu/gui_list.c (draw_menu): Don't add scrollbar width to padding.
Removed drawing_scrollbar argument. All users updated
Fixes #29792.
Reported by Jo Shields
2010-05-23 Vladimir Serbinenko <phcoder@gmail.com>
* gfxmenu/view.c (grub_gfxmenu_draw_terminal_box): Apply only to current
buffer since gfxterm handles double repaint.
2010-05-23 Vladimir Serbinenko <phcoder@gmail.com>
* gfxmenu/gfxmenu.c (grub_gfxmenu_try): Change viewport on both buffers.
* term/gfxterm.c (real_scroll): Likewise.
2010-05-21 Vladimir Serbinenko <phcoder@gmail.com>
* kern/i386/pc/mmap.c (grub_machine_mmap_iterate): Zero-fill entry
before calling BIOS.
2010-05-21 Vladimir Serbinenko <phcoder@gmail.com>
* include/grub/i18n.h: Always enable grub_gettext.
2010-05-21 Vladimir Serbinenko <phcoder@gmail.com>
* kern/i386/pc/init.c (make_install_device): Fix a leftover usage of old
partition naming style.
2010-05-21 Colin Watson <cjwatson@ubuntu.com>
* util/grub-mkconfig.in: Fix handling of -o so that it works when
not the first option.
2010-05-20 Colin Watson <cjwatson@ubuntu.com>
* util/grub-mkrelpath.c (usage): Remove excess apostrophe.
2010-05-20 Colin Watson <cjwatson@ubuntu.com>
* util/misc.c: Move inclusion of <limits.h> to ...
* kern/emu/misc.c: ... here. Needed for canonicalize_file_name.
2010-05-20 Grégoire Sutre <gregoire.sutre@gmail.com>
* kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev) [__NetBSD__]:
Fix merge error in NetBSD code.
(find_partition_start) [__NetBSD__]: Likewise.
2010-05-19 BVK Chaitanya <bvk.groups@gmail.com> 2010-05-19 BVK Chaitanya <bvk.groups@gmail.com>
Fix grub-mkrescue usage unit testing. Fix grub-mkrescue usage unit testing.

16
INSTALL
View file

@ -16,8 +16,24 @@ configuring the GRUB.
* GNU Bison 2.3 or later * GNU Bison 2.3 or later
* GNU gettext 0.17 or later * GNU gettext 0.17 or later
* GNU binutils 2.9.1.0.23 or later * GNU binutils 2.9.1.0.23 or later
* Flex 2.5.35 or later
* Other standard GNU/Unix tools * Other standard GNU/Unix tools
On GNU/Linux, you also need:
* libdevmapper (recommended)
To build grub-emu, you need:
* ncurses
* libusb (recommended)
* SDL (recommended)
To build GRUB's graphical terminal (gfxterm), you need:
* FreeType 2 or later
* GNU Unifont
If you use a development snapshot or want to hack on GRUB you may If you use a development snapshot or want to hack on GRUB you may
need the following. need the following.

215
bus/cs5536.c Normal file
View file

@ -0,0 +1,215 @@
/*
* 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/types.h>
#include <grub/cs5536.h>
#include <grub/pci.h>
#include <grub/time.h>
#include <grub/ata.h>
int
grub_cs5536_find (grub_pci_device_t *devp)
{
int found = 0;
auto int NESTED_FUNC_ATTR hook (grub_pci_device_t dev,
grub_pci_id_t pciid);
int NESTED_FUNC_ATTR hook (grub_pci_device_t dev,
grub_pci_id_t pciid)
{
if (pciid == GRUB_CS5536_PCIID)
{
*devp = dev;
found = 1;
return 1;
}
return 0;
}
grub_pci_iterate (hook);
return found;
}
grub_uint64_t
grub_cs5536_read_msr (grub_pci_device_t dev, grub_uint32_t addr)
{
grub_uint64_t ret = 0;
grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR),
addr);
ret = (grub_uint64_t)
grub_pci_read (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0));
ret |= (((grub_uint64_t)
grub_pci_read (grub_pci_make_address (dev,
GRUB_CS5536_MSR_MAILBOX_DATA1)))
<< 32);
return ret;
}
void
grub_cs5536_write_msr (grub_pci_device_t dev, grub_uint32_t addr,
grub_uint64_t val)
{
grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_ADDR),
addr);
grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA0),
val & 0xffffffff);
grub_pci_write (grub_pci_make_address (dev, GRUB_CS5536_MSR_MAILBOX_DATA1),
val >> 32);
}
grub_err_t
grub_cs5536_smbus_wait (grub_port_t smbbase)
{
grub_uint64_t start = grub_get_time_ms ();
while (1)
{
grub_uint8_t status;
status = grub_inb (smbbase + GRUB_CS5536_SMB_REG_STATUS);
if (status & GRUB_CS5536_SMB_REG_STATUS_SDAST)
return GRUB_ERR_NONE;
if (status & GRUB_CS5536_SMB_REG_STATUS_BER)
return grub_error (GRUB_ERR_IO, "SM bus error");
if (status & GRUB_CS5536_SMB_REG_STATUS_NACK)
return grub_error (GRUB_ERR_IO, "NACK received");
if (grub_get_time_ms () > start + 40)
return grub_error (GRUB_ERR_IO, "SM stalled");
}
return GRUB_ERR_NONE;
}
grub_err_t
grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev,
grub_uint8_t addr, grub_uint8_t *res)
{
grub_err_t err;
/* Send START. */
grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1)
| GRUB_CS5536_SMB_REG_CTRL1_START,
smbbase + GRUB_CS5536_SMB_REG_CTRL1);
/* Send device address. */
err = grub_cs5536_smbus_wait (smbbase);
if (err)
return err;
grub_outb (dev << 1, smbbase + GRUB_CS5536_SMB_REG_DATA);
/* Send ACK. */
err = grub_cs5536_smbus_wait (smbbase);
if (err)
return err;
grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1)
| GRUB_CS5536_SMB_REG_CTRL1_ACK,
smbbase + GRUB_CS5536_SMB_REG_CTRL1);
/* Send byte address. */
grub_outb (addr, smbbase + GRUB_CS5536_SMB_REG_DATA);
/* Send START. */
err = grub_cs5536_smbus_wait (smbbase);
if (err)
return err;
grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1)
| GRUB_CS5536_SMB_REG_CTRL1_START,
smbbase + GRUB_CS5536_SMB_REG_CTRL1);
/* Send device address. */
err = grub_cs5536_smbus_wait (smbbase);
if (err)
return err;
grub_outb ((dev << 1) | 1, smbbase + GRUB_CS5536_SMB_REG_DATA);
/* Send STOP. */
err = grub_cs5536_smbus_wait (smbbase);
if (err)
return err;
grub_outb (grub_inb (smbbase + GRUB_CS5536_SMB_REG_CTRL1)
| GRUB_CS5536_SMB_REG_CTRL1_STOP,
smbbase + GRUB_CS5536_SMB_REG_CTRL1);
err = grub_cs5536_smbus_wait (smbbase);
if (err)
return err;
*res = grub_inb (smbbase + GRUB_CS5536_SMB_REG_DATA);
return GRUB_ERR_NONE;
}
grub_err_t
grub_cs5536_init_smbus (grub_pci_device_t dev, grub_uint16_t divisor,
grub_port_t *smbbase)
{
grub_uint64_t smbbar;
smbbar = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_SMB_BAR);
/* FIXME */
if (!(smbbar & GRUB_CS5536_LBAR_ENABLE))
return grub_error(GRUB_ERR_IO, "SMB controller not enabled\n");
*smbbase = (smbbar & GRUB_CS5536_LBAR_ADDR_MASK) + GRUB_MACHINE_PCI_IO_BASE;
if (divisor < 8)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid divisor");
/* Disable SMB. */
grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL2);
/* Disable interrupts. */
grub_outb (0, *smbbase + GRUB_CS5536_SMB_REG_CTRL1);
/* Set as master. */
grub_outb (GRUB_CS5536_SMB_REG_ADDR_MASTER,
*smbbase + GRUB_CS5536_SMB_REG_ADDR);
/* Launch. */
grub_outb (((divisor >> 7) & 0xff), *smbbase + GRUB_CS5536_SMB_REG_CTRL3);
grub_outb (((divisor << 1) & 0xfe) | GRUB_CS5536_SMB_REG_CTRL2_ENABLE,
*smbbase + GRUB_CS5536_SMB_REG_CTRL2);
return GRUB_ERR_NONE;
}
grub_err_t
grub_cs5536_read_spd (grub_port_t smbbase, grub_uint8_t dev,
struct grub_smbus_spd *res)
{
grub_err_t err;
grub_size_t size;
grub_uint8_t b;
grub_size_t ptr;
err = grub_cs5536_read_spd_byte (smbbase, dev, 0, &b);
if (err)
return err;
if (b == 0)
return grub_error (GRUB_ERR_IO, "no SPD found");
size = b;
((grub_uint8_t *) res)[0] = b;
for (ptr = 1; ptr < size; ptr++)
{
err = grub_cs5536_read_spd_byte (smbbase, dev, ptr,
&((grub_uint8_t *) res)[ptr]);
if (err)
return err;
}
return GRUB_ERR_NONE;
}

View file

@ -19,6 +19,50 @@
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/pci.h> #include <grub/pci.h>
#include <grub/mm.h>
/* FIXME: correctly support 64-bit architectures. */
/* #if GRUB_TARGET_SIZEOF_VOID_P == 4 */
struct grub_pci_dma_chunk *
grub_memalign_dma32 (grub_size_t align, grub_size_t size)
{
return grub_memalign (align, size);
}
void
grub_dma_free (struct grub_pci_dma_chunk *ch)
{
grub_free (ch);
}
/* #endif */
#ifdef GRUB_MACHINE_MIPS_YEELOONG
volatile void *
grub_dma_get_virt (struct grub_pci_dma_chunk *ch)
{
return (void *) ((((grub_uint32_t) ch) & 0x1fffffff) | 0xa0000000);
}
grub_uint32_t
grub_dma_get_phys (struct grub_pci_dma_chunk *ch)
{
return (((grub_uint32_t) ch) & 0x1fffffff) | 0x80000000;
}
#else
volatile void *
grub_dma_get_virt (struct grub_pci_dma_chunk *ch)
{
return (void *) ch;
}
grub_uint32_t
grub_dma_get_phys (struct grub_pci_dma_chunk *ch)
{
return (grub_uint32_t) (grub_addr_t) ch;
}
#endif
grub_pci_address_t grub_pci_address_t
grub_pci_make_address (grub_pci_device_t dev, int reg) grub_pci_make_address (grub_pci_device_t dev, int reg)
@ -48,6 +92,16 @@ grub_pci_iterate (grub_pci_iteratefunc_t hook)
if (id >> 16 == 0xFFFF) if (id >> 16 == 0xFFFF)
continue; continue;
#ifdef GRUB_MACHINE_MIPS_YEELOONG
/* Skip ghosts. */
if (id == GRUB_YEELOONG_OHCI_PCIID
&& dev.function == GRUB_YEELOONG_OHCI_GHOST_FUNCTION)
continue;
if (id == GRUB_YEELOONG_EHCI_PCIID
&& dev.function == GRUB_YEELOONG_EHCI_GHOST_FUNCTION)
continue;
#endif
if (hook (dev, id)) if (hook (dev, id))
return; return;

View file

@ -24,8 +24,10 @@
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/pci.h> #include <grub/pci.h>
#include <grub/cpu/pci.h> #include <grub/cpu/pci.h>
#include <grub/i386/io.h> #include <grub/cpu/io.h>
#include <grub/time.h> #include <grub/time.h>
#include <grub/cs5536.h>
#include <grub/loader.h>
struct grub_ohci_hcca struct grub_ohci_hcca
{ {
@ -63,13 +65,15 @@ struct grub_ohci_td
grub_uint32_t buffer_end; grub_uint32_t buffer_end;
} __attribute__((packed)); } __attribute__((packed));
typedef struct grub_ohci_td *grub_ohci_td_t; typedef volatile struct grub_ohci_td *grub_ohci_td_t;
typedef struct grub_ohci_ed *grub_ohci_ed_t; typedef volatile struct grub_ohci_ed *grub_ohci_ed_t;
struct grub_ohci struct grub_ohci
{ {
volatile grub_uint32_t *iobase; volatile grub_uint32_t *iobase;
volatile struct grub_ohci_hcca *hcca; volatile struct grub_ohci_hcca *hcca;
grub_uint32_t hcca_addr;
struct grub_pci_dma_chunk *hcca_chunk;
struct grub_ohci *next; struct grub_ohci *next;
}; };
@ -91,10 +95,32 @@ typedef enum
GRUB_OHCI_REG_BULKCURR, GRUB_OHCI_REG_BULKCURR,
GRUB_OHCI_REG_DONEHEAD, GRUB_OHCI_REG_DONEHEAD,
GRUB_OHCI_REG_FRAME_INTERVAL, GRUB_OHCI_REG_FRAME_INTERVAL,
GRUB_OHCI_REG_PERIODIC_START = 16,
GRUB_OHCI_REG_RHUBA = 18, GRUB_OHCI_REG_RHUBA = 18,
GRUB_OHCI_REG_RHUBPORT = 21 GRUB_OHCI_REG_RHUBPORT = 21,
GRUB_OHCI_REG_LEGACY_CONTROL = 0x100,
GRUB_OHCI_REG_LEGACY_INPUT = 0x104,
GRUB_OHCI_REG_LEGACY_OUTPUT = 0x108,
GRUB_OHCI_REG_LEGACY_STATUS = 0x10c
} grub_ohci_reg_t; } grub_ohci_reg_t;
#define GRUB_OHCI_RHUB_PORT_POWER_MASK 0x300
#define GRUB_OHCI_RHUB_PORT_ALL_POWERED 0x200
#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_MASK 0x8fff0000
#define GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT 16
#define GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT 0
/* XXX: Is this choice of timings sane? */
#define GRUB_OHCI_FSMPS 0x2778
#define GRUB_OHCI_PERIODIC_START 0x257f
#define GRUB_OHCI_FRAME_INTERVAL 0x2edf
#define GRUB_OHCI_SET_PORT_ENABLE (1 << 1)
#define GRUB_OHCI_CLEAR_PORT_ENABLE (1 << 0)
#define GRUB_OHCI_SET_PORT_RESET (1 << 4)
#define GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE (1 << 20)
static grub_uint32_t static grub_uint32_t
grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg) grub_ohci_readreg32 (struct grub_ohci *o, grub_ohci_reg_t reg)
{ {
@ -114,51 +140,81 @@ grub_ohci_writereg32 (struct grub_ohci *o,
controller. If this is the case, initialize it. */ controller. If this is the case, initialize it. */
static int NESTED_FUNC_ATTR static int NESTED_FUNC_ATTR
grub_ohci_pci_iter (grub_pci_device_t dev, grub_ohci_pci_iter (grub_pci_device_t dev,
grub_pci_id_t pciid __attribute__((unused))) grub_pci_id_t pciid)
{ {
grub_uint32_t class_code;
grub_uint32_t class;
grub_uint32_t subclass;
grub_uint32_t interf; grub_uint32_t interf;
grub_uint32_t base; grub_uint32_t base;
grub_pci_address_t addr; grub_pci_address_t addr;
struct grub_ohci *o; struct grub_ohci *o;
grub_uint32_t revision; grub_uint32_t revision;
grub_uint32_t frame_interval; int cs5536;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
class_code = grub_pci_read (addr) >> 8;
interf = class_code & 0xFF;
subclass = (class_code >> 8) & 0xFF;
class = class_code >> 16;
/* If this is not an OHCI controller, just return. */
if (class != 0x0c || subclass != 0x03 || interf != 0x10)
return 0;
/* Determine IO base address. */ /* Determine IO base address. */
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); grub_dprintf ("ohci", "pciid = %x\n", pciid);
base = grub_pci_read (addr);
if (pciid == GRUB_CS5536_PCIID)
{
grub_uint64_t basereg;
cs5536 = 1;
basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE);
if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE))
{
/* Shouldn't happen. */
grub_dprintf ("ohci", "No OHCI address is assigned\n");
return 0;
}
base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK);
basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED;
basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS;
grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, basereg);
}
else
{
grub_uint32_t class_code;
grub_uint32_t class;
grub_uint32_t subclass;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
class_code = grub_pci_read (addr) >> 8;
interf = class_code & 0xFF;
subclass = (class_code >> 8) & 0xFF;
class = class_code >> 16;
/* If this is not an OHCI controller, just return. */
if (class != 0x0c || subclass != 0x03 || interf != 0x10)
return 0;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
base = grub_pci_read (addr);
#if 0 #if 0
/* Stop if there is no IO space base address defined. */ /* Stop if there is no IO space base address defined. */
if (! (base & 1)) if (! (base & 1))
return 0; return 0;
#endif #endif
grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x\n",
class, subclass, interf);
}
/* Allocate memory for the controller and register it. */ /* Allocate memory for the controller and register it. */
o = grub_malloc (sizeof (*o)); o = grub_malloc (sizeof (*o));
if (! o) if (! o)
return 1; return 1;
o->iobase = (grub_uint32_t *) base; o->iobase = grub_pci_device_map_range (dev, base, 0x800);
grub_dprintf ("ohci", "base=%p\n", o->iobase);
/* Reserve memory for the HCCA. */ /* Reserve memory for the HCCA. */
o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256); o->hcca_chunk = grub_memalign_dma32 (256, 256);
if (! o->hcca_chunk)
grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x base=%p\n", return 1;
class, subclass, interf, o->iobase); o->hcca = grub_dma_get_virt (o->hcca_chunk);
o->hcca_addr = grub_dma_get_phys (o->hcca_chunk);
/* Check if the OHCI revision is actually 1.0 as supported. */ /* Check if the OHCI revision is actually 1.0 as supported. */
revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION); revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION);
@ -166,27 +222,116 @@ grub_ohci_pci_iter (grub_pci_device_t dev,
if ((revision & 0xFF) != 0x10) if ((revision & 0xFF) != 0x10)
goto fail; goto fail;
/* Backup the frame interval register. */
frame_interval = grub_ohci_readreg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL); {
grub_uint32_t control;
/* Check SMM/BIOS ownership of OHCI (SMM = USB Legacy Support driver for BIOS) */
control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
if ((control & 0x100) != 0)
{
unsigned i;
grub_dprintf("ohci", "OHCI is owned by SMM\n");
/* Do change of ownership */
/* Ownership change request */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, (1<<3)); /* XXX: Magic. */
/* Waiting for SMM deactivation */
for (i=0; i < 10; i++)
{
if ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & 0x100) == 0)
{
grub_dprintf("ohci", "Ownership changed normally.\n");
break;
}
grub_millisleep (100);
}
if (i >= 10)
{
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL,
grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & ~0x100);
grub_dprintf("ohci", "Ownership changing timeout, change forced !\n");
}
}
else if (((control & 0x100) == 0) &&
((control & 0xc0) != 0)) /* Not owned by SMM nor reset */
{
grub_dprintf("ohci", "OHCI is owned by BIOS\n");
/* Do change of ownership - not implemented yet... */
/* In fact we probably need to do nothing ...? */
}
else
{
grub_dprintf("ohci", "OHCI is not owned by SMM nor BIOS\n");
/* We can setup OHCI. */
}
}
/* Suspend the OHCI by issuing a reset. */ /* Suspend the OHCI by issuing a reset. */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */
grub_millisleep (1); grub_millisleep (1);
grub_dprintf ("ohci", "OHCI reset\n"); grub_dprintf ("ohci", "OHCI reset\n");
/* Restore the frame interval register. */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL,
grub_ohci_writereg32 (o, GRUB_OHCI_REG_FRAME_INTERVAL, frame_interval); (GRUB_OHCI_FSMPS
<< GRUB_OHCI_REG_FRAME_INTERVAL_FSMPS_SHIFT)
| (GRUB_OHCI_FRAME_INTERVAL
<< GRUB_OHCI_REG_FRAME_INTERVAL_FI_SHIFT));
grub_ohci_writereg32 (o, GRUB_OHCI_REG_PERIODIC_START,
GRUB_OHCI_PERIODIC_START);
/* Setup the HCCA. */ /* Setup the HCCA. */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca); o->hcca->donehead = 0;
grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr);
grub_dprintf ("ohci", "OHCI HCCA\n"); grub_dprintf ("ohci", "OHCI HCCA\n");
/* Misc. pre-sets. */
o->hcca->donehead = 0;
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0);
/* Check OHCI Legacy Support */
if ((revision & 0x100) != 0)
{
grub_dprintf ("ohci", "Legacy Support registers detected\n");
grub_dprintf ("ohci", "Current state of legacy control reg.: 0x%04x\n",
grub_ohci_readreg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL));
grub_ohci_writereg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL,
(grub_ohci_readreg32 (o, GRUB_OHCI_REG_LEGACY_CONTROL)) & ~1);
grub_dprintf ("ohci", "OHCI Legacy Support disabled.\n");
}
/* Enable the OHCI. */ /* Enable the OHCI. */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL,
(2 << 6)); (2 << 6));
grub_dprintf ("ohci", "OHCI enable: 0x%02x\n", grub_dprintf ("ohci", "OHCI enable: 0x%02x\n",
(grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) >> 6) & 3); (grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) >> 6) & 3);
/* Power on all ports */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBA,
(grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA)
& ~GRUB_OHCI_RHUB_PORT_POWER_MASK)
| GRUB_OHCI_RHUB_PORT_ALL_POWERED);
/* Wait for stable power (100ms) and stable attachment (100ms) */
/* I.e. minimum wait time should be probably 200ms. */
/* We assume that device is attached when ohci is loaded. */
/* Some devices take long time to power-on or indicate attach. */
/* Here is some experimental value which should probably mostly work. */
/* Cameras with manual USB mode selection and maybe some other similar
* devices will not work in some cases - they are repowered during
* ownership change and then they are starting slowly and mostly they
* are wanting select proper mode again...
* The same situation can be on computers where BIOS not set-up OHCI
* to be at least powered USB bus (maybe it is Yeelong case...?)
* Possible workaround could be for example some prompt
* for user with confirmation of proper USB device connection.
* Another workaround - "rmmod usbms", "rmmod ohci", proper start
* and configuration of USB device and then "insmod ohci"
* and "insmod usbms". */
grub_millisleep (500);
/* Link to ohci now that initialisation is successful. */ /* Link to ohci now that initialisation is successful. */
o->next = ohci; o->next = ohci;
ohci = o; ohci = o;
@ -195,10 +340,10 @@ grub_ohci_pci_iter (grub_pci_device_t dev,
fail: fail:
if (o) if (o)
grub_free ((void *) o->hcca); grub_dma_free (o->hcca_chunk);
grub_free (o); grub_free (o);
return 1; return 0;
} }
@ -229,7 +374,7 @@ grub_ohci_iterate (int (*hook) (grub_usb_controller_t dev))
static void static void
grub_ohci_transaction (grub_ohci_td_t td, grub_ohci_transaction (grub_ohci_td_t td,
grub_transfer_type_t type, unsigned int toggle, grub_transfer_type_t type, unsigned int toggle,
grub_size_t size, char *data) grub_size_t size, grub_uint32_t data)
{ {
grub_uint32_t token; grub_uint32_t token;
grub_uint32_t buffer; grub_uint32_t buffer;
@ -254,20 +399,38 @@ grub_ohci_transaction (grub_ohci_td_t td,
break; break;
} }
#if 0 /* Always generate interrupt */
/* Generate no interrupts. */ /* Generate no interrupts. */
token |= 7 << 21; token |= 7 << 21;
#endif
/* Set the token. */ /* Set the token. */
token |= toggle << 24; token |= toggle << 24;
token |= 1 << 25; token |= 1 << 25;
buffer = (grub_uint32_t) data; /* Set "Not accessed" error code */
token |= 15 << 28;
buffer = data;
buffer_end = buffer + size - 1; buffer_end = buffer + size - 1;
/* Set correct buffer values in TD if zero transfer occurs */
if (size)
{
buffer = (grub_uint32_t) data;
buffer_end = buffer + size - 1;
td->buffer = grub_cpu_to_le32 (buffer);
td->buffer_end = grub_cpu_to_le32 (buffer_end);
}
else
{
td->buffer = 0;
td->buffer_end = 0;
}
/* Set the rest of TD */
td->token = grub_cpu_to_le32 (token); td->token = grub_cpu_to_le32 (token);
td->buffer = grub_cpu_to_le32 (buffer);
td->next_td = 0; td->next_td = 0;
td->buffer_end = grub_cpu_to_le32 (buffer_end);
} }
static grub_usb_err_t static grub_usb_err_t
@ -276,7 +439,10 @@ grub_ohci_transfer (grub_usb_controller_t dev,
{ {
struct grub_ohci *o = (struct grub_ohci *) dev->data; struct grub_ohci *o = (struct grub_ohci *) dev->data;
grub_ohci_ed_t ed; grub_ohci_ed_t ed;
grub_uint32_t ed_addr;
struct grub_pci_dma_chunk *ed_chunk, *td_list_chunk;
grub_ohci_td_t td_list; grub_ohci_td_t td_list;
grub_uint32_t td_list_addr;
grub_uint32_t target; grub_uint32_t target;
grub_uint32_t td_tail; grub_uint32_t td_tail;
grub_uint32_t td_head; grub_uint32_t td_head;
@ -284,20 +450,30 @@ grub_ohci_transfer (grub_usb_controller_t dev,
grub_uint32_t control; grub_uint32_t control;
grub_usb_err_t err; grub_usb_err_t err;
int i; int i;
grub_uint64_t maxtime;
int err_timeout = 0;
int err_unrec = 0;
grub_uint32_t intstatus;
grub_uint32_t tderr_addr = 0;
/* Allocate an Endpoint Descriptor. */ /* Allocate an Endpoint Descriptor. */
ed = grub_memalign (16, sizeof (*ed)); ed_chunk = grub_memalign_dma32 (256, sizeof (*ed));
if (! ed) if (! ed_chunk)
return GRUB_USB_ERR_INTERNAL; return GRUB_USB_ERR_INTERNAL;
ed = grub_dma_get_virt (ed_chunk);
ed_addr = grub_dma_get_phys (ed_chunk);
td_list = grub_memalign (16, sizeof (*td_list) * (transfer->transcnt + 1)); td_list_chunk = grub_memalign_dma32 (256, sizeof (*td_list)
if (! td_list) * (transfer->transcnt + 1));
if (! td_list_chunk)
{ {
grub_free ((void *) ed); grub_dma_free (ed_chunk);
return GRUB_USB_ERR_INTERNAL; return GRUB_USB_ERR_INTERNAL;
} }
td_list = grub_dma_get_virt (td_list_chunk);
td_list_addr = grub_dma_get_phys (td_list_chunk);
grub_dprintf ("ohci", "alloc=%p\n", td_list); grub_dprintf ("ohci", "alloc=%p/0x%x\n", td_list, td_list_addr);
/* Setup all Transfer Descriptors. */ /* Setup all Transfer Descriptors. */
for (i = 0; i < transfer->transcnt; i++) for (i = 0; i < transfer->transcnt; i++)
@ -307,16 +483,31 @@ grub_ohci_transfer (grub_usb_controller_t dev,
grub_ohci_transaction (&td_list[i], tr->pid, tr->toggle, grub_ohci_transaction (&td_list[i], tr->pid, tr->toggle,
tr->size, tr->data); tr->size, tr->data);
td_list[i].next_td = grub_cpu_to_le32 (&td_list[i + 1]); td_list[i].next_td = grub_cpu_to_le32 (td_list_addr
+ (i + 1) * sizeof (td_list[0]));
} }
#if 0 /* Better will be enable interrupt on all TDs. */
/* The last-1 TD token we should change to enable interrupt when TD finishes.
* As OHCI interrupts are disabled, it does only setting of WDH bit in
* HcInterruptStatus register - and that is what we want to safely detect
* normal end of all transactions. */
td_list[transfer->transcnt - 1].token &= ~(7 << 21);
#endif
td_list[transfer->transcnt].token = 0;
td_list[transfer->transcnt].buffer = 0;
td_list[transfer->transcnt].buffer_end = 0;
td_list[transfer->transcnt].next_td =
(grub_uint32_t) &td_list[transfer->transcnt];
/* Setup the Endpoint Descriptor. */ /* Setup the Endpoint Descriptor. */
/* Set the device address. */ /* Set the device address. */
target = transfer->devaddr; target = transfer->devaddr;
/* Set the endpoint. */ /* Set the endpoint. It should be masked, we need 4 bits only. */
target |= transfer->endpoint << 7; target |= (transfer->endpoint & 15) << 7;
/* Set the device speed. */ /* Set the device speed. */
target |= (transfer->dev->speed == GRUB_USB_SPEED_LOW) << 13; target |= (transfer->dev->speed == GRUB_USB_SPEED_LOW) << 13;
@ -324,9 +515,9 @@ grub_ohci_transfer (grub_usb_controller_t dev,
/* Set the maximum packet size. */ /* Set the maximum packet size. */
target |= transfer->max << 16; target |= transfer->max << 16;
td_head = (grub_uint32_t) td_list; td_head = td_list_addr;
td_tail = (grub_uint32_t) &td_list[transfer->transcnt]; td_tail = td_list_addr + transfer->transcnt * sizeof (*td_list);
ed->target = grub_cpu_to_le32 (target); ed->target = grub_cpu_to_le32 (target);
ed->td_head = grub_cpu_to_le32 (td_head); ed->td_head = grub_cpu_to_le32 (td_head);
@ -335,6 +526,30 @@ grub_ohci_transfer (grub_usb_controller_t dev,
grub_dprintf ("ohci", "program OHCI\n"); grub_dprintf ("ohci", "program OHCI\n");
/* Disable the Control and Bulk lists. */
control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
control &= ~(3 << 4);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
/* Clear BulkListFilled and ControlListFilled. */
status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
status &= ~(3 << 1);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
/* Now we should wait for start of next frame. Because we are not using
* interrupt, we reset SF bit and wait when it goes to 1. */
/* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2));
/* Wait for new SOF */
while ((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0);
/* Now it should be safe to change CONTROL and BULK lists. */
/* This we do for safety's sake - it should be done in previous call
* of grub_ohci_transfer and nobody should change it in meantime...
* It should be done before start of control or bulk OHCI list. */
o->hcca->donehead = 0;
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */
/* Program the OHCI to actually transfer. */ /* Program the OHCI to actually transfer. */
switch (transfer->type) switch (transfer->type)
{ {
@ -342,24 +557,22 @@ grub_ohci_transfer (grub_usb_controller_t dev,
{ {
grub_dprintf ("ohci", "add to bulk list\n"); grub_dprintf ("ohci", "add to bulk list\n");
status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); /* Set BulkList Head and Current */
control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL); grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, ed_addr);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0);
/* Disable the Control and Bulk lists. */ #define GRUB_OHCI_REG_CONTROL_BULK_ENABLE (1 << 5)
control &= ~(3 << 4); #define GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE (1 << 4)
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
/* Clear BulkListFilled. */
status &= ~(1 << 2);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, (grub_uint32_t) ed);
/* Enable the Bulk list. */ /* Enable the Bulk list. */
control |= 1 << 5; control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
control |= GRUB_OHCI_REG_CONTROL_BULK_ENABLE;
control &= ~GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE;
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
/* Set BulkListFilled. */ /* Set BulkListFilled. */
status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
status |= 1 << 2; status |= 1 << 2;
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
@ -369,24 +582,14 @@ grub_ohci_transfer (grub_usb_controller_t dev,
case GRUB_USB_TRANSACTION_TYPE_CONTROL: case GRUB_USB_TRANSACTION_TYPE_CONTROL:
{ {
grub_dprintf ("ohci", "add to control list\n"); grub_dprintf ("ohci", "add to control list\n");
status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
control = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL);
/* Disable the Control and Bulk lists. */ /* Set ControlList Head and Current */
control &= ~(3 << 4); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, ed_addr);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0);
/* Clear ControlListFilled. */
status &= ~(1 << 1);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD,
(grub_uint32_t) ed);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD+1,
(grub_uint32_t) ed);
/* Enable the Control list. */ /* Enable the Control list. */
control |= 1 << 4; control |= GRUB_OHCI_REG_CONTROL_CONTROL_ENABLE;
control &= ~GRUB_OHCI_REG_CONTROL_BULK_ENABLE;
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, control);
/* Set ControlListFilled. */ /* Set ControlListFilled. */
@ -397,37 +600,138 @@ grub_ohci_transfer (grub_usb_controller_t dev,
} }
grub_dprintf ("ohci", "wait for completion\n"); grub_dprintf ("ohci", "wait for completion\n");
grub_dprintf ("ohci", "control=0x%02x status=0x%02x\n", grub_dprintf ("ohci", "begin: control=0x%02x status=0x%02x\n",
grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL), grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL),
grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS)); grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS));
grub_dprintf ("ohci","intstatus=0x%02x\n",
grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS));
/* Safety measure to avoid a hang. */
maxtime = grub_get_time_ms () + 1000;
/* Wait until the transfer is completed or STALLs. */ /* Wait until the transfer is completed or STALLs. */
while ((ed->td_head & ~0xf) != (ed->td_tail & ~0xf)) do
{ {
grub_cpu_idle (); /* Check transfer status */
intstatus = grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS);
if ((intstatus & 0x2) != 0)
{
grub_dprintf ("ohci", "Current HccaDoneHead=0x%08x\n",
o->hcca->donehead);
/* Remember last successful TD */
tderr_addr = grub_le_to_cpu32 (o->hcca->donehead) & ~0xf;
/* Reset DoneHead */
o->hcca->donehead = 0;
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1));
/* if TD is last, finish */
if (tderr_addr == td_list_addr
+ sizeof (td_list[0]) * (transfer->transcnt - 1))
break;
continue;
}
grub_dprintf ("ohci", "head=0x%02x tail=0x%02x\n", ed->td_head, ed->td_tail); if ((intstatus & 0x10) != 0)
{ /* Unrecoverable error - only reset can help...! */
err_unrec = 1;
break;
}
/* Detected a STALL. */ /* Detected a HALT. */
if (ed->td_head & 1) if (grub_le_to_cpu32 (ed->td_head) & 1)
break;
/* Timeout ? */
if (grub_get_time_ms () > maxtime)
{
/* Disable the Control and Bulk lists. */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL,
grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) & ~(3 << 4));
err_timeout = 1;
break;
}
if ((ed->td_head & ~0xf) == (ed->td_tail & ~0xf))
break; break;
grub_cpu_idle ();
} }
while (1);
grub_dprintf ("ohci", "complete\n"); grub_dprintf ("ohci", "end: control=0x%02x status=0x%02x\n",
grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL),
grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS));
grub_dprintf ("ohci", "intstatus=0x%02x\n",
grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS));
/* if (ed->td_head & 1) */ if (!tderr_addr)
/* err = GRUB_USB_ERR_STALL; */ {
/* else if (ed->td */ /* It means that something wrong happened,
* it could be:
* - timeout and no TD processed
* - some or unrecoverable error and no TD processed
* - something unexpected... :-( */
/* Try look into DONEHEAD reg., but there should be also zero */
grub_dprintf("ohci", "HCCA DoneHead is zero, something is bad!\n");
tderr_addr = grub_ohci_readreg32 (o, GRUB_OHCI_REG_DONEHEAD) & ~0xf;
}
/* Remember last processed transaction (TD) - it is necessary for
* proper setting of toggle bit in next transaction. */
transfer->last_trans = ((tderr_addr - td_list_addr) / sizeof (*td_list));
grub_dprintf("ohci", "tderr_addr=0x%x, td_list_addr=0x%x,\n",
tderr_addr, td_list_addr);
if ((ed->td_head & ~0xf) == (ed->td_tail & ~0xf))
transfer->last_trans = transfer->transcnt - 1;
if (ed->td_head & 1) /* Check correct value in last_trans */
/* It could happen if timeout happens and no TD was retired */
if (transfer->last_trans >= transfer->transcnt || !tderr_addr)
{
grub_dprintf("ohci", "tderr==0 or out of TDs range!\n");
grub_dprintf("ohci", "last_trans=%d, transcnt=%d\n",
transfer->last_trans, transfer->transcnt);
/* We should set something valid... */
transfer->last_trans = -1; /* Probably no TD done */
tderr_addr = td_list_addr;
}
/* In case of timeout do not detect error from TD */
if (err_timeout)
{
err = GRUB_ERR_TIMEOUT;
grub_dprintf("ohci", "Timeout, target=%08x, head=%08x\n",
grub_le_to_cpu32(ed->target),
grub_le_to_cpu32(ed->td_head));
grub_dprintf("ohci", "tail=%08x, next=%08x\n",
grub_le_to_cpu32(ed->td_tail),
grub_le_to_cpu32(ed->next_ed));
}
/* In case of unrecoverable error do not detect error from TD */
else if (err_unrec)
{
err = GRUB_USB_ERR_UNRECOVERABLE;
grub_dprintf("ohci",
"Unrecoverable error, target=%08x, head=%08x\n",
grub_le_to_cpu32(ed->target),
grub_le_to_cpu32(ed->td_head));
grub_dprintf("ohci", "tail=%08x, next=%08x\n",
grub_le_to_cpu32(ed->td_tail),
grub_le_to_cpu32(ed->next_ed));
}
else if (grub_le_to_cpu32 (ed->td_head) & 1)
{ {
grub_uint8_t errcode; grub_uint8_t errcode;
grub_ohci_td_t tderr; grub_ohci_td_t tderr = NULL;
tderr = (grub_ohci_td_t) grub_ohci_readreg32 (o, transfer->last_trans--;
GRUB_OHCI_REG_DONEHEAD);
errcode = tderr->token >> 28; tderr = (grub_ohci_td_t) ((char *) td_list
+ (tderr_addr - td_list_addr));
errcode = grub_le_to_cpu32 (tderr->token) >> 28;
grub_dprintf ("ohci", "OHCI errcode=0x%02x\n", errcode);
switch (errcode) switch (errcode)
{ {
@ -473,11 +777,17 @@ grub_ohci_transfer (grub_usb_controller_t dev,
case 8: case 8:
/* XXX: Data overrun error. */ /* XXX: Data overrun error. */
err = GRUB_USB_ERR_DATA; err = GRUB_USB_ERR_DATA;
grub_dprintf ("ohci", "Overrun, failed TD address: %p, index: %d\n",
tderr, transfer->last_trans);
break; break;
case 9: case 9:
/* XXX: Data underrun error. */ /* XXX: Data underrun error. */
err = GRUB_USB_ERR_DATA; err = GRUB_USB_ERR_DATA;
grub_dprintf ("ohci", "Underrun, failed TD address: %p, index: %d\n",
tderr, transfer->last_trans);
grub_dprintf ("ohci", "Underrun, number of not transferred bytes: %d\n",
1 + grub_le_to_cpu32 (tderr->buffer_end) - grub_le_to_cpu32 (tderr->buffer));
break; break;
case 10: case 10:
@ -515,12 +825,58 @@ grub_ohci_transfer (grub_usb_controller_t dev,
/* Clear BulkListFilled and ControlListFilled. */ /* Clear BulkListFilled and ControlListFilled. */
status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS); status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_CMDSTATUS);
status &= ~((1 << 2) | (1 << 3)); status &= ~(3 << 1);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status); grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, status);
/* Set ED to be skipped - for safety */
ed->target |= grub_cpu_to_le32 (1 << 14);
/* Now we should wait for start of next frame.
* It is necessary because we will invalidate pointer to ED and it
* can be on OHCI active till SOF!
* Because we are not using interrupt, we reset SF bit and wait when
* it goes to 1. */
/* SF bit reset. (SF bit indicates Start Of Frame (SOF) packet) */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1<<2));
/* Wait for new SOF */
while (((grub_ohci_readreg32 (o, GRUB_OHCI_REG_INTSTATUS) & 0x4) == 0)
&& !err_unrec);
/* Now it should be safe to change CONTROL and BULK lists. */
/* Important cleaning. */
o->hcca->donehead = 0;
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, (1 << 1)); /* Clears WDH */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0);
/* XXX */ if (err_unrec)
grub_free (td_list); {
grub_free (ed); /* Do OHCI reset in case of unrecoverable error - maybe we will need
* do more - re-enumerate bus etc. (?) */
/* Suspend the OHCI by issuing a reset. */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1); /* XXX: Magic. */
grub_millisleep (1);
grub_dprintf ("ohci", "Unrecoverable error - OHCI reset\n");
/* Misc. resets. */
o->hcca->donehead = 0;
grub_ohci_writereg32 (o, GRUB_OHCI_REG_INTSTATUS, 0x7f); /* Clears everything */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0);
/* Enable the OHCI. */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, (2 << 6));
}
grub_dprintf ("ohci", "OHCI finished, freeing, err=0x%02x\n", err);
grub_dma_free (td_list_chunk);
grub_dma_free (ed_chunk);
return err; return err;
} }
@ -530,28 +886,30 @@ grub_ohci_portstatus (grub_usb_controller_t dev,
unsigned int port, unsigned int enable) unsigned int port, unsigned int enable)
{ {
struct grub_ohci *o = (struct grub_ohci *) dev->data; struct grub_ohci *o = (struct grub_ohci *) dev->data;
grub_uint32_t status;
/* Reset the port. */ grub_dprintf ("ohci", "begin of portstatus=0x%02x\n",
status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port));
status |= (1 << 4); /* XXX: Magic. */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
grub_millisleep (100);
/* End the reset signaling. */ grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); GRUB_OHCI_SET_PORT_RESET);
status |= (1 << 20); /* XXX: Magic. */ grub_millisleep (50); /* For root hub should be nominaly 50ms */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status);
/* End the reset signaling. */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
GRUB_OHCI_SET_PORT_RESET_STATUS_CHANGE);
grub_millisleep (10); grub_millisleep (10);
/* Enable the port. */ if (enable)
status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
status |= (enable << 1); /* XXX: Magic. */ GRUB_OHCI_SET_PORT_ENABLE);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port, status); else
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + port,
status = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port); GRUB_OHCI_CLEAR_PORT_ENABLE);
grub_dprintf ("ohci", "portstatus=0x%02x\n", status); grub_millisleep (10);
grub_dprintf ("ohci", "end of portstatus=0x%02x\n",
grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBPORT + port));
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@ -587,6 +945,42 @@ grub_ohci_hubports (grub_usb_controller_t dev)
return portinfo & 0xFF; return portinfo & 0xFF;
} }
static grub_err_t
grub_ohci_fini_hw (int noreturn __attribute__ ((unused)))
{
struct grub_ohci *o;
for (o = ohci; o; o = o->next)
{
int i, nports = grub_ohci_readreg32 (o, GRUB_OHCI_REG_RHUBA) & 0xff;
for (i = 0; i < nports; i++)
grub_ohci_writereg32 (o, GRUB_OHCI_REG_RHUBPORT + i,
GRUB_OHCI_CLEAR_PORT_ENABLE);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLHEAD, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROLCURR, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKHEAD, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_BULKCURR, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_DONEHEAD, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL, 0);
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CMDSTATUS, 1);
}
grub_millisleep (10);
return GRUB_ERR_NONE;
}
static grub_err_t
grub_ohci_restore_hw (void)
{
struct grub_ohci *o;
for (o = ohci; o; o = o->next)
grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, o->hcca_addr);
return GRUB_ERR_NONE;
}
static struct grub_usb_controller_dev usb_controller = static struct grub_usb_controller_dev usb_controller =
@ -603,9 +997,12 @@ GRUB_MOD_INIT(ohci)
{ {
grub_ohci_inithw (); grub_ohci_inithw ();
grub_usb_controller_dev_register (&usb_controller); grub_usb_controller_dev_register (&usb_controller);
grub_loader_register_preboot_hook (grub_ohci_fini_hw, grub_ohci_restore_hw,
GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK);
} }
GRUB_MOD_FINI(ohci) GRUB_MOD_FINI(ohci)
{ {
grub_ohci_fini_hw (0);
grub_usb_controller_dev_unregister (&usb_controller); grub_usb_controller_dev_unregister (&usb_controller);
} }

View file

@ -174,14 +174,15 @@ grub_uhci_pci_iter (grub_pci_device_t dev,
return 1; return 1;
u->iobase = base & GRUB_UHCI_IOMASK; u->iobase = base & GRUB_UHCI_IOMASK;
grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x\n",
class, subclass, interf, u->iobase);
/* Reserve a page for the frame list. */ /* Reserve a page for the frame list. */
u->framelist = grub_memalign (4096, 4096); u->framelist = grub_memalign (4096, 4096);
if (! u->framelist) if (! u->framelist)
goto fail; goto fail;
grub_dprintf ("uhci", "class=0x%02x 0x%02x interface 0x%02x base=0x%x framelist=%p\n",
class, subclass, interf, u->iobase, u->framelist);
/* The framelist pointer of UHCI is only 32 bits, make sure this /* The framelist pointer of UHCI is only 32 bits, make sure this
code works on on 64 bits architectures. */ code works on on 64 bits architectures. */
#if GRUB_CPU_SIZEOF_VOID_P == 8 #if GRUB_CPU_SIZEOF_VOID_P == 8
@ -221,6 +222,9 @@ grub_uhci_pci_iter (grub_pci_device_t dev,
} }
#endif #endif
grub_dprintf ("uhci", "QH=%p, TD=%p\n",
u->qh, u->td);
/* Link all Transfer Descriptors in a list of available Transfer /* Link all Transfer Descriptors in a list of available Transfer
Descriptors. */ Descriptors. */
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
@ -328,13 +332,20 @@ grub_free_td (struct grub_uhci *u, grub_uhci_td_t td)
} }
static void static void
grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td) grub_free_queue (struct grub_uhci *u, grub_uhci_td_t td,
grub_usb_transfer_t transfer)
{ {
/* Free the TDs in this queue. */ int i; /* Index of TD in transfer */
while (td)
/* Free the TDs in this queue and set last_trans. */
for (i=0; td; i++)
{ {
grub_uhci_td_t tdprev; grub_uhci_td_t tdprev;
/* Check state of TD and possibly set last_trans */
if (transfer && (td->linkptr & 1))
transfer->last_trans = i;
/* Unlink the queue. */ /* Unlink the queue. */
tdprev = td; tdprev = td;
td = (grub_uhci_td_t) td->linkptr2; td = (grub_uhci_td_t) td->linkptr2;
@ -380,7 +391,7 @@ static grub_uhci_td_t
grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
grub_transfer_type_t type, unsigned int addr, grub_transfer_type_t type, unsigned int addr,
unsigned int toggle, grub_size_t size, unsigned int toggle, grub_size_t size,
char *data) grub_uint32_t data)
{ {
grub_uhci_td_t td; grub_uhci_td_t td;
static const unsigned int tf[] = { 0x69, 0xE1, 0x2D }; static const unsigned int tf[] = { 0x69, 0xE1, 0x2D };
@ -398,7 +409,7 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
} }
grub_dprintf ("uhci", grub_dprintf ("uhci",
"transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=%p td=%p\n", "transaction: endp=%d, type=%d, addr=%d, toggle=%d, size=%d data=0x%x td=%p\n",
endp, type, addr, toggle, size, data, td); endp, type, addr, toggle, size, data, td);
/* Don't point to any TD, just terminate. */ /* Don't point to any TD, just terminate. */
@ -418,7 +429,7 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp,
td->token = ((size << 21) | (toggle << 19) | (endp << 15) td->token = ((size << 21) | (toggle << 19) | (endp << 15)
| (addr << 8) | tf[type]); | (addr << 8) | tf[type]);
td->buffer = (grub_uint32_t) data; td->buffer = data;
return td; return td;
} }
@ -441,6 +452,8 @@ grub_uhci_transfer (grub_usb_controller_t dev,
if (! qh) if (! qh)
return grub_errno; return grub_errno;
grub_dprintf ("uhci", "transfer, iobase:%08x\n", u->iobase);
for (i = 0; i < transfer->transcnt; i++) for (i = 0; i < transfer->transcnt; i++)
{ {
grub_usb_transaction_t tr = &transfer->transactions[i]; grub_usb_transaction_t tr = &transfer->transactions[i];
@ -455,7 +468,7 @@ grub_uhci_transfer (grub_usb_controller_t dev,
td_prev->linkptr = 1; td_prev->linkptr = 1;
if (td_first) if (td_first)
grub_free_queue (u, td_first); grub_free_queue (u, td_first, NULL);
return GRUB_USB_ERR_INTERNAL; return GRUB_USB_ERR_INTERNAL;
} }
@ -548,12 +561,13 @@ grub_uhci_transfer (grub_usb_controller_t dev,
fail: fail:
grub_dprintf ("uhci", "transaction failed\n"); if (err != GRUB_USB_ERR_NONE)
grub_dprintf ("uhci", "transaction failed\n");
/* Place the QH back in the free list and deallocate the associated /* Place the QH back in the free list and deallocate the associated
TDs. */ TDs. */
qh->elinkptr = 1; qh->elinkptr = 1;
grub_free_queue (u, td_first); grub_free_queue (u, td_first, transfer);
return err; return err;
} }
@ -583,6 +597,8 @@ grub_uhci_portstatus (grub_usb_controller_t dev,
unsigned int status; unsigned int status;
grub_uint64_t endtime; grub_uint64_t endtime;
grub_dprintf ("uhci", "portstatus, iobase:%08x\n", u->iobase);
grub_dprintf ("uhci", "enable=%d port=%d\n", enable, port); grub_dprintf ("uhci", "enable=%d port=%d\n", enable, port);
if (port == 0) if (port == 0)
@ -600,7 +616,7 @@ grub_uhci_portstatus (grub_usb_controller_t dev,
grub_uhci_writereg16 (u, reg, enable << 9); grub_uhci_writereg16 (u, reg, enable << 9);
/* Wait for the reset to complete. XXX: How long exactly? */ /* Wait for the reset to complete. XXX: How long exactly? */
grub_millisleep (10); grub_millisleep (50); /* For root hub should be nominaly 50ms */
status = grub_uhci_readreg16 (u, reg); status = grub_uhci_readreg16 (u, reg);
grub_uhci_writereg16 (u, reg, status & ~(1 << 9)); grub_uhci_writereg16 (u, reg, status & ~(1 << 9));
grub_dprintf ("uhci", "reset completed\n"); grub_dprintf ("uhci", "reset completed\n");
@ -631,6 +647,8 @@ grub_uhci_detect_dev (grub_usb_controller_t dev, int port)
int reg; int reg;
unsigned int status; unsigned int status;
grub_dprintf ("uhci", "detect_dev, iobase:%08x\n", u->iobase);
if (port == 0) if (port == 0)
reg = GRUB_UHCI_REG_PORTSC1; reg = GRUB_UHCI_REG_PORTSC1;
else if (port == 1) else if (port == 1)

View file

@ -105,10 +105,7 @@ grub_usb_clear_halt (grub_usb_device_t dev, int endpoint)
grub_usb_err_t grub_usb_err_t
grub_usb_set_configuration (grub_usb_device_t dev, int configuration) grub_usb_set_configuration (grub_usb_device_t dev, int configuration)
{ {
int i; grub_memset (dev->toggle, 0, sizeof (dev->toggle));
for (i = 0; i < 16; i++)
dev->toggle[i] = 0;
return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
| GRUB_USB_REQTYPE_STANDARD | GRUB_USB_REQTYPE_STANDARD
@ -163,6 +160,16 @@ grub_usb_device_initialize (grub_usb_device_t dev)
grub_usb_err_t err; grub_usb_err_t err;
int i; int i;
/* First we have to read first 8 bytes only and determine
* max. size of packet */
dev->descdev.maxsize0 = 0; /* invalidating, for safety only, can be removed if it is sure it is zero here */
err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE,
0, 8, (char *) &dev->descdev);
if (err)
return err;
/* Now we have valid value in dev->descdev.maxsize0,
* so we can read whole device descriptor */
err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE, err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE,
0, sizeof (struct grub_usb_desc_device), 0, sizeof (struct grub_usb_desc_device),
(char *) &dev->descdev); (char *) &dev->descdev);

View file

@ -18,6 +18,7 @@
*/ */
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/pci.h>
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/usb.h> #include <grub/usb.h>
@ -29,30 +30,59 @@ grub_usb_control_msg (grub_usb_device_t dev,
grub_uint8_t request, grub_uint8_t request,
grub_uint16_t value, grub_uint16_t value,
grub_uint16_t index, grub_uint16_t index,
grub_size_t size, char *data) grub_size_t size0, char *data_in)
{ {
int i; int i;
grub_usb_transfer_t transfer; grub_usb_transfer_t transfer;
int datablocks; int datablocks;
struct grub_usb_packet_setup setupdata; volatile struct grub_usb_packet_setup *setupdata;
grub_uint32_t setupdata_addr;
grub_usb_err_t err; grub_usb_err_t err;
unsigned int max; unsigned int max;
struct grub_pci_dma_chunk *data_chunk, *setupdata_chunk;
volatile char *data;
grub_uint32_t data_addr;
grub_size_t size = size0;
/* FIXME: avoid allocation any kind of buffer in a first place. */
data_chunk = grub_memalign_dma32 (128, size ? : 16);
if (!data_chunk)
return GRUB_USB_ERR_INTERNAL;
data = grub_dma_get_virt (data_chunk);
data_addr = grub_dma_get_phys (data_chunk);
grub_memcpy ((char *) data, data_in, size);
grub_dprintf ("usb", grub_dprintf ("usb",
"control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%d\n", "control: reqtype=0x%02x req=0x%02x val=0x%02x idx=0x%02x size=%d\n",
reqtype, request, value, index, size); reqtype, request, value, index, size);
/* Create a transfer. */ /* Create a transfer. */
transfer = grub_malloc (sizeof (struct grub_usb_transfer)); transfer = grub_malloc (sizeof (*transfer));
if (! transfer) if (! transfer)
return grub_errno; {
grub_dma_free (data_chunk);
return grub_errno;
}
setupdata_chunk = grub_memalign_dma32 (32, sizeof (*setupdata));
if (! setupdata_chunk)
{
grub_free (transfer);
grub_dma_free (data_chunk);
return grub_errno;
}
setupdata = grub_dma_get_virt (setupdata_chunk);
setupdata_addr = grub_dma_get_phys (setupdata_chunk);
/* Determine the maximum packet size. */ /* Determine the maximum packet size. */
if (dev->initialized) if (dev->descdev.maxsize0)
max = dev->descdev.maxsize0; max = dev->descdev.maxsize0;
else else
max = 64; max = 64;
grub_dprintf ("usb", "transfer = %p, dev = %p\n", transfer, dev);
datablocks = (size + max - 1) / max; datablocks = (size + max - 1) / max;
/* XXX: Discriminate between different types of control /* XXX: Discriminate between different types of control
@ -71,18 +101,20 @@ grub_usb_control_msg (grub_usb_device_t dev,
if (! transfer->transactions) if (! transfer->transactions)
{ {
grub_free (transfer); grub_free (transfer);
grub_dma_free (setupdata_chunk);
grub_dma_free (data_chunk);
return grub_errno; return grub_errno;
} }
/* Build a Setup packet. XXX: Endianness. */ /* Build a Setup packet. XXX: Endianness. */
setupdata.reqtype = reqtype; setupdata->reqtype = reqtype;
setupdata.request = request; setupdata->request = request;
setupdata.value = value; setupdata->value = value;
setupdata.index = index; setupdata->index = index;
setupdata.length = size; setupdata->length = size;
transfer->transactions[0].size = sizeof (setupdata); transfer->transactions[0].size = sizeof (*setupdata);
transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP; transfer->transactions[0].pid = GRUB_USB_TRANSFER_TYPE_SETUP;
transfer->transactions[0].data = (char *) &setupdata; transfer->transactions[0].data = setupdata_addr;
transfer->transactions[0].toggle = 0; transfer->transactions[0].toggle = 0;
/* Now the data... XXX: Is this the right way to transfer control /* Now the data... XXX: Is this the right way to transfer control
@ -99,14 +131,14 @@ grub_usb_control_msg (grub_usb_device_t dev,
tr->pid = GRUB_USB_TRANSFER_TYPE_IN; tr->pid = GRUB_USB_TRANSFER_TYPE_IN;
else else
tr->pid = GRUB_USB_TRANSFER_TYPE_OUT; tr->pid = GRUB_USB_TRANSFER_TYPE_OUT;
tr->data = &data[i * max]; tr->data = data_addr + i * max;
size -= max; size -= max;
} }
/* End with an empty OUT transaction. */ /* End with an empty OUT transaction. */
transfer->transactions[datablocks + 1].size = 0; transfer->transactions[datablocks + 1].size = 0;
transfer->transactions[datablocks + 1].data = NULL; transfer->transactions[datablocks + 1].data = 0;
if (reqtype & 128) if ((reqtype & 128) && datablocks)
transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT; transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT;
else else
transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_IN; transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_IN;
@ -116,14 +148,19 @@ grub_usb_control_msg (grub_usb_device_t dev,
err = dev->controller.dev->transfer (&dev->controller, transfer); err = dev->controller.dev->transfer (&dev->controller, transfer);
grub_free (transfer->transactions); grub_free (transfer->transactions);
grub_free (transfer); grub_free (transfer);
grub_dma_free (data_chunk);
grub_dma_free (setupdata_chunk);
grub_memcpy (data_in, (char *) data, size0);
return err; return err;
} }
static grub_usb_err_t static grub_usb_err_t
grub_usb_bulk_readwrite (grub_usb_device_t dev, grub_usb_bulk_readwrite (grub_usb_device_t dev,
int endpoint, grub_size_t size, char *data, int endpoint, grub_size_t size0, char *data_in,
grub_transfer_type_t type) grub_transfer_type_t type)
{ {
int i; int i;
@ -132,6 +169,19 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
unsigned int max; unsigned int max;
grub_usb_err_t err; grub_usb_err_t err;
int toggle = dev->toggle[endpoint]; int toggle = dev->toggle[endpoint];
volatile char *data;
grub_uint32_t data_addr;
struct grub_pci_dma_chunk *data_chunk;
grub_size_t size = size0;
/* FIXME: avoid allocation any kind of buffer in a first place. */
data_chunk = grub_memalign_dma32 (128, size);
if (!data_chunk)
return GRUB_USB_ERR_INTERNAL;
data = grub_dma_get_virt (data_chunk);
data_addr = grub_dma_get_phys (data_chunk);
if (type == GRUB_USB_TRANSFER_TYPE_OUT)
grub_memcpy ((char *) data, data_in, size);
/* Use the maximum packet size given in the endpoint descriptor. */ /* Use the maximum packet size given in the endpoint descriptor. */
if (dev->initialized) if (dev->initialized)
@ -150,16 +200,20 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
/* Create a transfer. */ /* Create a transfer. */
transfer = grub_malloc (sizeof (struct grub_usb_transfer)); transfer = grub_malloc (sizeof (struct grub_usb_transfer));
if (! transfer) if (! transfer)
return grub_errno; {
grub_dma_free (data_chunk);
return grub_errno;
}
datablocks = ((size + max - 1) / max); datablocks = ((size + max - 1) / max);
transfer->transcnt = datablocks; transfer->transcnt = datablocks;
transfer->size = size - 1; transfer->size = size - 1;
transfer->endpoint = endpoint; transfer->endpoint = endpoint & 15;
transfer->devaddr = dev->addr; transfer->devaddr = dev->addr;
transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK; transfer->type = GRUB_USB_TRANSACTION_TYPE_BULK;
transfer->max = max; transfer->max = max;
transfer->dev = dev; transfer->dev = dev;
transfer->last_trans = -1; /* Reset index of last processed transaction (TD) */
/* Allocate an array of transfer data structures. */ /* Allocate an array of transfer data structures. */
transfer->transactions = grub_malloc (transfer->transcnt transfer->transactions = grub_malloc (transfer->transcnt
@ -167,6 +221,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
if (! transfer->transactions) if (! transfer->transactions)
{ {
grub_free (transfer); grub_free (transfer);
grub_dma_free (data_chunk);
return grub_errno; return grub_errno;
} }
@ -181,16 +236,27 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev,
tr->toggle = toggle; tr->toggle = toggle;
toggle = toggle ? 0 : 1; toggle = toggle ? 0 : 1;
tr->pid = type; tr->pid = type;
tr->data = &data[i * max]; tr->data = data_addr + i * max;
size -= tr->size; size -= tr->size;
} }
err = dev->controller.dev->transfer (&dev->controller, transfer); err = dev->controller.dev->transfer (&dev->controller, transfer);
/* We must remember proper toggle value even if some transactions
* were not processed - correct value should be inversion of last
* processed transaction (TD). */
if (transfer->last_trans >= 0)
toggle = transfer->transactions[transfer->last_trans].toggle ? 0 : 1;
else
toggle = dev->toggle[endpoint]; /* Nothing done, take original */
grub_dprintf ("usb", "toggle=%d\n", toggle); grub_dprintf ("usb", "toggle=%d\n", toggle);
dev->toggle[endpoint] = toggle; dev->toggle[endpoint] = toggle;
grub_free (transfer->transactions); grub_free (transfer->transactions);
grub_free (transfer); grub_free (transfer);
grub_dma_free (data_chunk);
if (type == GRUB_USB_TRANSFER_TYPE_IN)
grub_memcpy (data_in, (char *) data, size0);
return err; return err;
} }

View file

@ -138,8 +138,8 @@ grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)),
{ {
grub_device_close (dev); grub_device_close (dev);
return grub_error (GRUB_ERR_OUT_OF_RANGE, return grub_error (GRUB_ERR_OUT_OF_RANGE,
"only partitions resding in the first 2TB " "only partitions residing in the first 2TB "
"can be presen in hybrid MBR"); "can be present in hybrid MBR");
} }
@ -243,8 +243,8 @@ GRUB_MOD_INIT(gptsync)
cmd = grub_register_command ("gptsync", grub_cmd_gptsync, cmd = grub_register_command ("gptsync", grub_cmd_gptsync,
N_("DEVICE [PARTITION[+/-[TYPE]]] ..."), N_("DEVICE [PARTITION[+/-[TYPE]]] ..."),
N_("Fill hybrid MBR of GPT drive DEVICE. " N_("Fill hybrid MBR of GPT drive DEVICE. "
"specified partitions will be a part " "Specified partitions will be a part "
"of hybrid mbr. Up to 3 partitions are " "of hybrid MBR. Up to 3 partitions are "
"allowed. TYPE is an MBR type. " "allowed. TYPE is an MBR type. "
"+ means that partition is active. " "+ means that partition is active. "
"Only one partition can be active.")); "Only one partition can be active."));

59
commands/i386/cmostest.c Normal file
View file

@ -0,0 +1,59 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 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/dl.h>
#include <grub/command.h>
#include <grub/misc.h>
#include <grub/cmos.h>
static grub_err_t
grub_cmd_cmostest (struct grub_command *cmd __attribute__ ((unused)),
int argc, char *argv[])
{
int byte, bit;
char *rest;
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required.");
byte = grub_strtoul (argv[0], &rest, 0);
if (*rest != ':')
return grub_error (GRUB_ERR_BAD_ARGUMENT, "Address required.");
bit = grub_strtoul (rest + 1, 0, 0);
if (grub_cmos_read (byte) & (1 << bit))
return GRUB_ERR_NONE;
return grub_error (GRUB_ERR_TEST_FAILURE, "false");
}
static grub_command_t cmd;
GRUB_MOD_INIT(cmostest)
{
cmd = grub_register_command ("cmostest", grub_cmd_cmostest,
"cmostest BYTE:BIT",
"Test bit at BYTE:BIT in CMOS.");
}
GRUB_MOD_FINI(cmostest)
{
grub_unregister_command (cmd);
}

View file

@ -96,7 +96,7 @@ grub_setpci_iter (grub_pci_device_t dev, grub_pci_id_t pciid)
if (check_device && grub_pci_get_device (dev) != device) if (check_device && grub_pci_get_device (dev) != device)
return 0; return 0;
if (check_function && grub_pci_get_function (dev) != device) if (check_function && grub_pci_get_function (dev) != function)
return 0; return 0;
addr = grub_pci_make_address (dev, regaddr); addr = grub_pci_make_address (dev, regaddr);

View file

@ -83,15 +83,24 @@ grub_usb_get_string (grub_usb_device_t dev, grub_uint8_t index, int langid,
0x06, (3 << 8) | index, 0x06, (3 << 8) | index,
langid, descstr.length, (char *) descstrp); langid, descstr.length, (char *) descstrp);
*string = grub_malloc (descstr.length / 2); if (descstrp->length == 0)
{
grub_free (descstrp);
*string = grub_strdup ("");
if (! *string)
return GRUB_USB_ERR_INTERNAL;
return GRUB_USB_ERR_NONE;
}
*string = grub_malloc (descstr.length * 2 + 1);
if (! *string) if (! *string)
{ {
grub_free (descstrp); grub_free (descstrp);
return GRUB_USB_ERR_INTERNAL; return GRUB_USB_ERR_INTERNAL;
} }
grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str, descstrp->length / 2 - 1); *grub_utf16_to_utf8 ((grub_uint8_t *) *string, descstrp->str,
(*string)[descstr.length / 2 - 1] = '\0'; descstrp->length / 2 - 1) = 0;
grub_free (descstrp); grub_free (descstrp);
return GRUB_USB_ERR_NONE; return GRUB_USB_ERR_NONE;

View file

@ -1,7 +1,5 @@
# -*- makefile -*- # -*- makefile -*-
COMMON_CFLAGS += -nostdinc -isystem $(shell $(TARGET_CC) -print-file-name=include)
kernel_img_RELOCATABLE = yes kernel_img_RELOCATABLE = yes
pkglib_PROGRAMS = kernel.img pkglib_PROGRAMS = kernel.img
kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \ kernel_img_SOURCES = kern/device.c kern/disk.c kern/dl.c kern/env.c \
@ -22,14 +20,14 @@ TARGET_NO_STRIP = yes
ifneq ($(TARGET_NO_MODULES), yes) ifneq ($(TARGET_NO_MODULES), yes)
kernel_img_SOURCES += symlist.c kern/$(target_cpu)/dl.c kernel_img_SOURCES += symlist.c kern/$(target_cpu)/dl.c
else
kernel_img_SOURCES += grub_emu_init.c
endif
ifneq ($(target_cpu), i386) ifneq ($(target_cpu), i386)
ifneq ($(target_cpu), x86_64) ifneq ($(target_cpu), x86_64)
kernel_img_SOURCES += kern/$(target_cpu)/cache.S kernel_img_SOURCES += kern/$(target_cpu)/cache.S
endif endif
endif endif
else
kernel_img_SOURCES += grub_emu_init.c
endif
# For halt.mod. # For halt.mod.
pkglib_MODULES += halt.mod pkglib_MODULES += halt.mod

View file

@ -68,5 +68,11 @@ datetime_mod_SOURCES = lib/cmos_datetime.c
datetime_mod_CFLAGS = $(COMMON_CFLAGS) datetime_mod_CFLAGS = $(COMMON_CFLAGS)
datetime_mod_LDFLAGS = $(COMMON_LDFLAGS) datetime_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For cmostest.mod
pkglib_MODULES += cmostest.mod
cmostest_mod_SOURCES = commands/i386/cmostest.c
cmostest_mod_CFLAGS = $(COMMON_CFLAGS)
cmostest_mod_LDFLAGS = $(COMMON_LDFLAGS)
include $(srcdir)/conf/i386.mk include $(srcdir)/conf/i386.mk
include $(srcdir)/conf/common.mk include $(srcdir)/conf/common.mk

View file

@ -244,6 +244,12 @@ hdparm_mod_SOURCES = commands/hdparm.c lib/hexdump.c
hdparm_mod_CFLAGS = $(COMMON_CFLAGS) hdparm_mod_CFLAGS = $(COMMON_CFLAGS)
hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS) hdparm_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For cmostest.mod
pkglib_MODULES += cmostest.mod
cmostest_mod_SOURCES = commands/i386/cmostest.c
cmostest_mod_CFLAGS = $(COMMON_CFLAGS)
cmostest_mod_LDFLAGS = $(COMMON_LDFLAGS)
ifeq ($(enable_efiemu), yes) ifeq ($(enable_efiemu), yes)
efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF) efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)

View file

@ -56,6 +56,12 @@ pci_mod_SOURCES = bus/pci.c
pci_mod_CFLAGS = $(COMMON_CFLAGS) pci_mod_CFLAGS = $(COMMON_CFLAGS)
pci_mod_LDFLAGS = $(COMMON_LDFLAGS) pci_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For cs5536.mod
pkglib_MODULES += cs5536.mod
cs5536_mod_SOURCES = bus/cs5536.c
cs5536_mod_CFLAGS = $(COMMON_CFLAGS)
cs5536_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For lspci.mod # For lspci.mod
pkglib_MODULES += lspci.mod pkglib_MODULES += lspci.mod
lspci_mod_SOURCES = commands/lspci.c lspci_mod_SOURCES = commands/lspci.c

View file

@ -4,7 +4,8 @@ target_machine=yeeloong
COMMON_CFLAGS += -march=mips3 COMMON_CFLAGS += -march=mips3
COMMON_ASFLAGS += -march=mips3 COMMON_ASFLAGS += -march=mips3
kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h bitmap_scale.h bufio.h kernel_img_HEADERS += pci.h bitmap.h video.h gfxterm.h font.h \
bitmap_scale.h bufio.h cs5536.h machine/pci.h
include $(srcdir)/conf/mips.mk include $(srcdir)/conf/mips.mk
@ -26,6 +27,7 @@ kernel_img_SOURCES = kern/$(target_cpu)/startup.S \
video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \ video/fb/fbfill.c video/fb/fbutil.c video/bitmap.c \
video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \ video/bitmap_scale.c video/sm712.c bus/pci.c bus/bonito.c \
term/gfxterm.c commands/extcmd.c lib/arg.c \ term/gfxterm.c commands/extcmd.c lib/arg.c \
bus/cs5536.c \
symlist.c symlist.c
kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK kernel_img_CFLAGS = $(COMMON_CFLAGS) -DUSE_ASCII_FAILBACK
kernel_img_ASFLAGS = $(COMMON_ASFLAGS) kernel_img_ASFLAGS = $(COMMON_ASFLAGS)
@ -69,5 +71,35 @@ linux_mod_CFLAGS = $(COMMON_CFLAGS)
linux_mod_ASFLAGS = $(COMMON_ASFLAGS) linux_mod_ASFLAGS = $(COMMON_ASFLAGS)
linux_mod_LDFLAGS = $(COMMON_LDFLAGS) linux_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For usb.mod
pkglib_MODULES += usb.mod
usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
usb_mod_CFLAGS = $(COMMON_CFLAGS)
usb_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For usbtest.mod
pkglib_MODULES += usbtest.mod
usbtest_mod_SOURCES = commands/usbtest.c
usbtest_mod_CFLAGS = $(COMMON_CFLAGS)
usbtest_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For ohci.mod
pkglib_MODULES += ohci.mod
ohci_mod_SOURCES = bus/usb/ohci.c
ohci_mod_CFLAGS = $(COMMON_CFLAGS)
ohci_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For usbms.mod
pkglib_MODULES += usbms.mod
usbms_mod_SOURCES = disk/usbms.c
usbms_mod_CFLAGS = $(COMMON_CFLAGS)
usbms_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For usb_keyboard.mod
pkglib_MODULES += usb_keyboard.mod
usb_keyboard_mod_SOURCES = term/usb_keyboard.c
usb_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
usb_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
sbin_SCRIPTS += grub-install sbin_SCRIPTS += grub-install
grub_install_SOURCES = util/grub-install.in grub_install_SOURCES = util/grub-install.in

View file

@ -179,11 +179,13 @@ if test "x$YACC" = x; then
AC_MSG_ERROR([bison is not found]) AC_MSG_ERROR([bison is not found])
fi fi
for file in /usr/src/unifont.bdf /usr/share/fonts/X11/misc/unifont.pcf.gz /usr/share/fonts/unifont/unifont.pcf.gz; do for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do
if test -e $file ; then for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont; do
AC_SUBST([FONT_SOURCE], [$file]) if test -f "$dir/unifont.$ext"; then
break AC_SUBST([FONT_SOURCE], [$dir/unifont.$ext])
fi break 2
fi
done
done done
AC_PROG_INSTALL AC_PROG_INSTALL
@ -192,7 +194,7 @@ AC_PROG_LEX
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
AC_PROG_MKDIR_P AC_PROG_MKDIR_P
if test "x$LEX" = x; then if test "x$LEX" = "x:"; then
AC_MSG_ERROR([flex is not found]) AC_MSG_ERROR([flex is not found])
else else
version=`$LEX --version | $AWK '{ split($NF,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'` version=`$LEX --version | $AWK '{ split($NF,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'`

View file

@ -120,7 +120,8 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
{ {
data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM; data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM;
data->sectors = 32; data->sectors = 32;
total_sectors = GRUB_ULONG_MAX; /* TODO: get the correct size. */ /* TODO: get the correct size. */
total_sectors = GRUB_DISK_SIZE_UNKNOWN;
} }
else if (drive & 0x80) else if (drive & 0x80)
{ {

View file

@ -204,7 +204,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
/* XXX: There is no property to read the number of blocks. There /* XXX: There is no property to read the number of blocks. There
should be a property `#blocks', but it is not there. Perhaps it should be a property `#blocks', but it is not there. Perhaps it
is possible to use seek for this. */ is possible to use seek for this. */
disk->total_sectors = 0xFFFFFFFFUL; disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
disk->id = (unsigned long) op; disk->id = (unsigned long) op;

View file

@ -25,6 +25,7 @@
#include <grub/types.h> #include <grub/types.h>
#include <grub/scsi.h> #include <grub/scsi.h>
#include <grub/scsicmd.h> #include <grub/scsicmd.h>
#include <grub/time.h>
static grub_scsi_dev_t grub_scsi_dev_list; static grub_scsi_dev_t grub_scsi_dev_list;
@ -50,7 +51,62 @@ grub_scsi_dev_unregister (grub_scsi_dev_t dev)
} }
/* Determine the the device is removable and the type of the device /* Check result of previous operation. */
static grub_err_t
grub_scsi_request_sense (grub_scsi_t scsi)
{
struct grub_scsi_request_sense rs;
struct grub_scsi_request_sense_data rsd;
grub_err_t err;
rs.opcode = grub_scsi_cmd_request_sense;
rs.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
rs.reserved1 = 0;
rs.reserved2 = 0;
rs.alloc_length = 0x12; /* XXX: Hardcoded for now */
rs.control = 0;
grub_memset (rs.pad, 0, sizeof(rs.pad));
err = scsi->dev->read (scsi, sizeof (rs), (char *) &rs,
sizeof (rsd), (char *) &rsd);
if (err)
return err;
return GRUB_ERR_NONE;
}
/* Self commenting... */
static grub_err_t
grub_scsi_test_unit_ready (grub_scsi_t scsi)
{
struct grub_scsi_test_unit_ready tur;
grub_err_t err;
grub_err_t err_sense;
tur.opcode = grub_scsi_cmd_test_unit_ready;
tur.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
tur.reserved1 = 0;
tur.reserved2 = 0;
tur.reserved3 = 0;
tur.control = 0;
grub_memset (tur.pad, 0, sizeof(tur.pad));
err = scsi->dev->read (scsi, sizeof (tur), (char *) &tur,
0, NULL);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
if (err)
return err;
return GRUB_ERR_NONE;
}
/* Determine if the device is removable and the type of the device
SCSI. */ SCSI. */
static grub_err_t static grub_err_t
grub_scsi_inquiry (grub_scsi_t scsi) grub_scsi_inquiry (grub_scsi_t scsi)
@ -58,15 +114,26 @@ grub_scsi_inquiry (grub_scsi_t scsi)
struct grub_scsi_inquiry iq; struct grub_scsi_inquiry iq;
struct grub_scsi_inquiry_data iqd; struct grub_scsi_inquiry_data iqd;
grub_err_t err; grub_err_t err;
grub_err_t err_sense;
iq.opcode = grub_scsi_cmd_inquiry; iq.opcode = grub_scsi_cmd_inquiry;
iq.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; iq.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
iq.page = 0;
iq.reserved = 0; iq.reserved = 0;
iq.alloc_length = 0x24; /* XXX: Hardcoded for now */ iq.alloc_length = 0x24; /* XXX: Hardcoded for now */
iq.reserved2 = 0; iq.control = 0;
grub_memset (iq.pad, 0, sizeof(iq.pad));
err = scsi->dev->read (scsi, sizeof (iq), (char *) &iq, err = scsi->dev->read (scsi, sizeof (iq), (char *) &iq,
sizeof (iqd), (char *) &iqd); sizeof (iqd), (char *) &iqd);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
if (err) if (err)
return err; return err;
@ -83,13 +150,27 @@ grub_scsi_read_capacity (grub_scsi_t scsi)
struct grub_scsi_read_capacity rc; struct grub_scsi_read_capacity rc;
struct grub_scsi_read_capacity_data rcd; struct grub_scsi_read_capacity_data rcd;
grub_err_t err; grub_err_t err;
grub_err_t err_sense;
rc.opcode = grub_scsi_cmd_read_capacity; rc.opcode = grub_scsi_cmd_read_capacity;
rc.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; rc.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
grub_memset (rc.reserved, 0, sizeof (rc.reserved)); rc.logical_block_addr = 0;
rc.reserved1 = 0;
rc.reserved2 = 0;
rc.PMI = 0;
rc.control = 0;
rc.pad = 0;
err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc, err = scsi->dev->read (scsi, sizeof (rc), (char *) &rc,
sizeof (rcd), (char *) &rcd); sizeof (rcd), (char *) &rcd);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
if (err) if (err)
return err; return err;
@ -107,6 +188,8 @@ grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector,
{ {
grub_scsi_t scsi; grub_scsi_t scsi;
struct grub_scsi_read10 rd; struct grub_scsi_read10 rd;
grub_err_t err;
grub_err_t err_sense;
scsi = disk->data; scsi = disk->data;
@ -118,7 +201,16 @@ grub_scsi_read10 (grub_disk_t disk, grub_disk_addr_t sector,
rd.reserved2 = 0; rd.reserved2 = 0;
rd.pad = 0; rd.pad = 0;
return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
return err;
} }
/* Send a SCSI request for DISK: read SIZE sectors starting with /* Send a SCSI request for DISK: read SIZE sectors starting with
@ -129,6 +221,8 @@ grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector,
{ {
grub_scsi_t scsi; grub_scsi_t scsi;
struct grub_scsi_read12 rd; struct grub_scsi_read12 rd;
grub_err_t err;
grub_err_t err_sense;
scsi = disk->data; scsi = disk->data;
@ -139,7 +233,16 @@ grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector,
rd.reserved = 0; rd.reserved = 0;
rd.control = 0; rd.control = 0;
return scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf); err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
return err;
} }
#if 0 #if 0
@ -151,6 +254,8 @@ grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector,
{ {
grub_scsi_t scsi; grub_scsi_t scsi;
struct grub_scsi_write10 wr; struct grub_scsi_write10 wr;
grub_err_t err;
grub_err_t err_sense;
scsi = disk->data; scsi = disk->data;
@ -162,7 +267,16 @@ grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector,
wr.reserved2 = 0; wr.reserved2 = 0;
wr.pad = 0; wr.pad = 0;
return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
return err;
} }
/* Send a SCSI request for DISK: write the data stored in BUF to SIZE /* Send a SCSI request for DISK: write the data stored in BUF to SIZE
@ -172,7 +286,9 @@ grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector,
grub_size_t size, char *buf) grub_size_t size, char *buf)
{ {
grub_scsi_t scsi; grub_scsi_t scsi;
struct grub_scsi_write10 wr; struct grub_scsi_write12 wr;
grub_err_t err;
grub_err_t err_sense;
scsi = disk->data; scsi = disk->data;
@ -181,9 +297,18 @@ grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector,
wr.lba = grub_cpu_to_be32 (sector); wr.lba = grub_cpu_to_be32 (sector);
wr.size = grub_cpu_to_be32 (size); wr.size = grub_cpu_to_be32 (size);
wr.reserved = 0; wr.reserved = 0;
wr.pad = 0; wr.control = 0;
return scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf); err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
/* Each SCSI command should be followed by Request Sense.
If not so, many devices STALLs or definitely freezes. */
err_sense = grub_scsi_request_sense (scsi);
if (err_sense != GRUB_ERR_NONE)
grub_errno = err;
/* err_sense is ignored for now and Request Sense Data also... */
return err;
} }
#endif #endif
@ -235,6 +360,7 @@ grub_scsi_open (const char *name, grub_disk_t disk)
grub_err_t err; grub_err_t err;
int len; int len;
int lun; int lun;
grub_uint64_t maxtime;
scsi = grub_malloc (sizeof (*scsi)); scsi = grub_malloc (sizeof (*scsi));
if (! scsi) if (! scsi)
@ -292,6 +418,31 @@ grub_scsi_open (const char *name, grub_disk_t disk)
else else
disk->has_partitions = 1; disk->has_partitions = 1;
/* According to USB MS tests specification, issue Test Unit Ready
* until OK */
maxtime = grub_get_time_ms () + 5000; /* It is safer value */
do
{
/* Timeout is necessary - for example in case when we have
* universal card reader with more LUNs and we have only
* one card inserted (or none), so only one LUN (or none)
* will be ready - and we want not to hang... */
if (grub_get_time_ms () > maxtime)
{
err = GRUB_ERR_READ_ERROR;
grub_free (scsi);
grub_dprintf ("scsi", "LUN is not ready - timeout\n");
return err;
}
err = grub_scsi_test_unit_ready (scsi);
}
while (err == GRUB_ERR_READ_ERROR);
/* Reset grub_errno !
* It is set to some error code in loop before... */
grub_errno = GRUB_ERR_NONE;
/* Read capacity of media */
err = grub_scsi_read_capacity (scsi); err = grub_scsi_read_capacity (scsi);
if (err) if (err)
{ {
@ -302,12 +453,14 @@ grub_scsi_open (const char *name, grub_disk_t disk)
/* SCSI blocks can be something else than 512, although GRUB /* SCSI blocks can be something else than 512, although GRUB
wants 512 byte blocks. */ wants 512 byte blocks. */
disk->total_sectors = ((scsi->size * scsi->blocksize) disk->total_sectors = ((grub_uint64_t)scsi->size
<< GRUB_DISK_SECTOR_BITS); * (grub_uint64_t)scsi->blocksize)
>> GRUB_DISK_SECTOR_BITS;
grub_dprintf ("scsi", "capacity=%llu, blksize=%d\n", grub_dprintf ("scsi", "blocks=%u, blocksize=%u\n",
(unsigned long long) disk->total_sectors, scsi->size, scsi->blocksize);
scsi->blocksize); grub_dprintf ("scsi", "Disk total 512 sectors = %llu\n",
(unsigned long long) disk->total_sectors);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }
@ -366,6 +519,37 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
/* XXX: Never reached. */ /* XXX: Never reached. */
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
#if 0 /* Workaround - it works - but very slowly, from some reason
* unknown to me (specially on OHCI). Do not use it. */
/* Split transfer requests to device sector size because */
/* some devices are not able to transfer more than 512-1024 bytes */
grub_err_t err = GRUB_ERR_NONE;
for ( ; size; size--)
{
/* Depending on the type, select a read function. */
switch (scsi->devtype)
{
case grub_scsi_devtype_direct:
err = grub_scsi_read10 (disk, sector, 1, buf);
break;
case grub_scsi_devtype_cdrom:
err = grub_scsi_read12 (disk, sector, 1, buf);
break;
default: /* This should not happen */
return GRUB_ERR_READ_ERROR;
}
if (err)
return err;
sector++;
buf += scsi->blocksize;
}
return err;
#endif
} }
static grub_err_t static grub_err_t

View file

@ -84,7 +84,8 @@ grub_usbms_finddevs (void)
struct grub_usb_desc_device *descdev = &usbdev->descdev; struct grub_usb_desc_device *descdev = &usbdev->descdev;
int i; int i;
if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0) if (descdev->class != 0 || descdev->subclass || descdev->protocol != 0
|| descdev->configcnt == 0)
return 0; return 0;
/* XXX: Just check configuration 0 for now. */ /* XXX: Just check configuration 0 for now. */
@ -93,19 +94,31 @@ grub_usbms_finddevs (void)
struct grub_usbms_dev *usbms; struct grub_usbms_dev *usbms;
struct grub_usb_desc_if *interf; struct grub_usb_desc_if *interf;
int j; int j;
grub_uint8_t luns; grub_uint8_t luns = 0;
grub_dprintf ("usbms", "alive\n");
interf = usbdev->config[0].interf[i].descif; interf = usbdev->config[0].interf[i].descif;
/* If this is not a USB Mass Storage device with a supported /* If this is not a USB Mass Storage device with a supported
protocol, just skip it. */ protocol, just skip it. */
grub_dprintf ("usbms", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n",
i, interf->class, interf->subclass, interf->protocol);
if (interf->class != GRUB_USB_CLASS_MASS_STORAGE if (interf->class != GRUB_USB_CLASS_MASS_STORAGE
|| interf->subclass != GRUB_USBMS_SUBCLASS_BULK || ( interf->subclass != GRUB_USBMS_SUBCLASS_BULK &&
/* Experimental support of RBC, MMC-2, UFI, SFF-8070i devices */
interf->subclass != GRUB_USBMS_SUBCLASS_RBC &&
interf->subclass != GRUB_USBMS_SUBCLASS_MMC2 &&
interf->subclass != GRUB_USBMS_SUBCLASS_UFI &&
interf->subclass != GRUB_USBMS_SUBCLASS_SFF8070 )
|| interf->protocol != GRUB_USBMS_PROTOCOL_BULK) || interf->protocol != GRUB_USBMS_PROTOCOL_BULK)
{ {
continue; continue;
} }
grub_dprintf ("usbms", "alive\n");
devcnt++; devcnt++;
usbms = grub_zalloc (sizeof (struct grub_usbms_dev)); usbms = grub_zalloc (sizeof (struct grub_usbms_dev));
if (! usbms) if (! usbms)
@ -114,6 +127,8 @@ grub_usbms_finddevs (void)
usbms->dev = usbdev; usbms->dev = usbdev;
usbms->interface = i; usbms->interface = i;
grub_dprintf ("usbms", "alive\n");
/* Iterate over all endpoints of this interface, at least a /* Iterate over all endpoints of this interface, at least a
IN and OUT bulk endpoint are required. */ IN and OUT bulk endpoint are required. */
for (j = 0; j < interf->endpointcnt; j++) for (j = 0; j < interf->endpointcnt; j++)
@ -125,14 +140,16 @@ grub_usbms_finddevs (void)
{ {
/* Bulk IN endpoint. */ /* Bulk IN endpoint. */
usbms->in = endp; usbms->in = endp;
grub_usb_clear_halt (usbdev, endp->endp_addr & 128); /* Clear Halt is not possible yet! */
/* grub_usb_clear_halt (usbdev, endp->endp_addr); */
usbms->in_maxsz = endp->maxpacket; usbms->in_maxsz = endp->maxpacket;
} }
else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2) else if (!(endp->endp_addr & 128) && (endp->attrib & 3) == 2)
{ {
/* Bulk OUT endpoint. */ /* Bulk OUT endpoint. */
usbms->out = endp; usbms->out = endp;
grub_usb_clear_halt (usbdev, endp->endp_addr & 128); /* Clear Halt is not possible yet! */
/* grub_usb_clear_halt (usbdev, endp->endp_addr); */
usbms->out_maxsz = endp->maxpacket; usbms->out_maxsz = endp->maxpacket;
} }
} }
@ -143,51 +160,63 @@ grub_usbms_finddevs (void)
return 0; return 0;
} }
grub_dprintf ("usbms", "alive\n");
/* XXX: Activate the first configuration. */
grub_usb_set_configuration (usbdev, 1);
/* Query the amount of LUNs. */ /* Query the amount of LUNs. */
err = grub_usb_control_msg (usbdev, 0xA1, 254, err = grub_usb_control_msg (usbdev, 0xA1, 254,
0, i, 1, (char *) &luns); 0, i, 1, (char *) &luns);
if (err) if (err)
{ {
/* In case of a stall, clear the stall. */ /* In case of a stall, clear the stall. */
if (err == GRUB_USB_ERR_STALL) if (err == GRUB_USB_ERR_STALL)
{ {
grub_usb_clear_halt (usbdev, usbms->in->endp_addr & 3); grub_usb_clear_halt (usbdev, usbms->in->endp_addr);
grub_usb_clear_halt (usbdev, usbms->out->endp_addr & 3); grub_usb_clear_halt (usbdev, usbms->out->endp_addr);
} }
/* Just set the amount of LUNs to one. */ /* Just set the amount of LUNs to one. */
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
usbms->luns = 1; usbms->luns = 1;
} }
else else
usbms->luns = luns; /* luns = 0 means one LUN with ID 0 present ! */
/* We get from device not number of LUNs but highest
* LUN number. LUNs are numbered from 0,
* i.e. number of LUNs is luns+1 ! */
usbms->luns = luns + 1;
/* XXX: Check the magic values, does this really make grub_dprintf ("usbms", "alive\n");
sense? */
grub_usb_control_msg (usbdev, (1 << 6) | 1, 255,
0, i, 0, 0);
/* XXX: To make Qemu work? */
if (usbms->luns == 0)
usbms->luns = 1;
usbms->next = grub_usbms_dev_list; usbms->next = grub_usbms_dev_list;
grub_usbms_dev_list = usbms; grub_usbms_dev_list = usbms;
/* XXX: Activate the first configuration. */ #if 0 /* All this part should be probably deleted.
grub_usb_set_configuration (usbdev, 1); * This make trouble on some devices if they are not in
* Phase Error state - and there they should be not in such state...
* Bulk only mass storage reset procedure should be used only
* on place and in time when it is really necessary. */
/* Reset recovery procedure */
/* Bulk-Only Mass Storage Reset, after the reset commands /* Bulk-Only Mass Storage Reset, after the reset commands
will be accepted. */ will be accepted. */
grub_usbms_reset (usbdev, i); grub_usbms_reset (usbdev, i);
grub_usb_clear_halt (usbdev, usbms->in->endp_addr);
grub_usb_clear_halt (usbdev, usbms->out->endp_addr);
#endif
return 0; return 0;
} }
grub_dprintf ("usbms", "alive\n");
return 0; return 0;
} }
grub_dprintf ("usbms", "alive\n");
grub_usb_iterate (usb_iterate); grub_usb_iterate (usb_iterate);
grub_dprintf ("usbms", "alive\n");
} }
@ -224,7 +253,9 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
struct grub_usbms_csw status; struct grub_usbms_csw status;
static grub_uint32_t tag = 0; static grub_uint32_t tag = 0;
grub_usb_err_t err = GRUB_USB_ERR_NONE; grub_usb_err_t err = GRUB_USB_ERR_NONE;
grub_usb_err_t errCSW = GRUB_USB_ERR_NONE;
int retrycnt = 3 + 1; int retrycnt = 3 + 1;
grub_size_t i;
retry: retry:
retrycnt--; retrycnt--;
@ -237,73 +268,102 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
cbw.tag = tag++; cbw.tag = tag++;
cbw.transfer_length = grub_cpu_to_le32 (size); cbw.transfer_length = grub_cpu_to_le32 (size);
cbw.flags = (!read_write) << GRUB_USBMS_DIRECTION_BIT; cbw.flags = (!read_write) << GRUB_USBMS_DIRECTION_BIT;
cbw.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT; cbw.lun = scsi->lun; /* In USB MS CBW are LUN bits on another place than in SCSI CDB, both should be set correctly. */
cbw.length = cmdsize; cbw.length = cmdsize;
grub_memcpy (cbw.cbwcb, cmd, cmdsize); grub_memcpy (cbw.cbwcb, cmd, cmdsize);
/* Debug print of CBW content. */
grub_dprintf ("usb", "CBW: sign=0x%08x tag=0x%08x len=0x%08x\n",
cbw.signature, cbw.tag, cbw.transfer_length);
grub_dprintf ("usb", "CBW: flags=0x%02x lun=0x%02x CB_len=0x%02x\n",
cbw.flags, cbw.lun, cbw.length);
grub_dprintf ("usb", "CBW: cmd:\n %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
cbw.cbwcb[ 0], cbw.cbwcb[ 1], cbw.cbwcb[ 2], cbw.cbwcb[ 3],
cbw.cbwcb[ 4], cbw.cbwcb[ 5], cbw.cbwcb[ 6], cbw.cbwcb[ 7],
cbw.cbwcb[ 8], cbw.cbwcb[ 9], cbw.cbwcb[10], cbw.cbwcb[11],
cbw.cbwcb[12], cbw.cbwcb[13], cbw.cbwcb[14], cbw.cbwcb[15]);
/* Write the request. */ /* Write the request.
err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr & 15, * XXX: Error recovery is maybe still not fully correct. */
err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr,
sizeof (cbw), (char *) &cbw); sizeof (cbw), (char *) &cbw);
if (err) if (err)
{ {
if (err == GRUB_USB_ERR_STALL) if (err == GRUB_USB_ERR_STALL)
{ {
grub_usb_clear_halt (dev->dev, dev->out->endp_addr); grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
goto retry; goto CheckCSW;
} }
return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed"); return grub_error (GRUB_ERR_IO, "USB Mass Storage request failed");
} }
/* Read/write the data. */ /* Read/write the data, (maybe) according to specification. */
if (read_write == 0) if (size && (read_write == 0))
{ {
err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15, size, buf); err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr, size, buf);
grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL); grub_dprintf ("usb", "read: %d %d\n", err, GRUB_USB_ERR_STALL);
if (err) if (err)
{ {
if (err == GRUB_USB_ERR_STALL) if (err == GRUB_USB_ERR_STALL)
{ grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
grub_usb_clear_halt (dev->dev, dev->in->endp_addr); goto CheckCSW;
goto retry; }
} /* Debug print of received data. */
return grub_error (GRUB_ERR_READ_ERROR, grub_dprintf ("usb", "buf:\n");
"can't read from USB Mass Storage device"); if (size <= 64)
} for (i=0; i<size; i++)
grub_dprintf ("usb", "0x%02x: 0x%02x\n", i, buf[i]);
else
grub_dprintf ("usb", "Too much data for debug print...\n");
} }
else else if (size)
{ {
err = grub_usb_bulk_write (dev->dev, dev->in->endp_addr & 15, size, buf); err = grub_usb_bulk_write (dev->dev, dev->out->endp_addr, size, buf);
grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL); grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL);
grub_dprintf ("usb", "buf:\n");
if (err) if (err)
{ {
if (err == GRUB_USB_ERR_STALL) if (err == GRUB_USB_ERR_STALL)
{ grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
grub_usb_clear_halt (dev->dev, dev->out->endp_addr); goto CheckCSW;
goto retry; }
} /* Debug print of sent data. */
return grub_error (GRUB_ERR_WRITE_ERROR, if (size <= 256)
"can't write to USB Mass Storage device"); for (i=0; i<size; i++)
} grub_dprintf ("usb", "0x%02x: 0x%02x\n", i, buf[i]);
else
grub_dprintf ("usb", "Too much data for debug print...\n");
} }
/* Read the status. */ /* Read the status - (maybe) according to specification. */
err = grub_usb_bulk_read (dev->dev, dev->in->endp_addr & 15, CheckCSW:
sizeof (status), (char *) &status); errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr,
if (err) sizeof (status), (char *) &status);
if (errCSW)
{ {
if (err == GRUB_USB_ERR_STALL) grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
{ errCSW = grub_usb_bulk_read (dev->dev, dev->in->endp_addr,
grub_usb_clear_halt (dev->dev, dev->in->endp_addr); sizeof (status), (char *) &status);
if (errCSW)
{ /* Bulk-only reset device. */
grub_dprintf ("usb", "Bulk-only reset device - errCSW\n");
grub_usbms_reset (dev->dev, dev->interface);
grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
goto retry; goto retry;
} }
return grub_error (GRUB_ERR_READ_ERROR,
"can't read status from USB Mass Storage device");
} }
/* XXX: Magic and check this code. */ /* Debug print of CSW content. */
if (status.status == 2) grub_dprintf ("usb", "CSW: sign=0x%08x tag=0x%08x resid=0x%08x\n",
{ status.signature, status.tag, status.residue);
/* XXX: Phase error, reset device. */ grub_dprintf ("usb", "CSW: status=0x%02x\n", status.status);
/* If phase error or not valid signature, do bulk-only reset device. */
if ((status.status == 2) ||
(status.signature != grub_cpu_to_le32(0x53425355)))
{ /* Bulk-only reset device. */
grub_dprintf ("usb", "Bulk-only reset device - bad status\n");
grub_usbms_reset (dev->dev, dev->interface); grub_usbms_reset (dev->dev, dev->interface);
grub_usb_clear_halt (dev->dev, dev->in->endp_addr); grub_usb_clear_halt (dev->dev, dev->in->endp_addr);
grub_usb_clear_halt (dev->dev, dev->out->endp_addr); grub_usb_clear_halt (dev->dev, dev->out->endp_addr);
@ -311,9 +371,13 @@ grub_usbms_transfer (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
goto retry; goto retry;
} }
if (status.status) /* If "command failed" status or data transfer failed -> error */
if ((status.status || err) && !read_write)
return grub_error (GRUB_ERR_READ_ERROR, return grub_error (GRUB_ERR_READ_ERROR,
"error communication with USB Mass Storage device"); "error communication with USB Mass Storage device");
else if ((status.status || err) && read_write)
return grub_error (GRUB_ERR_WRITE_ERROR,
"error communication with USB Mass Storage device");
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
} }

File diff suppressed because it is too large Load diff

View file

@ -114,7 +114,7 @@ grub_pxe_open (const char *name, grub_disk_t disk)
return err; return err;
if (*ptr == ':') if (*ptr == ':')
{ {
err = parse_ip (ptr + 1, &(data->server_ip), 0); err = parse_ip (ptr + 1, &(data->gateway_ip), 0);
if (err) if (err)
return err; return err;
} }

View file

@ -49,6 +49,13 @@
#define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1) #define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1)
#define NILFS_BTREE_LEVEL_MAX 14 #define NILFS_BTREE_LEVEL_MAX 14
/* nilfs 1st super block posission from beginning of the partition
in 512 block size */
#define NILFS_1ST_SUPER_BLOCK 2
/* nilfs 2nd super block posission from end of the partition
in 512 block size */
#define NILFS_2ND_SUPER_BLOCK 8
struct grub_nilfs2_inode struct grub_nilfs2_inode
{ {
grub_uint64_t i_blocks; grub_uint64_t i_blocks;
@ -703,6 +710,52 @@ grub_nilfs2_valid_sb (struct grub_nilfs2_super_block *sbp)
return 1; return 1;
} }
static grub_err_t
grub_nilfs2_load_sb (struct grub_nilfs2_data *data)
{
grub_disk_t disk = data->disk;
struct grub_nilfs2_super_block sb2;
grub_uint64_t partition_size;
int valid[2];
int swp = 0;
/* Read first super block. */
grub_disk_read (disk, NILFS_1ST_SUPER_BLOCK, 0,
sizeof (struct grub_nilfs2_super_block), &data->sblock);
/* Make sure if 1st super block is valid. */
valid[0] = grub_nilfs2_valid_sb (&data->sblock);
partition_size = grub_disk_get_size (disk);
if (partition_size != GRUB_DISK_SIZE_UNKNOWN)
{
/* Read second super block. */
grub_disk_read (disk, partition_size - NILFS_2ND_SUPER_BLOCK, 0,
sizeof (struct grub_nilfs2_super_block), &sb2);
/* Make sure if 2nd super block is valid. */
valid[1] = grub_nilfs2_valid_sb (&sb2);
}
else
/* 2nd super block may not exist, so it's invalid. */
valid[1] = 0;
if (!valid[0] && !valid[1])
return grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem");
swp = valid[1] && (!valid[0] ||
grub_le_to_cpu64 (data->sblock.s_last_cno) <
grub_le_to_cpu64 (sb2.s_last_cno));
/* swap if first super block is invalid or older than second one. */
if (swp)
grub_memcpy (&data->sblock, &sb2,
sizeof (struct grub_nilfs2_super_block));
grub_errno = GRUB_ERR_NONE;
return grub_errno;
}
static struct grub_nilfs2_data * static struct grub_nilfs2_data *
grub_nilfs2_mount (grub_disk_t disk) grub_nilfs2_mount (grub_disk_t disk)
{ {
@ -717,19 +770,13 @@ grub_nilfs2_mount (grub_disk_t disk)
if (!data) if (!data)
return 0; return 0;
data->disk = disk;
/* Read the superblock. */ /* Read the superblock. */
grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_block), grub_nilfs2_load_sb (data);
&data->sblock);
if (grub_errno) if (grub_errno)
goto fail; goto fail;
/* Make sure this is an nilfs2 filesystem. */
if (!grub_nilfs2_valid_sb (&data->sblock))
{
grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem");
goto fail;
}
nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data)); nilfs2_block_count = (1 << LOG2_NILFS2_BLOCK_SIZE (data));
/* Read the last segment summary. */ /* Read the last segment summary. */
@ -748,8 +795,6 @@ grub_nilfs2_mount (grub_disk_t disk)
if (grub_errno) if (grub_errno)
goto fail; goto fail;
data->disk = disk;
grub_nilfs2_read_last_checkpoint (data, &last_checkpoint); grub_nilfs2_read_last_checkpoint (data, &last_checkpoint);
if (grub_errno) if (grub_errno)

View file

@ -110,6 +110,13 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
view->nested = nested; view->nested = nested;
view->first_timeout = -1; view->first_timeout = -1;
grub_video_set_viewport (0, 0, mode_info.width, mode_info.height);
if (view->double_repaint)
{
grub_video_swap_buffers ();
grub_video_set_viewport (0, 0, mode_info.width, mode_info.height);
}
grub_gfxmenu_view_draw (view); grub_gfxmenu_view_draw (view);
instance->data = view; instance->data = view;

View file

@ -210,8 +210,7 @@ draw_scrollbar (list_impl_t self,
/* Draw the list of items. */ /* Draw the list of items. */
static void static void
draw_menu (list_impl_t self, int width, int drawing_scrollbar, draw_menu (list_impl_t self, int width, int num_shown_items)
int num_shown_items)
{ {
if (! self->menu_box || ! self->selected_item_box) if (! self->menu_box || ! self->selected_item_box)
return; return;
@ -226,8 +225,6 @@ draw_menu (list_impl_t self, int width, int drawing_scrollbar,
make_selected_item_visible (self); make_selected_item_visible (self);
int scrollbar_h_space = drawing_scrollbar ? self->scrollbar_width : 0;
grub_gfxmenu_box_t selbox = self->selected_item_box; grub_gfxmenu_box_t selbox = self->selected_item_box;
int sel_leftpad = selbox->get_left_pad (selbox); int sel_leftpad = selbox->get_left_pad (selbox);
int item_top = boxpad; int item_top = boxpad;
@ -244,12 +241,8 @@ draw_menu (list_impl_t self, int width, int drawing_scrollbar,
if (is_selected) if (is_selected)
{ {
int sel_toppad = selbox->get_top_pad (selbox); int sel_toppad = selbox->get_top_pad (selbox);
selbox->set_content_size (selbox, selbox->set_content_size (selbox, (width - 2 * boxpad), item_height);
(width - 2 * boxpad selbox->draw (selbox, item_left - sel_leftpad,
- scrollbar_h_space),
item_height);
selbox->draw (selbox,
item_left - sel_leftpad,
item_top - sel_toppad); item_top - sel_toppad);
} }
@ -320,7 +313,7 @@ list_paint (void *vself, const grub_video_rect_t *region)
box->draw (box, 0, 0); box->draw (box, 0, 0);
grub_gui_set_viewport (&content_rect, &vpsave2); grub_gui_set_viewport (&content_rect, &vpsave2);
draw_menu (self, content_rect.width, drawing_scrollbar, num_shown_items); draw_menu (self, content_rect.width, num_shown_items);
grub_gui_restore_viewport (&vpsave2); grub_gui_restore_viewport (&vpsave2);
if (drawing_scrollbar) if (drawing_scrollbar)

View file

@ -357,11 +357,6 @@ grub_gfxmenu_draw_terminal_box (void)
term_box->draw (term_box, term_box->draw (term_box,
term_rect.x - term_box->get_left_pad (term_box), term_rect.x - term_box->get_left_pad (term_box),
term_rect.y - term_box->get_top_pad (term_box)); term_rect.y - term_box->get_top_pad (term_box));
grub_video_swap_buffers ();
if (term_view->double_repaint)
term_box->draw (term_box,
term_rect.x - term_box->get_left_pad (term_box),
term_rect.y - term_box->get_top_pad (term_box));
} }
static void static void

190
include/grub/cs5536.h Normal file
View file

@ -0,0 +1,190 @@
/*
* 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/>.
*/
#ifndef GRUB_CS5536_HEADER
#define GRUB_CS5536_HEADER 1
#ifndef ASM_FILE
#include <grub/pci.h>
#include <grub/err.h>
#include <grub/smbus.h>
#endif
#define GRUB_CS5536_PCIID 0x208f1022
#define GRUB_CS5536_MSR_MAILBOX_ADDR 0xf4
#define GRUB_CS5536_MSR_MAILBOX_DATA0 0xf8
#define GRUB_CS5536_MSR_MAILBOX_DATA1 0xfc
#define GRUB_CS5536_MSR_IRQ_MAP_BAR 0x80000008
#define GRUB_CS5536_MSR_SMB_BAR 0x8000000b
#define GRUB_CS5536_SMBUS_REGS_SIZE 8
#define GRUB_CS5536_GPIO_REGS_SIZE 256
#define GRUB_CS5536_MFGPT_REGS_SIZE 64
#define GRUB_CS5536_IRQ_MAP_REGS_SIZE 32
#define GRUB_CS5536_PM_REGS_SIZE 128
#define GRUB_CS5536_ACPI_REGS_SIZE 32
#define GRUB_CS5536_USB_OPTION_REGS_SIZE 0x1c
#define GRUB_CS5536_USB_OPTION_REG_UOCMUX 1
#define GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_MASK 0x03
#define GRUB_CS5536_USB_OPTION_REG_UOCMUX_PMUX_HC 0x02
#define GRUB_CS5536_DESTINATION_GLIU 0
#define GRUB_CS5536_DESTINATION_GLPCI_SB 1
#define GRUB_CS5536_DESTINATION_USB 2
#define GRUB_CS5536_DESTINATION_IDE 3
#define GRUB_CS5536_DESTINATION_DD 4
#define GRUB_CS5536_DESTINATION_ACC 5
#define GRUB_CS5536_DESTINATION_GLCP 7
#define GRUB_CS5536_P2D_DEST_SHIFT 61
#define GRUB_CS5536_P2D_LOG_ALIGN 12
#define GRUB_CS5536_P2D_ALIGN (1 << GRUB_CS5536_P2D_LOG_ALIGN)
#define GRUB_CS5536_P2D_BASE_SHIFT 20
#define GRUB_CS5536_P2D_MASK_SHIFT 0
#define GRUB_CS5536_MSR_GL_IOD_START 0x000100e0
#define GRUB_CS5536_IOD_DEST_SHIFT 61
#define GRUB_CS5536_IOD_BASE_SHIFT 20
#define GRUB_CS5536_IOD_MASK_SHIFT 0
#define GRUB_CS5536_IOD_ADDR_MASK 0xfffff
#define GRUB_CS5536_MSR_GPIO_BAR 0x8000000c
#define GRUB_CS5536_MSR_MFGPT_BAR 0x8000000d
#define GRUB_CS5536_MSR_ACPI_BAR 0x8000000e
#define GRUB_CS5536_MSR_PM_BAR 0x8000000f
#define GRUB_CS5536_MSR_DIVIL_LEG_IO 0x80000014
#define GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE0 0x00000001
#define GRUB_CS5536_MSR_DIVIL_LEG_IO_RTC_ENABLE1 0x00000002
#define GRUB_CS5536_MSR_DIVIL_LEG_IO_MODE_X86 0x10000000
#define GRUB_CS5536_MSR_DIVIL_LEG_IO_F_REMAP 0x04000000
#define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_PRIMARY_MASK 0x80000024
#define GRUB_CS5536_MSR_DIVIL_IRQ_MAPPER_LPC_MASK 0x80000025
#define GRUB_CS5536_DIVIL_LPC_INTERRUPTS 0x1002
#define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL 0x8000004e
#define GRUB_CS5536_MSR_DIVIL_LPC_SERIAL_IRQ_CONTROL_ENABLE 0x80
#define GRUB_CS5536_MSR_USB_OHCI_BASE 0x40000008
#define GRUB_CS5536_MSR_USB_EHCI_BASE 0x40000009
#define GRUB_CS5536_MSR_USB_CONTROLLER_BASE 0x4000000a
#define GRUB_CS5536_MSR_USB_OPTION_CONTROLLER_BASE 0x4000000b
#define GRUB_CS5536_MSR_USB_BASE_ADDR_MASK 0x00ffffff00ULL
#define GRUB_CS5536_MSR_USB_BASE_BUS_MASTER 0x0400000000ULL
#define GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE 0x0200000000ULL
#define GRUB_CS5536_MSR_USB_BASE_PME_ENABLED 0x0800000000ULL
#define GRUB_CS5536_MSR_USB_BASE_PME_STATUS 0x1000000000ULL
#define GRUB_CS5536_MSR_USB_EHCI_BASE_FLDJ_SHIFT 40
#define GRUB_CS5536_MSR_IDE_IO_BAR 0x60000008
#define GRUB_CS5536_MSR_IDE_IO_BAR_UNITS 1
#define GRUB_CS5536_MSR_IDE_IO_BAR_ADDR_MASK 0xfffffff0
#define GRUB_CS5536_MSR_IDE_CFG 0x60000010
#define GRUB_CS5536_MSR_IDE_CFG_CHANNEL_ENABLE 2
#define GRUB_CS5536_MSR_IDE_TIMING 0x60000012
#define GRUB_CS5536_MSR_IDE_TIMING_PIO0 0x98
#define GRUB_CS5536_MSR_IDE_TIMING_DRIVE0_SHIFT 24
#define GRUB_CS5536_MSR_IDE_TIMING_DRIVE1_SHIFT 16
#define GRUB_CS5536_MSR_IDE_CAS_TIMING 0x60000013
#define GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_PIO0 0x99
#define GRUB_CS5536_MSR_IDE_CAS_TIMING_CMD_SHIFT 24
#define GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE0_SHIFT 6
#define GRUB_CS5536_MSR_IDE_CAS_TIMING_DRIVE1_SHIFT 4
#define GRUB_CS5536_MSR_IDE_CAS_TIMING_PIO0 2
#define GRUB_CS5536_MSR_GL_PCI_CTRL 0x00000010
#define GRUB_CS5536_MSR_GL_PCI_CTRL_MEMORY_ENABLE 1
#define GRUB_CS5536_MSR_GL_PCI_CTRL_IO_ENABLE 2
#define GRUB_CS5536_MSR_GL_PCI_CTRL_LATENCY_SHIFT 35
#define GRUB_CS5536_MSR_GL_PCI_CTRL_OUT_THR_SHIFT 60
#define GRUB_CS5536_MSR_GL_PCI_CTRL_IN_THR_SHIFT 56
#define GRUB_CS5536_MSR_GL_REGIONS_START 0x00000020
#define GRUB_CS5536_MSR_GL_REGIONS_NUM 16
#define GRUB_CS5536_MSR_GL_REGION_ENABLE 1
#define GRUB_CS5536_MSR_GL_REGION_IO 0x100000000ULL
#define GRUB_CS5536_MSR_GL_REGION_BASE_MASK 0xfffff000ULL
#define GRUB_CS5536_MSR_GL_REGION_IO_BASE_SHIFT 12
#define GRUB_CS5536_MSR_GL_REGION_TOP_MASK 0xfffff00000000000ULL
#define GRUB_CS5536_MSR_GL_REGION_IO_TOP_SHIFT 44
#define GRUB_CS5536_MSR_GL_P2D_START 0x00010020
#define GRUB_CS5536_SMB_REG_DATA 0x0
#define GRUB_CS5536_SMB_REG_STATUS 0x1
#define GRUB_CS5536_SMB_REG_STATUS_SDAST (1 << 6)
#define GRUB_CS5536_SMB_REG_STATUS_BER (1 << 5)
#define GRUB_CS5536_SMB_REG_STATUS_NACK (1 << 4)
#define GRUB_CS5536_SMB_REG_CTRL1 0x3
#define GRUB_CS5536_SMB_REG_CTRL1_START 0x01
#define GRUB_CS5536_SMB_REG_CTRL1_STOP 0x02
#define GRUB_CS5536_SMB_REG_CTRL1_ACK 0x10
#define GRUB_CS5536_SMB_REG_ADDR 0x4
#define GRUB_CS5536_SMB_REG_ADDR_MASTER 0x0
#define GRUB_CS5536_SMB_REG_CTRL2 0x5
#define GRUB_CS5536_SMB_REG_CTRL2_ENABLE 0x1
#define GRUB_CS5536_SMB_REG_CTRL3 0x6
#ifdef ASM_FILE
#define GRUB_ULL(x) x
#else
#define GRUB_ULL(x) x ## ULL
#endif
#define GRUB_CS5536_LBAR_ADDR_MASK GRUB_ULL (0x000000000000fff8)
#define GRUB_CS5536_LBAR_ENABLE GRUB_ULL (0x0000000100000000)
#define GRUB_CS5536_LBAR_MASK_MASK GRUB_ULL (0x0000f00000000000)
#define GRUB_CS5536_LBAR_TURN_ON (GRUB_CS5536_LBAR_ENABLE | GRUB_CS5536_LBAR_MASK_MASK)
/* PMON-compatible LBARs. */
#define GRUB_CS5536_LBAR_GPIO 0xb000
#define GRUB_CS5536_LBAR_ACC 0xb200
#define GRUB_CS5536_LBAR_PM 0xb280
#define GRUB_CS5536_LBAR_MFGPT 0xb300
#define GRUB_CS5536_LBAR_ACPI 0xb340
#define GRUB_CS5536_LBAR_IRQ_MAP 0xb360
#define GRUB_CS5536_LBAR_IDE 0xb380
#define GRUB_CS5536_LBAR_SMBUS 0xb390
#define GRUB_GPIO_SMBUS_PINS ((1 << 14) | (1 << 15))
#define GRUB_GPIO_REG_OUT_EN 0x4
#define GRUB_GPIO_REG_OUT_AUX1 0x10
#define GRUB_GPIO_REG_IN_EN 0x20
#define GRUB_GPIO_REG_IN_AUX1 0x34
#ifndef ASM_FILE
int EXPORT_FUNC (grub_cs5536_find) (grub_pci_device_t *devp);
grub_uint64_t EXPORT_FUNC (grub_cs5536_read_msr) (grub_pci_device_t dev,
grub_uint32_t addr);
void EXPORT_FUNC (grub_cs5536_write_msr) (grub_pci_device_t dev,
grub_uint32_t addr,
grub_uint64_t val);
grub_err_t grub_cs5536_read_spd_byte (grub_port_t smbbase, grub_uint8_t dev,
grub_uint8_t addr, grub_uint8_t *res);
grub_err_t EXPORT_FUNC (grub_cs5536_read_spd) (grub_port_t smbbase,
grub_uint8_t dev,
struct grub_smbus_spd *res);
grub_err_t grub_cs5536_smbus_wait (grub_port_t smbbase);
grub_err_t EXPORT_FUNC (grub_cs5536_init_smbus) (grub_pci_device_t dev,
grub_uint16_t divisor,
grub_port_t *smbbase);
void grub_cs5536_init_geode (grub_pci_device_t dev);
#endif
#endif

View file

@ -138,6 +138,9 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t;
#define GRUB_DISK_CACHE_SIZE 8 #define GRUB_DISK_CACHE_SIZE 8
#define GRUB_DISK_CACHE_BITS 3 #define GRUB_DISK_CACHE_BITS 3
/* Return value of grub_disk_get_size() in case disk size is unknown. */
#define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL
/* This is called from the memory manager. */ /* This is called from the memory manager. */
void grub_disk_cache_invalidate_all (void); void grub_disk_cache_invalidate_all (void);

View file

@ -46,5 +46,10 @@ int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...);
#endif #endif
char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); char * EXPORT_FUNC(xasprintf) (const char *fmt, ...);
extern char * canonicalize_file_name (const char *path);
#ifdef HAVE_DEVICE_MAPPER
int grub_device_mapper_supported (void);
#endif
#endif /* GRUB_EMU_MISC_H */ #endif /* GRUB_EMU_MISC_H */

View file

@ -22,10 +22,10 @@
#include <config.h> #include <config.h>
#include <grub/symbol.h> #include <grub/symbol.h>
extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s);
/* NLS can be disabled through the configure --disable-nls option. */ /* NLS can be disabled through the configure --disable-nls option. */
#if (defined(ENABLE_NLS) && ENABLE_NLS) #if (defined(ENABLE_NLS) && ENABLE_NLS) || !defined (GRUB_UTIL)
extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s);
# ifdef GRUB_UTIL # ifdef GRUB_UTIL
@ -41,19 +41,11 @@ extern const char *(*EXPORT_VAR(grub_gettext)) (const char *s);
for invalid uses of the value returned from these functions. for invalid uses of the value returned from these functions.
On pre-ANSI systems without 'const', the config.h file is supposed to On pre-ANSI systems without 'const', the config.h file is supposed to
contain "#define const". */ contain "#define const". */
# ifdef GRUB_UTIL
static inline const char * __attribute__ ((always_inline)) static inline const char * __attribute__ ((always_inline))
gettext (const char *str) gettext (const char *str)
{ {
return str; return str;
} }
# else
static inline const char * __attribute__ ((always_inline))
grub_gettext (const char *str)
{
return str;
}
# endif /* GRUB_UTIL */
#endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */ #endif /* (defined(ENABLE_NLS) && ENABLE_NLS) */

View file

@ -80,7 +80,7 @@ grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)),
static inline void static inline void
grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)),
void *mem __attribute__ ((unused)), volatile void *mem __attribute__ ((unused)),
grub_size_t size __attribute__ ((unused))) grub_size_t size __attribute__ ((unused)))
{ {
} }

View file

@ -19,16 +19,30 @@
#ifndef GRUB_MACHINE_PCI_H #ifndef GRUB_MACHINE_PCI_H
#define GRUB_MACHINE_PCI_H 1 #define GRUB_MACHINE_PCI_H 1
#ifndef ASM_FILE
#include <grub/types.h> #include <grub/types.h>
#include <grub/cpu/io.h> #include <grub/cpu/io.h>
#endif
#define GRUB_YEELOONG_OHCI_PCIID 0x00351033
#define GRUB_YEELOONG_EHCI_PCIID 0x00e01033
#define GRUB_YEELOONG_OHCI_GHOST_FUNCTION 4
#define GRUB_YEELOONG_EHCI_GHOST_FUNCTION 5
#define GRUB_PCI_NUM_BUS 1 #define GRUB_PCI_NUM_BUS 1
#define GRUB_PCI_NUM_DEVICES 16 #define GRUB_PCI_NUM_DEVICES 16
#define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000 #define GRUB_MACHINE_PCI_IO_BASE 0xbfd00000
#define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000 #define GRUB_MACHINE_PCI_CONFSPACE 0xbfe80000
#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00118) #define GRUB_MACHINE_PCI_CONTROLLER_HEADER 0xbfe00000
#define GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR 0xbfe00118
#ifndef ASM_FILE
#define GRUB_MACHINE_PCI_CONF_CTRL_REG (*(volatile grub_uint32_t *) \
GRUB_MACHINE_PCI_CONF_CTRL_REG_ADDR)
#define GRUB_MACHINE_PCI_IO_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00110) #define GRUB_MACHINE_PCI_IO_CTRL_REG (*(volatile grub_uint32_t *) 0xbfe00110)
#endif
#define GRUB_MACHINE_PCI_WIN_MASK_SIZE 6 #define GRUB_MACHINE_PCI_WIN_MASK_SIZE 6
#define GRUB_MACHINE_PCI_WIN_MASK ((1 << GRUB_MACHINE_PCI_WIN_MASK_SIZE) - 1) #define GRUB_MACHINE_PCI_WIN_MASK ((1 << GRUB_MACHINE_PCI_WIN_MASK_SIZE) - 1)
@ -46,6 +60,7 @@
#define GRUB_MACHINE_PCI_WIN2_ADDR 0xb4000000 #define GRUB_MACHINE_PCI_WIN2_ADDR 0xb4000000
#define GRUB_MACHINE_PCI_WIN3_ADDR 0xb8000000 #define GRUB_MACHINE_PCI_WIN3_ADDR 0xb8000000
#ifndef ASM_FILE
static inline grub_uint32_t static inline grub_uint32_t
grub_pci_read (grub_pci_address_t addr) grub_pci_read (grub_pci_address_t addr)
{ {
@ -95,11 +110,12 @@ grub_pci_write_byte (grub_pci_address_t addr, grub_uint8_t data)
} }
volatile void * volatile void *
grub_pci_device_map_range (grub_pci_device_t dev __attribute__ ((unused)), EXPORT_FUNC (grub_pci_device_map_range) (grub_pci_device_t dev,
grub_addr_t base, grub_size_t size); grub_addr_t base, grub_size_t size);
void void
grub_pci_device_unmap_range (grub_pci_device_t dev __attribute__ ((unused)), EXPORT_FUNC (grub_pci_device_unmap_range) (grub_pci_device_t dev,
volatile void *mem, volatile void *mem,
grub_size_t size __attribute__ ((unused))); grub_size_t size);
#endif
#endif /* GRUB_MACHINE_PCI_H */ #endif /* GRUB_MACHINE_PCI_H */

View file

@ -19,8 +19,10 @@
#ifndef GRUB_PCI_H #ifndef GRUB_PCI_H
#define GRUB_PCI_H 1 #define GRUB_PCI_H 1
#ifndef ASM_FILE
#include <grub/types.h> #include <grub/types.h>
#include <grub/symbol.h> #include <grub/symbol.h>
#endif
#define GRUB_PCI_ADDR_SPACE_MASK 0x01 #define GRUB_PCI_ADDR_SPACE_MASK 0x01
#define GRUB_PCI_ADDR_SPACE_MEMORY 0x00 #define GRUB_PCI_ADDR_SPACE_MEMORY 0x00
@ -66,6 +68,20 @@
#define GRUB_PCI_REG_MIN_GNT 0x3e #define GRUB_PCI_REG_MIN_GNT 0x3e
#define GRUB_PCI_REG_MAX_LAT 0x3f #define GRUB_PCI_REG_MAX_LAT 0x3f
#define GRUB_PCI_COMMAND_IO_ENABLED 0x0001
#define GRUB_PCI_COMMAND_MEM_ENABLED 0x0002
#define GRUB_PCI_COMMAND_BUS_MASTER 0x0004
#define GRUB_PCI_COMMAND_PARITY_ERROR 0x0040
#define GRUB_PCI_COMMAND_SERR_ENABLE 0x0100
#define GRUB_PCI_STATUS_CAPABILITIES 0x0010
#define GRUB_PCI_STATUS_66MHZ_CAPABLE 0x0020
#define GRUB_PCI_STATUS_FAST_B2B_CAPABLE 0x0080
#define GRUB_PCI_STATUS_DEVSEL_TIMING_SHIFT 9
#define GRUB_PCI_STATUS_DEVSEL_TIMING_MASK 0x0600
#ifndef ASM_FILE
typedef grub_uint32_t grub_pci_id_t; typedef grub_uint32_t grub_pci_id_t;
#ifdef GRUB_MACHINE_EMU #ifdef GRUB_MACHINE_EMU
@ -107,4 +123,14 @@ grub_pci_address_t EXPORT_FUNC(grub_pci_make_address) (grub_pci_device_t dev,
void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook); void EXPORT_FUNC(grub_pci_iterate) (grub_pci_iteratefunc_t hook);
struct grub_pci_dma_chunk;
struct grub_pci_dma_chunk *EXPORT_FUNC(grub_memalign_dma32) (grub_size_t align,
grub_size_t size);
void EXPORT_FUNC(grub_dma_free) (struct grub_pci_dma_chunk *ch);
volatile void *EXPORT_FUNC(grub_dma_get_virt) (struct grub_pci_dma_chunk *ch);
grub_uint32_t EXPORT_FUNC(grub_dma_get_phys) (struct grub_pci_dma_chunk *ch);
#endif
#endif /* GRUB_PCI_H */ #endif /* GRUB_PCI_H */

View file

@ -25,14 +25,26 @@
#define GRUB_SCSI_REMOVABLE_BIT 7 #define GRUB_SCSI_REMOVABLE_BIT 7
#define GRUB_SCSI_LUN_SHIFT 5 #define GRUB_SCSI_LUN_SHIFT 5
struct grub_scsi_test_unit_ready
{
grub_uint8_t opcode;
grub_uint8_t lun; /* 7-5 LUN, 4-0 reserved */
grub_uint8_t reserved1;
grub_uint8_t reserved2;
grub_uint8_t reserved3;
grub_uint8_t control;
grub_uint8_t pad[6]; /* To be ATAPI compatible */
} __attribute__((packed));
struct grub_scsi_inquiry struct grub_scsi_inquiry
{ {
grub_uint8_t opcode; grub_uint8_t opcode;
grub_uint8_t lun; grub_uint8_t lun; /* 7-5 LUN, 4-1 reserved, 0 EVPD */
grub_uint16_t reserved; grub_uint8_t page; /* page code if EVPD=1 */
grub_uint16_t alloc_length; grub_uint8_t reserved;
grub_uint8_t reserved2; grub_uint8_t alloc_length;
grub_uint8_t pad[5]; grub_uint8_t control;
grub_uint8_t pad[6]; /* To be ATAPI compatible */
} __attribute__((packed)); } __attribute__((packed));
struct grub_scsi_inquiry_data struct grub_scsi_inquiry_data
@ -47,12 +59,42 @@ struct grub_scsi_inquiry_data
char prodrev[4]; char prodrev[4];
} __attribute__((packed)); } __attribute__((packed));
struct grub_scsi_request_sense
{
grub_uint8_t opcode;
grub_uint8_t lun; /* 7-5 LUN, 4-0 reserved */
grub_uint8_t reserved1;
grub_uint8_t reserved2;
grub_uint8_t alloc_length;
grub_uint8_t control;
grub_uint8_t pad[6]; /* To be ATAPI compatible */
} __attribute__((packed));
struct grub_scsi_request_sense_data
{
grub_uint8_t error_code; /* 7 Valid, 6-0 Err. code */
grub_uint8_t segment_number;
grub_uint8_t sense_key; /*7 FileMark, 6 EndOfMedia, 5 ILI, 4-0 sense key */
grub_uint32_t information;
grub_uint8_t additional_sense_length;
grub_uint32_t cmd_specific_info;
grub_uint8_t additional_sense_code;
grub_uint8_t additional_sense_code_qualifier;
grub_uint8_t field_replaceable_unit_code;
grub_uint8_t sense_key_specific[3];
/* there can be additional sense field */
} __attribute__((packed));
struct grub_scsi_read_capacity struct grub_scsi_read_capacity
{ {
grub_uint8_t opcode; grub_uint8_t opcode;
grub_uint8_t lun; grub_uint8_t lun; /* 7-5 LUN, 4-1 reserved, 0 reserved */
grub_uint8_t reserved[8]; grub_uint32_t logical_block_addr; /* only if PMI=1 */
grub_uint8_t pad[2]; grub_uint8_t reserved1;
grub_uint8_t reserved2;
grub_uint8_t PMI;
grub_uint8_t control;
grub_uint16_t pad; /* To be ATAPI compatible */
} __attribute__((packed)); } __attribute__((packed));
struct grub_scsi_read_capacity_data struct grub_scsi_read_capacity_data
@ -105,12 +147,14 @@ struct grub_scsi_write12
typedef enum typedef enum
{ {
grub_scsi_cmd_test_unit_ready = 0x00,
grub_scsi_cmd_request_sense = 0x03,
grub_scsi_cmd_inquiry = 0x12, grub_scsi_cmd_inquiry = 0x12,
grub_scsi_cmd_read_capacity = 0x25, grub_scsi_cmd_read_capacity = 0x25,
grub_scsi_cmd_read10 = 0x28, grub_scsi_cmd_read10 = 0x28,
grub_scsi_cmd_write10 = 0x2a, grub_scsi_cmd_write10 = 0x2a,
grub_scsi_cmd_read12 = 0xa8, grub_scsi_cmd_read12 = 0xa8,
grub_scsi_cmd_write12 = 0xaa grub_scsi_cmd_write12 = 0xaa,
} grub_scsi_cmd_t; } grub_scsi_cmd_t;
typedef enum typedef enum

70
include/grub/smbus.h Normal file
View file

@ -0,0 +1,70 @@
/*
* 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/>.
*/
#ifndef GRUB_SMBUS_HEADER
#define GRUB_SMBUS_HEADER 1
#define GRUB_SMB_RAM_START_ADDR 0x50
#define GRUB_SMB_RAM_NUM_MAX 0x08
#define GRUB_SMBUS_SPD_MEMORY_TYPE_ADDR 2
#define GRUB_SMBUS_SPD_MEMORY_TYPE_DDR2 8
#define GRUB_SMBUS_SPD_MEMORY_NUM_BANKS_ADDR 17
#define GRUB_SMBUS_SPD_MEMORY_NUM_ROWS_ADDR 3
#define GRUB_SMBUS_SPD_MEMORY_NUM_COLUMNS_ADDR 4
#define GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_ADDR 5
#define GRUB_SMBUS_SPD_MEMORY_NUM_OF_RANKS_MASK 0x7
#define GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_ADDR 18
#define GRUB_SMBUS_SPD_MEMORY_CAS_LATENCY_MIN_VALUE 5
#define GRUB_SMBUS_SPD_MEMORY_TRAS_ADDR 30
#define GRUB_SMBUS_SPD_MEMORY_TRTP_ADDR 38
#ifndef ASM_FILE
struct grub_smbus_spd
{
grub_uint8_t written_size;
grub_uint8_t log_total_flash_size;
grub_uint8_t memory_type;
union
{
grub_uint8_t unknown[253];
struct {
grub_uint8_t num_rows;
grub_uint8_t num_columns;
grub_uint8_t num_of_ranks;
grub_uint8_t unused1[12];
grub_uint8_t num_of_banks;
grub_uint8_t unused2[2];
grub_uint8_t cas_latency;
grub_uint8_t unused3[9];
grub_uint8_t rank_capacity;
grub_uint8_t unused4[1];
grub_uint8_t tras;
grub_uint8_t unused5[7];
grub_uint8_t trtp;
grub_uint8_t unused6[31];
grub_uint8_t part_number[18];
grub_uint8_t unused7[165];
} ddr2;
};
};
#endif
#endif

View file

@ -35,7 +35,8 @@ typedef enum
GRUB_USB_ERR_NAK, GRUB_USB_ERR_NAK,
GRUB_USB_ERR_BABBLE, GRUB_USB_ERR_BABBLE,
GRUB_USB_ERR_TIMEOUT, GRUB_USB_ERR_TIMEOUT,
GRUB_USB_ERR_BITSTUFF GRUB_USB_ERR_BITSTUFF,
GRUB_USB_ERR_UNRECOVERABLE
} grub_usb_err_t; } grub_usb_err_t;
typedef enum typedef enum
@ -156,7 +157,7 @@ struct grub_usb_device
int initialized; int initialized;
/* Data toggle values (used for bulk transfers only). */ /* Data toggle values (used for bulk transfers only). */
int toggle[16]; int toggle[256];
/* Device-specific data. */ /* Device-specific data. */
void *data; void *data;
@ -184,7 +185,12 @@ typedef enum
typedef enum typedef enum
{ {
GRUB_USBMS_SUBCLASS_BULK = 0x06 GRUB_USBMS_SUBCLASS_BULK = 0x06,
/* Experimental support for non-pure SCSI devices */
GRUB_USBMS_SUBCLASS_RBC = 0x01,
GRUB_USBMS_SUBCLASS_MMC2 = 0x02,
GRUB_USBMS_SUBCLASS_UFI = 0x04,
GRUB_USBMS_SUBCLASS_SFF8070 = 0x05
} grub_usbms_subclass_t; } grub_usbms_subclass_t;
typedef enum typedef enum

View file

@ -37,7 +37,7 @@ struct grub_usb_transaction
int size; int size;
int toggle; int toggle;
grub_transfer_type_t pid; grub_transfer_type_t pid;
char *data; grub_uint32_t data;
}; };
typedef struct grub_usb_transaction *grub_usb_transaction_t; typedef struct grub_usb_transaction *grub_usb_transaction_t;
@ -58,6 +58,9 @@ struct grub_usb_transfer
struct grub_usb_device *dev; struct grub_usb_device *dev;
struct grub_usb_transaction *transactions; struct grub_usb_transaction *transactions;
int last_trans;
/* Index of last processed transaction in OHCI/UHCI driver. */
}; };
typedef struct grub_usb_transfer *grub_usb_transfer_t; typedef struct grub_usb_transfer *grub_usb_transfer_t;
@ -86,9 +89,9 @@ typedef struct grub_usb_transfer *grub_usb_transfer_t;
#define GRUB_USB_REQ_HUB_GET_PORT_STATUS 0x00 #define GRUB_USB_REQ_HUB_GET_PORT_STATUS 0x00
#define GRUB_USB_FEATURE_ENDP_HALT 0x01 #define GRUB_USB_FEATURE_ENDP_HALT 0x00
#define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x02 #define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x01
#define GRUB_USB_FEATURE_TEST_MODE 0x04 #define GRUB_USB_FEATURE_TEST_MODE 0x02
#define GRUB_USB_HUB_STATUS_CONNECTED (1 << 0) #define GRUB_USB_HUB_STATUS_CONNECTED (1 << 0)
#define GRUB_USB_HUB_STATUS_LOWSPEED (1 << 9) #define GRUB_USB_HUB_STATUS_LOWSPEED (1 << 9)

View file

@ -80,6 +80,86 @@ xgetcwd (void)
return path; return path;
} }
#ifdef __linux__
/* Statting something on a btrfs filesystem always returns a virtual device
major/minor pair rather than the real underlying device, because btrfs
can span multiple underlying devices (and even if it's currently only
using a single device it can be dynamically extended onto another). We
can't deal with the multiple-device case yet, but in the meantime, we can
at least cope with the single-device case by scanning
/proc/self/mountinfo. */
static char *
find_root_device_from_mountinfo (const char *dir)
{
FILE *fp;
char *buf = NULL;
size_t len = 0;
char *ret = NULL;
fp = fopen ("/proc/self/mountinfo", "r");
if (! fp)
return NULL; /* fall through to other methods */
while (getline (&buf, &len, fp) > 0)
{
int mnt_id, parent_mnt_id;
unsigned int major, minor;
char enc_root[PATH_MAX], enc_path[PATH_MAX];
int count;
size_t enc_path_len;
const char *sep;
char fstype[PATH_MAX], device[PATH_MAX];
struct stat st;
if (sscanf (buf, "%d %d %u:%u %s %s%n",
&mnt_id, &parent_mnt_id, &major, &minor, enc_root, enc_path,
&count) < 6)
continue;
if (strcmp (enc_root, "/") != 0)
continue; /* only a subtree is mounted */
enc_path_len = strlen (enc_path);
if (strncmp (dir, enc_path, enc_path_len) != 0 ||
(dir[enc_path_len] && dir[enc_path_len] != '/'))
continue;
/* This is a parent of the requested directory. /proc/self/mountinfo
is in mount order, so it must be the closest parent we've
encountered so far. If it's virtual, return its device node;
otherwise, carry on to try to find something closer. */
free (ret);
ret = NULL;
if (major != 0)
continue; /* not a virtual device */
sep = strstr (buf + count, " - ");
if (!sep)
continue;
sep += sizeof (" - ") - 1;
if (sscanf (sep, "%s %s", fstype, device) != 2)
continue;
if (stat (device, &st) < 0)
continue;
if (!S_ISBLK (st.st_mode))
continue; /* not a block device */
ret = strdup (device);
}
free (buf);
fclose (fp);
return ret;
}
#endif /* __linux__ */
#ifdef __MINGW32__ #ifdef __MINGW32__
static char * static char *
@ -126,9 +206,20 @@ find_root_device (const char *dir, dev_t dev)
/* Ignore any error. */ /* Ignore any error. */
continue; continue;
if (S_ISLNK (st.st_mode)) if (S_ISLNK (st.st_mode)) {
/* Don't follow symbolic links. */ #ifdef __linux__
if (strcmp (dir, "mapper") == 0) {
/* Follow symbolic links under /dev/mapper/; the canonical name
may be something like /dev/dm-0, but the names under
/dev/mapper/ are more human-readable and so we prefer them if
we can get them. */
if (stat (ent->d_name, &st) < 0)
continue;
} else
#endif /* __linux__ */
/* Don't follow other symbolic links. */
continue; continue;
}
if (S_ISDIR (st.st_mode)) if (S_ISDIR (st.st_mode))
{ {
@ -355,6 +446,12 @@ grub_guess_root_device (const char *dir)
#else /* !__GNU__ */ #else /* !__GNU__ */
struct stat st; struct stat st;
#ifdef __linux__
os_dev = find_root_device_from_mountinfo (dir);
if (os_dev)
return os_dev;
#endif /* __linux__ */
if (stat (dir, &st) < 0) if (stat (dir, &st) < 0)
grub_util_error ("cannot stat `%s'", dir); grub_util_error ("cannot stat `%s'", dir);

View file

@ -338,11 +338,11 @@ find_partition_start (const char *dev)
struct hd_geometry hdg; struct hd_geometry hdg;
# else /* defined(__NetBSD__) */ # else /* defined(__NetBSD__) */
struct disklabel label; struct disklabel label;
int index; int p_index;
# endif /* !defined(__NetBSD__) */ # endif /* !defined(__NetBSD__) */
# ifdef HAVE_DEVICE_MAPPER # ifdef HAVE_DEVICE_MAPPER
if (device_is_mapped (dev)) { if (grub_device_mapper_supported () && device_is_mapped (dev)) {
struct dm_task *task = NULL; struct dm_task *task = NULL;
grub_uint64_t start, length; grub_uint64_t start, length;
char *target_type, *params, *space; char *target_type, *params, *space;
@ -412,7 +412,12 @@ devmapper_fail:
fd = open (dev, O_RDONLY); fd = open (dev, O_RDONLY);
if (fd == -1) if (fd == -1)
{ {
grub_error (GRUB_ERR_BAD_DEVICE, "cannot open `%s' while attempting to get disk geometry", dev); grub_error (GRUB_ERR_BAD_DEVICE,
# if !defined(__NetBSD__)
"cannot open `%s' while attempting to get disk geometry", dev);
# else /* defined(__NetBSD__) */
"cannot open `%s' while attempting to get disk label", dev);
# endif /* !defined(__NetBSD__) */
return 0; return 0;
} }
@ -424,7 +429,11 @@ devmapper_fail:
# endif /* !defined(__NetBSD__) */ # endif /* !defined(__NetBSD__) */
{ {
grub_error (GRUB_ERR_BAD_DEVICE, grub_error (GRUB_ERR_BAD_DEVICE,
# if !defined(__NetBSD__)
"cannot get disk geometry of `%s'", dev); "cannot get disk geometry of `%s'", dev);
# else /* defined(__NetBSD__) */
"cannot get disk label of `%s'", dev);
# endif /* !defined(__NetBSD__) */
close (fd); close (fd);
return 0; return 0;
} }
@ -434,18 +443,15 @@ devmapper_fail:
# if !defined(__NetBSD__) # if !defined(__NetBSD__)
return hdg.start; return hdg.start;
# else /* defined(__NetBSD__) */ # else /* defined(__NetBSD__) */
/* Since dev and convert_system_partition_to_system_disk (dev) are p_index = dev[strlen(dev) - 1] - 'a';
* different, we know that dev is of the form /dev/r[wsc]d[0-9]+[a-z]
* and in particular it cannot be a floppy device. */
index = dev[strlen(dev) - 1] - 'a';
if (index >= label.d_npartitions) if (p_index >= label.d_npartitions)
{ {
grub_error (GRUB_ERR_BAD_DEVICE, grub_error (GRUB_ERR_BAD_DEVICE,
"no disk label entry for `%s'", dev); "no disk label entry for `%s'", dev);
return 0; return 0;
} }
return (grub_disk_addr_t) label.d_partitions[index].p_offset; return (grub_disk_addr_t) label.d_partitions[p_index].p_offset;
# endif /* !defined(__NetBSD__) */ # endif /* !defined(__NetBSD__) */
} }
#endif /* __linux__ || __CYGWIN__ */ #endif /* __linux__ || __CYGWIN__ */
@ -1258,22 +1264,28 @@ devmapper_out:
return path; return path;
#elif defined(__NetBSD__) #elif defined(__NetBSD__)
/* NetBSD uses "/dev/r[wsc]d[0-9]+[a-z]". */ /* NetBSD uses "/dev/r[a-z]+[0-9][a-z]". */
char *path = xstrdup (os_dev); char *path = xstrdup (os_dev);
if (strncmp ("/dev/rwd", path, 8) == 0 || if (strncmp ("/dev/r", path, sizeof("/dev/r") - 1) == 0 &&
strncmp ("/dev/rsd", path, 8) == 0 || (path[sizeof("/dev/r") - 1] >= 'a' && path[sizeof("/dev/r") - 1] <= 'z') &&
strncmp ("/dev/rcd", path, 8) == 0) strncmp ("fd", path + sizeof("/dev/r") - 1, sizeof("fd") - 1) != 0) /* not a floppy device name */
{ {
char *q; char *p;
q = path + strlen(path) - 1; /* last character */ for (p = path + sizeof("/dev/r"); *p >= 'a' && *p <= 'z'; p++);
if (grub_isalpha(*q) && grub_isdigit(*(q-1))) if (grub_isdigit(*p))
{ {
int rawpart = -1; p++;
if ((*p >= 'a' && *p <= 'z') && (*(p+1) == '\0'))
{
/* path matches the required regular expression and
p points to its last character. */
int rawpart = -1;
# ifdef HAVE_GETRAWPARTITION # ifdef HAVE_GETRAWPARTITION
rawpart = getrawpartition(); rawpart = getrawpartition();
# endif /* HAVE_GETRAWPARTITION */ # endif /* HAVE_GETRAWPARTITION */
if (rawpart >= 0) if (rawpart >= 0)
*q = 'a' + rawpart; *p = 'a' + rawpart;
}
} }
} }
return path; return path;
@ -1431,9 +1443,7 @@ grub_util_biosdisk_get_grub_dev (const char *os_dev)
return name; return name;
# else /* defined(__NetBSD__) */ # else /* defined(__NetBSD__) */
/* Since os_dev and convert_system_partition_to_system_disk (os_dev) are /* Since os_dev and convert_system_partition_to_system_disk (os_dev) are
* different, we know that os_dev is of the form /dev/r[wsc]d[0-9]+[a-z] * different, we know that os_dev cannot be a floppy device. */
* and in particular it cannot be a floppy device. */
index = os_dev[strlen(os_dev) - 1] - 'a';
# endif /* !defined(__NetBSD__) */ # endif /* !defined(__NetBSD__) */
start = find_partition_start (os_dev); start = find_partition_start (os_dev);

View file

@ -9,6 +9,9 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#include <grub/mm.h> #include <grub/mm.h>
#include <grub/err.h> #include <grub/err.h>
@ -19,6 +22,10 @@
#include <grub/time.h> #include <grub/time.h>
#include <grub/emu/misc.h> #include <grub/emu/misc.h>
#ifdef HAVE_DEVICE_MAPPER
# include <libdevmapper.h>
#endif
int verbosity; int verbosity;
void void
@ -182,7 +189,8 @@ canonicalize_file_name (const char *path)
char *ret; char *ret;
#ifdef PATH_MAX #ifdef PATH_MAX
ret = xmalloc (PATH_MAX); ret = xmalloc (PATH_MAX);
(void) realpath (path, ret); if (!realpath (path, ret))
return NULL;
#else #else
ret = realpath (path, NULL); ret = realpath (path, NULL);
#endif #endif
@ -307,3 +315,38 @@ grub_make_system_path_relative_to_its_root (const char *path)
return buf3; return buf3;
} }
#ifdef HAVE_DEVICE_MAPPER
static void device_mapper_null_log (int level __attribute__ ((unused)),
const char *file __attribute__ ((unused)),
int line __attribute__ ((unused)),
int dm_errno __attribute__ ((unused)),
const char *f __attribute__ ((unused)),
...)
{
}
int
grub_device_mapper_supported (void)
{
static int supported = -1;
if (supported == -1)
{
struct dm_task *dmt;
/* Suppress annoying log messages. */
dm_log_with_errno_init (&device_mapper_null_log);
dmt = dm_task_create (DM_DEVICE_VERSION);
supported = (dmt != NULL);
if (dmt)
dm_task_destroy (dmt);
/* Restore the original logger. */
dm_log_with_errno_init (NULL);
}
return supported;
}
#endif /* HAVE_DEVICE_MAPPER */

View file

@ -75,8 +75,8 @@ make_install_device (void)
ptr += grub_strlen (ptr); ptr += grub_strlen (ptr);
if (grub_install_bsd_part >= 0) if (grub_install_bsd_part >= 0)
grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%c", grub_snprintf (ptr, sizeof (dev) - (ptr - dev), ",%u",
grub_install_bsd_part + 'a'); grub_install_bsd_part + 1);
ptr += grub_strlen (ptr); ptr += grub_strlen (ptr);
} }

View file

@ -20,6 +20,7 @@
#include <grub/machine/memory.h> #include <grub/machine/memory.h>
#include <grub/err.h> #include <grub/err.h>
#include <grub/types.h> #include <grub/types.h>
#include <grub/misc.h>
grub_err_t grub_err_t
grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t)) grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
@ -28,6 +29,8 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin
struct grub_machine_mmap_entry *entry struct grub_machine_mmap_entry *entry
= (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
grub_memset (entry, 0, sizeof (entry));
/* Check if grub_get_mmap_entry works. */ /* Check if grub_get_mmap_entry works. */
cont = grub_get_mmap_entry (entry, 0); cont = grub_get_mmap_entry (entry, 0);
@ -43,6 +46,8 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin
if (! cont) if (! cont)
break; break;
grub_memset (entry, 0, sizeof (entry));
cont = grub_get_mmap_entry (entry, cont); cont = grub_get_mmap_entry (entry, cont);
} }
while (entry->size); while (entry->size);

View file

@ -1058,7 +1058,7 @@ grub_abort (void)
void abort (void) __attribute__ ((alias ("grub_abort"))); void abort (void) __attribute__ ((alias ("grub_abort")));
#endif #endif
#if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) #if defined(NEED_ENABLE_EXECUTE_STACK) && !defined(GRUB_UTIL) && !defined(GRUB_MACHINE_EMU)
/* Some gcc versions generate a call to this function /* Some gcc versions generate a call to this function
in trampolines for nested functions. */ in trampolines for nested functions. */
void __enable_execute_stack (void *addr __attribute__ ((unused))) void __enable_execute_stack (void *addr __attribute__ ((unused)))
@ -1075,3 +1075,4 @@ void __deregister_frame_info (void)
{ {
} }
#endif #endif

View file

@ -74,7 +74,11 @@ CONCAT(grub_multiboot_load_elf, XX) (grub_file_t file, void *buffer)
if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH) if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset"); return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
#ifdef MULTIBOOT_LOAD_ELF64 #if defined (MULTIBOOT_LOAD_ELF64) && defined (__mips)
/* We still in 32-bit mode. */
if (ehdr->e_entry < 0xffffffff80000000ULL)
return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64");
#else
/* We still in 32-bit mode. */ /* We still in 32-bit mode. */
if (ehdr->e_entry > 0xffffffff) if (ehdr->e_entry > 0xffffffff)
return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64"); return grub_error (GRUB_ERR_BAD_OS, "invalid entry point for ELF64");

View file

@ -496,7 +496,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
= (struct multiboot_tag_module *) ptrorig; = (struct multiboot_tag_module *) ptrorig;
tag->type = MULTIBOOT_TAG_TYPE_MODULE; tag->type = MULTIBOOT_TAG_TYPE_MODULE;
tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size; tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size;
tag->mod_start = dest + cur->start; tag->mod_start = cur->start;
tag->mod_end = tag->mod_start + cur->size; tag->mod_end = tag->mod_start + cur->size;
grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size); grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size);
ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN); ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);

View file

@ -414,6 +414,14 @@ grub_normal_do_completion (char *buf, int *restore,
else else
current_word = argv[argc - 1]; current_word = argv[argc - 1];
if (argc > 1 && ! grub_strcmp (argv[0], "set"))
{
char *equals = grub_strchr (current_word, '=');
if (equals)
/* Complete the value of the variable. */
current_word = equals + 1;
}
/* Determine the state the command line is in, depending on the /* Determine the state the command line is in, depending on the
state, it can be determined how to complete. */ state, it can be determined how to complete. */
cmdline_state = get_state (buf); cmdline_state = get_state (buf);

View file

@ -204,7 +204,7 @@ grub_normal_add_menu_entry (int argc, const char **args,
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
{ {
/* Capture arguments. */ /* Capture arguments. */
if (grub_strncmp ("--", args[i], 2) == 0) if (grub_strncmp ("--", args[i], 2) == 0 && i + 1 < argc)
{ {
const char *arg = &args[i][2]; const char *arg = &args[i][2];

View file

@ -707,12 +707,6 @@ real_scroll (void)
draw_cursor (0); draw_cursor (0);
grub_video_set_active_render_target (render_target); grub_video_set_active_render_target (render_target);
/* Save viewport and set it to our window. */
grub_video_get_viewport ((unsigned *) &saved_view.x,
(unsigned *) &saved_view.y,
(unsigned *) &saved_view.width,
(unsigned *) &saved_view.height);
grub_video_set_viewport (window.x, window.y, window.width, window.height);
i = window.double_repaint ? 2 : 1; i = window.double_repaint ? 2 : 1;
@ -720,6 +714,15 @@ real_scroll (void)
while (i--) while (i--)
{ {
/* Save viewport and set it to our window. */
grub_video_get_viewport ((unsigned *) &saved_view.x,
(unsigned *) &saved_view.y,
(unsigned *) &saved_view.width,
(unsigned *) &saved_view.height);
grub_video_set_viewport (window.x, window.y, window.width,
window.height);
/* Clear new border area. */ /* Clear new border area. */
grub_video_fill_rect (color, grub_video_fill_rect (color,
virtual_screen.offset_x, virtual_screen.offset_x,
@ -735,6 +738,10 @@ real_scroll (void)
grub_video_scroll (color, 0, -virtual_screen.normal_char_height grub_video_scroll (color, 0, -virtual_screen.normal_char_height
* virtual_screen.total_scroll); * virtual_screen.total_scroll);
/* Restore saved viewport. */
grub_video_set_viewport (saved_view.x, saved_view.y,
saved_view.width, saved_view.height);
if (i) if (i)
grub_video_swap_buffers (); grub_video_swap_buffers ();
} }
@ -746,9 +753,6 @@ real_scroll (void)
grub_video_scroll (color, 0, -virtual_screen.normal_char_height grub_video_scroll (color, 0, -virtual_screen.normal_char_height
* virtual_screen.total_scroll); * virtual_screen.total_scroll);
/* Restore saved viewport. */
grub_video_set_viewport (saved_view.x, saved_view.y,
saved_view.width, saved_view.height);
grub_video_set_active_render_target (render_target); grub_video_set_active_render_target (render_target);
} }

View file

@ -18,7 +18,6 @@
*/ */
#include <grub/term.h> #include <grub/term.h>
#include <grub/machine/console.h>
#include <grub/time.h> #include <grub/time.h>
#include <grub/cpu/io.h> #include <grub/cpu/io.h>
#include <grub/misc.h> #include <grub/misc.h>

View file

@ -33,6 +33,7 @@
#include <grub/util/deviceiter.h> #include <grub/util/deviceiter.h>
#include <grub/list.h> #include <grub/list.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/emu/misc.h>
#ifdef __linux__ #ifdef __linux__
# if !defined(__GLIBC__) || \ # if !defined(__GLIBC__) || \
@ -676,112 +677,113 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
} }
/* DM-RAID. */ /* DM-RAID. */
{ if (grub_device_mapper_supported ())
struct dm_tree *tree = NULL; {
struct dm_task *task = NULL; struct dm_tree *tree = NULL;
struct dm_names *names = NULL; struct dm_task *task = NULL;
unsigned int next = 0; struct dm_names *names = NULL;
void *top_handle, *second_handle; unsigned int next = 0;
struct dm_tree_node *root, *top, *second; void *top_handle, *second_handle;
struct dmraid_seen *seen = NULL; struct dm_tree_node *root, *top, *second;
struct dmraid_seen *seen = NULL;
/* Build DM tree for all devices. */ /* Build DM tree for all devices. */
tree = dm_tree_create (); tree = dm_tree_create ();
dmraid_check (tree, "dm_tree_create failed\n"); dmraid_check (tree, "dm_tree_create failed\n");
task = dm_task_create (DM_DEVICE_LIST); task = dm_task_create (DM_DEVICE_LIST);
dmraid_check (task, "dm_task_create failed\n"); dmraid_check (task, "dm_task_create failed\n");
dmraid_check (dm_task_run (task), "dm_task_run failed\n"); dmraid_check (dm_task_run (task), "dm_task_run failed\n");
names = dm_task_get_names (task); names = dm_task_get_names (task);
dmraid_check (names, "dm_task_get_names failed\n"); dmraid_check (names, "dm_task_get_names failed\n");
dmraid_check (names->dev, "No DM devices found\n"); dmraid_check (names->dev, "No DM devices found\n");
do do
{ {
names = (void *) names + next; names = (void *) names + next;
dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev),
MINOR (names->dev)), MINOR (names->dev)),
"dm_tree_add_dev (%s) failed\n", names->name); "dm_tree_add_dev (%s) failed\n", names->name);
next = names->next; next = names->next;
} }
while (next); while (next);
/* Walk the second-level children of the inverted tree; that is, devices /* Walk the second-level children of the inverted tree; that is, devices
which are directly composed of non-DM devices such as hard disks. which are directly composed of non-DM devices such as hard disks.
This class includes all DM-RAID disks and excludes all DM-RAID This class includes all DM-RAID disks and excludes all DM-RAID
partitions. */ partitions. */
root = dm_tree_find_node (tree, 0, 0); root = dm_tree_find_node (tree, 0, 0);
top_handle = NULL; top_handle = NULL;
top = dm_tree_next_child (&top_handle, root, 1); top = dm_tree_next_child (&top_handle, root, 1);
while (top) while (top)
{ {
second_handle = NULL; second_handle = NULL;
second = dm_tree_next_child (&second_handle, top, 1); second = dm_tree_next_child (&second_handle, top, 1);
while (second) while (second)
{ {
const char *node_name, *node_uuid; const char *node_name, *node_uuid;
char *name; char *name;
struct dmraid_seen *seen_elt; struct dmraid_seen *seen_elt;
node_name = dm_tree_node_get_name (second); node_name = dm_tree_node_get_name (second);
dmraid_check (node_name, "dm_tree_node_get_name failed\n"); dmraid_check (node_name, "dm_tree_node_get_name failed\n");
node_uuid = dm_tree_node_get_uuid (second); node_uuid = dm_tree_node_get_uuid (second);
dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n");
if (strncmp (node_uuid, "DMRAID-", 7) != 0) if (strncmp (node_uuid, "DMRAID-", 7) != 0)
{ {
grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name);
goto dmraid_next_child; goto dmraid_next_child;
} }
/* Have we already seen this node? There are typically very few /* Have we already seen this node? There are typically very few
DM-RAID disks, so a list should be fast enough. */ DM-RAID disks, so a list should be fast enough. */
if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name))
{ {
grub_dprintf ("deviceiter", "Already seen DM device %s\n", grub_dprintf ("deviceiter", "Already seen DM device %s\n",
node_name); node_name);
goto dmraid_next_child; goto dmraid_next_child;
} }
name = xasprintf ("/dev/mapper/%s", node_name); name = xasprintf ("/dev/mapper/%s", node_name);
if (check_device (name)) if (check_device (name))
{ {
if (hook (name, 0)) if (hook (name, 0))
{ {
free (name); free (name);
while (seen) while (seen)
{ {
struct dmraid_seen *seen_elt = struct dmraid_seen *seen_elt =
grub_list_pop (GRUB_AS_LIST_P (&seen)); grub_list_pop (GRUB_AS_LIST_P (&seen));
free (seen_elt); free (seen_elt);
} }
if (task) if (task)
dm_task_destroy (task); dm_task_destroy (task);
if (tree) if (tree)
dm_tree_free (tree); dm_tree_free (tree);
return; return;
} }
} }
free (name); free (name);
seen_elt = xmalloc (sizeof *seen_elt); seen_elt = xmalloc (sizeof *seen_elt);
seen_elt->name = node_name; seen_elt->name = node_name;
grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt));
dmraid_next_child: dmraid_next_child:
second = dm_tree_next_child (&second_handle, top, 1); second = dm_tree_next_child (&second_handle, top, 1);
} }
top = dm_tree_next_child (&top_handle, root, 1); top = dm_tree_next_child (&top_handle, root, 1);
} }
dmraid_end: dmraid_end:
while (seen) while (seen)
{ {
struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen)); struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen));
free (seen_elt); free (seen_elt);
} }
if (task) if (task)
dm_task_destroy (task); dm_task_destroy (task);
if (tree) if (tree)
dm_tree_free (tree); dm_tree_free (tree);
} }
# endif /* HAVE_DEVICE_MAPPER */ # endif /* HAVE_DEVICE_MAPPER */
#endif /* __linux__ */ #endif /* __linux__ */
} }

View file

@ -34,6 +34,8 @@ font=@datadir@/@PACKAGE_TARNAME@/ascii.pf2
pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
localedir=@datadir@/locale localedir=@datadir@/locale
self=`basename $0`
grub_setup=${sbindir}/`echo grub-setup | sed ${transform}` grub_setup=${sbindir}/`echo grub-setup | sed ${transform}`
grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
@ -61,7 +63,7 @@ fi
# Print the usage. # Print the usage.
usage () { usage () {
cat <<EOF cat <<EOF
Usage: grub-install [OPTION] install_device Usage: $self [OPTION] install_device
Install GRUB on your drive. Install GRUB on your drive.
-h, --help print this message and exit -h, --help print this message and exit
@ -91,10 +93,10 @@ fi
INSTALL_DEVICE can be a GRUB device name or a system device filename. INSTALL_DEVICE can be a GRUB device name or a system device filename.
grub-install copies GRUB images into /boot/grub (or /grub on NetBSD and $self copies GRUB images into /boot/grub (or /grub on NetBSD and
OpenBSD), and uses grub-setup to install grub into the boot sector. OpenBSD), and uses grub-setup to install grub into the boot sector.
If the --root-directory option is used, then grub-install will copy If the --root-directory option is used, then $self will copy
images into the operating system installation rooted at that directory. images into the operating system installation rooted at that directory.
Report bugs to <bug-grub@gnu.org>. Report bugs to <bug-grub@gnu.org>.
@ -108,7 +110,7 @@ for option in "$@"; do
usage usage
exit 0 ;; exit 0 ;;
-v | --version) -v | --version)
echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;; exit 0 ;;
--modules=*) --modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;; modules=`echo "$option" | sed 's/--modules=//'` ;;

View file

@ -23,7 +23,8 @@ exec_prefix=@exec_prefix@
sbindir=@sbindir@ sbindir=@sbindir@
libdir=@libdir@ libdir=@libdir@
sysconfdir=@sysconfdir@ sysconfdir=@sysconfdir@
package_version=@PACKAGE_VERSION@ PACKAGE_NAME=@PACKAGE_NAME@
PACKAGE_VERSION=@PACKAGE_VERSION@
host_os=@host_os@ host_os=@host_os@
datarootdir=@datarootdir@ datarootdir=@datarootdir@
datadir=@datadir@ datadir=@datadir@
@ -31,6 +32,8 @@ pkgdatadir=${datadir}/`echo @PACKAGE_TARNAME@ | sed "${transform}"`
grub_cfg="" grub_cfg=""
grub_mkconfig_dir=${sysconfdir}/grub.d grub_mkconfig_dir=${sysconfdir}/grub.d
self=`basename $0`
grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
@ -38,7 +41,7 @@ grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
# Print the usage. # Print the usage.
usage () { usage () {
cat <<EOF cat <<EOF
Usage: $0 [OPTION] Usage: $self [OPTION]
Generate a grub config file Generate a grub config file
-o, --output=FILE output generated config to FILE [default=stdout] -o, --output=FILE output generated config to FILE [default=stdout]
@ -50,17 +53,22 @@ EOF
} }
# Check the arguments. # Check the arguments.
next_grub_cfg=false
for option in "$@"; do for option in "$@"; do
if $next_grub_cfg; then
grub_cfg=$option
next_grub_cfg=false
continue
fi
case "$option" in case "$option" in
-h | --help) -h | --help)
usage usage
exit 0 ;; exit 0 ;;
-v | --version) -v | --version)
echo "$0 (GNU GRUB ${package_version})" echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;; exit 0 ;;
-o) -o)
shift next_grub_cfg=:
grub_cfg=$1
;; ;;
--output=*) --output=*)
grub_cfg=`echo "$option" | sed 's/--output=//'` grub_cfg=`echo "$option" | sed 's/--output=//'`
@ -72,6 +80,11 @@ for option in "$@"; do
;; ;;
esac esac
done done
if $next_grub_cfg; then
echo "Missing argument to \`-o'" 1>&2
usage
exit 1
fi
. ${libdir}/grub/grub-mkconfig_lib . ${libdir}/grub/grub-mkconfig_lib
@ -103,7 +116,7 @@ if [ "$EUID" != 0 ] ; then
done ;; done ;;
esac esac
if [ $root != t ] ; then if [ $root != t ] ; then
echo "$0: You must run this as root" >&2 echo "$self: You must run this as root" >&2
exit 1 exit 1
fi fi
fi fi
@ -236,6 +249,10 @@ export GRUB_DEFAULT \
GRUB_HIDDEN_TIMEOUT \ GRUB_HIDDEN_TIMEOUT \
GRUB_HIDDEN_TIMEOUT_QUIET \ GRUB_HIDDEN_TIMEOUT_QUIET \
GRUB_TIMEOUT \ GRUB_TIMEOUT \
GRUB_DEFAULT_BUTTON \
GRUB_HIDDEN_TIMEOUT_BUTTON \
GRUB_TIMEOUT_BUTTON \
GRUB_BUTTON_CMOS_ADDRESS \
GRUB_DISTRIBUTOR \ GRUB_DISTRIBUTOR \
GRUB_CMDLINE_LINUX \ GRUB_CMDLINE_LINUX \
GRUB_CMDLINE_LINUX_DEFAULT \ GRUB_CMDLINE_LINUX_DEFAULT \
@ -270,7 +287,7 @@ cat << EOF
# #
# DO NOT EDIT THIS FILE # DO NOT EDIT THIS FILE
# #
# It is automatically generated by $0 using templates # It is automatically generated by $self using templates
# from ${grub_mkconfig_dir} and settings from ${sysconfdir}/default/grub # from ${grub_mkconfig_dir} and settings from ${sysconfdir}/default/grub
# #
EOF EOF

View file

@ -105,6 +105,11 @@ prepare_grub_to_access_device ()
echo "insmod ${module}" echo "insmod ${module}"
done done
partmap="`${grub_probe} --device ${device} --target=partmap`"
for module in ${partmap} ; do
echo "insmod part_${module}"
done
fs="`${grub_probe} --device ${device} --target=fs`" fs="`${grub_probe} --device ${device} --target=fs`"
for module in ${fs} ; do for module in ${fs} ; do
echo "insmod ${module}" echo "insmod ${module}"

View file

@ -1253,7 +1253,7 @@ main (int argc, char *argv[])
image_target = &image_targets[i]; image_target = &image_targets[i];
if (!image_target) if (!image_target)
{ {
printf ("unknown target %s\n", optarg); printf ("unknown target format %s\n", optarg);
usage (1); usage (1);
} }
break; break;
@ -1307,7 +1307,7 @@ main (int argc, char *argv[])
break; break;
case 'V': case 'V':
printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
return 0; return 0;
case 'v': case 'v':
@ -1322,7 +1322,7 @@ main (int argc, char *argv[])
if (!image_target) if (!image_target)
{ {
printf ("Target not specified.\n"); printf ("Target format not specified (use the -O option).\n");
usage (1); usage (1);
} }

View file

@ -112,7 +112,7 @@ hexify (char *hex, grub_uint8_t *bin, grub_size_t n)
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
unsigned int c = 10000, buflen = 64, saltlen = 64; unsigned int count = 10000, buflen = 64, saltlen = 64;
char *pass1, *pass2; char *pass1, *pass2;
char *bufhex, *salthex; char *bufhex, *salthex;
gcry_err_code_t gcry_err; gcry_err_code_t gcry_err;
@ -137,7 +137,7 @@ main (int argc, char *argv[])
switch (c) switch (c)
{ {
case 'c': case 'c':
c = strtoul (optarg, NULL, 0); count = strtoul (optarg, NULL, 0);
break; break;
case 'l': case 'l':
@ -307,7 +307,7 @@ main (int argc, char *argv[])
gcry_err = grub_crypto_pbkdf2 (GRUB_MD_SHA512, gcry_err = grub_crypto_pbkdf2 (GRUB_MD_SHA512,
(grub_uint8_t *) pass1, strlen (pass1), (grub_uint8_t *) pass1, strlen (pass1),
salt, saltlen, salt, saltlen,
c, buf, buflen); count, buf, buflen);
memset (pass1, 0, strlen (pass1)); memset (pass1, 0, strlen (pass1));
free (pass1); free (pass1);
@ -327,7 +327,8 @@ main (int argc, char *argv[])
hexify (bufhex, buf, buflen); hexify (bufhex, buf, buflen);
hexify (salthex, salt, saltlen); hexify (salthex, salt, saltlen);
printf ("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n", c, salthex, bufhex); printf ("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n",
count, salthex, bufhex);
memset (buf, 0, buflen); memset (buf, 0, buflen);
memset (bufhex, 0, 2 * buflen); memset (bufhex, 0, 2 * buflen);
free (buf); free (buf);

View file

@ -41,7 +41,7 @@ usage (int status)
printf ("\ printf ("\
Usage: %s [OPTIONS] PATH\n\ Usage: %s [OPTIONS] PATH\n\
\n\ \n\
Make a system path relative to it's root.\n\ Make a system path relative to its root.\n\
\n\ \n\
Options:\n\ Options:\n\
-h, --help display this message and exit\n\ -h, --help display this message and exit\n\

View file

@ -30,6 +30,8 @@ target_cpu=@target_cpu@
native_platform=@platform@ native_platform=@platform@
pkglib_DATA="@pkglib_DATA@" pkglib_DATA="@pkglib_DATA@"
self=`basename $0`
multiboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-multiboot multiboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-multiboot
coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-coreboot coreboot_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-coreboot
qemu_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-qemu qemu_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-qemu
@ -37,13 +39,14 @@ pc_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-pc
efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi efi32_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/i386-efi
efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi efi64_dir=${libdir}/$(echo ${PACKAGE_TARNAME} | sed ${transform})/x86_64-efi
rom_directory= rom_directory=
override_dir=
grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
# Usage: usage # Usage: usage
# Print the usage. # Print the usage.
usage () { usage () {
cat <<EOF cat <<EOF
Usage: $0 [OPTION] SOURCE... Usage: $self [OPTION] SOURCE...
Make GRUB rescue image. Make GRUB rescue image.
-h, --help print this message and exit -h, --help print this message and exit
@ -53,7 +56,7 @@ Make GRUB rescue image.
--rom-directory=DIR save rom images in DIR [optional] --rom-directory=DIR save rom images in DIR [optional]
--grub-mkimage=FILE use FILE as grub-mkimage --grub-mkimage=FILE use FILE as grub-mkimage
$0 generates a bootable rescue image with specified source files or directories. $self generates a bootable rescue image with specified source files or directories.
Report bugs to <bug-grub@gnu.org>. Report bugs to <bug-grub@gnu.org>.
EOF EOF
@ -66,7 +69,7 @@ for option in "$@"; do
usage usage
exit 0 ;; exit 0 ;;
-v | --version) -v | --version)
echo "$0 (GNU GRUB ${PACKAGE_VERSION})" echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;; exit 0 ;;
--modules=*) --modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;; modules=`echo "$option" | sed 's/--modules=//'` ;;

View file

@ -22,6 +22,10 @@ transform="@program_transform_name@"
prefix=@prefix@ prefix=@prefix@
exec_prefix=@exec_prefix@ exec_prefix=@exec_prefix@
bindir=@bindir@ bindir=@bindir@
PACKAGE_NAME=@PACKAGE_NAME@
PACKAGE_VERSION=@PACKAGE_VERSION@
self=`basename $0`
grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}`
rootdir= rootdir=
@ -30,7 +34,7 @@ rootdir=
# Print the usage. # Print the usage.
usage () { usage () {
cat <<EOF cat <<EOF
Usage: $0 [OPTION] entry Usage: $self [OPTION] entry
Set the default boot entry for GRUB, for the next boot only. Set the default boot entry for GRUB, for the next boot only.
-h, --help print this message and exit -h, --help print this message and exit
@ -51,7 +55,7 @@ for option in "$@"; do
usage usage
exit 0 ;; exit 0 ;;
-v | --version) -v | --version)
echo "grub-reboot (GNU GRUB ${PACKAGE_VERSION})" echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;; exit 0 ;;
--root-directory=*) --root-directory=*)
rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;

View file

@ -145,7 +145,8 @@ main (int argc, char *argv[])
char *input; char *input;
FILE *file = 0; FILE *file = 0;
int verbose = 0; int verbose = 0;
struct grub_script *script; int found_input = 0;
struct grub_script *script = NULL;
auto grub_err_t get_config_line (char **line, int cont); auto grub_err_t get_config_line (char **line, int cont);
grub_err_t get_config_line (char **line, int cont __attribute__ ((unused))) grub_err_t get_config_line (char **line, int cont __attribute__ ((unused)))
@ -247,6 +248,7 @@ main (int argc, char *argv[])
get_config_line(&input, 0); get_config_line(&input, 0);
if (! input) if (! input)
break; break;
found_input = 1;
script = grub_script_parse (input, get_config_line); script = grub_script_parse (input, get_config_line);
if (script) if (script)
@ -262,5 +264,5 @@ main (int argc, char *argv[])
grub_fini_all (); grub_fini_all ();
if (file) fclose (file); if (file) fclose (file);
return (script == 0); return (found_input && script == 0);
} }

View file

@ -22,6 +22,10 @@ transform="@program_transform_name@"
prefix=@prefix@ prefix=@prefix@
exec_prefix=@exec_prefix@ exec_prefix=@exec_prefix@
bindir=@bindir@ bindir=@bindir@
PACKAGE_NAME=@PACKAGE_NAME@
PACKAGE_VERSION=@PACKAGE_VERSION@
self=`basename $0`
grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}` grub_editenv=${bindir}/`echo grub-editenv | sed ${transform}`
rootdir= rootdir=
@ -30,7 +34,7 @@ rootdir=
# Print the usage. # Print the usage.
usage () { usage () {
cat <<EOF cat <<EOF
Usage: $0 [OPTION] entry Usage: $self [OPTION] entry
Set the default boot entry for GRUB. Set the default boot entry for GRUB.
-h, --help print this message and exit -h, --help print this message and exit
@ -51,7 +55,7 @@ for option in "$@"; do
usage usage
exit 0 ;; exit 0 ;;
-v | --version) -v | --version)
echo "grub-set-default (GNU GRUB ${PACKAGE_VERSION})" echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;; exit 0 ;;
--root-directory=*) --root-directory=*)
rootdir=`echo "$option" | sed 's/--root-directory=//'` ;; rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;

View file

@ -38,13 +38,31 @@ if [ "x${GRUB_DEFAULT}" = "xsaved" ] ; then GRUB_DEFAULT='${saved_entry}' ; fi
if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi
if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=640x480 ; fi if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=640x480 ; fi
if [ "x${GRUB_DEFAULT_BUTTON}" = "x" ] ; then GRUB_DEFAULT_BUTTON="$GRUB_DEFAULT" ; fi
if [ "x${GRUB_DEFAULT_BUTTON}" = "xsaved" ] ; then GRUB_DEFAULT_BUTTON='${saved_entry}' ; fi
if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT" ; fi
cat << EOF cat << EOF
if [ -s \$prefix/grubenv ]; then if [ -s \$prefix/grubenv ]; then
load_env load_env
fi fi
EOF
if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then
cat <<EOF
if cmostest $GRUB_BUTTON_CMOS_ADDRESS ; then
set default="${GRUB_DEFAULT_BUTTON}"
else
set default="${GRUB_DEFAULT}"
fi
EOF
else
cat <<EOF
set default="${GRUB_DEFAULT}" set default="${GRUB_DEFAULT}"
if [ \${prev_saved_entry} ]; then EOF
set saved_entry=\${prev_saved_entry} fi
cat <<EOF
if [ "\${prev_saved_entry}" ]; then
set saved_entry="\${prev_saved_entry}"
save_env saved_entry save_env saved_entry
set prev_saved_entry= set prev_saved_entry=
save_env prev_saved_entry save_env prev_saved_entry
@ -52,8 +70,8 @@ if [ \${prev_saved_entry} ]; then
fi fi
function savedefault { function savedefault {
if [ -z \${boot_once} ]; then if [ -z "\${boot_once}" ]; then
saved_entry=\${chosen} saved_entry="\${chosen}"
save_env saved_entry save_env saved_entry
fi fi
} }
@ -177,7 +195,7 @@ EOF
esac esac
# Gettext variables and module # Gettext variables and module
if [ "x${LANG}" != "xC" ] ; then if [ "x${LANG}" != "xC" ] && [ -d "${locale_dir}" ] ; then
prepare_grub_to_access_device $(${grub_probe} --target=device ${locale_dir}) prepare_grub_to_access_device $(${grub_probe} --target=device ${locale_dir})
cat << EOF cat << EOF
set locale_dir=(\$root)$(make_system_path_relative_to_its_root ${locale_dir}) set locale_dir=(\$root)$(make_system_path_relative_to_its_root ${locale_dir})
@ -186,21 +204,36 @@ insmod gettext
EOF EOF
fi fi
if [ "x${GRUB_HIDDEN_TIMEOUT}" != "x" ] ; then make_timeout ()
if [ "x${GRUB_HIDDEN_TIMEOUT_QUIET}" = "xtrue" ] ; then {
verbose= if [ "x${1}" != "x" ] ; then
else if [ "x${GRUB_HIDDEN_TIMEOUT_QUIET}" = "xtrue" ] ; then
verbose=" --verbose" verbose=
fi else
cat << EOF verbose=" --verbose"
if sleep$verbose --interruptible ${GRUB_HIDDEN_TIMEOUT} ; then fi
set timeout=${GRUB_TIMEOUT} cat << EOF
if sleep$verbose --interruptible ${1} ; then
set timeout=${2}
fi fi
EOF EOF
else else
cat << EOF cat << EOF
set timeout=${GRUB_TIMEOUT} set timeout=${2}
EOF EOF
fi
}
if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then
cat <<EOF
if cmostest $GRUB_BUTTON_CMOS_ADDRESS ; then
EOF
make_timeout "${GRUB_HIDDEN_TIMEOUT_BUTTON}" "${GRUB_TIMEOUT_BUTTON}"
echo else
make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}"
echo fi
else
make_timeout "${GRUB_HIDDEN_TIMEOUT}" "${GRUB_TIMEOUT}"
fi fi
# Play an initial tune # Play an initial tune

View file

@ -33,6 +33,8 @@ host_os=@host_os@
pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
localedir=@datadir@/locale localedir=@datadir@/locale
self=`basename $0`
grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
@ -50,7 +52,7 @@ debug=no
# Print the usage. # Print the usage.
usage () { usage () {
cat <<EOF cat <<EOF
Usage: grub-install [OPTION] Usage: $self [OPTION]
Install GRUB on your EFI partition. Install GRUB on your EFI partition.
-h, --help print this message and exit -h, --help print this message and exit
@ -64,7 +66,7 @@ Install GRUB on your EFI partition.
--no-floppy do not probe any floppy drive --no-floppy do not probe any floppy drive
--recheck probe a device map even if it already exists --recheck probe a device map even if it already exists
grub-install copies GRUB images into the DIR/boot directory specified by $self copies GRUB images into the DIR/boot directory specified by
--root-directory. --root-directory.
Report bugs to <bug-grub@gnu.org>. Report bugs to <bug-grub@gnu.org>.
@ -78,7 +80,7 @@ for option in "$@"; do
usage usage
exit 0 ;; exit 0 ;;
-v | --version) -v | --version)
echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;; exit 0 ;;
--modules=*) --modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;; modules=`echo "$option" | sed 's/--modules=//'` ;;
@ -219,7 +221,7 @@ $grub_mkimage -O ${target_cpu}-efi --output=${grubdir}/grub.efi $modules || exit
echo "Installation finished. No error reported." echo "Installation finished. No error reported."
echo "This is the contents of the device map $device_map." echo "This is the contents of the device map $device_map."
echo "Check if this is correct or not. If any of the lines is incorrect," echo "Check if this is correct or not. If any of the lines is incorrect,"
echo "fix it and re-run the script \`grub-install'." echo "fix it and re-run the script \`$self'."
echo echo
cat $device_map cat $device_map

View file

@ -126,8 +126,8 @@ setup (const char *dir,
/* There's always an embed region, and it starts right after the MBR. */ /* There's always an embed region, and it starts right after the MBR. */
embed_region.start = 1; embed_region.start = 1;
if (embed_region.end > p->start) if (embed_region.end > grub_partition_get_start (p))
embed_region.end = p->start; embed_region.end = grub_partition_get_start (p);
return 0; return 0;
} }
@ -147,8 +147,8 @@ setup (const char *dir,
/* If there's an embed region, it is in a dedicated partition. */ /* If there's an embed region, it is in a dedicated partition. */
if (! memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16)) if (! memcmp (&gptdata.type, &grub_gpt_partition_type_bios_boot, 16))
{ {
embed_region.start = p->start; embed_region.start = grub_partition_get_start (p);
embed_region.end = p->start + p->len; embed_region.end = grub_partition_get_start (p) + grub_partition_get_len (p);
return 1; return 1;
} }
@ -361,7 +361,7 @@ setup (const char *dir,
else else
grub_util_error (_("No DOS-style partitions found")); grub_util_error (_("No DOS-style partitions found"));
if (embed_region.end == embed_region.start) if (embed_region.end <= embed_region.start)
{ {
if (! strcmp (dest_partmap, "msdos")) if (! strcmp (dest_partmap, "msdos"))
grub_util_warn (_("This msdos-style partition label has no post-MBR gap; embedding won't be possible!")); grub_util_warn (_("This msdos-style partition label has no post-MBR gap; embedding won't be possible!"));
@ -702,7 +702,7 @@ main (int argc, char *argv[])
break; break;
case 'V': case 'V':
printf ("grub-setup (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
return 0; return 0;
case 'v': case 'v':

View file

@ -34,6 +34,8 @@ target_cpu=@target_cpu@
platform=@platform@ platform=@platform@
pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
self=`basename $0`
grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}` grub_mkdevicemap=${sbindir}/`echo grub-mkdevicemap | sed ${transform}`
grub_probe=${sbindir}/`echo grub-probe | sed ${transform}` grub_probe=${sbindir}/`echo grub-probe | sed ${transform}`
@ -53,7 +55,7 @@ nvsetenv=`which nvsetenv`
# Print the usage. # Print the usage.
usage () { usage () {
cat <<EOF cat <<EOF
Usage: grub-install [OPTION] [install_device] Usage: $self [OPTION] [install_device]
Install GRUB on your drive. Install GRUB on your drive.
-h, --help print this message and exit -h, --help print this message and exit
@ -66,7 +68,7 @@ Install GRUB on your drive.
--grub-probe=FILE use FILE as grub-probe --grub-probe=FILE use FILE as grub-probe
--no-nvram don't update the boot-device NVRAM variable --no-nvram don't update the boot-device NVRAM variable
grub-install copies GRUB images into the DIR/boot directory specified by $self copies GRUB images into the DIR/boot directory specified by
--root-directory, and uses nvsetenv to set the Open Firmware boot-device --root-directory, and uses nvsetenv to set the Open Firmware boot-device
variable. variable.
@ -81,7 +83,7 @@ for option in "$@"; do
usage usage
exit 0 ;; exit 0 ;;
-v | --version) -v | --version)
echo "grub-install (GNU GRUB ${PACKAGE_VERSION})" echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;; exit 0 ;;
--modules=*) --modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;; modules=`echo "$option" | sed 's/--modules=//'` ;;
@ -231,7 +233,7 @@ fi
echo "Installation finished. No error reported." echo "Installation finished. No error reported."
echo "This is the contents of the device map $device_map." echo "This is the contents of the device map $device_map."
echo "Check if this is correct or not. If any of the lines is incorrect," echo "Check if this is correct or not. If any of the lines is incorrect,"
echo "fix it and re-run the script \`grub-install'." echo "fix it and re-run the script \`$self'."
echo echo
cat $device_map cat $device_map

View file

@ -30,9 +30,6 @@
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#include <grub/kernel.h> #include <grub/kernel.h>
#include <grub/dl.h> #include <grub/dl.h>

View file

@ -30,13 +30,15 @@ target_cpu=@target_cpu@
platform=@platform@ platform=@platform@
pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}`
self=`basename $0`
grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}`
# Usage: usage # Usage: usage
# Print the usage. # Print the usage.
usage () { usage () {
cat <<EOF cat <<EOF
Usage: grub-mkrescue [OPTION] output_image Usage: $self [OPTION] output_image
Make GRUB rescue image. Make GRUB rescue image.
-h, --help print this message and exit -h, --help print this message and exit
@ -46,7 +48,7 @@ Make GRUB rescue image.
default: ${pkglibdir} default: ${pkglibdir}
--grub-mkimage=FILE use FILE as grub-mkimage --grub-mkimage=FILE use FILE as grub-mkimage
grub-mkimage generates a bootable rescue CD image for PowerMac and CHRP. $self generates a bootable rescue CD image for PowerMac and CHRP.
Report bugs to <bug-grub@gnu.org>. Report bugs to <bug-grub@gnu.org>.
EOF EOF
@ -61,7 +63,7 @@ for option in "$@"; do
usage usage
exit 0 ;; exit 0 ;;
-v | --version) -v | --version)
echo "grub-mkrescue (GNU GRUB ${PACKAGE_VERSION})" echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
exit 0 ;; exit 0 ;;
--modules=*) --modules=*)
modules=`echo "$option" | sed 's/--modules=//'` ;; modules=`echo "$option" | sed 's/--modules=//'` ;;

View file

@ -503,7 +503,7 @@ parse_options (struct grub_setup_info *gp, int argc, char *argv[])
break; break;
case 'V': case 'V':
printf ("grub-setup (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
return 0; return 0;
case 'v': case 'v':