diff options
author | David Cantrell <dcantrell@redhat.com> | 2008-08-25 17:13:37 -1000 |
---|---|---|
committer | David Cantrell <dcantrell@redhat.com> | 2008-08-25 17:13:37 -1000 |
commit | 80713e3f73e48856221c667f32b94b0a023ebecc (patch) | |
tree | aff4d9170fc24d2f1acc238a2d8908159a71d3dd /loader/hardware.c | |
parent | ef5fbf7bc72572f3a6326b12f9187a5438e58e4c (diff) | |
download | anaconda-80713e3f73e48856221c667f32b94b0a023ebecc.tar.gz anaconda-80713e3f73e48856221c667f32b94b0a023ebecc.tar.xz anaconda-80713e3f73e48856221c667f32b94b0a023ebecc.zip |
Renamed loader2 subdirectory to loader (hooray for git)
Diffstat (limited to 'loader/hardware.c')
-rw-r--r-- | loader/hardware.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/loader/hardware.c b/loader/hardware.c new file mode 100644 index 000000000..202c64187 --- /dev/null +++ b/loader/hardware.c @@ -0,0 +1,201 @@ +/* + * hardware.c - various hardware probing functionality + * + * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. + * + * Author(s): Erik Troan <ewt@redhat.com> + * Matt Wilson <msw@redhat.com> + * Michael Fulbright <msf@redhat.com> + * Jeremy Katz <katzj@redhat.com> + */ + +#include <errno.h> +#include <fcntl.h> +#include <popt.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/wait.h> + +#include "loader.h" +#include "hardware.h" +#include "log.h" + +/* FIXME: for turning off dma */ +#include <sys/ioctl.h> +#include <linux/hdreg.h> +#include "../isys/isys.h" + +/* boot flags */ +extern uint64_t flags; + +static int detectHardware() { + int child, rc, status; + int timeout = 0; /* FIXME: commandline option for this */ + + fprintf(stderr, "detecting hardware...\n"); + logMessage(DEBUGLVL, "probing buses"); + + if (!(child = fork())) { + int fd = open("/dev/tty3", O_RDWR); + + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + close(fd); + + rc = execl("/sbin/udevadm", "udevadm", "trigger", NULL); + _exit(1); + } + + waitpid(child, &status, 0); + if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) { + rc = 1; + } else { + rc = 0; + } + + fprintf(stderr, "waiting for hardware to initialize...\n"); + logMessage(DEBUGLVL, "waiting for hardware to initialize"); + + if (!(child = fork())) { + char *args[] = { "/sbin/udevsettle", "udevsettle", NULL, NULL }; + int fd = open("/dev/tty3", O_RDWR); + + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + close(fd); + + if (timeout) { + if (asprintf(&args[2],"--timeout=%d",timeout) == -1) { + logMessage(CRITICAL, "%s: %d: %m", __func__, __LINE__); + abort(); + } + } + + rc = execv("/sbin/udevsettle",args); + _exit(1); + } + + waitpid(child, &status, 0); + if (!WIFEXITED(status) || (WIFEXITED(status) && WEXITSTATUS(status))) { + rc = 1; + } else { + rc = 0; + } + if (rc) { + return LOADER_ERROR; + } + return LOADER_OK; +} + +/* this allows us to do an early load of modules specified on the + * command line to allow automating the load order of modules so that + * eg, certain scsi controllers are definitely first. + * FIXME: this syntax is likely to change in a future release + * but is done as a quick hack for the present. + */ +int earlyModuleLoad(int justProbe) { + int fd, len, i; + char buf[1024], *cmdLine; + int argc; + char ** argv; + + /* FIXME: reparsing /proc/cmdline to avoid major loader changes. + * should probably be done in loader.c:parseCmdline() like everything + * else + */ + if ((fd = open("/proc/cmdline", O_RDONLY)) < 0) return 1; + len = read(fd, buf, sizeof(buf) - 1); + close(fd); + if (len <= 0) return 1; + + buf[len] = '\0'; + cmdLine = buf; + + if (poptParseArgvString(cmdLine, &argc, (const char ***) &argv)) + return 1; + + for (i=0; i < argc; i++) { + if (!strncasecmp(argv[i], "driverload=", 11)) { + logMessage(INFO, "loading %s early", argv[i] + 11); + mlLoadModuleSet(argv[i] + 11); + } + } + return 0; +} + +int busProbe(int justProbe) { + /* autodetect whatever we can */ + if (justProbe) + return 0; + return detectHardware(); +} + +/* check if the system has been booted with dasd parameters */ +/* These parameters define the order in which the DASDs */ +/* are visible to Linux. Otherwise load dasd modules probeonly, */ +/* then parse proc to find active DASDs */ +/* Reload dasd_mod with correct range of DASD ports */ +void dasdSetup() { +#if !defined(__s390__) && !defined(__s390x__) + return; +#else + char **dasd_parms; + char *line; + char *parms = NULL, *parms_end; + FILE *fd; + + dasd_parms = malloc(sizeof(*dasd_parms) * 2); + dasd_parms[0] = NULL; + dasd_parms[1] = NULL; + + fd = fopen ("/tmp/dasd_ports", "r"); + if(fd) { + line = (char *)malloc(sizeof(char) * 200); + while (fgets (line, 199, fd) != NULL) { + if((parms = strstr(line, "dasd=")) || + (parms = strstr(line, "DASD="))) { + strncpy(parms, "dasd", 4); + parms_end = parms; + while(*parms_end && !(isspace(*parms_end))) parms_end++; + *parms_end = '\0'; + break; + } + } + fclose(fd); + if (strlen(parms) > 5) + dasd_parms[0] = strdup(parms); + free(line); + } + if(dasd_parms[0]) { + mlLoadModule("dasd_mod", dasd_parms); + + mlLoadModuleSet("dasd_diag_mod:dasd_fba_mod:dasd_eckd_mod"); + free(dasd_parms); + return; + } else { + dasd_parms[0] = "dasd=autodetect"; + mlLoadModule("dasd_mod", dasd_parms); + mlLoadModuleSet("dasd_diag_mod:dasd_fba_mod:dasd_eckd_mod"); + free(dasd_parms); + } +#endif +} |